"Fossies" - the Fresh Open Source Software Archive

Member "nss_ldap-265/snprintf.c" (6 Nov 2009, 7118 Bytes) of package /linux/privat/old/nss_ldap-265.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 static char rcsId[] = "$Id: snprintf.c,v 2.9 2001/08/17 05:30:14 lukeh Exp $";
    2 
    3 #include "config.h"
    4 
    5 #ifndef HAVE_SNPRINTF
    6 
    7 /**************************************************************
    8  * Original:
    9  * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
   10  * A bombproof version of doprnt (dopr) included.
   11  * Sigh. This sort of thing is always nasty do deal with. Note that
   12  * the version here does not include floating point...
   13  *
   14  * snprintf() is used instead of sprintf() as it does limit checks
   15  * for string length. This covers a nasty loophole.
   16  *
   17  * The other functions are there to prevent NULL pointers from
   18  * causing nast effects.
   19  **************************************************************/
   20 
   21 static void dopr ();
   22 static char *end;
   23 
   24 #include "snprintf.h"
   25 #include <string.h>
   26 
   27 #ifdef HAVE_CTYPE_H
   28 #include <ctype.h>
   29 #endif
   30 
   31 /* varargs declarations: */
   32 
   33 #if defined(HAVE_STDARG_H)
   34 #include <stdarg.h>
   35 #define HAVE_STDARGS        /* let's hope that works everywhere (mj) */
   36 #define VA_LOCAL_DECL va_list ap;
   37 #define VA_START(f) va_start(ap, f)
   38 #define VA_SHIFT(v,t) ;     /* no-op for ANSI */
   39 #define VA_END va_end(ap)
   40 #else
   41 #if defined(HAVE_VARARGS_H)
   42 #include <varargs.h>
   43 #undef HAVE_STDARGS
   44 #define VA_LOCAL_DECL va_list ap;
   45 #define VA_START(f) va_start(ap)    /* f is ignored! */
   46 #define VA_SHIFT(v,t) v = va_arg(ap,t)
   47 #define VA_END va_end(ap)
   48 #else
   49 XX **NO VARARGS ** XX
   50 #endif
   51 #endif
   52 #ifdef HAVE_STDARGS
   53 int snprintf (char *str, size_t count, const char *fmt, ...);
   54 int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
   55 #else
   56 int snprintf ();
   57 int vsnprintf ();
   58 #endif
   59 
   60 int
   61 vsnprintf (str, count, fmt, args)
   62      char *str;
   63      size_t count;
   64      const char *fmt;
   65      va_list args;
   66 {
   67   str[0] = 0;
   68   end = str + count - 1;
   69   dopr (str, fmt, args);
   70   if (count > 0)
   71     {
   72       end[0] = 0;
   73     }
   74   return (strlen (str));
   75 }
   76 
   77 /* VARARGS3 */
   78 #ifdef HAVE_STDARGS
   79 int
   80 snprintf (char *str, size_t count, const char *fmt, ...)
   81 #else
   82 int
   83 snprintf (va_alist)
   84      va_dcl
   85 #endif
   86 {
   87 #ifndef HAVE_STDARGS
   88   char *str;
   89   size_t count;
   90   char *fmt;
   91 #endif
   92   VA_LOCAL_DECL VA_START (fmt);
   93   VA_SHIFT (str, char *);
   94   VA_SHIFT (count, size_t);
   95   VA_SHIFT (fmt, char *);
   96   (void) vsnprintf (str, count, fmt, ap);
   97   VA_END;
   98   return (strlen (str));
   99 }
  100 
  101 /*
  102  * dopr(): poor man's version of doprintf
  103  */
  104 
  105 static void fmtstr (char *value, int ljust, int len, int zpad);
  106 static void fmtnum (long value, int base, int dosign,
  107             int ljust, int len, int zpad);
  108 static void dostr (char *);
  109 static char *output;
  110 static void dopr_outch (int c);
  111 
  112 static void
  113 dopr (buffer, format, args)
  114      char *buffer;
  115      char *format;
  116      va_list args;
  117 {
  118   int ch;
  119   long value;
  120   int longflag = 0;
  121   char *strvalue;
  122   int ljust;
  123   int len;
  124   int zpad;
  125 
  126   output = buffer;
  127   while ((ch = *format++))
  128     {
  129       switch (ch)
  130     {
  131     case '%':
  132       ljust = len = zpad = 0;
  133     nextch:
  134       ch = *format++;
  135       switch (ch)
  136         {
  137         case 0:
  138           dostr ("**end of format**");
  139           return;
  140         case '-':
  141           ljust = 1;
  142           goto nextch;
  143         case '0':       /* set zero padding if len not set */
  144           if (len == 0)
  145         zpad = '0';
  146         case '1':
  147         case '2':
  148         case '3':
  149         case '4':
  150         case '5':
  151         case '6':
  152         case '7':
  153         case '8':
  154         case '9':
  155           len = len * 10 + ch - '0';
  156           goto nextch;
  157         case 'l':
  158           longflag = 1;
  159           goto nextch;
  160         case 'u':
  161         case 'U':
  162           /*fmtnum(value,base,dosign,ljust,len,zpad) */
  163           if (longflag)
  164         {
  165           value = va_arg (args, long);
  166         }
  167           else
  168         {
  169           value = va_arg (args, int);
  170         }
  171           fmtnum (value, 10, 0, ljust, len, zpad);
  172           break;
  173         case 'o':
  174         case 'O':
  175           /*fmtnum(value,base,dosign,ljust,len,zpad) */
  176           if (longflag)
  177         {
  178           value = va_arg (args, long);
  179         }
  180           else
  181         {
  182           value = va_arg (args, int);
  183         }
  184           fmtnum (value, 8, 0, ljust, len, zpad);
  185           break;
  186         case 'd':
  187         case 'D':
  188           if (longflag)
  189         {
  190           value = va_arg (args, long);
  191         }
  192           else
  193         {
  194           value = va_arg (args, int);
  195         }
  196           fmtnum (value, 10, 1, ljust, len, zpad);
  197           break;
  198         case 'x':
  199           if (longflag)
  200         {
  201           value = va_arg (args, long);
  202         }
  203           else
  204         {
  205           value = va_arg (args, int);
  206         }
  207           fmtnum (value, 16, 0, ljust, len, zpad);
  208           break;
  209         case 'X':
  210           if (longflag)
  211         {
  212           value = va_arg (args, long);
  213         }
  214           else
  215         {
  216           value = va_arg (args, int);
  217         }
  218           fmtnum (value, -16, 0, ljust, len, zpad);
  219           break;
  220         case 's':
  221           strvalue = va_arg (args, char *);
  222           fmtstr (strvalue, ljust, len, zpad);
  223           break;
  224         case 'c':
  225           ch = va_arg (args, int);
  226           dopr_outch (ch);
  227           break;
  228         case '%':
  229           dopr_outch (ch);
  230           continue;
  231         default:
  232           dostr ("???????");
  233         }
  234       longflag = 0;
  235       break;
  236     default:
  237       dopr_outch (ch);
  238       break;
  239     }
  240     }
  241   *output = 0;
  242 }
  243 
  244 static void
  245 fmtstr (value, ljust, len, zpad)
  246      char *value;
  247      int ljust, len, zpad;
  248 {
  249   int padlen, strlen;       /* amount to pad */
  250 
  251   if (value == 0)
  252     {
  253       value = "<NULL>";
  254     }
  255   for (strlen = 0; value[strlen]; ++strlen);    /* strlen */
  256   padlen = len - strlen;
  257   if (padlen < 0)
  258     padlen = 0;
  259   if (ljust)
  260     padlen = -padlen;
  261   while (padlen > 0)
  262     {
  263       dopr_outch (' ');
  264       --padlen;
  265     }
  266   dostr (value);
  267   while (padlen < 0)
  268     {
  269       dopr_outch (' ');
  270       ++padlen;
  271     }
  272 }
  273 
  274 static void
  275 fmtnum (value, base, dosign, ljust, len, zpad)
  276      long value;
  277      int base, dosign, ljust, len, zpad;
  278 {
  279   int signvalue = 0;
  280   unsigned long uvalue;
  281   char convert[20];
  282   int place = 0;
  283   int padlen = 0;       /* amount to pad */
  284   int caps = 0;
  285 
  286   /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
  287      value, base, dosign, ljust, len, zpad )); */
  288   uvalue = value;
  289   if (dosign)
  290     {
  291       if (value < 0)
  292     {
  293       signvalue = '-';
  294       uvalue = -value;
  295     }
  296     }
  297   if (base < 0)
  298     {
  299       caps = 1;
  300       base = -base;
  301     }
  302   do
  303     {
  304       convert[place++] =
  305     (caps ? "0123456789ABCDEF" : "0123456789abcdef")
  306     [uvalue % (unsigned) base];
  307       uvalue = (uvalue / (unsigned) base);
  308     }
  309   while (uvalue);
  310   convert[place] = 0;
  311   padlen = len - place;
  312   if (padlen < 0)
  313     padlen = 0;
  314   if (ljust)
  315     padlen = -padlen;
  316   /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
  317      convert,place,signvalue,padlen)); */
  318   if (zpad && padlen > 0)
  319     {
  320       if (signvalue)
  321     {
  322       dopr_outch (signvalue);
  323       --padlen;
  324       signvalue = 0;
  325     }
  326       while (padlen > 0)
  327     {
  328       dopr_outch (zpad);
  329       --padlen;
  330     }
  331     }
  332   while (padlen > 0)
  333     {
  334       dopr_outch (' ');
  335       --padlen;
  336     }
  337   if (signvalue)
  338     dopr_outch (signvalue);
  339   while (place > 0)
  340     dopr_outch (convert[--place]);
  341   while (padlen < 0)
  342     {
  343       dopr_outch (' ');
  344       ++padlen;
  345     }
  346 }
  347 
  348 static void
  349 dostr (str)
  350      char *str;
  351 {
  352   while (*str)
  353     dopr_outch (*str++);
  354 }
  355 
  356 static void
  357 dopr_outch (c)
  358      int c;
  359 {
  360   if (iscntrl (c) && c != '\n' && c != '\t')
  361     {
  362       c = '@' + (c & 0x1F);
  363       if (end == 0 || output < end)
  364     {
  365       *output++ = '^';
  366     }
  367     }
  368   if (end == 0 || output < end)
  369     {
  370       *output++ = c;
  371     }
  372 }
  373 
  374 #endif /* !HAVE_SNPRINTF */