SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

001 /* Copyright (C) 2004  David Decotigny (with INSA Rennes for vsnprintf)
002    Copyright (C) 2003  The KOS Team
003    Copyright (C) 1999  Free Software Foundation
004 
005    This program is free software; you can redistribute it and/or
006    modify it under the terms of the GNU General Public License
007    as published by the Free Software Foundation; either version 2
008    of the License, or (at your option) any later version.
009    
010    This program is distributed in the hope that it will be useful,
011    but WITHOUT ANY WARRANTY; without even the implied warranty of
012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013    GNU General Public License for more details.
014    
015    You should have received a copy of the GNU General Public License
016    along with this program; if not, write to the Free Software
017    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
018    USA. 
019 */
020 #include <string.h>
021 
022 #include "stdarg.h"
023 
024 
025 /* I (d2) borrowed and rewrote this for Nachos/INSA Rennes. Thanks to
026    them for having kindly allowed me to do so. */
027 int vsnprintf(char *buff, size_t len, const char * format, va_list ap)
028 {
029   int i, result;
030   int fmt_modifiers = 0;
031   int prefix_long   = 0;
032   int prefix_long_long = 0;
033  
034   if (!buff || !format || (len < 0))
035     return -1;
036   
037 #define PUTCHAR(thechar) \
038   do { \
039     if (result < len-1) \
040       *buff++ = (thechar);  \
041     result++; \
042   } while (0)
043   
044   result = 0;
045   for(i=0 ; format[i] != '\0' ; i++)
046     {
047       if (!fmt_modifiers && (format[i] != '%'))
048         {
049           PUTCHAR(format[i]);
050           continue;
051         }
052         
053       switch (format[i])
054         {
055         case '%':
056           if (fmt_modifiers)
057             {
058               PUTCHAR('%');
059               fmt_modifiers = 0;
060               break;
061             }
062           
063           fmt_modifiers    = 1;
064           prefix_long      = 0;
065           prefix_long_long = 0;
066           break;
067           
068         case 'l':
069           if (prefix_long)
070             prefix_long_long = 1;
071           else
072             prefix_long = 1;
073           break;
074           
075         case 'u':
076           {
077             if (! prefix_long_long)
078               {
079                 unsigned int integer = va_arg(ap,unsigned int);
080                 int cpt2 = 0;
081                 char buff_int[16];
082                 
083                 do {
084                   int m10 = integer%10;
085                   buff_int[cpt2++]=(char)('0'+ m10);
086                   integer=integer/10;
087                 } while(integer!=0);
088             
089                 for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--)
090                   PUTCHAR(buff_int[cpt2]);
091               }
092             else
093               {
094                 unsigned long long int integer
095                   = va_arg(ap,unsigned long long int);
096                 int cpt2 = 0;
097                 char buff_int[32];
098                 
099                 do {
100                   int m10 = integer%10;
101                   buff_int[cpt2++]=(char)('0'+ m10);
102                   integer=integer/10;
103                 } while(integer!=0);
104             
105                 for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--)
106                   PUTCHAR(buff_int[cpt2]);
107               }
108           }
109           fmt_modifiers = 0;
110           break;
111 
112         case 'i':
113         case 'd':
114           {
115             if (! prefix_long_long)
116               {
117                 int integer = va_arg(ap,int);
118                 int cpt2 = 0;
119                 char buff_int[16];
120                 
121                 if (integer<0)
122                   PUTCHAR('-');
123                 /* Ne fait pas integer = -integer ici parce que INT_MIN
124                    n'a pas d'equivalent positif (int = [-2^31, 2^31-1]) */
125                 
126                 do {
127                   int m10 = integer%10;
128                   m10 = (m10 < 0)? -m10:m10;
129                   buff_int[cpt2++]=(char)('0'+ m10);
130                   integer=integer/10;
131                 } while(integer!=0);
132             
133                 for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--)
134                   PUTCHAR(buff_int[cpt2]);
135               }
136             else
137               {
138                 long long int integer = va_arg(ap,long long int);
139                 int cpt2 = 0;
140                 char buff_int[32];
141                 
142                 if (integer<0)
143                   PUTCHAR('-');
144                 /* Ne fait pas integer = -integer ici parce que INT_MIN
145                    n'a pas d'equivalent positif (int = [-2^63, 2^63-1]) */
146                 
147                 do {
148                   int m10 = integer%10;
149                   m10 = (m10 < 0)? -m10:m10;
150                   buff_int[cpt2++]=(char)('0'+ m10);
151                   integer=integer/10;
152                 } while(integer!=0);
153             
154                 for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--)
155                   PUTCHAR(buff_int[cpt2]);
156               }
157           }
158           fmt_modifiers = 0;
159           break;
160           
161         case 'c':
162           {
163             int value = va_arg(ap,int);
164             PUTCHAR((char)value);
165             fmt_modifiers = 0;
166             break;
167           }
168           
169         case 's':
170           {
171             char *string = va_arg(ap,char *);
172             if (! string)
173               string = "(null)";
174             for( ; *string != '\0' ; string++)
175               PUTCHAR(*string);
176             fmt_modifiers = 0;
177             break;
178           }
179           
180         case 'p':
181           PUTCHAR('0');
182           PUTCHAR('x');
183         case 'x':
184           {
185             unsigned long long int hexa;
186             unsigned long long int nb;
187             int i, had_nonzero = 0;
188             
189             if (prefix_long_long)
190               hexa = va_arg(ap,unsigned long long int);
191             else
192               hexa = va_arg(ap,unsigned int);
193             
194             for(i=0 ; i < 16 ; i++)
195               {
196                 nb = (unsigned long long int)(hexa << (i*4));
197                 nb = (nb >> 60) & 0xf;
198                 // Skip the leading zeros
199                 if (nb == 0)
200                   {
201                     if (had_nonzero)
202                       PUTCHAR('0');
203                   }
204                 else
205                   {
206                     had_nonzero = 1;
207                     if (nb < 10)
208                       PUTCHAR('0'+nb);
209                     else
210                       PUTCHAR('a'+(nb-10));
211                   }
212               }
213             if (! had_nonzero)
214               PUTCHAR('0');
215           }
216           fmt_modifiers = 0;
217           break;
218           
219         default:
220           PUTCHAR('%');
221           if (prefix_long)
222             PUTCHAR('l');
223           if (prefix_long_long)
224             PUTCHAR('l');
225           PUTCHAR(format[i]);
226           fmt_modifiers = 0;
227         }
228     }
229 
230   *buff = '\0';
231   return result;
232 }
233 
234 
235 int snprintf(char * buff, size_t len, const char *format, ...)
236 {
237   va_list ap;
238  
239   va_start(ap, format);
240   len = vsnprintf(buff, len, format, ap);
241   va_end(ap);
242  
243   return len;
244 }

source navigation ] diff markup ] identifier search ] general search ]