feat: basically finish clap parser
- basically finish clap parser except ctor. - add skeleton for clap resolver.
This commit is contained in:
@ -34,6 +34,10 @@ namespace yycc::carton::clap::option {
|
||||
|
||||
Option::~Option() {}
|
||||
|
||||
bool Option::has_value() const {
|
||||
return this->value_hint.has_value();
|
||||
}
|
||||
|
||||
std::optional<std::u8string_view> Option::get_short_name() const {
|
||||
return this->short_name;
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ namespace yycc::carton::clap::option {
|
||||
YYCC_DEFAULT_COPY_MOVE(Option)
|
||||
|
||||
public:
|
||||
bool has_value() const;
|
||||
std::optional<std::u8string_view> get_short_name() const;
|
||||
std::optional<std::u8string_view> get_long_name() const;
|
||||
std::optional<std::u8string_view> get_value_hint() const;
|
||||
|
||||
@ -1,3 +1,216 @@
|
||||
#include "parser.hpp"
|
||||
#include "types.hpp"
|
||||
#include "../../env.hpp"
|
||||
#include <stdexcept>
|
||||
#include <ranges>
|
||||
|
||||
namespace yycc::carton::clap::parser {}
|
||||
#define TYPES ::yycc::carton::clap::types
|
||||
#define APPLICATION ::yycc::carton::clap::application
|
||||
#define ENV ::yycc::env
|
||||
|
||||
namespace yycc::carton::clap::parser {
|
||||
|
||||
#pragma region Misc
|
||||
|
||||
/// @brief The kind of argument.
|
||||
enum class ArgumentKind { LongName, ShortName, Value };
|
||||
/// @brief Representing a classified argument.
|
||||
struct ClassifiedArgument {
|
||||
ClassifiedArgument(const std::u8string_view& arg) {
|
||||
if (arg.starts_with(TYPES::DOUBLE_DASH)) {
|
||||
kind = ArgumentKind::LongName;
|
||||
content = arg.substr(TYPES::DOUBLE_DASH.length());
|
||||
} else if (arg.starts_with(TYPES::DASH)) {
|
||||
kind = ArgumentKind::ShortName;
|
||||
content = arg.substr(TYPES::DASH.length());
|
||||
} else {
|
||||
kind = ArgumentKind::Value;
|
||||
content = arg;
|
||||
}
|
||||
}
|
||||
YYCC_DEFAULT_COPY_MOVE(ClassifiedArgument)
|
||||
|
||||
/// @brief The kind of argument.
|
||||
ArgumentKind kind;
|
||||
/**
|
||||
* @brief The data of argument.
|
||||
* @details For long and short name, it is the body of option, the words removing any leading dash.
|
||||
* For value, it just the value self.
|
||||
*/
|
||||
std::u8string_view content;
|
||||
};
|
||||
|
||||
/// @brief The states of parser internal state machine.
|
||||
enum class ParserState {
|
||||
Normal, ///< Normal state. Expect an option.
|
||||
WaitingValue, ///< Waiting an associated value.
|
||||
};
|
||||
/// @brief The state machine context prepared for parser.
|
||||
struct ParserContext {
|
||||
ParserContext(const APPLICATION::Application& app) : state(ParserState::Normal), opt_waiting(std::nullopt), app(app), values() {}
|
||||
YYCC_DEFAULT_COPY_MOVE(ParserContext)
|
||||
|
||||
ParserState state; ///< Current state.
|
||||
std::optional<TYPES::Token> opt_waiting; ///< The token to the option waiting for associated value.
|
||||
const APPLICATION::Application& app; ///< Associated application.
|
||||
std::map<TYPES::Token, std::optional<std::u8string>> values; ///< The container storing captured options.
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Core
|
||||
|
||||
/// @brief Core capture function.
|
||||
static TYPES::ClapResult<std::map<TYPES::Token, std::optional<std::u8string>>> capture(const APPLICATION::Application& app) {
|
||||
// Create context.
|
||||
ParserContext ctx(app);
|
||||
|
||||
// Fetch commandline arguments
|
||||
// And skip the first argument because it is the path to executable.
|
||||
// Then start to execute until all arguments are consumed.
|
||||
for (const auto& arg : ENV::get_args() | std::views::drop(1)) {
|
||||
// Fetch argument kind
|
||||
ClassifiedArgument classified_arg(arg);
|
||||
|
||||
// Execute handler according to state.
|
||||
TYPES::ClapResult<void> rv;
|
||||
switch (ctx.state) {
|
||||
case ParserState::Normal:
|
||||
rv = normal_state(ctx, classified_arg);
|
||||
break;
|
||||
case ParserState::WaitingValue:
|
||||
rv = waiting_value_state(ctx, classified_arg);
|
||||
break;
|
||||
}
|
||||
if (!rv.has_value()) {
|
||||
return std::unexpected(rv.error());
|
||||
}
|
||||
}
|
||||
|
||||
// If the final state is waiting value,
|
||||
// it means that the last option lose its asociated value.
|
||||
// So we need report error.
|
||||
if (ctx.state == ParserState::WaitingValue && ctx.opt_waiting.has_value()) {
|
||||
return std::unexpected(TYPES::ClapError::LostValue);
|
||||
}
|
||||
|
||||
// Return capture result.
|
||||
return ctx.values;
|
||||
}
|
||||
|
||||
/// @brief The handler for state machine Normal state.
|
||||
static TYPES::ClapResult<void> normal_state(ParserContext& ctx, const ClassifiedArgument& arg) {
|
||||
// Do thing according all registered options.
|
||||
const auto& options = ctx.app.get_options();
|
||||
|
||||
// In normal state, we should fetch a name.
|
||||
// Check whether this name is existing, report error if not.
|
||||
std::optional<TYPES::Token> opt_token;
|
||||
switch (arg.kind) {
|
||||
// We can not meet associated value in normal state.
|
||||
case ArgumentKind::Value:
|
||||
return std::unexpected(TYPES::ClapError::UnexpectedValue);
|
||||
// Fetch token according to long name or short name.
|
||||
case ArgumentKind::LongName:
|
||||
opt_token = options.find_long_name(arg.content);
|
||||
break;
|
||||
case ArgumentKind::ShortName:
|
||||
opt_token = options.find_short_name(arg.content);
|
||||
break;
|
||||
}
|
||||
if (!opt_token.has_value()) {
|
||||
return std::unexpected(TYPES::ClapError::InvalidName);
|
||||
}
|
||||
TYPES::Token token = opt_token.value();
|
||||
|
||||
// Check whether this token has been captured.
|
||||
// If it is, report error.
|
||||
if (ctx.values.contains(token)) {
|
||||
return std::unexpected(TYPES::ClapError::DuplicatedAssign);
|
||||
}
|
||||
|
||||
// Finally, check whether this token has associated value.
|
||||
// If it has, set state machine, otherwise push it into capture list directly.
|
||||
if (options.get_option(token).has_value()) {
|
||||
ctx.opt_waiting = token;
|
||||
ctx.state = ParserState::WaitingValue;
|
||||
} else {
|
||||
ctx.values.emplace(token, std::nullopt);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/// @brief The handler for state machine WaitingValue state.
|
||||
static TYPES::ClapResult<void> waiting_value_state(ParserContext& ctx, const ClassifiedArgument& arg) {
|
||||
// Do thing according all registered options.
|
||||
const auto& options = ctx.app.get_options();
|
||||
TYPES::Token token = ctx.opt_waiting.value();
|
||||
switch (arg.kind) {
|
||||
case ArgumentKind::LongName:
|
||||
case ArgumentKind::ShortName:
|
||||
// Got option name when waiting associated value.
|
||||
// It means that previous option lost associated value.
|
||||
return std::unexpected(TYPES::ClapError::LostValue);
|
||||
case ArgumentKind::Value:
|
||||
// We got associated value.
|
||||
// Push it with option waiting value into capture list.
|
||||
ctx.values.emplace(token, arg.content);
|
||||
// Clear token waiting value.
|
||||
ctx.opt_waiting = std::nullopt;
|
||||
// Reset state at last.
|
||||
ctx.state = ParserState::Normal;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Parser Class
|
||||
|
||||
TYPES::ClapResult<Parser> Parser::from_user(const APPLICATION::Application& app, const std::vector<std::u8string_view>& args) {
|
||||
return TYPES::ClapResult<Parser>();
|
||||
}
|
||||
|
||||
TYPES::ClapResult<Parser> Parser::from_system(const APPLICATION::Application& app) {
|
||||
return TYPES::ClapResult<Parser>();
|
||||
}
|
||||
|
||||
Parser::Parser(decltype(Parser::values)&& value) : values(std::move(values)) {}
|
||||
|
||||
Parser::~Parser() {}
|
||||
|
||||
bool Parser::has_option(TYPES::Token token) const {
|
||||
return this->values.contains(token);
|
||||
}
|
||||
|
||||
TYPES::ClapResult<bool> Parser::get_flag_option(TYPES::Token token) const {
|
||||
auto finder = this->values.find(token);
|
||||
if (finder == this->values.end()) {
|
||||
// Not found.
|
||||
return false;
|
||||
} else {
|
||||
// Found.
|
||||
auto val = finder->second;
|
||||
if (val.has_value()) throw std::logic_error("get flag option as value option.");
|
||||
else return true;
|
||||
}
|
||||
}
|
||||
|
||||
TYPES::ClapResult<std::u8string_view> Parser::get_raw_value_option(TYPES::Token token) const {
|
||||
auto finder = this->values.find(token);
|
||||
if (finder == this->values.end()) {
|
||||
// Not found.
|
||||
return std::unexpected(TYPES::ClapError::NotCaptured);
|
||||
} else {
|
||||
// Found.
|
||||
auto val = finder->second;
|
||||
if (val.has_value()) return std::u8string_view(val.value());
|
||||
else throw std::logic_error("get value option as flag option.");
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
} // namespace yycc::carton::clap::parser
|
||||
|
||||
@ -1,5 +1,65 @@
|
||||
#pragma once
|
||||
#include "../../macro/class_copy_move.hpp"
|
||||
#include "application.hpp"
|
||||
#include "validator.hpp"
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#define NS_YYCC_CLAP_TYPES ::yycc::carton::clap::types
|
||||
#define NS_YYCC_CLAP_APPLICATION ::yycc::carton::clap::application
|
||||
#define NS_YYCC_CLAP_VALIDATOR ::yycc::carton::clap::validator
|
||||
|
||||
namespace yycc::carton::clap::parser {
|
||||
|
||||
}
|
||||
class Parser {
|
||||
private:
|
||||
/**
|
||||
* @brief All captured commandline argument.
|
||||
* @details Key is the token to already registered option.
|
||||
* Value is the associated value for key token.
|
||||
* If it is no-value option, the value will be \c std::nullopt.
|
||||
*/
|
||||
std::map<NS_YYCC_CLAP_TYPES::Token, std::optional<std::u8string>> values;
|
||||
|
||||
public:
|
||||
static NS_YYCC_CLAP_TYPES::ClapResult<Parser> from_user(const NS_YYCC_CLAP_APPLICATION::Application& app,
|
||||
const std::vector<std::u8string_view>& args);
|
||||
static NS_YYCC_CLAP_TYPES::ClapResult<Parser> from_system(const NS_YYCC_CLAP_APPLICATION::Application& app);
|
||||
|
||||
private:
|
||||
Parser(decltype(Parser::values)&& value);
|
||||
|
||||
public:
|
||||
~Parser();
|
||||
YYCC_DEFAULT_COPY_MOVE(Parser)
|
||||
|
||||
private:
|
||||
NS_YYCC_CLAP_TYPES::ClapResult<std::u8string_view> get_raw_value_option(NS_YYCC_CLAP_TYPES::Token token) const;
|
||||
|
||||
public:
|
||||
bool has_option(NS_YYCC_CLAP_TYPES::Token token) const;
|
||||
NS_YYCC_CLAP_TYPES::ClapResult<bool> get_flag_option(NS_YYCC_CLAP_TYPES::Token token) const;
|
||||
template<NS_YYCC_CLAP_VALIDATOR::Validator T>
|
||||
NS_YYCC_CLAP_TYPES::ClapResult<NS_YYCC_CLAP_VALIDATOR::ValidatorReturnType<T>> get_value_option(
|
||||
NS_YYCC_CLAP_TYPES::Token token) const {
|
||||
auto raw_value = this->get_raw_value_option(token);
|
||||
if (raw_value.has_value()) {
|
||||
T validator{};
|
||||
auto value = validator.validate(raw_value.value());
|
||||
if (value.has_value()) return value.value();
|
||||
else return std::unexpected(NS_YYCC_CLAP_TYPES::ClapError::BadCast);
|
||||
} else {
|
||||
return std::unexpected(raw_value.error())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace yycc::carton::clap::parser
|
||||
|
||||
#undef NS_YYCC_CLAP_VALIDATOR
|
||||
#undef NS_YYCC_CLAP_APPLICATION
|
||||
#undef NS_YYCC_CLAP_TYPES
|
||||
|
||||
@ -1,81 +1,50 @@
|
||||
#include "resolver.hpp"
|
||||
#include "types.hpp"
|
||||
#include <string_view>
|
||||
|
||||
#define TYPES ::yycc::carton::clap::types
|
||||
|
||||
namespace yycc::carton::clap::resolver {
|
||||
|
||||
#pragma region Misc
|
||||
|
||||
/// @brief The states of parser internal state machine.
|
||||
enum class ParserState {
|
||||
Normal, ///< Normal state. Expect an option.
|
||||
WaitingValue, ///< Waiting an associated value.
|
||||
};
|
||||
/// @brief The state machine context prepared for parser.
|
||||
struct ParserContext {
|
||||
ParserContext() : state(ParserState::Normal), opt_waiting(std::nullopt) {}
|
||||
YYCC_DEFAULT_COPY_MOVE(ParserContext)
|
||||
|
||||
ParserState state; ///< Current state.
|
||||
std::optional<TYPES::Token> opt_waiting; ///< The token to the option waiting for associated value.
|
||||
};
|
||||
|
||||
/// @brief The kind of argument.
|
||||
enum class ArgumentKind { LongName, ShortName, Value };
|
||||
/// @brief Representing a classified argument.
|
||||
struct ClassifiedArgument {
|
||||
ClassifiedArgument(const std::u8string_view& arg) {
|
||||
if (arg.starts_with(TYPES::DOUBLE_DASH)) {
|
||||
kind = ArgumentKind::LongName;
|
||||
content = arg.substr(TYPES::DOUBLE_DASH.length());
|
||||
} else if (arg.starts_with(TYPES::DASH)) {
|
||||
kind = ArgumentKind::ShortName;
|
||||
content = arg.substr(TYPES::DASH.length());
|
||||
} else {
|
||||
kind = ArgumentKind::Value;
|
||||
content = arg;
|
||||
}
|
||||
}
|
||||
YYCC_DEFAULT_COPY_MOVE(ClassifiedArgument)
|
||||
|
||||
/// @brief The kind of argument.
|
||||
ArgumentKind kind;
|
||||
/**
|
||||
* @brief The data of argument.
|
||||
* @details For long and short name, it is the body of option, the words removing any leading dash.
|
||||
* For value, it just the value self.
|
||||
*/
|
||||
std::u8string_view content;
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Core
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Parser Class
|
||||
#pragma region Resolver Class
|
||||
|
||||
Parser::Parser(const NS_YYCC_CLAP_APPLICATION::Application& app) {}
|
||||
Resolver::Resolver(decltype(Resolver::values)&& values) : values(std::move(values)) {}
|
||||
|
||||
Parser::~Parser() {}
|
||||
Resolver::~Resolver() {}
|
||||
|
||||
bool Parser::has_option(TYPES::Token token) const {
|
||||
// TODO:
|
||||
return false;
|
||||
bool Resolver::has_variable(TYPES::Token token) const {
|
||||
return this->values.contains(token);
|
||||
}
|
||||
|
||||
TYPES::ClapResult<bool> Parser::get_flag_option(TYPES::Token token) const {
|
||||
// TODO:
|
||||
return TYPES::ClapResult<bool>();
|
||||
TYPES::ClapResult<bool> Resolver::get_flag_variable(TYPES::Token token) const {
|
||||
auto finder = this->values.find(token);
|
||||
if (finder == this->values.end()) {
|
||||
// Not found.
|
||||
return false;
|
||||
} else {
|
||||
// Found.
|
||||
auto val = finder->second;
|
||||
if (val.has_value()) throw std::logic_error("get flag variable as value variable.");
|
||||
else return true;
|
||||
}
|
||||
}
|
||||
|
||||
TYPES::ClapResult<std::u8string_view> Parser::get_raw_value_option(TYPES::Token token) const {
|
||||
// TODO:
|
||||
return TYPES::ClapResult<std::u8string_view>();
|
||||
TYPES::ClapResult<std::u8string_view> Resolver::get_raw_value_variable(TYPES::Token token) const {
|
||||
auto finder = this->values.find(token);
|
||||
if (finder == this->values.end()) {
|
||||
// Not found.
|
||||
return std::unexpected(TYPES::ClapError::NotCaptured);
|
||||
} else {
|
||||
// Found.
|
||||
auto val = finder->second;
|
||||
if (val.has_value()) return std::u8string_view(val.value());
|
||||
else throw std::logic_error("get value variable as flag variable.");
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
} // namespace yycc::carton::clap::resolver
|
||||
|
||||
@ -2,9 +2,12 @@
|
||||
#include "../../macro/class_copy_move.hpp"
|
||||
#include "application.hpp"
|
||||
#include "validator.hpp"
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#define NS_YYCC_CLAP_TYPES ::yycc::carton::clap::types
|
||||
#define NS_YYCC_CLAP_APPLICATION ::yycc::carton::clap::application
|
||||
@ -12,22 +15,38 @@
|
||||
|
||||
namespace yycc::carton::clap::resolver {
|
||||
|
||||
class Parser {
|
||||
class Resolver {
|
||||
private:
|
||||
/**
|
||||
* @brief All captured environment variable.
|
||||
* @details Key is the token to already registered variable.
|
||||
* Value is the associated value for key token.
|
||||
* If it is no-value variable, the value will be \c std::nullopt.
|
||||
*/
|
||||
std::map<NS_YYCC_CLAP_TYPES::Token, std::optional<std::u8string>> values;
|
||||
|
||||
public:
|
||||
Parser(const NS_YYCC_CLAP_APPLICATION::Application& app);
|
||||
~Parser();
|
||||
YYCC_DEFAULT_COPY_MOVE(Parser)
|
||||
static NS_YYCC_CLAP_TYPES::ClapResult<Resolver> from_user(
|
||||
const NS_YYCC_CLAP_APPLICATION::Application& app, const std::vector<std::pair<std::u8string_view, std::u8string_view>>& vars);
|
||||
static NS_YYCC_CLAP_TYPES::ClapResult<Resolver> from_system(const NS_YYCC_CLAP_APPLICATION::Application& app);
|
||||
|
||||
private:
|
||||
NS_YYCC_CLAP_TYPES::ClapResult<std::u8string_view> get_raw_value_option(NS_YYCC_CLAP_TYPES::Token token) const;
|
||||
Resolver(decltype(Resolver::values)&& values);
|
||||
|
||||
public:
|
||||
bool has_option(NS_YYCC_CLAP_TYPES::Token token) const;
|
||||
NS_YYCC_CLAP_TYPES::ClapResult<bool> get_flag_option(NS_YYCC_CLAP_TYPES::Token token) const;
|
||||
~Resolver();
|
||||
YYCC_DEFAULT_COPY_MOVE(Resolver)
|
||||
|
||||
private:
|
||||
NS_YYCC_CLAP_TYPES::ClapResult<std::u8string_view> get_raw_value_variable(NS_YYCC_CLAP_TYPES::Token token) const;
|
||||
|
||||
public:
|
||||
bool has_variable(NS_YYCC_CLAP_TYPES::Token token) const;
|
||||
NS_YYCC_CLAP_TYPES::ClapResult<bool> get_flag_variable(NS_YYCC_CLAP_TYPES::Token token) const;
|
||||
template<NS_YYCC_CLAP_VALIDATOR::Validator T>
|
||||
NS_YYCC_CLAP_TYPES::ClapResult<NS_YYCC_CLAP_VALIDATOR::ValidatorReturnType<T>> get_value_option(
|
||||
NS_YYCC_CLAP_TYPES::ClapResult<NS_YYCC_CLAP_VALIDATOR::ValidatorReturnType<T>> get_value_variable(
|
||||
NS_YYCC_CLAP_TYPES::Token token) const {
|
||||
auto raw_value = this->get_raw_value_option(token);
|
||||
auto raw_value = this->get_raw_value_variable(token);
|
||||
if (raw_value.has_value()) {
|
||||
T validator{};
|
||||
auto value = validator.validate(raw_value.value());
|
||||
@ -37,17 +56,10 @@ namespace yycc::carton::clap::resolver {
|
||||
return std::unexpected(raw_value.error())
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief All captured commandline argument.
|
||||
* @details Key is the token to already registered option.
|
||||
* Value is the associated value for key token.
|
||||
* If it is no-value option, the value will be \c std::nullopt.
|
||||
*/
|
||||
std::map<NS_YYCC_CLAP_TYPES::Token, std::optional<std::u8string>> values;
|
||||
};
|
||||
|
||||
} // namespace yycc::carton::clap::resolver
|
||||
|
||||
#undef NS_YYCC_CLAP_VALIDATOR
|
||||
#undef NS_YYCC_CLAP_APPLICATION
|
||||
#undef NS_YYCC_CLAP_TYPES
|
||||
|
||||
@ -9,7 +9,8 @@ namespace yycc::carton::clap::variable {
|
||||
|
||||
#pragma region Variable
|
||||
|
||||
Variable::Variable(const std::u8string_view &name, const std::u8string_view &description) : name(name), description(description) {
|
||||
Variable::Variable(const std::u8string_view &name, const std::u8string_view &description, bool care_value) :
|
||||
name(name), description(description), care_value(care_value) {
|
||||
if (name.empty()) {
|
||||
throw std::logic_error("the name of variable should not be empty");
|
||||
}
|
||||
@ -17,6 +18,10 @@ namespace yycc::carton::clap::variable {
|
||||
|
||||
Variable::~Variable() {}
|
||||
|
||||
bool Variable::is_care_value() const {
|
||||
return this->care_value;
|
||||
}
|
||||
|
||||
std::u8string_view Variable::get_name() const {
|
||||
return this->name;
|
||||
}
|
||||
|
||||
@ -12,15 +12,17 @@ namespace yycc::carton::clap::variable {
|
||||
|
||||
class Variable {
|
||||
public:
|
||||
Variable(const std::u8string_view& name, const std::u8string_view& description);
|
||||
Variable(const std::u8string_view& name, const std::u8string_view& description, bool care_value);
|
||||
~Variable();
|
||||
YYCC_DEFAULT_COPY_MOVE(Variable)
|
||||
|
||||
public:
|
||||
bool is_care_value() const;
|
||||
std::u8string_view get_name() const;
|
||||
std::u8string_view get_description() const;
|
||||
|
||||
private:
|
||||
bool care_value;
|
||||
std::u8string name;
|
||||
std::u8string description;
|
||||
};
|
||||
|
||||
@ -146,7 +146,7 @@ namespace yycc::env {
|
||||
#endif
|
||||
}
|
||||
|
||||
VarResult<std::vector<VarPair>> get_vars() {
|
||||
std::vector<VarPair> get_vars() {
|
||||
// TODO: finish this function according to Rust implementation.
|
||||
// Considering whether replace return value with an iterator.
|
||||
throw std::logic_error("not implemented");
|
||||
|
||||
@ -72,7 +72,7 @@ namespace yycc::env {
|
||||
* for all the environment variables of the current process.
|
||||
* @return The list holding all variables.
|
||||
*/
|
||||
VarResult<std::vector<VarPair>> get_vars();
|
||||
std::vector<VarPair> get_vars();
|
||||
|
||||
#pragma endregion
|
||||
|
||||
@ -131,7 +131,7 @@ namespace yycc::env {
|
||||
* @brief Returns the arguments that this program was started with (normally passed via the command line).
|
||||
* @return The list holding all argument one by one.
|
||||
*/
|
||||
ArgResult<std::vector<std::u8string>> get_args();
|
||||
std::vector<std::u8string> get_args();
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
Reference in New Issue
Block a user