Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/lib/libsa/vsprintf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. divide
  2. atoi
  3. vsprintf
  4. sprintf

   1 /*-
   2  * Copyright (c) 2005, Kohsuke Ohtani
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the author nor the names of any co-contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 /*
  31  * vsprintf.c - Format and output data to buffer
  32  */
  33 
  34 #include <limits.h>
  35 #include <stdarg.h>
  36 #include <string.h>
  37 #include <stdio.h>
  38 
  39 #define isdigit(c)  ((unsigned)((c) - '0') < 10)
  40 
  41 static int
  42 divide(long *n, int base)
  43 {
  44         int res;
  45 
  46         /*
  47          * Note: Optimized for ARM processor which does not support
  48          * divide instructions.
  49          *
  50          * res = ((unsigned long)*n) % (unsigned int)base;
  51          * *n = ((unsigned long)*n) / (unsigned int)base;
  52          */
  53 
  54         if (base == 10) {
  55                 res = (int)(((unsigned long)*n) % 10U);
  56                 *n = (long)(((unsigned long)*n) / 10U);
  57         } else {
  58                 res = (int)(((unsigned long)*n) % 16U);
  59                 *n = (long)(((unsigned long)*n) / 16U);
  60         }
  61         return res;
  62 }
  63 
  64 static int
  65 atoi(const char **s)
  66 {
  67         int i = 0;
  68         while (isdigit((int)**s))
  69                 i = i * 10 + *((*s)++) - '0';
  70         return i;
  71 }
  72 
  73 /*
  74  * Print formatted output - scaled down version
  75  *
  76  * Identifiers:
  77  *  %d - Decimal signed int
  78  *  %x - Hex integer
  79  *  %u - Unsigned integer
  80  *  %c - Character
  81  *  %s - String
  82  *
  83  * Flags:
  84  *   0 - Zero pad
  85  */
  86 int
  87 vsprintf(char *buf, const char *fmt, va_list args)
  88 {
  89         char *p, *str;
  90         const char *digits = "0123456789abcdef";
  91         char pad, tmp[16];
  92         int width, base, sign, i, size;
  93         long num;
  94 
  95         size = 0;
  96         for (p = buf; *fmt && (size < LINE_MAX); fmt++, size++) {
  97                 if (*fmt != '%') {
  98                         *p++ = *fmt;
  99                         continue;
 100                 }
 101                 /* get flags */
 102                 ++fmt;
 103                 pad = ' ';
 104                 if (*fmt == '0') {
 105                         pad = '0';
 106                         fmt++;
 107                 }
 108                 if (*fmt == 'l')
 109                         fmt++;
 110                 /* get width */
 111                 width = -1;
 112                 if (isdigit((int)*fmt)) {
 113                         width = atoi(&fmt);
 114                 }
 115                 base = 10;
 116                 sign = 0;
 117                 switch (*fmt) {
 118                 case 'c':
 119                         *p++ = (unsigned char)va_arg(args, int);
 120                         continue;
 121                 case 's':
 122                         str = va_arg(args, char *);
 123                         if (str == NULL)
 124                                 str = "<NULL>";
 125                         for (; *str; str++) {
 126                                 *p++ = *str;
 127                                 if (size++ >= LINE_MAX)
 128                                         break;
 129                         }
 130                         continue;
 131                 case 'X':
 132                 case 'x':
 133                         base = 16;
 134                         break;
 135                 case 'd':
 136                         sign = 1;
 137                         break;
 138                 case 'u':
 139                         break;
 140                 default:
 141                         continue;
 142                 }
 143                 num = va_arg(args, long);
 144                 if (sign && num < 0) {
 145                         num = -num;
 146                         *p++ = '-';
 147                         width--;
 148                 }
 149                 i = 0;
 150                 if (num == 0)
 151                         tmp[i++] = '0';
 152                 else
 153                         while (num != 0)
 154                                 tmp[i++] = digits[divide(&num, base)];
 155                 width -= i;
 156                 while (width-- > 0)
 157                         *p++ = pad;
 158                 while (i-- > 0)
 159                         *p++ = tmp[i];
 160         }
 161         *p = '\0';
 162         return (p - buf);
 163 }
 164 
 165 int
 166 sprintf(char *buf, const char *fmt, ...)
 167 {
 168         va_list args;
 169         int i;
 170 
 171         va_start(args, fmt);
 172         i = vsprintf(buf, fmt, args);
 173         va_end(args);
 174         return i;
 175 }

/* [<][>][^][v][top][bottom][index][help] */