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;