[DCOMLAUNCH] Add a DcomLaunch service stub
[reactos.git] / base / shell / 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 * 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 */