update for HEAD-2003091401
[reactos.git] / subsys / system / cmd / strtoclr.c
1 /*
2  *  STRTOCLR.C - read color (for color command and other)
3  *
4  *
5  *  History:
6  *
7  *    07-Oct-1999 (Paolo Pantaleo)
8  *        Started.
9  *
10  *
11  */
12
13 /*only
14 BOOL StringToColor(LPWORD lpColor, LPTSTR*str)
15 is to be called
16 other are internal service functions*/
17
18
19 #include "cmd.h"
20
21 #include <ctype.h>
22 #include <tchar.h>
23
24
25 #define _B FOREGROUND_BLUE
26 #define _G FOREGROUND_GREEN
27 #define _R FOREGROUND_RED
28 #define _I FOREGROUND_INTENSITY
29
30
31 /*return values for chop_blank*/
32 #define CP_OK                           0
33 #define CP_BLANK_NOT_FOUND      1
34 #define CP_END_OF_STRING        2
35
36 #define SC_HEX 0x0100
37 #define SC_TXT 0x0200
38
39
40
41 typedef struct _CLRTABLE
42 {
43         LPTSTR          name;
44         WORD            val;
45 } CLRTABLE;
46
47
48 CLRTABLE clrtable[] =
49 {
50         {_T("bla")      ,0              },
51         {_T("blu")      ,_B             },
52         {_T("gre")      ,_G             },
53         {_T("cya")      ,_B|_G          },
54         {_T("red")      ,_R             },
55         {_T("mag")      ,_B|_R          },
56         {_T("yel")      ,_R|_G          },
57         {_T("whi")      ,_R|_G|_B       },
58         {_T("gra")      ,_I             },
59
60         
61         {_T("0")        ,0              },
62         {_T("2")        ,_G             },
63         {_T("3")        ,_B|_G          },
64         {_T("4")        ,_R             },
65         {_T("5")        ,_B|_R          },
66         {_T("6")        ,_R|_G          },
67         {_T("7")        ,_R|_G|_B       },
68
69         {_T("8")        ,_I             },
70         {_T("9")        ,_I|_B          },
71         {_T("10")       ,_I|_G          },
72         {_T("11")       ,_I|_B|_G       },
73         {_T("12")       ,_I|_R          },
74         {_T("13")       ,_I|_B|_R       },
75         {_T("14")       ,_I|_R|_G       },
76         {_T("15")       ,_I|_R|_G|_B    },
77
78         
79         /* note that 1 is at the end of list
80         to avoid to confuse it with 10-15*/
81         {_T("1")        ,_B             },
82
83         /*cyan synonimous*/
84         {_T("aqu")      ,_B|_G          },
85         /*magenta synonimous*/
86         {_T("pur")      ,_B|_R          },
87
88         
89         {_T("")   ,0},
90 };
91
92
93
94 /*
95 move string pointer to next word (skip all spaces)
96 on erro retunr nonzero value
97 */
98 static
99 INT chop_blank(LPTSTR *arg_str)
100 {
101         
102         LPTSTR str;
103         str = _tcschr(*arg_str,_T(' '));
104         if(!str)
105         {
106                 str = _tcschr (*arg_str, _T('\0'));
107                 if(str != NULL)
108                         *arg_str=str;
109                 return CP_BLANK_NOT_FOUND;
110         }
111
112         
113
114         while(_istspace(*str))
115                 str++;
116
117         if (*str == _T('\0'))
118         {
119                 *arg_str=str;
120                 return CP_END_OF_STRING;
121         }
122
123         *arg_str = str;
124
125         return CP_OK;   
126 }
127
128
129
130 /*
131 read a color value in hex (like win nt's cmd syntax)
132 if an error occurs return -1    
133 */ 
134 static
135 WORD hex_clr(LPTSTR str)
136 {
137         WORD ret= (WORD)-1;
138         TCHAR ch;
139         
140         ch = str[1];
141         
142         if(_istdigit(ch))
143                 ret = ch-_T('0');
144         else
145         {       
146                 ch=_totupper(ch);
147
148                 if(  ch >= _T('A') && ch <= _T('F')  )
149                         ret = ch-_T('A')+10;
150                 else
151                         return (WORD)-1;
152         }
153
154         
155         ch = str[0];
156         
157         if(_istdigit(ch))
158                 ret |= (ch-_T('0')) << 4;
159         else
160         {       
161                 ch=_totupper(ch);
162
163                 if(  ch >= _T('A') && ch <= _T('F')  )
164                         ret |= (ch-_T('A')+10) <<4;
165                 else
166                         return (WORD)-1;
167         }
168
169         return ret;
170 }
171
172
173 /*
174 read a color value from a string (like 4nt's syntax)
175 if an error occurs return -1    
176 */
177 static
178 WORD txt_clr(LPTSTR str)
179 {
180         INT i;
181         
182         for(i=0;*(clrtable[i].name);i++)
183                 if(     _tcsnicmp(str,clrtable[i].name,_tcslen(clrtable[i].name)) == 0)                 
184                         return clrtable[i].val;
185         
186         return (WORD)-1;
187 }
188
189
190
191 /*search for x on y*/ 
192 static
193 WORD str_to_color(LPTSTR* arg_str)
194 {
195         LPTSTR str;     
196         BOOL bBri;
197
198         WORD tmp_clr,ret_clr;
199
200         str = *arg_str;
201
202
203         
204         if(!(*str))
205                 return (WORD)-1;
206
207
208         /*foreground*/
209         bBri = FALSE;
210
211         if(_tcsnicmp(str,_T("bri"),3) == 0 )
212         {
213                 bBri = TRUE;
214
215                 if(chop_blank(&str))
216                         return (WORD)-1;
217         }
218
219         if( (tmp_clr = txt_clr(str)) == (WORD)-1 )
220         {
221                 return (WORD)-1;
222         }
223
224         /*skip spaces and "on"*/        
225         if ( chop_blank(&str) || chop_blank(&str) )
226                 return (WORD)-1;
227
228         ret_clr = tmp_clr | (bBri << 3);
229
230         /*background*/
231         bBri = FALSE;
232
233         if(_tcsnicmp(str,_T("bri"),3) == 0 )
234         {
235                 bBri = TRUE;
236
237                 if(chop_blank(&str))
238                         return (WORD)-1;
239         }
240                 
241         
242         if( (tmp_clr = txt_clr(str)) == (WORD)-1 )
243                 return (WORD)-1;
244
245         chop_blank(&str);
246         
247         *arg_str = str;
248
249         return SC_HEX | ret_clr | tmp_clr << 4 | bBri << 7;
250 }
251
252
253
254 /****main function****/
255 /*
256 the only parameter is arg_str, a pointer to a string.
257 the string is modified so it will begin to first word after
258 color specification
259 (only the char* is moved, no chars in the string are modfied)
260
261
262 it returns the color in the l.o. byte, plus two flags in the
263 h.o. byte, they are:
264 SC_HEX win nt's cmd syntax (for exampl a0)
265 SC_TXT 4nt's syntax ( "bri gre on bla" or "10 on 0")
266
267 if succedes also move the LPTSTR to end of
268 string that specify color
269 */
270
271
272 BOOL StringToColor(LPWORD lpColor, LPTSTR*str)
273 {
274         WORD wRet;
275
276         wRet = str_to_color (str);
277         if (wRet == (WORD)-1)
278         {
279                 wRet=hex_clr (*str);
280                 chop_blank (str);
281                 if (wRet == (WORD)-1)
282                         return FALSE;
283         }
284
285         *lpColor = wRet;
286
287         return TRUE;
288 }
289
290 /* EOF */