Bug Summary

File:dynarray.c
Warning:line 516, column 19
Result of 'calloc' is converted to a pointer of type 'struct fsm_state *', which is incompatible with sizeof operand type 'struct fsm **'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name dynarray.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/tmp/build/foma/foma-0.10.0+g279~a2d32b38 -resource-dir /usr/lib/llvm-16/lib/clang/16 -D _GNU_SOURCE -I /tmp/build/foma/foma-0.10.0+g279~a2d32b38 -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-missing-field-initializers -Wno-deprecated -Wno-unused-parameter -std=c18 -fdebug-compilation-dir=/tmp/build/foma/foma-0.10.0+g279~a2d32b38 -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/build/foma/scan-build/2024-09-11-155945-2678-1 -x c /tmp/build/foma/foma-0.10.0+g279~a2d32b38/dynarray.c
1/* Foma: a finite-state toolkit and library. */
2/* Copyright © 2008-2021 Mans Hulden */
3
4/* This file is part of foma. */
5
6/* Licensed under the Apache License, Version 2.0 (the "License"); */
7/* you may not use this file except in compliance with the License. */
8/* You may obtain a copy of the License at */
9
10/* http://www.apache.org/licenses/LICENSE-2.0 */
11
12/* Unless required by applicable law or agreed to in writing, software */
13/* distributed under the License is distributed on an "AS IS" BASIS, */
14/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
15/* See the License for the specific language governing permissions and */
16/* limitations under the License. */
17
18#include <stdio.h>
19#include <stdlib.h>
20#include "foma.h"
21
22#define INITIAL_SIZE16384 16384
23#define SIGMA_HASH_SIZE1021 1021
24#define MINSIGMA3 3
25
26struct foma_reserved_symbols {
27 char *symbol;
28 int number;
29 char *prints_as;
30} foma_reserved_symbols[] = {
31 {"@_EPSILON_SYMBOL_@" , EPSILON0 , "0"},
32 {"@_UNKNOWN_SYMBOL_@" , UNKNOWN1 , "?"},
33 {"@_IDENTITY_SYMBOL_@", IDENTITY2, "@"},
34 {NULL((void*)0),0,NULL((void*)0)}
35};
36
37static size_t current_fsm_size;
38static unsigned int current_fsm_linecount, current_state_no, current_final, current_start, current_trans, num_finals, num_initials, arity, statecount;
39static _Bool is_deterministic, is_epsilon_free;
40static struct fsm_state *current_fsm_head;
41
42static unsigned int mainloop, ssize, arccount;
43
44struct sigma_lookup {
45 int target;
46 unsigned int mainloop;
47};
48
49static struct sigma_lookup *slookup;
50
51/* Functions for directly building a fsm_state structure */
52/* dynamically. */
53
54/* fsm_state_init() is called when a new machine is constructed */
55
56/* fsm_state_add_arc() adds an arc and possibly reallocs the array */
57
58/* fsm_state_close() adds the sentinel entry and clears values */
59
60struct fsm_state *fsm_state_init(int sigma_size) {
61 current_fsm_head = malloc(INITIAL_SIZE16384 * sizeof(struct fsm_state));
62 current_fsm_size = INITIAL_SIZE16384;
63 current_fsm_linecount = 0;
64 ssize = sigma_size+1;
65 slookup = calloc(ssize*ssize,sizeof(struct sigma_lookup));
66 mainloop = 1;
67 is_deterministic = 1;
68 is_epsilon_free = 1;
69 arccount = 0;
70 num_finals = 0;
71 num_initials = 0;
72 statecount = 0;
73 arity = 1;
74 current_trans = 1;
75 return(current_fsm_head);
76}
77
78void fsm_state_set_current_state(int state_no, int final_state, int start_state) {
79 current_state_no = state_no;
80 current_final = final_state;
81 current_start = start_state;
82 current_trans = 0;
83 if (current_final == 1)
84 num_finals++;
85 if (current_start == 1)
86 num_initials++;
87}
88
89/* Add sentinel if needed */
90void fsm_state_end_state() {
91 if (current_trans == 0) {
92 fsm_state_add_arc(current_state_no, -1, -1, -1, current_final, current_start);
93 }
94 statecount++;
95 mainloop++;
96}
97
98void fsm_state_add_arc(int state_no, int in, int out, int target, int final_state, int start_state) {
99 struct fsm_state *cptr;
100
101 if (in != out) {
102 arity = 2;
103 }
104 /* Check epsilon moves */
105 if (in == EPSILON0 && out == EPSILON0) {
106 if (state_no == target) {
107 return;
108 } else {
109 is_deterministic = 0;
110 is_epsilon_free = 0;
111 }
112 }
113
114 /* Check if we already added this particular arc and skip */
115 /* Also check if net becomes non-det */
116 if (in != -1 && out != -1) {
117 if ((slookup+(ssize*in)+out)->mainloop == mainloop) {
118 if ((slookup+(ssize*in)+out)->target == target) {
119 return;
120 } else {
121 is_deterministic = 0;
122 }
123 }
124 arccount++;
125 (slookup+(ssize*in)+out)->mainloop = mainloop;
126 (slookup+(ssize*in)+out)->target = target;
127 }
128
129 current_trans = 1;
130 if (current_fsm_linecount >= current_fsm_size) {
131 current_fsm_size *= 2;
132 current_fsm_head = realloc(current_fsm_head, current_fsm_size * sizeof(struct fsm_state));
133 if (current_fsm_head == NULL((void*)0)) {
134 perror("Fatal error: out of memory\n");
135 exit(1);
136 }
137 }
138 cptr = current_fsm_head + current_fsm_linecount;
139 cptr->state_no = state_no;
140 cptr->in = in;
141 cptr->out = out;
142 cptr->target = target;
143 cptr->final_state = final_state;
144 cptr->start_state = start_state;
145 current_fsm_linecount++;
146}
147
148void fsm_state_close(struct fsm *net) {
149 fsm_state_add_arc(-1,-1,-1,-1,-1,-1);
150 current_fsm_head = realloc(current_fsm_head, current_fsm_linecount * sizeof(struct fsm_state));
151 net->arity = arity;
152 net->arccount = arccount;
153 net->statecount = statecount;
154 net->linecount = current_fsm_linecount;
155 net->finalcount = num_finals;
156 net->pathcount = PATHCOUNT_UNKNOWN-3;
157 if (num_initials > 1)
158 is_deterministic = 0;
159 net->is_deterministic = is_deterministic;
160 net->is_pruned = UNK2;
161 net->is_minimized = UNK2;
162 net->is_epsilon_free = is_epsilon_free;
163 net->is_loop_free = UNK2;
164 net->is_completed = UNK2;
165 net->arcs_sorted_in = 0;
166 net->arcs_sorted_out = 0;
167
168 net->states = current_fsm_head;
169 free(slookup);
170}
171
172/* Construction functions */
173
174struct fsm_construct_handle *fsm_construct_init(char *name) {
175 struct fsm_construct_handle *handle;
176 handle = malloc(sizeof(struct fsm_construct_handle));
177 handle->fsm_state_list = calloc(1024,sizeof(struct fsm_state_list));
178 handle->fsm_state_list_size = 1024;
179 handle->fsm_sigma_list = calloc(1024,sizeof(struct fsm_sigma_list));
180 handle->fsm_sigma_list_size = 1024;
181 handle->fsm_sigma_hash = calloc(SIGMA_HASH_SIZE1021,sizeof(struct fsm_sigma_hash));
182 handle->maxstate = -1;
183 handle->maxsigma = -1;
184 handle->numfinals = 0;
185 if (name == NULL((void*)0)) {
186 handle->name = NULL((void*)0);
187 } else {
188 handle->name = strdup(name);
189 }
190 handle->hasinitial = 0;
191 return(handle);
192}
193
194void fsm_construct_check_size(struct fsm_construct_handle *handle, int state_no) {
195 int i, oldsize, newsize;
196 struct fsm_state_list *sl;
197 oldsize = handle->fsm_state_list_size;
198 if (oldsize <= state_no) {
199 newsize = next_power_of_two(state_no);
200 handle->fsm_state_list = realloc(handle->fsm_state_list, newsize*sizeof(struct fsm_state_list));
201 handle->fsm_state_list_size = newsize;
202 sl = handle->fsm_state_list;
203 for (i=oldsize; i<newsize;i++) {
204 (sl+i)->is_final = 0;
205 (sl+i)->is_initial = 0;
206 (sl+i)->used = 0;
207 (sl+i)->num_trans = 0;
208 (sl+i)->fsm_trans_list = NULL((void*)0);
209 }
210 }
211}
212
213void fsm_construct_set_final(struct fsm_construct_handle *handle, int state_no) {
214 struct fsm_state_list *sl;
215 fsm_construct_check_size(handle, state_no);
216
217 if (state_no > handle->maxstate)
218 handle->maxstate = state_no;
219
220 sl = handle->fsm_state_list;
221 if (!(sl+state_no)->is_final) {
222 (sl+state_no)->is_final = 1;
223 handle->numfinals++;
224 }
225}
226
227void fsm_construct_set_initial(struct fsm_construct_handle *handle, int state_no) {
228 struct fsm_state_list *sl;
229 fsm_construct_check_size(handle, state_no);
230
231 if (state_no > handle->maxstate)
232 handle->maxstate = state_no;
233
234 sl = handle->fsm_state_list;
235 (sl+state_no)->is_initial = 1;
236 handle->hasinitial = 1;
237}
238
239void fsm_construct_add_arc(struct fsm_construct_handle *handle, int source, int target, char *in, char *out) {
240 struct fsm_state_list *sl;
241 struct fsm_trans_list *tl;
242 int symin, symout;
243 fsm_construct_check_size(handle, source);
244 fsm_construct_check_size(handle, target);
245
246 if (source > handle->maxstate)
247 handle->maxstate = source;
248 if (target > handle->maxstate)
249 handle->maxstate = target;
250
251 sl = (handle->fsm_state_list)+target;
252 sl->used = 1;
253 sl = (handle->fsm_state_list)+source;
254 sl->used = 1;
255 tl = malloc(sizeof(struct fsm_trans_list));
256 tl->next = sl->fsm_trans_list;
257 sl->fsm_trans_list = tl;
258 if ((symin = fsm_construct_check_symbol(handle,in)) == -1)
259 symin = fsm_construct_add_symbol(handle,in);
260 if ((symout = fsm_construct_check_symbol(handle,out)) == -1)
261 symout = fsm_construct_add_symbol(handle,out);
262 tl->in = symin;
263 tl->out = symout;
264 tl->target = target;
265}
266
267unsigned int fsm_construct_hash_sym(char *symbol) {
268 register unsigned int hash;
269 hash = 0;
270
271 while (*symbol != '\0')
272 hash = hash + *symbol++;
273 return (hash % SIGMA_HASH_SIZE1021);
274}
275
276void fsm_construct_add_arc_nums(struct fsm_construct_handle *handle, int source, int target, int in, int out) {
277 struct fsm_state_list *sl;
278 struct fsm_trans_list *tl;
279 fsm_construct_check_size(handle, source);
280 fsm_construct_check_size(handle, target);
281
282 if (source > handle->maxstate)
283 handle->maxstate = source;
284 if (target > handle->maxstate)
285 handle->maxstate = target;
286
287 sl = (handle->fsm_state_list)+target;
288 sl->used = 1;
289 sl = (handle->fsm_state_list)+source;
290 sl->used = 1;
291 tl = malloc(sizeof(struct fsm_trans_list));
292 tl->next = sl->fsm_trans_list;
293 sl->fsm_trans_list = tl;
294 tl->in = in;
295 tl->out = out;
296 tl->target = target;
297}
298
299/* Copies entire alphabet from existing network */
300
301void fsm_construct_copy_sigma(struct fsm_construct_handle *handle, struct sigma *sigma) {
302
303 unsigned int hash;
304 int symnum;
305 struct fsm_sigma_hash *fh, *newfh;
306 char *symbol, *symdup;
307
308 for (; sigma != NULL((void*)0) && sigma->number != -1; sigma = sigma->next) {
309 symnum = sigma->number;
310 if (symnum > handle->maxsigma) {
311 handle->maxsigma = symnum;
312 }
313 symbol = sigma->symbol;
314 if (symnum >= handle->fsm_sigma_list_size) {
315 handle->fsm_sigma_list_size = next_power_of_two(handle->fsm_sigma_list_size);
316 handle->fsm_sigma_list = realloc(handle->fsm_sigma_list, (handle->fsm_sigma_list_size) * sizeof(struct fsm_sigma_list));
317 }
318 /* Insert into list */
319 symdup = strdup(symbol);
320 ((handle->fsm_sigma_list)+symnum)->symbol = symdup;
321
322 /* Insert into hashtable */
323 hash = fsm_construct_hash_sym(symbol);
324 fh = (handle->fsm_sigma_hash)+hash;
325 if (fh->symbol == NULL((void*)0)) {
326 fh->symbol = symdup;
327 fh->sym = symnum;
328 } else {
329 newfh = calloc(1,sizeof(struct fsm_sigma_hash));
330 newfh->next = fh->next;
331 fh->next = newfh;
332 newfh->symbol = symdup;
333 newfh->sym = symnum;
334 }
335 }
336}
337
338int fsm_construct_add_symbol(struct fsm_construct_handle *handle, char *symbol) {
339 int i, symnum, reserved;
340 unsigned int hash;
341 struct fsm_sigma_hash *fh, *newfh;
342 char *symdup;
343
344 /* Is symbol reserved? */
345 for (i=0, reserved = 0; foma_reserved_symbols[i].symbol != NULL((void*)0); i++) {
346 if (strcmp(symbol, foma_reserved_symbols[i].symbol) == 0) {
347 symnum = foma_reserved_symbols[i].number;
348 reserved = 1;
349 if (handle->maxsigma < symnum) {
350 handle->maxsigma = symnum;
351 }
352 break;
353 }
354 }
355
356 if (reserved == 0) {
357 symnum = handle->maxsigma + 1;
358 if (symnum < MINSIGMA3)
359 symnum = MINSIGMA3;
360 handle->maxsigma = symnum;
361 }
362
363 if (symnum >= handle->fsm_sigma_list_size) {
364 handle->fsm_sigma_list_size = next_power_of_two(handle->fsm_sigma_list_size);
365 handle->fsm_sigma_list = realloc(handle->fsm_sigma_list, (handle->fsm_sigma_list_size) * sizeof(struct fsm_sigma_list));
366 }
367 /* Insert into list */
368 symdup = strdup(symbol);
369 ((handle->fsm_sigma_list)+symnum)->symbol = symdup;
370
371 /* Insert into hashtable */
372 hash = fsm_construct_hash_sym(symbol);
373 fh = (handle->fsm_sigma_hash)+hash;
374 if (fh->symbol == NULL((void*)0)) {
375 fh->symbol = symdup;
376 fh->sym = symnum;
377 } else {
378 newfh = calloc(1,sizeof(struct fsm_sigma_hash));
379 newfh->next = fh->next;
380 fh->next = newfh;
381 newfh->symbol = symdup;
382 newfh->sym = symnum;
383 }
384 return symnum;
385}
386
387int fsm_construct_check_symbol(struct fsm_construct_handle *handle, char *symbol) {
388 int hash;
389 struct fsm_sigma_hash *fh;
390 hash = fsm_construct_hash_sym(symbol);
391 fh = (handle->fsm_sigma_hash)+hash;
392 if (fh->symbol == NULL((void*)0))
393 return -1;
394 for (; fh != NULL((void*)0); fh = fh->next) {
395 if (strcmp(symbol,fh->symbol) == 0) {
396 return (fh->sym);
397 }
398 }
399 return -1;
400}
401
402struct sigma *fsm_construct_convert_sigma(struct fsm_construct_handle *handle) {
403 struct fsm_sigma_list *sl;
404 struct sigma *sigma, *oldsigma, *newsigma;
405 int i;
406 oldsigma = sigma = NULL((void*)0);
407 sl = handle->fsm_sigma_list;
408 for (i=0; i <= handle->maxsigma; i++) {
409 if ((sl+i)->symbol != NULL((void*)0)) {
410 newsigma = malloc(sizeof(struct sigma));
411 newsigma->number = i;
412 newsigma->symbol = (sl+i)->symbol;
413 newsigma->next = NULL((void*)0);
414 if (oldsigma != NULL((void*)0)) {
415 oldsigma->next = newsigma;
416 } else {
417 sigma = newsigma;
418 }
419 oldsigma = newsigma;
420 }
421 }
422 return(sigma);
423}
424
425struct fsm *fsm_construct_done(struct fsm_construct_handle *handle) {
426 int i, emptyfsm;
427 struct fsm *net;
428 struct fsm_state_list *sl;
429 struct fsm_trans_list *trans, *transnext;
430 struct fsm_sigma_hash *sigmahash, *sigmahashnext;
431
432 sl = handle->fsm_state_list;
433 if (handle->maxstate == -1 || handle->numfinals == 0 || handle->hasinitial == 0) {
434 return(fsm_empty_set());
435 }
436 fsm_state_init((handle->maxsigma)+1);
437
438 for (i=0, emptyfsm = 1; i <= handle->maxstate; i++) {
439 fsm_state_set_current_state(i, (sl+i)->is_final, (sl+i)->is_initial);
440 if ((sl+i)->is_initial && (sl+i)->is_final)
441 emptyfsm = 0; /* We want to keep track of if FSM has (a) something outgoing from initial, or (b) initial is final */
442 for (trans = (sl+i)->fsm_trans_list; trans != NULL((void*)0); trans = trans->next) {
443 if ((sl+i)->is_initial)
444 emptyfsm = 0;
445 fsm_state_add_arc(i, trans->in, trans->out, trans->target, (sl+i)->is_final, (sl+i)->is_initial);
446 }
447 fsm_state_end_state();
448 }
449 net = fsm_create("");
450 sprintf(net->name, "%X",rand());
451 free(net->sigma);
452 fsm_state_close(net);
453
454 net->sigma = fsm_construct_convert_sigma(handle);
455 if (handle->name != NULL((void*)0)) {
456 strncpy(net->name, handle->name, 40);
457 free(handle->name);
458 } else {
459 sprintf(net->name, "%X",rand());
460 }
461
462 /* Free transitions */
463 for (i=0; i < handle->fsm_state_list_size; i++) {
464 trans = (((handle->fsm_state_list)+i)->fsm_trans_list);
465 while (trans != NULL((void*)0)) {
466 transnext = trans->next;
467 free(trans);
468 trans = transnext;
469 }
470 }
471 /* Free hash table */
472 for (i=0; i < SIGMA_HASH_SIZE1021; i++) {
473 sigmahash = (((handle->fsm_sigma_hash)+i)->next);
474 while (sigmahash != NULL((void*)0)) {
475 sigmahashnext = sigmahash->next;
476 free(sigmahash);
477 sigmahash = sigmahashnext;
478 }
479 }
480 free(handle->fsm_sigma_list);
481 free(handle->fsm_sigma_hash);
482 free(handle->fsm_state_list);
483 free(handle);
484 sigma_sort(net);
485 if (emptyfsm) {
486 fsm_destroy(net);
487 return(fsm_empty_set());
488 }
489 return(net);
490}
491
492/* Reading functions */
493
494int fsm_read_is_final(struct fsm_read_handle *h, int state) {
495 return (*((h->lookuptable)+state) & 2);
496}
497
498int fsm_read_is_initial(struct fsm_read_handle *h, int state) {
499 return (*((h->lookuptable)+state) & 1);
500}
501
502struct fsm_read_handle *fsm_read_init(struct fsm *net) {
503 struct fsm_read_handle *handle;
504 struct fsm_state *fsm, **states_head;
505 int i, j, k, num_states, num_initials, num_finals, sno, *finals_head, *initials_head, laststate;
506
507 unsigned char *lookuptable;
508 if (net == NULL((void*)0)) {return (NULL((void*)0));}
509
510 num_states = net->statecount;
511 lookuptable = calloc(num_states, sizeof(unsigned char));
512
513 num_initials = num_finals = 0;
514
515 handle = calloc(1,sizeof(struct fsm_read_handle));
516 states_head = calloc(num_states+1,sizeof(struct fsm **));
Result of 'calloc' is converted to a pointer of type 'struct fsm_state *', which is incompatible with sizeof operand type 'struct fsm **'
517
518 laststate = -1;
519 for (i=0, fsm=net->states; (fsm+i)->state_no != -1; i++) {
520 sno = (fsm+i)->state_no;
521 if ((fsm+i)->start_state) {
522 if (!(*(lookuptable+sno) & 1)) {
523 *(lookuptable+sno) |= 1;
524 num_initials++;
525 }
526
527 }
528 if ((fsm+i)->final_state) {
529 if (!(*(lookuptable+sno) & 2)) {
530 *(lookuptable+sno) |= 2;
531 num_finals++;
532 }
533 }
534 if ((fsm+i)->in == UNKNOWN1 || (fsm+i)->out == UNKNOWN1 || (fsm+i)->in == IDENTITY2 || (fsm+i)->out == IDENTITY2) {
535 handle->has_unknowns = 1;
536 }
537 if ((fsm+i)->state_no != laststate) {
538 *(states_head+(fsm+i)->state_no) = fsm+i;
539 }
540 laststate = (fsm+i)->state_no;
541 }
542
543 finals_head = calloc(num_finals+1,sizeof(int));
544 initials_head = calloc(num_initials+1,sizeof(int));
545
546
547 for (i=j=k=0; i < num_states; i++) {
548 if (*(lookuptable+i) & 1) {
549 *(initials_head+j) = i;
550 j++;
551 }
552 if (*(lookuptable+i) & 2) {
553 *(finals_head+k) = i;
554 k++;
555 }
556 }
557 *(initials_head+j) = -1;
558 *(finals_head+k) = -1;
559
560 handle->finals_head = finals_head;
561 handle->initials_head = initials_head;
562 handle->states_head = states_head;
563
564 handle->fsm_sigma_list = sigma_to_list(net->sigma);
565 handle->sigma_list_size = sigma_max(net->sigma)+1;
566 handle->arcs_head = fsm;
567 handle->lookuptable = lookuptable;
568 handle->net = net;
569 return(handle);
570}
571
572void fsm_read_reset(struct fsm_read_handle *handle) {
573 if (handle == NULL((void*)0))
574 return;
575 handle->arcs_cursor = NULL((void*)0);
576 handle->initials_cursor = NULL((void*)0);
577 handle->finals_cursor = NULL((void*)0);
578 handle->states_cursor = NULL((void*)0);
579}
580
581int fsm_get_next_state_arc(struct fsm_read_handle *handle) {
582 handle->arcs_cursor++;
583 if ((handle->arcs_cursor->state_no != handle->current_state) || (handle->arcs_cursor->target == -1)) {
584 handle->arcs_cursor--;
585 return 0;
586 }
587 return 1;
588}
589
590int fsm_get_next_arc(struct fsm_read_handle *handle) {
591 if (handle->arcs_cursor == NULL((void*)0)) {
592 handle->arcs_cursor = handle->arcs_head;
593 while (handle->arcs_cursor->state_no != -1 && handle->arcs_cursor->target == -1) {
594 handle->arcs_cursor++;
595 }
596 if (handle->arcs_cursor->state_no == -1) {
597 return 0;
598 }
599 } else {
600 if (handle->arcs_cursor->state_no == -1) {
601 return 0;
602 }
603 do {
604 handle->arcs_cursor++;
605 } while (handle->arcs_cursor->state_no != -1 && handle->arcs_cursor->target == -1);
606 if (handle->arcs_cursor->state_no == -1) {
607 return 0;
608 }
609 }
610 return 1;
611}
612
613int fsm_get_arc_source(struct fsm_read_handle *handle) {
614 if (handle->arcs_cursor == NULL((void*)0)) { return -1;}
615 return(handle->arcs_cursor->state_no);
616}
617
618int fsm_get_arc_target(struct fsm_read_handle *handle) {
619 if (handle->arcs_cursor == NULL((void*)0)) { return -1;}
620 return(handle->arcs_cursor->target);
621}
622
623int fsm_get_symbol_number(struct fsm_read_handle *handle, char *symbol) {
624 int i;
625 for (i=0; i < handle->sigma_list_size; i++) {
626 if ((handle->fsm_sigma_list+i)->symbol == NULL((void*)0))
627 continue;
628 if (strcmp(symbol, (handle->fsm_sigma_list+i)->symbol) == 0) {
629 return i;
630 }
631 }
632 return -1;
633}
634
635char *fsm_get_arc_in(struct fsm_read_handle *handle) {
636 int index;
637 char *sym;
638 if (handle->arcs_cursor == NULL((void*)0)) { return NULL((void*)0);}
639 index = handle->arcs_cursor->in;
640 sym = (handle->fsm_sigma_list+index)->symbol;
641 return(sym);
642}
643
644int fsm_get_arc_num_in(struct fsm_read_handle *handle) {
645 if (handle->arcs_cursor == NULL((void*)0)) { return -1;}
646 return(handle->arcs_cursor->in);
647}
648
649int fsm_get_arc_num_out(struct fsm_read_handle *handle) {
650 if (handle->arcs_cursor == NULL((void*)0)) { return -1;}
651 return(handle->arcs_cursor->out);
652}
653
654char *fsm_get_arc_out(struct fsm_read_handle *handle) {
655 int index;
656 char *sym;
657 if (handle->arcs_cursor == NULL((void*)0)) { return NULL((void*)0); }
658 index = handle->arcs_cursor->out;
659 sym = (handle->fsm_sigma_list+index)->symbol;
660 return(sym);
661}
662
663int fsm_get_next_initial(struct fsm_read_handle *handle) {
664 if (handle->initials_cursor == NULL((void*)0)) {
665 handle->initials_cursor = handle->initials_head;
666 } else {
667 if (*(handle->initials_cursor) == -1) {
668 return -1;
669 }
670 handle->initials_cursor++;
671 }
672 return *(handle->initials_cursor);
673}
674
675int fsm_get_next_final(struct fsm_read_handle *handle) {
676 if (handle->finals_cursor == NULL((void*)0)) {
677 handle->finals_cursor = handle->finals_head;
678 } else {
679 if (*(handle->finals_cursor) == -1) {
680 return -1;
681 }
682 handle->finals_cursor++;
683 }
684 return *(handle->finals_cursor);
685}
686
687int fsm_get_num_states(struct fsm_read_handle *handle) {
688 return(handle->net->statecount);
689}
690
691int fsm_get_has_unknowns(struct fsm_read_handle *handle) {
692 return(handle->has_unknowns);
693}
694
695int fsm_get_next_state(struct fsm_read_handle *handle) {
696 int stateno;
697 if (handle->states_cursor == NULL((void*)0)) {
698 handle->states_cursor = handle->states_head;
699 } else {
700 handle->states_cursor++;
701 }
702 if (handle->states_cursor - handle->states_head >= fsm_get_num_states(handle)) {
703 return -1;
704 }
705 handle->arcs_cursor = *(handle->states_cursor);
706 stateno = (*(handle->states_cursor))->state_no;
707 handle->arcs_cursor--;
708 handle->current_state = stateno;
709 return (stateno);
710}
711
712void fsm_read_done(struct fsm_read_handle *handle) {
713 free(handle->lookuptable);
714 free(handle->fsm_sigma_list);
715 free(handle->finals_head);
716 free(handle->initials_head);
717 free(handle->states_head);
718 free(handle);
719}