Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

printf.c

Go to the documentation of this file.
00001 
00006 /*
00007  *  The contents of this file are subject to the Mozilla Public License
00008  *  Version 1.0 (the "License"); you may not use this file except in
00009  *  compliance with the License. You may obtain a copy of the License at
00010  *  http://www.mozilla.org/MPL/
00011  *
00012  *  Software distributed under the License is distributed on an "AS IS"
00013  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00014  *  License for the specific language governing rights and limitations
00015  *  under the License.
00016  *
00017  *  The Original Code is from the Brown Computer Science Department,
00018  *  Weenix support code.
00019  *
00020  *  The Initial Developer of the Original Code is David Powell.
00021  *
00022  *  Contributor(s): Matthew Ahrens <mahrens@acm.org>
00023  */
00024 
00025 #include <stdarg.h>
00026 
00027 static const char hexdigits[] = "0123456789ABCDEF";
00028 static const char lhexdigits[] = "0123456789abcdef";
00029 static const char empty_string[] = "(null string)";
00030 
00031 /* This function takes an unsigned int and puts its ascii
00032  * representation at a particular location in a buffer of given
00033  * length.  The radix used is must also be provided, as well as a
00034  * string containing the characters used in the ascii representation.
00035  *
00036  * This function makes no attempt to handle two-byte characters. 
00037  */
00038 static int itoa(unsigned int value, char *dst, int pos, int len,
00039                 int radix, const char *digits)
00040 {
00041         char    sbuf[10];
00042         int     spos;
00043 
00044         spos = 0;
00045         while(value) {
00046                 sbuf[spos] = value % radix;
00047                 spos++;
00048                 value /= radix;
00049         }
00050         if(!spos)
00051                 *sbuf = 0, spos = 1;
00052 
00053         for(spos--; pos<len && spos>=0; pos++,spos--) {
00054                 dst[pos] = digits[(int)sbuf[spos]];
00055         }
00056 
00057         return pos-1;
00058 }
00059 
00060 
00061 /* This function takes a buffer, its length, a format specification,
00062  * and a va_list, formats the provided data according the the format
00063  * spec, and places the result in the buffer.  It returns the length of
00064  * the output.  The only format options supported by this function
00065  * are:
00066  *   %d - decimal unsigned int
00067  *   %i -    "        "     "
00068  *   %x - hexidecimal unsigned int (lowercase letters)
00069  *   %X -      "          "     "   (uppercase letters)
00070  *   %c - character
00071  *   %s - string
00072  *   %% - '%' character
00073  */
00074 int vsnprintf(char *dst, int len, const char *fmt, va_list arg)
00075 {
00076         int             pos;
00077         int             cc;
00078         const char      *temp;
00079         unsigned int    scratch;
00080 
00081         for(pos=0, cc=0; (pos<len) && (cc=*fmt); pos++, fmt++) {
00082                 if(cc!='%')
00083                         dst[pos] = cc;
00084                 else {
00085                         cc = *(++fmt);
00086                         switch(cc) {
00087                         case 'd':
00088                         case 'i':
00089                                 /* integer */
00090                                 scratch = va_arg(arg, unsigned);
00091                                 pos = itoa(scratch, dst, pos, len, 10,
00092                                            hexdigits);
00093                                 break;
00094                         case 'X':
00095                                 /* hexadecimal (uppercase) */
00096                                 scratch = va_arg(arg, unsigned);
00097                                 pos = itoa(scratch, dst, pos, len, 16,
00098                                            hexdigits);
00099                                 break;
00100                         case 'x':
00101                                 /* hexadecimal (lowercase) */
00102                                 scratch = va_arg(arg, unsigned);
00103                                 pos = itoa(scratch, dst, pos, len, 16,
00104                                            lhexdigits);
00105                                 break;
00106                         case 's':
00107                                 /* string */
00108                                 temp = va_arg(arg, const char*);
00109                                 if(!temp)
00110                                         temp = empty_string;
00111                                 for(; pos<len && *temp; pos++, temp++) {
00112                                         dst[pos] = *temp;
00113                                 }
00114                                 pos--;
00115                                 break;
00116                         case 'c':
00117                                 /* character */
00118                                 dst[pos] = va_arg(arg, int);
00119                                 break;
00120                         case '\0':
00121                         case '%':
00122                                 dst[pos] = cc;
00123                                 break;
00124                         }
00125 
00126                         if(!cc) {
00127                                 break;
00128                         }
00129                 }
00130         }
00131 
00132         dst[pos++] = '\0';
00133 
00134         return pos;
00135 }
00136 
00137 
00138 /* This function prints the specified format into the provided buffer
00139  * taking care not to access beyond the end of the string. 
00140  */
00141 char *snprintf(char *dst, int len, const char *fmt, ...)
00142 {
00143         va_list arg;
00144 
00145         va_start(arg, fmt);
00146         (void) vsnprintf(dst, len, fmt, arg);
00147         va_end(arg);
00148 
00149         return dst;
00150 }
00151 

Generated on Fri Feb 25 08:02:39 2005 for brickos by  doxygen 1.3.9.1