--- nono/lib/mainapp.cpp 2026/04/29 17:04:34 1.1.1.3 +++ nono/lib/mainapp.cpp 2026/04/29 17:04:48 1.1.1.6 @@ -22,10 +22,10 @@ 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,24} (default:12)"); + p("--fontsize fontsize in monitors {12,16} (default:12)"); p("-h show brief help message"); p("--help show all help message including for developers"); if (IsGUI()) @@ -36,7 +36,7 @@ MainApp::ShowHelp(bool all) const if (all) { printf("\n(options for developers)\n"); - p("-b breakpoint"); + p("-b [,] set breakpoint"); p("-B benchmark mode"); p("-C output log to console"); p("-d debugger prompt on startup"); @@ -67,13 +67,16 @@ static struct option longopts[] = { // 起動時の処理、VM の実行開始前まで。 // 所々 CLI と GUI で処理が違う。 -bool +// 戻り値は以下のいずれか。 +// MainApp::PASS .. 実行を継続(通常パス) +// EXIT_SUCCESS / EXIT_FAILURE .. この終了コードでアプリケーションを終了 +int MainApp::Init(bool is_cli_, int ac, char *av[]) { is_cli = is_cli_; if (!ParseOpt(ac, av)) { - return false; + return EXIT_FAILURE; } // ログ機構は引数処理後なるはや @@ -84,17 +87,17 @@ 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 false; + return EXIT_FAILURE; } if (gConfig->Update(file) == false) { - return false; + return EXIT_FAILURE; } // 最後にコマンドライン引数で更新 if (gConfig->Update(config_options) == false) { - return false; + return EXIT_FAILURE; } // VM 種別を決定 @@ -118,7 +121,7 @@ MainApp::Init(bool is_cli_, int ac, char // ユーザ由来の時 item.Err("invalid vmtype"); } - return false; + return EXIT_FAILURE; } } @@ -129,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: @@ -144,25 +147,27 @@ MainApp::Init(bool is_cli_, int ac, char __unreachable(); } - // 設定内容表示 - // (MPU コンストラクタでクロック数の初期値を決めるため、その後で表示) + // 動的なコンストラクション + if (!gVM->Create()) { + return EXIT_FAILURE; + } + + // 設定内容を表示して終了 + // (VM コンストラクタで変数の増減があるのでそれより後、 + // Create() でも SCSI パラメータを減らすので、それより後) gConfig->Fix(); if (show_config) { gConfig->Show(show_config - 1); - } - - // 動的なコンストラクション - if (!gVM->Create()) { - return false; + return EXIT_SUCCESS; } // ログレベルを設定。コンストラクト後すぐに行う。 // -L help もここで処理。 if (!ParseLogopt()) { - return false; + return EXIT_FAILURE; } - return true; + return PASS; } // VM の実行部分。 @@ -196,12 +201,14 @@ MainApp::Start() bool MainApp::ParseOpt(int ac, char *av[]) { + struct stat st; + const char *cpath; int b; int c; - uint32 u; 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) { @@ -211,8 +218,7 @@ MainApp::ParseOpt(int ac, char *av[]) break; case 'b': - u = (uint32)strtoul(optarg, NULL, 16); - debug_breakaddr.push_back(u); + debug_breakaddr.push_back(optarg); break; case 'B': @@ -225,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': @@ -317,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 つけても黙って起動するのはさすがにどうかと思う。 @@ -436,7 +467,7 @@ MainApp::ParseLogopt() printf("invalid logname '%s'\n", name); goto abort; } - } + } } rv = true;