]> granicus.if.org Git - graphviz/commitdiff
replace a use of sfstropen with malloc+vsnprintf
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 3 Apr 2021 20:13:02 +0000 (13:13 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 10 Apr 2021 02:20:50 +0000 (19:20 -0700)
This is another step towards removing uses of sfstropen in the code base.
Related to #1873.

lib/expr/exerror.c

index bb0e1ea3f46f483ed22ac38b4af61ba5db8f2fdc..c63ae4acf6176cc5eb0ad6ce4e4e9e8f3cd2392d 100644 (file)
  * expression library
  */
 
+#include <assert.h>
 #include <expr/exlib.h>
 #include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 /*
  * library error handler
  */
 
+static char *make_msg(const char *format, va_list ap) {
+
+  // retrieve buffered message
+  char buf[64];
+  excontext(expr.program, buf, sizeof(buf));
+
+  // how many bytes do we need to construct the message?
+  size_t len = (size_t)snprintf(NULL, 0, "%s\n -- ", buf);
+  {
+    va_list ap2;
+    va_copy(ap2, ap);
+    int r = vsnprintf(NULL, 0, format, ap2);
+    va_end(ap2);
+    if (r < 0) {
+      return strdup("malformed format");
+    }
+    len += (size_t)r + 1; // +1 for NUL
+  }
+
+  char *s = malloc(len);
+  if (s == NULL) {
+    return NULL;
+  }
+
+  int offset = snprintf(s, len, "%s\n -- ", buf);
+  assert(offset > 0);
+  vsnprintf(s + offset, len - (size_t)offset, format, ap);
+
+  return s;
+}
+
 void
 exerror(const char* format, ...)
 {
-       Sfio_t* sp;
-
-       if (expr.program->disc->errorf && !expr.program->errors && (sp = sfstropen()))
+       if (expr.program->disc->errorf && !expr.program->errors)
        {
                va_list ap;
-               char*   s;
-               char    buf[64];
 
                expr.program->errors = 1;
-               excontext(expr.program, buf, sizeof(buf));
-               sfputr(sp, buf, -1);
-               sfputr(sp, "\n -- ", -1);
                va_start(ap, format);
-               sfvprintf(sp, format, ap);
+               char *s = make_msg(format, ap);
                va_end(ap);
-               if (!(s = sfstruse(sp)))
-                       s = "out of space";
-               (*expr.program->disc->errorf)(expr.program, expr.program->disc, (expr.program->disc->flags & EX_FATAL) ? 3 : 2, "%s", s);
-               sfclose(sp);
+               (*expr.program->disc->errorf)(expr.program, expr.program->disc,
+                 (expr.program->disc->flags & EX_FATAL) ? 3 : 2, "%s",
+                 s ? s : "out of space");
+    free(s);
        }
        else if (expr.program->disc->flags & EX_FATAL)
                exit(1);
@@ -52,22 +80,14 @@ exerror(const char* format, ...)
 void 
 exwarn(const char *format, ...)
 {
-       Sfio_t *sp;
-
-       if (expr.program->disc->errorf && (sp = sfstropen())) {
+       if (expr.program->disc->errorf) {
                va_list ap;
-               char *s;
-               char buf[64];
 
-               excontext(expr.program, buf, sizeof(buf));
-               sfputr(sp, buf, -1);
-               sfputr(sp, "\n -- ", -1);
                va_start(ap, format);
-               sfvprintf(sp, format, ap);
+               char *s = make_msg(format, ap);
                va_end(ap);
-               s = sfstruse(sp);
                (*expr.program->disc->errorf) (expr.program, expr.program->disc,
-                                      ERROR_WARNING, "%s", s);
-       sfclose(sp);
+                                      ERROR_WARNING, "%s", s ? s : "out of space");
+               free(s);
        }
 }