// // Created by quentin on 1/8/23. // #include "mainOptHandler.h" #include "accountOperation.h" #include "createOperation.h" #include "earnOperation.h" #include "PaymentOperation.h" #include #include #include using namespace Budget::OptHandlers; MainOptHandler::MainOptHandler(const std::vector &_argv) : argv(_argv){ struct option actionLongOpts[] = { {"help", no_argument, nullptr, 'h'}, {"account", required_argument, nullptr, 'a'}, {"create", required_argument, nullptr, 'c'}, {"earn", required_argument, nullptr, 'e'}, {"payment", required_argument, nullptr, 'p'} }; while (true) { int opt = getopt_long(argv.size(), argv.data(), "ha:c:e:p:", actionLongOpts, nullptr); if (opt == -1) break; switch (opt) { case 'h': help(); exit(0); case 'a': accountOptHandler(optarg); break; case 'c': createOptHandler(optarg); break; case 'e': earnOptHandler(optarg); break; case 'p': paymentOptHandler(optarg); break; case '?': help(); exit(0); default: break; } } } void MainOptHandler::accountOptHandler(std::string account) { struct option accountLongOpts[] = { {"help", no_argument, nullptr, 'h'}, {"account", required_argument, nullptr, 'a'}, {"create", required_argument, nullptr, 'c'}, {"earn", required_argument, nullptr, 'e'}, {"payment", required_argument, nullptr, 'p'}, {"delete", no_argument, nullptr, 'd'}, {"force-delete", no_argument, nullptr, 'F'}, {"value", no_argument, nullptr, 'v'}, {"description", no_argument, nullptr, 'D'}, }; auto acctOperation = std::make_unique(); while (true) { int opt = getopt_long(argv.size(), argv.data(), "ha:c:e:p:dFvD", accountLongOpts, nullptr); if (opt == -1) break; switch (opt) { case 'h': help(); exit(0); case 'a': case 'c': case 'e': case 'p': optind--; operations.push(std::move(acctOperation)); return; case 'd': acctOperation->flags.del = true; break; case 'F': acctOperation->flags.del = true; acctOperation->flags.forceDel = true; break; case 'v': acctOperation->flags.value = true; break; case 'D': acctOperation->flags.description = optarg; break; case '?': help(); exit(0); default: break; } } operations.push(std::move(acctOperation)); } void MainOptHandler::createOptHandler(std::string account) { struct option createLongOpts[] = { {"help", no_argument, nullptr, 'h'}, {"account", required_argument, nullptr, 'a'}, {"create", required_argument, nullptr, 'c'}, {"earn", required_argument, nullptr, 'e'}, {"payment", required_argument, nullptr, 'p'}, {"description", required_argument, nullptr, 'd'}, }; auto createOperation = std::make_unique(); while (true) { int opt = getopt_long(argv.size(), argv.data(), "ha:c:e:p:d:", createLongOpts, nullptr); if (opt == -1) break; switch (opt) { case 'h': help(); exit(0); case 'a': case 'c': case 'e': case 'p': optind--; operations.push(std::move(createOperation)); return; case 'd': createOperation->flags.description = optarg; break; case '?': help(); exit(0); default: break; } } operations.push(std::move(createOperation)); } void MainOptHandler::earnOptHandler(std::string account) { struct option earnLongOpts[] = { {"help", no_argument, nullptr, 'h'}, {"account", required_argument, nullptr, 'a'}, {"create", required_argument, nullptr, 'c'}, {"earn", required_argument, nullptr, 'e'}, {"payment", required_argument, nullptr, 'p'}, {"value", required_argument, nullptr, 'v'}, {"description", required_argument, nullptr, 'd'}, {"receipt", required_argument, nullptr, 'r'}, {"date", required_argument, nullptr, 'D'}, }; auto earnOperation = std::make_unique(); while (true) { int opt = getopt_long(argv.size(), argv.data(), "ha:c:e:p:v:d:r:D:", earnLongOpts, nullptr); if (opt == -1) break; switch (opt) { case 'h': help(); exit(0); case 'a': case 'c': case 'e': case 'p': optind--; operations.push(std::move(earnOperation)); return; case 'v': { try { earnOperation->flags.value = std::stod(optarg); } catch (std::exception const &e) { help(); std::cout << "Bad value value" << std::endl; exit(1); } break; } case 'd': earnOperation->flags.description = optarg; break; case 'r': earnOperation->flags.receipt = optarg; break; case 'D': { struct tm t{}; time_t ts; memset(&t, 0, sizeof(struct tm)); if (strptime(optarg, "%m/%d/%YT%H:%M:%S", &t) == nullptr) { help(); std::cout << "Bad time value" << std::endl; exit(1); } ts = mktime(&t); earnOperation->flags.date = (long long) ts; break; } case '?': help(); exit(0); default: break; } } operations.push(std::move(earnOperation)); } void MainOptHandler::paymentOptHandler(std::string account) { struct option paymentLongOpts[] = { {"help", no_argument, nullptr, 'h'}, {"account", required_argument, nullptr, 'a'}, {"create", required_argument, nullptr, 'c'}, {"earn", required_argument, nullptr, 'e'}, {"payment", required_argument, nullptr, 'p'}, {"value", required_argument, nullptr, 'v'}, {"description", required_argument, nullptr, 'd'}, {"receipt", required_argument, nullptr, 'r'}, {"date", required_argument, nullptr, 'D'}, }; auto payOperation = std::make_unique(); while (true) { int opt = getopt_long(argv.size(), argv.data(), "ha:c:e:p:v:d:r:D", paymentLongOpts, nullptr); if (opt == -1) break; switch (opt) { case 'h': help(); exit(0); case 'a': case 'c': case 'e': case 'p': optind--; operations.push(std::move(payOperation)); return; case 'v': { try { payOperation->flags.value = std::stod(optarg); } catch (std::exception const &e) { help(); std::cout << "Bad value value" << std::endl; exit(1); } break; } case 'd': payOperation->flags.description = optarg; break; case 'r': payOperation->flags.receipt = optarg; break; case 'D': { struct tm t{}; time_t ts; memset(&t, 0, sizeof(struct tm)); if (strptime(optarg, "%m/%d/%YT%H:%M:%S", &t) == nullptr) { help(); std::cout << "Bad time value" << std::endl; exit(1); } ts = mktime(&t); payOperation->flags.date = (long long) ts; break; } case '?': help(); exit(0); default: break; } } operations.push(std::move(payOperation)); } void MainOptHandler::help() { std::cout << "Output of budget." << std::endl; std::cout << "Usage:" << std::endl; std::cout << "\tbudget [options] ..." << std::endl; std::cout << "Actions:" << std::endl; std::cout << "\t-h --help Prints this." << std::endl; std::cout << "\t-a --account<=STRING> Management tools for an account." << std::endl; std::cout << "\t-c --create<=STRING> Creates a new account with NAME." << std::endl; std::cout << "\t-e --earn<=STRING> Add an earning to an account." << std::endl; std::cout << "\t-p --payment<=STRING> Add a payment to an account." << std::endl; std::cout << "Account Options: [-dvD]" << std::endl; std::cout << "\t-d --delete Deletes specified account." << std::endl; std::cout << "\t--force-delete Deletes the specified account without confirmation." << std::endl; std::cout << "\t-v --value Gets the current value of the account." << std::endl; std::cout << "\t-D --description<=STRING> Changes the description of the account." << std::endl; std::cout << "Create Options: [-d]" << std::endl; std::cout << "\t-d --description<=STRING> Sets a description for an account." << std::endl; std::cout << "Earn Options: -v [-drD]" << std::endl; std::cout << "\t-v --value= Value for earning." << std::endl; std::cout << "\t-d --description= Description for earning." << std::endl; std::cout << "\t-r --receipt= Path to file to store in DB as receipt." << std::endl; std::cout << "\t-D --date= Date as dd/mm/yyyyTHH:MM:SS. Default will be today." << std::endl; std::cout << "Payment Options: -v [-drD]" << std::endl; std::cout << "\t-v --value= Value for payment." << std::endl; std::cout << "\t-d --description= Description for payment." << std::endl; std::cout << "\t-r --receipt= Path to file to store in DB as receipt." << std::endl; std::cout << "\t-D --date= Date as dd/mm/yyyyTHH:MM:SS. Default will be today." << std::endl; std::cout << std::endl; std::cout << "Arguments are processed like blocks with each one terminated by the next Action. For example" << std::endl; std::cout << std::endl; std::cout << R"(budget -cAcct -eAcct -v10.00 -r"./receipt.pdf" -pAcct -v5.50 -r"./payment.pdf")" << std::endl; std::cout << std::endl; std::cout << "Does the following in order:" << std::endl; std::cout << "Creates an account named Acct with no description." << std::endl; std::cout << "Earns 10.00 to it with a receipt." << std::endl; std::cout << "Pays 5.50 to it with a receipt." << std::endl; }