xref: /reactos/base/shell/cmd/prompt.c (revision 50cf16b3)
1 /*
2  *  PROMPT.C - prompt handling.
3  *
4  *
5  *  History:
6  *
7  *    14/01/95 (Tim Normal)
8  *        started.
9  *
10  *    08/08/95 (Matt Rains)
11  *        i have cleaned up the source code. changes now bring this source
12  *        into guidelines for recommended programming practice.
13  *
14  *    01/06/96 (Tim Norman)
15  *        added day of the week printing (oops, forgot about that!)
16  *
17  *    08/07/96 (Steffan Kaiser)
18  *        small changes for speed
19  *
20  *    20-Jul-1998 (John P Price <linux-guru@gcfl.net>)
21  *        removed redundant day strings. Use ones defined in date.c.
22  *
23  *    27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
24  *        added config.h include
25  *
26  *    28-Jul-1998 (John P Price <linux-guru@gcfl.net>)
27  *        moved cmd_prompt from internal.c to here
28  *
29  *    09-Dec-1998 (Eric Kohl)
30  *        Added help text ("/?").
31  *
32  *    14-Dec-1998 (Eric Kohl)
33  *        Added "$+" option.
34  *
35  *    09-Jan-1999 (Eric Kohl)
36  *        Added "$A", "$C" and "$F" option.
37  *        Added locale support.
38  *        Fixed "$V" option.
39  *
40  *    20-Jan-1999 (Eric Kohl)
41  *        Unicode and redirection safe!
42  *
43  *    24-Jan-1999 (Eric Kohl)
44  *        Fixed Win32 environment handling.
45  *
46  *    30-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
47  *        Remove all hardcoded strings in En.rc
48  */
49 #include "precomp.h"
50 
51 /* The default prompt */
52 static TCHAR DefaultPrompt[] = _T("$P$G");
53 
54 /*
55  * Initialize prompt support
56  */
57 VOID InitPrompt(VOID)
58 {
59     TCHAR Buffer[2];
60 
61     /*
62      * Set the PROMPT environment variable if it doesn't exist already.
63      * You can change the PROMPT environment variable before cmd starts.
64      */
65     if (GetEnvironmentVariable(_T("PROMPT"), Buffer, ARRAYSIZE(Buffer)) == 0)
66         SetEnvironmentVariable(_T("PROMPT"), DefaultPrompt);
67 }
68 
69 /*
70  * Print an information line on top of the screen
71  */
72 VOID PrintInfoLine(VOID)
73 {
74 #define FOREGROUND_WHITE (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY)
75 
76     HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
77     CONSOLE_SCREEN_BUFFER_INFO csbi;
78     COORD coPos;
79     DWORD dwWritten;
80 
81     PTSTR pszInfoLine = NULL;
82     INT iInfoLineLen;
83 
84     /* Return directly if the output handle is not a console handle */
85     if (!GetConsoleScreenBufferInfo(hOutput, &csbi))
86         return;
87 
88     iInfoLineLen = LoadString(CMD_ModuleHandle, STRING_CMD_INFOLINE, (PTSTR)&pszInfoLine, 0);
89     if (!pszInfoLine || iInfoLineLen == 0)
90         return;
91 
92     /* Display the localized information line */
93     coPos.X = 0;
94     coPos.Y = 0;
95     FillConsoleOutputAttribute(hOutput, BACKGROUND_BLUE | FOREGROUND_WHITE,
96                                csbi.dwSize.X,
97                                coPos, &dwWritten);
98     FillConsoleOutputCharacter(hOutput, _T(' '),
99                                csbi.dwSize.X,
100                                coPos, &dwWritten);
101 
102     WriteConsoleOutputCharacter(hOutput, pszInfoLine, iInfoLineLen,
103                                 coPos, &dwWritten);
104 }
105 
106 /*
107  * Print the command-line prompt
108  */
109 VOID PrintPrompt(VOID)
110 {
111     TCHAR  szPrompt[256];
112     LPTSTR pr;
113 
114     if (GetEnvironmentVariable(_T("PROMPT"), szPrompt, 256))
115         pr = szPrompt;
116     else
117         pr = DefaultPrompt;
118 
119     while (*pr)
120     {
121         if (*pr != _T('$'))
122         {
123             ConOutChar(*pr);
124         }
125         else
126         {
127             pr++;
128 
129             switch (_totupper(*pr))
130             {
131                 case _T('A'):
132                     ConOutChar(_T('&'));
133                     break;
134 
135                 case _T('B'):
136                     ConOutChar(_T('|'));
137                     break;
138 
139                 case _T('C'):
140                     ConOutChar(_T('('));
141                     break;
142 
143                 case _T('D'):
144                     ConOutPrintf(_T("%s"), GetDateString());
145                     break;
146 
147                 case _T('E'):
148                     ConOutChar(_T('\x1B'));
149                     break;
150 
151                 case _T('F'):
152                     ConOutChar(_T(')'));
153                     break;
154 
155                 case _T('G'):
156                     ConOutChar(_T('>'));
157                     break;
158 
159                 case _T('H'):
160                     ConOutChar(_T('\x08'));
161                     ConOutChar(_T(' '));
162                     ConOutChar(_T('\x08'));
163                     break;
164 
165                 case _T('I'):
166                     PrintInfoLine();
167                     break;
168 
169                 case _T('L'):
170                     ConOutChar(_T('<'));
171                     break;
172 
173                 case _T('N'):
174                     {
175                         TCHAR szPath[MAX_PATH];
176                         GetCurrentDirectory(MAX_PATH, szPath);
177                         ConOutChar(szPath[0]);
178                     }
179                     break;
180 
181                 case _T('P'):
182                     {
183                         TCHAR szPath[MAX_PATH];
184                         GetCurrentDirectory(MAX_PATH, szPath);
185                         ConOutPrintf(_T("%s"), szPath);
186                     }
187                     break;
188 
189                 case _T('Q'):
190                     ConOutChar(_T('='));
191                     break;
192 
193                 case _T('S'):
194                     ConOutChar(_T(' '));
195                     break;
196 
197                 case _T('T'):
198                     ConOutPrintf(_T("%s"), GetTimeString());
199                     break;
200 
201                 case _T('V'):
202                     PrintOSVersion();
203                     break;
204 
205                 case _T('_'):
206                     ConOutChar(_T('\n'));
207                     break;
208 
209                 case '$':
210                     ConOutChar(_T('$'));
211                     break;
212 
213 #ifdef FEATURE_DIRECTORY_STACK
214                 case '+':
215                     {
216                         INT i;
217                         for (i = 0; i < GetDirectoryStackDepth (); i++)
218                             ConOutChar(_T('+'));
219                     }
220                     break;
221 #endif
222             }
223         }
224         pr++;
225     }
226 }
227 
228 
229 #ifdef INCLUDE_CMD_PROMPT
230 
231 INT cmd_prompt(LPTSTR param)
232 {
233     if (!_tcsncmp(param, _T("/?"), 2))
234     {
235         ConOutResPaging(TRUE, STRING_PROMPT_HELP1);
236 
237 #ifdef FEATURE_DIRECTORY_STACK
238         ConOutResPaging(FALSE, STRING_PROMPT_HELP2);
239 #endif
240         ConOutResPaging(FALSE, STRING_PROMPT_HELP3);
241         return 0;
242     }
243 
244     /*
245      * Set the PROMPT environment variable. If 'param' is NULL or is
246      * an empty string (the user entered "prompt" only), then remove
247      * the environment variable and therefore use the default prompt.
248      * Otherwise, use the new prompt.
249      */
250     if (!SetEnvironmentVariable(_T("PROMPT"),
251                                 (param && param[0] != _T('\0') ? param : NULL)))
252     {
253         return 1;
254     }
255 
256     return 0;
257 }
258 #endif
259 
260 /* EOF */
261