[augeas-devel] augeas: master - interpreter: do not abort() on fatal errors or print on stderr

David Lutterkort lutter at fedoraproject.org
Thu Oct 1 00:24:01 UTC 2009


Gitweb:        http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=c006538412b3692b3fc63cf144f5fcc90659121c
Commit:        c006538412b3692b3fc63cf144f5fcc90659121c
Parent:        0f91b235a91bfda1d0d7d4934dd349619ee08757
Author:        David Lutterkort <lutter at redhat.com>
AuthorDate:    Wed Sep 30 17:04:25 2009 -0700
Committer:     David Lutterkort <lutter at redhat.com>
CommitterDate: Wed Sep 30 17:20:39 2009 -0700

interpreter: do not abort() on fatal errors or print on stderr

Use the error reporting infrastructure for most errors. Fatal errors (bugs)
in the interpreter now lead to an error code AUG_EINTERNAL, and not an
abort()
---
 src/syntax.c |   92 ++++++++++++++++++++++++++++++++++++++++++++-------------
 src/syntax.h |    4 +-
 2 files changed, 73 insertions(+), 23 deletions(-)

diff --git a/src/syntax.c b/src/syntax.c
index fb2a59f..63c88ea 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -76,26 +76,60 @@ struct ctx {
     struct binding *local;
 };
 
