Use print_char('x') instead of print_string("x").
[cparser] / ast.c
diff --git a/ast.c b/ast.c
index 8f9fb16..c62110a 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -47,6 +47,7 @@
 struct obstack ast_obstack;
 
 static int indent;
+static int case_indent;
 
 bool print_implicit_casts = false;
 bool print_parenthesis = false;
@@ -63,7 +64,7 @@ void change_indent(int delta)
 void print_indent(void)
 {
        for (int i = 0; i < indent; ++i)
-               print_string("\t");
+               print_char('\t');
 }
 
 static void print_stringrep(const string_t *string)
@@ -207,7 +208,7 @@ static void print_quoted_string(const string_t *const string, char border,
        for (const char *c = string->begin; c != end; ++c) {
                const char tc = *c;
                if (tc == border) {
-                       print_string("\\");
+                       print_char('\\');
                }
                switch (tc) {
                case '\\': print_string("\\\\"); break;
@@ -292,9 +293,9 @@ static void print_funcname(const funcname_expression_t *funcname)
 static void print_compound_literal(
                const compound_literal_expression_t *expression)
 {
-       print_string("(");
+       print_char('(');
        print_type(expression->type);
-       print_string(")");
+       print_char(')');
        print_initializer(expression->initializer);
 }
 
@@ -311,7 +312,7 @@ static void print_assignment_expression(const expression_t *const expr)
 static void print_call_expression(const call_expression_t *call)
 {
        print_expression_prec(call->function, PREC_POSTFIX);
-       print_string("(");
+       print_char('(');
        call_argument_t *argument = call->arguments;
        int              first    = 1;
        while (argument != NULL) {
@@ -324,7 +325,7 @@ static void print_call_expression(const call_expression_t *call)
 
                argument = argument->next;
        }
-       print_string(")");
+       print_char(')');
 }
 
 /**
@@ -386,14 +387,14 @@ static void print_unary_expression(const unary_expression_t *unexpr)
 {
        unsigned prec = get_expression_precedence(unexpr->base.kind);
        switch (unexpr->base.kind) {
-       case EXPR_UNARY_NEGATE:           print_string("-"); break;
-       case EXPR_UNARY_PLUS:             print_string("+"); break;
-       case EXPR_UNARY_NOT:              print_string("!"); break;
-       case EXPR_UNARY_BITWISE_NEGATE:   print_string("~"); break;
+       case EXPR_UNARY_NEGATE:           print_char  ('-' ); break;
+       case EXPR_UNARY_PLUS:             print_char  ('+' ); break;
+       case EXPR_UNARY_NOT:              print_char  ('!' ); break;
+       case EXPR_UNARY_BITWISE_NEGATE:   print_char  ('~' ); break;
        case EXPR_UNARY_PREFIX_INCREMENT: print_string("++"); break;
        case EXPR_UNARY_PREFIX_DECREMENT: print_string("--"); break;
-       case EXPR_UNARY_DEREFERENCE:      print_string("*"); break;
-       case EXPR_UNARY_TAKE_ADDRESS:     print_string("&"); break;
+       case EXPR_UNARY_DEREFERENCE:      print_char  ('*' ); break;
+       case EXPR_UNARY_TAKE_ADDRESS:     print_char  ('&' ); break;
        case EXPR_UNARY_DELETE:           print_string("delete "); break;
        case EXPR_UNARY_DELETE_ARRAY:     print_string("delete [] "); break;
 
@@ -406,14 +407,14 @@ static void print_unary_expression(const unary_expression_t *unexpr)
                print_string("--");
                return;
        case EXPR_UNARY_CAST:
-               print_string("(");
+               print_char('(');
                print_type(unexpr->base.type);
-               print_string(")");
+               print_char(')');
                break;
        case EXPR_UNARY_ASSUME:
                print_string("__assume(");
                print_assignment_expression(unexpr->value);
-               print_string(")");
+               print_char(')');
                return;
 
        case EXPR_UNARY_THROW:
@@ -459,14 +460,14 @@ static void print_array_expression(const array_access_expression_t *expression)
 {
        if (!expression->flipped) {
                print_expression_prec(expression->array_ref, PREC_POSTFIX);
-               print_string("[");
+               print_char('[');
                print_expression(expression->index);
-               print_string("]");
+               print_char(']');
        } else {
                print_expression_prec(expression->index, PREC_POSTFIX);
-               print_string("[");
+               print_char('[');
                print_expression(expression->array_ref);
-               print_string("]");
+               print_char(']');
        }
 }
 
@@ -487,9 +488,9 @@ static void print_typeprop_expression(const typeprop_expression_t *expression)
                /* PREC_TOP: always print the '()' here, sizeof x is right but unusual */
                print_expression_prec(expression->tp_expression, PREC_TOP);
        } else {
-               print_string("(");
+               print_char('(');
                print_type(expression->type);
-               print_string(")");
+               print_char(')');
        }
 }
 
@@ -502,7 +503,7 @@ static void print_builtin_constant(const builtin_constant_expression_t *expressi
 {
        print_string("__builtin_constant_p(");
        print_assignment_expression(expression->value);
-       print_string(")");
+       print_char(')');
 }
 
 /**
@@ -517,7 +518,7 @@ static void print_builtin_types_compatible(
        print_type(expression->left);
        print_string(", ");
        print_type(expression->right);
-       print_string(")");
+       print_char(')');
 }
 
 /**
@@ -550,7 +551,7 @@ static void print_va_start(const va_start_expression_t *const expression)
        print_assignment_expression(expression->ap);
        print_string(", ");
        print_string(expression->parameter->base.base.symbol->string);
-       print_string(")");
+       print_char(')');
 }
 
 /**
@@ -564,7 +565,7 @@ static void print_va_arg(const va_arg_expression_t *expression)
        print_assignment_expression(expression->ap);
        print_string(", ");
        print_type(expression->base.type);
-       print_string(")");
+       print_char(')');
 }
 
 /**
@@ -578,7 +579,7 @@ static void print_va_copy(const va_copy_expression_t *expression)
        print_assignment_expression(expression->dst);
        print_string(", ");
        print_assignment_expression(expression->src);
-       print_string(")");
+       print_char(')');
 }
 
 /**
@@ -598,7 +599,7 @@ static void print_select(const select_expression_t *expression)
        if (is_type_pointer(skip_typeref(expression->compound->base.type))) {
                print_string("->");
        } else {
-               print_string(".");
+               print_char('.');
        }
        print_string(expression->compound_entry->base.symbol->string);
 }
@@ -613,7 +614,7 @@ static void print_classify_type_expression(
 {
        print_string("__builtin_classify_type(");
        print_assignment_expression(expr->type_expression);
-       print_string(")");
+       print_char(')');
 }
 
 /**
@@ -625,11 +626,11 @@ static void print_designator(const designator_t *designator)
 {
        for ( ; designator != NULL; designator = designator->next) {
                if (designator->symbol == NULL) {
-                       print_string("[");
+                       print_char('[');
                        print_expression(designator->array_index);
-                       print_string("]");
+                       print_char(']');
                } else {
-                       print_string(".");
+                       print_char('.');
                        print_string(designator->symbol->string);
                }
        }
@@ -644,9 +645,9 @@ static void print_offsetof_expression(const offsetof_expression_t *expression)
 {
        print_string("__builtin_offsetof(");
        print_type(expression->type);
-       print_string(",");
+       print_char(',');
        print_designator(expression->designator);
-       print_string(")");
+       print_char(')');
 }
 
 /**
@@ -656,9 +657,9 @@ static void print_offsetof_expression(const offsetof_expression_t *expression)
  */
 static void print_statement_expression(const statement_expression_t *expression)
 {
-       print_string("(");
+       print_char('(');
        print_statement(expression->statement);
-       print_string(")");
+       print_char(')');
 }
 
 /**
@@ -680,7 +681,7 @@ static void print_expression_prec(const expression_t *expression, unsigned top_p
                top_prec > get_expression_precedence(expression->base.kind);
 
        if (parenthesized)
-               print_string("(");
+               print_char('(');
        switch (expression->kind) {
        case EXPR_ERROR:
                print_string("$error$");
@@ -753,7 +754,25 @@ static void print_expression_prec(const expression_t *expression, unsigned top_p
                break;
        }
        if (parenthesized)
-               print_string(")");
+               print_char(')');
+}
+
+static void print_indented_statement(statement_t const *const stmt)
+{
+       switch (stmt->kind) {
+       case STATEMENT_LABEL:
+               break;
+
+       case STATEMENT_CASE_LABEL:
+               for (int i = 0; i != case_indent; ++i)
+                       print_char('\t');
+               break;
+
+       default:
+               print_indent();
+               break;
+       }
+       print_statement(stmt);
 }
 
 /**
@@ -768,17 +787,14 @@ static void print_compound_statement(const compound_statement_t *block)
 
        statement_t *statement = block->statements;
        while (statement != NULL) {
-               if (statement->base.kind == STATEMENT_CASE_LABEL)
-                       --indent;
-               if (statement->kind != STATEMENT_LABEL)
-                       print_indent();
-               print_statement(statement);
+               print_indented_statement(statement);
+               print_char('\n');
 
                statement = statement->base.next;
        }
        --indent;
        print_indent();
-       print_string(block->stmt_expr ? "}" : "}\n");
+       print_char('}');
 }
 
 /**
@@ -792,9 +808,9 @@ static void print_return_statement(const return_statement_t *statement)
        if (val != NULL) {
                print_string("return ");
                print_expression(val);
-               print_string(";\n");
+               print_char(';');
        } else {
-               print_string("return;\n");
+               print_string("return;");
        }
 }
 
@@ -806,7 +822,7 @@ static void print_return_statement(const return_statement_t *statement)
 static void print_expression_statement(const expression_statement_t *statement)
 {
        print_expression(statement->expression);
-       print_string(";\n");
+       print_char(';');
 }
 
 /**
@@ -818,12 +834,12 @@ static void print_goto_statement(const goto_statement_t *statement)
 {
        print_string("goto ");
        if (statement->expression != NULL) {
-               print_string("*");
+               print_char('*');
                print_expression(statement->expression);
        } else {
                print_string(statement->label->base.symbol->string);
        }
-       print_string(";\n");
+       print_char(';');
 }
 
 /**
@@ -834,8 +850,30 @@ static void print_goto_statement(const goto_statement_t *statement)
 static void print_label_statement(const label_statement_t *statement)
 {
        print_format("%s:\n", statement->label->base.symbol->string);
-       print_indent();
-       print_statement(statement->statement);
+       print_indented_statement(statement->statement);
+}
+
+static void print_inner_statement(statement_t const *const stmt)
+{
+       if (stmt->kind == STATEMENT_COMPOUND) {
+               print_char(' ');
+               print_compound_statement(&stmt->compound);
+       } else {
+               print_char('\n');
+               ++indent;
+               print_indented_statement(stmt);
+               --indent;
+       }
+}
+
+static void print_after_inner_statement(statement_t const *const stmt)
+{
+       if (stmt->kind == STATEMENT_COMPOUND) {
+               print_char(' ');
+       } else {
+               print_char('\n');
+               print_indent();
+       }
 }
 
 /**
@@ -847,13 +885,19 @@ static void print_if_statement(const if_statement_t *statement)
 {
        print_string("if (");
        print_expression(statement->condition);
-       print_string(") ");
-       print_statement(statement->true_statement);
-
-       if (statement->false_statement != NULL) {
-               print_indent();
-               print_string("else ");
-               print_statement(statement->false_statement);
+       print_char(')');
+       print_inner_statement(statement->true_statement);
+
+       statement_t const *const f = statement->false_statement;
+       if (f) {
+               print_after_inner_statement(statement->true_statement);
+               print_string("else");
+               if (f->kind == STATEMENT_IF) {
+                       print_char(' ');
+                       print_if_statement(&f->ifs);
+               } else {
+                       print_inner_statement(f);
+               }
        }
 }
 
@@ -864,10 +908,15 @@ static void print_if_statement(const if_statement_t *statement)
  */
 static void print_switch_statement(const switch_statement_t *statement)
 {
+       int const old_case_indent = case_indent;
+       case_indent = indent;
+
        print_string("switch (");
        print_expression(statement->expression);
-       print_string(") ");
-       print_statement(statement->body);
+       print_char(')');
+       print_inner_statement(statement->body);
+
+       case_indent = old_case_indent;
 }
 
 /**
@@ -888,19 +937,14 @@ static void print_case_label(const case_label_statement_t *statement)
                }
                print_string(":\n");
        }
-       ++indent;
-       if (statement->statement->base.kind == STATEMENT_CASE_LABEL) {
-               --indent;
-       }
-       print_indent();
-       print_statement(statement->statement);
+       print_indented_statement(statement->statement);
 }
 
 static void print_typedef(const entity_t *entity)
 {
        print_string("typedef ");
        print_type_ext(entity->typedefe.type, entity->base.symbol, NULL);
-       print_string(";");
+       print_char(';');
 }
 
 /**
@@ -929,7 +973,7 @@ static void print_declaration_statement(
        bool first = true;
        entity_t *entity = statement->declarations_begin;
        if (entity == NULL) {
-               print_string("/* empty declaration statement */\n");
+               print_string("/* empty declaration statement */");
                return;
        }
 
@@ -941,13 +985,13 @@ static void print_declaration_statement(
                        continue;
 
                if (!first) {
+                       print_char('\n');
                        print_indent();
                } else {
                        first = false;
                }
 
                print_entity(entity);
-               print_string("\n");
        }
 }
 
