Annotation of nono/util/sramedit/sramedit.cpp, revision 1.1

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2021 nono project
        !             4: // Licensed under nono-license.txt
        !             5: //
        !             6: 
        !             7: //
        !             8: // X680x0 SRAM.DAT エディタ
        !             9: //
        !            10: 
        !            11: #include "sramedit.h"
        !            12: #include <err.h>
        !            13: #include <fcntl.h>
        !            14: #include <unistd.h>
        !            15: #include <sys/mman.h>
        !            16: 
        !            17: [[noreturn]] static void usage();
        !            18: static void calc_width();
        !            19: static void show();
        !            20: static void edit(int ac, char *av[]);
        !            21: 
        !            22: static int width;
        !            23: int debug;
        !            24: uint8 *sram;
        !            25: 
        !            26: int
        !            27: main(int ac, char *av[])
        !            28: {
        !            29:        const char *filename;
        !            30:        int c;
        !            31:        int fd;
        !            32:        int mode;
        !            33:        int prot;
        !            34:        size_t maplen;
        !            35: 
        !            36:        calc_width();
        !            37: 
        !            38:        while ((c = getopt(ac, av, "dh")) != -1) {
        !            39:                switch (c) {
        !            40:                 case 'd':
        !            41:                        debug++;
        !            42:                        break;
        !            43:                 case 'h':
        !            44:                 default:
        !            45:                        usage();
        !            46:                        break;
        !            47:                }
        !            48:        }
        !            49:        ac -= optind;
        !            50:        av += optind;
        !            51: 
        !            52:        if (ac == 0) {
        !            53:                usage();
        !            54:        }
        !            55: 
        !            56:        filename = av[0];
        !            57:        ac--;
        !            58:        av++;
        !            59: 
        !            60:        if (ac == 0) {
        !            61:                // show
        !            62:                mode = O_RDONLY;
        !            63:                prot = PROT_READ;
        !            64:        } else {
        !            65:                // edit
        !            66:                mode = O_RDWR;
        !            67:                prot = PROT_READ | PROT_WRITE;
        !            68:        }
        !            69: 
        !            70:        fd = open(filename, mode);
        !            71:        if (fd < 0) {
        !            72:                err(1, "%s: open", filename);
        !            73:        }
        !            74:        maplen = 0x100;
        !            75:        int flag = MAP_FILE | MAP_SHARED;
        !            76:        void *m = mmap(NULL, maplen, prot, flag, fd, 0);
        !            77:        if (m == MAP_FAILED) {
        !            78:                err(1, "%s: mmap", filename);
        !            79:        }
        !            80:        sram = (uint8 *)m;
        !            81: 
        !            82:        if (ac == 0) {
        !            83:                show();
        !            84:        } else {
        !            85:                edit(ac, av);
        !            86:        }
        !            87: 
        !            88:        munmap(m, maplen);
        !            89:        close(fd);
        !            90:        return 0;
        !            91: }
        !            92: 
        !            93: static void
        !            94: usage()
        !            95: {
        !            96:        fprintf(stderr, "usage: %s <SRAM.DAT>             .. show all\n",
        !            97:                getprogname());
        !            98:        fprintf(stderr, "       %s <SRAM.DAT> <key=value> .. set\n",
        !            99:                getprogname());
        !           100:        exit(1);
        !           101: }
        !           102: 
        !           103: // グローバル変数 width に代入する
        !           104: static void
        !           105: calc_width()
        !           106: {
        !           107:        width = 0;
        !           108: 
        !           109:        for (const auto& si : sraminfo) {
        !           110:                if (si.reader == NULL) {
        !           111:                        continue;
        !           112:                }
        !           113: 
        !           114:                width = std::max(width, (int)strlen(si.name));
        !           115:        }
        !           116: }
        !           117: 
        !           118: static void
        !           119: show1(const sraminfo_t& si)
        !           120: {
        !           121:        std::string val = si.reader(si);
        !           122:        printf("$%02x: %-*s = %s\n", si.offset, width, si.name, val.c_str());
        !           123: }
        !           124: 
        !           125: static void
        !           126: show()
        !           127: {
        !           128:        for (const auto& si : sraminfo) {
        !           129:                if (si.reader) {
        !           130:                        show1(si);
        !           131:                }
        !           132:        }
        !           133: }
        !           134: 
        !           135: static void
        !           136: edit(int ac, char *av[])
        !           137: {
        !           138:        int updated = 0;
        !           139: 
        !           140:        for (int i = 0; i < ac; i++) {
        !           141:                const char *s;
        !           142:                const char *e;
        !           143:                std::string key;
        !           144:                std::string val;
        !           145: 
        !           146:                s = av[i];
        !           147:                e = strchr(s, '=');
        !           148:                if (e) {
        !           149:                        key = std::string(s, (e - s));
        !           150:                        val = std::string(e + 1);
        !           151:                } else {
        !           152:                        key = std::string(s);
        !           153:                }
        !           154: 
        !           155:                if (key.empty()) {
        !           156:                        warnx("%s: key must be specified", av[i]);
        !           157:                        return;
        !           158:                }
        !           159: 
        !           160:                bool found = false;
        !           161:                for (const auto& si : sraminfo) {
        !           162:                        if (strcasecmp(key.c_str(), si.name) != 0) {
        !           163:                                continue;
        !           164:                        }
        !           165: 
        !           166:                        if (val.empty()) {
        !           167:                                // key のみなら、現在値と書式ヘルプを表示
        !           168:                                printf("current value:\n\t");
        !           169:                                show1(si);
        !           170: 
        !           171:                                if (si.help != NULL) {
        !           172:                                        const std::string msg0 = si.help(si);
        !           173:                                        // 行頭にタブを追加
        !           174:                                        std::string msg = "\t";
        !           175:                                        for (auto c : msg0) {
        !           176:                                                msg += c;
        !           177:                                                if (c == '\n') {
        !           178:                                                        msg += '\t';
        !           179:                                                }
        !           180:                                        }
        !           181:                                        printf("syntax:\n");
        !           182:                                        printf("%s\n", msg.c_str());
        !           183:                                }
        !           184:                                return;
        !           185:                        } else {
        !           186:                                // key=val なら更新
        !           187:                                int result = (si.writer)(si, val);
        !           188:                                if (result == -1) {
        !           189:                                        // エラーは向こうで表示済み
        !           190:                                        return;
        !           191:                                }
        !           192:                                show1(si);
        !           193:                                // エラーでなければ更新件数を返している
        !           194:                                updated += result;
        !           195:                                found = true;
        !           196:                                break;
        !           197:                        }
        !           198:                }
        !           199:                if (!found) {
        !           200:                        warnx("%s: key not found", av[i]);
        !           201:                        return;
        !           202:                }
        !           203:        }
        !           204: 
        !           205:        if (updated == 0) {
        !           206:                printf("Nothing was updated\n");
        !           207:        } else {
        !           208:                printf("%d updated\n", updated);
        !           209:        }
        !           210: }

unix.superglobalmegacorp.com

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