ときどきの雑記帖 RE* (新南口)
シニカルヒステリーアワー
山手線
なぜ明日明後日の山手線は、外回りの本数も減ってしまうのかを説明してみた pic.twitter.com/06AwxWvrCt
— まん電 (@wkmk06yr1) October 22, 2021
☎️<どうして山手線の内回りが工事で運休するのに、外回りの本数を増やさないのですか?運休するなら車両は余っているのではないですか?
— 島村悠道 / Yudo S. 🛂 (@toike_shimamura) October 20, 2021
A、内回りで運休しない区間で使う車両を、外回りの線路を使って持っていかないといけないからです。 pic.twitter.com/Yc7GyUmWnk
内回りは一部の区間だけ動かすと聞いて、折り返しはどうするのかと思ったのだけど、 なるほど「外回りに混ぜる」のか(だから「内回りの折り返し」でない外回りの本数も減る)。
土曜日(23日)の昼のニュースでは確か、
- 内回りの 大崎→(東京)→池袋が通常の3割
- 外回りの 大崎→(渋谷)→池袋が通常の6割
- 外回りの 池袋→(東京)→大崎が通常の9割
の運転本数だとか言ってたな。
「無双する」
異世界転生した天才マンガ家が画力を生かし無双する「ドローイング」連載開始 | マイナビニュース
どうもこの使い方も好きになれないんだよなあ>「無双する」 (自分が使わないだけで人が使うのを止める気はない)。
カレンダー
ホワイトボード×カレンダー 巻物型のロールカレンダーがイイかも | MADURO ONLINE(マデュロオンライン)
これいいな。
月末には次の月の途中まででもみたくなることは割とあるし (1か月ごとに別々にめくれる3か月単位のカレンダーなんかもありますが)。
tr
前回の続き。
ふと、前回の記事を読み返していたら
kbk@toybox4:/mnt/c/Users/kbk$ LC_ALL=ja_JP.UTF8 tr --help
使用法: tr [OPTION]... SET1 [SET2]
Translate, squeeze, and/or delete characters from standard input,
writing to standard output.
-c, -C, --complement use the complement of SET1
-d, --delete delete characters in SET1, do not translate
-s, --squeeze-repeats replace each sequence of a repeated character
that is listed in the last specified SET,
with a single occurrence of that character
-t, --truncate-set1 first truncate SET1 to length of SET2
--help この使い方を表示して終了する
--version バージョン情報を表示して終了する
SET は文字列によって指定します。多くの場合その文字自身を表現します。
解釈のされ方は以下の通りです:
\NNN 文字の八進数表現(1 から 3 個の 八進数)
\\ バックスラッシュ
\a ベル
\b バックスペース
\f フォームフィード
\n 改行
\r 復帰
\t 水平タブ
\v 垂直タブ
CHAR1-CHAR2 CHAR1 から CHAR2 までを昇順に展開した文字列
[CHAR1-CHAR2] SET1 と SET2 の両方で指定した場合には CHAR1-CHAR2 と同じ
[CHAR*] SET2 として, CHAR を SET1 の長さ分展開した文字列
[CHAR*REPEAT] CHAR を REPEAT 個展開した文字列, REPEAT の値を 0 から
始めた場合には八進数として解釈する
[:alnum:] 全てのアルファベットと数字
[:alpha:] 全てのアルファベット
[:blank:] 全ての水平方向空白類文字
[:cntrl:] 全ての制御文字
[:digit:] 全ての数字
[:graph:] 全ての表示可能文字。空白は含まない
[:lower:] 全ての小文字アルファベット
[:print:] 全ての表示可能文字。空白も含む
[:punct:] 全ての句読点
[:space:] 全ての水平及び垂直タブ文字
[:upper:] 全ての大文字アルファベット
[:xdigit:] 全ての十六進数数値
[=CHAR=] 全ての CHAR と等価な文字
Translation occurs if -d is not given and both SET1 and SET2 appear.
-t may be used only when translating. SET2 is extended to length of
SET1 by repeating its last character as necessary. Excess characters
of SET2 are ignored. Only [:lower:] and [:upper:] are guaranteed to
expand in ascending order; used in SET2 while translating, they may
only be used in pairs to specify case conversion. -s uses the last
specified SET, and occurs after translation or deletion.
GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
tr の翻訳に関するバグは <http://translationproject.org/team/ja.html> に連絡してください。
Full documentation at: <http://www.gnu.org/software/coreutils/tr>
or available locally via: info '(coreutils) tr invocation'
翻訳されていない部分があるのに今更気がついた。 ja.po ではちゃんと訳されていたような…? と思いつつ何が起きているのか確かめてみた。 すると…
比較
(おそらく最新の)ソースコードと、(ちょっと前の)ja.poの該当する部分をみる。
問題のヘルプメッセージは丸々一つの文字列になっているわけでもなく、 逆に一つ一つのセンテンスごとのように細かくわけられているのでもない。 実際のところ5つに分けられているのだけど、 それらを一つずつ ja.poのものとソースコードのものとで比較する。
ja.po
#: src/tr.c:290
msgid ""
"Translate, squeeze, and/or delete characters from standard input,\n"
"writing to standard output.\n"
"\n"
" -c, -C, --complement use the complement of SET1\n"
" -d, --delete delete characters in SET1, do not translate\n"
" -s, --squeeze-repeats replace each input sequence of a repeated character\n"
" that is listed in SET1 with a single occurrence\n"
" of that character\n"
" -t, --truncate-set1 first truncate SET1 to length of SET2\n"
msgstr ""
"標準入力から読み込んだ文字を置換、切り詰め、削除し、標準出力に書き込みます。\n"
"\n"
" -c, --complement SET1 の補集合を使用する\n"
" -d, --delete SET1 中の文字を削除する。置換は行わない\n"
" -s, --squeeze-repeats 入力の中に SET1 に含まれる文字が連続して存在する\n"
" 場合に 1 個に置換する\n"
" -t, --truncate-set1 最初に SET1 を SET2 の長さまで切り詰める\n"
ソースコード
fputs (_("\
Translate, squeeze, and/or delete characters from standard input,\n\
writing to standard output.\n\
\n\
-c, -C, --complement use the complement of SET1\n\
-d, --delete delete characters in SET1, do not translate\n\
-s, --squeeze-repeats replace each sequence of a repeated character\n\
that is listed in the last specified SET,\n\
with a single occurrence of that character\n\
-t, --truncate-set1 first truncate SET1 to length of SET2\n\
"), stdout);
よーく見ると-sオプションの説明の2行目以降に違いがある。
ja.po
#: src/tr.c:303
msgid ""
"\n"
"SETs are specified as strings of characters. Most represent themselves.\n"
"Interpreted sequences are:\n"
"\n"
" \\NNN character with octal value NNN (1 to 3 octal digits)\n"
" \\\\ backslash\n"
" \\a audible BEL\n"
" \\b backspace\n"
" \\f form feed\n"
" \\n new line\n"
" \\r return\n"
" \\t horizontal tab\n"
msgstr ""
"\n"
"SET は文字列によって指定します。多くの場合その文字自身を表現します。\n"
"解釈のされ方は以下の通りです:\n"
"\n"
" \\NNN 文字の八進数表現(1 から 3 個の 八進数)\n"
" \\\\ バックスラッシュ\n"
" \\a ベル\n"
" \\b バックスペース\n"
" \\f フォームフィード\n"
" \\n 改行\n"
" \\r 復帰\n"
" \\t 水平タブ\n"
ソースコード
fputs (_("\
\n\
SETs are specified as strings of characters. Most represent themselves.\n\
Interpreted sequences are:\n\
\n\
\\NNN character with octal value NNN (1 to 3 octal digits)\n\
\\\\ backslash\n\
\\a audible BEL\n\
\\b backspace\n\
\\f form feed\n\
\\n new line\n\
\\r return\n\
\\t horizontal tab\n\
"), stdout);
ここは同じ。
ja.po
#: src/tr.c:317
msgid ""
" \\v vertical tab\n"
" CHAR1-CHAR2 all characters from CHAR1 to CHAR2 in ascending order\n"
" [CHAR*] in SET2, copies of CHAR until length of SET1\n"
" [CHAR*REPEAT] REPEAT copies of CHAR, REPEAT octal if starting with 0\n"
" [:alnum:] all letters and digits\n"
" [:alpha:] all letters\n"
" [:blank:] all horizontal whitespace\n"
" [:cntrl:] all control characters\n"
" [:digit:] all digits\n"
msgstr ""
" \\v 垂直タブ\n"
" CHAR1-CHAR2 CHAR1 から CHAR2 までを昇順に展開した文字列\n"
" [CHAR1-CHAR2] SET1 と SET2 の両方で指定した場合には CHAR1-CHAR2 と同じ\n"
" [CHAR*] SET2 として, CHAR を SET1 の長さ分展開した文字列\n"
" [CHAR*REPEAT] CHAR を REPEAT 個展開した文字列, REPEAT の値を 0 から\n"
" 始めた場合には八進数として解釈する\n"
" [:alnum:] 全てのアルファベットと数字\n"
" [:alpha:] 全てのアルファベット\n"
" [:blank:] 全ての水平方向空白類文字\n"
" [:cntrl:] 全ての制御文字\n"
" [:digit:] 全ての数字\n"
ソースコード
fputs (_("\
\\v vertical tab\n\
CHAR1-CHAR2 all characters from CHAR1 to CHAR2 in ascending order\n\
[CHAR*] in SET2, copies of CHAR until length of SET1\n\
[CHAR*REPEAT] REPEAT copies of CHAR, REPEAT octal if starting with 0\n\
[:alnum:] all letters and digits\n\
[:alpha:] all letters\n\
[:blank:] all horizontal whitespace\n\
[:cntrl:] all control characters\n\
[:digit:] all digits\n\
"), stdout);
ここは例の文があるところ。
ja.po
#: src/tr.c:328
msgid ""
" [:graph:] all printable characters, not including space\n"
" [:lower:] all lower case letters\n"
" [:print:] all printable characters, including space\n"
" [:punct:] all punctuation characters\n"
" [:space:] all horizontal or vertical whitespace\n"
" [:upper:] all upper case letters\n"
" [:xdigit:] all hexadecimal digits\n"
" [=CHAR=] all characters which are equivalent to CHAR\n"
msgstr ""
" [:graph:] 全ての表示可能文字。空白は含まない\n"
" [:lower:] 全ての小文字アルファベット\n"
" [:print:] 全ての表示可能文字。空白も含む\n"
" [:punct:] 全ての句読点\n"
" [:space:] 全ての水平及び垂直タブ文字\n"
" [:upper:] 全ての大文字アルファベット\n"
" [:xdigit:] 全ての十六進数数値\n"
" [=CHAR=] 全ての CHAR と等価な文字\n"
ソースコード
fputs (_("\
[:graph:] all printable characters, not including space\n\
[:lower:] all lower case letters\n\
[:print:] all printable characters, including space\n\
[:punct:] all punctuation characters\n\
[:space:] all horizontal or vertical whitespace\n\
[:upper:] all upper case letters\n\
[:xdigit:] all hexadecimal digits\n\
[=CHAR=] all characters which are equivalent to CHAR\n\
"), stdout);
ここには違いはなし。
ja.po
#: src/tr.c:338
msgid ""
"\n"
"Translation occurs if -d is not given and both SET1 and SET2 appear.\n"
"-t may be used only when translating. SET2 is extended to length of\n"
"SET1 by repeating its last character as necessary. Excess characters\n"
"of SET2 are ignored. Only [:lower:] and [:upper:] are guaranteed to\n"
"expand in ascending order; used in SET2 while translating, they may\n"
"only be used in pairs to specify case conversion. -s uses SET1 if not\n"
"translating nor deleting; else squeezing uses SET2 and occurs after\n"
"translation or deletion.\n"
msgstr ""
"\n"
"置換は -d が与えられず、 SET1 および SET2 の両方が指定されたときに実行されます。\n"
"-t は置換の時のみ使用されます。SET2 は必要に応じて SET1 の長さまで最後の文字を\n"
"繰り返すことで拡張されます。 SET2 の超過した文字は無視されます。[:lower:] およ\n"
"び [:upper:] のみ、置換における SET2 で使用すると昇順であることが保証されます。\n"
"これは大文字・小文字の変換を指定する時のみに組み合わせとして使用されます。置換\n"
"でも削除でもない場合は -s では SET1 が使われます。切り詰めの場合には SET2 が置\n"
"換、削除の後に使用されます。\n"
ソースコード
fputs (_("\
\n\
Translation occurs if -d is not given and both SET1 and SET2 appear.\n\
-t may be used only when translating. SET2 is extended to length of\n\
SET1 by repeating its last character as necessary. Excess characters\n\
of SET2 are ignored. Only [:lower:] and [:upper:] are guaranteed to\n\
expand in ascending order; used in SET2 while translating, they may\n\
only be used in pairs to specify case conversion. -s uses the last\n\
specified SET, and occurs after translation or deletion.\n\
"), stdout);
最後の文、-s以降に違いがある。
いつ頃からこの「食い違い」があるのかはわからない(し、調べない)けど、
目視確認ではわかりづらくても自動的な検査はできそうだよな…
と再度 The coreutils textual domain
の日本語のところを見ると8.31.90から状態がグリーン(未翻訳なし)になっていて、
最新(9.0-pre1)のもので上記の比較をしたら
正しい状態になっていた。
ただし、例の[CHAR1-CHAR2]
の部分はそのまま残っている
(そりゃまあ翻訳前文字列とソースコード中の文字列とは対応取れてるんだしねえ)。
ということは報告するならここだけでよいのか。
new standarized awk’s features
なんか目の敵にしているようにも思えて申し訳ないのだけど😅
次期POSIX(Issue 8)で標準化されるawkの機能は delete array, nextfile, fflush() - Qiita
次期 POSIX (Issue 8、2022 年後期予定)で標準化される awk の機能は delete array、nextfile ステートメント、fflush() 関数の 3 つです。
(略)
ついでにどのバージョンから使えるようになっているのかを確認しました。見出しのカッコの中の日付は、これらの変更が提案された日付です。
補足 (略) Debian 2.2 より前の環境は調査していないのでそれよりも古いバージョンから使える可能性が高いです。
ということなので、これらの機能のgawkにおける実装時期ついて。
delete array
gawk.texi.in
まずは delete array
(配列全体に対する delete)は
最新のドキュメントにはこうあって(例によってTexinfo形式そのまま)
All the elements of an array may be deleted with a single statement
by leaving off the subscript in the @code{delete} statement,
as follows:
@example
delete @var{array}
@end example
Using this version of the @code{delete} statement is about three times
more efficient than the equivalent loop that deletes each element one
at a time.
This form of the @code{delete} statement is also supported
by BWK @command{awk} and @command{mawk}, as well as
by a number of other implementations.
@cindex Brian Kernighan's @command{awk}
@quotation NOTE
For many years, using @code{delete} without a subscript was a common
extension. In September 2012, it was accepted for inclusion into the
POSIX standard. See @uref{http://austingroupbugs.net/view.php?id=544,
the Austin Group website}.
@end quotation
ここにも 2012年にaccepted for inclusion into the POSIX standard
されたとありますね。
まあそれはそれとして
texi
以前公開していたgawkのドキュメントの翻訳テキスト(の残骸)が SSDの片隅にあったのでちょいと貼り付け。
以下のように
delete
文で添え字付けを行わないことによって、 その配列のすべての要素を一つの文で削除することができる。
delete array
この機能は
gawk
の拡張であり、互換モードでは使うことはできない。この形式の
delete
文を使うのは、 ループを使って配列の要素の削除を行うものより三倍以上効率的である。
NEWS
この機能、実はもっと古くからあって、NEWSファイル(正確にはNEWS.0という古いものを追い出した先の方)をみると
Changes from 2.15.3 to 2.15.4
の部分に
New `delete array’ feature added. Only documented in the man page.
とあるので、3.0より前からあったわけですね (詳細なリリース時期は知らん>2.15.4)。
nextfile
次にnextfile
。これはgawk発祥だったような記憶がある。
また、最初はnextfile
じゃなくて、next file
と空白入りのキーワード(と表現してよいのだろうか)だったはず。
gawk.texi.in
まずは最新のドキュメントから
@quotation NOTE
For many years, @code{nextfile} was a common extension. In September 2012, it was accepted for inclusion into the POSIX standard. See @uref{http://austingroupbugs.net/view.php?id=607, the Austin Group website}.
@end quotation
texi
続いてわたしの拙訳(これもベースは3.0.X時代のもの)
現在のバージョンのベル研究所による
awk
もまたnextfile
をサポートしている。 しかしながら、関数の本体でnextfile
を使うことはできない。gawk
はできる。関数本体にあるnextfile
は その他の場所のnextfile
がそうであるように 次のレコードを読み込みプログラムの最初のルールから処理を開始する。
警告:
3.0以前のバージョンの
gawk
では、nextfile
文には二つの単語(`next file')を使っていた。 これは3.0で一つの単語に変更された。 それは、 `file'の取り扱いが一貫性のないものであったからだ。 `file'がnextの後に現れた場合それはキーワードとなる。 しかしそれ以外の場合には通常の識別子になるのだ。 古い使用法はもはや受け付けられない。 `next file'は構文エラーとなる。
あ、記述ありましたね>next file
しかし今見ると手直ししたい訳ばかりだなあ😅
NEWS
これについてもNEWS.0から
Changes from 3.0.6 to 3.1.0
(略)
8. Gawk no longer supports `next file’ as two words.
Changes from 2.15.6 to 3.0.0
(略)
next file' has changed to one word,
nextfile’.next file' is still accepted but generates a lint warning.
next file’ will go away eventually.
Changes from 2.13.2 to 2.14
(略)
Added “next file” to skip efficiently to the next input file.
キーワードの空白あるなしの違いを無視すれば、2.14の時点ですでにあったと。
fflush
最後にfflush。
gawk.texi.in
まずはドキュメント。
@item @code{fflush(}[@var{filename}]@code{)}
@cindexawkfunc{fflush}
@cindex flush buffered output
Flush any buffered output associated with @var{filename}, which is either a
file opened for writing or a shell command for redirecting output to
a pipe or coprocess.
@cindex buffers @subentry flushing
@cindex output @subentry buffering
Many utility programs @dfn{buffer} their output (i.e., they save information
to write to a disk file or the screen in memory until there is enough
for it to be worthwhile to send the data to the output device).
This is often more efficient than writing
every little bit of information as soon as it is ready. However, sometimes
it is necessary to force a program to @dfn{flush} its buffers (i.e.,
write the information to its destination, even if a buffer is not full).
This is the purpose of the @code{fflush()} function---@command{gawk} also
buffers its output, and the @code{fflush()} function forces
@command{gawk} to flush its buffers.
@cindex extensions @subentry common @subentry @code{fflush()} function
@cindex Brian Kernighan's @command{awk}
Brian Kernighan added @code{fflush()} to his @command{awk} in April
1992. For two decades, it was a common extension. In December
2012, it was accepted for inclusion into the POSIX standard.
See @uref{http://austingroupbugs.net/view.php?id=634, the Austin Group website}.
POSIX standardizes @code{fflush()} as follows: if there
is no argument, or if the argument is the null string (@w{@code{""}}),
then @command{awk} flushes the buffers for @emph{all} open output files
and pipes.
@quotation NOTE
Prior to @value{PVERSION} 4.0.2, @command{gawk}
would flush only the standard output if there was no argument,
and flush all output files and pipes if the argument was the null
string. This was changed in order to be compatible with BWK
@command{awk}, in the hope that standardizing this
feature in POSIX would then be easier (which indeed proved to be the case).
With @command{gawk},
you can use @samp{fflush("/dev/stdout")} if you wish to flush
only the standard output.
@end quotation
Brian Kernighan added fflush() to his awk in April 1992.
とあるので、発祥は(おそらく) One True awkで
最初に実装された時期は1992年と。
ただこの頃はまだ「オープン」になってなかったんじゃなかろうか
>One True awkのソースコード
texi
拙訳。
fflush([filename])
Flush any buffered output associated with filename, which is either a file opened for writing or a shell command for redirecting output to a pipe or coprocess.
filenameに結び付けられているオープンしたファイルの出力や、 パイプ、コプロセスにリダイレクト出力しているシェルコマンドのための出力バッファをフラッシュする。
多くのユーティリティプログラムがその出力をバッファリングしている。 これは、ディスク上のファイルやターミナルに書き出す情報をメモリ上に貯えておき、 (送るのに)十分な量になったところで出力デバイスにまとめて送るものである。 しかし、時としてバッファがいっぱいになっていなくても、 情報をその出力先に出力するために強制的にプログラムにそのバッファを フラッシュ (flush)させる必要があることがある。 これが、
fflush
の目的である。gawk
もまたその出力をバッファリングしており、fflush
関数はgawk
のバッファを 強制的にフラッシュさせるために使うことができる。
fflush
は1994年にベル研究所で開発されたawk
で追加された。 これはPOSIXの標準ではなく、 `--posix'がコマンドラインで指定された場合は使用できない。
gawk
はfflush
関数を二つの方法で拡張した。 一つは引数なしの場合を認めたというものであり、 この場合は標準出力のバッファがフラッシュされる。 もう一つは引数として空文字列(""
) を認めたというものであり、 これはすべてのオープンされているファイル、パイプをフラッシュする。
fflush
はバッファのフラッシュに成功した場合は0を返し、それ以外では -1を返す。 すべてのバッファをフラッシュする場合には、 すべてのバッファのフラッシュに成功したときに0を返す。 そうでない場合には-1を返し、gawk
は問題のあったfilenameに関して警告する。
gawk
は(getline
を使うなどして) 読み込みのためにオープンされたファイルやパイプをフラッシュしようとしたときや、 filenameがオープンされたファイル、パイプ、コプロセスでないとき にも警告を行う。 このような場合、fflush
は-1を返す。
あれ? こっちだと1994年とありますね。
NEWS
NEWS.0から。
Changes from 2.15.6 to 3.0.0
The AT&T Bell Labs Research awk fflush builtin function is now supported. fflush is extended to flush stdout if no arg and everything if given the null string as an argument.
mawk
おまけでmawk。
mawk の nextfile も Debian に搭載されるのが遅かっただけで CHANGES を見る限り 1.3.4 20120627 には実装されてるようです (delete array と fflush() は 1996 年の 1.2 の時点ですでに対応済み)。
「1.3.4」の扱いについてはとりあえず今回は触れないでおいて、 該当の部分はここですね。
Changes from version 1.1.4 to 1.2:
6) New built-in function fflush() -- copied from the lastest att awk.
fflush() : flushes stdout and returns 0
fflush(file) flushes file and returns 0; if file was not an
open output file then returns -1.
7) delete A ; -- removes all elements of the array A
intended to replace:
for( i in A) delete A[i]
mawk 1.2 って1996年だったっけか?
もっと前だったような気もするんだけど、 昔のことで自分の記憶も不鮮明だし きちんと調べて書いているんだろうし 1996年でいいんだろう。たぶん。
といいつつ手元のアーカイブ(1.3.3ベースにわたしが手を入れたもの)を見ると、 CHANGESというファイルに
1.3.1 -> 1.3.2 Sep 1996
1) Numeric but not integer indices caused core dump in new array scheme.
Fixed bug and fired test division.
2) Added ferror() checks on writes.
3) Added some static storage specs to array.c to keep non-ansi
compilers happy.
1.3 -> 1.3.1 Sep 1996
Release to new ftp site ftp://ftp.whidbey.net.
1) Workaround for overflow exception in strtod, sunos5.5 solaris.
2) []...] and [^]...] put ] in a class (or not in a class) without
having to use back-slash escape.
1.2.2 -> 1.3 Jul 1996
Extensive redesign of array data structures to support large arrays and
fast access to arrays created with split. Many of the ideas in the
new design were inspired by reading "The Design and Implementation of
Dynamic Hashing Sets and Tables in Icon" by William Griswold and
Gregg Townsend, SPE 23,351-367.
1.2.1 -> 1.2.2 Jan 1996
1) Improved autoconfig, in particular, fpe tests. This is far from
perfect and never will be until C standardizes an interface to ieee754.
2) Removed automatic error message on open failure for getline.
3) Flush all output before system(). Previous behavior was to only
flush std{out,err}.
4) Explicitly fclose() all output on exit to work around AIX4.1 bug.
5) Fixed random number generator to work with longs larger than
32bits.
6) Added a type Int which is int on real machines and long on dos machines.
Believe that all implicit assumptions that int=32bits are now gone.
とかあるなあ。これより過去の記載はないんだけど、 1.2.1→1.2.2が96年1月なので1.2のリリースが96年かどうかは微妙だなあ。
さらにmanディレクトリの下にあるmawk.1の先頭には
.TH MAWK 1 "Dec 22 1994" "Version 1.2" "USER COMMANDS"
.\" strings
.ds ex \fIexpr\fR
.SH NAME
mawk \- pattern scanning and text processing language
とあった(roff形式だ…)。
まあ古いバージョンのソースコードのアーカイブがあれば疑問は解決できるんだろうけど、 置いているサイトはないだろうなあ。 あとは90年代に売られていた「フリーウェア」(やシェアウェア)を集めたCD-ROMがあれば そこに入っているかもしれないけど、手元にはないよなあたぶん (秋葉原にあった某店で当時何枚か買ってた)。