166 lines
4.5 KiB
C++
166 lines
4.5 KiB
C++
#include "shell.h"
|
|
#include "theme.h"
|
|
#include "parser.h"
|
|
#include "commands.h"
|
|
#include "errors.h"
|
|
|
|
#include <fmt/core.h>
|
|
#include <fmt/color.h>
|
|
|
|
#include <fxos/memory.h>
|
|
#include <fxos/util/log.h>
|
|
|
|
using namespace FxOS;
|
|
|
|
//---
|
|
// bs
|
|
//---
|
|
|
|
struct _bs_args
|
|
{
|
|
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 args;
|
|
}
|
|
|
|
void _bs(Session &session, struct _bs_args const &args)
|
|
{
|
|
/* 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;
|
|
}
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
/* 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);
|
|
}
|
|
}
|
|
|
|
//---
|
|
// bm
|
|
//---
|
|
|
|
struct _bm_args
|
|
{
|
|
std::string path;
|
|
std::vector<MemoryRegion> regions;
|
|
};
|
|
|
|
static _bm_args parse_bm(Session &session, Parser &parser)
|
|
{
|
|
_bm_args args {};
|
|
args.path = parser.str();
|
|
|
|
/* TODO: bm: Allow specifying address without a size */
|
|
do
|
|
args.regions.push_back(parser.region(session.currentBinary()));
|
|
while(!parser.at_end());
|
|
|
|
parser.end();
|
|
return args;
|
|
}
|
|
|
|
void _bm(Session &session, std::string file, std::vector<MemoryRegion> regions)
|
|
{
|
|
Binary *b = session.currentBinary();
|
|
if(!b) {
|
|
FxOS_log(ERR, "No current binary");
|
|
return;
|
|
}
|
|
|
|
Buffer contents(file);
|
|
for(auto &r: regions)
|
|
b->vspace().bind_region(r, contents);
|
|
|
|
session.project().setDirty();
|
|
}
|
|
|
|
//---
|
|
// 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, new, rename or remove", R"(
|
|
bs [-n | -r] <binary>
|
|
bs --remove <binary>
|
|
|
|
Selects the specified binary from the current project. With -n, creates a new
|
|
binary and selects it. With -r, renames the currently-selected binary.
|
|
|
|
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(
|
|
"bm",
|
|
[](Session &s, Parser &p) {
|
|
auto const &args = parse_bm(s, p);
|
|
_bm(s, args.path, args.regions);
|
|
},
|
|
[](Session &s, Parser &p) { parse_bm(s, p); }, "Binary Map file", R"(
|
|
bm "<file>" <region>...
|
|
|
|
Maps the named file into all the specified regions of the current binary. If
|
|
the file is smaller than the region, it is zero-padded; if the region is
|
|
smaller, the extra data is ignored. The amount of data mapped is always exactly
|
|
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.
|
|
)");
|