Prex Home / Browse Source - Prex Version: 0.9.0

root/sys/lib/vsprintf.c

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

DEFINITIONS

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

   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 <kernel.h>
  35 
  36 #define isdigit(c)  ((u_int)((c) - '0') < 10)
  37 
  38 static u_long
  39 divide(long *n, int base)
  40 {
  41         u_long res;
  42 
  43         res = ((u_long)*n) % base;
  44         *n = (long)(((u_long)*n) / base);
  45         return res;
  46 }
  47 
  48 static int
  49 atoi(const char **s)
  50 {
  51         int i = 0;
  52         while (isdigit((int)**s))
  53                 i = i * 10 + *((*s)++) - '0';
  54         return i;
  55 }
  56 
  57 /*
  58  * Print formatted output - scaled down version
  59  *
  60  * Identifiers:
  61  *  %d - Decimal signed int
  62  *  %x - Hex integer
  63  *  %u - Unsigned integer
  64  *  %c - Character
  65  *  %s - String
  66  *
  67  * Flags:
  68  *   0 - Zero pad
  69  */
  70 int
  71 vsprintf(char *buf, const char *fmt, va_list args)
  72 {
  73         char *p, *str;
  74         const char *digits = "0123456789abcdef";
  75         char pad, tmp[16];
  76         int width, base, sign, i;
  77         long num;
  78 
  79         for (p = buf; *fmt; fmt++) {
  80                 if (*fmt != '%') {
  81                         *p++ = *fmt;
  82                         continue;
  83                 }
  84                 /* get flags */
  85                 ++fmt;
  86                 pad = ' ';
  87                 if (*fmt == '0') {
  88                         pad = '0';
  89                         fmt++;
  90                 }
  91                 /* get width */
  92                 width = -1;
  93                 if (isdigit(*fmt)) {
  94                         width = atoi(&fmt);
  95                 }
  96                 /* ignore long */
  97                 if (*fmt == 'l')
  98                         fmt++;
  99                 base = 10;
 100                 sign = 0;
 101                 switch (*fmt) {
 102                 case 'c':
 103                         *p++ = (char)va_arg(args, int);
 104                         continue;
 105                 case 's':
 106                         str = va_arg(args, char *);
 107                         if (str == NULL)
 108                                 str = "<NULL>";
 109                         for (; *str && width != 0; str++, width--) {
 110                                 *p++ = *str;
 111                         }
 112                         while (width-- > 0)
 113                                 *p++ = pad;
 114                         continue;
 115                 case 'X':
 116                 case 'x':
 117                         base = 16;
 118                         break;
 119                 case 'd':
 120                         sign = 1;
 121                         break;
 122                 case 'u':
 123                         break;
 124                 default:
 125                         continue;
 126                 }
 127                 num = va_arg(args, long);
 128                 if (sign && num < 0) {
 129                         num = -num;
 130                         *p++ = '-';
 131                         width--;
 132                 }
 133                 i = 0;
 134                 if (num == 0)
 135                         tmp[i++] = '0';
 136                 else
 137                         while (num != 0)
 138                                 tmp[i++] = digits[divide(&num, base)];
 139                 width -= i;
 140                 while (width-- > 0)
 141                         *p++ = pad;
 142                 while (i-- > 0)
 143                         *p++ = tmp[i];
 144         }
 145         *p = '\0';
 146         return 0;
 147 }

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