1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2019-2021 Cyril Hrubis <chrubis@suse.cz> 4f08c3bdfSopenharmony_ci * Copyright (c) 2020 Petr Vorel <pvorel@suse.cz> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci#define _GNU_SOURCE 8f08c3bdfSopenharmony_ci 9f08c3bdfSopenharmony_ci#include <search.h> 10f08c3bdfSopenharmony_ci#include <stdio.h> 11f08c3bdfSopenharmony_ci#include <string.h> 12f08c3bdfSopenharmony_ci#include <libgen.h> 13f08c3bdfSopenharmony_ci#include <ctype.h> 14f08c3bdfSopenharmony_ci#include <unistd.h> 15f08c3bdfSopenharmony_ci#include <errno.h> 16f08c3bdfSopenharmony_ci 17f08c3bdfSopenharmony_ci#include "data_storage.h" 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_ci#define INCLUDE_PATH_MAX 5 20f08c3bdfSopenharmony_ci 21f08c3bdfSopenharmony_cistatic int verbose; 22f08c3bdfSopenharmony_cistatic char *cmdline_includepath[INCLUDE_PATH_MAX]; 23f08c3bdfSopenharmony_cistatic unsigned int cmdline_includepaths; 24f08c3bdfSopenharmony_cistatic char *includepath; 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_ci#define WARN(str) fprintf(stderr, "WARNING: " str "\n") 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_cistatic void oneline_comment(FILE *f) 29f08c3bdfSopenharmony_ci{ 30f08c3bdfSopenharmony_ci int c; 31f08c3bdfSopenharmony_ci 32f08c3bdfSopenharmony_ci do { 33f08c3bdfSopenharmony_ci c = getc(f); 34f08c3bdfSopenharmony_ci } while (c != '\n'); 35f08c3bdfSopenharmony_ci} 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_cistatic const char *eat_asterisk_space(const char *c) 38f08c3bdfSopenharmony_ci{ 39f08c3bdfSopenharmony_ci unsigned int i = 0; 40f08c3bdfSopenharmony_ci 41f08c3bdfSopenharmony_ci while (isspace(c[i])) 42f08c3bdfSopenharmony_ci i++; 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_ci if (c[i] == '*') { 45f08c3bdfSopenharmony_ci if (isspace(c[i+1])) 46f08c3bdfSopenharmony_ci i++; 47f08c3bdfSopenharmony_ci return &c[i+1]; 48f08c3bdfSopenharmony_ci } 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci return c; 51f08c3bdfSopenharmony_ci} 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_cistatic void multiline_comment(FILE *f, struct data_node *doc) 54f08c3bdfSopenharmony_ci{ 55f08c3bdfSopenharmony_ci int c; 56f08c3bdfSopenharmony_ci int state = 0; 57f08c3bdfSopenharmony_ci char buf[4096]; 58f08c3bdfSopenharmony_ci unsigned int bufp = 0; 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_ci for (;;) { 61f08c3bdfSopenharmony_ci c = getc(f); 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_ci if (doc) { 64f08c3bdfSopenharmony_ci if (c == '\n') { 65f08c3bdfSopenharmony_ci struct data_node *line; 66f08c3bdfSopenharmony_ci buf[bufp] = 0; 67f08c3bdfSopenharmony_ci line = data_node_string(eat_asterisk_space(buf)); 68f08c3bdfSopenharmony_ci if (data_node_array_add(doc, line)) 69f08c3bdfSopenharmony_ci WARN("doc string comment truncated"); 70f08c3bdfSopenharmony_ci bufp = 0; 71f08c3bdfSopenharmony_ci continue; 72f08c3bdfSopenharmony_ci } 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_ci if (bufp + 1 >= sizeof(buf)) 75f08c3bdfSopenharmony_ci continue; 76f08c3bdfSopenharmony_ci 77f08c3bdfSopenharmony_ci buf[bufp++] = c; 78f08c3bdfSopenharmony_ci } 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_ci switch (state) { 81f08c3bdfSopenharmony_ci case 0: 82f08c3bdfSopenharmony_ci if (c == '*') 83f08c3bdfSopenharmony_ci state = 1; 84f08c3bdfSopenharmony_ci break; 85f08c3bdfSopenharmony_ci case 1: 86f08c3bdfSopenharmony_ci switch (c) { 87f08c3bdfSopenharmony_ci case '/': 88f08c3bdfSopenharmony_ci return; 89f08c3bdfSopenharmony_ci case '*': 90f08c3bdfSopenharmony_ci continue; 91f08c3bdfSopenharmony_ci default: 92f08c3bdfSopenharmony_ci state = 0; 93f08c3bdfSopenharmony_ci break; 94f08c3bdfSopenharmony_ci } 95f08c3bdfSopenharmony_ci break; 96f08c3bdfSopenharmony_ci } 97f08c3bdfSopenharmony_ci } 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci} 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_cistatic const char doc_prefix[] = "\\\n"; 102f08c3bdfSopenharmony_ci 103f08c3bdfSopenharmony_cistatic void maybe_doc_comment(FILE *f, struct data_node *doc) 104f08c3bdfSopenharmony_ci{ 105f08c3bdfSopenharmony_ci int c, i; 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci for (i = 0; doc_prefix[i]; i++) { 108f08c3bdfSopenharmony_ci c = getc(f); 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci if (c == doc_prefix[i]) 111f08c3bdfSopenharmony_ci continue; 112f08c3bdfSopenharmony_ci 113f08c3bdfSopenharmony_ci if (c == '*') 114f08c3bdfSopenharmony_ci ungetc(c, f); 115f08c3bdfSopenharmony_ci 116f08c3bdfSopenharmony_ci multiline_comment(f, NULL); 117f08c3bdfSopenharmony_ci return; 118f08c3bdfSopenharmony_ci } 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci multiline_comment(f, doc); 121f08c3bdfSopenharmony_ci} 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_cistatic void maybe_comment(FILE *f, struct data_node *doc) 124f08c3bdfSopenharmony_ci{ 125f08c3bdfSopenharmony_ci int c = getc(f); 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_ci switch (c) { 128f08c3bdfSopenharmony_ci case '/': 129f08c3bdfSopenharmony_ci oneline_comment(f); 130f08c3bdfSopenharmony_ci break; 131f08c3bdfSopenharmony_ci case '*': 132f08c3bdfSopenharmony_ci maybe_doc_comment(f, doc); 133f08c3bdfSopenharmony_ci break; 134f08c3bdfSopenharmony_ci default: 135f08c3bdfSopenharmony_ci ungetc(c, f); 136f08c3bdfSopenharmony_ci break; 137f08c3bdfSopenharmony_ci } 138f08c3bdfSopenharmony_ci} 139f08c3bdfSopenharmony_ci 140f08c3bdfSopenharmony_cistatic char *next_token2(FILE *f, char *buf, size_t buf_len, struct data_node *doc) 141f08c3bdfSopenharmony_ci{ 142f08c3bdfSopenharmony_ci size_t i = 0; 143f08c3bdfSopenharmony_ci int c; 144f08c3bdfSopenharmony_ci int in_str = 0; 145f08c3bdfSopenharmony_ci 146f08c3bdfSopenharmony_ci buf_len--; 147f08c3bdfSopenharmony_ci 148f08c3bdfSopenharmony_ci for (;;) { 149f08c3bdfSopenharmony_ci c = fgetc(f); 150f08c3bdfSopenharmony_ci 151f08c3bdfSopenharmony_ci if (c == EOF) 152f08c3bdfSopenharmony_ci goto exit; 153f08c3bdfSopenharmony_ci 154f08c3bdfSopenharmony_ci if (in_str) { 155f08c3bdfSopenharmony_ci if (c == '"') { 156f08c3bdfSopenharmony_ci if (i == 0 || buf[i-1] != '\\') 157f08c3bdfSopenharmony_ci goto exit; 158f08c3bdfSopenharmony_ci } 159f08c3bdfSopenharmony_ci 160f08c3bdfSopenharmony_ci if (i < buf_len) 161f08c3bdfSopenharmony_ci buf[i++] = c; 162f08c3bdfSopenharmony_ci continue; 163f08c3bdfSopenharmony_ci } 164f08c3bdfSopenharmony_ci 165f08c3bdfSopenharmony_ci switch (c) { 166f08c3bdfSopenharmony_ci case '{': 167f08c3bdfSopenharmony_ci case '}': 168f08c3bdfSopenharmony_ci case ';': 169f08c3bdfSopenharmony_ci case '(': 170f08c3bdfSopenharmony_ci case ')': 171f08c3bdfSopenharmony_ci case '=': 172f08c3bdfSopenharmony_ci case ',': 173f08c3bdfSopenharmony_ci case '[': 174f08c3bdfSopenharmony_ci case ']': 175f08c3bdfSopenharmony_ci case '#': 176f08c3bdfSopenharmony_ci if (i) { 177f08c3bdfSopenharmony_ci ungetc(c, f); 178f08c3bdfSopenharmony_ci goto exit; 179f08c3bdfSopenharmony_ci } 180f08c3bdfSopenharmony_ci 181f08c3bdfSopenharmony_ci if (i < buf_len) 182f08c3bdfSopenharmony_ci buf[i++] = c; 183f08c3bdfSopenharmony_ci goto exit; 184f08c3bdfSopenharmony_ci case '0' ... '9': 185f08c3bdfSopenharmony_ci case 'a' ... 'z': 186f08c3bdfSopenharmony_ci case 'A' ... 'Z': 187f08c3bdfSopenharmony_ci case '.': 188f08c3bdfSopenharmony_ci case '_': 189f08c3bdfSopenharmony_ci case '-': 190f08c3bdfSopenharmony_ci buf[i++] = c; 191f08c3bdfSopenharmony_ci break; 192f08c3bdfSopenharmony_ci case '/': 193f08c3bdfSopenharmony_ci maybe_comment(f, doc); 194f08c3bdfSopenharmony_ci break; 195f08c3bdfSopenharmony_ci case '"': 196f08c3bdfSopenharmony_ci in_str = 1; 197f08c3bdfSopenharmony_ci break; 198f08c3bdfSopenharmony_ci case ' ': 199f08c3bdfSopenharmony_ci case '\n': 200f08c3bdfSopenharmony_ci case '\t': 201f08c3bdfSopenharmony_ci if (i) 202f08c3bdfSopenharmony_ci goto exit; 203f08c3bdfSopenharmony_ci break; 204f08c3bdfSopenharmony_ci } 205f08c3bdfSopenharmony_ci } 206f08c3bdfSopenharmony_ci 207f08c3bdfSopenharmony_ciexit: 208f08c3bdfSopenharmony_ci if (i == 0 && !in_str) 209f08c3bdfSopenharmony_ci return NULL; 210f08c3bdfSopenharmony_ci 211f08c3bdfSopenharmony_ci buf[i] = 0; 212f08c3bdfSopenharmony_ci return buf; 213f08c3bdfSopenharmony_ci} 214f08c3bdfSopenharmony_ci 215f08c3bdfSopenharmony_cistatic char *next_token(FILE *f, struct data_node *doc) 216f08c3bdfSopenharmony_ci{ 217f08c3bdfSopenharmony_ci static char buf[4096]; 218f08c3bdfSopenharmony_ci 219f08c3bdfSopenharmony_ci return next_token2(f, buf, sizeof(buf), doc); 220f08c3bdfSopenharmony_ci} 221f08c3bdfSopenharmony_ci 222f08c3bdfSopenharmony_cistatic FILE *open_file(const char *dir, const char *fname) 223f08c3bdfSopenharmony_ci{ 224f08c3bdfSopenharmony_ci FILE *f; 225f08c3bdfSopenharmony_ci char *path; 226f08c3bdfSopenharmony_ci 227f08c3bdfSopenharmony_ci if (asprintf(&path, "%s/%s", dir, fname) < 0) 228f08c3bdfSopenharmony_ci return NULL; 229f08c3bdfSopenharmony_ci 230f08c3bdfSopenharmony_ci f = fopen(path, "r"); 231f08c3bdfSopenharmony_ci 232f08c3bdfSopenharmony_ci free(path); 233f08c3bdfSopenharmony_ci 234f08c3bdfSopenharmony_ci return f; 235f08c3bdfSopenharmony_ci} 236f08c3bdfSopenharmony_ci 237f08c3bdfSopenharmony_cistatic FILE *open_include(FILE *f) 238f08c3bdfSopenharmony_ci{ 239f08c3bdfSopenharmony_ci char buf[256], *fname; 240f08c3bdfSopenharmony_ci FILE *inc; 241f08c3bdfSopenharmony_ci unsigned int i; 242f08c3bdfSopenharmony_ci 243f08c3bdfSopenharmony_ci if (!fscanf(f, "%s\n", buf)) 244f08c3bdfSopenharmony_ci return NULL; 245f08c3bdfSopenharmony_ci 246f08c3bdfSopenharmony_ci if (buf[0] != '"') 247f08c3bdfSopenharmony_ci return NULL; 248f08c3bdfSopenharmony_ci 249f08c3bdfSopenharmony_ci fname = buf + 1; 250f08c3bdfSopenharmony_ci 251f08c3bdfSopenharmony_ci if (!buf[0]) 252f08c3bdfSopenharmony_ci return NULL; 253f08c3bdfSopenharmony_ci 254f08c3bdfSopenharmony_ci fname[strlen(fname)-1] = 0; 255f08c3bdfSopenharmony_ci 256f08c3bdfSopenharmony_ci inc = open_file(includepath, fname); 257f08c3bdfSopenharmony_ci if (inc) { 258f08c3bdfSopenharmony_ci if (verbose) 259f08c3bdfSopenharmony_ci fprintf(stderr, "INCLUDE %s/%s\n", includepath, fname); 260f08c3bdfSopenharmony_ci 261f08c3bdfSopenharmony_ci return inc; 262f08c3bdfSopenharmony_ci } 263f08c3bdfSopenharmony_ci 264f08c3bdfSopenharmony_ci for (i = 0; i < cmdline_includepaths; i++) { 265f08c3bdfSopenharmony_ci inc = open_file(cmdline_includepath[i], fname); 266f08c3bdfSopenharmony_ci 267f08c3bdfSopenharmony_ci if (!inc) 268f08c3bdfSopenharmony_ci continue; 269f08c3bdfSopenharmony_ci 270f08c3bdfSopenharmony_ci if (verbose) { 271f08c3bdfSopenharmony_ci fprintf(stderr, "INCLUDE %s/%s\n", 272f08c3bdfSopenharmony_ci cmdline_includepath[i], fname); 273f08c3bdfSopenharmony_ci } 274f08c3bdfSopenharmony_ci 275f08c3bdfSopenharmony_ci return inc; 276f08c3bdfSopenharmony_ci } 277f08c3bdfSopenharmony_ci 278f08c3bdfSopenharmony_ci return NULL; 279f08c3bdfSopenharmony_ci} 280f08c3bdfSopenharmony_ci 281f08c3bdfSopenharmony_cistatic void close_include(FILE *inc) 282f08c3bdfSopenharmony_ci{ 283f08c3bdfSopenharmony_ci if (verbose) 284f08c3bdfSopenharmony_ci fprintf(stderr, "INCLUDE END\n"); 285f08c3bdfSopenharmony_ci 286f08c3bdfSopenharmony_ci fclose(inc); 287f08c3bdfSopenharmony_ci} 288f08c3bdfSopenharmony_ci 289f08c3bdfSopenharmony_cistatic int parse_array(FILE *f, struct data_node *node) 290f08c3bdfSopenharmony_ci{ 291f08c3bdfSopenharmony_ci const char *token; 292f08c3bdfSopenharmony_ci 293f08c3bdfSopenharmony_ci for (;;) { 294f08c3bdfSopenharmony_ci if (!(token = next_token(f, NULL))) 295f08c3bdfSopenharmony_ci return 1; 296f08c3bdfSopenharmony_ci 297f08c3bdfSopenharmony_ci if (!strcmp(token, "{")) { 298f08c3bdfSopenharmony_ci struct data_node *ret = data_node_array(); 299f08c3bdfSopenharmony_ci parse_array(f, ret); 300f08c3bdfSopenharmony_ci 301f08c3bdfSopenharmony_ci if (data_node_array_len(ret)) 302f08c3bdfSopenharmony_ci data_node_array_add(node, ret); 303f08c3bdfSopenharmony_ci else 304f08c3bdfSopenharmony_ci data_node_free(ret); 305f08c3bdfSopenharmony_ci 306f08c3bdfSopenharmony_ci continue; 307f08c3bdfSopenharmony_ci } 308f08c3bdfSopenharmony_ci 309f08c3bdfSopenharmony_ci if (!strcmp(token, "}")) 310f08c3bdfSopenharmony_ci return 0; 311f08c3bdfSopenharmony_ci 312f08c3bdfSopenharmony_ci if (!strcmp(token, ",")) 313f08c3bdfSopenharmony_ci continue; 314f08c3bdfSopenharmony_ci 315f08c3bdfSopenharmony_ci if (!strcmp(token, "NULL")) 316f08c3bdfSopenharmony_ci continue; 317f08c3bdfSopenharmony_ci 318f08c3bdfSopenharmony_ci struct data_node *str = data_node_string(token); 319f08c3bdfSopenharmony_ci 320f08c3bdfSopenharmony_ci data_node_array_add(node, str); 321f08c3bdfSopenharmony_ci } 322f08c3bdfSopenharmony_ci 323f08c3bdfSopenharmony_ci return 0; 324f08c3bdfSopenharmony_ci} 325f08c3bdfSopenharmony_ci 326f08c3bdfSopenharmony_cistatic void try_apply_macro(char **res) 327f08c3bdfSopenharmony_ci{ 328f08c3bdfSopenharmony_ci ENTRY macro = { 329f08c3bdfSopenharmony_ci .key = *res, 330f08c3bdfSopenharmony_ci }; 331f08c3bdfSopenharmony_ci 332f08c3bdfSopenharmony_ci ENTRY *ret; 333f08c3bdfSopenharmony_ci 334f08c3bdfSopenharmony_ci ret = hsearch(macro, FIND); 335f08c3bdfSopenharmony_ci 336f08c3bdfSopenharmony_ci if (!ret) 337f08c3bdfSopenharmony_ci return; 338f08c3bdfSopenharmony_ci 339f08c3bdfSopenharmony_ci if (verbose) 340f08c3bdfSopenharmony_ci fprintf(stderr, "APPLYING MACRO %s=%s\n", ret->key, (char*)ret->data); 341f08c3bdfSopenharmony_ci 342f08c3bdfSopenharmony_ci *res = ret->data; 343f08c3bdfSopenharmony_ci} 344f08c3bdfSopenharmony_ci 345f08c3bdfSopenharmony_cistatic int parse_get_array_len(FILE *f) 346f08c3bdfSopenharmony_ci{ 347f08c3bdfSopenharmony_ci const char *token; 348f08c3bdfSopenharmony_ci int cnt = 0, depth = 0, prev_comma = 0; 349f08c3bdfSopenharmony_ci 350f08c3bdfSopenharmony_ci if (!(token = next_token(f, NULL))) 351f08c3bdfSopenharmony_ci return 0; 352f08c3bdfSopenharmony_ci 353f08c3bdfSopenharmony_ci if (strcmp(token, "{")) 354f08c3bdfSopenharmony_ci return 0; 355f08c3bdfSopenharmony_ci 356f08c3bdfSopenharmony_ci for (;;) { 357f08c3bdfSopenharmony_ci if (!(token = next_token(f, NULL))) 358f08c3bdfSopenharmony_ci return 0; 359f08c3bdfSopenharmony_ci 360f08c3bdfSopenharmony_ci if (!strcmp(token, "{")) 361f08c3bdfSopenharmony_ci depth++; 362f08c3bdfSopenharmony_ci 363f08c3bdfSopenharmony_ci if (!strcmp(token, "}")) 364f08c3bdfSopenharmony_ci depth--; 365f08c3bdfSopenharmony_ci else 366f08c3bdfSopenharmony_ci prev_comma = 0; 367f08c3bdfSopenharmony_ci 368f08c3bdfSopenharmony_ci if (!strcmp(token, ",") && !depth) { 369f08c3bdfSopenharmony_ci prev_comma = 1; 370f08c3bdfSopenharmony_ci cnt++; 371f08c3bdfSopenharmony_ci } 372f08c3bdfSopenharmony_ci 373f08c3bdfSopenharmony_ci if (depth < 0) 374f08c3bdfSopenharmony_ci return cnt + !prev_comma; 375f08c3bdfSopenharmony_ci } 376f08c3bdfSopenharmony_ci} 377f08c3bdfSopenharmony_ci 378f08c3bdfSopenharmony_cistatic void look_for_array_size(FILE *f, const char *arr_id, struct data_node **res) 379f08c3bdfSopenharmony_ci{ 380f08c3bdfSopenharmony_ci const char *token; 381f08c3bdfSopenharmony_ci char buf[2][2048] = {}; 382f08c3bdfSopenharmony_ci int cur_buf = 0; 383f08c3bdfSopenharmony_ci int prev_buf = 1; 384f08c3bdfSopenharmony_ci 385f08c3bdfSopenharmony_ci for (;;) { 386f08c3bdfSopenharmony_ci if (!(token = next_token2(f, buf[cur_buf], sizeof(buf[cur_buf]), NULL))) 387f08c3bdfSopenharmony_ci break; 388f08c3bdfSopenharmony_ci 389f08c3bdfSopenharmony_ci if (!strcmp(token, "=") && !strcmp(buf[prev_buf], arr_id)) { 390f08c3bdfSopenharmony_ci int arr_len = parse_get_array_len(f); 391f08c3bdfSopenharmony_ci 392f08c3bdfSopenharmony_ci if (verbose) 393f08c3bdfSopenharmony_ci fprintf(stderr, "ARRAY %s LENGTH = %i\n", arr_id, arr_len); 394f08c3bdfSopenharmony_ci 395f08c3bdfSopenharmony_ci *res = data_node_int(arr_len); 396f08c3bdfSopenharmony_ci 397f08c3bdfSopenharmony_ci break; 398f08c3bdfSopenharmony_ci } 399f08c3bdfSopenharmony_ci 400f08c3bdfSopenharmony_ci if (strcmp(buf[cur_buf], "]") && strcmp(buf[cur_buf], "[")) { 401f08c3bdfSopenharmony_ci cur_buf = !cur_buf; 402f08c3bdfSopenharmony_ci prev_buf = !prev_buf; 403f08c3bdfSopenharmony_ci } 404f08c3bdfSopenharmony_ci } 405f08c3bdfSopenharmony_ci} 406f08c3bdfSopenharmony_ci 407f08c3bdfSopenharmony_cistatic int parse_array_size(FILE *f, struct data_node **res) 408f08c3bdfSopenharmony_ci{ 409f08c3bdfSopenharmony_ci const char *token; 410f08c3bdfSopenharmony_ci char *arr_id; 411f08c3bdfSopenharmony_ci long pos; 412f08c3bdfSopenharmony_ci int hash = 0; 413f08c3bdfSopenharmony_ci 414f08c3bdfSopenharmony_ci *res = NULL; 415f08c3bdfSopenharmony_ci 416f08c3bdfSopenharmony_ci if (!(token = next_token(f, NULL))) 417f08c3bdfSopenharmony_ci return 1; 418f08c3bdfSopenharmony_ci 419f08c3bdfSopenharmony_ci if (strcmp(token, "(")) 420f08c3bdfSopenharmony_ci return 1; 421f08c3bdfSopenharmony_ci 422f08c3bdfSopenharmony_ci if (!(token = next_token(f, NULL))) 423f08c3bdfSopenharmony_ci return 1; 424f08c3bdfSopenharmony_ci 425f08c3bdfSopenharmony_ci arr_id = strdup(token); 426f08c3bdfSopenharmony_ci 427f08c3bdfSopenharmony_ci if (verbose) 428f08c3bdfSopenharmony_ci fprintf(stderr, "COMPUTING ARRAY '%s' LENGHT\n", arr_id); 429f08c3bdfSopenharmony_ci 430f08c3bdfSopenharmony_ci pos = ftell(f); 431f08c3bdfSopenharmony_ci 432f08c3bdfSopenharmony_ci rewind(f); 433f08c3bdfSopenharmony_ci 434f08c3bdfSopenharmony_ci look_for_array_size(f, arr_id, res); 435f08c3bdfSopenharmony_ci 436f08c3bdfSopenharmony_ci if (!*res) { 437f08c3bdfSopenharmony_ci FILE *inc; 438f08c3bdfSopenharmony_ci 439f08c3bdfSopenharmony_ci rewind(f); 440f08c3bdfSopenharmony_ci 441f08c3bdfSopenharmony_ci for (;;) { 442f08c3bdfSopenharmony_ci if (!(token = next_token(f, NULL))) 443f08c3bdfSopenharmony_ci break; 444f08c3bdfSopenharmony_ci 445f08c3bdfSopenharmony_ci if (token[0] == '#') { 446f08c3bdfSopenharmony_ci hash = 1; 447f08c3bdfSopenharmony_ci continue; 448f08c3bdfSopenharmony_ci } 449f08c3bdfSopenharmony_ci 450f08c3bdfSopenharmony_ci if (!hash) 451f08c3bdfSopenharmony_ci continue; 452f08c3bdfSopenharmony_ci 453f08c3bdfSopenharmony_ci if (!strcmp(token, "include")) { 454f08c3bdfSopenharmony_ci inc = open_include(f); 455f08c3bdfSopenharmony_ci 456f08c3bdfSopenharmony_ci if (inc) { 457f08c3bdfSopenharmony_ci look_for_array_size(inc, arr_id, res); 458f08c3bdfSopenharmony_ci close_include(inc); 459f08c3bdfSopenharmony_ci } 460f08c3bdfSopenharmony_ci } 461f08c3bdfSopenharmony_ci 462f08c3bdfSopenharmony_ci if (*res) 463f08c3bdfSopenharmony_ci break; 464f08c3bdfSopenharmony_ci } 465f08c3bdfSopenharmony_ci } 466f08c3bdfSopenharmony_ci 467f08c3bdfSopenharmony_ci free(arr_id); 468f08c3bdfSopenharmony_ci 469f08c3bdfSopenharmony_ci if (fseek(f, pos, SEEK_SET)) 470f08c3bdfSopenharmony_ci return 1; 471f08c3bdfSopenharmony_ci 472f08c3bdfSopenharmony_ci return 0; 473f08c3bdfSopenharmony_ci} 474f08c3bdfSopenharmony_ci 475f08c3bdfSopenharmony_cistatic int parse_test_struct(FILE *f, struct data_node *doc, struct data_node *node) 476f08c3bdfSopenharmony_ci{ 477f08c3bdfSopenharmony_ci char *token; 478f08c3bdfSopenharmony_ci char *id = NULL; 479f08c3bdfSopenharmony_ci int state = 0; 480f08c3bdfSopenharmony_ci struct data_node *ret; 481f08c3bdfSopenharmony_ci 482f08c3bdfSopenharmony_ci for (;;) { 483f08c3bdfSopenharmony_ci if (!(token = next_token(f, doc))) 484f08c3bdfSopenharmony_ci return 1; 485f08c3bdfSopenharmony_ci 486f08c3bdfSopenharmony_ci if (!strcmp(token, "}")) 487f08c3bdfSopenharmony_ci return 0; 488f08c3bdfSopenharmony_ci 489f08c3bdfSopenharmony_ci switch (state) { 490f08c3bdfSopenharmony_ci case 0: 491f08c3bdfSopenharmony_ci id = strdup(token); 492f08c3bdfSopenharmony_ci state = 1; 493f08c3bdfSopenharmony_ci continue; 494f08c3bdfSopenharmony_ci case 1: 495f08c3bdfSopenharmony_ci if (!strcmp(token, "=")) 496f08c3bdfSopenharmony_ci state = 2; 497f08c3bdfSopenharmony_ci else 498f08c3bdfSopenharmony_ci WARN("Expected '='"); 499f08c3bdfSopenharmony_ci continue; 500f08c3bdfSopenharmony_ci case 2: 501f08c3bdfSopenharmony_ci if (!strcmp(token, "(")) { 502f08c3bdfSopenharmony_ci state = 3; 503f08c3bdfSopenharmony_ci continue; 504f08c3bdfSopenharmony_ci } 505f08c3bdfSopenharmony_ci break; 506f08c3bdfSopenharmony_ci case 3: 507f08c3bdfSopenharmony_ci if (!strcmp(token, ")")) 508f08c3bdfSopenharmony_ci state = 2; 509f08c3bdfSopenharmony_ci continue; 510f08c3bdfSopenharmony_ci 511f08c3bdfSopenharmony_ci case 4: 512f08c3bdfSopenharmony_ci if (!strcmp(token, ",")) 513f08c3bdfSopenharmony_ci state = 0; 514f08c3bdfSopenharmony_ci continue; 515f08c3bdfSopenharmony_ci } 516f08c3bdfSopenharmony_ci 517f08c3bdfSopenharmony_ci if (!strcmp(token, "{")) { 518f08c3bdfSopenharmony_ci ret = data_node_array(); 519f08c3bdfSopenharmony_ci parse_array(f, ret); 520f08c3bdfSopenharmony_ci } else if (!strcmp(token, "ARRAY_SIZE")) { 521f08c3bdfSopenharmony_ci if (parse_array_size(f, &ret)) 522f08c3bdfSopenharmony_ci return 1; 523f08c3bdfSopenharmony_ci } else { 524f08c3bdfSopenharmony_ci try_apply_macro(&token); 525f08c3bdfSopenharmony_ci ret = data_node_string(token); 526f08c3bdfSopenharmony_ci } 527f08c3bdfSopenharmony_ci 528f08c3bdfSopenharmony_ci if (!ret) 529f08c3bdfSopenharmony_ci continue; 530f08c3bdfSopenharmony_ci 531f08c3bdfSopenharmony_ci const char *key = id; 532f08c3bdfSopenharmony_ci if (key[0] == '.') 533f08c3bdfSopenharmony_ci key++; 534f08c3bdfSopenharmony_ci 535f08c3bdfSopenharmony_ci data_node_hash_add(node, key, ret); 536f08c3bdfSopenharmony_ci free(id); 537f08c3bdfSopenharmony_ci state = 4; 538f08c3bdfSopenharmony_ci } 539f08c3bdfSopenharmony_ci} 540f08c3bdfSopenharmony_ci 541f08c3bdfSopenharmony_cistatic const char *tokens[] = { 542f08c3bdfSopenharmony_ci "static", 543f08c3bdfSopenharmony_ci "struct", 544f08c3bdfSopenharmony_ci "tst_test", 545f08c3bdfSopenharmony_ci "test", 546f08c3bdfSopenharmony_ci "=", 547f08c3bdfSopenharmony_ci "{", 548f08c3bdfSopenharmony_ci}; 549f08c3bdfSopenharmony_ci 550f08c3bdfSopenharmony_cistatic void macro_get_string(FILE *f, char *buf, char *buf_end) 551f08c3bdfSopenharmony_ci{ 552f08c3bdfSopenharmony_ci int c; 553f08c3bdfSopenharmony_ci char *buf_start = buf; 554f08c3bdfSopenharmony_ci 555f08c3bdfSopenharmony_ci for (;;) { 556f08c3bdfSopenharmony_ci c = fgetc(f); 557f08c3bdfSopenharmony_ci 558f08c3bdfSopenharmony_ci switch (c) { 559f08c3bdfSopenharmony_ci case EOF: 560f08c3bdfSopenharmony_ci *buf = 0; 561f08c3bdfSopenharmony_ci return; 562f08c3bdfSopenharmony_ci case '"': 563f08c3bdfSopenharmony_ci if (buf == buf_start || buf[-1] != '\\') { 564f08c3bdfSopenharmony_ci *buf = 0; 565f08c3bdfSopenharmony_ci return; 566f08c3bdfSopenharmony_ci } 567f08c3bdfSopenharmony_ci buf[-1] = '"'; 568f08c3bdfSopenharmony_ci break; 569f08c3bdfSopenharmony_ci default: 570f08c3bdfSopenharmony_ci if (buf < buf_end) 571f08c3bdfSopenharmony_ci *(buf++) = c; 572f08c3bdfSopenharmony_ci } 573f08c3bdfSopenharmony_ci } 574f08c3bdfSopenharmony_ci} 575f08c3bdfSopenharmony_ci 576f08c3bdfSopenharmony_cistatic void macro_get_val(FILE *f, char *buf, size_t buf_len) 577f08c3bdfSopenharmony_ci{ 578f08c3bdfSopenharmony_ci int c, prev = 0; 579f08c3bdfSopenharmony_ci char *buf_end = buf + buf_len - 1; 580f08c3bdfSopenharmony_ci 581f08c3bdfSopenharmony_ci while (isspace(c = fgetc(f))); 582f08c3bdfSopenharmony_ci 583f08c3bdfSopenharmony_ci if (c == '"') { 584f08c3bdfSopenharmony_ci macro_get_string(f, buf, buf_end); 585f08c3bdfSopenharmony_ci return; 586f08c3bdfSopenharmony_ci } 587f08c3bdfSopenharmony_ci 588f08c3bdfSopenharmony_ci for (;;) { 589f08c3bdfSopenharmony_ci switch (c) { 590f08c3bdfSopenharmony_ci case '\n': 591f08c3bdfSopenharmony_ci if (prev == '\\') { 592f08c3bdfSopenharmony_ci buf--; 593f08c3bdfSopenharmony_ci } else { 594f08c3bdfSopenharmony_ci *buf = 0; 595f08c3bdfSopenharmony_ci return; 596f08c3bdfSopenharmony_ci } 597f08c3bdfSopenharmony_ci break; 598f08c3bdfSopenharmony_ci case EOF: 599f08c3bdfSopenharmony_ci *buf = 0; 600f08c3bdfSopenharmony_ci return; 601f08c3bdfSopenharmony_ci case ' ': 602f08c3bdfSopenharmony_ci case '\t': 603f08c3bdfSopenharmony_ci break; 604f08c3bdfSopenharmony_ci default: 605f08c3bdfSopenharmony_ci if (buf < buf_end) 606f08c3bdfSopenharmony_ci *(buf++) = c; 607f08c3bdfSopenharmony_ci } 608f08c3bdfSopenharmony_ci 609f08c3bdfSopenharmony_ci prev = c; 610f08c3bdfSopenharmony_ci c = fgetc(f); 611f08c3bdfSopenharmony_ci } 612f08c3bdfSopenharmony_ci} 613f08c3bdfSopenharmony_ci 614f08c3bdfSopenharmony_cistatic void parse_macro(FILE *f) 615f08c3bdfSopenharmony_ci{ 616f08c3bdfSopenharmony_ci char name[128]; 617f08c3bdfSopenharmony_ci char val[256]; 618f08c3bdfSopenharmony_ci 619f08c3bdfSopenharmony_ci if (!fscanf(f, "%s[^\n]", name)) 620f08c3bdfSopenharmony_ci return; 621f08c3bdfSopenharmony_ci 622f08c3bdfSopenharmony_ci if (fgetc(f) == '\n') 623f08c3bdfSopenharmony_ci return; 624f08c3bdfSopenharmony_ci 625f08c3bdfSopenharmony_ci macro_get_val(f, val, sizeof(val)); 626f08c3bdfSopenharmony_ci 627f08c3bdfSopenharmony_ci if (name[0] == '_') 628f08c3bdfSopenharmony_ci return; 629f08c3bdfSopenharmony_ci 630f08c3bdfSopenharmony_ci ENTRY e = { 631f08c3bdfSopenharmony_ci .key = strdup(name), 632f08c3bdfSopenharmony_ci .data = strdup(val), 633f08c3bdfSopenharmony_ci }; 634f08c3bdfSopenharmony_ci 635f08c3bdfSopenharmony_ci if (verbose) 636f08c3bdfSopenharmony_ci fprintf(stderr, " MACRO %s=%s\n", e.key, (char*)e.data); 637f08c3bdfSopenharmony_ci 638f08c3bdfSopenharmony_ci hsearch(e, ENTER); 639f08c3bdfSopenharmony_ci} 640f08c3bdfSopenharmony_ci 641f08c3bdfSopenharmony_cistatic void parse_include_macros(FILE *f) 642f08c3bdfSopenharmony_ci{ 643f08c3bdfSopenharmony_ci FILE *inc; 644f08c3bdfSopenharmony_ci const char *token; 645f08c3bdfSopenharmony_ci int hash = 0; 646f08c3bdfSopenharmony_ci 647f08c3bdfSopenharmony_ci inc = open_include(f); 648f08c3bdfSopenharmony_ci if (!inc) 649f08c3bdfSopenharmony_ci return; 650f08c3bdfSopenharmony_ci 651f08c3bdfSopenharmony_ci while ((token = next_token(inc, NULL))) { 652f08c3bdfSopenharmony_ci if (token[0] == '#') { 653f08c3bdfSopenharmony_ci hash = 1; 654f08c3bdfSopenharmony_ci continue; 655f08c3bdfSopenharmony_ci } 656f08c3bdfSopenharmony_ci 657f08c3bdfSopenharmony_ci if (!hash) 658f08c3bdfSopenharmony_ci continue; 659f08c3bdfSopenharmony_ci 660f08c3bdfSopenharmony_ci if (!strcmp(token, "define")) 661f08c3bdfSopenharmony_ci parse_macro(inc); 662f08c3bdfSopenharmony_ci 663f08c3bdfSopenharmony_ci hash = 0; 664f08c3bdfSopenharmony_ci } 665f08c3bdfSopenharmony_ci 666f08c3bdfSopenharmony_ci close_include(inc); 667f08c3bdfSopenharmony_ci} 668f08c3bdfSopenharmony_ci 669f08c3bdfSopenharmony_cistatic struct data_node *parse_file(const char *fname) 670f08c3bdfSopenharmony_ci{ 671f08c3bdfSopenharmony_ci int state = 0, found = 0; 672f08c3bdfSopenharmony_ci const char *token; 673f08c3bdfSopenharmony_ci 674f08c3bdfSopenharmony_ci if (access(fname, F_OK)) { 675f08c3bdfSopenharmony_ci fprintf(stderr, "file %s does not exist\n", fname); 676f08c3bdfSopenharmony_ci return NULL; 677f08c3bdfSopenharmony_ci } 678f08c3bdfSopenharmony_ci 679f08c3bdfSopenharmony_ci FILE *f = fopen(fname, "r"); 680f08c3bdfSopenharmony_ci 681f08c3bdfSopenharmony_ci includepath = dirname(strdup(fname)); 682f08c3bdfSopenharmony_ci 683f08c3bdfSopenharmony_ci struct data_node *res = data_node_hash(); 684f08c3bdfSopenharmony_ci struct data_node *doc = data_node_array(); 685f08c3bdfSopenharmony_ci 686f08c3bdfSopenharmony_ci while ((token = next_token(f, doc))) { 687f08c3bdfSopenharmony_ci if (state < 6 && !strcmp(tokens[state], token)) { 688f08c3bdfSopenharmony_ci state++; 689f08c3bdfSopenharmony_ci } else { 690f08c3bdfSopenharmony_ci if (token[0] == '#') { 691f08c3bdfSopenharmony_ci token = next_token(f, doc); 692f08c3bdfSopenharmony_ci if (token) { 693f08c3bdfSopenharmony_ci if (!strcmp(token, "define")) 694f08c3bdfSopenharmony_ci parse_macro(f); 695f08c3bdfSopenharmony_ci 696f08c3bdfSopenharmony_ci if (!strcmp(token, "include")) 697f08c3bdfSopenharmony_ci parse_include_macros(f); 698f08c3bdfSopenharmony_ci } 699f08c3bdfSopenharmony_ci } 700f08c3bdfSopenharmony_ci 701f08c3bdfSopenharmony_ci state = 0; 702f08c3bdfSopenharmony_ci } 703f08c3bdfSopenharmony_ci 704f08c3bdfSopenharmony_ci if (state < 6) 705f08c3bdfSopenharmony_ci continue; 706f08c3bdfSopenharmony_ci 707f08c3bdfSopenharmony_ci found = 1; 708f08c3bdfSopenharmony_ci parse_test_struct(f, doc, res); 709f08c3bdfSopenharmony_ci } 710f08c3bdfSopenharmony_ci 711f08c3bdfSopenharmony_ci if (data_node_array_len(doc)) { 712f08c3bdfSopenharmony_ci data_node_hash_add(res, "doc", doc); 713f08c3bdfSopenharmony_ci found = 1; 714f08c3bdfSopenharmony_ci } else { 715f08c3bdfSopenharmony_ci data_node_free(doc); 716f08c3bdfSopenharmony_ci } 717f08c3bdfSopenharmony_ci 718f08c3bdfSopenharmony_ci fclose(f); 719f08c3bdfSopenharmony_ci 720f08c3bdfSopenharmony_ci if (!found) { 721f08c3bdfSopenharmony_ci data_node_free(res); 722f08c3bdfSopenharmony_ci return NULL; 723f08c3bdfSopenharmony_ci } 724f08c3bdfSopenharmony_ci 725f08c3bdfSopenharmony_ci return res; 726f08c3bdfSopenharmony_ci} 727f08c3bdfSopenharmony_ci 728f08c3bdfSopenharmony_cistatic struct typemap { 729f08c3bdfSopenharmony_ci const char *id; 730f08c3bdfSopenharmony_ci enum data_type type; 731f08c3bdfSopenharmony_ci} tst_test_typemap[] = { 732f08c3bdfSopenharmony_ci {.id = "test_variants", .type = DATA_INT}, 733f08c3bdfSopenharmony_ci {} 734f08c3bdfSopenharmony_ci}; 735f08c3bdfSopenharmony_ci 736f08c3bdfSopenharmony_cistatic void convert_str2int(struct data_node *res, const char *id, const char *str_val) 737f08c3bdfSopenharmony_ci{ 738f08c3bdfSopenharmony_ci long val; 739f08c3bdfSopenharmony_ci char *endptr; 740f08c3bdfSopenharmony_ci 741f08c3bdfSopenharmony_ci errno = 0; 742f08c3bdfSopenharmony_ci val = strtol(str_val, &endptr, 10); 743f08c3bdfSopenharmony_ci 744f08c3bdfSopenharmony_ci if (errno || *endptr) { 745f08c3bdfSopenharmony_ci fprintf(stderr, "Cannot convert %s value %s to int!\n", id, str_val); 746f08c3bdfSopenharmony_ci exit(1); 747f08c3bdfSopenharmony_ci } 748f08c3bdfSopenharmony_ci 749f08c3bdfSopenharmony_ci if (verbose) 750f08c3bdfSopenharmony_ci fprintf(stderr, "NORMALIZING %s TO INT %li\n", id, val); 751f08c3bdfSopenharmony_ci 752f08c3bdfSopenharmony_ci data_node_hash_del(res, id); 753f08c3bdfSopenharmony_ci data_node_hash_add(res, id, data_node_int(val)); 754f08c3bdfSopenharmony_ci} 755f08c3bdfSopenharmony_ci 756f08c3bdfSopenharmony_cistatic void check_normalize_types(struct data_node *res) 757f08c3bdfSopenharmony_ci{ 758f08c3bdfSopenharmony_ci unsigned int i; 759f08c3bdfSopenharmony_ci 760f08c3bdfSopenharmony_ci for (i = 0; tst_test_typemap[i].id; i++) { 761f08c3bdfSopenharmony_ci struct data_node *n; 762f08c3bdfSopenharmony_ci struct typemap *typemap = &tst_test_typemap[i]; 763f08c3bdfSopenharmony_ci 764f08c3bdfSopenharmony_ci n = data_node_hash_get(res, typemap->id); 765f08c3bdfSopenharmony_ci if (!n) 766f08c3bdfSopenharmony_ci continue; 767f08c3bdfSopenharmony_ci 768f08c3bdfSopenharmony_ci if (n->type == typemap->type) 769f08c3bdfSopenharmony_ci continue; 770f08c3bdfSopenharmony_ci 771f08c3bdfSopenharmony_ci if (n->type == DATA_STRING && typemap->type == DATA_INT) { 772f08c3bdfSopenharmony_ci convert_str2int(res, typemap->id, n->string.val); 773f08c3bdfSopenharmony_ci continue; 774f08c3bdfSopenharmony_ci } 775f08c3bdfSopenharmony_ci 776f08c3bdfSopenharmony_ci fprintf(stderr, "Cannot convert %s from %s to %s!\n", 777f08c3bdfSopenharmony_ci typemap->id, data_type_name(n->type), 778f08c3bdfSopenharmony_ci data_type_name(typemap->type)); 779f08c3bdfSopenharmony_ci exit(1); 780f08c3bdfSopenharmony_ci } 781f08c3bdfSopenharmony_ci} 782f08c3bdfSopenharmony_ci 783f08c3bdfSopenharmony_cistatic const char *filter_out[] = { 784f08c3bdfSopenharmony_ci "bufs", 785f08c3bdfSopenharmony_ci "cleanup", 786f08c3bdfSopenharmony_ci "mntpoint", 787f08c3bdfSopenharmony_ci "setup", 788f08c3bdfSopenharmony_ci "tcnt", 789f08c3bdfSopenharmony_ci "test", 790f08c3bdfSopenharmony_ci "test_all", 791f08c3bdfSopenharmony_ci NULL 792f08c3bdfSopenharmony_ci}; 793f08c3bdfSopenharmony_ci 794f08c3bdfSopenharmony_cistatic struct implies { 795f08c3bdfSopenharmony_ci const char *flag; 796f08c3bdfSopenharmony_ci const char **implies; 797f08c3bdfSopenharmony_ci} implies[] = { 798f08c3bdfSopenharmony_ci {"mount_device", (const char *[]) {"format_device", "needs_device", 799f08c3bdfSopenharmony_ci "needs_tmpdir", NULL}}, 800f08c3bdfSopenharmony_ci {"format_device", (const char *[]) {"needs_device", "needs_tmpdir", 801f08c3bdfSopenharmony_ci NULL}}, 802f08c3bdfSopenharmony_ci {"all_filesystems", (const char *[]) {"needs_device", "needs_tmpdir", 803f08c3bdfSopenharmony_ci NULL}}, 804f08c3bdfSopenharmony_ci {"needs_device", (const char *[]) {"needs_tmpdir", NULL}}, 805f08c3bdfSopenharmony_ci {"needs_checkpoints", (const char *[]) {"needs_tmpdir", NULL}}, 806f08c3bdfSopenharmony_ci {"resource_files", (const char *[]) {"needs_tmpdir", NULL}}, 807f08c3bdfSopenharmony_ci {NULL, (const char *[]) {NULL}} 808f08c3bdfSopenharmony_ci}; 809f08c3bdfSopenharmony_ci 810f08c3bdfSopenharmony_ciconst char *strip_name(char *path) 811f08c3bdfSopenharmony_ci{ 812f08c3bdfSopenharmony_ci char *name = basename(path); 813f08c3bdfSopenharmony_ci size_t len = strlen(name); 814f08c3bdfSopenharmony_ci 815f08c3bdfSopenharmony_ci if (len > 2 && name[len-1] == 'c' && name[len-2] == '.') 816f08c3bdfSopenharmony_ci name[len-2] = '\0'; 817f08c3bdfSopenharmony_ci 818f08c3bdfSopenharmony_ci return name; 819f08c3bdfSopenharmony_ci} 820f08c3bdfSopenharmony_ci 821f08c3bdfSopenharmony_cistatic void print_help(const char *prgname) 822f08c3bdfSopenharmony_ci{ 823f08c3bdfSopenharmony_ci printf("usage: %s [-vh] input.c\n\n", prgname); 824f08c3bdfSopenharmony_ci printf("-v sets verbose mode\n"); 825f08c3bdfSopenharmony_ci printf("-I add include path\n"); 826f08c3bdfSopenharmony_ci printf("-h prints this help\n\n"); 827f08c3bdfSopenharmony_ci exit(0); 828f08c3bdfSopenharmony_ci} 829f08c3bdfSopenharmony_ci 830f08c3bdfSopenharmony_ciint main(int argc, char *argv[]) 831f08c3bdfSopenharmony_ci{ 832f08c3bdfSopenharmony_ci unsigned int i, j; 833f08c3bdfSopenharmony_ci struct data_node *res; 834f08c3bdfSopenharmony_ci int opt; 835f08c3bdfSopenharmony_ci 836f08c3bdfSopenharmony_ci while ((opt = getopt(argc, argv, "hI:v")) != -1) { 837f08c3bdfSopenharmony_ci switch (opt) { 838f08c3bdfSopenharmony_ci case 'h': 839f08c3bdfSopenharmony_ci print_help(argv[0]); 840f08c3bdfSopenharmony_ci break; 841f08c3bdfSopenharmony_ci case 'I': 842f08c3bdfSopenharmony_ci if (cmdline_includepaths >= INCLUDE_PATH_MAX) { 843f08c3bdfSopenharmony_ci fprintf(stderr, "Too much include paths!"); 844f08c3bdfSopenharmony_ci exit(1); 845f08c3bdfSopenharmony_ci } 846f08c3bdfSopenharmony_ci 847f08c3bdfSopenharmony_ci cmdline_includepath[cmdline_includepaths++] = optarg; 848f08c3bdfSopenharmony_ci break; 849f08c3bdfSopenharmony_ci case 'v': 850f08c3bdfSopenharmony_ci verbose = 1; 851f08c3bdfSopenharmony_ci break; 852f08c3bdfSopenharmony_ci } 853f08c3bdfSopenharmony_ci } 854f08c3bdfSopenharmony_ci 855f08c3bdfSopenharmony_ci if (optind >= argc) { 856f08c3bdfSopenharmony_ci fprintf(stderr, "No input filename.c\n"); 857f08c3bdfSopenharmony_ci return 1; 858f08c3bdfSopenharmony_ci } 859f08c3bdfSopenharmony_ci 860f08c3bdfSopenharmony_ci if (!hcreate(128)) { 861f08c3bdfSopenharmony_ci fprintf(stderr, "Failed to initialize hash table\n"); 862f08c3bdfSopenharmony_ci return 1; 863f08c3bdfSopenharmony_ci } 864f08c3bdfSopenharmony_ci 865f08c3bdfSopenharmony_ci res = parse_file(argv[optind]); 866f08c3bdfSopenharmony_ci if (!res) 867f08c3bdfSopenharmony_ci return 0; 868f08c3bdfSopenharmony_ci 869f08c3bdfSopenharmony_ci /* Filter out useless data */ 870f08c3bdfSopenharmony_ci for (i = 0; filter_out[i]; i++) 871f08c3bdfSopenharmony_ci data_node_hash_del(res, filter_out[i]); 872f08c3bdfSopenharmony_ci 873f08c3bdfSopenharmony_ci /* Normalize the result */ 874f08c3bdfSopenharmony_ci for (i = 0; implies[i].flag; i++) { 875f08c3bdfSopenharmony_ci if (data_node_hash_get(res, implies[i].flag)) { 876f08c3bdfSopenharmony_ci for (j = 0; implies[i].implies[j]; j++) { 877f08c3bdfSopenharmony_ci if (data_node_hash_get(res, implies[i].implies[j])) 878f08c3bdfSopenharmony_ci fprintf(stderr, "%s: useless tag: %s\n", 879f08c3bdfSopenharmony_ci argv[optind], implies[i].implies[j]); 880f08c3bdfSopenharmony_ci } 881f08c3bdfSopenharmony_ci } 882f08c3bdfSopenharmony_ci } 883f08c3bdfSopenharmony_ci 884f08c3bdfSopenharmony_ci /* Normalize types */ 885f08c3bdfSopenharmony_ci check_normalize_types(res); 886f08c3bdfSopenharmony_ci 887f08c3bdfSopenharmony_ci for (i = 0; implies[i].flag; i++) { 888f08c3bdfSopenharmony_ci if (data_node_hash_get(res, implies[i].flag)) { 889f08c3bdfSopenharmony_ci for (j = 0; implies[i].implies[j]; j++) { 890f08c3bdfSopenharmony_ci if (!data_node_hash_get(res, implies[i].implies[j])) 891f08c3bdfSopenharmony_ci data_node_hash_add(res, implies[i].implies[j], 892f08c3bdfSopenharmony_ci data_node_string("1")); 893f08c3bdfSopenharmony_ci } 894f08c3bdfSopenharmony_ci } 895f08c3bdfSopenharmony_ci } 896f08c3bdfSopenharmony_ci 897f08c3bdfSopenharmony_ci data_node_hash_add(res, "fname", data_node_string(argv[optind])); 898f08c3bdfSopenharmony_ci printf(" \"%s\": ", strip_name(argv[optind])); 899f08c3bdfSopenharmony_ci data_to_json(res, stdout, 2); 900f08c3bdfSopenharmony_ci data_node_free(res); 901f08c3bdfSopenharmony_ci 902f08c3bdfSopenharmony_ci return 0; 903f08c3bdfSopenharmony_ci} 904