]> git.mxchange.org Git - flightgear.git/blob - utils/xmlgrep/xmlgrep.cxx
- GPL license block
[flightgear.git] / utils / xmlgrep / xmlgrep.cxx
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include <simgear/props/props.hxx>
7 #include <simgear/props/props_io.hxx>
8 #include <simgear/structure/exception.hxx>
9
10
11 unsigned int _fcount = 0;
12 char **_filenames = 0;
13 char *_element = 0;
14 char *_value = 0;
15 char *_root = 0;
16 char *_print = 0;
17
18 int print_filenames = 0;
19
20 #define DEBUG 0
21
22 void free_and_exit(int i);
23
24
25 #define SHOW_NOVAL(opt) \
26 { \
27    printf("option '%s' requires a value\n\n", (opt)); \
28    free_and_exit(-1); \
29 }
30
31 void show_help ()
32 {
33   printf("usage: xmlgrep [options] [file ...]\n\n");
34   printf("Options:\n");
35   printf("\t-h\t\tshow this help message\n");
36   printf("\t-e <id>\t\tshow sections that contain this element\n");
37   printf("\t-p <id>\t\tprint this element as the output\n");
38   printf("\t-r <path>\tspecify the XML search root\n");
39   printf("\t-v <string>\tshow sections where on of the elements has this value \n");
40   printf("\n");
41   printf(" To print the contents of the 'type' element of the XML section ");
42   printf("that begins\n at '/printer/output' one would use the following ");
43   printf("syntax:\n\n\txmlgrep -r /printer/output -p type sample.xml\n\n");
44   printf(" To filter out sections that contain the 'driver' element with ");
45   printf("'generic' as\n it's value one would issue the following command:\n");
46   printf("\n\txmlgrep -r /printer/output -e driver -v generic -p type ");
47   printf("sample.xml\n\n");
48   free_and_exit(0);
49 }
50
51 void free_and_exit(int i)
52 {
53    if (_root) free(_root);
54    if (_value) free(_value);
55    if (_element) free(_element);
56    if (_filenames)
57    {
58       for (i=0; i < _fcount; i++) {
59          if (_filenames[i]) {
60             if (print_filenames) printf("%s\n", _filenames[i]);
61             free(_filenames[i]);
62          }
63       }
64       free(_filenames);
65    }
66
67    exit(i);
68 }
69
70 int parse_option(char **args, int n, int max) {
71   char *opt, *arg = 0;
72   int sz;
73
74   opt = args[n];
75   if (opt[0] == '-' && opt[1] == '-')
76     opt++;
77
78   if ((arg = strchr(opt, '=')) != NULL)
79     *arg++ = 0;
80
81   else if (++n < max)
82   {
83     arg = args[n];
84     if (arg && arg[0] == '-')
85       arg = 0;
86   }
87
88 #if DEBUG
89     fprintf(stderr, "processing '%s'='%s'\n", opt, arg ? arg : "NULL");
90 #endif
91
92   sz = strlen(opt);
93   if (strncmp(opt, "-help", sz) == 0) {
94     show_help();
95   }
96
97   else if (strncmp(opt, "-root", sz) == 0) {
98     if (arg == 0) SHOW_NOVAL(opt);
99     _root = strdup(arg);
100 #if DEBUG
101     fprintf(stderr, "\troot=%s\n", _root);
102 #endif
103     return 2;
104   }
105
106   else if (strncmp(opt, "-element", sz) == 0) {
107     if (arg == 0) SHOW_NOVAL(opt);
108     _element = strdup(arg);
109 #if DEBUG
110     fprintf(stderr, "\telement=%s\n", _element);
111 #endif
112     return 2;
113   }
114
115   else if (strncmp(opt, "-value", sz) == 0) {
116     if (arg == 0) SHOW_NOVAL(opt);
117     _value = strdup(arg);
118 #if DEBUG
119     fprintf(stderr, "\tvalue=%s\n", _value);
120 #endif
121     return 2;
122   }
123
124   else if (strncmp(opt, "-print", sz) == 0) {
125     if (arg == 0) SHOW_NOVAL(opt);
126     _print = strdup(arg);
127 #if DEBUG
128     fprintf(stderr, "\tprint=%s\n", _print);
129 #endif
130     return 2;
131   }
132
133
134   /* undocumented test argument */
135   else if (strncmp(opt, "-list-filenames", sz) == 0) {
136     print_filenames = 1;
137     return 1;
138   }
139
140   else if (opt[0] == '-') {
141     printf("Unknown option %s\n", opt);
142     free_and_exit(-1);
143   }
144
145   else {
146     int pos = _fcount++;
147     if (_filenames == 0)
148       _filenames = (char **)malloc(sizeof(char*));
149     else {
150       char **ptr = (char **)realloc(_filenames, _fcount*sizeof(char*));
151       if (ptr == 0) {
152          printf("Out of memory.\n\n");
153          free_and_exit(-1);
154       }
155       _filenames = ptr;
156     }
157
158     _filenames[pos] = strdup(opt);
159 #if DEBUG
160     fprintf(stderr, "\tadding filenames[%i]='%s'\n", pos, _filenames[pos]);
161 #endif
162   }
163
164   return 1;
165 }
166
167 void grep_file(unsigned num)
168 {
169    SGPropertyNode root, *path;
170
171 #if DEBUG
172    fprintf(stderr, "Reading filenames[%i]: %s ... ", num, _filenames[num]);
173 #endif
174    try {
175       readProperties(_filenames[num], &root);
176    } catch (const sg_exception &e) {
177       fprintf(stderr, "Error reading file '%s'\n", _filenames[num]);
178       // free_and_exit(-1);
179       return;
180    }
181 #if DEBUG
182    fprintf(stderr, "done.\n");
183 #endif
184
185    if ((path = root.getNode(_root, false)) != NULL)
186    {
187       SGPropertyNode *elem;
188
189       if (_element && _value)
190       {
191          if ((elem = path->getNode(_element, false)) != NULL)
192          {
193             if (strcmp(elem->getStringValue(), _value) == NULL)
194             {
195                SGPropertyNode *print = path->getNode(_print, false);
196                if (print)
197                {
198                   printf("%s: <%s>%s</%s>\n", _filenames[num],
199                                    _print, print->getStringValue(), _print);
200                }
201             }
202          }
203       }
204       else if (_element)
205       {
206       }
207       else if (_value)
208       {
209       }
210    }
211 #if DEBUG
212    else
213       fprintf(stderr," No root node specified.\n");
214 #endif
215 }
216
217 inline void grep_files()
218 {
219 #if DEBUG
220    fprintf(stderr, "Reading files ...\n");
221 #endif
222    for (int i=0; i<_fcount; i++)
223       grep_file(i);
224 }
225
226 int
227 main (int argc, char **argv)
228 {
229    int i;
230
231    if (argc == 1)
232       show_help();
233
234    for (i=1; i<argc;)
235    {
236       int ret = parse_option(argv, i, argc);
237       i += ret;
238 #if DEBUG
239       fprintf(stderr, "%i arguments processed.\n", ret);
240 #endif
241    }
242
243
244    grep_files();
245
246    free_and_exit(0);
247
248    return 0;
249 }