#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;
}
if(*p == '\0')
break;
if(*p == '$') {
- if(!addchar(&b, *p))
+ if(!sbaddchar(&b, *p))
break;
continue;
}
c = "(bad format specifier)";
}
if(c)
- if(!addstr(&b, c))
+ if(!sbaddstr(&b, c))
break;
}
- buf[b.len] = '\0';
+ sbterminate(&b);
/* not required */
/*