commit 1a89f8a178f528c1acb4ab130f2163665759614c
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Sun May 1 19:20:19 2022 +0200

    move imap_vprintf() to util.c and rename it to xvasprintf()
    
    it's currently used only by IMAP, but it's logically low-level.

 src/common.h   |   2 +
 src/drv_imap.c | 104 +-----------------------------------------------
 src/util.c     | 106 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 109 insertions(+), 103 deletions(-)

diff --git a/src/common.h b/src/common.h
index b22a4cbb..f4810604 100644
--- a/src/common.h
+++ b/src/common.h
@@ -165,6 +165,8 @@ void ATTR_PRINTFLIKE(1, 0) vsys_error( const char *, 
va_list va );
 void ATTR_PRINTFLIKE(1, 2) sys_error( const char *, ... );
 void flushn( void );
 
+char *xvasprintf( const char *fmt, va_list ap );
+
 #if !defined(_POSIX_SYNCHRONIZED_IO) || _POSIX_SYNCHRONIZED_IO <= 0
 # define fdatasync fsync
 #endif
diff --git a/src/drv_imap.c b/src/drv_imap.c
index e92c53f1..1f75e6cf 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -487,108 +487,6 @@ submit_imap_cmd( imap_store_t *ctx, imap_cmd_t *cmd )
        }
 }
 
