snprintf.c

Go to the documentation of this file.
00001 /* @(#)root/clib:$Id: snprintf.c 23600 2008-04-28 19:47:05Z pcanal $ */
00002 /* Author: Tomi Salo & Fons Rademakers */
00003 
00004 /*
00005    Portable snprintf and vsnprintf implementation.
00006 
00007    Format:
00008       snprintf(holder, sizeof_holder, format, ...)
00009       vsnprintf(holder, sizeof_holder, format, args)
00010 
00011    Return values:
00012       number of characters written or -1 if truncated or -2 if there is an
00013       error in format specification
00014 
00015    Author:
00016       Tomi Salo
00017          Original code
00018 
00019    Modified:
00020       Fons Rademakers
00021          Return -1 in case of truncation
00022          Added test program.
00023       M.Asokan
00024          Return -2 in case of error in format specification
00025          Distinguish between missing precision and a specified precision of 0
00026 
00027    To test snprintf and vsnprintf compile this file with:
00028       cc -g -DSNTEST `root-config --cflags` snprintf.c -o snprintf
00029 */
00030 
00031 #include <stdarg.h>
00032 #include <stdlib.h>
00033 #include <ctype.h>
00034 #include <stdio.h>
00035 #include <string.h>
00036 
00037 #include "RConfig.h"            /* for NEED_SNPRINTF */
00038 
00039 #if defined(NEED_SNPRINTF) || defined(SNTEST)
00040 
00041 /* to be able to test this code on machines that have snprintf */
00042 #ifndef NEED_SNPRINTF
00043 #define snprintf  r__snprintf
00044 #define vsnprintf r__vsnprintf
00045 #endif
00046 
00047 #if defined(R__WIN32) && !defined(__CINT__)
00048 typedef __int64            Long64_t;  /* Portable signed long integer 8 bytes */
00049 typedef unsigned __int64   ULong64_t; /* Portable unsigned long integer 8 bytes */
00050 #else
00051 typedef long long          Long64_t;  /* Portable signed long integer 8 bytes */
00052 typedef unsigned long long ULong64_t; /* Portable unsigned long integer 8 bytes */
00053 #endif
00054 
00055 #undef isdigit
00056 #define isdigit(ch) ((ch) >= '0' && (ch) <= '9')
00057 
00058 #define MINUS_FLAG 0x1
00059 #define PLUS_FLAG 0x2
00060 #define SPACE_FLAG 0x4
00061 #define HASH_FLAG 0x8
00062 #define CONV_TO_SHORT 0x10
00063 #define IS_LONG_INT 0x20
00064 #define IS_LONG_DOUBLE 0x40
00065 #define X_UPCASE 0x80
00066 #define IS_NEGATIVE 0x100
00067 #define UNSIGNED_DEC 0x200
00068 #define ZERO_PADDING 0x400
00069 #define IS_LONG_LONG_INT 0x800
00070 
00071 #ifndef DONTNEED_VSNPRINTF
00072 
00073 /* Extract a formatting directive from str. Str must point to a '%'.
00074    Returns number of characters used or zero if extraction failed. */
00075 
00076 static int snprintf_get_directive(const char *str, int *flags, int *width,
00077                                   int *precision, char *format_char,
00078                                   va_list *ap)
00079 {
00080    int length, value;
00081    const char *orig_str = str;
00082 
00083    *flags = 0;
00084    *width = 0;
00085    *precision = -1; /* Assume unspecified */
00086    *format_char = (char) 0;
00087 
00088    if (*str == '%') {
00089       /* Get the flags */
00090       str++;
00091       while (*str == '-' || *str == '+' || *str == ' '
00092              || *str == '#' || *str == '0') {
00093          switch (*str) {
00094          case '-':
00095             *flags |= MINUS_FLAG;
00096             break;
00097          case '+':
00098             *flags |= PLUS_FLAG;
00099             break;
00100          case ' ':
00101             *flags |= SPACE_FLAG;
00102             break;
00103          case '#':
00104             *flags |= HASH_FLAG;
00105             break;
00106          case '0':
00107             *flags |= ZERO_PADDING;
00108             break;
00109          }
00110          str++;
00111       }
00112 
00113       /* Don't pad left-justified numbers withs zeros */
00114       if ((*flags & MINUS_FLAG) && (*flags & ZERO_PADDING))
00115          *flags &= ~ZERO_PADDING;
00116 
00117       /* Is width field present? */
00118       if (isdigit(*str)) {
00119          for (value = 0; *str && isdigit(*str); str++)
00120             value = 10 * value + *str - '0';
00121          *width = value;
00122       } else if (*str == '*') {
00123          *width = va_arg(*ap, int);
00124          str++;
00125       }
00126 
00127       /* Is the precision field present? */
00128       if (*str == '.') {
00129          str++;
00130          if (isdigit(*str)) {
00131             for (value = 0; *str && isdigit(*str); str++)
00132                value = 10 * value + *str - '0';
00133             *precision = value;
00134          } else if (*str == '*') {
00135             *precision = va_arg(*ap, int);
00136             str++;
00137          } else
00138             *precision = 0;
00139       }
00140 
00141       /* Get the optional type character */
00142       if (*str == 'h') {
00143          *flags |= CONV_TO_SHORT;
00144          str++;
00145       } else {
00146          if (*str == 'l') {
00147             if (*(str+1)=='l') {
00148                *flags |= IS_LONG_LONG_INT;
00149                str++;
00150             } else {
00151                *flags |= IS_LONG_INT;
00152             }
00153             str++;
00154          } else {
00155             /* Support Win32 I64 type specifier, i.e. %I64d or %I64u */
00156             if (*str == 'I' && *(str+1)=='6' && *(str+2)=='4') {
00157                *flags |= IS_LONG_LONG_INT;
00158                str += 3;
00159             } else if (*str == 'L') {
00160                *flags |= IS_LONG_DOUBLE;
00161                str++;
00162             }
00163          }
00164       }
00165 
00166       /* Get and check the formatting character */
00167 
00168       *format_char = *str;
00169       str++;
00170       length = str - orig_str;
00171 
00172       switch (*format_char) {
00173       case 'i':
00174       case 'd':
00175       case 'o':
00176       case 'u':
00177       case 'x':
00178       case 'X':
00179       case 'f':
00180       case 'e':
00181       case 'E':
00182       case 'g':
00183       case 'G':
00184       case 'c':
00185       case 's':
00186       case 'p':
00187       case 'n':
00188          if (*format_char == 'X')
00189             *flags |= X_UPCASE;
00190          if (*format_char == 'o')
00191             *flags |= UNSIGNED_DEC;
00192          return length;
00193 
00194       default:
00195          return 0;
00196       }
00197    } else {
00198       return 0;
00199    }
00200 }
00201 
00202 /*
00203    Convert a integer from unsigned long int representation
00204    to string representation. This will insert prefixes if needed
00205    (leading zero for octal and 0x or 0X for hexadecimal) and
00206    will write at most buf_size characters to buffer.
00207    tmp_buf is used because we want to get correctly truncated
00208    results.
00209 */
00210 static int snprintf_convert_ulong(char *buffer, size_t buf_size, int base,
00211                                   char *digits, ULong64_t ulong_val,
00212                                   int flags, int width, int precision)
00213 {
00214    int tmp_buf_len = 100 + width, len;
00215    char *tmp_buf, *tmp_buf_ptr, prefix[2];
00216    tmp_buf = malloc(tmp_buf_len);
00217 
00218    prefix[0] = '\0';
00219    prefix[1] = '\0';
00220 
00221    /* Make tmp_buf_ptr point just past the last char of buffer */
00222    tmp_buf_ptr = tmp_buf + tmp_buf_len;
00223 
00224    /* Main conversion loop */
00225    do {
00226       *--tmp_buf_ptr = digits[ulong_val % base];
00227       ulong_val /= base;
00228       precision--;
00229    }
00230    while ((ulong_val != 0 || precision > 0) && tmp_buf_ptr > tmp_buf);
00231 
00232    /* Get the prefix */
00233    if (!(flags & IS_NEGATIVE)) {
00234       if (base == 16 && (flags & HASH_FLAG)) {
00235          if (flags && X_UPCASE) {
00236             prefix[0] = 'x';
00237             prefix[1] = '0';
00238          } else {
00239             prefix[0] = 'X';
00240             prefix[1] = '0';
00241          }
00242       }
00243 
00244       if (base == 8 && (flags & HASH_FLAG))
00245          prefix[0] = '0';
00246 
00247       if (base == 10 && !(flags & UNSIGNED_DEC) && (flags & PLUS_FLAG))
00248          prefix[0] = '+';
00249       else
00250           if (base == 10 && !(flags & UNSIGNED_DEC)
00251               && (flags & SPACE_FLAG)) prefix[0] = ' ';
00252    } else
00253       prefix[0] = '-';
00254 
00255    if (prefix[0] != '\0' && tmp_buf_ptr > tmp_buf) {
00256       *--tmp_buf_ptr = prefix[0];
00257       if (prefix[1] != '\0' && tmp_buf_ptr > tmp_buf)
00258          *--tmp_buf_ptr = prefix[1];
00259    }
00260 
00261    len = (tmp_buf + tmp_buf_len) - tmp_buf_ptr;
00262 
00263    if (len <= (int)buf_size) {
00264       if (len < width) {
00265          if (width > (tmp_buf_ptr - tmp_buf))
00266             width = (tmp_buf_ptr - tmp_buf);
00267          if (flags & MINUS_FLAG) {
00268             memcpy(buffer, tmp_buf_ptr, len);
00269             memset(buffer + len, (flags & ZERO_PADDING) ? '0' : ' ',
00270                    width - len);
00271             len = width;
00272          } else {
00273             memset(buffer, (flags & ZERO_PADDING) ? '0' : ' ',
00274                    width - len);
00275             memcpy(buffer + width - len, tmp_buf_ptr, len);
00276             len = width;
00277          }
00278       } else {
00279          memcpy(buffer, tmp_buf_ptr, len);
00280       }
00281       free(tmp_buf);
00282       return len;
00283    } else {
00284       memcpy(buffer, tmp_buf_ptr, buf_size);
00285       free(tmp_buf);
00286       return buf_size;
00287    }
00288 }
00289 
00290 
00291 static int snprintf_convert_float(char *buffer, size_t buf_size,
00292                                   double dbl_val, int flags, int width,
00293                                   int precision, char format_char)
00294 {
00295    char print_buf[160], print_buf_len = 0;
00296    char format_str[80], *format_str_ptr;
00297 
00298    format_str_ptr = format_str;
00299 
00300    if (width > 155)
00301       width = 155;
00302    if (precision <= 0)
00303       precision = 6;
00304    if (precision > 120)
00305       precision = 120;
00306 
00307    /* Construct the formatting string and let system's sprintf
00308       do the real work. */
00309 
00310    *format_str_ptr++ = '%';
00311 
00312    if (flags & MINUS_FLAG)
00313       *format_str_ptr++ = '-';
00314    if (flags & PLUS_FLAG)
00315       *format_str_ptr++ = '+';
00316    if (flags & SPACE_FLAG)
00317       *format_str_ptr++ = ' ';
00318    if (flags & ZERO_PADDING)
00319       *format_str_ptr++ = '0';
00320    if (flags & HASH_FLAG)
00321       *format_str_ptr++ = '#';
00322 
00323    sprintf(format_str_ptr, "%d.%d", width, precision);
00324    format_str_ptr += strlen(format_str_ptr);
00325 
00326    if (flags & IS_LONG_DOUBLE)
00327       *format_str_ptr++ = 'L';
00328    *format_str_ptr++ = format_char;
00329    *format_str_ptr++ = '\0';
00330 
00331    sprintf(print_buf, format_str, dbl_val);
00332    print_buf_len = strlen(print_buf);
00333 
00334    if (print_buf_len > (int)buf_size)
00335       print_buf_len = buf_size;
00336    strncpy(buffer, print_buf, print_buf_len);
00337    return print_buf_len;
00338 }
00339 
00340 int vsnprintf(char *str, size_t size, const char *format, va_list ap)
00341 {
00342    int status, left = (int) size - 1;
00343    const char *format_ptr = format;
00344    int flags, width, precision, i;
00345    char format_char, *orig_str = str;
00346    int *int_ptr;
00347    Long64_t long_val;
00348    ULong64_t ulong_val;
00349    char *str_val;
00350    double dbl_val;
00351    int precision_specified = 0;
00352 
00353   if (size <= 0 || str == NULL || format == NULL)
00354     return -1;
00355 
00356    flags = 0;
00357    while (format_ptr < format + strlen(format)) {
00358       if (*format_ptr == '%') {
00359          if (format_ptr[1] == '%' && left > 0) {
00360             *str++ = '%';
00361             left--;
00362             format_ptr += 2;
00363          } else {
00364             if (left <= 0) {
00365                *str = '\0';
00366                return -1;   /* size; */
00367             } else {
00368                status = snprintf_get_directive(format_ptr, &flags, &width,
00369                                                &precision, &format_char,
00370                                                &ap);
00371                if (status == 0) {
00372                   *str = '\0';
00373                   return -2;
00374                } else {
00375                   if (precision >= 0) {
00376                      precision_specified = 1;
00377                   } else {
00378                      precision_specified = 0;
00379                      precision = 0;
00380                   }
00381                   format_ptr += status;
00382                   /* Print a formatted argument */
00383                   switch (format_char) {
00384                   case 'i':
00385                   case 'd':
00386                      /* Convert to unsigned long int before
00387                         actual conversion to string */
00388                      if (flags & IS_LONG_LONG_INT)
00389                         long_val = va_arg(ap, Long64_t);
00390                      else if (flags & IS_LONG_INT)
00391                         long_val = (Long64_t) va_arg(ap, long int);
00392                      else
00393                         long_val = (Long64_t) va_arg(ap, int);
00394 
00395                      if (long_val < 0) {
00396                         ulong_val = (ULong64_t) -long_val;
00397                         flags |= IS_NEGATIVE;
00398                      } else {
00399                         ulong_val = (ULong64_t) long_val;
00400                      }
00401                      status = snprintf_convert_ulong(str, left, 10,
00402                                                      "0123456789",
00403                                                      ulong_val, flags,
00404                                                      width, precision);
00405                      str += status;
00406                      left -= status;
00407                      break;
00408 
00409                   case 'x':
00410                      if (flags & IS_LONG_LONG_INT)
00411                         ulong_val = va_arg(ap, ULong64_t);
00412                      else if (flags & IS_LONG_INT)
00413                         ulong_val = (ULong64_t) va_arg(ap, unsigned long int);
00414                      else
00415                         ulong_val = (ULong64_t) va_arg(ap, unsigned int);
00416 
00417                      status = snprintf_convert_ulong(str, left, 16,
00418                                                      "0123456789abcdef",
00419                                                      ulong_val, flags,
00420                                                      width, precision);
00421                      str += status;
00422                      left -= status;
00423                      break;
00424 
00425                   case 'X':
00426                      if (flags & IS_LONG_LONG_INT)
00427                         ulong_val = va_arg(ap, ULong64_t);
00428                      else if (flags & IS_LONG_INT)
00429                         ulong_val = (ULong64_t) va_arg(ap, unsigned long int);
00430                      else
00431                         ulong_val = (ULong64_t) va_arg(ap, unsigned int);
00432 
00433                      status = snprintf_convert_ulong(str, left, 16,
00434                                                      "0123456789ABCDEF",
00435                                                      ulong_val, flags,
00436                                                      width, precision);
00437                      str += status;
00438                      left -= status;
00439                      break;
00440 
00441                   case 'o':
00442                      if (flags & IS_LONG_LONG_INT)
00443                         ulong_val = va_arg(ap, ULong64_t);
00444                      else if (flags & IS_LONG_INT)
00445                         ulong_val = (ULong64_t) va_arg(ap, unsigned long int);
00446                      else
00447                         ulong_val = (ULong64_t) va_arg(ap, unsigned int);
00448 
00449                      status = snprintf_convert_ulong(str, left, 8,
00450                                                      "01234567",
00451                                                      ulong_val, flags,
00452                                                      width, precision);
00453                      str += status;
00454                      left -= status;
00455                      break;
00456 
00457                   case 'u':
00458                      if (flags & IS_LONG_LONG_INT)
00459                         ulong_val = va_arg(ap, ULong64_t);
00460                      else if (flags & IS_LONG_INT)
00461                         ulong_val = (ULong64_t) va_arg(ap, unsigned long int);
00462                      else
00463                         ulong_val = (ULong64_t) va_arg(ap, unsigned int);
00464 
00465                      status = snprintf_convert_ulong(str, left, 10,
00466                                                      "0123456789",
00467                                                      ulong_val, flags,
00468                                                      width, precision);
00469                      str += status;
00470                      left -= status;
00471                      break;
00472 
00473                   case 'p':
00474                      *str++ = '0';
00475                      *str++ = 'x';
00476                      ulong_val = (ULong64_t) va_arg(ap, unsigned long int);
00477 
00478                      status = snprintf_convert_ulong(str, left, 16,
00479                                                      "0123456789abcdef",
00480                                                      ulong_val, flags,
00481                                                      width, precision);
00482                      str += status;
00483                      left -= status;
00484                      break;
00485 
00486                   case 'c':
00487                      if (flags & IS_LONG_LONG_INT)
00488                         ulong_val = va_arg(ap, ULong64_t);
00489                      else if (flags & IS_LONG_INT)
00490                         ulong_val = (ULong64_t) va_arg(ap, unsigned long int);
00491                      else
00492                         ulong_val = (ULong64_t) va_arg(ap, unsigned int);
00493 
00494                      if (width==0) {
00495                         *str++ = (unsigned char) ulong_val;
00496                         --left;
00497                      } else {
00498                         if (width > left)
00499                            width = left;
00500                         i = width - 1;
00501 
00502                         if (flags & MINUS_FLAG) {
00503                            *str = (unsigned char) ulong_val;
00504                            memset(str + 1,
00505                                   (flags & ZERO_PADDING) ? '0' : ' ', i);
00506                         } else {
00507                            memset(str, (flags & ZERO_PADDING) ? '0' : ' ', i);
00508                            *(str+i) = (unsigned char) ulong_val;
00509                         }
00510                         str += width;
00511                         left -= width;
00512                      }
00513                      break;
00514 
00515                   case 's':
00516                      str_val = va_arg(ap, char *);
00517 
00518                      if (str_val == NULL || ((long)str_val) == -1)
00519                         str_val = "(null)";
00520 
00521                      if (!precision_specified)
00522                         precision = strlen(str_val);
00523                      else {
00524                         if (memchr(str_val, 0, precision) != NULL)
00525                            precision = strlen(str_val);
00526                      }
00527                      if (precision > left)
00528                         precision = left;
00529 
00530                      if (width > left)
00531                         width = left;
00532                      if (width < precision)
00533                         width = precision;
00534                      i = width - precision;
00535 
00536                      if (flags & MINUS_FLAG) {
00537                         strncpy(str, str_val, precision);
00538                         memset(str + precision,
00539                                (flags & ZERO_PADDING) ? '0' : ' ', i);
00540                      } else {
00541                         memset(str, (flags & ZERO_PADDING) ? '0' : ' ', i);
00542                         strncpy(str + i, str_val, precision);
00543                      }
00544                      str += width;
00545                      left -= width;
00546                      break;
00547 
00548                   case 'n':
00549                      int_ptr = va_arg(ap, int *);
00550                      *int_ptr = str - orig_str;
00551                      break;
00552 
00553                   case 'f':
00554                   case 'e':
00555                   case 'E':
00556                   case 'g':
00557                   case 'G':
00558                      if (flags & IS_LONG_DOUBLE)
00559                         dbl_val = (double) va_arg(ap, long double);
00560                      else
00561                         dbl_val = va_arg(ap, double);
00562                      status =
00563                          snprintf_convert_float(str, left, dbl_val, flags,
00564                                                 width, precision,
00565                                                 format_char);
00566                      str += status;
00567                      left -= status;
00568                      break;
00569 
00570                   default:
00571                      break;
00572                   }
00573                }
00574             }
00575          }
00576       } else {
00577          if (left > 0) {
00578             *str++ = *format_ptr++;
00579             left--;
00580          } else {
00581             *str = '\0';
00582             return -1;  /* size; */
00583          }
00584       }
00585    }
00586    *str = '\0';
00587 
00588    if (left <= 0)
00589       return -1;
00590 
00591    return size - left - 1;
00592 }
00593 #endif
00594 
00595 int snprintf(char *str, size_t size, const char *format, ...)
00596 {
00597    int ret;
00598    va_list ap;
00599    va_start(ap, format);
00600    ret = vsnprintf(str, size, format, ap);
00601    va_end(ap);
00602 
00603    return ret;
00604 }
00605 
00606 
00607 
00608 #ifdef SNTEST
00609 
00610 #include <stdio.h>
00611 
00612 /* set of small tests for snprintf() */
00613 int main()
00614 {
00615    char holder[100];
00616    int i;
00617 
00618 /*
00619    printf("Suite of test for snprintf:\n");
00620    printf("a_format\n");
00621    printf("printf() format\n");
00622    printf("snprintf() format\n\n");
00623 */
00624 
00625    /* Checking the field widths */
00626    printf("/%%d/, 336\n");
00627    snprintf(holder, sizeof holder, "/%d/\n", 336);
00628    printf("/%d/\n", 336);
00629    printf("%s\n", holder);
00630 
00631    printf("/%%2d/, 336\n");
00632    snprintf(holder, sizeof holder, "/%2d/\n", 336);
00633    printf("/%2d/\n", 336);
00634    printf("%s\n", holder);
00635 
00636    printf("/%%10d/, 336\n");
00637    snprintf(holder, sizeof holder, "/%10d/\n", 336);
00638    printf("/%10d/\n", 336);
00639    printf("%s\n", holder);
00640 
00641    printf("/%%-10d/, 336\n");
00642    snprintf(holder, sizeof holder, "/%-10d/\n", 336);
00643    printf("/%-10d/\n", 336);
00644    printf("%s\n", holder);
00645 
00646    /* floating points */
00647    printf("/%%f/, 1234.56\n");
00648    snprintf(holder, sizeof holder, "/%f/\n", 1234.56);
00649    printf("/%f/\n", 1234.56);
00650    printf("%s\n", holder);
00651 
00652    printf("/%%e/, 1234.56\n");
00653    snprintf(holder, sizeof holder, "/%e/\n", 1234.56);
00654    printf("/%e/\n", 1234.56);
00655    printf("%s\n", holder);
00656 
00657    printf("/%%4.2f/, 1234.56\n");
00658    snprintf(holder, sizeof holder, "/%4.2f/\n", 1234.56);
00659    printf("/%4.2f/\n", 1234.56);
00660    printf("%s\n", holder);
00661 
00662    printf("/%%3.1f/, 1234.56\n");
00663    snprintf(holder, sizeof holder, "/%3.1f/\n", 1234.56);
00664    printf("/%3.1f/\n", 1234.56);
00665    printf("%s\n", holder);
00666 
00667    printf("/%%10.3f/, 1234.56\n");
00668    snprintf(holder, sizeof holder, "/%10.3f/\n", 1234.56);
00669    printf("/%10.3f/\n", 1234.56);
00670    printf("%s\n", holder);
00671 
00672    printf("/%%10.3e/, 1234.56\n");
00673    snprintf(holder, sizeof holder, "/%10.3e/\n", 1234.56);
00674    printf("/%10.3e/\n", 1234.56);
00675    printf("%s\n", holder);
00676 
00677    printf("/%%+4.2f/, 1234.56\n");
00678    snprintf(holder, sizeof holder, "/%+4.2f/\n", 1234.56);
00679    printf("/%+4.2f/\n", 1234.56);
00680    printf("%s\n", holder);
00681 
00682    printf("/%%010.2f/, 1234.56\n");
00683    snprintf(holder, sizeof holder, "/%010.2f/\n", 1234.56);
00684    printf("/%010.2f/\n", 1234.56);
00685    printf("%s\n", holder);
00686 
00687 #define BLURB "Outstanding acting !"
00688    /* strings precisions */
00689    printf("/%%2s/, \"%s\"\n", BLURB);
00690    snprintf(holder, sizeof holder, "/%2s/\n", BLURB);
00691    printf("/%2s/\n", BLURB);
00692    printf("%s\n", holder);
00693 
00694    printf("/%%22s/ %s\n", BLURB);
00695    snprintf(holder, sizeof holder, "/%22s/\n", BLURB);
00696    printf("/%22s/\n", BLURB);
00697    printf("%s\n", holder);
00698 
00699    printf("/%%22.5s/ %s\n", BLURB);
00700    snprintf(holder, sizeof holder, "/%22.5s/\n", BLURB);
00701    printf("/%22.5s/\n", BLURB);
00702    printf("%s\n", holder);
00703 
00704    printf("/%%-22.5s/ %s\n", BLURB);
00705    snprintf(holder, sizeof holder, "/%-22.5s/\n", BLURB);
00706    printf("/%-22.5s/\n", BLURB);
00707    printf("%s\n", holder);
00708 
00709    /* see some flags */
00710    printf("%%x %%X %%#x, 31, 31, 31\n");
00711    snprintf(holder, sizeof holder, "%x %X %#x\n", 31, 31, 31);
00712    printf("%x %X %#x\n", 31, 31, 31);
00713    printf("%s\n", holder);
00714 
00715    printf("**%%d**%% d**%% d**, 42, 42, -42\n");
00716    snprintf(holder, sizeof holder, "**%d**% d**% d**\n", 42, 42, -42);
00717    printf("**%d**% d**% d**\n", 42, 42, -42);
00718    printf("%s\n", holder);
00719 
00720    /* other flags */
00721    printf("/%%g/, 31.4\n");
00722    snprintf(holder, sizeof holder, "/%g/\n", 31.4);
00723    printf("/%g/\n", 31.4);
00724    printf("%s\n", holder);
00725 
00726    printf("/%%.6g/, 31.4\n");
00727    snprintf(holder, sizeof holder, "/%.6g/\n", 31.4);
00728    printf("/%.6g/\n", 31.4);
00729    printf("%s\n", holder);
00730 
00731    printf("/%%.1G/, 31.4\n");
00732    snprintf(holder, sizeof holder, "/%.1G/\n", 31.4);
00733    printf("/%.1G/\n", 31.4);
00734    printf("%s\n", holder);
00735 
00736    printf("abc%%n\n");
00737    printf("abc%n", &i);
00738    printf("%d\n", i);
00739    snprintf(holder, sizeof holder, "abc%n", &i);
00740    printf("%s", holder);
00741    printf("%d\n\n", i);
00742 
00743    printf("%%*.*s --> 10.10\n");
00744    snprintf(holder, sizeof holder, "%*.*s\n", 10, 10, BLURB);
00745    printf("%*.*s\n", 10, 10, BLURB);
00746    printf("%s\n", holder);
00747 
00748    printf("%%%%%%%%\n");
00749    snprintf(holder, sizeof holder, "%%%%\n");
00750    printf("%%%%\n");
00751    printf("%s\n", holder);
00752 
00753 #define BIG "Hello this is a too big string for the buffer"
00754    /* printf("A buffer of size 10, trying to put this:\n");*/
00755    printf("<%%s>, %s\n", BIG);
00756    i = snprintf(holder, 10, "%s", BIG);
00757    printf("<%s>\n", BIG);
00758    printf("<%s> i = %d\n", holder, i);
00759    i = snprintf(holder, sizeof holder, "%s", BIG);
00760    printf("<%s> i = %d\n", holder, i);
00761 
00762    return 0;
00763 }
00764 #endif
00765 
00766 #endif /* defined(NEED_SNPRINTF) || defined(SNTEST) */

Generated on Tue Jul 5 14:11:25 2011 for ROOT_528-00b_version by  doxygen 1.5.1