I've worked a bit on support for symbolic color names. Notes: * One can't mix numeric and symbolic formats. The last patch accepted: color=0x17 green/red but this one won't. * You can't specify blinking foreground characters symbolically. Personally, I think blink is useless, but if someone know a good syntax for blinking, I can implement it. * Symbolic color-names now work both on the commandline and in the menu-file. Comments are appreciated. ///// o o -... said Peter.
diff -urN --exclude-from=diffexclude cvsgrub/stage2/char_io.c grub/stage2/char_io.c --- cvsgrub/stage2/char_io.c Tue Jul 13 22:39:46 1999 +++ grub/stage2/char_io.c Sat Jul 17 15:21:08 1999 @@ -23,6 +23,12 @@ #include "shared.h" + +/* Color settings */ +int normal_color; +int highlight_color; + + void print_error (void) { @@ -484,6 +490,8 @@ } + + int grub_tolower (int c) { @@ -524,7 +532,6 @@ return 1; } - int grub_strcmp (const char *s1, const char *s2) { @@ -582,6 +589,21 @@ return 0; } +/* Find the first occurrence of C in S. */ +char * +grub_strchr (const char *str, int c) +{ + unsigned char *ptr; + + for (ptr = (unsigned char *) str; + *ptr != '\0'; + ++ptr) + if (*ptr == c) + return ptr; + + return 0; +} + int grub_strlen (const char *str) { @@ -593,6 +615,109 @@ return len; } #endif /* ! STAGE1_5 */ + + +#ifndef STAGE1_5 +int +parse_color_command (char *str_ptr) +{ + char *arg1, *arg2; + int new_normal, new_highlight; + + /* Separate the arguments */ + arg1 = str_ptr; + arg2 = strchr(str_ptr, ' '); + if (arg2) { + /* Found space. Terminate. */ + *arg2 = '\0'; + arg2++; + while(strchr(arg2, ' ')) arg2++; + } + if(*arg2 == '\0') arg2 = NULL; + + /* Try parse arg1 numeric */ + if(safe_parse_maxint(&arg1, &new_normal)) { + /* Success */ + if (arg2) { + safe_parse_maxint(&arg2, &new_highlight); + } else { + /* There was no second argument. Calc default. */ + new_highlight = (new_normal >> 4) | ((new_normal & 0xf) << 4); + } + } else { + /* Numeric parse of arg1 failed. Reset errnum. Try symbolics. */ + errnum = 0; + new_normal = parse_symbolic_color(arg1); + if (!errnum) { + if (arg2) + new_highlight = parse_symbolic_color(arg2); + else + new_highlight = (new_normal >> 4) | ((new_normal & 0xf) << 4); + } + } + + if (!errnum) { + normal_color = new_normal; + highlight_color = new_highlight; + } + + return 0; +} + +/* Translate symbolic colors */ +int +parse_symbolic_color(const char *str) +{ + /* Symbolic color names */ + static char *colors[16] = + { + "black", + "blue", + "green", + "cyan", + "red", + "magenta", + "brown", + "lightgray", + + /* Only available for foreground */ + "darkgray", + "lightblue", + "lightgreen", + "lightcyan", + "lightred", + "lightmagenta", + "yellow", + "white" + }; + + int i, result=0; + char *fg, *bg; + + /* Separate fg and bg */ + fg = (unsigned char *) str; + bg = strchr(str, '/'); + if (!bg) + errnum = ERR_INVALID_COLORS; + else { + /* Slash found. */ + *bg = '\0'; + bg++; + + for (i = 0; i < 16; i++) + if (strcmp(colors[i], fg) == 0) break; + result = i; + if (i > 15) errnum = ERR_INVALID_COLORS; + + for (i = 0; i < 16; i++) + if (strcmp(colors[i], bg) == 0) break; + result += i << 4; + if (i > 7) errnum = ERR_BACKGROUND_COLOR; + + } + return result; +} +#endif int diff -urN --exclude-from=diffexclude cvsgrub/stage2/cmdline.c grub/stage2/cmdline.c --- cvsgrub/stage2/cmdline.c Thu Jul 15 13:22:18 1999 +++ grub/stage2/cmdline.c Fri Jul 16 21:22:11 1999 @@ -36,9 +36,8 @@ /* True when the debug mode is turned on, and false when it is turned off. */ int debug = 0; -/* Color settings */ -int normal_color; -int highlight_color; + + char * skip_to (int after_equal, char *cmdline) @@ -637,22 +636,10 @@ } else if (substring ("color", cur_heap) < 1) { - char *normal; - char *highlight; - - normal = cur_cmdline; - highlight = skip_to (0, normal); - - if (safe_parse_maxint (&normal, &normal_color)) - { - /* The second argument is optional, so set highlight_color - to inverted NORMAL_COLOR. */ - if (*highlight == 0 - || ! safe_parse_maxint (&highlight, &highlight_color)) - highlight_color = ((normal_color >> 4) - | ((normal_color & 0xf) << 4)); - } + parse_color_command (cur_cmdline); + if (errnum) goto restart; } + else if (substring ("quit", cur_heap) < 1) { #ifdef GRUB_UTIL diff -urN --exclude-from=diffexclude cvsgrub/stage2/common.c grub/stage2/common.c --- cvsgrub/stage2/common.c Thu Jun 24 02:03:12 1999 +++ grub/stage2/common.c Sat Jul 17 12:55:38 1999 @@ -72,6 +72,8 @@ [ERR_UNRECOGNIZED] = "Unrecognized command", [ERR_WONT_FIT] = "Selected item cannot fit into memory", [ERR_WRITE] = "Disk write error", + [ERR_INVALID_COLORS] = "Invalid colors", + [ERR_BACKGROUND_COLOR] = "Impossible background color", }; diff -urN --exclude-from=diffexclude cvsgrub/stage2/shared.h grub/stage2/shared.h --- cvsgrub/stage2/shared.h Tue Jul 13 17:46:28 1999 +++ grub/stage2/shared.h Sat Jul 17 13:57:49 1999 @@ -234,6 +234,7 @@ #define strstr grub_strstr #define strcmp grub_strcmp #define tolower grub_tolower +#define strchr grub_strchr #define strlen grub_strlen #endif /* WITHOUT_LIBC_STUBS */ @@ -293,6 +294,8 @@ ERR_UNRECOGNIZED, ERR_WONT_FIT, ERR_WRITE, + ERR_INVALID_COLORS, + ERR_BACKGROUND_COLOR, MAX_ERR_NUM } grub_error_t; @@ -511,6 +514,7 @@ void *grub_memset (void *start, int c, int len); char *grub_strstr (const char *s1, const char *s2); int grub_strcmp (const char *s1, const char *s2); +char *grub_strchr (const char *str, int c); int grub_strlen (const char *str); /* misc */ @@ -522,6 +526,8 @@ int substring (char *s1, char *s2); int get_based_digit (int c, int base); int safe_parse_maxint (char **str_ptr, int *myint_ptr); +int parse_color_command (char *str_ptr); +int parse_symbolic_color(const char *str); int memcheck (int start, int len); #ifndef NO_DECOMPRESSION diff -urN --exclude-from=diffexclude cvsgrub/stage2/stage2.c grub/stage2/stage2.c --- cvsgrub/stage2/stage2.c Thu Jun 24 02:03:29 1999 +++ grub/stage2/stage2.c Fri Jul 16 21:24:13 1999 @@ -637,22 +637,7 @@ else if (substring ("default", cmdline) < 1) safe_parse_maxint (&ptr, &default_entry); else if (substring ("color", cmdline) < 1) - { - char *normal; - char *highlight; - - normal = ptr; - highlight = skip_to (0, normal); - - if (safe_parse_maxint (&normal, &normal_color)) - { - if (*highlight == 0 - || ! safe_parse_maxint (&highlight, - &highlight_color)) - highlight_color = ((normal_color >> 4) - | ((normal_color & 0xf) << 4)); - } - } + parse_color_command (ptr); else if (substring ("password", cmdline) < 1) { password = config_entries;