|
|
1.1 root 1: # include <stdio.h>
2: # include "constants.h"
3: # include "globals.h"
4: # include <sccs.h>
5:
6: SCCSID(@(#)include.c 8.1 12/31/84)
7:
8:
9:
10: /*
11: ** TST_INCLUDE -- Test and process a "#include" line
12: **
13: ** Checks that a line is of the form '# include "<filename.q.h>"',
14: ** and calls include to change i/o files if so.
15: **
16: ** Returns:
17: ** 1 -- if change of file was done
18: ** 0 -- otherwise
19: */
20:
21:
22: tst_include()
23: {
24: register char *lp, *tp, *chp;
25: char temp [MAXSTRING + 1];
26:
27: /* copy line read into temp ( because temp is same
28: * size as Linebuf, no overflow check is needed
29: */
30: for (tp = temp, lp = Line_buf; (*tp++ = *lp++) != '\n'; )
31: ;
32: /* skip white space between "#" and "include" */
33: for (tp = &temp [1]; *tp == ' ' || *tp == '\t'; tp++)
34: ;
35: if (scompare("include", 7, tp, 7))
36: return (0);
37: /* skip "include", the white space till '"' */
38: for (tp = &tp [7]; *tp == ' ' || *tp == '\t'; tp++)
39: ;
40: if (*tp++ != '"')
41: return (0);
42:
43: /* {tp points to X in a line "#<white>include<white>"X..." }
44: * make "lp" point at right end '"' (filename must not have
45: * escaped '"' in it
46: */
47: for (lp = tp; *lp != '"' && *lp != '\n'; lp++)
48: ;
49:
50: if (*lp != '"')
51: return (0);
52: /* make sure filename is long enough to have the equel "include"
53: * suffix ".q.h"
54: */
55: if (lp - tp < 4)
56: return (0);
57: if (scompare(".q.h", 4, &lp [-4], 4))
58: return (0); /* other include (non-equel) */
59:
60: /* "chp" points at 'q' in '.q.h' which will be changed to 'c' */
61: chp = &lp [-3];
62:
63: /* check that rest of the line is white space */
64: for (lp++; *lp == ' ' || *lp == '\t'; lp++)
65: ;
66: if (*lp != '\n')
67: {
68: *lp = '\0';
69: yysemerr("garbage after valid \"#include\"", temp);
70: return (0);
71: }
72: *++lp = '\0';
73: return (include(temp, tp, chp, &chp [3]));
74: }
75: /*
76: ** INCLUDE -- Change i/o files for a file inclusion
77: ** Saves status of current i/o files, puts out
78: ** '#include"___.c.h"', and opens appropriate files.
79: ** Makes both files legal C files, closing quotes,
80: ** and reopeneing them in the new file, if necessary.
81: **
82: ** Parameters:
83: ** buf -- "#include..." line
84: ** start -- start of filename
85: ** chp -- *chp is 'q' in ".q.h" of filename
86: ** end -- ptr to last '"' after filename
87: **
88: ** Returns:
89: ** 1 -- if i/o files changed
90: ** 0 -- otherwise
91: **
92: ** Called By:
93: ** tst_include() -- [include.c] on seeing a pre-processor
94: ** line.
95: */
96:
97:
98: include(buf, start, chp, end)
99: char *buf;
100: char *start;
101: char *chp;
102: char *end;
103: {
104: char in_q_flag;
105: register struct inc_file *i_f;
106: char *salloc();
107:
108: in_q_flag = In_quote;
109: if (in_q_flag)
110: {
111: end_quote();
112: equate_lines();
113: }
114:
115: if (!(i_f = (struct inc_file *)nalloc(sizeof *i_f)))
116: {
117: err1 :
118: *++end = '\0'; /* overwrite before new-line at end */
119: yysemerr("alloc error in #include processing", buf);
120: if (in_q_flag)
121: begin_quote();
122: *end = '\n';
123: return (0);
124: }
125: i_f->inc_yyline = yyline + 1; /* next line that will be read is
126: * yyline + 1 because getch does not
127: * see the '\n' at the end of the
128: * "#include" line
129: */
130: i_f->inc_lineout = Lineout + 1; /* because the write of the "#include
131: * "... .c.h" file is done after the
132: * fixation of the value of Lineout.
133: */
134: i_f->inc_fid = Input_file_name;
135: i_f->inc_outfile = Out_file;
136: i_f->inc_infile = In_file;
137: i_f->inc_next = 0;
138:
139: *end = '\0';
140: if (!(Input_file_name = salloc(start)))
141: {
142: xfree(i_f);
143: goto err1;
144: }
145:
146: if ((In_file = fopen(Input_file_name, "r")) == NULL)
147: {
148: cant("read", Input_file_name);
149: err3 :
150: xfree(Input_file_name);
151: Input_file_name = i_f->inc_fid;
152: In_file = i_f->inc_infile;
153: xfree(i_f);
154: return (0);
155: }
156: *end = '"';
157: *chp = 'c';
158:
159: /* write out "#include..c.h" line (make sure it's at beginning
160: * of line.
161: */
162: equate_lines();
163: if (Charcnt != 0)
164: w_op("\n");
165: w_op(buf);
166: fflush(Out_file);
167: *end = '\0';
168: if ((Out_file = fopen(start, "w")) == NULL)
169: {
170: cant("write", start);
171: fclose(In_file);
172: Out_file = i_f->inc_outfile;
173: goto err3;
174: }
175:
176: /* go to it !!! */
177: Lineout = yyline = Newline = 1;
178: Pre_proc_flg = 0;
179: Line_pos = 0;
180: if (in_q_flag)
181: begin_quote();
182: Inc_files = i_f;
183: return (1);
184: }
185: /*
186: ** RESTOREF -- Restore previous file environment
187: ** Closes current files, and restores global variable
188: ** values for old files.
189: **
190: ** Returns:
191: ** 0 -- if no old files (top level, no "#include"s)
192: ** 1 -- otherwise
193: **
194: ** Called By:
195: ** equel() -- to close any files that may remain
196: ** open after a reset(III).
197: ** getch() -- upon receiving end-of-file
198: ** at some include level.
199: */
200:
201:
202: restoref()
203: {
204: register struct inc_file *i_f;
205:
206: if (Inc_files)
207: {
208: fclose(Out_file);
209: fclose(In_file);
210: xfree(Input_file_name);
211:
212: /* restore previous environment */
213: i_f = Inc_files;
214: yyline = i_f->inc_yyline;
215: Lineout = i_f->inc_lineout;
216: Input_file_name = i_f->inc_fid;
217: Out_file = i_f->inc_outfile;
218: In_file = i_f->inc_infile;
219: Line_pos = 0;
220: Inc_files = i_f->inc_next;
221: xfree(i_f);
222: return (1);
223: }
224: return (0);
225: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.