fxos/shell/b.cpp

175 lines
4.1 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
//---
static std::string parse_bs(Session &, Parser &parser)
{
std::string name = parser.symbol("binary_name");
parser.end();
return name;
}
void _bs(Session &session, std::string const &name)
{
Binary *b = session.project().getBinary(name);
if(!b) {
FxOS_log(ERR, "No binary “%s” in current project", name.c_str());
return;
}
session.selectBinary(name);
}
//---
// bc
//---
static std::string parse_bc(Session &, Parser &parser)
{
std::string name = "";
if(!parser.at_end())
name = parser.symbol();
parser.end();
return 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);
}
//---
// 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.current_space));
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();
}
//---
// 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 <binary_name>
Selects the specified binary from the current project.
)");
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 [<name>]
Creates a new binary in the current project and selects it. If the name
collides, a suffix like "_0" will be added.
)");
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.
)");
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 <binary_name>
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.
)");