5a817a3e182dda775776797763c5d4f5a9d67245
[reactos.git] / sdk / tools / log2lines / cmd.c
1 /*
2 * ReactOS log2lines
3 * Written by Jan Roeloffzen
4 *
5 * - Cli for escape commands
6 */
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11
12 #include "util.h"
13 #include "cmd.h"
14 #include "options.h"
15 #include "log2lines.h"
16 #include "help.h"
17
18 /* When you edit the cmd line and/or use the history instead of just typing,
19 * a bunch of editing BS and space characters
20 * is inserted, so the string looks right on the console but still
21 * contains the original string, plus other garbage:
22 */
23 static char
24 *backSpaceEdit(char *s)
25 {
26 char c;
27 char *edit = s;
28 char *text = s;
29
30 while (( c = *edit++ ))
31 {
32 switch (c)
33 {
34 case KDBG_BS_CHAR:
35 if (text > s)
36 text --;
37 break;
38 default:
39 *text++ = c;
40 }
41 }
42 *text = '\0';
43
44 return s;
45 }
46
47 static int
48 handle_switch(FILE *outFile, int *sw, char *arg, char *desc)
49 {
50 int changed =0;
51 int x = 0;
52
53 if (arg && (strcmp(arg,"") != 0))
54 {
55 x = atoi(arg);
56 if (x != *sw)
57 {
58 *sw = x;
59 changed = 1;
60 }
61 }
62 if (desc)
63 {
64 esclog(outFile, "%s is %d (%s)\n", desc, *sw, changed ? "changed":"unchanged");
65 if (!arg)
66 esclog(outFile, "(readonly)\n");
67 }
68
69 return changed;
70 }
71
72 static int
73 handle_switch_str(FILE *outFile, char *sw, char *arg, char *desc)
74 {
75 int changed =0;
76
77 if (arg)
78 {
79 if (strcmp(arg,"") != 0)
80 {
81 if (strcmp(arg,KDBG_ESC_OFF) == 0)
82 {
83 if (*sw)
84 changed = 1;
85 *sw = '\0';
86 }
87 else if (strcmp(arg, sw) != 0)
88 {
89 strcpy(sw, arg);
90 changed = 1;
91 }
92 }
93 }
94 if (desc)
95 {
96 esclog(outFile, "%s is \"%s\" (%s)\n", desc, sw, changed ? "changed":"unchanged");
97 if (!arg)
98 esclog(outFile, "(readonly)\n");
99 }
100
101 return changed;
102 }
103
104 static int
105 handle_switch_pstr(FILE *outFile, char **psw, char *arg, char *desc)
106 {
107 int changed =0;
108
109 if (arg)
110 {
111 if (strcmp(arg,"") != 0)
112 {
113 if (strcmp(arg,KDBG_ESC_OFF) == 0)
114 {
115 if (*psw)
116 changed = 1;
117 free(*psw);
118 *psw = NULL;
119 }
120 else
121 {
122 if (!*psw)
123 {
124 *psw = malloc(LINESIZE);
125 **psw = '\0';
126 }
127
128 if (strcmp(arg, *psw) != 0)
129 {
130 strcpy(*psw, arg);
131 changed = 1;
132 }
133 }
134 }
135 }
136 if (desc)
137 {
138 esclog(outFile, "%s is \"%s\" (%s)\n", desc, *psw, changed ? "changed":"unchanged");
139 if (!arg)
140 esclog(outFile, "(readonly)\n");
141 }
142
143 return changed;
144 }
145
146 static int
147 handle_address_cmd(FILE *outFile, char *arg)
148 {
149 PLIST_MEMBER plm;
150 char Image[NAMESIZE];
151 DWORD Offset;
152 int cnt;
153 char *s;
154
155 if(( s = strchr(arg, ':') ))
156 {
157 *s = ' ';
158 if ( (cnt = sscanf(arg,"%20s %x", Image, &Offset)) == 2)
159 {
160 if (( plm = entry_lookup(&cache, Image) ))
161 {
162 if (plm->RelBase != INVALID_BASE)
163 esclog(outFile, "Address: 0x%lx\n", plm->RelBase + Offset)
164 else
165 esclog(outFile, "Relocated base missing for '%s' ('mod' will update)\n", Image);
166 }
167 else
168 esclog(outFile, "Image '%s' not found\n", Image);
169 }
170 else
171 esclog(outFile, "usage: `a <Image>:<offset>\n");
172 }
173 else
174 esclog(outFile, "':' expected\n");
175
176 return 1;
177 }
178
179 char
180 handle_escape_cmd(FILE *outFile, char *Line, char *path, char *LineOut)
181 {
182 char cmd;
183 char sep = '\n';
184 char *arg;
185 char *l = Line;
186 int res = 1;
187 int cnt = 0;
188 int changed = 0;
189
190 l = backSpaceEdit(l);
191 if (l[1] != KDBG_ESC_CHAR)
192 return l[1]; //for reprocessing as not escaped
193
194 log(outFile, "\n");
195
196 l += 2; //skip space+escape character
197 if ( (cnt=sscanf(l,"%c%c",&cmd,&sep)) < 1)
198 {
199 esclog(outFile, "Command expected\n");
200 res = 0;
201 }
202
203 if (res && cnt==2 && sep != ' ')
204 {
205 esclog(outFile, "' ' expected\n");
206 res = 0;
207 }
208 l++; //skip cmd
209 while ( *l == ' ')l++; //skip more spaces
210 arg = l;
211 opt_cli = 1;
212 switch (cmd)
213 {
214 case 'a':
215 handle_address_cmd(outFile, arg);
216 break;
217 case 'h':
218 usage(1);
219 break;
220 case 'b':
221 if (handle_switch(outFile, &opt_buffered, arg, "-b Logfile buffering"))
222 set_LogFile(&logFile); //re-open same logfile
223 break;
224 case 'c':
225 handle_switch(outFile, &opt_console, NULL, "-c Console option");
226 break;
227 case 'd':
228 handle_switch_str(outFile, opt_dir, NULL, "-d Directory option");
229 break;
230 case 'l':
231 if (handle_switch_str(outFile, opt_logFile, arg, "-l logfile") || (strcmp(opt_mod,"a")!=0))
232 {
233 opt_mod = "a";
234 set_LogFile(&logFile); //open new logfile
235 }
236 break;
237 case 'L':
238 if (handle_switch_str(outFile, opt_logFile, arg, "-L logfile") || (strcmp(opt_mod,"w")!=0))
239 {
240 opt_mod = "w";
241 set_LogFile(&logFile); //open new logfile
242 }
243 break;
244 case 'm':
245 handle_switch(outFile, &opt_Mark, arg, "-m mark (*)");
246 break;
247 case 'M':
248 handle_switch(outFile, &opt_Mark, arg, "-M Mark (?)");
249 break;
250 case 'P':
251 handle_switch_str(outFile, opt_Pipe, NULL, "-P Pipeline option");
252 break;
253 case 'q':
254 opt_quit = 1;
255 esclog(outFile, "Bye!\n");
256 break;
257 case 'r':
258 handle_switch(outFile, &opt_raw, arg, "-r Raw");
259 break;
260 case 'R':
261 changed = handle_switch_pstr(outFile, &opt_Revision, arg, NULL);
262 opt_Revision_check = 0;
263 if (opt_Revision)
264 {
265 opt_Revision_check = 1;
266 if (strstr(opt_Revision, "check") == opt_Revision)
267 {
268 esclog(outFile, "-R is \"%s\" (%s)\n", opt_Revision, changed ? "changed":"unchanged");
269 }
270 else if (strstr(opt_Revision, "regscan") == opt_Revision)
271 {
272 char *s = strchr(opt_Revision, ',');
273
274 revinfo.range = DEF_RANGE;
275 if (s)
276 {
277 *s++ = '\0';
278 revinfo.range = atoi(s);
279 }
280 regscan(outFile);
281 }
282 else if (strstr(opt_Revision, "regclear") == opt_Revision)
283 {
284 list_clear(&sources);
285 summ.regfound = 0;
286 esclog(outFile, "cleared regression scan results\n");
287 }
288 }
289 break;
290 case 's':
291 if (strcmp(arg,"clear") == 0)
292 {
293 memset(&summ, 0, sizeof(SUMM));
294 esclog(outFile, "Statistics cleared\n");
295 }
296 else
297 stat_print(outFile, &summ);
298 break;
299 case 'S':
300 cnt = sscanf(arg, "%d+%d", &opt_Source, &opt_SrcPlus);
301 if (opt_Source)
302 {
303 handle_switch(outFile, &opt_undo, "1", "-u Undo");
304 handle_switch(outFile, &opt_redo, "1", "-U Undo and reprocess");
305 opt_Revision_check = 1;
306 }
307 esclog(outFile, "-S Sources option is %d+%d,\"%s\"\n", opt_Source, opt_SrcPlus, opt_SourcesPath);
308 esclog(outFile, "(Setting source tree not implemented)\n");
309 break;
310 case 't':
311 handle_switch(outFile, &opt_twice, arg, "-t Translate twice");
312 break;
313 case 'T':
314 handle_switch(outFile, &opt_twice, arg, NULL);
315 handle_switch(outFile, &opt_Twice, arg, "-T Translate for (address-1)");
316 break;
317 case 'u':
318 handle_switch(outFile, &opt_undo, arg, "-u undo");
319 break;
320 case 'U':
321 handle_switch(outFile, &opt_undo, arg, NULL);
322 handle_switch(outFile, &opt_redo, arg, "-U Undo and reprocess");
323 break;
324 case 'v':
325 handle_switch(outFile, &opt_verbose, arg, "-v Verbosity");
326 break;
327 case 'z':
328 handle_switch_str(outFile, opt_7z, NULL, "-z 7z path");
329 break;
330 default:
331 if (strchr(optchars, cmd))
332 esclog(outFile, "Command not implemented in cli: %c %s\n",cmd, arg)
333 else
334 esclog(outFile, "Unknown command: %c %s\n",cmd, arg);
335 }
336 opt_cli = 0;
337
338 memset(Line, '\0', LINESIZE); // flushed
339
340 return KDBG_ESC_CHAR; //handled escaped command
341 }
342
343 /* EOF */