1 /* xa65 - 65xx/65816 cross-assembler and utility suite
2 *
3 * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de)
4 * Maintained by Cameron Kaiser
5 *
6 * File handling and preprocessor (also see xaa.c) module
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <ctype.h>
26 #include <string.h>
27 #ifndef _MSC_VER
28 #include <strings.h>
29 #endif
30
31 #include "xad.h"
32 #include "xah.h"
33 #include "xah2.h"
34
35 #include "xar.h"
36 #include "xa.h"
37 #include "xam.h"
38 #include "xal.h"
39 #include "xat.h"
40 #include "xap.h"
41
42 /* define this for recursive evaluation output */
43 /* #define DEBUG_RECMAC */
44
45 char s[MAXLINE];
46 Datei *filep;
47
48 static int tcompare(char*,char**,int);
49 static int pp_replace(char*,char*,int,int);
50 static int searchdef(char*);
51 static int fgetline(char*,int len, int *rlen, FILE*);
52
53 static int icl_open(char*),pp_ifdef(char*),pp_ifndef(char*);
54 static int pp_else(char*),pp_endif(char*);
55 static int pp_echo(char*),pp_if(char*),pp_print(char*),pp_prdef(char*);
56 static int pp_ifldef(char*),pp_iflused(char*);
57 static int pp_undef(char*);
58
59 #define ANZBEF 13
60 #define VALBEF 6
61
62 static int ungeteof = 0;
63
64 static char *cmd[]={ "echo","include","define","undef","printdef","print",
65 "ifdef","ifndef","else","endif",
66 "ifldef","iflused","if" };
67
68 static int (*func[])(char*) = { pp_echo,icl_open,pp_define,pp_undef,
69 pp_prdef,pp_print, pp_ifdef,pp_ifndef,
70 pp_else,pp_endif,
71 pp_ifldef,pp_iflused,pp_if };
72
73 static char *mem;
74 static unsigned long memfre;
75 static int nlf;
76 static int nff;
77 static int hashindex[256];
78
79 static List *liste;
80 static unsigned int rlist;
81 static int fsp;
82 static int loopfl;
83 static Datei flist[MAXFILE+1];
84 static char in_line[MAXLINE];
85
pp_comand(char * t)86 int pp_comand(char *t)
87 {
88 int i,l,er=1;
89
90 i=tcompare(t,cmd,ANZBEF);
91
92 if(i>=0)
93 {
94 if(loopfl && (i<VALBEF))
95 er=0;
96 else
97 {
98 l=(int)strlen(cmd[i]);
99 while(isspace(t[l])) l++;
100
101 er=(*func[i])(t+l);
102 }
103 }
104 return(er);
105 }
106
pp_ifdef(char * t)107 int pp_ifdef(char *t)
108 {
109 /* int x;
110 printf("t=%s\n",t);
111 x=searchdef(t);
112 printf("searchdef(t)=%d\n",x);
113 */
114 loopfl=(loopfl<<1)+( searchdef(t) ? 0 : 1 );
115 return(0);
116 }
117
pp_ifndef(char * t)118 int pp_ifndef(char *t)
119 {
120 loopfl=(loopfl<<1)+( searchdef(t) ? 1 : 0 );
121 return(0);
122 }
123
pp_ifldef(char * t)124 int pp_ifldef(char *t)
125 {
126 loopfl=(loopfl<<1)+( ll_pdef(t) ? 1 : 0 );
127 return(0);
128 }
129
pp_iflused(char * t)130 int pp_iflused(char *t)
131 {
132 int n;
133 loopfl=(loopfl<<1)+( ll_search(t,&n) ? 1 : 0 );
134 return(0);
135 }
136
pp_echo(char * t)137 int pp_echo(char *t)
138 {
139 int er;
140
141 if((er=pp_replace(s,t,-1,rlist)))
142 errout(er);
143 else
144 {
145 logout(s);
146 logout("\n");
147 }
148 return(0);
149 }
150
pp_print(char * t)151 int pp_print(char *t)
152 {
153 int f,a,er;
154
155 logout(t);
156 if((er=pp_replace(s,t,-1,rlist)))
157 {
158 logout("\n");
159 errout(er);
160 }
161 else
162 {
163 logout("=");
164 logout(s);
165 logout("=");
166 er=b_term(s,&a,&f,pc[segment]);
167 if(er)
168 {
169 logout("\n");
170 errout(er);
171 }
172 else
173 { sprintf(s,"%d\n",a); logout(s); }
174 }
175
176 return(0);
177 }
178
pp_if(char * t)179 int pp_if(char *t)
180 {
181 int a,f,l,er;
182
183 if((er=pp_replace(s,t,-1,rlist)))
184 errout(er);
185 else
186 {
187 dsb_len = 1;
188 f=b_term(s,&a,&l,pc[segment]);
189 dsb_len = 0;
190
191 if((!loopfl) && f)
192 errout(f);
193 else
194 loopfl=(loopfl<<1)+( a ? 0 : 1 );
195 }
196 return(0);
197 }
198
pp_else(char * t)199 int pp_else(char *t)
200 {
201 (void)t; /* quench warning */
202 loopfl ^=1;
203 return(0);
204 }
205
pp_endif(char * t)206 int pp_endif(char *t)
207 {
208 (void)t; /* quench warning */
209 loopfl=loopfl>>1;
210 return(0);
211 }
212
213
214 /* stub for handling CPP directives */
pp_cpp(char * t)215 int pp_cpp(char *t) {
216 char name[MAXLINE];
217
218 if(sscanf(t, " %d \"%s\"", &filep->fline, name) == 2) {
219 /* massage it into our parameters and drop last quote */
220 char *u;
221
222 filep->fline--;
223 if((u = (char *)strrchr(name, '"')))
224 *u = '\0';
225
226 free(filep->fname);
227 filep->fname = strdup(name);
228 if(!filep->fname) {
229 fprintf(stderr,"Oops, no more memory!\n");
230 exit(1);
231 }
232 return (0);
233 } else {
234 return(E_SYNTAX);
235 }
236 }
237
238 /* pp_undef is a great hack to get it working fast... */
pp_undef(char * t)239 int pp_undef(char *t) {
240 int i;
241 if((i=searchdef(t))) {
242 i+=rlist;
243 liste[i].s_len=0;
244 }
245 return 0;
246 }
247
pp_prdef(char * t)248 int pp_prdef(char *t)
249 {
250 char *x;
251 int i,j;
252
253 if((i=searchdef(t)))
254 {
255 i+=rlist;
256 x=liste[i].search;
257 sprintf(s,"\n%s",x);
258 if(liste[i].p_anz)
259 {
260 sprintf(s+strlen(s),"(");
261 for(j=0;j<liste[i].p_anz;j++)
262 {
263 x+=strlen(x)+1;
264 sprintf(s+strlen(s),"%s%c",x,(liste[i].p_anz-j-1) ? ',' : ')');
265 }
266 }
267 sprintf(s+strlen(s),"=%s\n",liste[i].replace);
268 logout(s);
269 }
270 return(E_OK);
271 }
272
searchdef(char * t)273 int searchdef(char *t)
274 {
275 int i=0,j,k,l=0;
276
277 while(t[l]!=' ' && t[l]!='\0') l++;
278
279 if(rlist)
280 {
281 i=hashindex[hashcode(t,l)];
282
283 do /*for(i=0;i<rlist;i++)*/
284 {
285 k=liste[i].s_len;
286 j=0;
287
288 if(k && (k==l))
289 {
290 while((t[j]==liste[i].search[j])&&j<k) j++;
291 if(j==k)
292 break;
293 }
294
295 if(!i)
296 {
297 i=rlist;
298 break;
299 }
300
301 i=liste[i].nextindex;
302
303 } while(1);
304 }
305
306 return(i-rlist);
307 }
308
ga_pp(void)309 int ga_pp(void)
310 {
311 return(rlist);
312 }
313
gm_pp(void)314 int gm_pp(void)
315 {
316 return(ANZDEF);
317 }
318
gm_ppm(void)319 long gm_ppm(void)
320 {
321 return(MAXPP);
322 }
323
ga_ppm(void)324 long ga_ppm(void)
325 {
326 return(MAXPP-memfre);
327 }
328
pp_define(char * k)329 int pp_define(char *k)
330 {
331 int i,er=E_OK,hash,rl;
332 char h[MAXLINE*2],*t;
333 unsigned int j;
334
335 t=k;
336
337 if(rlist>=ANZDEF || memfre<MAXLINE*2)
338 return(E_NOMEM);
339 /*
340 printf("define:mem=%04lx\n",mem);
341 getchar();
342 */
343 rl=rlist++;
344
345 liste[rl].search=mem;
346 for(i=0; (t[i]!=' ') && (t[i]!='\0') && (t[i]!='(') ;i++)
347 *mem++=t[i];
348 *mem++='\0';
349 memfre-=i+1;
350 liste[rl].s_len=i;
351 liste[rl].p_anz=0;
352
353
354 /* printf("define:%s\nlen1=%d\n",liste[rl].search,liste[rl].s_len);
355 getchar();
356 */
357
358 if(t[i]=='(')
359 {
360 while(t[i]!=')' && t[i]!='\0')
361 {
362 i++;
363 liste[rl].p_anz++;
364 for(j=0; t[i+j]!=')' && t[i+j]!=',' && t[i+j]!='\0';j++);
365 if(j<memfre)
366 {
367 strncpy(mem,t+i,j);
368 mem+=j;
369 *mem++='\0';
370 memfre-=j+1;
371 }
372 i+=j;
373 }
374 if(t[i]==')')
375 i++;
376 }
377 while(t[i]==' ')
378 i++;
379 t+=i;
380
381 pp_replace(h,t,-1,0);
382
383 t=h;
384
385 liste[rl].replace=mem;
386 (void)strcpy(mem,t);
387 mem+=strlen(t)+1;
388 #if 0 /* debug */
389 { char *ss;
390 if(liste[rl].p_anz)
391 {
392 ss=liste[rl].search;
393 printf("define:\n%s(",liste[rl].search);
394 for(j=0;j<liste[rl].p_anz;j++)
395 {
396 ss+=strlen(ss)+1;
397 printf("%s%c",ss,(liste[rl].p_anz-j-1) ? ',' : ')');
398 }
399 printf("=%s\n",liste[rl].replace);
400 getchar();
401 }
402 else
403 {
404 printf("define:%s=%s\nlen1=%d\n",liste[rl].search,
405 liste[rl].replace,liste[rl].s_len);
406 }
407 }
408 #endif
409 if(!er)
410 {
411 hash=hashcode(liste[rl].search,liste[rl].s_len);
412 liste[rl].nextindex=hashindex[hash];
413 hashindex[hash]=rl;
414 } else
415 rlist=rl;
416
417 return(er);
418 }
419
tcompare(char s[],char * v[],int n)420 int tcompare(char s[],char *v[], int n)
421 {
422 int i,j,l;
423 static char t[MAXLINE];
424
425 for(i=0; s[i]!='\0'; i++)
426 t[i]=tolower(s[i]);
427 t[i]='\0';
428
429 for(i=0;i<n;i++)
430 {
431 l=(int)strlen(v[i]);
432
433 for(j=0;j<l;j++)
434 {
435 if(t[j]!=v[i][j])
436 break;
437 }
438 if(j==l)
439 break;
440 }
441 return((i==n)? -1 : i);
442 }
443
pp_replace(char * to,char * ti,int a,int b)444 int pp_replace(char *to, char *ti, int a,int b)
445 {
446 char *t=to,c,*x,*y,*mx,*rs;
447 int i,l,n,sl,d,ld,er=E_OK,hkfl,klfl;
448 char fti[MAXLINE],fto[MAXLINE];
449 /*
450 int flag=!strncmp(ti,"TOUT",4);
451 if(flag) printf("flag=%d\n",flag);
452 */
453 (void)strcpy(t,ti);
454
455 if(rlist)
456 {
457 while(t[0]!='\0')
458 {
459 /* find start of a potential token to be replaced */
460 while(!isalpha(t[0]) && t[0]!='_') {
461
462 /* escape strings quoted with " */
463 if (!ppinstr && t[0] == '\"') {
464 do {
465 t++;
466 ti++;
467 } while (t[0] && t[0]!='\"');
468 }
469
470 /* escape strings quoted with ' */
471 if (!ppinstr && t[0] == '\'') {
472 do {
473 t++;
474 ti++;
475 } while (t[0] && t[0]!='\'');
476 }
477
478 if(t[0]=='\0')
479 break; /*return(E_OK);*/
480 else
481 {
482 t++;
483 ti++;
484 }
485 }
486
487 for(l=0;isalnum(t[l])||t[l]=='_';l++);
488 ld=l;
489 /*
490 if(flag) printf("l=%d,a=%d,t=%s\n",l,a,t);
491 */
492 if(a<0)
493 {
494 n=hashindex[hashcode(t,l)];
495
496 do
497 {
498 sl=liste[n].s_len;
499
500 if(sl && (sl==l))
501 {
502 i=0;
503 x=liste[n].search;
504 while(t[i]==*x++ && t[i])
505 i++;
506
507 if(i==sl)
508 {
509 rs=liste[n].replace;
510
511 if(liste[n].p_anz)
512 {
513 (void)strcpy(fti,liste[n].replace);
514
515 if(rlist+liste[n].p_anz>=ANZDEF || memfre<MAXLINE*2)
516 er=E_NOMEM;
517 else
518 {
519 y=t+sl;
520 x=liste[n].search+sl+1;
521 if(*y!='(')
522 er=E_SYNTAX;
523 else
524 {
525 mx=mem-1;
526 for(i=0;i<liste[n].p_anz;i++)
527 {
528 liste[rlist+i].search=x;
529 liste[rlist+i].s_len=(int)strlen(x);
530 x+=strlen(x)+1;
531 liste[rlist+i].p_anz=0;
532 liste[rlist+i].replace=mx+1;
533 c=*(++mx)=*(++y);
534 hkfl=klfl=0;
535 while(c!='\0'
536 && ((hkfl!=0
537 || klfl!=0)
538 || (c!=','
539 && c!=')')
540 )
541 )
542 {
543 if(c=='\"')
544 hkfl=hkfl^1;
545 if(!hkfl)
546 {
547 if(c=='(')
548 klfl++;
549 if(c==')')
550 klfl--;
551 }
552 c=*(++mx)=*(++y);
553 }
554 *mx='\0';
555 if(c!=((i==liste[n].p_anz-1) ? ')' : ','))
556 {
557 er=E_ANZPAR;
558 break;
559 }
560 }
561 #ifdef DEBUG_RECMAC
562 printf("replace:\n");
563 printf("%s=%s\n",liste[n].search,liste[n].replace);
564 #endif
565 for(i=0;i<liste[n].p_anz;i++) {
566 /* recursively evaluate arguments */
567 char nfto[MAXLINE];
568 char nfwas[MAXLINE];
569 int j = 0;
570 int k;
571
572 (void)strcpy(nfwas, liste[rlist+i].replace);
573 if (!er)
574 er=pp_replace(nfto,nfwas,-1,rlist);
575 #ifdef DEBUG_RECMAC
576 printf("-%s=%s\n",liste[rlist+i].search,liste[rlist+i].replace);
577 printf("SUBB: -%s=%s\n", nfwas, nfto);
578 #endif
579 while ((k = strcmp(nfto, nfwas))) {
580 (void)strcpy(nfto, nfwas);
581 if (!er)
582 er=pp_replace(nfto,nfwas,-1,rlist);
583 (void)strcpy(nfwas, nfto);
584 #ifdef DEBUG_RECMAC
585 printf("SUBB2 (%i): -%s=%s\n", k, liste[rlist+i].replace, nfto);
586 #endif
587 if (++j>10)
588 errout(E_ORECMAC);
589 }
590 (void)strcpy(liste[rlist+i].replace, nfto);
591 #ifdef DEBUG_RECMAC
592 printf("FINAL: -%s=%s\n",liste[rlist+i].search,liste[rlist+i].replace);
593 #endif
594 }
595 if(!er)
596 er=pp_replace(fto,fti,rlist,rlist+i);
597 /* if(flag) printf("sl=%d,",sl);*/
598 sl=(int)((long)y+1L-(long)t);
599 /* if(flag) printf("sl=%d\n",sl);*/
600 rs=fto;
601 /* printf("->%s\n",fto);*/
602 }
603 }
604 if(er)
605 return(er);
606 }
607
608 d=(int)strlen(rs)-sl;
609
610 if(strlen(to)+d>=MAXLINE)
611 return(E_NOMEM);
612
613 /*
614 if(d<0)
615 {
616 y=t+sl+d;
617 x=t+sl;
618 while(*y++=*x++);
619 }
620 if(d>0)
621 {
622 for(ll=strlen(t);ll>=sl;ll--)
623 t[ll+d]=t[ll];
624 }
625 */
626 if(d)
627 (void)strcpy(t+sl+d,ti+sl);
628
629 i=0;
630 while((c=rs[i]))
631 t[i++]=c;
632 l=sl+d;/*=0;*/
633 break;
634 }
635 }
636 if(!n)
637 break;
638
639 n=liste[n].nextindex;
640
641 } while(1);
642 } else
643 {
644 for(n=b-1;n>=a;n--)
645 {
646 sl=liste[n].s_len;
647
648 if(sl && (sl==l))
649 {
650 i=0;
651 x=liste[n].search;
652 while(t[i]==*x++ && t[i])
653 i++;
654
655 if(i==sl)
656 {
657 rs=liste[n].replace;
658 if(liste[n].p_anz)
659 {
660 (void)strcpy(fti,liste[n].replace);
661 if(rlist+liste[n].p_anz>=ANZDEF || memfre<MAXLINE*2)
662 er=E_NOMEM;
663 else
664 {
665 y=t+sl;
666 x=liste[n].search+sl+1;
667 if(*y!='(')
668 er=E_SYNTAX;
669 else
670 {
671 mx=mem-1;
672 for(i=0;i<liste[n].p_anz;i++)
673 {
674 liste[rlist+i].search=x;
675 liste[rlist+i].s_len=strlen(x);
676 x+=strlen(x)+1;
677 liste[rlist+i].p_anz=0;
678 liste[rlist+i].replace=mx+1;
679 c=*(++mx)=*(++y);
680 hkfl=klfl=0;
681 while(c!='\0'
682 && ((hkfl!=0
683 || klfl!=0)
684 || (c!=','
685 && c!=')')
686 )
687 )
688 {
689 if(c=='\"')
690 hkfl=hkfl^1;
691 if(!hkfl)
692 {
693 if(c=='(')
694 klfl++;
695 if(c==')')
696 klfl--;
697 }
698 c=*(++mx)=*(++y);
699 }
700 *mx='\0';
701 if(c!=((i==liste[n].p_anz-1) ? ')' : ','))
702 {
703 er=E_ANZPAR;
704 break;
705 }
706 }
707 if(!er)
708 er=pp_replace(fto,fti,0,rlist+i);
709 sl=(int)((long)y+1L-(long)t);
710 rs=fto;
711 }
712 }
713 if(er)
714 return(er);
715 }
716 d=(int)strlen(rs)-sl;
717
718 if(strlen(to)+d>=MAXLINE)
719 return(E_NOMEM);
720 /*
721 if(d<0)
722 {
723 y=t+sl+d;
724 x=t+sl;
725 while(*y++=*x++);
726 }
727 if(d>0)
728 {
729 for(ll=strlen(t);ll>=sl;ll--)
730 t[ll+d]=t[ll];
731 }
732 */
733 if(d)
734 (void)strcpy(t+sl+d,ti+sl);
735
736 i=0;
737 while((c=rs[i]))
738 t[i++]=c;
739 l+=d;/*0;*/
740 break;
741 }
742 }
743 }
744 }
745 ti+=ld;
746 t+=l;
747 }
748 }
749 return(E_OK);
750 }
751
pp_init(void)752 int pp_init(void)
753 {
754 int er;
755
756 for(er=0;er<256;er++)
757 hashindex[er]=0;
758
759 fsp=0;
760
761 er=0;
762 mem=malloc(MAXPP);
763 if(!mem) er=E_NOMEM;
764
765 memfre=MAXPP;
766 rlist=0;
767 nlf=1;
768 nff=1;
769 if(!er) {
770 liste=malloc((long)ANZDEF*sizeof(List));
771 if(!liste) er=E_NOMEM;
772 }
773 return(er);
774 }
775
pp_open(char * name)776 int pp_open(char *name)
777 {
778 FILE *fp;
779
780 fp=xfopen(name,"r");
781
782 /* we have to alloc it dynamically to make the name survive another
783 pp_open - it's used in the cross-reference list */
784 flist[0].fname = malloc(strlen(name)+1);
785 if(!flist[0].fname) {
786 fprintf(stderr,"Oops, no more memory!\n");
787 exit(1);
788 }
789 (void)strcpy(flist[0].fname,name);
790 flist[0].fline=0;
791 flist[0].bdepth=b_depth();
792 flist[0].filep=fp;
793 flist[0].flinep=NULL;
794
795 return(((long)fp)==0l);
796 }
797
pp_close(void)798 void pp_close(void)
799 {
800 if(flist[fsp].bdepth != b_depth()) {
801 fprintf(stderr, "Blocks not consistent in file %s: start depth=%d, end depth=%d\n",
802 flist[fsp].fname, flist[fsp].bdepth, b_depth());
803 }
804 fclose(flist[fsp].filep);
805 }
806
pp_end(void)807 void pp_end(void) { }
808
pp_getidat(void)809 Datei *pp_getidat(void) {
810 return &flist[fsp];
811 }
812
icl_close(int * c)813 int icl_close(int *c)
814 {
815 *c='\n';
816 if(!fsp)
817 return(E_EOF);
818
819 if(flist[fsp].bdepth != b_depth()) {
820 fprintf(stderr, "Blocks not consistent in file %s: start depth=%d, end depth=%d\n",
821 flist[fsp].fname, flist[fsp].bdepth, b_depth());
822 }
823
824 fclose(flist[fsp--].filep);
825 nff=1;
826
827 return(E_OK);
828 }
829
icl_open(char * tt)830 int icl_open(char *tt)
831 {
832 FILE *fp2;
833 int j,i=0;
834
835 pp_replace(s,tt,-1,rlist);
836
837 if(fsp>=MAXFILE)
838 return(-1);
839
840 if(s[i]=='<' || s[i]=='"')
841 i++;
842
843 for(j=i;s[j];j++)
844 if(s[j]=='>' || s[j]=='"')
845 s[j]='\0';
846
847 fp2=xfopen(s+i,"r");
848
849 if(!fp2)
850 return(E_FNF);
851
852 setvbuf(fp2,NULL,_IOFBF,BUFSIZE);
853
854 fsp++;
855
856 /* we have to alloc it dynamically to make the name survive another
857 pp_open - it's used in the cross-reference list */
858 flist[fsp].fname = malloc(strlen(s+i)+1);
859 if(!flist[fsp].fname) {
860 fprintf(stderr,"Oops, no more memory!\n");
861 exit(1);
862 }
863 strcpy(flist[fsp].fname,s+i);
864 flist[fsp].fline=0;
865 flist[fsp].bdepth=b_depth();
866 flist[fsp].flinep=NULL;
867 flist[fsp].filep=fp2;
868 nff=1;
869
870 return(0);
871 }
872
pgetline(char * t)873 int pgetline(char *t)
874 {
875 int c,er=E_OK;
876 int rlen, tlen;
877 char *p = 0;
878
879 loopfl =0; /* set if additional fetch needed */
880
881 filep =flist+fsp;
882
883 do {
884 c=fgetline(in_line, MAXLINE, &rlen, flist[fsp].filep);
885 /* continuation lines */
886 tlen = rlen;
887 while(c=='\n' && tlen && in_line[tlen-1]=='\\') {
888 c=fgetline(in_line + tlen-1, MAXLINE-tlen, &rlen, flist[fsp].filep);
889 tlen += rlen-1;
890 }
891 if(in_line[0]=='#' || in_line[0] == altppchar)
892 {
893 if (in_line[1]==' ') { /* cpp comment -- pp_comand doesn't
894 handle this right */
895 er=pp_cpp(in_line+1);
896 } else {
897 if((er=pp_comand(in_line+1)))
898 {
899 if(er!=1)
900 {
901 logout(in_line);
902 logout("\n");
903 }
904 }
905 }
906 } else
907 er=1;
908
909 if(c==EOF) {
910 if (loopfl && fsp) {
911 char bletch[MAXLINE];
912 sprintf(bletch,
913 "at end of included file %s:\n", flist[fsp].fname);
914 logout(bletch);
915 errout(W_OPENPP);
916 }
917 er=icl_close(&c);
918 }
919
920 } while(!er || (loopfl && er!=E_EOF));
921
922 if (loopfl) {
923 errout(E_OPENPP);
924 }
925
926 /* handle the double-slash comment (like in C++) */
927 p = strchr(in_line, '/');
928 if (p != NULL) {
929 if (p[1] == '/') {
930 *p = 0; /* terminate string */
931 }
932 }
933
934 if(!er || loopfl) {
935 in_line[0]='\0';
936 }
937
938 er= (er==1) ? E_OK : er ;
939
940 if(!er)
941 er=pp_replace(t,in_line,-1,rlist);
942
943 if(!er && nff)
944 er=E_NEWFILE;
945 if(!er && nlf)
946 er=E_NEWLINE;
947 nlf=nff=0;
948
949 filep=flist+fsp;
950 filep->flinep=in_line;
951
952 return(er);
953 }
954
955
956 /*************************************************************************/
957
958 /* this is the most disgusting code I have ever written, but Andre drove me
959 to it because I can't think of any other F$%Y#*U(%&Y##^#KING way to fix the
960 last line bug ... a very irritated Cameron */
961
962 /* however, it also solved the problem of open #ifdefs not bugging out */
963
964 /* #define DEBUG_EGETC */
egetc(FILE * fp)965 int egetc(FILE *fp) {
966 int c;
967
968 c = getc(fp);
969 if (c == EOF) {
970 if (ungeteof) {
971 #ifdef DEBUG_EGETC
972 fprintf(stderr, "eof claimed\n");
973 #endif
974 return c;
975 } else {
976 #ifdef DEBUG_EGETC
977 fprintf(stderr, "got eof!!\n");
978 #endif
979 ungeteof = 1;
980 return '\n';
981 }
982 }
983 ungeteof = 0;
984 return c;
985 }
986
987 /* smart getc that can skip C comment blocks */
rgetc(FILE * fp)988 int rgetc(FILE *fp)
989 {
990 static int c,d,fl;
991
992 fl=0;
993
994 do
995 {
996 while((c=egetc(fp))==13); /* remove ^M for unices */
997
998 if(fl && (c=='*'))
999 {
1000 if((d=egetc(fp))!='/')
1001 ungetc(d,fp);
1002 else
1003 {
1004 fl--;
1005 while((c=egetc(fp))==13);
1006 }
1007 }
1008 if(c=='\n')
1009 {
1010 flist[fsp].fline++;
1011 nlf=1;
1012 } else
1013 if(c=='/')
1014 {
1015 if((d=egetc(fp))!='*')
1016 ungetc(d,fp);
1017 else
1018 fl++;
1019 }
1020
1021 } while(fl && (c!=EOF));
1022
1023 return(c-'\t'?c:' ');
1024 }
1025
fgetline(char * t,int len,int * rlen,FILE * fp)1026 int fgetline(char *t, int len, int *rlen, FILE *fp)
1027 {
1028 static int c,i;
1029
1030 i=0;
1031
1032 do {
1033 c=rgetc(fp);
1034
1035 if(c==EOF || c=='\n')
1036 {
1037 t[i]='\0';
1038 break;
1039 }
1040 t[i]=c;
1041 i= (i<len-1) ? i+1 : len-1;
1042 } while(1);
1043
1044 *rlen = i;
1045 return(c);
1046 }
1047
1048