~ubuntu-branches/ubuntu/dapper/asn1c/dapper

« back to all changes in this revision

Viewing changes to libasn1fix/check_fixer.c

  • Committer: Bazaar Package Importer
  • Author(s): W. Borgert
  • Date: 2005-05-28 12:36:42 UTC
  • Revision ID: james.westby@ubuntu.com-20050528123642-3h6kstws5u0xcovl
Tags: upstream-0.9.14
ImportĀ upstreamĀ versionĀ 0.9.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#undef  NDEBUG
 
2
#include "asn1fix_internal.h"
 
3
 
 
4
#ifdef  WIN32
 
5
#include <io.h>
 
6
#include <direct.h>
 
7
#define chdir _chdir
 
8
#else
 
9
#include <dirent.h>
 
10
#include <sysexits.h>
 
11
#endif
 
12
#include <errno.h>
 
13
 
 
14
#include "asn1fix.h"
 
15
 
 
16
static int check(const char *fname,
 
17
        enum asn1p_flags parser_flags,
 
18
        enum asn1f_flags fixer_flags);
 
19
static int post_fix_check(asn1p_t *asn);
 
20
static int post_fix_check_element(asn1p_module_t *mod, asn1p_expr_t *expr);
 
21
 
 
22
int
 
23
main(int ac, char **av) {
 
24
#ifdef  WIN32
 
25
        intptr_t dir;
 
26
        struct _finddata_t c_file;
 
27
#else
 
28
        struct dirent *dp;
 
29
        DIR *dir;
 
30
#endif
 
31
        int failed = 0;
 
32
        int completed = 0;
 
33
        enum asn1p_flags parser_flags = A1P_NOFLAGS;
 
34
        enum asn1f_flags fixer_flags  = A1F_NOFLAGS;
 
35
        const char *filename;
 
36
        size_t len;
 
37
        int ret;
 
38
 
 
39
        /*
 
40
         * Just in case when one decides that some flags better be
 
41
         * enabled during `ASN1_FIXER_FLAGS=1 make check` or some
 
42
         * similar usage.
 
43
         */
 
44
        if(getenv("ASN1_PARSER_FLAGS"))
 
45
                parser_flags = atoi(getenv("ASN1_PARSER_FLAGS"));
 
46
        if(getenv("ASN1_FIXER_FLAGS"))
 
47
                fixer_flags = atoi(getenv("ASN1_FIXER_FLAGS"));
 
48
 
 
49
        /*
 
50
         * Go into a directory with tests.
 
51
         */
 
52
        if(ac <= 1) {
 
53
                fprintf(stderr, "Testing in ./tests...\n");
 
54
                ret = chdir("../tests");
 
55
                assert(ret == 0);
 
56
#ifdef  WIN32
 
57
                dir = _findfirst("*.asn1", &c_file);
 
58
                assert(dir != -1L);
 
59
#else
 
60
                dir = opendir(".");
 
61
                assert(dir);
 
62
#endif  /* WIN32 */
 
63
        } else {
 
64
                dir = 0;
 
65
        }
 
66
 
 
67
        /*
 
68
         * Scan every *.asn1 file and try to parse and fix it.
 
69
         */
 
70
        if(dir) {
 
71
#ifdef  WIN32
 
72
                do {
 
73
                        filename = c_file.name;
 
74
#else
 
75
                while((dp = readdir(dir))) {
 
76
                        filename = dp->d_name;
 
77
#endif  /* WIN32 */
 
78
                        len = strlen(filename);
 
79
                        if(len && strcmp(filename + len - 5, ".asn1") == 0) {
 
80
                                ret = check(filename, parser_flags,fixer_flags);
 
81
                                if(ret) {
 
82
                                        fprintf(stderr, "FAILED: %s\n",
 
83
                                                filename);
 
84
                                        failed++;
 
85
                                }
 
86
                                completed++;
 
87
                        }
 
88
#ifdef  WIN32
 
89
                } while(_findnext(dir, &c_file) == 0);
 
90
                _findclose(dir);
 
91
#else
 
92
                }
 
93
                closedir(dir);
 
94
#endif  /* WIN32 */
 
95
 
 
96
 
 
97
                fprintf(stderr,
 
98
                        "Tests COMPLETED: %d\n"
 
99
                        "Tests FAILED:    %d\n"
 
100
                        ,
 
101
                        completed, failed
 
102
                );
 
103
        } else {
 
104
                int i;
 
105
                for(i = 1; i < ac; i++) {
 
106
                        ret = check(av[i], parser_flags, fixer_flags);
 
107
                        if(ret) {
 
108
                                fprintf(stderr, "FAILED: %s\n", av[i]);
 
109
                                failed++;
 
110
                        }
 
111
                        completed++;
 
112
                }
 
113
        }
 
114
 
 
115
        if(completed == 0) {
 
116
                fprintf(stderr, "No tests defined?!\n");
 
117
                exit(EX_NOINPUT);
 
118
        }
 
119
 
 
120
        if(failed)
 
121
                exit(EX_DATAERR);
 
122
        return 0;
 
123
}
 
124
 
 
125
static int
 
126
check(const char *fname,
 
127
                enum asn1p_flags parser_flags,
 
128
                enum asn1f_flags fixer_flags) {
 
129
        asn1p_t *asn;
 
130
        int expected_parseable;         /* Is it expected to be parseable? */
 
131
        int expected_fix_code;          /* What code a fixer must return */
 
132
        int r_value = 0;
 
133
 
 
134
        /*
 
135
         * Figure out how the processing should go by inferring
 
136
         * expectations from the file name.
 
137
         */
 
138
        if(strstr(fname, "-OK.")) {
 
139
                expected_parseable = 1;
 
140
                expected_fix_code  = 0;
 
141
        } else if(strstr(fname, "-NP.")) {
 
142
                expected_parseable = 0;
 
143
                expected_fix_code  = 123;       /* Does not matter */
 
144
        } else if(strstr(fname, "-SE.")) {
 
145
                expected_parseable = 1;
 
146
                expected_fix_code  = -1;        /* Semantically incorrect */
 
147
        } else if(strstr(fname, "-SW.")) {
 
148
                expected_parseable = 1;
 
149
                expected_fix_code  = 1; /* Semantically suspicious */
 
150
        } else {
 
151
                fprintf(stderr, "%s: Invalid file name format\n", fname);
 
152
                return -1;
 
153
        }
 
154
 
 
155
        fprintf(stderr, "[=> %s]\n", fname);
 
156
 
 
157
        /*
 
158
         * Perform low-level parsing.
 
159
         */
 
160
        if(!expected_parseable)
 
161
                fprintf(stderr, "Expecting error...\n");
 
162
        asn = asn1p_parse_file(fname, parser_flags);
 
163
        if(asn == NULL) {
 
164
                if(expected_parseable) {
 
165
                        fprintf(stderr, "Cannot parse file \"%s\"\n", fname);
 
166
                        r_value = -1;
 
167
                } else {
 
168
                        fprintf(stderr,
 
169
                                "Previous error is EXPECTED, no worry\n");
 
170
                }
 
171
        } else if(!expected_parseable) {
 
172
                fprintf(stderr,
 
173
                        "The file \"%s\" is not expected to be parseable, "
 
174
                        "yet parsing was successfull!\n", fname);
 
175
                r_value = -1;
 
176
        }
 
177
 
 
178
        /*
 
179
         * Perform semantical checks and fixes.
 
180
         */
 
181
        if(asn && r_value == 0) {
 
182
                int ret;
 
183
 
 
184
                if(expected_fix_code)
 
185
                        fprintf(stderr, "Expecting some problems...\n");
 
186
 
 
187
                ret = asn1f_process(asn, fixer_flags, 0);
 
188
                if(ret) {
 
189
                        if(ret == expected_fix_code) {
 
190
                                fprintf(stderr,
 
191
                                        "Previous error is EXPECTED, "
 
192
                                        "no worry\n");
 
193
                        } else {
 
194
                                fprintf(stderr,
 
195
                                        "Cannot process file \"%s\": %d\n",
 
196
                                        fname, ret);
 
197
                                r_value = -1;
 
198
                }
 
199
                } else if(ret != expected_fix_code) {
 
200
                        fprintf(stderr,
 
201
                                "File \"%s\" is expected "
 
202
                                "to be semantically incorrect, "
 
203
                                "yet processing was successful!\n",
 
204
                                fname);
 
205
                        r_value = -1;
 
206
                }
 
207
        }
 
208
 
 
209
        /*
 
210
         * Check validity of some values, if grammar has special
 
211
         * instructions for that.
 
212
         */
 
213
        if(asn && r_value == 0) {
 
214
                if(post_fix_check(asn))
 
215
                        r_value = -1;
 
216
        }
 
217
 
 
218
        /*
 
219
         * TODO: destroy the asn.
 
220
         */
 
221
 
 
222
        return r_value;
 
223
}
 
