Main Page | Directories | File List | Globals

vsprintf.c

Go to the documentation of this file.
00001 
00002 /*
00003  * kernel_libs/other/vsprintf.c
00004  *
00005  * Copyright (c) 2003-2004 Lukasz Dembinski <dembol@nasa.com.pl>
00006  * All Rights Reserved
00007  * 
00008  * Date:        2004/01
00009  * Author:      Lukasz Dembinski
00010  * Info:        vsprintf.c core file
00011  * Contact:     mailto: <dembol@nasa.com.pl>
00012  *
00013  */
00014 
00015 #include <stdarg.h>
00016 #include <agnix/types.h>
00017 #include <agnix/memory.h>
00018 
00019 #define SX_SMALL        1
00020 #define SX_BIG          2
00021 #define SS_NORMAL       3
00022 #define SS_UPPER        4
00023 
00024 #define TAB_LEN         4
00025 #define MAX_NUM_STR     32
00026 
00027 #define DIGIT_D(c)       (c >= '0' && c <= '9')
00028 #define DIGIT_H(c)      ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || \
00029                          (c >= 'a' && c <= 'f'))
00030 
00031 unsigned long convert_str_to_num(const char *fmtt, int len, unsigned char base)
00032 {
00033     unsigned long liczba = 0;
00034     unsigned char val;
00035     int i = len - 1;
00036     unsigned long cur_base = 1;
00037     
00038     do {
00039         if (DIGIT_D(fmtt[i])) {
00040             val = fmtt[i] - '0';
00041             liczba += (unsigned long)(val * cur_base);
00042             cur_base *= base;
00043         } else
00044             break;
00045             
00046         i--;
00047     } while ((i >= 0) && (fmtt[i] != 0));
00048     
00049     return liczba;    
00050 }
00051 
00052 char *convert_num_to_str(char *buf, unsigned long number, unsigned char base, 
00053                          int number_len, int size_ch, char which_ch)
00054 {
00055     char num_str[MAX_NUM_STR];
00056     unsigned long rest;
00057     unsigned long liczba;
00058     char digit;
00059     int dig_nr = 0;
00060     int i = 0;
00061 
00062     memset(num_str, 0, MAX_NUM_STR);
00063 
00064     liczba = number;
00065     do {
00066         rest   = liczba % base;
00067         liczba = liczba / base;
00068         
00069         if (base > 10) {
00070             if (rest >= 10) {
00071                 if (size_ch == SX_SMALL)
00072                     digit = (rest - 10) + 'a';
00073                 else
00074                     digit = (rest - 10) + 'A';
00075             } else
00076                 digit = rest + '0';
00077         }
00078         else {
00079             digit = rest + '0';
00080         }
00081     
00082         num_str[dig_nr++] = digit;
00083     
00084     } while(liczba > 0);
00085 
00086     if (number_len > 0) {
00087         for (i = 0; i < number_len; i++)
00088             buf[i] = which_ch;
00089     }
00090 
00091     dig_nr--;
00092     
00093     if (number_len > 0) {
00094         number_len--;
00095 
00096         if (dig_nr > number_len)
00097             dig_nr = number_len;
00098 
00099         i = number_len - dig_nr;
00100     }
00101 
00102     buf += i;
00103     for (; dig_nr >=0; dig_nr--) {
00104         *buf = num_str[dig_nr];
00105         buf++;
00106     }
00107     
00108     return buf;
00109 }
00110 
00111 char *convert_str_to_str(char *buf, char *ptr, int size_ch)
00112 {
00113     if (ptr == 0) {
00114         memcpy(buf, "<NULL>", 6);
00115         buf += 6;
00116         return buf;
00117     }
00118 
00119     do {
00120         if (*ptr != 0) {
00121             *buf = *ptr;
00122             buf++;
00123             ptr++;
00124         }
00125     } while(*ptr);
00126     
00127     return buf;
00128 }
00129 
00130 int vsnprintf(char *buf, int size, const char *fmt_ptr, va_list args)
00131 {
00132     char *tmp;
00133     const char *fmtt_ptr, *fmtt_tmp;
00134     unsigned char base;
00135     unsigned char string;
00136     int size_ch = 0;
00137     unsigned long number;
00138     char asciinumber;
00139     char *ptr;
00140     int ile;
00141     int  number_len;
00142     char which_ch;
00143     
00144     tmp = buf;
00145     fmtt_ptr = fmt_ptr;
00146 
00147     do {
00148         if (*fmtt_ptr != '%') {
00149         
00150             if (*fmtt_ptr == '\t') {    
00151                 ile = TAB_LEN - ((int)(tmp - buf) & TAB_LEN);
00152                 
00153                 for(; ile >= 0; ile--) {
00154                     *tmp = ' ';
00155                     tmp++;
00156                 }
00157                                 
00158                 fmtt_ptr++;
00159                 continue;
00160             }
00161         
00162             *tmp = *fmtt_ptr;
00163             tmp++;
00164             
00165             if (*fmtt_ptr == 0)
00166                 break;
00167 
00168             fmtt_ptr++;
00169             continue;
00170         }
00171 
00172         fmtt_ptr++;
00173         
00174         number_len = 0;
00175         which_ch   = 0;
00176         
00177         if (DIGIT_D(*fmtt_ptr)) {
00178 
00179             switch(*fmtt_ptr) {
00180                 case '0':
00181                     which_ch = '0';
00182                     fmtt_ptr++; break;
00183                 default:
00184                     which_ch = ' ';
00185             }
00186                 
00187             ile = 0;    
00188             fmtt_tmp = fmtt_ptr;
00189             do {
00190                 if ((*fmtt_tmp == 0) || (!DIGIT_D(*fmtt_tmp)))
00191                     break;
00192             
00193                 ile++;
00194                 fmtt_tmp++;
00195             } while(DIGIT_D(*fmtt_tmp) && (*fmtt_tmp != 0));        
00196                     
00197             number_len = convert_str_to_num(fmtt_ptr, ile, 10);
00198             fmtt_ptr = fmtt_tmp;
00199         }
00200 
00201         if (*fmtt_ptr == 0) {
00202             *tmp = *fmtt_ptr;
00203             break;
00204         }
00205 
00206         base = 0; string = 0;
00207         switch (*fmtt_ptr) {
00208             case 'd': base = 10;
00209                       break;
00210 
00211             case 'x': base = 16;
00212                       size_ch = SX_SMALL;
00213                       break;
00214 
00215             case 'X': base = 16;
00216                       size_ch = SX_BIG;
00217                       break;
00218 
00219             case 's': string = 1;
00220                       size_ch = SS_NORMAL;
00221                       break;
00222 
00223             case 'S': string = 1;
00224                       size_ch = SS_UPPER;
00225                       break;
00226 
00227             case 'c':
00228                       asciinumber = (unsigned char)va_arg(args, int);
00229                       *(tmp++) = asciinumber;   
00230                       break;
00231 
00232             default:
00233                       break;
00234         }       
00235         
00236         if (base > 0) {
00237             number = va_arg(args, long);
00238             tmp = convert_num_to_str(tmp, number, base, number_len, size_ch, which_ch);
00239         }
00240         
00241         if (string) {
00242             ptr = va_arg(args, char *);
00243             tmp = convert_str_to_str(tmp, ptr, size_ch);
00244         }
00245 
00246         fmtt_ptr++;
00247         if (*fmtt_ptr == 0)
00248             *tmp = *fmtt_ptr;
00249     
00250     } while (*fmtt_ptr != 0);
00251 
00252     return tmp-buf;
00253 }
00254 
00255 int snprintf(char *buf, int size, const char *fmt_ptr, ...)
00256 {
00257         va_list args;
00258         int i;
00259 
00260         va_start(args, fmt_ptr);
00261         i=vsnprintf(buf, size, fmt_ptr, args);
00262         va_end(args);
00263         
00264         return i;
00265 }
00266 
00267 int sprintf(char *buf, const char *fmt_ptr, ...)
00268 {
00269         va_list args;
00270         int i;
00271 
00272         va_start(args, fmt_ptr);
00273         i = vsnprintf(buf, 0xFFFFFFFFUL, fmt_ptr, args);
00274         va_end(args);
00275         
00276         return i;
00277 }
00278 
00279 int vsprintf(char *buf, const char *fmt_ptr, va_list args)
00280 {
00281         return vsnprintf(buf, 0xFFFFFFFFUL, fmt_ptr, args);
00282 }
00283 
Dokumentacje wygenerowano programem Doxygen 1.4.2 dla projektu Agnix