chiark / gitweb /
Import upstream sources.
[cparse] / dump.c
CommitLineData
3cd4b0f8
MW
1#include "cparse.h"
2#include <ctype.h>
3
4#define INDENT 2
5#define CASEIND 1
6#define MARGIN 72
7
8struct dump_state {
9 FILE *fp;
10 int last;
11 int y;
12 const char *path;
13 int line;
14 int locations;
15};
16
17static int dump_string(dump_state *dump,
18 const char *s,
19 int l,
20 int q);
21
22dump_state *dump_new(FILE *fp) {
23 dump_state *dump = xmalloc(sizeof *dump);
24 dump->fp = fp;
25 dump->locations = 1;
26 return dump;
27}
28
29void dump_locations(struct dump_state *dump, int flag) {
30 dump->locations = flag;
31}
32
33static int location(dump_state *dump, const struct location *l, int ind) {
34 int change_path = 0, change_line = 0;
35
36 if(!dump->path
37 || strcmp(dump->path, l->path))
38 change_path = 1;
39 else if(dump->line != l->line)
40 change_line = 1;
41 else if(dump->y > MARGIN)
42 change_line = 1;
43 else
44 return 0;
45 if(change_line && l->line > dump->line && l->line - dump->line < 5) {
46 while(dump->line < l->line) {
47 if(fputc('\n', dump->fp) < 0) return -1;
48 ++dump->line;
49 }
50 } else {
51 if(dump->y)
52 if(fputc('\n', dump->fp) < 0) return -1;
53 if(dump->locations) {
54 if(fprintf(dump->fp, "# %d", l->line) < 0) return -1;
55 if(change_path) {
56 if(fputc(' ', dump->fp) < 0) return -1;
57 if(dump_string(dump, l->path, 0, '"')) return -1;
58 }
59 if(fputc('\n', dump->fp) < 0) return -1;
60 }
61 dump->path = l->path;
62 dump->line = l->line;
63 }
64 dump->y = 0;
65 if(fprintf(dump->fp, "%*s", ind, "") < 0) return -1;
66 dump->last = ' ';
67 return 0;
68}
69
70static int word(dump_state *dump, const char *w) {
71 int force_space_before = 1;
72 switch(dump->last) {
73 case '.':
74 case MEMBER:
75 case INCR:
76 case DECR:
77 case '(':
78 case '[':
79 case ' ':
80 case 0:
81 force_space_before = 0;
82 break;
83 }
84 if(force_space_before) {
85 if(fputc(' ', dump->fp) < 0) return -1;
86 ++dump->y;
87 }
88 if(fputs(w, dump->fp) < 0) return -1;
89 dump->y += strlen(w);
90 dump->last = ID;
91 return 0;
92}
93
94static int punc(dump_state *dump, int c) {
95 const char *s = 0;
96 int force_space_before = 1;
97
98 switch(c) {
99 case SIZEOF:
100 s = "sizeof";
101 break;
102 case MEMBER:
103 force_space_before = (dump->last == '-');
104 s = "->";
105 break;
106 case INCR:
107 force_space_before = (dump->last == '+');
108 s = "++";
109 break;
110 case DECR:
111 force_space_before = (dump->last == '-');
112 s = "--";
113 break;
114 case SL:
115 s = "<<";
116 break;
117 case SR:
118 s = ">>";
119 break;
120 case LE:
121 s = "<=";
122 break;
123 case GE:
124 s = ">=";
125 break;
126 case EQ:
127 s = "==";
128 break;
129 case NE:
130 s = "!=";
131 break;
132 case AND:
133 s = "&&";
134 break;
135 case OR:
136 s = "||";
137 break;
138 case VARARG:
139 s = "...";
140 break;
141 case MULEQ:
142 s = "*=";
143 break;
144 case DIVEQ:
145 s = "/=";
146 break;
147 case MODEQ:
148 s = "%=";
149 break;
150 case ADDEQ:
151 s = "+=";
152 break;
153 case SUBEQ:
154 s = "-=";
155 break;
156 case SLEQ:
157 s = "<<=";
158 break;
159 case SREQ:
160 s = ">>=";
161 break;
162 case ANDEQ:
163 s = "&=";
164 break;
165 case XOREQ:
166 s = "^=";
167 break;
168 case OREQ:
169 s = "|=";
170 break;
171 case '(':
172 if(dump->last == ',') break;
173 case ')':
174 case '[':
175 case ']':
176 case ',':
177 case ';':
178 case ':':
179 force_space_before = 0;
180 break;
181 }
182 if(force_space_before && dump->last && dump->last != ' ') {
183 if(fputc(' ', dump->fp) < 0) return -1;
184 ++dump->y;
185 }
186 if(s) {
187 if(fputs(s, dump->fp) < 0) return -1;
188 dump->y += strlen(s);
189 } else {
190 if(fputc(c, dump->fp) < 0) return -1;
191 ++dump->y;
192 }
193 switch(c) {
194 case '(':
195 case '[':
196 case ']':
197 dump->last = 0;
198 break;
199 default:
200 dump->last = c;
201 break;
202 }
203 return 0;
204}
205
206struct table {
207 unsigned bit;
208 const char *kw;
209};
210
211struct masktable {
212 unsigned mask, value;
213 const char *kw;
214};
215
216static const struct masktable type_specifier_table[] = {
217 { TS__BASIC, TS_VOID, "void" },
218 { TS__BASIC, TS_CHAR, "char" },
219 { TS__BASIC, TS_INT, "int" },
220 { TS__BASIC, TS_FLOAT, "float" },
221 { TS__BASIC, TS_DOUBLE, "double" },
222 { TS__BASIC, TS_BOOL, "_Bool" },
223 { TS__BASIC, TS_STRUCT, "struct" },
224 { TS__BASIC, TS_UNION, "union" },
225 { TS__BASIC, TS_ENUM, "enum" },
226 { TS__BASIC, TS_GCC_VA_LIST, "__builtin_va_list" },
227
228 { TS__CI, TS_COMPLEX, "_Complex" },
229 { TS__CI, TS_IMAGINARY, "_Imaginary" },
230
231 { TS__LENGTH, TS_SHORT, "short" },
232 { TS__LENGTH, TS_LONG, "long" },
233 { TS__LENGTH, TS_LONGLONG , "long long" },
234
235 { TS__SIGN, TS_SIGNED, "signed" },
236 { TS__SIGN, TS_UNSIGNED, "unsigned" },
237
238 { 0, 0, 0 }
239};
240
241static const struct table storage_class_specifier_table[] = {
242 { SCS_TYPEDEF, "typedef" },
243 { SCS_EXTERN, "extern" },
244 { SCS_STATIC, "static" },
245 { SCS_AUTO, "auto" },
246 { SCS_REGISTER, "register" },
247 { 0, 0 }
248};
249
250static const struct table type_qualifier_table[] = {
251 { TQ_CONST, "const" },
252 { TQ_VOLATILE, "volatile" },
253 { TQ_RESTRICT, RESTRICT_KW },
254 { 0, 0 }
255};
256
257static const struct table function_specifier_table[] = {
258 { FS_INLINE, "inline" },
259 { 0, 0 }
260};
261
262static int dump_on_bit(dump_state *dump,
263 unsigned u,
264 const struct table *t) {
265 int n;
266 for(n = 0; t[n].bit; ++n)
267 if(t[n].bit & u)
268 if(word(dump, t[n].kw)) return -1;
269 return 0;
270}
271
272int dump_declaration_specifiers(dump_state *dump,
273 const struct declaration_specifiers *ds,
274 int ind) {
275 struct declaration *d;
276 struct enumerator *e;
277 int offset;
278 size_t n;
279
280 if(dump_on_bit(dump, ds->storage_class_specifiers,
281 storage_class_specifier_table)) return -1;
282 if(dump_on_bit(dump, ds->function_specifiers, function_specifier_table))
283 return -1;
284 if(dump_on_bit(dump, ds->type_qualifiers, type_qualifier_table)) return -1;
285 for(n = 0; type_specifier_table[n].mask; ++n)
286 if((ds->type_specifiers & type_specifier_table[n].mask)
287 == type_specifier_table[n].value)
288 if(word(dump, type_specifier_table[n].kw)) return -1;
289 if(ds->name)
290 if(word(dump, ds->name)) return -1;
291 if(ds->type_specifiers & TS_DEFINITION) {
292 if(punc(dump, '{')) return -1;
293 switch(ds->type_specifiers & TS__BASIC) {
294 case TS_STRUCT:
295 case TS_UNION:
296 for(d = ds->structure; d; d = d->next)
297 if(dump_declaration(dump, d, ind + INDENT)) return -1;
298 break;
299 case TS_ENUM:
300 offset = dump->y;
301 if(ds->enumerators)
302 if(location(dump, &ds->enumerators->where, ind + INDENT)) return -1;
303 for(e = ds->enumerators; e; e = e->next) {
304 if(word(dump, e->name)) return -1;
305 if(e->value) {
306 if(punc(dump, '=')) return -1;
307 if(dump_expression(dump, e->value, ind + 2 * INDENT)) return -1;
308 }
309 if(e->next) {
310 if(punc(dump, ',')) return -1;
311 if(location(dump, &e->next->where, ind + INDENT)) return -1;
312 }
313 }
314 break;
315 }
316 if(punc(dump, '}')) return -1;
317 }
318 return 0;
319}
320
321static int dump_pointer_declarator(dump_state *dump,
322 const struct declarator *d,
323 const struct declarator_type *t,
324 int ind) {
325 if(t && t->type == dt_pointer) {
326 if(dump_pointer_declarator(dump, d, t->next, ind)) return -1;
327 if(punc(dump, '*')) return -1;
328 if(dump_on_bit(dump, t->type_qualifiers, type_qualifier_table))
329 return -1;
330 }
331 return 0;
332}
333
334static int dump_identifier_list(dump_state *dump,
335 const struct identifier_list *i) {
336 while(i) {
337 if(word(dump, i->id)) return -1;
338 if(i->next)
339 if(punc(dump, ',')) return -1;
340 i = i->next;
341 }
342 return 0;
343}
344
345static int dump_declaration_raw(dump_state *dump,
346 const struct declaration *d,
347 int ind) {
348 struct declarator *dc;
349
350 if(dump_declaration_specifiers(dump, d->declaration_specifiers, ind))
351 return -1;
352 for(dc = d->declarator_list; dc; dc = dc->next) {
353 /*if((dc->name || dc->type) && space(dump)) return -1;*/
354 if(dump_declarator(dump, dc, ind + INDENT))
355 return -1;
356 if(dc->next)
357 if(punc(dump, ',')) return -1;
358 }
359 return 0;
360}
361
362static int dump_parameter_list(dump_state *dump,
363 const struct declaration *p,
364 int ind) {
365 if(location(dump, &p->where, ind)) return -1;
366 while(p) {
367 if(dump_declaration_raw(dump, p, ind)) return -1;
368 if(p->next) {
369 if(punc(dump, ',')) return -1;
370 if(location(dump, &p->next->where, ind + INDENT)) return -1;
371 }
372 p = p->next;
373 }
374 return 0;
375}
376
377static int dump_declarator_type(dump_state *dump,
378 const struct declarator *d,
379 const struct declarator_type *t,
380 int ind) {
381 const struct declarator_type *u;
382 int offset;
383
384 /* C declarator syntax really bites */
385 if(t) {
386 switch(t->type) {
387 case dt_pointer:
388 for(u = t; u && u->type == dt_pointer; u = u->next)
389 ;
390 if(u) {
391 if(punc(dump, '(')) return -1;
392 if(dump_pointer_declarator(dump, d, t, ind + INDENT)) return -1;
393 if(dump_declarator_type(dump, d, 0, ind + INDENT)) return -1;
394 if(punc(dump, ')')) return -1;
395 if(dump_declarator_type(dump, 0, u, ind)) return -1;
396 } else {
397 if(dump_pointer_declarator(dump, d, t, ind)) return -1;
398 if(dump_declarator_type(dump, d, u, ind)) return -1;
399 }
400 break;
401 case dt_array:
402 if(dump_declarator_type(dump, d, t->next, ind)) return -1;
403 if(punc(dump, '[')) return -1;
404 if(dump_on_bit(dump, t->storage_class_specifiers,
405 storage_class_specifier_table)) return -1;
406 if(dump_on_bit(dump, t->type_qualifiers, type_qualifier_table))
407 return -1;
408 if(t->u.array.flags & AF_STAR) {
409 if(punc(dump, '*')) return -1;
410 } else if(t->u.array.size)
411 if(dump_expression(dump, t->u.array.size, ind + INDENT)) return -1;
412 if(punc(dump, ']')) return -1;
413 break;
414 case dt_old_function:
415 if(dump_declarator_type(dump, d, t->next, ind)) return -1;
416 if(punc(dump, '(')) return -1;
417 if(dump_identifier_list(dump, t->u.old_function.args))
418 return -1;
419 if(punc(dump, ')')) return -1;
420 break;
421 case dt_function:
422 if(dump_declarator_type(dump, d, t->next, ind)) return -1;
423 if(punc(dump, '(')) return -1;
424 offset = dump->y;
425 if(dump_parameter_list(dump, t->u.function.args, ind + INDENT)) return -1;
426 if(t->u.function.variadic) {
427 if(punc(dump, ',')) return -1;
428 if(punc(dump, VARARG)) return -1;
429 }
430 if(punc(dump, ')')) return -1;
431 break;
432 }
433 } else
434 if(d && d->name && word(dump, d->name)) return -1;
435 return 0;
436}
437
438int dump_declarator(dump_state *dump,
439 const struct declarator *d,
440 int ind) {
441 if(location(dump, &d->where, ind)) return -1;
442 if(dump_declarator_type(dump, d, d->declarator_type, ind)) return -1;
443 if(d->bits) {
444 if(punc(dump, ':')) return -1;
445 if(dump_expression(dump, d->bits, ind + INDENT)) return -1;
446 }
447 if(d->initializer) {
448 if(punc(dump, '=')) return -1;
449 if(dump_initializer(dump, d->initializer, ind + INDENT)) return -1;
450 }
451 return 0;
452}
453
454int dump_declaration(dump_state *dump,
455 const struct declaration *d,
456 int ind) {
457 if(location(dump, &d->where, ind)) return -1;
458 if(dump_declaration_raw(dump, d, ind)) return -1;
459 if(punc(dump, ';')) return -1;
460 return 0;
461}
462
463int dump_translation_unit(dump_state *dump,
464 const struct external_declaration *ed,
465 int ind) {
466 for(; ed; ed = ed->next)
467 switch(ed->type) {
468 case ed_declaration:
469 if(dump_declaration(dump, ed->u.declaration, ind)) return -1;
470 break;
471 case ed_function_definition:
472 if(dump_function_definition(dump, ed->u.function_definition, ind))
473 return -1;
474 break;
475 }
476 if(fputc('\n', dump->fp) < 0) return -1;
477 dump->y = 0;
478 ++dump->line;
479 return 0;
480}
481
482static int dump_string(dump_state *dump,
483 const char *s,
484 int l,
485 int q) {
486 if(dump->last)
487 if(fputc(' ', dump->fp) < 0) return -1;
488 if(l)
489 if(fputc(l, dump->fp) < 0) return -1;
490 if(fputc(q, dump->fp) < 0) return -1;
491 if(fputs(s, dump->fp) < 0) return -1;
492 if(fputc(q, dump->fp) < 0) return -1;
493 ++dump->y;
494 dump->last = '"';
495 return 0;
496}
497
498static int dump_expression_list(dump_state *dump,
499 const struct expression_list *l,
500 int ind) {
501 while(l) {
502 if(dump_expression(dump, l->e, ind)) return -1;
503 if(l->next)
504 if(punc(dump, ',')) return -1;
505 l = l->next;
506 }
507 return 0;
508}
509
510static int dump_initializer_list(dump_state *dump,
511 const struct initializer *i,
512 int ind) {
513 int offset;
514
515 if(punc(dump, '{')) return -1;
516 offset = dump->y;
517 while(i) {
518 if(dump_initializer(dump, i, ind + INDENT)) return -1;
519 if(i->next)
520 if(punc(dump, ',')) return -1;
521 i = i->next;
522 }
523 return punc(dump, '}');
524}
525
526int dump_initializer(dump_state *dump,
527 const struct initializer *i,
528 int ind) {
529 struct designator *d;
530
531 if(i->designator) {
532 for(d = i->designator; d; d = d->next) {
533 if(location(dump, &d->where, ind)) return -1;
534 switch(d->type) {
535 case des_expr:
536 if(punc(dump, '[')) return -1;
537 if(dump_expression(dump, d->u.expr, ind + INDENT)) return -1;
538 if(punc(dump, ']')) return -1;
539 break;
540 case des_field:
541 if(i->syntax == des_c99 || d != i->designator)
542 if(punc(dump, '.')) return -1;
543 if(word(dump, d->u.name)) return -1;
544 break;
545 }
546 }
547 switch(i->syntax) {
548 case des_c99:
549 if(punc(dump, '=')) return -1;
550 break;
551 case des_gcc_colon:
552 if(punc(dump, ':')) return -1;
553 break;
554 case des_gcc_raw:
555 break;
556 }
557 }
558 switch(i->type) {
559 case in_expr: return dump_expression(dump, i->u.expr, ind);
560 case in_list: return dump_initializer_list(dump, i->u.list, ind);
561 }
562 abort();
563}
564
565int dump_expression(dump_state *dump,
566 const struct expression *e,
567 int ind) {
568 switch(e->type) {
569 case ex_paren:
570 if(location(dump, &e->where, ind)) return -1;
571 if(punc(dump, '(')) return -1;
572 if(dump_expression(dump, e->u.unary, ind + INDENT)) return -1;
573 if(punc(dump, ')')) return -1;
574 break;
575 case ex_prefix:
576 if(location(dump, &e->where, ind)) return -1;
577 if(punc(dump, e->operator)) return -1;
578 if(dump_expression(dump, e->u.unary, ind + INDENT)) return -1;
579 break;
580 case ex_binary:
581 if(e->operator != '[') {
582 if(dump_expression(dump, e->u.binary.l, ind)) return -1;
583 if(location(dump, &e->where, ind)) return -1;
584 if(punc(dump, e->operator)) return -1;
585 if(dump_expression(dump, e->u.binary.r, ind + INDENT)) return -1;
586 } else {
587 if(dump_expression(dump, e->u.binary.l, ind)) return -1;
588 if(location(dump, &e->where, ind + INDENT)) return -1;
589 if(punc(dump, '[')) return -1;
590 if(dump_expression(dump, e->u.binary.r, ind + INDENT)) return -1;
591 if(punc(dump, ']')) return -1;
592 }
593 break;
594 case ex_postfix:
595 if(dump_expression(dump, e->u.unary, ind)) return -1;
596 if(location(dump, &e->where, ind)) return -1;
597 if(punc(dump, e->operator)) return -1;
598 break;
599 case ex_id:
600 if(location(dump, &e->where, ind)) return -1;
601 if(word(dump, e->u.name)) return -1;
602 break;
603 case ex_number:
604 if(location(dump, &e->where, ind)) return -1;
605 if(word(dump, e->u.constant)) return -1;
606 break;
607 case ex_char:
608 if(location(dump, &e->where, ind)) return -1;
609 if(dump_string(dump, e->u.constant, 0, '\''))
610 return -1;
611 break;
612 case ex_string:
613 if(location(dump, &e->where, ind)) return -1;
614 if(dump_string(dump, e->u.constant, 0, '"'))
615 return -1;
616 break;
617 case ex_wchar:
618 if(location(dump, &e->where, ind)) return -1;
619 if(dump_string(dump, e->u.constant, 'L', '\''))
620 return -1;
621 break;
622 case ex_wstring:
623 if(location(dump, &e->where, ind)) return -1;
624 if(dump_string(dump, e->u.constant, 'L', '"'))
625 return -1;
626 break;
627 case ex_fncall:
628 if(dump_expression(dump, e->u.fncall.fn, ind)) return -1;
629 if(location(dump, &e->where, ind)) return -1;
630 if(punc(dump, '(')) return -1;
631 if(dump_expression_list(dump, e->u.fncall.args, ind + INDENT))
632 return -1;
633 if(punc(dump, ')')) return -1;
634 break;
635 case ex_gcc_va_arg:
636 if(word(dump, "__builtin_va_arg")) return -1;
637 if(punc(dump, '(')) return -1;
638 if(dump_expression(dump, e->u.gcc_va_arg.arg, ind + INDENT))
639 return -1;
640 if(punc(dump, ',')) return -1;
641 if(dump_declaration_raw(dump, e->u.gcc_va_arg.type, ind + INDENT))
642 return -1;
643 if(punc(dump, ')')) return -1;
644 break;
645 case ex_gcc_expect:
646 if(word(dump, "__builtin_expect")) return -1;
647 if(punc(dump, '(')) return -1;
648 if(dump_expression(dump, e->u.binary.l, ind + INDENT))
649 return -1;
650 if(punc(dump, ',')) return -1;
651 if(dump_expression(dump, e->u.binary.r, ind + INDENT))
652 return -1;
653 if(punc(dump, ')')) return -1;
654 break;
655 case ex_compound_literal:
656 if(location(dump, &e->where, ind)) return -1;
657 if(punc(dump, '(')) return -1;
658 if(location(dump, &e->u.compound_literal.type->where, ind + INDENT))
659 return -1;
660 if(dump_declaration_raw(dump, e->u.compound_literal.type, ind + INDENT))
661 return -1;
662 if(punc(dump, ')')) return -1;
663 if(dump_initializer_list(dump, e->u.compound_literal.value,
664 ind + 2 * INDENT))
665 return -1;
666 break;
667 case ex_sizeof_type:
668 if(location(dump, &e->where, ind)) return -1;
669 if(word(dump, "sizeof")) return -1;
670 if(punc(dump, '(')) return -1;
671 if(location(dump, &e->u.type->where, ind + INDENT)) return -1;
672 if(dump_declaration_raw(dump, e->u.type, ind + 2 * INDENT)) return -1;
673 if(punc(dump, ')')) return -1;
674 break;
675 case ex_cast:
676 if(location(dump, &e->where, ind)) return -1;
677 if(punc(dump, '(')) return -1;
678 if(location(dump, &e->valuetype->where, ind + INDENT)) return -1;
679 if(dump_declaration_specifiers(dump, e->valuetype->declaration_specifiers,
680 ind))
681 return -1;
682 if(dump_declarator(dump, e->valuetype, ind + INDENT)) return -1;
683 if(punc(dump, ')')) return -1;
684 if(dump_expression(dump, e->u.cast, ind + 2 * INDENT)) return -1;
685 break;
686 case ex_implicit_conversion:
687 if(dump_expression(dump, e->u.cast, ind)) return -1;
688 break;
689 }
690 return 0;
691}
692
693int dump_function_definition(dump_state *dump,
694 const struct function_definition *fd,
695 int ind) {
696 const struct declaration *d;
697
698 if(location(dump, &fd->declaration->where, ind)) return -1;
699 if(dump_declaration_raw(dump, fd->declaration, ind)) return -1;
700 for(d = fd->args; d; d = d->next)
701 if(dump_declaration(dump, d, ind + INDENT)) return -1;
702 if(dump_statement(dump, fd->body, ind)) return -1;
703 return 0;
704}
705
706int dump_statement(dump_state *dump,
707 const struct statement *s,
708 int ind) {
709 const struct statement *ss;
710
711 switch(s->type) {
712 case st_label:
713 if(location(dump, &s->where, 0)) return -1;
714 break;
715 case st_case:
716 case st_default:
717 if(location(dump, &s->where, ind - CASEIND)) return -1;
718 break;
719 default:
720 if(location(dump, &s->where, ind)) return -1;
721 break;
722 }
723 switch(s->type) {
724 case st_label:
725 if(word(dump, s->u.label.label)) return -1;
726 if(punc(dump, ':')) return -1;
727 if(dump_statement(dump, s->u.label.body, ind)) return -1;
728 break;
729 case st_case:
730 if(word(dump, "case")) return -1;
731 if(dump_expression(dump, s->u.case_.value, ind + INDENT)) return -1;
732 if(punc(dump, ':')) return -1;
733 if(dump_statement(dump, s->u.case_.body, ind)) return -1;
734 break;
735 case st_default:
736 if(word(dump, "default")) return -1;
737 if(punc(dump, ':')) return -1;
738 if(dump_statement(dump, s->u.default_, ind)) return -1;
739 break;
740 case st_declaration:
741 if(dump_declaration(dump, s->u.declaration, ind + INDENT)) return -1;
742 break;
743 case st_expression:
744 if(s->u.expression && dump_expression(dump, s->u.expression, ind + INDENT))
745 return -1;
746 if(punc(dump, ';')) return -1;
747 break;
748 case st_if:
749 if(word(dump, "if")) return -1;
750 if(punc(dump, '(')) return -1;
751 if(dump_expression(dump, s->u.if_.cond, ind + INDENT))
752 return -1;
753 if(punc(dump, ')')) return -1;
754 if(dump_statement(dump, s->u.if_.true, ind + INDENT)) return -1;
755 if(s->u.if_.false) {
756 if(word(dump, "else")) return -1;
757 if(dump_statement(dump, s->u.if_.false, ind + INDENT)) return -1;
758 }
759 break;
760 case st_switch:
761 if(word(dump, "switch")) return -1;
762 if(punc(dump, '(')) return -1;
763 if(dump_expression(dump, s->u.switch_.cond, ind + INDENT))
764 return -1;
765 if(punc(dump, ')')) return -1;
766 if(dump_statement(dump, s->u.switch_.body, ind + INDENT)) return -1;
767 break;
768 case st_while:
769 if(word(dump, "while")) return -1;
770 if(punc(dump, '(')) return -1;
771 if(dump_expression(dump, s->u.while_.cond, ind + INDENT))
772 return -1;
773 if(punc(dump, ')')) return -1;
774 if(dump_statement(dump, s->u.while_.body, ind + INDENT)) return -1;
775 break;
776 case st_do:
777 if(word(dump, "do")) return -1;
778 if(dump_statement(dump, s->u.while_.body, ind + INDENT)) return -1;
779 if(word(dump, "while")) return -1;
780 if(punc(dump, '(')) return -1;
781 if(dump_expression(dump, s->u.while_.cond, ind + INDENT))
782 return -1;
783 if(punc(dump, ')')) return -1;
784 if(punc(dump, ';')) return -1;
785 break;
786 case st_for:
787 if(word(dump, "for")) return -1;
788 if(punc(dump, '(')) return -1;
789 if(s->u.for_.init && dump_expression(dump, s->u.for_.init, ind + INDENT))
790 return -1;
791 if(punc(dump, ';')) return -1;
792 if(s->u.for_.cond && dump_expression(dump, s->u.for_.cond, ind + INDENT))
793 return -1;
794 if(punc(dump, ';')) return -1;
795 if(s->u.for_.iter && dump_expression(dump, s->u.for_.iter, ind + INDENT))
796 return -1;
797 if(punc(dump, ')')) return -1;
798 if(dump_statement(dump, s->u.for_.body, ind + INDENT)) return -1;
799 break;
800 case st_for_declaration:
801 if(word(dump, "for")) return -1;
802 if(punc(dump, '(')) return -1;
803 if(s->u.for_declaration.init
804 && dump_declaration_raw(dump, s->u.for_declaration.init, ind + INDENT))
805 return -1;
806 if(punc(dump, ';')) return -1;
807 if(s->u.for_declaration.cond
808 && dump_expression(dump, s->u.for_declaration.cond, ind + INDENT))
809 return -1;
810 if(punc(dump, ';')) return -1;
811 if(s->u.for_declaration.iter
812 && dump_expression(dump, s->u.for_declaration.iter, ind + INDENT))
813 return -1;
814 if(punc(dump, ')')) return -1;
815 if(dump_statement(dump, s->u.for_declaration.body, ind + INDENT)) return -1;
816 break;
817 case st_goto:
818 if(word(dump, "goto")) return -1;
819 if(word(dump, s->u.goto_)) return -1;
820 if(punc(dump, ';')) return -1;
821 break;
822 case st_continue:
823 if(word(dump, "continue")) return -1;
824 if(punc(dump, ';')) return -1;
825 break;
826 case st_break:
827 if(word(dump, "break")) return -1;
828 if(punc(dump, ';')) return -1;
829 break;
830 case st_return:
831 if(word(dump, "return")) return -1;
832 if(s->u.expression && dump_expression(dump, s->u.expression, ind + INDENT))
833 return -1;
834 if(punc(dump, ';')) return -1;
835 break;
836 case st_compound:
837 if(ind == 0) ind = INDENT; /* top level */
838 if(punc(dump, '{')) return -1;
839 for(ss = s->u.compound.body; ss; ss = ss->next)
840 if(dump_statement(dump, ss, ind)) return -1;
841 if(location(dump, &s->u.compound.endwhere, ind - INDENT)) return -1;
842 if(punc(dump, '}')) return -1;
843 break;
844 }
845 return 0;
846}
847
848/*
849Local Variablesf:
850c-basic-offset:2
851comment-column:40
852End:
853*/