注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Tsecer的回音岛

Tsecer的博客

 
 
 

日志

 
 

make对依赖中空格的处理  

2010-12-26 00:52:24|  分类: make源代码分析 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

一、gcc对空格的处理

gcc-4.3.1\libcpp\directives.c

gcc的代码中包含了对包含头文件的处理

static const char *
parse_include (cpp_reader *pfile, int *pangle_brackets,
        const cpp_token ***buf)
{
  char *fname;
  const cpp_token *header;

  /* Allow macro expansion.  */
  header = get_token_no_padding (pfile);
  if (header->type == CPP_STRING || header->type == CPP_HEADER_NAME)
    {
      fname = XNEWVEC (char, header->val.str.len - 1);
      memcpy (fname, header->val.str.text + 1, header->val.str.len - 2);
      fname[header->val.str.len - 2] = '\0';
      *pangle_brackets = header->type == CPP_HEADER_NAME;
    }
  else if (header->type == CPP_LESS)
    {
      fname = glue_header_name (pfile);
      *pangle_brackets = 1;
    }

可以看到,它是对包含的头文件按照字符串来解释并且复制的,这样包含的头文件的路径中就可以包含空格了。

gcc-4.3.1\libcpp\mkdeps.c

static const char *
munge (const char *filename)

for (p = filename, dst = buffer; *p; p++, dst++)
    {
      switch (*p)
 {
 case ' ':
 case '\t':
   for (q = p - 1; filename <= q && *q == '\\';  q--)
     *dst++ = '\\';
   *dst++ = '\\';
   break;

 case '$':
   *dst++ = '$';
   break;

 default:
   /* nothing */;
 }
      *dst = *p;
    }

可以看到这里对空格,制表符,美元符号和反斜杠都进行了转义。所以一个

#include "first "

在依赖中将会显示为:

main.c:first\ \

这样加上一个逻辑换行符,可能拼接出一个特别长的不合法的路径。

二、make对空格的处理

make中对于其中的处理为:

static char *
find_char_unquote (char *string, int stop1, int stop2, int blank,
                   int ignorevars)
{
  unsigned int string_len = 0;
  char *p = string;

  if (ignorevars)
    ignorevars = '$';

即对于反斜杠的处理将会

> gnumake.exe!find_char_unquote(char * string=0x0098b7f8, int stop1=124, int stop2=0, int blank=1, int ignorevars=0)  行2186 C
  gnumake.exe!parse_file_seq(char * * stringp=0x0012efc0, unsigned int size=20, int stopchar=124, const char * prefix=0x00000000, int flags=0)  行2923 + 0x13 字节 C
  gnumake.exe!split_prereqs(char * p=0x0098b7f8)  行429 + 0x11 字节 C
  gnumake.exe!record_files(nameseq * filenames=0x0098b678, const char * pattern=0x00000000, const char * pattern_percent=0x00000000, char * depstr=0x0098b7f8, unsigned int cmds_started=1, char * commands=0x0098b898, unsigned int commands_idx=0, int two_colon=0, const floc * flocp=0x0012f168)  行1886 + 0x9 字节 C
  gnumake.exe!eval(ebuffer * ebuf=0x0012f194, int set_default=1)  行1296 + 0x35 字节 C
  gnumake.exe!eval_makefile(const char * filename=0x00960203, int flags=0)  行423 + 0x17 字节 C

对于查找分割的方法,这里p一般指向第一个空格,然后空格的状态将会引起之前的反斜杠的状态的迁移,这是一个状态决定的问题,但是在前面的扫面中,反斜杠本身并不会引起扫描的终止。

    if (p > string && p[-1] == '\\')
 {
   /* Search for more backslashes.  */
   int i = -2;
   while (&p[i] >= string && p[i] == '\\')
     --i;
   ++i;
   /* Only compute the length if really needed.  */
   if (string_len == 0)
     string_len = strlen (string);
   /* The number of backslashes is now -I.
      Copy P over itself to swallow half of them.  */
   memmove (&p[i], &p[i/2], (string_len - (p - string)) - (i/2) + 1);
   p += i/2;
   if (i % 2 == 0)
     /* All the backslashes quoted each other; the STOPCHAR was
        unquoted.  */
     return p;

   /* The STOPCHAR was quoted by a backslash.  Look for another.  */
 }
      else
 /* No backslash in sight.  */
 return p;

当一个空格钱不是斜杠的时候,会走到第二个分支,从而在遇到空格的时候直接返回

 

在cygwin中测试,

#include <stdio.h>
#include <fcntl.h>
int main()
{
 int fd = open("first.h ",O_RDONLY , 0);
 printf("fd is\t%d\n",fd);

 }

将多余的空格加在开始有语法错误,但是加在最后可以正常运行,这个应该是cygwin的bug而不是linux内核的bug

  评论这张
 
阅读(629)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017