1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | #include "extern.h" |
28 | |
29 | static DFAPTR _build_dfa ANSI((char *))(char *); |
30 | static char _shift_dfa ANSI((DFAPTR, char *))(DFAPTR, char *); |
31 | |
32 | |
33 | #define NO_ACTION0 0 |
34 | #define START_PERCENT1 1 |
35 | #define END_PERCENT2 2 |
36 | #define ACCEPT4 4 |
37 | #define FAIL-1 -1 |
38 | |
39 | static NFAPTR _nfa = NIL( NFA )((NFA*)((void*)0)); |
40 | |
41 | |
42 | PUBLIC DFALINKPTR |
43 | Match_dfa( buf ) |
44 | |
45 | |
46 | |
47 | char *buf; |
48 | { |
49 | register NFAPTR nfa; |
50 | int adv; |
51 | DFALINKPTR dfa_list = NIL(DFALINK)((DFALINK*)((void*)0)); |
52 | |
53 | DB_ENTER( "Match_dfa" ); |
54 | DB_PRINT( "dfa", ("Matching %s", buf) ); |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | do { |
62 | adv = FALSE0; |
63 | |
64 | for( nfa = _nfa; nfa != NIL( NFA )((NFA*)((void*)0)); nfa = nfa->next ) |
65 | if( nfa->status != (char) FAIL-1 && nfa->status != (char) ACCEPT4 ) { |
66 | adv++; |
67 | nfa->status = _shift_dfa( nfa->dfa, buf ); |
68 | |
69 | |
70 | if( nfa->status == (char) ACCEPT4 ) { |
71 | DFALINKPTR dl; |
72 | |
73 | TALLOC( dl, 1, DFALINK )if ((dl = (DFALINK*) calloc((unsigned int)(1), (size_t)sizeof (DFALINK))) == (DFALINK*)0) {No_ram();}; |
74 | dl->dl_meta = nfa->dfa->node; |
75 | dl->dl_per = DmSubStr( nfa->dfa->pstart, nfa->dfa->pend ); |
76 | dl->dl_state = nfa->dfa->states - nfa->dfa->c_state; |
77 | |
78 | if( dfa_list == NIL(DFALINK)((DFALINK*)((void*)0)) ) |
79 | dfa_list = dl; |
80 | else { |
81 | DFALINKPTR tdli = dfa_list; |
82 | DFALINKPTR tdlp = NIL(DFALINK)((DFALINK*)((void*)0)); |
83 | |
84 | for( ; tdli != NIL(DFALINK)((DFALINK*)((void*)0)); tdli = tdli->dl_next ) { |
85 | if( dl->dl_state >= tdli->dl_state ) |
86 | break; |
87 | tdlp = tdli; |
88 | } |
89 | |
90 | if( tdli != NIL(DFALINK)((DFALINK*)((void*)0)) ) { |
91 | tdli->dl_prev = dl; |
92 | dl->dl_next = tdli; |
93 | } |
94 | |
95 | if( tdlp != NIL(DFALINK)((DFALINK*)((void*)0)) ) { |
96 | tdlp->dl_next = dl; |
97 | dl->dl_prev = tdlp; |
98 | } |
99 | else |
100 | dfa_list = dl; |
101 | } |
102 | |
103 | DB_PRINT( "dfa", ("Matched [%s]", dl->dl_meta->CE_NAME) ); |
104 | } |
105 | } |
106 | |
107 | buf++; |
108 | } |
109 | while ( adv ); |
110 | |
111 | for( nfa = _nfa; nfa != NIL( NFA )((NFA*)((void*)0)); nfa = nfa->next ) { |
112 | nfa->status = 0; |
113 | nfa->dfa->c_state = nfa->dfa->states; |
114 | } |
115 | |
116 | DB_RETURN( dfa_list )return (dfa_list); |
117 | } |
118 | |
119 | |
120 | PUBLIC void |
121 | Check_circle_dfa() |
122 | |
123 | |
124 | |
125 | { |
126 | register NFAPTR nfa; |
127 | |
128 | for( nfa = _nfa; nfa != NIL(NFA)((NFA*)((void*)0)); nfa = nfa->next ) |
129 | if( Test_circle( nfa->dfa->node, FALSE0 ) ) |
130 | Fatal( "Detected circular dependency in inference graph at [%s]", |
131 | nfa->dfa->node->CE_NAMEce_name->ht_name ); |
132 | } |
133 | |
134 | |
135 | PUBLIC void |
136 | Add_nfa( name ) |
137 | |
138 | |
139 | |
140 | char *name; |
141 | { |
142 | NFAPTR nfa; |
143 | |
144 | TALLOC(nfa, 1, NFA)if ((nfa = (NFA*) calloc((unsigned int)(1), (size_t)sizeof(NFA ))) == (NFA*)0) {No_ram();}; |
| 1 | Within the expansion of the macro 'TALLOC':
| |
b | Assuming pointer value is null |
|
145 | nfa->dfa = _build_dfa(name); |
| 2 | | Access to field 'dfa' results in a dereference of a null pointer (loaded from variable 'nfa') |
|
146 | |
147 | if( _nfa != NIL(NFA)((NFA*)((void*)0)) ) nfa->next = _nfa; |
148 | |
149 | _nfa = nfa; |
150 | } |
151 | |
152 | |
153 | static DFAPTR |
154 | _build_dfa( name ) |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | char *name; |
167 | { |
168 | DFAPTR dfa; |
169 | int nstates; |
170 | register STATEPTR sp; |
171 | STATEPTR per_state = NIL(STATE)((STATE*)((void*)0)); |
172 | int pcount=0; |
173 | int end_percent=FALSE0; |
174 | |
175 | nstates = strlen(name)+2; |
176 | |
177 | |
178 | TALLOC(dfa, 1, DFA)if ((dfa = (DFA*) calloc((unsigned int)(1), (size_t)sizeof(DFA ))) == (DFA*)0) {No_ram();}; |
179 | TALLOC(sp=dfa->c_state=dfa->states, nstates, STATE)if ((sp=dfa->c_state=dfa->states = (STATE*) calloc((unsigned int)(nstates), (size_t)sizeof(STATE))) == (STATE*)0) {No_ram ();}; |
180 | dfa->node = Def_cell( name ); |
181 | |
182 | |
183 | do { |
184 | if( *name == '%' ) { |
185 | if( pcount++ > 0 ) |
186 | Error( "Only one %% allowed within a %%-meta target" ); |
187 | |
188 | sp->symbol = 0; |
189 | sp->action = START_PERCENT1; |
190 | sp->no_match = sp->match = per_state = sp+1; |
191 | end_percent = TRUE1; |
192 | } |
193 | else { |
194 | sp->symbol = *name; |
195 | sp->no_match = per_state; |
196 | |
197 | if( *name == '\0' ) { |
198 | sp->action = ACCEPT4; |
199 | sp->match = dfa->states; |
200 | } |
201 | else { |
202 | sp->action = NO_ACTION0; |
203 | sp->match = sp+1; |
204 | } |
205 | |
206 | if( end_percent ) { |
207 | sp->action |= END_PERCENT2; |
208 | end_percent = FALSE0; |
209 | } |
210 | } |
211 | |
212 | sp++; |
213 | } |
214 | while( *name++ ); |
215 | |
216 | return(dfa); |
217 | } |
218 | |
219 | |
220 | static char |
221 | _shift_dfa( dfa, data ) |
222 | |
223 | |
224 | |
225 | DFAPTR dfa; |
226 | char *data; |
227 | { |
228 | register STATEPTR sp = dfa->c_state; |
229 | char c = *data; |
230 | |
231 | |
232 | |
233 | if( sp->action & START_PERCENT1 ) { |
234 | dfa->pstart = data; |
235 | sp++; |
236 | } |
237 | |
238 | |
239 | |
240 | |
241 | |
242 | if( sp->symbol == c ) { |
243 | if( sp->action & END_PERCENT2 ) dfa->pend = data; |
244 | if( sp->action & ACCEPT4 ) return(ACCEPT4); |
245 | dfa->c_state = sp->match; |
246 | } |
247 | else if( (dfa->c_state = sp->no_match) == NIL(STATE)((STATE*)((void*)0)) || !c ) |
248 | return((unsigned char) FAIL-1); |
249 | |
250 | return(NO_ACTION0); |
251 | } |