* 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);
         int i = fread(w->p + a_VecChr_N(w), 1, bufSz, fp);
         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)
 {
     int i, n = strlen(tag);
     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