Re: [RFC v4 3/9] Add basic Linux kernel support

Pedro Alves
2017-06-16T11:43:07Z

On 06/16/2017 11:10 AM, Philipp Rudo wrote:
> True, but that would lead to code duplication. That's why I chose the way
> using the two goto.
>
> Without goto the function reads like this
>
> struct lk_private_data *
> lk_init_struct (const char *name, const char *alias, int silent)
> {

> {
> /* Chek for "typedef struct { ... } name;"-like definitions. */
> sym = lookup_symbol (name, global, VAR_DOMAIN, NULL).symbol;
> if (sym == NULL)
> {
> if (!silent)
> error (_("Could not find %s. Aborting."), alias);
>
> return NULL;
> }
>
> type = check_typedef (SYMBOL_TYPE (sym));
> if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
> {
> if (!silent)
> error (_("Could not find %s. Aborting."), alias);
>
> return NULL;
> }
> }

You could add a helper function or lambda that handles the
error return. E.g., with a lambda it'd look something like:

lk_init_struct (const char *name, const char *alias, bool silent)
{
...
auto not_found = [=] ()
{
if (!silent)
error (_("Could not find %s. Aborting."), alias);
return NULL;
};
...
sym = lookup_symbol (name, global, VAR_DOMAIN, NULL).symbol;
if (sym == NULL)
return not_found ();

type = check_typedef (SYMBOL_TYPE (sym));
if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
return not_found ();

Alternatively, since NULL return is always an error
indication, split into two functions, one that returns
NULL if not found, and another that throws on error.
The latter calls the former. I.e., something like this:

/* Returns NULL if not found. */
lk_private_data *
lk_init_struct_nothrow (const char *name, const char *alias)
{
...
sym = lookup_symbol (name, global, VAR_DOMAIN, NULL).symbol;
if (sym == NULL)
return NULL;
...
return data;
}

/* Either returns non-NULL, or throws an error. */

lk_private_data *
lk_init_struct (const char *name, const char *alias)
{
lk_private_data *data = lk_init_struct_nothrow (name, alias);
if (data == NULL)
error (_("Could not find %s. Aborting."), alias);
return data;
}

Thanks,
Pedro Alves