1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci#include "shell_bas.h" 16d9f0492fSopenharmony_ci#include <fcntl.h> 17d9f0492fSopenharmony_ci#include <signal.h> 18d9f0492fSopenharmony_ci 19d9f0492fSopenharmony_ci#include "init_utils.h" 20d9f0492fSopenharmony_ci#include "shell_utils.h" 21d9f0492fSopenharmony_ci 22d9f0492fSopenharmony_cichar *BShellEnvErrString(BShellHandle handle, int32_t err) 23d9f0492fSopenharmony_ci{ 24d9f0492fSopenharmony_ci static BShellErrInfo shellErrString[] = { 25d9f0492fSopenharmony_ci {BSH_SHELL_INFO, "\r\n\r\n" 26d9f0492fSopenharmony_ci "+=========================================================+\r\n" 27d9f0492fSopenharmony_ci "| Parameter shell v"BSH_VERSION" |\r\n" 28d9f0492fSopenharmony_ci "+=========================================================+\r\n" 29d9f0492fSopenharmony_ci }, 30d9f0492fSopenharmony_ci {BSH_CMD_TOO_LONG, "\r\nWarnig: Command is too long\r\n"}, 31d9f0492fSopenharmony_ci {BSH_SHOW_CMD_LIST, "Command list:\r\n"}, 32d9f0492fSopenharmony_ci {BSH_CMD_NOT_EXIST, "Command not found\r\n"} 33d9f0492fSopenharmony_ci }; 34d9f0492fSopenharmony_ci for (size_t i = 0; i < sizeof(shellErrString) / sizeof(shellErrString[0]); i++) { 35d9f0492fSopenharmony_ci if ((int32_t)shellErrString[i].err == err) { 36d9f0492fSopenharmony_ci return shellErrString[i].desc; 37d9f0492fSopenharmony_ci } 38d9f0492fSopenharmony_ci } 39d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return "System unknown err", "Invalid shell env"); 40d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 41d9f0492fSopenharmony_ci int len = sprintf_s(shell->data, sizeof(shell->data) - 1, "System unknown err 0x%08x", err); 42d9f0492fSopenharmony_ci if (len <= 0) { 43d9f0492fSopenharmony_ci BSH_LOGE("Write shell data size failed."); 44d9f0492fSopenharmony_ci } 45d9f0492fSopenharmony_ci return shell->data; 46d9f0492fSopenharmony_ci} 47d9f0492fSopenharmony_ci 48d9f0492fSopenharmony_cistatic void BShellCmdOutputCmdHelp(BShellHandle handle, BShellCommand *cmd) 49d9f0492fSopenharmony_ci{ 50d9f0492fSopenharmony_ci BShellEnvOutputString(handle, " "); 51d9f0492fSopenharmony_ci int32_t spaceLength = BShellEnvOutputString(handle, cmd->help); 52d9f0492fSopenharmony_ci spaceLength = BSH_CMD_NAME_END - spaceLength; 53d9f0492fSopenharmony_ci spaceLength = (spaceLength > 0) ? spaceLength : 4; // 4 min 54d9f0492fSopenharmony_ci do { 55d9f0492fSopenharmony_ci BShellEnvOutputString(handle, " "); 56d9f0492fSopenharmony_ci } while (--spaceLength); 57d9f0492fSopenharmony_ci BShellEnvOutputString(handle, "--"); 58d9f0492fSopenharmony_ci BShellEnvOutputString(handle, cmd->desc); 59d9f0492fSopenharmony_ci BShellEnvOutputString(handle, "\r\n"); 60d9f0492fSopenharmony_ci} 61d9f0492fSopenharmony_ci 62d9f0492fSopenharmony_ciint32_t BShellCmdHelp(BShellHandle handle, int32_t argc, char *argv[]) 63d9f0492fSopenharmony_ci{ 64d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 65d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 66d9f0492fSopenharmony_ci BShellEnvOutputString(handle, BShellEnvErrString(handle, BSH_SHOW_CMD_LIST)); 67d9f0492fSopenharmony_ci 68d9f0492fSopenharmony_ci int show = 0; 69d9f0492fSopenharmony_ci BShellCommand *cmd = shell->command; 70d9f0492fSopenharmony_ci while (cmd != NULL) { 71d9f0492fSopenharmony_ci if ((argc >= 1) && 72d9f0492fSopenharmony_ci (strncmp(argv[0], cmd->name, strlen(argv[0])) == 0) && 73d9f0492fSopenharmony_ci (strncmp(argv[0], "help", strlen(argv[0])) != 0)) { 74d9f0492fSopenharmony_ci BShellCmdOutputCmdHelp(handle, cmd); 75d9f0492fSopenharmony_ci show = 1; 76d9f0492fSopenharmony_ci } 77d9f0492fSopenharmony_ci cmd = cmd->next; 78d9f0492fSopenharmony_ci } 79d9f0492fSopenharmony_ci if (show) { 80d9f0492fSopenharmony_ci return 0; 81d9f0492fSopenharmony_ci } 82d9f0492fSopenharmony_ci cmd = shell->command; 83d9f0492fSopenharmony_ci while (cmd != NULL) { 84d9f0492fSopenharmony_ci BShellCmdOutputCmdHelp(handle, cmd); 85d9f0492fSopenharmony_ci cmd = cmd->next; 86d9f0492fSopenharmony_ci } 87d9f0492fSopenharmony_ci return 0; 88d9f0492fSopenharmony_ci} 89d9f0492fSopenharmony_ci 90d9f0492fSopenharmony_cistatic int32_t BShellCmdExit(BShellHandle handle, int32_t argc, char *argv[]) 91d9f0492fSopenharmony_ci{ 92d9f0492fSopenharmony_ci#ifndef STARTUP_INIT_TEST 93d9f0492fSopenharmony_ci kill(getpid(), SIGINT); 94d9f0492fSopenharmony_ci#endif 95d9f0492fSopenharmony_ci return 0; 96d9f0492fSopenharmony_ci} 97d9f0492fSopenharmony_ci 98d9f0492fSopenharmony_ciint32_t BShellEnvOutput(BShellHandle handle, char *fmt, ...) 99d9f0492fSopenharmony_ci{ 100d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 101d9f0492fSopenharmony_ci va_list list; 102d9f0492fSopenharmony_ci va_start(list, fmt); 103d9f0492fSopenharmony_ci int len = vfprintf(stdout, fmt, list); 104d9f0492fSopenharmony_ci va_end(list); 105d9f0492fSopenharmony_ci (void)fflush(stdout); 106d9f0492fSopenharmony_ci return len; 107d9f0492fSopenharmony_ci} 108d9f0492fSopenharmony_ci 109d9f0492fSopenharmony_ciint32_t BShellEnvOutputString(BShellHandle handle, const char *string) 110d9f0492fSopenharmony_ci{ 111d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 112d9f0492fSopenharmony_ci printf("%s", string); 113d9f0492fSopenharmony_ci (void)fflush(stdout); 114d9f0492fSopenharmony_ci return strlen(string); 115d9f0492fSopenharmony_ci} 116d9f0492fSopenharmony_ci 117d9f0492fSopenharmony_ciint32_t BShellEnvOutputPrompt(BShellHandle handle, const char *prompt) 118d9f0492fSopenharmony_ci{ 119d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 120d9f0492fSopenharmony_ci BSH_CHECK(prompt != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 121d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 122d9f0492fSopenharmony_ci if (shell->prompt != NULL) { 123d9f0492fSopenharmony_ci free(shell->prompt); 124d9f0492fSopenharmony_ci } 125d9f0492fSopenharmony_ci size_t promptLen = strlen(prompt); 126d9f0492fSopenharmony_ci if (promptLen > BSH_CMD_NAME_END) { 127d9f0492fSopenharmony_ci shell->prompt = strdup(prompt + promptLen - BSH_CMD_NAME_END); 128d9f0492fSopenharmony_ci if (shell->prompt != NULL) { 129d9f0492fSopenharmony_ci shell->prompt[0] = '.'; 130d9f0492fSopenharmony_ci shell->prompt[1] = '.'; 131d9f0492fSopenharmony_ci shell->prompt[2] = '.'; // 2 index 132d9f0492fSopenharmony_ci } 133d9f0492fSopenharmony_ci } else { 134d9f0492fSopenharmony_ci shell->prompt = strdup(prompt); 135d9f0492fSopenharmony_ci BSH_CHECK(shell->prompt != NULL, return BSH_INVALID_PARAM, "strdup prompt failed."); 136d9f0492fSopenharmony_ci } 137d9f0492fSopenharmony_ci return 0; 138d9f0492fSopenharmony_ci} 139d9f0492fSopenharmony_ci 140d9f0492fSopenharmony_civoid BShellEnvOutputByte(BShellHandle handle, char data) 141d9f0492fSopenharmony_ci{ 142d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return, "Invalid shell env"); 143d9f0492fSopenharmony_ci printf("%c", data); 144d9f0492fSopenharmony_ci (void)fflush(stdout); 145d9f0492fSopenharmony_ci} 146d9f0492fSopenharmony_ci 147d9f0492fSopenharmony_civoid BShellEnvOutputResult(BShellHandle handle, int32_t result) 148d9f0492fSopenharmony_ci{ 149d9f0492fSopenharmony_ci if (result == 0) { 150d9f0492fSopenharmony_ci return; 151d9f0492fSopenharmony_ci } 152d9f0492fSopenharmony_ci printf("result: 0x%08x\r\n", result); 153d9f0492fSopenharmony_ci (void)fflush(stdout); 154d9f0492fSopenharmony_ci} 155d9f0492fSopenharmony_ci 156d9f0492fSopenharmony_cistatic void BShellEnvOutputParam(BShellHandle handle, char *var) 157d9f0492fSopenharmony_ci{ 158d9f0492fSopenharmony_ci BShellEnvOutput(handle, (var[0] == '$') ? var + 1 : var); 159d9f0492fSopenharmony_ci BShellEnvOutputString(handle, " = "); 160d9f0492fSopenharmony_ci BShellEnvOutputString(handle, BShellEnvGetStringParam(handle, var)); 161d9f0492fSopenharmony_ci} 162d9f0492fSopenharmony_ci 163d9f0492fSopenharmony_civoid BShellEnvBackspace(BShellHandle handle, uint32_t length) 164d9f0492fSopenharmony_ci{ 165d9f0492fSopenharmony_ci for (uint32_t i = 0; i < length; i++) { 166d9f0492fSopenharmony_ci BShellEnvOutputString(handle, "\b \b"); 167d9f0492fSopenharmony_ci } 168d9f0492fSopenharmony_ci} 169d9f0492fSopenharmony_ci 170d9f0492fSopenharmony_cistatic void BShellEnvParseParam(BShellEnv *shell) 171d9f0492fSopenharmony_ci{ 172d9f0492fSopenharmony_ci uint8_t quotes = 0; 173d9f0492fSopenharmony_ci uint8_t record = 1; 174d9f0492fSopenharmony_ci shell->argc = 0; 175d9f0492fSopenharmony_ci for (uint16_t i = 0; i < shell->length; i++) { 176d9f0492fSopenharmony_ci char data = *(shell->buffer + i); 177d9f0492fSopenharmony_ci if ((quotes != 0 || (data != ' ' && data != '\t' && data != ',')) && data != 0) { 178d9f0492fSopenharmony_ci if (data == '\"') { 179d9f0492fSopenharmony_ci quotes = quotes ? 0 : 1; 180d9f0492fSopenharmony_ci } 181d9f0492fSopenharmony_ci if (record == 1) { 182d9f0492fSopenharmony_ci BSH_CHECK(shell->argc < BSH_PARAMETER_MAX_NUMBER, return, "argc out of range"); 183d9f0492fSopenharmony_ci shell->args[shell->argc++] = shell->buffer + i; 184d9f0492fSopenharmony_ci record = 0; 185d9f0492fSopenharmony_ci } 186d9f0492fSopenharmony_ci if (*(shell->buffer + i) == '\\' && *(shell->buffer + i + 1) != 0) { 187d9f0492fSopenharmony_ci i++; 188d9f0492fSopenharmony_ci } 189d9f0492fSopenharmony_ci } else { 190d9f0492fSopenharmony_ci *(shell->buffer + i) = 0; 191d9f0492fSopenharmony_ci record = 1; 192d9f0492fSopenharmony_ci } 193d9f0492fSopenharmony_ci } 194d9f0492fSopenharmony_ci} 195d9f0492fSopenharmony_ci 196d9f0492fSopenharmony_cistatic int32_t BShellEnvExcuteCmd(BShellEnv *shell, BShellCommand *cmd) 197d9f0492fSopenharmony_ci{ 198d9f0492fSopenharmony_ci return cmd->executer((BShellHandle)shell, shell->argc - cmd->argStart, &shell->args[cmd->argStart]); 199d9f0492fSopenharmony_ci} 200d9f0492fSopenharmony_ci 201d9f0492fSopenharmony_cistatic int32_t BShellEnvHandleEnter(BShellHandle handle, uint8_t data) 202d9f0492fSopenharmony_ci{ 203d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 204d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 205d9f0492fSopenharmony_ci if (shell->length == 0) { 206d9f0492fSopenharmony_ci BShellEnvOutputString(shell, "\n"); 207d9f0492fSopenharmony_ci BShellEnvOutputString(handle, shell->prompt); 208d9f0492fSopenharmony_ci return 0; 209d9f0492fSopenharmony_ci } 210d9f0492fSopenharmony_ci 211d9f0492fSopenharmony_ci *(shell->buffer + shell->length++) = 0; 212d9f0492fSopenharmony_ci BShellEnvParseParam(shell); 213d9f0492fSopenharmony_ci shell->length = 0; 214d9f0492fSopenharmony_ci shell->cursor = 0; 215d9f0492fSopenharmony_ci if (shell->argc == 0) { 216d9f0492fSopenharmony_ci BShellEnvOutputString(shell, shell->prompt); 217d9f0492fSopenharmony_ci return 0; 218d9f0492fSopenharmony_ci } 219d9f0492fSopenharmony_ci 220d9f0492fSopenharmony_ci BShellEnvOutputString(shell, "\n"); 221d9f0492fSopenharmony_ci if (strcmp((const char *)shell->args[0], "help") == 0) { 222d9f0492fSopenharmony_ci BShellCmdHelp(handle, shell->argc, shell->args); 223d9f0492fSopenharmony_ci BShellEnvOutputString(shell, shell->prompt); 224d9f0492fSopenharmony_ci return 0; 225d9f0492fSopenharmony_ci } 226d9f0492fSopenharmony_ci if (shell->args[0][0] == '$') { 227d9f0492fSopenharmony_ci BShellEnvOutputParam(shell, shell->args[0]); 228d9f0492fSopenharmony_ci BShellEnvOutputString(shell, shell->prompt); 229d9f0492fSopenharmony_ci return 0; 230d9f0492fSopenharmony_ci } 231d9f0492fSopenharmony_ci 232d9f0492fSopenharmony_ci BShellCommand *cmd = BShellEnvGetCmd(handle, (uint32_t)shell->argc, shell->args); 233d9f0492fSopenharmony_ci if (cmd != NULL) { 234d9f0492fSopenharmony_ci int32_t ret = BShellEnvExcuteCmd(shell, cmd); 235d9f0492fSopenharmony_ci BShellEnvOutputResult(shell, ret); 236d9f0492fSopenharmony_ci } else { 237d9f0492fSopenharmony_ci BShellEnvOutputString(shell, BShellEnvErrString(handle, BSH_CMD_NOT_EXIST)); 238d9f0492fSopenharmony_ci } 239d9f0492fSopenharmony_ci BShellEnvOutputString(shell, shell->prompt); 240d9f0492fSopenharmony_ci return 0; 241d9f0492fSopenharmony_ci} 242d9f0492fSopenharmony_ci 243d9f0492fSopenharmony_cistatic int32_t BShellEnvHandleBackspace(BShellHandle handle, uint8_t code) 244d9f0492fSopenharmony_ci{ 245d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 246d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 247d9f0492fSopenharmony_ci if (shell->length == 0) { 248d9f0492fSopenharmony_ci return 0; 249d9f0492fSopenharmony_ci } 250d9f0492fSopenharmony_ci if (shell->cursor == shell->length) { 251d9f0492fSopenharmony_ci shell->length--; 252d9f0492fSopenharmony_ci shell->cursor--; 253d9f0492fSopenharmony_ci shell->buffer[shell->length] = 0; 254d9f0492fSopenharmony_ci BShellEnvBackspace(handle, 1); 255d9f0492fSopenharmony_ci } else if (shell->cursor > 0) { 256d9f0492fSopenharmony_ci for (short i = 0; i < shell->length - shell->cursor; i++) { 257d9f0492fSopenharmony_ci shell->buffer[shell->cursor + i - 1] = shell->buffer[shell->cursor + i]; 258d9f0492fSopenharmony_ci } 259d9f0492fSopenharmony_ci shell->length--; 260d9f0492fSopenharmony_ci shell->cursor--; 261d9f0492fSopenharmony_ci shell->buffer[shell->length] = 0; 262d9f0492fSopenharmony_ci BShellEnvOutputByte(shell, '\b'); 263d9f0492fSopenharmony_ci for (short i = shell->cursor; i < shell->length; i++) { 264d9f0492fSopenharmony_ci BShellEnvOutputByte(shell, shell->buffer[i]); 265d9f0492fSopenharmony_ci } 266d9f0492fSopenharmony_ci BShellEnvOutputByte(shell, ' '); 267d9f0492fSopenharmony_ci for (short i = shell->length - shell->cursor + 1; i > 0; i--) { 268d9f0492fSopenharmony_ci BShellEnvOutputByte(shell, '\b'); 269d9f0492fSopenharmony_ci } 270d9f0492fSopenharmony_ci } 271d9f0492fSopenharmony_ci return 0; 272d9f0492fSopenharmony_ci} 273d9f0492fSopenharmony_ci 274d9f0492fSopenharmony_cistatic int32_t BShellEnvHandleTab(BShellHandle handle, uint8_t code) 275d9f0492fSopenharmony_ci{ 276d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 277d9f0492fSopenharmony_ci return 0; 278d9f0492fSopenharmony_ci} 279d9f0492fSopenharmony_ci 280d9f0492fSopenharmony_cistatic void BShellEnvHandleNormal(BShellHandle handle, uint8_t data) 281d9f0492fSopenharmony_ci{ 282d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return, "Invalid shell env"); 283d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 284d9f0492fSopenharmony_ci if (data == 0) { 285d9f0492fSopenharmony_ci return; 286d9f0492fSopenharmony_ci } 287d9f0492fSopenharmony_ci if (shell->length < BSH_COMMAND_MAX_LENGTH - 1) { 288d9f0492fSopenharmony_ci if (shell->length == shell->cursor) { 289d9f0492fSopenharmony_ci shell->buffer[shell->length++] = data; 290d9f0492fSopenharmony_ci shell->cursor++; 291d9f0492fSopenharmony_ci BShellEnvOutputByte(shell, data); 292d9f0492fSopenharmony_ci } else { 293d9f0492fSopenharmony_ci for (uint16_t i = shell->length - shell->cursor; i > 0; i--) { 294d9f0492fSopenharmony_ci shell->buffer[shell->cursor + i] = shell->buffer[shell->cursor + i - 1]; 295d9f0492fSopenharmony_ci } 296d9f0492fSopenharmony_ci shell->buffer[shell->cursor++] = data; 297d9f0492fSopenharmony_ci shell->buffer[++shell->length] = 0; 298d9f0492fSopenharmony_ci for (uint16_t i = shell->cursor - 1; i < shell->length; i++) { 299d9f0492fSopenharmony_ci BShellEnvOutputByte(shell, shell->buffer[i]); 300d9f0492fSopenharmony_ci } 301d9f0492fSopenharmony_ci for (uint16_t i = shell->length - shell->cursor; i > 0; i--) { 302d9f0492fSopenharmony_ci BShellEnvOutputByte(shell, '\b'); 303d9f0492fSopenharmony_ci } 304d9f0492fSopenharmony_ci } 305d9f0492fSopenharmony_ci } else { 306d9f0492fSopenharmony_ci BShellEnvOutputString(shell, BShellEnvErrString(handle, BSH_CMD_TOO_LONG)); 307d9f0492fSopenharmony_ci BShellEnvOutputString(shell, shell->prompt); 308d9f0492fSopenharmony_ci 309d9f0492fSopenharmony_ci shell->cursor = shell->length; 310d9f0492fSopenharmony_ci } 311d9f0492fSopenharmony_ci} 312d9f0492fSopenharmony_ci 313d9f0492fSopenharmony_cistatic int32_t BShellEnvHandleCtrC(BShellHandle handle, uint8_t code) 314d9f0492fSopenharmony_ci{ 315d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 316d9f0492fSopenharmony_ci BSH_LOGV("BShellEnvHandleCtrC %d", getpid()); 317d9f0492fSopenharmony_ci#ifndef STARTUP_INIT_TEST 318d9f0492fSopenharmony_ci kill(getpid(), SIGKILL); 319d9f0492fSopenharmony_ci#endif 320d9f0492fSopenharmony_ci return 0; 321d9f0492fSopenharmony_ci} 322d9f0492fSopenharmony_ci 323d9f0492fSopenharmony_cistatic int32_t BShellEnvHandleEsc(BShellHandle handle, uint8_t code) 324d9f0492fSopenharmony_ci{ 325d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 326d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 327d9f0492fSopenharmony_ci shell->shellState = BSH_ANSI_ESC; 328d9f0492fSopenharmony_ci return 0; 329d9f0492fSopenharmony_ci} 330d9f0492fSopenharmony_ci 331d9f0492fSopenharmony_ciBShellKey *BShellEnvGetDefaultKey(uint8_t code) 332d9f0492fSopenharmony_ci{ 333d9f0492fSopenharmony_ci static BShellKey defaultKeys[] = { 334d9f0492fSopenharmony_ci {BSH_KEY_LF, BShellEnvHandleEnter, NULL}, 335d9f0492fSopenharmony_ci {BSH_KEY_CR, BShellEnvHandleEnter, NULL}, 336d9f0492fSopenharmony_ci {BSH_KEY_TAB, BShellEnvHandleTab, NULL}, 337d9f0492fSopenharmony_ci {BSH_KEY_BACKSPACE, BShellEnvHandleBackspace, NULL}, 338d9f0492fSopenharmony_ci {BSH_KEY_DELETE, BShellEnvHandleBackspace, NULL}, 339d9f0492fSopenharmony_ci {BSH_KEY_CTRLC, BShellEnvHandleCtrC, NULL}, 340d9f0492fSopenharmony_ci {BSH_KEY_ESC, BShellEnvHandleEsc, NULL}, 341d9f0492fSopenharmony_ci }; 342d9f0492fSopenharmony_ci for (size_t i = 0; i < sizeof(defaultKeys) / sizeof(defaultKeys[0]); i++) { 343d9f0492fSopenharmony_ci if (defaultKeys[i].keyCode == code) { 344d9f0492fSopenharmony_ci return &defaultKeys[i]; 345d9f0492fSopenharmony_ci } 346d9f0492fSopenharmony_ci } 347d9f0492fSopenharmony_ci return NULL; 348d9f0492fSopenharmony_ci} 349d9f0492fSopenharmony_ci 350d9f0492fSopenharmony_ciSHELLSTATIC void BShellEnvProcessInput(BShellHandle handle, char data) 351d9f0492fSopenharmony_ci{ 352d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return, "Invalid shell env"); 353d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 354d9f0492fSopenharmony_ci if (shell->shellState == BSH_IN_NORMAL) { 355d9f0492fSopenharmony_ci BShellKey *key = BShellEnvGetKey(handle, data); 356d9f0492fSopenharmony_ci if (key != NULL) { 357d9f0492fSopenharmony_ci key->keyHandle(shell, (uint8_t)data); 358d9f0492fSopenharmony_ci return; 359d9f0492fSopenharmony_ci } 360d9f0492fSopenharmony_ci key = BShellEnvGetDefaultKey(data); 361d9f0492fSopenharmony_ci if (key != NULL) { 362d9f0492fSopenharmony_ci key->keyHandle(shell, (uint8_t)data); 363d9f0492fSopenharmony_ci return; 364d9f0492fSopenharmony_ci } 365d9f0492fSopenharmony_ci BShellEnvHandleNormal(shell, data); 366d9f0492fSopenharmony_ci } else if (shell->shellState == BSH_ANSI_CSI) { 367d9f0492fSopenharmony_ci switch (data) { 368d9f0492fSopenharmony_ci case 0x41: // up 369d9f0492fSopenharmony_ci break; 370d9f0492fSopenharmony_ci case 0x42: // down 371d9f0492fSopenharmony_ci break; 372d9f0492fSopenharmony_ci case 0x43: // -> 373d9f0492fSopenharmony_ci if (shell->cursor < shell->length) { 374d9f0492fSopenharmony_ci BShellEnvOutputByte(handle, shell->buffer[shell->cursor]); 375d9f0492fSopenharmony_ci shell->cursor++; 376d9f0492fSopenharmony_ci } 377d9f0492fSopenharmony_ci break; 378d9f0492fSopenharmony_ci case 0x44: // <- 379d9f0492fSopenharmony_ci if (shell->cursor > 0) { 380d9f0492fSopenharmony_ci BShellEnvOutputByte(shell, '\b'); 381d9f0492fSopenharmony_ci shell->cursor--; 382d9f0492fSopenharmony_ci } 383d9f0492fSopenharmony_ci break; 384d9f0492fSopenharmony_ci default: 385d9f0492fSopenharmony_ci break; 386d9f0492fSopenharmony_ci } 387d9f0492fSopenharmony_ci shell->shellState = BSH_IN_NORMAL; 388d9f0492fSopenharmony_ci } else if (shell->shellState == BSH_ANSI_ESC) { 389d9f0492fSopenharmony_ci if (data == 0x5B) { // input up/down 390d9f0492fSopenharmony_ci shell->shellState = BSH_ANSI_CSI; 391d9f0492fSopenharmony_ci } else { 392d9f0492fSopenharmony_ci shell->shellState = BSH_IN_NORMAL; 393d9f0492fSopenharmony_ci } 394d9f0492fSopenharmony_ci } 395d9f0492fSopenharmony_ci} 396d9f0492fSopenharmony_ci 397d9f0492fSopenharmony_civoid BShellEnvLoop(BShellHandle handle) 398d9f0492fSopenharmony_ci{ 399d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return, "Invalid shell env"); 400d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 401d9f0492fSopenharmony_ci BSH_CHECK(shell->input != NULL, return, "Invalid shell input"); 402d9f0492fSopenharmony_ci while (1) { 403d9f0492fSopenharmony_ci char data = 0; 404d9f0492fSopenharmony_ci if (shell->input(&data, 1) == 1) { 405d9f0492fSopenharmony_ci BShellEnvProcessInput(shell, data); 406d9f0492fSopenharmony_ci } 407d9f0492fSopenharmony_ci } 408d9f0492fSopenharmony_ci} 409d9f0492fSopenharmony_ci 410d9f0492fSopenharmony_ciint32_t BShellEnvInit(BShellHandle *handle, const BShellInfo *info) 411d9f0492fSopenharmony_ci{ 412d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 413d9f0492fSopenharmony_ci BSH_CHECK(info != NULL && info->prompt != NULL, return BSH_INVALID_PARAM, "Invalid cmd name"); 414d9f0492fSopenharmony_ci 415d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)calloc(1, sizeof(BShellEnv)); 416d9f0492fSopenharmony_ci BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Failed to create shell env"); 417d9f0492fSopenharmony_ci shell->length = 0; 418d9f0492fSopenharmony_ci shell->cursor = 0; 419d9f0492fSopenharmony_ci shell->shellState = BSH_IN_NORMAL; 420d9f0492fSopenharmony_ci shell->input = info->input; 421d9f0492fSopenharmony_ci shell->prompt = strdup(info->prompt); 422d9f0492fSopenharmony_ci BSH_CHECK(shell->prompt != NULL, free(shell); return BSH_INVALID_PARAM, "Failed to strdup prompt"); 423d9f0492fSopenharmony_ci shell->command = NULL; 424d9f0492fSopenharmony_ci shell->param = NULL; 425d9f0492fSopenharmony_ci shell->keyHandle = NULL; 426d9f0492fSopenharmony_ci shell->execMode = BSH_EXEC_INDEPENDENT; 427d9f0492fSopenharmony_ci *handle = (BShellHandle)shell; 428d9f0492fSopenharmony_ci return 0; 429d9f0492fSopenharmony_ci} 430d9f0492fSopenharmony_ci 431d9f0492fSopenharmony_ciint BShellEnvStart(BShellHandle handle) 432d9f0492fSopenharmony_ci{ 433d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 434d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 435d9f0492fSopenharmony_ci shell->execMode = BSH_EXEC_TASK; 436d9f0492fSopenharmony_ci BShellEnvOutputString(handle, BShellEnvErrString(handle, BSH_SHELL_INFO)); 437d9f0492fSopenharmony_ci BShellEnvOutputString(handle, shell->prompt); 438d9f0492fSopenharmony_ci 439d9f0492fSopenharmony_ci const CmdInfo infos[] = { 440d9f0492fSopenharmony_ci {"exit", BShellCmdExit, "exit parameter shell", "exit"}, 441d9f0492fSopenharmony_ci {"help", BShellCmdHelp, "help command", "help"} 442d9f0492fSopenharmony_ci }; 443d9f0492fSopenharmony_ci for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) { 444d9f0492fSopenharmony_ci BShellEnvRegisterCmd(handle, &infos[i]); 445d9f0492fSopenharmony_ci } 446d9f0492fSopenharmony_ci return 0; 447d9f0492fSopenharmony_ci} 448d9f0492fSopenharmony_ci 449d9f0492fSopenharmony_cistatic void BShellParamFree(BShellParam *param) 450d9f0492fSopenharmony_ci{ 451d9f0492fSopenharmony_ci if (param->desc != NULL) { 452d9f0492fSopenharmony_ci free(param->desc); 453d9f0492fSopenharmony_ci } 454d9f0492fSopenharmony_ci if (param->type == PARAM_STRING && param->value.string != NULL) { 455d9f0492fSopenharmony_ci free(param->value.string); 456d9f0492fSopenharmony_ci } 457d9f0492fSopenharmony_ci free(param); 458d9f0492fSopenharmony_ci} 459d9f0492fSopenharmony_ci 460d9f0492fSopenharmony_cistatic void BShellCmdFree(BShellCommand *cmd) 461d9f0492fSopenharmony_ci{ 462d9f0492fSopenharmony_ci if (cmd->desc != NULL) { 463d9f0492fSopenharmony_ci free(cmd->desc); 464d9f0492fSopenharmony_ci cmd->desc = NULL; 465d9f0492fSopenharmony_ci } 466d9f0492fSopenharmony_ci if (cmd->help != NULL) { 467d9f0492fSopenharmony_ci free(cmd->help); 468d9f0492fSopenharmony_ci cmd->help = NULL; 469d9f0492fSopenharmony_ci } 470d9f0492fSopenharmony_ci if (cmd->multikey != NULL) { 471d9f0492fSopenharmony_ci free(cmd->multikey); 472d9f0492fSopenharmony_ci cmd->multikey = NULL; 473d9f0492fSopenharmony_ci } 474d9f0492fSopenharmony_ci free(cmd); 475d9f0492fSopenharmony_ci} 476d9f0492fSopenharmony_ci 477d9f0492fSopenharmony_civoid BShellEnvDestory(BShellHandle handle) 478d9f0492fSopenharmony_ci{ 479d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return, "Invalid shell env"); 480d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 481d9f0492fSopenharmony_ci 482d9f0492fSopenharmony_ci BShellCommand *cmd = shell->command; 483d9f0492fSopenharmony_ci while (cmd != NULL) { 484d9f0492fSopenharmony_ci shell->command = cmd->next; 485d9f0492fSopenharmony_ci BShellCmdFree(cmd); 486d9f0492fSopenharmony_ci cmd = shell->command; 487d9f0492fSopenharmony_ci } 488d9f0492fSopenharmony_ci 489d9f0492fSopenharmony_ci BShellParam *param = shell->param; 490d9f0492fSopenharmony_ci while (param != NULL) { 491d9f0492fSopenharmony_ci shell->param = param->next; 492d9f0492fSopenharmony_ci BShellParamFree(param); 493d9f0492fSopenharmony_ci param = shell->param; 494d9f0492fSopenharmony_ci } 495d9f0492fSopenharmony_ci 496d9f0492fSopenharmony_ci BShellKey *key = shell->keyHandle; 497d9f0492fSopenharmony_ci while (key != NULL) { 498d9f0492fSopenharmony_ci shell->keyHandle = key->next; 499d9f0492fSopenharmony_ci free(key); 500d9f0492fSopenharmony_ci key = shell->keyHandle; 501d9f0492fSopenharmony_ci } 502d9f0492fSopenharmony_ci if (shell->prompt != NULL) { 503d9f0492fSopenharmony_ci free(shell->prompt); 504d9f0492fSopenharmony_ci } 505d9f0492fSopenharmony_ci free(shell); 506d9f0492fSopenharmony_ci} 507d9f0492fSopenharmony_ci 508d9f0492fSopenharmony_ciint32_t BShellEnvRegisterCmd(BShellHandle handle, const CmdInfo *cmdInfo) 509d9f0492fSopenharmony_ci{ 510d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 511d9f0492fSopenharmony_ci BSH_CHECK(cmdInfo != NULL && cmdInfo->name != NULL, return BSH_INVALID_PARAM, "Invalid cmd name"); 512d9f0492fSopenharmony_ci BSH_CHECK(cmdInfo->executer != NULL, return BSH_INVALID_PARAM, "Invalid cmd executer"); 513d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 514d9f0492fSopenharmony_ci size_t nameLen = strlen(cmdInfo->name) + 1; 515d9f0492fSopenharmony_ci BShellCommand *cmd = (BShellCommand *)calloc(1, sizeof(BShellCommand) + nameLen); 516d9f0492fSopenharmony_ci BSH_CHECK(cmd != NULL, return BSH_INVALID_PARAM, "Failed to alloc cmd name %s", cmdInfo->name); 517d9f0492fSopenharmony_ci cmd->executer = cmdInfo->executer; 518d9f0492fSopenharmony_ci cmd->argStart = 0; 519d9f0492fSopenharmony_ci int32_t ret = 0; 520d9f0492fSopenharmony_ci do { 521d9f0492fSopenharmony_ci ret = strcpy_s(cmd->name, nameLen, cmdInfo->name); 522d9f0492fSopenharmony_ci BSH_CHECK(ret == 0, break, "Failed to copy name %s", cmdInfo->name); 523d9f0492fSopenharmony_ci 524d9f0492fSopenharmony_ci ret = BSH_SYSTEM_ERR; 525d9f0492fSopenharmony_ci if (cmdInfo->desc != NULL) { 526d9f0492fSopenharmony_ci cmd->desc = strdup(cmdInfo->desc); 527d9f0492fSopenharmony_ci BSH_CHECK(cmd->desc != NULL, break, "Failed to copy desc %s", cmdInfo->name); 528d9f0492fSopenharmony_ci } 529d9f0492fSopenharmony_ci if (cmdInfo->help != NULL) { 530d9f0492fSopenharmony_ci cmd->help = strdup(cmdInfo->help); 531d9f0492fSopenharmony_ci BSH_CHECK(cmd->help != NULL, break, "Failed to copy help %s", cmdInfo->name); 532d9f0492fSopenharmony_ci } 533d9f0492fSopenharmony_ci cmd->multikey = NULL; 534d9f0492fSopenharmony_ci if (cmdInfo->multikey != NULL && strlen(cmdInfo->multikey) > nameLen) { 535d9f0492fSopenharmony_ci cmd->multikey = strdup(cmdInfo->multikey); 536d9f0492fSopenharmony_ci BSH_CHECK(cmd->multikey != NULL, break, "Failed to copy multikey %s", cmdInfo->name); 537d9f0492fSopenharmony_ci int argc = SplitString(cmd->multikey, " ", cmd->multikeys, (int)ARRAY_LENGTH(cmd->multikeys)); 538d9f0492fSopenharmony_ci BSH_CHECK(argc <= (int)ARRAY_LENGTH(cmd->multikeys) && argc > 0, break, "Invalid multikey"); 539d9f0492fSopenharmony_ci cmd->argStart = argc - 1; 540d9f0492fSopenharmony_ci if (argc == 1) { 541d9f0492fSopenharmony_ci free(cmd->multikey); 542d9f0492fSopenharmony_ci cmd->multikey = NULL; 543d9f0492fSopenharmony_ci } 544d9f0492fSopenharmony_ci } 545d9f0492fSopenharmony_ci ret = 0; 546d9f0492fSopenharmony_ci } while (0); 547d9f0492fSopenharmony_ci if (ret != 0) { 548d9f0492fSopenharmony_ci BShellCmdFree(cmd); 549d9f0492fSopenharmony_ci return ret; 550d9f0492fSopenharmony_ci } 551d9f0492fSopenharmony_ci cmd->next = shell->command; 552d9f0492fSopenharmony_ci shell->command = cmd; 553d9f0492fSopenharmony_ci return 0; 554d9f0492fSopenharmony_ci} 555d9f0492fSopenharmony_ci 556d9f0492fSopenharmony_cistatic const char *GetRealCmdName(const char *name) 557d9f0492fSopenharmony_ci{ 558d9f0492fSopenharmony_ci int i = 0; 559d9f0492fSopenharmony_ci int last = 0; 560d9f0492fSopenharmony_ci while (*(name + i) != '\0') { 561d9f0492fSopenharmony_ci if (*(name + i) == '/') { 562d9f0492fSopenharmony_ci last = i; 563d9f0492fSopenharmony_ci } 564d9f0492fSopenharmony_ci i++; 565d9f0492fSopenharmony_ci } 566d9f0492fSopenharmony_ci if (last != 0) { 567d9f0492fSopenharmony_ci return name + last + 1; 568d9f0492fSopenharmony_ci } else { 569d9f0492fSopenharmony_ci return name; 570d9f0492fSopenharmony_ci } 571d9f0492fSopenharmony_ci} 572d9f0492fSopenharmony_ci 573d9f0492fSopenharmony_ciBShellCommand *BShellEnvGetCmd(BShellHandle handle, int32_t argc, char *argv[]) 574d9f0492fSopenharmony_ci{ 575d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return NULL, "Invalid shell env"); 576d9f0492fSopenharmony_ci BSH_CHECK(argc >= 1, return NULL, "Invalid argc"); 577d9f0492fSopenharmony_ci const char *cmdName = GetRealCmdName(argv[0]); 578d9f0492fSopenharmony_ci BSH_LOGV("BShellEnvGetCmd %s cmd %s", argv[0], cmdName); 579d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 580d9f0492fSopenharmony_ci BShellCommand *cmd = shell->command; 581d9f0492fSopenharmony_ci while (cmd != NULL) { 582d9f0492fSopenharmony_ci if (strcmp(cmd->name, cmdName) != 0) { 583d9f0492fSopenharmony_ci cmd = cmd->next; 584d9f0492fSopenharmony_ci continue; 585d9f0492fSopenharmony_ci } 586d9f0492fSopenharmony_ci if (cmd->multikey == NULL) { 587d9f0492fSopenharmony_ci return cmd; 588d9f0492fSopenharmony_ci } 589d9f0492fSopenharmony_ci int32_t i = 0; 590d9f0492fSopenharmony_ci for (i = 0; i < (int32_t)ARRAY_LENGTH(cmd->multikeys) && i < argc; i++) { 591d9f0492fSopenharmony_ci if (cmd->multikeys[i] == NULL) { 592d9f0492fSopenharmony_ci return cmd; 593d9f0492fSopenharmony_ci } 594d9f0492fSopenharmony_ci char *tmp = argv[i]; 595d9f0492fSopenharmony_ci if (i == 0) { 596d9f0492fSopenharmony_ci tmp = (char *)cmdName; 597d9f0492fSopenharmony_ci } 598d9f0492fSopenharmony_ci if (strcmp(cmd->multikeys[i], tmp) != 0) { 599d9f0492fSopenharmony_ci break; 600d9f0492fSopenharmony_ci } 601d9f0492fSopenharmony_ci } 602d9f0492fSopenharmony_ci if (i >= (int32_t)ARRAY_LENGTH(cmd->multikeys)) { 603d9f0492fSopenharmony_ci return cmd; 604d9f0492fSopenharmony_ci } 605d9f0492fSopenharmony_ci if (i >= argc) { 606d9f0492fSopenharmony_ci if (cmd->multikeys[i] == NULL) { 607d9f0492fSopenharmony_ci return cmd; 608d9f0492fSopenharmony_ci } 609d9f0492fSopenharmony_ci } 610d9f0492fSopenharmony_ci cmd = cmd->next; 611d9f0492fSopenharmony_ci } 612d9f0492fSopenharmony_ci return NULL; 613d9f0492fSopenharmony_ci} 614d9f0492fSopenharmony_ci 615d9f0492fSopenharmony_ciint32_t BShellEnvRegisterKeyHandle(BShellHandle handle, uint8_t code, BShellkeyHandle keyHandle) 616d9f0492fSopenharmony_ci{ 617d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 618d9f0492fSopenharmony_ci BSH_CHECK(keyHandle != NULL, return BSH_INVALID_PARAM, "Invalid cmd name"); 619d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 620d9f0492fSopenharmony_ci 621d9f0492fSopenharmony_ci BShellKey *key = (BShellKey *)calloc(1, sizeof(BShellKey)); 622d9f0492fSopenharmony_ci BSH_CHECK(key != NULL, return BSH_INVALID_PARAM, "Failed to alloc key code %d", code); 623d9f0492fSopenharmony_ci key->keyCode = code; 624d9f0492fSopenharmony_ci key->keyHandle = keyHandle; 625d9f0492fSopenharmony_ci key->next = shell->keyHandle; 626d9f0492fSopenharmony_ci shell->keyHandle = key; 627d9f0492fSopenharmony_ci return 0; 628d9f0492fSopenharmony_ci} 629d9f0492fSopenharmony_ci 630d9f0492fSopenharmony_ciBShellKey *BShellEnvGetKey(BShellHandle handle, uint8_t code) 631d9f0492fSopenharmony_ci{ 632d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return NULL, "Invalid shell env"); 633d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 634d9f0492fSopenharmony_ci BShellKey *key = shell->keyHandle; 635d9f0492fSopenharmony_ci while (key != NULL) { 636d9f0492fSopenharmony_ci if (key->keyCode == code) { 637d9f0492fSopenharmony_ci return key; 638d9f0492fSopenharmony_ci } 639d9f0492fSopenharmony_ci key = key->next; 640d9f0492fSopenharmony_ci } 641d9f0492fSopenharmony_ci return NULL; 642d9f0492fSopenharmony_ci} 643d9f0492fSopenharmony_ci 644d9f0492fSopenharmony_cistatic int32_t BShellParamSetValue(BShellParam *param, void *value) 645d9f0492fSopenharmony_ci{ 646d9f0492fSopenharmony_ci static uint32_t paramValueLens[] = { 647d9f0492fSopenharmony_ci sizeof(uint8_t), sizeof(uint16_t), sizeof(uint32_t), sizeof(char *) 648d9f0492fSopenharmony_ci }; 649d9f0492fSopenharmony_ci if (param->type == PARAM_STRING) { 650d9f0492fSopenharmony_ci if (param->value.string != NULL) { 651d9f0492fSopenharmony_ci free(param->value.string); 652d9f0492fSopenharmony_ci } 653d9f0492fSopenharmony_ci param->value.string = strdup((char *)value); 654d9f0492fSopenharmony_ci BSH_CHECK(param->value.string != NULL, return BSH_SYSTEM_ERR, "Failed to copy value for %s", param->name); 655d9f0492fSopenharmony_ci } else if (param->type < PARAM_STRING) { 656d9f0492fSopenharmony_ci int ret = memcpy_s(¶m->value, sizeof(param->value), value, paramValueLens[param->type]); 657d9f0492fSopenharmony_ci BSH_CHECK(ret == 0, return BSH_SYSTEM_ERR, "Failed to copy value for %s", param->name); 658d9f0492fSopenharmony_ci } 659d9f0492fSopenharmony_ci return 0; 660d9f0492fSopenharmony_ci} 661d9f0492fSopenharmony_ci 662d9f0492fSopenharmony_ciint32_t BShellEnvSetParam(BShellHandle handle, const char *name, const char *desc, BShellParamType type, void *value) 663d9f0492fSopenharmony_ci{ 664d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); 665d9f0492fSopenharmony_ci BSH_CHECK(name != NULL, return BSH_INVALID_PARAM, "Invalid param name"); 666d9f0492fSopenharmony_ci BSH_CHECK(value != NULL, return BSH_INVALID_PARAM, "Invalid cmd value"); 667d9f0492fSopenharmony_ci BSH_CHECK(type <= PARAM_STRING, return BSH_INVALID_PARAM, "Invalid param type"); 668d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 669d9f0492fSopenharmony_ci const BShellParam *tmp = BShellEnvGetParam(handle, name); 670d9f0492fSopenharmony_ci if (tmp != NULL) { 671d9f0492fSopenharmony_ci BSH_CHECK(tmp->type <= type, return BSH_INVALID_PARAM, "Invalid param type %d", tmp->type); 672d9f0492fSopenharmony_ci return BShellParamSetValue((BShellParam *)tmp, value); 673d9f0492fSopenharmony_ci } 674d9f0492fSopenharmony_ci int32_t ret = 0; 675d9f0492fSopenharmony_ci BShellParam *param = NULL; 676d9f0492fSopenharmony_ci do { 677d9f0492fSopenharmony_ci size_t nameLen = strlen(name) + 1; 678d9f0492fSopenharmony_ci param = (BShellParam *)calloc(1, sizeof(BShellParam) + nameLen); 679d9f0492fSopenharmony_ci BSH_CHECK(param != NULL, return BSH_SYSTEM_ERR, "Failed to alloc cmd name %s", name); 680d9f0492fSopenharmony_ci param->type = type; 681d9f0492fSopenharmony_ci ret = strcpy_s(param->name, nameLen, name); 682d9f0492fSopenharmony_ci BSH_CHECK(ret == 0, break, "Failed to copy name %s", name); 683d9f0492fSopenharmony_ci if (desc != NULL) { 684d9f0492fSopenharmony_ci param->desc = strdup(desc); 685d9f0492fSopenharmony_ci BSH_CHECK(param->desc != NULL, free(param); return BSH_SYSTEM_ERR, "Failed to set desc"); 686d9f0492fSopenharmony_ci } 687d9f0492fSopenharmony_ci ret = BShellParamSetValue(param, value); 688d9f0492fSopenharmony_ci BSH_CHECK(ret == 0, break, "Failed set value for %s", name); 689d9f0492fSopenharmony_ci 690d9f0492fSopenharmony_ci param->next = shell->param; 691d9f0492fSopenharmony_ci shell->param = param; 692d9f0492fSopenharmony_ci } while (0); 693d9f0492fSopenharmony_ci if (ret != 0) { 694d9f0492fSopenharmony_ci BShellParamFree(param); 695d9f0492fSopenharmony_ci } 696d9f0492fSopenharmony_ci return ret; 697d9f0492fSopenharmony_ci} 698d9f0492fSopenharmony_ci 699d9f0492fSopenharmony_ciconst BShellParam *BShellEnvGetParam(BShellHandle handle, const char *name) 700d9f0492fSopenharmony_ci{ 701d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return NULL, "Invalid shell env"); 702d9f0492fSopenharmony_ci BShellEnv *shell = (BShellEnv *)handle; 703d9f0492fSopenharmony_ci BShellParam *param = shell->param; 704d9f0492fSopenharmony_ci while (param != NULL) { 705d9f0492fSopenharmony_ci if (strcmp(name, param->name) == 0) { 706d9f0492fSopenharmony_ci return param; 707d9f0492fSopenharmony_ci } 708d9f0492fSopenharmony_ci param = param->next; 709d9f0492fSopenharmony_ci } 710d9f0492fSopenharmony_ci return NULL; 711d9f0492fSopenharmony_ci} 712d9f0492fSopenharmony_ci 713d9f0492fSopenharmony_ciconst char *BShellEnvGetStringParam(BShellHandle handle, const char *name) 714d9f0492fSopenharmony_ci{ 715d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return "", "Invalid shell env"); 716d9f0492fSopenharmony_ci const BShellParam *param = BShellEnvGetParam(handle, name); 717d9f0492fSopenharmony_ci if (param == NULL) { 718d9f0492fSopenharmony_ci return ""; 719d9f0492fSopenharmony_ci } 720d9f0492fSopenharmony_ci switch (param->type) { 721d9f0492fSopenharmony_ci case PARAM_STRING: 722d9f0492fSopenharmony_ci return param->value.string; 723d9f0492fSopenharmony_ci default: 724d9f0492fSopenharmony_ci break; 725d9f0492fSopenharmony_ci } 726d9f0492fSopenharmony_ci return ""; 727d9f0492fSopenharmony_ci} 728d9f0492fSopenharmony_ci 729d9f0492fSopenharmony_ciconst ParamInfo *BShellEnvGetReservedParam(BShellHandle handle, const char *name) 730d9f0492fSopenharmony_ci{ 731d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return NULL, "Invalid shell env"); 732d9f0492fSopenharmony_ci static ParamInfo reservedParams[] = { 733d9f0492fSopenharmony_ci {PARAM_REVERESD_NAME_CURR_PARAMETER, "current parameter", PARAM_STRING} 734d9f0492fSopenharmony_ci }; 735d9f0492fSopenharmony_ci for (size_t i = 0; i < sizeof(reservedParams) / sizeof(reservedParams[0]); i++) { 736d9f0492fSopenharmony_ci if (strcmp(name, reservedParams[i].name) == 0) { 737d9f0492fSopenharmony_ci return &reservedParams[i]; 738d9f0492fSopenharmony_ci } 739d9f0492fSopenharmony_ci } 740d9f0492fSopenharmony_ci return NULL; 741d9f0492fSopenharmony_ci} 742d9f0492fSopenharmony_ci 743d9f0492fSopenharmony_ciint32_t BShellEnvDirectExecute(BShellHandle handle, int argc, char *args[]) 744d9f0492fSopenharmony_ci{ 745d9f0492fSopenharmony_ci BSH_CHECK(handle != NULL, return -1, "Invalid shell env"); 746d9f0492fSopenharmony_ci BShellCommand *cmd = BShellEnvGetCmd(handle, argc, args); 747d9f0492fSopenharmony_ci if (cmd != NULL) { 748d9f0492fSopenharmony_ci int32_t ret = cmd->executer(handle, argc - cmd->argStart, &args[cmd->argStart]); 749d9f0492fSopenharmony_ci BShellEnvOutputResult(handle, ret); 750d9f0492fSopenharmony_ci } else { 751d9f0492fSopenharmony_ci if (argc > 1) { 752d9f0492fSopenharmony_ci BShellEnvOutputString(handle, BShellEnvErrString(handle, BSH_CMD_NOT_EXIST)); 753d9f0492fSopenharmony_ci } 754d9f0492fSopenharmony_ci BShellCmdHelp(handle, argc, args); 755d9f0492fSopenharmony_ci } 756d9f0492fSopenharmony_ci return 0; 757d9f0492fSopenharmony_ci} 758