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