diff options
Diffstat (limited to 'Source/CTest/Curl/mprintf.c')
-rw-r--r-- | Source/CTest/Curl/mprintf.c | 1219 |
1 files changed, 0 insertions, 1219 deletions
diff --git a/Source/CTest/Curl/mprintf.c b/Source/CTest/Curl/mprintf.c deleted file mode 100644 index d620fcd..0000000 --- a/Source/CTest/Curl/mprintf.c +++ /dev/null @@ -1,1219 +0,0 @@ -/**************************************************************************** - * - * $Id$ - * - ************************************************************************* - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - * Purpose: - * A merge of Bjorn Reese's format() function and Daniel's dsprintf() - * 1.0. A full blooded printf() clone with full support for <num>$ - * everywhere (parameters, widths and precisions) including variabled - * sized parameters (like doubles, long longs, long doubles and even - * void * in 64-bit architectures). - * - * Current restrictions: - * - Max 128 parameters - * - No 'long double' support. - * - * If you ever want truly portable and good *printf() clones, the project that - * took on from here is named 'Trio' and you find more details on the trio web - * page at http://daniel.haxx.se/trio/ - */ - - -#include "setup.h" -#include <sys/types.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <ctype.h> -#include <string.h> - -#include <curl/mprintf.h> - -#ifndef SIZEOF_LONG_DOUBLE -#define SIZEOF_LONG_DOUBLE 0 -#endif - -#ifndef SIZEOF_SIZE_T -/* default to 4 bytes for size_t unless defined in the config.h */ -#define SIZEOF_SIZE_T 4 -#endif - -#ifdef DPRINTF_DEBUG -#define HAVE_LONGLONG -#define LONG_LONG long long -#define ENABLE_64BIT -#endif - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */ -#define MAX_PARAMETERS 128 /* lame static limit */ - -#undef TRUE -#undef FALSE -#undef BOOL -#ifdef __cplusplus -# define TRUE true -# define FALSE false -# define BOOL bool -#else -# define TRUE ((char)(1 == 1)) -# define FALSE ((char)(0 == 1)) -# define BOOL char -#endif - - -/* Lower-case digits. */ -static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; - -/* Upper-case digits. */ -static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -#define OUTCHAR(x) \ - do{ \ - if(stream((unsigned char)(x), (FILE *)data) != -1) \ - done++; \ - else \ - return done; /* return immediately on failure */ \ - } while(0) - -/* Data type to read from the arglist */ -typedef enum { - FORMAT_UNKNOWN = 0, - FORMAT_STRING, - FORMAT_PTR, - FORMAT_INT, - FORMAT_INTPTR, - FORMAT_LONG, - FORMAT_LONGLONG, - FORMAT_DOUBLE, - FORMAT_LONGDOUBLE, - FORMAT_WIDTH /* For internal use */ -} FormatType; - -/* convertion and display flags */ -enum { - FLAGS_NEW = 0, - FLAGS_SPACE = 1<<0, - FLAGS_SHOWSIGN = 1<<1, - FLAGS_LEFT = 1<<2, - FLAGS_ALT = 1<<3, - FLAGS_SHORT = 1<<4, - FLAGS_LONG = 1<<5, - FLAGS_LONGLONG = 1<<6, - FLAGS_LONGDOUBLE = 1<<7, - FLAGS_PAD_NIL = 1<<8, - FLAGS_UNSIGNED = 1<<9, - FLAGS_OCTAL = 1<<10, - FLAGS_HEX = 1<<11, - FLAGS_UPPER = 1<<12, - FLAGS_WIDTH = 1<<13, /* '*' or '*<num>$' used */ - FLAGS_WIDTHPARAM = 1<<14, /* width PARAMETER was specified */ - FLAGS_PREC = 1<<15, /* precision was specified */ - FLAGS_PRECPARAM = 1<<16, /* precision PARAMETER was specified */ - FLAGS_CHAR = 1<<17, /* %c story */ - FLAGS_FLOATE = 1<<18, /* %e or %E */ - FLAGS_FLOATG = 1<<19 /* %g or %G */ -}; - -typedef struct { - FormatType type; - int flags; - long width; /* width OR width parameter number */ - long precision; /* precision OR precision parameter number */ - union { - char *str; - void *ptr; - long num; -#ifdef ENABLE_64BIT - LONG_LONG lnum; -#endif - double dnum; - } data; -} va_stack_t; - -struct nsprintf { - char *buffer; - size_t length; - size_t max; -}; - -struct asprintf { - char *buffer; /* allocated buffer */ - size_t len; /* length of string */ - size_t alloc; /* length of alloc */ - bool fail; /* TRUE if an alloc has failed and thus the output is not - the complete data */ -}; - -int curl_msprintf(char *buffer, const char *format, ...); - -static long dprintf_DollarString(char *input, char **end) -{ - int number=0; - while(isdigit((int)*input)) { - number *= 10; - number += *input-'0'; - input++; - } - if(number && ('$'==*input++)) { - *end = input; - return number; - } - return 0; -} - -static BOOL dprintf_IsQualifierNoDollar(char c) -{ - switch (c) { - case '-': case '+': case ' ': case '#': case '.': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case 'h': case 'l': case 'L': case 'z': case 'q': - case '*': case 'O': - return TRUE; - default: - return FALSE; - } -} - -#ifdef DPRINTF_DEBUG2 -int dprintf_Pass1Report(va_stack_t *vto, int max) -{ - int i; - char buffer[128]; - int bit; - int flags; - - for(i=0; i<max; i++) { - char *type; - switch(vto[i].type) { - case FORMAT_UNKNOWN: - type = "unknown"; - break; - case FORMAT_STRING: - type ="string"; - break; - case FORMAT_PTR: - type ="pointer"; - break; - case FORMAT_INT: - type = "int"; - break; - case FORMAT_LONG: - type = "long"; - break; - case FORMAT_LONGLONG: - type = "long long"; - break; - case FORMAT_DOUBLE: - type = "double"; - break; - case FORMAT_LONGDOUBLE: - type = "long double"; - break; - } - - - buffer[0]=0; - - for(bit=0; bit<31; bit++) { - flags = vto[i].flags & (1<<bit); - - if(flags & FLAGS_SPACE) - strcat(buffer, "space "); - else if(flags & FLAGS_SHOWSIGN) - strcat(buffer, "plus "); - else if(flags & FLAGS_LEFT) - strcat(buffer, "left "); - else if(flags & FLAGS_ALT) - strcat(buffer, "alt "); - else if(flags & FLAGS_SHORT) - strcat(buffer, "short "); - else if(flags & FLAGS_LONG) - strcat(buffer, "long "); - else if(flags & FLAGS_LONGLONG) - strcat(buffer, "longlong "); - else if(flags & FLAGS_LONGDOUBLE) - strcat(buffer, "longdouble "); - else if(flags & FLAGS_PAD_NIL) - strcat(buffer, "padnil "); - else if(flags & FLAGS_UNSIGNED) - strcat(buffer, "unsigned "); - else if(flags & FLAGS_OCTAL) - strcat(buffer, "octal "); - else if(flags & FLAGS_HEX) - strcat(buffer, "hex "); - else if(flags & FLAGS_UPPER) - strcat(buffer, "upper "); - else if(flags & FLAGS_WIDTH) - strcat(buffer, "width "); - else if(flags & FLAGS_WIDTHPARAM) - strcat(buffer, "widthparam "); - else if(flags & FLAGS_PREC) - strcat(buffer, "precision "); - else if(flags & FLAGS_PRECPARAM) - strcat(buffer, "precparam "); - else if(flags & FLAGS_CHAR) - strcat(buffer, "char "); - else if(flags & FLAGS_FLOATE) - strcat(buffer, "floate "); - else if(flags & FLAGS_FLOATG) - strcat(buffer, "floatg "); - } - printf("REPORT: %d. %s [%s]\n", i, type, buffer); - - } - - -} -#endif - -/****************************************************************** - * - * Pass 1: - * Create an index with the type of each parameter entry and its - * value (may vary in size) - * - ******************************************************************/ - -static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos, - va_list arglist) -{ - char *fmt = format; - int param_num = 0; - long this_param; - long width; - long precision; - int flags; - long max_param=0; - long i; - - while (*fmt) { - if (*fmt++ == '%') { - if (*fmt == '%') { - fmt++; - continue; /* while */ - } - - flags = FLAGS_NEW; - - /* Handle the positional case (N$) */ - - param_num++; - - this_param = dprintf_DollarString(fmt, &fmt); - if (0 == this_param) - /* we got no positional, get the next counter */ - this_param = param_num; - - if (this_param > max_param) - max_param = this_param; - - /* - * The parameter with number 'i' should be used. Next, we need - * to get SIZE and TYPE of the parameter. Add the information - * to our array. - */ - - width = 0; - precision = 0; - - /* Handle the flags */ - - while (dprintf_IsQualifierNoDollar(*fmt)) { - switch (*fmt++) { - case ' ': - flags |= FLAGS_SPACE; - break; - case '+': - flags |= FLAGS_SHOWSIGN; - break; - case '-': - flags |= FLAGS_LEFT; - flags &= ~FLAGS_PAD_NIL; - break; - case '#': - flags |= FLAGS_ALT; - break; - case '.': - flags |= FLAGS_PREC; - if ('*' == *fmt) { - /* The precision is picked from a specified parameter */ - - flags |= FLAGS_PRECPARAM; - fmt++; - param_num++; - - i = dprintf_DollarString(fmt, &fmt); - if (i) - precision = i; - else - precision = param_num; - - if (precision > max_param) - max_param = precision; - } - else { - flags |= FLAGS_PREC; - precision = strtol(fmt, &fmt, 10); - } - break; - case 'h': - flags |= FLAGS_SHORT; - break; - case 'l': - if (flags & FLAGS_LONG) - flags |= FLAGS_LONGLONG; - else - flags |= FLAGS_LONG; - break; - case 'L': - flags |= FLAGS_LONGDOUBLE; - break; - case 'q': - flags |= FLAGS_LONGLONG; - break; - case 'z': - /* the code below generates a warning if -Wunreachable-code is - used */ -#if SIZEOF_SIZE_T>4 - flags |= FLAGS_LONGLONG; -#else - flags |= FLAGS_LONG; -#endif - break; - case 'O': -#if SIZEOF_CURL_OFF_T > 4 - flags |= FLAGS_LONGLONG; -#else - flags |= FLAGS_LONG; -#endif - break; - case '0': - if (!(flags & FLAGS_LEFT)) - flags |= FLAGS_PAD_NIL; - /* FALLTHROUGH */ - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - flags |= FLAGS_WIDTH; - width = strtol(fmt-1, &fmt, 10); - break; - case '*': /* Special case */ - flags |= FLAGS_WIDTHPARAM; - param_num++; - - i = dprintf_DollarString(fmt, &fmt); - if(i) - width = i; - else - width = param_num; - if(width > max_param) - max_param=width; - break; - default: - break; - } - } /* switch */ - - /* Handle the specifier */ - - i = this_param - 1; - - switch (*fmt) { - case 'S': - flags |= FLAGS_ALT; - /* FALLTHROUGH */ - case 's': - vto[i].type = FORMAT_STRING; - break; - case 'n': - vto[i].type = FORMAT_INTPTR; - break; - case 'p': - vto[i].type = FORMAT_PTR; - break; - case 'd': case 'i': - vto[i].type = FORMAT_INT; - break; - case 'u': - vto[i].type = FORMAT_INT; - flags |= FLAGS_UNSIGNED; - break; - case 'o': - vto[i].type = FORMAT_INT; - flags |= FLAGS_OCTAL; - break; - case 'x': - vto[i].type = FORMAT_INT; - flags |= FLAGS_HEX; - break; - case 'X': - vto[i].type = FORMAT_INT; - flags |= FLAGS_HEX|FLAGS_UPPER; - break; - case 'c': - vto[i].type = FORMAT_INT; - flags |= FLAGS_CHAR; - break; - case 'f': - vto[i].type = FORMAT_DOUBLE; - break; - case 'e': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATE; - break; - case 'E': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATE|FLAGS_UPPER; - break; - case 'g': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATG; - break; - case 'G': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATG|FLAGS_UPPER; - break; - default: - vto[i].type = FORMAT_UNKNOWN; - break; - } /* switch */ - - vto[i].flags = flags; - vto[i].width = width; - vto[i].precision = precision; - - if (flags & FLAGS_WIDTHPARAM) { - /* we have the width specified from a parameter, so we make that - parameter's info setup properly */ - vto[i].width = width - 1; - i = width - 1; - vto[i].type = FORMAT_WIDTH; - vto[i].flags = FLAGS_NEW; - vto[i].precision = vto[i].width = 0; /* can't use width or precision - of width! */ - } - if (flags & FLAGS_PRECPARAM) { - /* we have the precision specified from a parameter, so we make that - parameter's info setup properly */ - vto[i].precision = precision - 1; - i = precision - 1; - vto[i].type = FORMAT_WIDTH; - vto[i].flags = FLAGS_NEW; - vto[i].precision = vto[i].width = 0; /* can't use width or precision - of width! */ - } - *endpos++ = fmt + 1; /* end of this sequence */ - } - } - -#ifdef DPRINTF_DEBUG2 - dprintf_Pass1Report(vto, max_param); -#endif - - /* Read the arg list parameters into our data list */ - for (i=0; i<max_param; i++) { - if ((i + 1 < max_param) && (vto[i + 1].type == FORMAT_WIDTH)) - { - /* Width/precision arguments must be read before the main argument - * they are attached to - */ - vto[i + 1].data.num = va_arg(arglist, int); - } - - switch (vto[i].type) - { - case FORMAT_STRING: - vto[i].data.str = va_arg(arglist, char *); - break; - - case FORMAT_INTPTR: - case FORMAT_UNKNOWN: - case FORMAT_PTR: - vto[i].data.ptr = va_arg(arglist, void *); - break; - - case FORMAT_INT: -#ifdef ENABLE_64BIT - if(vto[i].flags & FLAGS_LONGLONG) - vto[i].data.lnum = va_arg(arglist, LONG_LONG); - else -#endif - if(vto[i].flags & FLAGS_LONG) - vto[i].data.num = va_arg(arglist, long); - else - vto[i].data.num = va_arg(arglist, int); - break; - - case FORMAT_DOUBLE: - vto[i].data.dnum = va_arg(arglist, double); - break; - - case FORMAT_WIDTH: - /* Argument has been read. Silently convert it into an integer - * for later use - */ - vto[i].type = FORMAT_INT; - break; - - default: - break; - } - } - - return max_param; - -} - -static int dprintf_formatf( - void *data, /* untouched by format(), just sent to the stream() function in - the second argument */ - /* function pointer called for each output character */ - int (*stream)(int, FILE *), - const char *format, /* %-formatted string */ - va_list ap_save) /* list of parameters */ -{ - /* Base-36 digits for numbers. */ - const char *digits = lower_digits; - - /* Pointer into the format string. */ - char *f; - - /* Number of characters written. */ - int done = 0; - - long param; /* current parameter to read */ - long param_num=0; /* parameter counter */ - - va_stack_t vto[MAX_PARAMETERS]; - char *endpos[MAX_PARAMETERS]; - char **end; - - char work[BUFFSIZE]; - - va_stack_t *p; - - /* Do the actual %-code parsing */ - dprintf_Pass1((char *)format, vto, endpos, ap_save); - - end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1() - created for us */ - - f = (char *)format; - while (*f != '\0') { - /* Format spec modifiers. */ - char alt; - - /* Width of a field. */ - long width; - - /* Precision of a field. */ - long prec; - - /* Decimal integer is negative. */ - char is_neg; - - /* Base of a number to be written. */ - long base; - - /* Integral values to be written. */ -#ifdef ENABLE_64BIT - unsigned LONG_LONG num; -#else - unsigned long num; -#endif - long signed_num; - - if (*f != '%') { - /* This isn't a format spec, so write everything out until the next one - OR end of string is reached. */ - do { - OUTCHAR(*f); - } while(*++f && ('%' != *f)); - continue; - } - - ++f; - - /* Check for "%%". Note that although the ANSI standard lists - '%' as a conversion specifier, it says "The complete format - specification shall be `%%'," so we can avoid all the width - and precision processing. */ - if (*f == '%') { - ++f; - OUTCHAR('%'); - continue; - } - - /* If this is a positional parameter, the position must follow imediately - after the %, thus create a %<num>$ sequence */ - param=dprintf_DollarString(f, &f); - - if(!param) - param = param_num; - else - --param; - - param_num++; /* increase this always to allow "%2$s %1$s %s" and then the - third %s will pick the 3rd argument */ - - p = &vto[param]; - - /* pick up the specified width */ - if(p->flags & FLAGS_WIDTHPARAM) - width = vto[p->width].data.num; - else - width = p->width; - - /* pick up the specified precision */ - if(p->flags & FLAGS_PRECPARAM) - prec = vto[p->precision].data.num; - else if(p->flags & FLAGS_PREC) - prec = p->precision; - else - prec = -1; - - alt = (p->flags & FLAGS_ALT)?TRUE:FALSE; - - switch (p->type) { - case FORMAT_INT: - num = p->data.num; - if(p->flags & FLAGS_CHAR) { - /* Character. */ - if (!(p->flags & FLAGS_LEFT)) - while (--width > 0) - OUTCHAR(' '); - OUTCHAR((char) num); - if (p->flags & FLAGS_LEFT) - while (--width > 0) - OUTCHAR(' '); - break; - } - if(p->flags & FLAGS_UNSIGNED) { - /* Decimal unsigned integer. */ - base = 10; - goto unsigned_number; - } - if(p->flags & FLAGS_OCTAL) { - /* Octal unsigned integer. */ - base = 8; - goto unsigned_number; - } - if(p->flags & FLAGS_HEX) { - /* Hexadecimal unsigned integer. */ - - digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits; - base = 16; - goto unsigned_number; - } - - /* Decimal integer. */ - base = 10; - -#ifdef ENABLE_64BIT - if(p->flags & FLAGS_LONGLONG) { - /* long long */ - is_neg = p->data.lnum < 0; - num = is_neg ? (- p->data.lnum) : p->data.lnum; - } - else -#endif - { - signed_num = (long) num; - is_neg = signed_num < 0; - num = is_neg ? (- signed_num) : signed_num; - } - goto number; - - unsigned_number: - /* Unsigned number of base BASE. */ - is_neg = 0; - - number: - /* Number of base BASE. */ - { - char *workend = &work[sizeof(work) - 1]; - char *w; - - /* Supply a default precision if none was given. */ - if (prec == -1) - prec = 1; - - /* Put the number in WORK. */ - w = workend; - while (num > 0) { - *w-- = digits[num % base]; - num /= base; - } - width -= workend - w; - prec -= workend - w; - - if (alt && base == 8 && prec <= 0) { - *w-- = '0'; - --width; - } - - if (prec > 0) { - width -= prec; - while (prec-- > 0) - *w-- = '0'; - } - - if (alt && base == 16) - width -= 2; - - if (is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE)) - --width; - - if (!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL)) - while (width-- > 0) - OUTCHAR(' '); - - if (is_neg) - OUTCHAR('-'); - else if (p->flags & FLAGS_SHOWSIGN) - OUTCHAR('+'); - else if (p->flags & FLAGS_SPACE) - OUTCHAR(' '); - - if (alt && base == 16) { - OUTCHAR('0'); - if(p->flags & FLAGS_UPPER) - OUTCHAR('X'); - else - OUTCHAR('x'); - } - - if (!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL)) - while (width-- > 0) - OUTCHAR('0'); - - /* Write the number. */ - while (++w <= workend) { - OUTCHAR(*w); - } - - if (p->flags & FLAGS_LEFT) - while (width-- > 0) - OUTCHAR(' '); - } - break; - - case FORMAT_STRING: - /* String. */ - { - static char null[] = "(nil)"; - char *str; - size_t len; - - str = (char *) p->data.str; - if ( str == NULL) { - /* Write null[] if there's space. */ - if (prec == -1 || prec >= (long) sizeof(null) - 1) { - str = null; - len = sizeof(null) - 1; - /* Disable quotes around (nil) */ - p->flags &= (~FLAGS_ALT); - } - else { - str = (char *)""; - len = 0; - } - } - else - len = strlen(str); - - if (prec != -1 && (size_t) prec < len) - len = prec; - width -= len; - - if (p->flags & FLAGS_ALT) - OUTCHAR('"'); - - if (!(p->flags&FLAGS_LEFT)) - while (width-- > 0) - OUTCHAR(' '); - - while (len-- > 0) - OUTCHAR(*str++); - if (p->flags&FLAGS_LEFT) - while (width-- > 0) - OUTCHAR(' '); - - if (p->flags & FLAGS_ALT) - OUTCHAR('"'); - } - break; - - case FORMAT_PTR: - /* Generic pointer. */ - { - void *ptr; - ptr = (void *) p->data.ptr; - if (ptr != NULL) { - /* If the pointer is not NULL, write it as a %#x spec. */ - base = 16; - digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits; - alt = 1; - num = (unsigned long) ptr; - is_neg = 0; - goto number; - } - else { - /* Write "(nil)" for a nil pointer. */ - static char strnil[] = "(nil)"; - char *point; - - width -= sizeof(strnil) - 1; - if (p->flags & FLAGS_LEFT) - while (width-- > 0) - OUTCHAR(' '); - for (point = strnil; *point != '\0'; ++point) - OUTCHAR(*point); - if (! (p->flags & FLAGS_LEFT)) - while (width-- > 0) - OUTCHAR(' '); - } - } - break; - - case FORMAT_DOUBLE: - { - char formatbuf[32]="%"; - char *fptr; - size_t left = sizeof(formatbuf)-strlen(formatbuf); - int len; - - width = -1; - if (p->flags & FLAGS_WIDTH) - width = p->width; - else if (p->flags & FLAGS_WIDTHPARAM) - width = vto[p->width].data.num; - - prec = -1; - if (p->flags & FLAGS_PREC) - prec = p->precision; - else if (p->flags & FLAGS_PRECPARAM) - prec = vto[p->precision].data.num; - - if (p->flags & FLAGS_LEFT) - strcat(formatbuf, "-"); - if (p->flags & FLAGS_SHOWSIGN) - strcat(formatbuf, "+"); - if (p->flags & FLAGS_SPACE) - strcat(formatbuf, " "); - if (p->flags & FLAGS_ALT) - strcat(formatbuf, "#"); - - fptr=&formatbuf[strlen(formatbuf)]; - - if(width >= 0) { - /* RECURSIVE USAGE */ - len = curl_msnprintf(fptr, left, "%ld", width); - fptr += len; - left -= len; - } - if(prec >= 0) { - /* RECURSIVE USAGE */ - len = curl_msnprintf(fptr, left, ".%ld", prec); - fptr += len; - left -= len; - } - (void)left; - if (p->flags & FLAGS_LONG) - *fptr++ = 'l'; - - if (p->flags & FLAGS_FLOATE) - *fptr++ = p->flags&FLAGS_UPPER ? 'E':'e'; - else if (p->flags & FLAGS_FLOATG) - *fptr++ = p->flags & FLAGS_UPPER ? 'G' : 'g'; - else - *fptr++ = 'f'; - - *fptr = 0; /* and a final zero termination */ - - /* NOTE NOTE NOTE!! Not all sprintf() implementations returns number - of output characters */ - (sprintf)(work, formatbuf, p->data.dnum); - - for(fptr=work; *fptr; fptr++) - OUTCHAR(*fptr); - } - break; - - case FORMAT_INTPTR: - /* Answer the count of characters written. */ -#ifdef ENABLE_64BIT - if (p->flags & FLAGS_LONGLONG) - *(LONG_LONG *) p->data.ptr = (LONG_LONG)done; - else -#endif - if (p->flags & FLAGS_LONG) - *(long *) p->data.ptr = (long)done; - else if (!(p->flags & FLAGS_SHORT)) - *(int *) p->data.ptr = (int)done; - else - *(short *) p->data.ptr = (short)done; - break; - - default: - break; - } - f = *end++; /* goto end of %-code */ - - } - return done; -} - -/* fputc() look-alike */ -static int addbyter(int output, FILE *data) -{ - struct nsprintf *infop=(struct nsprintf *)data; - unsigned char outc = (unsigned char)output; - - if(infop->length < infop->max) { - /* only do this if we haven't reached max length yet */ - infop->buffer[0] = outc; /* store */ - infop->buffer++; /* increase pointer */ - infop->length++; /* we are now one byte larger */ - return outc; /* fputc() returns like this on success */ - } - return -1; -} - -int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format, - va_list ap_save) -{ - int retcode; - struct nsprintf info; - - info.buffer = buffer; - info.length = 0; - info.max = maxlength; - - retcode = dprintf_formatf(&info, addbyter, format, ap_save); - if(info.max) { - /* we terminate this with a zero byte */ - if(info.max == info.length) - /* we're at maximum, scrap the last letter */ - info.buffer[-1] = 0; - else - info.buffer[0] = 0; - } - return retcode; -} - -int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...) -{ - int retcode; - va_list ap_save; /* argument pointer */ - va_start(ap_save, format); - retcode = curl_mvsnprintf(buffer, maxlength, format, ap_save); - va_end(ap_save); - return retcode; -} - -/* fputc() look-alike */ -static int alloc_addbyter(int output, FILE *data) -{ - struct asprintf *infop=(struct asprintf *)data; - unsigned char outc = (unsigned char)output; - - if(!infop->buffer) { - infop->buffer=(char *)malloc(32); - if(!infop->buffer) { - infop->fail = TRUE; - return -1; /* fail */ - } - infop->alloc = 32; - infop->len =0; - } - else if(infop->len+1 >= infop->alloc) { - char *newptr; - - newptr = (char *)realloc(infop->buffer, infop->alloc*2); - - if(!newptr) { - infop->fail = TRUE; - return -1; - } - infop->buffer = newptr; - infop->alloc *= 2; - } - - infop->buffer[ infop->len ] = outc; - - infop->len++; - - return outc; /* fputc() returns like this on success */ -} - -char *curl_maprintf(const char *format, ...) -{ - va_list ap_save; /* argument pointer */ - int retcode; - struct asprintf info; - - info.buffer = NULL; - info.len = 0; - info.alloc = 0; - info.fail = FALSE; - - va_start(ap_save, format); - retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); - va_end(ap_save); - if((-1 == retcode) || info.fail) { - if(info.alloc) - free(info.buffer); - return NULL; - } - if(info.alloc) { - info.buffer[info.len] = 0; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return strdup(""); -} - -char *curl_mvaprintf(const char *format, va_list ap_save) -{ - int retcode; - struct asprintf info; - - info.buffer = NULL; - info.len = 0; - info.alloc = 0; - info.fail = FALSE; - - retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); - if((-1 == retcode) || info.fail) { - if(info.alloc) - free(info.buffer); - return NULL; - } - - if(info.alloc) { - info.buffer[info.len] = 0; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return strdup(""); -} - -static int storebuffer(int output, FILE *data) -{ - char **buffer = (char **)data; - unsigned char outc = (unsigned char)output; - **buffer = outc; - (*buffer)++; - return outc; /* act like fputc() ! */ -} - -int curl_msprintf(char *buffer, const char *format, ...) -{ - va_list ap_save; /* argument pointer */ - int retcode; - va_start(ap_save, format); - retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save); - va_end(ap_save); - *buffer=0; /* we terminate this with a zero byte */ - return retcode; -} - -#ifndef WIN32 /* not needed on win32 */ -extern int fputc(int, FILE *); -#endif - -int curl_mprintf(const char *format, ...) -{ - int retcode; - va_list ap_save; /* argument pointer */ - va_start(ap_save, format); - retcode = dprintf_formatf(stdout, fputc, format, ap_save); - va_end(ap_save); - return retcode; -} - -int curl_mfprintf(FILE *whereto, const char *format, ...) -{ - int retcode; - va_list ap_save; /* argument pointer */ - va_start(ap_save, format); - retcode = dprintf_formatf(whereto, fputc, format, ap_save); - va_end(ap_save); - return retcode; -} - -int curl_mvsprintf(char *buffer, const char *format, va_list ap_save) -{ - int retcode; - retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save); - *buffer=0; /* we terminate this with a zero byte */ - return retcode; -} - -int curl_mvprintf(const char *format, va_list ap_save) -{ - return dprintf_formatf(stdout, fputc, format, ap_save); -} - -int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save) -{ - return dprintf_formatf(whereto, fputc, format, ap_save); -} - -#ifdef DPRINTF_DEBUG -int main() -{ - char buffer[129]; - char *ptr; -#ifdef ENABLE_64BIT - long long one=99; - long long two=100; - long long test = 0x1000000000LL; - curl_mprintf("%lld %lld %lld\n", one, two, test); -#endif - - curl_mprintf("%3d %5d\n", 10, 1998); - - 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); - - puts(ptr); - - memset(ptr, 55, strlen(ptr)+1); - - free(ptr); - -#if 1 - curl_mprintf(buffer, "%s %s %d", "daniel", "stenberg", 19988); - puts(buffer); - - curl_mfprintf(stderr, "%s %#08x\n", "dummy", 65); - - printf("%s %#08x\n", "dummy", 65); - { - double tryout = 3.14156592; - curl_mprintf(buffer, "%.2g %G %f %e %E", tryout, tryout, tryout, tryout, tryout); - puts(buffer); - printf("%.2g %G %f %e %E\n", tryout, tryout, tryout, tryout, tryout); - } -#endif - - return 0; -} - -#endif |