]> granicus.if.org Git - graphviz/commitdiff
expr: replace 'exdump' SFIO buffer with an 'agxbuf'
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Fri, 5 Aug 2022 03:36:32 +0000 (20:36 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Fri, 5 Aug 2022 03:36:32 +0000 (20:36 -0700)
Unfortunately there is no easy way to stage this. We need to do it all at once,
updating every use of `deparse` and all `exdump`’s internals.

This change improves locality – it is more obvious to both users and the
compiler that the contents of this temporary buffer does not need to be retained
beyond calls to `exerror`. This is a small step towards deprecating SFIO.

Gitlab: #1873

lib/expr/excc.c
lib/expr/expr.h
lib/gvpr/compile.c

index 3d648fd45f9f8fce47fa55e6e1d22c246d33d688..5ce19aa335299b4ffeb5c075065cc5e49efc6f82 100644 (file)
@@ -15,6 +15,7 @@
  * expression library C program generator
  */
 
+#include <cgraph/agxbuf.h>
 #include <cgraph/exit.h>
 #include <expr/exlib.h>
 #include <stddef.h>
@@ -26,7 +27,7 @@ typedef struct Exccdisc_s Exccdisc_t;
 
 struct Exccdisc_s                      /* excc() discipline            */
 {
-  Sfio_t*              text;           /* text output stream           */
+  agxbuf *text; // text output buffer
   char*                id;             /* symbol prefix                */
   uint64_t     flags;          /* EXCC_* flags                 */
   int          (*ccf)(Excc_t*, Exnode_t*, Exid_t*, Exref_t*, Exnode_t*, Exccdisc_t*);
@@ -126,26 +127,26 @@ print(Excc_t* cc, Exnode_t* expr)
 
        if ((x = expr->data.print.args))
        {
-               sfprintf(cc->ccdisc->text, "sfprintf(%s, \"%s", expr->data.print.descriptor->op == CONSTANT && expr->data.print.descriptor->data.constant.value.integer == 2 ? "sfstderr" : "sfstdout", fmtesq(x->format, quote));
+               agxbprint(cc->ccdisc->text, "sfprintf(%s, \"%s", expr->data.print.descriptor->op == CONSTANT && expr->data.print.descriptor->data.constant.value.integer == 2 ? "sfstderr" : "sfstdout", fmtesq(x->format, quote));
                while ((x = x->next))
-                       sfprintf(cc->ccdisc->text, "%s", fmtesq(x->format, quote));
-               sfprintf(cc->ccdisc->text, "\"");
+                       agxbput(cc->ccdisc->text, fmtesq(x->format, quote));
+               agxbputc(cc->ccdisc->text, '"');
                for (x = expr->data.print.args; x; x = x->next)
                {
                        if (x->arg)
                        {
                                for (size_t i = 0; i < elementsof(x->param) && x->param[i]; i++)
                                {
-                                       sfprintf(cc->ccdisc->text, ", (");
+                                       agxbput(cc->ccdisc->text, ", (");
                                        gen(cc, x->param[i]);
-                                       sfprintf(cc->ccdisc->text, ")");
+                                       agxbputc(cc->ccdisc->text, ')');
                                }
-                               sfprintf(cc->ccdisc->text, ", (");
+                               agxbput(cc->ccdisc->text, ", (");
                                gen(cc, x->arg);
-                               sfprintf(cc->ccdisc->text, ")");
+                               agxbputc(cc->ccdisc->text, ')');
                        }
                }
-               sfprintf(cc->ccdisc->text, ");\n");
+               agxbput(cc->ccdisc->text, ");\n");
        }
 }
 
@@ -160,26 +161,26 @@ scan(Excc_t* cc, Exnode_t* expr)
 
        if ((x = expr->data.print.args))
        {
-               sfprintf(cc->ccdisc->text, "sfscanf(sfstdin, \"%s", fmtesq(x->format, quote));
+               agxbprint(cc->ccdisc->text, "sfscanf(sfstdin, \"%s", fmtesq(x->format, quote));
                while ((x = x->next))
-                       sfprintf(cc->ccdisc->text, "%s", fmtesq(x->format, quote));
-               sfprintf(cc->ccdisc->text, "\"");
+                       agxbput(cc->ccdisc->text, fmtesq(x->format, quote));
+               agxbputc(cc->ccdisc->text, '"');
                for (x = expr->data.print.args; x; x = x->next)
                {
                        if (x->arg)
                        {
                                for (size_t i = 0; i < elementsof(x->param) && x->param[i]; i++)
                                {
-                                       sfprintf(cc->ccdisc->text, ", &(");
+                                       agxbput(cc->ccdisc->text, ", &(");
                                        gen(cc, x->param[i]);
-                                       sfprintf(cc->ccdisc->text, ")");
+                                       agxbputc(cc->ccdisc->text, ')');
                                }
-                               sfprintf(cc->ccdisc->text, ", &(");
+                               agxbput(cc->ccdisc->text, ", &(");
                                gen(cc, x->arg);
-                               sfprintf(cc->ccdisc->text, ")");
+                               agxbputc(cc->ccdisc->text, ')');
                        }
                }
-               sfprintf(cc->ccdisc->text, ");\n");
+               agxbput(cc->ccdisc->text, ");\n");
        }
 }
 
