"Fossies" - the Fresh Open Source Software Archive

Member "leafnode-1.12.0/snprintf.c" (28 Dec 2021, 5343 Bytes) of package /linux/misc/leafnode-1.12.0.tar.xz:


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. For more information about "snprintf.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.11.12_vs_1.12.0.

    1 /*
    2  * poor man's snprintf() - for systems which don't have their own
    3  *
    4  * This version of snprintf() currently supports only %s, %c, %d, %u,
    5  * %ld, %lu, %li, %i. It supports the 0, + and width modifiers only for decimal
    6  * output (%[l]{d|u|i}).
    7  *
    8  * Copyright (c) Cornelius Krasel 2000.
    9  * Modified by Matthias Andree <matthias.andree@gmx.de>.
   10  * Modifications (C)opyright 2002 - 2004.
   11  *
   12  * Permission is hereby granted, free of charge, to any person obtaining a copy
   13  * of this software and associated documentation files (the "Software"), to
   14  * deal in the Software without restriction, including without limitation the
   15  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   16  * sell copies of the Software, and to permit persons to whom the Software is
   17  * furnished to do so, subject to the following conditions:
   18  *
   19  * The above copyright notice and this permission notice shall be included in
   20  * all copies or substantial portions of the Software.
   21  *
   22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
   25  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   28  * IN THE SOFTWARE.
   29  */
   30 
   31 #include "leafnode.h"
   32 
   33 #ifndef HAVE_WORKING_SNPRINTF
   34 
   35 #include <stdarg.h>
   36 #include <stdlib.h>
   37 #include <string.h>
   38 #include <stdio.h>
   39 
   40 /** format unsigned value u into p */
   41 static void fmtu(char *p, unsigned long u) {
   42     unsigned int len = 0;
   43     unsigned long i = u, ni;
   44     unsigned char b[22];
   45     do {
   46     ni = i / 10;
   47     b[len++] = i - 10*ni;
   48     i = ni;
   49     } while (i);
   50 
   51     while (len) {
   52     *p++  = "0123456789"[b[--len]];
   53     }
   54     *p = '\0';
   55 }
   56 
   57 /** format signed value s into p, prefix asign if its nonzero and the
   58  * value is positive. asign is usually '+' or ' '. */
   59 static inline void fmts(char *p, long s, char asign) {
   60     if (s < 0) {
   61     *p++ = '-';
   62     fmtu(p, -s);
   63     } else {
   64     if (asign)
   65         *p++ = asign;
   66     fmtu(p, s);
   67     }
   68 }
   69 
   70 int
   71 ln_vsnprintf(char *str, size_t n, const char *format, va_list ap)
   72 {
   73     const char *p;
   74     char *q;
   75     int flag = 0;
   76     size_t width = 0;
   77     char fill = ' ';
   78     int lflag = 0;      /* checking for longs */
   79     int asign = 0;      /* always show sign */
   80     size_t i = 1;       /* because the terminating \0 also counts */
   81     size_t len, olen;
   82     char buf[30];       /* buffer for converting longs and ints */
   83 
   84     char *s;
   85     char c;
   86 
   87     p = format;
   88     q = str;
   89     while (p && *p) {
   90     if ((*p == '%') && !flag) {
   91         /* swallow the %, switch to % mode and initialize */
   92         lflag = 0;
   93         flag = 1;
   94         asign = 0; /* can be 0, '+' or later ' ' (' ' is unimplemented) */
   95         fill = ' ';
   96         width = 0;
   97         p++;
   98     } else if (flag) {
   99         /* % mode */
  100         switch (*p) {
  101         case 's': case 'm': {
  102             if (*p == 's')
  103             s = va_arg(ap, char *);
  104             else
  105             s = strerror(errno);
  106             olen = len = strlen(s);
  107             if (len > (n - i))
  108             len = n - i;
  109             *q = '\0';
  110             strncat(q, s, len);
  111             p++;
  112             q += len;
  113             i += olen;
  114             flag = 0;
  115             break;
  116         }
  117         case 'u':{
  118             unsigned long u;
  119             if (lflag) {
  120             u = va_arg(ap, unsigned long);
  121             } else {
  122             u = (unsigned long)va_arg(ap, unsigned int);
  123             }
  124             fmtu(buf, u);
  125             goto printdec;
  126         }
  127         case 'd': case 'i': {
  128             long l;
  129             if (lflag) {
  130             l = va_arg(ap, long);
  131             } else {
  132             l = (long)va_arg(ap, int);
  133             }
  134             fmts(buf, l, asign);
  135 printdec:
  136             olen = len = strlen(buf);
  137             if (width) {
  138             int off = !!asign;
  139             if (len < width) {
  140                 switch (fill) {
  141                 case ' ':
  142                     memmove(buf + width - len, buf, len + 1);
  143                     memset(buf, fill, width - len);
  144                     break;
  145                 case '0':
  146                     memmove(buf + off + width - len, buf + off, len + 1 - off);
  147                     memset(buf + off, fill, width - len);
  148                     break;
  149                 default:
  150                     abort();
  151                 }
  152                }
  153                olen = len = strlen(buf);
  154             }
  155             if (len > (n - i))
  156             len = n - i;
  157             *q = '\0';
  158             strncat(q, buf, len);
  159             q += len;
  160             i += olen;
  161             flag = 0;
  162             p++;
  163             break;
  164         }
  165         case 'l':{
  166             /* next argument will be long */
  167             lflag = 1;
  168             p++;
  169             break;
  170         }
  171         case 'c':{
  172             c = va_arg(ap, int);
  173             flag = 0;
  174             if (i < n)
  175             *q++ = c;
  176             i++;
  177             p++;
  178             break;
  179         }
  180         case '%':{
  181             flag = 0;
  182             if (i < n)
  183             *q++ = *p++;
  184             i++;
  185             break;
  186         }
  187         case '0':
  188              if (fill == ' ' && width == 0)
  189              fill='0';
  190              else
  191              width *= 10;
  192              p++;
  193              break;
  194         case '1': case '2': case '3': case '4': case '5':
  195         case '6': case '7': case '8': case '9':
  196              width = width * 10 + *p - '0';
  197              p++;
  198              break;
  199         case '+':
  200              asign = '+';
  201              p++;
  202              break;
  203         default:
  204              abort();
  205              break;
  206         }
  207     } else {
  208         if (i < n) {
  209         *q++ = *p;
  210         }
  211         p++;
  212         i++;
  213     }
  214     }
  215     va_end(ap);
  216     *q = '\0';
  217     return (i - 1);
  218 }
  219 
  220 int
  221 ln_snprintf(char *str, size_t n, const char *format, ...)
  222 {
  223     int r;
  224     va_list ap;
  225 
  226     va_start(ap, format);
  227     r = ln_vsnprintf(str, n, format, ap);
  228     va_end(ap);
  229     return r;
  230 }
  231 
  232 #endif