--- nono/lib/mainapp.cpp 2026/04/29 17:04:40 1.1.1.5 +++ nono/lib/mainapp.cpp 2026/04/29 17:04:48 1.1.1.6 @@ -22,7 +22,7 @@ MainApp::ShowHelp(bool all) const printf("usage: %s []\n", getprogname()); p("-A load and execute host binary (a.out or ELF)"); - p("-c vm directory"); + p("-c vm directory or configuration file"); p("-f fast mode"); if (IsGUI()) p("--fontsize fontsize in monitors {12,16} (default:12)"); @@ -87,8 +87,8 @@ MainApp::Init(bool is_cli_, int ac, char // 設定を作成。コンストラクタで初期値を用意 gConfig.reset(new Config()); - // 引数で指定されたディレクトリの設定ファイルを読み込んで設定を更新 - ConfigFile file(vmdir + "nono.cfg"); + // 引数で指定されたディレクトリの設定ファイルがあれば読み込んで設定を更新 + ConfigFile file(vmfile); if (file.Load() == false) { return EXIT_FAILURE; } @@ -132,7 +132,7 @@ MainApp::Init(bool is_cli_, int ac, char break; case VMTYPE_LUNA1: - gVM.reset(new VM_LUNA()); + gVM.reset(new VM_LUNA1()); break; case VMTYPE_RXZ: @@ -201,11 +201,14 @@ MainApp::Start() bool MainApp::ParseOpt(int ac, char *av[]) { + struct stat st; + const char *cpath; int b; int c; fontsize = 12; screen_scale = 1.0; + cpath = "."; while ((c = getopt_long(ac, av, "A:b:B:c:CdDfhL:M:s:vV:X:", longopts, NULL)) != -1) { @@ -228,7 +231,11 @@ MainApp::ParseOpt(int ac, char *av[]) break; case 'c': - vmdir = std::string(optarg); + cpath = optarg; + // 空文字列なら再び初期値に + if (cpath[0] == '\0') { + cpath = "."; + } break; case 'C': @@ -320,12 +327,33 @@ MainApp::ParseOpt(int ac, char *av[]) } } - // vmdir に '/' を付けておく - if (vmdir.empty()) { - vmdir = "."; + // 引数がディレクトリなら、それを VM ディレクトリとし、その中の + // nono.cfg を設定ファイルとする。 + // 引数がファイルなら、それを設定ファイルとし、そのファイルがある + // ディレクトリを VM ディレクトリとする。 + // -c DIR => vmdir = DIR, vmfile = DIR/nono.cfg + // -c DIR/FILE => vmdir = DIR, vmfile = FILE + if (stat(cpath, &st) < 0) { + warn("stat %s", cpath); + return false; } - if (vmdir.back() != '/') { - vmdir += '/'; + if (S_ISDIR(st.st_mode)) { + vmdir = std::string(cpath); + if (vmdir.back() != '/') { + vmdir += '/'; + } + vmfile = vmdir + "nono.cfg"; + } else if (S_ISREG(st.st_mode)) { + vmfile = std::string(cpath); + auto pos = vmfile.rfind('/'); + if (pos != std::string::npos) { + vmdir = vmfile.substr(0, pos + 1); + } else { + vmdir = "./"; + } + } else { + warnx("-c %s: path must be file or directory", cpath); + return false; } // CLI 版で -Mhelp つけても黙って起動するのはさすがにどうかと思う。 @@ -439,7 +467,7 @@ MainApp::ParseLogopt() printf("invalid logname '%s'\n", name); goto abort; } - } + } } rv = true;