acl4のページ0021

(1) 概要


(2) デモ

(3) ライブラリプログラム

a_static int a_Preprocessor_substitute0(a_Token0 *t0, a_VecChr *lin, a_VecChr *path, intptr_t linNo, uint32_t stpTkn, a_VecChr *tmp, a_VecChr *defEnum)
{
    char *p = lin->p; t0->s1 = p + a_VecChr_N(lin);
    int rv = 0;
    for (t0->s = p;;) {
        char *t = a_Token1_get(t0);
        if (t0->len == 0 || t0->c == stpTkn) break;
        if (t0->len == 2 && t[0] == '#' && t[1] == '#') { // ## があったら前後の空白類とともに削除する.
            intptr_t pos0 = t - p, pos1 = pos0 + 2;
            while (pos0 > 0 && p[pos0 - 1] <= ' ') pos0--;
            while (pos1 < a_VecChr_N(lin) && p[pos1] <= ' ') pos1++;
            a_VecChr_replace(lin, pos0, pos1 - pos0, NULL, 0);
            t0->s = p; // 長さが短くなるだけなのでpは変化しない.
            t0->s1 = p + a_VecChr_N(lin);
            rv = 1;
        }
    }
    if (rv != 0) return rv;
cont0:
    t0->c = 0; intptr_t pos0 = 0; 
    for (t0->s = p;;) {
        intptr_t c0 = t0->c, pos00 = pos0;
cont1:
        char *t = a_Token1_get(t0);
        if (t0->len == 0 || t0->c == stpTkn) break;
        pos0 = t - p;
        if (t0->c == '.' && t[1] == '(') {
            a_VecChr_replace(lin, pos0, 2, "(_a, ", 5); return 1; // 置換する.
        }
        if (c0 == '(' && t0->c == ',') { *t = ' '; rv = 1; goto cont1; } // ここで処理すると改行を超えられないという問題はある.
        if (c0 == '{' && t0->c == ',') { *t = ' '; rv = 1; goto cont1; } // それが深刻な問題になったら、別の方法を考えないといけない.
        if (c0 == ',' && t0->c == ',') { *t = ' '; rv = 1; goto cont1; }
        if (c0 == ',' && t0->c == ')') { puts(p); p[pos00] = ' '; rv = 1; goto cont0; }
        if (c0 == ',' && t0->c == '}') { p[pos00] = ' '; rv = 1; goto cont0; }
        if (t0->cTyp != 3) continue;
        if (t0->len == 8 && memcmp(t, "__FILE__", 8) == 0) {
            a_VecChr_N(tmp) = 0; a_VecChr_printf(tmp, "\"%.*s\"", (int) a_VecChr_N(path), path->p);
            a_VecChr_replace(lin, pos0, t0->len, tmp->p, a_VecChr_N(tmp)); return 1;
        }
        if (t0->len == 8 && memcmp(t, "__LINE__", 8) == 0) {
            a_VecChr_N(tmp) = 0; a_VecChr_printf(tmp, "%d", (int) linNo);
            a_VecChr_replace(lin, pos0, t0->len, tmp->p, a_VecChr_N(tmp)); return 1;
        }
        if (t0->len == 8 && &t[8] < t0->s1 && memcmp(t, "defRight(", 9) == 0) {
            t0->s = &t[9]; a_parseArgs(t0, tmp); a_parseArgs_Arg *paa = (a_parseArgs_Arg *) tmp->p;
            if (t0->c == ')' && a_VecChr_N(tmp) == 2 * (intptr_t) sizeof (a_parseArgs_Arg)) {
                a_VecChr vca[1], vcb[1];
                a_VecChr_iniCpy0(_a_ vca, paa[0].s, paa[0].n);
                a_VecChr_iniCpy0(_a_ vcb, paa[1].s, paa[1].n);
                char *ssp = strstr(vca->p, vcb->p);
                if (ssp != NULL) {
                    int len1 = a_VecChr_N(vca) - (ssp - vca->p) - a_VecChr_N(vcb);
                    a_VecChr_replace(lin, pos0, t0->s - t, ssp + a_VecChr_N(vcb), len1); rv = 1;
                    a_VecChr_din4(_a_ vca, vcb, 0, 0);
cont2:
                    p = lin->p;
                    t0->s = p + pos0 + len1;
                    t0->s1 = p + a_VecChr_N(lin);
                    goto cont0;
                }
                a_VecChr_din4(_a_ vca, vcb, 0, 0);
            }
            t0->s = t; a_Token1_get(t0); // 巻き戻す.
        }
        if (t0->len == 7 && &t[7] < t0->s1 && memcmp(t, "defEnum(", 8) == 0) {
            t0->s = &t[8]; a_parseArgs(t0, tmp); a_parseArgs_Arg *paa = (a_parseArgs_Arg *) tmp->p;
            if (t0->c == ')' && a_VecChr_N(tmp) == 2 * (intptr_t) sizeof (a_parseArgs_Arg)) {
                intptr_t i = strtol(paa[0].s, NULL, 0), j = strtol(paa[1].s, NULL, 0);
                a_VecChr_resize0(defEnum, (i + 1) * sizeof (intptr_t));
                *(intptr_t *) defEnum->p = j;
                a_VecChr_replace(lin, pos0, t0->s - t, NULL, 0); rv = 1; goto cont2;
            }
            if (t0->c == ')' && a_VecChr_N(tmp) == 1 * (intptr_t) sizeof (a_parseArgs_Arg)) {
                intptr_t i = strtol(paa[0].s, NULL, 0), j;
                a_VecChr_resize0(defEnum, (i + 1) * sizeof (intptr_t));
                j = *(intptr_t *) defEnum->p;
                char s[16]; sprintf(s, "%d", j);
                *(intptr_t *) defEnum->p = j + 1;
                a_VecChr_replace(lin, pos0, t0->s - t, s, strlen(s)); rv = 1; goto cont2;
            }
            t0->s = t; a_Token1_get(t0); // 巻き戻す.
        }
    }
    return rv;
}

