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
00029
00038 #include "ctrump/ast/ast.h"
00039 #include "ctrump/io/pretty-printer.h"
00040 #include "ctrump/common/abort.h"
00041 #include <stdlib.h>
00042 #include <stdarg.h>
00043 #include <string.h>
00044 #include "pprint-format.h"
00045 #include <ctype.h>
00046
00047 #define PRINT_STR_CONST(p,s) print_str(p, s, sizeof(s)-1)
00048 #define PRINT_STR_CONST_LOC(p,s,l) goto_loc(p,l); print_str(p, s, sizeof(s)-1)
00049
00053 struct printer {
00054 int indent;
00055 int cur_lineno;
00056 int cur_column;
00057 int line_begin;
00058 int use_column;
00059 int max_column;
00061 int print_internal_info;
00063 char *buffer;
00064 int content_len;
00065 int buf_len;
00067 int suspended;
00068 const char *filename;
00069 const struct ctrump_pprint_format *fmt;
00070 };
00071
00072 static void print_str(struct printer *p,
00073 const char *str,
00074 int strlen);
00075
00076 static void print_declspec(struct printer *p,
00077 const struct ctrump_decl_specifier *spec);
00078 static void print_declarator(struct printer *p,
00079 const struct ctrump_declarator *d);
00080 static void print_initializer_list(struct printer *p,
00081 const struct ctrump_initializer_list *il);
00082 static void print_initializer(struct printer *p,
00083 const struct ctrump_initializer *i);
00084 static void print_stmt(struct printer *p,
00085 const struct ctrump_stmt *stmt);
00086 static void print_decl(struct printer *p,
00087 const struct ctrump_decl *def);
00088 static void print_struct_decl(struct printer *p,
00089 const struct ctrump_struct_decl *decl);
00090 static void print_typespec(struct printer *p,
00091 const struct ctrump_typespec *spec);
00092 static void print_texpr(struct printer *p,
00093 const struct ctrump_texpr *texpr,
00094 int is_typename);
00095
00096 static void print_enum_list(struct printer *p,
00097 const struct ctrump_enum_list *el);
00098
00099 static void print_decl_with_init(struct printer *p,
00100 const struct ctrump_decl_with_init *d);
00101
00105 static void
00106 buf_reserve(struct printer *p,
00107 int len)
00108 {
00109 if (p->buf_len <= len) {
00110 p->buf_len *= 2;
00111 p->buffer = realloc(p->buffer, p->buf_len);
00112 }
00113 }
00114
00118 static void
00119 buf_putc(char c,
00120 struct printer *p)
00121 {
00122 buf_reserve(p, p->content_len+1);
00123 p->buffer[p->content_len] = c;
00124 p->content_len ++;
00125 }
00126
00130 static void
00131 print_newline(struct printer *p)
00132 {
00133 if (p->suspended) return;
00134
00135 buf_putc('\n', p);
00136
00137 p->cur_column = 1;
00138 p->line_begin = 1;
00139 p->cur_lineno += 1;
00140 }
00141
00142 static void
00143 print_newline_if_not_use_column(struct printer *p)
00144 {
00145 if (!p->use_column) {
00146 print_newline(p);
00147 }
00148 }
00149
00153 static void
00154 goto_bol(struct printer *p)
00155 {
00156 if (!p->line_begin) {
00157 print_newline(p);
00158 }
00159 }
00160
00164 static void
00165 goto_loc(struct printer *p,
00166 const struct ctrump_location *loc)
00167 {
00168 if (p->suspended) return;
00169
00170 if (p->use_column) {
00171 int cl = p->cur_lineno, col = p->cur_column;
00172 int tl = loc->lineno;
00173 for (; cl<tl; cl++) {
00174 print_newline(p);
00175 col = 1;
00176 }
00177
00178 tl = loc->column;
00179 if (tl > col) {
00180 for (; col<tl; col++) {
00181 buf_putc(' ', p);
00182 }
00183 p->cur_column = tl;
00184 }
00185 }
00186 }
00187
00191 static void
00192 print_str(struct printer *p,
00193 const char *str,
00194 int strlen)
00195 {
00196 int i;
00197
00198 if (p->suspended) return;
00199
00200 for (i=0; i<strlen; i++) {
00201 char c = str[i];
00202
00203 if (c == '\n') {
00204 print_newline(p);
00205 } else {
00206 if (p->line_begin) {
00207 if (!p->use_column) {
00208 int i;
00209 for (i=0; i<p->indent; i++) {
00210 buf_putc(' ', p);
00211 }
00212 p->cur_column = p->indent + 1;
00213 }
00214 p->line_begin = 0;
00215 }
00216 buf_putc(c, p);
00217 p->cur_column++;
00218 }
00219 }
00220 }
00221
00225 static void
00226 print_sint(struct printer *p,
00227 int val)
00228 {
00229 char buf[32];
00230 int len;
00231 len = snprintf(buf, 32, "%d", val);
00232 print_str(p, buf, len);
00233 }
00234
00238 static void
00239 print_source(struct printer *p,
00240 const struct ctrump_source_string *source)
00241 {
00242 print_str(p, source->chars, source->length);
00243 }
00244
00245
00249 static void
00250 print_sym(struct printer *p,
00251 const struct ctrump_symbol *sym)
00252 {
00253 print_str(p, sym->symstr, sym->symlen);
00254 }
00255
00259 static void
00260 delete_extra_space(struct printer *p)
00261 {
00262 if (p->buffer[p->content_len - 1] == ' ') {
00263 p->cur_column--;
00264 p->content_len--;
00265 }
00266 }
00267
00271 static void
00272 print_typename(struct printer *p,
00273 const struct ctrump_typename *typename)
00274 {
00275 PRINT_STR_CONST_LOC(p, "(", &typename->lpar_loc);
00276
00277 if (!p->use_column && p->fmt->padding_around_type_cast) {
00278 PRINT_STR_CONST(p, " ");
00279 }
00280
00281 print_declspec(p, &typename->spec);
00282 if (typename->abstract_decl->nodes.code == CTRUMP_DECLARATOR_EMPTY) {
00283 delete_extra_space(p);
00284 }
00285
00286 print_declarator(p, typename->abstract_decl);
00287
00288 if (!p->use_column && p->fmt->padding_around_type_cast) {
00289 PRINT_STR_CONST(p, " ");
00290 }
00291
00292 PRINT_STR_CONST_LOC(p, ")", &typename->rpar_loc);
00293 }
00294
00298 static __attribute__((unused)) void
00299 print_location_stderr(const struct ctrump_location *loc)
00300 {
00301 fprintf(stderr, "path= %s\n", loc->path);
00302 fprintf(stderr, "lineno= %d\t", loc->lineno);
00303 fprintf(stderr, "column= %d\n", loc->column);
00304 }
00305
00309 static void
00310 indent(struct printer *p)
00311 {
00312 if (!p->use_column) {
00313 p->indent += p->fmt->indentation_size;
00314 }
00315 }
00316
00320 static void
00321 dedent(struct printer *p)
00322 {
00323 if (!p->use_column) {
00324 p->indent -= p->fmt->indentation_size;
00325 }
00326 }
00327
00331 static void
00332 print_comma(struct printer *p)
00333 {
00334 PRINT_STR_CONST(p, ",");
00335 if (!p->use_column && p->fmt->space_after_comma) {
00336 PRINT_STR_CONST(p, " ");
00337 }
00338 }
00339
00340 static void
00341 print_space_before_statement_parens(struct printer *p)
00342 {
00343 if (!p->use_column && p->fmt->space_before_statement_parens) {
00344 PRINT_STR_CONST(p, " ");
00345 }
00346 }
00347
00348 static void
00349 print_space_before_braces(struct printer *p)
00350 {
00351 if (!p->use_column && p->fmt->space_before_braces) {
00352 PRINT_STR_CONST(p, " ");
00353 }
00354 }
00355
00356 static void
00357 print_space_before_brackets(struct printer *p)
00358 {
00359 if (!p->use_column && p->fmt->space_before_brackets) {
00360 PRINT_STR_CONST(p, " ");
00361 }
00362 }
00363
00364 static void
00365 print_space_around_assignment_op(struct printer *p)
00366 {
00367 if (!p->use_column && p->fmt->spaces_around_assignment_op) {
00368 PRINT_STR_CONST(p, " ");
00369 }
00370 }
00371
00372 static void
00373 print_padding_around_statement_parens(struct printer *p)
00374 {
00375 if (!p->use_column && p->fmt->padding_around_statement_parens) {
00376 PRINT_STR_CONST(p, " ");
00377 }
00378 }
00379
00380 static void
00381 print_padding_around_braces(struct printer *p)
00382 {
00383 if (!p->use_column && p->fmt->padding_around_braces) {
00384 PRINT_STR_CONST(p, " ");
00385 }
00386 }
00387 static void
00388 print_padding_around_brackets(struct printer *p)
00389 {
00390 if (!p->use_column && p->fmt->padding_around_brackets) {
00391 PRINT_STR_CONST(p, " ");
00392 }
00393 }
00394
00395 static void
00396 print_statement_lpar_loc(struct printer *p,
00397 const struct ctrump_location *loc)
00398 {
00399 print_space_before_statement_parens(p);
00400
00401 if (loc != NULL) goto_loc(p, loc);
00402 PRINT_STR_CONST(p, "(");
00403
00404 print_padding_around_statement_parens(p);
00405 }
00406
00407 static void
00408 print_statement_rpar_loc(struct printer *p,
00409 const struct ctrump_location *loc)
00410 {
00411 print_padding_around_statement_parens(p);
00412
00413 if (loc != NULL) goto_loc(p, loc);
00414 PRINT_STR_CONST(p, ")");
00415 }
00416
00417 static void
00418 print_lbracket_loc(struct printer *p,
00419 const struct ctrump_location *loc)
00420 {
00421 print_space_before_brackets(p);
00422
00423 if (loc != NULL) goto_loc(p, loc);
00424 PRINT_STR_CONST(p, "[");
00425
00426 print_padding_around_brackets(p);
00427 }
00428
00429 static void
00430 print_rbracket_loc(struct printer *p,
00431 const struct ctrump_location *loc)
00432 {
00433 print_padding_around_brackets(p);
00434
00435 if (loc != NULL) goto_loc(p, loc);
00436 PRINT_STR_CONST(p, "]");
00437 }
00438
00439
00440 static void
00441 print_expr(struct printer *p,
00442 const struct ctrump_expr *e)
00443 {
00444 int i, n;
00445
00446 switch (e->code) {
00447 case CTRUMP_EXPR_ARRREF:
00448 print_expr(p, e->u.arr_ref.array);
00449
00450 print_lbracket_loc(p, &e->u.arr_ref.lbr_loc);
00451 print_expr(p, e->u.arr_ref.subscript);
00452 print_rbracket_loc(p, &e->u.arr_ref.rbr_loc);
00453 break;
00454
00455 #define BIN_EXPR_STR(code,str) \
00456 case code: \
00457 print_expr(p, e->u.binary.lhs); \
00458 goto_loc(p, &e->u.binary.op_loc); \
00459 PRINT_STR_CONST(p, str); \
00460 print_expr(p, e->u.binary.rhs); \
00461 break
00462
00463 BIN_EXPR_STR(CTRUMP_EXPR_BIN_COMMA, ",");
00464
00465
00466 #define PRINT_EXPR_STR(code,str) \
00467 print_expr(p, e->u.binary.lhs); \
00468 goto_loc(p, &e->u.binary.op_loc); \
00469 PRINT_STR_CONST(p, str); \
00470 print_expr(p, e->u.binary.rhs);
00471 #define PRINT_EXPR_STR_ENCLOSED_IN_SPACE(code,str) \
00472 print_expr(p, e->u.binary.lhs); \
00473 PRINT_STR_CONST(p, " "); \
00474 goto_loc(p, &e->u.binary.op_loc); \
00475 PRINT_STR_CONST(p, str); \
00476 PRINT_STR_CONST(p, " "); \
00477 print_expr(p, e->u.binary.rhs);
00478
00479 #define BIN_EXPR_ASSIGN_OP(code,str) \
00480 case code: \
00481 if (!p->use_column && p->fmt->spaces_around_assignment_op) { \
00482 PRINT_EXPR_STR_ENCLOSED_IN_SPACE(code,str); \
00483 } else { \
00484 PRINT_EXPR_STR(code,str); \
00485 } \
00486 break
00487 #define BIN_EXPR_LOGICAL_OP(code,str) \
00488 case code: \
00489 if (!p->use_column && p->fmt->spaces_around_logical_op) { \
00490 PRINT_EXPR_STR_ENCLOSED_IN_SPACE(code,str); \
00491 } else { \
00492 PRINT_EXPR_STR(code,str); \
00493 } \
00494 break
00495 #define BIN_EXPR_RELATIONAL_OP(code,str) \
00496 case code: \
00497 if (!p->use_column && p->fmt->spaces_around_relational_op) { \
00498 PRINT_EXPR_STR_ENCLOSED_IN_SPACE(code,str); \
00499 } else { \
00500 PRINT_EXPR_STR(code,str); \
00501 } \
00502 break
00503 #define BIN_EXPR_BITWISE_OP(code,str) \
00504 case code: \
00505 if (!p->use_column && p->fmt->spaces_around_bitwise_op) { \
00506 PRINT_EXPR_STR_ENCLOSED_IN_SPACE(code,str); \
00507 } else { \
00508 PRINT_EXPR_STR(code,str); \
00509 } \
00510 break
00511 #define BIN_EXPR_MATH_OP(code,str) \
00512 case code: \
00513 if (!p->use_column && p->fmt->spaces_around_math_op) { \
00514 PRINT_EXPR_STR_ENCLOSED_IN_SPACE(code,str); \
00515 } else { \
00516 PRINT_EXPR_STR(code,str); \
00517 } \
00518 break
00519 #define BIN_EXPR_SHIFT_OP(code,str) \
00520 case code: \
00521 if (!p->use_column && p->fmt->spaces_around_shift_op) { \
00522 PRINT_EXPR_STR_ENCLOSED_IN_SPACE(code,str); \
00523 } else { \
00524 PRINT_EXPR_STR(code,str); \
00525 } \
00526 break
00527
00528
00529 BIN_EXPR_ASSIGN_OP (CTRUMP_EXPR_BIN_ASSIGN, "=");
00530 BIN_EXPR_ASSIGN_OP (CTRUMP_EXPR_BIN_ADD_ASSIGN, "+=");
00531 BIN_EXPR_ASSIGN_OP (CTRUMP_EXPR_BIN_SUB_ASSIGN, "-=");
00532 BIN_EXPR_ASSIGN_OP (CTRUMP_EXPR_BIN_MUL_ASSIGN, "*=");
00533 BIN_EXPR_ASSIGN_OP (CTRUMP_EXPR_BIN_DIV_ASSIGN, "/=");
00534 BIN_EXPR_ASSIGN_OP (CTRUMP_EXPR_BIN_MOD_ASSIGN, "%=");
00535 BIN_EXPR_ASSIGN_OP (CTRUMP_EXPR_BIN_BAND_ASSIGN, "&=");
00536 BIN_EXPR_ASSIGN_OP (CTRUMP_EXPR_BIN_BOR_ASSIGN, "|=");
00537 BIN_EXPR_ASSIGN_OP (CTRUMP_EXPR_BIN_BXOR_ASSIGN, "^=");
00538 BIN_EXPR_ASSIGN_OP (CTRUMP_EXPR_BIN_LSHIFT_ASSIGN, "<<=");
00539 BIN_EXPR_ASSIGN_OP (CTRUMP_EXPR_BIN_RSHIFT_ASSIGN, ">>=");
00540
00541 BIN_EXPR_LOGICAL_OP (CTRUMP_EXPR_BIN_LAND, "&&");
00542 BIN_EXPR_LOGICAL_OP (CTRUMP_EXPR_BIN_LOR, "||");
00543
00544 BIN_EXPR_RELATIONAL_OP (CTRUMP_EXPR_BIN_EQ, "==");
00545 BIN_EXPR_RELATIONAL_OP (CTRUMP_EXPR_BIN_NE, "!=");
00546 BIN_EXPR_RELATIONAL_OP (CTRUMP_EXPR_BIN_LT, "<");
00547 BIN_EXPR_RELATIONAL_OP (CTRUMP_EXPR_BIN_GT, ">");
00548 BIN_EXPR_RELATIONAL_OP (CTRUMP_EXPR_BIN_LE, "<=");
00549 BIN_EXPR_RELATIONAL_OP (CTRUMP_EXPR_BIN_GE, ">=");
00550
00551 BIN_EXPR_BITWISE_OP (CTRUMP_EXPR_BIN_BAND, "&");
00552 BIN_EXPR_BITWISE_OP (CTRUMP_EXPR_BIN_BOR, "|");
00553 BIN_EXPR_BITWISE_OP (CTRUMP_EXPR_BIN_BXOR, "^");
00554
00555 BIN_EXPR_MATH_OP (CTRUMP_EXPR_BIN_ADD, "+");
00556 BIN_EXPR_MATH_OP (CTRUMP_EXPR_BIN_SUB, "-");
00557 BIN_EXPR_MATH_OP (CTRUMP_EXPR_BIN_MUL, "*");
00558 BIN_EXPR_MATH_OP (CTRUMP_EXPR_BIN_DIV, "/");
00559 BIN_EXPR_MATH_OP (CTRUMP_EXPR_BIN_MOD, "%");
00560
00561 BIN_EXPR_SHIFT_OP (CTRUMP_EXPR_BIN_LSHIFT, "<<");
00562 BIN_EXPR_SHIFT_OP (CTRUMP_EXPR_BIN_RSHIFT, ">>");
00563
00564
00565 #define UNA_PRE_EXPR_STR(code,str) \
00566 case code: \
00567 PRINT_STR_CONST_LOC(p, str, &e->u.unary.op_loc); \
00568 print_expr(p, e->u.unary.expr); \
00569 break;
00570
00571 #define UNA_POST_EXPR_STR(code,str) \
00572 case code: \
00573 print_expr(p, e->u.unary.expr); \
00574 PRINT_STR_CONST_LOC(p, str, &e->u.unary.op_loc); \
00575 break;
00576
00577 UNA_PRE_EXPR_STR(CTRUMP_EXPR_UNA_PTRREF, "*");
00578 UNA_PRE_EXPR_STR(CTRUMP_EXPR_UNA_POS, "+");
00579 UNA_PRE_EXPR_STR(CTRUMP_EXPR_UNA_NEG, "-");
00580 UNA_PRE_EXPR_STR(CTRUMP_EXPR_UNA_PRE_INC, "++");
00581 UNA_PRE_EXPR_STR(CTRUMP_EXPR_UNA_PRE_DEC, "-");
00582 UNA_PRE_EXPR_STR(CTRUMP_EXPR_UNA_BCMPL, "~");
00583 UNA_PRE_EXPR_STR(CTRUMP_EXPR_UNA_ADDR, "&");
00584
00585 case CTRUMP_EXPR_UNA_LNEG:
00586 PRINT_STR_CONST_LOC(p, "!", &e->u.unary.op_loc);
00587 if (!p->use_column && p->fmt->space_after_negation) {
00588 PRINT_STR_CONST(p, " ");
00589 }
00590 print_expr(p, e->u.unary.expr);
00591 break;
00592
00593 case CTRUMP_EXPR_UNA_SIZEOF:
00594 if (e->u.unary.expr->code == CTRUMP_EXPR_PAREN) {
00595 PRINT_STR_CONST_LOC(p, "sizeof", &e->u.unary.op_loc);
00596 } else {
00597 PRINT_STR_CONST_LOC(p, "sizeof ", &e->u.unary.op_loc);
00598 }
00599 print_expr(p, e->u.unary.expr);
00600 break;
00601
00602 UNA_POST_EXPR_STR(CTRUMP_EXPR_UNA_POST_INC, "++");
00603 UNA_POST_EXPR_STR(CTRUMP_EXPR_UNA_POST_DEC, "--");
00604
00605 case CTRUMP_EXPR_PAREN:
00606 PRINT_STR_CONST_LOC(p,"(",&e->u.paren.lpar_loc);
00607 print_expr(p, e->u.paren.expr);
00608 PRINT_STR_CONST_LOC(p,")",&e->u.paren.rpar_loc);
00609 break;
00610
00611 case CTRUMP_EXPR_VARREF:
00612 goto_loc(p, &e->u.varref.loc);
00613 print_sym(p, e->u.varref.var->name);
00614 if (p->print_internal_info && e->u.varref.pdg) {
00615 PRINT_STR_CONST(p, "_");
00616 print_sint(p, e->u.varref.pdg->id);
00617 }
00618 break;
00619
00620 case CTRUMP_EXPR_SIZEOF_TYPE:
00621 PRINT_STR_CONST_LOC(p, "sizeof", &e->u.sizeof_type.sizeof_id_loc);
00622 print_typename(p, &e->u.sizeof_type.typename_);
00623 break;
00624
00625 case CTRUMP_EXPR_EMPTY:
00626 break;
00627
00628 case CTRUMP_EXPR_MEMBER_REF:
00629 print_expr(p, e->u.member_ref.obj_expr);
00630 PRINT_STR_CONST_LOC(p, ".", &e->u.member_ref.op_loc);
00631 goto_loc(p, &e->u.member_ref.symbol_loc);
00632 print_sym(p, e->u.member_ref.member_name);
00633 break;
00634
00635 case CTRUMP_EXPR_PTR_MEMBER_REF:
00636 print_expr(p, e->u.member_ref.obj_expr);
00637 PRINT_STR_CONST_LOC(p, "->", &e->u.member_ref.op_loc);
00638 goto_loc(p, &e->u.member_ref.symbol_loc);
00639 print_sym(p, e->u.member_ref.member_name);
00640 break;
00641
00642 case CTRUMP_EXPR_CALL:
00643 print_expr(p, e->u.call.func_expr);
00644 PRINT_STR_CONST_LOC(p, "(", &e->u.call.lpar_loc);
00645 n = e->u.call.num_args;
00646
00647 for (i=0; i<n; i++) {
00648 if (i != 0) {
00649 print_comma(p);
00650 }
00651 print_expr(p, &e->u.call.args[i]);
00652 }
00653
00654 PRINT_STR_CONST_LOC(p, ")", &e->u.call.rpar_loc);
00655 break;
00656
00657 case CTRUMP_EXPR_TEXT:
00658 print_str(p, e->u.text, strlen(e->u.text));
00659 break;
00660
00661 case CTRUMP_EXPR_CAST:
00662 print_typename(p, &e->u.cast.typename_);
00663 if (!p->use_column && p->fmt->space_after_type_cast) {
00664 PRINT_STR_CONST(p, " ");
00665 }
00666 print_expr(p, e->u.cast.expr);
00667 break;
00668
00669 case CTRUMP_EXPR_CONDITIONAL:
00670 print_expr(p, e->u.cond.cond);
00671
00672 if (!p->use_column && p->fmt->spaces_around_relational_op) {
00673 PRINT_STR_CONST(p, " ");
00674 }
00675
00676 PRINT_STR_CONST_LOC(p, "?", &e->u.cond.question_loc);
00677
00678 if (!p->use_column && p->fmt->spaces_around_relational_op) {
00679 PRINT_STR_CONST(p, " ");
00680 }
00681
00682 print_expr(p, e->u.cond.then_);
00683
00684 if (!p->use_column && p->fmt->spaces_around_relational_op) {
00685 PRINT_STR_CONST(p, " ");
00686 }
00687
00688 PRINT_STR_CONST_LOC(p, ":", &e->u.cond.colon_loc);
00689
00690 if (!p->use_column && p->fmt->spaces_around_relational_op) {
00691 PRINT_STR_CONST(p, " ");
00692 }
00693
00694 print_expr(p, e->u.cond.else_);
00695 break;
00696
00697 case CTRUMP_EXPR_IVTMP:
00698 print_expr(p, e->u.ivtmp.original_expr);
00699 break;
00700
00701 case CTRUMP_EXPR_IMPLICIT_CAST:
00702 if (p->print_internal_info) {
00703 PRINT_STR_CONST(p, "(");
00704 PRINT_STR_CONST(p, "implicit cast:");
00705 print_texpr(p, e->u.implicit_cast.cast_to, 1);
00706 PRINT_STR_CONST(p, ")");
00707 }
00708 print_expr(p, e->u.implicit_cast.expr);
00709 break;
00710
00711
00712 case CTRUMP_EXPR_STR_LITERAL:
00713 n = e->u.str_literal.num_str_literal;
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725 for (i=0; i<n; i++) {
00726 if (i != 0) {
00727 if (!p->use_column && p->fmt->spaces_around_relational_op) {
00728 PRINT_STR_CONST(p, " ");
00729 }
00730 }
00731 goto_loc(p, &e->u.str_literal.literals[i].loc);
00732 print_source(p, &e->u.str_literal.literals[i].literal);
00733 }
00734 break;
00735
00736 case CTRUMP_EXPR_FLOAT_LITERAL:
00737 goto_loc(p, &e->u.float_literal.loc);
00738 print_source(p, &e->u.float_literal.literal);
00739 break;
00740
00741 case CTRUMP_EXPR_DOUBLE_LITERAL:
00742 goto_loc(p, &e->u.double_literal.loc);
00743 print_source(p, &e->u.double_literal.literal);
00744 break;
00745
00746 case CTRUMP_EXPR_LONG_DOUBLE_LITERAL:
00747 goto_loc(p, &e->u.long_double_literal.loc);
00748 print_source(p, &e->u.long_double_literal.literal);
00749 break;
00750
00751 case CTRUMP_EXPR_SINT_LITERAL:
00752 goto_loc(p, &e->u.sint_literal.loc);
00753 print_source(p, &e->u.sint_literal.literal);
00754 break;
00755
00756 case CTRUMP_EXPR_SLONG_LITERAL:
00757 goto_loc(p, &e->u.slong_literal.loc);
00758 print_source(p, &e->u.slong_literal.literal);
00759 break;
00760
00761 case CTRUMP_EXPR_SLLONG_LITERAL:
00762 goto_loc(p, &e->u.sllong_literal.loc);
00763 print_source(p, &e->u.sllong_literal.literal);
00764 break;
00765
00766 case CTRUMP_EXPR_UINT_LITERAL:
00767 goto_loc(p, &e->u.uint_literal.loc);
00768 print_source(p, &e->u.uint_literal.literal);
00769 break;
00770
00771 case CTRUMP_EXPR_ULONG_LITERAL:
00772 goto_loc(p, &e->u.ulong_literal.loc);
00773 print_source(p, &e->u.ulong_literal.literal);
00774 break;
00775
00776 case CTRUMP_EXPR_ULLONG_LITERAL:
00777 goto_loc(p, &e->u.ullong_literal.loc);
00778 print_source(p, &e->u.ullong_literal.literal);
00779 break;
00780
00781 case CTRUMP_EXPR_INITIALIZER:
00782 print_typename(p, &e->u.initializer.typename_);
00783 print_initializer_list(p, &e->u.initializer.initializer);
00784 break;
00785
00786
00787 case CTRUMP_EXPR_MACRO_EXPAND:
00788 fprintf(stderr, "CTRUMP_EXPR_MACRO_EXPAND:\n");
00789 print_expr(p, e->u.macro_expand.expanded);
00790
00791 ctrump_fixme("CTRUMP_EXPR_MACRO_EXPAND:");
00792 break;
00793
00794 default:
00795 ctrump_unreachable("UNREACHABLE");
00796 break;
00797 }
00798 }
00799
00800 static void
00801 print_semicolon(struct printer *p)
00802 {
00803 PRINT_STR_CONST(p, ";");
00804 print_newline_if_not_use_column(p);
00805 }
00806
00807 static void
00808 print_brace_open(struct printer *p)
00809 {
00810 if (!p->use_column && p->fmt->indentation_before_left_brace) {
00811 indent(p);
00812 }
00813
00814 PRINT_STR_CONST(p, "{");
00815 print_newline_if_not_use_column(p);
00816 indent(p);
00817 }
00818
00819 static void
00820 print_brace_close(struct printer *p)
00821 {
00822 dedent(p);
00823 PRINT_STR_CONST(p, "}");
00824
00825 if (!p->use_column && p->fmt->indentation_before_left_brace) {
00826 dedent(p);
00827 }
00828 }
00829
00830 static void
00831 print_compound_stmt(struct printer *p,
00832 const struct ctrump_compound_stmt *c,
00833 char *context)
00834 {
00835 int i;
00836 int ni;
00837
00838 print_space_before_braces(p);
00839
00840 if (strcmp(context, "fundef") == 0) {
00841 if (!p->use_column && p->fmt->newline_after_declarator) {
00842 print_newline(p);
00843 }
00844 } else if (strcmp(context, "fundef-old-style") == 0) {
00845 print_newline_if_not_use_column(p);
00846 } else if (!p->use_column && p->fmt->newline_before_left_brace) {
00847 print_newline(p);
00848 }
00849
00850
00851 goto_loc(p, &c->lbr_loc);
00852 print_brace_open(p);
00853
00854 ni = c->num_item;
00855 for (i=0; i<ni; i++) {
00856 print_stmt(p, &c->items[i]);
00857 }
00858
00859 goto_loc(p, &c->rbr_loc);
00860 print_brace_close(p);
00861
00862 if (strcmp(context, "if-else") == 0) {
00863 if (!p->use_column && p->fmt->newline_after_right_brace) {
00864 print_newline(p);
00865 } else {
00866 print_space_before_braces(p);
00867 }
00868 } else if (strcmp(context, "do-while") == 0) {
00869 if (!p->use_column && p->fmt->newline_after_right_brace) {
00870 print_newline(p);
00871 } else {
00872 print_space_before_braces(p);
00873 }
00874 } else {
00875 print_newline_if_not_use_column(p);
00876 }
00877 }
00878
00879 static void
00880 print_stmt(struct printer *p,
00881 const struct ctrump_stmt *c)
00882 {
00883 tailcall:
00884 switch (c->code) {
00885
00886 case CTRUMP_STMT_DECL:
00887 print_decl(p, &c->u.decl);
00888 break;
00889
00890 case CTRUMP_STMT_FOR:
00891 PRINT_STR_CONST_LOC(p, "for", &c->u.for_.kwd_loc);
00892
00893 print_statement_lpar_loc(p, &c->u.for_.lpar_loc);
00894
00895 print_expr(p, &c->u.for_.init);
00896
00897 PRINT_STR_CONST_LOC(p, ";", &c->u.for_.semi_loc1);
00898 if (!p->use_column && p->fmt->space_after_semicolon) {
00899 PRINT_STR_CONST(p, " ");
00900 }
00901
00902 print_expr(p, &c->u.for_.cond);
00903
00904 PRINT_STR_CONST_LOC(p, ";", &c->u.for_.semi_loc2);
00905 if (!p->use_column && p->fmt->space_after_semicolon) {
00906 PRINT_STR_CONST(p, " ");
00907 }
00908
00909 print_expr(p, &c->u.for_.iter);
00910
00911 print_statement_rpar_loc(p, &c->u.for_.rpar_loc);
00912
00913 c = c->u.for_.body;
00914 if (c->code == CTRUMP_STMT_COMPOUND ||
00915 c->code == CTRUMP_STMT_LIST) {
00916 print_compound_stmt(p, &c->u.compound, "for");
00917 } else {
00918 print_newline_if_not_use_column(p);
00919 indent(p);
00920 print_stmt(p, c);
00921 dedent(p);
00922 }
00923 break;
00924
00925
00926 case CTRUMP_STMT_FOR_DECL:
00927
00928
00929
00930
00931
00932
00933
00934 PRINT_STR_CONST_LOC(p, "for", &c->u.for_decl.kwd_loc);
00935
00936 print_statement_lpar_loc(p, &c->u.for_decl.lpar_loc);
00937
00938 int i, nd;
00939 print_declspec(p, &c->u.for_decl.init.spec);
00940 nd = c->u.for_decl.init.num_decls;
00941 for (i=0; i<nd; i++) {
00942 if (i != 0) {
00943 print_comma(p);
00944 }
00945 print_decl_with_init(p, &c->u.for_decl.init.decls[i]);
00946 }
00947
00948 goto_loc(p, &c->u.for_decl.init.semi_loc);
00949 PRINT_STR_CONST(p, ";");
00950 if (!p->use_column && p->fmt->space_after_semicolon) {
00951 PRINT_STR_CONST(p, " ");
00952 }
00953
00954 print_expr(p, &c->u.for_decl.cond);
00955
00956 PRINT_STR_CONST_LOC(p, ";", &c->u.for_decl.semi_loc);
00957 if (!p->use_column && p->fmt->space_after_semicolon) {
00958 PRINT_STR_CONST(p, " ");
00959 }
00960
00961 print_expr(p, &c->u.for_decl.iter);
00962
00963 print_statement_rpar_loc(p, &c->u.for_decl.rpar_loc);
00964
00965 c = c->u.for_decl.body;
00966 if (c->code == CTRUMP_STMT_COMPOUND ||
00967 c->code == CTRUMP_STMT_LIST) {
00968 print_compound_stmt(p, &c->u.compound, "for");
00969 } else {
00970 print_newline_if_not_use_column(p);
00971 indent(p);
00972 print_stmt(p, c);
00973 dedent(p);
00974 }
00975 break;
00976
00977 case CTRUMP_STMT_COMPOUND:
00978 print_compound_stmt(p, &c->u.compound, "compound");
00979 break;
00980
00981 case CTRUMP_STMT_EXPR:
00982 print_expr(p, &c->u.expr.expr);
00983 goto_loc(p, &c->u.expr.semi_loc);
00984 print_semicolon(p);
00985 break;
00986
00987 case CTRUMP_STMT_EMPTY:
00988 goto_loc(p, &c->u.empty.semi_loc);
00989 print_semicolon(p);
00990 break;
00991
00992 case CTRUMP_STMT_NEWLINE:
00993 print_newline(p);
00994 break;
00995
00996 case CTRUMP_STMT_IF:
00997 PRINT_STR_CONST_LOC(p, "if", &c->u.if_.kwd_loc);
00998
00999 print_statement_lpar_loc(p, &c->u.if_.lpar_loc);
01000 print_expr(p, &c->u.if_.cond);
01001 print_statement_rpar_loc(p, &c->u.if_.rpar_loc);
01002
01003 c = c->u.if_.body;
01004 if (c->code == CTRUMP_STMT_COMPOUND) {
01005 print_compound_stmt(p, &c->u.compound, "if");
01006 } else {
01007 print_newline_if_not_use_column(p);
01008 indent(p);
01009 print_stmt(p, c);
01010 dedent(p);
01011 }
01012 break;
01013
01014 case CTRUMP_STMT_IF_ELSE:
01015 PRINT_STR_CONST_LOC(p, "if", &c->u.if_else.kwd_loc);
01016
01017 print_statement_lpar_loc(p, &c->u.if_else.lpar_loc);
01018 print_expr(p, &c->u.if_else.cond);
01019 print_statement_rpar_loc(p, &c->u.if_else.rpar_loc);
01020
01021 if (c->u.if_else.then_body->code == CTRUMP_STMT_COMPOUND) {
01022 print_compound_stmt(p, &c->u.if_else.then_body->u.compound, "if-else");
01023 } else {
01024 print_newline_if_not_use_column(p);
01025 indent(p);
01026 print_stmt(p, c->u.if_else.then_body);
01027 dedent(p);
01028 }
01029
01030
01031 PRINT_STR_CONST_LOC(p, "else", &c->u.if_else.else_loc);
01032
01033 if (c->u.if_else.else_body->code == CTRUMP_STMT_COMPOUND) {
01034 print_compound_stmt(p, &c->u.if_else.else_body->u.compound, "else");
01035 } else if (c->u.if_else.else_body->code == CTRUMP_STMT_IF_ELSE ||
01036 c->u.if_else.else_body->code == CTRUMP_STMT_IF) {
01037 PRINT_STR_CONST(p, " ");
01038 c = c->u.if_else.else_body;
01039 goto tailcall;
01040 } else {
01041 print_newline_if_not_use_column(p);
01042 indent(p);
01043 print_stmt(p, c->u.if_else.else_body);
01044 dedent(p);
01045 }
01046 break;
01047
01048 case CTRUMP_STMT_RETURN:
01049 PRINT_STR_CONST_LOC(p, "return", &c->u.return_.kwd_loc);
01050 goto_loc(p, &c->u.return_.semi_loc);
01051 print_semicolon(p);
01052
01053 break;
01054
01055 case CTRUMP_STMT_RETURN_EXPR:
01056 if (c->u.ret_expr.retval.code == CTRUMP_EXPR_PAREN) {
01057 PRINT_STR_CONST_LOC(p, "return", &c->u.ret_expr.kwd_loc);
01058 } else {
01059 PRINT_STR_CONST_LOC(p, "return ", &c->u.ret_expr.kwd_loc);
01060 }
01061 print_expr(p, &c->u.ret_expr.retval);
01062 goto_loc(p, &c->u.ret_expr.semi_loc);
01063 print_semicolon(p);
01064 break;
01065
01066 case CTRUMP_STMT_WHILE:
01067 PRINT_STR_CONST_LOC(p, "while", &c->u.while_.kwd_loc);
01068
01069 print_statement_lpar_loc(p, &c->u.while_.lpar_loc);
01070 print_expr(p, &c->u.while_.cond);
01071 print_statement_rpar_loc(p, &c->u.while_.rpar_loc);
01072
01073 c = c->u.while_.body;
01074 if (c->code == CTRUMP_STMT_COMPOUND) {
01075 print_compound_stmt(p, &c->u.compound, "while");
01076 } else {
01077 print_newline_if_not_use_column(p);
01078 indent(p);
01079 print_stmt(p, c);
01080 dedent(p);
01081 }
01082 break;
01083
01084 case CTRUMP_STMT_DO_WHILE:
01085 PRINT_STR_CONST_LOC(p, "do", &c->u.do_while.do_loc);
01086
01087 if (c->u.do_while.body->code == CTRUMP_STMT_COMPOUND) {
01088 print_compound_stmt(p, &c->u.do_while.body->u.compound, "do-while");
01089 } else {
01090 print_newline_if_not_use_column(p);
01091 indent(p);
01092 print_stmt(p, c->u.do_while.body);
01093 dedent(p);
01094 }
01095
01096 PRINT_STR_CONST_LOC(p, "while", &c->u.do_while.while_loc);
01097
01098 print_statement_lpar_loc(p, &c->u.do_while.lpar_loc);
01099 print_expr(p, &c->u.do_while.cond);
01100 print_statement_rpar_loc(p, &c->u.do_while.rpar_loc);
01101
01102 goto_loc(p, &c->u.do_while.semi_loc);
01103 print_semicolon(p);
01104 break;
01105
01106 case CTRUMP_STMT_GOTO:
01107 PRINT_STR_CONST_LOC(p, "goto ", &c->u.goto_.kwd_loc);
01108 goto_loc(p, &c->u.goto_.label_loc);
01109 print_sym(p, c->u.goto_.label);
01110 print_semicolon(p);
01111 break;
01112
01113 case CTRUMP_STMT_LABELED:
01114 goto_loc(p, &c->u.labeled.label_loc);
01115 dedent(p);
01116 print_sym(p, c->u.labeled.label_symbol);
01117 PRINT_STR_CONST_LOC(p, ":", &c->u.labeled.colon_loc);
01118 print_newline_if_not_use_column(p);
01119 indent(p);
01120 c = c->u.labeled.stmt;
01121 goto tailcall;
01122 break;
01123
01124 case CTRUMP_STMT_SWITCH:
01125 PRINT_STR_CONST_LOC(p, "switch", &c->u.switch_.kwd_loc);
01126
01127 print_statement_lpar_loc(p, &c->u.switch_.lpar_loc);
01128 print_expr(p, &c->u.switch_.cond);
01129 print_statement_rpar_loc(p, &c->u.switch_.rpar_loc);
01130
01131 c = c->u.switch_.body;
01132 if (c->code == CTRUMP_STMT_COMPOUND) {
01133 print_compound_stmt(p, &c->u.compound, "switch");
01134 } else {
01135 print_newline_if_not_use_column(p);
01136 indent(p);
01137 print_stmt(p, c);
01138 dedent(p);
01139 }
01140 break;
01141
01142 case CTRUMP_STMT_CASE:
01143 dedent(p);
01144 PRINT_STR_CONST_LOC(p, "case ", &c->u.case_.kwd_loc);
01145 print_expr(p, &c->u.case_.val);
01146 PRINT_STR_CONST_LOC(p, ":", &c->u.case_.colon_loc);
01147 print_newline_if_not_use_column(p);
01148 indent(p);
01149 c = c->u.case_.stmt;
01150 goto tailcall;
01151
01152 case CTRUMP_STMT_DEFAULT:
01153 dedent(p);
01154 PRINT_STR_CONST_LOC(p, "default", &c->u.default_.kwd_loc);
01155 PRINT_STR_CONST_LOC(p, ":", &c->u.default_.colon_loc);
01156 print_newline_if_not_use_column(p);
01157 indent(p);
01158 c = c->u.default_.stmt;
01159 goto tailcall;
01160
01161 case CTRUMP_STMT_CONTINUE:
01162 PRINT_STR_CONST_LOC(p, "continue", &c->u.continue_.kwd_loc);
01163 goto_loc(p, &c->u.continue_.semi_loc);
01164 print_semicolon(p);
01165 break;
01166
01167 case CTRUMP_STMT_BREAK:
01168 PRINT_STR_CONST_LOC(p, "break", &c->u.break_.kwd_loc);
01169 goto_loc(p, &c->u.break_.semi_loc);
01170 print_semicolon(p);
01171 break;
01172
01173
01174 case CTRUMP_STMT_PRAGMA:
01175 case CTRUMP_STMT_SLASLA_COMMENT:
01176 case CTRUMP_STMT_SLAAST_COMMENT:
01177 ctrump_fixme("Undefined print statement");
01178 break;
01179
01180
01181 case CTRUMP_STMT_IFDEF:
01182 case CTRUMP_STMT_ASM:
01183 case CTRUMP_STMT_DEFINE:
01184 case CTRUMP_STMT_UNDEF:
01185 ctrump_fixme("Postponed");
01186 break;
01187
01188 case CTRUMP_STMT_LIST:
01189 {
01190 int i, n = c->u.stmt_list.num_stmt;
01191
01192 for (i=0; i<n; i++) {
01193 print_stmt(p, &c->u.stmt_list.stmts[i]);
01194 }
01195 }
01196 break;
01197
01198 default:
01199 ctrump_unreachable("UNREACHABLE");
01200 break;
01201
01202 }
01203 }
01204
01205 static void print_ext_fundef(struct printer *p,
01206 const struct ctrump_fundef *def)
01207 {
01208 int i;
01209 int nod = def->num_oldstyle_declaration;
01210
01211 print_declspec(p, &def->decl_spec);
01212
01213 if (!p->use_column && p->fmt->newline_after_declspec) {
01214 print_newline(p);
01215 }
01216
01217 print_declarator(p, def->decl);
01218
01219 if (nod == 0) {
01220 print_compound_stmt(p, &def->body, "fundef");
01221 } else {
01222
01223
01224 print_newline_if_not_use_column(p);
01225 indent(p);
01226 for (i=0; i<nod; i++) {
01227 print_decl(p, &def->oldstyle_decl_list[i]);
01228 print_newline_if_not_use_column(p);
01229 }
01230 dedent(p);
01231
01232 print_compound_stmt(p, &def->body, "fundef-old-style");
01233 }
01234
01235 if (!p->use_column) {
01236 for (i=0; i<p->fmt->num_blank_lines_after_func; i++) {
01237 print_newline(p);
01238 }
01239 } else {
01240 print_newline_if_not_use_column(p);
01241 }
01242 }
01243
01244 static void
01245 print_qual_flags(struct printer *p, int flags)
01246 {
01247 if (flags & CTRUMP_QUAL_CONST) {
01248 PRINT_STR_CONST(p, "const ");
01249 }
01250 if (flags & CTRUMP_QUAL_RESTRICT) {
01251 PRINT_STR_CONST(p, "restrict ");
01252 }
01253 if (flags & CTRUMP_QUAL_VOLATILE) {
01254 PRINT_STR_CONST(p, "volatile ");
01255 }
01256 }
01257
01258 static void
01259 print_attr(struct printer *p,
01260 const struct ctrump_gccext_attribute *attr)
01261 {
01262 if (attr->aligned != CTRUMP_ALIGN_UNSPECIFIED) {
01263 PRINT_STR_CONST(p, "__attribute__((aligned(");
01264 print_sint(p, attr->aligned);
01265 PRINT_STR_CONST(p, "))) ");
01266 }
01267 }
01268
01269 static void
01270 print_record(struct printer *p,
01271 const struct ctrump_record_definition *def)
01272 {
01273 int i;
01274 int nd = def->num_decl;
01275
01276 print_space_before_braces(p);
01277 PRINT_STR_CONST_LOC(p, "{", &def->lbr_loc);
01278
01279 print_newline_if_not_use_column(p);
01280
01281 indent(p);
01282 for (i=0; i<nd; i++) {
01283 print_struct_decl(p, &def->decls[i]);
01284 goto_loc(p, &def->decls[i].semi_loc);
01285 print_semicolon(p);
01286 }
01287 dedent(p);
01288
01289 PRINT_STR_CONST_LOC(p, "}", &def->rbr_loc);
01290 print_space_before_braces(p);
01291
01292 print_attr(p, &def->attr);
01293 }
01294
01295 static void
01296 print_typespec(struct printer *p,
01297 const struct ctrump_typespec *spec)
01298 {
01299 switch (spec->code) {
01300 case CTRUMP_TYPESPEC_BUILTIN:
01301 print_str(p,
01302 spec->u.builtin.texpr->u.builtin.name,
01303 strlen(spec->u.builtin.texpr->u.builtin.name));
01304 PRINT_STR_CONST(p, " ");
01305 break;
01306 case CTRUMP_TYPESPEC_UNTYPED_SIGNED_INT:
01307 break;
01308 case CTRUMP_TYPESPEC_TYPEDEF_NAME:
01309 print_sym(p, spec->u.typedef_name.name);
01310 PRINT_STR_CONST(p, " ");
01311
01312 break;
01313 case CTRUMP_TYPESPEC_STRUCT_NAME:
01314 PRINT_STR_CONST_LOC(p, "struct ", &spec->u.struct_name.kwd_loc);
01315 print_sym(p, spec->u.struct_name.name);
01316 PRINT_STR_CONST(p, " ");
01317 break;
01318 case CTRUMP_TYPESPEC_STRUCT_DEFINITION:
01319 PRINT_STR_CONST_LOC(p, "struct ", &spec->u.struct_definition.kwd_loc);
01320 print_sym(p, spec->u.struct_definition.name);
01321 print_record(p, &spec->u.struct_definition.def);
01322 break;
01323 case CTRUMP_TYPESPEC_ANON_STRUCT_DEFINITION:
01324 PRINT_STR_CONST_LOC(p, "struct", &spec->u.anon_struct_definition.kwd_loc);
01325 print_record(p, &spec->u.anon_struct_definition.def);
01326 break;
01327
01328 case CTRUMP_TYPESPEC_UNION_NAME:
01329 PRINT_STR_CONST_LOC(p, "union ", &spec->u.union_name.kwd_loc);
01330 print_sym(p, spec->u.union_name.name);
01331 PRINT_STR_CONST(p, " ");
01332 break;
01333 case CTRUMP_TYPESPEC_UNION_DEFINITION:
01334 PRINT_STR_CONST_LOC(p, "union ", &spec->u.union_definition.kwd_loc);
01335 print_sym(p, spec->u.union_definition.name);
01336 print_record(p, &spec->u.union_definition.def);
01337 break;
01338 case CTRUMP_TYPESPEC_ANON_UNION_DEFINITION:
01339 PRINT_STR_CONST_LOC(p, "union", &spec->u.anon_union_definition.kwd_loc);
01340 print_record(p, &spec->u.anon_union_definition.def);
01341 break;
01342
01343 case CTRUMP_TYPESPEC_ENUM_NAME:
01344 PRINT_STR_CONST_LOC(p, "enum ", &spec->u.enum_name.kwd_loc);
01345 goto_loc(p, &spec->u.enum_name.name_loc);
01346 print_sym(p, spec->u.enum_name.name);
01347 PRINT_STR_CONST(p, " ");
01348 break;
01349 case CTRUMP_TYPESPEC_ENUM_DEFINITION:
01350 PRINT_STR_CONST_LOC(p, "enum ", &spec->u.enum_definition.kwd_loc);
01351 goto_loc(p, &spec->u.enum_definition.name_loc);
01352 print_sym(p, spec->u.enum_definition.name);
01353 print_enum_list(p, &spec->u.enum_definition.list);
01354 break;
01355 case CTRUMP_TYPESPEC_ANON_ENUM_DEFINITION:
01356 PRINT_STR_CONST_LOC(p, "enum", &spec->u.anon_enum_definition.kwd_loc);
01357 print_enum_list(p, &spec->u.anon_enum_definition.list);
01358 break;
01359
01360 default:
01361 ctrump_unreachable("UNREACHABLE");
01362 break;
01363 }
01364 }
01365
01366 static void
01367 print_declspec(struct printer *p,
01368 const struct ctrump_decl_specifier *spec)
01369 {
01370 goto_loc(p, &spec->begin);
01371 switch (spec->stor_class) {
01372 case CTRUMP_STOR_CLASS_EXTERN:
01373 PRINT_STR_CONST(p, "extern ");
01374 break;
01375 case CTRUMP_STOR_CLASS_STATIC:
01376 PRINT_STR_CONST(p, "static ");
01377 break;
01378 case CTRUMP_STOR_CLASS_REGISTER:
01379 PRINT_STR_CONST(p, "register ");
01380 break;
01381 case CTRUMP_STOR_CLASS_TYPEDEF:
01382 PRINT_STR_CONST(p, "typedef ");
01383 break;
01384
01385 default:
01386 break;
01387 }
01388
01389 if (spec->func_spec == CTRUMP_FUNC_SPEC_INLINE) {
01390 PRINT_STR_CONST(p, "inline ");
01391 }
01392
01393 print_qual_flags(p, spec->qual_flags);
01394 print_attr(p, &spec->attr);
01395 print_typespec(p, &spec->type_spec);
01396 }
01397
01398
01399 #define DECL_POINTER_PREC 1
01400 #define DECL_QUALIFIY_PREC 1
01401 #define DECL_ARRAY_PREC 2
01402 #define DECL_TYPELIST_PREC 3
01403
01404 static void
01405 print_decl_left(struct printer *p,
01406 const struct ctrump_declarator_node *n)
01407 {
01408 switch (n->code) {
01409 case CTRUMP_DECLARATOR_IDENTIFIER:
01410 goto_loc(p, &n->u.identifier.loc);
01411 print_sym(p, n->u.identifier.identifier);
01412 break;
01413
01414 case CTRUMP_DECLARATOR_EMPTY:
01415 break;
01416
01417 case CTRUMP_DECLARATOR_POINTER:
01418 PRINT_STR_CONST_LOC(p, "*", &n->u.pointer.star_loc);
01419 print_qual_flags(p, n->u.pointer.qual_flags);
01420 print_attr(p, &n->u.pointer.attr);
01421
01422 print_decl_left(p, n->u.pointer.decl);
01423 break;
01424
01425 case CTRUMP_DECLARATOR_ARRAY:
01426 print_decl_left(p, n->u.array.decl);
01427 break;
01428
01429 case CTRUMP_DECLARATOR_VARLEN_ARRAY:
01430 print_decl_left(p, n->u.varlen_array.decl);
01431 break;
01432
01433 case CTRUMP_DECLARATOR_INCOMPLETE_ARRAY:
01434 print_decl_left(p, n->u.incomplete_array.decl);
01435 break;
01436
01437 case CTRUMP_DECLARATOR_PARAM_TYPELIST:
01438 print_decl_left(p, n->u.param_typelist.decl);
01439 break;
01440
01441 case CTRUMP_DECLARATOR_PAREN:
01442 PRINT_STR_CONST_LOC(p, "(", &n->u.paren.lpar_loc);
01443 print_decl_left(p, n->u.paren.decl);
01444 break;
01445
01446
01447 case CTRUMP_DECLARATOR_PARAM_IDENTIFIER_LIST:
01448 print_decl_left(p, n->u.param_id_list.decl);
01449
01450 break;
01451
01452 default:
01453 ctrump_unreachable("UNREACHABLE");
01454 break;
01455 }
01456 }
01457
01458 static void
01459 print_decl_right(struct printer *p,
01460 const struct ctrump_declarator_node *n)
01461 {
01462 int i, na;
01463 switch (n->code) {
01464 case CTRUMP_DECLARATOR_IDENTIFIER:
01465 break;
01466
01467 case CTRUMP_DECLARATOR_EMPTY:
01468 break;
01469
01470 case CTRUMP_DECLARATOR_POINTER:
01471 print_decl_right(p, n->u.pointer.decl);
01472 break;
01473
01474 case CTRUMP_DECLARATOR_ARRAY:
01475 print_decl_right(p, n->u.array.decl);
01476
01477 print_lbracket_loc(p, &n->u.array.lbr_loc);
01478 print_qual_flags(p, n->u.array.qual_flags);
01479 print_expr(p, &n->u.array.size);
01480 print_rbracket_loc(p, &n->u.array.rbr_loc);
01481 break;
01482
01483 case CTRUMP_DECLARATOR_VARLEN_ARRAY:
01484 print_decl_right(p, n->u.varlen_array.decl);
01485
01486 print_lbracket_loc(p, &n->u.varlen_array.lbr_loc);
01487 print_qual_flags(p, n->u.varlen_array.qual_flags);
01488 PRINT_STR_CONST_LOC(p, "*", &n->u.varlen_array.star_loc);
01489 print_rbracket_loc(p, &n->u.varlen_array.rbr_loc);
01490 break;
01491
01492 case CTRUMP_DECLARATOR_INCOMPLETE_ARRAY:
01493 print_decl_right(p, n->u.incomplete_array.decl);
01494
01495 print_lbracket_loc(p, &n->u.incomplete_array.lbr_loc);
01496 print_qual_flags(p, n->u.incomplete_array.qual_flags);
01497 print_rbracket_loc(p, &n->u.incomplete_array.rbr_loc);
01498 break;
01499
01500 case CTRUMP_DECLARATOR_PARAM_TYPELIST:
01501 print_decl_right(p, n->u.param_typelist.decl);
01502 PRINT_STR_CONST_LOC(p, "(", &n->u.param_typelist.lpar_loc);
01503
01504 na = n->u.param_typelist.num_args;
01505 if (na == 0) {
01506 ;
01507 } else {
01508 if (!p->use_column && p->fmt->newline_after_decl_params) {
01509 int tab = p->indent;
01510 p->indent = p->cur_column-1;
01511
01512 for (i=0; i<na; i++) {
01513 if (i != 0) {
01514 PRINT_STR_CONST(p, ",");
01515 print_newline(p);
01516 }
01517 print_declspec(p, &n->u.param_typelist.args[i].decl_spec);
01518 print_declarator(p, n->u.param_typelist.args[i].decl);
01519 }
01520 if (n->u.param_typelist.has_unspecified_arg) {
01521 print_comma(p);
01522 PRINT_STR_CONST(p, "...");
01523 }
01524
01525 p->indent = tab;
01526 } else {
01527 for (i=0; i<na; i++) {
01528 if (i != 0) {
01529 goto_loc(p, &n->u.param_typelist.args[i].left_comma_loc);
01530 print_comma(p);
01531 }
01532 print_declspec(p, &n->u.param_typelist.args[i].decl_spec);
01533 print_declarator(p, n->u.param_typelist.args[i].decl);
01534 }
01535 if (n->u.param_typelist.has_unspecified_arg) {
01536 goto_loc(p, &n->u.param_typelist.unspec_comma_loc);
01537 print_comma(p);
01538 PRINT_STR_CONST_LOC(p, "...", &n->u.param_typelist.unspec_arg_loc);
01539 }
01540 }
01541 }
01542
01543 delete_extra_space(p);
01544 PRINT_STR_CONST_LOC(p, ")", &n->u.param_typelist.rpar_loc);
01545 break;
01546
01547 case CTRUMP_DECLARATOR_PAREN:
01548 print_decl_right(p, n->u.paren.decl);
01549 PRINT_STR_CONST_LOC(p, ")", &n->u.paren.rpar_loc);
01550 break;
01551
01552
01553 case CTRUMP_DECLARATOR_PARAM_IDENTIFIER_LIST:
01554 PRINT_STR_CONST_LOC(p, "(", &n->u.param_id_list.lpar_loc);
01555 na = n->u.param_id_list.num_args;
01556 for (i=0; i<na; i++) {
01557 if (i != 0) {
01558 goto_loc(p, &n->u.param_id_list.identifiers[i].comma_loc);
01559 print_comma(p);
01560 }
01561 goto_loc(p, &n->u.param_id_list.identifiers[i].id_loc);
01562 print_sym(p, n->u.param_id_list.identifiers[i].name);
01563 }
01564 PRINT_STR_CONST_LOC(p, ")", &n->u.param_id_list.rpar_loc);
01565
01566 break;
01567
01568 default:
01569 ctrump_unreachable("UNREACHABLE");
01570 break;
01571 }
01572 }
01573
01574
01575 static void
01576 print_declarator(struct printer *p,
01577 const struct ctrump_declarator *d)
01578 {
01579 print_decl_left(p, &d->nodes);
01580 print_decl_right(p, &d->nodes);
01581 print_attr(p, &d->attr);
01582 }
01583
01584 static void
01585 print_ctrump_designator(struct printer *p,
01586 const struct ctrump_designator *d)
01587 {
01588 switch (d->code) {
01589
01590 case CTRUMP_DESIGNATOR_INDEX:
01591 print_lbracket_loc(p, &d->u.index.lbr_loc);
01592 print_expr(p, d->u.index.index);
01593 print_rbracket_loc(p, &d->u.index.rbr_loc);
01594 break;
01595
01596 case CTRUMP_DESIGNATOR_IDENT:
01597 PRINT_STR_CONST_LOC(p, ".", &d->u.ident.dot_loc);
01598 goto_loc(p, &d->u.ident.name_loc);
01599 print_sym(p, d->u.ident.ident);
01600 break;
01601
01602 default:
01603 ctrump_unreachable("UNREACHABLE");
01604 break;
01605 }
01606 }
01607
01608 static void
01609 print_initializer_list(struct printer *p,
01610 const struct ctrump_initializer_list *il)
01611 {
01612 int i;
01613 int j;
01614 int ne;
01615 int nd;
01616
01617 print_space_before_braces(p);
01618 PRINT_STR_CONST_LOC(p, "{", &il->lbr_loc);
01619 print_padding_around_braces(p);
01620
01621 ne = il->num_elem;
01622 for (i=0; i<ne; i++) {
01623 if (i != 0) {
01624 goto_loc(p, &il->elems[i].left_comma_loc);
01625 print_comma(p);
01626 }
01627
01628 nd = il->elems[i].num_designator;
01629 for (j=0; j<nd; j++) {
01630 print_ctrump_designator(p, &il->elems[i].designators_list[j]);
01631 }
01632
01633 if (nd != 0) {
01634 print_space_around_assignment_op(p);
01635 PRINT_STR_CONST_LOC(p, "=", &il->elems[i].eq_loc);
01636 print_space_around_assignment_op(p);
01637 }
01638
01639 print_initializer(p, &il->elems[i].initializer);
01640 }
01641
01642 if (il->hints_for_printer == CTRUMP_INITIALIZER_HAVE_LAST_COMMA) {
01643 goto_loc(p, &il->last_comma_loc);
01644 print_comma(p);
01645 }
01646
01647 print_padding_around_braces(p);
01648 PRINT_STR_CONST_LOC(p, "}", &il->rbr_loc);
01649 }
01650
01651 static void
01652 print_initializer(struct printer *p,
01653 const struct ctrump_initializer *i)
01654 {
01655 switch (i->code) {
01656 case CTRUMP_INITIALIZER_EMPTY:
01657 ;
01658 break;
01659
01660 case CTRUMP_INITIALIZER_EXPR:
01661 print_expr(p, i->u.expr);
01662 break;
01663
01664 case CTRUMP_INITIALIZER_NESTED:
01665 print_initializer_list(p, i->u.nest);
01666 break;
01667
01668 default:
01669 ctrump_unreachable("UNREACHABLE");
01670 break;
01671 }
01672 }
01673
01674 static void
01675 print_decl_with_init(struct printer *p,
01676 const struct ctrump_decl_with_init *d)
01677 {
01678 print_declarator(p, d->decl);
01679
01680 switch (d->initializer.code) {
01681 case CTRUMP_INITIALIZER_EMPTY:
01682 break;
01683
01684 case CTRUMP_INITIALIZER_EXPR:
01685 case CTRUMP_INITIALIZER_NESTED:
01686 print_space_around_assignment_op(p);
01687 PRINT_STR_CONST_LOC(p, "=", &d->eq_loc);
01688 print_space_around_assignment_op(p);
01689
01690 print_initializer(p, &d->initializer);
01691 break;
01692 }
01693 }
01694
01695 static void
01696 print_decl(struct printer *p,
01697 const struct ctrump_decl *decl)
01698 {
01699 int i, nd;
01700
01701 print_declspec(p, &decl->spec);
01702
01703 nd = decl->num_decls;
01704 for (i=0; i<nd; i++) {
01705 if (i != 0) {
01706 print_comma(p);
01707 }
01708 print_decl_with_init(p, &decl->decls[i]);
01709 }
01710
01711 goto_loc(p, &decl->semi_loc);
01712 print_semicolon(p);
01713
01714 switch (decl->spec.type_spec.code) {
01715 case CTRUMP_TYPESPEC_STRUCT_DEFINITION:
01716 case CTRUMP_TYPESPEC_UNION_DEFINITION:
01717 case CTRUMP_TYPESPEC_ANON_STRUCT_DEFINITION:
01718 case CTRUMP_TYPESPEC_ANON_UNION_DEFINITION:
01719 case CTRUMP_TYPESPEC_ENUM_DEFINITION:
01720 case CTRUMP_TYPESPEC_ANON_ENUM_DEFINITION:
01721 print_newline_if_not_use_column(p);
01722 break;
01723 default:
01724 break;
01725 }
01726 }
01727
01728 static void
01729 print_struct_declarator(struct printer *p,
01730 const struct ctrump_struct_declarator *declarator)
01731 {
01732 if (declarator->decl)
01733 print_declarator(p, declarator->decl);
01734
01735 if (declarator->bitfield_expr) {
01736 goto_loc(p, &declarator->colon_loc);
01737 PRINT_STR_CONST(p, ":");
01738 print_expr(p, declarator->bitfield_expr);
01739 }
01740 }
01741
01742 static void
01743 print_struct_decl(struct printer *p,
01744 const struct ctrump_struct_decl *decl)
01745 {
01746 int i, nd;
01747
01748 if (decl->code == CTRUMP_STRUCT_DECL_FIELDS) {
01749 print_declspec(p, &decl->u.decl.spec);
01750
01751 nd = decl->u.decl.num_decls;
01752 for (i=0; i<nd; i++) {
01753 if (i != 0) {
01754 print_comma(p);
01755 }
01756 print_struct_declarator(p, &decl->u.decl.decls[i]);
01757 }
01758 }
01759 }
01760
01761
01762 static void
01763 pprint_tree(struct printer *p,
01764 const struct ctrump_translation_unit *t)
01765 {
01766 int i;
01767 int n = t->num_decl;
01768 struct ctrump_extdecl *decls = t->decls;
01769
01770 for (i=0; i<n; i++) {
01771 goto_loc(p, &decls[i].loc);
01772 switch (decls[i].code) {
01773 case CTRUMP_EXT_FUNCTION_DEFINITION:
01774 print_ext_fundef(p, &decls[i].u.func_def);
01775 break;
01776 case CTRUMP_EXT_OBJECT_DEFINITION:
01777 print_decl(p, &decls[i].u.obj_def);
01778 break;
01779 case CTRUMP_EXT_EMPTY_DEFINITION:
01780 print_semicolon(p);
01781 break;
01782 case CTRUMP_EXT_SLASLA_COMMENT:
01783 case CTRUMP_EXT_SLAAST_COMMENT:
01784 print_source(p, &decls[i].source_text);
01785 break;
01786
01787 case CTRUMP_EXT_INCLUDE_PATH:
01788 goto_bol(p);
01789 PRINT_STR_CONST(p, "#include ");
01790 if (decls[i].u.include_path.is_quote)
01791 PRINT_STR_CONST(p, "\"");
01792 else
01793 PRINT_STR_CONST(p, "<");
01794
01795 print_str(p,
01796 decls[i].u.include_path.path_str,
01797 strlen(decls[i].u.include_path.path_str));
01798
01799 if (decls[i].u.include_path.is_quote){
01800 PRINT_STR_CONST(p, "\"");
01801 print_newline(p);
01802 }else{
01803 PRINT_STR_CONST(p, ">");
01804 print_newline(p);
01805 }
01806 break;
01807
01808 case CTRUMP_EXT_NEWLINE:
01809 print_newline(p);
01810 break;
01811
01812
01813 case CTRUMP_EXT_IFDEF_BLOCK:
01814 case CTRUMP_EXT_INCLUDE:
01815 case CTRUMP_EXT_UNDEF:
01816 case CTRUMP_EXT_DEFINE:
01817 ctrump_fixme("Postponed");
01818 break;
01819
01820 case CTRUMP_EXT_GCC_CPP_NOTE:
01821 break;
01822 if (! p->suspended) {
01823 p->suspended = 1;
01824 break;
01825 }
01826
01827 if (strcmp(decls[i].u.gcc_cpp_note.path_str, p->filename) == 0) {
01828 int j, k;
01829 int num = decls[i].u.gcc_cpp_note.num_digit;
01830 FILE *fp;
01831 char buf[1024];
01832 struct ctrump_location loc;
01833
01834 for (j=0; j<num; j++) {
01835 if (decls[i].u.gcc_cpp_note.digits[j] == 2) {
01836
01837
01838
01839
01840 p->suspended = 0;
01841 loc.column = 1;
01842 loc.lineno = decls[i].u.gcc_cpp_note.line - 1;
01843 goto_loc(p, &loc);
01844
01845 if ((fp = fopen(p->filename, "r")) == NULL) {
01846 fprintf(stderr, "ERROR: cannot open file \"%s\".\n", p->filename);
01847 exit(1);
01848 }
01849
01850 for (k = 0; k < decls[i].u.gcc_cpp_note.line - 1; k++) {
01851 fgets(buf, sizeof(buf), fp);
01852 }
01853
01854 print_str(p, buf, strlen(buf));
01855 fclose(fp);
01856 break;
01857 }
01858 }
01859 }
01860 break;
01861
01862 default:
01863 ctrump_unreachable("UNREACHABLE");
01864 break;
01865 }
01866 }
01867 }
01868
01869 static void
01870 init_printer(struct printer *p, int is_use_column, int print_internal_info,
01871 const struct ctrump_translation_unit *t)
01872 {
01873 p->cur_lineno = 1;
01874 p->cur_column = 1;
01875 p->indent = 0;
01876 p->line_begin = 1;
01877 p->buffer = malloc(32);
01878 p->content_len = 0;
01879 p->buf_len = 32;
01880 p->use_column = is_use_column;
01881 p->max_column = 80;
01882 p->print_internal_info = print_internal_info;
01883
01884 p->suspended = 0;
01885 if (t != NULL) {
01886 p->filename = t->filename;
01887 }
01888 }
01889
01890 static void
01891 init_printer_with_format(struct printer *p,
01892 int print_internal_info,
01893 const struct ctrump_pprint_format *fmt,
01894 const struct ctrump_translation_unit *t)
01895 {
01896 init_printer(p, 0, print_internal_info, t);
01897 p->fmt = fmt;
01898 }
01899
01900 void
01901 ctrump_print_translation_unit(char **ret,
01902 int *ret_length,
01903 int print_internal_info,
01904 const struct ctrump_translation_unit *t)
01905 {
01906 struct printer p;
01907
01908 init_printer(&p, 1, print_internal_info, t);
01909 pprint_tree(&p, t);
01910 PRINT_STR_CONST(&p, "\n\0");
01911
01912 *ret = p.buffer;
01913 *ret_length = p.content_len-1;
01914 }
01915
01916 void
01917 ctrump_print_translation_unit_format(char **ret,
01918 int *ret_length,
01919 int print_internal_info,
01920 const struct ctrump_pprint_format *fmt,
01921 const struct ctrump_translation_unit *t)
01922 {
01923 struct printer p;
01924
01925 init_printer_with_format(&p, print_internal_info, fmt, t);
01926 pprint_tree(&p, t);
01927 PRINT_STR_CONST(&p, "\n\0");
01928
01929 *ret = p.buffer;
01930 *ret_length = p.content_len-1;
01931 }
01932
01933 void
01934 ctrump_print_stmt(char **ret,
01935 int *ret_length,
01936 int print_ssa_node,
01937 const struct ctrump_stmt *stmt)
01938 {
01939 struct printer p;
01940
01941 init_printer(&p, 0, print_ssa_node, NULL);
01942 print_stmt(&p, stmt);
01943 PRINT_STR_CONST(&p, "\0");
01944
01945 *ret = p.buffer;
01946 *ret_length = p.content_len-1;
01947 }
01948
01949 void ctrump_print_stmt_format(char **ret,
01950 int *ret_length,
01951 int print_ssa_node,
01952 const struct ctrump_pprint_format *fmt,
01953 const struct ctrump_stmt *stmt)
01954 {
01955 struct printer p;
01956
01957 init_printer_with_format(&p, print_ssa_node, fmt, NULL);
01958 print_stmt(&p, stmt);
01959 PRINT_STR_CONST(&p, "\0");
01960
01961 *ret = p.buffer;
01962 *ret_length = p.content_len-1;
01963 }
01964
01965 void
01966 ctrump_print_expr(char **ret,
01967 int *ret_length,
01968 int print_ssa_node,
01969 const struct ctrump_expr *expr)
01970 {
01971 struct printer p;
01972
01973 init_printer(&p, 0, print_ssa_node, NULL);
01974 print_expr(&p, expr);
01975 PRINT_STR_CONST(&p, "\0");
01976
01977 *ret = p.buffer;
01978 *ret_length = p.content_len-1;
01979 }
01980
01981 void
01982 ctrump_print_expr_format(char **ret,
01983 int *ret_length,
01984 int print_ssa_node,
01985 const struct ctrump_pprint_format *fmt,
01986 const struct ctrump_expr *expr)
01987 {
01988 struct printer p;
01989
01990 init_printer_with_format(&p, print_ssa_node, fmt, NULL);
01991 print_expr(&p, expr);
01992 PRINT_STR_CONST(&p, "\0");
01993
01994 *ret = p.buffer;
01995 *ret_length = p.content_len-1;
01996 }
01997
01998 static struct ctrump_gccext_attribute
01999 attr_empty(void)
02000 {
02001 struct ctrump_gccext_attribute attr;
02002 attr.flags = 0;
02003 attr.aligned = CTRUMP_ALIGN_UNSPECIFIED;
02004 return attr;
02005 }
02006
02007 static void
02008 print_texpr_record(struct printer *p,
02009 const struct ctrump_record_type *record,
02010 int is_typename)
02011 {
02012 int i,n;
02013 if (! record->is_completed){
02014 return;
02015 }
02016
02017 n = record->nfield;
02018
02019 if (record->name) {
02020 print_sym(p, record->name);
02021 } else {
02022 PRINT_STR_CONST(p, "<anon>");
02023 }
02024
02025 if (! is_typename) {
02026 PRINT_STR_CONST(p, "{");
02027 print_newline(p);
02028 indent(p);
02029
02030 for (i=0; i<n ;i++) {
02031 print_texpr(p, record->fields[i].type, is_typename);
02032 print_newline(p);
02033 }
02034
02035 dedent(p);
02036 PRINT_STR_CONST(p, "}");
02037 }
02038 }
02039
02040 static void
02041 print_texpr_spec(struct printer *p,
02042 const struct ctrump_texpr *texpr,
02043 int flags,
02044 struct ctrump_gccext_attribute *attr,
02045 int is_typename)
02046 {
02047 struct ctrump_gccext_attribute next_attr;
02048
02049 tailcall:
02050 switch (texpr->code) {
02051 case CTRUMP_TYPE_BUILTIN:
02052 print_qual_flags(p, flags);
02053 print_attr(p, attr);
02054 print_str(p, texpr->u.builtin.name, strlen(texpr->u.builtin.name));
02055 break;
02056
02057 case CTRUMP_TYPE_TYPEDEF_NAME:
02058 print_qual_flags(p, flags);
02059 print_attr(p, attr);
02060 print_sym(p, texpr->u.typedef_name.def_name);
02061 break;
02062
02063 case CTRUMP_TYPE_UNION:
02064 print_qual_flags(p, flags);
02065 print_attr(p, attr);
02066 PRINT_STR_CONST(p, "union ");
02067 print_texpr_record(p, &texpr->u.union_, is_typename);
02068 break;
02069
02070 case CTRUMP_TYPE_STRUCT:
02071 print_qual_flags(p, flags);
02072 print_attr(p, attr);
02073 PRINT_STR_CONST(p, "struct ");
02074 print_texpr_record(p, &texpr->u.struct_, is_typename);
02075 break;
02076
02077 case CTRUMP_TYPE_FUNC:
02078 flags = 0;
02079 next_attr = attr_empty();
02080 attr = &next_attr;
02081 texpr = texpr->u.func.ret;
02082 goto tailcall;
02083
02084 case CTRUMP_TYPE_POINTER:
02085 flags = 0;
02086 next_attr = attr_empty();
02087 attr = &next_attr;
02088 texpr = texpr->u.pointer_to;
02089 goto tailcall;
02090
02091 case CTRUMP_TYPE_ARRAY:
02092 flags = 0;
02093 next_attr = attr_empty();
02094 attr = &next_attr;
02095 texpr = texpr->u.array.array_of;
02096 goto tailcall;
02097
02098 case CTRUMP_TYPE_QUALIFIED:
02099 next_attr = ctrump_merge_attr(attr, &texpr->u.qualified.attr);
02100 flags |= texpr->u.qualified.qual_flags;
02101 attr = &next_attr;
02102 texpr = texpr->u.qualified.unqualified_type;
02103 goto tailcall;
02104
02105 case CTRUMP_TYPE_VARLEN_ARRAY:
02106 case CTRUMP_TYPE_INCOMPLETE_ARRAY:
02107 case CTRUMP_TYPE_ENUM:
02108 ctrump_fixme("print type spec");
02109 break;
02110
02111 default:
02112 ctrump_unreachable("UNREACHABLE");
02113 break;
02114 }
02115 }
02116
02117 static void
02118 print_texpr_abstract_declarator(struct printer *p,
02119 const struct ctrump_texpr *texpr,
02120 int prec,
02121 int flags,
02122 struct ctrump_gccext_attribute *attr,
02123 int is_typename)
02124 {
02125 struct ctrump_texpr **args;
02126 int has_unspecified_arg;
02127 struct ctrump_gccext_attribute next_attr;
02128
02129 tailcall:
02130 switch (texpr->code) {
02131 case CTRUMP_TYPE_BUILTIN:
02132 case CTRUMP_TYPE_UNION:
02133 case CTRUMP_TYPE_STRUCT:
02134 case CTRUMP_TYPE_TYPEDEF_NAME:
02135 break;
02136 break;
02137
02138 case CTRUMP_TYPE_FUNC:
02139 has_unspecified_arg = texpr->u.func.has_unspecified_arg;
02140 args = texpr->u.func.args;
02141 next_attr = attr_empty();
02142 print_texpr_abstract_declarator(p, texpr->u.func.ret, DECL_TYPELIST_PREC,
02143 0, &next_attr, is_typename);
02144 PRINT_STR_CONST(p, "(");
02145
02146 if (texpr->u.func.arg_num) {
02147 int i,n;
02148 indent(p);
02149 print_texpr(p, args[0], is_typename);
02150 n = texpr->u.func.arg_num;
02151 for (i=1; i<n; i++) {
02152 PRINT_STR_CONST(p, ", ");
02153 print_texpr(p, args[i], is_typename);
02154 }
02155
02156 if (has_unspecified_arg) {
02157 PRINT_STR_CONST(p, ", ...");
02158 }
02159
02160 dedent(p);
02161 } else if (!has_unspecified_arg) {
02162 PRINT_STR_CONST(p, "void");
02163 }
02164
02165 PRINT_STR_CONST(p, ")");
02166 break;
02167
02168 case CTRUMP_TYPE_POINTER:
02169 if (prec > DECL_POINTER_PREC) {
02170 PRINT_STR_CONST(p, "(");
02171 }
02172 PRINT_STR_CONST(p, "*");
02173 print_qual_flags(p, flags);
02174 print_attr(p, attr);
02175 print_texpr_abstract_declarator(p, texpr->u.pointer_to, DECL_POINTER_PREC,
02176 0, &next_attr, is_typename);
02177 if (prec > DECL_POINTER_PREC) {
02178 PRINT_STR_CONST(p, ")");
02179 }
02180 break;
02181
02182 case CTRUMP_TYPE_ARRAY:
02183 if (prec > DECL_ARRAY_PREC) {
02184 PRINT_STR_CONST(p, "(");
02185 }
02186 print_texpr_abstract_declarator(p, texpr->u.array.array_of,
02187 DECL_ARRAY_PREC, flags, attr, is_typename);
02188 PRINT_STR_CONST(p, "[");
02189 print_sint(p, texpr->u.array.size);
02190 PRINT_STR_CONST(p, "]");
02191
02192 if (prec > DECL_ARRAY_PREC) {
02193 PRINT_STR_CONST(p, ")");
02194 }
02195
02196 break;
02197
02198 case CTRUMP_TYPE_QUALIFIED:
02199 flags |= texpr->u.qualified.qual_flags;
02200 next_attr = ctrump_merge_attr(&texpr->u.qualified.attr, attr);
02201 attr = &next_attr;
02202 texpr = texpr->u.qualified.unqualified_type;
02203 goto tailcall;
02204
02205 case CTRUMP_TYPE_VARLEN_ARRAY:
02206 case CTRUMP_TYPE_INCOMPLETE_ARRAY:
02207 case CTRUMP_TYPE_ENUM:
02208 ctrump_fixme("print type spec");
02209 break;
02210
02211 default:
02212 ctrump_unreachable("UNREACHABLE");
02213 break;
02214 }
02215 }
02216
02217 static void
02218 print_texpr(struct printer *p,
02219 const struct ctrump_texpr *type,
02220 int is_typename)
02221 {
02222 struct ctrump_gccext_attribute attr;
02223 attr = attr_empty();
02224 print_texpr_spec(p, type, 0, &attr, is_typename);
02225 attr = attr_empty();
02226 print_texpr_abstract_declarator(p, type, 0, 0, &attr, is_typename);
02227 }
02228
02229 void
02230 ctrump_print_texpr_as_typename(char **ret,
02231 int *ret_length,
02232 const struct ctrump_texpr *texpr)
02233 {
02234 struct printer p;
02235 init_printer(&p, 0, 0, NULL);
02236
02237 print_texpr(&p, texpr, 1);
02238 PRINT_STR_CONST(&p, "\0");
02239
02240 *ret = p.buffer;
02241 *ret_length = p.content_len-1;
02242 }
02243
02244 void
02245 ctrump_print_texpr_as_internal(char **ret,
02246 int *ret_length,
02247 const struct ctrump_texpr *texpr)
02248 {
02249 struct printer p;
02250 init_printer(&p, 0, 0, NULL);
02251
02252 print_texpr(&p, texpr, 0);
02253 PRINT_STR_CONST(&p, "\0");
02254
02255 *ret = p.buffer;
02256 *ret_length = p.content_len-1;
02257 }
02258
02259 int
02260 ctrump_print_expr_stderr(struct ctrump_expr *e, int is_print_internal)
02261 {
02262 char *p;
02263 int len;
02264 int r;
02265 ctrump_print_expr(&p, &len, is_print_internal, e);
02266 r = fwrite(p, 1, len, stderr);
02267 if (r < 0)
02268 return r;
02269 fputc('\n', stderr);
02270 fflush(stderr);
02271 free(p);
02272
02273 return 0;
02274 }
02275
02276 int
02277 ctrump_print_translation_unit_stderr(struct ctrump_translation_unit *u)
02278 {
02279 char *p;
02280 int len;
02281 int r;
02282 ctrump_print_translation_unit(&p, &len, 1, u);
02283 r = fwrite(p, 1, len, stderr);
02284 if (r < 0)
02285 return r;
02286 fputc('\n', stderr);
02287 fflush(stderr);
02288 free(p);
02289
02290 return 0;
02291 }
02292
02293 int
02294 ctrump_print_texpr_stderr(const struct ctrump_texpr *texpr)
02295 {
02296 char *p;
02297 int len;
02298 int r;
02299 ctrump_print_texpr_as_internal(&p, &len, texpr);
02300 r = fwrite(p, 1, len, stderr);
02301 if (r < 0)
02302 return r;
02303 fputc('\n', stderr);
02304 fflush(stderr);
02305 free(p);
02306
02307 return 0;
02308 }
02309
02310 static void
02311 print_enum_list(struct printer *p,
02312 const struct ctrump_enum_list *el)
02313 {
02314 int i;
02315 int n;
02316
02317 print_space_before_braces(p);
02318 PRINT_STR_CONST_LOC(p, "{", &el->lbr_loc);
02319
02320 print_newline_if_not_use_column(p);
02321 indent(p);
02322
02323 n = el->num_elem;
02324 for (i = 0; i < n; i++) {
02325 goto_loc(p, &el->elems[i].name_loc);
02326 print_sym(p, el->elems[i].name);
02327
02328 if (el->elems[i].value) {
02329 print_space_around_assignment_op(p);
02330 PRINT_STR_CONST_LOC(p, "=", &el->elems[i].eq_loc);
02331 print_space_around_assignment_op(p);
02332
02333 print_expr(p, el->elems[i].value);
02334 }
02335
02336 if (i != n-1) {
02337 PRINT_STR_CONST_LOC(p, ",", &el->elems[i+1].comma_loc);
02338 } else if (el->flags == CTRUMP_ENUM_LIST_HAVE_LAST_COMMA) {
02339 PRINT_STR_CONST_LOC(p, ",", &el->comma_loc);
02340 }
02341
02342 print_newline_if_not_use_column(p);
02343 }
02344
02345 dedent(p);
02346
02347 PRINT_STR_CONST_LOC(p, "}", &el->rbr_loc);
02348 print_space_before_braces(p);
02349 }
02350
02351
02352 static int
02353 is_empty_line(char *buf)
02354 {
02355 char *c = buf;
02356
02357 while (*c != '\n') {
02358 if (*c++ != ' ') return 0;
02359 }
02360 return 1;
02361 }
02362
02363 static int
02364 is_slasla_comment_line(char *buf)
02365 {
02366 char *c = buf;
02367
02368 while (*c == ' ') c++;
02369 return (strncmp(c, "//", 2) == 0) ? 1 : 0;
02370 }
02371
02372 static int
02373 is_preprocessor_exp_line(char *buf)
02374 {
02375 char *c = buf;
02376
02377 while (*c == ' ') c++;
02378 return (*c == '#') ? 1 : 0;
02379 }
02380
02381
02382 static void
02383 remove_comment_preprocessor(char *file_in,
02384 char *file_out)
02385 {
02386 FILE *f_in;
02387 FILE *f_out;
02388
02389 if ((f_in = fopen(file_in, "r")) == NULL) {
02390 fprintf(stderr, "ERROR: cannot open file \"%s\".\n", file_in);
02391 exit(1);
02392 }
02393
02394 if ((f_out = fopen(file_out, "w")) == NULL) {
02395 fprintf(stderr, "ERROR: cannot open file \"%s\".\n", file_out);
02396 exit(1);
02397 }
02398
02399 char buf[1024];
02400 char *c;
02401 int in_slaast_comment = 0;
02402
02403 while (fgets(buf, sizeof(buf), f_in) != NULL) {
02404 c = buf;
02405 start_loop:
02406 if (!in_slaast_comment) {
02407 while (*c != '\n') {
02408 if (is_slasla_comment_line(c) ||
02409 is_preprocessor_exp_line(c)) {
02410 goto end_loop;
02411 }
02412
02413 if (strcmp(c, "/*") == 0) {
02414 fputc(' ', f_out);
02415 in_slaast_comment = 1;
02416 c += 2;
02417 goto start_loop;
02418 }
02419 fputc(*c, f_out);
02420 c++;
02421 }
02422 } else {
02423 while (*c != '\n') {
02424 if (strcmp(c, "*/") == 0) {
02425 in_slaast_comment = 0;
02426 c += 2;
02427 goto start_loop;
02428 }
02429 fputc(*c, f_out);
02430 c++;
02431 }
02432 }
02433 end_loop:
02434 fputc('\n', f_out);
02435 }
02436
02437 fclose(f_in);
02438 fclose(f_out);
02439 }
02440
02441 void
02442 ctrump_format_file2pprint_format(char *file_name,
02443 struct ctrump_pprint_format *fmt)
02444 {
02445 FILE *fp;
02446 char buf[1024];
02447 int n;
02448 char fmt_in[1024];
02449 int val;
02450 char dummy[1024];
02451 int error = 0;
02452
02453
02454 if ((fp = fopen(file_name, "r")) == NULL) {
02455 fprintf(stderr, "ERROR: cannot open file \"%s\".\n", file_name);
02456 exit(1);
02457 }
02458
02459 while (fgets(buf, sizeof(buf), fp) != NULL) {
02460 if (is_empty_line(buf) || is_slasla_comment_line(buf)) {
02461 continue;
02462 }
02463
02464 n = sscanf(buf, "%s %d %[^\n]s", fmt_in, &val, dummy);
02465
02466 #define READ_VAL_FOR_LABEL(label) \
02467 if (strcmp(fmt_in, #label) == 0) { \
02468 fmt->label = val; \
02469 } else
02470
02471 READ_VAL_FOR_LABEL(indentation_size)
02472 READ_VAL_FOR_LABEL(num_blank_lines_after_func)
02473 READ_VAL_FOR_LABEL(indentation_before_left_brace)
02474 READ_VAL_FOR_LABEL(newline_after_declspec)
02475 READ_VAL_FOR_LABEL(newline_after_decl_params)
02476 READ_VAL_FOR_LABEL(newline_after_declarator)
02477 READ_VAL_FOR_LABEL(newline_before_left_brace)
02478 READ_VAL_FOR_LABEL(newline_after_right_brace)
02479 READ_VAL_FOR_LABEL(space_before_statement_parens)
02480 READ_VAL_FOR_LABEL(space_before_braces)
02481 READ_VAL_FOR_LABEL(space_before_brackets)
02482 READ_VAL_FOR_LABEL(space_after_comma)
02483 READ_VAL_FOR_LABEL(space_after_semicolon)
02484 READ_VAL_FOR_LABEL(space_after_type_cast)
02485 READ_VAL_FOR_LABEL(space_after_negation)
02486 READ_VAL_FOR_LABEL(spaces_around_assignment_op)
02487 READ_VAL_FOR_LABEL(spaces_around_logical_op)
02488 READ_VAL_FOR_LABEL(spaces_around_relational_op)
02489 READ_VAL_FOR_LABEL(spaces_around_bitwise_op)
02490 READ_VAL_FOR_LABEL(spaces_around_math_op)
02491 READ_VAL_FOR_LABEL(spaces_around_shift_op)
02492 READ_VAL_FOR_LABEL(padding_around_statement_parens)
02493 READ_VAL_FOR_LABEL(padding_around_braces)
02494 READ_VAL_FOR_LABEL(padding_around_brackets)
02495 READ_VAL_FOR_LABEL(padding_around_type_cast)
02496 {
02497 fprintf(stderr, "ERROR: unknown label \"%s\" ", fmt_in);
02498 fprintf(stderr, "appears in \"%s\".\n", file_name);
02499 error = 1;
02500 continue;
02501 }
02502
02503 if (n == 1) {
02504 fprintf(stderr, "ERROR: too few arguments for label ");
02505 fprintf(stderr, "\"%s\"\n", fmt_in);
02506 error = 1;
02507 } else if (n > 2) {
02508 if (! is_slasla_comment_line(dummy)) {
02509 fprintf(stderr, "ERROR: too many arguments for label ");
02510 fprintf(stderr, "\"%s\"\n", fmt_in);
02511 error = 1;
02512 }
02513 }
02514 }
02515
02516 fclose(fp);
02517
02518 if (error) exit(1);
02519 }
02520
02521 struct ctrump_pprint_format
02522 ctrump_generate_pprint_format(char *file_name)
02523 {
02524 char *default_format = DEFAULT_PP_FORMAT_FILE;
02525 struct ctrump_pprint_format fmt;
02526
02527 if (file_name == NULL) {
02528 ctrump_format_file2pprint_format(default_format, &fmt);
02529 } else {
02530 ctrump_format_file2pprint_format(default_format, &fmt);
02531 ctrump_format_file2pprint_format(file_name, &fmt);
02532 }
02533
02534 return fmt;
02535 }
02536
02537
02538 static void
02539 call_preprocessor(const char *prog_file,
02540 const char *cpp_file)
02541 {
02542 char cpp_call[1024] = "cpp -imacros ../../data/compat-macros.h ";
02543
02544 strcat (cpp_call, prog_file);
02545 strcat (cpp_call, " > ");
02546 strcat (cpp_call, cpp_file);
02547
02548 system(cpp_call);
02549 }
02550
02551
02552 #include "ctrump/parser/error.h"
02553 #include "ctrump/parser/cfront.h"
02554
02555 void
02556 ctrump_indent(struct ctrump_translation_unit *tree,
02557 const struct ctrump_pprint_format *fmt,
02558 char *file_tmp)
02559 {
02560 FILE *fp;
02561 #ifdef _WIN32
02562 char file_tmp_cpp[L_tmpnam];
02563 #else
02564 char file_tmp_cpp[] = "tmp.ctrump_indent_e.c.XXXXXX";
02565 #endif
02566 char *ptr;
02567 int len;
02568
02569 strcpy(file_tmp, "tmp.ctrump_indent.c.XXXXXX");
02570 #ifdef _WIN32
02571 tmpnam(file_tmp);
02572 tmpnam(file_tmp_cpp);
02573 #else
02574 mkstemp(file_tmp);
02575 mkstemp(file_tmp_cpp);
02576 #endif
02577
02578 ctrump_print_translation_unit_format(&ptr, &len, 0, fmt, tree);
02579
02580 if ((fp = fopen(file_tmp, "w")) == NULL) {
02581 fprintf(stderr, "ERROR: cannot open file \"%s\".\n", file_tmp);
02582 exit(1);
02583 }
02584 fwrite(ptr, 1, len, fp);
02585 fclose(fp);
02586
02587 call_preprocessor(file_tmp, file_tmp_cpp);
02588
02589 struct ctrump_type_env type_env;
02590 struct ctrump_mempool tree_pool;
02591 int r;
02592 struct ctrump_loginfo *error;
02593 int num_error;
02594 struct ctrump_parser_option parse_opt;
02595
02596 ctrump_type_env_init(&type_env, 0);
02597 ctrump_mempool_init(&tree_pool, 1024);
02598
02599 ctrump_get_default_parser_option(&parse_opt);
02600
02601 r = ctrump_parse(&error, &num_error, tree, file_tmp_cpp, file_tmp,
02602 &type_env, &ctrump_ppc32_abi, &parse_opt,
02603 0, &tree_pool);
02604 if (r<0) {
02605 int i;
02606 fprintf(stderr, "num_error= %d\n", num_error);
02607 for(i=0;i<num_error;i++) {
02608 fprintf(stderr, "%d\n", error->code);
02609 }
02610 ctrump_fixme("ERROR: ctrump_parse() in ctrump_indent()\n");
02611 }
02612
02613 if (remove(file_tmp_cpp) != 0) {
02614 fprintf(stderr, "WARNING: fail to remove temporally file \"%s\".\n",
02615 file_tmp_cpp);
02616 }
02617 }
02618
02619
02620
02621 static char *
02622 column_begin_with(char *buf, char *key)
02623 {
02624 char *c1;
02625 int i;
02626
02627 c1 = strstr(buf, key);
02628 if (c1 != NULL) {
02629 for (i = 0; i < c1-buf; i++) {
02630 if (buf[i] != ' ') break;
02631 }
02632 if (i == c1-buf) return c1;
02633 }
02634
02635 return NULL;
02636 }
02637
02638
02639 static char *
02640 column_begin_with_forifwhileswitch(char *buf)
02641 {
02642 char *pc;
02643
02644 pc = column_begin_with(buf, "for");
02645 if (pc != NULL) return pc;
02646
02647 pc = column_begin_with(buf, "if");
02648 if (pc != NULL) return pc;
02649
02650 pc = column_begin_with(buf, "while");
02651 if (pc != NULL) return pc;
02652
02653 pc = column_begin_with(buf, "switch");
02654 if (pc != NULL) return pc;
02655
02656 return NULL;
02657 }
02658
02659
02660
02661 static void
02662 set_indentation_size(FILE *fp,
02663 struct ctrump_pprint_format *fmt)
02664 {
02665 int lineno;
02666 char buf[1024];
02667 int i;
02668
02669 rewind(fp);
02670
02671 lineno = 1;
02672 fmt->indentation_size = 1000;
02673
02674 while (fgets(buf, sizeof(buf), fp) != NULL) {
02675 if (buf[0] != ' ') continue;
02676
02677 for (i = 0; i < strlen(buf)-1; i++) {
02678 if (buf[i] == ':') goto next_loop;
02679 }
02680
02681 for (i = 0; i < strlen(buf)-1; i++) {
02682 if (buf[i] != ' ') break;
02683 }
02684 if (i == strlen(buf)-1) continue;
02685
02686 if (i < fmt->indentation_size) {
02687 fmt->indentation_size = i;
02688 }
02689
02690 next_loop:
02691 lineno++;
02692 }
02693
02694 if (fmt->indentation_size == 1000) {
02695 fmt->indentation_size = -1;
02696 }
02697 }
02698
02699 static void
02700 set_indentation_before_left_brace(FILE *fp,
02701 struct ctrump_pprint_format *fmt)
02702 {
02703 char buf[1024];
02704 int curr_kwd_col;
02705 int prev_kwd_col = -1;
02706 int lpar_col;
02707 char *pcurr_kwd;
02708 char *plpar;
02709
02710 rewind(fp);
02711
02712 while (fgets(buf, sizeof(buf), fp) != NULL) {
02713 pcurr_kwd = column_begin_with_forifwhileswitch(buf);
02714 curr_kwd_col = (pcurr_kwd == NULL) ? -1 : pcurr_kwd - buf;
02715
02716 plpar = column_begin_with(buf, "{");
02717 lpar_col = (plpar == NULL) ? -1 : plpar - buf;
02718
02719 if (lpar_col > 0 && curr_kwd_col < 0 && prev_kwd_col > 0) {
02720 fmt->indentation_before_left_brace = (prev_kwd_col < lpar_col) ? 1 : 0;
02721 return;
02722 }
02723
02724 prev_kwd_col = curr_kwd_col;
02725
02726 }
02727 }
02728
02729 static void
02730 ctrump_translation_unit2pprint_format(const struct ctrump_translation_unit *t,
02731 struct ctrump_pprint_format *fmt)
02732 {
02733 int i;
02734 int n = t->num_decl;
02735 struct ctrump_extdecl *decls = t->decls;
02736
02737 int lineno_decl_spec;
02738 int lineno_decl;
02739 int lineno_decl_param1;
02740 int lineno_decl_param2;
02741 int lineno_decl_rpar;
02742 int lineno_body_lbr;
02743 struct ctrump_declarator_node *nodes;
02744 int na;
02745
02746 for (i=0; i<n; i++) {
02747 lineno_decl_spec = -1;
02748 lineno_decl = -1;
02749 lineno_decl_param1 = -1;
02750 lineno_decl_param2 = -1;
02751 lineno_decl_rpar = -1;
02752 lineno_body_lbr = -1;
02753
02754 switch (decls[i].code) {
02755 case CTRUMP_EXT_FUNCTION_DEFINITION:
02756 lineno_decl_spec = decls[i].u.func_def.decl_spec.begin.lineno;
02757 lineno_decl = decls[i].u.func_def.decl->nodes.u.identifier.loc.lineno;
02758
02759 nodes = &decls[i].u.func_def.decl->nodes;
02760 if (nodes->code == CTRUMP_DECLARATOR_PARAM_TYPELIST) {
02761 na = nodes->u.param_typelist.num_args;
02762 if (na == 0) {
02763 ;
02764 } else if (na == 1) {
02765 lineno_decl_param1 =
02766 nodes->u.param_typelist.args[0].decl_spec.begin.lineno;
02767 } else {
02768 lineno_decl_param1 =
02769 nodes->u.param_typelist.args[0].decl_spec.begin.lineno;
02770 lineno_decl_param2 =
02771 nodes->u.param_typelist.args[1].decl_spec.begin.lineno;
02772 }
02773 lineno_decl_rpar = nodes->u.param_typelist.rpar_loc.lineno;
02774 }
02775 lineno_body_lbr = decls[i].u.func_def.body.lbr_loc.lineno;
02776 break;
02777
02778 default:
02779 break;
02780 }
02781
02782 if (lineno_decl_spec > 0 && lineno_decl > 0) {
02783 fmt->newline_after_declspec =
02784 (lineno_decl_spec == lineno_decl) ? 0 : 1;
02785 }
02786
02787 if (lineno_decl_param1 > 0 && lineno_decl_param2 > 0) {
02788 fmt->newline_after_decl_params =
02789 (lineno_decl_param1 == lineno_decl_param2) ? 0 : 1;
02790 }
02791
02792 if (lineno_decl_rpar > 0 && lineno_body_lbr > 0) {
02793 fmt->newline_after_declarator =
02794 (lineno_decl_rpar == lineno_body_lbr) ? 0 : 1;
02795 }
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810 if (fmt->newline_after_declspec != -1 &&
02811 fmt->newline_after_decl_params != -1 &&
02812 fmt->newline_after_declarator != -1) {
02813 break;
02814 }
02815 }
02816
02817
02818 int prev_fundef = 0;
02819 int lineno_prev_fundef_end = -1;
02820
02821 for (i=0; i<n; i++) {
02822 lineno_decl_spec = -1;
02823
02824 switch (decls[i].code) {
02825 case CTRUMP_EXT_FUNCTION_DEFINITION:
02826 lineno_decl_spec = decls[i].u.func_def.decl_spec.begin.lineno;
02827
02828 if (prev_fundef) {
02829 fmt->num_blank_lines_after_func =
02830 lineno_decl_spec - lineno_prev_fundef_end - 1;
02831 goto exit_num_blank_lines;
02832 }
02833
02834 prev_fundef = 1;
02835 lineno_prev_fundef_end = decls[i].u.func_def.body.rbr_loc.lineno;
02836 break;
02837
02838 default:
02839 prev_fundef = 0;
02840 break;
02841 }
02842 }
02843 exit_num_blank_lines:
02844 return;
02845 }
02846
02847
02848
02849 static void
02850 set_newline_before_left_brace(FILE *fp,
02851 struct ctrump_pprint_format *fmt)
02852 {
02853 char buf[1024];
02854 char *pcurr_kwd;
02855 char *pprev_kwd = NULL;
02856 char *plbr;
02857
02858 rewind(fp);
02859
02860 while (fgets(buf, sizeof(buf), fp) != NULL) {
02861 pcurr_kwd = column_begin_with_forifwhileswitch(buf);
02862 plbr = strstr(buf, "{");
02863 if (plbr != NULL) {
02864 if (pcurr_kwd != NULL && pcurr_kwd < plbr) {
02865 fmt->newline_before_left_brace = 0;
02866 return;
02867 } else if (pprev_kwd != 0) {
02868 fmt->newline_before_left_brace = 1;
02869 return;
02870 }
02871 }
02872
02873 pprev_kwd = pcurr_kwd;
02874 }
02875 }
02876
02877 static void
02878 set_newline_after_right_brace(FILE *fp,
02879 struct ctrump_pprint_format *fmt)
02880 {
02881 char buf[1024];
02882 char *pcurr_rbr;
02883 char *pprev_rbr = NULL;
02884 char *pelse;
02885
02886 rewind(fp);
02887
02888 while (fgets(buf, sizeof(buf), fp) != NULL) {
02889 pcurr_rbr = strstr(buf, "}");
02890 pelse = strstr(buf, "else");
02891
02892 if (pelse != NULL) {
02893 if (pcurr_rbr != NULL && pcurr_rbr < pelse) {
02894 fmt->newline_after_right_brace = 0;
02895 return;
02896 } else if (pprev_rbr != NULL) {
02897 fmt->newline_after_right_brace = 1;
02898 return;
02899 }
02900 }
02901
02902 pprev_rbr = pcurr_rbr;
02903 }
02904 }
02905
02906 static void
02907 set_space_before_statement_parens(FILE *fp,
02908 struct ctrump_pprint_format *fmt)
02909 {
02910 char buf[1024];
02911 int i;
02912 char *pkwd;
02913 char *plpar;
02914 char *kwd [] = { "for", "if", "while", "switch" };
02915
02916 rewind(fp);
02917
02918 while (fgets(buf, sizeof(buf), fp) != NULL) {
02919 for (i = 0; i < sizeof(kwd)/sizeof(kwd[0]); i++) {
02920 pkwd = column_begin_with(buf, kwd[i]);
02921 plpar = strstr(buf, "(");
02922 if (pkwd != NULL && plpar != NULL) {
02923 fmt->space_before_statement_parens =
02924 (plpar == pkwd + strlen(kwd[i])) ? 0 : 1;
02925 return;
02926 }
02927 }
02928 }
02929 }
02930
02931 static void
02932 set_space_before_braces(FILE *fp,
02933 struct ctrump_pprint_format *fmt)
02934 {
02935 char buf[1024];
02936 char *prpar;
02937 char *plbr;
02938
02939 rewind(fp);
02940
02941 while (fgets(buf, sizeof(buf), fp) != NULL) {
02942 if (!column_begin_with_forifwhileswitch(buf)) continue;
02943 prpar = strstr(buf, ")");
02944 plbr = strstr(buf, "{");
02945 if (prpar != NULL && plbr != NULL) {
02946 fmt->space_before_braces = (plbr == prpar+1) ? 0 : 1;
02947 return;
02948 }
02949 }
02950 }
02951
02952 static void
02953 set_space_before_brackets(FILE *fp,
02954 struct ctrump_pprint_format *fmt)
02955 {
02956 char buf[1024];
02957 char *plbracket;
02958
02959 rewind(fp);
02960
02961 while (fgets(buf, sizeof(buf), fp) != NULL) {
02962 plbracket = strstr(buf, "[");
02963 if (plbracket != NULL) {
02964 fmt->space_before_brackets = (*(plbracket-1) == ' ') ? 1 : 0;
02965 return;
02966 }
02967 }
02968 }
02969
02970 static void
02971 set_space_after_comma(FILE *fp,
02972 struct ctrump_pprint_format *fmt)
02973 {
02974 char buf[1024];
02975 char *pcomma;
02976
02977 rewind(fp);
02978
02979 while (fgets(buf, sizeof(buf), fp) != NULL) {
02980 pcomma = strstr(buf, ",");
02981 if (pcomma != NULL) {
02982 if (*(pcomma+1) == ' ') {
02983 fmt->space_after_comma = 1;
02984 return;
02985 } else if (isalnum(*(pcomma+1)) || *(pcomma+1) == '(') {
02986 fmt->space_after_comma = 0;
02987 return;
02988 }
02989 }
02990 }
02991 }
02992
02993 static void
02994 set_space_after_semicolon(FILE *fp,
02995 struct ctrump_pprint_format *fmt)
02996 {
02997 char buf[1024];
02998 char *psemi;
02999
03000 rewind(fp);
03001
03002 while (fgets(buf, sizeof(buf), fp) != NULL) {
03003 if (!column_begin_with(buf, "for")) continue;
03004
03005 psemi = strstr(buf, ";");
03006 if (psemi != NULL) {
03007 if (*(psemi+1) == ' ') {
03008 fmt->space_after_semicolon = 1;
03009 return;
03010 } else if (isalnum(*(psemi+1)) || *(psemi+1) == '(') {
03011 fmt->space_after_semicolon = 0;
03012 return;
03013 }
03014 }
03015 }
03016 }
03017
03018 static void
03019 set_space_after_type_cast(FILE *fp,
03020 struct ctrump_pprint_format *fmt)
03021 {
03022 char buf[1024];
03023 int i;
03024 char *pkwd;
03025 char *plpar;
03026 char *prpar;
03027 char *peq;
03028 char *kwd [] = { "char", "int", "long", "float", "double" };
03029
03030 rewind(fp);
03031
03032 while (fgets(buf, sizeof(buf), fp) != NULL) {
03033 for (i = 0; i < sizeof(kwd)/sizeof(kwd[0]); i++) {
03034 plpar = strstr(buf, "(");
03035 pkwd = strstr(buf, kwd[i]);
03036 prpar = strstr(buf, ")");
03037
03038 if (plpar != NULL && pkwd != NULL && prpar != NULL &&
03039 plpar < pkwd && pkwd < prpar) {
03040
03041
03042 peq = strstr(plpar, "=");
03043 if (peq != NULL && peq < prpar) break;
03044
03045 if (*(prpar+1) == ' ') {
03046 fmt->space_after_type_cast = 1;
03047 return;
03048 } else if (isalnum(*(prpar+1)) || *(prpar+1) == '(') {
03049 fmt->space_after_type_cast = 0;
03050 return;
03051 }
03052 }
03053 }
03054 }
03055 }
03056
03057 static void
03058 set_space_after_negation(FILE *fp,
03059 struct ctrump_pprint_format *fmt)
03060 {
03061 char buf[1024];
03062 char *pexcl;
03063
03064 rewind(fp);
03065
03066 while (fgets(buf, sizeof(buf), fp) != NULL) {
03067 pexcl = strstr(buf, "!");
03068
03069 if (pexcl != NULL) {
03070 if (*(pexcl+1) == ' ') {
03071 fmt->space_after_negation = 1;
03072 return;
03073 } else if (isalnum(*(pexcl+1)) || *(pexcl+1) == '(') {
03074 fmt->space_after_negation = 0;
03075 return;
03076 }
03077 }
03078 }
03079 }
03080
03081 static void
03082 set_spaces_around_op(FILE *fp,
03083 struct ctrump_pprint_format *fmt)
03084 {
03085 char buf[1024];
03086 int i;
03087 char *pop;
03088
03089 char *assign_op [] = { "=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=",
03090 "<<=", ">>=", ">>>=" };
03091 char *logical_op [] = { "&&", "||" };
03092 char *relational_op [] = { "==", "!=", "<", ">", "<=", ">=" };
03093 char *bitwise_op [] = { "|", "^" };
03094 char *math_op [] = { "+", "-", "/", "%" };
03095 char *shift_op [] = { "<<", ">>", ">>>" };
03096
03097 rewind(fp);
03098 while (fgets(buf, sizeof(buf), fp) != NULL) {
03099 for (i = 0; i < sizeof(assign_op)/sizeof(assign_op[0]); i++) {
03100 pop = strstr(buf, assign_op[i]);
03101
03102 if (pop != NULL) {
03103 if (strncmp(pop, "==", 2) == 0) break;
03104
03105 if (*(pop-1) == ' ') {
03106 fmt->spaces_around_assignment_op = 1;
03107 goto exit_assign_op;
03108 } else if (isalnum(*(pop-1)) || *(pop-1) == ')') {
03109 fmt->spaces_around_assignment_op = 0;
03110 goto exit_assign_op;
03111 }
03112 }
03113 }
03114 }
03115 exit_assign_op:
03116
03117 rewind(fp);
03118 while (fgets(buf, sizeof(buf), fp) != NULL) {
03119 for (i = 0; i < sizeof(logical_op)/sizeof(logical_op[0]); i++) {
03120 pop = strstr(buf, logical_op[i]);
03121
03122 if (pop != NULL) {
03123 if (*(pop-1) == ' ') {
03124 fmt->spaces_around_logical_op = 1;
03125 goto exit_logical_op;
03126 } else if (isalnum(*(pop-1)) || *(pop-1) == ')') {
03127 fmt->spaces_around_logical_op = 0;
03128 goto exit_logical_op;
03129 }
03130 }
03131 }
03132 }
03133 exit_logical_op:
03134
03135 rewind(fp);
03136 while (fgets(buf, sizeof(buf), fp) != NULL) {
03137 for (i = 0; i < sizeof(relational_op)/sizeof(relational_op[0]); i++) {
03138 pop = strstr(buf, relational_op[i]);
03139
03140 if (pop != NULL) {
03141 if (*(pop-1) == ' ') {
03142 fmt->spaces_around_relational_op = 1;
03143 goto exit_relational_op;
03144 } else if (isalnum(*(pop-1)) || *(pop-1) == ')') {
03145 fmt->spaces_around_relational_op = 0;
03146 goto exit_relational_op;
03147 }
03148 }
03149 }
03150 }
03151 exit_relational_op:
03152
03153 rewind(fp);
03154 while (fgets(buf, sizeof(buf), fp) != NULL) {
03155 for (i = 0; i < sizeof(bitwise_op)/sizeof(bitwise_op[0]); i++) {
03156 pop = strstr(buf, bitwise_op[i]);
03157
03158 if (pop != NULL) {
03159 if (strncmp(pop, "&&", 2) == 0) break;
03160 if (strncmp(pop, "||", 2) == 0) break;
03161 if (strncmp(pop, "&=", 2) == 0) break;
03162 if (strncmp(pop, "|=", 2) == 0) break;
03163 if (strncmp(pop, "^=", 2) == 0) break;
03164
03165 if (*(pop-1) == ' ') {
03166 fmt->spaces_around_bitwise_op = 1;
03167 goto exit_bitwise_op;
03168 } else if (isalnum(*(pop-1)) || *(pop-1) == ')') {
03169 fmt->spaces_around_bitwise_op = 0;
03170 goto exit_bitwise_op;
03171 }
03172 }
03173 }
03174 }
03175 exit_bitwise_op:
03176
03177 rewind(fp);
03178 while (fgets(buf, sizeof(buf), fp) != NULL) {
03179 for (i = 0; i < sizeof(math_op)/sizeof(math_op[0]); i++) {
03180 pop = strstr(buf, math_op[i]);
03181
03182 if (pop != NULL) {
03183 if (strncmp(pop, "++", 2) == 0) break;
03184 if (strncmp(pop, "--", 2) == 0) break;
03185 if (strncmp(pop, "+=", 2) == 0) break;
03186 if (strncmp(pop, "-=", 2) == 0) break;
03187 if (strncmp(pop, "/=", 2) == 0) break;
03188 if (strncmp(pop, "%=", 2) == 0) break;
03189
03190 if (*(pop-1) == ' ') {
03191 fmt->spaces_around_math_op = 1;
03192 goto exit_math_op;
03193 } else if (isalnum(*(pop-1)) || *(pop-1) == ')') {
03194 fmt->spaces_around_math_op = 0;
03195 goto exit_math_op;
03196 }
03197 }
03198 }
03199 }
03200 exit_math_op:
03201
03202 rewind(fp);
03203 while (fgets(buf, sizeof(buf), fp) != NULL) {
03204 for (i = 0; i < sizeof(shift_op)/sizeof(shift_op[0]); i++) {
03205 pop = strstr(buf, shift_op[i]);
03206
03207 if (pop != NULL) {
03208 if (strncmp(pop, "<<=", 3) == 0) break;
03209 if (strncmp(pop, ">>=", 3) == 0) break;
03210 if (strncmp(pop, ">>>=", 4) == 0) break;
03211
03212 if (*(pop-1) == ' ') {
03213 fmt->spaces_around_shift_op = 1;
03214 goto exit_shift_op;
03215 } else if (isalnum(*(pop-1)) || *(pop-1) == ')') {
03216 fmt->spaces_around_shift_op = 0;
03217 goto exit_shift_op;
03218 }
03219 }
03220 }
03221 }
03222 exit_shift_op:
03223
03224 return;
03225 }
03226
03227 static void
03228 set_padding_around_parens(FILE *fp,
03229 struct ctrump_pprint_format *fmt)
03230 {
03231 char buf[1024];
03232 char *pkwd;
03233 char *plpar;
03234 char *plbr;
03235 char *plbracket;
03236
03237 int i;
03238 char *prpar;
03239 char *peq;
03240 char *kwd [] = { "char", "int", "long", "float", "double" };
03241
03242 rewind(fp);
03243 while (fgets(buf, sizeof(buf), fp) != NULL) {
03244 pkwd = column_begin_with_forifwhileswitch(buf);
03245 if (pkwd != NULL) {
03246 plpar = strstr(pkwd, "(");
03247 if (plpar != NULL && pkwd < plpar) {
03248 if (*(plpar+1) == ' ') {
03249 fmt->padding_around_statement_parens = 1;
03250 goto exit_statement_parens;
03251 } else if (isalnum(*(plpar+1)) || *(plpar+1) == '(') {
03252 fmt->padding_around_statement_parens = 0;
03253 goto exit_statement_parens;
03254 }
03255 }
03256 }
03257 }
03258 exit_statement_parens:
03259
03260
03261 rewind(fp);
03262 while (fgets(buf, sizeof(buf), fp) != NULL) {
03263 plbr = strstr(buf, "{");
03264 if (plbr != NULL) {
03265 if (*(plbr+1) == ' ') {
03266 fmt->padding_around_braces = 1;
03267 goto exit_braces;
03268 } else if (isalnum(*(plbr+1)) || *(plbr+1) == '(') {
03269 fmt->padding_around_braces = 0;
03270 goto exit_braces;
03271 }
03272 }
03273 }
03274 exit_braces:
03275
03276 rewind(fp);
03277 while (fgets(buf, sizeof(buf), fp) != NULL) {
03278 plbracket = strstr(buf, "[");
03279 if (plbracket != NULL) {
03280 if (*(plbracket+1) == ' ') {
03281 fmt->padding_around_braces = 1;
03282 goto exit_brackets;
03283 } else if (isalnum(*(plbracket+1)) || *(plbracket+1) == '(') {
03284 fmt->padding_around_brackets = 0;
03285 goto exit_brackets;
03286 }
03287 }
03288 }
03289 exit_brackets:
03290
03291 rewind(fp);
03292 while (fgets(buf, sizeof(buf), fp) != NULL) {
03293 for (i = 0; i < sizeof(kwd)/sizeof(kwd[0]); i++) {
03294 plpar = strstr(buf, "(");
03295 pkwd = strstr(buf, kwd[i]);
03296 prpar = strstr(buf, ")");
03297
03298 if (plpar != NULL && pkwd != NULL && prpar != NULL &&
03299 plpar < pkwd && pkwd < prpar) {
03300
03301
03302 peq = strstr(plpar, "=");
03303 if (peq != NULL && peq < prpar) break;
03304
03305 if (*(plpar+1) == ' ') {
03306 fmt->padding_around_type_cast = 1;
03307 goto exit_type_cast;
03308 } else if (isalnum(*(prpar+1)) || *(prpar+1) == '(') {
03309 fmt->padding_around_type_cast = 0;
03310 goto exit_type_cast;
03311 }
03312 }
03313 }
03314 }
03315 exit_type_cast:
03316
03317 return;
03318 }
03319
03320 static void
03321 init_pprint_format(struct ctrump_pprint_format *fmt)
03322 {
03323
03324 #define INIT_LABEL(label) fmt->label = -1;
03325
03326 INIT_LABEL(indentation_size);
03327 INIT_LABEL(num_blank_lines_after_func);
03328 INIT_LABEL(indentation_before_left_brace);
03329 INIT_LABEL(newline_after_declspec);
03330 INIT_LABEL(newline_after_decl_params);
03331 INIT_LABEL(newline_after_declarator);
03332 INIT_LABEL(newline_before_left_brace);
03333 INIT_LABEL(newline_after_right_brace);
03334 INIT_LABEL(space_before_statement_parens);
03335 INIT_LABEL(space_before_braces);
03336 INIT_LABEL(space_before_brackets);
03337 INIT_LABEL(space_after_comma);
03338 INIT_LABEL(space_after_semicolon);
03339 INIT_LABEL(space_after_type_cast);
03340 INIT_LABEL(space_after_negation);
03341 INIT_LABEL(spaces_around_assignment_op);
03342 INIT_LABEL(spaces_around_logical_op);
03343 INIT_LABEL(spaces_around_relational_op);
03344 INIT_LABEL(spaces_around_bitwise_op);
03345 INIT_LABEL(spaces_around_math_op);
03346 INIT_LABEL(spaces_around_shift_op);
03347 INIT_LABEL(padding_around_statement_parens);
03348 INIT_LABEL(padding_around_braces);
03349 INIT_LABEL(padding_around_brackets);
03350 INIT_LABEL(padding_around_type_cast);
03351 }
03352
03353 void
03354 ctrump_prog_file2pprint_format(char *prog_file,
03355 struct ctrump_pprint_format *fmt)
03356 {
03357 FILE *fp;
03358 #ifdef _WIN32
03359 char prog_file_tmp[L_tmpnam];
03360 tmpnam(prog_file_tmp);
03361 #else
03362 char prog_file_tmp[] = "tmp.prog2format.c.XXXXXX";
03363 mkstemp(prog_file_tmp);
03364 #endif
03365
03366 remove_comment_preprocessor(prog_file, prog_file_tmp);
03367
03368
03369 if ((fp = fopen(prog_file_tmp, "r")) == NULL) {
03370 fprintf(stderr, "ERROR: cannot open file \"%s\".\n", prog_file);
03371 exit(1);
03372 }
03373
03374 init_pprint_format(fmt);
03375
03376 set_indentation_size(fp, fmt);
03377 set_indentation_before_left_brace(fp, fmt);
03378 set_newline_before_left_brace(fp, fmt);
03379 set_newline_after_right_brace(fp, fmt);
03380 set_space_before_statement_parens(fp, fmt);
03381 set_space_before_braces(fp, fmt);
03382 set_space_before_brackets(fp, fmt);
03383 set_space_after_comma(fp, fmt);
03384 set_space_after_semicolon(fp, fmt);
03385 set_space_after_type_cast(fp, fmt);
03386 set_space_after_negation(fp, fmt);
03387 set_spaces_around_op(fp, fmt);
03388 set_padding_around_parens(fp, fmt);
03389
03390 fclose(fp);
03391
03392 #ifdef _WIN32
03393 char cpp_file_tmp[L_tmpnam];
03394 tmpnam(cpp_file_tmp);
03395 #else
03396 char cpp_file_tmp[] = "tmp.prog2format_e.c.XXXXXX";
03397 mkstemp(cpp_file_tmp);
03398 #endif
03399
03400 call_preprocessor(prog_file, cpp_file_tmp);
03401
03402 struct ctrump_translation_unit tree;
03403 struct ctrump_type_env type_env;
03404 struct ctrump_mempool tree_pool;
03405 int r;
03406 struct ctrump_loginfo *error;
03407 int num_error;
03408 struct ctrump_parser_option parse_opt;
03409
03410 ctrump_type_env_init(&type_env, 0);
03411 ctrump_mempool_init(&tree_pool, 1024);
03412
03413 ctrump_get_default_parser_option(&parse_opt);
03414 r = ctrump_parse(&error, &num_error, &tree, cpp_file_tmp, prog_file_tmp,
03415 &type_env, &ctrump_ppc32_abi, &parse_opt,
03416 0, &tree_pool);
03417
03418
03419
03420
03421
03422 ctrump_translation_unit2pprint_format(&tree, fmt);
03423
03424
03425 if (remove(prog_file_tmp) != 0) {
03426 fprintf(stderr, "WARNING: fail to remove temporally file \"%s\".\n",
03427 prog_file_tmp);
03428 }
03429
03430 if (remove(cpp_file_tmp) != 0) {
03431 fprintf(stderr, "WARNING: fail to remove temporally file \"%s\".\n",
03432 cpp_file_tmp);
03433 }
03434 }
03435
03436
03437 void
03438 ctrump_pprint_format2format_file(const struct ctrump_pprint_format *fmt,
03439 char *fname)
03440 {
03441 FILE *fp;
03442 fp = fopen(fname, "w");
03443
03444 #define WRITE_VAL_FOR_LABEL(label) \
03445 if (fmt->label != -1) { \
03446 fprintf(fp, "%-40s%d\n", #label, fmt->label); \
03447 }
03448
03449 WRITE_VAL_FOR_LABEL(indentation_size);
03450 WRITE_VAL_FOR_LABEL(num_blank_lines_after_func);
03451 WRITE_VAL_FOR_LABEL(indentation_before_left_brace);
03452 WRITE_VAL_FOR_LABEL(newline_after_declspec);
03453 WRITE_VAL_FOR_LABEL(newline_after_decl_params);
03454 WRITE_VAL_FOR_LABEL(newline_after_declarator);
03455 WRITE_VAL_FOR_LABEL(newline_before_left_brace);
03456 WRITE_VAL_FOR_LABEL(newline_after_right_brace);
03457 WRITE_VAL_FOR_LABEL(space_before_statement_parens);
03458 WRITE_VAL_FOR_LABEL(space_before_braces);
03459 WRITE_VAL_FOR_LABEL(space_before_brackets);
03460 WRITE_VAL_FOR_LABEL(space_after_comma);
03461 WRITE_VAL_FOR_LABEL(space_after_semicolon);
03462 WRITE_VAL_FOR_LABEL(space_after_type_cast);
03463 WRITE_VAL_FOR_LABEL(space_after_negation);
03464 WRITE_VAL_FOR_LABEL(spaces_around_assignment_op);
03465 WRITE_VAL_FOR_LABEL(spaces_around_logical_op);
03466 WRITE_VAL_FOR_LABEL(spaces_around_relational_op);
03467 WRITE_VAL_FOR_LABEL(spaces_around_bitwise_op);
03468 WRITE_VAL_FOR_LABEL(spaces_around_math_op);
03469 WRITE_VAL_FOR_LABEL(spaces_around_shift_op);
03470 WRITE_VAL_FOR_LABEL(padding_around_statement_parens);
03471 WRITE_VAL_FOR_LABEL(padding_around_braces);
03472 WRITE_VAL_FOR_LABEL(padding_around_brackets);
03473 WRITE_VAL_FOR_LABEL(padding_around_type_cast);
03474
03475 fclose(fp);
03476 }
03477
03478
03479 void
03480 ctrump_prog_file2format_file(char *prog_fname,
03481 char *format_fname)
03482 {
03483 struct ctrump_pprint_format fmt;
03484
03485 ctrump_prog_file2pprint_format(prog_fname, &fmt);
03486 ctrump_pprint_format2format_file(&fmt, format_fname);
03487 }