Skip to content

Commit

Permalink
compiler: add support for explicit --help option
Browse files Browse the repository at this point in the history
Summary: If the user provides a --help argument, it is interpreted as an explicit request to provide usage information. In practice, compared to today, this means printing the usage information to STDOUT (vs. STDERR) and terminating with a successful exit code (i.e., 0) instead of an error (i.e., 1).

Reviewed By: iahs

Differential Revision: D67607961

fbshipit-source-id: 505072be2f96675df8a7cbb4a93e00176f982190
  • Loading branch information
Aristidis Papaioannou authored and facebook-github-bot committed Dec 24, 2024
1 parent d8eba66 commit 21cb812
Showing 1 changed file with 45 additions and 13 deletions.
58 changes: 45 additions & 13 deletions thrift/compiler/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <algorithm>
#include <ctime>
#include <filesystem>
#include <fstream>
Expand Down Expand Up @@ -78,12 +80,15 @@ constexpr bool bundle_annotations() {
}

/**
* Display the usage message.
* Display the usage message to the given C stream.
*
* @param stream See https://en.cppreference.com/w/c/io/FILE
*/
void usage() {
fprintf(stderr, R"(Usage: thrift [options] file
void printUsageTo(FILE* stream) {
fprintf(stream, R"(Usage: thrift [options] file
Options:
--help Print this message to stdout and exit (successfully).
-o dir Set the output directory for gen-* packages (default: current
directory).
At most one of this option (-o) or -out (see below) can be
Expand Down Expand Up @@ -144,14 +149,34 @@ Available generators (and options):
for (const auto& gen : generator_registry::get_generators()) {
const generator_factory& generator_factory = *gen.second;
fmt::print(
stderr,
stream,
" {} ({}):\n{}",
generator_factory.name(),
generator_factory.long_name(),
generator_factory.documentation());
}
}

/**
* Display the usage message to the standard error stream.
*/
void printUsageError() {
printUsageTo(stderr);
}

/**
* If `arguments` includes "--help" (in any position), prints usage message
* to STDOUT and returns true. Otherwise returns false.
*/
bool maybeHandleHelpInvocation(const std::vector<std::string>& arguments) {
if (std::find(arguments.begin(), arguments.end(), "--help") ==
arguments.end()) {
return false;
}
printUsageTo(stdout);
return true;
}

bool isPathSeparator(const char& c) {
#ifdef _WIN32
return c == ';';
Expand Down Expand Up @@ -185,7 +210,7 @@ const std::string* consume_next_arg(
arg_name,
arguments[arg_i].c_str(),
arguments[arg_i + 1].c_str());
usage();
printUsageError();
return nullptr;
}
return &arguments[++arg_i];
Expand All @@ -206,7 +231,7 @@ const std::string* consume_next_arg(
std::string parse_flag(const std::string& argument) {
if (argument.size() < 2 || argument[0] != '-' || (argument == "--")) {
fprintf(stderr, "!!! Expected flag, got: %s\n\n", argument.c_str());
usage();
printUsageError();
return {};
}

Expand All @@ -233,14 +258,14 @@ bool validate_params(const gen_params& gparams) {
const bool skip_gen = gparams.skip_gen;
if (has_targets && skip_gen) {
fprintf(stderr, "!!! Cannot specify both --skip-gen and --gen.\n\n");
usage();
printUsageError();
return false;
}
if (!has_targets && !skip_gen) {
fprintf(
stderr,
"!!! No output language(s) specified: need --gen or --skip-gen.\n\n");
usage();
printUsageError();
return false;
}
// Exactly one of skip_gen and has_targets is true => valid.
Expand Down Expand Up @@ -286,7 +311,7 @@ std::string parse_args(
// Check for necessary arguments, you gotta have at least a filename and
// an output language flag.
if (arguments.size() < 3 && gparams.targets.empty()) {
usage();
printUsageError();
return {};
}

Expand Down Expand Up @@ -361,7 +386,7 @@ std::string parse_args(

if (!gparams.out_path.empty()) {
fprintf(stderr, "!!! Cannot specify both -o and --out.\n\n");
usage();
printUsageError();
return {};
}

Expand Down Expand Up @@ -397,14 +422,14 @@ std::string parse_args(
} else {
fprintf(
stderr, "!!! Unrecognized validator: %s\n\n", validator.c_str());
usage();
printUsageError();
return {};
}
}
} else {
fprintf(
stderr, "!!! Unrecognized option: %s\n\n", arguments[arg_i].c_str());
usage();
printUsageError();
return {};
}
}
Expand Down Expand Up @@ -516,7 +541,7 @@ std::unique_ptr<t_generator> create_generator(
generator_name, program, program_bundle, diags);
if (generator == nullptr) {
fmt::print(stderr, "Error: Invalid generator name: {}\n", generator_name);
usage();
printUsageError();
return nullptr;
}
generator->process_options(
Expand Down Expand Up @@ -853,6 +878,13 @@ compile_result compile(
const std::vector<std::string>& arguments, source_manager& source_mgr) {
compile_result result;

// If --help is explicitly passed, print (non-error) usage and return
// successfully.
if (maybeHandleHelpInvocation(arguments)) {
result.retcode = compile_retcode::success;
return result;
}

// Parse arguments.
parsing_params pparams;
gen_params gparams;
Expand Down

0 comments on commit 21cb812

Please sign in to comment.