openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

snprintf.c (5993B)


      1 /* $Id: //depot/blt/lib/snprintf.c#2 $
      2 **
      3 ** Copyright 1998 Brian J. Swetland
      4 ** All rights reserved.
      5 **
      6 ** Redistribution and use in source and binary forms, with or without
      7 ** modification, are permitted provided that the following conditions
      8 ** are met:
      9 ** 1. Redistributions of source code must retain the above copyright
     10 **    notice, this list of conditions, and the following disclaimer.
     11 ** 2. Redistributions in binary form must reproduce the above copyright
     12 **    notice, this list of conditions, and the following disclaimer in the
     13 **    documentation and/or other materials provided with the distribution.
     14 ** 3. The name of the author may not be used to endorse or promote products
     15 **    derived from this software without specific prior written permission.
     16 **
     17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28 
     29 /* Copyright 1997, Brian J. Swetland <swetland@neog.com>                 
     30 ** Free for non-commercial use.  Share and enjoy                         
     31 **
     32 ** Minimal snprintf() function.
     33 ** %s - string     %d - signed int    %x - 32bit hex number (0 padded)
     34 ** %c - character  %u - unsigned int  %X -  8bit hex number (0 padded) 
     35 */
     36 
     37 #include <stdarg.h>
     38 
     39 static char hexmap[] = {
     40     '0', '1', '2', '3', '4', '5', '6', '7',
     41     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 
     42 };
     43 
     44 void va_snprintf(char *b, int l, char *fmt, va_list pvar) 
     45 {
     46     int n,i;
     47     unsigned u;
     48     unsigned long long ull;
     49     char *t,d[10], mod_l, mod_ll;
     50 
     51     if(!fmt || !b || (l < 1)) return;
     52 
     53     mod_l = mod_ll = 0;    
     54     while(l && *fmt) {
     55         if(*fmt == '%'){
     56             if(!(--l)) break;
     57         again:
     58             fmt++;
     59             
     60             switch(*fmt){
     61             case 'l': /* long modifier */
     62                 if (!mod_l)
     63                     mod_l = 1;
     64                 else if (!mod_ll)
     65                 {
     66                     mod_l = 0;
     67                     mod_ll = 1;
     68                 }
     69                 goto again;
     70 
     71             case 's': /* string */
     72                 t = va_arg(pvar,char *);
     73                 while(l && *t) *b++ = *t++, l--;                
     74                 break;
     75                 
     76             case 'c': /* single character */
     77                 *b++ = va_arg(pvar,char);
     78                 l--;                
     79                 break;
     80 
     81 			case 'S': /* uint32 as a short ... */
     82 				if(l < 4) { l = 0; break; }
     83 				u = va_arg(pvar,unsigned int);
     84 				for(i=3;i>=0;i--){
     85 					b[i] = hexmap[u & 0x0F];
     86 					u >>= 4;
     87 				}
     88 				b+=4;
     89 				l-=4;
     90 				break;            
     91    
     92 			case 'x':
     93 			case 'p':
     94                 if (!mod_ll) { /* 8 digit, unsigned 32-bit hex integer */
     95                     if(l < 8) { l = 0; break; }
     96                     u = va_arg(pvar,unsigned int);
     97                     for(i=7;i>=0;i--){
     98                         b[i] = hexmap[u & 0x0F];
     99                         u >>= 4;
    100                     }
    101 					b+=8;
    102 					l-=8;
    103                 }
    104                 else if (mod_ll) { /* 16 digit, unsigned 64-bit hex integer */
    105                     if (l < 16) { l = 0; break; }
    106                     ull = va_arg (pvar, unsigned long long);
    107                     for (i = 15; i >= 0; i--) {
    108                         b[i] = hexmap[ull & 0x0f];
    109                         ull >>= 4;
    110                     }
    111                     b += 16;
    112                     l -= 16;
    113                 }
    114                 mod_l = mod_ll = 0;
    115                 break;
    116 
    117             case 'd': /* signed integer */
    118                 n = va_arg(pvar,int);
    119                 if(n < 0) {
    120                     u = -n;
    121                     *b++ = '-';
    122                     if(!(--l)) break;                    
    123                 } else {
    124                     u = n;
    125                 }
    126                 goto u2;                
    127 
    128             case 'u': /* unsigned integer */
    129                 u = va_arg(pvar,unsigned int);                
    130               u2:
    131                 i = 9;
    132                 do {
    133                     d[i] = (u % 10) + '0';
    134                     u /= 10;
    135                     i--;
    136                 } while(u && i >= 0);
    137                 while(++i < 10){
    138                     *b++ = d[i];
    139                     if(!(--l)) break;                    
    140                 }
    141                 break;
    142                 
    143             case 'U':
    144                 u = va_arg(pvar,unsigned int);
    145                 i = 9;
    146                 d[8] = d[7] = d[6] = ' ';
    147                 do {
    148                     d[i] = (u % 10) + '0';
    149                     u /= 10;
    150                     i--;
    151                 } while(u && i >= 0);
    152                 i = 5;
    153                 while(++i < 10){
    154                     *b++ = d[i];
    155                     if(!(--l)) break;
    156                 }
    157                 break;
    158                 
    159             case 'X': /* 2 digit, unsigned 8bit hex int */
    160                 if(l < 2) { l = 0; break; }
    161                 n = va_arg(pvar,int);
    162                 *b++ = hexmap[(n & 0xF0) >> 4];
    163                 *b++ = hexmap[n & 0x0F];
    164                 l-=2;                
    165                 break;
    166             default:
    167                 *b++ = *fmt;                
    168             }
    169         } else {
    170             *b++ = *fmt;
    171             l--;            
    172         }
    173         fmt++;            
    174     }
    175     *b = 0;
    176 }
    177 
    178 void snprintf(char *str, int len, char *fmt, ...)
    179 {
    180     va_list pvar;    
    181     va_start(pvar,fmt);
    182     va_snprintf(str,len,fmt,pvar);
    183     va_end(pvar);    
    184 }
    185 
    186