a_static void a_SetElm_mallocCpy(a_SetElm *w, const char *s, intptr_t n)
{
    w->k = a_malloc(_a_  n); memcpy((char *) w->k, s, n); w->n = n;
}

a_class(a_TypedDef_TypeCache) { a_SetElm elm[1]; a_VecChr typ[1]; };

a_static void a_TypedDef_TypeCache_din(a_SetElm *elm)
{
    a_TypedDef_TypeCache *p = (a_TypedDef_TypeCache *) elm;
    a_VecChr *q = (a_VecChr *) p->typ->p;
    intptr_t i, i1 = a_VecChr_N(p->typ) / sizeof (a_VecChr);
    for (i = 0; i < i1; i++)
        a_VecChr_din(_a_ &q[i]);
    a_free(_a_ (char *) p->elm->k, p->elm->n);
    a_VecChr_din(_a_ p->typ);
    a_free(_a_ p,  sizeof(a_TypedDef_TypeCache));
}

a_static a_VecChr *a_TypedDef_getTypeList(a_Set0 *cache, const char *s, intptr_t n, Token0 *t0, a_VecChr *tmp)
{
    a_TypedDef_TypeCache *p;
    a_VecChr *q;
    intptr_t i, i1;
    if (n == 0) {
        static a_VecChr nulSub[1] = { (char *) &a_VecChr_p0[2] };
        static void *nulPtr[3] = { (void *) sizeof (a_VecChr), (void *) sizeof (a_VecChr), nulSub };
        static a_VecChr nul[1] = { (char *) &nulPtr[2] };
        return nul;
    }
    p = a_Set0_findKn(cache, s, n);
    if (p == NULL) {
        p = a_malloc(_a_  sizeof(a_TypedDef_TypeCache));
        a_SetElm_mallocCpy(p->elm, s, n);
        t0->s = s; t0->s1 = s + n;
        if (*s == '(' || *s == '{' || *s == '[') t0->s++;
        a_parseArgs(t0, tmp);
        a_parseArgs_Arg *paa = (a_parseArgs_Arg *) tmp->p; i1 = a_VecChr_N(tmp) / sizeof (a_parseArgs_Arg);
        a_VecChr_ini(_a_ p->typ); a_VecChr_resize(p->typ, i1 * sizeof (a_VecChr));
        q = (a_VecChr *) p->typ->p;
        for (i = 0; i < i1; i++)
            a_VecChr_iniCpy(_a_ &q[i], paa[i].s, paa[i].n);
        a_Set0_add(cache, p->elm);
    }
    return p->typ;
}

a_static int a_TypedDef_cmpTyp(a_VecChr *typ, const char *s, intptr_t n)
{
    a_VecChr *q = (a_VecChr *) typ->p;
    intptr_t i, i1 = a_VecChr_N(typ) / sizeof (a_VecChr);
    for (i = 0; i < i1; i++) {
        intptr_t qin = a_VecChr_N(&q[i]);
        if (qin == 0) return 1;
        if (n >= qin && memcmp(s, q[i].p, qin) == 0) return 1;
    }
    return 0;
}

a_static int a_TypedDef_cmpTyps(a_VecChr *typs, a_parseArgs_Arg *paa, intptr_t an)
{
    intptr_t i;
    if (a_VecChr_N(typs) == 0) return 1;
    a_VecChr **tp = (a_VecChr **) typs->p;
    for (i = 0; i < an; i++) {
        if (a_TypedDef_cmpTyp(tp[i], paa[i].s, paa[i].n) == 0) return 0;
    }
    return 1;
}

a_class(a_Preprocessor_Define0) { a_SetElm elm[1]; a_VecChr vc[1]; };
a_class(a_Preprocessor_Define1) { a_VecChr typs[1], def[1]; };

a_static void a_Preprocessor_Define0_din(a_SetElm *elm)
{
    a_Preprocessor_Define0 *p = (a_Preprocessor_Define0 *) elm;
    a_VecChr *anp = (a_VecChr *) p->vc->p; intptr_t ani = a_VecChr_N(p->vc) / sizeof (a_VecChr) - 1;
    for (; ani >= 0; ani--) {
        a_Preprocessor_Define1 *d1p = (a_Preprocessor_Define1 *) anp[ani].p;
        intptr_t d1i = a_VecChr_N(&anp[ani]) / sizeof (a_Preprocessor_Define1) - 1;
        for (; d1i >= 0; d1i--)
            a_VecChr_din4(_a_ d1p[d1i].typs, d1p[d1i].def, 0, 0);
        a_VecChr_din(_a_ &anp[ani]);
    }
    a_free(_a_ (char *) p->elm->k, p->elm->n);
    a_VecChr_din(_a_ p->vc);
    a_free(_a_ p,  sizeof(a_Preprocessor_Define0));
}

a_static a_VecChr *a_Preprocessor_findDef(a_Set0 *set, char *t, a_Token0 *t0, a_VecChr *tmp, int rmvFlg, intptr_t *repLen) {

	intptr_t n = t0->len, i;
	a_Preprocessor_Define0 *pd = a_Set0_findKn(set, t, n);
	if (pd == NULL) return NULL;
	a_VecChr *vcp = (a_VecChr *) pd->vc->p;
	intptr_t vcn = a_VecChr_N(pd->vc) / sizeof (a_VecChr), an, def1n, rl = n;
	a_Preprocessor_Define1 *def1p;
	if (t + n < t0->s1 && t[n] == '(') {
       a_Token1_get(t0);
       a_parseArgs(t0, tmp);
		an = a_VecChr_N(tmp) / sizeof (a_parseArgs_Arg);
		if (an + 1 >= vcn) goto skip;
		def1n = a_VecChr_N(&vcp[an + 1]) / sizeof (a_Preprocessor_Define1);
		if (def1n == 0) goto skip;
		def1p = (a_Preprocessor_Define1 *) vcp[an + 1].p;
		rl = t0->s - t;
		for (i = def1n - 1; i >= 0; i--) {
			if (a_TypedDef_cmpTyps(def1p[i].typs, (a_parseArgs_Arg *) tmp->p, an) != 0) goto find;
		}
	}

skip:

	an = -1;
	def1n = a_VecChr_N(&vcp[0]) / sizeof (a_Preprocessor_Define1);;
	def1p = (a_Preprocessor_Define1 *) vcp[0].p;
	if (def1n == 0) return NULL;
	i = def1n - 1;

find:

	if (rmvFlg != 0) {
		a_VecChr_din4(_a_ def1p[i].typs, def1p[i].def, 0, 0);
		a_VecChr_replace(&vcp[an + 1], i * sizeof (a_Preprocessor_Define1), sizeof (a_Preprocessor_Define1), NULL, 0);
		while (vcn > 0) {
			if (a_VecChr_N(&vcp[vcn - 1]) > 0) break;
			a_VecChr_din(_a_ &vcp[vcn - 1]);
			vcn--;
		}
		a_VecChr_N(pd->vc) = vcn * sizeof (a_VecChr);
		if (vcn == 0) {
		    a_SetElm elm[1];
   		elm->k = t;
   		elm->n = n;
			a_Set0_rmv(set, elm);
			a_VecChr_din(_a_ pd->vc);
		}
		return NULL;
	}
	*repLen = rl;
	return def1p[i].def;

}

a_static int a_Preprocessor_substitute1(a_Token0 *t0, a_Token0 *t0a, a_VecChr *lin, uint32_t stpTkn, a_Set0 *set, a_VecChr *tmp, a_VecChr *tmp1, int defC) {

   char *p = lin->p; t0a->s1 = t0->s1 = p + a_VecChr_N(lin);
	a_Preprocessor_Define0 *pd;
   for (t0->s = p;;) {
       char *t = a_Token1_get(t0), *u; intptr_t repLen;
       if (t0->len == 0 || t0->c == stpTkn) break;
       if (t0->cTyp != 3) continue;
       if (t0->len == 7 && &t[7] < t0->s1 && memcmp(t, "defined(", 8) == 0) {
           t0a->s = &t[8]; a_parseArgs(t0a, tmp);
           if (t0a->c == ')' && a_VecChr_N(tmp) == sizeof (a_parseArgs_Arg)) {
				a_parseArgs_Arg *paa = (a_parseArgs_Arg *) tmp->p;
				pd = a_Set0_findKn(set, paa->s, paa->n);

defined1: ;

				char c = '0';
				if (pd != NULL) c = '1';
               a_VecChr_replace(lin, t - p, t0a->s - t, &c, 1);
				return 1;
			}
		}
       if (t0->len == 7 && memcmp(t, "defined", 7) == 0) {
           t0a->s = &t[7]; u = a_Token1_get(t0a);
			pd = a_Set0_findKn(set, u, t0a->len);
			goto defined1;
		}
       if (t0->len == 8 && &t[8] < t0->s1 && memcmp(t, "definedx(", 9) == 0) {
			t0a->s = &t[9]; t = a_Token1_get(t0a);
			char c = '0';
			if (a_Preprocessor_findDef(set, t, t0a, tmp, 0, &repLen) != 0) c = '1';
           a_VecChr_replace(lin, t - p, repLen, &c, 1);
			return 1;
		}
		// マクロ展開.
		t0a->s = t; t = a_Token1_get(t0a);
		a_VecChr *def = a_Preprocessor_findDef(set, t, t0a, tmp, 0, &repLen);
		a_parseArgs_Arg *paa = (a_parseArgs_Arg *) tmp->p;
		if (def != NULL) {
			a_VecChr_resize(tmp1, a_VecChr_N(def));
			memcpy(tmp1->p, def->p, a_VecChr_N(def));
           for (;;) {
               char *q = memchr(tmp1->p, defC, a_VecChr_N(tmp1));
               if (q == NULL) break;
               int i = ((unsigned char *) q)[1] - defC;
               a_VecChr_replace(tmp1, q - tmp1->p, 2, paa[i].s, paa[i].n); // 引数を代入.
           }
           a_VecChr_replace(lin, t - p, repLen, tmp1->p, a_VecChr_N(tmp1));
			return 1;
		}
	}
	return 0;

}

