fputc(border, out);
const char *end = string->begin + string->size - skip;
for (const char *c = string->begin; c != end; ++c) {
- if (*c == border) {
+ unsigned char const tc = *c;
+ if (tc == border) {
fputc('\\', out);
}
- switch (*c) {
+ switch (tc) {
case '\\': fputs("\\\\", out); break;
case '\a': fputs("\\a", out); break;
case '\b': fputs("\\b", out); break;
}
/* FALLTHROUGH */
default:
- if (!isprint(*c)) {
- fprintf(out, "\\%03o", (unsigned)(unsigned char)*c);
- break;
+ if (tc < 0x80 && !isprint(tc)) {
+ fprintf(out, "\\%03o", (unsigned)tc);
+ } else {
+ fputc(tc, out);
}
- fputc(*c, out);
break;
}
}
default: {
const unsigned tc = *c;
if (tc < 0x80U) {
- if (!isprint(*c)) {
- fprintf(out, "\\%03o", (char)*c);
- } else {
+ if (isprint(*c)) {
fputc(*c, out);
+ } else {
+ fprintf(out, "\\%03o", tc);
}
} else if (tc < 0x800) {
fputc(0xC0 | (tc >> 6), out);
}
--indent;
print_indent();
- fputs("}\n", out);
+ fputs(block->stmt_expr ? "}" : "}\n", out);
}
/**
}
}
-static void print_local_label(const local_label_statement_t *statement)
-{
- fputs("__label__ ", out);
-
- bool first = true;
- entity_t *entity = statement->labels_begin;
- for (;
- entity != statement->labels_end->base.next;
- entity = entity->base.next) {
- if (!first) {
- fputs(", ", out);
- } else {
- first = false;
- }
- fputs(entity->base.symbol->string, out);
- }
- fputs(";\n", out);
-}
-
static void print_typedef(const entity_t *entity)
{
fputs("typedef ", out);
entity_t *const end = statement->declarations_end->base.next;
for (; entity != end; entity = entity->base.next) {
- if (!is_declaration(entity) && entity->kind != ENTITY_TYPEDEF)
+ if (entity->kind == ENTITY_ENUM_VALUE)
continue;
if (is_generated_entity(entity))
continue;
first = false;
}
- if (entity->kind == ENTITY_TYPEDEF) {
- print_typedef(entity);
- } else {
- assert(is_declaration(entity));
- print_declaration(entity);
- }
-
+ print_entity(entity);
fputc('\n', out);
}
}
case STATEMENT_LABEL:
print_label_statement(&statement->label);
break;
- case STATEMENT_LOCAL_LABEL:
- print_local_label(&statement->local_label);
- break;
case STATEMENT_GOTO:
print_goto_statement(&statement->gotos);
break;
{
switch (storage_class) {
case STORAGE_CLASS_NONE: return;
- case STORAGE_CLASS_TYPEDEF: fputs("typedef ", out); return;
- case STORAGE_CLASS_EXTERN: fputs("extern ", out); return;
- case STORAGE_CLASS_STATIC: fputs("static ", out); return;
- case STORAGE_CLASS_AUTO: fputs("auto ", out); return;
+ case STORAGE_CLASS_TYPEDEF: fputs("typedef ", out); return;
+ case STORAGE_CLASS_EXTERN: fputs("extern ", out); return;
+ case STORAGE_CLASS_STATIC: fputs("static ", out); return;
+ case STORAGE_CLASS_AUTO: fputs("auto ", out); return;
case STORAGE_CLASS_REGISTER: fputs("register ", out); return;
}
panic("invalid storage class");
case ENTITY_NAMESPACE:
print_namespace(&entity->namespacee);
return;
+ case ENTITY_LOCAL_LABEL:
+ fprintf(out, "__label__ %s;", entity->base.symbol->string);
+ return;
case ENTITY_LABEL:
case ENTITY_ENUM_VALUE:
- case ENTITY_LOCAL_LABEL:
panic("print_entity used on unexpected entity type");
case ENTITY_INVALID:
break;
case EXPR_BINARY_BITWISE_AND:
case EXPR_BINARY_BITWISE_OR:
case EXPR_BINARY_BITWISE_XOR:
- case EXPR_BINARY_LOGICAL_AND:
- case EXPR_BINARY_LOGICAL_OR:
case EXPR_BINARY_SHIFTLEFT:
case EXPR_BINARY_SHIFTRIGHT:
case EXPR_BINARY_ISGREATER:
return is_constant_expression(expression->binary.left)
&& is_constant_expression(expression->binary.right);
+ case EXPR_BINARY_LOGICAL_AND: {
+ expression_t const *const left = expression->binary.left;
+ if (!is_constant_expression(left))
+ return false;
+ if (fold_constant(left) == 0)
+ return true;
+ return is_constant_expression(expression->binary.right);
+ }
+
+ case EXPR_BINARY_LOGICAL_OR: {
+ expression_t const *const left = expression->binary.left;
+ if (!is_constant_expression(left))
+ return false;
+ if (fold_constant(left) != 0)
+ return true;
+ return is_constant_expression(expression->binary.right);
+ }
+
case EXPR_COMPOUND_LITERAL:
return is_constant_initializer(expression->compound_literal.initializer);