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 #ifdef HAVE_CONFIG_H
00026 #include "config.h"
00027 #endif
00028 #include <ansidecl.h>
00029 #ifdef ANSI_PROTOTYPES
00030 #include <stdarg.h>
00031 #else
00032 #include <varargs.h>
00033 #endif
00034 #if !defined (va_copy) && defined (__va_copy)
00035 # define va_copy(d,s) __va_copy((d),(s))
00036 #endif
00037 #include <stdio.h>
00038 #ifdef HAVE_STRING_H
00039 #include <string.h>
00040 #endif
00041 #ifdef HAVE_STDLIB_H
00042 #include <stdlib.h>
00043 #else
00044 extern unsigned long strtoul ();
00045 extern PTR malloc ();
00046 #endif
00047 #include "libiberty.h"
00048
00049 #ifdef TEST
00050 int global_total_width;
00051 #endif
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 static int int_vasprintf PARAMS ((char **, const char *, va_list));
00070
00071 static int
00072 int_vasprintf (result, format, args)
00073 char **result;
00074 const char *format;
00075 va_list args;
00076 {
00077 const char *p = format;
00078
00079
00080 int total_width = strlen (format) + 1;
00081 va_list ap;
00082
00083 #ifdef va_copy
00084 va_copy (ap, args);
00085 #else
00086 memcpy ((PTR) &ap, (PTR) &args, sizeof (va_list));
00087 #endif
00088
00089 while (*p != '\0')
00090 {
00091 if (*p++ == '%')
00092 {
00093 while (strchr ("-+ #0", *p))
00094 ++p;
00095 if (*p == '*')
00096 {
00097 ++p;
00098 total_width += abs (va_arg (ap, int));
00099 }
00100 else
00101 total_width += strtoul (p, (char **) &p, 10);
00102 if (*p == '.')
00103 {
00104 ++p;
00105 if (*p == '*')
00106 {
00107 ++p;
00108 total_width += abs (va_arg (ap, int));
00109 }
00110 else
00111 total_width += strtoul (p, (char **) &p, 10);
00112 }
00113 while (strchr ("hlL", *p))
00114 ++p;
00115
00116 total_width += 30;
00117 switch (*p)
00118 {
00119 case 'd':
00120 case 'i':
00121 case 'o':
00122 case 'u':
00123 case 'x':
00124 case 'X':
00125 case 'c':
00126 (void) va_arg (ap, int);
00127 break;
00128 case 'f':
00129 case 'e':
00130 case 'E':
00131 case 'g':
00132 case 'G':
00133 (void) va_arg (ap, double);
00134
00135
00136 total_width += 307;
00137 break;
00138 case 's':
00139 total_width += strlen (va_arg (ap, char *));
00140 break;
00141 case 'p':
00142 case 'n':
00143 (void) va_arg (ap, char *);
00144 break;
00145 }
00146 p++;
00147 }
00148 }
00149 #ifdef va_copy
00150 va_end (ap);
00151 #endif
00152 #ifdef TEST
00153 global_total_width = total_width;
00154 #endif
00155 *result = (char *) malloc (total_width);
00156 if (*result != NULL)
00157 return vsprintf (*result, format, args);
00158 else
00159 return -1;
00160 }
00161
00162 int
00163 vasprintf (result, format, args)
00164 char **result;
00165 const char *format;
00166 #if defined (_BSD_VA_LIST_) && defined (__FreeBSD__)
00167 _BSD_VA_LIST_ args;
00168 #else
00169 va_list args;
00170 #endif
00171 {
00172 return int_vasprintf (result, format, args);
00173 }
00174
00175 #ifdef TEST
00176 static void ATTRIBUTE_PRINTF_1
00177 checkit VPARAMS ((const char *format, ...))
00178 {
00179 char *result;
00180 VA_OPEN (args, format);
00181 VA_FIXEDARG (args, const char *, format);
00182 vasprintf (&result, format, args);
00183 VA_CLOSE (args);
00184
00185 if (strlen (result) < (size_t) global_total_width)
00186 printf ("PASS: ");
00187 else
00188 printf ("FAIL: ");
00189 printf ("%d %s\n", global_total_width, result);
00190
00191 free (result);
00192 }
00193
00194 extern int main PARAMS ((void));
00195
00196 int
00197 main ()
00198 {
00199 checkit ("%d", 0x12345678);
00200 checkit ("%200d", 5);
00201 checkit ("%.300d", 6);
00202 checkit ("%100.150d", 7);
00203 checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
00204 777777777777777777333333333333366666666666622222222222777777777777733333");
00205 checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
00206
00207 return 0;
00208 }
00209 #endif