From c7c1e4ff01b7f799c41e80543075ae6eb58caf97 Mon Sep 17 00:00:00 2001 From: duansizhao Date: Fri, 1 May 2026 11:41:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96cli=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Agent Signed-off-by: duansizhao Change-Id: Id40186d1fc966d7795fa149bb8c4dff1ba68dceb --- tools/ohos-example/config.json | 11 +- tools/ohos-example/src/main.cpp | 215 ++++++++++++++++---------- tools/ohos-simple/config.json | 6 +- tools/ohos-simple/src/main.cpp | 178 ++++++++++++++------- tools/ohos-timer/config.json | 8 +- tools/ohos-timer/src/main.cpp | 263 +++++++++++++++++--------------- 6 files changed, 398 insertions(+), 283 deletions(-) diff --git a/tools/ohos-example/config.json b/tools/ohos-example/config.json index 8114e36ea1..121d72da86 100644 --- a/tools/ohos-example/config.json +++ b/tools/ohos-example/config.json @@ -3,7 +3,7 @@ "version": "1.0.0", "description": "Example CLI tool, demonstrates CLI tool specification implementation (with subcommand format)", "executablePath": "/system/bin/cli_tool/executable/ohos-example", - "hasSubcommands": true, + "hasSubCommand": true, "requirePermissions": [], "inputSchema": { "type": "object", @@ -56,7 +56,7 @@ "description": "Current status" } }, - "required": ["percentage", "status"] + "required": ["type", "percentage", "status"] } } }, @@ -65,12 +65,7 @@ "requirePermissions": [], "inputSchema": { "type": "object", - "properties": { - "reserved": { - "type": "string", - "description": "Reserved placeholder parameter for future use, not required for normal calls" - } - } + "properties": {} }, "outputSchema": { "type": "object", diff --git a/tools/ohos-example/src/main.cpp b/tools/ohos-example/src/main.cpp index 4cb278ac75..09861f6475 100644 --- a/tools/ohos-example/src/main.cpp +++ b/tools/ohos-example/src/main.cpp @@ -14,120 +14,167 @@ #include #include #include -#include -#include -#include -// Constants for magic numbers namespace { - constexpr int PROGRESS_MAX = 100; - constexpr int MIN_ARGC = 2; +constexpr int PROGRESS_MAX = 100; +constexpr int MIN_ARGC = 2; +constexpr const char* VERSION = "1.0.0"; +constexpr const char* BUILD_TIME = "2026-04-04 00:00:00"; +} + +std::string EscapeJson(const std::string& input) +{ + std::string escaped; + escaped.reserve(input.size()); + for (char ch : input) { + switch (ch) { + case '\\': + escaped += "\\\\"; + break; + case '"': + escaped += "\\\""; + break; + case '\n': + escaped += "\\n"; + break; + case '\r': + escaped += "\\r"; + break; + case '\t': + escaped += "\\t"; + break; + default: + escaped += ch; + break; + } + } + return escaped; } void EmitProgress(int percentage, const std::string& status) { - std::cout << "{\"type\": \"progress\", " - << "\"percentage\": " << percentage << ", " - << "\"status\": \"" << status << "\"" - << "}" << std::endl; + std::cout << "{\"type\":\"progress\",\"percentage\":" << percentage + << ",\"status\":\"" << EscapeJson(status) << "\"}" << std::endl; } -void EmitRunResult(const std::string& result) +void EmitSuccessResult(const std::string& dataJson) { - std::cout << "{\"type\": \"result\", " - << "\"status\": \"success\", " - << "\"data\": {" - << "\"result\": \"" << result << "\"" - << "}}" - << "}" << std::endl; -} - -void EmitVersionResult(const std::string& version, const std::string& buildTime) -{ - std::cout << "{\"type\": \"result\", " - << "\"status\": \"success\", " - << "\"data\": {" - << "\"version\": \"" << version << "\", " - << "\"build_time\": \"" << buildTime << "\"" - << "}}" - << "}" << std::endl; + std::cout << "{\"type\":\"result\",\"status\":\"success\",\"data\":" + << dataJson << "}" << std::endl; } void EmitError(const std::string& errCode, const std::string& errMsg, const std::string& suggestion) { - std::cout << "{\"type\": \"result\", " - << "\"status\": \"failed\", " - << "\"errCode\": \"" << errCode << "\", " - << "\"errMsg\": \"" << errMsg << "\", " - << "\"suggestion\": \"" << suggestion << "\"" - << "}" << std::endl; -} - -int RunCommand(const std::vector& args) -{ - EmitProgress(0, "starting"); - - std::string result = "执行完成"; - for (size_t i = 0; i < args.size(); i++) { - if (i > 0 || !result.empty()) { - result += " "; - } - result += args[i]; - - int progress = static_cast((i + 1) * PROGRESS_MAX / (args.size() + 1)); - EmitProgress(progress, "running"); - } - - EmitProgress(PROGRESS_MAX, "completed"); - EmitRunResult(result); - - return 0; -} - -int VersionCommand() -{ - std::string version = "1.0.0"; - - const char* buildTime = "2026-04-04 00:00:00"; - - EmitVersionResult(version, buildTime); - - return 0; + std::cout << "{\"type\":\"result\",\"status\":\"failed\",\"errCode\":\"" + << EscapeJson(errCode) << "\",\"errMsg\":\"" << EscapeJson(errMsg) + << "\",\"suggestion\":\"" << EscapeJson(suggestion) << "\"}" << std::endl; } void ShowHelp() { - std::cout << "Usage: ohos-example [args]" << std::endl; + std::cout << "Usage: ohos-example [options]" << std::endl; std::cout << "Subcommands:" << std::endl; - std::cout << " run [args...] Run the tool with arguments" << std::endl; - std::cout << " version Show version information" << std::endl; - std::cout << " help Show this help message" << std::endl; + std::cout << " run --argLine Run the tool with a single string argument" << std::endl; + std::cout << " version Show version information" << std::endl; + std::cout << " help Show this help message" << std::endl; +} + +void ShowRunHelp() +{ + std::cout << "Usage: ohos-example run [options]" << std::endl; + std::cout << "Options:" << std::endl; + std::cout << " --argLine Argument string to pass to the tool" << std::endl; + std::cout << " --help, -h Show this help message" << std::endl; +} + +void ShowVersionHelp() +{ + std::cout << "Usage: ohos-example version [options]" << std::endl; + std::cout << "Options:" << std::endl; + std::cout << " --help, -h Show this help message" << std::endl; +} + +int RunCommand(int argc, char* argv[]) +{ + std::string argLine; + int i = 2; + while (i < argc) { + std::string arg = argv[i]; + if (arg == "--help" || arg == "-h") { + ShowRunHelp(); + return 0; + } + if (arg == "--argLine") { + if (i + 1 >= argc) { + EmitError("ERR_MISSING_PARAM", "Missing value for parameter 'argLine'.", + "Use: ohos-example run --argLine "); + return 1; + } + ++i; + argLine = argv[i]; + ++i; + continue; + } + + EmitError("ERR_UNKNOWN_PARAM", "Unknown parameter '" + arg + "' for subcommand 'run'.", + "Use: ohos-example run --argLine "); + return 1; + } + + if (argLine.empty()) { + EmitError("ERR_MISSING_PARAM", "Missing required parameter 'argLine'.", + "Use: ohos-example run --argLine "); + return 1; + } + + EmitProgress(0, "starting"); + EmitProgress(50, "running"); + EmitProgress(PROGRESS_MAX, "completed"); + EmitSuccessResult("{\"result\":\"执行完成 " + EscapeJson(argLine) + "\"}"); + return 0; +} + +int VersionCommand(int argc, char* argv[]) +{ + if (argc == 3) { + std::string arg = argv[2]; + if (arg == "--help" || arg == "-h") { + ShowVersionHelp(); + return 0; + } + } + if (argc != 2) { + EmitError("ERR_UNKNOWN_PARAM", "Subcommand 'version' does not accept extra parameters.", + "Use: ohos-example version"); + return 1; + } + + EmitSuccessResult("{\"version\":\"" + std::string(VERSION) + "\",\"build_time\":\"" + + std::string(BUILD_TIME) + "\"}"); + return 0; } int main(int argc, char* argv[]) { if (argc < MIN_ARGC) { - ShowHelp(); + EmitError("ERR_MISSING_PARAM", "Missing required subcommand.", + "Use one of: ohos-example run --argLine , ohos-example version"); return 1; } std::string subcommand = argv[1]; - if (subcommand == "run") { - std::vector args; - for (int i = 2; i < argc; ++i) { - args.push_back(argv[i]); - } - return RunCommand(args); - } else if (subcommand == "version") { - return VersionCommand(); - } else if (subcommand == "help" || subcommand == "--help" || subcommand == "-h") { + return RunCommand(argc, argv); + } + if (subcommand == "version") { + return VersionCommand(argc, argv); + } + if (subcommand == "help" || subcommand == "--help" || subcommand == "-h") { ShowHelp(); return 0; - } else { - ShowHelp(); - return 1; } - return 0; + EmitError("ERR_INVALID_PARAM", "Unknown subcommand '" + subcommand + "'.", + "Use one of: run, version, help"); + return 1; } diff --git a/tools/ohos-simple/config.json b/tools/ohos-simple/config.json index b42711bfd9..4f294acc97 100644 --- a/tools/ohos-simple/config.json +++ b/tools/ohos-simple/config.json @@ -32,10 +32,6 @@ "type": "object", "description": "Tool execution result", "properties": { - "status": { - "type": "string", - "description": "Execution status, success when completed successfully" - }, "message": { "type": "string", "description": "Processed output message" @@ -45,6 +41,6 @@ "description": "Actual repeat count" } }, - "required": ["status", "message", "repeat_count"] + "required": ["message", "repeat_count"] } } diff --git a/tools/ohos-simple/src/main.cpp b/tools/ohos-simple/src/main.cpp index 73518a5997..d8e5c2acfe 100644 --- a/tools/ohos-simple/src/main.cpp +++ b/tools/ohos-simple/src/main.cpp @@ -11,76 +11,136 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include +#include #include #include -#include -// Constants for magic numbers namespace { - constexpr int MESSAGE_PREFIX_LEN = 10; - constexpr int COUNT_PREFIX_LEN = 8; - constexpr int MAX_COUNT = 10; - constexpr int MIN_COUNT = 1; +constexpr int MAX_COUNT = 10; +constexpr int MIN_COUNT = 1; } -void EmitResult(const std::string& status, const std::string& message, int repeatCount) +struct SimpleConfig { + std::string message = "Hello from ohos-simple"; + int count = 1; + bool verbose = false; +}; + +std::string EscapeJson(const std::string& input) { - std::cout << "{\"type\": \"result\", " - << "\"status\": \"" << status << "\", " - << "\"data\": {" - << "\"status\": \"" << status << "\", " - << "\"message\": \"" << message << "\", " - << "\"repeat_count\": " << repeatCount - << "}}" - << "}" << std::endl; + std::string escaped; + escaped.reserve(input.size()); + for (char ch : input) { + switch (ch) { + case '\\': + escaped += "\\\\"; + break; + case '"': + escaped += "\\\""; + break; + case '\n': + escaped += "\\n"; + break; + case '\r': + escaped += "\\r"; + break; + case '\t': + escaped += "\\t"; + break; + default: + escaped += ch; + break; + } + } + return escaped; +} + +void EmitSuccessResult(const std::string& dataJson) +{ + std::cout << "{\"type\":\"result\",\"status\":\"success\",\"data\":" + << dataJson << "}" << std::endl; } void EmitError(const std::string& errCode, const std::string& errMsg, const std::string& suggestion) { - std::cout << "{\"type\": \"result\", " - << "\"status\": \"failed\", " - << "\"errCode\": \"" << errCode << "\", " - << "\"errMsg\": \"" << errMsg << "\", " - << "\"suggestion\": \"" << suggestion << "\"" - << "}" << std::endl; + std::cout << "{\"type\":\"result\",\"status\":\"failed\",\"errCode\":\"" + << EscapeJson(errCode) << "\",\"errMsg\":\"" << EscapeJson(errMsg) + << "\",\"suggestion\":\"" << EscapeJson(suggestion) << "\"}" << std::endl; } void ShowHelp() { std::cout << "Usage: ohos-simple [options]" << std::endl; std::cout << "Options:" << std::endl; - std::cout << " --message= Set message to display (default: 'Hello from ohos-simple')" << std::endl; - std::cout << " --count= Number of repetitions (1-10, default: 1)" << std::endl; + std::cout << " --message Set message to display (default: 'Hello from ohos-simple')" << std::endl; + std::cout << " --count Number of repetitions (1-10, default: 1)" << std::endl; std::cout << " --verbose Enable verbose output" << std::endl; std::cout << " --help, -h Show this help message" << std::endl; } -bool ParseArguments(int argc, char* argv[], std::string& message, int& count, bool& verbose) +bool ParseInteger(const std::string& value, int& result) { - for (int i = 1; i < argc; ++i) { - std::string arg = argv[i]; - - if (arg.find("--message=") == 0) { - message = arg.substr(MESSAGE_PREFIX_LEN); - } else if (arg.find("--count=") == 0) { - count = std::atoi(arg.substr(COUNT_PREFIX_LEN).c_str()); - if (count < MIN_COUNT) { - count = MIN_COUNT; - } - if (count > MAX_COUNT) { - count = MAX_COUNT; - } - } else if (arg == "--verbose") { - verbose = true; - } else if (arg == "--help" || arg == "-h") { - ShowHelp(); - return false; - } + char* end = nullptr; + errno = 0; + long parsed = std::strtol(value.c_str(), &end, 10); + if (errno != 0 || end == value.c_str() || *end != '\0' || parsed < INT_MIN || parsed > INT_MAX) { + return false; } + result = static_cast(parsed); return true; } -std::string ExecuteTask(const std::string& message, int count, bool verbose) +int ParseArguments(int argc, char* argv[], SimpleConfig& config) +{ + int i = 1; + while (i < argc) { + std::string arg = argv[i]; + if (arg == "--message") { + if (i + 1 >= argc) { + EmitError("ERR_MISSING_PARAM", "Missing value for parameter 'message'.", + "Use: ohos-simple --message [--count ] [--verbose]"); + return 1; + } + ++i; + config.message = argv[i]; + ++i; + continue; + } + if (arg == "--count") { + if (i + 1 >= argc) { + EmitError("ERR_MISSING_PARAM", "Missing value for parameter 'count'.", + "Use: ohos-simple --count [--message ] [--verbose]"); + return 1; + } + ++i; + if (!ParseInteger(argv[i], config.count)) { + EmitError("ERR_INVALID_PARAM", "Parameter 'count' must be an integer.", + "Use an integer between 1 and 10, for example: --count 2"); + return 1; + } + ++i; + continue; + } + if (arg == "--verbose") { + config.verbose = true; + ++i; + continue; + } + if (arg == "--help" || arg == "-h") { + ShowHelp(); + return 2; + } + + EmitError("ERR_UNKNOWN_PARAM", "Unknown parameter '" + arg + "'.", + "Supported parameters are: --message, --count, --verbose"); + return 1; + } + return 0; +} + +std::string ExecuteTask(const std::string& message, int count) { std::string result; for (int i = 0; i < count; ++i) { @@ -89,27 +149,33 @@ std::string ExecuteTask(const std::string& message, int count, bool verbose) } result += message; } - return result; } int main(int argc, char* argv[]) { - std::string message = "Hello from ohos-simple"; - int count = 1; - bool verbose = false; - - if (!ParseArguments(argc, argv, message, count, verbose)) { - return 0; + SimpleConfig config; + int parseResult = ParseArguments(argc, argv, config); + if (parseResult != 0) { + return parseResult == 2 ? 0 : 1; } - if (message.empty()) { + if (config.message.empty()) { + EmitError("ERR_INVALID_PARAM", "Parameter 'message' must not be empty.", + "Provide a non-empty string, for example: --message hello"); + return 1; + } + if (config.count < MIN_COUNT || config.count > MAX_COUNT) { + EmitError("ERR_INVALID_PARAM", "Parameter 'count' must be between 1 and 10.", + "Use an integer between 1 and 10, for example: --count 2"); return 1; } - std::string result = ExecuteTask(message, count, verbose); - - EmitResult("success", result, count); - + std::string result = ExecuteTask(config.message, config.count); + if (config.verbose) { + result = "[verbose] " + result; + } + EmitSuccessResult("{\"message\":\"" + EscapeJson(result) + "\",\"repeat_count\":" + + std::to_string(config.count) + "}"); return 0; } diff --git a/tools/ohos-timer/config.json b/tools/ohos-timer/config.json index 1707a64710..8e829a8843 100644 --- a/tools/ohos-timer/config.json +++ b/tools/ohos-timer/config.json @@ -37,10 +37,6 @@ "type": "object", "description": "Tool output result", "properties": { - "status": { - "type": "string", - "description": "Execution status" - }, "duration": { "type": "integer", "description": "Planned duration (seconds)" @@ -50,7 +46,7 @@ "description": "Actual duration (seconds)" } }, - "required": ["status", "duration", "actual_duration"] + "required": ["duration", "actual_duration"] }, "eventSchemas": { "progress": { @@ -71,7 +67,7 @@ "description": "Current status" } }, - "required": ["percentage", "status"] + "required": ["type", "percentage", "status"] } } } diff --git a/tools/ohos-timer/src/main.cpp b/tools/ohos-timer/src/main.cpp index ebcc894da8..b433486ce1 100644 --- a/tools/ohos-timer/src/main.cpp +++ b/tools/ohos-timer/src/main.cpp @@ -11,25 +11,19 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include +#include +#include #include #include -#include -#include #include -#include -#include -#include -// Constants for magic numbers namespace { - constexpr int PROGRESS_PERCENTAGE_MAX = 100; - constexpr int DEFAULT_INTERVAL = 1; - constexpr int MIN_DURATION = 1; - constexpr int MIN_INTERVAL = 1; - constexpr int DURATION_PREFIX_LEN = 11; - constexpr int INTERVAL_PREFIX_LEN = 11; - constexpr int HELP_ARGC = 2; - constexpr int ARG_PARSE_START_INDEX = 1; +constexpr int PROGRESS_MAX = 100; +constexpr int DEFAULT_INTERVAL = 1; +constexpr int MIN_DURATION = 1; +constexpr int MIN_INTERVAL = 1; } struct TimerConfig { @@ -39,119 +33,137 @@ struct TimerConfig { bool verbose = false; }; -void EmitProgress(int percentage, const std::string& status) +std::string EscapeJson(const std::string& input) { - std::cout << "{\"type\": \"progress\", " - << "\"percentage\": " << percentage << ", " - << "\"status\": \"" << status << "\"" - << "}" << std::endl; + std::string escaped; + escaped.reserve(input.size()); + for (char ch : input) { + switch (ch) { + case '\\': + escaped += "\\\\"; + break; + case '"': + escaped += "\\\""; + break; + case '\n': + escaped += "\\n"; + break; + case '\r': + escaped += "\\r"; + break; + case '\t': + escaped += "\\t"; + break; + default: + escaped += ch; + break; + } + } + return escaped; } -void EmitResult(const std::string& status, int duration, int actualDuration) +void EmitProgress(int percentage, const std::string& status) { - std::cout << "{\"type\": \"result\", " - << "\"status\": \"" << status << "\", " - << "\"data\": {" - << "\"status\": \"" << status << "\", " - << "\"duration\": " << duration << ", " - << "\"actual_duration\": " << actualDuration - << "}}" - << "}" << std::endl; + std::cout << "{\"type\":\"progress\",\"percentage\":" << percentage + << ",\"status\":\"" << EscapeJson(status) << "\"}" << std::endl; +} + +void EmitSuccessResult(const std::string& dataJson) +{ + std::cout << "{\"type\":\"result\",\"status\":\"success\",\"data\":" + << dataJson << "}" << std::endl; } void EmitError(const std::string& errCode, const std::string& errMsg, const std::string& suggestion) { - std::cout << "{\"type\": \"result\", " - << "\"status\": \"failed\", " - << "\"errCode\": \"" << errCode << "\", " - << "\"errMsg\": \"" << errMsg << "\", " - << "\"suggestion\": \"" << suggestion << "\"" - << "}" << std::endl; + std::cout << "{\"type\":\"result\",\"status\":\"failed\",\"errCode\":\"" + << EscapeJson(errCode) << "\",\"errMsg\":\"" << EscapeJson(errMsg) + << "\",\"suggestion\":\"" << EscapeJson(suggestion) << "\"}" << std::endl; } void ShowHelp() { std::cout << "Usage: ohos-timer [options]" << std::endl; std::cout << "Options:" << std::endl; - std::cout << " --duration= Duration in seconds (required, minimum 1)" << std::endl; - std::cout << " --interval= Progress update interval in seconds (optional, default 1)" << std::endl; - std::cout << " --progress Enable progress events" << std::endl; - std::cout << " --verbose Enable verbose output" << std::endl; - std::cout << " --help, -h Show this help message" << std::endl; + std::cout << " --duration Duration in seconds (required, minimum 1)" << std::endl; + std::cout << " --interval Progress update interval in seconds (default 1)" << std::endl; + std::cout << " --showProgress Enable progress events" << std::endl; + std::cout << " --verbose Enable verbose mode" << std::endl; + std::cout << " --help, -h Show this help message" << std::endl; } -bool ParseArguments(int argc, char* argv[], TimerConfig& config) +bool ParseInteger(const std::string& value, int& result) { - for (int i = ARG_PARSE_START_INDEX; i < argc; ++i) { + char* end = nullptr; + errno = 0; + long parsed = std::strtol(value.c_str(), &end, 10); + if (errno != 0 || end == value.c_str() || *end != '\0' || parsed < INT_MIN || parsed > INT_MAX) { + return false; + } + result = static_cast(parsed); + return true; +} + +int ParseArguments(int argc, char* argv[], TimerConfig& config) +{ + int i = 1; + while (i < argc) { std::string arg = argv[i]; - - if (arg.find("--duration=") == 0) { - std::string value = arg.substr(DURATION_PREFIX_LEN); - char* end = nullptr; - errno = 0; - long val = std::strtol(value.c_str(), &end, 10); - if (errno != 0 || end == value.c_str() || *end != '\0' || val < 0 || val > INT_MAX) { - return false; + if (arg == "--duration") { + if (i + 1 >= argc) { + EmitError("ERR_MISSING_PARAM", "Missing value for parameter 'duration'.", + "Use: ohos-timer --duration [--interval ] [--showProgress] [--verbose]"); + return 1; } - config.duration = static_cast(val); - } else if (arg.find("--interval=") == 0) { - std::string value = arg.substr(INTERVAL_PREFIX_LEN); - char* end = nullptr; - errno = 0; - long val = std::strtol(value.c_str(), &end, 10); - if (errno != 0 || end == value.c_str() || *end != '\0' || val < 0 || val > INT_MAX) { - return false; + ++i; + if (!ParseInteger(argv[i], config.duration)) { + EmitError("ERR_INVALID_PARAM", "Parameter 'duration' must be an integer.", + "Use a positive integer, for example: --duration 5"); + return 1; } - config.interval = static_cast(val); - } else if (arg == "--progress") { - config.showProgress = true; - } else if (arg == "--verbose") { - config.verbose = true; - } else if (arg == "--help" || arg == "-h") { - ShowHelp(); - return false; + ++i; + continue; } + if (arg == "--interval") { + if (i + 1 >= argc) { + EmitError("ERR_MISSING_PARAM", "Missing value for parameter 'interval'.", + "Use: ohos-timer --interval [--duration ] [--showProgress] [--verbose]"); + return 1; + } + ++i; + if (!ParseInteger(argv[i], config.interval)) { + EmitError("ERR_INVALID_PARAM", "Parameter 'interval' must be an integer.", + "Use a positive integer, for example: --interval 1"); + return 1; + } + ++i; + continue; + } + if (arg == "--showProgress") { + config.showProgress = true; + ++i; + continue; + } + if (arg == "--verbose") { + config.verbose = true; + ++i; + continue; + } + if (arg == "--help" || arg == "-h") { + ShowHelp(); + return 2; + } + + EmitError("ERR_UNKNOWN_PARAM", "Unknown parameter '" + arg + "'.", + "Supported parameters are: --duration, --interval, --showProgress, --verbose"); + return 1; } - return true; -} - -bool ValidateArguments(const TimerConfig& config) -{ - if (config.duration < MIN_DURATION) { - return false; - } - - if (config.interval < MIN_INTERVAL) { - return false; - } - - if (config.interval > config.duration) { - return false; - } - - return true; -} - -void UpdateProgress(int elapsed, int duration, int& lastPercentage) -{ - if (duration == 0) { - return; - } - - int percentage = static_cast( - (elapsed * PROGRESS_PERCENTAGE_MAX) / duration - ); - - if (percentage > lastPercentage && percentage > 0) { - EmitProgress(percentage, "running"); - lastPercentage = percentage; - } + return 0; } int ExecuteTimer(const TimerConfig& config) { auto startTime = std::chrono::steady_clock::now(); - int lastPercentage = -1; int elapsed = 0; if (config.showProgress) { @@ -159,46 +171,49 @@ int ExecuteTimer(const TimerConfig& config) } while (elapsed < config.duration) { - if (config.showProgress) { - UpdateProgress(elapsed, config.duration, lastPercentage); - } - std::this_thread::sleep_for(std::chrono::seconds(config.interval)); - - elapsed = static_cast( - std::chrono::duration_cast( - std::chrono::steady_clock::now() - startTime - ).count() - ); + elapsed = static_cast(std::chrono::duration_cast( + std::chrono::steady_clock::now() - startTime).count()); + if (config.showProgress && elapsed < config.duration) { + int percentage = elapsed * PROGRESS_MAX / config.duration; + EmitProgress(percentage, config.verbose ? "running (verbose)" : "running"); + } } if (config.showProgress) { - EmitProgress(PROGRESS_PERCENTAGE_MAX, "completed"); + EmitProgress(PROGRESS_MAX, "completed"); } - EmitResult("success", config.duration, elapsed); - + EmitSuccessResult("{\"duration\":" + std::to_string(config.duration) + + ",\"actual_duration\":" + std::to_string(elapsed) + "}"); return 0; } int main(int argc, char* argv[]) { TimerConfig config; - - if (argc < HELP_ARGC) { - ShowHelp(); - return 1; - } - - if (!ParseArguments(argc, argv, config)) { - return 1; + int parseResult = ParseArguments(argc, argv, config); + if (parseResult != 0) { + return parseResult == 2 ? 0 : 1; } if (config.duration == 0) { - ShowHelp(); + EmitError("ERR_MISSING_PARAM", "Missing required parameter 'duration'.", + "Use: ohos-timer --duration [--interval ] [--showProgress] [--verbose]"); return 1; } - - if (!ValidateArguments(config)) { + if (config.duration < MIN_DURATION) { + EmitError("ERR_INVALID_PARAM", "Parameter 'duration' must be greater than or equal to 1.", + "Use a positive integer, for example: --duration 5"); + return 1; + } + if (config.interval < MIN_INTERVAL) { + EmitError("ERR_INVALID_PARAM", "Parameter 'interval' must be greater than or equal to 1.", + "Use a positive integer, for example: --interval 1"); + return 1; + } + if (config.interval > config.duration) { + EmitError("ERR_INVALID_PARAM", "Parameter 'interval' must not be greater than 'duration'.", + "Use values such as: --duration 5 --interval 1"); return 1; }