+static void format_error(struct info *info, aug_errcode_t code,
+                         const char *format, va_list ap) {
+    struct error *error = info->error;
+    char *si = NULL, *sf = NULL, *sd = NULL;
+    int r;
+
+    error->code = code;
+    /* Only syntax errors are cumulative */
+    if (code != AUG_ESYNTAX)
+        FREE(error->details);
+
+    si = format_info(info);
+    r = vasprintf(&sf, format, ap);
+    if (r < 0)
+        sf = NULL;
+    if (error->details != NULL) {
+        r = xasprintf(&sd, "%s\n%s%s", error->details,
+                      (si == NULL) ? "(no location)" : si,
+                      (sf == NULL) ? "(no details)" : sf);
+    } else {
+        r = xasprintf(&sd, "%s%s",
+                      (si == NULL) ? "(no location)" : si,
+                      (sf == NULL) ? "(no details)" : sf);
+    }
+    if (r >= 0) {
+        free(error->details);
+        error->details = sd;
+    }
+    free(si);
+    free(sf);
+}
+
 void syntax_error(struct info *info, const char *format, ...) {
+    struct error *error = info->error;
     va_list ap;
 
-    print_info(stderr, info);
+    if (error->code != AUG_NOERROR && error->code != AUG_ESYNTAX)
+        return;
+
 	va_start(ap, format);
-    vfprintf(stderr, format, ap);
+    format_error(info, AUG_ESYNTAX, format, ap);
     va_end(ap);
-    fprintf(stderr, "\n");
 }
 
 void fatal_error(struct info *info, const char *format, ...) {
+    struct error *error = info->error;
     va_list ap;
 
-    fprintf(stderr, "Fatal internal error. Aborting. Details:\n");
-    print_info(stderr, info);
+    if (error->code == AUG_EINTERNAL)
+        return;
+
 	va_start(ap, format);
-    vfprintf(stderr, format, ap);
+    format_error(info, AUG_EINTERNAL, format, ap);
     va_end(ap);
-    fprintf(stderr, "\n");
-    abort();
 }
 
 void assert_error_at(const char *srcfile, int srclineno, struct info *info,
@@ -634,11 +668,11 @@ static void print_value(FILE *out, struct value *v) {
         break;
     case V_LENS:
         fprintf(out, "<lens:");
-        print_info(stdout, v->lens->info);
+        print_info(out, v->lens->info);
         fprintf(out, ">");
         break;
     case V_TREE:
-        print_tree(stdout, 0, v->origin);
+        print_tree(out, 0, v->origin);
         break;
     case V_FILTER:
         fprintf(out, "<filter:");
@@ -649,21 +683,21 @@ static void print_value(FILE *out, struct value *v) {
         break;
     case V_TRANSFORM:
         fprintf(out, "<transform:");
-        print_info(stdout, v->transform->lens->info);
+        print_info(out, v->transform->lens->info);
         fprintf(out, ">");
         break;
     case V_NATIVE:
         fprintf(out, "<native:");
-        print_info(stdout, v->info);
+        print_info(out, v->info);
         fprintf(out, ">");
         break;
     case V_CLOS:
         fprintf(out, "<closure:");
-        print_info(stdout, v->func->info);
+        print_info(out, v->func->info);
         fprintf(out, ">");
         break;
     case V_EXN:
-        print_info(stdout, v->exn->info);
+        print_info(out, v->exn->info);
         fprintf(out, "exception: %s\n", v->exn->message);
         for (int i=0; i < v->exn->nlines; i++) {
             fprintf(out, "    %s\n", v->exn->lines[i]);
@@ -895,8 +929,8 @@ static struct value *coerce(struct value *v, struct type *t) {
         unref(vt, type);
         return rxp;
     }
-    fatal_error(v->info, "Failed to coerce %s to %s",
-                type_name(vt), type_name(t));
+    return make_exn_value(v->info, "Type %s can not be coerced to %s",
+                          type_name(vt), type_name(t));
 }
 
 /* Return one of the expected types (passed as ...).
@@ -1314,10 +1348,17 @@ static struct value *compile_union(struct term *exp, struct ctx *ctx) {
 
     struct type *t = exp->type;
     struct info *info = exp->info;
-    struct value *v;
+    struct value *v = NULL;
 
     v1 = coerce(v1, t);
+    if (EXN(v1))
+        return v1;
     v2 = coerce(v2, t);
+    if (EXN(v2)) {
+        unref(v1, value);
+        return v2;
+    }
+
     if (t->tag == T_REGEXP) {
         v = make_value(V_REGEXP, ref(info));
         v->regexp = regexp_union(info, v1->regexp, v2->regexp);
@@ -1669,11 +1710,20 @@ static int compile_decl(struct term *term, struct ctx *ctx) {
         bind(&ctx->local, term->bname, term->type, v);
 
         if (EXN(v) && !v->exn->seen) {
+            struct error *error = term->info->error;
+            struct memstream ms;
+
+            init_memstream(&ms);
+
             syntax_error(term->info, "Failed to compile %s",
                          term->bname);
-            print_value(stdout, v);
-            printf("\n");
+            fprintf(ms.stream, "%s\n", error->details);
+            print_value(ms.stream, v);
+            close_memstream(&ms);
+
             v->exn->seen = 1;
+            free(error->details);
+            error->details = ms.buf;
         }
         result = ! EXN(v);
         unref(v, value);
@@ -1867,8 +1917,8 @@ int __aug_load_module_file(struct augeas *aug, const char *filename) {
     struct term *term = NULL;
     int result = -1;
 
-    if (augl_parse_file(aug, filename, &term) == -1)
-        goto error;
+    augl_parse_file(aug, filename, &term);
+    ERR_BAIL(aug);
 
     if (! typecheck(term, aug))
         goto error;
diff --git a/src/syntax.h b/src/syntax.h
index cb8be01..e0698bb 100644
--- a/src/syntax.h
+++ b/src/syntax.h
@@ -34,8 +34,8 @@
 void syntax_error(struct info *info, const char *format, ...)
     ATTRIBUTE_FORMAT(printf, 2, 3);
 
-__attribute__((noreturn))
-void fatal_error(struct info *info, const char *format, ...);
+void fatal_error(struct info *info, const char *format, ...)
+    ATTRIBUTE_FORMAT(printf, 2, 3);
 
 void assert_error_at(const char *srcfile, int srclineno, struct info *info,
                      const char *format, ...)




More information about the augeas-devel mailing list