Fail loudly on invalid parser output
authorMichael Spang <mspang@csclub.uwaterloo.ca>
Thu, 3 Dec 2009 23:47:37 +0000 (18:47 -0500)
committerMichael Spang <mspang@csclub.uwaterloo.ca>
Tue, 22 Dec 2009 03:09:50 +0000 (22:09 -0500)
Signed-off-by: Michael Spang <mspang@csclub.uwaterloo.ca>
Makefile
inapt.cc
inapt.h
parser.rl
util.cc [new file with mode: 0644]
util.h [new file with mode: 0644]

index 992b1cd..4aaf2ee 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ override CFLAGS  += -std=gnu99 $(INCLUDES)
 
 all: inapt parser.png
 
-inapt: inapt.o parser.o acqprogress.o
+inapt: inapt.o parser.o acqprogress.o util.o
        g++ -o inapt -g3 -Wall -Werror -lapt-pkg -lapt-inst $^
 
 parser.cc: parser.rl
index f11ddc3..12c75f4 100644 (file)
--- a/inapt.cc
+++ b/inapt.cc
@@ -14,6 +14,7 @@
 #include <apt-pkg/acquire-item.h>
 
 #include "inapt.h"
+#include "util.h"
 #include "acqprogress.h"
 
 using namespace std;
@@ -198,6 +199,8 @@ int main(int argc, char *argv[]) {
                 break;
             case inapt_action::REMOVE:
                 break;
+            default:
+                fatal("uninitialized action");
         }
     }
 
@@ -211,6 +214,8 @@ int main(int argc, char *argv[]) {
                 printf("remove %s %s:%d\n", i->package, i->filename, i->linenum);
                 DCache->MarkDelete(cache->FindPkg(i->package), false);
                 break;
+            default:
+                fatal("uninitialized action");
         }
     }
 
diff --git a/inapt.h b/inapt.h
index 2e6b043..73c62ba 100644 (file)
--- a/inapt.h
+++ b/inapt.h
@@ -2,7 +2,7 @@
 
 struct inapt_action {
     const char *package;
-    enum action_t { INSTALL, REMOVE } action;
+    enum action_t { INSTALL, REMOVE, UNSET } action;
     const char *filename;
     int linenum;
 };
