* Re: [PATCH v4 2/4] blsuki: Add blscfg command to parse Boot Loader Specification snippets
[not found] <mailman.2919.1747831917.8051.grub-devel@gnu.org>
@ 2025-05-29 10:59 ` Avnish Chouhan
2025-06-03 19:47 ` [External] : " Alec Brown via Grub-devel
0 siblings, 1 reply; 5+ messages in thread
From: Avnish Chouhan @ 2025-05-29 10:59 UTC (permalink / raw)
To: alec.r.brown; +Cc: grub-devel, Daniel Kiper
On 2025-05-21 18:21, grub-devel-request@gnu.org wrote:
> Send Grub-devel mailing list submissions to
> grub-devel@gnu.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
> https://lists.gnu.org/mailman/listinfo/grub-devel
> or, via email, send a message with subject or body 'help' to
> grub-devel-request@gnu.org
>
> You can reach the person managing the list at
> grub-devel-owner@gnu.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Grub-devel digest..."
>
>
> Today's Topics:
>
> 1. [PATCH v4 2/4] blsuki: Add blscfg command to parse Boot
> Loader Specification snippets (Alec Brown)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Wed, 21 May 2025 12:51:24 +0000
> From: Alec Brown <alec.r.brown@oracle.com>
> To: grub-devel@gnu.org
> Cc: christopher.obbard@linaro.org, daniel.kiper@oracle.com,
> jan.setjeeilers@oracle.com, alec.r.brown@oracle.com,
> mate.kukri@canonical.com, pjones@redhat.com,
> ross.philipson@oracle.com, 93sam@debian.org, phcoder@gmail.com
> Subject: [PATCH v4 2/4] blsuki: Add blscfg command to parse Boot
> Loader Specification snippets
> Message-ID: <20250521125126.3928350-3-alec.r.brown@oracle.com>
>
> From: Peter Jones <pjones@redhat.com>
>
> The BootLoaderSpec (BLS) defines a scheme where different bootloaders
> can
> share a format for boot items and a configuration directory that
> accepts
> these common configurations as drop-in files.
>
> The BLS Specification:
> https://uapi-group.org/specifications/specs/boot_loader_specification/
>
> Signed-off-by: Peter Jones <pjones@redhat.com>
> Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
> Signed-off-by: Will Thompson <wjt@endlessm.com>
> Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
> ---
> docs/grub.texi | 47 ++
> grub-core/Makefile.core.def | 10 +
> grub-core/commands/blsuki.c | 1198 ++++++++++++++++++++++++++++++++
> grub-core/commands/legacycfg.c | 4 +-
> grub-core/commands/menuentry.c | 8 +-
> grub-core/normal/main.c | 6 +
> include/grub/menu.h | 15 +
> include/grub/normal.h | 2 +-
> 8 files changed, 1284 insertions(+), 6 deletions(-)
> create mode 100644 grub-core/commands/blsuki.c
>
> diff --git a/docs/grub.texi b/docs/grub.texi
> index d9b26fa36..adab93668 100644
> --- a/docs/grub.texi
> +++ b/docs/grub.texi
> @@ -6417,6 +6417,7 @@ you forget a command, you can run the command
> @command{help}
> * background_image:: Load background image for active
> terminal
> * badram:: Filter out bad regions of RAM
> * blocklist:: Print a block list
> +* blscfg:: Load Boot Loader Specification menu
> entries
> * boot:: Start up your operating system
> * cat:: Show the contents of a file
> * clear:: Clear the screen
> @@ -6603,6 +6604,52 @@ Print a block list (@pxref{Block list syntax})
> for @var{file}.
> @end deffn
>
>
> +@node blscfg
> +@subsection blscfg
> +
> +@deffn Command blscfg [@option{-p|--path} dir]
> [@option{-f|--enable-fallback}] [@option{-d|--show-default}]
> [@option{-n|--show-non-default}] [@option{-e|--entry} file]
> +Load Boot Loader Specification (BLS) entries into the GRUB menu. Boot
> entries
> +generated from @command{blscfg} won't interfere with entries from
> @file{grub.cfg} appearing in
> +the GRUB menu. Also, entries generated from @command{blscfg} only
> generate in memory and
> +don't update @file{grub.cfg}.
> +
> +The @option{--path} option overrides the default path to the
> directory containing
> +the BLS entries. If this option isn't used, the default location is
> +/loader/entries in @code{$BOOT}. If no BLS entries are found, the
> +@option{--enable-fallback} option can be used to check for entries in
> the default
> +directory.
> +
> +The @option{--show-default} option allows the default boot entry to
> be added to the
> +GRUB menu from the BLS entries.
> +
> +The @option{--show-non-default} option allows non-default boot
> entries to be added to
> +the GRUB menu from the BLS entries.
> +
> +The @option{--entry} option allows specific boot entries to be added
> to the GRUB menu
> +from the BLS entries.
> +
> +The @option{--entry}, @option{--show-default}, and
> @option{--show-non-default} options
> +are used to filter which BLS entries are added to the GRUB menu. If
> none are
> +used, all entries in the default location or the location specified
> by @option{--path}
> +will be added to the GRUB menu.
> +
> +A BLS config file example:
> +@example
> +#
> /boot/loader/entries/6a9857a393724b7a981ebb5b8495b9ea-3.8.0-2.fc19.x86_64.conf
> +title Fedora 19 (Rawhide)
> +sort-key fedora
> +machine-id 6a9857a393724b7a981ebb5b8495b9ea
> +version 3.8.0-2.fc19.x86_64
> +options root=UUID=6d3376e4-fc93-4509-95ec-a21d68011da2 quiet
> +architecture x64
> +linux
> /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/linux
> +initrd
> /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/initrd
> +@end example
> +
> +References:
> @uref{https://uapi-group.org/specifications/specs/boot_loader_specification/,
> The Boot Loader Specification}
> +@end deffn
> +
> +
> @node boot
> @subsection boot
>
> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> index f70e02e69..67628f65f 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -845,6 +845,16 @@ module = {
> common = commands/blocklist.c;
> };
>
> +module = {
> + name = blsuki;
> + common = commands/blsuki.c;
> + common = kern/vercmp.c;
> + enable = powerpc_ieee1275;
> + enable = efi;
> + enable = i386_pc;
> + enable = emu;
> +};
> +
> module = {
> name = boot;
> common = commands/boot.c;
> diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
> new file mode 100644
> index 000000000..2ad960ae3
> --- /dev/null
> +++ b/grub-core/commands/blsuki.c
> @@ -0,0 +1,1198 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2025 Free Software Foundation, Inc.
> + *
> + * GRUB is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published
> by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <grub/list.h>
> +#include <grub/types.h>
> +#include <grub/misc.h>
> +#include <grub/mm.h>
> +#include <grub/err.h>
> +#include <grub/dl.h>
> +#include <grub/extcmd.h>
> +#include <grub/i18n.h>
> +#include <grub/fs.h>
> +#include <grub/env.h>
> +#include <grub/file.h>
> +#include <grub/normal.h>
> +#include <grub/safemath.h>
> +#include <grub/vercmp.h>
> +#include <grub/lib/envblk.h>
> +
> +GRUB_MOD_LICENSE ("GPLv3+");
> +
> +#define GRUB_BLS_CONFIG_PATH "/loader/entries/"
> +
> +static const struct grub_arg_option bls_opt[] =
> + {
> + {"path", 'p', 0, "Specify path to find BLS entries.", N_("DIR"),
> ARG_TYPE_PATHNAME},
> + {"enable-fallback", 'f', 0, "Fallback to the default BLS path if
> --path fails to find BLS entries.", 0, ARG_TYPE_NONE},
> + {"show-default", 'd', 0, "Allow the default BLS entry to be added
> to the GRUB menu.", 0, ARG_TYPE_NONE},
> + {"show-non-default", 'n', 0, "Allow the non-default BLS entries
> to be added to the GRUB menu.", 0, ARG_TYPE_NONE},
> + {"entry", 'e', 0, "Allow specific BLS entries to be added to the
> GRUB menu.", N_("FILE"), ARG_TYPE_FILE},
> + {0, 0, 0, 0, 0, 0}
> + };
> +
> +struct keyval
> +{
> + const char *key;
> + char *val;
> +};
> +
> +static grub_blsuki_entry_t *entries = NULL;
> +
> +#define FOR_BLSUKI_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
> +
> +/*
> + * This function will add a new keyval pair to a list of keyvals
> stored in the
> + * entry parameter.
> + */
> +static grub_err_t
> +blsuki_add_keyval (grub_blsuki_entry_t *entry, char *key, char *val)
> +{
> + char *k, *v;
> + struct keyval **kvs, *kv;
> + grub_size_t size;
> + int new_n = entry->nkeyvals + 1;
> +
> + if (entry->keyvals_size == 0)
> + {
> + size = sizeof (struct keyval *);
> + kvs = grub_malloc (size);
> + if (kvs == NULL)
> + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate space
> for BLS key values");
Hi Alec,
Indentation seems off here!
> +
> + entry->keyvals = kvs;
> + entry->keyvals_size = size;
> + }
> + else if (entry->keyvals_size < new_n * sizeof (struct keyval *))
> + {
> + size = entry->keyvals_size * 2;
> + kvs = grub_realloc (entry->keyvals, size);
> + if (kvs == NULL)
> + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't reallocate
> space for BLS key values");
> +
Indentation seems off here!
> + entry->keyvals = kvs;
> + entry->keyvals_size = size;
> + }
> +
> + kv = grub_malloc (sizeof (struct keyval));
> + if (kv == NULL)
> + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't find space
> for new BLS key value");
> +
> + k = grub_strdup (key);
> + if (k == NULL)
> + {
> + grub_free (kv);
> + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't find space
> for new BLS key value");
> + }
> +
> + v = grub_strdup (val);
> + if (v == NULL)
> + {
> + grub_free (k);
> + grub_free (kv);
> + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't find space
> for new BLS key value");
> + }
> +
> + kv->key = k;
> + kv->val = v;
> +
> + entry->keyvals[entry->nkeyvals] = kv;
> + entry->nkeyvals = new_n;
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +/*
> + * Find the value of the key named by keyname. If there are allowed to
> be
> + * more than one, pass a pointer to an int set to -1 the first time,
> and pass
> + * the same pointer through each time after, and it'll return them in
> sorted
> + * order as defined in the BLS fragment file.
> + */
> +static char *
> +blsuki_get_val (grub_blsuki_entry_t *entry, const char *keyname, int
> *last)
> +{
> + int idx, start = 0;
> + struct keyval *kv = NULL;
> + char *ret = NULL;
> +
> + if (last != NULL)
> + start = *last + 1;
> +
> + for (idx = start; idx < entry->nkeyvals; idx++)
> + {
> + kv = entry->keyvals[idx];
> +
> + if (grub_strcmp (keyname, kv->key) == 0)
> + {
> + ret = kv->val;
> + break;
> + }
Indentation seems off in if condition!
> + }
> +
> + if (last != NULL)
> + {
> + if (idx == entry->nkeyvals)
> + *last = -1;
> + else
> + *last = idx;
Same as above!
> + }
> +
> + return ret;
> +}
> +
> +/*
> + * Add a new grub_blsuki_entry_t struct to the entries list and sort
> it's
> + * position on the list.
> + */
> +static grub_err_t
> +blsuki_add_entry (grub_blsuki_entry_t *entry)
> +{
> + grub_blsuki_entry_t *e, *last = NULL;
> + grub_err_t err;
> + int rc;
> +
> + if (entries == NULL)
> + {
> + grub_dprintf ("blsuki", "Add entry with id \"%s\"\n",
> entry->filename);
> + entries = entry;
> + return GRUB_ERR_NONE;
> + }
> +
> + FOR_BLSUKI_ENTRIES (e)
> + {
> + err = grub_split_vercmp (entry->filename, e->filename, true,
> &rc);
> + if (err != GRUB_ERR_NONE)
> + return err;
Indentation seems off!
> +
> + if (rc == GRUB_VERCMP_SAME)
> + return grub_error (GRUB_ERR_BAD_ARGUMENT, "duplicate file");
> +
Same here!
> + if (rc == GRUB_VERCMP_NEWER)
> + {
> + grub_dprintf ("blsuki", "Add entry with id \"%s\"\n",
> entry->filename);
> + grub_list_push (GRUB_AS_LIST_P (&e), GRUB_AS_LIST (entry));
> + if (entry->next == entries)
> + {
> + entries = entry;
> + entry->prev = NULL;
> + }
> + else
> + last->next = entry;
> + return GRUB_ERR_NONE;
> + }
> + last = e;
> + }
Indentation seems off in if condition!
> +
> + if (last != NULL)
> + {
> + grub_dprintf ("blsuki", "Add entry with id \"%s\"\n",
> entry->filename);
> + last->next = entry;
> + entry->prev = &last;
> + }
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +/*
> + * This function parses each line of a BLS config file to obtain the
> key value
> + * pairs that will be used to setup the GRUB menu entries. The key
> value pair
> + * will be stored in a list in the entry parameter.
> + */
> +static grub_err_t
> +bls_parse_keyvals (grub_file_t f, grub_blsuki_entry_t *entry)
> +{
> + grub_err_t err = GRUB_ERR_NONE;
> +
> + for (;;)
> + {
> + char *buf;
> + char *separator;
> +
> + buf = grub_file_getline (f);
> + if (buf == NULL)
> + break;
Indentation seems off!
> +
> + while (buf != NULL && buf[0] != '\0' && (buf[0] == ' ' ||
> buf[0] == '\t'))
> + buf++;
Indentation seems off!
> + if (buf[0] == '#')
> + {
> + grub_free (buf);
> + continue;
> + }
Indentation seems off in if condition!
> +
> + separator = grub_strchr (buf, ' ');
> +
> + if (separator == NULL)
> + separator = grub_strchr (buf, '\t');
Indentation seems off!
> +
> + if (separator == NULL || separator[1] == '\0')
> + {
> + grub_free (buf);
> + break;
> + }
Indentation seems off in if condition!
> +
> + separator[0] = '\0';
> +
> + do
> + {
> + separator++;
> + }
Indentation seems off!
> + while (*separator == ' ' || *separator == '\t');
What's the use of this while condition? It may result in an infinite
loop...
> +
> + err = blsuki_add_keyval (entry, buf, separator);
> + grub_free (buf);
> + if (err != GRUB_ERR_NONE)
> + break;
Indentation seems off!
> + }
> +
> + return err;
> +}
> +
> +struct read_entry_info
> +{
> + const char *devid;
> + const char *dirname;
> + grub_file_t file;
> +};
> +
> +/*
> + * If a file hasn't already been opened, this function opens a BLS
> config file
> + * and initializes entry data before parsing keyvals and adding the
> entry to
> + * the list of BLS entries.
> + */
> +static int
> +blsuki_read_entry (const char *filename,
> + const struct grub_dirhook_info *dirhook_info __attribute__
> ((__unused__)),
> + void *data)
Indentation seems off!
blsuki_read_entry (const char *filename,
const struct grub_dirhook_info *dirhook_info
__attribute__ ((__unused__)),
void *data)
> +{
> + grub_size_t prefix_len = 0, filename_len, ext_len = 5;
> + grub_err_t err;
> + char *p = NULL;
> + grub_file_t f = NULL;
> + grub_blsuki_entry_t *entry;
> + struct read_entry_info *info = (struct read_entry_info *) data;
> +
> + grub_dprintf ("blsuki", "filename: \"%s\"\n", filename);
> +
> + filename_len = grub_strlen (filename);
> +
> + if (info->file != NULL)
> + f = info->file;
> + else
> + {
> + if (filename_len < ext_len || grub_strcmp (filename +
> filename_len - ext_len, ".conf") != 0)
> + return 0;
Indentation seems off!
> +
> + p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname,
> filename);
> +
> + f = grub_file_open (p, GRUB_FILE_TYPE_CONFIG);
> + grub_free (p);
> + if (f == NULL)
> + goto finish;
Indentation seems off!
> + }
> +
> + entry = grub_zalloc (sizeof (*entry));
> + if (entry == NULL)
> + goto finish;
> +
> + /*
> + * If a file is opened before this function, the filename may have a
> prefix.
> + * Since the filename is used for the ID of the GRUB menu entry, we
> can
> + * remove the prefix.
> + */
> + if (info->file != NULL)
> + {
> + char *slash;
> +
> + slash = grub_strrchr (filename, '/');
> + if (slash == NULL)
> + slash = grub_strrchr (filename, '\\');
Indentation seems off!
> +
> + if (slash != NULL)
> + {
> + while (*slash == '/' || *slash == '\\')
> + slash++;
> +
> + prefix_len = slash - filename;
> + }
Indentation seems off in if condition!
> + }
> + filename_len -= prefix_len;
> +
> + entry->filename = grub_strndup (filename + prefix_len,
> filename_len);
> + if (entry->filename == NULL)
> + {
> + grub_free (entry);
> + goto finish;
> + }
> +
> + err = bls_parse_keyvals (f, entry);
> +
> + if (err == GRUB_ERR_NONE)
> + blsuki_add_entry (entry);
> + else
> + grub_free (entry);
> +
> + finish:
> + if (f != NULL)
> + grub_file_close (f);
> +
> + return 0;
> +}
> +
> +/*
> + * This function returns a list of values that had the same key in the
> BLS
> + * config file. The number of entries in this list is returned by the
> len
> + * parameter.
> + */
> +static char **
> +blsuki_make_list (grub_blsuki_entry_t *entry, const char *key, int
> *len)
> +{
> + int last = -1;
> + char *val;
> + int nlist = 0;
> + char **list;
> +
> + list = grub_zalloc (sizeof (char *));
> + if (list == NULL)
> + return NULL;
> +
> + while (1)
> + {
> + char **new;
> +
> + /*
> + * Since the same key might appear more than once, the 'last'
> variable
> + * starts at -1 and increments to indicate the last index in the
> list
> + * we obtained from blsuki_get_val().
> + */
> + val = blsuki_get_val (entry, key, &last);
> + if (val == NULL)
> + break;
Indentation seems off!
> +
> + new = grub_realloc (list, (nlist + 2) * sizeof (char *));
> + if (new == NULL)
> + break;
Indentation seems off!
> +
> + list = new;
> + list[nlist++] = val;
> + list[nlist] = NULL;
> + }
> +
> + if (nlist == 0)
> + {
> + grub_free (list);
> + return NULL;
> + }
> +
> + if (len != NULL)
> + *len = nlist;
> +
> + return list;
> +}
> +
> +/*
> + * This function appends a field to the end of a buffer. If the field
> given is
> + * an enviornmental variable, it gets the value stored for that
> variable and
> + * appends that to the buffer instead.
> + */
> +static char *
> +blsuki_field_append (bool is_env_var, char *buffer, const char
> *start, const char *end)
> +{
> + char *tmp;
> + const char *field;
> + int term = (is_env_var == true) ? 2 : 1;
> + grub_size_t size = 0;
> +
> + tmp = grub_strndup (start, end - start + 1);
> + if (tmp == NULL)
> + return NULL;
> +
> + field = tmp;
> +
> + if (is_env_var == true)
> + {
> + field = grub_env_get (tmp);
> + if (field == NULL)
> + return buffer;
> + }
> +
> + if (grub_add (grub_strlen (field), term, &size))
> + return NULL;
> +
> + if (buffer == NULL)
> + buffer = grub_zalloc (size);
> + else
> + {
> + if (grub_add (size, grub_strlen (buffer), &size))
> + return NULL;
Indentation seems off!
Adding one new line would be good here!
> + buffer = grub_realloc (buffer, size);
> + }
> +
> + if (buffer == NULL)
> + return NULL;
> +
> + tmp = buffer + grub_strlen (buffer);
> + tmp = grub_stpcpy (tmp, field);
> +
> + if (is_env_var == true)
> + tmp = grub_stpcpy (tmp, " ");
> +
> + return buffer;
> +}
> +
> +/*
> + * This function takes a value string, checks for environmental
> variables, and
> + * returns the value string with all environmental variables replaced
> with the
> + * value stored in the variable.
> + */
> +static char *
> +blsuki_expand_val (const char *value)
> +{
> + char *buffer = NULL;
> + const char *start = value;
> + const char *end = value;
> + bool is_env_var = false;
> +
> + if (value == NULL)
> + return NULL;
> +
> + while (*value != '\0')
> + {
> + if (*value == '$')
> + {
> + if (start != end)
> + {
> + buffer = blsuki_field_append (is_env_var, buffer, start, end);
> + if (buffer == NULL)
> + return NULL;
> + }
> +
> + is_env_var = true;
> + start = value + 1;
> + }
> + else if (is_env_var == true)
> + {
> + if (grub_isalnum (*value) == 0 && *value != '_')
> + {
> + buffer = blsuki_field_append (is_env_var, buffer, start, end);
> + is_env_var = false;
> + start = value;
> + if (*start == ' ')
> + start++;
> + }
> + }
Indentation seems off in "if (*value == '$')" and else if conditions.
Missing else condition in if else ladder. Adding it would be good!
> +
> + end = value;
> + value++;
> + }
> +
> + if (start != end)
> + {
> + buffer = blsuki_field_append (is_env_var, buffer, start, end);
> + if (buffer == NULL)
> + return NULL;
Indentation seems off!
> + }
> +
> + return buffer;
> +}
> +
> +/*
> + * This function parses a string containing initrd paths and returns
> it as a
> + * list.
> + */
> +static char **
> +blsuki_early_initrd_list (const char *initrd)
> +{
> + int nlist = 0;
> + char **list = NULL;
> + const char *separator = initrd;
> + char *tmp;
> +
> + for (;;)
> + {
> + while (*separator != '\0' && *separator != ' ' && *separator !=
> '\t')
> + separator++;
Indentation seems off!
> + if (*separator == '\0')
> + break;
Indentation seems off!
> +
> + list = grub_realloc (list, (nlist + 2) * sizeof (char *));
Good to use grub_malloc here!
> + if (list == NULL)
> + return NULL;
Indentation seems off!
> +
> + tmp = grub_strndup (initrd, separator - initrd);
> + if (tmp == NULL)
> + {
> + grub_free (list);
> + return NULL;
> + }
Indentation seems off in if condition!
> + list[nlist++] = tmp;
> + list[nlist] = NULL;
> + separator++;
> + initrd = separator;
> + }
> +
> + list = grub_realloc (list, (nlist + 2) * sizeof (char *));
> + if (list == NULL)
> + return NULL;
> +
> + tmp = grub_strndup (initrd, grub_strlen (initrd));
> + if (tmp == NULL)
> + {
> + grub_free (list);
> + return NULL;
> + }
> + list[nlist++] = tmp;
> + list[nlist] = NULL;
> +
> + return list;
> +}
> +
> +/*
> + * This function returns a string with the command to load a linux
> kernel with
> + * kernel command-line options based on what was specified in the BLS
> config
> + * file.
> + */
> +static char *
> +bls_get_linux (grub_blsuki_entry_t *entry)
> +{
> + char *linux_path;
> + char *linux_cmd = NULL;
> + char *options = NULL;
> + char *tmp;
> + grub_size_t size;
> +
> + linux_path = blsuki_get_val (entry, "linux", NULL);
> + options = blsuki_expand_val (blsuki_get_val (entry, "options",
> NULL));
> +
> + if (options == NULL)
> + options = blsuki_expand_val (grub_env_get ("default_kernelopts"));
> +
> + if (grub_add (grub_strlen ("linux "), grub_strlen (linux_path),
> &size))
> + {
> + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while
> calculating linux buffer size");
> + goto finish;
> + }
> +
> + if (options != NULL)
> + {
> + if (grub_add (size, grub_strlen (options), &size) ||
> + grub_add (size, 1, &size))
> + {
> + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while
> calculating linux buffer size");
> + goto finish;
> + }
Indentation seems off!
if (grub_add (size, grub_strlen (options), &size) || grub_add
(size, 1, &size))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while
calculating linux buffer size");
goto finish;
}
> + }
> +
> + linux_cmd = grub_malloc (size);
> + if (linux_cmd == NULL)
> + goto finish;
> +
> + tmp = linux_cmd;
> + tmp = grub_stpcpy (tmp, "linux ");
> + tmp = grub_stpcpy (tmp, linux_path);
> + if (options != NULL)
> + {
> + tmp = grub_stpcpy (tmp, " ");
> + tmp = grub_stpcpy (tmp, options);
> + }
> + tmp = grub_stpcpy (tmp, "\n");
> +
> + finish:
> + grub_free (options);
> +
> + return linux_cmd;
> +}
> +
> +/*
> + * This function returns a string with the command to load all initrds
> for a
> + * linux kernel image based on the list provided by the BLS config
> file.
> + */
> +static char *
> +bls_get_initrd (grub_blsuki_entry_t *entry)
> +{
> + char **initrd_list;
> + char *initrd_cmd = NULL;
> + const char *early_initrd;
> + char **early_initrd_list = NULL;
> + char *tmp;
> + char *slash;
> + char *prefix = NULL;
> + grub_size_t prefix_len = 0;
> + char *linux_path;
> + grub_size_t size;
> + int i;
> +
> + initrd_list = blsuki_make_list (entry, "initrd", NULL);
> + early_initrd = grub_env_get ("early_initrd");
> +
> + if (early_initrd != NULL)
> + {
> + early_initrd_list = blsuki_early_initrd_list (early_initrd);
> + if (early_initrd_list == NULL)
> + {
> + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("failed to create early
> initrd list"));
> + goto finish;
> + }
Indentation seems off in if condition!
> +
> + if (initrd_list != NULL && initrd_list[0] != NULL)
> + {
> + slash = grub_strrchr (initrd_list[0], '/');
> + if (slash == NULL)
> + prefix_len = slash - initrd_list[0] + 1;
> + prefix = grub_strndup (initrd_list[0], prefix_len);
> + }
Indentation seems off in if condition!
> + else
> + {
> + linux_path = blsuki_get_val (entry, "linux", NULL);
> + slash = grub_strrchr (linux_path, '/');
> + if (slash != NULL)
> + prefix_len = slash - linux_path + 1;
> + prefix = grub_strndup (linux_path, prefix_len);
> + }
Indentation seems off in else condition!
> +
> + if (prefix == NULL)
> + {
> + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("failed to allocate initrd
> prefix buffer"));
> + goto finish;
> + }
Indentation seems off in if condition!
> + }
> +
> + if (early_initrd_list != NULL || initrd_list != NULL)
> + {
> +
> + size = grub_strlen ("initrd");
> +
> + for (i = 0; early_initrd_list != NULL && early_initrd_list[i]
> != NULL; i++)
> + {
> + if (grub_add (size, 1, &size) ||
> + grub_add (size, grub_strlen (prefix), &size) ||
> + grub_add (size, grub_strlen (early_initrd_list[i]), &size))
> + {
> + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected
> calculating initrd buffer size");
> + goto finish;
> + }
> + }
> +
> + for (i = 0; initrd_list != NULL && initrd_list[i] != NULL; i++)
> + {
Indentation seems off!
> + if (grub_add (size, 1, &size) ||
> + grub_add (size, grub_strlen (initrd_list[i]), &size))
> + {
> + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected
> calculating initrd buffer size");
> + goto finish;
> + }
> + }
> +
> + if (grub_add (size, 1, &size))
> + {
> + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected calculating
> initrd buffer size");
> + goto finish;
> + }
Indentation seems off in if condition!
> +
> + initrd_cmd = grub_malloc (size);
> + if (initrd_cmd == NULL)
> + goto finish;
Indentation seems off!
> +
> + tmp = grub_stpcpy (initrd_cmd, "initrd");
> + for (i = 0; early_initrd_list != NULL && early_initrd_list[i]
> != NULL; i++)
> + {
Indentation seems off!
> + grub_dprintf ("blsuki", "adding early initrd %s\n",
> early_initrd_list[i]);
> + tmp = grub_stpcpy (tmp, " ");
> + tmp = grub_stpcpy (tmp, prefix);
> + tmp = grub_stpcpy (tmp, early_initrd_list[i]);
> + }
> +
> + for (i = 0; initrd_list != NULL && initrd_list[i] != NULL; i++)
> + {
Indentation seems off!
> + grub_dprintf ("blsuki", "adding initrd %s\n", initrd_list[i]);
> + tmp = grub_stpcpy (tmp, " ");
> + tmp = grub_stpcpy (tmp, initrd_list[i]);
> + }
> + tmp = grub_stpcpy (tmp, "\n");
> + }
> +
> + finish:
> + for (i = 0; early_initrd_list != NULL && early_initrd_list[i] !=
> NULL; i++)
> + grub_free (early_initrd_list[i]);
> + grub_free (prefix);
> +
> + return initrd_cmd;
> +}
> +
> +/*
> + * This function returns a string with the command to load a device
> tree blob
> + * from the BLS config file.
> + */
> +static char *
> +bls_get_devicetree (grub_blsuki_entry_t *entry)
> +{
> + char *dt_path;
> + char *dt_cmd = NULL;
> + char *tmp;
> + char *linux_path;
> + char *slash;
> + char *prefix = NULL;
> + grub_size_t prefix_len = 0;
> + grub_size_t size;
> + bool add_dt_prefix = false;
> +
> + dt_path = blsuki_expand_val (blsuki_get_val (entry, "devicetree",
> NULL));
> +
> + if (dt_path == NULL)
> + {
> + dt_path = blsuki_expand_val (grub_env_get ("devicetree"));
> + add_dt_prefix = true;
> + }
> +
> + if (dt_path != NULL)
> + {
> + if (add_dt_prefix == true)
> + {
Indentation seems off!
> + linux_path = blsuki_get_val (entry, "linux", NULL);
> + slash = grub_strchr (linux_path, '/');
> + if (slash != NULL)
> + prefix_len = slash - linux_path + 1;
Adding a new line here would be good!
> + prefix = grub_strndup (linux_path, prefix_len);
> + if (prefix == NULL)
> + {
> + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("failed to allocate
> prefix buffer"));
> + goto finish;
> + }
> + }
> +
> + if (grub_add (grub_strlen ("devicetree "), grub_strlen
> (dt_path), &size) ||
> + grub_add (size, 1, &size))
Indentation seems off!
> + {
Indentation seems off!
> + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected calculating
> device tree buffer size");
> + goto finish;
> + }
> +
> + if (add_dt_prefix == true)
> + {
Indentation seems off!
> + if (grub_add (size, grub_strlen (prefix), &size))
> + {
> + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected
> calculating device tree buffer size");
> + goto finish;
> + }
> + }
> + dt_cmd = grub_malloc (size);
> + if (dt_cmd == NULL)
> + goto finish;
Indentation seems off! and anding a new line would be good!
> + tmp = dt_cmd;
> + tmp = grub_stpcpy (dt_cmd, "devicetree");
> + tmp = grub_stpcpy (tmp, " ");
> + if (add_dt_prefix == true)
> + tmp = grub_stpcpy (tmp, prefix);
Adding a new line would be good!
> + tmp = grub_stpcpy (tmp, dt_path);
> + tmp = grub_stpcpy (tmp, "\n");
> + }
> +
> + finish:
> + grub_free (prefix);
> +
> + return dt_cmd;
> +}
> +
> +/*
> + * This function puts together all of the commands generated from the
> contents
> + * of the BLS config file and creates a new entry in the GRUB boot
> menu.
> + */
> +static void
> +bls_create_entry (grub_blsuki_entry_t *entry)
> +{
> + int argc = 0;
> + const char **argv = NULL;
> + char *title = NULL;
> + char *linux_path = NULL;
> + char *linux_cmd = NULL;
> + char *initrd_cmd = NULL;
> + char *dt_cmd = NULL;
> + char *id = entry->filename;
> + grub_size_t id_len;
> + char *hotkey = NULL;
> + char *users = NULL;
> + char **classes = NULL;
> + char **args = NULL;
> + char *src = NULL;
> + const char *sdval = NULL;
> + int i;
> + grub_size_t size;
> + bool savedefault;
> +
> + linux_path = blsuki_get_val (entry, "linux", NULL);
> + if (linux_path == NULL)
> + {
> + grub_dprintf ("blsuki", "Skipping file %s with no 'linux'
> key.\n", entry->filename);
> + goto finish;
> + }
> +
> + id_len = grub_strlen (id);
> + if (id_len >= 5 && grub_strcmp (id + id_len - 5, ".conf") == 0)
> + id[id_len - 5] = '\0';
> +
> + title = blsuki_get_val (entry, "title", NULL);
> + hotkey = blsuki_get_val (entry, "grub_hotkey", NULL);
> + users = blsuki_expand_val (blsuki_get_val (entry, "grub_users",
> NULL));
> + classes = blsuki_make_list (entry, "grub_class", NULL);
> + args = blsuki_make_list (entry, "grub_arg", &argc);
> +
> + argc++;
> + if (grub_mul (argc + 1, sizeof (char *), &size))
> + {
> + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected
> creating argv list"));
> + goto finish;
> + }
> +
> + argv = grub_malloc (size);
> + if (argv == NULL)
> + goto finish;
Adding a new line would be good!
> + argv[0] = title ? title : linux_path;
> + for (i = 1; i < argc; i++)
> + argv[i] = args[i-1];
Adding a new line would be good!
> + argv[argc] = NULL;
> +
> + linux_cmd = bls_get_linux (entry);
> + if (linux_cmd == NULL)
> + goto finish;
> +
> + initrd_cmd = bls_get_initrd (entry);
> + if (grub_errno != GRUB_ERR_NONE)
> + goto finish;
> +
> + dt_cmd = bls_get_devicetree (entry);
> + if (grub_errno != GRUB_ERR_NONE)
> + goto finish;
> +
> + sdval = grub_env_get ("save_default");
> + savedefault = ((NULL != sdval) && (grub_strcmp (sdval, "true") ==
> 0));
> + src = grub_xasprintf ("%s%s%s%s",
> + savedefault ? "savedefault\n" : "",
> + linux_cmd, initrd_cmd ? initrd_cmd : "",
> + dt_cmd ? dt_cmd : "");
Indentation seems off!
> +
> + grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey,
> NULL, src, 0, entry);
> +
> + finish:
> + grub_free (linux_cmd);
> + grub_free (dt_cmd);
> + grub_free (initrd_cmd);
> + grub_free (classes);
> + grub_free (args);
> + grub_free (argv);
> + grub_free (src);
> +}
> +
> +struct find_entry_info
> +{
> + const char *dirname;
> + const char *devid;
> + grub_device_t dev;
> + grub_fs_t fs;
> +};
> +
> +/*
> + * This function fills a find_entry_info struct passed in by the info
> parameter.
> + * If the dirname or devid parameters are set to NULL, the dirname and
> devid
> + * fields in the info parameter will be set to default values. If info
> already
> + * has a value in the dev fields, we can compare it to the value
> passed in by
> + * the devid parameter or the default devid to see if we need to open
> a new
> + * device.
> + */
> +static grub_err_t
> +blsuki_set_find_entry_info (struct find_entry_info *info, const char
> *dirname, const char *devid)
> +{
> + grub_device_t dev;
> + grub_fs_t fs;
> +
> + if (info == NULL)
> + return grub_error (GRUB_ERR_BAD_ARGUMENT, "info parameter is not
> set");
> +
> + if (devid == NULL)
> + {
> + devid = grub_env_get ("root");
> + if (devid == NULL)
> + return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't
Indentation seems off!
> set"), "root");
> + }
> +
> + /* Check that we aren't closing and opening the same device. */
> + if (info->dev != NULL && grub_strcmp (info->devid, devid) != 0)
> + {
> + grub_device_close (info->dev);
> + info->dev = NULL;
> + }
> + /* If we are using the same device, then we can skip this step and
> only set the directory. */
> + if (info->dev == NULL)
> + {
> + grub_dprintf ("blsuki", "opening %s\n", devid);
> + dev = grub_device_open (devid);
> + if (dev == NULL)
> + return grub_errno;
Indentation seems off!
> +
> + grub_dprintf ("blsuki", "probing fs\n");
> + fs = grub_fs_probe (dev);
> + if (fs == NULL)
> + {
> + grub_device_close (dev);
> + return grub_errno;
> + }
Indentation seems off in if condition!
> +
> + info->devid = devid;
> + info->dev = dev;
> + info->fs = fs;
> + }
> +
> + info->dirname = dirname;
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +/*
> + * This function searches for BLS config files based on the data in
> the info
> + * parameter. If the fallback option is enabled, the default location
> will be
> + * checked for BLS config files if the first attempt fails.
> + */
> +static void
> +blsuki_find_entry (struct find_entry_info *info, bool enable_fallback)
> +{
> + struct read_entry_info read_entry_info;
> + grub_fs_t dir_fs = NULL;
> + grub_device_t dir_dev = NULL;
> + bool fallback = false;
> + int r;
> +
> + do
> + {
> + read_entry_info.file = NULL;
> + read_entry_info.dirname = info->dirname;
> +
> + grub_dprintf ("blsuki", "scanning dir: %s\n", info->dirname);
> + dir_dev = info->dev;
> + dir_fs = info->fs;
> + read_entry_info.devid = info->devid;
> +
> + r = dir_fs->fs_dir (dir_dev, read_entry_info.dirname,
> blsuki_read_entry,
> + &read_entry_info);
Indentation seems off!
> + if (r != 0)
> + {
> + grub_dprintf ("blsuki", "blsuki_read_entry returned error\n");
> + grub_errno = GRUB_ERR_NONE;
> + }
Indentation seems off in if condition!
> +
> + /*
> + * If we aren't able to find BLS entries in the directory given
> by info->dirname,
> + * we can fallback to the default location
> "/boot/loader/entries/" and see if we
> + * can find the files there.
> + */
> + if (entries == NULL && fallback == false && enable_fallback ==
> true)
> + {
> + blsuki_set_find_entry_info (info, GRUB_BLS_CONFIG_PATH, NULL);
> + grub_dprintf ("blsuki", "Entries weren't found in %s, fallback to
> %s\n",
> + read_entry_info.dirname, info->dirname);
> + fallback = true;
> + }
Indentation seems off in if condition!
> + else
> + fallback = false;
Indentation seems off!
> + }
> + while (fallback == true);
> +}
> +
> +static grub_err_t
> +blsuki_load_entries (char *path, bool enable_fallback)
> +{
> + grub_size_t len;
> + static grub_err_t r;
> + const char *devid = NULL;
> + char *dir = NULL;
> + struct find_entry_info info = {
> + .dev = NULL,
> + .fs = NULL,
> + .dirname = NULL,
> + };
> + struct read_entry_info rei = {
> + .devid = NULL,
> + .dirname = NULL,
> + };
> +
> + if (path != NULL)
> + {
> + len = grub_strlen (path);
> + if (len >= 5 && grub_strcmp (path + len - 5, ".conf") == 0)
> + {
> + rei.file = grub_file_open (path, GRUB_FILE_TYPE_CONFIG);
> + if (rei.file == NULL)
> + return grub_errno;
> +
> + /* blsuki_read_entry() closes the file. */
> + return blsuki_read_entry (path, NULL, &rei);
> + }
> + else if (path[0] == '(')
> + {
> + devid = path + 1;
> +
> + dir = grub_strchr (path, ')');
> + if (dir == NULL)
> + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid file name
> `%s'"), path);
> +
> + *dir = '\0';
> +
> + /* Check if there is more than the devid in the path. */
> + if (dir + 1 < path + len)
> + dir = dir + 1;
> + }
> + else if (path[0] == '/')
> + dir = path;
> + }
Indentation seems off in if else ladder! adding else condition would be
good!
> +
> + if (dir == NULL)
> + dir = (char *) GRUB_BLS_CONFIG_PATH;
> +
> + r = blsuki_set_find_entry_info (&info, dir, devid);
> + if (r == GRUB_ERR_NONE)
> + blsuki_find_entry (&info, enable_fallback);
> +
> + if (info.dev != NULL)
> + grub_device_close (info.dev);
> +
> + return r;
> +}
> +
> +static bool
> +blsuki_is_default_entry (const char *def_entry, grub_blsuki_entry_t
> *entry, int idx)
> +{
> + const char *title;
> + const char *def_entry_end;
> + int def_idx;
> +
> + if (def_entry == NULL)
> + return false;
> +
> + if (grub_strcmp (def_entry, entry->filename) == 0)
> + return true;
> +
> + title = blsuki_get_val (entry, "title", NULL);
> +
> + if (title != NULL && grub_strcmp (def_entry, title) == 0)
> + return true;
> +
> + def_idx = (int) grub_strtol (def_entry, &def_entry_end, 0);
> + if (grub_errno != GRUB_ERR_NONE)
> + {
> + grub_errno = GRUB_ERR_NONE;
> + return false;
> + }
> + if (*def_entry == '\0' || *def_entry_end != '\0')
> + return false;
> +
> + if (def_idx == idx)
> + return true;
> +
> + return false;
> +}
> +
> +/*
> + * This function creates a GRUB boot menu entry for each BLS entry in
> the
> + * entries list.
> + */
> +static grub_err_t
> +blsuki_create_entries (bool show_default, bool show_non_default, char
> *entry_id)
> +{
> + const char *def_entry = NULL;
> + grub_blsuki_entry_t *entry = NULL;
> + int idx = 0;
> +
> + def_entry = grub_env_get ("default");
> +
> + FOR_BLSUKI_ENTRIES(entry)
> + {
> + if (entry->visible == 1)
> + {
> + idx++;
> + continue;
> + }
> + if ((show_default == true && blsuki_is_default_entry
> (def_entry, entry, idx) == true) ||
> + (show_non_default == true && blsuki_is_default_entry (def_entry,
> entry, idx) == false) ||
> + (entry_id != NULL && grub_strcmp (entry_id, entry->filename) == 0))
> + {
> + bls_create_entry (entry);
> + entry->visible = 1;
> + }
> + idx++;
> + }
Indentation seems off in both if conditions!
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_cmd_blscfg (grub_extcmd_context_t ctxt, int argc __attribute__
> ((unused)),
> + char **args __attribute__ ((unused)))
> +{
> + grub_err_t err;
> + struct grub_arg_list *state = ctxt->state;
> + char *path = NULL;
> + char *entry_id = NULL;
> + bool enable_fallback = false;
> + bool show_default = false;
> + bool show_non_default = false;
> + bool all = true;
> +
> + if (state[0].set)
> + path = state[0].arg;
> + if (state[1].set)
> + enable_fallback = true;
> + if (state[2].set)
> + {
> + show_default = true;
> + all = false;
> + }
> + if (state[3].set)
> + {
> + show_non_default = true;
> + all = false;
> + }
> + if (state[4].set)
> + {
> + entry_id = state[4].arg;
> + all = false;
> + }
> + if (all == true)
> + {
> + show_default = true;
> + show_non_default = true;
> + }
> +
> + err = blsuki_load_entries (path, enable_fallback);
> + if (err != GRUB_ERR_NONE)
> + return err;
> +
> + return blsuki_create_entries (show_default, show_non_default,
> entry_id);
> +}
> +
> +static grub_extcmd_t bls_cmd;
> +
> +GRUB_MOD_INIT(blsuki)
> +{
> + bls_cmd = grub_register_extcmd ("blscfg", grub_cmd_blscfg, 0,
> + N_("[-p|--path] [-f|--enable-fallback] DIR [-d|--show-default]
> [-n|--show-non-default] [-e|--entry] FILE"),
> + N_("Import Boot Loader Specification snippets."),
> + bls_opt);
> +}
> +
> +GRUB_MOD_FINI(blsuki)
> +{
> + grub_unregister_extcmd (bls_cmd);
> +}
> diff --git a/grub-core/commands/legacycfg.c
> b/grub-core/commands/legacycfg.c
> index 3bf9fe2e4..f3c86dc7f 100644
> --- a/grub-core/commands/legacycfg.c
> +++ b/grub-core/commands/legacycfg.c
> @@ -143,7 +143,7 @@ legacy_file (const char *filename)
> args[0] = oldname;
> grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy",
> NULL, NULL,
> - entrysrc, 0);
> + entrysrc, 0, NULL);
> grub_free (args);
> entrysrc[0] = 0;
> grub_free (oldname);
> @@ -204,7 +204,7 @@ legacy_file (const char *filename)
> }
> args[0] = entryname;
> grub_normal_add_menu_entry (1, args, NULL, NULL, NULL,
> - NULL, NULL, entrysrc, 0);
> + NULL, NULL, entrysrc, 0, NULL);
> grub_free (args);
> }
>
> diff --git a/grub-core/commands/menuentry.c
> b/grub-core/commands/menuentry.c
> index 720e6d8ea..09749c415 100644
> --- a/grub-core/commands/menuentry.c
> +++ b/grub-core/commands/menuentry.c
> @@ -78,7 +78,7 @@ grub_normal_add_menu_entry (int argc, const char
> **args,
> char **classes, const char *id,
> const char *users, const char *hotkey,
> const char *prefix, const char *sourcecode,
> - int submenu)
> + int submenu, grub_blsuki_entry_t *blsuki)
> {
> int menu_hotkey = 0;
> char **menu_args = NULL;
> @@ -188,6 +188,7 @@ grub_normal_add_menu_entry (int argc, const char
> **args,
> (*last)->args = menu_args;
> (*last)->sourcecode = menu_sourcecode;
> (*last)->submenu = submenu;
> + (*last)->blsuki = blsuki;
>
> menu->size++;
> return GRUB_ERR_NONE;
> @@ -286,7 +287,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt,
> int argc, char **args)
> users,
> ctxt->state[2].arg, 0,
> ctxt->state[3].arg,
> - ctxt->extcmd->cmd->name[0] == 's');
> + ctxt->extcmd->cmd->name[0] == 's',
> + NULL);
>
> src = args[argc - 1];
> args[argc - 1] = NULL;
> @@ -303,7 +305,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt,
> int argc, char **args)
> ctxt->state[0].args, ctxt->state[4].arg,
> users,
> ctxt->state[2].arg, prefix, src + 1,
> - ctxt->extcmd->cmd->name[0] == 's');
> + ctxt->extcmd->cmd->name[0] == 's', NULL);
>
> src[len - 1] = ch;
> args[argc - 1] = src;
> diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
> index 04d058f55..2d493f21e 100644
> --- a/grub-core/normal/main.c
> +++ b/grub-core/normal/main.c
> @@ -21,6 +21,7 @@
> #include <grub/net.h>
> #include <grub/normal.h>
> #include <grub/dl.h>
> +#include <grub/menu.h>
> #include <grub/misc.h>
> #include <grub/file.h>
> #include <grub/mm.h>
> @@ -67,6 +68,11 @@ grub_normal_free_menu (grub_menu_t menu)
> grub_free (entry->args);
> }
>
> + if (entry->blsuki)
> + {
> + entry->blsuki->visible = 0;
> + }
Brackets not required!
Alec , I see many Indentation issues. I have tried pointing out as much
as I can. Please fix!
Thank you!
Regards,
Avnish Chouhan
> +
> End of Grub-devel Digest, Vol 255, Issue 51
> *******************************************
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [External] : Re: [PATCH v4 2/4] blsuki: Add blscfg command to parse Boot Loader Specification snippets
2025-05-29 10:59 ` [PATCH v4 2/4] blsuki: Add blscfg command to parse Boot Loader Specification snippets Avnish Chouhan
@ 2025-06-03 19:47 ` Alec Brown via Grub-devel
2025-06-05 6:02 ` Avnish Chouhan
0 siblings, 1 reply; 5+ messages in thread
From: Alec Brown via Grub-devel @ 2025-06-03 19:47 UTC (permalink / raw)
To: Avnish Chouhan; +Cc: Alec Brown, grub-devel@gnu.org, Daniel Kiper
On Thu, May 29, 2025 at 6:59 AM, Avnish Chouhan <avnish@linux.ibm.com> wrote:
> On 2025-05-21 18:21, grub-devel-request@gnu.org wrote:
[...]
> > +static grub_err_t
> > +blsuki_add_keyval (grub_blsuki_entry_t *entry, char *key, char *val)
> > +{
> > + char *k, *v;
> > + struct keyval **kvs, *kv;
> > + grub_size_t size;
> > + int new_n = entry->nkeyvals + 1;
> > +
> > + if (entry->keyvals_size == 0)
> > + {
> > + size = sizeof (struct keyval *);
> > + kvs = grub_malloc (size);
> > + if (kvs == NULL)
> > + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate space
> > for BLS key values");
>
> Hi Alec,
>
> Indentation seems off here!
Hi Avnish,
The reason the indentations looks strange here and through out the patches is
because those are spots where more than 8 spaces were used. In those cases, a
tab is used in the GRUB code. Unfortunately, the formatting of the patch makes
it look strange.
[...]
> > +static grub_err_t
> > +bls_parse_keyvals (grub_file_t f, grub_blsuki_entry_t *entry)
> > +{
> > + grub_err_t err = GRUB_ERR_NONE;
> > +
> > + for (;;)
> > + {
> > + char *buf;
> > + char *separator;
> > +
> > + buf = grub_file_getline (f);
> > + if (buf == NULL)
> > + break;
>
> Indentation seems off!
>
> > +
> > + while (buf != NULL && buf[0] != '\0' && (buf[0] == ' ' ||
> > buf[0] == '\t'))
> > + buf++;
>
> Indentation seems off!
>
> > + if (buf[0] == '#')
> > + {
> > + grub_free (buf);
> > + continue;
> > + }
>
> Indentation seems off in if condition!
>
> > +
> > + separator = grub_strchr (buf, ' ');
> > +
> > + if (separator == NULL)
> > + separator = grub_strchr (buf, '\t');
>
> Indentation seems off!
>
> > +
> > + if (separator == NULL || separator[1] == '\0')
> > + {
> > + grub_free (buf);
> > + break;
> > + }
>
> Indentation seems off in if condition!
>
> > +
> > + separator[0] = '\0';
> > +
> > + do
> > + {
> > + separator++;
> > + }
>
> Indentation seems off!
>
> > + while (*separator == ' ' || *separator == '\t');
>
> What's the use of this while condition? It may result in an infinite
> loop...
>
The purpose of this while loop is to remove any additional spaces or tabs
separating the key from the value. I don't believe this would result in an
infinite loop unless the rest of memory was a space or tab. However, an issue
I do see is we aren't checking if there is a value after removing the excess
spaces and tabs in the loop. I'll fix this.
> > +
> > + err = blsuki_add_keyval (entry, buf, separator);
> > + grub_free (buf);
> > + if (err != GRUB_ERR_NONE)
> > + break;
>
> Indentation seems off!
>
> > + }
> > +
> > + return err;
> > +}
[...]
> > +static char *
> > +blsuki_field_append (bool is_env_var, char *buffer, const char
> > *start, const char *end)
> > +{
> > + char *tmp;
> > + const char *field;
> > + int term = (is_env_var == true) ? 2 : 1;
> > + grub_size_t size = 0;
> > +
> > + tmp = grub_strndup (start, end - start + 1);
> > + if (tmp == NULL)
> > + return NULL;
> > +
> > + field = tmp;
> > +
> > + if (is_env_var == true)
> > + {
> > + field = grub_env_get (tmp);
> > + if (field == NULL)
> > + return buffer;
> > + }
> > +
> > + if (grub_add (grub_strlen (field), term, &size))
> > + return NULL;
> > +
> > + if (buffer == NULL)
> > + buffer = grub_zalloc (size);
> > + else
> > + {
> > + if (grub_add (size, grub_strlen (buffer), &size))
> > + return NULL;
>
> Indentation seems off!
> Adding one new line would be good here!
Sure thing!
>
> > + buffer = grub_realloc (buffer, size);
> > + }
> > +
> > + if (buffer == NULL)
> > + return NULL;
> > +
> > + tmp = buffer + grub_strlen (buffer);
> > + tmp = grub_stpcpy (tmp, field);
> > +
> > + if (is_env_var == true)
> > + tmp = grub_stpcpy (tmp, " ");
> > +
> > + return buffer;
> > +}
> > +
> > +/*
> > + * This function takes a value string, checks for environmental
> > variables, and
> > + * returns the value string with all environmental variables replaced
> > with the
> > + * value stored in the variable.
> > + */
> > +static char *
> > +blsuki_expand_val (const char *value)
> > +{
> > + char *buffer = NULL;
> > + const char *start = value;
> > + const char *end = value;
> > + bool is_env_var = false;
> > +
> > + if (value == NULL)
> > + return NULL;
> > +
> > + while (*value != '\0')
> > + {
> > + if (*value == '$')
> > + {
> > + if (start != end)
> > + {
> > + buffer = blsuki_field_append (is_env_var, buffer, start, end);
> > + if (buffer == NULL)
> > + return NULL;
> > + }
> > +
> > + is_env_var = true;
> > + start = value + 1;
> > + }
> > + else if (is_env_var == true)
> > + {
> > + if (grub_isalnum (*value) == 0 && *value != '_')
> > + {
> > + buffer = blsuki_field_append (is_env_var, buffer, start, end);
> > + is_env_var = false;
> > + start = value;
> > + if (*start == ' ')
> > + start++;
> > + }
> > + }
>
> Indentation seems off in "if (*value == '$')" and else if conditions.
> Missing else condition in if else ladder. Adding it would be good!
I don't believe an else condition would be necessary since there isn't any code
that needs to be done exclusive of both these conditionals.
>
> > +
> > + end = value;
> > + value++;
> > + }
> > +
> > + if (start != end)
> > + {
> > + buffer = blsuki_field_append (is_env_var, buffer, start, end);
> > + if (buffer == NULL)
> > + return NULL;
>
> Indentation seems off!
>
> > + }
> > +
> > + return buffer;
> > +}
> > +
> > +/*
> > + * This function parses a string containing initrd paths and returns
> > it as a
> > + * list.
> > + */
> > +static char **
> > +blsuki_early_initrd_list (const char *initrd)
> > +{
> > + int nlist = 0;
> > + char **list = NULL;
> > + const char *separator = initrd;
> > + char *tmp;
> > +
> > + for (;;)
> > + {
> > + while (*separator != '\0' && *separator != ' ' && *separator !=
> > '\t')
> > + separator++;
>
> Indentation seems off!
>
> > + if (*separator == '\0')
> > + break;
>
> Indentation seems off!
>
> > +
> > + list = grub_realloc (list, (nlist + 2) * sizeof (char *));
>
> Good to use grub_malloc here!
If list is NULL, grub_realloc() will call grub_malloc(), but I'll take a look
to see if there is a possibility to only call grub_malloc() once before the
loop so we don't keep calling grub_realloc().
>
> > + if (list == NULL)
> > + return NULL;
>
> Indentation seems off!
>
> > +
> > + tmp = grub_strndup (initrd, separator - initrd);
> > + if (tmp == NULL)
> > + {
> > + grub_free (list);
> > + return NULL;
> > + }
>
> Indentation seems off in if condition!
>
> > + list[nlist++] = tmp;
> > + list[nlist] = NULL;
> > + separator++;
> > + initrd = separator;
> > + }
> > +
> > + list = grub_realloc (list, (nlist + 2) * sizeof (char *));
> > + if (list == NULL)
> > + return NULL;
> > +
> > + tmp = grub_strndup (initrd, grub_strlen (initrd));
> > + if (tmp == NULL)
> > + {
> > + grub_free (list);
> > + return NULL;
> > + }
> > + list[nlist++] = tmp;
> > + list[nlist] = NULL;
> > +
> > + return list;
> > +}
[...]
> > +static char *
> > +bls_get_devicetree (grub_blsuki_entry_t *entry)
> > +{
> > + char *dt_path;
> > + char *dt_cmd = NULL;
> > + char *tmp;
> > + char *linux_path;
> > + char *slash;
> > + char *prefix = NULL;
> > + grub_size_t prefix_len = 0;
> > + grub_size_t size;
> > + bool add_dt_prefix = false;
> > +
> > + dt_path = blsuki_expand_val (blsuki_get_val (entry, "devicetree",
> > NULL));
> > +
> > + if (dt_path == NULL)
> > + {
> > + dt_path = blsuki_expand_val (grub_env_get ("devicetree"));
> > + add_dt_prefix = true;
> > + }
> > +
> > + if (dt_path != NULL)
> > + {
> > + if (add_dt_prefix == true)
> > + {
>
> Indentation seems off!
>
> > + linux_path = blsuki_get_val (entry, "linux", NULL);
> > + slash = grub_strchr (linux_path, '/');
> > + if (slash != NULL)
> > + prefix_len = slash - linux_path + 1;
>
> Adding a new line here would be good!
Sure thing!
>
>
> > + prefix = grub_strndup (linux_path, prefix_len);
> > + if (prefix == NULL)
> > + {
> > + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("failed to allocate
> > prefix buffer"));
> > + goto finish;
> > + }
> > + }
> > +
> > + if (grub_add (grub_strlen ("devicetree "), grub_strlen
> > (dt_path), &size) ||
> > + grub_add (size, 1, &size))
>
> Indentation seems off!
>
> > + {
>
> Indentation seems off!
>
> > + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected calculating
> > device tree buffer size");
> > + goto finish;
> > + }
> > +
> > + if (add_dt_prefix == true)
> > + {
>
> Indentation seems off!
>
> > + if (grub_add (size, grub_strlen (prefix), &size))
> > + {
> > + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected
> > calculating device tree buffer size");
> > + goto finish;
> > + }
> > + }
> > + dt_cmd = grub_malloc (size);
> > + if (dt_cmd == NULL)
> > + goto finish;
>
> Indentation seems off! and anding a new line would be good!
Sure thing!
>
> > + tmp = dt_cmd;
> > + tmp = grub_stpcpy (dt_cmd, "devicetree");
> > + tmp = grub_stpcpy (tmp, " ");
> > + if (add_dt_prefix == true)
> > + tmp = grub_stpcpy (tmp, prefix);
>
> Adding a new line would be good!
>
> > + tmp = grub_stpcpy (tmp, dt_path);
> > + tmp = grub_stpcpy (tmp, "\n");
> > + }
> > +
> > + finish:
> > + grub_free (prefix);
> > +
> > + return dt_cmd;
> > +}
> > +
> > +/*
> > + * This function puts together all of the commands generated from the
> > contents
> > + * of the BLS config file and creates a new entry in the GRUB boot
> > menu.
> > + */
> > +static void
> > +bls_create_entry (grub_blsuki_entry_t *entry)
> > +{
> > + int argc = 0;
> > + const char **argv = NULL;
> > + char *title = NULL;
> > + char *linux_path = NULL;
> > + char *linux_cmd = NULL;
> > + char *initrd_cmd = NULL;
> > + char *dt_cmd = NULL;
> > + char *id = entry->filename;
> > + grub_size_t id_len;
> > + char *hotkey = NULL;
> > + char *users = NULL;
> > + char **classes = NULL;
> > + char **args = NULL;
> > + char *src = NULL;
> > + const char *sdval = NULL;
> > + int i;
> > + grub_size_t size;
> > + bool savedefault;
> > +
> > + linux_path = blsuki_get_val (entry, "linux", NULL);
> > + if (linux_path == NULL)
> > + {
> > + grub_dprintf ("blsuki", "Skipping file %s with no 'linux'
> > key.\n", entry->filename);
> > + goto finish;
> > + }
> > +
> > + id_len = grub_strlen (id);
> > + if (id_len >= 5 && grub_strcmp (id + id_len - 5, ".conf") == 0)
> > + id[id_len - 5] = '\0';
> > +
> > + title = blsuki_get_val (entry, "title", NULL);
> > + hotkey = blsuki_get_val (entry, "grub_hotkey", NULL);
> > + users = blsuki_expand_val (blsuki_get_val (entry, "grub_users",
> > NULL));
> > + classes = blsuki_make_list (entry, "grub_class", NULL);
> > + args = blsuki_make_list (entry, "grub_arg", &argc);
> > +
> > + argc++;
> > + if (grub_mul (argc + 1, sizeof (char *), &size))
> > + {
> > + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected
> > creating argv list"));
> > + goto finish;
> > + }
> > +
> > + argv = grub_malloc (size);
> > + if (argv == NULL)
> > + goto finish;
>
> Adding a new line would be good!
Sure thing!
>
> > + argv[0] = title ? title : linux_path;
> > + for (i = 1; i < argc; i++)
> > + argv[i] = args[i-1];
>
> Adding a new line would be good!
Sure thing!
>
> > + argv[argc] = NULL;
> > +
> > + linux_cmd = bls_get_linux (entry);
> > + if (linux_cmd == NULL)
> > + goto finish;
> > +
> > + initrd_cmd = bls_get_initrd (entry);
> > + if (grub_errno != GRUB_ERR_NONE)
> > + goto finish;
> > +
> > + dt_cmd = bls_get_devicetree (entry);
> > + if (grub_errno != GRUB_ERR_NONE)
> > + goto finish;
> > +
> > + sdval = grub_env_get ("save_default");
> > + savedefault = ((NULL != sdval) && (grub_strcmp (sdval, "true") ==
> > 0));
> > + src = grub_xasprintf ("%s%s%s%s",
> > + savedefault ? "savedefault\n" : "",
> > + linux_cmd, initrd_cmd ? initrd_cmd : "",
> > + dt_cmd ? dt_cmd : "");
>
> Indentation seems off!
>
> > +
> > + grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey,
> > NULL, src, 0, entry);
> > +
> > + finish:
> > + grub_free (linux_cmd);
> > + grub_free (dt_cmd);
> > + grub_free (initrd_cmd);
> > + grub_free (classes);
> > + grub_free (args);
> > + grub_free (argv);
> > + grub_free (src);
> > +}
[...]
> > +static grub_err_t
> > +blsuki_load_entries (char *path, bool enable_fallback)
> > +{
> > + grub_size_t len;
> > + static grub_err_t r;
> > + const char *devid = NULL;
> > + char *dir = NULL;
> > + struct find_entry_info info = {
> > + .dev = NULL,
> > + .fs = NULL,
> > + .dirname = NULL,
> > + };
> > + struct read_entry_info rei = {
> > + .devid = NULL,
> > + .dirname = NULL,
> > + };
> > +
> > + if (path != NULL)
> > + {
> > + len = grub_strlen (path);
> > + if (len >= 5 && grub_strcmp (path + len - 5, ".conf") == 0)
> > + {
> > + rei.file = grub_file_open (path, GRUB_FILE_TYPE_CONFIG);
> > + if (rei.file == NULL)
> > + return grub_errno;
> > +
> > + /* blsuki_read_entry() closes the file. */
> > + return blsuki_read_entry (path, NULL, &rei);
> > + }
> > + else if (path[0] == '(')
> > + {
> > + devid = path + 1;
> > +
> > + dir = grub_strchr (path, ')');
> > + if (dir == NULL)
> > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid file name
> > `%s'"), path);
> > +
> > + *dir = '\0';
> > +
> > + /* Check if there is more than the devid in the path. */
> > + if (dir + 1 < path + len)
> > + dir = dir + 1;
> > + }
> > + else if (path[0] == '/')
> > + dir = path;
> > + }
>
> Indentation seems off in if else ladder! adding else condition would be
> good!
Same as before, I don't think there is any code that would require an else
condition here.
>
> > +
> > + if (dir == NULL)
> > + dir = (char *) GRUB_BLS_CONFIG_PATH;
> > +
> > + r = blsuki_set_find_entry_info (&info, dir, devid);
> > + if (r == GRUB_ERR_NONE)
> > + blsuki_find_entry (&info, enable_fallback);
> > +
> > + if (info.dev != NULL)
> > + grub_device_close (info.dev);
> > +
> > + return r;
> > +}
[...]
> > diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
> > index 04d058f55..2d493f21e 100644
> > --- a/grub-core/normal/main.c
> > +++ b/grub-core/normal/main.c
> > @@ -21,6 +21,7 @@
> > #include <grub/net.h>
> > #include <grub/normal.h>
> > #include <grub/dl.h>
> > +#include <grub/menu.h>
> > #include <grub/misc.h>
> > #include <grub/file.h>
> > #include <grub/mm.h>
> > @@ -67,6 +68,11 @@ grub_normal_free_menu (grub_menu_t menu)
> > grub_free (entry->args);
> > }
> >
> > + if (entry->blsuki)
> > + {
> > + entry->blsuki->visible = 0;
> > + }
>
> Brackets not required!
Sure thing! I'll fix this!
>
> Alec , I see many Indentation issues. I have tried pointing out as much
> as I can. Please fix!
> Thank you!
>
> Regards,
> Avnish Chouhan
>
Thanks for taking a look at these patches!
Alec Brown
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: : Re: [PATCH v4 2/4] blsuki: Add blscfg command to parse Boot Loader Specification snippets
2025-06-03 19:47 ` [External] : " Alec Brown via Grub-devel
@ 2025-06-05 6:02 ` Avnish Chouhan
2025-06-05 13:57 ` Alec Brown via Grub-devel
0 siblings, 1 reply; 5+ messages in thread
From: Avnish Chouhan @ 2025-06-05 6:02 UTC (permalink / raw)
To: Alec Brown; +Cc: grub-devel, Daniel Kiper
On 2025-06-04 01:17, Alec Brown wrote:
> On Thu, May 29, 2025 at 6:59 AM, Avnish Chouhan <avnish@linux.ibm.com>
> wrote:
>> On 2025-05-21 18:21, grub-devel-request@gnu.org wrote:
[...]
>> > + while (*separator == ' ' || *separator == '\t');
>>
>> What's the use of this while condition? It may result in an infinite
>> loop...
>>
>
> The purpose of this while loop is to remove any additional spaces or
> tabs
> separating the key from the value. I don't believe this would result in
> an
> infinite loop unless the rest of memory was a space or tab. However, an
> issue
> I do see is we aren't checking if there is a value after removing the
> excess
> spaces and tabs in the loop. I'll fix this.
Hi Alec,
In my opinion, if we have any of the given condition evaluates as
'True', it will be an infinite loop. We are't incriminating the pointer
and we will be in a loop forever if "*separator == ' ' or *separator ==
'\t'" evaluates 'True'.
If I understood the purpose of this loop correctly, I would do something
like this below:
while (*separator == ' ' || *separator == '\t')
{
...
separator++;
}
Thank you!
Regards,
Avnish Chouhan
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: : Re: [PATCH v4 2/4] blsuki: Add blscfg command to parse Boot Loader Specification snippets
2025-06-05 6:02 ` Avnish Chouhan
@ 2025-06-05 13:57 ` Alec Brown via Grub-devel
2025-06-06 8:45 ` Avnish Chouhan
0 siblings, 1 reply; 5+ messages in thread
From: Alec Brown via Grub-devel @ 2025-06-05 13:57 UTC (permalink / raw)
To: Avnish Chouhan; +Cc: Alec Brown, grub-devel@gnu.org, Daniel Kiper
On Thu, June 5, 2025 at 2:02 AM, Avnish Chouhan <avnish@linux.ibm.com> wrote:
> On 2025-06-04 01:17, Alec Brown wrote:
> > On Thu, May 29, 2025 at 6:59 AM, Avnish Chouhan <avnish@linux.ibm.com>
> > wrote:
> >> On 2025-05-21 18:21, grub-devel-request@gnu.org wrote:
> [...]
> >> > + while (*separator == ' ' || *separator == '\t');
> >>
> >> What's the use of this while condition? It may result in an infinite
> >> loop...
> >>
> >
> > The purpose of this while loop is to remove any additional spaces or
> > tabs
> > separating the key from the value. I don't believe this would result in
> > an
> > infinite loop unless the rest of memory was a space or tab. However, an
> > issue
> > I do see is we aren't checking if there is a value after removing the
> > excess
> > spaces and tabs in the loop. I'll fix this.
>
> Hi Alec,
>
> In my opinion, if we have any of the given condition evaluates as
> 'True', it will be an infinite loop. We are't incriminating the pointer
> and we will be in a loop forever if "*separator == ' ' or *separator ==
> '\t'" evaluates 'True'.
>
Hi Avnish,
For the loop, we are incrementing the 'separator' pointer but since we are
using a do-while loop, it's happening before we check the escape condition of
the loop.
> If I understood the purpose of this loop correctly, I would do something
> like this below:
>
> while (*separator == ' ' || *separator == '\t')
> {
> ...
> separator++;
> }
>
We could write it this way but we would still need to increment the 'separator'
pointer before entering the loop since we just wrote an end of string character
where the previous space or tab was.
Alec Brown
>
> Thank you!
>
> Regards,
> Avnish Chouhan
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: : Re: [PATCH v4 2/4] blsuki: Add blscfg command to parse Boot Loader Specification snippets
2025-06-05 13:57 ` Alec Brown via Grub-devel
@ 2025-06-06 8:45 ` Avnish Chouhan
0 siblings, 0 replies; 5+ messages in thread
From: Avnish Chouhan @ 2025-06-06 8:45 UTC (permalink / raw)
To: Alec Brown; +Cc: grub-devel, Daniel Kiper
Hi Alec,
I believe you're are right. Making "do while" a "while" will not make
any difference for the infinite scenario.
Adding a check which you mentioned "checking a value after removing the
excess" will resolve the concerns I raised.
Thank you!
Regards,
Avnish Chouhan
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
> Hi Avnish,
>
> For the loop, we are incrementing the 'separator' pointer but since we
> are
> using a do-while loop, it's happening before we check the escape
> condition of
> the loop.
>
>> If I understood the purpose of this loop correctly, I would do
>> something
>> like this below:
>>
>> while (*separator == ' ' || *separator == '\t')
>> {
>> ...
>> separator++;
>> }
>>
>
> We could write it this way but we would still need to increment the
> 'separator'
> pointer before entering the loop since we just wrote an end of string
> character
> where the previous space or tab was.
>
> Alec Brown
>
>>
>> Thank you!
>>
>> Regards,
>> Avnish Chouhan
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-06-06 8:46 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <mailman.2919.1747831917.8051.grub-devel@gnu.org>
2025-05-29 10:59 ` [PATCH v4 2/4] blsuki: Add blscfg command to parse Boot Loader Specification snippets Avnish Chouhan
2025-06-03 19:47 ` [External] : " Alec Brown via Grub-devel
2025-06-05 6:02 ` Avnish Chouhan
2025-06-05 13:57 ` Alec Brown via Grub-devel
2025-06-06 8:45 ` Avnish Chouhan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.