Revert "pthreadpool: add pthreadpool_tevent_[current_job_]per_thread_cwd()"
[samba.git] / lib / replace / snprintf.c
index 877d2a1d62b8f46eadd7c6be9cce140d340e21c6..6e4424b0b318bbf5919a32c8d223296397deca89 100644 (file)
  *    probably requires libm on most operating systems.  Don't yet
  *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
  *    was pretty badly broken, it just wasn't being exercised in ways
- *    which showed it, so that's been fixed.  Also, formated the code
+ *    which showed it, so that's been fixed.  Also, formatted the code
  *    to mutt conventions, and removed dead code left over from the
  *    original.  Also, there is now a builtin-test, just compile with:
  *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
  *    and run snprintf for results.
- * 
+ *
  *  Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
- *    The PGP code was using unsigned hexadecimal formats. 
+ *    The PGP code was using unsigned hexadecimal formats.
  *    Unfortunately, unsigned formats simply didn't work.
  *
  *  Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
  *
  * date: 2002/12/19 19:56:31;  author: herb;  state: Exp;  lines: +2 -0
  * actually print args for %g and %e
- * 
+ *
  * date: 2002/06/03 13:37:52;  author: jmcd;  state: Exp;  lines: +8 -0
  * Since includes.h isn't included here, VA_COPY has to be defined here.  I don't
  * see any include file that is guaranteed to be here, so I'm defining it
  * locally.  Fixes AIX and Solaris builds.
- * 
+ *
  * date: 2002/06/03 03:07:24;  author: tridge;  state: Exp;  lines: +5 -13
  * put the ifdef for HAVE_VA_COPY in one place rather than in lots of
  * functions
- * 
+ *
  * date: 2002/05/17 14:51:22;  author: jmcd;  state: Exp;  lines: +21 -4
  * Fix usage of va_list passed as an arg.  Use __va_copy before using it
  * when it exists.
- * 
+ *
  * date: 2002/04/16 22:38:04;  author: idra;  state: Exp;  lines: +20 -14
  * Fix incorrect zpadlen handling in fmtfp.
  * Thanks to Ollie Oldham <ollie.oldham@metro-optix.com> for spotting it.
@@ -97,8 +97,8 @@
  *    From OpenSSH.  Also added test for same.
  *
  * Simo Sorce (idra@samba.org) Jan 2006
- * 
- *    Add support for position independent parameters 
+ *
+ *    Add support for position independent parameters
  *    fix fmtstr now it conforms to sprintf wrt min.max
  *
  **************************************************************/
 #include <stdio.h>
  /* make the compiler happy with an empty file */
  void dummy_snprintf(void);
- void dummy_snprintf(void) {} 
+ void dummy_snprintf(void) {}
 #endif /* HAVE_SNPRINTF, etc */
 
 /* yes this really must be a ||. Don't muck with this (tridge) */
 #define DP_S_DONE    7
 
 /* format flags - Bits */
