#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cpp.h"
#include <windows.h>
Includelist includelist[NINCLUDE];
extern char *objname;
void //处理include 文件
doinclude(Tokenrow *trp)
{
char fname[512]={0}, iname[512]={0};
Includelist *ip;
int angled, len, i;
FILE *fd;
trp->tp += 1;
if (trp->tp>=trp->lp)
goto syntax;
if (trp->tp->type != STRING && trp->tp->type != LT) //如果不是字符串或者<,先做宏替换.
{
len = trp->tp - trp->bp;
expandrow(trp, "<include>");
trp->tp = trp->bp+len;
}
//#include "xxx"
if (trp->tp->type==STRING)
{
len = trp->tp->len-2;
if (len > sizeof(fname) - 1)
len = sizeof(fname) - 1;
strncpy(fname, (char*)trp->tp->t+1, len);
angled = 0;
}
//#include <xxx>
else if (trp->tp->type == LT)
{
len = 0;
trp->tp++;
while (trp->tp->type ! =GT)
{
if (trp->tp>trp->lp || len+trp->tp->len+2 >= sizeof(fname))
goto syntax;
//把<>内部的字符串copy出来.
strncpy(fname+len, (char*)trp->tp->t, trp->tp->len);
len += trp->tp->len;
trp->tp++;
}
angled = 1;
}
//其余是错误的.
else
goto syntax;
trp->tp += 2;
if (trp->tp < trp->lp || len==0)
goto syntax;
fname[len] = '\0';
// do fopen if it is absolute path
//绝地路径.
if (fname[0]=='/' || fname[0]=='\\' ||
(fname[1]==':' &&
(fname[0]>='a' && fname[0]<='z' ||
fname[0]>='A' && fname[0]<='Z')
)
)
{
OutputDebugString(fname);
OutputDebugString("\n");
//直接打开.
fd = fopen(fname, "r");
strcpy(iname, fname);
}
else
{
if (!angled && cursource->filename)
{ // 在当前路径查找.
// search in current file directory first
Source *s = cursource;
char *p;
p = strrchr(s->filename,'/');
if (!p)
p = strrchr(s->filename,'\\');
if (p)
{
strncpy(iname,s->filename,p - s->filename);
iname[p - s->filename] = 0;
strcat(iname, "\\");
strcat(iname, fname);
OutputDebugString(iname);
OutputDebugString("\n");
if ((fd = fopen(iname, "r")) != NULL)
goto found_file;
}
}
for (fd = NULL,i=NINCLUDE-1; i>=0; i--)
{ //从所有-I设置的位置开始找.
ip = &includelist[i];
if (ip->file==NULL || ip->deleted || (angled && ip->always==0))
continue;
if (strlen(fname)+strlen(ip->file)+2 > sizeof(iname))
continue;
strcpy(iname, ip->file);
strcat(iname, "\\");
strcat(iname, fname);
OutputDebugString(iname);
OutputDebugString("\n");
//找到谁算谁.
if ((fd = fopen(iname, "r")) != NULL)
break;
}
}
found_file:
if (/* Mflag>1 || */!angled && Mflag == 2) //打印依赖文件.
{
// fwrite(objname,1,strlen(objname),stdout);
fwrite(iname,1,strlen(iname),stdout);
fwrite(" \\\n ",1,4,stdout);
}
else if(Mflag == 1 && *iname)
{
// fwrite(objname,1,strlen(objname),stdout);
fwrite(iname,1,strlen(iname),stdout);
fwrite(" \\\n ",1,4,stdout);
}
if (fd != NULL)
{
if (++incdepth > 10)
error(E_FATAL, "#include too deeply nested");
setsource((char*)newstring((uchar*)iname, strlen(iname), 0), fd, NULL);
genline();
}
else
{
trp->tp = trp->bp+2;
error(E_ERROR, "Could not find include file %r", trp);
}
return;
syntax:
if (!skipping)
error(E_ERROR, "Syntax error in #include");
return;
}
/*
* Generate a line directive for cursource
*/
void//产生# line numbler filename
genline(void)
{
static Token ta = { UNCLASS };
static Tokenrow tr = { &ta, &ta, &ta+1, 1 };
uchar *p;
if(cursource->line <= 0) return;
ta.t = p = (uchar*)outP;
strcpy((char*)p, "#line ");
p += sizeof("#line ")-1;
p = (uchar*)outnum((char*)p, cursource->line);
*p++ = ' '; *p++ = '"';
strcpy((char*)p, cursource->filename);
p += strlen((char*)p);
*p++ = '"'; *p++ = '\n';
ta.len = (char*)p-outP;
outP = (char*)p;
tr.tp = tr.bp;
puttokens(&tr);
}
/*
* Generate n '\n' characters
*/
void //产生n个换行符.
genblankline(int n)
{
static Token ta = { UNCLASS };
static Tokenrow tr = { &ta, &ta, &ta+1, 1 };
uchar *p;
int i;
ta.t = p = (uchar*)outP;
for (i=0; i<n; i++)
*p++ = '\n';
ta.len = (char*)p-outP;
outP = (char*)p;
tr.tp = tr.bp;
puttokens(&tr);
}
/*
设置.o档的dependence file,如:
test.o: \
test.c \
*/
void
setobjname(char *f)
{
int n = strlen(f);
const char * p = "o: \\\n ";
objname = (char*)domalloc(n+strlen(p)+1);
strcpy(objname,f);
if(objname[n-2]=='.'){
strcpy(objname+n-1,p);
}else{
strcpy(objname+n,p); //没有.就直接copy,似乎也不对.
}
fwrite(objname,1,strlen(objname),stdout);
fwrite(f,1,strlen(f),stdout);
fwrite(" \\\n ",1,4,stdout);
}