a_static void a_Preprocessor_marking0(a_VecChr *tmp, a_parseArgs_Arg *paa, intptr_t an, intptr_t as, int c, a_Token0 *t0) {

   int i;
   a_Set0 set[1]; a_Set0_ini(_a_ set, NULL); a_SetElm elm[256];
   char mark[2], *t; mark[0] = c;
   if (an + c > 256) a_errExit("Preprocessor_define1: too many args (c=%d, an=%d)", c, an);
   for (i = 0; i < an; i++) {
       elm[i].k = paa->s;
       elm[i].n = paa->n;
		paa += as;
       a_Set0_add(set, &elm[i]);
   }
   t0->s = tmp->p; t0->s1 = tmp->p + a_VecChr_N(tmp); a_VecChr_N(tmp) = 0;
   for (;;) {
       t = a_Token1_get(t0);
       if (t0->len == 0) break;
       a_VecChr_N(tmp) = t + t0->len - tmp->p;
   }
   t0->s = tmp->p; t0->s1 = tmp->p + a_VecChr_N(tmp);
   for (;;) {
       t = a_Token1_get(t0);
       if (t0->len == 0) break;
       if (t0->len >= 2 && t[0] == '/' && t[1] == '/') {
           a_VecChr_N(tmp) = t - tmp->p; // コメントが後続しているならそこから打ち切る。
           break;
       }
   }
   while (a_VecChr_N(tmp) > 0 && ((unsigned char *) tmp->p)[a_VecChr_N(tmp) - 1] <= ' ') a_VecChr_N(tmp)--;
   t0->s = tmp->p; t0->s1 = tmp->p + a_VecChr_N(tmp);
   for (;;) {
       t = a_Token1_get(t0);
       if (t0->len == 0) break;
       a_SetElm *e = a_Set0_findKn(set, t, t0->len);
       if (e != NULL) {
           mark[1] = (char) (c + (e - elm));
           intptr_t pos0 = t - tmp->p;
           a_VecChr_replace(tmp, pos0, t0->len, mark, 2); // 変数名を [01 xx] に置換.
           t0->s = tmp->p + pos0 + t0->len;
           t0->s1 = tmp->p + a_VecChr_N(tmp);
       }
   }
   a_Set0_din(_a_ set);

}

a_static void a_Preprocessor_marking1(a_VecChr *tmp, a_parseArgs_Arg *paa, intptr_t an, intptr_t as, int c, a_VecChr *tmp1) {

   int i; // Token1_getをあえて使わずに、strstrで見つけて置換していく.
   for (i = 0; i < an; i++) {
       a_VecChr_N(tmp1) = 0;
       a_VecChr_puts(tmp1, paa->s, paa->n);
       char *p = strstr(tmp->p, tmp1->p), mark[2];
       mark[0] = c;
       mark[1] = c + i;
       while (p != NULL) {
           intptr_t pos = p - tmp->p;
           a_VecChr_replace(tmp, pos, a_VecChr_N(tmp1), mark, 2);
           p = strstr(tmp->p + pos + 2, tmp1->p);
       }
		paa += as;
   }

}

a_static void a_Preprocessor_define0(a_Set0 *set, const char *s, intptr_t sn, const char *t, intptr_t tn, intptr_t an, a_Set0 *typCache, a_parseArgs_Arg *tyPaa, intptr_t as, a_Token0 *t0a, a_VecChr *tmp) {

	a_Preprocessor_Define0 *pd0 = a_Set0_findKn(set, s, sn);
	if (pd0 == NULL) {
		pd0 = a_malloc(_a_ sizeof (a_Preprocessor_Define0));
		a_SetElm_mallocCpy(pd0->elm, s, sn);
		a_VecChr_ini(_a_ pd0->vc);
		a_Set0_add(set, pd0->elm);
	}
	while ((an + 1) * sizeof (a_VecChr) >= (unsigned int) a_VecChr_N(pd0->vc)) {
		a_VecChr *tvc = a_VecChr_stkAdd(pd0->vc, sizeof (a_VecChr));
		a_VecChr_ini(_a_ tvc);
	}
	a_VecChr *vcp = (a_VecChr *) pd0->vc->p;
	a_Preprocessor_Define1 *pd1 = a_VecChr_stkAdd(&vcp[an + 1], sizeof (a_Preprocessor_Define1));
	a_VecChr_ini(_a_ pd1->typs);
	a_VecChr_iniCpy(_a_ pd1->def, t, tn);
	if (an > 0 && tyPaa != NULL) {
		a_VecChr_resize(pd1->typs, an * sizeof (a_VecChr *));
		a_VecChr **tp = (a_VecChr **) pd1->typs->p;
		intptr_t i;
		for (i = 0; i < an; i++) {
			tp[i] = a_TypedDef_getTypeList(typCache, tyPaa->s, tyPaa->n, t0a, tmp);
			tyPaa += as;
		}
	}

}

