diff --git a/docs/grub.texi b/docs/grub.texi index a72d73ce3..851b7b093 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -3388,9 +3388,16 @@ processed by commands @command{configfile} (@pxref{configfile}) or @command{norm @subsection debug This variable may be set to enable debugging output from various components -of GRUB. The value is a list of debug facility names separated by -whitespace or @samp{,}, or @samp{all} to enable all available debugging -output. The facility names are the first argument to grub_dprintf. Consult +of GRUB. The value is an ordered list of debug facility names separated by +whitespace or @samp{,}. If the special facility named @samp{all} is present +then debugging output of all facility names is enabled at the start of +processing the value of this variable. A facility's debug output can then be +disabled by prefixing its name with a @samp{-}. The last occurence facility +name with or without a leading @samp{-} takes precendent over any previous +occurence. This allows the easy enabling or disabling of facilities by +appending a @samp{,} and then the facility name with or without the leading +@samp{-}, which will preserve the state of the rest of the facilities. +The facility names are the first argument to grub_dprintf. Consult the source for more details. diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 11b8592c8..de40f566d 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -162,16 +162,49 @@ __attribute__ ((alias("grub_printf"))); int grub_debug_enabled (const char * condition) { - const char *debug; + const char *debug, *found; + grub_size_t clen; + int ret = 0; debug = grub_env_get ("debug"); if (!debug) return 0; - if (grub_strword (debug, "all") || grub_strword (debug, condition)) - return 1; + if (grub_strword (debug, "all")) + { + if (debug[3] == '\0') + return 1; + ret = 1; + } - return 0; + clen = grub_strlen (condition); + found = debug-1; + while(1) + { + found = grub_strstr (found+1, condition); + + if (found == NULL) + break; + + /* Found condition is not a whole word, so ignore it. */ + if (*(found + clen) != '\0' && *(found + clen) != ',' + && !grub_isspace (*(found + clen))) + continue; + + /* + * If found condition is at the start of debug or the start is on a word + * boundary, then enable debug. Else if found condition is prefixed with + * '-' and the start is on a word boundary, then disable debug. If none + * of these cases, ignore. + */ + if (found == debug || *(found - 1) == ',' || grub_isspace (*(found - 1))) + ret = 1; + else if (*(found - 1) == '-' && ((found == debug + 1) || (*(found - 2) == ',' + || grub_isspace (*(found - 2))))) + ret = 0; + } + + return ret; } void