Robert Shearman : widl: Eliminate redundant callback routines.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Jan 31 06:04:28 CST 2006
Module: wine
Branch: refs/heads/master
Commit: a6909fa5e82cc70fc376bddbe23dad38fd027ede
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=a6909fa5e82cc70fc376bddbe23dad38fd027ede
Author: Robert Shearman <rob at codeweavers.com>
Date: Tue Jan 31 12:24:11 2006 +0100
widl: Eliminate redundant callback routines.
Add a function for comparing expressions and use it to eliminate
redundant callback functions.
---
tools/widl/typegen.c | 83 +++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 71 insertions(+), 12 deletions(-)
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 6a17719..b429fa0 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -62,6 +62,52 @@ struct expr_eval_routine
static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array);
static size_t fields_memsize(const var_t *v);
+static int compare_expr(const expr_t *a, const expr_t *b)
+{
+ int ret;
+
+ if (a->type != b->type)
+ return a->type - b->type;
+
+ switch (a->type)
+ {
+ case EXPR_NUM:
+ case EXPR_HEXNUM:
+ return a->u.lval - b->u.lval;
+ case EXPR_IDENTIFIER:
+ return strcmp(a->u.sval, b->u.sval);
+ case EXPR_COND:
+ ret = compare_expr(a->ref, b->ref);
+ if (ret != 0)
+ return ret;
+ ret = compare_expr(a->u.ext, b->u.ext);
+ if (ret != 0)
+ return ret;
+ return compare_expr(a->ext2, b->ext2);
+ case EXPR_OR:
+ case EXPR_AND:
+ case EXPR_ADD:
+ case EXPR_SUB:
+ case EXPR_MUL:
+ case EXPR_DIV:
+ case EXPR_SHL:
+ case EXPR_SHR:
+ ret = compare_expr(a->ref, b->ref);
+ if (ret != 0)
+ return ret;
+ return compare_expr(a->u.ext, b->u.ext);
+ case EXPR_NOT:
+ case EXPR_NEG:
+ case EXPR_PPTR:
+ case EXPR_CAST:
+ case EXPR_SIZEOF:
+ return compare_expr(a->ref, b->ref);
+ case EXPR_VOID:
+ return 0;
+ }
+ return -1;
+}
+
static int print_file(FILE *file, int indent, const char *format, ...)
{
va_list va;
@@ -382,21 +428,31 @@ static size_t write_conf_or_var_desc(FIL
else
{
unsigned int callback_offset = 0;
- struct list *cursor;
-
- LIST_FOR_EACH(cursor, &expr_eval_routines)
- callback_offset++;
-
- if (callback_offset > USHRT_MAX)
- error("Maximum number of callback routines reached\n");
if (structure)
{
- struct expr_eval_routine *eval = xmalloc(sizeof(*eval));
- eval->structure = structure;
- eval->structure_size = fields_memsize(structure->fields);
- eval->expr = expr;
- list_add_tail(&expr_eval_routines, &eval->entry);
+ struct expr_eval_routine *eval;
+ int found = 0;
+
+ LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
+ {
+ if (!strcmp(eval->structure->name, structure->name) &&
+ !compare_expr(eval->expr, expr))
+ {
+ found = 1;
+ break;
+ }
+ callback_offset++;
+ }
+
+ if (!found)
+ {
+ eval = xmalloc(sizeof(*eval));
+ eval->structure = structure;
+ eval->structure_size = fields_memsize(structure->fields);
+ eval->expr = expr;
+ list_add_tail(&expr_eval_routines, &eval->entry);
+ }
correlation_type = RPC_FC_NORMAL_CONFORMANCE;
}
@@ -406,6 +462,9 @@ static size_t write_conf_or_var_desc(FIL
correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE;
}
+ if (callback_offset > USHRT_MAX)
+ error("Maximum number of callback routines reached\n");
+
print_file(file, 2, "0x%x, /* Corr desc: %s */\n",
correlation_type,
correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter" : "");
More information about the wine-cvs
mailing list