@@ -202,146 +203,147 @@ gen(Excc_t* cc, Exnode_t* expr)
        if (!expr)
                return;
        if (expr->op == CALL) {
-               sfprintf(cc->ccdisc->text, "%s(", expr->data.call.procedure->name);
+               agxbprint(cc->ccdisc->text, "%s(", expr->data.call.procedure->name);
                if (expr->data.call.args)
                        gen(cc, expr->data.call.args);
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        }
        x = expr->data.operand.left;
        switch (expr->op)
        {
        case BREAK:
-               sfprintf(cc->ccdisc->text, "break;\n");
+               agxbput(cc->ccdisc->text, "break;\n");
                return;
        case CONTINUE:
-               sfprintf(cc->ccdisc->text, "continue;\n");
+               agxbput(cc->ccdisc->text, "continue;\n");
                return;
        case CONSTANT:
                switch (expr->type)
                {
                case FLOATING:
-                       sfprintf(cc->ccdisc->text, "%g", expr->data.constant.value.floating);
+                       agxbprint(cc->ccdisc->text, "%g", expr->data.constant.value.floating);
                        break;
                case STRING:
-                       sfprintf(cc->ccdisc->text, "\"%s\"", fmtesq(expr->data.constant.value.string, quote));
+                       agxbprint(cc->ccdisc->text, "\"%s\"", fmtesq(expr->data.constant.value.string, quote));
                        break;
                case UNSIGNED:
-                       sfprintf(cc->ccdisc->text, "%I*u", sizeof(expr->data.constant.value.integer), expr->data.constant.value.integer);
+                       agxbprint(cc->ccdisc->text, "%llu",
+                                 (long long unsigned)expr->data.constant.value.integer);
                        break;
                default:
-                       sfprintf(cc->ccdisc->text, "%I*d", sizeof(expr->data.constant.value.integer), expr->data.constant.value.integer);
+                       agxbprint(cc->ccdisc->text, "%lld", expr->data.constant.value.integer);
                        break;
                }
                return;
        case DEC:
-               sfprintf(cc->ccdisc->text, "%s--", x->data.variable.symbol->name);
+               agxbprint(cc->ccdisc->text, "%s--", x->data.variable.symbol->name);
                return;
        case DYNAMIC:
-               sfprintf(cc->ccdisc->text, "%s", expr->data.variable.symbol->name);
+               agxbput(cc->ccdisc->text, expr->data.variable.symbol->name);
                return;
        case EXIT:
-                sfprintf(cc->ccdisc->text, "exit(");
+               agxbput(cc->ccdisc->text, "exit(");
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ");\n");
+               agxbput(cc->ccdisc->text, ");\n");
                return;
        case FUNCTION:
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, "(");
+               agxbputc(cc->ccdisc->text, '(');
                if ((y = expr->data.operand.right)) {
                        gen(cc, y);
                }
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case RAND:
-               sfprintf(cc->ccdisc->text, "rand();\n");
+               agxbput(cc->ccdisc->text, "rand();\n");
                return;
        case SRAND:
                if (expr->binary) {
-                       sfprintf(cc->ccdisc->text, "srand(");
+                       agxbput(cc->ccdisc->text, "srand(");
                        gen(cc, x);
-                       sfprintf(cc->ccdisc->text, ");\n");
+                       agxbput(cc->ccdisc->text, ");\n");
                } else
-                       sfprintf(cc->ccdisc->text, "srand();\n");
+                       agxbput(cc->ccdisc->text, "srand();\n");
                return;
        case GSUB:
        case SUB:
        case SUBSTR:
                s = (expr->op == GSUB ? "gsub(" : expr->op == SUB ? "sub(" : "substr(");
-               sfprintf(cc->ccdisc->text, s);
+               agxbput(cc->ccdisc->text, s);
                gen(cc, expr->data.string.base);
