Annotation of nono/lib/monitor_id.pl, revision 1.1.1.6

1.1       root        1: #
                      2: # nono
                      3: # Copyright (C) 2021 nono project
                      4: # Licensed under nono-license.txt
                      5: #
                      6: 
                      7: # monitor_id.txt から monitor_id.h, monitor_id.cpp を作る。
                      8: #
                      9: # usage: perl monitor_id.pl monitor_id.txt
                     10: 
                     11: {
                     12:        $defs = "";
                     13:        $body = "";
                     14:        $first_mon_id = "";
                     15:        $first_sub_id = "";
1.1.1.3   root       16:        @maxes = ();
1.1       root       17: 
                     18:        # $#ARGV は引数の数-1。ここでいう引数は monitor_id.pl の後ろから。
                     19:        if ($#ARGV != 0) {
                     20:                die "usage: $0 <id.txt>\n";
                     21:        }
                     22: 
                     23:        # ファイル名
                     24:        $infile = $ARGV[0];
                     25:        $hdrfile = $infile;
                     26:        $srcfile = $infile;
                     27:        $hdrfile =~ s/txt$/h/;
                     28:        $srcfile =~ s/txt$/cpp/;
                     29: 
1.1.1.6 ! root       30:        # 先頭に一つダミーエントリを入れる。
        !            31:        # (あまりサポートしてないけど) wxMac ではメニュー ID が 0 だと死ぬので。
        !            32:        $id = "ID_MONITOR_zeroth_dummy_for_wxmac";
        !            33:        $mon_defs .= "\t$id = 0,\n";
        !            34:        $mon_body .= "\t{ $id, },\n";
        !            35: 
1.1       root       36:        open(IN, $infile) || die "Cannot open infile: ${infile}\n";
                     37:        while (<IN>) {
                     38:                # Remove comments.
                     39:                chomp;
                     40:                s/#.*$//;
                     41:                next if /^$/;
                     42: 
                     43:                @names = split(/\s+/);
                     44: 
1.1.1.3   root       45:                if ($names[0] =~ /([^%]+)%(\d+)/) {
                     46:                        # %n なら 0..(n-1) に展開
                     47:                        $basename = $1;
                     48:                        $atnum = $2 + 0;
1.1       root       49: 
1.1.1.3   root       50:                        # モニタの最大数はここが一次情報なので、これから定数を作る
                     51:                        push(@maxes, "MAX_${basename}_MONITOR = ${atnum}");
1.1       root       52:                        for ($i = 0; $i < $atnum; $i++) {
                     53:                                @rep_names = ();
                     54:                                foreach $n (@names) {
                     55:                                        $r = $n;
                     56:                                        $r =~ s/%${atnum}/${i}/g;
1.1.1.4   root       57:                                        $r =~ s/%/${i}/g;
1.1       root       58:                                        push(@rep_names, $r);
                     59:                                }
                     60:                                parse_line(@rep_names);
                     61:                        }
                     62:                } else {
                     63:                        # default
                     64:                        parse_line(@names);
                     65:                }
                     66:        }
                     67:        close(IN);
                     68: 
                     69:        # 文字列として出力
                     70:        $hdrnew = "";
                     71:        $srcnew = "";
                     72: 
                     73:        $hdrnew .= "// Generated from ${0}\n";
                     74:        $hdrnew .= "\n";
                     75:        $hdrnew .= $mon_defs;
                     76:        $hdrnew .= "\n";
                     77:        $hdrnew .= $sub_defs;
                     78:        $hdrnew .= "\n";
                     79:        $hdrnew .= "\tID_MONITOR_START = ${first_mon_id},\n";
                     80:        $hdrnew .= "\tID_MONITOR_END = ${last_mon_id},\n";
                     81:        $hdrnew .= "\tID_MONITOR_MAX = ID_MONITOR_END + 1,\n";
                     82:        $hdrnew .= "\tID_SUBWIN_START = ${first_sub_id},\n";
                     83:        $hdrnew .= "\tID_SUBWIN_END = ${last_sub_id},\n";
                     84:        $hdrnew .= "\tID_SUBWIN_MAX = ID_SUBWIN_END + 1,\n";
                     85:        $hdrnew .= "\n";
                     86:        $hdrnew .= "\t// これは enum じゃないけど自動生成の都合でここに置く\n";
1.1.1.3   root       87:        foreach $str (@maxes) {
                     88:                $hdrnew .= "\t${str},\n";
                     89:        }
1.1       root       90: 
                     91:        $srcnew .= "// Generated from ${0}\n";
                     92:        $srcnew .= "\n";
                     93:        $srcnew .= "#include \"monitor.h\"\n";
                     94:        $srcnew .= "\n";
                     95:        $srcnew .= "/*static*/ const std::vector<MonitorManager::MonitorInfo>\n";
                     96:        $srcnew .= "MonitorManager::info {\n";
                     97:        $srcnew .= $mon_body;
                     98:        $srcnew .= "\n";
                     99:        $srcnew .= $sub_body;
                    100:        $srcnew .= "};\n";
1.1.1.3   root      101:        $srcnew .= "\n";
1.1.1.5   root      102:        $srcnew .= "/*static*/ const std::vector<std::pair<uint, const char *>>\n";
1.1.1.3   root      103:        $srcnew .= "Monitor::idtext {\n";
                    104:        $srcnew .= $label_body;
                    105:        $srcnew .= "};\n";
1.1       root      106: 
                    107:        # 更新があれば書き出す
                    108:        do_update($hdrfile, $hdrnew);
                    109:        do_update($srcfile, $srcnew);
                    110: 
                    111:        exit 0;
                    112: }
                    113: 
                    114: sub parse_line()
                    115: {
                    116:        local @names = @_;
                    117:        local $id = shift(@names);
                    118:        local $type = shift(@names);
                    119:        local $flag = shift(@names);
                    120:        local $first;
                    121: 
                    122:        if ($#names == -1) {
                    123:                # If <names...> are ommited, use ID instead.
                    124:                $first = lc $id;
                    125:        } else {
                    126:                # If <names...> are specified, use it.
                    127:                $first = shift(@names);
                    128:        }
                    129: 
                    130:        if ($type eq "m") {
                    131:                $id = "ID_MONITOR_${id}";
                    132:                if ($first_mon_id eq "") {
                    133:                        $first_mon_id = $id;
                    134:                }
                    135:                $last_mon_id = $id;
                    136:        } else {
                    137:                $id = "ID_SUBWIN_${id}";
                    138:                if ($first_sub_id eq "") {
                    139:                        $first_sub_id = $id;
                    140:                }
                    141:                $last_sub_id = $id;
                    142:        }
                    143: 
1.1.1.4   root      144:        if ($flag eq ".") {
                    145:                # フラグ省略時(モニタの場合)は vmcap を参照することはないはず
                    146:                $flag = "NONE";
                    147:        }
                    148:        # フラグは '|' で並べることが出来る。
1.1.1.3   root      149:        @flags = split(/\|/, $flag);
                    150:        @caps = map { "VMCap::".$_ } @flags;
                    151:        $cap = join('|', @caps);
                    152: 
1.1       root      153:        $defs = "\t${id},\n";
1.1.1.3   root      154:        $body = "\t{ ${id},\t${cap},\t{ \"${first}\"";
1.1       root      155:        foreach $name (@names) {
                    156:                $body .= ", \"${name}\"";
                    157:        }
                    158:        $body .= " } },\n";
                    159: 
                    160:        if ($type eq "m") {
                    161:                $mon_defs .= $defs;
                    162:                $mon_body .= $body;
                    163:        } else {
                    164:                $sub_defs .= $defs;
                    165:                $sub_body .= $body;
                    166:        }
1.1.1.3   root      167: 
                    168:        # デバッグ用の ID と文字列の対応表
                    169:        $label_body .= "\t{ ${id}, \"${id}\" },\n";
1.1       root      170: }
                    171: 
                    172: sub do_update()
                    173: {
                    174:        local $filename = $_[0];
                    175:        local $filebody = $_[1];
                    176:        local $old;
                    177:        local @contents;
                    178: 
                    179:        # まず出力先ファイルを文字列として読み込む
                    180:        $old = "";
                    181:        if (open(IN, $filename)) {
                    182:                @contents = <IN>;
                    183:                $old = join("", @contents);
                    184:                close(IN);
                    185:        }
                    186: 
                    187:        # 全文を比較して変更があれば出力
                    188:        if ($filebody ne $old) {
                    189:                open(OUT, ">${filename}") || die "Cannot open ${filename}\n";
                    190:                print OUT $filebody;
                    191:                close(OUT);
                    192:                print "Updated ${filename}\n";
                    193:        }
                    194: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.