ときどきの雑記帖 RE* (新南口)
悲しみよこんにちは
linter
linterってなんか「むずがゆさ」を感じる呼び方だよなあ と思っているのだけど
“Linting”, “Linter (software)”, and “Lint tool” redirect here. For the MediaWiki extension, see Wikipedia:Linter.
Lint, or a linter, is a static code analysis tool used to flag programming errors, bugs, stylistic errors and suspicious constructs.[4] The term originates from a Unix utility that examined C language source code.[1]
へー(でも使わない。たぶん😄)。
工作人員
前回書いたのとは違うとある工事現場にあった看板の文言が 中国語と英語も併記されていて こんな感じだった(中文は簡体字なので字体が違うんだけどそれはそれ)。
- 関係者以外立入禁止
- 前方非工作人員禁止通行
- DO NOT ENTER AUTHORIZED PERSONS ONLY
英語表記のこれ、DO NOT ENTER
とAUTHORIZED PERSONS ONLY
で明確に二つの文に分かれるような気がするのだけど
そのままくっつけちゃってもよいのだろうか?
セイバーメトリクス
とある本を読んでいたら これでもかというくらい指標が出てきてなんじゃこりゃ状態。 巻末に一覧があったので転記してみるとこう。
BABIP, Barrel%, BB/9, BsR, Clutch, Concat%, Defensive Runs Saved, DER, xwOBA, FIP, FIPR9, F-Strike%, GPA, HradHit%, HR/9, HQS, ifFIP, inLI, ISO, IsoD, K/BB, K/9, NOI, OAA, O-Concat%, OPS, OPS+, O-Swing%, PF, phLI, Pitching Runs, Plate Discipline, pLI, QS, RC, RCAA, RCWIN, RC27, RE24, RF, RPW, RRF, RSAA, RSWIN, SecA, SIERA, Sweet Spot%, Swing%, SwStr%, TA, tRA, UBR, UZR, WAR, wGDP, Whiff%, WHIP, wOBA, wRAA, wRC, wSB, WPA, xFIP, XR, Z-Contact%, Zone%, ZR, Z-Swing%
それぞれ解説を読めばなるほどと思わないでもないんだけど、 こんなにたくさん要るの? というのが本音(なんの?)
【保存版】セイバーメトリクス指標一覧【基本から分かりやすく解説】
unboxing
本当、某方面で「ボックス化」「非ボックス化」とかいう 訳語をひねくりだした(ぴー)は(ry
cost performance
常々(他にも色々あるけど。たとえば「パラダイム」とか) コスパ(コストパフォーマンス)って安易に使いすぎてないか と思っているのだけど
英語のcost performanceはガチの専門用語で、日常会話で使うようなものではない(広く一般には知られていない)からである。
へー>「日常会話で使うようなものではない」
ノーノー
まさか生きている間に ベイスターズの選手がノーヒットノーランを達成するのを目にする機会が訪れるとは😄
横浜マリンタワー
横浜マリンタワー 今夏リニューアル、営業再開へ - 産経ニュース
「動く実物大ガンダム」観に行ったときにすぐそばを通ったのだけど、 そうか営業していなかったのか。あれ。
NF=NF
'$1=$1'はquoteしないといけないので、NF=NFがおすすめ #シェル芸
— eban (@eban) May 27, 2022
NF+=0でもいいけど、まあ、どれを選んでも意味不明ではある。 #シェル芸
— eban (@eban) May 27, 2022
echo ' a b c d ' | awk '{print "."; print $0";"; NF=NF; print $0";"}'#シェル芸
— eban (@eban) May 27, 2022
言われてみればそうだなあと思いつつも、 以前NFを操作しても$0の再構成が行われなかった というバグがgawkになかったっけか なんて記憶もあり。
それはさておきまずはマニュアル。
gawk.texi
@cindex portability @subentry @code{NF} variable, decrementing
@quotation CAUTION
Some versions of @command{awk} don't
rebuild @code{$0} when @code{NF} is decremented.
Until August, 2018, this included BWK @command{awk}; fortunately
his version now handles this correctly.
@end quotation
Finally, there are times when it is convenient to force
@command{awk} to rebuild the entire record, using the current
values of the fields and @code{OFS}. To do this, use the
seemingly innocuous assignment:
@example
@group
$1 = $1 # force record to be reconstituted
print $0 # or whatever else with $0
@end group
@end example
@noindent
This forces @command{awk} to rebuild the record. It does help
to add a comment, as we've shown here.
There is a flip side to the relationship between @code{$0} and
the fields. Any assignment to @code{$0} causes the record to be
reparsed into fields using the @emph{current} value of @code{FS}.
This also applies to any built-in function that updates @code{$0},
such as @code{sub()} and @code{gsub()}
(@pxref{String Functions}).
なるほど。 2022年時点ではそれほど気にする必要もなさそうだけど 注意は必要と。
いくつかのawk処理系でNFを操作したときのコードを見てみる。
gawk
field.c:150:/* rebuild_record --- Someone assigned a value to $(something).
awk.h:1153:extern bool field0_valid;
builtin.c:2334: if (! field0_valid || do_lint) // lint check for field access in END
eval.c:812: if (! field0_valid) {
eval.c:1211: if (field_num == 0 && field0_valid) { /* short circuit */
field.c:83:bool field0_valid; /* $(>0) has not been changed yet */
field.c:111: field0_valid = true;
field.c:250: field0_valid = true;
field.c:391: field0_valid = true;
field.c:437: field0_valid = false;
field.c:843: field0_valid = false;
field.c:869: if (! field0_valid) {
field.c:900: field0_valid = false; /* $0 needs reconstruction */
debug.c:3891: "reset_record()" : "invalidate_field0()");
field.c:838:/* invalidate_field0 --- $0 needs reconstruction */
field.c:841:invalidate_field0()
field.c:911: *assign = invalidate_field0; /* $0 needs reconstruction */
gawk/src/filed.c
/* set_NF --- handle what happens to $0 and fields when NF is changed */
void
set_NF()
{
mawk
field.c:81:static void PROTO(build_field0, (void)) ;
field.c:339: build_field0() ;
field.c:410: build_field0() ;
field.c:419:build_field0()
field.c:424: if (nf < 0) bozo("nf <0 in build_field0") ;
field.c field_assign
switch (i = (fp - field))
{
case NF_field:
ontrueawk
Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
{
int fldno;
f += 0.0; /* normalise negative zero to positive zero */
if ((vp->tval & (NUM | STR)) == 0)
funnyvar(vp, "assign to");
if (isfld(vp)) {
donerec = false; /* mark $0 invalid */
fldno = atoi(vp->nval);
if (fldno > *NF)
newfld(fldno);
dprintf( ("setting field %d to %g\n", fldno, f) );
} else if (&vp->fval == NF) {
donerec = false; /* mark $0 invalid */
setlastfld(f);
dprintf( ("setting NF to %g\n", f) );
goawk
https://t.co/2D5EgaT5PEのPOSIX非準拠のバグをいくつか報告してきた。POSIXコマンドと言えど実装のバグでPOSIXに準拠していない事は当然ある
— Koichi Nakashima (@ko1nksm) June 4, 2022
POSIXコマンドは多くのベンダが実装しているが、それは互換性問題が大きい事を意味する。POSIXコマンドを使うからこそシェルスクリプトはテストが重要になる
goawkはPOSIX準拠であると主張しているが実際にはバグが有った
— Koichi Nakashima (@ko1nksm) June 4, 2022
POSIX準拠のシェルスクリプトを他の環境に持っていった時、それが正しく動作すると保証できるだろうか?
シェルスクリプトは依存ライブラリ(コマンド)が多い。それらに完全な互換性が保証されない以上テストなしに動作保証は出来ない
というのでgoawkのリポジトリを確かめた。 この辺かな。
- Consider making handling of CR LF newlines more consistent with Gawk · Issue #51 · benhoyt/goawk
- -v must interpret escape sequences · Issue #129 · benhoyt/goawk
- Incompatibility of regular expression \b · Issue #131 · benhoyt/goawk
- Regular expression does not match multi-line string · Issue #130 · benhoyt/goawk
RSに正規表現入れていいんだっけ? と思ったけど(それを許しているものがあるのは知っている) 問題なさげ?
GNU
色々調べているときに偶然遭遇した bug-gnulib (date) で
- regex module has dropped support for syntax tables
- Accepting [xyz—abc] - three minus signs to mean one
なんてのを見つけた。 そう言えばいまのglibcのregexにはsyntax tableなかったんだっけか。
link_warning
今だとヘッダに関数宣言がないのはいいとして、リンク時も警告が出るようになってるんだけど、これどうやってるんだろう。 pic.twitter.com/VIdrVxMKY1
— yoh2 (@yoh2_sdj) June 6, 2022
ということで(ry
メッセージからglibcのソースを探してみると二つ見つかった。
glibc/debug/gets_chk.c glibc/gets_chk.c at 895ef79e04a953cac1493863bcae29ad85657ee1 · lattera/glibc
#include "../libio/libioP.h"
#include <limits.h>
char *
__gets_chk (char *buf, size_t size)
{
size_t count;
int ch;
char *retval;
if (size == 0)
__chk_fail ();
_IO_acquire_lock (_IO_stdin);
ch = _IO_getc_unlocked (_IO_stdin);
if (ch == EOF)
{
retval = NULL;
goto unlock_return;
}
if (ch == '\n')
count = 0;
else
{
/* This is very tricky since a file descriptor may be in the
non-blocking mode. The error flag doesn't mean much in this
case. We return an error only when there is a new error. */
int old_error = _IO_stdin->_flags & _IO_ERR_SEEN;
_IO_stdin->_flags &= ~_IO_ERR_SEEN;
buf[0] = (char) ch;
count = _IO_getline (_IO_stdin, buf + 1, size - 1, '\n', 0) + 1;
if (_IO_stdin->_flags & _IO_ERR_SEEN)
{
retval = NULL;
goto unlock_return;
}
else
_IO_stdin->_flags |= old_error;
}
if (count >= size)
__chk_fail ();
buf[count] = 0;
retval = buf;
unlock_return:
_IO_release_lock (_IO_stdin);
return retval;
}
link_warning (__gets_chk, "the `gets' function is dangerous and should not be used.")
libio/iogets.c glibc/iogets.c at master · bminor/glibc
#include "libioP.h"
#include <limits.h>
char *
_IO_gets (char *buf)
{
size_t count;
int ch;
char *retval;
_IO_acquire_lock (stdin);
ch = _IO_getc_unlocked (stdin);
if (ch == EOF)
{
retval = NULL;
goto unlock_return;
}
if (ch == '\n')
count = 0;
else
{
/* This is very tricky since a file descriptor may be in the
non-blocking mode. The error flag doesn't mean much in this
case. We return an error only when there is a new error. */
int old_error = stdin->_flags & _IO_ERR_SEEN;
stdin->_flags &= ~_IO_ERR_SEEN;
buf[0] = (char) ch;
count = _IO_getline (stdin, buf + 1, INT_MAX, '\n', 0) + 1;
if (stdin->_flags & _IO_ERR_SEEN)
{
retval = NULL;
goto unlock_return;
}
else
stdin->_flags |= old_error;
}
buf[count] = 0;
retval = buf;
unlock_return:
_IO_release_lock (stdin);
return retval;
}
weak_alias (_IO_gets, gets)
link_warning (gets, "the `gets' function is dangerous and should not be used.")
二つ目が本命だろうけどそれはさておき
どちらもlink_warning
というディレクティブ?
で指示しているようだ。
んが、gccのライブラリを探しても
このlink_warning
が見つからない。
じゃあとglibcからlink_warningを探してみると
debug/gets_chk.c:75:link_warning (__gets_chk, "the `gets' function is dangerous and should not be used.")
debug/getwd_chk.c:32:link_warning (getwd,
dlfcn/dlmopen.c:107:static_link_warning (dlmopen)
dlfcn/dlopen.c:102:static_link_warning (dlopen)
hurd/hurdexec.c:42:link_warning (_hurd_exec,
include/libc-symbols.h:226:#define link_warning(symbol, msg) \
include/libc-symbols.h:228: static const char __evoke_link_warning_##symbol[] \
include/libc-symbols.h:235: link_warning (name, #name " is not implemented and will always fail")
include/libc-symbols.h:239:#define static_link_warning(name)
include/libc-symbols.h:241:#define static_link_warning(name) static_link_warning1(name)
include/libc-symbols.h:242:#define static_link_warning1(name) \
include/libc-symbols.h:243: link_warning(name, "Using '" #name "' in statically linked applications \
inet/inet6_option.c:96:link_warning (inet6_option_space,
inet/inet6_option.c:129:link_warning (inet6_option_init,
inet/inet6_option.c:161:link_warning (inet6_option_append,
inet/inet6_option.c:221:link_warning (inet6_option_alloc,
inet/inet6_option.c:278:link_warning (inet6_option_next,
inet/inet6_option.c:346:link_warning (inet6_option_find,
io/getwd.c:53:link_warning (getwd,
libio/iogets.c:72:link_warning (gets, "the `gets' function is dangerous and should not be used.")
misc/getsysstats.c:31:link_warning (get_nprocs_conf, "warning: get_nprocs_conf will always return 1")
misc/getsysstats.c:44:link_warning (get_nprocs, "warning: get_nprocs will always return 1")
misc/mktemp.c:36:link_warning (mktemp, "the use of `mktemp' is dangerous, "
nptl/pthread_attr_getstackaddr.c:43:link_warning (pthread_attr_getstackaddr,
nptl/pthread_attr_setstackaddr.c:45:link_warning (pthread_attr_setstackaddr,
nss/nsswitch.h:85:# define nss_interface_function(name) static_link_warning (name)
posix/regex.c:81:link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
pwd/getpw.c:62:link_warning (getpw, "the `getpw' function is dangerous and should not be used.")
signal/siggetmask.c:27:link_warning (siggetmask,
stdio-common/tempnam.c:42:link_warning (tempnam,
stdio-common/tmpnam.c:50:link_warning (tmpnam,
stdio-common/tmpnam_r.c:36:link_warning (tmpnam_r,
sysdeps/unix/sysv/linux/sigstack.c:61:link_warning (sigstack, "the `sigstack' function is dangerous. `sigaltstack' should be used instead.")
ヘッダーファイル(include/libc-symbols.h)で定義しているのが見つかった。 実際どんな定義かというとこう。
include/libc-symbols.h glibc/libc-symbols.h at master · bminor/glibc
/* When a reference to SYMBOL is encountered, the linker will emit a
warning message MSG. */
/* We want the .gnu.warning.SYMBOL section to be unallocated. */
#define __make_section_unallocated(section_string) \
asm (".section " section_string "\n\t.previous");
/* Tacking on "\n\t#" to the section name makes gcc put it's bogus
section attributes on what looks like a comment to the assembler. */
#ifdef HAVE_SECTION_QUOTES
# define __sec_comment "\"\n\t#\""
#else
# define __sec_comment "\n\t#"
#endif
#define link_warning(symbol, msg) \
__make_section_unallocated (".gnu.warning." #symbol) \
static const char __evoke_link_warning_##symbol[] \
__attribute__ ((used, section (".gnu.warning." #symbol __sec_comment))) \
= msg;
link_warningから__make_section_unallocatedを経由して
asmを使ってごにょごにょしていた
(When a reference to SYMBOL is encountered, the linker will emit a warning message MSG.
)と。
なるほどねえ。
- Binutils - GNU Project - Free Software Foundation
- Documentation for binutils 2.38
- Using as
- LD
- how to produce glibc’s odd static linking warning about getaddrinfo