index 007bbd3..9a2ee72 100644 (file)
--- a/parser.rl
+++ b/parser.rl
@@ -16,17 +16,18 @@ using namespace std;
 
     action add_list {
       tmp_action.package = xstrndup(ts, p - ts);
+      tmp_action.action = curaction;
       tmp_action.linenum = curline;
       tmp_action.filename = curfile;
       actions->push_back(tmp_action);
     }
 
     action install {
-        tmp_action.action = inapt_action::INSTALL;
+        curaction = inapt_action::INSTALL;
     }
 
     action remove {
-        tmp_action.action = inapt_action::REMOVE;
+        curaction = inapt_action::REMOVE;
     }
 
     action misc_error {
@@ -54,11 +55,10 @@ void scanner(vector<inapt_action> *actions)
     int done = 0;
     int curline = 1;
     char *ts = 0, *te = 0;
-    //int tl = 0;
 
-    vector<char *> tmp_list;
     inapt_action tmp_action;
     const char *curfile = "stdin";
+    enum inapt_action::action_t curaction = inapt_action::UNSET;
 
     %% write init;
 
diff --git a/util.cc b/util.cc
new file mode 100644 (file)
index 0000000..b5f6926
--- /dev/null
+++ b/util.cc
@@ -0,0 +1,104 @@
+#include <unistd.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <errno.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include "util.h"
+
+static void errmsg(int prio, const char *prefix, const char *fmt, va_list args) {
+    fprintf(stderr, "%s: ", prefix);
+    vfprintf(stderr, fmt, args);
+    fprintf(stderr, "\n");
+}
+
+static void errmsgpe(int prio, const char *prefix, const char *fmt, va_list args) {
+    fprintf(stderr, "%s: ", prefix);
+    vfprintf(stderr, fmt, args);
+    fprintf(stderr, ": %s\n", strerror(errno));
+}
+
+NORETURN static void die(int prio, const char *prefix, const char *msg, va_list args) {
+    errmsg(prio, prefix, msg, args);
+    exit(1);
+}
+
+NORETURN static void diepe(int prio, const char *prefix, const char *msg, va_list args) {
+    errmsgpe(prio, prefix, msg, args);
+    exit(1);
+}
+
+NORETURN void fatal(const char *msg, ...) {
+    va_list args;
+    va_start(args, msg);
+    die(LOG_CRIT, "fatal", msg, args);
+    va_end(args);
+}
+
+void error(const char *msg, ...) {
+    va_list args;
+    va_start(args, msg);
+    errmsg(LOG_ERR, "error", msg, args);
+    va_end(args);
+}
+
+void warn(const char *msg, ...) {
+    va_list args;
+    va_start(args, msg);
+    errmsg(LOG_WARNING, "warning", msg, args);
+    va_end(args);
+}
+
+void notice(const char *msg, ...) {
+    va_list args;
+    va_start(args, msg);
+    errmsg(LOG_NOTICE, "notice", msg, args);
+    va_end(args);
+}
+
+void debug(const char *msg, ...) {
+    va_list args;
+    va_start(args, msg);
+    errmsg(LOG_DEBUG, "debug", msg, args);
+    va_end(args);
+}
+
+NORETURN void deny(const char *msg, ...) {
+    va_list args;
+    va_start(args, msg);
+    die(LOG_ERR, "denied", msg, args);
+    va_end(args);
+}
+
+NORETURN void badconf(const char *msg, ...) {
+    va_list args;
+    va_start(args, msg);
+    die(LOG_CRIT, "configuration error", msg, args);
+    va_end(args);
+}
+
+NORETURN void fatalpe(const char *msg, ...) {
+    va_list args;
+    va_start(args, msg);
+    diepe(LOG_CRIT, "fatal", msg, args);
+    va_end(args);
+}
+
+void errorpe(const char *msg, ...) {
+    va_list args;
+    va_start(args, msg);
+    errmsgpe(LOG_ERR, "error", msg, args);
+    va_end(args);
+}
+
+void warnpe(const char *msg, ...) {
+    va_list args;
+    va_start(args, msg);
+    errmsgpe(LOG_WARNING, "warning", msg, args);
+    va_end(args);
+}
diff --git a/util.h b/util.h
new file mode 100644 (file)
index 0000000..78bb3d3
--- /dev/null
+++ b/util.h
@@ -0,0 +1,67 @@
+#ifndef CEO_UTIL_H
+#define CEO_UTIL_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+#ifdef __GNUC__
+#define NORETURN __attribute__((__noreturn__))
+#define PRINTF_LIKE(extra) __attribute__((format(printf, extra+1, extra+2)))
+#else
+#define NORETURN
+#define PRINTF_LIKE(extra)
+#endif
+
+PRINTF_LIKE(0) NORETURN void fatal(const char *, ...);
+PRINTF_LIKE(0) NORETURN void fatalpe(const char *, ...);
+PRINTF_LIKE(0) NORETURN void badconf(const char *, ...);
+PRINTF_LIKE(0) NORETURN void deny(const char *, ...);
+PRINTF_LIKE(0) void error(const char *, ...);
+PRINTF_LIKE(0) void warn(const char *, ...);
+PRINTF_LIKE(0) void notice(const char *, ...);
+PRINTF_LIKE(0) void debug(const char *, ...);
+PRINTF_LIKE(0) void errorpe(const char *, ...);
+PRINTF_LIKE(0) void warnpe(const char *, ...);
+
+static inline void *xmalloc(size_t size) {
+    void *alloc = malloc(size);
+
+    if (alloc == NULL)
+        fatal("out of memory");
+
+    return alloc;
+}
+
+static inline void *xrealloc(void *ptr, size_t size) {
+    void *alloc = realloc(ptr, size);
+
+    if (alloc == NULL)
+        fatal("out of memory");
+
+    return alloc;
+}
+
+static inline void *xcalloc(size_t nmemb, size_t size) {
+    void *alloc = calloc(nmemb, size);
+
+    if (alloc == NULL)
+        fatal("out of memory");
+
+    return alloc;
+}
+
+static inline char *xstrdup(const char *s) {
+    char *dup = strdup(s);
+
+    if (dup == NULL)
+        fatal("out of memory");
+
+    return dup;
+}
+
+#endif