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
00032 #ifdef _WIN32
00033 #include "winconfig.h"
00034 #else
00035 #include "config.h"
00036 #endif
00037
00038
00039
00040
00041
00042
00043 #ifndef HAVE_STRDUP
00044 char *
00045 mxml_strdup(const char *s)
00046 {
00047 char *t;
00048
00049
00050 if (s == NULL)
00051 return (NULL);
00052
00053 if ((t = malloc(strlen(s) + 1)) == NULL)
00054 return (NULL);
00055
00056 return (strcpy(t, s));
00057 }
00058 #endif
00059
00060
00061
00062
00063
00064
00065 char *
00066 mxml_strdupf(const char *format,
00067 va_list ap)
00068 {
00069 int bytes;
00070 char *buffer,
00071 temp[256];
00072
00073
00074
00075
00076
00077
00078
00079 bytes = mxml_vsnprintf(temp, sizeof(temp), format, ap);
00080
00081 if (bytes < sizeof(temp))
00082 {
00083
00084
00085
00086
00087 return (strdup(temp));
00088 }
00089
00090
00091
00092
00093
00094
00095 if ((buffer = (char*)calloc(1, bytes + 1)) != NULL)
00096 mxml_vsnprintf(buffer, bytes + 1, format, ap);
00097
00098
00099
00100
00101
00102 return (buffer);
00103 }
00104
00105
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 const char *bufformat;
00122 int width,
00123 prec;
00124 char tformat[100],
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 bufformat = format;
00144 format ++;
00145
00146 if (*format == '%')
00147 {
00148 *bufptr++ = *format++;
00149 continue;
00150 }
00151 else if (strchr(" -+#\'", *format))
00152 sign = *format++;
00153 else
00154 sign = 0;
00155
00156 width = 0;
00157 while (isdigit(*format))
00158 width = width * 10 + *format++ - '0';
00159
00160 if (*format == '.')
00161 {
00162 format ++;
00163 prec = 0;
00164
00165 while (isdigit(*format))
00166 prec = prec * 10 + *format++ - '0';
00167 }
00168 else
00169 prec = -1;
00170
00171 if (*format == 'l' && format[1] == 'l')
00172 {
00173 size = 'L';
00174 format += 2;
00175 }
00176 else if (*format == 'h' || *format == 'l' || *format == 'L')
00177 size = *format++;
00178
00179 if (!*format)
00180 break;
00181
00182 type = *format++;
00183
00184 switch (type)
00185 {
00186 case 'E' :
00187 case 'G' :
00188 case 'e' :
00189 case 'f' :
00190 case 'g' :
00191 if ((format - bufformat + 1) > sizeof(tformat) ||
00192 (width + 2) > sizeof(temp))
00193 break;
00194
00195 strncpy(tformat, bufformat, format - bufformat);
00196 tformat[format - bufformat] = '\0';
00197
00198 sprintf(temp, tformat, va_arg(ap, double));
00199
00200 bytes += strlen(temp);
00201
00202 if (bufptr)
00203 {
00204 if ((bufptr + strlen(temp)) > bufend)
00205 {
00206 strncpy(bufptr, temp, bufend - bufptr);
00207 bufptr = bufend;
00208 break;
00209 }
00210 else
00211 {
00212 strcpy(bufptr, temp);
00213 bufptr += strlen(temp);
00214 }
00215 }
00216 break;
00217
00218 case 'B' :
00219 case 'X' :
00220 case 'b' :
00221 case 'd' :
00222 case 'i' :
00223 case 'o' :
00224 case 'u' :
00225 case 'x' :
00226 if ((format - bufformat + 1) > sizeof(tformat) ||
00227 (width + 2) > sizeof(temp))
00228 break;
00229
00230 strncpy(tformat, bufformat, format - bufformat);
00231 tformat[format - bufformat] = '\0';
00232
00233 sprintf(temp, tformat, va_arg(ap, int));
00234
00235 bytes += strlen(temp);
00236
00237 if (bufptr)
00238 {
00239 if ((bufptr + strlen(temp)) > bufend)
00240 {
00241 strncpy(bufptr, temp, bufend - bufptr);
00242 bufptr = bufend;
00243 break;
00244 }
00245 else
00246 {
00247 strcpy(bufptr, temp);
00248 bufptr += strlen(temp);
00249 }
00250 }
00251 break;
00252
00253 case 'p' :
00254 if ((format - bufformat + 1) > sizeof(tformat) ||
00255 (width + 2) > sizeof(temp))
00256 break;
00257
00258 strncpy(tformat, bufformat, format - bufformat);
00259 tformat[format - bufformat] = '\0';
00260
00261 sprintf(temp, tformat, va_arg(ap, void *));
00262
00263 bytes += strlen(temp);
00264
00265 if (bufptr)
00266 {
00267 if ((bufptr + strlen(temp)) > bufend)
00268 {
00269 strncpy(bufptr, temp, bufend - bufptr);
00270 bufptr = bufend;
00271 break;
00272 }
00273 else
00274 {
00275 strcpy(bufptr, temp);
00276 bufptr += strlen(temp);
00277 }
00278 }
00279 break;
00280
00281 case 'c' :
00282 bytes += width;
00283
00284 if (bufptr)
00285 {
00286 if (width <= 1)
00287 *bufptr++ = va_arg(ap, int);
00288 else
00289 {
00290 if ((bufptr + width) > bufend)
00291 width = bufend - bufptr;
00292
00293 memcpy(bufptr, va_arg(ap, char *), width);
00294 bufptr += width;
00295 }
00296 }
00297 break;
00298
00299 case 's' :
00300 if ((s = va_arg(ap, char *)) == NULL)
00301 s = "(null)";
00302
00303 slen = strlen(s);
00304 if (slen > width && prec != width)
00305 width = slen;
00306
00307 bytes += width;
00308
00309 if (bufptr)
00310 {
00311 if ((bufptr + width) > bufend)
00312 width = bufend - bufptr;
00313
00314 if (slen > width)
00315 slen = width;
00316
00317 if (sign == '-')
00318 {
00319 strncpy(bufptr, s, slen);
00320 memset(bufptr + slen, ' ', width - slen);
00321 }
00322 else
00323 {
00324 memset(bufptr, ' ', width - slen);
00325 strncpy(bufptr + width - slen, s, slen);
00326 }
00327
00328 bufptr += width;
00329 }
00330 break;
00331
00332 case 'n' :
00333 if ((format - bufformat + 1) > sizeof(tformat) ||
00334 (width + 2) > sizeof(temp))
00335 break;
00336
00337 strncpy(tformat, bufformat, format - bufformat);
00338 tformat[format - bufformat] = '\0';
00339
00340 sprintf(temp, tformat, va_arg(ap, int));
00341
00342 bytes += strlen(temp);
00343
00344 if (bufptr)
00345 {
00346 if ((bufptr + strlen(temp)) > bufend)
00347 {
00348 strncpy(bufptr, temp, bufend - bufptr);
00349 bufptr = bufend;
00350 break;
00351 }
00352 else
00353 {
00354 strcpy(bufptr, temp);
00355 bufptr += strlen(temp);
00356 }
00357 }
00358 break;
00359 }
00360 }
00361 else
00362 {
00363 bytes ++;
00364
00365 if (bufptr && bufptr < bufend)
00366 *bufptr++ = *format++;
00367 }
00368 }
00369
00370
00371
00372
00373
00374 *bufptr = '\0';
00375
00376 return (bytes);
00377 }
00378
00379
00380
00381
00382
00383