* acpp0 -(by [[K]], 2024.09.02) ** (0) -C言語のプリプロセッサより前にこれを使うことで、プリプロセッサを拡張します。 -以下が使えるようになります。 --#include_once --#longdef --#endlongdef --#longuse ** (1) ver.1.10 [2024.09.15] (250行) ** (1) ver.1.20 [2024.09.20] (248行) #include <acl1Tiny.c> #include <AMemMan.c> #include <AMemFile.c> int cmpCmd(const char *s, const char *cmd) { AInt len = strlen(cmd); if (strncmp(s, cmd, len) == 0 && ((unsigned char *) s)[len] <= ' ') return 1; return 0; } char *skpLf(const char *s) // 次の行の先頭を得る. { while (*s != 0 && *s != '\n') s++; if (*s == '\n') s++; return (char *) s; } char *skpSpc(const char *s) { while (*s == ' ' || *s == '\t') s++; return (char *) s; } void commentOut(AMemFile *mp, const char *s0, const char *s, const char *s1) { AMemFile_write(mp, 0, s0, s - s0); // s0からsまでを出力. AMemFile_write(mp, 0, "//", 2); AMemFile_write(mp, 0, s, s1 - s); // sからs1までを出力. } /// includeOnce()関係. void includeOnce_sub(const char *s, AMemFile *mp, AMemFile *included) { char tmp[1024]; int i; while (*s != 0) { const char *s0 = s, *s1 = skpLf(s); s = skpSpc(s); if (*s == '#') { // これがある方が少し速い. if (cmpCmd(s, "#include_once")) { const char *s2 = s; s = skpSpc(s + 13); if (*s == 0x22 || *s == '<') { char c = *s++; if (c == '<') c = '>'; commentOut(mp, s0, s2, s1); for (i = 0; s + i < s1 && s[i] != c; i++); sprintf(tmp, "\n%.*s\n", i, s); if (strstr(included->p0, tmp) == 0) { included->p -= 2; // 末尾の"\n\0"を取り除く. AMemFile_write(included, 0, tmp, i + 3); // 末尾の'\0'も書く. tmp[i + 1] = 0; AMemFile *mp1 = AMemFile_open(AMemFile_Text, am0, tmp + 1); includeOnce_sub(mp1->p0, mp, included); AMemFile_dst(mp1); } s = s1; continue; } } } AMemFile_write(mp, 0, s0, s1 - s0); s = s1; } } AMemFile *includeOnce(const char *s) { AMemFile *included = AMemFile_newSiz(0, am0, 4096); // ここにインクルード済みのファイル名一覧を追記していく. AMemFile_write(included, 0, "\n", 2); // 末尾の'\0'も書き込む. AMemFile *mp = AMemFile_new(AMemFile_Text, am0); includeOnce_sub(s, mp, included); AMemFile_dst(included); AMemFile_toReadMode(mp, 0); return mp; } /// longdef()関係. char *skpNam(const char *s) { while (*s != 0 && strchr("\t\n\r =(){},", *s) == 0) { s++; } return (char *) s; } char *skpExpr(const char *s) { int i = 0, n = 0; for (;;) { if (*s == 0) break; if (*s == '(' || *s == '[') n++; if (*s == ')' || *s == ']') { if (n == 0) break; n--; } if (*s == ',' && n == 0) break; s++; } return (char *) s; } char *searchName(void **a, void **a1, AInt len, const char *nam) { while (a < a1) { if ((AInt) a[0] == len && memcmp(a[1], nam, len) == 0) { if (a[1] == a[2]) { return a[2]; } return ((AMemFile *) a[2])->p0; } a += 3; } return 0; } void longdef_sub(const char *s, AMemFile *mp, char mod, AMemFile *def); const char *longdef_longdef(const char *nam, AMemFile *mp, AMemFile *def, const char *s1) { AMemFile *mq = 0; if (*nam == '@') { nam++; mq = AMemFile_newSiz(0, am0, 4096); } const char *s = skpNam(nam); AInt namLen = s - nam; if (searchName((void **) def->p0, (void **) def->p, namLen, nam) != 0) aErrExit("#longdef: double-def: %.*s\n", namLen, nam); s = skpSpc(s); if (*s != '(') { aErrExit("#longdef: syntax error: %.*s\n", namLen, nam); } void *a[3]; a[0] = (void *) namLen; a[1] = (void *) nam; a[2] = (void *) nam; if (mq != 0) { a[2] = (void *) mq; } AMemFile_write(def, 0, (char *) a, sizeof a); s = s1; while (*s != 0) { // エラーチェックしながら#endlongdefまでを読み飛ばす. s = skpSpc(s); s1 = skpLf(s); if (*s == '#') { if (cmpCmd(s, "#longdef")) // #longdef中に#longdefが出てきた. aErrExit("not found #endlongdef: %.*s\n", namLen, nam); if (cmpCmd(s, "#endlongdef")) break; } s = s1; } if (*s == 0) { aErrExit("not found #endlongdef: %.*s\n", namLen, nam); } if (mq != 0) { for (s = nam; s < s1; ) { const char *s0 = s; while (s < s1 && *s != '@') s++; AMemFile_write(mq, 0, s0, s - s0); if (s < s1) { s++; // @を読み飛ばす. AMemFile_write(mq, 0, nam, namLen); // 代わりに以下を出力. AMemFile_write(mq, 0, "_", 1); } } AMemFile_toReadMode(mq, 0); } return s1; } void longdef_longuse(const char *nam, AMemFile *mp, AMemFile *def) { const char *s = skpNam(nam); AInt namLen = s - nam; const char *p = searchName((void **) def->p0, (void **) def->p, namLen, nam); if (p == 0) { aErrExit("#longuse: not found: %.*s\n", namLen, nam); } const char *p0 = skpSpc(strchr(p + namLen, '(') + 1), *p1, *s1; s = skpSpc(s); if (*s != '(') { aErrExit("#longuse: syntax error (1): %.*s\n", namLen, nam); } s = skpSpc(s + 1); for (p = p0; *p != ')'; ) { // #define出力. p1 = skpNam(p); s1 = skpExpr(s); AMemFile_write(mp, 0, "#define ", 8); AMemFile_write(mp, 0, p, p1 - p); AMemFile_write(mp, 0, " ", 1); AMemFile_write(mp, 0, s, s1 - s); AMemFile_write(mp, 0, "\n", 1); p = skpSpc(p1); s = skpSpc(s1); if (*p == ',') p = skpSpc(p + 1); if (*s == ',') s = skpSpc(s + 1); if (*p != ')' && *s == ')') { aErrExit("#longuse: syntax error (2): %.*s\n", namLen, nam); } // 引数の数があってない. } if (*s != ')') { aErrExit("#longuse: syntax error (3): %.*s\n", namLen, nam); } // 引数の数があってない. longdef_sub(skpLf(p), mp, 1, def); for (p = p0; *p != ')'; ) { // #undef出力. p1 = skpNam(p); AMemFile_write(mp, 0, "#undef ", 7); AMemFile_write(mp, 0, p, p1 - p); AMemFile_write(mp, 0, "\n", 1); p = skpSpc(p1); if (*p == ',') { p = skpSpc(p + 1); } } } void longdef_sub(const char *s, AMemFile *mp, char mod, AMemFile *def) { while (*s != 0) { const char *s0 = s, *s1 = skpLf(s); s = skpSpc(s); if (*s == '#') { if (cmpCmd(s, "#longdef")) { commentOut(mp, s0, s, s1); s = longdef_longdef(skpSpc(s + 8), mp, def, s1); continue; } if (cmpCmd(s, "#endlongdef")) { if (mod != 0) { commentOut(mp, s0, s, s1); break; } aErrExit("not found #longdef\n"); } if (cmpCmd(s, "#longuse")) { commentOut(mp, s0, s, s1); longdef_longuse(skpSpc(s + 8), mp, def); s = s1; continue; } } AMemFile_write(mp, 0, s0, s1 - s0); s = s1; } } AMemFile *longdef(const char *s) { void **a; AMemFile *def = AMemFile_newSiz(0, am0, 4096); // { len, defName },... AMemFile *mp = AMemFile_new(AMemFile_Text, am0); longdef_sub(s, mp, 0, def); for (a = (void **) def->p0; a < (void **) def->p; a += 3) { if (a[1] != a[2]) { AMemFile_dst(a[2]); } } AMemFile_dst(def); AMemFile_toReadMode(mp, 0); return mp; } /// main()関数. int main(int argc, const char **argv) { if (argc < 3) { aErrExit("usage>acpp0 input-file output-file\n"); } AMemFile *mp0 = AMemFile_open(AMemFile_Text, am0, argv[1]); AMemFile *mp1 = includeOnce(mp0->p0); AMemFile_dst(mp0); AMemFile *mp2 = longdef(mp1->p0); AMemFile_dst(mp1); AMemFile_saveDst(mp2, 0, argv[2]); AM_dst(am0); return 0; }