widl: Remove duplicated code in the form of the write_struct_expr function by enhancing write_expr to allow toplevel identifiers to be prefixed by a string, if specified.
diff --git a/tools/widl/expr.c b/tools/widl/expr.c index ca9986a..1265e43 100644 --- a/tools/widl/expr.c +++ b/tools/widl/expr.c
@@ -354,6 +354,44 @@ expr_loc->attr ? expr_loc->attr : ""); } +static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type) +{ + type_t *type = NULL; + const var_t *field; + const var_list_t *fields = NULL; + + *found_in_cont_type = 0; + + if (cont_type && (cont_type->type == RPC_FC_FUNCTION || is_struct(cont_type->type))) + fields = cont_type->fields_or_args; + else if (cont_type && is_union(cont_type->type)) + { + if (cont_type->type == RPC_FC_ENCAPSULATED_UNION) + { + const var_t *uv = LIST_ENTRY(list_tail(cont_type->fields_or_args), const var_t, entry); + fields = uv->type->fields_or_args; + } + else + fields = cont_type->fields_or_args; + } + + if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) + if (field->name && !strcmp(identifier, field->name)) + { + type = field->type; + *found_in_cont_type = 1; + break; + } + + if (!type) + { + var_t *const_var = find_const(identifier, 0); + if (const_var) type = const_var->type; + } + + return type; +} + static struct expression_type resolve_expression(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *e) @@ -380,34 +418,10 @@ break; case EXPR_IDENTIFIER: { - const var_t *field; - const var_list_t *fields = NULL; - - if (cont_type && (cont_type->type == RPC_FC_FUNCTION || is_struct(cont_type->type))) - fields = cont_type->fields_or_args; - else if (cont_type && is_union(cont_type->type)) - { - if (cont_type->type == RPC_FC_ENCAPSULATED_UNION) - { - const var_t *uv = LIST_ENTRY(list_tail(cont_type->fields_or_args), const var_t, entry); - fields = uv->type->fields_or_args; - } - else - fields = cont_type->fields_or_args; - } - - if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) - if (field->name && !strcmp(e->u.sval, field->name)) - { - result.type = field->type; - break; - } - - if (!result.type) - { - var_t *const_var = find_const(e->u.sval, 0); - if (const_var) result.type = const_var->type; - } + int found_in_cont_type; + result.is_variable = TRUE; + result.is_temporary = FALSE; + result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type); if (!result.type) { error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n", @@ -550,7 +564,9 @@ return expr_type.type; } -void write_expr(FILE *h, const expr_t *e, int brackets) +void write_expr(FILE *h, const expr_t *e, int brackets, + int toplevel, const char *toplevel_prefix, + const type_t *cont_type) { switch (e->type) { @@ -572,37 +588,43 @@ fprintf(h, "TRUE"); break; case EXPR_IDENTIFIER: + if (toplevel && toplevel_prefix && cont_type) + { + int found_in_cont_type; + find_identifier(e->u.sval, cont_type, &found_in_cont_type); + if (found_in_cont_type) fprintf(h, "%s", toplevel_prefix); + } fprintf(h, "%s", e->u.sval); break; case EXPR_LOGNOT: fprintf(h, "!"); - write_expr(h, e->ref, 1); + write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type); break; case EXPR_NOT: fprintf(h, "~"); - write_expr(h, e->ref, 1); + write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type); break; case EXPR_POS: fprintf(h, "+"); - write_expr(h, e->ref, 1); + write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type); break; case EXPR_NEG: fprintf(h, "-"); - write_expr(h, e->ref, 1); + write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type); break; case EXPR_ADDRESSOF: fprintf(h, "&"); - write_expr(h, e->ref, 1); + write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type); break; case EXPR_PPTR: fprintf(h, "*"); - write_expr(h, e->ref, 1); + write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type); break; case EXPR_CAST: fprintf(h, "("); write_type_decl(h, e->u.tref, NULL); fprintf(h, ")"); - write_expr(h, e->ref, 1); + write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type); break; case EXPR_SIZEOF: fprintf(h, "sizeof("); @@ -628,7 +650,7 @@ case EXPR_GTREQL: case EXPR_LESSEQL: if (brackets) fprintf(h, "("); - write_expr(h, e->ref, 1); + write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type); switch (e->type) { case EXPR_SHL: fprintf(h, " << "); break; @@ -651,38 +673,38 @@ case EXPR_LESSEQL: fprintf(h, " <= "); break; default: break; } - write_expr(h, e->u.ext, 1); + write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type); if (brackets) fprintf(h, ")"); break; case EXPR_MEMBER: if (brackets) fprintf(h, "("); if (e->ref->type == EXPR_PPTR) { - write_expr(h, e->ref->ref, 1); + write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type); fprintf(h, "->"); } else { - write_expr(h, e->ref, 1); + write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type); fprintf(h, "."); } - write_expr(h, e->u.ext, 1); + write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type); if (brackets) fprintf(h, ")"); break; case EXPR_COND: if (brackets) fprintf(h, "("); - write_expr(h, e->ref, 1); + write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type); fprintf(h, " ? "); - write_expr(h, e->u.ext, 1); + write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type); fprintf(h, " : "); - write_expr(h, e->ext2, 1); + write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type); if (brackets) fprintf(h, ")"); break; case EXPR_ARRAY: if (brackets) fprintf(h, "("); - write_expr(h, e->ref, 1); + write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type); fprintf(h, "["); - write_expr(h, e->u.ext, 1); + write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type); fprintf(h, "]"); if (brackets) fprintf(h, ")"); break;
diff --git a/tools/widl/expr.h b/tools/widl/expr.h index e32ec29..1b773e0 100644 --- a/tools/widl/expr.h +++ b/tools/widl/expr.h
@@ -37,4 +37,4 @@ extern const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr); extern int compare_expr(const expr_t *a, const expr_t *b); -extern void write_expr(FILE *h, const expr_t *e, int brackets); +extern void write_expr(FILE *h, const expr_t *e, int brackets, int toplevel, const char *toplevel_prefix, const type_t *cont_type);
diff --git a/tools/widl/header.c b/tools/widl/header.c index a22a3ec..3915244 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c
@@ -195,7 +195,7 @@ write_name(h, v); if (v->eval) { fprintf(h, " = "); - write_expr(h, v->eval, 0); + write_expr(h, v->eval, 0, 1, NULL, NULL); } } if (list_next( enums, &v->entry )) fprintf(h, ",\n"); @@ -476,7 +476,7 @@ void write_constdef(const var_t *v) { fprintf(header, "#define %s (", v->name); - write_expr(header, v->eval, 0); + write_expr(header, v->eval, 0, 1, NULL, NULL); fprintf(header, ")\n\n"); }
diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c index 01ad4da..2fa0a4d 100644 --- a/tools/widl/proxy.c +++ b/tools/widl/proxy.c
@@ -194,7 +194,7 @@ if (size) { print_proxy( "_StubMsg.MaxCount = " ); - write_expr(proxy, size, 0); + write_expr(proxy, size, 0, 1, NULL, NULL); fprintf(proxy, ";\n\n"); print_proxy( "NdrClearOutParameters( &_StubMsg, "); fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset ); @@ -222,7 +222,7 @@ if( iid ) { print_proxy( "_StubMsg.MaxCount = (unsigned long) " ); - write_expr(proxy, iid, 1); + write_expr(proxy, iid, 1, 1, NULL, NULL); print_proxy( ";\n\n" ); } print_proxy( "NdrClearOutParameters( &_StubMsg, ");
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index 7a5f6f9..a2f8258 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c
@@ -2759,7 +2759,7 @@ if (type->size_is && is_size_needed_for_phase(phase)) { print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, type->size_is, 1); + write_expr(file, type->size_is, 1, 1, NULL, NULL); fprintf(file, ";\n"); } @@ -2789,7 +2789,7 @@ { print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); - write_expr(file, type->length_is, 1); + write_expr(file, type->length_is, 1, 1, NULL, NULL); fprintf(file, ";\n\n"); } array_type = "VaryingArray"; @@ -2799,7 +2799,7 @@ if (is_size_needed_for_phase(phase)) { print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, type->size_is, 1); + write_expr(file, type->size_is, 1, 1, NULL, NULL); fprintf(file, ";\n\n"); } array_type = "ConformantArray"; @@ -2811,14 +2811,14 @@ if (type->size_is) { print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, type->size_is, 1); + write_expr(file, type->size_is, 1, 1, NULL, NULL); fprintf(file, ";\n"); } if (type->length_is) { print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); - write_expr(file, type->length_is, 1); + write_expr(file, type->length_is, 1, 1, NULL, NULL); fprintf(file, ";\n\n"); } } @@ -2882,7 +2882,7 @@ if ((iid = get_attrp( var->attrs, ATTR_IIDIS ))) { print_file( file, indent, "_StubMsg.MaxCount = (unsigned long) " ); - write_expr( file, iid, 1 ); + write_expr( file, iid, 1, 1, NULL, NULL ); fprintf( file, ";\n\n" ); } print_phase_function(file, indent, "Pointer", phase, var, start_offset); @@ -2912,13 +2912,13 @@ if ((iid = get_attrp( var->attrs, ATTR_IIDIS ))) { print_file( file, indent, "_StubMsg.MaxCount = (unsigned long) " ); - write_expr( file, iid, 1 ); + write_expr( file, iid, 1, 1, NULL, NULL ); fprintf( file, ";\n\n" ); } else if (sx) { print_file(file, indent, "_StubMsg.MaxCount = (unsigned long) "); - write_expr(file, sx, 1); + write_expr(file, sx, 1, 1, NULL, NULL); fprintf(file, ";\n\n"); } if (var->type->ref->type == RPC_FC_IP) @@ -3009,156 +3009,6 @@ return process_tfs(NULL, ifaces, pred); } -static void write_struct_expr(FILE *h, const expr_t *e, int brackets, - const var_list_t *fields, const char *structvar) -{ - switch (e->type) { - case EXPR_VOID: - break; - case EXPR_NUM: - fprintf(h, "%lu", e->u.lval); - break; - case EXPR_HEXNUM: - fprintf(h, "0x%lx", e->u.lval); - break; - case EXPR_DOUBLE: - fprintf(h, "%#.15g", e->u.dval); - break; - case EXPR_TRUEFALSE: - if (e->u.lval == 0) - fprintf(h, "FALSE"); - else - fprintf(h, "TRUE"); - break; - case EXPR_IDENTIFIER: - { - const var_t *field; - LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) - if (!strcmp(e->u.sval, field->name)) - { - fprintf(h, "%s->%s", structvar, e->u.sval); - break; - } - - if (&field->entry == fields) error("no field found for identifier %s\n", e->u.sval); - break; - } - case EXPR_LOGNOT: - fprintf(h, "!"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_NOT: - fprintf(h, "~"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_POS: - fprintf(h, "+"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_NEG: - fprintf(h, "-"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_ADDRESSOF: - fprintf(h, "&"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_PPTR: - fprintf(h, "*"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_CAST: - fprintf(h, "("); - write_type_decl(h, e->u.tref, NULL); - fprintf(h, ")"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_SIZEOF: - fprintf(h, "sizeof("); - write_type_decl(h, e->u.tref, NULL); - fprintf(h, ")"); - break; - case EXPR_SHL: - case EXPR_SHR: - case EXPR_MOD: - case EXPR_MUL: - case EXPR_DIV: - case EXPR_ADD: - case EXPR_SUB: - case EXPR_AND: - case EXPR_OR: - case EXPR_LOGOR: - case EXPR_LOGAND: - case EXPR_XOR: - case EXPR_EQUALITY: - case EXPR_INEQUALITY: - case EXPR_GTR: - case EXPR_LESS: - case EXPR_GTREQL: - case EXPR_LESSEQL: - if (brackets) fprintf(h, "("); - write_struct_expr(h, e->ref, 1, fields, structvar); - switch (e->type) { - case EXPR_SHL: fprintf(h, " << "); break; - case EXPR_SHR: fprintf(h, " >> "); break; - case EXPR_MOD: fprintf(h, " %% "); break; - case EXPR_MUL: fprintf(h, " * "); break; - case EXPR_DIV: fprintf(h, " / "); break; - case EXPR_ADD: fprintf(h, " + "); break; - case EXPR_SUB: fprintf(h, " - "); break; - case EXPR_AND: fprintf(h, " & "); break; - case EXPR_OR: fprintf(h, " | "); break; - case EXPR_MEMBER: fprintf(h, "."); break; - case EXPR_LOGOR: fprintf(h, " || "); break; - case EXPR_LOGAND: fprintf(h, " && "); break; - case EXPR_XOR: fprintf(h, " ^ "); break; - case EXPR_EQUALITY: fprintf(h, " == "); break; - case EXPR_INEQUALITY: fprintf(h, " != "); break; - case EXPR_GTR: fprintf(h, " > "); break; - case EXPR_LESS: fprintf(h, " < "); break; - case EXPR_GTREQL: fprintf(h, " >= "); break; - case EXPR_LESSEQL: fprintf(h, " <= "); break; - default: break; - } - write_struct_expr(h, e->u.ext, 1, fields, structvar); - if (brackets) fprintf(h, ")"); - break; - case EXPR_MEMBER: - if (brackets) fprintf(h, "("); - if (e->ref->type == EXPR_PPTR) - { - write_expr(h, e->ref->ref, 1); - fprintf(h, "->"); - } - else - { - write_expr(h, e->ref, 1); - fprintf(h, "."); - } - write_expr(h, e->u.ext, 1); - if (brackets) fprintf(h, ")"); - break; - case EXPR_COND: - if (brackets) fprintf(h, "("); - write_struct_expr(h, e->ref, 1, fields, structvar); - fprintf(h, " ? "); - write_struct_expr(h, e->u.ext, 1, fields, structvar); - fprintf(h, " : "); - write_struct_expr(h, e->ext2, 1, fields, structvar); - if (brackets) fprintf(h, ")"); - break; - case EXPR_ARRAY: - if (brackets) fprintf(h, "("); - write_struct_expr(h, e->ref, 1, fields, structvar); - fprintf(h, "["); - write_struct_expr(h, e->u.ext, 1, fields, structvar); - fprintf(h, "]"); - if (brackets) fprintf(h, ")"); - break; - } -} - - void declare_stub_args( FILE *file, int indent, const func_t *func ) { int in_attr, out_attr; @@ -3254,7 +3104,7 @@ fprintf(file, " = NdrAllocate(&_StubMsg, "); for ( ; type->size_is ; type = type->ref) { - write_expr(file, type->size_is, TRUE); + write_expr(file, type->size_is, TRUE, TRUE, NULL, NULL); fprintf(file, " * "); } size = type_memsize(type, &align); @@ -3279,6 +3129,7 @@ int write_expr_eval_routines(FILE *file, const char *iface) { static const char *var_name = "pS"; + static const char *var_name_expr = "pS->"; int result = 0; struct expr_eval_routine *eval; unsigned short callback_offset = 0; @@ -3286,7 +3137,6 @@ LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) { const char *name = eval->structure->name; - const var_list_t *fields = eval->structure->fields_or_args; result = 1; print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n", @@ -3296,7 +3146,7 @@ name, var_name, name, eval->baseoff); print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */ print_file(file, 1, "pStubMsg->MaxCount = (unsigned long)"); - write_struct_expr(file, eval->expr, 1, fields, var_name); + write_expr(file, eval->expr, 1, 1, var_name_expr, eval->structure); fprintf(file, ";\n"); print_file(file, 0, "}\n\n"); callback_offset++;