by shigemk2

当面は技術的なことしか書かない

lpcanon() #firstv6

1バイト文字に対応した処理を行う。

switch caseやってる。 シングルクォートをそのまま出力するとシンタックスエラーになるので、エスケープしてる。 一文字カウントを戻して、同じ場所に印字する。

  • ccc 処理中の論理的な印字ヘッドの位置
  • mcc 処理中の物理的な印字ヘッドの位置
  • ページ中の処理行数

cccのほうがmccよりインクリメントされている可能性がある。 ところが、mccとcccの値は最終的に帳尻が合うようになっている。

dmr/lp.c

lpcanon(c)
{
    register c1, c2;

    c1 = c;
    if(lp11.flag&CAP) {
        if(c1>='a' && c1<='z')
            c1 =+ 'A'-'a'; else
        switch(c1) {

        case '{':
            c2 = '(';
            goto esc;

        case '}':
            c2 = ')';
            goto esc;

        case '`':
            c2 = '\'';
            goto esc;

        case '|':
            c2 = '!';
            goto esc;

        case '~':
            c2 = '^';

        esc:
            lpcanon(c2);
            lp11.ccc--;
            c1 = '-';
        }
    }

    switch(c1) {

    case '\t':
        lp11.ccc = (lp11.ccc+8) & ~7;
        return;

    case FORM:
    case '\n':
        if((lp11.flag&EJECT) == 0 ||
           lp11.mcc!=0 || lp11.mlc!=0) {
            lp11.mcc = 0;
            lp11.mlc++;
            if(lp11.mlc >= EJLINE && lp11.flag&EJECT)
                c1 = FORM;
            lpoutput(c1);
            if(c1 == FORM)
                lp11.mlc = 0;
        }

    case '\r':
        lp11.ccc = 0;
        if(lp11.flag&IND)
            lp11.ccc = 8;
        return;

    case 010:
        if(lp11.ccc > 0)
            lp11.ccc--;
        return;

    case ' ':
        lp11.ccc++;
        return;

    default:
        if(lp11.ccc < lp11.mcc) {
            lpoutput('\r');
            lp11.mcc = 0;
        }
        if(lp11.ccc < MAXCOL) {
            while(lp11.ccc > lp11.mcc) {
                lpoutput(' ');
                lp11.mcc++;
            }
            lpoutput(c1);
            lp11.mcc++;
        }
        lp11.ccc++;
    }
}