xref: /plan9/sys/src/cmd/cpp/include.c (revision 05dd16479b5ff7590ef006e043ecb1599b7837cb)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include "cpp.h"
43e12c5d1SDavid du Colombier 
57dd7cddfSDavid du Colombier Includelist	includelist[NINCLUDE];
63e12c5d1SDavid du Colombier 
7bd389b36SDavid du Colombier char	*objname;
8bd389b36SDavid du Colombier 
93e12c5d1SDavid du Colombier void
doinclude(Tokenrow * trp)103e12c5d1SDavid du Colombier doinclude(Tokenrow *trp)
113e12c5d1SDavid du Colombier {
127dd7cddfSDavid du Colombier 	char fname[256], iname[256], *p;
133e12c5d1SDavid du Colombier 	Includelist *ip;
143e12c5d1SDavid du Colombier 	int angled, len, fd, i;
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier 	trp->tp += 1;
173e12c5d1SDavid du Colombier 	if (trp->tp>=trp->lp)
183e12c5d1SDavid du Colombier 		goto syntax;
193e12c5d1SDavid du Colombier 	if (trp->tp->type!=STRING && trp->tp->type!=LT) {
203e12c5d1SDavid du Colombier 		len = trp->tp - trp->bp;
21*05dd1647SDavid du Colombier 		expandrow(trp, "<include>", Notinmacro);
223e12c5d1SDavid du Colombier 		trp->tp = trp->bp+len;
233e12c5d1SDavid du Colombier 	}
243e12c5d1SDavid du Colombier 	if (trp->tp->type==STRING) {
253e12c5d1SDavid du Colombier 		len = trp->tp->len-2;
263e12c5d1SDavid du Colombier 		if (len > sizeof(fname) - 1)
273e12c5d1SDavid du Colombier 			len = sizeof(fname) - 1;
283e12c5d1SDavid du Colombier 		strncpy(fname, (char*)trp->tp->t+1, len);
293e12c5d1SDavid du Colombier 		angled = 0;
307dd7cddfSDavid du Colombier 	} else if (trp->tp->type==LT) {
313e12c5d1SDavid du Colombier 		len = 0;
323e12c5d1SDavid du Colombier 		trp->tp++;
333e12c5d1SDavid du Colombier 		while (trp->tp->type!=GT) {
343e12c5d1SDavid du Colombier 			if (trp->tp>trp->lp || len+trp->tp->len+2 >= sizeof(fname))
353e12c5d1SDavid du Colombier 				goto syntax;
363e12c5d1SDavid du Colombier 			strncpy(fname+len, (char*)trp->tp->t, trp->tp->len);
373e12c5d1SDavid du Colombier 			len += trp->tp->len;
383e12c5d1SDavid du Colombier 			trp->tp++;
393e12c5d1SDavid du Colombier 		}
403e12c5d1SDavid du Colombier 		angled = 1;
417dd7cddfSDavid du Colombier 	} else
427dd7cddfSDavid du Colombier 		goto syntax;
433e12c5d1SDavid du Colombier 	trp->tp += 2;
443e12c5d1SDavid du Colombier 	if (trp->tp < trp->lp || len==0)
453e12c5d1SDavid du Colombier 		goto syntax;
463e12c5d1SDavid du Colombier 	fname[len] = '\0';
473e12c5d1SDavid du Colombier 	if (fname[0]=='/') {
483e12c5d1SDavid du Colombier 		fd = open(fname, 0);
493e12c5d1SDavid du Colombier 		strcpy(iname, fname);
503e12c5d1SDavid du Colombier 	} else for (fd=-1,i=NINCLUDE-1; i>=0; i--) {
513e12c5d1SDavid du Colombier 		ip = &includelist[i];
523e12c5d1SDavid du Colombier 		if (ip->file==NULL || ip->deleted || (angled && ip->always==0))
533e12c5d1SDavid du Colombier 			continue;
543e12c5d1SDavid du Colombier 		if (strlen(fname)+strlen(ip->file)+2 > sizeof(iname))
553e12c5d1SDavid du Colombier 			continue;
563e12c5d1SDavid du Colombier 		strcpy(iname, ip->file);
573e12c5d1SDavid du Colombier 		strcat(iname, "/");
583e12c5d1SDavid du Colombier 		strcat(iname, fname);
593e12c5d1SDavid du Colombier 		if ((fd = open(iname, 0)) >= 0)
603e12c5d1SDavid du Colombier 			break;
613e12c5d1SDavid du Colombier 	}
627dd7cddfSDavid du Colombier 	if(fd < 0) {
637dd7cddfSDavid du Colombier 		strcpy(iname, cursource->filename);
647dd7cddfSDavid du Colombier 		p = strrchr(iname, '/');
657dd7cddfSDavid du Colombier 		if(p != NULL) {
667dd7cddfSDavid du Colombier 			*p = '\0';
677dd7cddfSDavid du Colombier 			strcat(iname, "/");
687dd7cddfSDavid du Colombier 			strcat(iname, fname);
697dd7cddfSDavid du Colombier 			fd = open(iname, 0);
707dd7cddfSDavid du Colombier 		}
717dd7cddfSDavid du Colombier 	}
72bd389b36SDavid du Colombier 	if ( Mflag>1 || !angled&&Mflag==1 ) {
73bd389b36SDavid du Colombier 		write(1,objname,strlen(objname));
74bd389b36SDavid du Colombier 		write(1,iname,strlen(iname));
75bd389b36SDavid du Colombier 		write(1,"\n",1);
76bd389b36SDavid du Colombier 	}
773e12c5d1SDavid du Colombier 	if (fd >= 0) {
78219b2ee8SDavid du Colombier 		if (++incdepth > 20)
793e12c5d1SDavid du Colombier 			error(FATAL, "#include too deeply nested");
803e12c5d1SDavid du Colombier 		setsource((char*)newstring((uchar*)iname, strlen(iname), 0), fd, NULL);
813e12c5d1SDavid du Colombier 		genline();
823e12c5d1SDavid du Colombier 	} else {
833e12c5d1SDavid du Colombier 		trp->tp = trp->bp+2;
843e12c5d1SDavid du Colombier 		error(ERROR, "Could not find include file %r", trp);
853e12c5d1SDavid du Colombier 	}
863e12c5d1SDavid du Colombier 	return;
873e12c5d1SDavid du Colombier syntax:
883e12c5d1SDavid du Colombier 	error(ERROR, "Syntax error in #include");
893e12c5d1SDavid du Colombier 	return;
903e12c5d1SDavid du Colombier }
913e12c5d1SDavid du Colombier 
923e12c5d1SDavid du Colombier /*
933e12c5d1SDavid du Colombier  * Generate a line directive for cursource
943e12c5d1SDavid du Colombier  */
953e12c5d1SDavid du Colombier void
genline(void)963e12c5d1SDavid du Colombier genline(void)
973e12c5d1SDavid du Colombier {
983e12c5d1SDavid du Colombier 	static Token ta = { UNCLASS, NULL, 0, 0 };
993e12c5d1SDavid du Colombier 	static Tokenrow tr = { &ta, &ta, &ta+1, 1 };
1003e12c5d1SDavid du Colombier 	uchar *p;
1013e12c5d1SDavid du Colombier 
1027dd7cddfSDavid du Colombier 	if(nolineinfo)
1037dd7cddfSDavid du Colombier 		return;
1047dd7cddfSDavid du Colombier 
1053e12c5d1SDavid du Colombier 	ta.t = p = (uchar*)outp;
1063e12c5d1SDavid du Colombier 	strcpy((char*)p, "#line ");
1073e12c5d1SDavid du Colombier 	p += sizeof("#line ")-1;
1083e12c5d1SDavid du Colombier 	p = (uchar*)outnum((char*)p, cursource->line);
1093e12c5d1SDavid du Colombier 	*p++ = ' '; *p++ = '"';
110219b2ee8SDavid du Colombier 	if (cursource->filename[0]!='/' && wd[0]) {
111219b2ee8SDavid du Colombier 		strcpy((char*)p, wd);
112219b2ee8SDavid du Colombier 		p += strlen(wd);
113219b2ee8SDavid du Colombier 		*p++ = '/';
114219b2ee8SDavid du Colombier 	}
1153e12c5d1SDavid du Colombier 	strcpy((char*)p, cursource->filename);
1163e12c5d1SDavid du Colombier 	p += strlen((char*)p);
1173e12c5d1SDavid du Colombier 	*p++ = '"'; *p++ = '\n';
1183e12c5d1SDavid du Colombier 	ta.len = (char*)p-outp;
1193e12c5d1SDavid du Colombier 	outp = (char*)p;
1203e12c5d1SDavid du Colombier 	tr.tp = tr.bp;
1213e12c5d1SDavid du Colombier 	puttokens(&tr);
1223e12c5d1SDavid du Colombier }
123bd389b36SDavid du Colombier 
124bd389b36SDavid du Colombier void
setobjname(char * f)125bd389b36SDavid du Colombier setobjname(char *f)
126bd389b36SDavid du Colombier {
127bd389b36SDavid du Colombier 	int n = strlen(f);
128bd389b36SDavid du Colombier 	objname = (char*)domalloc(n+5);
129bd389b36SDavid du Colombier 	strcpy(objname,f);
130bd389b36SDavid du Colombier 	if(objname[n-2]=='.'){
131bd389b36SDavid du Colombier 		strcpy(objname+n-1,"$O: ");
132bd389b36SDavid du Colombier 	}else{
133bd389b36SDavid du Colombier 		strcpy(objname+n,"$O: ");
134bd389b36SDavid du Colombier 	}
135bd389b36SDavid du Colombier }
136