📄 debug.c
字号:
{
int st = 0;
int curNdx;
char c;
for (curNdx = 0; st == 0 && curNdx < inCnt; curNdx++) {
c = rBuf[curNdx];
switch(c) {
case '\r':
if ((st = monParseCmd(mc)) < 0) {
;
} else if ((st = mc->commandFcn(mc)) < 0) {
;
} else if ((st = fputs(MONPROMPT, mc->fp)) < 0 || fflush(mc->fp) < 0) {
DIAGMONTRACE((LOG_ERR, "monProcInput[%d]: Error %d on write errno=%d",
(int)(mc - &monitorControl[0]), st, errno));
}
mc->cmdLen = 0;
break;
case '\n':
/* Ignore line feeds for now. */
break;
case '\b':
if (mc->cmdLen > 0)
mc->cmdLen--;
break;
default:
if (mc->cmdLen < CMDLINESZ)
mc->cmdBuf[mc->cmdLen++] = c;
}
}
return st;
}
/*
* monParseCmd - Parse the current command line. This is called when an
* end-of-line indication is reached. This sets up the commmand parameters
* for a call to the appropriate command handler.
* Return 0 on success, an error code on failure.
*/
static int monParseCmd(MonitorControl *mc)
{
int st = 0;
int curNdx;
char *tokenPtr; /* Current token in command line. */
int tokenLen = 0; /* Current length of token. */
char c;
mc->parseFcn = parseCmdToken;
mc->curTokenTbl = cmdToken;
mc->sendStr = MONCMDLIST;
mc->curCmdArgQty = 0;
for (curNdx = 0; curNdx < MAXCMDARGS; curNdx++)
mc->curCmdArgs[curNdx] = -1;
for (curNdx = 0; st >= 0 && curNdx <= mc->cmdLen; curNdx++) {
if (curNdx < mc->cmdLen)
c = mc->cmdBuf[curNdx];
else
c = '\0';
/*
* Alphanumerics are treated as strings separated by white space
* and operators/punctuation.
*/
if (isalnum(c)) {
mc->cmdBuf[curNdx] = toupper(c);
if (tokenLen++ == 0)
tokenPtr = &mc->cmdBuf[curNdx];
} else {
/*
* Anything else is treated as white space which is used
* to delimit string tokens.
*/
if (tokenLen > 0) {
st = mc->parseFcn(mc, tokenPtr, tokenLen);
tokenLen = 0;
}
/*
* Handle special characters. This could be a little more
* sophisticated and do a lookahead for multi-character
* operators but we'll worry about that when we need to.
*/
if (c && st >= 0 && (ispunct(c) || iscntrl(c))) {
tokenPtr = &mc->cmdBuf[curNdx];
st = mc->parseFcn(mc, tokenPtr, 1);
}
}
}
mc->cmdLen = 0;
return st;
}
/*
* parseCmdToken - Interpret a command token. This is handled separately
* the command line arguments since there is no previous token table
* entry to define an error string for unrecognized commands.
* Return 0 on success, an error code on failure.
*/
static int parseCmdToken(MonitorControl *mc, const char *tokenPtr, int tokenLen)
{
const TokenTable *t0;
int st = 0;
if ((t0 = findToken(tokenPtr, tokenLen, cmdToken)) == NULL) {
// Unrecognized command so display command list.
mc->sendStr = MONCMDLIST;
mc->commandFcn = monSendStr;
mc->parseFcn = parseEOL;
} else {
mc->commandFcn = cmdFcn[t0->tokenValue];
mc->curTokenTbl = t0->nextTbl;
mc->parseFcn = t0->parseFcn;
mc->sendStr = t0->errStr;
}
return st;
}
/*
* parseCmdArg - Process a command argument.
* Return 0 on success, an error code on failure.
*/
static int parseCmdArg(MonitorControl *mc, const char *tokenPtr, int tokenLen)
{
const TokenTable *t0;
int st = 0;
if ((t0 = findToken(tokenPtr, tokenLen, mc->curTokenTbl)) == NULL) {
// Unrecognized arguement so display error message.
mc->commandFcn = monSendStr;
mc->parseFcn = parseEOL;
} else {
if (t0->tokenLabel[0] == '%') {
int tokVal = 0, i;
switch(t0->tokenLabel[1]) {
case 'd':
for (i = 0; i < tokenLen && isdigit(tokenPtr[i]); i++)
tokVal = tokVal * 10 + tokenPtr[i] - '0';
// Ignore trailing non-digit characters.
break;
default:
break;
}
mc->curCmdArgs[mc->curCmdArgQty++] = tokVal;
} else
mc->curCmdArgs[mc->curCmdArgQty++] = t0->tokenValue;
mc->curTokenTbl = t0->nextTbl;
mc->parseFcn = t0->parseFcn;
mc->sendStr = t0->errStr;
}
return st;
}
/*
* findToken - Do a linear search of the token table for the first token
* that matches the first tokenLen characters of the token buffer.
* Return a pointer to the token table record if found, otherwise NULL.
*/
static const TokenTable *findToken(const char *tokenPtr, int tokenLen, const TokenTable *tt)
{
const TokenTable *st = NULL, *t0;
if (tt) {
// Note: The last entry in a table must have an empty string for a label.
for (t0 = tt; !st && t0->tokenLabel[0]; t0++) {
// Handle simplified printf style format types as wild cards.
if (t0->tokenLabel[0] == '%') {
switch(t0->tokenLabel[1]) {
case 'd':
if (isdigit(tokenPtr[0]))
st = t0;
break;
default:
break;
}
// Otherwise require a perfect match.
} else if (!strncmp(tokenPtr, t0->tokenLabel, tokenLen))
st = t0;
}
}
return st;
}
/*
* parseEOL - Skip to the end of the command line.
* Return 0 on success, an error code on failure.
*/
#pragma argsused
static int parseEOL(MonitorControl *mc, const char *tokenPtr, int tokenLen)
{
/* Ignore everything! */
return 0;
}
/*
* monDump - Perform a dump command. Dump is used to display a sequence of
* data that needs to be paginated. The dump option is saved so that a
* dump command without an option repeats the last option.
*/
static int monDump(MonitorControl *mc)
{
int st = 0;
static int lastCmd = MONDUMP_TRACE;
if (mc->curCmdArgQty > 0)
lastCmd = mc->curCmdArgs[0];
switch(lastCmd) {
case MONDUMP_SCAN:
scanDump(mc->fp, mc->curCmdArgs[1], mc->curCmdArgs[2]);
break;
case MONDUMP_TRACE:
default:
traceDump(mc->fp, mc->curCmdArgs[1], mc->curCmdArgs[2]);
break;
}
fflush(mc->fp);
return st;
}
/*
* monSet - Perform a set command.
*/
static int monSet(MonitorControl *mc)
{
int st = 0;
switch(mc->curCmdArgs[0]) {
case MONSET_TRACE: /* Set the trace levels. */
if (mc->curCmdArgQty < 2) {
st = monSendMask(mc);
} else {
traceLevel[mc->curCmdArgs[1]] = mc->curCmdArgs[2];
}
break;
default:
mc->sendStr = MONSETOPTIONS;
st = monSendStr(mc);
break;
}
return st;
}
/*
* monDisplay - Display a table.
*/
static int monDisplay(MonitorControl *mc)
{
int st = 0;
static int lastCmd = MONDISP_MCARD;
if (mc->curCmdArgQty > 0)
lastCmd = mc->curCmdArgs[0];
switch(lastCmd) {
#if STATS_SUPPORT > 0
case MONDISP_BUFFER: /* Display the buffer statistics. */
st = monSendStats(mc, (DiagStat *)&nBufStats);
break;
case MONDISP_TCP: /* Display TCP session statistics. */
st = monSendStats(mc, (DiagStat *)&tcpStats);
break;
case MONDISP_IP: /* Display IP statistics. */
st = monSendStats(mc, (DiagStat *)&ipStats);
break;
case MONDISP_PPP: /* Display PPP session statistics. */
st = monSendStats(mc, (DiagStat *)&pppStats);
break;
case MONDISP_SERIAL: /* Display serial driver statistics. */
st = monSendStats(mc, (DiagStat *)&sioStats);
break;
#endif
case MONDISP_MCARD: /* Display memory card status*/
default:
memCardDump(mc->fp, 0, 1000);
break;
}
return st;
}
static int monSendStr(MonitorControl *mc)
{
int st;
if ((st = write(fileno(mc->fp), mc->sendStr, strlen(mc->sendStr))) < 0) {
DIAGMONTRACE((LOG_ERR, "monSendStr[%d]: Error %d on write errno=%d",
(int)(mc - &monitorControl[0]), st, errno));
}
return st;
}
/*
* monSendMask - Send the trace mask.
*/
static int monSendMask(MonitorControl *mc)
{
int st = 0, i, n;
char sendBuf[SENDLINESZ + 1]; /* Extra for null termination. */
strcpy(sendBuf, "\r\n\t\tMODULE TRACE LEVELS\r\n");
n = strlen(sendBuf);
mc->sendStr = sendBuf;
/* Step through each of the trace modules. */
for (i = 0; st >= 0 && i < TL_MAX;) {
/* Build and send a buffer. */
while (i < TL_MAX && n <= SENDLINESZ - 16) {
sprintf(sendBuf + n, "\t%10s:%2u\r\n",
maskModuleToken[i].tokenLabel,
traceLevel[i]);
n = strlen(sendBuf);
i++;
}
st = monSendStr(mc);
n = 0;
sendBuf[0] = '\0';
}
return st >= 0 ? 0 : st;
}
/*
* monSendStats - Send network statistics.
*/
static int monSendStats(MonitorControl *mc, DiagStat ds[])
{
int st = 0, i, n;
char sendBuf[SENDLINESZ + 1]; /* Extra for null termination. */
char *strPtr;
mc->sendStr = sendBuf;
/*
* Step through each of the statistics records until reaching one with an
* empty name.
*/
for (i = 0; st >= 0 && ds[i].fmtStr && ds[i].fmtStr[0];) {
/* Build and send a buffer. */
n = 0;
sendBuf[0] = '\0';
while ((strPtr = ds[i].fmtStr) != NULL && *strPtr
&& n <= SENDLINESZ - (strlen(strPtr) + 10)) {
sprintf(sendBuf + n, strPtr, ds[i].val);
n = strlen(sendBuf);
i++;
}
st = monSendStr(mc);
}
return st >= 0 ? 0 : st;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -