From 64899475f9b895628fd7b654f7b549e50494229a Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 16 Sep 2013 16:26:46 +0800 Subject: [PATCH] discover/grub2: Function infrastructure improvements For user-defined functions, we'll need a data pointer to the function's execution callback. Add this as a void *, and change references from 'command' to 'function'. Signed-off-by: Jeremy Kerr --- discover/grub2/builtins.c | 16 +++++++---- discover/grub2/grub2.h | 18 +++++-------- discover/grub2/script.c | 56 ++++++++++++++++++++++++--------------- 3 files changed, 52 insertions(+), 38 deletions(-) diff --git a/discover/grub2/builtins.c b/discover/grub2/builtins.c index 379e870..55597c1 100644 --- a/discover/grub2/builtins.c +++ b/discover/grub2/builtins.c @@ -8,7 +8,9 @@ #include "grub2.h" -static int builtin_set(struct grub2_script *script, int argc, char *argv[]) +static int builtin_set(struct grub2_script *script, + void *data __attribute__((unused)), + int argc, char *argv[]) { char *name, *value, *p; int i; @@ -31,10 +33,13 @@ static int builtin_set(struct grub2_script *script, int argc, char *argv[]) return 0; } -static struct grub2_command commands[] = { +static struct { + const char *name; + grub2_function fn; +} builtins[] = { { .name = "set", - .exec = builtin_set + .fn = builtin_set }, }; @@ -42,6 +47,7 @@ void register_builtins(struct grub2_script *script) { unsigned int i; - for (i = 0; i < ARRAY_SIZE(commands); i++) - script_register_command(script, &commands[i]); + for (i = 0; i < ARRAY_SIZE(builtins); i++) + script_register_function(script, builtins[i].name, + builtins[i].fn, NULL); } diff --git a/discover/grub2/grub2.h b/discover/grub2/grub2.h index 1ac9f88..2de77a2 100644 --- a/discover/grub2/grub2.h +++ b/discover/grub2/grub2.h @@ -71,17 +71,10 @@ struct grub2_statement_block { struct grub2_statements *statements; }; -struct grub2_command { - const char *name; - int (*exec)(struct grub2_script *script, - int argc, char *argv[]); - struct list_item list; -}; struct grub2_script { struct grub2_statements *statements; struct list environment; - struct list commands; struct list symtab; struct discover_context *ctx; struct discover_boot_option *opt; @@ -96,6 +89,10 @@ struct grub2_root { char *uuid; }; +/* type for builtin functions */ +typedef int (*grub2_function)(struct grub2_script *script, void *data, + int argc, char *argv[]); + struct grub2_statements *create_statements(struct grub2_parser *parser); struct grub2_statement *create_statement_simple(struct grub2_parser *parser, @@ -145,11 +142,8 @@ const char *script_env_get(struct grub2_script *script, const char *name); void script_env_set(struct grub2_script *script, const char *name, const char *value); -void script_register_command(struct grub2_script *script, - struct grub2_command *command); - -struct grub2_command *script_lookup_command(struct grub2_script *script, - const char *name); +void script_register_function(struct grub2_script *script, + const char *name, grub2_function fn, void *data); void register_builtins(struct grub2_script *script); diff --git a/discover/grub2/script.c b/discover/grub2/script.c index 8b008c4..ec37fbb 100644 --- a/discover/grub2/script.c +++ b/discover/grub2/script.c @@ -20,6 +20,26 @@ struct env_entry { struct list_item list; }; +struct grub2_symtab_entry { + const char *name; + grub2_function fn; + void *data; + struct list_item list; +}; + +static struct grub2_symtab_entry *script_lookup_function( + struct grub2_script *script, const char *name) +{ + struct grub2_symtab_entry *entry; + + list_for_each_entry(&script->symtab, entry, list) { + if (!strcmp(entry->name, name)) + return entry; + } + + return NULL; +} + const char *script_env_get(struct grub2_script *script, const char *name) { struct env_entry *entry; @@ -208,7 +228,7 @@ int statement_simple_execute(struct grub2_script *script, struct grub2_statement *statement) { struct grub2_statement_simple *st = to_stmt_simple(statement); - struct grub2_command *cmd; + struct grub2_symtab_entry *entry; int rc; if (!st->argv) @@ -219,13 +239,13 @@ int statement_simple_execute(struct grub2_script *script, if (!st->argv->argc) return 0; - cmd = script_lookup_command(script, st->argv->argv[0]); - if (!cmd) { - fprintf(stderr, "undefined command '%s'\n", st->argv->argv[0]); + entry = script_lookup_function(script, st->argv->argv[0]); + if (!entry) { + fprintf(stderr, "undefined function '%s'\n", st->argv->argv[0]); return 0; } - rc = cmd->exec(script, st->argv->argc, st->argv->argv); + rc = entry->fn(script, entry->data, st->argv->argc, st->argv->argv); return rc; } @@ -290,23 +310,17 @@ static void init_env(struct grub2_script *script) list_add(&script->environment, &env->list); } -struct grub2_command *script_lookup_command(struct grub2_script *script, - const char *name) +void script_register_function(struct grub2_script *script, + const char *name, grub2_function fn, + void *data) { - struct grub2_command *command; - - list_for_each_entry(&script->commands, command, list) { - if (!strcmp(command->name, name)) - return command; - } + struct grub2_symtab_entry *entry; - return NULL; -} - -void script_register_command(struct grub2_script *script, - struct grub2_command *command) -{ - list_add(&script->commands, &command->list); + entry = talloc(script, struct grub2_symtab_entry); + entry->fn = fn; + entry->name = name; + entry->data = data; + list_add(&script->symtab, &entry->list); } @@ -326,7 +340,7 @@ struct grub2_script *create_script(struct grub2_parser *parser, script->ctx = ctx; script->opt = NULL; - list_init(&script->commands); + list_init(&script->symtab); register_builtins(script); return script; -- 2.39.2