fix: review fixes + feat: imports, assertions, merge engine, per-package overrides
Review fixes (8 blocking issues):
- Extract ParseError to shared error.hpp (ODR fix)
- Remove dead package.cpp/package.hpp + tomlplusplus dep
- Safe parse_int() helper replacing crash-prone std::stoi
- consume_string() now accepts bare numbers and idents
- line_at() fixed for post-EOF line numbers
- Subcommand validation before file read in CLI
- KwService/KwAssert/KwImport added to consume_ident()
- root partition promoted to first-class BootBlock field
New features:
- Imports: imports = [...] with recursive merge resolution
- Assertions: assert { "msg" : field op value } in both parsers
- Merge engine: resolve_package() with features/config merge + force support
- Per-package overrides: /kappa/system/builds/<name>.kap
- .gitignore: added vcpkg_installed/ and kappa binary
This commit is contained in:
+22
-13
@@ -48,24 +48,25 @@ static std::string read_file(const char* path) {
|
||||
static void handle_parse_error(const char* path,
|
||||
std::string_view source,
|
||||
const std::runtime_error& e) {
|
||||
// ParseError format: "line:col: message"
|
||||
auto msg = std::string_view(e.what());
|
||||
auto first_colon = msg.find(':');
|
||||
auto second_colon = msg.find(':', first_colon + 1);
|
||||
|
||||
if (first_colon != std::string_view::npos &&
|
||||
second_colon != std::string_view::npos) {
|
||||
int line = std::stoi(std::string(msg.substr(0, first_colon)));
|
||||
int col = std::stoi(std::string(
|
||||
msg.substr(first_colon + 1, second_colon - first_colon - 1)));
|
||||
auto message = msg.substr(second_colon + 2); // skip ": "
|
||||
try {
|
||||
int line = std::stoi(std::string(msg.substr(0, first_colon)));
|
||||
int col = std::stoi(std::string(
|
||||
msg.substr(first_colon + 1, second_colon - first_colon - 1)));
|
||||
auto message = msg.substr(second_colon + 2);
|
||||
|
||||
cli::print_error(std::cerr, source,
|
||||
{path, line, col}, message,
|
||||
"check the syntax at this location");
|
||||
} else {
|
||||
std::cerr << "error: " << e.what() << '\n';
|
||||
cli::print_error(std::cerr, source,
|
||||
{path, line, col}, message,
|
||||
"check the syntax at this location");
|
||||
return;
|
||||
} catch (const std::exception&) {}
|
||||
}
|
||||
std::cerr << "error: " << e.what() << '\n';
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
@@ -86,6 +87,16 @@ int main(int argc, char* argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool valid_subcommand = (subcommand == "parse-package")
|
||||
|| (subcommand == "parse-config")
|
||||
|| (subcommand == "validate");
|
||||
|
||||
if (!valid_subcommand) {
|
||||
std::cerr << "error: unknown subcommand '" << subcommand << "'\n\n";
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Find the file argument (skip flags)
|
||||
const char* file_arg = nullptr;
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
@@ -145,7 +156,5 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "error: unknown subcommand '" << subcommand << "'\n\n";
|
||||
print_usage();
|
||||
return 1;
|
||||
return 1; // unreachable
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user