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