このページを編集する際は,編集に関する方針に従ってください.[]
概要[]
- gcc-4.1.0/gcc/pretty-print.cにて定義
- text infoを元にフォーマットしバッファに入れる
引数[]
- pretty_printer *pp
- text_info *text
実装[]
203 /* Formatting phases 1 and 2: render TEXT->format_spec plus
204 TEXT->args_ptr into a series of chunks in PP->buffer->args[].
205 Phase 3 is in pp_base_format_text. */
206
207 void
208 pp_base_format (pretty_printer *pp, text_info *text)
209 {
210 output_buffer *buffer = pp->buffer;
211 const char *p;
212 const char **args;
213 struct chunk_info *new_chunk_array;
214
215 unsigned int curarg = 0, chunk = 0, argno;
216 pp_wrapping_mode_t old_wrapping_mode;
217 bool any_unnumbered = false, any_numbered = false;
218 const char **formatters[[[PP_NL_ARGMAX]]];
219
220 /* Allocate a new chunk structure. */
221 new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info);
222 new_chunk_array->prev = buffer->cur_chunk_array;
223 buffer->cur_chunk_array = new_chunk_array;
224 args = new_chunk_array->args;
225
226 /* Formatting phase 1: split up TEXT->format_spec into chunks in
227 PP->buffer->args[]. Even-numbered chunks are to be output
228 verbatim, odd-numbered chunks are format specifiers.
229 %m, %%, %<, %>, and %' are replaced with the appropriate text at
230 this point. */
231
232 memset (formatters, 0, sizeof formatters);
233
234 for (p = text->format_spec; *p; )
235 {
236 while (*p != '\0' && *p != '%')
237 {
238 obstack_1grow (&buffer->chunk_obstack, *p);
239 p++;
240 }
241
242 if (*p == '\0')
243 break;
244
%のときの処理
245 switch (*++p)
246 {
247 case '\0':
248 gcc_unreachable ();
249
250 case '%':
251 obstack_1grow (&buffer->chunk_obstack, '%');
252 p++;
253 continue;
254
255 case '<':
256 obstack_grow (&buffer->chunk_obstack,
257 open_quote, strlen (open_quote));
258 p++;
259 continue;
260
261 case '>':
262 case '\:
263 obstack_grow (&buffer->chunk_obstack,
264 close_quote, strlen (close_quote));
265 p++;
266 continue;
267
268 case 'm':
269 {
270 const char *errstr = xstrerror (text->err_no);
271 obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr));
272 }
273 p++;
274 continue;
275
276 default:
277 /* Handled in phase 2. Terminate the plain chunk here. */
278 obstack_1grow (&buffer->chunk_obstack, '\0');
279 gcc_assert (chunk < PP_NL_ARGMAX * 2);
280 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
281 break;
282 }
283
284 if (ISDIGIT (*p))
285 {
286 char *end;
287 argno = strtoul (p, &end, 10) - 1;
288 p = end;
289 gcc_assert (*p == '$');
290 p++;
291
292 any_numbered = true;
293 gcc_assert (!any_unnumbered);
294 }
295 else
296 {
297 argno = curarg++;
298 any_unnumbered = true;
299 gcc_assert (!any_numbered);
300 }
301 gcc_assert (argno < PP_NL_ARGMAX);
302 gcc_assert (!formatters[argno]);
303 formatters[argno] = &args[chunk];
304 do
305 {
306 obstack_1grow (&buffer->chunk_obstack, *p);
307 p++;
308 }
309 while (strchr ("qwl+#", p[-1]));
310
311 if (p[-1] == '.')
312 {
313 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
314 (where M == N + 1). */
315 if (ISDIGIT (*p))
316 {
317 do
318 {
319 obstack_1grow (&buffer->chunk_obstack, *p);
320 p++;
321 }
322 while (ISDIGIT (p[-1]));
323 gcc_assert (p[-1] == 's');
324 }
325 else
326 {
327 gcc_assert (*p == '*');
328 obstack_1grow (&buffer->chunk_obstack, '*');
329 p++;
330
331 if (ISDIGIT (*p))
332 {
333 char *end;
334 unsigned int argno2 = strtoul (p, &end, 10) - 1;
335 p = end;
336 gcc_assert (argno2 == argno - 1);
337 gcc_assert (!any_unnumbered);
338 gcc_assert (*p == '$');
339
340 p++;
341 formatters[argno2] = formatters[argno];
342 }
343 else
344 {
345 gcc_assert (!any_numbered);
346 formatters[argno+1] = formatters[argno];
347 curarg++;
348 }
349 gcc_assert (*p == 's');
350 obstack_1grow (&buffer->chunk_obstack, 's');
351 p++;
352 }
353 }
354 if (*p == '\0')
355 break;
356
357 obstack_1grow (&buffer->chunk_obstack, '\0');
358 gcc_assert (chunk < PP_NL_ARGMAX * 2);
359 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
360 }
361
362 obstack_1grow (&buffer->chunk_obstack, '\0');
363 gcc_assert (chunk < PP_NL_ARGMAX * 2);
364 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
365 args[chunk] = 0;
366
367 /* Set output to the argument obstack, and switch line-wrapping and
368 prefixing off. */
369 buffer->obstack = &buffer->chunk_obstack;
370 old_wrapping_mode = pp_set_verbatim_wrapping (pp);
371
372 /* Second phase. Replace each formatter with the formatted text it
373 corresponds to. */
374
375 for (argno = 0; formatters[argno]; argno++)
376 {
377 int precision = 0;
378 bool wide = false;
379 bool plus = false;
380 bool hash = false;
381 bool quote = false;
382
383 /* We do not attempt to enforce any ordering on the modifier
384 characters. */
385
386 for (p = *formatters[argno];; p++)
387 {
388 switch (*p)
389 {
390 case 'q':
391 gcc_assert (!quote);
392 quote = true;
393 continue;
394
395 case '+':
396 gcc_assert (!plus);
397 plus = true;
398 continue;
399
400 case '#':
401 gcc_assert (!hash);
402 hash = true;
403 continue;
404
405 case 'w':
406 gcc_assert (!wide);
407 wide = true;
408 continue;
409
410 case 'l':
411 /* We don't support precision beyond that of "long long". */
412 gcc_assert (precision < 2);
413 precision++;
414 continue;
415 }
416 break;
417 }
418
419 gcc_assert (!wide || precision == 0);
420
421 if (quote)
422 pp_string (pp, open_quote);
423
424 switch (*p)
425 {
426 case 'c':
427 pp_character (pp, va_arg (*text->args_ptr, int));
428 break;
429
430 case 'd':
431 case 'i':
432 if (wide)
433 pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
434 else
435 pp_integer_with_precision
436 (pp, *text->args_ptr, precision, int, "d");
437 break;
438
439 case 'o':
440 if (wide)
441 pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
442 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
443 else
444 pp_integer_with_precision
445 (pp, *text->args_ptr, precision, unsigned, "o");
446 break;
447
448 case 's':
449 pp_string (pp, va_arg (*text->args_ptr, const char *));
450 break;
451
452 case 'p':
453 pp_pointer (pp, va_arg (*text->args_ptr, void *));
454 break;
455
456 case 'u':
457 if (wide)
458 pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
459 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
460 else
461 pp_integer_with_precision
462 (pp, *text->args_ptr, precision, unsigned, "u");
463 break;
464
465 case 'x':
466 if (wide)
467 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
468 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
469 else
470 pp_integer_with_precision
471 (pp, *text->args_ptr, precision, unsigned, "x");
472 break;
473
474 case 'H':
475 {
476 location_t *locus = va_arg (*text->args_ptr, location_t *);
477 gcc_assert (text->locus != NULL);
478 *text->locus = *locus;
479 }
480 break;
481
482 case 'J':
483 {
484 tree t = va_arg (*text->args_ptr, tree);
485 gcc_assert (text->locus != NULL);
486 *text->locus = DECL_SOURCE_LOCATION (t);
487 }
488 break;
489
490 case '.':
491 {
492 int n;
493 const char *s;
494
495 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
496 (where M == N + 1). The format string should be verified
497 already from the first phase. */
498 p++;
499 if (ISDIGIT (*p))
500 {
501 char *end;
502 n = strtoul (p, &end, 10);
503 p = end;
504 gcc_assert (*p == 's');
505 }
506 else
507 {
508 gcc_assert (*p == '*');
509 p++;
510 gcc_assert (*p == 's');
511 n = va_arg (*text->args_ptr, int);
512
513 /* This consumes a second entry in the formatters array. */
514 gcc_assert (formatters[argno] == formatters[argno+1]);
515 argno++;
516 }
517
518 s = va_arg (*text->args_ptr, const char *);
519 pp_append_text (pp, s, s + n);
520 }
521 break;
522
523 default:
524 {
525 bool ok;
526
527 gcc_assert (pp_format_decoder (pp));
528 ok = pp_format_decoder (pp) (pp, text, p,
529 precision, wide, plus, hash);
530 gcc_assert (ok);
531 }
532 }
533
534 if (quote)
535 pp_string (pp, close_quote);
536
537 obstack_1grow (&buffer->chunk_obstack, '\0');
538 *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
539 }
540
541 #ifdef ENABLE_CHECKING
542 for (; argno < PP_NL_ARGMAX; argno++)
543 gcc_assert (!formatters[argno]);
544 #endif
545
546 /* Revert to normal obstack and wrapping mode. */
547 buffer->obstack = &buffer->formatted_obstack;
548 buffer->line_length = 0;
549 pp_wrapping_mode (pp) = old_wrapping_mode;
550 pp_clear_state (pp);
551 }