@@ -960,8 +1004,8 @@ static void print_while_statement(const while_statement_t *statement)
 {
        print_string("while (");
        print_expression(statement->condition);
-       print_string(") ");
-       print_statement(statement->body);
+       print_char(')');
+       print_inner_statement(statement->body);
 }
 
 /**
@@ -971,12 +1015,12 @@ static void print_while_statement(const while_statement_t *statement)
  */
 static void print_do_while_statement(const do_while_statement_t *statement)
 {
-       print_string("do ");
-       print_statement(statement->body);
-       print_indent();
+       print_string("do");
+       print_inner_statement(statement->body);
+       print_after_inner_statement(statement->body);
        print_string("while (");
        print_expression(statement->condition);
-       print_string(");\n");
+       print_string(");");
 }
 
 /**
@@ -989,7 +1033,7 @@ static void print_for_statement(const for_statement_t *statement)
        print_string("for (");
        if (statement->initialisation != NULL) {
                print_expression(statement->initialisation);
-               print_string(";");
+               print_char(';');
        } else {
                entity_t const *entity = statement->scope.entities;
                for (; entity != NULL; entity = entity->base.next) {
@@ -1000,16 +1044,16 @@ static void print_for_statement(const for_statement_t *statement)
                }
        }
        if (statement->condition != NULL) {
-               print_string(" ");
+               print_char(' ');
                print_expression(statement->condition);
        }
-       print_string(";");
+       print_char(';');
        if (statement->step != NULL) {
-               print_string(" ");
+               print_char(' ');
                print_expression(statement->step);
        }
-       print_string(") ");
-       print_statement(statement->body);
+       print_char(')');
+       print_inner_statement(statement->body);
 }
 
 /**
@@ -1030,7 +1074,7 @@ static void print_asm_arguments(asm_argument_t *arguments)
                print_quoted_string(&argument->constraints, '"', 1);
                print_string(" (");
                print_expression(argument->expression);
-               print_string(")");
+               print_char(')');
        }
 }
 
@@ -1061,7 +1105,7 @@ static void print_asm_statement(const asm_statement_t *statement)
        if (statement->is_volatile) {
                print_string("volatile ");
        }
-       print_string("(");
+       print_char('(');
        print_quoted_string(&statement->asm_text, '"', 1);
        if (statement->outputs  == NULL &&
            statement->inputs   == NULL &&
@@ -1082,7 +1126,7 @@ static void print_asm_statement(const asm_statement_t *statement)
        print_asm_clobbers(statement->clobbers);
 
 end_of_print_asm_statement:
-       print_string(");\n");
+       print_string(");");
 }
 
 /**
@@ -1092,17 +1136,17 @@ end_of_print_asm_statement:
  */
 static void print_ms_try_statement(const ms_try_statement_t *statement)
 {
-       print_string("__try ");
-       print_statement(statement->try_statement);
-       print_indent();
+       print_string("__try");
+       print_inner_statement(statement->try_statement);
+       print_after_inner_statement(statement->try_statement);
        if (statement->except_expression != NULL) {
                print_string("__except(");
                print_expression(statement->except_expression);
-               print_string(") ");
+               print_char(')');
        } else {
-               print_string("__finally ");
+               print_string("__finally");
        }
-       print_statement(statement->final_statement);
+       print_inner_statement(statement->final_statement);
 }
 
 /**
@@ -1113,7 +1157,7 @@ static void print_ms_try_statement(const ms_try_statement_t *statement)
 static void print_leave_statement(const leave_statement_t *statement)
 {
        (void)statement;
-       print_string("__leave;\n");
+       print_string("__leave;");
 }
 
 /**
@@ -1125,7 +1169,7 @@ void print_statement(const statement_t *statement)
 {
        switch (statement->kind) {
        case STATEMENT_EMPTY:
-               print_string(";\n");
+               print_char(';');
                break;
        case STATEMENT_COMPOUND:
                print_compound_statement(&statement->compound);
@@ -1143,10 +1187,10 @@ void print_statement(const statement_t *statement)
                print_goto_statement(&statement->gotos);
                break;
        case STATEMENT_CONTINUE:
-               print_string("continue;\n");
+               print_string("continue;");
                break;
        case STATEMENT_BREAK:
-               print_string("break;\n");
+               print_string("break;");
                break;
        case STATEMENT_IF:
                print_if_statement(&statement->ifs);
@@ -1179,7 +1223,7 @@ void print_statement(const statement_t *statement)
                print_leave_statement(&statement->leave);
                break;
        case STATEMENT_ERROR:
-               print_string("$error statement$\n");
+               print_string("$error statement$");
                break;
        }
 }
@@ -1288,7 +1332,7 @@ static void print_ms_modifiers(const declaration_t *declaration)
                                }
                                if (variable->put_property_sym != NULL)
                                        print_format("%sput=%s", comma, variable->put_property_sym->string);
-                               print_string(")");
+                               print_char(')');
                        }
                }
        }
@@ -1351,7 +1395,7 @@ static void print_scope(const scope_t *scope)
        for ( ; entity != NULL; entity = entity->base.next) {
                print_indent();
                print_entity(entity);
-               print_string("\n");
+               print_char('\n');
        }
 }
 
@@ -1360,7 +1404,7 @@ static void print_namespace(const namespace_t *namespace)
        print_string("namespace ");
        if (namespace->base.symbol != NULL) {
                print_string(namespace->base.symbol->string);
-               print_string(" ");
+               print_char(' ');
        }
 
        print_string("{\n");
@@ -1401,9 +1445,9 @@ void print_declaration(const entity_t *entity)
                                        &entity->function.parameters);
 
                        if (entity->function.statement != NULL) {
-                               print_string("\n");
-                               print_indent();
-                               print_statement(entity->function.statement);
+                               print_char('\n');
+                               print_indented_statement(entity->function.statement);
+                               print_char('\n');
                                return;
                        }
                        break;
@@ -1429,7 +1473,7 @@ void print_declaration(const entity_t *entity)
                        print_type_ext(declaration->type, declaration->base.symbol, NULL);
                        break;
        }
-       print_string(";");
+       print_char(';');
 }
 
 /**
@@ -1476,17 +1520,17 @@ void print_entity(const entity_t *entity)
 print_compound:
                print_string(entity->base.symbol->string);
                if (entity->compound.complete) {
-                       print_string(" ");
+                       print_char(' ');
                        print_compound_definition(&entity->compound);
                }
-               print_string(";");
+               print_char(';');
                return;
        case ENTITY_ENUM:
                print_string("enum ");
                print_string(entity->base.symbol->string);
-               print_string(" ");
+               print_char(' ');
                print_enum_definition(&entity->enume);
-               print_string(";");
+               print_char(';');
                return;
        case ENTITY_NAMESPACE:
                print_namespace(&entity->namespacee);
@@ -1494,7 +1538,7 @@ print_compound:
        case ENTITY_LOCAL_LABEL:
                print_string("__label__ ");
                print_string(entity->base.symbol->string);
-               print_string(";");
+               print_char(';');
                return;
        case ENTITY_LABEL:
        case ENTITY_ENUM_VALUE:
@@ -1522,7 +1566,7 @@ void print_ast(const translation_unit_t *unit)
 
                print_indent();
                print_entity(entity);
-               print_string("\n");
+               print_char('\n');
        }
 }