acl4のページ0019

  • (by K, 2026.04.25)

(1) 概要

  • a4_0019 は、 acl4v1 にとっての4番目のライブラリプログラムになります。
  • 提供される主な機能は、以下の通りです。
    • (1-1)VecChrに対するprintfなど
    • (1-2)VecChrを使ったファイル入出力など
  • 以下、それぞれについてもう少し詳しく説明します。


  • (1-1)VecChrに対するprintfなど
    • printf/vprintf/putc/puts のほかに、 VecChr の一部を置換する replace 関数もあります。
  • (1-2)VecChrを使ったファイル入出力など
    • readFileAll/writeFileAll などのほかにコマンドライン引数を簡単に取得するための getArg もあります。

(2) デモ

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

#if (a_Version >= 1)
    #define VecChr_iniCpy   a_VecChr_iniCpy
    #define VecChr_iniCpy0  a_VecChr_iniCpy0
    #define VecChr_replace  a_VecChr_replace
    #define VecChr_vprintf  a_VecChr_vprintf
    #define VecChr_printf   a_VecChr_printf
    #define VecChr_putc     a_VecChr_putc
    #define VecChr_puts     a_VecChr_puts
    #define hexDump         a_hexDump
#endif

a_static void a_VecChr_iniCpy(_aDef_ a_VecChr *w, const char *s, intptr_t n)
{
    if (n < 0) n = strlen(s);
    a_VecChr_ini(_aThr_ w);
    a_VecChr_resize(w, n);
    a_memcpy(w->p, s, n);
}

a_static void a_VecChr_iniCpy0(_aDef_ a_VecChr *w, const char *s, intptr_t n)
{
    a_VecChr_iniCpy(_aThr_ w, s, n);
    a_VecChr_reserve0(w);
}

a_static void a_VecChr_replace(a_VecChr *w, intptr_t pos0, intptr_t n0, const void *p1, intptr_t n1)
{
    #if (a_DbgLv >= 2)
        if (pos0 < 0) a_errExit("VecChr_replace: pos0=%d", (int) pos0);
        if (n0   < 0) a_errExit("VecChr_replace: n0=%d", (int) n0);
        if (n1   < 0) a_errExit("VecChr_replace: n1=%d", (int) n1);
        if (pos0 + n0 > a_VecChr_N(w)) a_errExit("VecChr_replace: pos0+n0=%d VecChr_N()=%d", (int) (pos0 + n0), (int) a_VecChr_N(w));
    #endif
    intptr_t diff = n1 - n0, pos1 = pos0 + n0, n2 = a_VecChr_N(w) - pos1;
    a_VecChr_resizeDiff(w, diff);
    a_memmove(w->p + pos1 + diff, w->p + pos1, n2);
    a_memcpy(w->p + pos0, p1, n1);
}

a_static intptr_t a_VecChr_vprintf(a_VecChr *w, const char *f, va_list a)
{
    intptr_t n = ((intptr_t *) w->p)[-1], d = a_VecChr_N1(w) - n;
    intptr_t i = vsnprintf(w->p + n, d, f, a);
    if (i <= 0) goto fin;
    if (i + 1 > d) {
        a_VecChr_reserveDiff(w, i + 1);
        d = ((intptr_t *) w->p)[-2] - n;
        i = vsnprintf(w->p + n, d, f, a);
        if (i <= 0) goto fin;
    }
    ((intptr_t *) w->p)[-1] += i;
fin:
    return i;
}

a_static intptr_t a_VecChr_printf(a_VecChr *w, const char *f, ...)
{
    va_list ap;
    va_start(ap, f);
    intptr_t i = a_VecChr_vprintf(w, f, ap);
    va_end(ap);
    return i;
}

a_static int a_VecChr_putc(a_VecChr *w, int c)
{
    a_VecChr_reserveDiff(w, 2);
    intptr_t n = a_VecChr_N(w);
    w->p[n++] = (char) c;
    w->p[n  ] = '\0';
    a_VecChr_N(w) = n;
    return c;
}

a_static void a_VecChr_puts(a_VecChr *w, const char *s, intptr_t n)
{
    if (n < 0) n = strlen(s);
    a_VecChr_reserveDiff(w, n + 1);
    a_memcpy(w->p + a_VecChr_N(w), s, n);
    a_VecChr_N(w) += n;
    w->p[a_VecChr_N(w)] = '\0';
}

a_static void a_hexDump(const char *s, intptr_t n, FILE *fp)
{
    intptr_t i;
    fprintf(fp, "[");
    for (i = 0; i < n; i++)
        fprintf(fp, "%02X ", ((unsigned char *) s)[i]);
    fprintf(fp, "]\n");
}

#if (a_Version >= 1)
    #define VecChr_readFileAll          a_VecChr_readFileAll
    #define VecChr_readFileAll_errChk   a_VecChr_readFileAll_errChk
    #define VecChr_eraseCr              a_VecChr_eraseCr
    #define VecChr_gets                 a_VecChr_gets
    #define VecChr_writeFileAll         a_VecChr_writeFileAll
    #define VecChr_writeFileAll_errChk  a_VecChr_writeFileAll_errChk
    #define getArg                      a_getArg
    #define VecChr_iniArg               a_VecChr_iniArg