-#define DP_F_MINUS     (1 << 0)
-#define DP_F_PLUS      (1 << 1)
-#define DP_F_SPACE     (1 << 2)
-#define DP_F_NUM       (1 << 3)
-#define DP_F_ZERO      (1 << 4)
-#define DP_F_UP        (1 << 5)
-#define DP_F_UNSIGNED  (1 << 6)
+#define DP_F_MINUS     (1 << 0)
+#define DP_F_PLUS      (1 << 1)
+#define DP_F_SPACE     (1 << 2)
+#define DP_F_NUM       (1 << 3)
+#define DP_F_ZERO      (1 << 4)
+#define DP_F_UP                (1 << 5)
+#define DP_F_UNSIGNED  (1 << 6)
 
 /* Conversion Flags */
 #define DP_C_CHAR    1
 struct pr_chunk {
        int type; /* chunk type */
        int num; /* parameter number */
-       int min; 
+       int min;
        int max;
        int flags;
        int cflags;
@@ -224,7 +224,7 @@ struct pr_chunk_x {
        int num;
 };
 
-static int dopr(char *buffer, size_t maxlen, const char *format, 
+static int dopr(char *buffer, size_t maxlen, const char *format,
                   va_list args_in);
 static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
                    char *value, int flags, int min, int max);
@@ -263,15 +263,15 @@ static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in
        max_pos = 0;
        base = format;
        ch = *format++;
-       
+
        /* retrieve the string structure as chunks */
        while (state != DP_S_DONE) {
-               if (ch == '\0') 
+               if (ch == '\0')
                        state = DP_S_DONE;
 
                switch(state) {
                case DP_S_DEFAULT:
-                       
+
                        if (cnk) {
                                cnk->next = new_chunk();
                                cnk = cnk->next;
@@ -280,7 +280,7 @@ static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in
                        }
                        if (!cnk) goto done;
                        if (!chunks) chunks = cnk;
-                       
+
                        if (ch == '%') {
                                state = DP_S_FLAGS;
                                ch = *format++;
@@ -376,7 +376,7 @@ static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in
                        if (ch == '.') {
                                state = DP_S_MAX;
                                ch = *format++;
-                       } else { 
+                       } else {
                                state = DP_S_MOD;
                        }
                        break;
@@ -445,6 +445,10 @@ static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in
                                        ch = *format++;
                                }
                                break;
+                       case 'j':
+                               cnk->cflags = DP_C_LLONG;
+                               ch = *format++;
+                               break;
                        case 'L':
                                cnk->cflags = DP_C_LDOUBLE;
                                ch = *format++;
@@ -463,7 +467,7 @@ static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in
                        max_pos = add_cnk_list_entry(&clist, max_pos, cnk);
                        if (max_pos == 0) /* out of memory :-( */
                                goto done;
-                       
+
                        switch (ch) {
                        case 'd':
                        case 'i':
@@ -556,7 +560,7 @@ static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in
                cnk = clist[pnum].chunks[0];
                switch (cnk->type) {
                case CNK_INT:
-                       if (cnk->cflags == DP_C_SHORT) 
+                       if (cnk->cflags == DP_C_SHORT)
                                cnk->value = va_arg (args, int);
                        else if (cnk->cflags == DP_C_LONG)
                                cnk->value = va_arg (args, long int);
@@ -674,7 +678,7 @@ static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in
                                memcpy(&(buffer[currlen]), &(base[cnk->start]), len);
                        }
                        currlen += cnk->len;
-                               
+
                        break;
 
                case CNK_INT:
@@ -735,9 +739,9 @@ static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in
                cnk = cnk->next;
        }
        if (maxlen != 0) {
-               if (currlen < maxlen - 1) 
+               if (currlen < maxlen - 1)
                        buffer[currlen] = '\0';
-               else if (maxlen > 0) 
+               else if (maxlen > 0)
                        buffer[maxlen - 1] = '\0';
        }
        ret = currlen;
@@ -774,11 +778,11 @@ static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
 
        for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */
        padlen = min - strln;
-       if (padlen < 0) 
+       if (padlen < 0)
                padlen = 0;
-       if (flags & DP_F_MINUS) 
+       if (flags & DP_F_MINUS)
                padlen = -padlen; /* Left Justify */
-       
+
        while (padlen > 0) {
                dopr_outch (buffer, currlen, maxlen, ' ');
                --padlen;
@@ -800,17 +804,17 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
 {
        int signvalue = 0;
        unsigned LLONG uvalue;
-       char convert[20];
+       char convert[22+1]; /* 64-bit value in octal: 22 digits + \0 */
        int place = 0;
        int spadlen = 0; /* amount to space pad */
        int zpadlen = 0; /* amount to zero pad */
        int caps = 0;
-       
+
        if (max < 0)
                max = 0;
-       
+
        uvalue = value;
-       
+
        if(!(flags & DP_F_UNSIGNED)) {
                if( value < 0 ) {
                        signvalue = '-';
@@ -822,7 +826,7 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
                                signvalue = ' ';
                }
        }
-  
+
        if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
 
        do {
@@ -830,8 +834,8 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
                        (caps? "0123456789ABCDEF":"0123456789abcdef")
                        [uvalue % (unsigned)base  ];
                uvalue = (uvalue / (unsigned)base );
-       } while(uvalue && (place < 20));
-       if (place == 20) place--;
+       } while(uvalue && (place < sizeof(convert)));
+       if (place == sizeof(convert)) place--;
        convert[place] = 0;
 
        zpadlen = max - place;
@@ -842,7 +846,7 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
                zpadlen = MAX(zpadlen, spadlen);
                spadlen = 0;
        }
-       if (flags & DP_F_MINUS) 
+       if (flags & DP_F_MINUS)
                spadlen = -spadlen; /* Left Justifty */
 
 #ifdef DEBUG_SNPRINTF
@@ -857,7 +861,7 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
        }
 
        /* Sign */
-       if (signvalue) 
+       if (signvalue)
                dopr_outch (buffer, currlen, maxlen, signvalue);
 
        /* Zeros */
@@ -869,9 +873,9 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
        }
 
        /* Digits */
-       while (place > 0) 
+       while (place > 0)
                dopr_outch (buffer, currlen, maxlen, convert[--place]);
-  
+
        /* Left Justified spaces */
        while (spadlen < 0) {
                dopr_outch (buffer, currlen, maxlen, ' ');
@@ -885,19 +889,19 @@ static LDOUBLE abs_val(LDOUBLE value)
 
        if (value < 0)
                result = -value;
-       
+
        return result;
 }
 
 static LDOUBLE POW10(int exp)
 {
        LDOUBLE result = 1;
-       
+
        while (exp) {
                result *= 10;
                exp--;
        }
-  
+
        return result;
 }
 
@@ -908,7 +912,7 @@ static LLONG ROUND(LDOUBLE value)
        intpart = (LLONG)value;
        value = value - intpart;
        if (value >= 0.5) intpart++;
-       
+
        return intpart;
 }
 
