1 //
2 // Copyright (C) 2013 Nick Gasson
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17
18 #include "rt.h"
19 #include "util.h"
20 #include "tree.h"
21
22 #include <string.h>
23
24 typedef struct {
25 char *text;
26 size_t len;
27 } glob_t;
28
29 static int n_incl = 0;
30 static int incl_sz = 0;
31 static int n_excl = 0;
32 static int excl_sz = 0;
33 static glob_t *incl;
34 static glob_t *excl;
35
wave_include_glob(const char * glob)36 void wave_include_glob(const char *glob)
37 {
38 if (n_incl == incl_sz) {
39 incl_sz = MAX(incl_sz * 2, 256);
40 incl = xrealloc(incl, incl_sz * sizeof(glob_t));
41 }
42
43 incl[n_incl].text = strdup(glob);
44 incl[n_incl].len = strlen(glob);
45
46 n_incl++;
47 }
48
wave_exclude_glob(const char * glob)49 void wave_exclude_glob(const char *glob)
50 {
51 if (n_excl == excl_sz) {
52 excl_sz = MAX(excl_sz * 2, 256);
53 excl = xrealloc(excl, excl_sz * sizeof(glob_t));
54 }
55
56 excl[n_excl].text = strdup(glob);
57 excl[n_excl].len = strlen(glob);
58
59 n_excl++;
60 }
61
wave_process_file(const char * fname,bool include)62 static void wave_process_file(const char *fname, bool include)
63 {
64 FILE *f = fopen(fname, "r");
65 if (f == NULL)
66 return;
67
68 notef("%s signals from %s", include ? "including" : "excluding", fname);
69
70 int lineno = 0;
71 char line[1024];
72 while (!feof(f) && (lineno++, fgets(line, sizeof(line), f) != NULL)) {
73 // Erase comments
74 bool comment = false;
75 for (char *p = line; *p != '\0'; p++) {
76 if (*p == '#')
77 comment = true;
78 if (comment || (*p == '\r') || (*p == '\n'))
79 *p = '\0';
80 }
81
82 char glob[1024];
83 if (sscanf(line, " %1023s ", glob) == 1) {
84 if (include)
85 wave_include_glob(glob);
86 else
87 wave_exclude_glob(glob);
88 }
89 }
90
91 fclose(f);
92 }
93
wave_include_file(const char * base)94 void wave_include_file(const char *base)
95 {
96 char buf[256];
97
98 checked_sprintf(buf, sizeof(buf), "%s.include", base);
99 wave_process_file(buf, true);
100
101 checked_sprintf(buf, sizeof(buf), "%s.exclude", base);
102 wave_process_file(buf, false);
103 }
104
wave_should_dump(tree_t decl)105 bool wave_should_dump(tree_t decl)
106 {
107 ident_t name = tree_ident(decl);
108
109 for (int i = 0; i < n_excl; i++) {
110 if (ident_glob(name, excl[i].text, excl[i].len))
111 return false;
112 }
113
114 for (int i = 0; i < n_incl; i++) {
115 if (ident_glob(name, incl[i].text, incl[i].len))
116 return true;
117 }
118
119 return (n_incl == 0);
120 }
121