Mercurial > emacs
comparison src/doprnt.c @ 109358:a9586dc942d5
Merge from mainline.
author | Katsumi Yamaoka <katsumi@flagship2> |
---|---|
date | Mon, 12 Jul 2010 13:21:11 +0000 |
parents | e856a274549b |
children | 7ea64e427cb0 |
comparison
equal
deleted
inserted
replaced
109240:6f0915b37828 | 109358:a9586dc942d5 |
---|---|
57 A double counts as two arguments. | 57 A double counts as two arguments. |
58 String arguments are passed as C strings. | 58 String arguments are passed as C strings. |
59 Integers are passed as C integers. */ | 59 Integers are passed as C integers. */ |
60 | 60 |
61 int | 61 int |
62 doprnt (char *buffer, register int bufsize, char *format, char *format_end, int nargs, char **args) | 62 doprnt (char *buffer, register int bufsize, const char *format, |
63 const char *format_end, va_list ap) | |
63 { | 64 { |
64 int cnt = 0; /* Number of arg to gobble next */ | 65 const char *fmt = format; /* Pointer into format string */ |
65 register char *fmt = format; /* Pointer into format string */ | |
66 register char *bufptr = buffer; /* Pointer into output buffer.. */ | 66 register char *bufptr = buffer; /* Pointer into output buffer.. */ |
67 | 67 |
68 /* Use this for sprintf unless we need something really big. */ | 68 /* Use this for sprintf unless we need something really big. */ |
69 char tembuf[DBL_MAX_10_EXP + 100]; | 69 char tembuf[DBL_MAX_10_EXP + 100]; |
70 | 70 |
159 | 159 |
160 /* case 'b': */ | 160 /* case 'b': */ |
161 case 'd': | 161 case 'd': |
162 case 'o': | 162 case 'o': |
163 case 'x': | 163 case 'x': |
164 if (cnt == nargs) | |
165 error ("Not enough arguments for format string"); | |
166 if (sizeof (int) == sizeof (EMACS_INT)) | 164 if (sizeof (int) == sizeof (EMACS_INT)) |
167 ; | 165 ; |
168 else if (sizeof (long) == sizeof (EMACS_INT)) | 166 else if (sizeof (long) == sizeof (EMACS_INT)) |
169 /* Insert an `l' the right place. */ | 167 /* Insert an `l' the right place. */ |
170 string[1] = string[0], | 168 string[1] = string[0], |
171 string[0] = string[-1], | 169 string[0] = string[-1], |
172 string[-1] = 'l', | 170 string[-1] = 'l', |
173 string++; | 171 string++; |
174 else | 172 else |
175 abort (); | 173 abort (); |
176 sprintf (sprintf_buffer, fmtcpy, args[cnt++]); | 174 sprintf (sprintf_buffer, fmtcpy, va_arg(ap, char *)); |
177 /* Now copy into final output, truncating as nec. */ | 175 /* Now copy into final output, truncating as nec. */ |
178 string = (unsigned char *) sprintf_buffer; | 176 string = (unsigned char *) sprintf_buffer; |
179 goto doit; | 177 goto doit; |
180 | 178 |
181 case 'f': | 179 case 'f': |
182 case 'e': | 180 case 'e': |
183 case 'g': | 181 case 'g': |
184 { | 182 { |
185 union { double d; char *half[2]; } u; | 183 double d = va_arg(ap, double); |
186 if (cnt + 1 == nargs) | 184 sprintf (sprintf_buffer, fmtcpy, d); |
187 error ("Not enough arguments for format string"); | |
188 u.half[0] = args[cnt++]; | |
189 u.half[1] = args[cnt++]; | |
190 sprintf (sprintf_buffer, fmtcpy, u.d); | |
191 /* Now copy into final output, truncating as nec. */ | 185 /* Now copy into final output, truncating as nec. */ |
192 string = (unsigned char *) sprintf_buffer; | 186 string = (unsigned char *) sprintf_buffer; |
193 goto doit; | 187 goto doit; |
194 } | 188 } |
195 | 189 |
196 case 'S': | 190 case 'S': |
197 string[-1] = 's'; | 191 string[-1] = 's'; |
198 case 's': | 192 case 's': |
199 if (cnt == nargs) | |
200 error ("Not enough arguments for format string"); | |
201 if (fmtcpy[1] != 's') | 193 if (fmtcpy[1] != 's') |
202 minlen = atoi (&fmtcpy[1]); | 194 minlen = atoi (&fmtcpy[1]); |
203 string = (unsigned char *) args[cnt++]; | 195 string = va_arg(ap, unsigned char *); |
204 tem = strlen (string); | 196 tem = strlen (string); |
205 width = strwidth (string, tem); | 197 width = strwidth (string, tem); |
206 goto doit1; | 198 goto doit1; |
207 | 199 |
208 /* Copy string into final output, truncating if no room. */ | 200 /* Copy string into final output, truncating if no room. */ |
248 minlen = 0; | 240 minlen = 0; |
249 } | 241 } |
250 continue; | 242 continue; |
251 | 243 |
252 case 'c': | 244 case 'c': |
253 if (cnt == nargs) | 245 { |
254 error ("Not enough arguments for format string"); | 246 /* Sometimes for %c we pass a char, which would widen |
255 tem = CHAR_STRING ((int) (EMACS_INT) args[cnt], charbuf); | 247 to int. Sometimes we pass XFASTINT() or XINT() |
256 string = charbuf; | 248 values, which would be EMACS_INT. Let's hope that |
257 cnt++; | 249 both are passed the same way, otherwise we'll need |
258 string[tem] = 0; | 250 to rewrite callers. */ |
259 width = strwidth (string, tem); | 251 EMACS_INT chr = va_arg(ap, EMACS_INT); |
260 if (fmtcpy[1] != 'c') | 252 tem = CHAR_STRING ((int) chr, charbuf); |
261 minlen = atoi (&fmtcpy[1]); | 253 string = charbuf; |
262 goto doit1; | 254 string[tem] = 0; |
255 width = strwidth (string, tem); | |
256 if (fmtcpy[1] != 'c') | |
257 minlen = atoi (&fmtcpy[1]); | |
258 goto doit1; | |
259 } | |
263 | 260 |
264 case '%': | 261 case '%': |
265 fmt--; /* Drop thru and this % will be treated as normal */ | 262 fmt--; /* Drop thru and this % will be treated as normal */ |
266 } | 263 } |
267 } | 264 } |