emulator/commands.c
static void
command_reader(commands_t *cmd, const wchar_t *name, wchar_t **ptr) {
  long unit = 0;

  const wchar_t *w = parser_get_token(ptr);
  if (NULL != w) {
    unit = wcstol(w, NULL, 10);
  }
  if (unit < 1 || unit > 2) {
    cmd->error = wcsdup(L"error: invalid unit");
    return;
  }
  w = parser_get_token(ptr);
  if (NULL == w) {
    cmd->error = wcsdup(L"error: missing filename");
    return;
  }

  commands_io_t io = 1 == unit ? commands_reader_1 : commands_reader_2;
  io5_mode_t mode = io5_mode_hex5;

  const wchar_t *w1 = parser_get_token(ptr);
  if (NULL != w1) {
    mode = string_to_mode(w);
    if (0 == wcscasecmp(w1, L"close")) {
      io5_file_close(cmd->file[io]);
      return;
    } else if (io5_mode_invalid == mode) {
      cmd->error = wcsdup(L"error: mode is invalid");
      return;
    }
    w = w1;
  }

  char filename[1024];
  size_t n = snprintf(filename, sizeof(filename), "%ls", w);
  if (n >= sizeof(filename) - 1) {
    cmd->error = wcsdup(L"error: filename is too long");
    return;
  }

  if ('/' == filename[0] || ('.' == filename[0] && '/' == filename[1]) ||
      ('.' == filename[0] && '.' == filename[1] && '/' == filename[2])) {

    // absolute/relative path
    if (io5_ok == io5_file_open(cmd->file[io], filename, mode)) {
      return;
    }

  } else { // search the path

    switch (path_search(filename, sizeof(filename), "", w)) {
    case PS_ok:
      if (io5_ok != io5_file_open(cmd->file[io], filename, mode)) {
        cmd->error = wcsdup(L"error: file cannot be opened");
      }
      break;
    case PS_malloc_failed:
      cmd->error = wcsdup(L"error: malloc failed");
      break;
    case PS_filename_too_long:
      cmd->error = wcsdup(L"error: filename too long");
      break;
    case PS_file_not_found:
      cmd->error = wcsdup(L"error: file not found");
      break;
    }
  }
}
// reader unit [mode] file
// if mode is absent then assume "hex5"
reader unit [mode] file
if mode is absent then assume "hex5"
reader unit [ mode ] file if mode is absent then assume " hex5 "
static void
command_reader(commands_t *cmd, const wchar_t *name, wchar_t **ptr) {
  long unit = 0;
  const wchar_t *w = parser_get_token(ptr);
  if (NULL != w) {
    unit = wcstol(w, NULL, 10);
  }
  if (unit < 1 || unit > 2) {
    cmd->error = wcsdup(L"error: invalid unit");
    return;
  }
  w = parser_get_token(ptr);
  if (NULL == w) {
    cmd->error = wcsdup(L"error: missing filename");
    return;
  }
  commands_io_t io = 1 == unit ? commands_reader_1 : commands_reader_2;
  io5_mode_t mode = io5_mode_hex5;
  const wchar_t *w1 = parser_get_token(ptr);
  if (NULL != w1) {
    mode = string_to_mode(w);
    if (0 == wcscasecmp(w1, L"close")) {
      io5_file_close(cmd->file[io]);
      return;
    } else if (io5_mode_invalid == mode) {
      cmd->error = wcsdup(L"error: mode is invalid");
      return;
    }
    w = w1;
  }
  char filename[1024];
  size_t n = snprintf(filename, sizeof(filename), "%ls", w);
  if (n >= sizeof(filename) - 1) {
    cmd->error = wcsdup(L"error: filename is too long");
    return;
  }
  if ('/' == filename[0] || ('.' == filename[0] && '/' == filename[1]) ||
      ('.' == filename[0] && '.' == filename[1] && '/' == filename[2])) {
    if (io5_ok == io5_file_open(cmd->file[io], filename, mode)) {
      return;
    }
  } else { 
    switch (path_search(filename, sizeof(filename), "", w)) {
    case PS_ok:
      if (io5_ok != io5_file_open(cmd->file[io], filename, mode)) {
        cmd->error = wcsdup(L"error: file cannot be opened");
      }
      break;
    case PS_malloc_failed:
      cmd->error = wcsdup(L"error: malloc failed");
      break;
    case PS_filename_too_long:
      cmd->error = wcsdup(L"error: filename too long");
      break;
    case PS_file_not_found:
      cmd->error = wcsdup(L"error: file not found");
      break;
    }
  }
}
static void command_reader ( commands_t * cmd , const wchar_t * name , wchar_t * * ptr ) { long unit = 0 ; const wchar_t * w = parser_get_token ( ptr ) ; if ( NULL != w ) { unit = wcstol ( w , NULL , 10 ) ; } if ( unit < 1 || unit > 2 ) { cmd -> error = wcsdup ( L" " ) ; return ; } w = parser_get_token ( ptr ) ; if ( NULL == w ) { cmd -> error = wcsdup ( L" " ) ; return ; } commands_io_t io = 1 == unit ? commands_reader_1 : commands_reader_2 ; io5_mode_t mode = io5_mode_hex5 ; const wchar_t * w1 = parser_get_token ( ptr ) ; if ( NULL != w1 ) { mode = string_to_mode ( w ) ; if ( 0 == wcscasecmp ( w1 , L" " ) ) { io5_file_close ( cmd -> file [ io ] ) ; return ; } else if ( io5_mode_invalid == mode ) { cmd -> error = wcsdup ( L" " ) ; return ; } w = w1 ; } char filename [ 1024 ] ; size_t n = snprintf ( filename , sizeof ( filename ) , " " , w ) ; if ( n >= sizeof ( filename ) - 1 ) { cmd -> error = wcsdup ( L" " ) ; return ; } if ( ' ' == filename [ 0 ] || ( ' ' == filename [ 0 ] && ' ' == filename [ 1 ] ) || ( ' ' == filename [ 0 ] && ' ' == filename [ 1 ] && ' ' == filename [ 2 ] ) ) { if ( io5_ok == io5_file_open ( cmd -> file [ io ] , filename , mode ) ) { return ; } } else { switch ( path_search ( filename , sizeof ( filename ) , " " , w ) ) { case PS_ok : if ( io5_ok != io5_file_open ( cmd -> file [ io ] , filename , mode ) ) { cmd -> error = wcsdup ( L" " ) ; } break ; case PS_malloc_failed : cmd -> error = wcsdup ( L" " ) ; break ; case PS_filename_too_long : cmd -> error = wcsdup ( L" " ) ; break ; case PS_file_not_found : cmd -> error = wcsdup ( L" " ) ; break ; } } }
reader unit [mode] file
if mode is absent then assume "hex5"
reader unit [ mode ] file if mode is absent then assume " hex5 "
// absolute/relative path // search the path