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