a_static void a_Preprocessor_define1(int mod, a_Token0 *t0, a_VecChr *lin, a_Preprocessor_SourceFiles *sfs, a_VecChr *args, a_VecChr *tmp, a_VecChr *tmp1, a_Set0 *set, int defC, a_Set0 *typCache) {

   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) return;
		an = a_VecChr_N(args) / sizeof (a_parseArgs_Arg);
       if (an + defC > 256) a_errExit("Preprocessor_define1: too many args (c=%d, n=%d)", defC, an);
   }
	if (mod == 1 && an < 2) return;
   char *t = a_Token1_get(t0), *s1 = lin->p + a_VecChr_N(lin);
	a_VecChr_replace(tmp, 0, a_VecChr_N(tmp), t, s1 - t);
   a_VecChr_reserve0(tmp);
	int mod1 = 0;
   if (t + 1 < s1 && t[0] == '[' && t[1] == '^') {
		mod1 = 1;
       a_VecChr_replace(tmp, 0, 2, NULL, 0);
       int mc = 1;
       char *u = strstr(tmp->p, "^]");
       if (u != NULL) {
           mc = 0;
           a_VecChr_N(tmp) = u - tmp->p;
       }
       while (mc > 0) {
           a_Preprocessor_SourceFiles_gets(sfs, tmp1);
           if (a_VecChr_N(tmp1) == 0) break;
           char *u = strstr(tmp1->p, "^]");
           if (strstr(tmp1->p, "[^") != NULL) mc++;
           if (u != NULL) mc--;
           if (mc > 0)
               a_VecChr_replace(tmp, a_VecChr_N(tmp), 0, tmp1->p, a_VecChr_N(tmp1));
           else
               a_VecChr_replace(tmp, a_VecChr_N(tmp), 0, tmp1->p, u - tmp1->p);
       }
   } else {
       while (a_VecChr_N(tmp) > 0 && tmp->p[a_VecChr_N(tmp) - 1] <= ' ') a_VecChr_N(tmp)--;
   }
	if (mod1 == 0)
		a_Preprocessor_marking0(tmp, ((a_parseArgs_Arg *) args->p) + mod, an >> mod, mod + 1, defC, t0);
	else
		a_Preprocessor_marking1(tmp, ((a_parseArgs_Arg *) args->p) + mod, an >> mod, mod + 1, defC, tmp1);
	if (mod == 0)
		a_Preprocessor_define0(set, k, kn, tmp->p, a_VecChr_N(tmp), an >> mod, NULL, NULL, 0, t0, tmp1);
	else
		a_Preprocessor_define0(set, k, kn, tmp->p, a_VecChr_N(tmp), an >> mod, typCache, (a_parseArgs_Arg *) args->p, 2, t0, tmp1);

}

a_static void a_Preprocessor_define2(int mod, const char *s, a_Token0 *t0, a_Set0 *set, int defC, a_Set0 *typCache) {

	a_VecChr lin[1], args[1], tmp[1], tmp1[1]; a_VecChr_ini4(_a_ lin, args, tmp, tmp1);
	a_VecChr_puts(lin, s, -1); t0->s = lin->p; t0->s1 = lin->p + a_VecChr_N(lin); 
	a_Preprocessor_define1(mod, t0, lin, NULL, args, tmp, tmp1, set, defC, typCache);
	a_VecChr_din4(_a_ lin, args, tmp, tmp1);

}

(99) 更新履歴


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS