* acl4のページ0012
-(by [[K]], 2026.02.11)

** (1)
 #if (a_Version >= 1)
     #define Preprocessor_define5    a_Preprocessor_define5
     #define Preprocessor_define6    a_Preprocessor_define6
     #define Preprocessor_define7    a_Preprocessor_define7
     #define Preprocessor_define0    a_Preprocessor_define0
 #endif
 
 a_static void a_Preprocessor_define5(a_Set0 *set, a_Token0 *t0, a_VecChr *lin, int defC, a_Preprocessor_SourceFiles *sfs, a_VecChr *stkDef, int mod)
 {
     a_VecChr args[1], tmp[1], tmp1[1]; a_VecChr_ini4(args, tmp, tmp1, 0);
     char *k = a_Token1_get(t0);
     intptr_t kn = t0->len, an = -1;
     if (k[kn] == '(') {
         t0->s++; a_parseArgs(t0, args);
         if (t0->len == 0) goto fin;
         an = args->n / (2 * sizeof (char *));
         if (an + defC > 256) a_errExit("Preprocessor_define5: too many args (c=%d, n=%d)", defC, an);
     }
     char *t = a_Token1_get(t0);
 //  if (mod > 0 && t0->c == ':') t = a_Token1_get(t0);
     a_VecChr_resize(_arg_  tmp, lin->p + lin->n - t);
     memcpy(tmp->p, t, tmp->n); 
     a_VecChr_reserve0(tmp);
     if (t + 1 < lin->p + lin->n && t[0] == '[' && t[1] == '^') {
         a_VecChr_replace(tmp, 0, 2, NULL, 0);
         int mc = 1;
         char *u = strstr(tmp->p, "^]");
         if (u != NULL) {
             mc = 0;
             tmp->n = u - tmp->p;
         }
         while (mc > 0) {
             a_Preprocessor_SourceFiles_gets(sfs, tmp1);
             if (tmp1->n == 0) break;
             char *u = strstr(tmp1->p, "^]");
             if (strstr(tmp1->p, "[^") != NULL) mc++;
             if (u != NULL) mc--;
             if (mc > 0)
                 a_VecChr_replace(tmp, tmp->n, 0, tmp1->p, tmp1->n);
             else
                 a_VecChr_replace(tmp, tmp->n, 0, tmp1->p, u - tmp1->p);
         }
     } else {
         if (tmp->p[tmp->n - 1] == '\n') tmp->n--;
     }
     if (mod == 0)
         a_Preprocessor_marking0(tmp, t0, args, defC);
     else
         a_Preprocessor_marking1(tmp, args, defC, (int) an, tmp1);
     unsigned char *kk = a_Preprocessor_newKey(an & 0xff, k, kn);
     unsigned char *kk = (unsigned char *) a_Preprocessor_newKey(an & 0xff, k, kn);
     a_Preprocessor_Define *d0 = a_Set0_findKn(set, kk, kn + 1);
     if (d0 == NULL) {
         d0 = a_malloc(_arg_  sizeof (a_Preprocessor_Define));
         d0->elm->k = a_Preprocessor_newKey(an & 0xff, k, kn);
         d0->elm->n = kn + 1;
         d0->q = NULL;
         d0->n = -1;
         a_Set0_add(set, d0->elm);
     }
     if (mod == 0) {
         if (d0->q != NULL)
             a_free(_arg_  d0->q, d0->n);
     }
     if (mod == 1) {
         a_Preprocessor_Define *sp = a_VecChr_stkAdd(stkDef, sizeof (a_Preprocessor_Define));
         sp->elm->k = a_Preprocessor_newKey(an & 0xff, k, kn);
         sp->n = kn + 1;
         sp->elm->n = kn + 1;
         sp->q = d0->q;
         sp->n = d0->n;
     }
     if (mod <= 1) {
         d0->q = a_malloc(_arg_  tmp->n);
         d0->n = tmp->n;
         if (tmp->n > 0)
             memcpy(d0->q, tmp->p, tmp->n);
     }
     if (mod >= 2) {
         if (d0->q == NULL) {
             d0->q = a_malloc(_arg_  0);
             d0->n = 0;
         }
         char *q1 = a_malloc(_arg_  d0->n + tmp->n);
         if (mod == 2) {
             if (d0->n  > 0) memcpy(q1,          d0->q,  d0->n);
             if (tmp->n > 0) memcpy(q1 + d0->n,  tmp->p, tmp->n);
         } else {
             if (tmp->n > 0) memcpy(q1,          tmp->p, tmp->n);
             if (d0->n  > 0) memcpy(q1 + tmp->n, d0->q,  d0->n);
         }
         if (d0->q != NULL) a_free(_arg_  d0->q, d0->n);
         d0->q = q1;
         d0->n += tmp->n;
     }
     a_free(_arg_  kk, kn + 1);
 fin:
     a_VecChr_din4(args, tmp, tmp1, 0);
 }
 
 a_static int a_Preprocessor_define6(a_Set0 *set, a_Token0 *t0, a_VecChr *lin, a_VecChr *stkDef, int mod)
 {
     char *k = a_Token1_get(t0);
     char *k = a_Token1_get(t0); (void) lin;
     intptr_t kn = t0->len, an = -2;
     char *t = a_Token1_get(t0);
     if (t0->c == ',') an = strtol(t + 1, NULL, 0);
     char *kk = a_Preprocessor_newKey(an & 0xff, k, kn);
     a_Preprocessor_Define *d;
     if (mod == 0) {
         if (an == -2) {
             for (an = -1; an <= 64; an++) {
                 kk[0] = an & 0xff;
                 d = a_Set0_findKn(set, kk, kn + 1);
                 if (d != NULL) break;
             }
         } else
             d = a_Set0_findKn(set, kk, kn + 1);
         if (d != NULL)
             a_Set0_rmv(set, d->elm);
         a_Preprocessor_Define_din(d);
     } else {
         d = a_Set0_findKn(set, kk, kn + 1);
         if (stkDef->n == 0) {
 err:
             a_free(_arg_  kk, kn + 1);
             return 0;
         }
         if (stkDef->n == 0) goto err;
         a_Preprocessor_Define *sp = a_VecChr_stkRmv(stkDef, sizeof (a_Preprocessor_Define));
         stkDef->n += sizeof (a_Preprocessor_Define);
         if (sp->elm->n != kn + 1) goto err;
         if (memcmp(sp->elm->k, kk, kn + 1) != 0) goto err;
         stkDef->n -= sizeof (a_Preprocessor_Define);
         if (sp->n >= 0) {
             if (d->q != NULL) a_free(_arg_  d->q, d->n);
             d->q = sp->q;
             d->n = sp->n;
             sp->q = NULL;
         } else {
             a_Set0_rmv(set, d->elm);
             a_Preprocessor_Define_din(d);
             a_free(_arg_  d, sizeof (a_Preprocessor_Define));
         }
         a_Preprocessor_Define_din(sp);
     }
     a_free(_arg_  kk, kn + 1);
     return 1;
 }
 
 a_static void a_Preprocessor_define7(a_Set0 *set, int an, const char *k, const char *v)
 {
     intptr_t kn = strlen(k), vn = strlen(v);
     a_Preprocessor_Define *d = a_malloc(_arg_  sizeof (a_Preprocessor_Define));
     d->elm->k = a_Preprocessor_newKey(an & 0xff, k, kn);
     d->elm->n = kn + 1;
     d->q = a_malloc(_arg_  vn); memcpy(d->q, v, vn);
     d->n = vn;
     a_Set0_add(set, d->elm);
 }
 
 a_static void a_Preprocessor_define0(a_Set0 *set, a_Token0 *t0, a_VecChr *lin, int defC)
 // #defineの登録処理. (もはや使ってないが、互換性のために残してある).
 {
     a_Preprocessor_define5(set, t0, lin, defC, NULL, NULL, 0);
 }

** (2) 説明
-#define のほかに、 #.def 、 #.addTl 、 #.addHd をサポートしようと思い、 Preprocessor_define0 を大幅に書き足して、 Preprocessor_define5 を作りました。
--mod=0: #define 処理
--mod=1; #.def 処理
--mod=2: #.addTl 処理
--mod=3: #.addHd 処理
-Preprocessor_define6 → #undef (mod=0)、 #.undef (mod=1)処理
-Preprocessor_define7 → プリプロセッサに対するコマンドライン引数などで、あらかじめ #define 処理をしたい場合がありますが、そのために使う関数です。

** (3)
-このページにはサンプルプログラムがありません。
-これらを使って、 [[a4_0013]] でプリプロセッサを作ります。

** (99) 更新履歴
-2026.02.11(水) 初版

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS