xref: /csrg-svn/usr.bin/pascal/src/savenl.c (revision 5446)
1*5446Slinton /* Copyright (c) 1982 Regents of the University of California */
2*5446Slinton 
3*5446Slinton static char sccsid[] = "@(#)savenl.c 1.1 01/18/82";
4*5446Slinton 
5*5446Slinton /*
6*5446Slinton  * savenl - routines for saving namelist and line number information
7*5446Slinton  *
8*5446Slinton  * This module contains the routines that make pi dump a namelist
9*5446Slinton  * at the end of the object file.  We do this by first creating
10*5446Slinton  * four temporary files in "startnlfile".  One temp file contains
11*5446Slinton  * the string table, one the symbol table, one the file name
12*5446Slinton  * information and one the line number information.
13*5446Slinton  *
14*5446Slinton  * Prior to generation of the code for a statement the "lineno"
15*5446Slinton  * routine is called to dump the line number and current object
16*5446Slinton  * address.  At the end of each block "savenl" is called to dump
17*5446Slinton  * the strings and symbol structures.
18*5446Slinton  *
19*5446Slinton  * At the end of execution "copynlfile" is called and it copies
20*5446Slinton  * the temp files onto the end of the obj file.
21*5446Slinton  *
22*5446Slinton  * In case of error, "removenlfile" is called to destroy the temp files.
23*5446Slinton  *
24*5446Slinton  * The only other changes to pi are in calling these routines from
25*5446Slinton  *
26*5446Slinton  * 	"main"		(main.c)
27*5446Slinton  *	"yymain"	(yymain.c)
28*5446Slinton  *	"funcend"	(fend.c)
29*5446Slinton  *	"yyget"		(yyget.c)
30*5446Slinton  *	"putline"	(stat.c)
31*5446Slinton  */
32*5446Slinton 
33*5446Slinton #include "whoami.h"
34*5446Slinton #include "0.h"
35*5446Slinton 
36*5446Slinton #undef NIL
37*5446Slinton 
38*5446Slinton /*
39*5446Slinton  * pdx header files
40*5446Slinton  */
41*5446Slinton 
42*5446Slinton #include "defs.h"
43*5446Slinton #include "object.h"
44*5446Slinton #include "object/objsym.rep"
45*5446Slinton #include "mappings.h"
46*5446Slinton #include "mappings/filetab.h"
47*5446Slinton 
48*5446Slinton LOCAL char *symname = "/tmp/obj.symXXXX";
49*5446Slinton LOCAL char *strname = "/tmp/obj.strXXXX";
50*5446Slinton LOCAL char *filesname = "/tmp/obj.filesXXXX";
51*5446Slinton LOCAL char *linesname = "/tmp/obj.linesXXXX";
52*5446Slinton 
53*5446Slinton LOCAL FILE *symfp;
54*5446Slinton LOCAL FILE *strfp;
55*5446Slinton LOCAL FILE *filesfp;
56*5446Slinton LOCAL FILE *linesfp;
57*5446Slinton 
58*5446Slinton /*
59*5446Slinton  * create temporary files for the namelist info
60*5446Slinton  */
61*5446Slinton 
62*5446Slinton startnlfile()
63*5446Slinton {
64*5446Slinton 	mktemp(symname);
65*5446Slinton 	mktemp(strname);
66*5446Slinton 	mktemp(filesname);
67*5446Slinton 	mktemp(linesname);
68*5446Slinton 	symfp = fopen(symname, "w");
69*5446Slinton 	strfp = fopen(strname, "w");
70*5446Slinton 	filesfp = fopen(filesname, "w");
71*5446Slinton 	linesfp = fopen(linesname, "w");
72*5446Slinton 	if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) {
73*5446Slinton 		fprintf(stderr, "can't create /tmp/obj");
74*5446Slinton 		pexit(NOSTART);
75*5446Slinton 	}
76*5446Slinton 	newfile(filename, 1);
77*5446Slinton }
78*5446Slinton 
79*5446Slinton /*
80*5446Slinton  * now copy the temp files back to obj; strings, symbols, file names, and lines
81*5446Slinton  *
82*5446Slinton  * There's some efficiency garbage here that uses straight system
83*5446Slinton  * calls rather than standard I/O library calls.
84*5446Slinton  */
85*5446Slinton 
86*5446Slinton copynlfile()
87*5446Slinton {
88*5446Slinton 	register int n;
89*5446Slinton 	int symfd, strfd, filesfd, linesfd;
90*5446Slinton 	char buff[BUFSIZ];
91*5446Slinton 
92*5446Slinton 	fclose(symfp);
93*5446Slinton 	fclose(strfp);
94*5446Slinton 	fclose(filesfp);
95*5446Slinton 	fclose(linesfp);
96*5446Slinton 	symfd = open(symname, 0);
97*5446Slinton 	strfd = open(strname, 0);
98*5446Slinton 	filesfd = open(filesname, 0);
99*5446Slinton 	linesfd = open(linesname, 0);
100*5446Slinton 	if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) {
101*5446Slinton 		fprintf(stderr, "sync error on /tmp/obj");
102*5446Slinton 		pexit(ERRS);
103*5446Slinton 	}
104*5446Slinton 	lseek(ofil, 0L, 2);
105*5446Slinton 	write(ofil, &nlhdr, sizeof(nlhdr));
106*5446Slinton 	n = read(strfd, buff, BUFSIZ - sizeof(nlhdr));
107*5446Slinton 	write(ofil, buff, n);
108*5446Slinton 	cat(strfd);
109*5446Slinton 	cat(symfd);
110*5446Slinton 	cat(filesfd);
111*5446Slinton 	cat(linesfd);
112*5446Slinton 	removenlfile();
113*5446Slinton }
114*5446Slinton 
115*5446Slinton cat(fd)
116*5446Slinton int fd;
117*5446Slinton {
118*5446Slinton 	register int n;
119*5446Slinton 	char buff[BUFSIZ];
120*5446Slinton 
121*5446Slinton 	while ((n = read(fd, buff, BUFSIZ)) > 0) {
122*5446Slinton 		write(ofil, buff, n);
123*5446Slinton 	}
124*5446Slinton 	close(fd);
125*5446Slinton }
126*5446Slinton 
127*5446Slinton removenlfile()
128*5446Slinton {
129*5446Slinton 	unlink(symname);
130*5446Slinton 	unlink(strname);
131*5446Slinton 	unlink(filesname);
132*5446Slinton 	unlink(linesname);
133*5446Slinton }
134*5446Slinton 
135*5446Slinton #define isblock(s)	(s->class == FUNC || s->class == PROC)
136*5446Slinton #define isbuiltin(s)	((s->nl_block&037) == 0 && isblock(s))
137*5446Slinton #define symno(p)	(p==NULL ? 0 : nloff(p))
138*5446Slinton 
139*5446Slinton struct nls {
140*5446Slinton 	struct nl *nls_low;
141*5446Slinton 	struct nl *nls_high;
142*5446Slinton };
143*5446Slinton 
144*5446Slinton struct nl nl[], *nlp, ntab[], *nlact;
145*5446Slinton 
146*5446Slinton savenl(to, rout)
147*5446Slinton struct nl *to;
148*5446Slinton {
149*5446Slinton 	register struct nl *p;
150*5446Slinton 	register OBJSYM *s;
151*5446Slinton 	OBJSYM tmpsym;
152*5446Slinton 	struct nls *nlsp;
153*5446Slinton 	int v;
154*5446Slinton 
155*5446Slinton 	if (to != NIL) {
156*5446Slinton 		putblock(rout);
157*5446Slinton 	} else {
158*5446Slinton 		putblock("main program");
159*5446Slinton 	}
160*5446Slinton 	nlsp = nlact;
161*5446Slinton 	s = &tmpsym;
162*5446Slinton 	for (p = nlp; p != to;) {
163*5446Slinton 		if (p == nlsp->nls_low) {
164*5446Slinton 			if (nlsp == &ntab[0])
165*5446Slinton 				break;
166*5446Slinton 			nlsp--;
167*5446Slinton 			p = nlsp->nls_high;
168*5446Slinton 		}
169*5446Slinton 		p--;
170*5446Slinton 		if (isbuiltin(p) || symno(p) == 0) {
171*5446Slinton 			continue;
172*5446Slinton 		}
173*5446Slinton 		nlhdr.nsyms++;
174*5446Slinton 		putw(symno(p), symfp);
175*5446Slinton 		if (p->symbol != NULL) {
176*5446Slinton 			s->strindex = nlhdr.stringsize;
177*5446Slinton 			putstring(p->symbol);
178*5446Slinton 		} else {
179*5446Slinton 			s->strindex = 0;
180*5446Slinton 		}
181*5446Slinton 		s->oclass = p->class;
182*5446Slinton 		s->oblkno = (p->nl_block&037);
183*5446Slinton 		s->typno = symno(p->type);
184*5446Slinton 		s->chno = symno(p->chain);
185*5446Slinton 		s->osymvalue.orangev.lower = p->range[0];
186*5446Slinton 		s->osymvalue.orangev.upper = p->range[1];
187*5446Slinton 		if (isblock(p)) {
188*5446Slinton 			s->osymvalue.ofuncv.codeloc = p->entloc;
189*5446Slinton 		} else if (p->class == RECORD || p->class == VARNT) {
190*5446Slinton 			s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]);
191*5446Slinton 			s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]);
192*5446Slinton 		}
193*5446Slinton 		fwrite(s, sizeof(*s), 1, symfp);
194*5446Slinton 	}
195*5446Slinton }
196*5446Slinton 
197*5446Slinton /*
198*5446Slinton  * Dump a line number and the current object location counter.
199*5446Slinton  *
200*5446Slinton  * To save space the difference from the previous line number and offset
201*5446Slinton  * (one byte each) is dumped.
202*5446Slinton  */
203*5446Slinton 
204*5446Slinton LOCAL int oline = 0;
205*5446Slinton LOCAL int olc = BASEADDR;
206*5446Slinton 
207*5446Slinton lineno(line)
208*5446Slinton int line;
209*5446Slinton {
210*5446Slinton 	if (line != oline) {
211*5446Slinton 		nlhdr.nlines++;
212*5446Slinton 		putc(line - oline, linesfp);
213*5446Slinton 		putc(lc - olc, linesfp);
214*5446Slinton 		oline = line;
215*5446Slinton 		olc = lc;
216*5446Slinton 	}
217*5446Slinton }
218*5446Slinton 
219*5446Slinton /*
220*5446Slinton  * put out a file name entry, including:
221*5446Slinton  *
222*5446Slinton  *	the current line number for the new file
223*5446Slinton  *	the current location counter
224*5446Slinton  *	the string table address of the file name
225*5446Slinton  *	an index into the current line number information
226*5446Slinton  */
227*5446Slinton 
228*5446Slinton newfile(s, line)
229*5446Slinton char *s;
230*5446Slinton int line;
231*5446Slinton {
232*5446Slinton 	FILETAB ft;
233*5446Slinton 
234*5446Slinton 	nlhdr.nfiles++;
235*5446Slinton 	ft.line = line;
236*5446Slinton 	oline = line;
237*5446Slinton 	if (lc == 0) {
238*5446Slinton 		ft.addr = 0;
239*5446Slinton 	} else {
240*5446Slinton 		ft.addr = lc - BASEADDR;
241*5446Slinton 	}
242*5446Slinton 	ft.filename = (char *) nlhdr.stringsize;
243*5446Slinton 	putstring(s);
244*5446Slinton 	ft.lineindex = nlhdr.nlines;
245*5446Slinton 	fwrite(&ft, sizeof(ft), 1, filesfp);
246*5446Slinton }
247*5446Slinton 
248*5446Slinton /*
249*5446Slinton  * put out a dummy symbol at the beginning of a block
250*5446Slinton  */
251*5446Slinton 
252*5446Slinton LOCAL putblock(s)
253*5446Slinton char *s;
254*5446Slinton {
255*5446Slinton 	register int i;
256*5446Slinton 	static OBJSYM zerosym;
257*5446Slinton 
258*5446Slinton 	nlhdr.nsyms++;
259*5446Slinton 	putw(0, symfp);
260*5446Slinton 	zerosym.strindex = nlhdr.stringsize;
261*5446Slinton 	putstring(s);
262*5446Slinton 	fwrite(&zerosym, sizeof(zerosym), 1, symfp);
263*5446Slinton }
264*5446Slinton 
265*5446Slinton /*
266*5446Slinton  * put out a string to the string table file
267*5446Slinton  */
268*5446Slinton 
269*5446Slinton LOCAL putstring(s)
270*5446Slinton char *s;
271*5446Slinton {
272*5446Slinton 	register char *p;
273*5446Slinton 
274*5446Slinton 	for (p = s; *p != '\0'; p++)
275*5446Slinton 		putc(*p, strfp);
276*5446Slinton 	nlhdr.stringsize += (p - s + 1);
277*5446Slinton 	putc('\0', strfp);
278*5446Slinton }
279