return 1;
if (script)
- grub_script_free (script);
+ grub_script_put (script);
- script = grub_malloc (sizeof (*script));
- if (! script)
- return 1;
-
- script->cmd = ctxt->script_params[0]->cmd;
- script->mem = ctxt->script_params[0]->mem;
- ctxt->script_params[0]->cmd = 0;
- ctxt->script_params[0]->mem = 0;
+ script = grub_script_get (ctxt->script_params[0]);
}
return 0;
GRUB_MOD_FINI(hello)
{
if (script)
- grub_script_free (script);
+ grub_script_put (script);
+ script = 0;
grub_unregister_extcmd (cmd);
}
struct grub_script
{
+ unsigned refcnt;
struct grub_script_mem *mem;
struct grub_script_cmd *cmd;
};
char *str;
/* Parsed block argument. */
- struct grub_script block;
+ struct grub_script *block;
/* Next argument part. */
struct grub_script_arg *next;
struct grub_lexer_param *lexerstate;
};
+void grub_script_mem_free (struct grub_script_mem *mem);
+
void grub_script_argv_free (struct grub_script_argv *argv);
int grub_script_argv_next (struct grub_script_argv *argv);
int grub_script_argv_append (struct grub_script_argv *argv, const char *s);
char **
grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count);
+static inline struct grub_script *
+grub_script_get (struct grub_script *script)
+{
+ script->refcnt++;
+ return script;
+}
+
+static inline void
+grub_script_put (struct grub_script *script)
+{
+ if (script->refcnt == 0)
+ grub_script_free (script);
+ else
+ script->refcnt--;
+}
+
#endif /* ! GRUB_NORMAL_PARSER_HEADER */
if (argv->scripts)
{
for (i = 0; i < argv->argc; i++)
- grub_script_free (argv->scripts[i]);
+ if (argv->scripts[i])
+ grub_script_put (argv->scripts[i]);
grub_free (argv->scripts);
}
grub_script_argv_script_append (struct grub_script_argv *argv,
struct grub_script *script)
{
- struct grub_script *s;
-
- s = grub_malloc (sizeof (*s));
- if (! s)
- return 1;
-
if (argv->scripts[argv->argc - 1])
- grub_script_free (argv->scripts[argv->argc - 1]);
+ grub_script_put (argv->scripts[argv->argc - 1]);
- *s = *script;
- argv->scripts[argv->argc - 1] = s;
+ argv->scripts[argv->argc - 1] = grub_script_get (script);
return 0;
}
case GRUB_SCRIPT_ARG_TYPE_BLOCK:
if (grub_script_argv_append (&result, arg->str) ||
- grub_script_argv_script_append (&result, &arg->block))
+ grub_script_argv_script_append (&result, arg->block))
goto fail;
break;
if ((p = grub_script_lexer_record_stop (state, $<offset>2)))
*grub_strrchr (p, '}') = '\0';
- if ((arg = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_BLOCK, p)))
- {
- arg->block.cmd = $3;
- arg->block.mem = memory;
- }
+ arg = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_BLOCK, p);
+ if (! arg || ! (arg->block = grub_script_create ($3, memory)))
+ grub_script_mem_free (memory);
$$ = grub_script_add_arglist (state, 0, arg);
grub_script_lexer_deref (state->lexerstate);
state->func_mem = grub_script_mem_record_stop (state,
state->func_mem);
script = grub_script_create ($6, state->func_mem);
- if (script)
- grub_script_function_create ($2, script);
+ if (! script)
+ grub_script_mem_free (state->func_mem);
+ else
+ grub_script_function_create ($2, script);
grub_script_lexer_deref (state->lexerstate);
}
}
/* Free all memory described by MEM. */
-static void
+void
grub_script_mem_free (struct grub_script_mem *mem)
{
struct grub_script_mem *memfree;
return arg;
argpart->type = type;
- argpart->block.mem = 0;
- argpart->block.cmd = 0;
+ argpart->block = 0;
len = grub_strlen (str) + 1;
argpart->str = grub_script_malloc (state, len);
struct grub_script *parsed;
parsed = grub_malloc (sizeof (*parsed));
- if (!parsed)
- {
- grub_script_mem_free (mem);
- grub_free (cmd);
-
- return 0;
- }
+ if (! parsed)
+ return 0;
parsed->mem = mem;
parsed->cmd = cmd;
+ parsed->refcnt = 0;
return parsed;
}
struct grub_lexer_param *lexstate;
struct grub_parser_param *parsestate;
- parsed = grub_malloc (sizeof (*parsed));
+ parsed = grub_script_create (0, 0);
if (!parsed)
return 0;