106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci 1606f6ba60Sopenharmony_ci#ifndef COMMAND_LINE_FLAGS_H 1706f6ba60Sopenharmony_ci#define COMMAND_LINE_FLAGS_H 1806f6ba60Sopenharmony_ci#include <iostream> 1906f6ba60Sopenharmony_ci#include <string> 2006f6ba60Sopenharmony_ci#include <vector> 2106f6ba60Sopenharmony_ci#include <unordered_map> 2206f6ba60Sopenharmony_ci#include <cstddef> 2306f6ba60Sopenharmony_ci#include <inttypes.h> 2406f6ba60Sopenharmony_ci#include <cstdint> 2506f6ba60Sopenharmony_ci#include <type_traits> 2606f6ba60Sopenharmony_ci#include <typeinfo> 2706f6ba60Sopenharmony_ci#include <cstdlib> 2806f6ba60Sopenharmony_ci#include <climits> 2906f6ba60Sopenharmony_ci 3006f6ba60Sopenharmony_cinamespace CommandLineFlags { 3106f6ba60Sopenharmony_cienum class FlagTypes { 3206f6ba60Sopenharmony_ci FT_void, 3306f6ba60Sopenharmony_ci FT_bool, 3406f6ba60Sopenharmony_ci FT_int8, 3506f6ba60Sopenharmony_ci FT_int16, 3606f6ba60Sopenharmony_ci FT_int32, 3706f6ba60Sopenharmony_ci FT_int64, 3806f6ba60Sopenharmony_ci FT_uint8, 3906f6ba60Sopenharmony_ci FT_uint16, 4006f6ba60Sopenharmony_ci FT_uint32, 4106f6ba60Sopenharmony_ci FT_uint64, 4206f6ba60Sopenharmony_ci FT_double, 4306f6ba60Sopenharmony_ci FT_string, 4406f6ba60Sopenharmony_ci FT_bool_array, 4506f6ba60Sopenharmony_ci FT_int8_array, 4606f6ba60Sopenharmony_ci FT_int16_array, 4706f6ba60Sopenharmony_ci FT_int32_array, 4806f6ba60Sopenharmony_ci FT_int64_array, 4906f6ba60Sopenharmony_ci FT_uint8_array, 5006f6ba60Sopenharmony_ci FT_uint16_array, 5106f6ba60Sopenharmony_ci FT_uint32_array, 5206f6ba60Sopenharmony_ci FT_uint64_array, 5306f6ba60Sopenharmony_ci FT_double_array, 5406f6ba60Sopenharmony_ci FT_string_array, 5506f6ba60Sopenharmony_ci}; 5606f6ba60Sopenharmony_ci 5706f6ba60Sopenharmony_cistruct MetaFlag { 5806f6ba60Sopenharmony_ci FlagTypes type_ {FlagTypes::FT_void}; 5906f6ba60Sopenharmony_ci void* addr_ {nullptr}; 6006f6ba60Sopenharmony_ci MetaFlag() = default; 6106f6ba60Sopenharmony_ci MetaFlag(const FlagTypes& flagType, void* flagPtr): type_ {flagType}, addr_ {flagPtr} {} 6206f6ba60Sopenharmony_ci}; 6306f6ba60Sopenharmony_ci 6406f6ba60Sopenharmony_cistd::unordered_map<std::string, MetaFlag> flags_ {}; 6506f6ba60Sopenharmony_ci 6606f6ba60Sopenharmony_citemplate<typename T> 6706f6ba60Sopenharmony_ciclass FlagRegesterer { 6806f6ba60Sopenharmony_cipublic: 6906f6ba60Sopenharmony_ci FlagRegesterer(const std::string& name, const T& flag) 7006f6ba60Sopenharmony_ci { 7106f6ba60Sopenharmony_ci if (flags_.count(name) != 0) { 7206f6ba60Sopenharmony_ci std::cout << "CommandLineFlags WARN: flag " << name << " redefined" << std::endl; 7306f6ba60Sopenharmony_ci } else { 7406f6ba60Sopenharmony_ci auto& metaFlag = flags_[name]; 7506f6ba60Sopenharmony_ci metaFlag.addr_ = (void*) &flag; 7606f6ba60Sopenharmony_ci 7706f6ba60Sopenharmony_ci if (std::is_same<T, bool>::value) { 7806f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_bool; 7906f6ba60Sopenharmony_ci } else if (std::is_same<T, int8_t>::value) { 8006f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_int8; 8106f6ba60Sopenharmony_ci } else if (std::is_same<T, int16_t>::value) { 8206f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_int16; 8306f6ba60Sopenharmony_ci } else if (std::is_same<T, int32_t>::value) { 8406f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_int32; 8506f6ba60Sopenharmony_ci } else if (std::is_same<T, int64_t>::value) { 8606f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_int64; 8706f6ba60Sopenharmony_ci } else if (std::is_same<T, uint8_t>::value) { 8806f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_uint8; 8906f6ba60Sopenharmony_ci } else if (std::is_same<T, uint16_t>::value) { 9006f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_uint16; 9106f6ba60Sopenharmony_ci } else if (std::is_same<T, uint32_t>::value) { 9206f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_uint32; 9306f6ba60Sopenharmony_ci } else if (std::is_same<T, uint64_t>::value) { 9406f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_uint64; 9506f6ba60Sopenharmony_ci } else if (std::is_same<T, double>::value) { 9606f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_double; 9706f6ba60Sopenharmony_ci } else if (std::is_same<T, std::string>::value) { 9806f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_string; 9906f6ba60Sopenharmony_ci } else if (std::is_same<T, std::vector<bool>>::value) { 10006f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_bool_array; 10106f6ba60Sopenharmony_ci } else if (std::is_same<T, std::vector<int8_t>>::value) { 10206f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_int8_array; 10306f6ba60Sopenharmony_ci } else if (std::is_same<T, std::vector<int16_t>>::value) { 10406f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_int16_array; 10506f6ba60Sopenharmony_ci } else if (std::is_same<T, std::vector<int32_t>>::value) { 10606f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_int32_array; 10706f6ba60Sopenharmony_ci } else if (std::is_same<T, std::vector<int64_t>>::value) { 10806f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_int64_array; 10906f6ba60Sopenharmony_ci } else if (std::is_same<T, std::vector<uint8_t>>::value) { 11006f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_uint8_array; 11106f6ba60Sopenharmony_ci } else if (std::is_same<T, std::vector<uint16_t>>::value) { 11206f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_uint16_array; 11306f6ba60Sopenharmony_ci } else if (std::is_same<T, std::vector<uint32_t>>::value) { 11406f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_uint32_array; 11506f6ba60Sopenharmony_ci } else if (std::is_same<T, std::vector<uint64_t>>::value) { 11606f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_uint64_array; 11706f6ba60Sopenharmony_ci } else if (std::is_same<T, std::vector<double>>::value) { 11806f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_double_array; 11906f6ba60Sopenharmony_ci } else if (std::is_same<T, std::vector<std::string>>::value) { 12006f6ba60Sopenharmony_ci metaFlag.type_ = FlagTypes::FT_string_array; 12106f6ba60Sopenharmony_ci } 12206f6ba60Sopenharmony_ci } 12306f6ba60Sopenharmony_ci } 12406f6ba60Sopenharmony_ci}; 12506f6ba60Sopenharmony_ci 12606f6ba60Sopenharmony_cistatic inline void PrintArgFormat() 12706f6ba60Sopenharmony_ci{ 12806f6ba60Sopenharmony_ci std::string format {"Arguments Format: <command> -<character> <value> --<word>[-<word>] <value>"}; 12906f6ba60Sopenharmony_ci std::cout << format << std::endl; 13006f6ba60Sopenharmony_ci return; 13106f6ba60Sopenharmony_ci} 13206f6ba60Sopenharmony_ci 13306f6ba60Sopenharmony_cistatic inline std::string ConvertToFlagName(char* argStr, int argLen) 13406f6ba60Sopenharmony_ci{ 13506f6ba60Sopenharmony_ci for (int k = 0; k < argLen; ++k) { 13606f6ba60Sopenharmony_ci if (argStr[k] == '-') { 13706f6ba60Sopenharmony_ci if (argStr[k-1] == '-') { 13806f6ba60Sopenharmony_ci // continuous '-', bad argument 13906f6ba60Sopenharmony_ci return ""; 14006f6ba60Sopenharmony_ci } 14106f6ba60Sopenharmony_ci argStr[k] = '_'; 14206f6ba60Sopenharmony_ci } 14306f6ba60Sopenharmony_ci } 14406f6ba60Sopenharmony_ci return std::string(argStr, argLen); 14506f6ba60Sopenharmony_ci} 14606f6ba60Sopenharmony_ci 14706f6ba60Sopenharmony_cistatic int GetFlagName( 14806f6ba60Sopenharmony_ci char*** argv, 14906f6ba60Sopenharmony_ci int& argIndex, 15006f6ba60Sopenharmony_ci std::string& flagName) 15106f6ba60Sopenharmony_ci{ 15206f6ba60Sopenharmony_ci if ((*argv)[argIndex] == nullptr) { 15306f6ba60Sopenharmony_ci // argument has been removed, skip it 15406f6ba60Sopenharmony_ci flagName = ""; 15506f6ba60Sopenharmony_ci ++argIndex; 15606f6ba60Sopenharmony_ci return 0; 15706f6ba60Sopenharmony_ci } 15806f6ba60Sopenharmony_ci 15906f6ba60Sopenharmony_ci // get argument prefix length and argument length 16006f6ba60Sopenharmony_ci char* argStr = (*argv)[argIndex]; 16106f6ba60Sopenharmony_ci int prefix {0}; 16206f6ba60Sopenharmony_ci int argLen {0}; 16306f6ba60Sopenharmony_ci bool keepCounting {true}; 16406f6ba60Sopenharmony_ci for (; argStr[argLen] != '\0'; ++argLen) { 16506f6ba60Sopenharmony_ci if (argStr[argLen] != '-') { 16606f6ba60Sopenharmony_ci keepCounting = false; 16706f6ba60Sopenharmony_ci } 16806f6ba60Sopenharmony_ci if (keepCounting and argStr[argLen] == '-') { 16906f6ba60Sopenharmony_ci ++prefix; 17006f6ba60Sopenharmony_ci } 17106f6ba60Sopenharmony_ci } 17206f6ba60Sopenharmony_ci argLen -= prefix; 17306f6ba60Sopenharmony_ci 17406f6ba60Sopenharmony_ci // short argument 17506f6ba60Sopenharmony_ci constexpr int shortFlagLen {1}; 17606f6ba60Sopenharmony_ci if (prefix == shortFlagLen and argLen == shortFlagLen) { 17706f6ba60Sopenharmony_ci flagName = std::string(argStr + prefix, argLen); 17806f6ba60Sopenharmony_ci ++argIndex; 17906f6ba60Sopenharmony_ci return 0; 18006f6ba60Sopenharmony_ci } 18106f6ba60Sopenharmony_ci 18206f6ba60Sopenharmony_ci // long argument 18306f6ba60Sopenharmony_ci constexpr int longPrefix {2}; 18406f6ba60Sopenharmony_ci if (prefix == longPrefix and argLen > shortFlagLen) { 18506f6ba60Sopenharmony_ci flagName = ConvertToFlagName(argStr + longPrefix, argLen); 18606f6ba60Sopenharmony_ci if (flagName.empty()) { 18706f6ba60Sopenharmony_ci // bad argument 18806f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: unrecognized argument format: " 18906f6ba60Sopenharmony_ci << argStr << std::endl; 19006f6ba60Sopenharmony_ci PrintArgFormat(); 19106f6ba60Sopenharmony_ci return -1; 19206f6ba60Sopenharmony_ci } 19306f6ba60Sopenharmony_ci ++argIndex; 19406f6ba60Sopenharmony_ci return 0; 19506f6ba60Sopenharmony_ci } 19606f6ba60Sopenharmony_ci // bad argument 19706f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: unrecognized argument format: " 19806f6ba60Sopenharmony_ci << argStr << std::endl; 19906f6ba60Sopenharmony_ci PrintArgFormat(); 20006f6ba60Sopenharmony_ci return -1; 20106f6ba60Sopenharmony_ci} 20206f6ba60Sopenharmony_ci 20306f6ba60Sopenharmony_cistatic int GetFlagValue( 20406f6ba60Sopenharmony_ci char*** argv, 20506f6ba60Sopenharmony_ci int& argIndex, 20606f6ba60Sopenharmony_ci std::string& flagValue) 20706f6ba60Sopenharmony_ci{ 20806f6ba60Sopenharmony_ci if ((*argv)[argIndex] == nullptr) { 20906f6ba60Sopenharmony_ci // arg removed, skip it 21006f6ba60Sopenharmony_ci flagValue = ""; 21106f6ba60Sopenharmony_ci ++argIndex; 21206f6ba60Sopenharmony_ci return 0; 21306f6ba60Sopenharmony_ci } 21406f6ba60Sopenharmony_ci char* argStr = (*argv)[argIndex]; 21506f6ba60Sopenharmony_ci int argLen {0}; 21606f6ba60Sopenharmony_ci for (; argStr[argLen] != '\0'; ++argLen); 21706f6ba60Sopenharmony_ci flagValue = std::string(argStr, argLen); 21806f6ba60Sopenharmony_ci ++argIndex; 21906f6ba60Sopenharmony_ci return 0; 22006f6ba60Sopenharmony_ci} 22106f6ba60Sopenharmony_ci 22206f6ba60Sopenharmony_cistatic void ClearCString(char* str) 22306f6ba60Sopenharmony_ci{ 22406f6ba60Sopenharmony_ci if (str == nullptr) { 22506f6ba60Sopenharmony_ci return; 22606f6ba60Sopenharmony_ci } 22706f6ba60Sopenharmony_ci for (int k = 0; ; ++k) { 22806f6ba60Sopenharmony_ci if (str[k] == '\0') { 22906f6ba60Sopenharmony_ci break; 23006f6ba60Sopenharmony_ci } 23106f6ba60Sopenharmony_ci str[k] = '\0'; 23206f6ba60Sopenharmony_ci } 23306f6ba60Sopenharmony_ci return; 23406f6ba60Sopenharmony_ci} 23506f6ba60Sopenharmony_ci 23606f6ba60Sopenharmony_cistatic int GetNextFlag( 23706f6ba60Sopenharmony_ci char*** argv, 23806f6ba60Sopenharmony_ci int& argIndex, 23906f6ba60Sopenharmony_ci bool rm, 24006f6ba60Sopenharmony_ci std::string& flagName, 24106f6ba60Sopenharmony_ci std::string& flagValue) 24206f6ba60Sopenharmony_ci{ 24306f6ba60Sopenharmony_ci if (GetFlagName(argv, argIndex, flagName) != 0) { 24406f6ba60Sopenharmony_ci return -1; 24506f6ba60Sopenharmony_ci } 24606f6ba60Sopenharmony_ci GetFlagValue(argv, argIndex, flagValue); 24706f6ba60Sopenharmony_ci // flag parsing done 24806f6ba60Sopenharmony_ci if (rm and flags_.count(flagName) != 0) { 24906f6ba60Sopenharmony_ci // remove parsed argument and its value 25006f6ba60Sopenharmony_ci ClearCString((*argv)[argIndex - 1]); 25106f6ba60Sopenharmony_ci ClearCString((*argv)[argIndex - 2]); // 2: point of args 25206f6ba60Sopenharmony_ci } 25306f6ba60Sopenharmony_ci return 0; 25406f6ba60Sopenharmony_ci} 25506f6ba60Sopenharmony_ci 25606f6ba60Sopenharmony_cistatic int ParseBoolFlag(const std::string& flag, const std::string& valStr) 25706f6ba60Sopenharmony_ci{ 25806f6ba60Sopenharmony_ci bool *val = (bool*) flags_[flag].addr_; 25906f6ba60Sopenharmony_ci if (valStr.compare("false") == 0) { 26006f6ba60Sopenharmony_ci *val = false; 26106f6ba60Sopenharmony_ci } else if (valStr.compare("true") == 0) { 26206f6ba60Sopenharmony_ci *val = true; 26306f6ba60Sopenharmony_ci } else { 26406f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 26506f6ba60Sopenharmony_ci << " of bool type should only be assigned with 'true' or 'false' but " 26606f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 26706f6ba60Sopenharmony_ci return -1; 26806f6ba60Sopenharmony_ci } 26906f6ba60Sopenharmony_ci return 0; 27006f6ba60Sopenharmony_ci} 27106f6ba60Sopenharmony_ci 27206f6ba60Sopenharmony_ci// we will not handle any exceptions thrown by std::stoi() series functions, we should 27306f6ba60Sopenharmony_ci// just let exceptions abort the process. 27406f6ba60Sopenharmony_cistatic int ParseInt8Flag(const std::string& flag, const std::string& valStr) 27506f6ba60Sopenharmony_ci{ 27606f6ba60Sopenharmony_ci char* pos = nullptr; 27706f6ba60Sopenharmony_ci long int tmpVal = strtol(valStr.c_str(), &pos, 10); 27806f6ba60Sopenharmony_ci if (tmpVal == 0L || tmpVal == LONG_MAX || tmpVal == LONG_MIN) { 27906f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 28006f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 28106f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 28206f6ba60Sopenharmony_ci return -1; 28306f6ba60Sopenharmony_ci } 28406f6ba60Sopenharmony_ci int8_t* val = (int8_t*) flags_[flag].addr_; 28506f6ba60Sopenharmony_ci *val = static_cast<int8_t>(tmpVal); 28606f6ba60Sopenharmony_ci return 0; 28706f6ba60Sopenharmony_ci} 28806f6ba60Sopenharmony_ci 28906f6ba60Sopenharmony_cistatic int ParseInt16Flag(const std::string& flag, const std::string& valStr) 29006f6ba60Sopenharmony_ci{ 29106f6ba60Sopenharmony_ci char* pos = nullptr; 29206f6ba60Sopenharmony_ci long int tmpVal = strtol(valStr.c_str(), &pos, 10); 29306f6ba60Sopenharmony_ci if (tmpVal == 0L || tmpVal == LONG_MAX || tmpVal == LONG_MIN) { 29406f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 29506f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 29606f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 29706f6ba60Sopenharmony_ci return -1; 29806f6ba60Sopenharmony_ci } 29906f6ba60Sopenharmony_ci int16_t* val = (int16_t*) flags_[flag].addr_; 30006f6ba60Sopenharmony_ci *val = static_cast<int16_t>(tmpVal); 30106f6ba60Sopenharmony_ci return 0; 30206f6ba60Sopenharmony_ci} 30306f6ba60Sopenharmony_ci 30406f6ba60Sopenharmony_cistatic int ParseInt32Flag(const std::string& flag, const std::string& valStr) 30506f6ba60Sopenharmony_ci{ 30606f6ba60Sopenharmony_ci char* pos = nullptr; 30706f6ba60Sopenharmony_ci long int tmpVal = strtol(valStr.c_str(), &pos, 10); 30806f6ba60Sopenharmony_ci if (tmpVal == 0L || tmpVal == LONG_MAX || tmpVal == LONG_MIN) { 30906f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 31006f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 31106f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 31206f6ba60Sopenharmony_ci return -1; 31306f6ba60Sopenharmony_ci } 31406f6ba60Sopenharmony_ci int32_t* val = (int32_t*) flags_[flag].addr_; 31506f6ba60Sopenharmony_ci *val = static_cast<int32_t>(tmpVal); 31606f6ba60Sopenharmony_ci return 0; 31706f6ba60Sopenharmony_ci} 31806f6ba60Sopenharmony_ci 31906f6ba60Sopenharmony_cistatic int ParseInt64Flag(const std::string& flag, const std::string& valStr) 32006f6ba60Sopenharmony_ci{ 32106f6ba60Sopenharmony_ci char* pos = nullptr; 32206f6ba60Sopenharmony_ci long int tmpVal = strtol(valStr.c_str(), &pos, 10); 32306f6ba60Sopenharmony_ci if (tmpVal == 0L || tmpVal == LONG_MAX || tmpVal == LONG_MIN) { 32406f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 32506f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 32606f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 32706f6ba60Sopenharmony_ci return -1; 32806f6ba60Sopenharmony_ci } 32906f6ba60Sopenharmony_ci int64_t* val = (int64_t*) flags_[flag].addr_; 33006f6ba60Sopenharmony_ci *val = static_cast<int64_t>(tmpVal); 33106f6ba60Sopenharmony_ci return 0; 33206f6ba60Sopenharmony_ci} 33306f6ba60Sopenharmony_ci 33406f6ba60Sopenharmony_cistatic int ParseUint8Flag(const std::string& flag, const std::string& valStr) 33506f6ba60Sopenharmony_ci{ 33606f6ba60Sopenharmony_ci char* pos = nullptr; 33706f6ba60Sopenharmony_ci unsigned long long int tmpVal = strtoull(valStr.c_str(), &pos, 10); 33806f6ba60Sopenharmony_ci if (tmpVal == 0ULL || tmpVal == ULONG_MAX) { 33906f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 34006f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 34106f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 34206f6ba60Sopenharmony_ci return -1; 34306f6ba60Sopenharmony_ci } 34406f6ba60Sopenharmony_ci uint8_t* val = (uint8_t*) flags_[flag].addr_; 34506f6ba60Sopenharmony_ci *val = static_cast<uint8_t>(tmpVal); 34606f6ba60Sopenharmony_ci return 0; 34706f6ba60Sopenharmony_ci} 34806f6ba60Sopenharmony_ci 34906f6ba60Sopenharmony_cistatic int ParseUint16Flag(const std::string& flag, const std::string& valStr) 35006f6ba60Sopenharmony_ci{ 35106f6ba60Sopenharmony_ci char* pos = nullptr; 35206f6ba60Sopenharmony_ci unsigned long long int tmpVal = strtoull(valStr.c_str(), &pos, 10); 35306f6ba60Sopenharmony_ci if (tmpVal == 0ULL || tmpVal == ULONG_MAX) { 35406f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 35506f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 35606f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 35706f6ba60Sopenharmony_ci return -1; 35806f6ba60Sopenharmony_ci } 35906f6ba60Sopenharmony_ci uint16_t* val = (uint16_t*) flags_[flag].addr_; 36006f6ba60Sopenharmony_ci *val = static_cast<uint16_t>(tmpVal); 36106f6ba60Sopenharmony_ci return 0; 36206f6ba60Sopenharmony_ci} 36306f6ba60Sopenharmony_ci 36406f6ba60Sopenharmony_cistatic int ParseUint32Flag(const std::string& flag, const std::string& valStr) 36506f6ba60Sopenharmony_ci{ 36606f6ba60Sopenharmony_ci char* pos = nullptr; 36706f6ba60Sopenharmony_ci unsigned long long int tmpVal = strtoull(valStr.c_str(), &pos, 10); 36806f6ba60Sopenharmony_ci if (tmpVal == 0ULL || tmpVal == ULONG_MAX) { 36906f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 37006f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 37106f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 37206f6ba60Sopenharmony_ci return -1; 37306f6ba60Sopenharmony_ci } 37406f6ba60Sopenharmony_ci uint32_t* val = (uint32_t*) flags_[flag].addr_; 37506f6ba60Sopenharmony_ci *val = static_cast<uint32_t>(tmpVal); 37606f6ba60Sopenharmony_ci return 0; 37706f6ba60Sopenharmony_ci} 37806f6ba60Sopenharmony_ci 37906f6ba60Sopenharmony_cistatic int ParseUint64Flag(const std::string& flag, const std::string& valStr) 38006f6ba60Sopenharmony_ci{ 38106f6ba60Sopenharmony_ci char* pos = nullptr; 38206f6ba60Sopenharmony_ci unsigned long long int tmpVal = strtoull(valStr.c_str(), &pos, 10); 38306f6ba60Sopenharmony_ci if (tmpVal == 0ULL || tmpVal == ULONG_MAX) { 38406f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 38506f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 38606f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 38706f6ba60Sopenharmony_ci return -1; 38806f6ba60Sopenharmony_ci } 38906f6ba60Sopenharmony_ci uint64_t* val = (uint64_t*) flags_[flag].addr_; 39006f6ba60Sopenharmony_ci *val = static_cast<uint64_t>(tmpVal); 39106f6ba60Sopenharmony_ci return 0; 39206f6ba60Sopenharmony_ci} 39306f6ba60Sopenharmony_ci 39406f6ba60Sopenharmony_cistatic int ParseDoubleFlag(const std::string& flag, const std::string& valStr) 39506f6ba60Sopenharmony_ci{ 39606f6ba60Sopenharmony_ci char* pos = nullptr; 39706f6ba60Sopenharmony_ci double tmpVal = strtod(valStr.c_str(), &pos); 39806f6ba60Sopenharmony_ci if (tmpVal == 0.0 || tmpVal == HUGE_VAL) { 39906f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 40006f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 40106f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 40206f6ba60Sopenharmony_ci return -1; 40306f6ba60Sopenharmony_ci } 40406f6ba60Sopenharmony_ci double* val = (double*) flags_[flag].addr_; 40506f6ba60Sopenharmony_ci *val = tmpVal; 40606f6ba60Sopenharmony_ci return 0; 40706f6ba60Sopenharmony_ci} 40806f6ba60Sopenharmony_ci 40906f6ba60Sopenharmony_cistatic int ParseStringFlag(const std::string& flag, const std::string& valStr) 41006f6ba60Sopenharmony_ci{ 41106f6ba60Sopenharmony_ci std::string* val = (std::string*) flags_[flag].addr_; 41206f6ba60Sopenharmony_ci *val = valStr; 41306f6ba60Sopenharmony_ci return 0; 41406f6ba60Sopenharmony_ci} 41506f6ba60Sopenharmony_ci 41606f6ba60Sopenharmony_cistatic int ParseBoolArrayFlag(const std::string& flag, const std::string& valStr) 41706f6ba60Sopenharmony_ci{ 41806f6ba60Sopenharmony_ci std::vector<bool>* val = (std::vector<bool>*) flags_[flag].addr_; 41906f6ba60Sopenharmony_ci for (std::size_t start = 0, end = 0; end <= valStr.length(); ++end) { 42006f6ba60Sopenharmony_ci if (valStr[end] == ',' or end == valStr.length()) { 42106f6ba60Sopenharmony_ci if (start == end) { 42206f6ba60Sopenharmony_ci ++start; 42306f6ba60Sopenharmony_ci continue; 42406f6ba60Sopenharmony_ci } 42506f6ba60Sopenharmony_ci auto str = valStr.substr(start, end - start); 42606f6ba60Sopenharmony_ci if (str.compare("false") == 0) { 42706f6ba60Sopenharmony_ci val->push_back(false); 42806f6ba60Sopenharmony_ci } else if (str.compare("true") == 0) { 42906f6ba60Sopenharmony_ci val->push_back(true); 43006f6ba60Sopenharmony_ci } else { 43106f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 43206f6ba60Sopenharmony_ci << " of bool type should only be assigned with 'true' or 'false' but " 43306f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 43406f6ba60Sopenharmony_ci val->clear(); 43506f6ba60Sopenharmony_ci return -1; 43606f6ba60Sopenharmony_ci } 43706f6ba60Sopenharmony_ci start = end + 1; 43806f6ba60Sopenharmony_ci } 43906f6ba60Sopenharmony_ci } 44006f6ba60Sopenharmony_ci return 0; 44106f6ba60Sopenharmony_ci} 44206f6ba60Sopenharmony_ci 44306f6ba60Sopenharmony_cistatic int ParseInt8ArrayFlag(const std::string& flag, const std::string& valStr) 44406f6ba60Sopenharmony_ci{ 44506f6ba60Sopenharmony_ci std::vector<int8_t>* val = (std::vector<int8_t>*) flags_[flag].addr_; 44606f6ba60Sopenharmony_ci for (std::size_t start = 0, end = 0; end <= valStr.length(); ++end) { 44706f6ba60Sopenharmony_ci if (valStr[end] == ',' or end == valStr.length()) { 44806f6ba60Sopenharmony_ci if (start == end) { 44906f6ba60Sopenharmony_ci ++start; 45006f6ba60Sopenharmony_ci continue; 45106f6ba60Sopenharmony_ci } 45206f6ba60Sopenharmony_ci auto str = valStr.substr(start, end - start); 45306f6ba60Sopenharmony_ci char* pos = nullptr; 45406f6ba60Sopenharmony_ci long int tmpVal = strtol(valStr.c_str(), &pos, 10); 45506f6ba60Sopenharmony_ci if (tmpVal == 0L || tmpVal == LONG_MAX || tmpVal == LONG_MIN) { 45606f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 45706f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 45806f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 45906f6ba60Sopenharmony_ci val->clear(); 46006f6ba60Sopenharmony_ci return -1; 46106f6ba60Sopenharmony_ci } 46206f6ba60Sopenharmony_ci val->push_back(static_cast<int8_t>(tmpVal)); 46306f6ba60Sopenharmony_ci start = end + 1; 46406f6ba60Sopenharmony_ci } 46506f6ba60Sopenharmony_ci } 46606f6ba60Sopenharmony_ci return 0; 46706f6ba60Sopenharmony_ci} 46806f6ba60Sopenharmony_ci 46906f6ba60Sopenharmony_cistatic int ParseInt16ArrayFlag(const std::string& flag, const std::string& valStr) 47006f6ba60Sopenharmony_ci{ 47106f6ba60Sopenharmony_ci std::vector<int16_t>* val = (std::vector<int16_t>*) flags_[flag].addr_; 47206f6ba60Sopenharmony_ci for (std::size_t start = 0, end = 0; end <= valStr.length(); ++end) { 47306f6ba60Sopenharmony_ci if (valStr[end] == ',' or end == valStr.length()) { 47406f6ba60Sopenharmony_ci if (start == end) { 47506f6ba60Sopenharmony_ci ++start; 47606f6ba60Sopenharmony_ci continue; 47706f6ba60Sopenharmony_ci } 47806f6ba60Sopenharmony_ci auto str = valStr.substr(start, end - start); 47906f6ba60Sopenharmony_ci char* pos = nullptr; 48006f6ba60Sopenharmony_ci long int tmpVal = strtol(valStr.c_str(), &pos, 10); 48106f6ba60Sopenharmony_ci if (tmpVal == 0L || tmpVal == LONG_MAX || tmpVal == LONG_MIN) { 48206f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 48306f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 48406f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 48506f6ba60Sopenharmony_ci val->clear(); 48606f6ba60Sopenharmony_ci return -1; 48706f6ba60Sopenharmony_ci } 48806f6ba60Sopenharmony_ci val->push_back(static_cast<int16_t>(tmpVal)); 48906f6ba60Sopenharmony_ci start = end + 1; 49006f6ba60Sopenharmony_ci } 49106f6ba60Sopenharmony_ci } 49206f6ba60Sopenharmony_ci return 0; 49306f6ba60Sopenharmony_ci} 49406f6ba60Sopenharmony_ci 49506f6ba60Sopenharmony_cistatic int ParseInt32ArrayFlag(const std::string& flag, const std::string& valStr) 49606f6ba60Sopenharmony_ci{ 49706f6ba60Sopenharmony_ci std::vector<int32_t>* val = (std::vector<int32_t>*) flags_[flag].addr_; 49806f6ba60Sopenharmony_ci for (std::size_t start = 0, end = 0; end <= valStr.length(); ++end) { 49906f6ba60Sopenharmony_ci if (valStr[end] == ',' or end == valStr.length()) { 50006f6ba60Sopenharmony_ci if (start == end) { 50106f6ba60Sopenharmony_ci ++start; 50206f6ba60Sopenharmony_ci continue; 50306f6ba60Sopenharmony_ci } 50406f6ba60Sopenharmony_ci auto str = valStr.substr(start, end - start); 50506f6ba60Sopenharmony_ci char* pos = nullptr; 50606f6ba60Sopenharmony_ci long int tmpVal = strtol(valStr.c_str(), &pos, 10); 50706f6ba60Sopenharmony_ci if (tmpVal == 0L || tmpVal == LONG_MAX || tmpVal == LONG_MIN) { 50806f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 50906f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 51006f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 51106f6ba60Sopenharmony_ci val->clear(); 51206f6ba60Sopenharmony_ci return -1; 51306f6ba60Sopenharmony_ci } 51406f6ba60Sopenharmony_ci val->push_back(static_cast<int32_t>(tmpVal)); 51506f6ba60Sopenharmony_ci start = end + 1; 51606f6ba60Sopenharmony_ci } 51706f6ba60Sopenharmony_ci } 51806f6ba60Sopenharmony_ci return 0; 51906f6ba60Sopenharmony_ci} 52006f6ba60Sopenharmony_ci 52106f6ba60Sopenharmony_cistatic int ParseInt64ArrayFlag(const std::string& flag, const std::string& valStr) 52206f6ba60Sopenharmony_ci{ 52306f6ba60Sopenharmony_ci std::vector<int64_t>* val = (std::vector<int64_t>*) flags_[flag].addr_; 52406f6ba60Sopenharmony_ci for (std::size_t start = 0, end = 0; end <= valStr.length(); ++end) { 52506f6ba60Sopenharmony_ci if (valStr[end] == ',' or end == valStr.length()) { 52606f6ba60Sopenharmony_ci if (start == end) { 52706f6ba60Sopenharmony_ci ++start; 52806f6ba60Sopenharmony_ci continue; 52906f6ba60Sopenharmony_ci } 53006f6ba60Sopenharmony_ci auto str = valStr.substr(start, end - start); 53106f6ba60Sopenharmony_ci char* pos = nullptr; 53206f6ba60Sopenharmony_ci long int tmpVal = strtol(valStr.c_str(), &pos, 10); 53306f6ba60Sopenharmony_ci if (tmpVal == 0L || tmpVal == LONG_MAX || tmpVal == LONG_MIN) { 53406f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 53506f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 53606f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 53706f6ba60Sopenharmony_ci val->clear(); 53806f6ba60Sopenharmony_ci return -1; 53906f6ba60Sopenharmony_ci } 54006f6ba60Sopenharmony_ci val->push_back(static_cast<int64_t>(tmpVal)); 54106f6ba60Sopenharmony_ci start = end + 1; 54206f6ba60Sopenharmony_ci } 54306f6ba60Sopenharmony_ci } 54406f6ba60Sopenharmony_ci return 0; 54506f6ba60Sopenharmony_ci} 54606f6ba60Sopenharmony_ci 54706f6ba60Sopenharmony_cistatic int ParseUint8ArrayFlag(const std::string& flag, const std::string& valStr) 54806f6ba60Sopenharmony_ci{ 54906f6ba60Sopenharmony_ci std::vector<uint8_t>* val = (std::vector<uint8_t>*) flags_[flag].addr_; 55006f6ba60Sopenharmony_ci for (std::size_t start = 0, end = 0; end <= valStr.length(); ++end) { 55106f6ba60Sopenharmony_ci if (valStr[end] == ',' or end == valStr.length()) { 55206f6ba60Sopenharmony_ci if (start == end) { 55306f6ba60Sopenharmony_ci ++start; 55406f6ba60Sopenharmony_ci continue; 55506f6ba60Sopenharmony_ci } 55606f6ba60Sopenharmony_ci auto str = valStr.substr(start, end - start); 55706f6ba60Sopenharmony_ci char* pos = nullptr; 55806f6ba60Sopenharmony_ci unsigned long long int tmpVal = strtoull(valStr.c_str(), &pos, 10); 55906f6ba60Sopenharmony_ci if (tmpVal == 0ULL || tmpVal == ULONG_MAX) { 56006f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 56106f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 56206f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 56306f6ba60Sopenharmony_ci val->clear(); 56406f6ba60Sopenharmony_ci return -1; 56506f6ba60Sopenharmony_ci } 56606f6ba60Sopenharmony_ci val->push_back(static_cast<uint8_t>(tmpVal)); 56706f6ba60Sopenharmony_ci start = end + 1; 56806f6ba60Sopenharmony_ci } 56906f6ba60Sopenharmony_ci } 57006f6ba60Sopenharmony_ci return 0; 57106f6ba60Sopenharmony_ci} 57206f6ba60Sopenharmony_ci 57306f6ba60Sopenharmony_cistatic int ParseUint16ArrayFlag(const std::string& flag, const std::string& valStr) 57406f6ba60Sopenharmony_ci{ 57506f6ba60Sopenharmony_ci std::vector<uint16_t>* val = (std::vector<uint16_t>*) flags_[flag].addr_; 57606f6ba60Sopenharmony_ci for (std::size_t start = 0, end = 0; end <= valStr.length(); ++end) { 57706f6ba60Sopenharmony_ci if (valStr[end] == ',' or end == valStr.length()) { 57806f6ba60Sopenharmony_ci if (start == end) { 57906f6ba60Sopenharmony_ci ++start; 58006f6ba60Sopenharmony_ci continue; 58106f6ba60Sopenharmony_ci } 58206f6ba60Sopenharmony_ci auto str = valStr.substr(start, end - start); 58306f6ba60Sopenharmony_ci char* pos = nullptr; 58406f6ba60Sopenharmony_ci unsigned long long int tmpVal = strtoull(valStr.c_str(), &pos, 10); 58506f6ba60Sopenharmony_ci if (tmpVal == 0ULL || tmpVal == ULONG_MAX) { 58606f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 58706f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 58806f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 58906f6ba60Sopenharmony_ci val->clear(); 59006f6ba60Sopenharmony_ci return -1; 59106f6ba60Sopenharmony_ci } 59206f6ba60Sopenharmony_ci val->push_back(static_cast<uint16_t>(tmpVal)); 59306f6ba60Sopenharmony_ci start = end + 1; 59406f6ba60Sopenharmony_ci } 59506f6ba60Sopenharmony_ci } 59606f6ba60Sopenharmony_ci return 0; 59706f6ba60Sopenharmony_ci} 59806f6ba60Sopenharmony_ci 59906f6ba60Sopenharmony_cistatic int ParseUint32ArrayFlag(const std::string& flag, const std::string& valStr) 60006f6ba60Sopenharmony_ci{ 60106f6ba60Sopenharmony_ci std::vector<uint32_t>* val = (std::vector<uint32_t>*) flags_[flag].addr_; 60206f6ba60Sopenharmony_ci for (std::size_t start = 0, end = 0; end <= valStr.length(); ++end) { 60306f6ba60Sopenharmony_ci if (valStr[end] == ',' or end == valStr.length()) { 60406f6ba60Sopenharmony_ci if (start == end) { 60506f6ba60Sopenharmony_ci ++start; 60606f6ba60Sopenharmony_ci continue; 60706f6ba60Sopenharmony_ci } 60806f6ba60Sopenharmony_ci auto str = valStr.substr(start, end - start); 60906f6ba60Sopenharmony_ci char* pos = nullptr; 61006f6ba60Sopenharmony_ci unsigned long long int tmpVal = strtoull(valStr.c_str(), &pos, 10); 61106f6ba60Sopenharmony_ci if (tmpVal == 0ULL || tmpVal == ULONG_MAX) { 61206f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 61306f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 61406f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 61506f6ba60Sopenharmony_ci val->clear(); 61606f6ba60Sopenharmony_ci return -1; 61706f6ba60Sopenharmony_ci } 61806f6ba60Sopenharmony_ci val->push_back(static_cast<uint32_t>(tmpVal)); 61906f6ba60Sopenharmony_ci start = end + 1; 62006f6ba60Sopenharmony_ci } 62106f6ba60Sopenharmony_ci } 62206f6ba60Sopenharmony_ci return 0; 62306f6ba60Sopenharmony_ci} 62406f6ba60Sopenharmony_ci 62506f6ba60Sopenharmony_cistatic int ParseUint64ArrayFlag(const std::string& flag, const std::string& valStr) 62606f6ba60Sopenharmony_ci{ 62706f6ba60Sopenharmony_ci std::vector<uint64_t>* val = (std::vector<uint64_t>*) flags_[flag].addr_; 62806f6ba60Sopenharmony_ci for (std::size_t start = 0, end = 0; end <= valStr.length(); ++end) { 62906f6ba60Sopenharmony_ci if (valStr[end] == ',' or end == valStr.length()) { 63006f6ba60Sopenharmony_ci if (start == end) { 63106f6ba60Sopenharmony_ci ++start; 63206f6ba60Sopenharmony_ci continue; 63306f6ba60Sopenharmony_ci } 63406f6ba60Sopenharmony_ci auto str = valStr.substr(start, end - start); 63506f6ba60Sopenharmony_ci char* pos = nullptr; 63606f6ba60Sopenharmony_ci unsigned long long int tmpVal = strtoull(valStr.c_str(), &pos, 10); 63706f6ba60Sopenharmony_ci if (tmpVal == 0ULL || tmpVal == ULONG_MAX) { 63806f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 63906f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 64006f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 64106f6ba60Sopenharmony_ci val->clear(); 64206f6ba60Sopenharmony_ci return -1; 64306f6ba60Sopenharmony_ci } 64406f6ba60Sopenharmony_ci val->push_back(static_cast<uint64_t>(tmpVal)); 64506f6ba60Sopenharmony_ci start = end + 1; 64606f6ba60Sopenharmony_ci } 64706f6ba60Sopenharmony_ci } 64806f6ba60Sopenharmony_ci return 0; 64906f6ba60Sopenharmony_ci} 65006f6ba60Sopenharmony_ci 65106f6ba60Sopenharmony_cistatic int ParseDoubleArrayFlag(const std::string& flag, const std::string& valStr) 65206f6ba60Sopenharmony_ci{ 65306f6ba60Sopenharmony_ci std::vector<double>* val = (std::vector<double>*) flags_[flag].addr_; 65406f6ba60Sopenharmony_ci for (std::size_t start = 0, end = 0; end <= valStr.length(); ++end) { 65506f6ba60Sopenharmony_ci if (valStr[end] == ',' or end == valStr.length()) { 65606f6ba60Sopenharmony_ci if (start == end) { 65706f6ba60Sopenharmony_ci ++start; 65806f6ba60Sopenharmony_ci continue; 65906f6ba60Sopenharmony_ci } 66006f6ba60Sopenharmony_ci auto str = valStr.substr(start, end - start); 66106f6ba60Sopenharmony_ci char* pos = nullptr; 66206f6ba60Sopenharmony_ci double tmpVal = strtod(valStr.c_str(), &pos); 66306f6ba60Sopenharmony_ci if (tmpVal == 0.0 || tmpVal == HUGE_VAL) { 66406f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROR: argument " << flag 66506f6ba60Sopenharmony_ci << " of numeric type should only be assigned with number but " 66606f6ba60Sopenharmony_ci << valStr << " is given" << std::endl; 66706f6ba60Sopenharmony_ci val->clear(); 66806f6ba60Sopenharmony_ci return -1; 66906f6ba60Sopenharmony_ci } 67006f6ba60Sopenharmony_ci val->push_back(tmpVal); 67106f6ba60Sopenharmony_ci start = end + 1; 67206f6ba60Sopenharmony_ci } 67306f6ba60Sopenharmony_ci } 67406f6ba60Sopenharmony_ci return 0; 67506f6ba60Sopenharmony_ci} 67606f6ba60Sopenharmony_ci 67706f6ba60Sopenharmony_cistatic int ParseStringArrayFlag(const std::string& flag, const std::string& valStr) 67806f6ba60Sopenharmony_ci{ 67906f6ba60Sopenharmony_ci std::vector<std::string>* val = (std::vector<std::string>*) flags_[flag].addr_; 68006f6ba60Sopenharmony_ci for (std::size_t start = 0, end = 0; end <= valStr.length(); ++end) { 68106f6ba60Sopenharmony_ci if (valStr[end] == ',' or end == valStr.length()) { 68206f6ba60Sopenharmony_ci if (start == end) { 68306f6ba60Sopenharmony_ci ++start; 68406f6ba60Sopenharmony_ci continue; 68506f6ba60Sopenharmony_ci } 68606f6ba60Sopenharmony_ci val->emplace_back(valStr.c_str() + start, end - start); 68706f6ba60Sopenharmony_ci start = end + 1; 68806f6ba60Sopenharmony_ci } 68906f6ba60Sopenharmony_ci } 69006f6ba60Sopenharmony_ci return 0; 69106f6ba60Sopenharmony_ci} 69206f6ba60Sopenharmony_ci 69306f6ba60Sopenharmony_cistatic int ParseFlag(const std::string& flagName, const std::string flagValue) 69406f6ba60Sopenharmony_ci{ 69506f6ba60Sopenharmony_ci int ret {0}; 69606f6ba60Sopenharmony_ci switch (flags_[flagName].type_) { 69706f6ba60Sopenharmony_ci case FlagTypes::FT_bool: ret = ParseBoolFlag(flagName, flagValue); break; 69806f6ba60Sopenharmony_ci case FlagTypes::FT_int8: ret = ParseInt8Flag(flagName, flagValue); break; 69906f6ba60Sopenharmony_ci case FlagTypes::FT_int16: ret = ParseInt16Flag(flagName, flagValue); break; 70006f6ba60Sopenharmony_ci case FlagTypes::FT_int32: ret = ParseInt32Flag(flagName, flagValue); break; 70106f6ba60Sopenharmony_ci case FlagTypes::FT_int64: ret = ParseInt64Flag(flagName, flagValue); break; 70206f6ba60Sopenharmony_ci case FlagTypes::FT_uint8: ret = ParseUint8Flag(flagName, flagValue); break; 70306f6ba60Sopenharmony_ci case FlagTypes::FT_uint16: ret = ParseUint16Flag(flagName, flagValue); break; 70406f6ba60Sopenharmony_ci case FlagTypes::FT_uint32: ret = ParseUint32Flag(flagName, flagValue); break; 70506f6ba60Sopenharmony_ci case FlagTypes::FT_uint64: ret = ParseUint64Flag(flagName, flagValue); break; 70606f6ba60Sopenharmony_ci case FlagTypes::FT_double: ret = ParseDoubleFlag(flagName, flagValue); break; 70706f6ba60Sopenharmony_ci case FlagTypes::FT_string: ret = ParseStringFlag(flagName, flagValue); break; 70806f6ba60Sopenharmony_ci case FlagTypes::FT_bool_array: ret = ParseInt8ArrayFlag(flagName, flagValue); break; 70906f6ba60Sopenharmony_ci case FlagTypes::FT_int8_array: ret = ParseInt8ArrayFlag(flagName, flagValue); break; 71006f6ba60Sopenharmony_ci case FlagTypes::FT_int16_array: ret = ParseInt16ArrayFlag(flagName, flagValue); break; 71106f6ba60Sopenharmony_ci case FlagTypes::FT_int32_array: ret = ParseInt32ArrayFlag(flagName, flagValue); break; 71206f6ba60Sopenharmony_ci case FlagTypes::FT_int64_array: ret = ParseInt64ArrayFlag(flagName, flagValue); break; 71306f6ba60Sopenharmony_ci case FlagTypes::FT_uint8_array: ret = ParseUint8ArrayFlag(flagName, flagValue); break; 71406f6ba60Sopenharmony_ci case FlagTypes::FT_uint16_array: ret = ParseUint16ArrayFlag(flagName, flagValue); break; 71506f6ba60Sopenharmony_ci case FlagTypes::FT_uint32_array: ret = ParseUint32ArrayFlag(flagName, flagValue); break; 71606f6ba60Sopenharmony_ci case FlagTypes::FT_uint64_array: ret = ParseUint64ArrayFlag(flagName, flagValue); break; 71706f6ba60Sopenharmony_ci case FlagTypes::FT_double_array: ret = ParseDoubleArrayFlag(flagName, flagValue); break; 71806f6ba60Sopenharmony_ci case FlagTypes::FT_string_array: ret = ParseStringArrayFlag(flagName, flagValue); break; 71906f6ba60Sopenharmony_ci default: ret = -1; 72006f6ba60Sopenharmony_ci } 72106f6ba60Sopenharmony_ci return ret; 72206f6ba60Sopenharmony_ci} 72306f6ba60Sopenharmony_ci 72406f6ba60Sopenharmony_ciint ParseFlags(int *argc, char ***argv, bool rm = true) 72506f6ba60Sopenharmony_ci{ 72606f6ba60Sopenharmony_ci std::string flagName {}; 72706f6ba60Sopenharmony_ci std::string flagValue {}; 72806f6ba60Sopenharmony_ci int argIndex {1}; 72906f6ba60Sopenharmony_ci if (((*argc) % 2) == 0) { // 2: double 73006f6ba60Sopenharmony_ci std::cout << "CommandLineFlags ERROE: incorrect number of arguments" << std::endl; 73106f6ba60Sopenharmony_ci PrintArgFormat(); 73206f6ba60Sopenharmony_ci return -1; 73306f6ba60Sopenharmony_ci } 73406f6ba60Sopenharmony_ci while (argIndex < (*argc) - 1) { 73506f6ba60Sopenharmony_ci if (GetNextFlag(argv, argIndex, rm, flagName, flagValue) != 0) { 73606f6ba60Sopenharmony_ci // argument format error 73706f6ba60Sopenharmony_ci return -1; 73806f6ba60Sopenharmony_ci } 73906f6ba60Sopenharmony_ci if (flagName.empty() or flags_.count(flagName) == 0) { 74006f6ba60Sopenharmony_ci // argument removed or undefined, skip it and continue; 74106f6ba60Sopenharmony_ci continue; 74206f6ba60Sopenharmony_ci } 74306f6ba60Sopenharmony_ci if (ParseFlag(flagName, flagValue) != 0) { 74406f6ba60Sopenharmony_ci // argument value error 74506f6ba60Sopenharmony_ci return -1; 74606f6ba60Sopenharmony_ci } 74706f6ba60Sopenharmony_ci } 74806f6ba60Sopenharmony_ci 74906f6ba60Sopenharmony_ci return 0; 75006f6ba60Sopenharmony_ci} 75106f6ba60Sopenharmony_ci} // end of namespace CommandLineFlags 75206f6ba60Sopenharmony_ci 75306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_bool(name, default_val, help) \ 75406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 75506f6ba60Sopenharmony_cinamespace BoolFlags { \ 75606f6ba60Sopenharmony_ci static bool FLAGS_##name {default_val}; \ 75706f6ba60Sopenharmony_ci static std::string FLAGS_HELP_##name {help}; \ 75806f6ba60Sopenharmony_ci static FlagRegesterer<bool> name##_obj {#name, FLAGS_##name}; \ 75906f6ba60Sopenharmony_ci} \ 76006f6ba60Sopenharmony_ci} \ 76106f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 76206f6ba60Sopenharmony_ci 76306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_int8(name, default_val, help) \ 76406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 76506f6ba60Sopenharmony_cinamespace Int8Flags { \ 76606f6ba60Sopenharmony_ci static int8_t FLAGS_##name {default_val}; \ 76706f6ba60Sopenharmony_ci static std::string FLAGS_##name##_help {help}; \ 76806f6ba60Sopenharmony_ci static FlagRegesterer name##_obj {#name, FLAGS_##name}; \ 76906f6ba60Sopenharmony_ci} \ 77006f6ba60Sopenharmony_ci} \ 77106f6ba60Sopenharmony_ciusing CommandLineFlags::Int8Flags::FLAGS_##name; 77206f6ba60Sopenharmony_ci 77306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_int16(name, default_val, help) \ 77406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 77506f6ba60Sopenharmony_cinamespace Int16Flags { \ 77606f6ba60Sopenharmony_ci static int16_t FLAGS_##name {default_val}; \ 77706f6ba60Sopenharmony_ci static std::string FLAGS_##name##_help {help}; \ 77806f6ba60Sopenharmony_ci static FlagRegesterer name##_obj {#name, FLAGS_##name}; \ 77906f6ba60Sopenharmony_ci} \ 78006f6ba60Sopenharmony_ci} \ 78106f6ba60Sopenharmony_ciusing CommandLineFlags::Int16Flags::FLAGS_##name; 78206f6ba60Sopenharmony_ci 78306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_int32(name, default_val, help) \ 78406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 78506f6ba60Sopenharmony_cinamespace Int32Flags { \ 78606f6ba60Sopenharmony_ci static int32_t FLAGS_##name {default_val}; \ 78706f6ba60Sopenharmony_ci static std::string FLAGS_##name##_help {help}; \ 78806f6ba60Sopenharmony_ci static FlagRegesterer name##_obj {#name, FLAGS_##name}; \ 78906f6ba60Sopenharmony_ci} \ 79006f6ba60Sopenharmony_ci} \ 79106f6ba60Sopenharmony_ciusing CommandLineFlags::Int32Flags::FLAGS_##name; 79206f6ba60Sopenharmony_ci 79306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_int64(name, default_val, help) \ 79406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 79506f6ba60Sopenharmony_cinamespace Int64Flags { \ 79606f6ba60Sopenharmony_ci static int64_t FLAGS_##name {default_val}; \ 79706f6ba60Sopenharmony_ci static std::string FLAGS_##name##_help {help}; \ 79806f6ba60Sopenharmony_ci static FlagRegesterer name##_obj {#name, FLAGS_##name}; \ 79906f6ba60Sopenharmony_ci} \ 80006f6ba60Sopenharmony_ci} \ 80106f6ba60Sopenharmony_ciusing CommandLineFlags::Int64Flags::FLAGS_##name; 80206f6ba60Sopenharmony_ci 80306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_uint8(name, default_val, help) \ 80406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 80506f6ba60Sopenharmony_cinamespace Uint8Flags { \ 80606f6ba60Sopenharmony_ci static uint8_t FLAGS_##name {default_val}; \ 80706f6ba60Sopenharmony_ci static std::string FLAGS_##name##_help {help}; \ 80806f6ba60Sopenharmony_ci static FlagRegesterer name##_obj {#name, FLAGS_##name}; \ 80906f6ba60Sopenharmony_ci} \ 81006f6ba60Sopenharmony_ci} \ 81106f6ba60Sopenharmony_ciusing CommandLineFlags::Uint8Flags::FLAGS_##name; 81206f6ba60Sopenharmony_ci 81306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_uint16(name, default_val, help) \ 81406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 81506f6ba60Sopenharmony_cinamespace Uint16Flags { \ 81606f6ba60Sopenharmony_ci static uint16_t FLAGS_##name {default_val}; \ 81706f6ba60Sopenharmony_ci static std::string FLAGS_##name##_help {help}; \ 81806f6ba60Sopenharmony_ci static FlagRegesterer name##_obj {#name, FLAGS_##name}; \ 81906f6ba60Sopenharmony_ci} \ 82006f6ba60Sopenharmony_ci} \ 82106f6ba60Sopenharmony_ciusing CommandLineFlags::Uint16Flags::FLAGS_##name; 82206f6ba60Sopenharmony_ci 82306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_uint32(name, default_val, help) \ 82406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 82506f6ba60Sopenharmony_cinamespace Uint32Flags { \ 82606f6ba60Sopenharmony_ci static uint32_t FLAGS_##name {default_val}; \ 82706f6ba60Sopenharmony_ci static std::string FLAGS_##name##_help {help}; \ 82806f6ba60Sopenharmony_ci static FlagRegesterer name##_obj {#name, FLAGS_##name}; \ 82906f6ba60Sopenharmony_ci} \ 83006f6ba60Sopenharmony_ci} \ 83106f6ba60Sopenharmony_ciusing CommandLineFlags::Uint32Flags::FLAGS_##name; 83206f6ba60Sopenharmony_ci 83306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_uint64(name, default_val, help) \ 83406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 83506f6ba60Sopenharmony_cinamespace Uint64Flags { \ 83606f6ba60Sopenharmony_ci static uint64_t FLAGS_##name {default_val}; \ 83706f6ba60Sopenharmony_ci static std::string FLAGS_##name##_help {help}; \ 83806f6ba60Sopenharmony_ci static FlagRegesterer name##_obj {#name, FLAGS_##name}; \ 83906f6ba60Sopenharmony_ci} \ 84006f6ba60Sopenharmony_ci} \ 84106f6ba60Sopenharmony_ciusing CommandLineFlags::Uint64Flags::FLAGS_##name; 84206f6ba60Sopenharmony_ci 84306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_double(name, default_val, help) \ 84406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 84506f6ba60Sopenharmony_cinamespace DoubleFlags { \ 84606f6ba60Sopenharmony_ci static double FLAGS_##name {default_val}; \ 84706f6ba60Sopenharmony_ci static std::string FLAGS_##name##_help {help}; \ 84806f6ba60Sopenharmony_ci static FlagRegesterer name##_obj {#name, FLAGS_##name}; \ 84906f6ba60Sopenharmony_ci} \ 85006f6ba60Sopenharmony_ci} \ 85106f6ba60Sopenharmony_ciusing CommandLineFlags::DoubleFlags::FLAGS_##name; 85206f6ba60Sopenharmony_ci 85306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_string(name, default_val, help) \ 85406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 85506f6ba60Sopenharmony_cinamespace StringFlags { \ 85606f6ba60Sopenharmony_ci static std::string FLAGS_##name {default_val}; \ 85706f6ba60Sopenharmony_ci static std::string FLAGS_##name##_help {help}; \ 85806f6ba60Sopenharmony_ci static FlagRegesterer name##_obj {#name, FLAGS_##name}; \ 85906f6ba60Sopenharmony_ci} \ 86006f6ba60Sopenharmony_ci} \ 86106f6ba60Sopenharmony_ciusing CommandLineFlags::StringFlags::FLAGS_##name; 86206f6ba60Sopenharmony_ci 86306f6ba60Sopenharmony_ci#define HIEBPF_DEFINE_array(name, type, help) \ 86406f6ba60Sopenharmony_cinamespace CommandLineFlags { \ 86506f6ba60Sopenharmony_cinamespace ArrayFlags { \ 86606f6ba60Sopenharmony_ci using std::string; \ 86706f6ba60Sopenharmony_ci static std::vector<type> FLAGS_##name {}; \ 86806f6ba60Sopenharmony_ci static std::string FLAGS_##name##_help {help}; \ 86906f6ba60Sopenharmony_ci static FlagRegesterer name##_obj {#name, FLAGS_##name}; \ 87006f6ba60Sopenharmony_ci} \ 87106f6ba60Sopenharmony_ci} \ 87206f6ba60Sopenharmony_ciusing CommandLineFlags::ArrayFlags::FLAGS_##name; 87306f6ba60Sopenharmony_ci 87406f6ba60Sopenharmony_ci#define DECLARE_bool(name) \ 87506f6ba60Sopenharmony_ciextern bool CommandLineFlags::BoolFlags::FLAGS_##name; \ 87606f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 87706f6ba60Sopenharmony_ci 87806f6ba60Sopenharmony_ci#define DECLARE_int8(name) \ 87906f6ba60Sopenharmony_ciextern int8_t CommandLineFlags::BoolFlags::FLAGS_##name; \ 88006f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 88106f6ba60Sopenharmony_ci 88206f6ba60Sopenharmony_ci#define DECLARE_int16(name) \ 88306f6ba60Sopenharmony_ciextern int16_t CommandLineFlags::BoolFlags::FLAGS_##name; \ 88406f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 88506f6ba60Sopenharmony_ci 88606f6ba60Sopenharmony_ci#define DECLARE_int32(name) \ 88706f6ba60Sopenharmony_ciextern int32_t CommandLineFlags::BoolFlags::FLAGS_##name; \ 88806f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 88906f6ba60Sopenharmony_ci 89006f6ba60Sopenharmony_ci#define DECLARE_int64(name) \ 89106f6ba60Sopenharmony_ciextern int64_t CommandLineFlags::BoolFlags::FLAGS_##name; \ 89206f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 89306f6ba60Sopenharmony_ci 89406f6ba60Sopenharmony_ci#define DECLARE_uint8(name) \ 89506f6ba60Sopenharmony_ciextern uint8_t CommandLineFlags::BoolFlags::FLAGS_##name; \ 89606f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 89706f6ba60Sopenharmony_ci 89806f6ba60Sopenharmony_ci#define DECLARE_uint16(name) \ 89906f6ba60Sopenharmony_ciextern uint16_t CommandLineFlags::BoolFlags::FLAGS_##name; \ 90006f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 90106f6ba60Sopenharmony_ci 90206f6ba60Sopenharmony_ci#define DECLARE_uint32(name) \ 90306f6ba60Sopenharmony_ciextern uint32_t CommandLineFlags::BoolFlags::FLAGS_##name; \ 90406f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 90506f6ba60Sopenharmony_ci 90606f6ba60Sopenharmony_ci#define DECLARE_uint64(name) \ 90706f6ba60Sopenharmony_ciextern uint64_t CommandLineFlags::BoolFlags::FLAGS_##name; \ 90806f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 90906f6ba60Sopenharmony_ci 91006f6ba60Sopenharmony_ci#define DECLARE_double(name) \ 91106f6ba60Sopenharmony_ciextern double CommandLineFlags::BoolFlags::FLAGS_##name; \ 91206f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 91306f6ba60Sopenharmony_ci 91406f6ba60Sopenharmony_ci#define DECLARE_string(name) \ 91506f6ba60Sopenharmony_ciextern std::string CommandLineFlags::BoolFlags::FLAGS_##name; \ 91606f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 91706f6ba60Sopenharmony_ci 91806f6ba60Sopenharmony_ci#define DECLARE_array(name, type) \ 91906f6ba60Sopenharmony_ciusing std::string; \ 92006f6ba60Sopenharmony_ciextern std::vector<type> CommandLineFlags::BoolFlags::FLAGS_##name; \ 92106f6ba60Sopenharmony_ciusing CommandLineFlags::BoolFlags::FLAGS_##name; 92206f6ba60Sopenharmony_ci 92306f6ba60Sopenharmony_ci#endif