Changeset 598:26946168046e

Show
Ignore:
Timestamp:
06/11/08 09:39:25 (7 months ago)
Author:
Maxime Petazzoni <maxime.petazzoni@…>
Branch:
default
Message:

Refactor RCMD to use only one single source file.

Location:
nxos/base/lib/rcmd
Files:
2 removed
2 modified

Legend:

Unmodified
Added
Removed
  • nxos/base/lib/rcmd/rcmd.c

    r591 r598  
    1010#include "base/util.h" 
    1111#include "base/assert.h" 
     12#include "base/display.h" 
     13#include "base/nxt.h" 
     14#include "base/drivers/motors.h" 
     15#include "base/drivers/sound.h" 
     16#include "base/drivers/systick.h" 
    1217#include "base/lib/fs/fs.h" 
    1318#include "base/lib/rcmd/rcmd.h" 
    14 #include "base/lib/rcmd/_rcmd.h" 
     19 
     20static rcmd_err_t nx_rcmd_move(char *line); 
     21static rcmd_err_t nx_rcmd_print(char *line); 
     22static rcmd_err_t nx_rcmd_clear(char *line); 
     23static rcmd_err_t nx_rcmd_play(char *line); 
     24static rcmd_err_t nx_rcmd_exec(char *line); 
     25static rcmd_err_t nx_rcmd_wait(char *line); 
     26 
     27static rcmd_command_def rcmd_commands[] = { 
     28  { "move",  4, nx_rcmd_move }, 
     29  { "print", 2, nx_rcmd_print }, 
     30  { "clear", 1, nx_rcmd_clear }, 
     31  { "play",  3, nx_rcmd_play }, 
     32  { "exec",  2, nx_rcmd_exec }, 
     33  { "wait",  2, nx_rcmd_wait }, 
     34  { NULL, 0, NULL }, 
     35}; 
     36 
     37static char *rcmd_err_str[RCMD_ERR_N_ERRS] = { 
     38  "No error.", 
     39  "Invalid parameter count.", 
     40  "Invalid parameter.", 
     41  "File I/O error.", 
     42  "Parser reached end of file.", 
     43  "Command not found.", 
     44}; 
     45 
     46static void nx_rcmd_tokenize(char *line, char sep, int *ntokens, int *indices) { 
     47  size_t len; 
     48  U32 i; 
     49 
     50  len = strlen(line); 
     51  *ntokens = 0; 
     52  i = 0; 
     53 
     54  while (i < len) { 
     55    while (i < len && line[i] == sep) { 
     56      /* Replace all occurences of the token separator char by \0. */ 
     57      line[i++] = 0; 
     58    } 
     59 
     60    if (i == len || *ntokens == RCMD_MAX_TOKENS) { 
     61      return; 
     62    } 
     63 
     64    indices[*ntokens] = i; 
     65    (*ntokens)++; 
     66 
     67    while (i < len && line[i] != sep) { 
     68      /* Pass token characters. */ 
     69      i++; 
     70    } 
     71  } 
     72} 
     73 
     74static rcmd_err_t nx_rcmd_move(char *line) { 
     75  int ntokens, indices[RCMD_MAX_TOKENS], subind[NXT_N_MOTORS], i; 
     76  char *spec; 
     77 
     78  bool active[NXT_N_MOTORS] = {FALSE}; 
     79  S32 speeds[NXT_N_MOTORS]; 
     80  U32 durations[NXT_N_MOTORS]; 
     81  bool success; 
     82 
     83  nx_rcmd_tokenize(line, RCMD_TOKEN_SEPARATOR, &ntokens, indices); 
     84 
     85  if (ntokens != rcmd_commands[RCMD_CMD_MOVE].argc) { 
     86    return RCMD_ERR_INCORRECT_ARGC; 
     87  } 
     88 
     89  /* Parse motors spec. */ 
     90  spec = line + indices[1]; 
     91  nx_rcmd_tokenize(spec, ',', &ntokens, subind); 
     92  for (i=0; i<ntokens; i++) { 
     93    U8 motor = spec[subind[i]] - 'A'; 
     94    if (motor < NXT_N_MOTORS) { 
     95      active[motor] = TRUE; 
     96    } else { 
     97      return RCMD_ERR_INVALID_PARAMETER; 
     98    } 
     99  } 
     100 
     101  /* Parse speeds spec. */ 
     102  spec = line + indices[2]; 
     103  nx_rcmd_tokenize(spec, ',', &ntokens, subind); 
     104  for (i=0; i<NXT_N_MOTORS; i++) { 
     105    if (ntokens <= i) { 
     106      success = atos32(spec + subind[ntokens-1], &speeds[i]); 
     107    } else { 
     108      success = atos32(spec + subind[i], &speeds[i]); 
     109    } 
     110 
     111    if (!success || speeds[i] > 100 || speeds[i] < -100) { 
     112      return RCMD_ERR_INVALID_PARAMETER; 
     113    } 
     114  } 
     115 
     116  /* Parse durations spec. */ 
     117  spec = line + indices[3]; 
     118  nx_rcmd_tokenize(spec, ',', &ntokens, subind); 
     119  for (i=0; i<NXT_N_MOTORS; i++) { 
     120    if (ntokens <= i) { 
     121      success = atou32(spec + subind[ntokens-1], &durations[i]); 
     122    } else { 
     123      success = atou32(spec + subind[i], &durations[i]); 
     124    } 
     125 
     126    if (!success || (speeds[i] != 0 && durations[i] == 0)) { 
     127      return RCMD_ERR_INVALID_PARAMETER; 
     128    } 
     129  } 
     130 
     131  /* Activate motors. */ 
     132  for (i=0; i<NXT_N_MOTORS; i++) { 
     133    if (active[i]) { 
     134      if (speeds[i] != 0) { 
     135        nx_motors_rotate_time(i, (S8) speeds[i], durations[i], FALSE); 
     136      } else { 
     137        nx_motors_stop(i, TRUE); 
     138      } 
     139    } 
     140  } 
     141 
     142  nx_display_string("moving?\n"); 
     143 
     144  return RCMD_ERR_NO_ERROR; 
     145} 
     146 
     147static rcmd_err_t nx_rcmd_print(char *line) { 
     148  int ntokens, indices[RCMD_MAX_TOKENS], i; 
     149 
     150  nx_rcmd_tokenize(line, RCMD_TOKEN_SEPARATOR, &ntokens, indices); 
     151 
     152  for (i=1; i<ntokens; i++) { 
     153    nx_display_string(line + indices[i]); 
     154    if (i < ntokens-1) 
     155      nx_display_string(" "); 
     156  } 
     157 
     158  nx_display_end_line(); 
     159  return RCMD_ERR_NO_ERROR; 
     160} 
     161 
     162static rcmd_err_t nx_rcmd_clear(char *line) { 
     163  /* No-op. */ 
     164  char c; 
     165  c = line[0]; 
     166 
     167  nx_display_clear(); 
     168  return RCMD_ERR_NO_ERROR; 
     169} 
     170 
     171static rcmd_err_t nx_rcmd_play(char *line) { 
     172  int ntokens, indices[RCMD_MAX_TOKENS]; 
     173  U32 freq, duration; 
     174 
     175  nx_rcmd_tokenize(line, RCMD_TOKEN_SEPARATOR, &ntokens, indices); 
     176 
     177  if (ntokens < rcmd_commands[RCMD_CMD_PLAY].argc) { 
     178    return RCMD_ERR_INCORRECT_ARGC; 
     179  } 
     180 
     181  if (!atou32(line + indices[1], &freq) || freq < 200 || 
     182      !atou32(line + indices[2], &duration) || duration < 100) { 
     183    return RCMD_ERR_INVALID_PARAMETER; 
     184  } 
     185 
     186  if (ntokens == 4 && streq(line + indices[3], "sync") == 0) { 
     187    nx_sound_freq(freq, duration); 
     188  } else { 
     189    nx_sound_freq_async(freq, duration); 
     190  } 
     191 
     192  return RCMD_ERR_NO_ERROR; 
     193} 
     194 
     195static rcmd_err_t nx_rcmd_exec(char *line) { 
     196  int ntokens, indices[RCMD_MAX_TOKENS]; 
     197  char *filename; 
     198 
     199  nx_rcmd_tokenize(line, RCMD_TOKEN_SEPARATOR, &ntokens, indices); 
     200 
     201  if (ntokens != rcmd_commands[RCMD_CMD_EXEC].argc) { 
     202    return RCMD_ERR_INCORRECT_ARGC; 
     203  } 
     204 
     205  filename = line + indices[1]; 
     206 
     207  /* Open the requested file and branch execution. */ 
     208  nx_display_string("exec:"); 
     209  nx_display_string(filename); 
     210  nx_display_end_line(); 
     211 
     212  return RCMD_ERR_NO_ERROR; 
     213} 
     214 
     215static rcmd_err_t nx_rcmd_wait(char *line) { 
     216  int ntokens, indices[RCMD_MAX_TOKENS]; 
     217  U32 wait; 
     218 
     219  nx_rcmd_tokenize(line, RCMD_TOKEN_SEPARATOR, &ntokens, indices); 
     220 
     221  if (ntokens != rcmd_commands[RCMD_CMD_EXEC].argc) { 
     222    return RCMD_ERR_INCORRECT_ARGC; 
     223  } 
     224 
     225  if (!atou32(line + indices[1], &wait) || wait == 0) { 
     226    return RCMD_ERR_INVALID_PARAMETER; 
     227  } 
     228 
     229  nx_systick_wait_ms(wait); 
     230  return RCMD_ERR_NO_ERROR; 
     231} 
     232 
     233static rcmd_err_t nx_rcmd_readline(fs_fd_t fd, char *line) { 
     234  fs_err_t err; 
     235  U32 i = 0; 
     236  U8 *buf = (U8 *)line; 
     237 
     238  while (i < RCMD_BUF_LEN - 2) { 
     239    err = nx_fs_read(fd, &(buf[i])); 
     240 
     241    if (err == FS_ERR_END_OF_FILE) { 
     242      buf[i] = 0; 
     243      return RCMD_ERR_END_OF_FILE; 
     244    } else if (err != FS_ERR_NO_ERROR) { 
     245      nx_display_uint(err); 
     246      nx_display_end_line(); 
     247      return RCMD_ERR_READ_ERROR; 
     248    } 
     249 
     250    if (buf[i] == '\n') { 
     251      break; 
     252    } 
     253 
     254    i++; 
     255  } 
     256 
     257  buf[i] = 0; 
     258  return RCMD_ERR_NO_ERROR; 
     259} 
     260 
     261static void nx_rcmd_error(rcmd_err_t err, char *filename, int line) { 
     262/*  nx_display_clear(); */ 
     263 
     264  nx_display_string("Error in file:\n"); 
     265  nx_display_string(filename); 
     266  nx_display_end_line(); 
     267 
     268  nx_display_string("At line "); 
     269  nx_display_uint(line); 
     270  nx_display_end_line(); 
     271 
     272  nx_display_string(rcmd_err_str[err]); 
     273} 
     274 
     275static rcmd_err_t nx_rcmd_find_command(char *line, rcmd_command_def *command) { 
     276  U32 i = 0; 
     277  char *sep; 
     278 
     279  sep = strchr(line, RCMD_TOKEN_SEPARATOR); 
     280  if (sep) { 
     281    *sep = '\0'; 
     282  } 
     283 
     284  while (rcmd_commands[i].name) { 
     285    if (streq(line, rcmd_commands[i].name)) { 
     286      *command = rcmd_commands[i]; 
     287      *sep = RCMD_TOKEN_SEPARATOR; 
     288      return RCMD_ERR_NO_ERROR; 
     289    } 
     290 
     291    i++; 
     292  } 
     293 
     294  *sep = RCMD_TOKEN_SEPARATOR; 
     295  return RCMD_ERR_COMMAND_NOT_FOUND; 
     296} 
    15297 
    16298rcmd_err_t nx_rcmd_do(const char *line) { 
     
    28310  memcpy(cmdline, line, strlen(line)); 
    29311 
    30   err = nx__rcmd_find_command(cmdline, &command); 
     312  err = nx_rcmd_find_command(cmdline, &command); 
    31313  if (err != RCMD_ERR_NO_ERROR) { 
    32314    return err; 
     
    44326  fserr = nx_fs_open(file, FS_FILE_MODE_OPEN, &fd); 
    45327  if (fserr != FS_ERR_NO_ERROR) { 
    46     nx__rcmd_error(RCMD_ERR_READ_ERROR, file, 0); 
     328    nx_rcmd_error(RCMD_ERR_READ_ERROR, file, 0); 
    47329    return; 
    48330  } 
     
    50332  do { 
    51333    char line[RCMD_BUF_LEN] = {0}; 
    52     err = nx__rcmd_readline(fd, line); 
     334    err = nx_rcmd_readline(fd, line); 
    53335    if (err == RCMD_ERR_READ_ERROR) { 
    54336      break; 
     
    61343    result = nx_rcmd_do(line); 
    62344    if (result != RCMD_ERR_NO_ERROR) { 
    63       nx__rcmd_error(result, file, n); 
     345      nx_rcmd_error(result, file, n); 
    64346      break; 
    65347    } 
  • nxos/base/lib/rcmd/rcmd.h

    r585 r598  
    6464} rcmd_err_t; 
    6565 
     66/** Command definition. */ 
     67typedef struct { 
     68  char *name;  /**< Command name. */ 
     69  int argc;    /**< Number of arguments expected by this command. */ 
     70 
     71  /** Command actuator. */ 
     72  rcmd_err_t (* actuator)(char*); 
     73} rcmd_command_def; 
     74 
    6675/** Execute the given line. 
    6776 *