C言語入門(45) 実際にプログラムを読んで理解を深めよう ls編(19)

Posted: 2013年06月20日

前回はユーティリティのlen_octal関数に書きました。
今回は、prn_octal関数です。

util.c prn_octal関数です。

プログラムプログラム:

int
prn_octal(const char *s)
{
    static const char esc[] = "\""aabbffnnrrttvv";
    const char *p;
    mbstate_t mbs;
    wchar_t wc;
    size_t clen;
    unsigned char ch;
    int goodchar, i, len, prtlen;

    memset(&mbs, 0, sizeof(mbs));
    len = 0;
    while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
        goodchar = clen != (size_t)-1 && clen != (size_t)-2;
        if (goodchar && iswprint(wc) && wc != L'"' && wc != L'') {
            for (i = 0; i < (int)clen; i++)
                putchar((unsigned char)s[i]);
            len += wcwidth(wc);
        } else if (goodchar && f_octal_escape &&
#if WCHAR_MIN < 0
                    wc >= 0 &&
#endif
            wc <= (wchar_t)UCHAR_MAX &&
            (p = strchr(esc, (char)wc)) != NULL) {
            putchar('');
            putchar(p[1]);
            len += 2;
        } else {
            if (goodchar)
                prtlen = clen;
            else if (clen == (size_t)-1)
                prtlen = 1;
            else
                prtlen = strlen(s);
            for (i = 0; i < prtlen; i++) {
                ch = (unsigned char)s[i];
                putchar('');
                putchar('0' + (ch >> 6));
                putchar('0' + ((ch >> 3) & 7));
                putchar('0' + (ch & 7));
                len += 4;
            }
        }
        if (clen == (size_t)-2)
            break;
        if (clen == (size_t)-1) {
            memset(&mbs, 0, sizeof(mbs));
            s++;
        } else
            s += clen;
    }
    return (len);
}

解説解説:

この関数では、表示できない文字は8進数表示
または、escに定義されているエスケープ文字の表示を行います。

8進数表示では、
‘0’に数値を加算し 0〜7のASCII文字を求めています。

6, >> 3 & 7, & 7の式で各桁の値を取得しています。
上位桁から取得しています。(表示するから)

escには、無駄に文字が設定されているように思えます。

「a」をチェックするために「aa」

この3文字目は、表示用に設定されています。
私としては、面白い作りだと思いますが
無駄な処理をツクらなく掏るならばたしかにこの方法は良いと思います。

ここの処理について
strchrでescに含まれる文字を探します。
見つかった場合は、
「\」を表示し見つかった位置の次の文字「a」を表示します。

この処理には、前提条件があり
表示できない文字、「”」、「\」の場合この処理が行われます。

今回でlsの話題が最後となります。
一般的に使用出来る

  • パラメータのチェック
  • 端末の色つけ表示
  • 様々な形式で表示

参考できるところは多くありました。
lsが入門編には、重い気がしますが
一般的には、これくらいできて当たり前と言われると凄いというしか・・・

カテゴリー: プログラム, 入門 | タグ: , , | コメント無し »

コメント