Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
8e68fa6e
T
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
8e68fa6e
编写于
12月 17, 2021
作者:
S
Shengliang Guan
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
TD-10431 tsim compile
上级
89f4a7ad
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
32 addition
and
247 deletion
+32
-247
CMakeLists.txt
CMakeLists.txt
+1
-0
tests/tsim/CMakeLists.txt
tests/tsim/CMakeLists.txt
+1
-1
tests/tsim/inc/sim.h
tests/tsim/inc/sim.h
+3
-4
tests/tsim/inc/simParse.h
tests/tsim/inc/simParse.h
+3
-3
tests/tsim/src/simExe.c
tests/tsim/src/simExe.c
+21
-226
tests/tsim/src/simMain.c
tests/tsim/src/simMain.c
+0
-4
tests/tsim/src/simParse.c
tests/tsim/src/simParse.c
+0
-1
tests/tsim/src/simSystem.c
tests/tsim/src/simSystem.c
+1
-6
tools/shell/inc/shellCommand.h
tools/shell/inc/shellCommand.h
+2
-2
未找到文件。
CMakeLists.txt
浏览文件 @
8e68fa6e
...
...
@@ -26,6 +26,7 @@ if(${BUILD_TEST})
endif
(
${
BUILD_TEST
}
)
add_subdirectory
(
source
)
add_subdirectory
(
tools
)
add_subdirectory
(
tests
)
# docs
add_subdirectory
(
docs
)
...
...
tests/tsim/CMakeLists.txt
浏览文件 @
8e68fa6e
...
...
@@ -6,7 +6,7 @@ target_link_libraries(
PUBLIC util
PUBLIC common
PUBLIC os
PUBLIC c
J
son
PUBLIC c
j
son
)
target_include_directories
(
tsim
...
...
tests/tsim/inc/sim.h
浏览文件 @
8e68fa6e
...
...
@@ -13,8 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _
_SIM_H_
_
#define _
_SIM_H_
_
#ifndef _
TD_SIM_H
_
#define _
TD_SIM_H
_
#include <semaphore.h>
#include <stdbool.h>
...
...
@@ -150,7 +150,6 @@ extern int32_t simScriptPos;
extern
int32_t
simScriptSucced
;
extern
int32_t
simDebugFlag
;
extern
char
tsScriptDir
[];
extern
bool
simAsyncQuery
;
extern
bool
abortExecution
;
SScript
*
simParseScript
(
char
*
fileName
);
...
...
@@ -178,4 +177,4 @@ bool simExecuteLineInsertCmd(SScript *script, char *option);
bool
simExecuteLineInsertErrorCmd
(
SScript
*
script
,
char
*
option
);
void
simVisuallizeOption
(
SScript
*
script
,
char
*
src
,
char
*
dst
);
#endif
\ No newline at end of file
#endif
/*_TD_SIM_H_*/
\ No newline at end of file
tests/tsim/inc/simParse.h
浏览文件 @
8e68fa6e
...
...
@@ -13,8 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _
_SIM_PARSE_H_
_
#define _
_SIM_PARSE_H_
_
#ifndef _
TD_SIM_PARSE_H
_
#define _
TD_SIM_PARSE_H
_
#define MAX_NUM_CMD 64
#define MAX_NUM_LABLES 100
...
...
@@ -52,4 +52,4 @@ typedef struct {
bool
simParseExpression
(
char
*
token
,
int32_t
lineNum
);
#endif
\ No newline at end of file
#endif
/*_TD_SIM_PARSE_H_*/
\ No newline at end of file
tests/tsim/src/simExe.c
浏览文件 @
8e68fa6e
...
...
@@ -14,14 +14,14 @@
*/
#define _DEFAULT_SOURCE
#include "
../../../include/client/
taos.h"
#include "taos.h"
#include "cJSON.h"
#include "os.h"
#include "sim.h"
#include "taoserror.h"
#include "tglobal.h"
#include "tutil.h"
#
undef TAOS_MEM_CHECK
#
include "ttypes.h"
void
simLogSql
(
char
*
sql
,
bool
useSharp
)
{
static
FILE
*
fp
=
NULL
;
...
...
@@ -466,10 +466,6 @@ void simVisuallizeOption(SScript *script, char *src, char *dst) {
strcpy
(
dst
+
dstLen
,
src
);
}
void
simCloseRestFulConnect
(
SScript
*
script
)
{
memset
(
script
->
auth
,
0
,
sizeof
(
script
->
auth
));
}
void
simCloseNativeConnect
(
SScript
*
script
)
{
if
(
script
->
taos
==
NULL
)
return
;
...
...
@@ -480,166 +476,7 @@ void simCloseNativeConnect(SScript *script) {
}
void
simCloseTaosdConnect
(
SScript
*
script
)
{
if
(
simAsyncQuery
)
{
simCloseRestFulConnect
(
script
);
}
else
{
simCloseNativeConnect
(
script
);
}
}
// {"status":"succ","code":0,"desc":"/KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04"}
// {"status":"succ","head":["affected_rows"],"data":[[1]],"rows":1}
// {"status":"succ","head":["ts","i"],"data":[["2017-12-25 21:28:41.022",1],["2017-12-25 21:28:42.022",2],["2017-12-25 21:28:43.022",3],["2017-12-25 21:28:44.022",4],["2017-12-25 21:28:45.022",5],["2017-12-25 21:28:46.022",6],["2017-12-25 21:28:47.022",7],["2017-12-25 21:28:48.022",8],["2017-12-25 21:28:49.022",9],["2017-12-25 21:28:50.022",10]],"rows":10}
int32_t
simParseHttpCommandResult
(
SScript
*
script
,
char
*
command
)
{
cJSON
*
root
=
cJSON_Parse
(
command
);
if
(
root
==
NULL
)
{
simError
(
"script:%s, failed to parse json, response:%s"
,
script
->
fileName
,
command
);
return
-
1
;
}
cJSON
*
status
=
cJSON_GetObjectItem
(
root
,
"status"
);
if
(
status
==
NULL
)
{
simError
(
"script:%s, failed to parse json, status is null, response:%s"
,
script
->
fileName
,
command
);
cJSON_Delete
(
root
);
return
-
1
;
}
if
(
status
->
valuestring
==
NULL
||
strlen
(
status
->
valuestring
)
==
0
)
{
simError
(
"script:%s, failed to parse json, status value is null, response:%s"
,
script
->
fileName
,
command
);
cJSON_Delete
(
root
);
return
-
1
;
}
if
(
strcmp
(
status
->
valuestring
,
"succ"
)
!=
0
)
{
cJSON
*
code
=
cJSON_GetObjectItem
(
root
,
"code"
);
if
(
code
==
NULL
)
{
simError
(
"script:%s, failed to parse json, code is null, response:%s"
,
script
->
fileName
,
command
);
cJSON_Delete
(
root
);
return
-
1
;
}
int32_t
retcode
=
(
int32_t
)
code
->
valueint
;
if
(
retcode
!=
1017
)
{
simError
(
"script:%s, json:status:%s not equal to succ, response:%s"
,
script
->
fileName
,
status
->
valuestring
,
command
);
cJSON_Delete
(
root
);
return
retcode
;
}
else
{
simDebug
(
"script:%s, json:status:%s not equal to succ, but code is %d, response:%s"
,
script
->
fileName
,
status
->
valuestring
,
retcode
,
command
);
cJSON_Delete
(
root
);
return
0
;
}
}
cJSON
*
desc
=
cJSON_GetObjectItem
(
root
,
"desc"
);
if
(
desc
!=
NULL
)
{
if
(
desc
->
valuestring
==
NULL
||
strlen
(
desc
->
valuestring
)
==
0
)
{
simError
(
"script:%s, failed to parse json, desc value is null, response:%s"
,
script
->
fileName
,
command
);
cJSON_Delete
(
root
);
return
-
1
;
}
strcpy
(
script
->
auth
,
desc
->
valuestring
);
cJSON_Delete
(
root
);
return
0
;
}
cJSON
*
data
=
cJSON_GetObjectItem
(
root
,
"data"
);
if
(
data
==
NULL
)
{
simError
(
"script:%s, failed to parse json, data is null, response:%s"
,
script
->
fileName
,
command
);
cJSON_Delete
(
root
);
return
-
1
;
}
int32_t
rowsize
=
cJSON_GetArraySize
(
data
);
if
(
rowsize
<
0
)
{
simError
(
"script:%s, failed to parse json:data, data size %d, response:%s"
,
script
->
fileName
,
rowsize
,
command
);
cJSON_Delete
(
root
);
return
-
1
;
}
int32_t
rowIndex
=
0
;
sprintf
(
script
->
rows
,
"%d"
,
rowsize
);
for
(
int32_t
r
=
0
;
r
<
rowsize
;
++
r
)
{
cJSON
*
row
=
cJSON_GetArrayItem
(
data
,
r
);
if
(
row
==
NULL
)
continue
;
if
(
rowIndex
++
>=
10
)
break
;
int32_t
colsize
=
cJSON_GetArraySize
(
row
);
if
(
colsize
<
0
)
{
break
;
}
colsize
=
MIN
(
10
,
colsize
);
for
(
int32_t
c
=
0
;
c
<
colsize
;
++
c
)
{
cJSON
*
col
=
cJSON_GetArrayItem
(
row
,
c
);
if
(
col
->
valuestring
!=
NULL
)
{
strcpy
(
script
->
data
[
r
][
c
],
col
->
valuestring
);
}
else
{
if
(
col
->
numberstring
[
0
]
==
0
)
{
strcpy
(
script
->
data
[
r
][
c
],
"null"
);
}
else
{
strcpy
(
script
->
data
[
r
][
c
],
col
->
numberstring
);
}
}
}
}
return
0
;
}
int32_t
simExecuteRestFulCommand
(
SScript
*
script
,
char
*
command
)
{
char
buf
[
5000
]
=
{
0
};
sprintf
(
buf
,
"%s 2>/dev/null"
,
command
);
FILE
*
fp
=
popen
(
buf
,
"r"
);
if
(
fp
==
NULL
)
{
simError
(
"failed to execute %s"
,
buf
);
return
-
1
;
}
int32_t
mallocSize
=
2000
;
int32_t
alreadyReadSize
=
0
;
char
*
content
=
malloc
(
mallocSize
);
while
(
!
feof
(
fp
))
{
int32_t
availSize
=
mallocSize
-
alreadyReadSize
;
int32_t
len
=
(
int32_t
)
fread
(
content
+
alreadyReadSize
,
1
,
availSize
,
fp
);
if
(
len
>=
availSize
)
{
alreadyReadSize
+=
len
;
mallocSize
*=
2
;
content
=
realloc
(
content
,
mallocSize
);
}
}
pclose
(
fp
);
return
simParseHttpCommandResult
(
script
,
content
);
}
bool
simCreateRestFulConnect
(
SScript
*
script
,
char
*
user
,
char
*
pass
)
{
char
command
[
4096
];
sprintf
(
command
,
"curl 127.0.0.1:6041/rest/login/%s/%s"
,
user
,
pass
);
bool
success
=
false
;
for
(
int32_t
attempt
=
0
;
attempt
<
10
;
++
attempt
)
{
success
=
simExecuteRestFulCommand
(
script
,
command
)
==
0
;
if
(
!
success
)
{
simDebug
(
"script:%s, user:%s connect taosd failed:%s, attempt:%d"
,
script
->
fileName
,
user
,
taos_errstr
(
NULL
),
attempt
);
taosMsleep
(
1000
);
}
else
{
simDebug
(
"script:%s, user:%s connect taosd successed, attempt:%d"
,
script
->
fileName
,
user
,
attempt
);
break
;
}
}
if
(
!
success
)
{
sprintf
(
script
->
error
,
"lineNum:%d. connect taosd failed:%s"
,
script
->
lines
[
script
->
linePos
].
lineNum
,
taos_errstr
(
NULL
));
return
false
;
}
simDebug
(
"script:%s, connect taosd successed, auth:%p"
,
script
->
fileName
,
script
->
auth
);
return
true
;
simCloseNativeConnect
(
script
);
}
bool
simCreateNativeConnect
(
SScript
*
script
,
char
*
user
,
char
*
pass
)
{
...
...
@@ -651,7 +488,7 @@ bool simCreateNativeConnect(SScript *script, char *user, char *pass) {
return
false
;
}
taos
=
taos_connect
(
NULL
,
user
,
pass
,
NULL
,
tsDnodeShellPort
);
taos
=
taos_connect
(
NULL
,
user
,
pass
,
NULL
,
0
);
if
(
taos
==
NULL
)
{
simDebug
(
"script:%s, user:%s connect taosd failed:%s, attempt:%d"
,
script
->
fileName
,
user
,
taos_errstr
(
NULL
),
attempt
);
...
...
@@ -684,11 +521,7 @@ bool simCreateTaosdConnect(SScript *script, char *rest) {
user
=
token
;
}
if
(
simAsyncQuery
)
{
return
simCreateRestFulConnect
(
script
,
user
,
TSDB_DEFAULT_PASS
);
}
else
{
return
simCreateNativeConnect
(
script
,
user
,
TSDB_DEFAULT_PASS
);
}
return
simCreateNativeConnect
(
script
,
user
,
TSDB_DEFAULT_PASS
);
}
bool
simExecuteNativeSqlCommand
(
SScript
*
script
,
char
*
rest
,
bool
isSlow
)
{
...
...
@@ -710,7 +543,7 @@ bool simExecuteNativeSqlCommand(SScript *script, char *rest, bool isSlow) {
pSql
=
taos_query
(
script
->
taos
,
rest
);
ret
=
taos_errno
(
pSql
);
if
(
ret
==
TSDB_CODE_MND_
TABLE
_ALREADY_EXIST
||
ret
==
TSDB_CODE_MND_DB_ALREADY_EXIST
)
{
if
(
ret
==
TSDB_CODE_MND_
STB
_ALREADY_EXIST
||
ret
==
TSDB_CODE_MND_DB_ALREADY_EXIST
)
{
simDebug
(
"script:%s, taos:%p, %s success, ret:%d:%s"
,
script
->
fileName
,
script
->
taos
,
rest
,
ret
&
0XFFFF
,
tstrerror
(
ret
));
ret
=
0
;
...
...
@@ -877,41 +710,6 @@ bool simExecuteNativeSqlCommand(SScript *script, char *rest, bool isSlow) {
return
true
;
}
bool
simExecuteRestFulSqlCommand
(
SScript
*
script
,
char
*
rest
)
{
SCmdLine
*
line
=
&
script
->
lines
[
script
->
linePos
];
char
command
[
4096
];
sprintf
(
command
,
"curl -H 'Authorization: Taosd %s' -d
\"
%s
\"
127.0.0.1:6041/rest/sql"
,
script
->
auth
,
rest
);
int32_t
ret
=
-
1
;
for
(
int32_t
attempt
=
0
;
attempt
<
10
;
++
attempt
)
{
ret
=
simExecuteRestFulCommand
(
script
,
command
);
if
(
ret
==
TSDB_CODE_MND_TABLE_ALREADY_EXIST
||
ret
==
TSDB_CODE_MND_DB_ALREADY_EXIST
)
{
simDebug
(
"script:%s, taos:%p, %s success, ret:%d:%s"
,
script
->
fileName
,
script
->
taos
,
rest
,
ret
&
0XFFFF
,
tstrerror
(
ret
));
ret
=
0
;
break
;
}
else
if
(
ret
!=
0
)
{
simDebug
(
"script:%s, taos:%p, %s failed, ret:%d"
,
script
->
fileName
,
script
->
taos
,
rest
,
ret
);
if
(
line
->
errorJump
==
SQL_JUMP_TRUE
)
{
script
->
linePos
=
line
->
jump
;
return
true
;
}
taosMsleep
(
1000
);
}
else
{
break
;
}
}
if
(
ret
)
{
sprintf
(
script
->
error
,
"lineNum:%d. sql:%s failed, ret:%d"
,
line
->
lineNum
,
rest
,
ret
);
return
false
;
}
script
->
linePos
++
;
return
true
;
}
bool
simExecuteSqlImpCmd
(
SScript
*
script
,
char
*
rest
,
bool
isSlow
)
{
char
buf
[
3000
];
SCmdLine
*
line
=
&
script
->
lines
[
script
->
linePos
];
...
...
@@ -935,7 +733,7 @@ bool simExecuteSqlImpCmd(SScript *script, char *rest, bool isSlow) {
return
true
;
}
if
(
(
!
simAsyncQuery
&&
script
->
taos
==
NULL
)
||
(
simAsyncQuery
&&
script
->
auth
[
0
]
==
0
)
)
{
if
(
script
->
taos
==
NULL
)
{
if
(
!
simCreateTaosdConnect
(
script
,
"connect root"
))
{
if
(
line
->
errorJump
==
SQL_JUMP_TRUE
)
{
script
->
linePos
=
line
->
jump
;
...
...
@@ -951,11 +749,7 @@ bool simExecuteSqlImpCmd(SScript *script, char *rest, bool isSlow) {
return
true
;
}
if
(
simAsyncQuery
)
{
return
simExecuteRestFulSqlCommand
(
script
,
rest
);
}
else
{
return
simExecuteNativeSqlCommand
(
script
,
rest
,
isSlow
);
}
return
simExecuteNativeSqlCommand
(
script
,
rest
,
isSlow
);
}
bool
simExecuteSqlCmd
(
SScript
*
script
,
char
*
rest
)
{
...
...
@@ -1009,6 +803,7 @@ bool simExecuteRestfulCmd(SScript *script, char *rest) {
return
simExecuteSystemCmd
(
script
,
cmd
);
}
bool
simExecuteSqlErrorCmd
(
SScript
*
script
,
char
*
rest
)
{
char
buf
[
3000
];
SCmdLine
*
line
=
&
script
->
lines
[
script
->
linePos
];
...
...
@@ -1032,7 +827,7 @@ bool simExecuteSqlErrorCmd(SScript *script, char *rest) {
return
true
;
}
if
(
(
!
simAsyncQuery
&&
script
->
taos
==
NULL
)
||
(
simAsyncQuery
&&
script
->
auth
[
0
]
==
0
)
)
{
if
(
script
->
taos
==
NULL
)
{
if
(
!
simCreateTaosdConnect
(
script
,
"connect root"
))
{
if
(
line
->
errorJump
==
SQL_JUMP_TRUE
)
{
script
->
linePos
=
line
->
jump
;
...
...
@@ -1048,17 +843,9 @@ bool simExecuteSqlErrorCmd(SScript *script, char *rest) {
return
true
;
}
int32_t
ret
;
TAOS_RES
*
pSql
=
NULL
;
if
(
simAsyncQuery
)
{
char
command
[
4096
];
sprintf
(
command
,
"curl -H 'Authorization: Taosd %s' -d '%s' 127.0.0.1:6041/rest/sql"
,
script
->
auth
,
rest
);
ret
=
simExecuteRestFulCommand
(
script
,
command
);
}
else
{
pSql
=
taos_query
(
script
->
taos
,
rest
);
ret
=
taos_errno
(
pSql
);
taos_free_result
(
pSql
);
}
TAOS_RES
*
pSql
=
pSql
=
taos_query
(
script
->
taos
,
rest
);
int32_t
ret
=
taos_errno
(
pSql
);
taos_free_result
(
pSql
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
simDebug
(
"script:%s, taos:%p, %s execute, expect failed, so success, ret:%d:%s"
,
script
->
fileName
,
script
->
taos
,
...
...
@@ -1084,7 +871,11 @@ bool simExecuteLineInsertCmd(SScript *script, char *rest) {
simInfo
(
"script:%s, %s"
,
script
->
fileName
,
rest
);
simLogSql
(
buf
,
true
);
char
*
lines
[]
=
{
rest
};
#if 0
int32_t ret = taos_insert_lines(script->taos, lines, 1);
#else
int32_t
ret
=
0
;
#endif
if
(
ret
==
TSDB_CODE_SUCCESS
)
{
simDebug
(
"script:%s, taos:%p, %s executed. success."
,
script
->
fileName
,
script
->
taos
,
rest
);
script
->
linePos
++
;
...
...
@@ -1107,7 +898,11 @@ bool simExecuteLineInsertErrorCmd(SScript *script, char *rest) {
simInfo
(
"script:%s, %s"
,
script
->
fileName
,
rest
);
simLogSql
(
buf
,
true
);
char
*
lines
[]
=
{
rest
};
#if 0
int32_t ret = taos_insert_lines(script->taos, lines, 1);
#else
int32_t
ret
=
0
;
#endif
if
(
ret
==
TSDB_CODE_SUCCESS
)
{
sprintf
(
script
->
error
,
"script:%s, taos:%p, %s executed. expect failed, but success."
,
script
->
fileName
,
script
->
taos
,
rest
);
script
->
linePos
++
;
...
...
tests/tsim/src/simMain.c
浏览文件 @
8e68fa6e
...
...
@@ -17,9 +17,7 @@
#include "os.h"
#include "tglobal.h"
#include "sim.h"
#undef TAOS_MEM_CHECK
bool
simAsyncQuery
=
false
;
bool
simExecSuccess
=
false
;
bool
abortExecution
=
false
;
...
...
@@ -38,8 +36,6 @@ int32_t main(int32_t argc, char *argv[]) {
tstrncpy
(
configDir
,
argv
[
++
i
],
128
);
}
else
if
(
strcmp
(
argv
[
i
],
"-f"
)
==
0
&&
i
<
argc
-
1
)
{
strcpy
(
scriptFile
,
argv
[
++
i
]);
}
else
if
(
strcmp
(
argv
[
i
],
"-a"
)
==
0
)
{
simAsyncQuery
=
true
;
}
else
{
printf
(
"usage: %s [options]
\n
"
,
argv
[
0
]);
printf
(
" [-c config]: config directory, default is: %s
\n
"
,
configDir
);
...
...
tests/tsim/src/simParse.c
浏览文件 @
8e68fa6e
...
...
@@ -62,7 +62,6 @@
#include "sim.h"
#include "simParse.h"
#include "tutil.h"
#undef TAOS_MEM_CHECK
static
SCommand
*
cmdHashList
[
MAX_NUM_CMD
];
static
SCmdLine
cmdLine
[
MAX_CMD_LINES
];
...
...
tests/tsim/src/simSystem.c
浏览文件 @
8e68fa6e
...
...
@@ -14,15 +14,13 @@
*/
#define _DEFAULT_SOURCE
#include "
../../../include/client/
taos.h"
#include "taos.h"
#include "os.h"
#include "sim.h"
#include "taoserror.h"
#include "tglobal.h"
#include "tsocket.h"
#include "ttimer.h"
#include "tutil.h"
#undef TAOS_MEM_CHECK
SScript
*
simScriptList
[
MAX_MAIN_SCRIPT_NUM
];
SCommand
simCmdList
[
SIM_CMD_END
];
...
...
@@ -81,9 +79,6 @@ char *simParseHostName(char *varName) {
}
bool
simSystemInit
()
{
if
(
taos_init
())
{
return
false
;
}
taosGetFqdn
(
simHostName
);
simInitsimCmdList
();
memset
(
simScriptList
,
0
,
sizeof
(
SScript
*
)
*
MAX_MAIN_SCRIPT_NUM
);
...
...
tools/shell/inc/shellCommand.h
浏览文件 @
8e68fa6e
...
...
@@ -13,8 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _
_COMMAND_STRUCT_
_
#define _
_COMMAND_STRUCT_
_
#ifndef _
TD_SHELL_COMMAND_H
_
#define _
TD_SHELL_COMMAND_H
_
#include "shell.h"
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录