#endif

a_static intptr_t a_VecChr_readFileAll(a_VecChr *w, const char *path)
{
    FILE *fp = fopen(path, "rb");
    if (fp == NULL) return -1;
    intptr_t bufSz = 1024 * 1024, n0 = a_VecChr_N(w);
    for (;;) {
        a_VecChr_reserveDiff(w, bufSz);
        intptr_t i = fread(w->p + a_VecChr_N(w), 1, bufSz, fp);
        if (i <= 0) break;
        a_VecChr_N(w) += i;
    }
    fclose(fp);
    a_VecChr_reserve0(w);
    a_VecChr_shrink(w, 1);
    return a_VecChr_N(w) - n0;
}

a_static intptr_t a_VecChr_readFileAll_errChk(a_VecChr *w, const char *path)
{
    if (path == NULL) a_errExit("fopen error: path=NULL");
    intptr_t i = a_VecChr_readFileAll(w, path);
    if (i < 0) a_errExit("fopen error: %s", path);
    return i;
}

a_static intptr_t a_VecChr_eraseCr(a_VecChr *w)
{
    char *p, *q, *p1;
    p = q = w->p;
    p1 = p + a_VecChr_N(w);
    while (p < p1) {
        if (*p++ != '\r')
            *q++ = p[-1];
    }
    a_VecChr_N(w) -= p1 - q;
    a_VecChr_reserve0(w);
    return p1 - q;
}

a_static char *a_VecChr_gets(a_VecChr *w, const char *s, const char *s1)
{
    const char *t = memchr(s, '\n', s1 - s);
    if (t == NULL) t = s1 - 1;
    t++;
    intptr_t n = t - s;
    a_VecChr_reserve(w, n + 1);
    a_memcpy(w->p, s, n);
    a_VecChr_N(w) = n;
    w->p[a_VecChr_N(w)] = '\0'; // reserve0()相当.
    return (char *) t;
}

a_static intptr_t a_VecChr_writeFileAll(a_VecChr *w, const char *path, const char *mod)
{
    FILE *fp = fopen(path, mod);
    if (fp == NULL) return -1;
    intptr_t i = 0, j;
    for (;;) {
        j = fwrite(w->p + i, 1, a_VecChr_N(w) - i, fp);
        if (j <= 0) break;
        i += j;
    }
    fclose(fp);
    return i;
}

a_static intptr_t a_VecChr_writeFileAll_errChk(a_VecChr *w, const char *path, const char *mod)
{
    if (path == NULL) a_errExit("fopen error: path=NULL");
    intptr_t i = a_VecChr_writeFileAll(w, path, mod);
    if (i < 0)
        a_errExit("fopen error: %s", path);
    if (i < a_VecChr_N(w))
        a_errExit("fwrite error: %s", path);
    return i;
}

a_static const char *a_getArg(int argc, const char **argv, const char *tag, const char *val0)
{
    intptr_t i, n = strlen(tag);
    for (i = 1; i < argc; i++) {
        if (strncmp(argv[i], tag, n) == 0)
            val0 = argv[i] + n;
    }
    return val0;
}

a_static void a_VecChr_iniArg(_aDef_ a_VecChr *w, const char *path, int flg)
// flg=1:デフォルトをinlineモードに変更.
//     2:ファイルから読んだ場合にeraseCrする.
//     4:inlineの場合でも、convEscしない.
//     8:fileの場合に、convEscする.
//    16:最初にiniしない.
// 典型値: flg=0(file-bin), flg=2(file-txt)
//         flg=1(inline-bin), flg=3(inline-txt)
// file:かinline:か。明示しなければデフォルト値が使われる.
{
    if ((flg & 16) == 0)
        a_VecChr_ini(_aThr_ w);
    a_VecChr_N(w) = 0;
    a_VecChr_puts(w, path, -1);
    if (w->p[0] == 0x22) {
        a_VecChr_replace(w, 0, 1, NULL, 0);
        if (a_VecChr_N(w) > 0 && w->p[a_VecChr_N(w) - 1] == 0x22)
            a_VecChr_N(w)--;
    }
    if (a_VecChr_N(w) >= 5 && memcmp(w->p, "file:", 5) == 0) {
        a_VecChr_replace(w, 0, 5, NULL, 0);
        flg &= ~1;
    }
    if (a_VecChr_N(w) >= 7 && memcmp(w->p, "inline:", 7) == 0) {
        a_VecChr_replace(w, 0, 7, NULL, 0);
        flg |= 1;
    }
    if ((flg & 1) == 0) {
        a_VecChr_reserve0(w);
        a_VecChr_N(w) = 0;
        a_VecChr_readFileAll_errChk(w, w->p);
        if ((flg & 2) != 0)
            a_VecChr_eraseCr(w);
        if ((flg & 8) != 0)
            flg |= 256;
    } else {
        if ((flg & 4) == 0)
            flg |= 256;
    }
    if ((flg & 256) != 0)
        a_VecChr_convEsc(w);
}

(99) 更新履歴

  • 2026.04.25(土) 初版

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2026-04-25 (土) 23:04:40 (51d)