diff --git a/include/fxos/project.h b/include/fxos/project.h index f00f56d..6e4036a 100644 --- a/include/fxos/project.h +++ b/include/fxos/project.h @@ -59,6 +59,8 @@ struct Project /* Get a binary by name. */ Binary *getBinary(std::string const &name); Binary const *getBinary(std::string const &name) const; + /* Rename a binary. */ + void renameBinary(std::string const &old_name, std::string const &new_name); /* List of all binaries. */ std::map const &binaries() const { diff --git a/lib/project.cpp b/lib/project.cpp index 42389ed..bc0431e 100644 --- a/lib/project.cpp +++ b/lib/project.cpp @@ -81,6 +81,19 @@ Binary const *Project::getBinary(std::string const &name) const return (it == m_binaries.end()) ? nullptr : &it->second; } +void Project::renameBinary( + std::string const &old_name, std::string const &new_name) +{ + if(!m_binaries.count(old_name)) + return; + + auto node = m_binaries.extract(old_name); + node.key() = new_name; + m_binaries.insert(std::move(node)); + + setDirty(); +} + void Project::removeBinary(std::string const &name) { if(m_binaries.erase(name)) diff --git a/shell/b.cpp b/shell/b.cpp index 9f33a33..5e7a9f8 100644 --- a/shell/b.cpp +++ b/shell/b.cpp @@ -16,42 +16,76 @@ using namespace FxOS; // bs //--- -static std::string parse_bs(Session &, Parser &parser) +struct _bs_args { - std::string name = parser.symbol("binary_name"); + bool make_new = false; + bool rename = false; + bool remove = false; + std::string name; +}; + +static struct _bs_args parse_bs(Session &, Parser &parser) +{ + struct _bs_args args; + parser.option("-n", [&args](Parser &) { args.make_new = true; }); + parser.option("-r", [&args](Parser &) { args.rename = true; }); + parser.option("--remove", [&args](Parser &) { args.remove = true; }); + parser.accept_options(); + + if(args.make_new + args.rename + args.remove > 1) + throw CommandError("bs: can only specify one of -n, -r, --remove"); + + args.name = parser.symbol("binary_name"); parser.end(); - return name; + return args; } -void _bs(Session &session, std::string const &name) +void _bs(Session &session, struct _bs_args const &args) { - Binary *b = session.project().getBinary(name); - if(!b) { - FxOS_log(ERR, "No binary “%s” in current project", name.c_str()); + /* Name checks */ + Binary *b = session.project().getBinary(args.name); + if((args.make_new || args.rename) && b) { + FxOS_log(ERR, "There is already a binary “%s” in the project", + args.name.c_str()); + return; + } + if((args.remove || (!args.make_new && !args.rename)) && !b) { + FxOS_log(ERR, "No binary “%s” in current project", args.name.c_str()); + return; + } + if(args.rename && !session.currentBinary()) { + FxOS_log(ERR, "No current binary!"); return; } - session.selectBinary(name); -} -//--- -// bc -//--- + if(args.make_new) { + /* Create an empty binary and select it */ + std::string name = session.project().createBinary(args.name); + fmt::print("Selecting new binary “{}”\n", name); + session.selectBinary(name); + } + else if(args.rename) { + fmt::print("Renaming binary “{}” into “{}”\n", + session.currentBinaryName(), args.name); -static std::string parse_bc(Session &, Parser &parser) -{ - std::string name = ""; - if(!parser.at_end()) - name = parser.symbol(); - parser.end(); - return name; -} + session.project().renameBinary(session.currentBinaryName(), args.name); + session.selectBinary(args.name); + } + else if(args.remove) { + Project &p = session.project(); + fmt::print("Removing binary “{}”.\n", args.name); + p.removeBinary(args.name); -void _bc(Session &session, std::string name) -{ - /* Create an empty binary and select it */ - name = session.project().createBinary(name); - fmt::print("Selecting a new binary “{}”\n", name); - session.selectBinary(name); + /* Select another binary if the current one is gone */ + if(session.currentBinaryName() == args.name) { + auto const &binaries = p.binaries(); + session.selectBinary( + binaries.size() ? binaries.begin()->first : ""); + } + } + else { + session.selectBinary(args.name); + } } //--- @@ -93,55 +127,23 @@ void _bm(Session &session, std::string file, std::vector regions) session.project().setDirty(); } -//--- -// brm -//--- - -static std::string parse_brm(Session &, Parser &parser) -{ - std::string name = parser.symbol("binary_name"); - parser.end(); - return name; -} - -void _brm(Session &session, std::string name) -{ - Project &p = session.project(); - Binary *b = p.getBinary(name); - if(!b) { - FxOS_log(ERR, "No binary “%s” in project!", name.c_str()); - return; - } - - fmt::print("Removing binary “{}”.\n", name); - p.removeBinary(name); - - /* Select another binary if the current one is gone */ - if(session.currentBinaryName() == name) { - auto const &binaries = p.binaries(); - session.selectBinary(binaries.size() ? binaries.begin()->first : ""); - } -} - //--- // Command registration //--- static ShellCommand _bs_cmd( "bs", [](Session &s, Parser &p) { _bs(s, parse_bs(s, p)); }, - [](Session &s, Parser &p) { parse_bs(s, p); }, "Binary Select", R"( -bs + [](Session &s, Parser &p) { parse_bs(s, p); }, + "Binary Select, new, rename or remove", R"( +bs [-n | -r] +bs --remove -Selects the specified binary from the current project. -)"); +Selects the specified binary from the current project. With -n, creates a new +binary and selects it. With -r, renames the currently-selected binary. -static ShellCommand _bc_cmd( - "bc", [](Session &s, Parser &p) { _bc(s, parse_bc(s, p)); }, - [](Session &s, Parser &p) { parse_bc(s, p); }, "Binary Create", R"( -bc [] - -Creates a new binary in the current project and selects it. If the name -collides, a suffix like "_0" will be added. +With --remove, delete the specified binary from the project. +WARNING: There is no undo (yet). If you mistakenly remove a binary, do not save +the project. Backup the project folder and exit fxos without saving. )"); static ShellCommand _bm_cmd( @@ -161,14 +163,3 @@ the size of the requested region. bm "/os/fx/3.10/3.10.bin" ROM ROM_P2 Maps a binary file 3.10.bin to ROM, through both P1 and P2. )"); - -static ShellCommand _brm_cmd( - "brm", [](Session &s, Parser &p) { _brm(s, parse_brm(s, p)); }, - [](Session &s, Parser &p) { parse_brm(s, p); }, "Binary Remove", R"( -brm - -Removes the specified binary from the current project. - -WARNING: There is no undo (yet). If you mistakenly delete a binary, do not save -the project. Backup the project folder and exit fxos without saving. -)"); diff --git a/shell/lexer.l b/shell/lexer.l index 31b6957..aefe309 100644 --- a/shell/lexer.l +++ b/shell/lexer.l @@ -148,7 +148,7 @@ num_suffix [kMG] num ({num_hex}|{num_dec}|{num_bin}){num_suffix}? syscall [%][a-fA-F0-9]+ -option -[a-zA-Z] +option (-[a-zA-Z]|--[a-zA-Z-]+) symbol \.|\.?[a-zA-Z_][a-zA-Z0-9_.]* space [ \t]+