Chinaunix首页 | 论坛 | 博客
  • 博客访问: 263554
  • 博文数量: 52
  • 博客积分: 1379
  • 博客等级: 大尉
  • 技术积分: 525
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-18 17:34
文章分类

全部博文(52)

文章存档

2011年(48)

2010年(4)

分类: C/C++

2011-03-05 22:08:38

  1. /* substitute args in macro_str and return allocated string */
  2. static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
  3. {//
  4.     int last_tok, t, spc;
  5.     const int *st;
  6.     Sym *s;
  7.     CValue cval;
  8.     TokenString str;
  9.     CString cstr;

  10.     tok_str_new(&str);
  11.     //tok_print(macro_str);
  12.     //assert(0);
  13.     //mstr: d + s
  14.     last_tok = 0;
  15.     while(1) {
  16.         TOK_GET(&t, &macro_str, &cval);
  17.         if (!t)
  18.             break;
  19.         if (t == '#') {
  20.             /* stringize */
  21.             TOK_GET(&t, &macro_str, &cval);
  22.             if (!t)
  23.                 break;
  24.             s = sym_find2(args, t);
  25.             if (s) {
  26.                 cstr_new(&cstr);
  27.                 st = s->d;
  28.                 spc = 0;
  29.                 while (*st) {
  30.                     TOK_GET(&t, &st, &cval);
  31.                     if (!check_space(t, &spc))
  32.                         cstr_cat(&cstr, get_tok_str(t, &cval));
  33.                 }
  34.                 cstr.size -= spc;
  35.                 cstr_ccat(&cstr, '\0');
  36. #ifdef PP_DEBUG
  37.                 printf("stringize: %s\n", (char *)cstr.data);
  38. #endif
  39.                 /* add string */
  40.                 cval.cstr = &cstr;
  41.                 tok_str_add2(&str, TOK_STR, &cval);
  42.                 cstr_free(&cstr);
  43.             } else {
  44.                 tok_str_add2(&str, t, &cval);
  45.             }
  46.         } else if (t >= TOK_IDENT) {
  47.             //d + s, 第一次, d
  48.             s = sym_find2(args, t);
  49.             if (s) {
  50.                 //yes, s is (the only) args of macro a
  51.                 //s->d: b(x)
  52.                 st = s->d;
  53.                 //tok_print(st);
  54.                 //assert(0);

  55.                 /* if '##' is present before or after, no arg substitution */
  56.                 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
  57.                     /* special case for var arg macros : ## eats the
  58.                        ',' if empty VA_ARGS variable. */
  59.                     /* XXX: test of the ',' is not 100%
  60.                        reliable. should fix it to avoid security
  61.                        problems */
  62.                     if (gnu_ext && s->type.t &&
  63.                         last_tok == TOK_TWOSHARPS &&
  64.                         str.len >= 2 && str.str[str.len - 2] == ',') {
  65.                         if (*st == 0) {
  66.                             /* suppress ',' '##' */
  67.                             str.len -= 2;
  68.                         } else {
  69.                             /* suppress '##' and add variable */
  70.                             str.len--;
  71.                             goto add_var;
  72.                         }
  73.                     } else {
  74.                         int t1;
  75.                     add_var:
  76.                         for(;;) {
  77.                             TOK_GET(&t1, &st, &cval);
  78.                             if (!t1)
  79.                                 break;
  80.                             tok_str_add2(&str, t1, &cval);
  81.                         }
  82.                     }
  83.                 } else {
  84.                     /* NOTE: the stream cannot be read when macro
  85.                        substituing an argument */
  86.                     //b(x) 需要替换成 t + t1, 里面会继续替换为 ttt + t2
  87.                     macro_subst(&str, nested_list, st, NULL);
  88.                     //tok_print(str.str);assert(0);
  89.                     // tok_print(str.str);
  90.                     // assert(0);
  91.                     // # 17 "t.c"
  92.                     //
  93.                     // tcc: tccpp.c:XXXX: macro_arg_subst: Assertion `0' failed.
  94.                 }
  95.             } else {
  96.                 //如果不是参数,就直接加入就可以
  97.                 //#define a(d) d + s 中的s

  98.                 tok_str_add(&str, t);
  99.             }
  100.         } else {
  101.             //参数必须是标示符 ' ', +属于这里
  102.             tok_str_add2(&str, t, &cval);
  103.         }
  104.         last_tok = t;
  105.     }
  106.     tok_str_add(&str, 0);
  107.     return str.str;
  108. }
阅读(1913) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~