##############################################################################
#                                                                            #
# IAR ARM ANSI C/C++ Compiler V4.11A/W32               20/Jul/2004  18:58:49 #
# Copyright 1999-2004 IAR Systems. All rights reserved.                      #
#                                                                            #
#    Cpu mode        =  arm                                                  #
#    Endian          =  little                                               #
#    Stack alignment =  4                                                    #
#    Source file     =  C:\medusa\cli.c                                      #
#    Command line    =  -I "C:\Program Files\IAR Systems\Embedded Workbench  #
#                       4.0\ARM\INC\" -lc C:\medusa\Debug\List\ -la          #
#                       C:\medusa\Debug\List\ -o C:\medusa\Debug\Obj\ -s2    #
#                       --no_cse --no_unroll --no_inline --no_code_motion    #
#                       --no_tbaa --no_clustering --no_scheduling --debug    #
#                       --cpu_mode arm --endian little --cpu ARM7TDMI-S      #
#                       --stack_align 4 -e --fpu None                        #
#                       "-D_DLIB_CONFIG_FILE=C:\Program Files\IAR            #
#                       Systems\Embedded Workbench                           #
#                       4.0\ARM\LIB\dl4tpannl8n.h" C:\medusa\cli.c           #
#    List file       =  C:\medusa\Debug\List\cli.lst                         #
#    Object file     =  C:\medusa\Debug\Obj\cli.r79                          #
#                                                                            #
#                                                                            #
##############################################################################