-               sfprintf(cc->ccdisc->text, ", ");
+               agxbput(cc->ccdisc->text, ", ");
                gen(cc, expr->data.string.pat);
                if (expr->data.string.repl) {
-                       sfprintf(cc->ccdisc->text, ", ");
+                       agxbput(cc->ccdisc->text, ", ");
                        gen(cc, expr->data.string.repl);
                }
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case IN_OP:
                gen(cc, expr->data.variable.index);
-               sfprintf(cc->ccdisc->text, " in %s", expr->data.variable.symbol->name);
+               agxbprint(cc->ccdisc->text, " in %s", expr->data.variable.symbol->name);
                return;
        case IF:
-               sfprintf(cc->ccdisc->text, "if (");
+               agxbput(cc->ccdisc->text, "if (");
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ") {\n");
+               agxbput(cc->ccdisc->text, ") {\n");
                gen(cc, expr->data.operand.right->data.operand.left);
                if (expr->data.operand.right->data.operand.right)
                {
-                       sfprintf(cc->ccdisc->text, "} else {\n");
+                       agxbput(cc->ccdisc->text, "} else {\n");
                        gen(cc, expr->data.operand.right->data.operand.right);
                }
-               sfprintf(cc->ccdisc->text, "}\n");
+               agxbput(cc->ccdisc->text, "}\n");
                return;
        case FOR:
-               sfprintf(cc->ccdisc->text, "for (;");
+               agxbput(cc->ccdisc->text, "for (;");
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ");");
+               agxbput(cc->ccdisc->text, ");");
                if (expr->data.operand.left)
                {
-                       sfprintf(cc->ccdisc->text, "(");
+                       agxbputc(cc->ccdisc->text, '(');
                        gen(cc, expr->data.operand.left);
-                       sfprintf(cc->ccdisc->text, ")");
+                       agxbputc(cc->ccdisc->text, ')');
                }
-               sfprintf(cc->ccdisc->text, ") {");
+               agxbput(cc->ccdisc->text, ") {");
                if (expr->data.operand.right)
                        gen(cc, expr->data.operand.right);
-               sfprintf(cc->ccdisc->text, "}");
+               agxbputc(cc->ccdisc->text, '}');
                return;
        case ID:
                if (cc->ccdisc->ccf)
                        cc->ccdisc->ccf(cc, expr, expr->data.variable.symbol, expr->data.variable.reference, expr->data.variable.index, cc->ccdisc);
                else
-                       sfprintf(cc->ccdisc->text, "%s", expr->data.variable.symbol->name);
+                       agxbput(cc->ccdisc->text, expr->data.variable.symbol->name);
                return;
        case INC:
-               sfprintf(cc->ccdisc->text, "%s++", x->data.variable.symbol->name);
+               agxbprint(cc->ccdisc->text, "%s++", x->data.variable.symbol->name);
                return;
        case ITERATE:
        case ITERATER:
                if (expr->op == DYNAMIC)
                {
-                       sfprintf(cc->ccdisc->text, "{ Exassoc_t* %stmp_%d;", cc->id, ++cc->tmp);
-                       sfprintf(cc->ccdisc->text, "for (%stmp_%d = (Exassoc_t*)dtfirst(%s); %stmp_%d && (%s = %stmp_%d->name); %stmp_%d = (Exassoc_t*)dtnext(%s, %stmp_%d)) {", cc->id, cc->tmp, expr->data.generate.array->data.variable.symbol->name, cc->id, cc->tmp, expr->data.generate.index->name, cc->id, cc->tmp, cc->id, cc->tmp, expr->data.generate.array->data.variable.symbol->name, cc->id, cc->tmp);
+                       agxbprint(cc->ccdisc->text, "{ Exassoc_t* %stmp_%d;", cc->id, ++cc->tmp);
+                       agxbprint(cc->ccdisc->text, "for (%stmp_%d = (Exassoc_t*)dtfirst(%s); %stmp_%d && (%s = %stmp_%d->name); %stmp_%d = (Exassoc_t*)dtnext(%s, %stmp_%d)) {", cc->id, cc->tmp, expr->data.generate.array->data.variable.symbol->name, cc->id, cc->tmp, expr->data.generate.index->name, cc->id, cc->tmp, cc->id, cc->tmp, expr->data.generate.array->data.variable.symbol->name, cc->id, cc->tmp);
                        gen(cc, expr->data.generate.statement);
-                       sfprintf(cc->ccdisc->text, "} }");
+                       agxbput(cc->ccdisc->text, "} }");
                }
                return;
        case PRINT:
-               sfprintf(cc->ccdisc->text, "print");
+               agxbput(cc->ccdisc->text, "print");
                if (x)
                        gen(cc, x);
                else
-                       sfprintf(cc->ccdisc->text, "()");
+                       agxbput(cc->ccdisc->text, "()");
                return;
        case PRINTF:
                print(cc, expr);
                return;
        case RETURN:
-               sfprintf(cc->ccdisc->text, "return(");
+               agxbput(cc->ccdisc->text, "return(");
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ");\n");
+               agxbput(cc->ccdisc->text, ");\n");
                return;
        case SCANF:
                scan(cc, expr);
@@ -349,29 +351,29 @@ gen(Excc_t* cc, Exnode_t* expr)
        case SPLIT:
        case TOKENS:
                if (expr->op == SPLIT)
-                       sfprintf(cc->ccdisc->text, "split (");
+                       agxbput(cc->ccdisc->text, "split (");
                else
-                       sfprintf(cc->ccdisc->text, "tokens (");
+                       agxbput(cc->ccdisc->text, "tokens (");
                gen(cc, expr->data.split.string);
-               sfprintf(cc->ccdisc->text, ", %s", expr->data.split.array->name);
+               agxbprint(cc->ccdisc->text, ", %s", expr->data.split.array->name);
                if (expr->data.split.seps) {
-                       sfprintf(cc->ccdisc->text, ",");
+                       agxbputc(cc->ccdisc->text, ',');
                        gen(cc, expr->data.split.seps);
                }
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case SWITCH:
                t = x->type;
-               sfprintf(cc->ccdisc->text, "{ %s %stmp_%d = ", extype(t), cc->id, ++cc->tmp);
+               agxbprint(cc->ccdisc->text, "{ %s %stmp_%d = ", extype(t), cc->id, ++cc->tmp);
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ";");
+               agxbputc(cc->ccdisc->text, ';');
                x = expr->data.operand.right;
                y = x->data.select.statement;
                n = 0;
                while ((x = x->data.select.next))
                {
                        if (n)
-                               sfprintf(cc->ccdisc->text, "else ");
+                               agxbput(cc->ccdisc->text, "else ");
                        if (!(p = x->data.select.constant))
                                y = x->data.select.statement;
                        else
@@ -380,67 +382,68 @@ gen(Excc_t* cc, Exnode_t* expr)
                                while ((v = *p++))
                                {
                                        if (m)
-                                               sfprintf(cc->ccdisc->text, "||");
+                                               agxbput(cc->ccdisc->text, "||");
                                        else
                                        {
                                                m = 1;
-                                               sfprintf(cc->ccdisc->text, "if (");
+                                               agxbput(cc->ccdisc->text, "if (");
                                        }
                                        if (t == STRING)
-                                               sfprintf(cc->ccdisc->text, "strmatch(%stmp_%d, \"%s\")", cc->id, cc->tmp, fmtesq(v->string, quote));
+                                               agxbprint(cc->ccdisc->text, "strmatch(%stmp_%d, \"%s\")", cc->id, cc->tmp, fmtesq(v->string, quote));
                                        else
                                        {
-                                               sfprintf(cc->ccdisc->text, "%stmp_%d == ", cc->id, cc->tmp);
+                                               agxbprint(cc->ccdisc->text, "%stmp_%d == ", cc->id, cc->tmp);
                                                switch (t)
                                                {
                                                case INTEGER:
                                                case UNSIGNED:
-                                                       sfprintf(cc->ccdisc->text, "%I*u", sizeof(v->integer), v->integer);
+                                                       agxbprint(cc->ccdisc->text, "%llu",
+                                                                 (unsigned long long)v->integer);
                                                        break;
                                                default:
-                                                       sfprintf(cc->ccdisc->text, "%g", v->floating);
+                                                       agxbprint(cc->ccdisc->text, "%g", v->floating);
                                                        break;
                                                }
                                        }
                                }
-                               sfprintf(cc->ccdisc->text, ") {");
+                               agxbput(cc->ccdisc->text, ") {");
                                gen(cc, x->data.select.statement);
-                               sfprintf(cc->ccdisc->text, "}");
+                               agxbputc(cc->ccdisc->text, '}');
                        }
                }
                if (y)
                {
                        if (n)
-                               sfprintf(cc->ccdisc->text, "else ");
-                       sfprintf(cc->ccdisc->text, "{");
+                               agxbput(cc->ccdisc->text, "else ");
+                       agxbputc(cc->ccdisc->text, '{');
                        gen(cc, y);
-                       sfprintf(cc->ccdisc->text, "}");
+                       agxbputc(cc->ccdisc->text, '}');
                }
-               sfprintf(cc->ccdisc->text, "}");
+               agxbputc(cc->ccdisc->text, '}');
                return;
        case UNSET:
-               sfprintf(cc->ccdisc->text, "unset(%s", expr->data.variable.symbol->name);
+               agxbprint(cc->ccdisc->text, "unset(%s", expr->data.variable.symbol->name);
                if (expr->data.variable.index) {
-                       sfprintf(cc->ccdisc->text, ",");
+                       agxbputc(cc->ccdisc->text, ',');
                        gen(cc, expr->data.variable.index);
                }
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case WHILE:
-               sfprintf(cc->ccdisc->text, "while (");
+               agxbput(cc->ccdisc->text, "while (");
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ") {");
+               agxbput(cc->ccdisc->text, ") {");
                if (expr->data.operand.right)
                        gen(cc, expr->data.operand.right);
-               sfprintf(cc->ccdisc->text, "}");
+               agxbputc(cc->ccdisc->text, '}');
                return;
     case '#':
-               sfprintf(cc->ccdisc->text, "# %s", expr->data.variable.symbol->name);
+               agxbprint(cc->ccdisc->text, "# %s", expr->data.variable.symbol->name);
                return;
        case '=':
-               sfprintf(cc->ccdisc->text, "(%s%s=", x->data.variable.symbol->name, expr->subop == '=' ? "" : exopname(expr->subop));
+               agxbprint(cc->ccdisc->text, "(%s%s=", x->data.variable.symbol->name, expr->subop == '=' ? "" : exopname(expr->subop));
                gen(cc, expr->data.operand.right);
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case ';':
                for (;;)
@@ -456,11 +459,11 @@ gen(Excc_t* cc, Exnode_t* expr)
                                case WHILE:
                                        break;
                                default:
-                                       sfprintf(cc->ccdisc->text, "_%svalue=", cc->id);
+                                       agxbprint(cc->ccdisc->text, "_%svalue=", cc->id);
                                        break;
                                }
                        gen(cc, expr->data.operand.left);
-                       sfprintf(cc->ccdisc->text, ";\n");
+                       agxbput(cc->ccdisc->text, ";\n");
                        if (!(expr = x))
                                break;
                        switch (cc->lastop = expr->op)
@@ -475,77 +478,76 @@ gen(Excc_t* cc, Exnode_t* expr)
                        case WHILE:
                                break;
                        default:
-                               sfprintf(cc->ccdisc->text, "_%svalue=", cc->id);
+                               agxbprint(cc->ccdisc->text, "_%svalue=", cc->id);
                                break;
                        }
                        gen(cc, expr);
-                       sfprintf(cc->ccdisc->text, ";\n");
+                       agxbput(cc->ccdisc->text, ";\n");
                        break;
                }
                return;
        case ',':
-               sfprintf(cc->ccdisc->text, "(");
+               agxbputc(cc->ccdisc->text, '(');
                gen(cc, x);
                while ((expr = expr->data.operand.right) && expr->op == ',')
                {
-                       sfprintf(cc->ccdisc->text, "), (");
+                       agxbput(cc->ccdisc->text, "), (");
                        gen(cc, expr->data.operand.left);
                }
                if (expr)
                {
-                       sfprintf(cc->ccdisc->text, "), (");
+                       agxbput(cc->ccdisc->text, "), (");
                        gen(cc, expr);
                }
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case '?':
-               sfprintf(cc->ccdisc->text, "(");
+               agxbputc(cc->ccdisc->text, '(');
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ") ? (");
+               agxbput(cc->ccdisc->text, ") ? (");
                gen(cc, expr->data.operand.right->data.operand.left);
-               sfprintf(cc->ccdisc->text, ") : (");
+               agxbput(cc->ccdisc->text, ") : (");
                gen(cc, expr->data.operand.right->data.operand.right);
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case AND:
-               sfprintf(cc->ccdisc->text, "(");
+               agxbputc(cc->ccdisc->text, '(');
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ") && (");
+               agxbput(cc->ccdisc->text, ") && (");
                gen(cc, expr->data.operand.right);
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case OR:
-               sfprintf(cc->ccdisc->text, "(");
+               agxbputc(cc->ccdisc->text, '(');
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ") || (");
+               agxbput(cc->ccdisc->text, ") || (");
                gen(cc, expr->data.operand.right);
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case F2I:
-               sfprintf(cc->ccdisc->text, "(%s)(", extype(INTEGER));
+               agxbprint(cc->ccdisc->text, "(%s)(", extype(INTEGER));
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case I2F:
-               sfprintf(cc->ccdisc->text, "(%s)(", extype(FLOATING));
+               agxbprint(cc->ccdisc->text, "(%s)(", extype(FLOATING));
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case S2I:
-               /* sfprintf(cc->ccdisc->text, "strto%s(", sizeof(intmax_t) > sizeof(long) ? "ll" : "l"); */
-               sfprintf(cc->ccdisc->text, "strtoll(");
+               agxbput(cc->ccdisc->text, "strtoll(");
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ",(char**)0,0)");
+               agxbput(cc->ccdisc->text, ",(char**)0,0)");
                return;
     case X2I:
-               sfprintf(cc->ccdisc->text, "X2I(");
+               agxbput(cc->ccdisc->text, "X2I(");
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        case X2X:
-               sfprintf(cc->ccdisc->text, "X2X(");
+               agxbput(cc->ccdisc->text, "X2X(");
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
                return;
        }
        y = expr->data.operand.right;
@@ -554,32 +556,32 @@ gen(Excc_t* cc, Exnode_t* expr)
                switch (expr->op)
                {
                case S2B:
-                       sfprintf(cc->ccdisc->text, "*(");
+                       agxbput(cc->ccdisc->text, "*(");
                        gen(cc, x);
-                       sfprintf(cc->ccdisc->text, ")!=0");
+                       agxbput(cc->ccdisc->text, ")!=0");
                        return;
                case S2F:
-                       sfprintf(cc->ccdisc->text, "strtod(");
+                       agxbput(cc->ccdisc->text, "strtod(");
                        gen(cc, x);
-                       sfprintf(cc->ccdisc->text, ",0)");
+                       agxbput(cc->ccdisc->text, ",0)");
                        return;
                case S2I:
-                       sfprintf(cc->ccdisc->text, "strtol(");
+                       agxbput(cc->ccdisc->text, "strtol(");
                        gen(cc, x);
-                       sfprintf(cc->ccdisc->text, ",0,0)");
+                       agxbput(cc->ccdisc->text, ",0,0)");
                        return;
                case S2X:
-                       sfprintf(cc->ccdisc->text, "** cannot convert string value to external **");
+                       agxbput(cc->ccdisc->text, "** cannot convert string value to external **");
                        return;
                case NE:
-                       sfprintf(cc->ccdisc->text, "!");
+                       agxbputc(cc->ccdisc->text, '!');
                        /*FALLTHROUGH*/
                case EQ:
-                       sfprintf(cc->ccdisc->text, "strmatch(");
+                       agxbput(cc->ccdisc->text, "strmatch(");
                        gen(cc, x);
-                       sfprintf(cc->ccdisc->text, ",");
+                       agxbputc(cc->ccdisc->text, ',');
                        gen(cc, y);
-                       sfprintf(cc->ccdisc->text, ")");
+                       agxbputc(cc->ccdisc->text, ')');
                        return;
                case '+':
                case '|':
@@ -587,7 +589,7 @@ gen(Excc_t* cc, Exnode_t* expr)
                case '^':
                case '%':
                case '*':
-                       sfprintf(cc->ccdisc->text, "** string bits not supported **");
+                       agxbput(cc->ccdisc->text, "** string bits not supported **");
                        return;
                }
                switch (expr->op)
@@ -608,25 +610,25 @@ gen(Excc_t* cc, Exnode_t* expr)
                        s = "** unknown string op **";
                        break;
                }
-               sfprintf(cc->ccdisc->text, "strcoll(");
+               agxbput(cc->ccdisc->text, "strcoll(");
                gen(cc, x);
-               sfprintf(cc->ccdisc->text, ",");
+               agxbputc(cc->ccdisc->text, ',');
                gen(cc, y);
-               sfprintf(cc->ccdisc->text, ")%s", s);
+               agxbprint(cc->ccdisc->text, ")%s", s);
                return;
        }
        else
        {
                if (!y)
-                       sfprintf(cc->ccdisc->text, "%s", exopname(expr->op));
-               sfprintf(cc->ccdisc->text, "(");
+                       agxbput(cc->ccdisc->text, exopname(expr->op));
+               agxbputc(cc->ccdisc->text, '(');
                gen(cc, x);
                if (y)
                {
-                       sfprintf(cc->ccdisc->text, ")%s(", exopname(expr->op));
+                       agxbprint(cc->ccdisc->text, ")%s(", exopname(expr->op));
                        gen(cc, y);
                }
-               sfprintf(cc->ccdisc->text, ")");
+               agxbputc(cc->ccdisc->text, ')');
        }
        return;
 }
