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