@@ -941,7 +945,7 @@ static double my_modf(double x0, double *iptr)
                ret = my_modf(x0-l*f, &i2);
                (*iptr) = l*f + i2;
                return ret;
-       } 
+       }
 
        (*iptr) = l;
        return x - (*iptr);
@@ -958,14 +962,14 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
        int iplace = 0;
        int fplace = 0;
        int padlen = 0; /* amount to pad */
-       int zpadlen = 0; 
+       int zpadlen = 0;
        int caps = 0;
        int idx;
        double intpart;
        double fracpart;
        double temp;
-  
-       /* 
+
+       /*
         * AIX manpage says the default is 0, but Solaris says the default
         * is 6, and sprintf on AIX defaults to 6
         */
@@ -993,8 +997,8 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
         if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */
 #endif
 
-       /* 
-        * Sorry, we only support 9 digits past the decimal because of our 
+       /*
+        * Sorry, we only support 9 digits past the decimal because of our
         * conversion method
         */
        if (max > 9)
@@ -1008,7 +1012,7 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
        my_modf(temp, &intpart);
 
        fracpart = ROUND((POW10(max)) * (ufvalue - intpart));
-       
+
        if (fracpart >= POW10(max)) {
                intpart++;
                fracpart -= POW10(max);
@@ -1043,16 +1047,16 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
                if (fplace == 311) fplace--;
        }
        fconvert[fplace] = 0;
-  
+
        /* -1 for decimal point, another -1 if we are printing a sign */
-       padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
+       padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
        zpadlen = max - fplace;
        if (zpadlen < 0) zpadlen = 0;
-       if (padlen < 0) 
+       if (padlen < 0)
                padlen = 0;
-       if (flags & DP_F_MINUS) 
+       if (flags & DP_F_MINUS)
                padlen = -padlen; /* Left Justifty */