@@ -640,11 +642,11 @@ global(Dt_t* table, void* object, void* handle)
 {
        (void)table;
 
-       Sfio_t *stream = handle;
+       agxbuf *stream = handle;
        Exid_t* sym = object;
 
        if (sym->lex == DYNAMIC)
-               sfprintf(stream, "static %s     %s;\n", extype(sym->type), sym->name);
+               agxbprint(stream, "static %s    %s;\n", extype(sym->type), sym->name);
        return 0;
 }
 
@@ -666,11 +668,11 @@ static Excc_t *exccopen(Expr_t *expr, Exccdisc_t *disc) {
        cc->ccdisc = disc;
        if (!(disc->flags & EX_CC_DUMP))
        {
-               sfprintf(disc->text, "/* : : generated by %s : : */\n", exversion);
-               sfprintf(disc->text, "\n#include <ast/ast.h>\n");
+               agxbprint(disc->text, "/* : : generated by %s : : */\n", exversion);
+               agxbput(disc->text, "\n#include <ast/ast.h>\n");
                if (*id)
                        snprintf(cc->id, strlen(id) + 2, "%s_", id);
-               sfprintf(disc->text, "\n");
+               agxbputc(disc->text, '\n');
                dtwalk(expr->symbols, global, disc->text);
        }
        return cc;
@@ -690,7 +692,7 @@ static int exccclose(Excc_t *cc) {
                if (!(cc->ccdisc->flags & EX_CC_DUMP))
                {
                        if (cc->ccdisc->text)
-                               sfclose(cc->ccdisc->text);
+                               agxbuse(cc->ccdisc->text);
                        else
                                r = -1;
                }
@@ -700,19 +702,17 @@ static int exccclose(Excc_t *cc) {
 }
 
 /*
- * dump an expression tree on sp
+ * dump an expression tree to a buffer
  */
 
-int
-exdump(Expr_t* expr, Exnode_t* node, Sfio_t* sp)
-{
+int exdump(Expr_t *expr, Exnode_t *node, agxbuf *xb) {
        Excc_t*         cc;
        Exccdisc_t      ccdisc;
        Exid_t*         sym;
 
        memset(&ccdisc, 0, sizeof(ccdisc));
        ccdisc.flags = EX_CC_DUMP;
-       ccdisc.text = sp;
+       ccdisc.text = xb;
        if (!(cc = exccopen(expr, &ccdisc)))
                return -1;
        if (node)
@@ -721,9 +721,9 @@ exdump(Expr_t* expr, Exnode_t* node, Sfio_t* sp)
                for (sym = dtfirst(expr->symbols); sym; sym = dtnext(expr->symbols, sym))
                        if (sym->lex == PROCEDURE && sym->value)
                        {
-                               sfprintf(sp, "%s:\n", sym->name);
+                               agxbprint(xb, "%s:\n", sym->name);
                                gen(cc, sym->value->data.procedure.body);
                        }
-       sfprintf(sp, "\n");
+       agxbputc(xb, '\n');
        return exccclose(cc);
 }
index cc18492aea8682bffbb6b18da38ff671eff04393..bf0ceed4efbaa7307f9f2b9461021b16a5200921 100644 (file)
@@ -31,6 +31,7 @@ extern "C" {
 
 #include <assert.h>
 #include <cdt.h>
+#include <cgraph/agxbuf.h>
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -244,7 +245,7 @@ extern Exnode_t*    exnoncast(Exnode_t *);
 extern void            exclose(Expr_t*, int);
 extern int             excomp(Expr_t*, const char*, int, const char*, Sfio_t*);
 extern char*           excontext(Expr_t*, char*, int);
-extern int             exdump(Expr_t*, Exnode_t*, Sfio_t*);
+extern int             exdump(Expr_t*, Exnode_t*, agxbuf*);
 #ifdef __GNUC__
 __attribute__((format(printf, 1, 2)))
 #endif
index 38aea632df87d5aa56397bba7c5a2dce76a4a991..c07594d3695f2f66c9ef165cb905f29bcbd90d46 100644 (file)
@@ -19,6 +19,7 @@
 #include <unistd.h>
 #include <gvpr/compile.h>
 #include <assert.h>
+#include <cgraph/agxbuf.h>
 #include <cgraph/cgraph.h>
 #include <cgraph/exit.h>
 #include <cgraph/itos.h>
@@ -264,12 +265,10 @@ static Agdesc_t xargs(char *args)
 /* deparse:
  * Recreate string representation of expression involving
  * a reference and a symbol.
- * The parameter sf must be a string stream.
  */
-static char *deparse(Expr_t * ex, Exnode_t * n, Sfio_t * sf)
-{
-    exdump(ex, n, sf);
-    return sfstruse(sf);
+static char *deparse(Expr_t *ex, Exnode_t *n, agxbuf *xb) {
+  exdump(ex, n, xb);
+  return xb->buf;
 }
 
 /* deref:
@@ -289,9 +288,11 @@ static Agobj_t *deref(Expr_t * pgm, Exnode_t * x, Exref_t * ref,
        ptr = int2ptr(x->data.variable.dyna->data.variable.dyna->data.
                    constant.value.integer);
        if (!ptr) {
+           agxbuf xb = {0};
+           agxbinit(&xb, 0, NULL);
            exerror("null reference %s in expression %s.%s",
-                 ref->symbol->name, ref->symbol->name, deparse(pgm, x,
-                                                               state->tmp));
+                 ref->symbol->name, ref->symbol->name, deparse(pgm, x, &xb));
+           agxbfree(&xb);
            return ptr;
        } else
            return deref(pgm, x, ref->next, (Agobj_t *) ptr, state);
@@ -1517,9 +1518,12 @@ getval(Expr_t * pgm, Exnode_t * node, Exid_t * sym, Exref_t * ref,
     state = env;
     if (ref) {
        objp = deref(pgm, node, ref, 0, state);
-       if (!objp)
-           exerror("null reference in expression %s",
-                 deparse(pgm, node, state->tmp));
+       if (!objp) {
+           agxbuf xb = {0};
+           agxbinit(&xb, 0, NULL);
+           exerror("null reference in expression %s", deparse(pgm, node, &xb));
+           agxbfree(&xb);
+       }
     } else if (sym->lex == ID && sym->index <= LAST_V) {
        switch (sym->index) {
        case V_this:
@@ -1563,14 +1567,20 @@ getval(Expr_t * pgm, Exnode_t * node, Exid_t * sym, Exref_t * ref,
     } else {
        objp = state->curobj;
        if (!objp) {
+           agxbuf xb = {0};
+           agxbinit(&xb, 0, NULL);
            exerror("current object $ not defined as reference for %s",
-                 deparse(pgm, node, state->tmp));
+                 deparse(pgm, node, &xb));
+           agxbfree(&xb);
        }
     }
 
     if (objp) {
        if (lookup(pgm, objp, sym, &v, state)) {
-           exerror("in expression %s", deparse(pgm, node, state->tmp));
+           agxbuf xb = {0};
+           agxbinit(&xb, 0, NULL);
+           exerror("in expression %s", deparse(pgm, node, &xb));
+           agxbfree(&xb);
            v.integer = 0;
        }
     }
@@ -1609,8 +1619,10 @@ setval(Expr_t * pgm, Exnode_t * x, Exid_t * sym, Exref_t * ref,
     if (ref) {
        objp = deref(pgm, x, ref, 0, state);
        if (!objp) {
-           exerror("in expression %s.%s",
-                 ref->symbol->name, deparse(pgm, x, state->tmp));
+           agxbuf xb = {0};
+           agxbinit(&xb, 0, NULL);
+           exerror("in expression %s.%s", ref->symbol->name, deparse(pgm, x, &xb));
+           agxbfree(&xb);
            return -1;
        }
     } else if (MINNAME <= sym->index && sym->index <= MAXNAME) {
@@ -1660,8 +1672,11 @@ setval(Expr_t * pgm, Exnode_t * x, Exid_t * sym, Exref_t * ref,
     } else {
        objp = state->curobj;
        if (!objp) {
+           agxbuf xb = {0};
+           agxbinit(&xb, 0, NULL);
            exerror("current object $ undefined in expression %s",
-                 deparse(pgm, x, state->tmp));
+                 deparse(pgm, x, &xb));
+           agxbfree(&xb);
            return -1;
        }
     }
@@ -1850,9 +1865,10 @@ refval(Expr_t * pgm, Exnode_t * node, Exid_t * sym, Exref_t * ref,
        }
     } else {
        if (!typeChkExp(ref, sym)) {
-           Gpr_t *state = disc->user;
-           exerror("type error using %s",
-                   deparse(pgm, node, state->tmp));
+           agxbuf xb = {0};
+           agxbinit(&xb, 0, NULL);
+           exerror("type error using %s", deparse(pgm, node, &xb));
+           agxbfree(&xb);
        }
        v = exzero(node->type);
     }