Revision 10fd7ac9 core/src/aos_shell.c

View differences:

core/src/aos_shell.c
544 544

  
545 545
  // move cursor right by printing line content
546 546
  while (pos < to) {
547
    streamPut(&shell->stream, shell->input.line[pos]);
547
    streamPut(&shell->stream, (uint8_t)shell->input.line[pos]);
548 548
    ++pos;
549 549
  }
550 550

  
......
568 568
  size_t cnt;
569 569

  
570 570
  for (cnt = 0; from + cnt < to; ++cnt) {
571
    streamPut(&shell->stream, shell->input.line[from + cnt]);
571
    streamPut(&shell->stream, (uint8_t)shell->input.line[from + cnt]);
572 572
  }
573 573

  
574 574
  return cnt;
......
578 578
  aosDbgCheck(shell != NULL);
579 579

  
580 580
  // check whether input line is already full
581
  if (shell->inputdata.lineend + 1 >= shell->input.width) {
581
  if (shell->inputdata.lineend + 1 >= shell->input.length) {
582 582
    return 0;
583 583
  } else {
584 584
    // clear old line content on first input
585 585
    if (shell->inputdata.noinput) {
586
      memset(shell->input.line, '\0', shell->input.width);
586
      memset(shell->input.line, '\0', shell->input.length);
587 587
      shell->inputdata.noinput = false;
588 588
    }
589 589
    // overwrite content
......
908 908
          charmatch_t mlvl = CHAR_MATCH_NOT;
909 909
          _strccmp(fill, cmd->name, shell->config & AOS_SHELL_CONFIG_MATCH_CASE, (n == 0) ? NULL : &n, &mlvl);
910 910
          const int cmp = (n < cmatch) ?
911
                            (n - cmatch) :
911
                            ((int)n - (int)cmatch) :
912 912
                            (cmd->name[n] != '\0') ?
913
                              strlen(cmd->name) - n :
913
                              (int)strlen(cmd->name) - (int)n :
914 914
                              0;
915 915
          // if an exact match was found
916
          if (cmatch + cmp == shell->inputdata.cursorpos) {
916
          if ((size_t)((int)cmatch + cmp) == shell->inputdata.cursorpos) {
917 917
            cmatch = shell->inputdata.cursorpos;
918 918
            fill = cmd->name;
919 919
            // break the loop only if there are no case mismatches with the input
......
924 924
            }
925 925
          }
926 926
          // if a not exact match was found
927
          else if (cmatch + cmp > shell->inputdata.cursorpos) {
927
          else if ((size_t)((int)cmatch + cmp) > shell->inputdata.cursorpos) {
928 928
            // if this is the first one
929 929
            if (fill == shell->input.line) {
930
              cmatch += cmp;
930
              cmatch = (size_t)((int)cmatch + cmp);
931 931
              fill = cmd->name;
932 932
            }
933 933
            // if this is a worse one
934 934
            else if ((cmp < 0) || (cmp == 0 && mlvl == CHAR_MATCH_CASE)) {
935
              cmatch += cmp;
935
              cmatch = (size_t)((int)cmatch + cmp);
936 936
            }
937 937
          }
938 938
          // non matching commands are ignored
......
945 945
        if (cmatch > shell->inputdata.cursorpos || (cmatch == shell->inputdata.cursorpos && matchlevel == CHAR_MATCH_NCASE)) {
946 946
          shell->inputdata.noinput = false;
947 947
          // limit auto fill so it will not overflow the line width
948
          if (shell->inputdata.lineend + (cmatch - shell->inputdata.cursorpos) > shell->input.width) {
949
            cmatch = shell->input.width - shell->inputdata.lineend + shell->inputdata.cursorpos;
948
          if (shell->inputdata.lineend + (cmatch - shell->inputdata.cursorpos) > shell->input.length) {
949
            cmatch = shell->input.length - shell->inputdata.lineend + shell->inputdata.cursorpos;
950 950
          }
951 951
          // move trailing memory further in the line
952 952
          memmove(&(shell->input.line[cmatch]), &(shell->input.line[shell->inputdata.cursorpos]), shell->inputdata.lineend - shell->inputdata.cursorpos);
......
982 982
            _strccmp(shell->input.line, cmd->name, true, &i, NULL);
983 983
          }
984 984
          const int cmp = (i < shell->inputdata.cursorpos) ?
985
                            (i - shell->inputdata.cursorpos) :
985
                            (int)(i - shell->inputdata.cursorpos) :
986 986
                            (cmd->name[i] != '\0') ?
987
                              strlen(cmd->name) - i :
987
                              (int)strlen(cmd->name) - (int)i :
988 988
                              0;
989 989
          // if a match was found
990 990
          if (cmp > 0) {
......
1048 1048
        size_t nul_start = 0;
1049 1049
        size_t nul_end = 0;
1050 1050
        // search line for a NUL byte
1051
        while (nul_start < shell->input.width) {
1051
        while (nul_start < shell->input.length) {
1052 1052
          if (shell->input.line[nul_start] == '\0') {
1053 1053
            nul_end = nul_start + 1;
1054 1054
            // keep searcjing for a byte that is not NUL
1055
            while (nul_end < shell->input.width) {
1055
            while (nul_end < shell->input.length) {
1056 1056
              if (shell->input.line[nul_end] != '\0') {
1057 1057
                // an intermediate NUL sequence was found
1058 1058
                memset(&(shell->input.line[nul_start]), ' ', nul_end - nul_start);
......
1149 1149
        streamPut(&shell->stream, '\n');
1150 1150
        // set the number of read bytes and return
1151 1151
        if (!shell->inputdata.noinput) {
1152
          *n = shell->input.width - shell->inputdata.lineend;
1152
          *n = shell->input.length - shell->inputdata.lineend;
1153 1153
          // fill the remainder of the line with NUL bytes
1154 1154
          memset(&(shell->input.line[shell->inputdata.lineend]), '\0', *n);
1155 1155
          // reset static variables
......
1192 1192
/**
1193 1193
 * @brief   Parses the content of the input buffer (line) to separate arguments.
1194 1194
 *
1195
 * @param[in] shell   Pointer to the shell object.
1195
 * @param[in]   shell   Pointer to the shell object.
1196
 * @param[out]  argbuf  Buffer to store argument pointers to.
1196 1197
 *
1197 1198
 * @return            Number of arguments found.
1198 1199
 */
1199
static size_t _parseArguments(aos_shell_t* shell)
1200
static size_t _parseArguments(aos_shell_t* shell, char** argbuf)
1200 1201
{
1201 1202
  aosDbgCheck(shell != NULL);
1203
  aosDbgCheck(argbuf != NULL);
1202 1204

  
1203 1205
  /*
1204 1206
   * States for a very small FSM.
......
1212 1214

  
1213 1215
  // local variables
1214 1216
  state_t state = START;
1215
  size_t arg = 0;
1217
  size_t nargs = 0;
1216 1218

  
1217 1219
  // iterate through the line
1218
  for (char* c = shell->input.line; c < shell->input.line + shell->input.width; ++c) {
1220
  for (char* c = shell->input.line; c < shell->input.line + shell->input.length; ++c) {
1219 1221
    // terminate at first NUL byte
1220 1222
    if (*c == '\0') {
1221 1223
      state = END;
......
1232 1234
        case START:
1233 1235
        case SPACE:
1234 1236
          // ignore too many arguments
1235
          if (arg < shell->arglistsize) {
1236
            shell->arglist[arg] = c;
1237
          if (nargs < shell->input.nargs) {
1238
            argbuf[nargs] = c;
1237 1239
          }
1238
          ++arg;
1240
          ++nargs;
1239 1241
          break;
1240 1242
        case TEXT:
1241 1243
        case END:
1242
        default:
1243 1244
          break;
1244 1245
      }
1245 1246
      state = TEXT;
......
1247 1248
  }
1248 1249

  
1249 1250
  // set all remaining argument pointers to NULL
1250
  for (size_t a = arg; a < shell->arglistsize; ++a) {
1251
    shell->arglist[a] = NULL;
1251
  for (size_t a = nargs; a < shell->input.nargs; ++a) {
1252
    argbuf[a] = NULL;
1252 1253
  }
1253 1254

  
1254
  return arg;
1255
  return nargs;
1255 1256
}
1256 1257

  
1257 1258
/******************************************************************************/
......
1266 1267
 * @param[in] prompt        Prompt line to print (NULL = use default prompt).
1267 1268
 * @param[in] line          Pointer to the input buffer.
1268 1269
 * @param[in] linesize      Size of the input buffer.
1269
 * @param[in] arglist       Pointer to the argument buffer.
1270
 * @param[in] arglistsize   Size of te argument buffer.
1270
 * @param[in] numargs       Maximum number of arguments (defines size of internal buffer).
1271 1271
 */
1272
void aosShellInit(aos_shell_t* shell, event_source_t* oseventsource, const char* prompt, char* line, size_t linesize, char** arglist, size_t arglistsize)
1272
void aosShellInit(aos_shell_t* shell, event_source_t* oseventsource, const char* prompt, char* line, size_t linesize, size_t numargs)
1273 1273
{
1274 1274
  aosDbgCheck(shell != NULL);
1275 1275
  aosDbgCheck(oseventsource != NULL);
1276 1276
  aosDbgCheck(line != NULL);
1277
  aosDbgCheck(arglist != NULL);
1278 1277

  
1279 1278
  // set parameters
1280 1279
  shell->thread = NULL;
......
1286 1285
  shell->execstatus.command = NULL;
1287 1286
  shell->execstatus.retval = 0;
1288 1287
  shell->input.line = line;
1289
  shell->input.width = linesize;
1288
  shell->input.length = linesize;
1290 1289
  shell->inputdata.lastaction = AOS_SHELL_ACTION_NONE;
1291 1290
  memset(shell->inputdata.escseq, '\0', sizeof(shell->inputdata.escseq)*sizeof(shell->inputdata.escseq[0]));
1292 1291
  shell->inputdata.cursorpos = 0;
1293 1292
  shell->inputdata.lineend = 0;
1294 1293
  shell->inputdata.noinput = true;
1295
  shell->arglist = arglist;
1296
  shell->arglistsize = arglistsize;
1294
  shell->input.nargs= numargs;
1297 1295
  shell->config = 0x00;
1298 1296

  
1299 1297
  // initialize buffers
1300
  memset(shell->input.line, '\0', shell->input.width);
1301
  for (size_t a = 0; a < shell->arglistsize; ++a) {
1302
    shell->arglist[a] = NULL;
1303
  }
1298
  memset(shell->input.line, '\0', shell->input.length);
1304 1299

  
1305 1300
  return;
1306 1301
}
......
1607 1602
  AosShellChannel* channel;
1608 1603
  aos_status_t readeval;
1609 1604
  size_t nchars = 0;
1605
  char* args[((aos_shell_t*)shell)->input.nargs];
1610 1606
  size_t nargs = 0;
1611 1607
  aos_shellcommand_t* cmd;
1612 1608

  
1609
  // initialize variables
1610
  for (size_t arg = 0; arg < ((aos_shell_t*)shell)->input.nargs; ++arg) {
1611
    args[arg] = NULL;
1612
  }
1613 1613

  
1614 1614
  // register OS related events
1615 1615
  chEvtRegisterMask(((aos_shell_t*)shell)->os.eventSource, &(((aos_shell_t*)shell)->os.eventListener), AOS_SHELL_EVENTMASK_OS);
......
1658 1658
            // read input from channel
1659 1659
            readeval = _readChannel((aos_shell_t*)shell, channel, &nchars);
1660 1660
            // parse input line to argument list only if the input shall be executed
1661
            nargs = (readeval == AOS_SUCCESS && nchars > 0) ? _parseArguments((aos_shell_t*)shell) : 0;
1661
            nargs = (readeval == AOS_SUCCESS && nchars > 0) ? _parseArguments((aos_shell_t*)shell, args) : 0;
1662 1662
            // check number of arguments
1663
            if (nargs > ((aos_shell_t*)shell)->arglistsize) {
1663
            if (nargs > ((aos_shell_t*)shell)->input.nargs) {
1664 1664
              // error too many arguments
1665 1665
              chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "\ttoo many arguments\n");
1666 1666
            } else if (nargs > 0) {
1667 1667
              // search command list for arg[0] and execute callback
1668 1668
              cmd = ((aos_shell_t*)shell)->commands;
1669 1669
              while (cmd != NULL) {
1670
                if (strcmp(((aos_shell_t*)shell)->arglist[0], cmd->name) == 0) {
1670
                if (strcmp(args[0], cmd->name) == 0) {
1671 1671
                  ((aos_shell_t*)shell)->execstatus.command = cmd;
1672 1672
                  chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_EXEC);
1673
                  ((aos_shell_t*)shell)->execstatus.retval = cmd->callback((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, nargs, ((aos_shell_t*)shell)->arglist);
1673
                  ((aos_shell_t*)shell)->execstatus.retval = cmd->callback((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, (int)nargs, args);
1674 1674
                  chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_DONE);
1675 1675
                  // notify if the command was not successful
1676 1676
                  if (((aos_shell_t*)shell)->execstatus.retval != 0) {
......
1683 1683

  
1684 1684
              // if no matching command was found, print an error
1685 1685
              if (cmd == NULL) {
1686
                chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "\tcommand '%s' not found\n", ((aos_shell_t*)shell)->arglist[0]);
1686
                chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "\tcommand '%s' not found\n", args[0]);
1687 1687
              }
1688 1688
            }
1689 1689

  

Also available in: Unified diff