2 #include "asn1fix_internal.h"
17 #include "asn1_buffer.h"
18 #include "asn1_namespace.h"
21 #define TOP_SRCDIR_S ".."
23 #define STRINGIFY_MACRO2(x) #x
24 #define STRINGIFY_MACRO(x) STRINGIFY_MACRO2(x)
25 #define TOP_SRCDIR_S STRINGIFY_MACRO(TOP_SRCDIR)
28 static int check(const char *fname,
29 enum asn1p_flags parser_flags,
30 enum asn1f_flags fixer_flags);
31 static int post_fix_check(asn1p_t *asn);
32 static int post_fix_check_element(asn1p_module_t *mod, asn1p_expr_t *expr);
35 main(int ac, char **av) {
38 struct _finddata_t c_file;
45 enum asn1p_flags parser_flags = A1P_NOFLAGS;
46 enum asn1f_flags fixer_flags = A1F_NOFLAGS;
51 * Just in case when one decides that some flags better be
52 * enabled during `ASN1_FIXER_FLAGS=1 make check` or some
55 if(getenv("ASN1_PARSER_FLAGS"))
56 parser_flags = atoi(getenv("ASN1_PARSER_FLAGS"));
57 if(getenv("ASN1_FIXER_FLAGS"))
58 fixer_flags = atoi(getenv("ASN1_FIXER_FLAGS"));
61 * Go into a directory with tests.
64 abuf *asn1_tests_dirname = abuf_new();
65 const char *top_srcdir = getenv("top_srcdir");
66 if(!top_srcdir) top_srcdir = TOP_SRCDIR_S;
68 abuf_printf(asn1_tests_dirname, "%s/tests/tests-asn1c-compiler",
71 fprintf(stderr, "Testing in %s...\n", top_srcdir);
72 int ret = chdir(asn1_tests_dirname->buffer);
74 fprintf(stderr, "%s: %s\n", asn1_tests_dirname->buffer,
77 /* For some reasons, tests could be hidden under extra tests dir. */
79 dir = _findfirst("*.asn1", &c_file);
90 * Scan every *.asn1 file and try to parse and fix it.
95 filename = c_file.name;
97 while((dp = readdir(dir))) {
98 filename = dp->d_name;
100 len = strlen(filename);
101 if(len <= 5 || !isdigit(filename[0])
102 || strcmp(filename + len - 5, ".asn1"))
104 int ret = check(filename, parser_flags, fixer_flags);
106 fprintf(stderr, "FAILED: %s\n", filename);
111 } while(_findnext(dir, &c_file) == 0);
120 "Tests COMPLETED: %d\n"
121 "Tests FAILED: %d\n",
124 for(int i = 1; i < ac; i++) {
125 int ret = check(av[i], parser_flags, fixer_flags);
127 fprintf(stderr, "FAILED: %s\n", av[i]);
135 fprintf(stderr, "No tests defined?!\n");
146 check(const char *fname,
147 enum asn1p_flags parser_flags,
148 enum asn1f_flags fixer_flags) {
150 int expected_parseable; /* Is it expected to be parseable? */
151 int expected_fix_code; /* What code a fixer must return */
155 * Figure out how the processing should go by inferring
156 * expectations from the file name.
158 if(strstr(fname, "-OK.")) {
159 expected_parseable = 1;
160 expected_fix_code = 0;
161 } else if(strstr(fname, "-NP.")) {
162 expected_parseable = 0;
163 expected_fix_code = 123; /* Does not matter */
164 } else if(strstr(fname, "-SE.")) {
165 expected_parseable = 1;
166 expected_fix_code = -1; /* Semantically incorrect */
167 } else if(strstr(fname, "-SW.")) {
168 expected_parseable = 1;
169 expected_fix_code = 1; /* Semantically suspicious */
171 fprintf(stderr, "%s: Invalid file name format\n", fname);
176 if(strstr(fname, "-blessSize-"))
177 fixer_flags |= A1F_EXTENDED_SizeConstraint;
179 fprintf(stderr, "[=> %s]\n", fname);
182 * Perform low-level parsing.
184 if(!expected_parseable)
185 fprintf(stderr, "Expecting error...\n");
186 asn = asn1p_parse_file(fname, parser_flags);
188 if(expected_parseable) {
189 fprintf(stderr, "Cannot parse file \"%s\"\n", fname);
193 "Previous error is EXPECTED, no worry\n");
195 } else if(!expected_parseable) {
197 "The file \"%s\" is not expected to be parseable, "
198 "yet parsing was successfull!\n", fname);
201 if(!asn) return r_value;
204 char *fname_copy = strdup(fname);
205 char *test_dir = dirname(fname_copy);
206 abuf *skeletons_dirname = abuf_new();
209 abuf_printf(skeletons_dirname,
210 "%s/../../skeletons/standard-modules/"
211 "ASN1C-UsefulInformationObjectClasses.asn1",
215 std_asn = asn1p_parse_file(skeletons_dirname->buffer, A1P_NOFLAGS);
218 while((mod = TQ_REMOVE(&(std_asn->modules), mod_next))) {
219 mod->_tags |= MT_STANDARD_MODULE;
220 TQ_ADD(&(asn->modules), mod, mod_next);
222 asn1p_delete(std_asn);
224 /* Allow referencing imported modules. */
225 asn1f_use_standard_namespaces(asn);
227 fprintf(stderr, "%s: %s\n", skeletons_dirname->buffer,
231 abuf_free(skeletons_dirname);
235 * Perform semantical checks and fixes.
240 if(expected_fix_code)
241 fprintf(stderr, "Expecting some problems...\n");
243 ret = asn1f_process(asn, fixer_flags, 0);
245 if(ret == expected_fix_code) {
247 "Previous error is EXPECTED, "
251 "Cannot process file \"%s\": %d\n",
255 } else if(ret != expected_fix_code) {
257 "File \"%s\" is expected "
258 "to be semantically incorrect, "
259 "yet processing was successful!\n",
266 * Check validity of some values, if grammar has special
267 * instructions for that.
270 if(post_fix_check(asn))
277 #ifdef CLEAN_EVERYTHING
286 post_fix_check(asn1p_t *asn) {
291 TQ_FOR(mod, &(asn->modules), mod_next) {
292 TQ_FOR(expr, &(mod->members), next) {
293 assert(expr->Identifier);
294 if(strncmp(expr->Identifier, "check-", 6) == 0) {
295 if(post_fix_check_element(mod, expr))
306 post_fix_check_element(asn1p_module_t *mod, asn1p_expr_t *check_expr) {
307 asn1p_expr_t *expr = NULL;
309 asn1p_value_t *value;
311 if(check_expr->expr_type != ASN_BASIC_INTEGER
312 || check_expr->meta_type != AMT_VALUE) {
314 "CHECKER: Unsupported type of \"%s\" value: "
315 "%d at line %d of %s\n",
316 check_expr->Identifier,
317 check_expr->expr_type,
319 mod->source_file_name
324 assert(check_expr->meta_type == AMT_VALUE);
326 value = check_expr->value;
327 if(value == NULL || value->type != ATV_INTEGER) {
329 "CHECKER: Unsupported value type of \"%s\": "
330 "%d at line %d of %s\n",
331 check_expr->Identifier,
332 value?(signed)value->type:-1,
334 mod->source_file_name
339 name = check_expr->Identifier + sizeof("check-") - 1;
342 * Scan in search for the original.
344 expr = genhash_get(mod->members_hash, name);
347 "CHECKER: Value \"%s\" requested by "
348 "\"check-%s\" at line %d of %s is not found!\n",
349 name, name, check_expr->_lineno,
350 mod->source_file_name
355 if(0 && expr->expr_type != check_expr->expr_type) {
357 "CHECKER: Value type of \"%s\" (=%d) at line %d "
358 "does not have desired type %d as requested by "
359 "\"check-%s\" in %s\n",
363 check_expr->expr_type,
365 mod->source_file_name
370 if(expr->value == NULL
371 || expr->value->type != value->type) {
373 "CHECKER: Value of \"%s\" (\"%s\", type=%d) at line %d "
374 "does not have desired type %d as requested by "
375 "\"check-%s\" in %s\n",
377 asn1f_printable_value(expr->value),
382 mod->source_file_name