|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.