ときどきの雑記帖 RE* (新南口)
微笑みがえし
定期券売り場(臨時)
東急武蔵小杉駅の 以前定期券売り場があったあたりに (通学定期向けの) 臨時の定期券購入受付 ができていた。
C#
Some of the newer C# patterns make things so much cleaner: pic.twitter.com/OiW4C6RQRX
— @Nick_Craver@infosec.exchange (@Nick_Craver) March 27, 2022
面白い構文だな。
string? line;
while ((line = reader.ReadLine()) != null)
を
string? line;
while (reader.ReadLine() is string line)
のように表すと。 条件式で代入が絡むと…というのはまあ理解できる。
ところでline
の宣言も while文に閉じ込めるのは難しいんですかね
(Perlのmy
みたいに)。
date
で
new_years_day="2022-01-01" for i in $(seq 0 364) do date +%Y-%m-%d -d "$new_years_day + $i day" done
というシェルスクリプトが例示されていたのだけど
閏年が考慮されていない(seqの引数が0 364
で固定)
のがちょっと気になったり。
開始の日が2022年1月1日になってるからと言えばそうなんだろうけど、 こういう「他にも直すべきところ」って 往々にして忘れられる(そして「ぎゃっ」となる)よね。
Eテレ
2022年度 タイムテーブル - キッズワールド - NHK Eテレ こどもポータル
メモメモ。
- 火 1650 テキシコー
- 水 1650 考えるカラス~科学の考え方~
ReDos
[B! 正規表現] 正規表現の脆弱性 (ReDoS) を JavaScript で学ぶ の hiromichinomata のブックマーク / はてなブックマーク
PerlもPHPもRubyも鬼車なので再帰が使える。
🤔
localedef
読んでいたのが少し前なので 記憶があやふやになっているところがあるのだけど 書いておかないのもなんなので ここで「ダンプ」しておく (書くにあたって読み返したりはしない😄)
例の、ある文字のコードがdigitだったりalphaだったりするかの 情報を収めているテーブル
/* Bit tables are accessed by cutting wc in four blocks of bits:
- the high 32-q-p bits,
- the next q bits,
- the next p bits,
- the next 5 bits.
+------------------+-----+-----+-----+
wc = + 32-q-p-5 | q | p | 5 |
+------------------+-----+-----+-----+
p and q are variable. For 16-bit Unicode it is sufficient to
choose p and q such that q+p+5 <= 16.
The table contains the following uint32_t words:
- q+p+5,
- s = upper exclusive bound for wc >> (q+p+5),
- p+5,
- 2^q-1,
- 2^p-1,
- 1st-level table: s offsets, pointing into the 2nd-level table,
- 2nd-level table: k*2^q offsets, pointing into the 3rd-level table,
- 3rd-level table: j*2^p words, each containing 32 bits of data.
*/
に関して、このp
だのq
だのの大きさはどのように決めているのか
というのが疑問だったのだけど、
テーブルの大きさによって作成時に動的に計算して決めているようなことは
せずにテーブルの種類に応じてあらかじめ決まっているらしい。
glibcのlocale/programs/
にある
localedef.c
loclfile.c
check_all_categories()
check_funcs()
ld-ctype.c
この辺を読んでいくと
/* Construction of sparse 3-level tables.
See wchar-lookup.h for their structure and the meaning of p and q. */
struct wctype_table
{
/* Parameters. */
unsigned int p;
unsigned int q;
/* Working representation. */
size_t level1_alloc;
size_t level1_size;
uint32_t *level1;
size_t level2_alloc;
size_t level2_size;
uint32_t *level2;
size_t level3_alloc;
size_t level3_size;
uint32_t *level3;
size_t result_size;
};
といった構造体や
t = &ctype->class_3level[nr];
t->p = 4; /* or: 5 */
t->q = 7; /* or: 6 */
wctype_table_init (t);
t = &ctype->map_3level[nr];
t->p = 7;
t->q = 9;
wctrans_table_init (t);
t = &ctype->width;
t->p = 7;
t->q = 9;
wcwidth_table_init (t);
のようなコードが見つかる。
最初の例のコメントにある
/* or: 5 */
と/* or: 6 */
の意味するところがわからないけれど、
(作成するテーブルの)初期化で定数を代入しているだけで
テーブルの作成途中で
->p
や->q
を
書き換えるようなことは
していなかった(たぶん)。
まあ実際にそれをやると割と大変そうなのは予想できるのでそんなもんだろうと思うけど 作成したテーブルの容量的な効率の面ではどうなんだろうか とか、 32bitプロセッサー向けのデータ構造だよな と思われる部分もこのままにし続けるんだろうかとは思ったり。
実際に眺めた関数はこの辺り。
/* Add one entry. */
static void
wctype_table_add (struct wctype_table *t, uint32_t wc)
/* Finalize and shrink. */
static void
add_locale_wctype_table (struct locale_file *file, struct wctype_table *t)
{
static void
allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
struct repertoire_t *repertoire)
{
for (idx = 0; idx < ctype->class_collection_act; ++idx)
if (ctype->class_collection[idx] & _ISwbit (nr))
wctype_table_add (t, ctype->charnames[idx]);
record_verbose (stderr, _("\
%s: table for class \"%s\": %lu bytes"),
"LC_CTYPE", ctype->classnames[nr],
(unsigned long int) t->result_size);
}
/* We have to be prepared that TABLE, MAX, and ACT can be NULL. This
is possible if we only want to extend the name array. */
static uint32_t *
find_idx (struct locale_ctype_t *ctype, uint32_t **table, size_t *max,
size_t *act, uint32_t idx)
{