acl4のページ0013
(1)
#if (a_Version >= 1)
#define Preprocessor_incl0 a_Preprocessor_incl0
#define Preprocessor_Put0 a_Preprocessor_Put0
#define Preprocessor_Put0_ini a_Preprocessor_Put0_ini
#define Preprocessor_Put0_din a_Preprocessor_Put0_din
#define Preprocessor_put0 a_Preprocessor_put0
#define Preprocessor a_Preprocessor
#define Preprocessor_ini a_Preprocessor_ini
#define Preprocessor_din a_Preprocessor_din
#define Preprocessor_line a_Preprocessor_line
#define Preprocessor_main a_Preprocessor_main
#endif
a_static int a_Preprocessor_incl0(void *w, char *s, char *s1, a_Preprocessor_SourceFiles *sfs)
{
(void) w;
while (s < s1 && *(unsigned char *) s <= ' ') s++;
if (*s == 0x22) {
char *t = strchr(s + 1, 0x22);
if (t == NULL) t = s1;
a_Preprocessor_SourceFiles_addFile(sfs, s + 1, t - (s + 1));
return 1;
}
if (*s == '<') {
char *t = strchr(s + 1, '>');
if (t == NULL) t = s1;
if (t[-2] == '.' && t[-1] == 'h') return 0; // through.
a_Preprocessor_SourceFiles_addFile(sfs, s + 1, t - (s + 1));
return 1;
}
return 0;
}
a_class(a_Preprocessor_Put0) {
a_Preprocessor_SourceFiles *sfs;
a_VecChr *dst, path[1];
intptr_t lin;
};
a_static void a_Preprocessor_Put0_ini(a_Preprocessor_Put0 *w) { a_VecChr_ini(w->path); w->lin = 0; }
a_static void a_Preprocessor_Put0_din(a_Preprocessor_Put0 *w) { a_VecChr_din(w->path); }
a_static void a_Preprocessor_put0(a_Preprocessor_Put0 *w, a_VecChr *lin)
{
a_Preprocessor_SourceFile *sf = a_Preprocessor_SourceFiles_getSf(w->sfs);
if (w->path->n != sf->path->n || (w->path->n > 0 && memcmp(w->path->p, sf->path->p, w->path->n) != 0)) {
char *s = a_malloc(_arg_ sf->path->n + 64);
sprintf(s, "#line %d \"%.*s\"\n", sf->lin, sf->path->n, sf->path->p);
a_VecChr_puts(w->dst, s, s + strlen(s));
a_free(_arg_ s, sf->path->n + 64);
a_VecChr_replace(w->path, 0, w->path->n, sf->path->p, sf->path->n);
} else if (w->lin + 1 != sf->lin) {
char s[64];
sprintf(s, "#line %d\n", sf->lin);
a_VecChr_puts(w->dst, s, s + strlen(s));
}
a_VecChr_puts(w->dst, lin->p, lin->p + lin->n);
w->lin = sf->lin;
}
a_class(a_Preprocessor) {
a_Token0 t0[1];
a_Preprocessor_SourceFiles sfs[1];
a_Set0 set[1];
a_Preprocessor_If ppIf[1];
a_Preprocessor_Eval ppEv[1];
a_Preprocessor_Put0 put0[1];
int (*incl)(void *, const char *, const char *, a_Preprocessor_SourceFiles *);
void (*put)(void *, a_VecChr *, a_Preprocessor_SourceFiles *);
void *w_incl, *w_put;
};
a_static void a_Preprocessor_ini(a_Preprocessor *w)
{
a_Token0_ini1(w->t0);
a_Preprocessor_SourceFiles_ini(w->sfs);
a_Preprocessor_if0(w->ppIf);
a_Set0_ini(w->set);
// 以下はとりあえずのデフォルト設定. 不要なら上書きする.
w->ppIf->eval = (void *) a_Preprocessor_eval;
w->ppIf->w_eval = w->ppEv;
w->incl = (void *) a_Preprocessor_incl0;
w->w_incl = NULL;
a_Preprocessor_Put0_ini(w->put0);
w->put = (void *) a_Preprocessor_put0;
w->w_put = w->put0;
w->put0->sfs = w->sfs;
a_Preprocessor_define7(w->set, -1, "ifdef", "if defined");
a_Preprocessor_define7(w->set, -1, "ifndef", "if !defined");
a_Preprocessor_define7(w->set, -1, "elifdef", "elif defined");
a_Preprocessor_define7(w->set, -1, "elifndef", "elif !defined");
}
a_static void a_Preprocessor_din(a_Preprocessor *w)
{
a_Preprocessor_define3(w->set);
a_Preprocessor_if3(w->ppIf);
a_Preprocessor_SourceFiles_din(w->sfs);
a_Preprocessor_Put0_din(w->put0);
}
a_static void a_Preprocessor_line(a_Preprocessor *w)
{
a_Preprocessor_SourceFile *sf = a_Preprocessor_SourceFiles_getSf(w->sfs);
const char *t = a_Token1_get(w->t0);
sf->lin = strtol(t, NULL, 0) - 1;
t = a_Token1_get(w->t0);
if (w->t0->len >= 2 && *t == 0x22) {
sf->path->n = 0;
a_VecChr_puts(sf->path, t + 1, t + w->t0->len - 1);
}
}
a_static void a_Preprocessor_main(a_Preprocessor *w)
{
int defC = 1;
a_VecChr lin[1], tmp[1], stkDef[1]; a_VecChr_ini4(lin, tmp, stkDef, 0);
for (;;) {
a_Preprocessor_SourceFiles_gets(w->sfs, lin);
if (lin->n == 0) break;
for (;;) { // 末尾が "\\\n"であれば、後続行を接続.
char *p1 = lin->p + lin->n;
if (!(lin->n >= 2 && p1[-2] == '\\' && p1[-1] == '\n')) break;
a_Preprocessor_SourceFiles_gets(w->sfs, tmp);
a_VecChr_replace(lin, lin->n - 2, 2, tmp->p, tmp->n);
}
if (a_Preprocessor_isDirective(lin->p, lin->p + lin->n) == 0) {
a_Preprocessor_SourceFile *sf = a_Preprocessor_SourceFiles_getSf(w->sfs);
if (a_Preprocessor_define2(w->set, w->t0, lin, defC, sf->path, sf->lin, 0) != 0) {
retry:
a_Preprocessor_SourceFiles_addBuf(w->sfs, lin->p, lin->n);
continue;
}
if (w->ppIf->phase != 0)
w->put(w->w_put, lin, w->sfs);
continue;
}
const char *s = lin->p, *s1 = lin->p + lin->n;
while (s < s1 && *(const unsigned char *) s <= ' ') s++;
s++; // '#'.
if (strncmp(s, "if", 2) == 0 || strncmp(s, "elif", 4) == 0) {
a_Preprocessor_SourceFile *sf = a_Preprocessor_SourceFiles_getSf(w->sfs);
if (a_Preprocessor_define2(w->set, w->t0, lin, defC, sf->path, sf->lin, 0) != 0) goto retry;
}
w->t0->s = s + 1; w->t0->s1 = lin->p + lin->n; a_Token1_get(w->t0);
if (w->ppIf->phase != 0) {
if (strncmp(s, "include", 7) == 0) { if (w->incl(w->w_incl, s + 7, s1, w->sfs) > 0) continue; }
if (strncmp(s, "define", 6) == 0) { a_Preprocessor_define5(w->set, w->t0, lin, defC, w->sfs, stkDef, 0); continue; }
if (strncmp(s, ".def", 4) == 0) { a_Preprocessor_define5(w->set, w->t0, lin, defC, w->sfs, stkDef, 1); continue; }
if (strncmp(s, ".addTl", 6) == 0) { a_Preprocessor_define5(w->set, w->t0, lin, defC, w->sfs, stkDef, 2); continue; }
if (strncmp(s, ".addHd", 6) == 0) { a_Preprocessor_define5(w->set, w->t0, lin, defC, w->sfs, stkDef, 3); continue; }
if (strncmp(s, "undef", 5) == 0) { if (a_Preprocessor_define6(w->set, w->t0, lin, stkDef, 0) > 0) continue; }
if (strncmp(s, ".undef", 6) == 0) { if (a_Preprocessor_define6(w->set, w->t0, lin, stkDef, 1) > 0) continue; }
if (strncmp(s, "line", 4) == 0) { a_Preprocessor_line(w); continue; }
}
w->t0->s = s; w->t0->s1 = lin->p + lin->n;
char *t = a_Token1_get(w->t0);
if (a_Preprocessor_if2(w->ppIf, lin, w->t0, t) > 0) continue;
if (w->ppIf->phase != 0)
w->put(w->w_put, lin, w->sfs); // エラー検出のため.
continue;
}
while (stkDef->n > 0) {
a_Preprocessor_Define *sp = a_VecChr_stkRmv(stkDef, sizeof (a_Preprocessor_Define));
a_Preprocessor_Define_din(sp);
}
a_VecChr_din4(lin, tmp, stkDef, 0);
}
(2) 説明
(3)
(99) 更新履歴