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 # include "lclintMacros.nf"
00029 # include "basic.h"
00030
00031
00032
00033 static char strbuf[64];
00034 static int modcode;
00035
00036 typedef enum
00037 {
00038 XINVALID,
00039 XCHAR, XSTRING, XSTRINGFREE, XTSTRINGFREE, XINT, XFLOAT, XBOOL, XUENTRY,
00040 XPERCENT, XCTYPE, XPLURAL, XREPREFIX, XFILELOC
00041 } ccode;
00042
00043
00044
00045 # define GETPRINTF(s,v) (sprintf (strbuf, s, v), mstring_copy (strbuf))
00046
00047
00048
00049
00050
00051
00052 static ccode
00053 identify_control (char **s)
00054 {
00055 char c;
00056
00057 modcode = 0;
00058
00059 c = **s;
00060 if (c == '\0')
00061 {
00062 return (XINVALID);
00063 }
00064
00065 if (c >= '0' && c <= '9')
00066 {
00067 modcode = getInt (s);
00068 }
00069
00070 c = **s;
00071
00072 (*s)++;
00073
00074
00075
00076
00077
00078 switch (c)
00079 {
00080 case '%':
00081 return (XPERCENT);
00082 case 'h':
00083 case 'c':
00084 return (XCHAR);
00085 case 's':
00086 return (XSTRING);
00087 case 'q':
00088 return (XSTRINGFREE);
00089 case 'x':
00090 return (XSTRINGFREE);
00091 case 'd':
00092 return (XINT);
00093 case 'u':
00094 return (XINT);
00095 case 'w':
00096 return (XINT);
00097 case 'f':
00098 return (XFLOAT);
00099 case 'b':
00100 return (XBOOL);
00101 case 't':
00102 return (XCTYPE);
00103 case 'l':
00104 return (XFILELOC);
00105 case 'p':
00106 return (XPLURAL);
00107 case 'r':
00108 return (XREPREFIX);
00109 default:
00110 llcontbug (message ("Message: invalid code: %h (%s)", c,
00111 cstring_fromChars (*s)));
00112 return (XINVALID);
00113 }
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 # if USEVARARGS
00135 cstring
00136 message (fmt, va_alist)
00137 char *fmt;
00138 va_dcl
00139 # else
00140 cstring
00141 message ( char *fmt, ...)
00142 # endif
00143 {
00144 char c;
00145 int lastint = 0;
00146 char *ret = mstring_createEmpty ();
00147 char *ofmt = fmt;
00148 va_list pvar;
00149
00150 # if USEVARARGS
00151 va_start (pvar);
00152 # else
00153 va_start (pvar, fmt);
00154 # endif
00155
00156 while ((c = *fmt++) != '\0')
00157 {
00158 if (c == '%')
00159 {
00160
00161
00162 switch (identify_control (&fmt))
00163 {
00164 case XPERCENT:
00165 {
00166 ret = mstring_concatFree1 (ret, "%");
00167 break;
00168 }
00169 case XCHAR:
00170 {
00171
00172
00173
00174
00175
00176 char lc = (char) va_arg (pvar, int);
00177
00178 ret = mstring_append (ret, lc);
00179 break;
00180 }
00181 case XSTRING:
00182 {
00183 cstring s = va_arg (pvar, cstring);
00184
00185 if (modcode != 0)
00186 {
00187 ret = mstring_concatFree (ret, cstring_toCharsSafe
00188 (cstring_fill (s, modcode)));
00189 }
00190 else
00191 {
00192 if (cstring_isDefined (s))
00193 {
00194 ret = mstring_concatFree1 (ret, cstring_toCharsSafe (s));
00195 }
00196 }
00197 }
00198 break;
00199 case XSTRINGFREE:
00200 case XTSTRINGFREE:
00201 {
00202 cstring s = va_arg (pvar, cstring);
00203
00204 if (modcode != 0)
00205 {
00206 ret = mstring_concatFree (ret, cstring_toCharsSafe
00207 (cstring_fill (s, modcode)));
00208 }
00209 else
00210 {
00211 if (cstring_isDefined (s))
00212 {
00213 ret = mstring_concatFree
00214 (ret, cstring_toCharsSafe (s));
00215 }
00216 }
00217 }
00218 break;
00219 case XREPREFIX:
00220 lastint = va_arg (pvar, int);
00221
00222 if (lastint != 0)
00223 {
00224 ret = mstring_concatFree1 (ret, "re");
00225 }
00226 break;
00227 case XPLURAL:
00228 if (lastint != 1)
00229 {
00230 ret = mstring_concatFree1 (ret, "s");
00231 }
00232 break;
00233 case XINT:
00234 lastint = va_arg (pvar, int);
00235 ret = mstring_concatFree (ret, GETPRINTF ("%d", lastint));
00236 break;
00237 case XFLOAT:
00238 ret = mstring_concatFree (ret, GETPRINTF ("%e", va_arg (pvar, double)));
00239 break;
00240 case XBOOL:
00241 ret = mstring_concatFree1 (ret, cstring_toCharsSafe
00242 (bool_unparse (va_arg (pvar, bool))));
00243 break;
00244 case XUENTRY:
00245 ret = mstring_concatFree (ret, cstring_toCharsSafe
00246 (uentry_unparse (va_arg (pvar, uentry))));
00247 break;
00248 case XCTYPE:
00249
00250 ret = mstring_concatFree1 (ret, cstring_toCharsSafe
00251 (ctype_unparse (va_arg (pvar, ctype))));
00252 break;
00253 case XFILELOC:
00254 ret = mstring_concatFree (ret, cstring_toCharsSafe
00255 (fileloc_unparse (va_arg (pvar, fileloc))));
00256 break;
00257 case XINVALID:
00258 default:
00259 llcontbug (cstring_makeLiteral ("message: bad control flag"));
00260 fprintf (stdout, "\tFormat string: %s", ofmt);
00261 }
00262
00263 }
00264 else
00265 {
00266 ret = mstring_append (ret, c);
00267 }
00268 }
00269
00270 va_end (pvar);
00271
00272
00273
00274
00275
00276 return (cstring_fromChars (ret));
00277 }