From 0628e17c7d98f62284af2009718a6414703488b9 Mon Sep 17 00:00:00 2001 From: Aleksandr Kirsanov Date: Sun, 5 May 2024 11:54:14 +0300 Subject: [PATCH] [FunC] Use td::OptionParser in func-main.cpp --- crypto/func/func-main.cpp | 136 +++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 75 deletions(-) diff --git a/crypto/func/func-main.cpp b/crypto/func/func-main.cpp index c8208eee..92321282 100644 --- a/crypto/func/func-main.cpp +++ b/crypto/func/func-main.cpp @@ -26,83 +26,69 @@ Copyright 2017-2020 Telegram Systems LLP */ #include "func.h" -#include "parser/srcread.h" -#include "parser/lexer.h" -#include "parser/symtable.h" -#include +#include "td/utils/OptionParser.h" #include #include "git.h" -void usage(const char* progname) { - std::cerr - << "usage: " << progname - << " [-vIAPSR][-O][-i][-o][-W] { ...}\n" - "\tGenerates Fift TVM assembler code from a funC source\n" - "-I\tEnables interactive mode (parse stdin)\n" - "-o\tWrites generated code into specified file instead of stdout\n" - "-v\tIncreases verbosity level (extra information output into stderr)\n" - "-i\tSets indentation for the output code (in two-space units)\n" - "-A\tPrefix code with `\"Asm.fif\" include` preamble\n" - "-O\tSets optimization level (2 by default)\n" - "-P\tEnvelope code into PROGRAM{ ... }END>c\n" - "-S\tInclude stack layout comments in the output code\n" - "-R\tInclude operation rewrite comments in the output code\n" - "-W\tInclude Fift code to serialize and save generated code into specified BoC file. Enables " - "-A and -P.\n" - "\t-s\tOutput semantic version of FunC and exit\n" - "\t-V\tShow func build information\n"; - std::exit(2); -} - -int main(int argc, char* const argv[]) { - int i; +int main(int argc, char* argv[]) { std::string output_filename; - while ((i = getopt(argc, argv, "Ahi:Io:O:PRsSvW:V")) != -1) { - switch (i) { - case 'A': - funC::asm_preamble = true; - break; - case 'I': - funC::interactive = true; - break; - case 'i': - funC::indent = std::max(0, atoi(optarg)); - break; - case 'o': - output_filename = optarg; - break; - case 'O': - funC::opt_level = std::max(0, atoi(optarg)); - break; - case 'P': - funC::program_envelope = true; - break; - case 'R': - funC::op_rewrite_comments = true; - break; - case 'S': - funC::stack_layout_comments = true; - break; - case 'v': - ++funC::verbosity; - break; - case 'W': - funC::boc_output_filename = optarg; - funC::asm_preamble = funC::program_envelope = true; - break; - case 's': - std::cout << funC::func_version << "\n"; - std::exit(0); - break; - case 'V': - std::cout << "FunC semantic version: v" << funC::func_version << "\n"; - std::cout << "Build information: [ Commit: " << GitMetadata::CommitSHA1() << ", Date: " << GitMetadata::CommitDate() << "]\n"; - std::exit(0); - break; - case 'h': - default: - usage(argv[0]); - } + td::OptionParser p; + p.set_description("usage: func " + "[-vIAPSR][-O][-i][-o][-W] { ...}\n" + "Generates Fift TVM assembler code from FunC sources"); + + p.add_option('I', "interactive", "Enables interactive mode (parse stdin)", [] { + funC::interactive = true; + }); + p.add_option('o', "output", "Writes generated code into specified file instead of stdout", [&output_filename](td::Slice arg) { + output_filename = arg.str(); + }); + p.add_option('v', "verbose", "Increases verbosity level (extra information output into stderr)", [] { + ++funC::verbosity; + }); + p.add_option('i', "indent", "Sets indentation for the output code (in two-space units)", [](td::Slice arg) { + funC::indent = std::max(0, std::atoi(arg.str().c_str())); + }); + p.add_option('A', "asm-preamble", "prefix code with `\"Asm.fif\" include` preamble", [] { + funC::asm_preamble = true; + }); + p.add_option('O', "opt-level", "Sets optimization level (2 by default)", [](td::Slice arg) { + funC::opt_level = std::max(0, std::atoi(arg.str().c_str())); + }); + p.add_option('P', "program-envelope", "Envelope code into PROGRAM{ ... }END>c", [] { + funC::program_envelope = true; + }); + p.add_option('S', "stack-comments", "Include stack layout comments in the output code", []{ + funC::stack_layout_comments = true; + }); + p.add_option('R', "rewrite-comments", "Include operation rewrite comments in the output code", [] { + funC::op_rewrite_comments = true; + }); + p.add_option('W', "boc-output", "Include Fift code to serialize and save generated code into specified BoC file. Enables -A and -P", [](td::Slice arg) { + funC::boc_output_filename = arg.str(); + funC::asm_preamble = funC::program_envelope = true; + }); + p.add_option('s', "version", "Output semantic version of FunC and exit", [] { + std::cout << funC::func_version << "\n"; + std::exit(0); + }); + p.add_option('V', "full-version", "Show FunC build information and exit", [] { + std::cout << "FunC semantic version: v" << funC::func_version << "\n"; + std::cout << "Build information: [ Commit: " << GitMetadata::CommitSHA1() << ", Date: " << GitMetadata::CommitDate() << "]\n"; + std::exit(0); + }); + p.add_option('h', "help", "Print help and exit", [&p] { + char b[10240]; + td::StringBuilder sb(td::MutableSlice{b, 10000}); + sb << p; + std::cout << sb.as_cslice().c_str(); + std::exit(2); + }); + + auto parse_result = p.run(argc, argv); + if (parse_result.is_error()) { + std::cerr << "failed to parse options: " << parse_result.error().message().c_str() << "\n"; + return 2; } std::ostream *outs = &std::cout; @@ -119,8 +105,8 @@ int main(int argc, char* const argv[]) { std::vector sources; - while (optind < argc) { - sources.push_back(std::string(argv[optind++])); + for (const char* in_filename : parse_result.ok()) { + sources.emplace_back(in_filename); } funC::read_callback = funC::fs_read_callback;