Added SILC Thread Queue API
[silc.git] / lib / silcutil / silcsnprintf.c
index 633bdf1d295eb489d6a477c165ccc86aa7a7705d..d49b6d1fa85df441aef677f93d99f3340432b281 100644 (file)
@@ -91,6 +91,7 @@
 #define DP_F_ZERO      (1 << 4)
 #define DP_F_UP        (1 << 5)
 #define DP_F_UNSIGNED  (1 << 6)
+#define DP_F_HEXPREFIX         (1 << 7)
 
 /* Conversion Flags */
 #define DP_C_SHORT   1
@@ -127,6 +128,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format,
   int cflags;
   size_t currlen;
   va_list args;
+  SilcSnprintfRender render;
 
   silc_va_copy(args, args_in);
 
@@ -322,8 +324,10 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format,
        fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
        break;
       case 'p':
+       flags |= (DP_F_UNSIGNED | DP_F_HEXPREFIX);
        strvalue = va_arg (args, void *);
-       fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
+       fmtint (buffer, &currlen, maxlen, (long )strvalue, 16, min, max,
+               flags);
        break;
       case 'n':
        if (cflags == DP_C_SHORT) {
@@ -351,6 +355,23 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format,
        /* not supported yet, treat as next char */
        ch = *format++;
        break;
+      case '@':
+       /* Renderer function */
+       render = va_arg (args, SilcSnprintfRender);
+       if (render) {
+         void *ptr = va_arg (args, void *);
+         if (ptr) {
+           strvalue = render (ptr);
+           if (strvalue) {
+             if (max == -1)
+               max = strlen(strvalue);
+             if (min > 0 && max >= 0 && min > max) max = min;
+             fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
+             silc_free(strvalue);
+           }
+         }
+       }
+       break;
       default:
        /* Unknown, skip */
        break;
@@ -413,7 +434,7 @@ static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
 /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
 
 static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
-                   long value, int base, int min, int max, int flags)
+                  long value, int base, int min, int max, int flags)
 {
   int signvalue = 0;
   unsigned long uvalue;
@@ -468,6 +489,12 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
     --spadlen;
   }
 
+  /* 0x prefix */
+  if (flags & DP_F_HEXPREFIX) {
+    dopr_outch (buffer, currlen, maxlen, '0');
+    dopr_outch (buffer, currlen, maxlen, 'x');
+  }
+
   /* Sign */
   if (signvalue)
     dopr_outch (buffer, currlen, maxlen, signvalue);