+ /* use location of the parsed config file to determine the prefix */
+ env = talloc(script, struct env_entry);
+
+ prefix = NULL;
+ if (script->filename) {
+ sep = strrchr(script->filename, '/');
+ if (sep)
+ prefix = talloc_strndup(env, script->filename,
+ sep - script->filename);
+ }
+
+ script_env_set(script, "prefix", prefix ? : default_prefix);
+ if (prefix)
+ talloc_free(prefix);
+
+ /* establish feature settings */
+ script_env_set(script, "feature_menuentry_id", "y");
+}
+
+void script_register_function(struct grub2_script *script,
+ const char *name, grub2_function fn,
+ void *data)
+{
+ struct grub2_symtab_entry *entry;
+
+ entry = talloc(script, struct grub2_symtab_entry);
+ entry->fn = fn;
+ entry->name = name;
+ entry->data = data;
+ list_add(&script->symtab, &entry->list);
+}
+
+static void set_fallback_default(struct grub2_script *script)
+{
+ struct discover_boot_option *opt, *first = NULL;
+ bool have_default = false;
+
+ list_for_each_entry(&script->options, opt, list) {
+ if (!first)
+ first = opt;
+ have_default = have_default || opt->option->is_default;
+ }
+
+ if (!have_default && first) {
+ const char *env = script_env_get(script, "default");
+
+ pb_log("grub: no explicit default (env default=%s), "
+ "falling back to first option (%s)\n",
+ env ?: "unset", first->option->name);
+
+ first->option->is_default = true;
+ }
+}
+
+void script_execute(struct grub2_script *script)
+{
+ struct discover_boot_option *opt, *tmp;
+
+ init_env(script);
+ statements_execute(script, script->statements);
+
+ set_fallback_default(script);
+
+ list_for_each_entry_safe(&script->options, opt, tmp, list)
+ discover_context_add_boot_option(script->ctx, opt);
+
+ /* Our option list will be invalid, as we've added all options to the
+ * discover context */
+ list_init(&script->options);
+}
+
+struct grub2_script *create_script(struct grub2_parser *parser,
+ struct discover_context *ctx)
+{
+ struct grub2_script *script;
+
+ script = talloc_zero(parser, struct grub2_script);
+
+ script->ctx = ctx;
+
+ list_init(&script->symtab);
+ list_init(&script->options);
+ register_builtins(script);
+