00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "setup.h"
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <stdarg.h>
00037 #include <ctype.h>
00038 #include <string.h>
00039
00040 #if defined(DJGPP) && (DJGPP_MINOR < 4)
00041 #undef _MPRINTF_REPLACE
00042 #endif
00043
00044 #include <curl/mprintf.h>
00045
00046 #ifndef SIZEOF_LONG_DOUBLE
00047 #define SIZEOF_LONG_DOUBLE 0
00048 #endif
00049
00050 #ifndef SIZEOF_SIZE_T
00051
00052 #define SIZEOF_SIZE_T 4
00053 #endif
00054
00055 #ifdef DPRINTF_DEBUG
00056 #define HAVE_LONGLONG
00057 #define LONG_LONG long long
00058 #define ENABLE_64BIT
00059 #endif
00060
00061 #include "memory.h"
00062
00063 #include "memdebug.h"
00064
00065 #define BUFFSIZE 256
00066 #define MAX_PARAMETERS 128
00067
00068 #undef TRUE
00069 #undef FALSE
00070 #undef BOOL
00071 #ifdef __cplusplus
00072 # define TRUE true
00073 # define FALSE false
00074 # define BOOL bool
00075 #else
00076 # define TRUE ((char)(1 == 1))
00077 # define FALSE ((char)(0 == 1))
00078 # define BOOL char
00079 #endif
00080
00081 #ifdef __AMIGA__
00082 # undef FORMAT_INT
00083 #endif
00084
00085
00086 static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
00087
00088
00089 static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00090
00091 #define OUTCHAR(x) \
00092 do{ \
00093 if(stream((unsigned char)(x), (FILE *)data) != -1) \
00094 done++; \
00095 else \
00096 return done; \
00097 } while(0)
00098
00099
00100 typedef enum {
00101 FORMAT_UNKNOWN = 0,
00102 FORMAT_STRING,
00103 FORMAT_PTR,
00104 FORMAT_INT,
00105 FORMAT_INTPTR,
00106 FORMAT_LONG,
00107 FORMAT_LONGLONG,
00108 FORMAT_DOUBLE,
00109 FORMAT_LONGDOUBLE,
00110 FORMAT_WIDTH
00111 } FormatType;
00112
00113
00114 enum {
00115 FLAGS_NEW = 0,
00116 FLAGS_SPACE = 1<<0,
00117 FLAGS_SHOWSIGN = 1<<1,
00118 FLAGS_LEFT = 1<<2,
00119 FLAGS_ALT = 1<<3,
00120 FLAGS_SHORT = 1<<4,
00121 FLAGS_LONG = 1<<5,
00122 FLAGS_LONGLONG = 1<<6,
00123 FLAGS_LONGDOUBLE = 1<<7,
00124 FLAGS_PAD_NIL = 1<<8,
00125 FLAGS_UNSIGNED = 1<<9,
00126 FLAGS_OCTAL = 1<<10,
00127 FLAGS_HEX = 1<<11,
00128 FLAGS_UPPER = 1<<12,
00129 FLAGS_WIDTH = 1<<13,
00130 FLAGS_WIDTHPARAM = 1<<14,
00131 FLAGS_PREC = 1<<15,
00132 FLAGS_PRECPARAM = 1<<16,
00133 FLAGS_CHAR = 1<<17,
00134 FLAGS_FLOATE = 1<<18,
00135 FLAGS_FLOATG = 1<<19
00136 };
00137
00138 typedef struct {
00139 FormatType type;
00140 int flags;
00141 long width;
00142 long precision;
00143 union {
00144 char *str;
00145 void *ptr;
00146 long num;
00147 #ifdef ENABLE_64BIT
00148 LONG_LONG lnum;
00149 #endif
00150 double dnum;
00151 } data;
00152 } va_stack_t;
00153
00154 struct nsprintf {
00155 char *buffer;
00156 size_t length;
00157 size_t max;
00158 };
00159
00160 struct asprintf {
00161 char *buffer;
00162 size_t len;
00163 size_t alloc;
00164 bool fail;
00165
00166 };
00167
00168 int curl_msprintf(char *buffer, const char *format, ...);
00169
00170 static long dprintf_DollarString(char *input, char **end)
00171 {
00172 int number=0;
00173 while(ISDIGIT(*input)) {
00174 number *= 10;
00175 number += *input-'0';
00176 input++;
00177 }
00178 if(number && ('$'==*input++)) {
00179 *end = input;
00180 return number;
00181 }
00182 return 0;
00183 }
00184
00185 static BOOL dprintf_IsQualifierNoDollar(char c)
00186 {
00187 switch (c) {
00188 case '-': case '+': case ' ': case '#': case '.':
00189 case '0': case '1': case '2': case '3': case '4':
00190 case '5': case '6': case '7': case '8': case '9':
00191 case 'h': case 'l': case 'L': case 'z': case 'q':
00192 case '*': case 'O':
00193 return TRUE;
00194 default:
00195 return FALSE;
00196 }
00197 }
00198
00199 #ifdef DPRINTF_DEBUG2
00200 int dprintf_Pass1Report(va_stack_t *vto, int max)
00201 {
00202 int i;
00203 char buffer[128];
00204 int bit;
00205 int flags;
00206
00207 for(i=0; i<max; i++) {
00208 char *type;
00209 switch(vto[i].type) {
00210 case FORMAT_UNKNOWN:
00211 type = "unknown";
00212 break;
00213 case FORMAT_STRING:
00214 type ="string";
00215 break;
00216 case FORMAT_PTR:
00217 type ="pointer";
00218 break;
00219 case FORMAT_INT:
00220 type = "int";
00221 break;
00222 case FORMAT_LONG:
00223 type = "long";
00224 break;
00225 case FORMAT_LONGLONG:
00226 type = "long long";
00227 break;
00228 case FORMAT_DOUBLE:
00229 type = "double";
00230 break;
00231 case FORMAT_LONGDOUBLE:
00232 type = "long double";
00233 break;
00234 }
00235
00236
00237 buffer[0]=0;
00238
00239 for(bit=0; bit<31; bit++) {
00240 flags = vto[i].flags & (1<<bit);
00241
00242 if(flags & FLAGS_SPACE)
00243 strcat(buffer, "space ");
00244 else if(flags & FLAGS_SHOWSIGN)
00245 strcat(buffer, "plus ");
00246 else if(flags & FLAGS_LEFT)
00247 strcat(buffer, "left ");
00248 else if(flags & FLAGS_ALT)
00249 strcat(buffer, "alt ");
00250 else if(flags & FLAGS_SHORT)
00251 strcat(buffer, "short ");
00252 else if(flags & FLAGS_LONG)
00253 strcat(buffer, "long ");
00254 else if(flags & FLAGS_LONGLONG)
00255 strcat(buffer, "longlong ");
00256 else if(flags & FLAGS_LONGDOUBLE)
00257 strcat(buffer, "longdouble ");
00258 else if(flags & FLAGS_PAD_NIL)
00259 strcat(buffer, "padnil ");
00260 else if(flags & FLAGS_UNSIGNED)
00261 strcat(buffer, "unsigned ");
00262 else if(flags & FLAGS_OCTAL)
00263 strcat(buffer, "octal ");
00264 else if(flags & FLAGS_HEX)
00265 strcat(buffer, "hex ");
00266 else if(flags & FLAGS_UPPER)
00267 strcat(buffer, "upper ");
00268 else if(flags & FLAGS_WIDTH)
00269 strcat(buffer, "width ");
00270 else if(flags & FLAGS_WIDTHPARAM)
00271 strcat(buffer, "widthparam ");
00272 else if(flags & FLAGS_PREC)
00273 strcat(buffer, "precision ");
00274 else if(flags & FLAGS_PRECPARAM)
00275 strcat(buffer, "precparam ");
00276 else if(flags & FLAGS_CHAR)
00277 strcat(buffer, "char ");
00278 else if(flags & FLAGS_FLOATE)
00279 strcat(buffer, "floate ");
00280 else if(flags & FLAGS_FLOATG)
00281 strcat(buffer, "floatg ");
00282 }
00283 printf("REPORT: %d. %s [%s]\n", i, type, buffer);
00284
00285 }
00286
00287
00288 }
00289 #endif
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
00300 va_list arglist)
00301 {
00302 char *fmt = format;
00303 int param_num = 0;
00304 long this_param;
00305 long width;
00306 long precision;
00307 int flags;
00308 long max_param=0;
00309 long i;
00310
00311 while (*fmt) {
00312 if (*fmt++ == '%') {
00313 if (*fmt == '%') {
00314 fmt++;
00315 continue;
00316 }
00317
00318 flags = FLAGS_NEW;
00319
00320
00321
00322 param_num++;
00323
00324 this_param = dprintf_DollarString(fmt, &fmt);
00325 if (0 == this_param)
00326
00327 this_param = param_num;
00328
00329 if (this_param > max_param)
00330 max_param = this_param;
00331
00332
00333
00334
00335
00336
00337
00338 width = 0;
00339 precision = 0;
00340
00341
00342
00343 while (dprintf_IsQualifierNoDollar(*fmt)) {
00344 switch (*fmt++) {
00345 case ' ':
00346 flags |= FLAGS_SPACE;
00347 break;
00348 case '+':
00349 flags |= FLAGS_SHOWSIGN;
00350 break;
00351 case '-':
00352 flags |= FLAGS_LEFT;
00353 flags &= ~FLAGS_PAD_NIL;
00354 break;
00355 case '#':
00356 flags |= FLAGS_ALT;
00357 break;
00358 case '.':
00359 flags |= FLAGS_PREC;
00360 if ('*' == *fmt) {
00361
00362
00363 flags |= FLAGS_PRECPARAM;
00364 fmt++;
00365 param_num++;
00366
00367 i = dprintf_DollarString(fmt, &fmt);
00368 if (i)
00369 precision = i;
00370 else
00371 precision = param_num;
00372
00373 if (precision > max_param)
00374 max_param = precision;
00375 }
00376 else {
00377 flags |= FLAGS_PREC;
00378 precision = strtol(fmt, &fmt, 10);
00379 }
00380 break;
00381 case 'h':
00382 flags |= FLAGS_SHORT;
00383 break;
00384 case 'l':
00385 if (flags & FLAGS_LONG)
00386 flags |= FLAGS_LONGLONG;
00387 else
00388 flags |= FLAGS_LONG;
00389 break;
00390 case 'L':
00391 flags |= FLAGS_LONGDOUBLE;
00392 break;
00393 case 'q':
00394 flags |= FLAGS_LONGLONG;
00395 break;
00396 case 'z':
00397
00398
00399 #if SIZEOF_SIZE_T>4
00400 flags |= FLAGS_LONGLONG;
00401 #else
00402 flags |= FLAGS_LONG;
00403 #endif
00404 break;
00405 case 'O':
00406 #if SIZEOF_CURL_OFF_T > 4
00407 flags |= FLAGS_LONGLONG;
00408 #else
00409 flags |= FLAGS_LONG;
00410 #endif
00411 break;
00412 case '0':
00413 if (!(flags & FLAGS_LEFT))
00414 flags |= FLAGS_PAD_NIL;
00415
00416 case '1': case '2': case '3': case '4':
00417 case '5': case '6': case '7': case '8': case '9':
00418 flags |= FLAGS_WIDTH;
00419 width = strtol(fmt-1, &fmt, 10);
00420 break;
00421 case '*':
00422 flags |= FLAGS_WIDTHPARAM;
00423 param_num++;
00424
00425 i = dprintf_DollarString(fmt, &fmt);
00426 if(i)
00427 width = i;
00428 else
00429 width = param_num;
00430 if(width > max_param)
00431 max_param=width;
00432 break;
00433 default:
00434 break;
00435 }
00436 }
00437
00438
00439
00440 i = this_param - 1;
00441
00442 switch (*fmt) {
00443 case 'S':
00444 flags |= FLAGS_ALT;
00445
00446 case 's':
00447 vto[i].type = FORMAT_STRING;
00448 break;
00449 case 'n':
00450 vto[i].type = FORMAT_INTPTR;
00451 break;
00452 case 'p':
00453 vto[i].type = FORMAT_PTR;
00454 break;
00455 case 'd': case 'i':
00456 vto[i].type = FORMAT_INT;
00457 break;
00458 case 'u':
00459 vto[i].type = FORMAT_INT;
00460 flags |= FLAGS_UNSIGNED;
00461 break;
00462 case 'o':
00463 vto[i].type = FORMAT_INT;
00464 flags |= FLAGS_OCTAL;
00465 break;
00466 case 'x':
00467 vto[i].type = FORMAT_INT;
00468 flags |= FLAGS_HEX;
00469 break;
00470 case 'X':
00471 vto[i].type = FORMAT_INT;
00472 flags |= FLAGS_HEX|FLAGS_UPPER;
00473 break;
00474 case 'c':
00475 vto[i].type = FORMAT_INT;
00476 flags |= FLAGS_CHAR;
00477 break;
00478 case 'f':
00479 vto[i].type = FORMAT_DOUBLE;
00480 break;
00481 case 'e':
00482 vto[i].type = FORMAT_DOUBLE;
00483 flags |= FLAGS_FLOATE;
00484 break;
00485 case 'E':
00486 vto[i].type = FORMAT_DOUBLE;
00487 flags |= FLAGS_FLOATE|FLAGS_UPPER;
00488 break;
00489 case 'g':
00490 vto[i].type = FORMAT_DOUBLE;
00491 flags |= FLAGS_FLOATG;
00492 break;
00493 case 'G':
00494 vto[i].type = FORMAT_DOUBLE;
00495 flags |= FLAGS_FLOATG|FLAGS_UPPER;
00496 break;
00497 default:
00498 vto[i].type = FORMAT_UNKNOWN;
00499 break;
00500 }
00501
00502 vto[i].flags = flags;
00503 vto[i].width = width;
00504 vto[i].precision = precision;
00505
00506 if (flags & FLAGS_WIDTHPARAM) {
00507
00508
00509 vto[i].width = width - 1;
00510 i = width - 1;
00511 vto[i].type = FORMAT_WIDTH;
00512 vto[i].flags = FLAGS_NEW;
00513 vto[i].precision = vto[i].width = 0;
00514
00515 }
00516 if (flags & FLAGS_PRECPARAM) {
00517
00518
00519 vto[i].precision = precision - 1;
00520 i = precision - 1;
00521 vto[i].type = FORMAT_WIDTH;
00522 vto[i].flags = FLAGS_NEW;
00523 vto[i].precision = vto[i].width = 0;
00524
00525 }
00526 *endpos++ = fmt + 1;
00527 }
00528 }
00529
00530 #ifdef DPRINTF_DEBUG2
00531 dprintf_Pass1Report(vto, max_param);
00532 #endif
00533
00534
00535 for (i=0; i<max_param; i++) {
00536 if ((i + 1 < max_param) && (vto[i + 1].type == FORMAT_WIDTH))
00537 {
00538
00539
00540
00541 vto[i + 1].data.num = va_arg(arglist, int);
00542 }
00543
00544 switch (vto[i].type)
00545 {
00546 case FORMAT_STRING:
00547 vto[i].data.str = va_arg(arglist, char *);
00548 break;
00549
00550 case FORMAT_INTPTR:
00551 case FORMAT_UNKNOWN:
00552 case FORMAT_PTR:
00553 vto[i].data.ptr = va_arg(arglist, void *);
00554 break;
00555
00556 case FORMAT_INT:
00557 #ifdef ENABLE_64BIT
00558 if(vto[i].flags & FLAGS_LONGLONG)
00559 vto[i].data.lnum = va_arg(arglist, LONG_LONG);
00560 else
00561 #endif
00562 if(vto[i].flags & FLAGS_LONG)
00563 vto[i].data.num = va_arg(arglist, long);
00564 else
00565 vto[i].data.num = va_arg(arglist, int);
00566 break;
00567
00568 case FORMAT_DOUBLE:
00569 vto[i].data.dnum = va_arg(arglist, double);
00570 break;
00571
00572 case FORMAT_WIDTH:
00573
00574
00575
00576 vto[i].type = FORMAT_INT;
00577 break;
00578
00579 default:
00580 break;
00581 }
00582 }
00583
00584 return max_param;
00585
00586 }
00587
00588 static int dprintf_formatf(
00589 void *data,
00590
00591
00592 int (*stream)(int, FILE *),
00593 const char *format,
00594 va_list ap_save)
00595 {
00596
00597 const char *digits = lower_digits;
00598
00599
00600 char *f;
00601
00602
00603 int done = 0;
00604
00605 long param;
00606 long param_num=0;
00607
00608 va_stack_t vto[MAX_PARAMETERS];
00609 char *endpos[MAX_PARAMETERS];
00610 char **end;
00611
00612 char work[BUFFSIZE];
00613
00614 va_stack_t *p;
00615
00616
00617 dprintf_Pass1((char *)format, vto, endpos, ap_save);
00618
00619 end = &endpos[0];
00620
00621
00622 f = (char *)format;
00623 while (*f != '\0') {
00624
00625 char alt;
00626
00627
00628 long width;
00629
00630
00631 long prec;
00632
00633
00634 char is_neg;
00635
00636
00637 long base;
00638
00639
00640 #ifdef ENABLE_64BIT
00641 unsigned LONG_LONG num;
00642 #else
00643 unsigned long num;
00644 #endif
00645 long signed_num;
00646
00647 if (*f != '%') {
00648
00649
00650 do {
00651 OUTCHAR(*f);
00652 } while(*++f && ('%' != *f));
00653 continue;
00654 }
00655
00656 ++f;
00657
00658
00659
00660
00661
00662 if (*f == '%') {
00663 ++f;
00664 OUTCHAR('%');
00665 continue;
00666 }
00667
00668
00669
00670 param=dprintf_DollarString(f, &f);
00671
00672 if(!param)
00673 param = param_num;
00674 else
00675 --param;
00676
00677 param_num++;
00678
00679
00680 p = &vto[param];
00681
00682
00683 if(p->flags & FLAGS_WIDTHPARAM)
00684 width = vto[p->width].data.num;
00685 else
00686 width = p->width;
00687
00688
00689 if(p->flags & FLAGS_PRECPARAM)
00690 prec = vto[p->precision].data.num;
00691 else if(p->flags & FLAGS_PREC)
00692 prec = p->precision;
00693 else
00694 prec = -1;
00695
00696 alt = (char)((p->flags & FLAGS_ALT)?TRUE:FALSE);
00697
00698 switch (p->type) {
00699 case FORMAT_INT:
00700 num = p->data.num;
00701 if(p->flags & FLAGS_CHAR) {
00702
00703 if (!(p->flags & FLAGS_LEFT))
00704 while (--width > 0)
00705 OUTCHAR(' ');
00706 OUTCHAR((char) num);
00707 if (p->flags & FLAGS_LEFT)
00708 while (--width > 0)
00709 OUTCHAR(' ');
00710 break;
00711 }
00712 if(p->flags & FLAGS_UNSIGNED) {
00713
00714 base = 10;
00715 goto unsigned_number;
00716 }
00717 if(p->flags & FLAGS_OCTAL) {
00718
00719 base = 8;
00720 goto unsigned_number;
00721 }
00722 if(p->flags & FLAGS_HEX) {
00723
00724
00725 digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
00726 base = 16;
00727 goto unsigned_number;
00728 }
00729
00730
00731 base = 10;
00732
00733 #ifdef ENABLE_64BIT
00734 if(p->flags & FLAGS_LONGLONG) {
00735
00736 is_neg = (char)(p->data.lnum < 0);
00737 num = is_neg ? (- p->data.lnum) : p->data.lnum;
00738 }
00739 else
00740 #endif
00741 {
00742 signed_num = (long) num;
00743 is_neg = (char)(signed_num < 0);
00744 num = is_neg ? (- signed_num) : signed_num;
00745 }
00746 goto number;
00747
00748 unsigned_number:
00749
00750 is_neg = 0;
00751
00752 number:
00753
00754 {
00755 char *workend = &work[sizeof(work) - 1];
00756 char *w;
00757
00758
00759 if (prec == -1)
00760 prec = 1;
00761
00762
00763 w = workend;
00764 while (num > 0) {
00765 *w-- = digits[num % base];
00766 num /= base;
00767 }
00768 width -= (long)(workend - w);
00769 prec -= (long)(workend - w);
00770
00771 if (alt && base == 8 && prec <= 0) {
00772 *w-- = '0';
00773 --width;
00774 }
00775
00776 if (prec > 0) {
00777 width -= prec;
00778 while (prec-- > 0)
00779 *w-- = '0';
00780 }
00781
00782 if (alt && base == 16)
00783 width -= 2;
00784
00785 if (is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE))
00786 --width;
00787
00788 if (!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL))
00789 while (width-- > 0)
00790 OUTCHAR(' ');
00791
00792 if (is_neg)
00793 OUTCHAR('-');
00794 else if (p->flags & FLAGS_SHOWSIGN)
00795 OUTCHAR('+');
00796 else if (p->flags & FLAGS_SPACE)
00797 OUTCHAR(' ');
00798
00799 if (alt && base == 16) {
00800 OUTCHAR('0');
00801 if(p->flags & FLAGS_UPPER)
00802 OUTCHAR('X');
00803 else
00804 OUTCHAR('x');
00805 }
00806
00807 if (!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL))
00808 while (width-- > 0)
00809 OUTCHAR('0');
00810
00811
00812 while (++w <= workend) {
00813 OUTCHAR(*w);
00814 }
00815
00816 if (p->flags & FLAGS_LEFT)
00817 while (width-- > 0)
00818 OUTCHAR(' ');
00819 }
00820 break;
00821
00822 case FORMAT_STRING:
00823
00824 {
00825 static const char null[] = "(nil)";
00826 const char *str;
00827 size_t len;
00828
00829 str = (char *) p->data.str;
00830 if ( str == NULL) {
00831
00832 if (prec == -1 || prec >= (long) sizeof(null) - 1) {
00833 str = null;
00834 len = sizeof(null) - 1;
00835
00836 p->flags &= (~FLAGS_ALT);
00837 }
00838 else {
00839 str = "";
00840 len = 0;
00841 }
00842 }
00843 else
00844 len = strlen(str);
00845
00846 if (prec != -1 && (size_t) prec < len)
00847 len = prec;
00848 width -= (long)len;
00849
00850 if (p->flags & FLAGS_ALT)
00851 OUTCHAR('"');
00852
00853 if (!(p->flags&FLAGS_LEFT))
00854 while (width-- > 0)
00855 OUTCHAR(' ');
00856
00857 while (len-- > 0)
00858 OUTCHAR(*str++);
00859 if (p->flags&FLAGS_LEFT)
00860 while (width-- > 0)
00861 OUTCHAR(' ');
00862
00863 if (p->flags & FLAGS_ALT)
00864 OUTCHAR('"');
00865 }
00866 break;
00867
00868 case FORMAT_PTR:
00869
00870 {
00871 void *ptr;
00872 ptr = (void *) p->data.ptr;
00873 if (ptr != NULL) {
00874
00875 base = 16;
00876 digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
00877 alt = 1;
00878 num = (size_t) ptr;
00879 is_neg = 0;
00880 goto number;
00881 }
00882 else {
00883
00884 static const char strnil[] = "(nil)";
00885 const char *point;
00886
00887 width -= sizeof(strnil) - 1;
00888 if (p->flags & FLAGS_LEFT)
00889 while (width-- > 0)
00890 OUTCHAR(' ');
00891 for (point = strnil; *point != '\0'; ++point)
00892 OUTCHAR(*point);
00893 if (! (p->flags & FLAGS_LEFT))
00894 while (width-- > 0)
00895 OUTCHAR(' ');
00896 }
00897 }
00898 break;
00899
00900 case FORMAT_DOUBLE:
00901 {
00902 char formatbuf[32]="%";
00903 char *fptr;
00904 size_t left = sizeof(formatbuf)-strlen(formatbuf);
00905 int len;
00906
00907 width = -1;
00908 if (p->flags & FLAGS_WIDTH)
00909 width = p->width;
00910 else if (p->flags & FLAGS_WIDTHPARAM)
00911 width = vto[p->width].data.num;
00912
00913 prec = -1;
00914 if (p->flags & FLAGS_PREC)
00915 prec = p->precision;
00916 else if (p->flags & FLAGS_PRECPARAM)
00917 prec = vto[p->precision].data.num;
00918
00919 if (p->flags & FLAGS_LEFT)
00920 strcat(formatbuf, "-");
00921 if (p->flags & FLAGS_SHOWSIGN)
00922 strcat(formatbuf, "+");
00923 if (p->flags & FLAGS_SPACE)
00924 strcat(formatbuf, " ");
00925 if (p->flags & FLAGS_ALT)
00926 strcat(formatbuf, "#");
00927
00928 fptr=&formatbuf[strlen(formatbuf)];
00929
00930 if(width >= 0) {
00931
00932 len = curl_msnprintf(fptr, left, "%ld", width);
00933 fptr += len;
00934 left -= len;
00935 }
00936 if(prec >= 0) {
00937
00938 len = curl_msnprintf(fptr, left, ".%ld", prec);
00939 fptr += len;
00940 left -= len;
00941 }
00942 if (p->flags & FLAGS_LONG)
00943 *fptr++ = 'l';
00944
00945 if (p->flags & FLAGS_FLOATE)
00946 *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'E':'e');
00947 else if (p->flags & FLAGS_FLOATG)
00948 *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'G' : 'g');
00949 else
00950 *fptr++ = 'f';
00951
00952 *fptr = 0;
00953
00954
00955
00956 (sprintf)(work, formatbuf, p->data.dnum);
00957
00958 for(fptr=work; *fptr; fptr++)
00959 OUTCHAR(*fptr);
00960 }
00961 break;
00962
00963 case FORMAT_INTPTR:
00964
00965 #ifdef ENABLE_64BIT
00966 if (p->flags & FLAGS_LONGLONG)
00967 *(LONG_LONG *) p->data.ptr = (LONG_LONG)done;
00968 else
00969 #endif
00970 if (p->flags & FLAGS_LONG)
00971 *(long *) p->data.ptr = (long)done;
00972 else if (!(p->flags & FLAGS_SHORT))
00973 *(int *) p->data.ptr = (int)done;
00974 else
00975 *(short *) p->data.ptr = (short)done;
00976 break;
00977
00978 default:
00979 break;
00980 }
00981 f = *end++;
00982
00983 }
00984 return done;
00985 }
00986
00987
00988 static int addbyter(int output, FILE *data)
00989 {
00990 struct nsprintf *infop=(struct nsprintf *)data;
00991 unsigned char outc = (unsigned char)output;
00992
00993 if(infop->length < infop->max) {
00994
00995 infop->buffer[0] = outc;
00996 infop->buffer++;
00997 infop->length++;
00998 return outc;
00999 }
01000 return -1;
01001 }
01002
01003 int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format,
01004 va_list ap_save)
01005 {
01006 int retcode;
01007 struct nsprintf info;
01008
01009 info.buffer = buffer;
01010 info.length = 0;
01011 info.max = maxlength;
01012
01013 retcode = dprintf_formatf(&info, addbyter, format, ap_save);
01014 if(info.max) {
01015
01016 if(info.max == info.length)
01017
01018 info.buffer[-1] = 0;
01019 else
01020 info.buffer[0] = 0;
01021 }
01022 return retcode;
01023 }
01024
01025 int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...)
01026 {
01027 int retcode;
01028 va_list ap_save;
01029 va_start(ap_save, format);
01030 retcode = curl_mvsnprintf(buffer, maxlength, format, ap_save);
01031 va_end(ap_save);
01032 return retcode;
01033 }
01034
01035
01036 static int alloc_addbyter(int output, FILE *data)
01037 {
01038 struct asprintf *infop=(struct asprintf *)data;
01039 unsigned char outc = (unsigned char)output;
01040
01041 if(!infop->buffer) {
01042 infop->buffer=(char *)malloc(32);
01043 if(!infop->buffer) {
01044 infop->fail = TRUE;
01045 return -1;
01046 }
01047 infop->alloc = 32;
01048 infop->len =0;
01049 }
01050 else if(infop->len+1 >= infop->alloc) {
01051 char *newptr;
01052
01053 newptr = (char *)realloc(infop->buffer, infop->alloc*2);
01054
01055 if(!newptr) {
01056 infop->fail = TRUE;
01057 return -1;
01058 }
01059 infop->buffer = newptr;
01060 infop->alloc *= 2;
01061 }
01062
01063 infop->buffer[ infop->len ] = outc;
01064
01065 infop->len++;
01066
01067 return outc;
01068 }
01069
01070 char *curl_maprintf(const char *format, ...)
01071 {
01072 va_list ap_save;
01073 int retcode;
01074 struct asprintf info;
01075
01076 info.buffer = NULL;
01077 info.len = 0;
01078 info.alloc = 0;
01079 info.fail = FALSE;
01080
01081 va_start(ap_save, format);
01082 retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
01083 va_end(ap_save);
01084 if((-1 == retcode) || info.fail) {
01085 if(info.alloc)
01086 free(info.buffer);
01087 return NULL;
01088 }
01089 if(info.alloc) {
01090 info.buffer[info.len] = 0;
01091 return info.buffer;
01092 }
01093 else
01094 return strdup("");
01095 }
01096
01097 char *curl_mvaprintf(const char *format, va_list ap_save)
01098 {
01099 int retcode;
01100 struct asprintf info;
01101
01102 info.buffer = NULL;
01103 info.len = 0;
01104 info.alloc = 0;
01105 info.fail = FALSE;
01106
01107 retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
01108 if((-1 == retcode) || info.fail) {
01109 if(info.alloc)
01110 free(info.buffer);
01111 return NULL;
01112 }
01113
01114 if(info.alloc) {
01115 info.buffer[info.len] = 0;
01116 return info.buffer;
01117 }
01118 else
01119 return strdup("");
01120 }
01121
01122 static int storebuffer(int output, FILE *data)
01123 {
01124 char **buffer = (char **)data;
01125 unsigned char outc = (unsigned char)output;
01126 **buffer = outc;
01127 (*buffer)++;
01128 return outc;
01129 }
01130
01131 int curl_msprintf(char *buffer, const char *format, ...)
01132 {
01133 va_list ap_save;
01134 int retcode;
01135 va_start(ap_save, format);
01136 retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
01137 va_end(ap_save);
01138 *buffer=0;
01139 return retcode;
01140 }
01141
01142 int curl_mprintf(const char *format, ...)
01143 {
01144 int retcode;
01145 va_list ap_save;
01146 va_start(ap_save, format);
01147
01148 retcode = dprintf_formatf(stdout, fputc, format, ap_save);
01149 va_end(ap_save);
01150 return retcode;
01151 }
01152
01153 int curl_mfprintf(FILE *whereto, const char *format, ...)
01154 {
01155 int retcode;
01156 va_list ap_save;
01157 va_start(ap_save, format);
01158 retcode = dprintf_formatf(whereto, fputc, format, ap_save);
01159 va_end(ap_save);
01160 return retcode;
01161 }
01162
01163 int curl_mvsprintf(char *buffer, const char *format, va_list ap_save)
01164 {
01165 int retcode;
01166 retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
01167 *buffer=0;
01168 return retcode;
01169 }
01170
01171 int curl_mvprintf(const char *format, va_list ap_save)
01172 {
01173 return dprintf_formatf(stdout, fputc, format, ap_save);
01174 }
01175
01176 int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save)
01177 {
01178 return dprintf_formatf(whereto, fputc, format, ap_save);
01179 }
01180
01181 #ifdef DPRINTF_DEBUG
01182 int main()
01183 {
01184 char buffer[129];
01185 char *ptr;
01186 #ifdef ENABLE_64BIT
01187 long long one=99;
01188 long long two=100;
01189 long long test = 0x1000000000LL;
01190 curl_mprintf("%lld %lld %lld\n", one, two, test);
01191 #endif
01192
01193 curl_mprintf("%3d %5d\n", 10, 1998);
01194
01195 ptr=curl_maprintf("test this then baby %s%s%s%s%s%s %d %d %d loser baby get a hit in yer face now!", "", "pretty long string pretty long string pretty long string pretty long string pretty long string", "/", "/", "/", "pretty long string", 1998, 1999, 2001);
01196
01197 puts(ptr);
01198
01199 memset(ptr, 55, strlen(ptr)+1);
01200
01201 free(ptr);
01202
01203 #if 1
01204 curl_mprintf(buffer, "%s %s %d", "daniel", "stenberg", 19988);
01205 puts(buffer);
01206
01207 curl_mfprintf(stderr, "%s %#08x\n", "dummy", 65);
01208
01209 printf("%s %#08x\n", "dummy", 65);
01210 {
01211 double tryout = 3.14156592;
01212 curl_mprintf(buffer, "%.2g %G %f %e %E", tryout, tryout, tryout, tryout, tryout);
01213 puts(buffer);
01214 printf("%.2g %G %f %e %E\n", tryout, tryout, tryout, tryout, tryout);
01215 }
01216 #endif
01217
01218 return 0;
01219 }
01220
01221 #endif