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 }