アニメ『音楽少女』(2018)
音楽家を両親に持つハナコ。
ダンスを一回見ただけで振り付け完璧に覚えられるし、歌も覚えてしまいます。
すごい才能です。さらに、各メンバーの個性も初見で把握、メンバー衣装のコーディネートもこなす。
さらにさらに、タクシーは渋滞だからと3km走る体力まで持っています。
そうです。
ハナコは100億人に一人のアイドルなんです! ハナコ、当然アイドルになるものと思っていたら、アイドル「音楽少女」を応援するためのスタッフになります。
へ? スタッフ?
まあ、いずれ本人もアイドルになるのでしょうけど、スタッフってのが面白かったので視聴始めました。
(親記事はコチラ中級者のためのLinuxコマンド入門)
前回に引き続き、psコマンドのオプションの解析方法をソースから追っかけます。
前回、ps/parser.cに各オプション処理(case文)を見つけました。
ps/parser.cにはどのような関数があるでしょうか。
228 static const char *parse_sysv_option(void){ 229 const char *arg; 230 const char *err; 231 232 flagptr = ps_argv[thisarg]; 233 while(*++flagptr){ 234 switch(*flagptr){ 235 case 'A': 236 trace("-A selects all processes\n"); 237 all_processes = 1; 238 break;
parse_sysv_optionという関数がありました。この関数の中でcase文がたくさん書かれておりオプション処理されています。関数名から分かる通り、SYSVオプションの処理のようです。つまり、SYSVオプションの処理以外は、別関数で処理していることでしょう。
この関数の使用箇所を探していきます。
同じくps/parser.cに、parse_sysv_option関数を呼び出している関数がありました。
parse_sysv_optionだけでなく、parse_gnu_optionや、parse_bsd_option関数も呼び出してますね。parse_all_optionsという関数名なので、おそらくここですべてのオプションを処理していると思います。
1102 /* First assume sysv, because that is the POSIX and Unix98 standard. */ 1103 static const char *parse_all_options(void){ 1104 const char *err = NULL; 1105 int at; 1106 while(++thisarg < ps_argc){ 1107 trace("parse_all_options calling arg_type for \"%s\"\n", ps_argv[thisarg] 1108 at = arg_type(ps_argv[thisarg]); 1109 trace("ps_argv[thisarg] is %s\n", ps_argv[thisarg]); 1110 switch(at){ 1111 case ARG_GNU: 1112 err = parse_gnu_option(); 1113 break; 1114 case ARG_SYSV: 1115 if(!force_bsd){ /* else go past case ARG_BSD */ 1116 err = parse_sysv_option(); 1117 break; 1118 case ARG_BSD: 1119 if(force_bsd && !(personality & PER_FORCE_BSD)) return _("way bad") 1120 } 1121 prefer_bsd_defaults = 1; 1122 err = parse_bsd_option(); 1123 break;
GNU、SYSV、BSDそれぞれの分岐は1108行目のarg_type関数で決められているようです。
では、arg_typeを見てみましょう。
1083 static int arg_type(const char *str){ 1084 int tmp = str[0]; 1085 if((tmp>='a') && (tmp<='z')) return ARG_BSD; 1086 if((tmp>='A') && (tmp<='Z')) return ARG_BSD; 1087 if((tmp>='0') && (tmp<='9')) return ARG_PID; 1088 if(tmp=='+') return ARG_SESS; 1089 if(tmp!='-') return ARG_FAIL; 1090 tmp = str[1]; 1091 if((tmp>='a') && (tmp<='z')) return ARG_SYSV; 1092 if((tmp>='A') && (tmp<='Z')) return ARG_SYSV; 1093 if((tmp>='0') && (tmp<='9')) return ARG_PGRP; 1094 if(tmp!='-') return ARG_FAIL; 1095 tmp = str[2]; 1096 if((tmp>='a') && (tmp<='z')) return ARG_GNU; 1097 if((tmp>='A') && (tmp<='Z')) return ARG_GNU; 1098 if(tmp=='\0') return ARG_END; 1099 return ARG_FAIL; 1100 }
なんと!
複雑なオプションは、やはり複雑な処理で解析されていたんですね。
コメント