/home/dko/projects/mobilec/trunk/src/mxml-2.2.2/mxml-string.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 174 $ : Last Committed Revision
00003  * $Date: 2008年06月24日 10:50:29 -0700 (2008年6月24日) $ : 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 Tue Oct 28 17:03:22 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /