六. C语言预处理器LCC-CPP之include.c代码分析

来源:互联网 发布:数据库运维工程师 编辑:程序博客网 时间:2024/05/22 19:57

D:\迅雷下载\lj1020-1022-hb-pd-win2kxp-sc(1)\lj1020-1022-HB-pd-win2kxp-sc

六. C语言预处理器LCC-CPP之include.c代码分析

#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);
}

 

原创粉丝点击