xref: /reactos/sdk/tools/log2lines/cmd.c (revision d6eebaa4)
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_address_cmd(FILE *outFile, char *arg)
106 {
107     PLIST_MEMBER plm;
108     char Image[NAMESIZE];
109     DWORD Offset;
110     int cnt;
111     char *s;
112 
113     if(( s = strchr(arg, ':') ))
114     {
115         *s = ' ';
116         if ( (cnt = sscanf(arg,"%20s %x", Image, &Offset)) == 2)
117         {
118             if (( plm = entry_lookup(&cache, Image) ))
119             {
120                 if (plm->RelBase != INVALID_BASE)
121                     esclog(outFile, "Address: 0x%lx\n", plm->RelBase + Offset)
122                 else
123                     esclog(outFile, "Relocated base missing for '%s' ('mod' will update)\n", Image);
124             }
125             else
126                 esclog(outFile, "Image '%s' not found\n", Image);
127         }
128         else
129             esclog(outFile, "usage: `a <Image>:<offset>\n");
130     }
131     else
132         esclog(outFile, "':' expected\n");
133 
134     return 1;
135 }
136 
137 char
138 handle_escape_cmd(FILE *outFile, char *Line)
139 {
140     char cmd;
141     char sep = '\n';
142     char *arg;
143     char *l = Line;
144     int res = 1;
145     int cnt = 0;
146     int changed = 0;
147 
148     l = backSpaceEdit(l);
149     if (l[1] != KDBG_ESC_CHAR)
150         return l[1]; //for reprocessing as not escaped
151 
152     log(outFile, "\n");
153 
154     l += 2; //skip space+escape character
155     if ( (cnt=sscanf(l,"%c%c",&cmd,&sep)) < 1)
156     {
157         esclog(outFile, "Command expected\n");
158         res = 0;
159     }
160 
161     if (res && cnt==2 && sep != ' ')
162     {
163         esclog(outFile, "' ' expected\n");
164         res = 0;
165     }
166     l++; //skip cmd
167     while ( *l == ' ')l++; //skip more spaces
168     arg = l;
169     opt_cli = 1;
170     switch (cmd)
171     {
172     case 'a':
173         handle_address_cmd(outFile, arg);
174         break;
175     case 'h':
176         usage(1);
177         break;
178     case 'b':
179         if (handle_switch(outFile, &opt_buffered, arg, "-b Logfile buffering"))
180             set_LogFile(&logFile); //re-open same logfile
181         break;
182     case 'c':
183         handle_switch(outFile, &opt_console, NULL, "-c Console option");
184         break;
185     case 'd':
186         handle_switch_str(outFile, opt_dir, NULL, "-d Directory option");
187         break;
188     case 'l':
189         if (handle_switch_str(outFile, opt_logFile, arg, "-l logfile") || (strcmp(opt_mod,"a")!=0))
190         {
191             opt_mod = "a";
192             set_LogFile(&logFile); //open new logfile
193         }
194         break;
195     case 'L':
196         if (handle_switch_str(outFile, opt_logFile, arg, "-L logfile") || (strcmp(opt_mod,"w")!=0))
197         {
198             opt_mod = "w";
199             set_LogFile(&logFile); //open new logfile
200         }
201         break;
202     case 'm':
203         handle_switch(outFile, &opt_Mark, arg, "-m mark (*)");
204         break;
205     case 'M':
206         handle_switch(outFile, &opt_Mark, arg, "-M Mark (?)");
207         break;
208     case 'P':
209         handle_switch_str(outFile, opt_Pipe, NULL, "-P Pipeline option");
210         break;
211     case 'q':
212         opt_quit = 1;
213         esclog(outFile, "Bye!\n");
214         break;
215     case 'r':
216         handle_switch(outFile, &opt_raw, arg, "-r Raw");
217         break;
218     case 's':
219         if (strcmp(arg,"clear") == 0)
220         {
221             memset(&summ, 0, sizeof(SUMM));
222             esclog(outFile, "Statistics cleared\n");
223         }
224         else
225             stat_print(outFile, &summ);
226         break;
227     case 'S':
228         cnt = sscanf(arg, "%d+%d", &opt_Source, &opt_SrcPlus);
229         if (opt_Source)
230         {
231             handle_switch(outFile, &opt_undo, "1", "-u Undo");
232             handle_switch(outFile, &opt_redo, "1", "-U Undo and reprocess");
233         }
234         esclog(outFile, "-S Sources option is %d+%d,\"%s\"\n", opt_Source, opt_SrcPlus, opt_SourcesPath);
235         esclog(outFile, "(Setting source tree not implemented)\n");
236         break;
237     case 't':
238         handle_switch(outFile, &opt_twice, arg, "-t Translate twice");
239         break;
240     case 'T':
241         handle_switch(outFile, &opt_twice, arg, NULL);
242         handle_switch(outFile, &opt_Twice, arg, "-T Translate for (address-1)");
243         break;
244     case 'u':
245         handle_switch(outFile, &opt_undo, arg, "-u undo");
246         break;
247     case 'U':
248         handle_switch(outFile, &opt_undo, arg, NULL);
249         handle_switch(outFile, &opt_redo, arg, "-U Undo and reprocess");
250         break;
251     case 'v':
252         handle_switch(outFile, &opt_verbose, arg, "-v Verbosity");
253         break;
254     case 'z':
255         handle_switch_str(outFile, opt_7z, NULL, "-z 7z path");
256         break;
257     default:
258         if (strchr(optchars, cmd))
259             esclog(outFile, "Command not implemented in cli: %c %s\n",cmd, arg)
260         else
261             esclog(outFile, "Unknown command: %c %s\n",cmd, arg);
262     }
263     opt_cli = 0;
264 
265     memset(Line, '\0', LINESIZE);  // flushed
266 
267     return KDBG_ESC_CHAR; //handled escaped command
268 }
269 
270 /* EOF */
271