Annotation of nono/util/sramedit/sramedit.cpp, revision 1.1.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.