ときどきの雑記帖 RE* (新南口)
キックの鬼
空手バカ一代のOP/EDが収録されているCDはないかいなと探してみると (サブスクリプションの類には出てきてないと思ったからだけど実はあったりする?)、 こんなのが見つかった。いい値段がついてるけど。
おお、空手バカ一代だけじゃなくてキックの鬼も収録されているじゃないかこのCD。
ところで「真空飛び膝蹴り」の「真空」とは? 🤔 などと思ったら 同様の疑問を持った人もいたらしい(笑)
grep \t
assign
あのさあ…(笑)
GCC、著作権をFSFに割り当てなくても貢献可能になる | スラド オープンソース
記事でリンクされてる Update to GCC copyright assignment policy のタイトルにあるassignmentか、 本文中のassignを「割り当て」としたんだろうけど、 辞書ひこうよ?
The GCC Steering Committee has decided to relax the requirement to assign copyright for all changes to the Free Software Foundation. GCC will continue to be developed, distributed, and licensed under the GNU General Public License v3.0. GCC will now accept contributions with or without an FSF copyright assignment.
assignmentの意味・使い方・読み方 | Weblio英和辞書
【法律, 法学】 (財産・権利などの)譲渡.
英語「assign」の意味・使い方・読み方 | Weblio英和辞書
【法律, 法学】〈人に〉〈財産・権利などを〉譲渡する; 〔人に〕〈財産・権利などを〉譲渡する.
あとこういう話も知らなかったということなんかね。
どうしてFSFは、FSFが著作権を有するプログラムへの貢献者が自らの著作権をFSFに譲渡することを要求するのですか? もしわたしがGPLが使われたプログラムの著作権を有しているならば、わたしも著作権譲渡を要求すべきでしょうか? もしそうなら、どうやって?
GNUプロジェクトはこのような事態に陥ることを回避するため、前述の通り著作権者からコードの著作権をFSFに譲渡するよう勧め、またソフトウェアのライセンスほぼ全てに"any later version"表明文を付したGPLを適用している。
皆が皆知っておくべきとは言わないし思わないけど、なんかあんまりだなあ。
世界線
以前から「面白い」記事を書く人だなあとは思っていたんだけど
オペレーティングシステム:マスター吹越のちょこっと情報学:エンジニアライフ
どこの「世界線」から来た人なんだろう…
このOSという概念を拡張してGUIを最初に作ったのはAppleコンピュータ(スティーブ・ジョブズ追放前時代)。
OSという概念が一般に広がったころ、オープンソースの流行もあってUNIXというOSがベル研究所からオープンソースで公開されました。 あとからライセンスを取るようになったため、UNIXを真似して独自開発されたのがLinuxです。
先のiOSのもとになったBSDもUNIXをまねて開発されたため、UNIXはそのクローンを大量に持っています。
Tronは日本産のOSでOS開発戦争期に開発された。軽いのが売りで扱いやすいことからIoTのOSとしての採用が多いらしい。PCのOSとしては負けたけど、入っている台数ベースで考えると世界一のOSかもしれない。
∀
AIは増えすぎたガンダムを見分けることができるのか?Teachable Machineで作った分類モデルで検証してみた - Qiita
∀を除いた状態で学習させて、そこから∀見せたりしたらにどう判定するかちょっと気になる。
今週のしずえさん
自転車(のペダル)。
自転車(の原型)の発明者とタイプライターの発明者が同じ人だとは知らなかった。
glob(そのn+6)
v7unix/v7/usr/src/cmd/sh at master ・ v7unix/v7unix
exfile
+ execute
| + cmd
| + list
| + term
| + word
| + item
+ getarg
| + split
| + expand
|
+ execa
+ execs
item
では前回のtermに続いてitemに (前述の図ではwordが先にあるけど)。
itemの構文的な定義は以下の通り。
/*
* item
*
* ( cmd ) [ < in ] [ > out ]
* word word* [ < in ] [ > out ]
* if ... then ... else ... fi
* for ... while ... do ... done
* case ... in ... esac
* begin ... end
*/
LOCAL TREPTR item(flag)
BOOL flag;
{
REG TREPTR t;
REG IOPTR io;
IF flag
THEN io=inout((IOPTR)0);
ELSE io=0;
FI
SWITCH wdval IN
ここでswitchのラベル部分にのみ注目する。
case CASYM:
case IFSYM:
case FORSYM:
case WHSYM:
case UNSYM:
case BRSYM:
case '(':
default:
case 0:
ENDSW
}
例によって省略が激しいのでわかりづらいけど
- CASYM → case symbol
- IFSYM → if symbol
- FORSYM → for symbol
- WHSYM → while symbol
- UNSYM → until symbol
- BRSYM → bracket symbol
{
でほぼ構文定義と一致しているので、今回追いかけているはずの 通常のコマンド呼び出しのフローは default か 0 のいずれか。 ではあるのだけど、省略していたラベルに続く処理部分を改めて見てみると default の方は
IF io==0
THEN return(0);
FI
なのでこちらではありえない。となると結論は 0 の方になる。
にしても「生の数値 0」ってなによ? と言いたくなるところで、 じゃあとこのswitch文の起点を見ると
SWITCH wdval IN
wdval なる変数を使っている。実はここまで意識的に説明を避けてきたのだけど、 この変数はグローバル変数でそのためいくつかの関数で代入されたり参照されたりする。 この種のグローバル変数は以前にもgchainなどがありましたな。
そしてこのwdvalを書き換えているところが先ほどはスキップした word という関数。
word
v7unix/word.c at ed636a47207476db76d53b7869447889dee3bbad · v7unix/v7unix
word.c
word()
{
REG CHAR c, d;
REG CHAR *argp=locstak()+BYTESPERWORD;
INT alpha=1;
wdnum=0; wdset=0;
WHILE (c=nextc(0), space(c)) DONE
IF !eofmeta(c)
THEN REP IF c==LITERAL
THEN *argp++=(DQUOTE);
WHILE (c=readc()) ANDF c!=LITERAL
DO *argp++=(c|QUOTE); chkpr(c) OD
*argp++=(DQUOTE);
ELSE *argp++=(c);
IF c=='=' THEN wdset |= alpha FI
IF !alphanum(c) THEN alpha=0 FI
IF qotchar(c)
THEN d=c;
WHILE (*argp++=(c=nextc(d))) ANDF c!=d
DO chkpr(c) OD
FI
FI
PER (c=nextc(0), !eofmeta(c)) DONE
argp=endstak(argp);
IF !letter(argp->argval[0]) THEN wdset=0 FI
peekc=c|MARK;
IF argp->argval[1]==0 ANDF (d=argp->argval[0], digit(d)) ANDF (c=='>' ORF c=='<')
THEN word(); wdnum=d-'0';
ELSE /*check for reserved words*/
IF reserv==FALSE ORF (wdval=syslook(argp->argval,reserved))==0
THEN wdarg=argp; wdval=0;
FI
FI
ELIF dipchar(c)
THEN IF (d=nextc(0))==c
THEN wdval = c|SYMREP;
ELSE peekc = d|MARK; wdval = c;
FI
ELSE IF (wdval=c)==EOF
THEN wdval=EOFSYM;
FI
IF iopend ANDF eolchar(c)
THEN copy(iopend); iopend=0;
FI
FI
reserv=FALSE;
return(wdval);
}
wdval のほかにも同じような名前の変数があるので列挙すると
- wdarg
- wdnum
- wdset
といった辺り。
eofmeta
WHILE (c=nextc(0), space(c)) DONE
IF !eofmeta(c)
このwhileループで空白を読み飛ばした後の最初のキャラクターに対して eofmetaという関数でなにやら判定しているけど、 これは実は関数ぽく見えるマクロ(Cではよくあるやつっすね)で お仲間も含めて以下のようなものがある。
v7unix/ctype.h at ed636a47207476db76d53b7869447889dee3bbad · v7unix/v7unix
/* nb these args are not call by value !!!! */
#define space(c) (((c)"E)==0 ANDF _ctype1[c]&(T_SPC))
#define eofmeta(c) (((c)"E)==0 ANDF _ctype1[c]&(_META|T_EOF))
#define qotchar(c) (((c)"E)==0 ANDF _ctype1[c]&(T_QOT))
#define eolchar(c) (((c)"E)==0 ANDF _ctype1[c]&(T_EOR|T_EOF))
#define dipchar(c) (((c)"E)==0 ANDF _ctype1[c]&(T_DIP))
#define subchar(c) (((c)"E)==0 ANDF _ctype1[c]&(T_SUB|T_QOT))
#define escchar(c) (((c)"E)==0 ANDF _ctype1[c]&(T_ESC))
で、eofmetaaはというと、_METAかT_EOFのビットが立っていたら真と
(ここでは前半部の((c)"E)==0
は見ないふりをすること。
QUOTEについては以前ちょっと説明した覚えもあるけど)。
T_EOFはまあEOFだよね。ですむのだけど、 じゃあ_METAって何よ?という話になって、それはこう。
/* abbreviations for tests */
#define _IDCH (T_IDC|T_DIG)
#define _META (T_SPC|T_DIP|T_MET|T_EOR)
さらに別のフラグ定義が出てきた。 ここで各フラグが何ビット目を使っているかという情報を追いかけて行っても 意味がないので、どういうモノ(文字)に対して使われているのかをみる。 すると
/* for single chars */
#define _TAB (T_SPC)
#define _SPC (T_SPC)
#define _UPC (T_IDC)
#define _LPC (T_IDC)
#define _DIG (T_DIG)
#define _EOF (T_EOF)
#define _EOR (T_EOR)
#define _BAR (T_DIP)
#define _HAT (T_MET)
#define _BRA (T_MET)
#define _KET (T_MET)
#define _SQB (T_FNG)
#define _AMP (T_DIP)
#define _SEM (T_DIP)
#define _LT (T_DIP)
#define _GT (T_DIP)
#define _LQU (T_QOT|T_ESC)
#define _BSL (T_ESC)
#define _DQU (T_QOT)
#define _DOL1 (T_SUB|T_ESC)
REP
REP (およびそれと組み合わされる PER)というマクロについてちょっと説明しておこう。 これは IF/THEN/ELSE/FIやWHILE/DO/DONEと同種の Algolっぽい表記をするためのもので、具体的には以下のように定義されている。
v7unix/mac.h at ed636a47207476db76d53b7869447889dee3bbad · v7unix/v7unix
#define REP do{
#define PER }while(
#define DONE );
ふと、PER
ってなんの略語だろうと思ったが、これ
IF→FI、DO→ODと同様の、逆からつづった並びだな。
REPeat → taePER。
COBOLのPERFORM辺りから来たものかと思ってしまった😄
まあそういう脇の話はさておき、
REP IF c==LITERAL
THEN *argp++=(DQUOTE);
WHILE (c=readc()) ANDF c!=LITERAL
DO *argp++=(c|QUOTE); chkpr(c) OD
*argp++=(DQUOTE);
ELSE *argp++=(c);
IF c=='=' THEN wdset |= alpha FI
IF !alphanum(c) THEN alpha=0 FI
IF qotchar(c)
THEN d=c;
WHILE (*argp++=(c=nextc(d))) ANDF c!=d
DO chkpr(c) OD
FI
FI
PER (c=nextc(0), !eofmeta(c)) DONE
のようなループ部分をふつーのCで書き直してみると こんな感じか(自分の好みで一部の演算子の周りに空白を置いた)。
do {
if (c==LITERAL) {
*argp++ = (DQUOTE);
while ((c=readc()) && c!=LITERAL) {
*argp++ = (c|QUOTE);
chkpr(c);
}
*argp++=(DQUOTE);
}
else {
*argp++ = (c);
if (c=='=') { wdset |= alpha; }
if (!alphanum(c)) { alpha=0; }
if (qotchar(c)) {
d=c;
while ((*argp++ = (c=nextc(d))) && c!=d) {
chkpr(c);
}
}
}
} while (c=nextc(0), !eofmeta(c));
そして上記のループに続く部分はこう
argp=endstak(argp);
IF !letter(argp->argval[0]) THEN wdset=0 FI
peekc=c|MARK;
IF argp->argval[1]==0 ANDF (d=argp->argval[0], digit(d)) ANDF (c=='>' ORF c=='<')
THEN word(); wdnum=d-'0';
ELSE /*check for reserved words*/
IF reserv==FALSE ORF (wdval=syslook(argp->argval,reserved))==0
THEN wdarg=argp; wdval=0;
FI
FI
ここで wdvalを0にしている。 ということは、ここまで切り出してきた文字列が 予約語 ではないということで、 前述の switch文で0に該当するのはクォートされてもいない、 予約語でもない alphanumericな文字の並び。 つまりは外部コマンド(の名前)などがここに該当するということですね。
LITERAL
v7unix/sym.h at ed636a47207476db76d53b7869447889dee3bbad · v7unix/v7unix
/* odd chars */
#define DQUOTE '"'
#define SQUOTE '`'
#define LITERAL '\''
#define DOLLAR '$'
#define ESCAPE '\\'
#define BRACE '{'
ここでは{
はbraceなんですな(笑)
LOCAL TREPTR item(flag)
BOOL flag;
{
REG TREPTR t;
REG IOPTR io;
IF flag
THEN io=inout((IOPTR)0);
ELSE io=0;
FI
SWITCH wdval IN
case CASYM:
BEGIN
t=getstak(SWTYPE);
chkword();
t->swarg=wdarg->argval;
skipnl(); chksym(INSYM|BRSYM);
t->swlst=syncase(wdval==INSYM?ESSYM:KTSYM);
t->swtyp=TSW;
break;
END
case IFSYM:
BEGIN
REG INT w;
t=getstak(IFTYPE);
t->iftyp=TIF;
t->iftre=cmd(THSYM,NLFLG);
t->thtre=cmd(ELSYM|FISYM|EFSYM,NLFLG);
t->eltre=((w=wdval)==ELSYM ? cmd(FISYM,NLFLG) : (w==EFSYM ? (wdval=IFSYM, item(0)) : 0));
IF w==EFSYM THEN return(t) FI
break;
END
case FORSYM:
BEGIN
t=getstak(FORTYPE);
t->fortyp=TFOR;
t->forlst=0;
chkword();
t->fornam=wdarg->argval;
IF skipnl()==INSYM
THEN chkword();
t->forlst=item(0);
IF wdval!=NL ANDF wdval!=';'
THEN synbad();
FI
chkpr(wdval); skipnl();
FI
chksym(DOSYM|BRSYM);
t->fortre=cmd(wdval==DOSYM?ODSYM:KTSYM,NLFLG);
break;
END
case WHSYM:
case UNSYM:
BEGIN
t=getstak(WHTYPE);
t->whtyp=(wdval==WHSYM ? TWH : TUN);
t->whtre = cmd(DOSYM,NLFLG);
t->dotre = cmd(ODSYM,NLFLG);
break;
END
case BRSYM:
t=cmd(KTSYM,NLFLG);
break;
case '(':
BEGIN
REG PARPTR p;
p=getstak(PARTYPE);
p->partre=cmd(')',NLFLG);
p->partyp=TPAR;
t=makefork(0,p);
break;
END
default:
IF io==0
THEN return(0);
FI
case 0:
BEGIN
REG ARGPTR argp;
REG ARGPTR *argtail;
REG ARGPTR *argset=0;
INT keywd=1;
t=getstak(COMTYPE);
t->comio=io; /*initial io chain*/
argtail = &(t->comarg);
WHILE wdval==0
DO argp = wdarg;
IF wdset ANDF keywd
THEN argp->argnxt=argset; argset=argp;
ELSE *argtail=argp; argtail = &(argp->argnxt); keywd=flags&keyflg;
FI
word();
IF flag
THEN t->comio=inout(t->comio);
FI
OD
t->comtyp=TCOM; t->comset=argset; *argtail=0;
return(t);
END
ENDSW
reserv++; word();
IF io=inout(io)
THEN t=makefork(0,t); t->treio=io;
FI
return(t);
}
reserv という変数の役割が今一つピンとこないけど まあいいや😄
10年物
わたしのところにもあったような…(笑)
買って10年積んでた本を読んでいるが、これ面白いな。熟成されたな
— kinaba (@kinaba) June 4, 2021
2012-02-16 に購入した本を 2021-06-06 に読み終えた。
— grove (@grove_twtr) June 6, 2021
「”何かが豊富に安価で提供されている(この場合だと病院に行く人の数)”のを土台にして技術開発をして金を稼ぐ」が構図として成り立ちそうなので、俺も”何かよくわからんけど豊富に提供されてるもの”を利用していきたい
— テラモナギ (@teramonagi) May 29, 2021
無地
Mandrel:Quarkusに特化したGraalVMのディストリビューション - 赤帽エンジニアブログ
私たちは無地のOpenJDK 11で構築したかったし、Oracle Labsはダウンストリームで保守するパッチの数を減らしたかったのです。
「無地」? どういう意味で使っているんだろう?
で(例によって)原文。
Mandrel: A specialized distribution of GraalVM for Quarkus | Red Hat Developer
We wanted to build with plain OpenJDK 11, and Oracle Labs wanted fewer patches to maintain downstream.
いや、この「plain」を「無地」はないでしょう。
Plain | Definition of Plain at Dictionary.com
あと patches to maintain downstream
は
「ダウンストリームで保守するパッチ」
じゃないと思う。