224
 
 
225
 
 
226
static int
 
227
post_fix_check(asn1p_t *asn) {
 
228
        asn1p_module_t *mod;
 
229
        asn1p_expr_t *expr;
 
230
        int r_value = 0;
 
231
 
 
232
        TQ_FOR(mod, &(asn->modules), mod_next) {
 
233
                TQ_FOR(expr, &(mod->members), next) {
 
234
                        assert(expr->Identifier);
 
235
                        if(strncmp(expr->Identifier, "check-", 6) == 0) {
 
236
                                if(post_fix_check_element(mod, expr))
 
237
                                        r_value = -1;
 
238
                        }
 
239
                }
 
240
        }
 
241
 
 
242
        return r_value;
 
243
}
 
244
 
 
245
 
 
246
static int
 
247
post_fix_check_element(asn1p_module_t *mod, asn1p_expr_t *check_expr) {
 
248
        asn1p_expr_t *expr = NULL;
 
249
        char *name;
 
250
        asn1p_value_t *value;
 
251
 
 
252
        if(check_expr->expr_type != ASN_BASIC_INTEGER
 
253
        || check_expr->meta_type != AMT_VALUE) {
 
254
                fprintf(stderr,
 
255
                        "CHECKER: Unsupported type of \"%s\" value: "
 
256
                        "%d at line %d of %s\n",
 
257
                        check_expr->Identifier,
 
258
                        check_expr->expr_type,
 
259
                        check_expr->_lineno,
 
260
                        mod->source_file_name
 
261
                );
 
262
                return -1;
 
263
        }
 
264
 
 
265
        assert(check_expr->meta_type == AMT_VALUE);
 
266
 
 
267
        value = check_expr->value;
 
268
        if(value == NULL || value->type != ATV_INTEGER) {
 
269
                fprintf(stderr,
 
270
                        "CHECKER: Unsupported value type of \"%s\": "
 
271
                        "%d at line %d of %s\n",
 
272
                        check_expr->Identifier,
 
273
                        value?(signed)value->type:-1,
 
274
                        expr->_lineno,
 
275
                        mod->source_file_name
 
276
                );
 
277
                return -1;
 
278
        }
 
279
 
 
280
        name = check_expr->Identifier + sizeof("check-") - 1;
 
281
 
 
282
        /*
 
283
         * Scan in search for the original.
 
284
         */
 
285
        TQ_FOR(expr, &(mod->members), next) {
 
286
                if(strcmp(expr->Identifier, name) == 0)
 
287
                        break;
 
288
        }
 
289
 
 
290
        if(expr == NULL) {
 
291
                fprintf(stderr,
 
292
                        "CHECKER: Value \"%s\" requested by "
 
293
                        "\"check-%s\" at line %d of %s is not found!\n",
 
294
                        name, name, check_expr->_lineno,
 
295
                        mod->source_file_name
 
296
                );
 
297
                return -1;
 
298
        }
 
299
 
 
300
        if(0 && expr->expr_type != check_expr->expr_type) {
 
301
                fprintf(stderr,
 
302
                        "CHECKER: Value type of \"%s\" (=%d) at line %d "
 
303
                        "does not have desired type %d as requested by "
 
304
                        "\"check-%s\" in %s\n",
 
305
                        expr->Identifier,
 
306
                        expr->expr_type,
 
307
                        expr->_lineno,
 
308
                        check_expr->expr_type,
 
309
                        name,
 
310
                        mod->source_file_name
 
311
                );
 
312
                return -1;
 
313
        }
 
314
 
 
315
        if(expr->value == NULL
 
316
        || expr->value->type != value->type) {
 
317
                fprintf(stderr,
 
318
                        "CHECKER: Value of \"%s\" (\"%s\", type=%d) at line %d "
 
319
                        "does not have desired type %d as requested by "
 
320
                        "\"check-%s\" in %s\n",
 
321
                        expr->Identifier,
 
322
                        asn1f_printable_value(expr->value),
 
323
                        expr->value->type,
 
324
                        expr->_lineno,
 
325
                        value->type,
 
326
                        name,
 
327
                        mod->source_file_name
 
328
                );
 
329
                return -1;
 
330
        }
 
331
 
 
332
        assert(value->type = ATV_INTEGER);
 
333
 
 
334
        return 0;
 
335
}
 
336
 
 
337