]> jfr.im git - irc/quakenet/newserv.git/blobdiff - chanserv/q9snprintf.c
Merge pull request #1 from meeb/meeb
[irc/quakenet/newserv.git] / chanserv / q9snprintf.c
index b57f0696530858a50cf233662854c4897587e7af..78219469917affecf4310f410569425007d75d52 100644 (file)
@@ -2,87 +2,80 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
+#include <time.h>
 #include "../lib/sstring.h"
+#include "../lib/stringbuf.h"
+#include "../lib/ccassert.h"
+#include "../core/error.h"
+#include "chanserv_messages.h"
 
 #define MAXARGS 10
+#define CONVBUF 512
 
-struct bufs {
-  char *buf;
-  int capacity;
-  int len;
-};
-
-static int addchar(struct bufs *buf, char c) {
-  if(buf->len >= buf->capacity - 1)
-    return 0;
-
-  buf->buf[buf->len++] = c;
-
-  return 1;
-}
-
-static int addstr(struct bufs *buf, char *c) {
-  int remaining = buf->capacity - buf->len - 1;
-  char *p;
-
-  for(p=c;*p;p++) {
-    if(remaining-- <= 0)
-      return 0;
-
-    buf->buf[buf->len++] = *p;
-  }
-
-  return 1;
+void q9strftime(char *buf, size_t size, time_t t) {
+  strftime(buf, size, Q9_FORMAT_TIME, gmtime(&t));
 }
 
 void q9vsnprintf(char *buf, size_t size, const char *format, const char *args, va_list ap) {
-  struct bufs b;
+  StringBuf b;
   const char *p;
   char *c;
-  char convbuf[MAXARGS][512];
+
+  char convbuf[MAXARGS][CONVBUF];
+
+  CCASSERT(CONVBUF > TIMELEN);
 
   if(size == 0)
     return;
 
   {
-    int argno = 0;
-    int d, i;
+    int argno = 0, i;
+
+    int d;
     char *s;
-    sstring *ss;
-    double f;
+    double g;
+    unsigned int u;
+    time_t t;
 
     for(i=0;i<MAXARGS;i++)
       convbuf[i][0] = '\0';
 
-    while(*args) {
-      switch(*args++) {
+    for(;*args;args++) {
+      char *cb = convbuf[argno++];
+
+      switch(*args) {
         case 's':
           s = va_arg(ap, char *);
-          snprintf(convbuf[argno++], sizeof(convbuf[0]), "%s", s);
-          break;
-        case 'S':
-          ss = va_arg(ap, sstring *);
-          snprintf(convbuf[argno++], sizeof(convbuf[0]), "%s", s?"(null)":ss->content);
+          snprintf(cb, CONVBUF, "%s", s);
           break;
         case 'd':
           d = va_arg(ap, int);
-          snprintf(convbuf[argno++], sizeof(convbuf[0]), "%d", d);
+          snprintf(cb, CONVBUF, "%d", d);
+          break;
+        case 'u':
+          u = va_arg(ap, unsigned int);
+          snprintf(cb, CONVBUF, "%u", u);
           break;
         case 'g':
-          f = va_arg(ap, double);
-          snprintf(convbuf[argno++], sizeof(convbuf[0]), "%.1f", f);
+          g = va_arg(ap, double);
+          snprintf(cb, CONVBUF, "%.1f", g);
+          break;
+        case 'T':
+          t = va_arg(ap, time_t);
+          q9strftime(cb, CONVBUF, t);
           break;
+        default:
+          /* calls exit(0) */
+          Error("chanserv", ERR_STOP, "Bad format specifier '%c' supplied in q9vsnprintf, format: '%s'", *args, format);
       }
     }
   }
 
-  b.buf = buf;
-  b.capacity = size;
-  b.len = 0;
+  sbinit(&b, buf, size);
 
   for(p=format;*p;p++) {
     if(*p != '$') {
-      if(!addchar(&b, *p))
+      if(!sbaddchar(&b, *p))
         break;
       continue;
     }
@@ -90,7 +83,7 @@ void q9vsnprintf(char *buf, size_t size, const char *format, const char *args, v
     if(*p == '\0')
       break;
     if(*p == '$') {
-      if(!addchar(&b, *p))
+      if(!sbaddchar(&b, *p))
         break;
       continue;
     }
@@ -118,11 +111,11 @@ void q9vsnprintf(char *buf, size_t size, const char *format, const char *args, v
         c = "(bad format specifier)";
     }
     if(c)
-      if(!addstr(&b, c))
+      if(!sbaddstr(&b, c))
         break;
   }
 
-  buf[b.len] = '\0';
+  sbterminate(&b);
 
   /* not required */
   /*