-       
+
        if ((flags & DP_F_ZERO) && (padlen > 0)) {
                if (signvalue) {
                        dopr_outch (buffer, currlen, maxlen, signvalue);
@@ -1068,10 +1072,10 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
                dopr_outch (buffer, currlen, maxlen, ' ');
                --padlen;
        }
-       if (signvalue) 
+       if (signvalue)
                dopr_outch (buffer, currlen, maxlen, signvalue);
-       
-       while (iplace > 0) 
+
+       while (iplace > 0)
                dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
 
 #ifdef DEBUG_SNPRINTF
@@ -1084,13 +1088,13 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
         */
        if (max > 0) {
                dopr_outch (buffer, currlen, maxlen, '.');
-               
+
                while (zpadlen > 0) {
                        dopr_outch (buffer, currlen, maxlen, '0');
                        --zpadlen;
                }
 
-               while (fplace > 0) 
+               while (fplace > 0)
                        dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
        }
 
@@ -1143,7 +1147,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
 
        if (chunk->num > max_num) {
                max = chunk->num;
-       
+
                if (*list == NULL) {
                        l = (struct pr_chunk_x *)malloc(sizeof(struct pr_chunk_x) * max);
                        pos = 0;
@@ -1169,7 +1173,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
        i = chunk->num - 1;
        cnum = l[i].num + 1;
        if (l[i].chunks == NULL) {
-               c = (struct pr_chunk **)malloc(sizeof(struct pr_chunk *) * cnum); 
+               c = (struct pr_chunk **)malloc(sizeof(struct pr_chunk *) * cnum);
        } else {
                c = (struct pr_chunk **)realloc(l[i].chunks, sizeof(struct pr_chunk *) * cnum);
        }
@@ -1204,7 +1208,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
 {
        size_t ret;
        va_list ap;
-    
+
        va_start(ap, fmt);
        ret = vsnprintf(str, count, fmt, ap);
        va_end(ap);
@@ -1254,9 +1258,9 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
 }
 #endif
 
-#endif 
+#endif
 
-#ifndef HAVE_VASPRINTF
+#if !defined(HAVE_VASPRINTF) || !defined(HAVE_C99_VSNPRINTF)
  int rep_vasprintf(char **ptr, const char *format, va_list ap)
 {
        int ret;
@@ -1278,13 +1282,12 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
 }
 #endif
 
-
-#ifndef HAVE_ASPRINTF
+#if !defined(HAVE_ASPRINTF) || !defined(HAVE_C99_VSNPRINTF)
  int rep_asprintf(char **ptr, const char *format, ...)
 {
        va_list ap;
        int ret;
-       
+
        *ptr = NULL;
        va_start(ap, format);
        ret = vasprintf(ptr, format, ap);
@@ -1323,7 +1326,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
                "%-9.9f",
                NULL
        };
-       double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 203.9, 0.96, 0.996, 
+       double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 203.9, 0.96, 0.996,
                             0.9996, 1.996, 4.136, 5.030201, 0.00205,
                             /* END LIST */ 0};
        char *int_fmt[] = {
@@ -1383,7 +1386,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
                        l2 = sprintf (buf2, fp_fmt[x], fp_nums[y]);
                        buf1[1023] = buf2[1023] = '\0';
                        if (strcmp (buf1, buf2) || (l1 != l2)) {
-                               printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", 
+                               printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
                                       fp_fmt[x], l1, buf1, l2, buf2);
                                fail++;
                        }
@@ -1398,7 +1401,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
                        l2 = sprintf (buf2, int_fmt[x], int_nums[y]);
                        buf1[1023] = buf2[1023] = '\0';
                        if (strcmp (buf1, buf2) || (l1 != l2)) {
-                               printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", 
+                               printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
                                       int_fmt[x], l1, buf1, l2, buf2);
                                fail++;
                        }
@@ -1413,7 +1416,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
                        l2 = sprintf (buf2, str_fmt[x], str_vals[y]);
                        buf1[1023] = buf2[1023] = '\0';
                        if (strcmp (buf1, buf2) || (l1 != l2)) {
-                               printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", 
+                               printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
                                       str_fmt[x], l1, buf1, l2, buf2);
                                fail++;
                        }
@@ -1429,7 +1432,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
                        l2 = sprintf (buf2, ll_fmt[x], ll_nums[y]);
                        buf1[1023] = buf2[1023] = '\0';
                        if (strcmp (buf1, buf2) || (l1 != l2)) {
-                               printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", 
+                               printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
                                       ll_fmt[x], l1, buf1, l2, buf2);
                                fail++;
                        }
@@ -1481,7 +1484,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
                        l2 = sprintf (buf2, ss_fmt[x], ss_nums[y]);
                        buf1[1023] = buf2[1023] = '\0';
                        if (strcmp (buf1, buf2) || (l1 != l2)) {
-                               printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", 
+                               printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n",
                                       ss_fmt[x], l1, buf1, l2, buf2);
                                fail++;
                        }
@@ -1515,7 +1518,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
        {
                double v0 = 0.12345678901234567890123456789012345678901;
                for (x=0; x<100; x++) {
-                       double p = pow(10, x); 
+                       double p = pow(10, x);
                        double r = v0*p;
                        snprintf(buf1, sizeof(buf1), "%1.1f", r);
                        sprintf(buf2,                "%1.1f", r);