mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Factor out common usage-help code
This commit is contained in:
3
Makefile
3
Makefile
@@ -51,7 +51,8 @@ all: rgbasm rgblink rgbfix rgbgfx
|
|||||||
|
|
||||||
common_obj := \
|
common_obj := \
|
||||||
src/extern/getopt.o \
|
src/extern/getopt.o \
|
||||||
src/diagnostics.o
|
src/diagnostics.o \
|
||||||
|
src/usage.o
|
||||||
|
|
||||||
rgbasm_obj := \
|
rgbasm_obj := \
|
||||||
${common_obj} \
|
${common_obj} \
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
// platform-specific hacks
|
|
||||||
|
|
||||||
#ifndef RGBDS_PLATFORM_HPP
|
#ifndef RGBDS_PLATFORM_HPP
|
||||||
#define RGBDS_PLATFORM_HPP
|
#define RGBDS_PLATFORM_HPP
|
||||||
|
|
||||||
|
|||||||
21
include/usage.hpp
Normal file
21
include/usage.hpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#ifndef RGBDS_USAGE_HPP
|
||||||
|
#define RGBDS_USAGE_HPP
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
class Usage {
|
||||||
|
char const *usage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Usage(char const *usage_) : usage(usage_) {}
|
||||||
|
|
||||||
|
[[noreturn]]
|
||||||
|
void printAndExit(int code) const;
|
||||||
|
|
||||||
|
[[gnu::format(printf, 2, 3), noreturn]]
|
||||||
|
void printAndExit(char const *fmt, ...) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RGBDS_USAGE_HPP
|
||||||
@@ -5,6 +5,7 @@ configure_file(version.cpp _version.cpp ESCAPE_QUOTES)
|
|||||||
set(common_src
|
set(common_src
|
||||||
"extern/getopt.cpp"
|
"extern/getopt.cpp"
|
||||||
"diagnostics.cpp"
|
"diagnostics.cpp"
|
||||||
|
"usage.cpp"
|
||||||
"_version.cpp"
|
"_version.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "extern/getopt.hpp"
|
#include "extern/getopt.hpp"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "parser.hpp" // Generated from parser.y
|
#include "parser.hpp" // Generated from parser.y
|
||||||
|
#include "usage.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
#include "asm/charmap.hpp"
|
#include "asm/charmap.hpp"
|
||||||
@@ -83,41 +84,25 @@ static option const longopts[] = {
|
|||||||
{nullptr, no_argument, nullptr, 0 }
|
{nullptr, no_argument, nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
// LCOV_EXCL_START
|
// clang-format off: long string literal
|
||||||
static void printUsage() {
|
static Usage usage(
|
||||||
fputs(
|
"Usage: rgbasm [-EhVvw] [-b chars] [-D name[=value]] [-g chars] [-I path]\n"
|
||||||
"Usage: rgbasm [-EhVvw] [-b chars] [-D name[=value]] [-g chars] [-I path]\n"
|
" [-M depend_file] [-MC] [-MG] [-MP] [-MT target_file] [-MQ target_file]\n"
|
||||||
" [-M depend_file] [-MC] [-MG] [-MP] [-MT target_file] [-MQ target_file]\n"
|
" [-o out_file] [-P include_file] [-p pad_value] [-Q precision]\n"
|
||||||
" [-o out_file] [-P include_file] [-p pad_value] [-Q precision]\n"
|
" [-r depth] [-s features:state_file] [-W warning] [-X max_errors]\n"
|
||||||
" [-r depth] [-s features:state_file] [-W warning] [-X max_errors]\n"
|
" <file>\n"
|
||||||
" <file>\n"
|
"Useful options:\n"
|
||||||
"Useful options:\n"
|
" -E, --export-all export all labels\n"
|
||||||
" -E, --export-all export all labels\n"
|
" -M, --dependfile <path> set the output dependency file\n"
|
||||||
" -M, --dependfile <path> set the output dependency file\n"
|
" -o, --output <path> set the output object file\n"
|
||||||
" -o, --output <path> set the output object file\n"
|
" -p, --pad-value <value> set the value to use for `ds'\n"
|
||||||
" -p, --pad-value <value> set the value to use for `ds'\n"
|
" -s, --state <features>:<path> set an output state file\n"
|
||||||
" -s, --state <features>:<path> set an output state file\n"
|
" -V, --version print RGBASM version and exit\n"
|
||||||
" -V, --version print RGBASM version and exit\n"
|
" -W, --warning <warning> enable or disable warnings\n"
|
||||||
" -W, --warning <warning> enable or disable warnings\n"
|
"\n"
|
||||||
"\n"
|
"For help, use `man rgbasm' or go to https://rgbds.gbdev.io/docs/\n"
|
||||||
"For help, use `man rgbasm' or go to https://rgbds.gbdev.io/docs/\n",
|
);
|
||||||
stderr
|
// clang-format on
|
||||||
);
|
|
||||||
}
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
|
|
||||||
[[gnu::format(printf, 1, 2), noreturn]]
|
|
||||||
static void fatalWithUsage(char const *fmt, ...) {
|
|
||||||
va_list ap;
|
|
||||||
fputs("FATAL: ", stderr);
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vfprintf(stderr, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
putc('\n', stderr);
|
|
||||||
|
|
||||||
printUsage();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse a comma-separated string of '-s/--state' features
|
// Parse a comma-separated string of '-s/--state' features
|
||||||
static std::vector<StateFeature> parseStateFeatures(char *str) {
|
static std::vector<StateFeature> parseStateFeatures(char *str) {
|
||||||
@@ -218,10 +203,7 @@ int main(int argc, char *argv[]) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
// LCOV_EXCL_START
|
usage.printAndExit(0); // LCOV_EXCL_LINE
|
||||||
printUsage();
|
|
||||||
exit(0);
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
|
|
||||||
case 'I':
|
case 'I':
|
||||||
fstk_AddIncludePath(musl_optarg);
|
fstk_AddIncludePath(musl_optarg);
|
||||||
@@ -382,10 +364,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
// Unrecognized options
|
// Unrecognized options
|
||||||
default:
|
default:
|
||||||
// LCOV_EXCL_START
|
usage.printAndExit(1); // LCOV_EXCL_LINE
|
||||||
printUsage();
|
|
||||||
exit(1);
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,9 +373,9 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (argc == musl_optind) {
|
if (argc == musl_optind) {
|
||||||
fatalWithUsage("Please specify an input file (pass `-` to read from standard input)");
|
usage.printAndExit("Please specify an input file (pass `-` to read from standard input)");
|
||||||
} else if (argc != musl_optind + 1) {
|
} else if (argc != musl_optind + 1) {
|
||||||
fatalWithUsage("More than one input file specified");
|
usage.printAndExit("More than one input file specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string mainFileName = argv[musl_optind];
|
std::string mainFileName = argv[musl_optind];
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "extern/getopt.hpp"
|
#include "extern/getopt.hpp"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
|
#include "usage.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
#include "fix/mbc.hpp"
|
#include "fix/mbc.hpp"
|
||||||
@@ -57,40 +58,24 @@ static option const longopts[] = {
|
|||||||
{nullptr, no_argument, nullptr, 0 }
|
{nullptr, no_argument, nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
// LCOV_EXCL_START
|
// clang-format off: long string literal
|
||||||
static void printUsage() {
|
static Usage usage(
|
||||||
fputs(
|
"Usage: rgbfix [-hjOsVvw] [-C | -c] [-f <fix_spec>] [-i <game_id>] [-k <licensee>]\n"
|
||||||
"Usage: rgbfix [-hjOsVvw] [-C | -c] [-f <fix_spec>] [-i <game_id>] [-k <licensee>]\n"
|
" [-L <logo_file>] [-l <licensee_byte>] [-m <mbc_type>]\n"
|
||||||
" [-L <logo_file>] [-l <licensee_byte>] [-m <mbc_type>]\n"
|
" [-n <rom_version>] [-p <pad_value>] [-r <ram_size>] [-t <title_str>]\n"
|
||||||
" [-n <rom_version>] [-p <pad_value>] [-r <ram_size>] [-t <title_str>]\n"
|
" [-W warning] <file> ...\n"
|
||||||
" [-W warning] <file> ...\n"
|
"Useful options:\n"
|
||||||
"Useful options:\n"
|
" -m, --mbc-type <value> set the MBC type byte to this value; refer\n"
|
||||||
" -m, --mbc-type <value> set the MBC type byte to this value; refer\n"
|
" to the man page for a list of values\n"
|
||||||
" to the man page for a list of values\n"
|
" -p, --pad-value <value> pad to the next valid size using this value\n"
|
||||||
" -p, --pad-value <value> pad to the next valid size using this value\n"
|
" -r, --ram-size <code> set the cart RAM size byte to this value\n"
|
||||||
" -r, --ram-size <code> set the cart RAM size byte to this value\n"
|
" -o, --output <path> set the output file\n"
|
||||||
" -o, --output <path> set the output file\n"
|
" -V, --version print RGBFIX version and exit\n"
|
||||||
" -V, --version print RGBFIX version and exit\n"
|
" -v, --validate fix the header logo and both checksums (-f lhg)\n"
|
||||||
" -v, --validate fix the header logo and both checksums (-f lhg)\n"
|
"\n"
|
||||||
"\n"
|
"For help, use `man rgbfix' or go to https://rgbds.gbdev.io/docs/\n"
|
||||||
"For help, use `man rgbfix' or go to https://rgbds.gbdev.io/docs/\n",
|
);
|
||||||
stderr
|
// clang-format on
|
||||||
);
|
|
||||||
}
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
|
|
||||||
[[gnu::format(printf, 1, 2), noreturn]]
|
|
||||||
static void fatalWithUsage(char const *fmt, ...) {
|
|
||||||
va_list ap;
|
|
||||||
fputs("FATAL: ", stderr);
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vfprintf(stderr, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
putc('\n', stderr);
|
|
||||||
|
|
||||||
printUsage();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t tpp1Rev[2];
|
static uint8_t tpp1Rev[2];
|
||||||
|
|
||||||
@@ -727,10 +712,7 @@ int main(int argc, char *argv[]) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
// LCOV_EXCL_START
|
usage.printAndExit(0); // LCOV_EXCL_LINE
|
||||||
printUsage();
|
|
||||||
exit(0);
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
gameID = musl_optarg;
|
gameID = musl_optarg;
|
||||||
@@ -835,10 +817,7 @@ int main(int argc, char *argv[]) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// LCOV_EXCL_START
|
usage.printAndExit(1); // LCOV_EXCL_LINE
|
||||||
printUsage();
|
|
||||||
exit(1);
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -894,11 +873,11 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
argv += musl_optind;
|
argv += musl_optind;
|
||||||
if (!*argv) {
|
if (!*argv) {
|
||||||
fatalWithUsage("Please specify an input file (pass `-` to read from standard input)");
|
usage.printAndExit("Please specify an input file (pass `-` to read from standard input)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outputFilename && argc != musl_optind + 1) {
|
if (outputFilename && argc != musl_optind + 1) {
|
||||||
fatalWithUsage("If `-o` is set then only a single input file may be specified");
|
usage.printAndExit("If `-o` is set then only a single input file may be specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool failed = warnings.nbErrors > 0;
|
bool failed = warnings.nbErrors > 0;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "extern/getopt.hpp"
|
#include "extern/getopt.hpp"
|
||||||
#include "file.hpp"
|
#include "file.hpp"
|
||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
|
#include "usage.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
#include "gfx/pal_spec.hpp"
|
#include "gfx/pal_spec.hpp"
|
||||||
@@ -98,39 +99,23 @@ static option const longopts[] = {
|
|||||||
{nullptr, no_argument, nullptr, 0 }
|
{nullptr, no_argument, nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
// LCOV_EXCL_START
|
// clang-format off: long string literal
|
||||||
static void printUsage() {
|
static Usage usage(
|
||||||
fputs(
|
"Usage: rgbgfx [-r stride] [-ChmOuVXYZ] [-v [-v ...]] [-a <attr_map> | -A]\n"
|
||||||
"Usage: rgbgfx [-r stride] [-ChmOuVXYZ] [-v [-v ...]] [-a <attr_map> | -A]\n"
|
" [-b <base_ids>] [-c <colors>] [-d <depth>] [-i <tileset_file>]\n"
|
||||||
" [-b <base_ids>] [-c <colors>] [-d <depth>] [-i <tileset_file>]\n"
|
" [-L <slice>] [-l <base_pal>] [-N <nb_tiles>] [-n <nb_pals>]\n"
|
||||||
" [-L <slice>] [-l <base_pal>] [-N <nb_tiles>] [-n <nb_pals>]\n"
|
" [-o <out_file>] [-p <pal_file> | -P] [-q <pal_map> | -Q]\n"
|
||||||
" [-o <out_file>] [-p <pal_file> | -P] [-q <pal_map> | -Q]\n"
|
" [-s <nb_colors>] [-t <tile_map> | -T] [-x <nb_tiles>] <file>\n"
|
||||||
" [-s <nb_colors>] [-t <tile_map> | -T] [-x <nb_tiles>] <file>\n"
|
"Useful options:\n"
|
||||||
"Useful options:\n"
|
" -m, --mirror-tiles optimize out mirrored tiles\n"
|
||||||
" -m, --mirror-tiles optimize out mirrored tiles\n"
|
" -o, --output <path> output the tile data to this path\n"
|
||||||
" -o, --output <path> output the tile data to this path\n"
|
" -t, --tilemap <path> output the tile map to this path\n"
|
||||||
" -t, --tilemap <path> output the tile map to this path\n"
|
" -u, --unique-tiles optimize out identical tiles\n"
|
||||||
" -u, --unique-tiles optimize out identical tiles\n"
|
" -V, --version print RGBGFX version and exit\n"
|
||||||
" -V, --version print RGBGFX version and exit\n"
|
"\n"
|
||||||
"\n"
|
"For help, use `man rgbgfx' or go to https://rgbds.gbdev.io/docs/\n"
|
||||||
"For help, use `man rgbgfx' or go to https://rgbds.gbdev.io/docs/\n",
|
);
|
||||||
stderr
|
// clang-format on
|
||||||
);
|
|
||||||
}
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
|
|
||||||
[[gnu::format(printf, 1, 2), noreturn]]
|
|
||||||
static void fatalWithUsage(char const *fmt, ...) {
|
|
||||||
va_list ap;
|
|
||||||
fputs("FATAL: ", stderr);
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vfprintf(stderr, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
putc('\n', stderr);
|
|
||||||
|
|
||||||
printUsage();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parses a number at the beginning of a string, moving the pointer to skip the parsed characters.
|
// Parses a number at the beginning of a string, moving the pointer to skip the parsed characters.
|
||||||
// Returns the provided errVal on error.
|
// Returns the provided errVal on error.
|
||||||
@@ -209,13 +194,13 @@ static void skipWhitespace(char *&arg) {
|
|||||||
|
|
||||||
static void registerInput(char const *arg) {
|
static void registerInput(char const *arg) {
|
||||||
if (!options.input.empty()) {
|
if (!options.input.empty()) {
|
||||||
fatalWithUsage(
|
usage.printAndExit(
|
||||||
"Input image specified more than once! (first \"%s\", then \"%s\")",
|
"Input image specified more than once! (first \"%s\", then \"%s\")",
|
||||||
options.input.c_str(),
|
options.input.c_str(),
|
||||||
arg
|
arg
|
||||||
);
|
);
|
||||||
} else if (arg[0] == '\0') { // Empty input path
|
} else if (arg[0] == '\0') { // Empty input path
|
||||||
fatalWithUsage("Input image path cannot be empty");
|
usage.printAndExit("Input image path cannot be empty");
|
||||||
} else {
|
} else {
|
||||||
options.input = arg;
|
options.input = arg;
|
||||||
}
|
}
|
||||||
@@ -379,10 +364,7 @@ static char *parseArgv(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
// LCOV_EXCL_START
|
usage.printAndExit(0); // LCOV_EXCL_LINE
|
||||||
printUsage();
|
|
||||||
exit(0);
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
case 'i':
|
case 'i':
|
||||||
if (!options.inputTileset.empty()) {
|
if (!options.inputTileset.empty()) {
|
||||||
warnx("Overriding input tileset file %s", options.inputTileset.c_str());
|
warnx("Overriding input tileset file %s", options.inputTileset.c_str());
|
||||||
@@ -591,10 +573,7 @@ static char *parseArgv(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// LCOV_EXCL_START
|
usage.printAndExit(1); // LCOV_EXCL_LINE
|
||||||
printUsage();
|
|
||||||
exit(1);
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -818,7 +797,7 @@ int main(int argc, char *argv[]) {
|
|||||||
if (autoOptEnabled) {
|
if (autoOptEnabled) {
|
||||||
std::string &image = localOptions.groupOutputs ? options.output : options.input;
|
std::string &image = localOptions.groupOutputs ? options.output : options.input;
|
||||||
if (image.empty()) {
|
if (image.empty()) {
|
||||||
fatalWithUsage(
|
usage.printAndExit(
|
||||||
"No %s specified",
|
"No %s specified",
|
||||||
localOptions.groupOutputs ? "output tile data file" : "input image"
|
localOptions.groupOutputs ? "output tile data file" : "input image"
|
||||||
);
|
);
|
||||||
@@ -875,7 +854,7 @@ int main(int argc, char *argv[]) {
|
|||||||
&& !localOptions.reverse) {
|
&& !localOptions.reverse) {
|
||||||
processPalettes();
|
processPalettes();
|
||||||
} else {
|
} else {
|
||||||
fatalWithUsage("No input image specified");
|
usage.printAndExit("No input image specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
requireZeroErrors();
|
requireZeroErrors();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "itertools.hpp"
|
#include "itertools.hpp"
|
||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
#include "script.hpp" // Generated from script.y
|
#include "script.hpp" // Generated from script.y
|
||||||
|
#include "usage.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
#include "link/assign.hpp"
|
#include "link/assign.hpp"
|
||||||
@@ -81,39 +82,23 @@ static option const longopts[] = {
|
|||||||
{nullptr, no_argument, nullptr, 0 }
|
{nullptr, no_argument, nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
// LCOV_EXCL_START
|
// clang-format off: long string literal
|
||||||
static void printUsage() {
|
static Usage usage(
|
||||||
fputs(
|
"Usage: rgblink [-dhMtVvwx] [-l script] [-m map_file] [-n sym_file]\n"
|
||||||
"Usage: rgblink [-dhMtVvwx] [-l script] [-m map_file] [-n sym_file]\n"
|
" [-O overlay_file] [-o out_file] [-p pad_value]\n"
|
||||||
" [-O overlay_file] [-o out_file] [-p pad_value]\n"
|
" [-S spec] <file> ...\n"
|
||||||
" [-S spec] <file> ...\n"
|
"Useful options:\n"
|
||||||
"Useful options:\n"
|
" -l, --linkerscript <path> set the input linker script\n"
|
||||||
" -l, --linkerscript <path> set the input linker script\n"
|
" -m, --map <path> set the output map file\n"
|
||||||
" -m, --map <path> set the output map file\n"
|
" -n, --sym <path> set the output symbol list file\n"
|
||||||
" -n, --sym <path> set the output symbol list file\n"
|
" -o, --output <path> set the output file\n"
|
||||||
" -o, --output <path> set the output file\n"
|
" -p, --pad <value> set the value to pad between sections with\n"
|
||||||
" -p, --pad <value> set the value to pad between sections with\n"
|
" -x, --nopad disable padding of output binary\n"
|
||||||
" -x, --nopad disable padding of output binary\n"
|
" -V, --version print RGBLINK version and exits\n"
|
||||||
" -V, --version print RGBLINK version and exits\n"
|
"\n"
|
||||||
"\n"
|
"For help, use `man rgblink' or go to https://rgbds.gbdev.io/docs/\n"
|
||||||
"For help, use `man rgblink' or go to https://rgbds.gbdev.io/docs/\n",
|
);
|
||||||
stderr
|
// clang-format on
|
||||||
);
|
|
||||||
}
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
|
|
||||||
[[gnu::format(printf, 1, 2), noreturn]]
|
|
||||||
static void fatalWithUsage(char const *fmt, ...) {
|
|
||||||
va_list ap;
|
|
||||||
fputs("FATAL: ", stderr);
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vfprintf(stderr, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
putc('\n', stderr);
|
|
||||||
|
|
||||||
printUsage();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ScrambledRegion {
|
enum ScrambledRegion {
|
||||||
SCRAMBLE_ROMX,
|
SCRAMBLE_ROMX,
|
||||||
@@ -268,10 +253,7 @@ int main(int argc, char *argv[]) {
|
|||||||
options.isWRAM0Mode = true;
|
options.isWRAM0Mode = true;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
// LCOV_EXCL_START
|
usage.printAndExit(0); // LCOV_EXCL_LINE
|
||||||
printUsage();
|
|
||||||
exit(0);
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
case 'l':
|
case 'l':
|
||||||
if (linkerScriptName) {
|
if (linkerScriptName) {
|
||||||
warnx("Overriding linker script %s", linkerScriptName);
|
warnx("Overriding linker script %s", linkerScriptName);
|
||||||
@@ -345,10 +327,7 @@ int main(int argc, char *argv[]) {
|
|||||||
options.is32kMode = true;
|
options.is32kMode = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// LCOV_EXCL_START
|
usage.printAndExit(1); // LCOV_EXCL_LINE
|
||||||
printUsage();
|
|
||||||
exit(1);
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +335,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
// If no input files were specified, the user must have screwed up
|
// If no input files were specified, the user must have screwed up
|
||||||
if (curArgIndex == argc) {
|
if (curArgIndex == argc) {
|
||||||
fatalWithUsage("Please specify an input file (pass `-` to read from standard input)");
|
usage.printAndExit("Please specify an input file (pass `-` to read from standard input)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch the size array depending on command-line options
|
// Patch the size array depending on command-line options
|
||||||
|
|||||||
22
src/usage.cpp
Normal file
22
src/usage.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include "usage.hpp"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void Usage::printAndExit(int code) const {
|
||||||
|
fputs(usage, stderr);
|
||||||
|
exit(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Usage::printAndExit(char const *fmt, ...) const {
|
||||||
|
va_list args;
|
||||||
|
fputs("FATAL: ", stderr);
|
||||||
|
va_start(args, fmt);
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
putc('\n', stderr);
|
||||||
|
|
||||||
|
printAndExit(1);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user