RPA Toolkit
65c8a50ad9974b29801f4fb6a1aed910bc19405c
[rpatk.git] / rgrep / win32 / main.c
1 /*
2  *  Regular Pattern Analyzer (RPA)
3  *  Copyright (c) 2009-2010 Martin Stoilov
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  *  Martin Stoilov <martin@rpasearch.com>
19  */
20
21
22 #include <wchar.h>
23 #include <windows.h>
24 #include "rlib/rmem.h"
25 #include "rlib/rarray.h"
26 #include "rpa/rpadbex.h"
27 #include "rpagrep.h"
28 #include "rpagrepdep.h"
29
30 rpa_buffer_t * rpa_buffer_from_wchar(const wchar_t *wstr);
31
32
33 int usage(int argc, const wchar_t *argv[])
34 {
35             fwprintf(stderr, L"RPA Grep with RPA Engine: %s \n", rpa_dbex_version());
36                 fwprintf(stderr, L"Copyright (C) 2010 Martin Stoilov\n\n");
37
38                 fwprintf(stderr, L"Usage: \n %s [OPTIONS] <filename>\n", argv[0]);
39                 fwprintf(stderr, L" OPTIONS:\n");
40                 fwprintf(stderr, L"\t-e patterns              BNF Expression.\n");
41                 fwprintf(stderr, L"\t-f patternfile           Read the BNF rules from a file, the last pattern will be executed.\n");
42                 fwprintf(stderr, L"\t-i                       Ignore case.\n");
43                 fwprintf(stderr, L"\t-m                       Match.\n");
44                 fwprintf(stderr, L"\t-p                       Parse.\n");
45                 fwprintf(stderr, L"\t-l                       Line mode.\n");
46                 fwprintf(stderr, L"\t-16                      Force UTF16 encoding.\n");
47                 fwprintf(stderr, L"\t-b                       Force byte encoding.\n");
48                 fwprintf(stderr, L"\t-d                       Dump a production in a tree format.\n");
49                 fwprintf(stderr, L"\t-t                       Display time elapsed.\n");
50                 fwprintf(stderr, L"\t-L, --list-rules         List all patterns.\n");
51                 fwprintf(stderr, L"\t-v                       Display version information.\n");
52                 fwprintf(stderr, L"\t-h, --help               Display this help.\n");
53                 fwprintf(stderr, L"\t    --debug-compile      Display debug compilation information.\n");
54                 fwprintf(stderr, L"\t    --dump-info          Display rules info.\n");
55                 fwprintf(stderr, L"\t    --dump-alias         Display alias info.\n");
56                 fwprintf(stderr, L"\t    --dump-records       Display rules parsing records.\n");
57                 fwprintf(stderr, L"\t    --no-optimizations   Disable optimizations.\n");
58                 fwprintf(stderr, L"\t    --exec-debug         Execute in debug mode.\n");
59                 fwprintf(stderr, L"\t    --dissable-cache     Dissable execution cache.\n");
60         
61                 return 0;
62 }
63
64
65 int wmain(int argc, const wchar_t* argv[])
66 {
67         unsigned long sckb;
68         int ret, scanned = 0, i;
69         rpa_grep_t *pGrep = NULL;
70         DWORD eticks, bticks = GetTickCount();
71         rarray_t *buffers;
72
73         buffers = r_array_create(sizeof(rpa_buffer_t *));
74         pGrep = rpa_grep_create();
75
76         if (argc <= 1) {
77                 usage(argc, argv);
78                 goto end;
79         }
80
81         for (i = 1; i < argc; i++) {
82                 if (wcscmp(argv[i], L"-t") == 0) {
83                         pGrep->showtime = 1;
84                 }
85         }
86
87         for (i = 1; i < argc; i++) {
88                 if (wcscmp(argv[i], L"--help") == 0 || wcscmp(argv[i], L"-help") == 0 || wcscmp(argv[i], L"/?") == 0 || wcscmp(argv[i], L"-h") == 0) {
89                         usage(argc, argv);
90                         goto end;
91                 }
92         }
93         for (i = 1; i < argc; i++) {
94                 if (wcscmp(argv[i], L"-c") == 0) {
95                         if (++i < argc) {
96                                 rpa_buffer_t *pattern = rpa_buffer_from_wchar(argv[i]);
97                                 if (!pattern) {
98                                         goto error;
99                                 }
100                                 rpa_grep_setup_callback(pGrep, pattern);
101                                 rpa_buffer_destroy(pattern);
102                         }
103                 }
104         }
105
106
107         for (i = 1; i < argc; i++) {
108                 if (wcscmp(argv[i], L"-f") == 0) {
109                         if (++i < argc) {
110                                 rpa_buffer_t *pattern = rpa_buffer_map_file(argv[i]);
111                                 if (pattern) {
112                                         ret = rpa_grep_load_pattern(pGrep, pattern);
113                                         r_array_add(buffers, &pattern);
114                                 } else {
115                                         ret = -1;
116                                 }
117                                 if (ret < 0)
118                                         goto error;
119                         }
120                 }
121         }
122
123         for (i = 1; i < argc; i++) {
124                 if (wcscmp(argv[i], L"-e") == 0) {
125                         if (++i < argc) {
126                                 rpa_buffer_t *pattern = rpa_buffer_from_wchar(argv[i]);
127                                 if (!pattern) {
128                                         goto error;
129                                 }
130                                 ret = rpa_grep_load_string_pattern(pGrep, pattern);
131                                 rpa_buffer_destroy(pattern);
132                                 if (ret < 0)
133                                         goto error;
134
135                         }
136                 } 
137         }
138
139
140         for (i = 1; i < argc; i++) {
141                 if (wcscmp(argv[i], L"--dump-code") == 0) {
142                         if (rpa_dbex_compile(pGrep->hDbex) == 0) {
143                                 if (++i < argc) {
144                                         rpa_dbex_dumpcode(pGrep->hDbex, rpa_dbex_lookup_s(pGrep->hDbex, argv[i]));
145                                 }
146                         }
147                         goto end;
148                 }
149         }
150
151
152         for (i = 1; i < argc; i++) {
153                 if (wcscmp(argv[i], L"--dump-info") == 0) {
154                         rpa_grep_dump_pattern_info(pGrep);
155                         goto end;
156                 }
157         }
158
159         for (i = 1; i < argc; i++) {
160                 if (wcscmp(argv[i], L"--debug-compile") == 0) {
161                         rpa_grep_debug_compile(pGrep);
162                         goto end;
163                 }
164         }
165
166
167         for (i = 1; i < argc; i++) {
168                 if (wcscmp(argv[i], L"--dump-alias") == 0) {
169                         rpa_grep_dump_alias_info(pGrep);
170                         goto end;
171                 }
172         }
173
174         for (i = 1; i < argc; i++) {
175                 if (wcscmp(argv[i], L"--dump-records") == 0) {
176                         rpa_grep_dump_pattern_records(pGrep);
177                         goto end;
178                 }
179         }
180
181         for (i = 1; i < argc; i++) {
182                 if (wcscmp(argv[i], L"--exec-debug") == 0) {
183                         pGrep->execdebug = 1;
184                 }
185         }
186
187         for (i = 1; i < argc; i++) {
188                 if (wcscmp(argv[i], L"--dissable-cache") == 0) {
189                         pGrep->disablecache = 1;
190                 }
191         }
192
193
194         if (rpa_dbex_compile(pGrep->hDbex) < 0) {
195                 rpa_errinfo_t errinfo;
196                 rpa_dbex_lasterrorinfo(pGrep->hDbex, &errinfo);
197                 if (errinfo.code == RPA_E_UNRESOLVEDSYMBOL) {
198                         fprintf(stdout, "ERROR: Unresolved Symbol: %s\n", errinfo.name);
199                 } else {
200                         fprintf(stdout, "ERROR %ld: Compilation failed.\n", errinfo.code);
201                 }
202                 goto end;
203         }
204
205
206         for (i = 1; i < argc; i++) {
207                 if (wcscmp(argv[i], L"-L") == 0) {
208                         rpa_grep_list_patterns(pGrep);
209                         goto end;
210                 } else if (wcscmp(argv[i], L"-d") == 0) {
211                         if (++i < argc) {
212                                 rpa_buffer_t *pattern = rpa_buffer_from_wchar(argv[i]);
213                                 if (!pattern) {
214                                         goto error;
215                                 }
216                                 rpa_grep_dump_pattern_tree(pGrep, pattern);
217                                 rpa_buffer_destroy(pattern);
218                                 goto end;
219                         }
220                 } else if (wcscmp(argv[i], L"-i") == 0) {
221                         pGrep->icase = 1;
222                 } else if (wcscmp(argv[i], L"-l") == 0) {
223                         pGrep->greptype = RPA_GREPTYPE_SCANLINES;
224                 } else if (wcscmp(argv[i], L"-m") == 0) {
225                         pGrep->greptype = RPA_GREPTYPE_MATCH;
226                 } else if (wcscmp(argv[i], L"-p") == 0) {
227                         pGrep->greptype = RPA_GREPTYPE_PARSE;
228                 } else if (wcscmp(argv[i], L"-a") == 0) {
229                         pGrep->greptype = RPA_GREPTYPE_PARSEAST;
230                 } else if (wcscmp(argv[i], L"-16") == 0) {
231                         pGrep->forceEncoding = RPA_GREP_FORCE_UTF16;
232                 } else if (wcscmp(argv[i], L"-b") == 0) {
233                         pGrep->forceEncoding = RPA_GREP_FORCE_BYTE;
234                 }
235                 
236         }
237
238
239         for (i = 1; i < argc; i++) {
240                 if (wcscmp(argv[i], L"-s") == 0) {
241                         if (++i < argc) {
242                                 rpa_buffer_t *buf = rpa_buffer_from_wchar(argv[i]);
243                                 rpa_grep_scan_buffer(pGrep, buf);
244                                 rpa_buffer_destroy(buf);
245                                 ++scanned;
246                         }
247                 }
248         }
249
250         /* scan files */
251         for (i = 1; i < argc; i++) {
252                 if (argv[i][0] != L'-') {
253                         ++scanned;
254                         rpa_grep_scan_path(pGrep, argv[i]);
255                 } else if (argv[i][1] == L'e' || argv[i][1] == L'f' || argv[i][1] == L'c' || argv[i][1] == L'C'){
256                         ++i;
257                 }
258                 
259         }
260
261         if (!scanned) {
262                 rpa_buffer_t *buf = rpa_buffer_loadfile(stdin);
263                 if (buf) {
264                         rpa_grep_scan_buffer(pGrep, buf);
265                         rpa_buffer_destroy(buf);
266                 }
267         }
268
269
270         /* scan files */
271         for (i = 1; i < argc; i++) {
272                 if (argv[i][0] != '-') {
273                         ++scanned;
274                         rpa_grep_scan_path(pGrep, argv[i]);
275                 } else if (argv[i][1] == L'e' || argv[i][1] == L'f' || argv[i][1] == L'c'){
276                         ++i;
277                 }
278                 
279         }
280
281         if (!scanned) {
282                 rpa_buffer_t *buf = rpa_buffer_loadfile(stdin);
283                 if (buf) {
284                         rpa_grep_scan_buffer(pGrep, buf);
285                         rpa_buffer_destroy(buf);
286                 }
287         }
288
289 end:
290         for (i = 0; i < r_array_length(buffers); i++) {
291                 rpa_buffer_destroy(r_array_index(buffers, i, rpa_buffer_t*));
292         }
293         r_object_destroy((robject_t*)buffers);
294         rpa_grep_close(pGrep);
295
296
297         rpa_grep_close(pGrep);
298         sckb = (unsigned long)(pGrep->scsize/1024);
299
300         if (pGrep->showtime) {
301                 unsigned long milsec;
302                 unsigned long minutes;
303                 float sec;
304                 milsec = pGrep->scanmilisec;
305                 if (milsec == 0)
306                         milsec = 1;
307                 minutes = milsec/60000;
308                 sec = (milsec%60000)/1000.0;
309                 fwprintf(stdout, L"\ntime: %0ldm%1.3fs, %ld KB (%ld KB/sec), stack: %ld KB, memory: %ld KB (leaked %ld Bytes), cachehit: %ld \n", 
310                                 minutes, sec, sckb, 1000*sckb/milsec, pGrep->usedstack / 1000, (long)r_debug_get_maxmem()/1000, (long)r_debug_get_allocmem(),
311                                 pGrep->cachehit);
312         }
313
314         rpa_grep_destroy(pGrep);
315         return 0;
316
317 error:
318         rpa_grep_destroy(pGrep);
319         return 1;
320 }