/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/src/mxml-2.2.2/mxml-string.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 207 $ : Last Committed Revision
00003  * $Date: 2008-07-11 17:55:19 -0700 (Fri, 11 Jul 2008) $ : Last Committed Date */
00004 /*
00005  * "$Id: mxml-string.c,v 1.1 2007/05/23 20:43:28 david_ko Exp $"
00006  *
00007  * String functions for Mini-XML, a small XML-like file parsing library.
00008  *
00009  * Copyright 2003-2005 by Michael Sweet.
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU Library General Public
00013  * License as published by the Free Software Foundation; either
00014  * version 2, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * Contents:
00022  *
00023  *   mxml_strdup()    - Duplicate a string.
00024  *   mxml_strdupf()   - Format and duplicate a string.
00025  *   mxml_vsnprintf() - Format a string into a fixed size buffer.
00026  */
00027 
00028 /*
00029  * Include necessary headers...
00030  */
00031 
00032 #include "config.h"
00033 
00034 
00035 /*
00036  * 'mxml_strdup()' - Duplicate a string.
00037  */
00038 
00039 #ifndef HAVE_STRDUP
00040 char    *                               /* O - New string pointer */
00041 mxml_strdup(const char *s)              /* I - String to duplicate */
00042 {
00043   char  *t;                             /* New string pointer */
00044 
00045 
00046   if (s == NULL)
00047     return (NULL);
00048 
00049   if ((t = malloc(strlen(s) + 1)) == NULL)
00050     return (NULL);
00051 
00052   return (strcpy(t, s));
00053 }
00054 #endif /* !HAVE_STRDUP */
00055 
00056 
00057 /*
00058  * 'mxml_strdupf()' - Format and duplicate a string.
00059  */
00060 
00061 char *                                  /* O - New string pointer */
00062 mxml_strdupf(const char *format,        /* I - Printf-style format string */
00063              va_list    ap)             /* I - Pointer to additional arguments */
00064 {
00065   int   bytes;                          /* Number of bytes required */
00066   char  *buffer,                        /* String buffer */
00067         temp[256];                      /* Small buffer for first vsnprintf */
00068 
00069 
00070  /*
00071   * First format with a tiny buffer; this will tell us how many bytes are
00072   * needed...
00073   */
00074 
00075   bytes = mxml_vsnprintf(temp, sizeof(temp), format, ap);
00076 
00077   if (bytes < sizeof(temp))
00078   {
00079    /*
00080     * Hey, the formatted string fits in the tiny buffer, so just dup that...
00081     */
00082 
00083     return (strdup(temp));
00084   }
00085 
00086  /*
00087   * Allocate memory for the whole thing and reformat to the new, larger
00088   * buffer...
00089   */
00090 
00091   if ((buffer = calloc(1, bytes + 1)) != NULL)
00092     mxml_vsnprintf(buffer, bytes + 1, format, ap);
00093 
00094  /*
00095   * Return the new string...
00096   */
00097 
00098   return (buffer);
00099 }
00100 
00101 
00102 /*
00103  * 'mxml_vsnprintf()' - Format a string into a fixed size buffer.
00104  */
00105 
00106 int                                     /* O - Number of bytes formatted */
00107 mxml_vsnprintf(char       *buffer,      /* O - Output buffer */
00108                size_t     bufsize,      /* O - Size of output buffer */
00109                const char *format,      /* I - Printf-style format string */
00110                va_list    ap)           /* I - Pointer to additional arguments */
00111 {
00112   char          *bufptr,                /* Pointer to position in buffer */
00113                 *bufend,                /* Pointer to end of buffer */
00114                 sign,                   /* Sign of format width */
00115                 size,                   /* Size character (h, l, L) */
00116                 type;                   /* Format type character */
00117   const char    *bufformat;             /* Start of format */
00118   int           width,                  /* Width of field */
00119                 prec;                   /* Number of characters of precision */
00120   char          tformat[100],           /* Temporary format string for sprintf() */
00121                 temp[1024];             /* Buffer for formatted numbers */
00122   char          *s;                     /* Pointer to string */
00123   int           slen;                   /* Length of string */
00124   int           bytes;                  /* Total number of bytes needed */
00125 
00126 
00127  /*
00128   * Loop through the format string, formatting as needed...
00129   */
00130 
00131   bufptr = buffer;
00132   bufend = buffer + bufsize - 1;
00133   bytes  = 0;
00134 
00135   while (*format)
00136   {
00137     if (*format == '%')
00138     {
00139       bufformat = format;
00140       format ++;
00141 
00142       if (*format == '%')
00143       {
00144         *bufptr++ = *format++;
00145         continue;
00146       }
00147       else if (strchr(" -+#\'", *format))
00148         sign = *format++;
00149       else
00150         sign = 0;
00151 
00152       width = 0;
00153       while (isdigit(*format))
00154         width = width * 10 + *format++ - '0';
00155 
00156       if (*format == '.')
00157       {
00158         format ++;
00159         prec = 0;
00160 
00161         while (isdigit(*format))
00162           prec = prec * 10 + *format++ - '0';
00163       }
00164       else
00165         prec = -1;
00166 
00167       if (*format == 'l' && format[1] == 'l')
00168       {
00169         size = 'L';
00170         format += 2;
00171       }
00172       else if (*format == 'h' || *format == 'l' || *format == 'L')
00173         size = *format++;
00174 
00175       if (!*format)
00176         break;
00177 
00178       type = *format++;
00179 
00180       switch (type)
00181       {
00182         case 'E' : /* Floating point formats */
00183         case 'G' :
00184         case 'e' :
00185         case 'f' :
00186         case 'g' :
00187             if ((format - bufformat + 1) > sizeof(tformat) ||
00188                 (width + 2) > sizeof(temp))
00189               break;
00190 
00191             strncpy(tformat, bufformat, format - bufformat);
00192             tformat[format - bufformat] = '\0';
00193 
00194             sprintf(temp, tformat, va_arg(ap, double));
00195 
00196             bytes += strlen(temp);
00197 
00198             if (bufptr)
00199             {
00200               if ((bufptr + strlen(temp)) > bufend)
00201               {
00202                 strncpy(bufptr, temp, bufend - bufptr);
00203                 bufptr = bufend;
00204                 break;
00205               }
00206               else
00207               {
00208                 strcpy(bufptr, temp);
00209                 bufptr += strlen(temp);
00210               }
00211             }
00212             break;
00213 
00214         case 'B' : /* Integer formats */
00215         case 'X' :
00216         case 'b' :
00217         case 'd' :
00218         case 'i' :
00219         case 'o' :
00220         case 'u' :
00221         case 'x' :
00222             if ((format - bufformat + 1) > sizeof(tformat) ||
00223                 (width + 2) > sizeof(temp))
00224               break;
00225 
00226             strncpy(tformat, bufformat, format - bufformat);
00227             tformat[format - bufformat] = '\0';
00228 
00229             sprintf(temp, tformat, va_arg(ap, int));
00230 
00231             bytes += strlen(temp);
00232 
00233             if (bufptr)
00234             {
00235               if ((bufptr + strlen(temp)) > bufend)
00236               {
00237                 strncpy(bufptr, temp, bufend - bufptr);
00238                 bufptr = bufend;
00239                 break;
00240               }
00241               else
00242               {
00243                 strcpy(bufptr, temp);
00244                 bufptr += strlen(temp);
00245               }
00246             }
00247             break;
00248             
00249         case 'p' : /* Pointer value */
00250             if ((format - bufformat + 1) > sizeof(tformat) ||
00251                 (width + 2) > sizeof(temp))
00252               break;
00253 
00254             strncpy(tformat, bufformat, format - bufformat);
00255             tformat[format - bufformat] = '\0';
00256 
00257             sprintf(temp, tformat, va_arg(ap, void *));
00258 
00259             bytes += strlen(temp);
00260 
00261             if (bufptr)
00262             {
00263               if ((bufptr + strlen(temp)) > bufend)
00264               {
00265                 strncpy(bufptr, temp, bufend - bufptr);
00266                 bufptr = bufend;
00267                 break;
00268               }
00269               else
00270               {
00271                 strcpy(bufptr, temp);
00272                 bufptr += strlen(temp);
00273               }
00274             }
00275             break;
00276 
00277         case 'c' : /* Character or character array */
00278             bytes += width;
00279 
00280             if (bufptr)
00281             {
00282               if (width <= 1)
00283                 *bufptr++ = va_arg(ap, int);
00284               else
00285               {
00286                 if ((bufptr + width) > bufend)
00287                   width = bufend - bufptr;
00288 
00289                 memcpy(bufptr, va_arg(ap, char *), width);
00290                 bufptr += width;
00291               }
00292             }
00293             break;
00294 
00295         case 's' : /* String */
00296             if ((s = va_arg(ap, char *)) == NULL)
00297               s = "(null)";
00298 
00299             slen = strlen(s);
00300             if (slen > width && prec != width)
00301               width = slen;
00302 
00303             bytes += width;
00304 
00305             if (bufptr)
00306             {
00307               if ((bufptr + width) > bufend)
00308                 width = bufend - bufptr;
00309 
00310               if (slen > width)
00311                 slen = width;
00312 
00313               if (sign == '-')
00314               {
00315                 strncpy(bufptr, s, slen);
00316                 memset(bufptr + slen, ' ', width - slen);
00317               }
00318               else
00319               {
00320                 memset(bufptr, ' ', width - slen);
00321                 strncpy(bufptr + width - slen, s, slen);
00322               }
00323 
00324               bufptr += width;
00325             }
00326             break;
00327 
00328         case 'n' : /* Output number of chars so far */
00329             if ((format - bufformat + 1) > sizeof(tformat) ||
00330                 (width + 2) > sizeof(temp))
00331               break;
00332 
00333             strncpy(tformat, bufformat, format - bufformat);
00334             tformat[format - bufformat] = '\0';
00335 
00336             sprintf(temp, tformat, va_arg(ap, int));
00337 
00338             bytes += strlen(temp);
00339 
00340             if (bufptr)
00341             {
00342               if ((bufptr + strlen(temp)) > bufend)
00343               {
00344                 strncpy(bufptr, temp, bufend - bufptr);
00345                 bufptr = bufend;
00346                 break;
00347               }
00348               else
00349               {
00350                 strcpy(bufptr, temp);
00351                 bufptr += strlen(temp);
00352               }
00353             }
00354             break;
00355       }
00356     }
00357     else
00358     {
00359       bytes ++;
00360 
00361       if (bufptr && bufptr < bufend)
00362         *bufptr++ = *format++;
00363     }
00364   }
00365 
00366  /*
00367   * Nul-terminate the string and return the number of characters needed.
00368   */
00369 
00370   *bufptr = '\0';
00371 
00372   return (bytes);
00373 }
00374 
00375 
00376 
00377 /*
00378  * End of "$Id: mxml-string.c,v 1.1 2007/05/23 20:43:28 david_ko Exp $".
00379  */

Generated on Fri Jul 11 17:59:45 2008 for Mobile-C by  doxygen 1.5.4