1 /* input.c - input for bcc */
3 /* Copyright (C) 1992 Bruce Evans */
5 #define ARBITRARY_BACKSLASH_NEWLINES_NOT
6 #define INSERT_BACKSLASH_NEWLINES_NOT
20 #define INBUFSIZE 2048
23 struct fbufstruct
/* file buffer structure */
25 struct fcbstruct fcb
; /* status after opening an include sub-file */
26 char *fname
; /* file name */
27 bool_t fname_malloced
; /* nonzero if fname was malloced */
28 char pushback
[3]; /* allows pushback to 2 before start of fbuf
30 * XXX should do everything in fbuf */
31 char fbuf
[INBUFSIZE
+ 1]; /* buffer to read into */
35 struct inclist
/* list of include file directories */
38 struct inclist
*incnext
;
41 PRIVATE
char filemacro
[] = "__FILE__";
42 PRIVATE
struct inclist incabsolute
; /* dummy list for absolute names */
43 /* depends on zero (NULL) init */
44 PRIVATE
struct inclist incfirst
;
45 /* begin include searches here for "" */
46 /* at next in list for <> */
47 /* -I directories are put in list */
48 /* between first and last */
49 PRIVATE
struct inclist inclast
=
51 #ifdef DEFAULT_INCLUDE_DIR
56 PRIVATE fastin_t inclevel
; /* nest level of include files */
57 /* depends on zero init */
59 PRIVATE
struct fbufstruct
*inputbuf
; /* current input file buffer */
60 /* its fcb only to date in includes */
61 /* depends on zero (NULL) init */
62 PRIVATE bool_t suppress_line_numbers
;
64 #ifdef ARBITRARY_BACKSLASH_NEWLINES
65 FORWARD
void backslash
P((void));
68 FORWARD
void definefile
P((char *fname
));
69 FORWARD
void leaveinclude
P((void));
71 FORWARD
void inputinit
P((char *fname
, fd_t fd
));
72 FORWARD
void usage
P((void));
74 #ifdef ARBITRARY_BACKSLASH_NEWLINES
75 PRIVATE
void backslash()
77 static unsigned nbackslash
;
83 while (*(lineptr
+ 1) == '\\')
88 if (*(lineptr
+ 1) != EOL
)
90 if (--nbackslash
!= 0)
91 *--lineptr
= '\\'; /* force look at current backslash again */
96 if (!eofile
&& lineptr
>= input
.limit
)
102 eofin("backslash-newline");
106 if (ch
== EOL
&& !eofile
&& lineptr
>= input
.limit
)
108 #ifdef COEOL /* XXX - this should go through specialchar() */
112 if (ch
== EOL
&& !eofile
&& lineptr
>= input
.limit
)
119 if (nbackslash
!= 0 && ch
== EOL
&& !eofile
)
123 ch
= *--lineptr
= '\\';
124 if (--nbackslash
!= 0)
125 ch
= *--lineptr
= '\\';
131 if (ch
== EOL
&& !eofile
)
133 ch
= *--lineptr
= '\\'; /* pushback */
134 if (--nbackslash
!= 0)
135 ch
= *--lineptr
= '\\';
139 PUBLIC
void closein()
141 #ifdef FAKE_INBUFSIZE_1
147 while (inclevel
!= 0)
153 PRIVATE
void definefile(fname
)
158 def
= ourmalloc(sizeof filemacro
- 1 + 2 + strlen(fname
) + 1 + 1);
159 strcpy(def
, filemacro
);
168 PUBLIC
void errorloc()
170 register struct fbufstruct
*infbuf
;
172 if ((infbuf
= inputbuf
) == NULL
)
174 outstr(infbuf
->fname
);
180 outudec(input
.linenumber
);
184 outudec((unsigned) (lineptr
- inputbuf
->fbuf
) - input
.lineoffset
);
187 outudec((unsigned) (savedlineptr() - inputbuf
->fbuf
)
189 outstr(" (macro level ");
190 outudec((unsigned) maclevel
);
194 outudec((unsigned) (lineptr
- inputbuf
->fbuf
) - input
.lineoffset
);
197 infbuf
->fcb
.includer
= input
.includer
;
198 while ((infbuf
= infbuf
->fcb
.includer
) != NULL
)
201 outstr(infbuf
->fname
);
203 outudec(infbuf
->fcb
.linenumber
);
209 /* gch1() - get next char, advance ptr (only works on current line) */
213 if (SYMOFCHAR(ch
= *++lineptr
) != SPECIALCHAR
)
219 /* process #include */
221 PUBLIC
void include()
229 struct inclist
*incptr
;
232 while (blanksident())
234 if ((gsymptr
= findlorg(gsname
)) == NULL
||
235 gsymptr
->flags
!= DEFINITION
)
239 if ((terminator
= ch
) == '<')
241 else if (terminator
!= '"')
243 error("bad file name");
250 if (ch
== EOL
) /* no escapes in file names */
252 if (ch
== terminator
)
258 if (charptr
>= chartop
)
259 fnameptr
= growobject(fnameptr
, 1);
268 if (charptr
>= chartop
)
269 fnameptr
= growobject(fnameptr
, 1);
271 ++ts_n_filename_term
;
272 ++ts_s_filename_term
;
277 if (isabspath(fnameptr
, &ch
))
278 incptr
= &incabsolute
;
282 if (terminator
== '>')
283 incptr
= incptr
->incnext
;
286 dirnameptr
= inputbuf
->fname
;
287 if ((dirnamend
= strrchr(dirnameptr
, DIRCHAR
)) == NULL
)
288 incptr
->incdirname
= NULL
;
292 incptr
->incdirname
= dirnameptr
;
298 if (incptr
->incdirname
== NULL
)
300 fullnameptr
= ourmalloc(strlen(fnameptr
) + 1);
303 ts_s_pathname
+= strlen(fnameptr
) + 1;
304 ts_s_pathname_tot
+= strlen(fnameptr
) + 1;
306 strcpy(fullnameptr
, fnameptr
);
310 dirnamelen
= strlen(incptr
->incdirname
);
311 fullnameptr
= ourmalloc(dirnamelen
+ (int) (charptr
- fnameptr
)
313 /* 2 extra for null and maybe DIRCHAR */
316 ts_s_pathname
+= dirnamelen
+ (charptr
- fnameptr
) + 2;
317 ts_s_pathname_tot
+= dirnamelen
+ (charptr
- fnameptr
) + 2;
319 dirnameptr
= fullnameptr
+ dirnamelen
;
320 strcpy(fullnameptr
, incptr
->incdirname
);
321 if (*fullnameptr
!= 0 && *(dirnameptr
- 1) != DIRCHAR
)
322 strcat(fullnameptr
, DIRSTRING
);
323 strcat(fullnameptr
, fnameptr
);
324 if (dirnamend
!= NULL
)
326 *dirnamend
= DIRCHAR
;
330 fd
= open(fullnameptr
, 0);
334 ts_s_filename_tot
-= charptr
- fnameptr
;
337 input
.lineptr
= lineptr
;
338 inputbuf
->fcb
= input
;
339 ++inclevel
; /* XXX - will run out of memory before overflow */
340 inputinit(fullnameptr
, fd
);
341 inputbuf
->fname_malloced
= TRUE
;
345 ts_s_pathname_tot
-= strlen(fullnameptr
) + 1;
347 ourfree(fullnameptr
);
349 while ((incptr
= incptr
->incnext
) != NULL
);
351 fullnameptr
= ourmalloc(strlen(fnameptr
) + 40);
352 strcpy(fullnameptr
, "cannot find include file ");
353 strcat(fullnameptr
, fnameptr
);
355 ourfree(fullnameptr
);
358 ts_s_filename_tot
-= charptr
- fnameptr
;
364 /* initialise current input file */
366 PRIVATE
void inputinit(fname
, fd
)
370 register struct fbufstruct
*newinputbuf
;
372 /* don't allocate after saying input.includer = inputbuf (to save a reg)
373 * or an error in the alloc would cycle trying to print the include list
375 newinputbuf
= (struct fbufstruct
*) ourmalloc(sizeof *inputbuf
);
378 ts_s_inputbuf
+= sizeof *inputbuf
;
379 ts_s_inputbuf_tot
+= sizeof *inputbuf
;
382 #ifdef FAKE_INBUFSIZE_1
383 input
.fp
= fdopen(fd
, "r");
385 input
.linenumber
= 0;
386 input
.lineoffset
= 0;
387 input
.includer
= inputbuf
;
388 inputbuf
= newinputbuf
;
389 newinputbuf
->fname
= fname
;
390 newinputbuf
->fname_malloced
= FALSE
;
392 undefinestring(filemacro
);
394 if (orig_cppmode
&& !suppress_line_numbers
)
395 outcpplinenumber(1, fname
, input
.includer
== NULL
? "" : " 1");
397 *(input
.limit
= newinputbuf
->fbuf
) = EOL
;
399 /* dummy line so processing can start with skipline() */
400 ch
= *(lineptr
= newinputbuf
->fbuf
- 1) = EOL
;
403 PUBLIC
void linecontol()
410 input
.linenumber
= atoi(lineptr
)-1;
411 while( SYMOFCHAR(ch
) == INTCONST
) gch1();
413 if( ch
!= '"' ) return;
414 for(ptr
=lineptr
+1; *ptr
417 && i
<sizeof(linename
)-1; i
++, ptr
++)
421 if (inputbuf
->fname_malloced
)
424 ts_s_pathname_tot
-= strlen(inputbuf
->fname
) + 1;
426 ourfree(inputbuf
->fname
);
428 inputbuf
->fname_malloced
= TRUE
;
429 ptr
= ourmalloc(strlen(linename
)+1);
430 strcpy(ptr
, linename
);
431 inputbuf
->fname
= ptr
;
435 undefinestring(filemacro
);
436 definefile(inputbuf
->fname
);
438 ch
= *(lineptr
= ptr
);
442 /* switch from include file to file which included it */
444 PRIVATE
void leaveinclude()
447 if (inputbuf
->fname_malloced
)
450 ts_s_pathname_tot
-= strlen(inputbuf
->fname
) + 1;
452 ourfree(inputbuf
->fname
);
455 ts_s_inputbuf_tot
-= sizeof *inputbuf
;
457 ourfree((char *) inputbuf
);
462 #ifdef FAKE_INBUFSIZE_1
465 inputbuf
= input
.includer
;
466 input
= inputbuf
->fcb
;
467 undefinestring(filemacro
);
468 definefile(inputbuf
->fname
);
469 ch
= *(lineptr
= input
.lineptr
);
471 if (orig_cppmode
&& !suppress_line_numbers
)
472 outcpplinenumber(input
.linenumber
, inputbuf
->fname
, " 2");
476 /* open input and output files and get options */
478 PUBLIC
void openio(argc
, argv
)
487 struct inclist
*incnew
;
488 struct inclist
*incptr
;
493 lineptr
= "\n"; /* empty line in case error message */
495 fd
= 0; /* standard input */
496 memset(flag
, 0, sizeof flag
);
498 flag
['3'] = sizeof (int) >= 4;
502 (incptr
= &incfirst
)->incnext
= &inclast
;
505 for (argn
= 1; argn
< argc
; ++argn
)
511 fatalerror("more than one input file");
513 if ((fd
= open(arg
, 0)) < 0)
514 fatalerror("cannot open input");
520 case '0': /* generate 16-bit code */
523 case '3': /* generate 32-bit code */
525 case 'c': /* caller saves */
527 case 'd': /* print debugging information in asm output */
530 case 'E': /* acting as cpp */
532 case 'f': /* pass first argument in register */
533 #ifdef DYNAMIC_LONG_ORDER
534 case 'l': /* long big-endian */
536 case 'P': /* if acting as cpp, suppress line numbers */
537 #ifdef POSINDEPENDENT
538 case 'p': /* generate almost-position-independent code */
540 case 't': /* print source code in asm output */
541 case 'w': /* watch location counter */
542 case 'O': /* Optimisation. */
544 flag
[(int)arg
[1]] = TRUE
;
545 else if (arg
[2] == '-' && arg
[3] == 0)
546 flag
[(int)arg
[1]] = FALSE
;
549 if (arg
[1] == '0') /* flag 0 is negative logic flag 3 */
550 flag
['3'] = TRUE
+ FALSE
- flag
['0'];
554 definestring(arg
+ 2);
557 (incnew
= (struct inclist
*) ourmalloc(sizeof *incnew
))
558 ->incdirname
= arg
+ 2;
561 ts_s_includelist
+= sizeof *incnew
;
563 incnew
->incnext
= incptr
->incnext
;
564 incptr
= incptr
->incnext
= incnew
;
567 undefinestring(arg
+ 2);
571 if (arg
[2] != 0 || ++argn
>= argc
)
586 definestring("__AS386_32__");
587 definestring("__i386__");
592 definestring("__AS386_16__");
593 definestring("__8086__");
597 definestring("__AS09__");
602 definestring("__CALLER_SAVES__");
605 dbnodeon
= flag
['d'];
607 orig_cppmode
= cppmode
= flag
['E'];
612 definestring("__FIRST_ARG_IN_AX__");
615 definestring("__FIRST_ARG_IN_X__");
618 arg1op
= arg1inreg
? ROOTLISTOP
: LISTOP
;
619 #ifdef DYNAMIC_LONG_ORDER
622 long_big_endian
= TRUE
;
623 definestring("__LONG_BIG_ENDIAN__");
626 suppress_line_numbers
= flag
['P'];
627 #ifdef POSINDEPENDENT
630 posindependent
= TRUE
;
631 definestring("__POS_INDEPENDENT__");
637 definestring("__OPTIMISED__");
640 definestring("__HAS_NO_FLOATS__");
643 #else /* !BUILTIN_CPP */
646 if (flag
['3']) i386_32
= TRUE
;
648 if (flag
['c']) callersaves
= TRUE
;
650 dbnodeon
= flag
['d'];
652 if (flag
['f']) arg1inreg
= TRUE
;
653 arg1op
= arg1inreg
? ROOTLISTOP
: LISTOP
;
654 #ifdef DYNAMIC_LONG_ORDER
655 if (flag
['l']) long_big_endian
= TRUE
;
657 suppress_line_numbers
= flag
['P'];
658 #ifdef POSINDEPENDENT
659 if (flag
['p']) posindependent
= TRUE
;
661 if (flag
['O']) optimise
= TRUE
;
666 if (ctext
) dbnodeon
= 1;
670 inputinit(fname
, fd
);
673 /* advance over EOL sentinel to new line */
675 PUBLIC
void skipeol()
677 #ifdef FAKE_INBUFSIZE_1
680 #ifdef INSERT_BACKSLASH_NEWLINES
682 static bool_t skip_printing_nl
;
685 debug(7, "skipeol %s:%d", inputbuf
->fname
, input
.linenumber
);
689 if (lineptr
< input
.limit
)
693 if (ctext
&& !asmmode
)
696 outudec(input
.linenumber
);
702 if (!virtual_nl
&& (orig_cppmode
|| asmmode
))
704 if (orig_cppmode
&& !asmmode
)
706 #ifdef INSERT_BACKSLASH_NEWLINES
707 if (!skip_printing_nl
)
710 #else /* !BUILTIN_CPP */
712 #ifdef INSERT_BACKSLASH_NEWLINES
713 if (!skip_printing_nl
)
718 #ifdef INSERT_BACKSLASH_NEWLINES
719 if (bs_state
== 1 && *(lineptr
- 1) == EOL
)
721 input
.lineoffset
= (int) (lineptr
- inputbuf
->fbuf
);
724 input
.lineoffset
-= (int) (lineptr
- inputbuf
->fbuf
);
725 #ifdef FAKE_INBUFSIZE_1
726 lineptr
= inputbuf
->fbuf
;
727 #ifdef INSERT_BACKSLASH_NEWLINES
732 bs_state
= nread
= (ich
= getc(input
.fp
)) == EOF
? 0 : 1;
733 skip_printing_nl
= FALSE
;
737 goto case0
; /* avoid chance of splitting \EOL */
747 skip_printing_nl
= TRUE
;
753 nread
= (ich
= getc(input
.fp
)) == EOF
? 0 : 1;
763 nread
= read(input
.fd
, lineptr
= inputbuf
->fbuf
, INBUFSIZE
);
766 if( nread
== 0 && inclevel
> 0 )
770 memcpy(inputbuf
->fbuf
, "\n", 1);
778 fatalerror("input error");
779 *(input
.limit
= lineptr
+ nread
) = EOL
;
799 if (ctext
&& !asmmode
)
802 outudec(input
.linenumber
);
808 PUBLIC
void specialchar()
813 if (ch
== EOL
) /* it might also be backslash or COEOL */
820 #ifdef ARBITRARY_BACKSLASH_NEWLINES
824 if (!eofile
&& lineptr
>= input
.limit
)
827 #ifdef ARBITRARY_BACKSLASH_NEWLINES
832 #ifndef ARBITRARY_BACKSLASH_NEWLINES
835 if (*(lineptr
+ 1) == EOL
)
837 if (lineptr
+ 1 >= input
.limit
)
841 ch
= *--lineptr
= '\\'; /* pushback */
843 if (*(lineptr
+ 1) == EOL
)
846 eofin("backslash-newline");
851 if (SYMOFCHAR(ch
) == SPECIALCHAR
)
855 || SYMOFCHAR(ch
= *++lineptr
) == SPECIALCHAR
)
865 if (ch
== EOL
&& !eofile
)
867 if (*(lineptr
+ 1) == EOL
&& lineptr
+ 1 >= input
.limit
)
870 skipeol(); /* refill buffer */
871 ch
= *--lineptr
= EOL
; /* pushback */
873 if (*(lineptr
+ 1) == COEOL
)
874 *++lineptr
= EOL
; /* discard COEOL */
884 "usage: cc1 [-cdfptw[-]] [-Ddefine] [-Iincdir] [-Uundef] [-o outfile] [infile]"
887 "usage: cc1 [-03cdfltw[-]] [-Ddefine] [-Iincdir] [-Uundef] [-o outfile] [infile]"
889 "usage: cc1 [-cdfltw[-]] [-Ddefine] [-Iincdir] [-Uundef] [-o outfile] [infile]"
894 "usage: cc1 [-03cdfltw[-]] [-o outfile] [infile]"
896 "usage: cc1 [-cdfltw[-]] [-o outfile] [infile]"