Update the changelog
[opencv] / apps / cvenv / EiC / symbol.c
1 /* symbol.c
2  *
3  *      (C) Copyright Apr 15 1995, Edmond J. Breen.
4  *                 ALL RIGHTS RESERVED.
5  * This code may be copied for personal, non-profit use only.
6  *
7  */
8 /* Modified by Intel OpenCV team. Added lines 528-531 in order to prevent 
9    the parser exceptions throwing in specific cases. No guarantee that this 
10    is the fix for all cases. */
11
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include "typemod.h"
18 #include "MachSet.h"
19 #include  "global.h"
20 #include "lexer.h"
21 #include "xalloc.h"
22 #include "preproc.h"
23 #include "symbol.h"
24 #include "parser.h"
25 #include "global.h"
26 #include "func.h"
27
28
29
30 int EiC_iskeyword(keyword_t *keywords,char*id,int n)
31 {
32     int i;
33     for(i=0;i<n;i++)
34         if(strcmp(keywords[i].id,id) == 0)
35             return keywords[i].token;
36     return 0;
37 }
38
39 #define MoD 2
40 void EiC_eicpush(eicstack_t *s, val_t v)
41 {
42     if(!(s->n%MoD)) {
43         if(!s->n)
44             s->val = (val_t*)xcalloc(sizeof(val_t),MoD);
45         else
46             s->val = (val_t*)xrealloc(s->val,(s->n+MoD)*sizeof(val_t));
47     }
48     s->val[s->n] = v;
49     s->n++;
50 }
51
52 int EiC_eicpop(eicstack_t *s, val_t *pop)
53 {
54     if(s->n == 0)
55         return 0;
56     s->n--;
57     *pop = s->val[s->n];
58     if(!(s->n%MoD)) {           
59         if(!s->n)
60             xfree(s->val);
61         else
62             s->val = (val_t*)xrealloc(s->val,s->n*sizeof(val_t));
63     }
64     return 1;
65 }
66
67
68 /* LOOK UP TABLE ROUTINES
69    --------------------------*/
70
71 static size_t _EnTrY_No = 0;
72 int hashsmc(char * s,int mod);
73 symentry_t *EiC_HTAB[HSIZE];
74
75
76 /* code for generating tempories */
77 unsigned int NumTemps=0, CurTemp =0;
78
79 symentry_t * EiC_nxtTemp(int obj, int level)
80 {
81     symentry_t *sym;
82     char tmpName[50];
83     sprintf(tmpName,"%s%d","__TeMp",NumTemps);
84
85     /* There should be no need to watch out for change of level !!!!
86      * It will be assumed that the compound statement routine will
87      * handle it.
88      */
89
90
91     sym = EiC_insertLUT(EiC_work_tab,tmpName,obj);
92     NumTemps++;
93
94     CurTemp++;
95
96     if(sym->val.ival == -1) /* needs a home */ 
97         EiC_stackit(sym,level);
98
99     /* Setting up the token information is left
100      * to the caller of this routine.
101      */
102
103     sym->level = level;
104     return sym;
105 }    
106
107
108
109 size_t EiC_lut_NextEntryNum(void)
110 {
111     return _EnTrY_No;
112 }
113                              /*CUT EiChashFunc*/
114 int hashsmc(char * s,int mod)
115 {
116     register unsigned int h, c;
117     h = 0;
118     while(  (c = (int) *s++) > 0)
119         h =   (h << 1) + c;
120     return ( h % mod);
121 }
122                            /*END CUT*/
123
124                             /*CUT lutLookUp*/
125 int Pclash;
126
127 char *EiC_getClashedfname(char nspace,char *id)
128 {
129     symentry_t *sym;
130     for(sym = EiC_HTAB[hashsmc(id,HSIZE)]; sym != NULL; sym = sym->next)
131         if(sym->nspace == nspace && strcmp(id,sym->id) == 0)
132             if((sym->sclass & c_private) &&
133                sym->fname != CurrentFileName()) {
134                 return sym->fname;
135             }
136     return NULL;
137 }
138
139 symentry_t * EiC_lookup(char nspace, char *id)
140 {
141     symentry_t *sym;
142     Pclash = 0;
143     for(sym = EiC_HTAB[hashsmc(id,HSIZE)]; sym != NULL; sym = sym->next)
144         if(sym->nspace == nspace && strcmp(id,sym->id) == 0) {
145             if((sym->sclass & c_private) &&
146                sym->fname != CurrentFileName()) {
147                 Pclash = 1;
148                 continue;
149             }
150             else
151                 break;
152         }
153
154     return(sym);
155 }
156                              /*END CUT*/
157
158 /* function added by Sergey Oblomov (Intel OpenCV team member) */
159 symentry_t * EiC_lookup_by_callback(char nspace, void* callback)
160 {
161     symentry_t *sym;
162     int i;
163     Pclash = 0;
164     for( i = 0; i < HSIZE; i++ )
165         if( EiC_HTAB[i] )
166             for(sym = EiC_HTAB[i]; sym != NULL; sym = sym->next)
167                     if(sym->nspace == nspace)
168                     if( sym->type->obj == t_func && sym->type->u.inf &&
169                         ((func_t*)sym->type->u.inf)->callBack == callback )
170                         return sym;
171     return 0;
172 }
173
174
175                            /*CUT lutInsert*/
176 symentry_t * EiC_insertLUT(char nspace,char *id,int type)
177 {
178     symentry_t *sym;
179     auto int  hashval;
180
181     sym = (symentry_t *) xcalloc(1,sizeof(symentry_t));
182     if(sym == NULL)
183         return(NULL);
184     if( (sym->id = EiC_strsave(id)) == NULL) {
185         xfree(sym);
186         return(NULL);
187     }
188     sym->entry = _EnTrY_No++;
189     hashval = hashsmc(sym->id,HSIZE);
190     sym->next = EiC_HTAB[hashval];
191     EiC_HTAB[hashval] = sym;
192     sym->nspace = nspace;
193     sym->val.ival = -1;         /* indicates  unused */
194     sym->type = EiC_addtype(type,NULL);
195     sym->fname =  CurrentFileName();
196     return(sym);
197 }
198                            /*END CUT*/
199
200 void delete(symentry_t *sym)
201 {
202     auto symentry_t * this;
203     auto int idx;
204     
205     idx = hashsmc(sym->id,HSIZE);
206     this = EiC_HTAB[idx];
207     if(this == sym)
208         EiC_HTAB[idx] = sym->next;
209     else {                      /* find and unlink  */
210         while(this && this->next != sym)
211             this = this->next;
212         this->next = sym->next;
213     }
214 }
215
216 void EiC_UpdateSymPos(symentry_t * sym)
217 {
218
219     if(sym->next && sym->next->level > sym->level) {
220         symentry_t * p = EiC_HTAB[hashsmc(sym->id,HSIZE)];
221         delete(sym);
222         while(p->next != sym)
223             if(p->next) {
224                 if(p->next->level > sym->level)
225                     p=p->next;
226                 else {
227                     sym->next = p->next;
228                     p->next = sym;
229                 }
230             } else {
231                 p->next = sym;
232                 sym->next = NULL;
233             }
234     }
235 }
236
237 void EiC_remsym(symentry_t *sym)
238 {
239
240   delete(sym);
241   free_sym(sym);
242
243 }
244 /*END CUT*/
245
246 #if 1
247 void remBuiltin(symentry_t *sym)
248 {
249     /* removes the prototype of the builtin function only */
250     EiC_freetype(sym->type);
251     sym->type = EiC_addtype(t_builtin,NULL);
252     sym->fname = "::EiC::";
253 }
254 #endif
255
256
257 /*CUT lutRemLevel*/
258 void EiC_remlevel(int level)
259 {
260   int i;
261   symentry_t * sym, *symh;
262
263   for(i=0;i<HSIZE;i++) {
264     sym = EiC_HTAB[i];
265     while(sym && sym->level >= level) {
266       symh = sym->next;
267       free_sym(sym);
268       sym = symh;
269     }
270     EiC_HTAB[i] = sym;
271   }
272 }
273 /*END CUT*/
274 /*CUT lutRemTempories*/
275 void EiC_remTempories(void)
276 {
277   int i;
278   symentry_t * sym, *symh;
279
280   for(i=0;i<HSIZE;i++) {
281     sym = EiC_HTAB[i];
282     while(sym && IsTemp(sym->type)) {
283       symh = sym->next;
284       free_sym(sym);
285       sym = symh;
286     }
287     EiC_HTAB[i] = sym;
288   }
289 }
290 /*END CUT*/
291
292
293
294 int  EiC_lutClearFileEntries(char *FileName)
295 {
296
297     int i;
298     symentry_t * sym, *p, *t;
299
300     for(i=0;i<HSIZE;i++) {
301         t = sym = EiC_HTAB[i];
302         p = NULL;
303         while(sym){
304             if(strcmp(sym->fname,FileName) == 0) {
305                 if(p)
306                     p->next = sym->next;
307                 else
308                     t = sym->next;
309                 free_sym(sym);
310                 if(!p) {
311                     sym = t;
312                     continue;
313                 }
314             } else
315                 p = sym;
316             sym=p->next;
317         }
318         EiC_HTAB[i] = t;
319     }
320     return 1;
321
322 }
323                     /*END CUT*/
324                      /*CUT lutCleanUp*/
325
326 void EiC_lut_CleanUp(size_t bot)
327 {
328
329     int i;
330     symentry_t * sym, *p, *t;
331     for(i=0;i<HSIZE;i++) {
332         t = sym = EiC_HTAB[i];
333         p = NULL;
334         while(sym){
335             if(sym->entry >= bot) {
336                 if(EiC_gettype(sym->type) == t_builtin) {
337                     remBuiltin(sym);
338                     p = sym;
339                 } else {
340                     if(p)
341                         p->next = sym->next;
342                     else
343                         t = sym->next;
344                     free_sym(sym);
345                     if(!p) {
346                         sym = t;
347                         continue;
348                     }
349                 }
350             } else
351                 p = sym;
352             sym=p->next;
353         }
354         EiC_HTAB[i] = t;
355     }
356
357 }
358                      /*END CUT*/
359                      /*CUT lutFreeSym*/
360
361 #define freeAg(X)   do {\
362                             symentry_t *x = X; \
363                             if(!isconst(x->type)) \
364                                  xfree(EiC_ENV->AR[x->val.ival].v.p.p);\
365                             else xfree(x->val.p.p);\
366                     } while (0)
367
368
369 #define freeAg1(X)  xfree(EiC_ENV->AR[X->val.ival].v.p.p)
370
371
372 static void free_sym(symentry_t *sym)
373 {
374
375 #if 0    
376       printf("Freeing [%s] %d  %d [%d]\n",
377         sym->id, sym->entry, sym->val.ival,EiC_gettype(sym->type));
378     
379 #endif    
380     
381     if(EiC_gettype(sym->type) == t_func) {
382         EiC_killcode(sym);
383     } else if(sym->level == 1)  { /* global value */
384         int t;
385         if((t=EiC_gettype(sym->type)) == t_array && sym->val.ival >=0) 
386             freeAg(sym);
387         else if ((t== t_union || t == t_struct) && sym->val.ival >=0 ) 
388             freeAg(sym);
389                 
390     }
391
392
393     /*
394      * the conditions for pushing  onto the ARgar stack
395      * must be the same as those for stacking as found in
396      * function establish_id
397      * Except for ParseError
398      */
399     if( sym->val.ival >=0
400        && sym->level == 1
401        && EiC_gettype(sym->type) != t_builtin ) {
402         if(! isconst(sym->type)
403            && sym->nspace == stand_tab
404            && sym->sclass != c_typedef) {
405             EiC_eicpush(&EiC_ENV->ARgar,sym->val);
406         }
407     }
408     EiC_freetype(sym->type);
409     xfree(sym->id);
410     xfree(sym);
411 }
412                         /*END CUT*/
413
414 void EiC_UpdateEntry(symentry_t *sym)
415 {
416     int t = EiC_gettype(sym->type);
417     if(CurrentFileName() != sym->fname &&
418        t != t_func &&
419        t != t_funcdec &&
420        t != t_builtin)
421         return;
422     sym->entry =  _EnTrY_No++;
423     sym->pname = sym->fname;
424     sym->fname = CurrentFileName();
425 }
426
427 void EiC_addoffsettolevel(char nspace,int level,int off)
428 {
429     int i;
430     symentry_t * sym;
431
432     for(i=0;i<HSIZE;i++) {
433         sym = EiC_HTAB[i];
434         while(sym && sym->level == level && sym->nspace == nspace) {
435             sym->val.ival = -(sym->val.ival + off);
436             sym = sym->next;
437         }
438     }
439 }
440
441 void EiC_marktype(type_expr *type, char mark)
442 {
443     int i;
444     struct_t *s;
445     void EiC_markFunc(type_expr *t,int mark);
446     
447     while(type) {
448         xmark(type,mark);
449         switch(EiC_gettype(type)) {
450           case t_builtin:
451             if(EiC_getInf(type) == NULL)
452                 break;
453           case t_funcdec:
454           case t_func:
455             EiC_markFunc(type,mark);
456             break;
457           case t_union:
458           case t_struct:
459             if(type->alias)
460                 break;
461             s = EiC_getInf(type);
462             /*
463              * REM must allow for incomplete
464              * types.
465              */
466             if(!s)
467                 break;
468             xmark(s,mark);
469             if(!s->cl)
470                 break;
471             xmark(s->offset,mark);
472             xmark(s->id,mark);
473             xmark(s->type,mark);
474             for(i=0;i<s->n;i++) {
475                 xmark(s->id[i],mark);
476                 EiC_marktype(s->type[i],mark);
477             }
478             if(s->ntags) {
479                 xmark(s->tag,mark);
480                 for(i=0;i<s->ntags;++i)
481                     EiC_marktype(s->tag[i],mark);
482             }
483             break;
484         }
485         type = nextType(type);
486     }
487 }
488
489 static void marklabel(Label_t *l,char mark) 
490 {
491     while(l) {
492         xmark(l,mark);
493         xmark(l->name,mark);
494         l = l->nxt;
495     }
496 }
497
498 static void markcode(symentry_t *sym,char mark)
499 {
500     int i;
501     InsT_t *inst;
502     code_t * code;
503     code = EiC_ENV->AR[sym->val.ival].v.p.p;
504     xmark(code,mark);
505     xmark(code->inst,mark);
506     marklabel(code->labels,mark);
507     marklabel(code->gotos,mark);
508
509     inst = code->inst;
510     for(i=0;i<code->nextinst;i++,inst++)
511         if(inst->opcode == jmptab) {
512             eicstack_t * s;
513             s = inst->val.p.p;
514             xmark(s->val,mark);
515             xmark(s,mark);
516         } else if(inst->opcode == assigntype)
517             EiC_marktype(inst->val.p.p,mark);
518 }
519
520
521 void EiC_marksyms(char mark)
522 {
523     void EiC_markmacros(char);
524     void EiC_markENV(char);
525     
526     int i;
527     symentry_t * sym;
528
529     EiC_markmacros(mark);
530     
531     if(EiC_ENV->AR)
532         xmark(EiC_ENV->AR,mark);
533     if(EiC_ENV->ARgar.n) 
534         xmark(EiC_ENV->ARgar.val,mark);
535     if(EiC_ENV->LAR)
536         xmark(EiC_ENV->LAR,mark);
537     if(EiC_ENV->CODE.nextinst)
538         xmark(EiC_ENV->CODE.inst,mark);
539     xmark(EiC_ENV,mark);
540
541     EiC_markENV(mark);
542     
543     for(i=0;i<HSIZE;i++) {
544         sym = EiC_HTAB[i];
545         while(sym) {
546             /*printf("marking %s\n",sym->id);*/
547             if(strcmp(sym->id,"p") == 0)
548               sym->id = sym->id;
549             xmark(sym,mark);
550             xmark(sym->id,mark);
551             EiC_marktype(sym->type,mark);           
552             if(sym->nspace != tag_tab)
553                 switch(EiC_gettype(sym->type)) {
554                   case t_func: markcode(sym,mark); break;
555                   case t_array:
556                   case t_union:
557                   case t_struct:
558                     if(isconst(sym->type))
559                        xmark(sym->val.p.p,mark);
560                     else
561                         if(sym->sclass != c_typedef && sym->val.ival >= 0)
562                             xmark(EiC_ENV->AR[sym->val.ival].v.p.p,mark);
563                     break;
564                 }
565             sym = sym->next;
566         }
567     }
568 }
569
570
571 char * EiC_strsave(char *s)
572 {
573     char *p;
574     int n;
575
576     for(n = 0,p =s; *p != '\0';++p,++n)
577         ;
578     n++;
579     p = xcalloc(n,sizeof(char));
580     if(p) 
581         while((*p++ = *s++));
582     return p - n;
583 }
584
585 void EiC_newsymtype(symentry_t *sym, type_expr *t)
586 {
587     if(sym) {
588         if(sym->type && sym->type != t)
589             EiC_freetype(sym->type);
590         sym->type = t;
591     }
592 }
593
594 int nextstackitem(int level)
595 {
596     if(level == 1) {            /* static variables */
597         val_t v;
598         if(!EiC_eicpop(&EiC_ENV->ARgar,&v))  { /* check for spare slots */
599             if(EiC_ENV->sp == EiC_ENV->ARsize) {
600                 if(!EiC_ENV->ARsize)
601                     EiC_ENV->AR = (AR_t*)xcalloc(sizeof(AR_t),1);
602                 else
603                     EiC_ENV->AR = (AR_t*)xrealloc(EiC_ENV->AR,
604                                               (EiC_ENV->sp+1)*sizeof(AR_t));
605                 EiC_ENV->ARsize++;
606             }
607             v.ival = EiC_ENV->sp;
608             EiC_ENV->sp++;
609         }
610         return v.ival;
611     } else {                    /* automatic variables */
612         if(EiC_ENV->lsp == EiC_ENV->LARsize) {
613             if(!EiC_ENV->LARsize)
614                 EiC_ENV->LAR = (AR_t*)xcalloc(sizeof(AR_t),1);
615             else
616                 EiC_ENV->LAR = (AR_t*)xrealloc(EiC_ENV->LAR,(EiC_ENV->lsp+1)*
617                                            sizeof(AR_t));
618             EiC_ENV->LARsize++;
619         }
620         EiC_ENV->lsp++;
621         return EiC_ENV->lsp - 1;
622     }
623 }
624
625 int EiC_stackit(symentry_t * sym,int level)
626 {
627     int i;
628     AR_t * ar;
629     
630     i = nextstackitem(level);
631     if(level == 1)              /* static variables */
632         ar = EiC_ENV->AR;
633     else                        /* local variable */    
634         ar = EiC_ENV->LAR;
635
636     sym->val.ival = i;
637
638     ar[i].v.dval = 0; /* NULL it */
639     ar[i].type = sym->type;
640     return i;
641 }
642
643
644 /*------------------------------------------------*/
645 void EiC_inittoken(token_t * e1)
646 {
647     e1->Pflag = 0;
648     e1->Code.binst = e1->Code.nextinst = 0;
649     e1->Code.labels = e1->Code.gotos = NULL;
650     e1->Typequal = e1->Sclass = 0;
651     e1->Sym = NULL;
652     e1->Val.sym = NULL;
653     e1->Type = NULL;
654 }
655 void EiC_freetoken(token_t * e1)
656 {
657     EiC_freetype(e1->Type);
658     e1->Type = NULL;
659 }
660 void initcode(code_t * code)
661 {
662     code->binst = code->nextinst = 0;
663 }
664
665
666 void EiC_cleancode(code_t * code)
667 {
668     unsigned int i;
669     InsT_t *inst;
670
671     if(!code)
672         return;
673     inst = code->inst;
674     /* printf("Next instr: %d\n", code->nextinst); */
675     /* rem free up other info also */
676     for(i=0;i<code->nextinst;i++,inst++)
677         if(inst->opcode == jmptab) {
678             eicstack_t *s;
679             s = inst->val.p.p;
680             xfree(s->val);
681             xfree(s);
682         } else if(inst->opcode == assigntype)
683             EiC_freetype(inst->val.p.p);
684
685 }    
686
687 static void freeCodeLabels(code_t *code)
688 {
689     void EiCp_freeLabels(Label_t *lab);
690     if(code->labels) {
691         EiCp_freeLabels(code->labels);
692         code->labels = NULL;
693     }
694     if(code->gotos) {
695         EiCp_freeLabels(code->gotos);
696         code->gotos = NULL;
697     }
698 }
699
700 void EiC_killcode(symentry_t *sym)
701 {
702     code_t * code;
703     code = EiC_ENV->AR[sym->val.ival].v.p.p;
704     if(!code)
705         return;
706     EiC_cleancode(code);
707     freeCodeLabels(code);
708     xfree(code->inst);
709     xfree(code);
710 }
711 void EiC_freecode(code_t * code)
712 {
713
714     if(code && code->binst > 0) {
715         xfree(code->inst);
716         code->nextinst = code->binst = 0;
717         freeCodeLabels(code);
718     }
719 }
720
721 #define ModSize 5
722
723 void EiC_generate(code_t * code, int opcode,val_t *val,int ext)
724 {
725     InsT_t * inst;
726     inst = code->inst;
727     if(code->nextinst == code->binst)
728         if(!(code->binst%ModSize)) {
729             if(!code->binst)
730                 inst = (InsT_t*)xcalloc(1,sizeof(InsT_t)*ModSize);
731             else
732                 inst = (InsT_t*)
733                     xrealloc(inst,(code->binst+ModSize)*sizeof(InsT_t));
734             code->binst += ModSize;
735         }
736     code->inst = inst;
737     inst[code->nextinst].opcode = opcode;
738     inst[code->nextinst].val = *val;
739     inst[code->nextinst].ext = ext;
740     inst[code->nextinst].line = CurrentLineNo();
741     code->nextinst++;
742 }
743
744 #if 0
745 void copycode(code_t * c1, code_t * c2)
746 {
747     /* this function needs to handle label and gotos */
748     unsigned int i;
749     InsT_t *inst;
750     inst = c2->inst;
751     for(i=0;i<c2->nextinst;++i,++inst) {
752         EiC_generate(c1,inst->opcode,&inst->val,inst->ext);
753         c1->inst[c1->nextinst-1].line = inst->line;
754     }
755 }
756 #else
757 void copycode(code_t * c1, code_t * c2)
758 {
759     Label_t * EiCp_addLabel(Label_t *, char *, int, int);
760     InsT_t *inst;
761     int h, Tsize;
762     Label_t *lab;
763
764     if(!c2->nextinst)
765         return;
766     /* concatenate labels*/
767     if(c2->labels) {
768         lab = c2->labels;
769         while(lab) {
770             c1->labels = EiCp_addLabel(c1->labels,lab->name,lab->loc+c1->nextinst,1);
771             lab = lab->nxt;
772         }
773     }
774     /* conatenate gotos */
775     if(c2->gotos) {
776         lab = c2->gotos;
777         while(lab) {
778             c1->gotos = EiCp_addLabel(c1->gotos,lab->name,lab->loc+c1->nextinst,0);
779             lab = lab->nxt;
780         }
781     }
782
783     Tsize = c1->nextinst + c2->nextinst;
784     /* make memory size a multiple of ModSize */
785     h = Tsize;
786     if(Tsize%ModSize) 
787         Tsize += ModSize - (Tsize%ModSize);
788     if(c1->binst)
789         c1->inst = xrealloc(c1->inst,Tsize*sizeof(InsT_t));
790     else
791         c1->inst = xcalloc(Tsize,sizeof(InsT_t));
792     inst = c1->inst;
793     memcpy(&inst[c1->nextinst], c2->inst, c2->nextinst * sizeof(InsT_t));
794     c1->binst = Tsize;
795     c1->nextinst = h;
796 }
797
798 #endif
799
800 void EiC_concode(code_t * c1, code_t * c2)
801 {
802     copycode(c1,c2);
803     EiC_freecode(c2);
804 }
805 void EiC_contoken(token_t * e1, token_t * e2)
806 {
807     EiC_concode(&e1->Code,&e2->Code);
808     e1->Type = EiC_getcontype(e1->Type,e2->Type);
809     EiC_freetoken(e2);
810 }
811
812 void EiC_swaptokens(token_t *e1, token_t * e2)
813 {
814     token_t e3;
815     e3 = *e2;
816     *e2 = *e1;
817     *e1 = e3;
818 }
819     
820
821 #if 0
822
823 typedef struct list_t {
824     char * fname;
825     struct list_t *nxt;
826 }list_t;
827
828
829 typdef struct llist_t {
830     list_t **list;
831     int n;
832 } llist_t;
833
834 static llist_t ** includes = NULL, ** included = NULL;
835
836 static int inllist(llist_t **list, char *fname)
837 {
838     /* returns -1 if not in list */
839     int i;
840     for(i=0;i<list->n,++i) {
841         if(fname == list->list[i]->fname == 0)
842             return i;
843     }
844     return -1;
845 }
846
847 static list_t * add2list(list_t *list, char *fname)
848 {
849    list_t n = calloc(sizeof(list_t),1);
850    n->fname = fname;
851    n->nxt = list;
852    return n;
853 }
854
855
856 static void add2includes(char *file, char * includes)
857 {
858     int i = inlist(includes,file);
859
860     if(i < 0) {
861         i = includes->n;
862         includes->list = realloc(includes->list, 
863                                  (includes->n + 1) * sizeof(*includes->list));
864         
865         includes->list = 
866         includes
867
868
869
870
871
872 #endif
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889