// Unicode 文字列型の VALUE の作成 VALUE *NewUniStrValue(wchar_t *str) { VALUE *v; // 引数チェック if (str == NULL) { return NULL; } // メモリ確保 v = Malloc(sizeof(VALUE)); // 文字列コピー v->Size = UniStrSize(str); v->UniStr = Malloc(v->Size); UniStrCpy(v->UniStr, v->Size, str); UniTrim(v->UniStr); return v; }
wchar_t *ParseCommandEx(wchar_t *str, wchar_t *name, TOKEN_LIST **param_list) { UNI_TOKEN_LIST *t; UINT i; wchar_t *tmp; wchar_t *ret = NULL; LIST *o; // Validate arguments if (str == NULL) { return NULL; } if (name != NULL && UniIsEmptyStr(name)) { name = NULL; } o = NULL; if (param_list != NULL) { o = NewListFast(CompareStr); } tmp = CopyUniStr(str); UniTrim(tmp); i = UniSearchStrEx(tmp, L"/CMD ", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'/') { i = INFINITE; } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"/CMD\t", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'/') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"/CMD:", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'/') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"/CMD=", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'/') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"-CMD ", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'-') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"-CMD\t", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'-') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"-CMD:", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'-') { i = INFINITE; } } if (i == INFINITE) { i = UniSearchStrEx(tmp, L"-CMD=", 0, false); if (i != INFINITE && i >= 1 && tmp[i - 1] == L'-') { i = INFINITE; } } if (i != INFINITE) { char *s = CopyStr("CMD"); if (InsertStr(o, s) == false) { Free(s); } if (UniStrCmpi(name, L"CMD") == 0) { ret = CopyUniStr(&str[i + 5]); UniTrim(ret); } else { tmp[i] = 0; } } if (ret == NULL) { t = UniParseCmdLine(tmp); if (t != NULL) { for (i = 0;i < t->NumTokens;i++) { wchar_t *token = t->Token[i]; if ((token[0] == L'-' && token[1] != L'-') || (UniStrCmpi(token, L"--help") == 0) || (token[0] == L'/' && token[1] != L'/')) { UINT i; // Named parameter // Examine whether there is a colon character if (UniStrCmpi(token, L"--help") == 0) { token++; } i = UniSearchStrEx(token, L":", 0, false); if (i == INFINITE) { i = UniSearchStrEx(token, L"=", 0, false); } if (i != INFINITE) { wchar_t *tmp; char *a; // There is a colon character tmp = CopyUniStr(token); tmp[i] = 0; a = CopyUniToStr(&tmp[1]); if (InsertStr(o, a) == false) { Free(a); } if (UniStrCmpi(name, &tmp[1]) == 0) { if (ret == NULL) { // Content ret = UniCopyStr(&token[i + 1]); } } Free(tmp); } else { // There is no colon character char *a; a = CopyUniToStr(&token[1]); if (InsertStr(o, a) == false) { Free(a); } if (UniStrCmpi(name, &token[1]) == 0) { if (ret == NULL) { // Empty character ret = UniCopyStr(L""); } } } } else { // Nameless argument if (name == NULL) { if (ret == NULL) { if (token[0] == L'-' && token[1] == L'-') { ret = UniCopyStr(&token[1]); } else if (token[0] == L'/' && token[1] == L'/') { ret = UniCopyStr(&token[1]); } else { ret = UniCopyStr(token); } } } } } UniFreeToken(t); } } Free(tmp); if (o != NULL) { TOKEN_LIST *t = ZeroMalloc(sizeof(TOKEN_LIST)); UINT i; t->NumTokens = LIST_NUM(o); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); for (i = 0;i < t->NumTokens;i++) { t->Token[i] = LIST_DATA(o, i); } ReleaseList(o); *param_list = t; } if (UniStrCmpi(ret, L"none") == 0 || UniStrCmpi(ret, L"null") == 0) { // Null and none are reserved words ret[0] = 0; } return ret; }
bool DispatchNextCmdEx(CONSOLE *c, wchar_t *exec_command, char *prompt, CMD cmd[], UINT num_cmd, void *param) { wchar_t *str; wchar_t *tmp; char *cmd_name; bool b_exit = false; wchar_t *cmd_param; UINT ret = ERR_NO_ERROR; TOKEN_LIST *t; TOKEN_LIST *candidate; bool no_end_crlf = false; UINT i; // Validate arguments if (c == NULL || (num_cmd >= 1 && cmd == NULL)) { return false; } if (exec_command == NULL) { // Show the prompt RETRY: tmp = CopyStrToUni(prompt); if (c->ProgrammingMode) { wchar_t tmp2[MAX_PATH]; UniFormat(tmp2, sizeof(tmp2), L"[PROMPT:%u:%s]\r\n", c->RetCode, tmp); Free(tmp); tmp = CopyUniStr(tmp2); } str = c->ReadLine(c, tmp, false); Free(tmp); if (str != NULL && IsEmptyUniStr(str)) { Free(str); goto RETRY; } } else { wchar_t tmp[MAX_SIZE]; // Use exec_command if (UniStartWith(exec_command, L"vpncmd") == false) { if (prompt != NULL) { if (c->ConsoleType != CONSOLE_CSV) { UniFormat(tmp, sizeof(tmp), L"%S%s", prompt, exec_command); c->Write(c, tmp); } } } str = CopyUniStr(exec_command); } if (str == NULL) { // User canceled return false; } UniTrimCrlf(str); UniTrim(str); if (UniIsEmptyStr(str)) { // Do Nothing Free(str); return true; } // Divide into command name and parameter if (SeparateCommandAndParam(str, &cmd_name, &cmd_param) == false) { // Do Nothing Free(str); return true; } if (StrLen(cmd_name) >= 2 && cmd_name[0] == '?' && cmd_name[1] != '?') { char tmp[MAX_SIZE]; wchar_t *s; StrCpy(tmp, sizeof(tmp), cmd_name + 1); StrCpy(cmd_name, 0, tmp); s = UniCopyStr(L"/?"); Free(cmd_param); cmd_param = s; } if (StrLen(cmd_name) >= 2 && EndWith(cmd_name, "?") && cmd_name[StrLen(cmd_name) - 2] != '?') { wchar_t *s; cmd_name[StrLen(cmd_name) - 1] = 0; s = UniCopyStr(L"/?"); Free(cmd_param); cmd_param = s; } // Get the candidate of command t = ZeroMalloc(sizeof(TOKEN_LIST)); t->NumTokens = num_cmd; t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); for (i = 0;i < t->NumTokens;i++) { t->Token[i] = CopyStr(cmd[i].Name); } if (IsHelpStr(cmd_name)) { if (UniIsEmptyStr(cmd_param)) { wchar_t tmp[MAX_SIZE]; // Display the list of commands that can be used UniFormat(tmp, sizeof(tmp), _UU("CMD_HELP_1"), t->NumTokens); c->Write(c, tmp); PrintCandidateHelp(c, NULL, t, 1); c->Write(c, L""); c->Write(c, _UU("CMD_HELP_2")); } else { char *cmd_name; // Display the help for the specified command if (SeparateCommandAndParam(cmd_param, &cmd_name, NULL)) { bool b = true; if (IsHelpStr(cmd_name)) { b = false; } if (b) { wchar_t str[MAX_SIZE]; UniFormat(str, sizeof(str), L"%S /help", cmd_name); DispatchNextCmdEx(c, str, NULL, cmd, num_cmd, param); no_end_crlf = true; } Free(cmd_name); } } } else if (StrCmpi(cmd_name, "exit") == 0 || StrCmpi(cmd_name, "quit") == 0) { // Exit b_exit = true; } else { candidate = GetRealnameCandidate(cmd_name, t); if (candidate == NULL || candidate->NumTokens == 0) { wchar_t tmp[MAX_SIZE]; // No candidate UniFormat(tmp, sizeof(tmp), _UU("CON_UNKNOWN_CMD"), cmd_name); c->Write(c, tmp); c->RetCode = ERR_BAD_COMMAND_OR_PARAM; } else if (candidate->NumTokens >= 2) { wchar_t tmp[MAX_SIZE]; // There is more than one candidate UniFormat(tmp, sizeof(tmp), _UU("CON_AMBIGIOUS_CMD"), cmd_name); c->Write(c, tmp); c->Write(c, _UU("CON_AMBIGIOUS_CMD_1")); PrintCandidateHelp(c, NULL, candidate, 1); c->Write(c, _UU("CON_AMBIGIOUS_CMD_2")); c->RetCode = ERR_BAD_COMMAND_OR_PARAM; } else { char *real_cmd_name; UINT i; // The candidate was shortlisted to one real_cmd_name = candidate->Token[0]; for (i = 0;i < num_cmd;i++) { if (StrCmpi(cmd[i].Name, real_cmd_name) == 0) { if (cmd[i].Proc != NULL) { // Show the description of the command if it isn't in CSV mode if(c->ConsoleType != CONSOLE_CSV) { wchar_t tmp[256]; wchar_t *note; GetCommandHelpStr(cmd[i].Name, ¬e, NULL, NULL); UniFormat(tmp, sizeof(tmp), _UU("CMD_EXEC_MSG_NAME"), cmd[i].Name, note); c->Write(c, tmp); } // Call the procedure of the command ret = cmd[i].Proc(c, cmd[i].Name, cmd_param, param); if (ret == INFINITE) { // Exit command b_exit = true; } else { c->RetCode = ret; } } } } } FreeToken(candidate); } FreeToken(t); Free(str); Free(cmd_name); Free(cmd_param); if (no_end_crlf == false) { //c->Write(c, L""); } if (b_exit) { return false; } return true; }
// Separate the command line into the command and the parameters bool SeparateCommandAndParam(wchar_t *src, char **cmd, wchar_t **param) { UINT i, len, wp; wchar_t *tmp; wchar_t *src_tmp; // Validate arguments if (src == NULL) { return false; } if (cmd != NULL) { *cmd = NULL; } if (param != NULL) { *param = NULL; } src_tmp = UniCopyStr(src); UniTrimCrlf(src_tmp); UniTrim(src_tmp); len = UniStrLen(src_tmp); tmp = Malloc(sizeof(wchar_t) * (len + 32)); wp = 0; for (i = 0;i < (len + 1);i++) { wchar_t c = src_tmp[i]; switch (c) { case 0: case L' ': case L'\t': tmp[wp] = 0; if (UniIsEmptyStr(tmp)) { Free(tmp); Free(src_tmp); return false; } if (cmd != NULL) { *cmd = CopyUniToStr(tmp); Trim(*cmd); } goto ESCAPE; default: tmp[wp++] = c; break; } } ESCAPE: if (param != NULL) { *param = CopyUniStr(&src_tmp[wp]); UniTrim(*param); } Free(tmp); Free(src_tmp); return true; }