C:\medusa\cli.c
      1          #include "archinc.h"
      2          #include "strutil.h"
      3          #include "cli.h"
      4          #include "clichar.h"
      5          
      6          #include <stdio.h>
      7          
      8          /*
      9           * The raw character input comes into inputBuf, until a '\n' is encountered at 
     10           * which point '\0' is substituted. The line is parsed and any cli variables are
     11           * substituted into the argBuffer. Each argument is counted and an argv[] entry
     12           * is computed so that each command has an familiar argv[],argc interface. 
     13           * String parsing is still up to the cli command handler.
     14           */
     15          
     16          typedef struct cliCommand {
     17            char *cmdName;
     18            cliCommandHandler handler;
     19            char * helpText; // help strings should be allocated in text segment
     20          } cliCommand, *pCliCommand;
     21          
     22          static char argBuffer[CONFIG_CLI_ARG_BUF_SIZE];
     23          static char * argvArray[CONFIG_CLI_MAX_ARGUMENTS];
     24          
     25          cliCommand handlerTable[CONFIG_CLI_MAX_COMMANDS];
     26          
     27          static int handlerTableLen;
     28          
     29          int helpHandler(int, char **, int);
     30          
     31          
     32          // returns 0 and command structure if found, -1 otherwise
     33          static int lookupCommand(char *lookupName, pCliCommand * ppCmd)
     34          {
     35            int retVal = -1;
     36            int i;
     37              
     38            for(i=0;i<handlerTableLen;i++) {
     39              if ( (retVal = strutil_strncasecmp(lookupName, handlerTable[i].cmdName, 16)) == 0) {
     40                *ppCmd = &(handlerTable[i]);
     41                retVal = 0;
     42                break;
     43                }
     44              else {
     45                }
     46              }
     47                
     48            return retVal;
     49          }
     50          
     51          #ifdef CONFIG_TOOLCHAIN_IAR
     52          #pragma inline
     53          #endif
     54          static INLINE_KEYWORD int skipWhiteSpace(char **s)
     55          {
     56            while( ((**s == ' ') || (**s == '\t')) && (**s != '\0')) (*s)++; 
     57            return ((**s == '\0') ? -1 : 0);
     58          } 
     59          
     60          #ifdef CONFIG_TOOLCHAIN_IAR
     61          #pragma inline
     62          #endif
     63          static INLINE_KEYWORD int seekWhiteSpace(char **s)
     64          {
     65            while( (**s != ' ') && (**s != '\t') && (**s != '\0') ) (*s)++; 
     66            return ((**s == '\0') ? -1 : 0);
     67          }
     68          
     69          // This routine searches for a '#' character and if found, terminates the string at that point
     70          static int processLineComment(char * inputString, int maxInputLen)
     71          {
     72            int i;
     73            
     74            if ((maxInputLen == 0) || (*inputString == '\0')) {
     75              return -1;
     76              }
     77            
     78            i = 0;  
     79            while((i<maxInputLen) && (*inputString != '\0')) {
     80              if (*inputString == '#') {
     81                *inputString = '\0';
     82                break;
     83                }
     84              i++;
     85              inputString++;
     86              }
     87                
     88            return 0;
     89          }
     90          
     91          // copies *pSource to *pDest until (pSource = pTerm)  or *pSource = '\0'
     92          #ifdef CONFIG_TOOLCHAIN_IAR
     93          #pragma inline
     94          #endif
     95          static INLINE_KEYWORD int dupStr(char *pSource, char *pTerm, char *pDest)
     96          {
     97            int dupLen = 0;
     98            int ptrInc;
     99          
    100            if (pSource < pTerm)
    101              ptrInc = 1;
    102            else 
    103              ptrInc = -1; 
    104          
    105          
    106            while ((pSource != pTerm) && (*pSource != '\0')){
    107              *pDest = *pSource;
    108              pDest += ptrInc;
    109              pSource += ptrInc;
    110              dupLen++;
    111              }
    112            
    113            // copy pSource = pTerm (i.e. the null char)
    114            *pDest = *pSource;
    115            dupLen++;
    116          
    117            return dupLen;
    118          }
    119          
    120          // TODO: check input string length
    121          static int tokenizeString(char * inputString, char *argvArray[], int argvArraySize)
    122          {
    123            char *pLkup, *pA, *pB, *pC;
                         ^
Warning[Pe177]: variable "pLkup" was declared but never referenced

    char *pLkup, *pA, *pB, *pC;
                  ^
"C:\medusa\cli.c",123  Warning[Pe550]: variable "pA" was set but never used

    char *pLkup, *pA, *pB, *pC;
                       ^
"C:\medusa\cli.c",123  Warning[Pe550]: variable "pB" was set but never used

    char *pLkup, *pA, *pB, *pC;
                            ^
"C:\medusa\cli.c",123  Warning[Pe550]: variable "pC" was set but never used
    124            int argvIdx;
    125            int i;
    126            
    127            if (argvArraySize == 0)
    128              return -1;
    129              
    130            // initialize argv[] array
    131            for(i=0;i<argvArraySize;i++)
    132              argvArray[i] = NULL;
    133          
    134            // skip any leading whitespace
    135            if (skipWhiteSpace(&inputString) == -1)
    136              return -1;
    137              
    138            pA = pB = pC = inputString;
    139            
    140            // okay, we've got at least one argument
    141            argvIdx = 0;
    142            argvArray[argvIdx++] = inputString;
    143          
    144            // grab the rest of 'em...    
    145            while ((seekWhiteSpace(&inputString) == 0) && (argvIdx < argvArraySize)) {
    146              *inputString++ = '\0'; // null terminate previous token
    147          #if 1
    148              skipWhiteSpace(&inputString); // skip to current token
    149          #endif
    150          #if 0
    151            while ((skipWhite(&pA) == 0) && (i < argvArraySize)) {
    152              pC = pA;
    153          
    154              // handle cli variables
    155              if (*pA == '$') {
    156                pB = ++pA;         // skip past the '$'
    157                seekWhite(&pB);    // look for variable delimeter
    158                *pB = '\0';        // null terminate
    159          
    160                // copy pA to pLkup while pA <= pB
    161                dupStr(pA, pB, pLkup)
    162          
    163                if ((retVal = clivarDoLookup(pLkup)) != -1)
    164                  // TODO: copy pLkupResult to pC
    165                  }
    166                else {
    167                  // straight copy
    168                  }
    169          #endif
    170          
    171              argvArray[argvIdx++] = inputString; // add current token to argv array
    172              }
    173              
    174            // return the new argc
    175            return argvIdx;
    176          }
    177           
    178          int cliInit(void)
    179          {
    180            handlerTableLen = 0;
    181            
    182            // register char accumulator as input event recipient
    183            cliRegisterCommand("help", helpHandler, "help <command>");
    184            return 0;
    185          }
    186          
    187          int cliRegisterCommand(char * cmdStr, cliCommandHandler handler, char * helpStr)
    188          {
    189            pCliCommand pCmdEntry;
    190            
    191            if (handlerTableLen == CONFIG_CLI_MAX_COMMANDS)
    192              return -1;
    193              
    194            // TODO: search for duplicate commands
    195            
    196            // insert the command into the table
    197            pCmdEntry = &(handlerTable[handlerTableLen]);
    198            pCmdEntry->cmdName = cmdStr;
    199            pCmdEntry->handler = handler;
    200            pCmdEntry->helpText = helpStr;
    201            
    202            // bump the command table length
    203            handlerTableLen++;
    204            
    205            return 0;
    206          }
    207          
    208          int cliDoCommand(char * pBuffer, int maxBufferLen)
    209          {
    210            int i;
    211            int retVal = -1;
    212            pCliCommand pCmd;
    213            int argc;
    214            int flags;
    215            int bufLen;
    216            char * pOutBuf;
    217          
    218            pOutBuf = clicharGetOutputBuffer(&bufLen);
    219            
    220            // process any comment lines and return -1 if a null line
    221            if (processLineComment(pBuffer, maxBufferLen) == -1)
    222              return retVal;
    223              
    224            if ((argc = tokenizeString(pBuffer, argvArray, (int)CONFIG_CLI_MAX_ARGUMENTS)) != -1) {
    225              if (lookupCommand(argvArray[0], &pCmd) == 0) {
    226                if ((pCmd != NULL) && (pCmd->handler != NULL)) {
    227                  retVal = (pCmd->handler)(argc, argvArray, flags);
                                                                   ^
Warning[Pe549]: variable "flags" is used before its value is set

    int i;
        ^
"C:\medusa\cli.c",210  Warning[Pe177]: variable "i" was declared but never
          referenced

  static char argBuffer[CONFIG_CLI_ARG_BUF_SIZE];
              ^
"C:\medusa\cli.c",22  Warning[Pe177]: variable "argBuffer" was declared but
          never referenced

  static INLINE_KEYWORD int dupStr(char *pSource, char *pTerm, char *pDest)
                            ^
"C:\medusa\cli.c",95  Warning[Pe177]: function "dupStr" was declared but never
          referenced
    228                  if (retVal != 0) {
    229                    // do something: print error 
    230                    sprintf(pOutBuf, "%s: error, returned [%d]\r\n",argvArray[0],retVal);
    231                    clicharSendOutputBuffer(pOutBuf, bufLen);
    232                    } // (retVal != 0)
    233                  } // (pCmd->handler != NULL)
    234                }
    235              else {
    236                sprintf(pOutBuf, "error, command not found [%s]\r\n",argvArray[0]);
    237                clicharSendOutputBuffer(pOutBuf, bufLen);
    238                }
    239              }
    240          
    241            return retVal;
    242          }
    243          
    244          int helpHandler(int argc, char * argv[], int flags)
    245          {
    246            int i;
    247            pCliCommand pCmd;
    248            int bufLen;
    249            char * pOutBuf;
    250          
    251            pOutBuf = clicharGetOutputBuffer(&bufLen);
    252            
    253            if (argc > 1) {
    254              if (lookupCommand(argv[1], &pCmd) == 0) {
    255                if (pCmd->helpText != NULL) {
    256                  sprintf(pOutBuf, "%s: %s\r\n",argv[1],pCmd->helpText);
    257                  clicharSendOutputBuffer(pOutBuf, bufLen);
    258                  }
    259                }
    260              }
    261            else {
    262              pCmd = &(handlerTable[0]);
    263              for(i=0;i<handlerTableLen;i++,pCmd++) {
    264                if (pCmd->helpText != NULL) {
    265                  sprintf(pOutBuf, "%s: %s\r\n", pCmd->cmdName, pCmd->helpText);
    266                  clicharSendOutputBuffer(pOutBuf, bufLen);
    267                  }
    268                }
    269              }
    270              
    271            return 0;
    272          }
    273          

   Maximum stack usage in bytes:

     Function           CSTACK
     --------           ------
     cliDoCommand          40
     cliInit                4
     cliRegisterCommand     8
     helpHandler           32
     lookupCommand         20
     processLineComment     0
     seekWhiteSpace         0
     skipWhiteSpace         0
     tokenizeString        40


   Segment part sizes:

     Function/Label                 Bytes
     --------------                 -----
     argvArray                        32
     handlerTable                    768
     handlerTableLen                   4
     lookupCommand                   128
     ??skipWhiteSpace_0               96
     ??seekWhiteSpace_0               96
     processLineComment              104
     tokenizeString                  232
     cliInit                          52
     cliRegisterCommand              100
     cliDoCommand                    280
     helpHandler                     240
     ??DataTable9                      4
     ??DataTable10                     4
     ?<Constant "help">                8
     ?<Constant "help <command>">     16
     ?<Constant "%s: error, returned [...">
                                      28
     ?<Constant "error, command not fo...">
                                      32
     ?<Constant "%s: %s\r\n">         12
      Others                          60

 
 1 384 bytes in segment CODE
    96 bytes in segment DATA_C
   804 bytes in segment DATA_Z
    12 bytes in segment INITTAB
 
 1 336 bytes of CODE  memory (+ 60 bytes shared)
    96 bytes of CONST memory
   804 bytes of DATA  memory

Errors: none
Warnings: 8
