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