Revision c18a848e

View differences:

core/src/aos_shell.c
578 578
  aosDbgCheck(shell != NULL);
579 579

  
580 580
  // check whether input line is already full
581
  if (shell->inputdata.lineend + 1 >= shell->input.length) {
581
  if (shell->inputdata.lineend + 1 >= shell->input.size) {
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.length);
586
      memset(shell->input.line, '\0', shell->input.size);
587 587
      shell->inputdata.noinput = false;
588 588
    }
589 589
    // overwrite content
......
716 716
 *
717 717
 * @param[in]   shell     Pointer to the shell object.
718 718
 * @param[in]   channel   The channel to read from.
719
 * @param[out]  n         Optional pointer to a variable to store the number of read characters to.
719
 * @param[out]  exec      Optional pointer to a flag, which indicates, whether a command shall be executed.
720 720
 *
721
 * @return  Indicator, whether the read character(s) indicated, that a command shall be executed.
721
 * @return  Number of read characters.
722 722
 */
723
static bool _readChannel(aos_shell_t* shell, AosShellChannel* channel, size_t* n)
723
static int _readChannel(aos_shell_t* shell, AosShellChannel* channel, bool* execute)
724 724
{
725 725
  aosDbgCheck(shell != NULL);
726 726
  aosDbgCheck(channel != NULL);
......
729 729
  aos_shellaction_t action = AOS_SHELL_ACTION_NONE;
730 730
  char c;
731 731
  special_key_t key;
732

  
733
  // initialize output variables
734
  if (n) {
735
    *n = 0;
736
  }
732
  int nchars = 0;
733
  bool exec = false;
737 734

  
738 735
  // read character by character from the channel
739 736
  while (chnReadTimeout(channel, (uint8_t*)&c, 1, TIME_IMMEDIATE)) {
740 737
    key = KEY_UNKNOWN;
741 738

  
739
    // drop any input after an execution request was detected
740
    if (exec) {
741
      continue;
742
    }
743

  
744
    // incremet character counter
745
    ++nchars;
746

  
742 747
    // parse escape sequence
743 748
    if (strlen(shell->inputdata.escseq) > 0) {
744 749
      shell->inputdata.escseq[strlen(shell->inputdata.escseq)] = c;
......
946 951
        if (cmatch > shell->inputdata.cursorpos || (cmatch == shell->inputdata.cursorpos && matchlevel == CHAR_MATCH_NCASE)) {
947 952
          shell->inputdata.noinput = false;
948 953
          // limit auto fill so it will not overflow the line width
949
          if (shell->inputdata.lineend + (cmatch - shell->inputdata.cursorpos) > shell->input.length) {
950
            cmatch = shell->input.length - shell->inputdata.lineend + shell->inputdata.cursorpos;
954
          if (shell->inputdata.lineend + (cmatch - shell->inputdata.cursorpos) > shell->input.size) {
955
            cmatch = shell->input.size - shell->inputdata.lineend + shell->inputdata.cursorpos;
951 956
          }
952 957
          // move trailing memory further in the line
953 958
          memmove(&(shell->input.line[cmatch]), &(shell->input.line[shell->inputdata.cursorpos]), shell->inputdata.lineend - shell->inputdata.cursorpos);
......
1049 1054
        size_t nul_start = 0;
1050 1055
        size_t nul_end = 0;
1051 1056
        // search line for a NUL byte
1052
        while (nul_start < shell->input.length) {
1057
        while (nul_start < shell->input.size) {
1053 1058
          if (shell->input.line[nul_start] == '\0') {
1054 1059
            nul_end = nul_start + 1;
1055 1060
            // keep searcjing for a byte that is not NUL
1056
            while (nul_end < shell->input.length) {
1061
            while (nul_end < shell->input.size) {
1057 1062
              if (shell->input.line[nul_end] != '\0') {
1058 1063
                // an intermediate NUL sequence was found
1059 1064
                memset(&(shell->input.line[nul_start]), ' ', nul_end - nul_start);
......
1148 1153
      case AOS_SHELL_ACTION_EXECUTE:
1149 1154
      {
1150 1155
        streamPut(&shell->stream, '\n');
1151
        // set the number of read bytes and return
1156
        // if there was some input
1152 1157
        if (!shell->inputdata.noinput) {
1153
          if (n) {
1154
            *n = shell->input.length - shell->inputdata.lineend;
1155
          }
1156 1158
          // fill the remainder of the line with NUL bytes
1157
          memset(&(shell->input.line[shell->inputdata.lineend]), '\0', (shell->input.length - shell->inputdata.lineend));
1159
          memset(&(shell->input.line[shell->inputdata.lineend]), '\0', shell->input.size - shell->inputdata.lineend);
1158 1160
        }
1159
        return true;
1161
        // set the execution flag
1162
        exec = true;
1163
        break;
1160 1164
      }
1161 1165

  
1162 1166
      case AOS_SHELL_ACTION_ESCSTART:
......
1186 1190
    shell->inputdata.lastaction = action;
1187 1191
  } /* end of while */
1188 1192

  
1189
  // no more data could be read from the channel
1190
  return false;
1193
  // set the execution output flag
1194
  if (execute) {
1195
    *execute = exec;
1196
  }
1197

  
1198
  return nchars;
1191 1199
}
1192 1200

  
1193 1201
/**
......
1218 1226
  size_t nargs = 0;
1219 1227

  
1220 1228
  // iterate through the line
1221
  for (char* c = shell->input.line; c < shell->input.line + shell->input.length; ++c) {
1229
  for (char* c = shell->input.line; c < shell->input.line + shell->input.size; ++c) {
1222 1230
    // terminate at first NUL byte
1223 1231
    if (*c == '\0') {
1224 1232
      state = END;
......
1601 1609
  eventmask_t eventmask;
1602 1610
  eventflags_t eventflags;
1603 1611
  AosShellChannel* channel;
1604
  aos_status_t readeval;
1612
  bool execute;
1605 1613
  char* args[((aos_shell_t*)shell)->input.nargs];
1606 1614
  size_t nargs = 0;
1607 1615
  aos_shellcommand_t* cmd;
......
1654 1662
        while (channel != NULL) {
1655 1663
          eventflags = chEvtGetAndClearFlags(&channel->listener);
1656 1664
          // if there is new input and a command shall be executed
1657
          if ((eventflags & CHN_INPUT_AVAILABLE) && _readChannel((aos_shell_t*)shell, channel, NULL)) {
1658
            // parse input line to argument list
1659
            nargs = _parseArguments((aos_shell_t*)shell, args);
1660
            // check number of arguments
1661
            if (nargs > ((aos_shell_t*)shell)->input.nargs) {
1662
              // error too many arguments
1663
              chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "\ttoo many arguments\n");
1664
            } else if (nargs > 0) {
1665
              // search command list for arg[0] and execute callback
1666
              cmd = ((aos_shell_t*)shell)->commands;
1667
              while (cmd != NULL) {
1668
                if (strcmp(args[0], cmd->name) == 0) {
1669
                  ((aos_shell_t*)shell)->execstatus.command = cmd;
1670
                  chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_EXEC);
1671
                  ((aos_shell_t*)shell)->execstatus.retval = cmd->callback((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, (int)nargs, args);
1672
                  chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_DONE);
1673
                  // notify if the command was not successful
1674
                  if (((aos_shell_t*)shell)->execstatus.retval != 0) {
1675
                    chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "command returned exit status %d\n", ((aos_shell_t*)shell)->execstatus.retval);
1665
          if (eventflags & CHN_INPUT_AVAILABLE) {
1666
            _readChannel((aos_shell_t*)shell, channel, &execute);
1667
            // an execution request was detected
1668
            if (execute && !((aos_shell_t*)shell)->inputdata.noinput) {
1669
              // parse input line to argument list
1670
              nargs = _parseArguments((aos_shell_t*)shell, args);
1671
              // check number of arguments
1672
              if (nargs > ((aos_shell_t*)shell)->input.nargs) {
1673
                // error too many arguments
1674
                chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "\ttoo many arguments\n");
1675
              } else if (nargs > 0) {
1676
                // search command list for arg[0] and execute callback
1677
                cmd = ((aos_shell_t*)shell)->commands;
1678
                while (cmd != NULL) {
1679
                  if (strcmp(args[0], cmd->name) == 0) {
1680
                    ((aos_shell_t*)shell)->execstatus.command = cmd;
1681
                    chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_EXEC);
1682
                    ((aos_shell_t*)shell)->execstatus.retval = cmd->callback((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, (int)nargs, args);
1683
                    chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_DONE);
1684
                    // notify if the command was not successful
1685
                    if (((aos_shell_t*)shell)->execstatus.retval != 0) {
1686
                      chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "command returned exit status %d\n", ((aos_shell_t*)shell)->execstatus.retval);
1687
                    }
1688
                    break;
1676 1689
                  }
1677
                  break;
1678
                }
1679
                cmd = cmd->next;
1680
              } /* end of while */
1690
                  cmd = cmd->next;
1691
                } /* end of while */
1681 1692

  
1682
              // if no matching command was found, print an error
1683
              if (cmd == NULL) {
1684
                chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "\tcommand '%s' not found\n", args[0]);
1693
                // if no matching command was found, print an error
1694
                if (cmd == NULL) {
1695
                  chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "\tcommand '%s' not found\n", args[0]);
1696
                }
1685 1697
              }
1686 1698
            }
1687 1699

  
1688
            // reset some internal variables and eprint a new prompt
1689
            if (readeval == AOS_SUCCESS && !chThdShouldTerminateX()) {
1700
            // reset some internal variables and print a new prompt
1701
            if (execute && !chThdShouldTerminateX()) {
1690 1702
              ((aos_shell_t*)shell)->inputdata.cursorpos = 0;
1691 1703
              ((aos_shell_t*)shell)->inputdata.lineend = 0;
1692 1704
              ((aos_shell_t*)shell)->inputdata.noinput = true;

Also available in: Unified diff