-/* Minimal printf() replacement that supports an %\s format sequence to print 
backslash-escaped
- * string literals. Note that this does not automatically add quotes around 
the printed string,
- * so it is possible to concatenate multiple segments. */
-static char *
-imap_vprintf( const char *fmt, va_list ap )
-{
-       const char *s;
-       char *d, *ed;
-       char c;
-#define MAX_SEGS 16
-#define add_seg(s, l) \
-               do { \
-                       if (nsegs == MAX_SEGS) \
-                               oob(); \
-                       segs[nsegs] = s; \
-                       segls[nsegs++] = l; \
-                       totlen += l; \
-               } while (0)
-       int nsegs = 0;
-       uint totlen = 0;
-       const char *segs[MAX_SEGS];
-       uint segls[MAX_SEGS];
-       char buf[1000];
-
-       d = buf;
-       ed = d + sizeof(buf);
-       s = fmt;
-       for (;;) {
-               c = *fmt;
-               if (!c || c == '%') {
-                       uint l = fmt - s;
-                       if (l)
-                               add_seg( s, l );
-                       if (!c)
-                               break;
-                       uint maxlen = UINT_MAX;
-                       c = *++fmt;
-                       if (c == '\\') {
-                               c = *++fmt;
-                               if (c != 's') {
-                                       fputs( "Fatal: unsupported escaped 
format specifier. Please report a bug.\n", stderr );
-                                       abort();
-                               }
-                               char *bd = d;
-                               s = va_arg( ap, const char * );
-                               while ((c = *s++)) {
-                                       if (d + 2 > ed)
-                                               oob();
-                                       if (c == '\\' || c == '"')
-                                               *d++ = '\\';
-                                       *d++ = c;
-                               }
-                               l = d - bd;
-                               if (l)
-                                       add_seg( bd, l );
-                       } else { /* \\ cannot be combined with anything else. */
-                               if (c == '.') {
-                                       c = *++fmt;
-                                       if (c != '*') {
-                                               fputs( "Fatal: unsupported 
string length specification. Please report a bug.\n", stderr );
-                                               abort();
-                                       }
-                                       maxlen = va_arg( ap, uint );
-                                       c = *++fmt;
-                               }
-                               if (c == 'c') {
-                                       if (d + 1 > ed)
-                                               oob();
-                                       add_seg( d, 1 );
-                                       *d++ = (char)va_arg( ap , int );
-                               } else if (c == 's') {
-                                       s = va_arg( ap, const char * );
-                                       l = strnlen( s, maxlen );
-                                       if (l)
-                                               add_seg( s, l );
-                               } else if (c == 'd') {
-                                       l = nfsnprintf( d, ed - d, "%d", 
va_arg( ap, int ) );
-                                       add_seg( d, l );
-                                       d += l;
-                               } else if (c == 'u') {
-                                       l = nfsnprintf( d, ed - d, "%u", 
va_arg( ap, uint ) );
-                                       add_seg( d, l );
-                                       d += l;
-                               } else {
-                                       fputs( "Fatal: unsupported format 
specifier. Please report a bug.\n", stderr );
-                                       abort();
-                               }
-                       }
-                       s = ++fmt;
-               } else {
-                       fmt++;
-               }
-       }
-       char *out = d = nfmalloc( totlen + 1 );
-       for (int i = 0; i < nsegs; i++) {
-               memcpy( d, segs[i], segls[i] );
-               d += segls[i];
-       }
-       *d = 0;
-       return out;
-}
-
 static void
 imap_exec( imap_store_t *ctx, imap_cmd_t *cmdp,
            void (*done)( imap_store_t *ctx, imap_cmd_t *cmd, int response ),
@@ -600,7 +498,7 @@ imap_exec( imap_store_t *ctx, imap_cmd_t *cmdp,
                cmdp = new_imap_cmd( sizeof(*cmdp) );
        cmdp->param.done = done;
        va_start( ap, fmt );
-       cmdp->cmd = imap_vprintf( fmt, ap );
+       cmdp->cmd = xvasprintf( fmt, ap );
        va_end( ap );
        submit_imap_cmd( ctx, cmdp );
 }
diff --git a/src/util.c b/src/util.c
index b999a8c9..8a17da29 100644
--- a/src/util.c
+++ b/src/util.c
@@ -184,6 +184,112 @@ sys_error( const char *msg, ... )
        va_end( va );
 }
 
+// Minimal printf() replacement with custom format sequence(s):
+// - %\\s
+//   Print backslash-escaped string literals. Note that this does not
+//   automatically add quotes around the printed string, so it is
+//   possible to concatenate multiple segments.
+
+// TODO: Trade off segments vs. buffer capacity dynamically.
+#define QPRINTF_SEGS 16
+#define QPRINTF_BUFF 1000
+
+char *
+xvasprintf( const char *fmt, va_list ap )
+{
+       int nsegs = 0;
+       uint totlen = 0;
+       const char *segs[QPRINTF_SEGS];
+       uint segls[QPRINTF_SEGS];
+       char buf[QPRINTF_BUFF];
+
+#define ADD_SEG(p, l) \
+               do { \
+                       if (nsegs == QPRINTF_SEGS) \
+                               oob(); \
+                       segs[nsegs] = p; \
+                       segls[nsegs++] = l; \
+                       totlen += l; \
+               } while (0)
+
+       char *d = buf;
+       char *ed = d + sizeof(buf);
+       const char *s = fmt;
+       for (;;) {
+               char c = *fmt;
+               if (!c || c == '%') {
+                       uint l = fmt - s;
+                       if (l)
+                               ADD_SEG( s, l );
+                       if (!c)
+                               break;
+                       uint maxlen = UINT_MAX;
+                       c = *++fmt;
+                       if (c == '\\') {
+                               c = *++fmt;
+                               if (c != 's') {
+                                       fputs( "Fatal: unsupported escaped 
format specifier. Please report a bug.\n", stderr );
+                                       abort();
+                               }
+                               char *bd = d;
+                               s = va_arg( ap, const char * );
+                               while ((c = *s++)) {
+                                       if (d + 2 > ed)
+                                               oob();
+                                       if (c == '\\' || c == '"')
+                                               *d++ = '\\';
+                                       *d++ = c;
+                               }
+                               l = d - bd;
+                               if (l)
+                                       ADD_SEG( bd, l );
+                       } else {  // \\ cannot be combined with anything else.
+                               if (c == '.') {
+                                       c = *++fmt;
+                                       if (c != '*') {
+                                               fputs( "Fatal: unsupported 
string length specification. Please report a bug.\n", stderr );
+                                               abort();
+                                       }
+                                       maxlen = va_arg( ap, uint );
+                                       c = *++fmt;
+                               }
+                               if (c == 'c') {
+                                       if (d + 1 > ed)
+                                               oob();
+                                       ADD_SEG( d, 1 );
+                                       *d++ = (char)va_arg( ap, int );
+                               } else if (c == 's') {
+                                       s = va_arg( ap, const char * );
+                                       l = strnlen( s, maxlen );
+                                       if (l)
+                                               ADD_SEG( s, l );
+                               } else if (c == 'd') {
+                                       l = nfsnprintf( d, ed - d, "%d", 
va_arg( ap, int ) );
+                                       ADD_SEG( d, l );
+                                       d += l;
+                               } else if (c == 'u') {
+                                       l = nfsnprintf( d, ed - d, "%u", 
va_arg( ap, uint ) );
+                                       ADD_SEG( d, l );
+                                       d += l;
+                               } else {
+                                       fputs( "Fatal: unsupported format 
specifier. Please report a bug.\n", stderr );
+                                       abort();
+                               }
+                       }
+                       s = ++fmt;
+               } else {
+                       fmt++;
+               }
+       }
+       char *out = d = nfmalloc( totlen + 1 );
+       for (int i = 0; i < nsegs; i++) {
+               memcpy( d, segs[i], segls[i] );
+               d += segls[i];
+       }
+       *d = 0;
+       return out;
+}
+
 void
 vFprintf( FILE *f, const char *msg, va_list va )
 {


_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to