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