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;

Reply via email to