00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "config.h"
00032
00033
00034 #ifndef HAVE_SNPRINTF
00035
00036
00037
00038
00039 int
00040 _mxml_snprintf(char *buffer,
00041 size_t bufsize,
00042 const char *format,
00043 ...)
00044 {
00045 va_list ap;
00046 int bytes;
00047
00048
00049 va_start(ap, format);
00050 bytes = vsnprintf(buffer, bufsize, format, ap);
00051 va_end(ap);
00052
00053 return (bytes);
00054 }
00055 #endif
00056
00057
00058
00059
00060
00061
00062 #ifndef HAVE_STRDUP
00063 char *
00064 _mxml_strdup(const char *s)
00065 {
00066 char *t;
00067
00068
00069 if (s == NULL)
00070 return (NULL);
00071
00072 if ((t = malloc(strlen(s) + 1)) == NULL)
00073 return (NULL);
00074
00075 return (strcpy(t, s));
00076 }
00077 #endif
00078
00079
00080
00081
00082
00083
00084 char *
00085 _mxml_strdupf(const char *format,
00086 ...)
00087 {
00088 va_list ap;
00089 char *s;
00090
00091
00092
00093
00094
00095
00096
00097 va_start(ap, format);
00098 s = _mxml_vstrdupf(format, ap);
00099 va_end(ap);
00100
00101 return (s);
00102 }
00103
00104
00105 #ifndef HAVE_VSNPRINTF
00106
00107
00108
00109
00110 int
00111 _mxml_vsnprintf(char *buffer,
00112 size_t bufsize,
00113 const char *format,
00114 va_list ap)
00115 {
00116 char *bufptr,
00117 *bufend,
00118 sign,
00119 size,
00120 type;
00121 int width,
00122 prec;
00123 char tformat[100],
00124 *tptr,
00125 temp[1024];
00126 char *s;
00127 int slen;
00128 int bytes;
00129
00130
00131
00132
00133
00134
00135 bufptr = buffer;
00136 bufend = buffer + bufsize - 1;
00137 bytes = 0;
00138
00139 while (*format)
00140 {
00141 if (*format == '%')
00142 {
00143 tptr = tformat;
00144 *tptr++ = *format++;
00145
00146 if (*format == '%')
00147 {
00148 if (bufptr && bufptr < bufend) *bufptr++ = *format;
00149 bytes ++;
00150 format ++;
00151 continue;
00152 }
00153 else if (strchr(" -+#\'", *format))
00154 {
00155 *tptr++ = *format;
00156 sign = *format++;
00157 }
00158 else
00159 sign = 0;
00160
00161 if (*format == '*')
00162 {
00163
00164
00165
00166
00167 format ++;
00168 width = va_arg(ap, int);
00169
00170 snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width);
00171 tptr += strlen(tptr);
00172 }
00173 else
00174 {
00175 width = 0;
00176
00177 while (isdigit(*format & 255))
00178 {
00179 if (tptr < (tformat + sizeof(tformat) - 1))
00180 *tptr++ = *format;
00181
00182 width = width * 10 + *format++ - '0';
00183 }
00184 }
00185
00186 if (*format == '.')
00187 {
00188 if (tptr < (tformat + sizeof(tformat) - 1))
00189 *tptr++ = *format;
00190
00191 format ++;
00192
00193 if (*format == '*')
00194 {
00195
00196
00197
00198
00199 format ++;
00200 prec = va_arg(ap, int);
00201
00202 snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec);
00203 tptr += strlen(tptr);
00204 }
00205 else
00206 {
00207 prec = 0;
00208
00209 while (isdigit(*format & 255))
00210 {
00211 if (tptr < (tformat + sizeof(tformat) - 1))
00212 *tptr++ = *format;
00213
00214 prec = prec * 10 + *format++ - '0';
00215 }
00216 }
00217 }
00218 else
00219 prec = -1;
00220
00221 if (*format == 'l' && format[1] == 'l')
00222 {
00223 size = 'L';
00224
00225 if (tptr < (tformat + sizeof(tformat) - 2))
00226 {
00227 *tptr++ = 'l';
00228 *tptr++ = 'l';
00229 }
00230
00231 format += 2;
00232 }
00233 else if (*format == 'h' || *format == 'l' || *format == 'L')
00234 {
00235 if (tptr < (tformat + sizeof(tformat) - 1))
00236 *tptr++ = *format;
00237
00238 size = *format++;
00239 }
00240
00241 if (!*format)
00242 break;
00243
00244 if (tptr < (tformat + sizeof(tformat) - 1))
00245 *tptr++ = *format;
00246
00247 type = *format++;
00248 *tptr = '\0';
00249
00250 switch (type)
00251 {
00252 case 'E' :
00253 case 'G' :
00254 case 'e' :
00255 case 'f' :
00256 case 'g' :
00257 if ((width + 2) > sizeof(temp))
00258 break;
00259
00260 sprintf(temp, tformat, va_arg(ap, double));
00261
00262 bytes += strlen(temp);
00263
00264 if (bufptr)
00265 {
00266 if ((bufptr + strlen(temp)) > bufend)
00267 {
00268 strncpy(bufptr, temp, (size_t)(bufend - bufptr));
00269 bufptr = bufend;
00270 }
00271 else
00272 {
00273 strcpy(bufptr, temp);
00274 bufptr += strlen(temp);
00275 }
00276 }
00277 break;
00278
00279 case 'B' :
00280 case 'X' :
00281 case 'b' :
00282 case 'd' :
00283 case 'i' :
00284 case 'o' :
00285 case 'u' :
00286 case 'x' :
00287 if ((width + 2) > sizeof(temp))
00288 break;
00289
00290 sprintf(temp, tformat, va_arg(ap, int));
00291
00292 bytes += strlen(temp);
00293
00294 if (bufptr)
00295 {
00296 if ((bufptr + strlen(temp)) > bufend)
00297 {
00298 strncpy(bufptr, temp, (size_t)(bufend - bufptr));
00299 bufptr = bufend;
00300 }
00301 else
00302 {
00303 strcpy(bufptr, temp);
00304 bufptr += strlen(temp);
00305 }
00306 }
00307 break;
00308
00309 case 'p' :
00310 if ((width + 2) > sizeof(temp))
00311 break;
00312
00313 sprintf(temp, tformat, va_arg(ap, void *));
00314
00315 bytes += strlen(temp);
00316
00317 if (bufptr)
00318 {
00319 if ((bufptr + strlen(temp)) > bufend)
00320 {
00321 strncpy(bufptr, temp, (size_t)(bufend - bufptr));
00322 bufptr = bufend;
00323 }
00324 else
00325 {
00326 strcpy(bufptr, temp);
00327 bufptr += strlen(temp);
00328 }
00329 }
00330 break;
00331
00332 case 'c' :
00333 bytes += width;
00334
00335 if (bufptr)
00336 {
00337 if (width <= 1)
00338 *bufptr++ = va_arg(ap, int);
00339 else
00340 {
00341 if ((bufptr + width) > bufend)
00342 width = bufend - bufptr;
00343
00344 memcpy(bufptr, va_arg(ap, char *), (size_t)width);
00345 bufptr += width;
00346 }
00347 }
00348 break;
00349
00350 case 's' :
00351 if ((s = va_arg(ap, char *)) == NULL)
00352 s = "(null)";
00353
00354 slen = strlen(s);
00355 if (slen > width && prec != width)
00356 width = slen;
00357
00358 bytes += width;
00359
00360 if (bufptr)
00361 {
00362 if ((bufptr + width) > bufend)
00363 width = bufend - bufptr;
00364
00365 if (slen > width)
00366 slen = width;
00367
00368 if (sign == '-')
00369 {
00370 strncpy(bufptr, s, (size_t)slen);
00371 memset(bufptr + slen, ' ', (size_t)(width - slen));
00372 }
00373 else
00374 {
00375 memset(bufptr, ' ', (size_t)(width - slen));
00376 strncpy(bufptr + width - slen, s, (size_t)slen);
00377 }
00378
00379 bufptr += width;
00380 }
00381 break;
00382
00383 case 'n' :
00384 *(va_arg(ap, int *)) = bytes;
00385 break;
00386 }
00387 }
00388 else
00389 {
00390 bytes ++;
00391
00392 if (bufptr && bufptr < bufend)
00393 *bufptr++ = *format;
00394
00395 format ++;
00396 }
00397 }
00398
00399
00400
00401
00402
00403 *bufptr = '\0';
00404
00405 return (bytes);
00406 }
00407 #endif
00408
00409
00410
00411
00412
00413
00414 char *
00415 _mxml_vstrdupf(const char *format,
00416 va_list ap)
00417 {
00418 int bytes;
00419 char *buffer,
00420 temp[256];
00421
00422
00423
00424
00425
00426
00427
00428 bytes = vsnprintf(temp, sizeof(temp), format, ap);
00429
00430 if (bytes < sizeof(temp))
00431 {
00432
00433
00434
00435
00436 return (strdup(temp));
00437 }
00438
00439
00440
00441
00442
00443
00444 if ((buffer = calloc(1, bytes + 1)) != NULL)
00445 vsnprintf(buffer, bytes + 1, format, ap);
00446
00447
00448
00449
00450
00451 return (buffer);
00452 }