Более нормальный подход можно увидеть тоже для контроллера, к примеру, в SoftModemLibrary для dsPic'а:
dsPIC30F Soft Modem Library\V.22bis Modem_R1.0\source\ATCMD\AT_Cmds.c
Вот выдержка (к такому разбору нужно стремится, т.к. это универсальный и стандартный подход по разбору выражений, ну или похож на него):
/*-------------------------------------------------------------------------
Function Name: InterpretCommand
Description : This function is used to interpret the AT command
Input : AT_Conmmand Structure pointer
Output : None
--------------------------------------------------------------------------*/void InterpretCommand(AT_COMMAND *atcmdptr, INT CHNID)
{
INT i;
INT Quiet1, Verbose1;
UCHAR TempBuf[6];
Quiet1 = atcmdptr->commands[ATQ];
Verbose1 = atcmdptr->commands[ATV];
switch(atcmdptr->KeyBuf[0])
{
// According to the first character of the command it will store the command
// characters from command buffer to current buffer.
case 'A':
case 'a':
for(i=0;i<=atcmdptr->KeyNo-1;i++)
{
atcmdptr->aiCurBuf[i] = atcmdptr->KeyBuf[i];
}
atcmdptr->icount = atcmdptr->KeyNo;
ProcessFunction(atcmdptr,atcmdptr->aiCurBuf,atcmdptr->icount, CHNID);
break;
default:
for(i=0;i<=atcmdptr->KeyNo-1;i++)
{
atcmdptr->aiprevbuf[i] = atcmdptr->KeyBuf[i];
}
atcmdptr->PrevCmdCntr=atcmdptr->KeyNo;
SendResponse(atcmdptr,COMERROR);
break;
}
}
/*-------------------------------------------------------------------------
Function Name: ProcessFunction
Description : This function is used to process and execute the required
functionality of the lower layer
Input : AT_Conmmand Structure pointer,Command Buf Pointer, character
count
Output : None
--------------------------------------------------------------------------*/
void ProcessFunction(AT_COMMAND *atcmdptr, CHAR *aiCurBuf, CHAR icount, CHAR CHNID)
{
INT i=0,cntr=2, val,SValue,SIndex;
INT ch,a1,a2;
INT QuietControl, VerboseControl;
CHAR ch1;
UINT MsgParams[25];
QuietControl = atcmdptr->commands[ATQ];
VerboseControl = atcmdptr->commands[ATV];
// read the 2nd character for slash (/)
ch = aiCurBuf[1];
//check for / after A if not / copy aiCurBuf to prevbuf
if(ch != '/')
{
for(i=0;i<=icount;i++)
{
atcmdptr->aiprevbuf[i] = aiCurBuf[i];
}
// copy the number of characters in icount to prevcntr
atcmdptr->PrevCmdCntr = icount;
}
else
{
// Repeat command then copy the recent command from
// prevbuf to aiCurBuf
for(i=0;i<=atcmdptr->PrevCmdCntr;i++)
{
aiCurBuf[i] = atcmdptr->aiprevbuf[i];
}
// Copy the PrevCmdCntr characters to icount for analyzing
atcmdptr->icount = atcmdptr->PrevCmdCntr;
}
//if icount is 2 then we have AT command then send
//OK response to DTE.
if(atcmdptr->aiCurBuf[1] != '/' && atcmdptr->aiCurBuf[1] != 't' && atcmdptr->aiCurBuf[1] != 'T')
{
SendResponse(atcmdptr,COMERROR);
return;
}
if(atcmdptr->icount == 2)
{
SendResponse(atcmdptr,COMOK);
// return;
}
// if the command is 3 characters i.e., ATA,ATH,AT+,ATD
// Store the current address of aiCurBuf to aiCurBuf,to fetch
// 3rd character
aiCurBuf = &aiCurBuf[2];