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 #include "config.h"
00033
00034
00035
00036
00037
00038
00039 #ifndef HAVE_STRDUP
00040 char *
00041 mxml_strdup(const char *s)
00042 {
00043 char *t;
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
00055
00056
00057
00058
00059
00060
00061 char *
00062 mxml_strdupf(const char *format,
00063 va_list ap)
00064 {
00065 int bytes;
00066 char *buffer,
00067 temp[256];
00068
00069
00070
00071
00072
00073
00074
00075 bytes = mxml_vsnprintf(temp, sizeof(temp), format, ap);
00076
00077 if (bytes < sizeof(temp))
00078 {
00079
00080
00081
00082
00083 return (strdup(temp));
00084 }
00085
00086
00087
00088
00089
00090
00091 if ((buffer = calloc(1, bytes + 1)) != NULL)
00092 mxml_vsnprintf(buffer, bytes + 1, format, ap);
00093
00094
00095
00096
00097
00098 return (buffer);
00099 }
00100
00101
00102
00103
00104
00105
00106 int
00107 mxml_vsnprintf(char *buffer,
00108 size_t bufsize,
00109 const char *format,
00110 va_list ap)
00111 {
00112 char *bufptr,
00113 *bufend,
00114 sign,
00115 size,
00116 type;
00117 const char *bufformat;
00118 int width,
00119 prec;
00120 char tformat[100],
00121 temp[1024];
00122 char *s;
00123 int slen;
00124 int bytes;
00125
00126
00127
00128
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' :
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' :
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' :
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' :
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' :
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' :
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
00368
00369
00370 *bufptr = '\0';
00371
00372 return (bytes);
00373 }
00374
00375
00376
00377
00378
00379