アニメ『音楽少女』(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 }
なんと!
複雑なオプションは、やはり複雑な処理で解析されていたんですね。



コメント