# col --- convert single-column input to multi-column output include ARGUMENT_DEFS define (COLWIDTH,ARG_VALUE(w)) define (GUTTER,ARG_VALUE(g)) define (INDENT,ARG_VALUE(i)) define (LINK,0) define (MAXBUF,32767) define (MAXCOLS,8) define (NCOLS,ARG_VALUE(c)) define (NROWS,ARG_VALUE(l)) define (TEXT,1) define (MAXLINE,300) # to account for some backspacing ARG_DECL integer i, l, old_i, row, col, ptr (MAXCOLS), buf (MAXBUF) integer getlin, width string usage _ "Usage: col {-c|-g|-i|-l|-w}" procedure fill_buf forward PARSE_COMMAND_LINE ("cgiltw"s, usage) if (ARG_PRESENT (t)) { # set parameters for terminal display ARG_DEFAULT_INT (c, 5) ARG_DEFAULT_INT (g, 2) ARG_DEFAULT_INT (i, 0) ARG_DEFAULT_INT (l, 22) ARG_DEFAULT_INT (w, 14) } else { # set parameters for piping to print ARG_DEFAULT_INT (c, 2) ARG_DEFAULT_INT (g, 5) ARG_DEFAULT_INT (i, 0) ARG_DEFAULT_INT (l, 54) ARG_DEFAULT_INT (w, 30) } if (NCOLS > MAXCOLS) call error ("too many columns"s) for (fill_buf; ptr (1) ~= LAMBDA; fill_buf) { repeat { call print (STDOUT, "*#x"s, max0 (INDENT, 0)) for (col = 1; col <= NCOLS && ptr (col) ~= LAMBDA; col += 1) { call print (STDOUT, "*s*#x"s, buf (ptr (col) + TEXT), max0 (0, COLWIDTH - width (buf (ptr (col) + TEXT)))) if (col ~= NCOLS) call print (STDOUT, "*#x"s, max0 (0, GUTTER)) ptr (col) = buf (ptr (col) + LINK) } call putch (NEWLINE, STDOUT) } until (ptr (1) == LAMBDA) } stop # fill_buf --- read a page of text; set up 'buf' and 'ptr' arrays procedure fill_buf { i = 1 old_i = 1 l = 0 for (col = 1; col <= NCOLS; col += 1) { if (l == EOF) ptr (col) = LAMBDA else { ptr (col) = i for (row = 1; row <= NROWS; row += 1) { if (i > MAXBUF - (MAXLINE + 1) + 1) call error ("too many lines"s) l = getlin (buf (i + TEXT), STDIN, MAXLINE) if (l == EOF) break if (buf (i + TEXT + l - 1) == NEWLINE) { buf (i + TEXT + l - 1) = EOS l -= 1 } old_i = i i += l + 2 buf (old_i + LINK) = i } if (i == ptr (col)) ptr (col) = LAMBDA else buf (old_i + LINK) = LAMBDA } } } end # width --- compute width of character string integer function width (buf) character buf (MAXLINE) integer i, c width = 0 for (i = 1; buf (i) ~= EOS; i += 1) { c = or (buf (i), 8r200) select when (c >= ' 'c && c < DEL) width += 1 when (c == BACKSPACE) width -= 1 } return end