[LOG2LINES] Optimize malloc() calls.
[reactos.git] / sdk / tools / log2lines / options.c
1 /*
2 * ReactOS log2lines
3 * Written by Jan Roeloffzen
4 *
5 * - Option init and parsing
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <getopt.h>
12
13 #include "util.h"
14 #include "compat.h"
15 #include "config.h"
16 #include "help.h"
17 #include "log2lines.h"
18 #include "options.h"
19
20 char *optchars = "bcd:fFhl:L:mMP:rR:sS:tTuUvz:";
21 int opt_buffered = 0; // -b
22 int opt_help = 0; // -h
23 int opt_force = 0; // -f
24 int opt_exit = 0; // -e
25 int opt_verbose = 0; // -v
26 int opt_console = 0; // -c
27 int opt_mark = 0; // -m
28 int opt_Mark = 0; // -M
29 char *opt_Pipe = NULL; // -P
30 int opt_quit = 0; // -q (cli only)
31 int opt_cli = 0; // (cli internal)
32 int opt_raw = 0; // -r
33 int opt_stats = 0; // -s
34 int opt_Source = 0; // -S <opt_Source>[+<opt_SrcPlus>][,<sources_path>]
35 int opt_SrcPlus = 0; // -S <opt_Source>[+<opt_SrcPlus>][,<sources_path>]
36 int opt_twice = 0; // -t
37 int opt_Twice = 0; // -T
38 int opt_undo = 0; // -u
39 int opt_redo = 0; // -U
40 char *opt_Revision = NULL; // -R
41 int opt_Revision_check = 0; // -R check
42 char opt_dir[PATH_MAX]; // -d <opt_dir>
43 char opt_logFile[PATH_MAX]; // -l|L <opt_logFile>
44 char *opt_mod = NULL; // -mod for opt_logFile
45 char opt_7z[PATH_MAX]; // -z <opt_7z>
46 char opt_scanned[LINESIZE]; // all scanned options
47 char opt_SourcesPath[LINESIZE]; //sources path
48
49 /* optionInit returns 0 for normal operation, and -1 in case just "loglines.exe" was written.
50 In such case, the help is shown */
51
52 int optionInit(int argc, const char **argv)
53 {
54 int i;
55 char *s;
56
57 opt_mod = "a";
58 strcpy(opt_dir, "");
59 strcpy(opt_logFile, "");
60 strcpy(opt_7z, CMD_7Z);
61 strcpy(opt_SourcesPath, "");
62 if ((s = getenv(SOURCES_ENV)))
63 strcpy(opt_SourcesPath, s);
64 revinfo.rev = getRevision(NULL, 1);
65 revinfo.range = DEF_RANGE;
66 revinfo.buildrev = getTBRevision(opt_dir);
67 l2l_dbg(1, "Trunk build revision: %d\n", revinfo.buildrev);
68
69 strcpy(opt_scanned, "");
70
71 //The user introduced "log2lines.exe" or "log2lines.exe /?"
72 //Let's help the user
73 if ((argc == 1) ||
74 ((argc == 2) && (argv[1][0] == '/') && (argv[1][1] == '?')))
75 {
76 opt_help++;
77 usage(1);
78 return -1;
79 }
80
81 for (i = 1; i < argc; i++)
82 {
83
84 if ((argv[i][0] == '-') && (i+1 < argc))
85 {
86 //Because these arguments can contain spaces we cant use getopt(), a known bug:
87 switch (argv[i][1])
88 {
89 case 'd':
90 strcpy(opt_dir, argv[i+1]);
91 break;
92 case 'L':
93 opt_mod = "w";
94 //fall through
95 case 'l':
96 strcpy(opt_logFile, argv[i+1]);
97 break;
98 case 'P':
99 if (!opt_Pipe)
100 opt_Pipe = malloc(LINESIZE);
101 strcpy(opt_Pipe, argv[i+1]);
102 break;
103 case 'z':
104 strcpy(opt_7z, argv[i+1]);
105 break;
106 }
107 }
108
109 strcat(opt_scanned, argv[i]);
110 strcat(opt_scanned, " ");
111 }
112
113 l2l_dbg(4,"opt_scanned=[%s]\n",opt_scanned);
114
115 return 0;
116 }
117
118 int optionParse(int argc, const char **argv)
119 {
120 int i;
121 int optCount = 0;
122 int opt;
123
124 while (-1 != (opt = getopt(argc, (char **const)argv, optchars)))
125 {
126 switch (opt)
127 {
128 case 'b':
129 opt_buffered++;
130 break;
131 case 'c':
132 opt_console++;
133 break;
134 case 'd':
135 optCount++;
136 //just count, see optionInit()
137 break;
138 case 'f':
139 opt_force++;
140 break;
141 case 'h':
142 opt_help++;
143 usage(1);
144 return -1;
145 break;
146 case 'F':
147 opt_exit++;
148 opt_force++;
149 break;
150 case 'l':
151 optCount++;
152 //just count, see optionInit()
153 break;
154 case 'm':
155 opt_mark++;
156 break;
157 case 'M':
158 opt_Mark++;
159 break;
160 case 'r':
161 opt_raw++;
162 break;
163 case 'P':
164 optCount++;
165 //just count, see optionInit()
166 break;
167 case 'R':
168 optCount++;
169 if (!opt_Revision)
170 opt_Revision = malloc(LINESIZE);
171 sscanf(optarg, "%s", opt_Revision);
172 if (strcmp(opt_Revision, "check") == 0)
173 opt_Revision_check ++;
174 break;
175 case 's':
176 opt_stats++;
177 break;
178 case 'S':
179 optCount++;
180 i = sscanf(optarg, "%d+%d,%s", &opt_Source, &opt_SrcPlus, opt_SourcesPath);
181 if (i == 1)
182 sscanf(optarg, "%*d,%s", opt_SourcesPath);
183 l2l_dbg(3, "Sources option parse result: %d+%d,\"%s\"\n", opt_Source, opt_SrcPlus, opt_SourcesPath);
184 if (opt_Source)
185 {
186 /* need to retranslate for source info: */
187 opt_undo++;
188 opt_redo++;
189 opt_Revision_check ++;
190 }
191 break;
192 case 't':
193 opt_twice++;
194 break;
195 case 'T':
196 opt_twice++;
197 opt_Twice++;
198 break;
199 case 'u':
200 opt_undo++;
201 break;
202 case 'U':
203 opt_undo++;
204 opt_redo++;
205 break;
206 case 'v':
207 opt_verbose++;
208 break;
209 case 'z':
210 optCount++;
211 strcpy(opt_7z, optarg);
212 break;
213 default:
214 usage(0);
215 return -2;
216 break;
217 }
218 optCount++;
219 }
220 if(opt_console)
221 {
222 l2l_dbg(2, "Note: use 's' command in console mode. Statistics option disabled\n");
223 opt_stats = 0;
224 }
225 if (opt_SourcesPath[0])
226 {
227 strcat(opt_SourcesPath, PATH_STR);
228 }
229 if (!opt_dir[0])
230 {
231 strcpy(opt_dir, opt_SourcesPath);
232 strcat(opt_dir, DEF_OPT_DIR);
233 }
234
235 return optCount;
236 }
237
238 /* EOF */