/// Parse all command line entries and find valid options. bool get_opt(unsigned int argc_, char **argv_, CLoption *options, unsigned int num_valid_opt_, void (*help_)()/*=dummy_help*/){ unsigned int index = 1; unsigned int previous_opt = 0; bool need_an_argument = false; bool may_have_argument = false; bool is_valid_argument = false; while(index < argc_){ if(argv_[index][0] == '-'){ if(need_an_argument){ std::cout << "\n Error: --" << options[previous_opt].alias << " [-" << options[previous_opt].opt << "] requires an argument\n"; help_(); return false; } is_valid_argument = false; if(argv_[index][1] == '-'){ // Word options std::string word_arg = csubstr(argv_[index], 2); for(unsigned int i = 0; i < num_valid_opt_; i++){ if(word_arg == options[i].alias && word_arg != "NULL"){ options[i].is_active = true; previous_opt = i; if(options[i].require_arg){ need_an_argument = true; } else{ need_an_argument = false; } if(options[i].optional_arg){ may_have_argument = true; } else{ may_have_argument = false; } is_valid_argument = true; } } if(!is_valid_argument){ std::cout << "\n Error: encountered unknown option --" << word_arg << std::endl; help_(); return false; } } else{ // Character options unsigned int index2 = 1; while(argv_[index][index2] != '\0'){ for(unsigned int i = 0; i < num_valid_opt_; i++){ if(argv_[index][index2] == options[i].opt && argv_[index][index2] != 0x0){ options[i].is_active = true; previous_opt = i; if(options[i].require_arg){ need_an_argument = true; } else{ need_an_argument = false; } if(options[i].optional_arg){ may_have_argument = true; } else{ may_have_argument = false; } is_valid_argument = true; break; //We only mark the first match as active. } } if(!is_valid_argument){ std::cout << "\n Error: encountered unknown option -" << argv_[index][index2] << std::endl; help_(); return false; } index2++; } } } else{ // An option argument if(need_an_argument || may_have_argument){ options[previous_opt].value = csubstr(argv_[index]); need_an_argument = false; may_have_argument = false; } else{ std::cout << "\n Error: --" << options[previous_opt].alias << " [-" << options[previous_opt].opt << "] takes no argument\n"; help_(); return false; } } // Check for the case where the end option requires an argument, but did not receive it if(index == argc_-1 && need_an_argument){ std::cout << "\n Error: --" << options[previous_opt].alias << " [-" << options[previous_opt].opt << "] requires an argument\n"; help_(); return false; } index++; } return true; }
int main(int argc, char* argv[]) { if(argc == 1) { help_(argv[0]); return 0; } options opts; // 設定ファイルの読み込み std::string conf_path; if(utils::probe_file(conf_file_)) { // カレントにあるか? conf_path = conf_file_; } else { // コマンド、カレントから読んでみる conf_path = get_current_path_(argv[0]) + '/' + conf_file_; } if(conf_in_.load(conf_path)) { auto defa = conf_in_.get_default(); opts.device = defa.device_; #ifdef __CYGWIN__ opts.platform = "Cygwin"; opts.com_path = defa.port_win_; opts.com_speed = defa.speed_win_; #endif #ifdef __APPLE__ opts.platform = "OS-X"; opts.com_path = defa.port_osx_; opts.com_speed = defa.speed_osx_; #endif #ifdef __linux__ opts.platform = "Linux"; opts.com_path = defa.port_linux_; opts.com_speed = defa.speed_linux_; #endif if(opts.com_path.empty()) { opts.com_path = defa.port_; } if(opts.com_speed.empty()) { opts.com_speed = defa.speed_; } opts.id_val = defa.id_; } else { std::cerr << "Configuration file can't load: '" << conf_path << '\'' << std::endl; return -1; } // コマンドラインの解析 bool opterr = false; for(int i = 1; i < argc; ++i) { const std::string p = argv[i]; if(p[0] == '-') { if(p == "--verbose") opts.verbose = true; else if(p == "-s") opts.br = true; else if(p.find("--speed=") == 0) { opts.com_speed = &p[std::strlen("--speed=")]; } else if(p == "-d") opts.dv = true; else if(p.find("--device=") == 0) { opts.device = &p[std::strlen("--device=")]; } else if(p == "-P") opts.dp = true; else if(p.find("--port=") == 0) { opts.com_path = &p[std::strlen("--port=")]; /// } else if(p == "-a") { /// opts.area = true; /// } else if(p.find("--area=") == 0) { /// if(!opts.set_area_(&p[7])) { /// opterr = true; /// } // } else if(p == "-r" || p == "--read") { // opts.read = true; // } else if(p == "-i") { // opts.id = true; // } else if(p.find("--id=") == 0) { // opts.id_val = &p[std::strlen("--id=")]; } else if(p == "-w" || p == "--write") { opts.write = true; } else if(p == "-v" || p == "--verify") { opts.verify = true; } else if(p == "--progress") { opts.progress = true; } else if(p == "--device-list") { opts.device_list = true; } else if(p == "-e" || p == "--erase") { opts.erase = true; /// } else if(p == "--erase-rom") opts.erase_rom = true; /// } else if(p == "--erase-data") opts.erase_data = true; /// } else if(p == "--erase-all" || p == "--erase-chip") { // opts.erase_rom = true; // opts.erase_data = true; } else if(p == "-h" || p == "--help") { opts.help = true; } else { opterr = true; } } else { if(!opts.set_str(p)) { opterr = true; } } if(opterr) { std::cerr << "Option error: '" << p << "'" << std::endl; opts.help = true; } } if(opts.verbose) { std::cout << "# Platform: '" << opts.platform << '\'' << std::endl; std::cout << "# Configuration file path: '" << conf_path << '\'' << std::endl; std::cout << "# Device: '" << opts.device << '\'' << std::endl; std::cout << "# Serial port path: '" << opts.com_path << '\'' << std::endl; std::cout << "# Serial port speed: " << opts.com_speed << std::endl; } // HELP 表示 if(opts.help || opts.com_path.empty() || (opts.inp_file.empty() && !opts.device_list) /// && opts.sequrity_set.empty() && !opts.sequrity_get && !opts.sequrity_release) || opts.com_speed.empty() || opts.device.empty()) { if(opts.device.empty()) { std::cout << "Device name null." << std::endl; } if(opts.com_speed.empty()) { std::cout << "Serial speed none." << std::endl; } help_(argv[0]); return 0; } // デバイス・リスト表示 if(opts.device_list) { for(const auto& s : conf_in_.get_device_list()) { std::cout << s << std::endl; } } // 入力ファイルの読み込み uint32_t pageall = 0; if(!opts.inp_file.empty()) { if(opts.verbose) { std::cout << "# Input file path: '" << opts.inp_file << '\'' << std::endl; } if(!motsx_.load(opts.inp_file)) { std::cerr << "Can't open input file: '" << opts.inp_file << "'" << std::endl; return -1; } pageall = motsx_.get_total_page(); if(opts.verbose) { motsx_.list_area_map("# "); } } // Windwos系シリアル・ポート(COMx)の変換 if(!opts.com_path.empty() && opts.com_path[0] != '/') { std::string s = utils::to_lower_text(opts.com_path); if(s.size() > 3 && s[0] == 'c' && s[1] == 'o' && s[2] == 'm') { int val; if(utils::string_to_int(&s[3], val)) { if(val >= 1 ) { --val; opts.com_name = opts.com_path; opts.com_path = "/dev/ttyS" + (boost::format("%d") % val).str(); } } } if(opts.verbose) { std::cout << "# Serial port alias: " << opts.com_name << " ---> " << opts.com_path << std::endl; } } if(opts.com_path.empty()) { std::cerr << "Serial port path not found." << std::endl; return -1; } if(opts.verbose) { std::cout << "# Serial port path: '" << opts.com_path << '\'' << std::endl; } int com_speed = 0; if(!utils::string_to_int(opts.com_speed, com_speed)) { std::cerr << "Serial speed conversion error: '" << opts.com_speed << '\'' << std::endl; return -1; } if(!opts.erase && !opts.write && !opts.verify) return 0; // && opts.sequrity_set.empty() && !opts.sequrity_get && !opts.sequrity_release) return 0; rx::protocol::rx_t rx; { rx.verbose_ = opts.verbose; rx.cpu_type_ = opts.device; if(rx.cpu_type_ == "RX63T") { // rx.master_ = 1200; // 12.00MHz // rx.sys_div_ = 8; // x8 (96MHz) // rx.ext_div_ = 4; // x4 (48MHz) auto devt = conf_in_.get_device(); int32_t val = 0;; if(!utils::string_to_int(devt.clock_, val)) { std::cerr << "RX63T 'clock' tag conversion error: '" << devt.clock_ << '\'' << std::endl; return -1; } rx.master_ = val; if(!utils::string_to_int(devt.divide_sys_, val)) { std::cerr << "RX63T 'divide_sys' tag conversion error: '" << devt.divide_sys_ << '\'' << std::endl; return -1; } rx.sys_div_ = val; if(!utils::string_to_int(devt.divide_ext_, val)) { std::cerr << "RX63T 'divide_ext' tag conversion error: '" << devt.divide_ext_ << '\'' << std::endl; return -1; } rx.ext_div_ = val; } } rx::prog prog_(opts.verbose); if(!prog_.start(opts.com_path, com_speed, rx)) { prog_.end(); return -1; } //===================================== if(opts.erase) { // erase auto areas = motsx_.create_area_map(); if(opts.progress) { std::cout << "Erase: " << std::flush; } page_t page; for(const auto& a : areas) { uint32_t adr = a.min_ & 0xffffff00; uint32_t len = 0; while(len < (a.max_ - a.min_ + 1)) { if(opts.progress) { progress_(pageall, page); } if(!prog_.erase_page(adr)) { // 256 バイト単位で消去要求を送る prog_.end(); return -1; } adr += 256; len += 256; ++page.n; } } if(opts.progress) { std::cout << std::endl << std::flush; } } //===================================== if(opts.write) { // write auto areas = motsx_.create_area_map(); if(!areas.empty()) { if(!prog_.start_write(true)) { prog_.end(); return -1; } } if(opts.progress) { std::cout << "Write: " << std::flush; } page_t page; for(const auto& a : areas) { uint32_t adr = a.min_ & 0xffffff00; uint32_t len = 0; while(len < (a.max_ - a.min_ + 1)) { if(opts.progress) { progress_(pageall, page); } /// std::cout << boost::format("%08X to %08X") % adr % (adr + 255) << std::endl; auto mem = motsx_.get_memory(adr); if(!prog_.write(adr, &mem[0])) { prog_.end(); return -1; } adr += 256; len += 256; ++page.n; } } if(opts.progress) { std::cout << std::endl << std::flush; } if(!prog_.final_write()) { prog_.end(); return -1; } } //===================================== if(opts.verify) { // verify auto areas = motsx_.create_area_map(); if(opts.progress) { std::cout << "Verify: " << std::flush; } page_t page; for(const auto& a : areas) { uint32_t adr = a.min_ & 0xffffff00; uint32_t len = 0; while(len < (a.max_ - a.min_ + 1)) { if(opts.progress) { progress_(pageall, page); } /// std::cout << boost::format("%08X to %08X") % adr % (adr + 255) << std::endl; auto mem = motsx_.get_memory(adr); if(!prog_.verify_page(adr, &mem[0])) { prog_.end(); return -1; } adr += 256; len += 256; ++page.n; } } if(opts.progress) { std::cout << std::endl << std::flush; } } prog_.end(); }
int main(int argc, char* argv[]) { char ch; const char* archivename = NULL; aug_opterr = 0; if (!aug_autotlx()) return 1; AUG_INITLEAKDUMP(); if (atexit(exit_) < 0) { aug_perrinfo(aug_tlx, "atexit() failed", NULL); return 1; } while ((ch = aug_getopt(argc, argv, OPTIONS_)) < 0) switch (ch) { case 'i': case 'p': if (0 == strcmp(aug_optarg, "-")) { if (options_ & STDINOPT_) { fprintf(stderr, "multiple use of stdin"); goto info; } options_ |= STDINOPT_; } options_ |= (CREATEOPT_ | WRITEOPT_); break; case 'f': options_ |= FORCEOPT_; break; case 'h': help_(); return 0; case 'g': case 'l': case 'n': case 't': case 'x': options_ |= READOPT_; break; case 'c': case 'd': case 'o': case 'z': options_ |= WRITEOPT_; break; case '?': default: fprintf(stderr, "unknown option [-%c]", aug_optopt); goto info; } if (aug_optind < (argc - 1)) { fprintf(stderr, "too many arguments"); goto info; } if (aug_optind == argc) { fprintf(stderr, "archive not specified"); goto info; } archivename = argv[aug_optind]; aug_optind = 0; return run_BIN_(argc, argv, archivename) < 0 ? 1 : 0; info: fprintf(stderr, ": try 'mar -h' for more information\n"); return 1; }