Beispiel #1
0
int cli_do(const struct cli_cmd *cmds, char **args, unsigned int n)
{
	unsigned int i;
	const char *cmd;
	int r;

	if (!n)
		return -EAGAIN;

	cmd = *args++;
	--n;

	for (i = 0; cmds[i].cmd; ++i) {
		if (strcmp(cmd, cmds[i].cmd))
			continue;
		if (is_cli() && cmds[i].cli_cmp == CLI_N)
			continue;
		if (!is_cli() && cmds[i].cli_cmp == CLI_Y)
			continue;

		switch (cmds[i].argc_cmp) {
		case CLI_EQUAL:
			if (n != cmds[i].argc) {
				cli_printf("Invalid number of arguments\n");
				return -EINVAL;
			}

			break;
		case CLI_MORE:
			if (n < cmds[i].argc) {
				cli_printf("too few arguments\n");
				return -EINVAL;
			}

			break;
		case CLI_LESS:
			if (n > cmds[i].argc) {
				cli_printf("too many arguments\n");
				return -EINVAL;
			}

			break;
		}

		if (cmds[i].fn) {
			r = cmds[i].fn(args, n);
			return (r == -EAGAIN) ? -EINVAL : r;
		}

		break;
	}

	if (!strcmp(cmd, "help"))
		return cli_help(cmds);

	return -EAGAIN;
}
/**
 * Print available commands.
 */
static void
print_commands (char *prog_name_p) /**< program name */
{
  cli_help (prog_name_p, NULL, main_opts);

  printf ("\nAvailable commands:\n"
          "  generate\n"
          "  merge\n"
          "\nPassing -h or --help after a command displays its help.\n");
} /* print_commands */
Beispiel #3
0
/*
 * NAME 
 *    cli_find_cmd
 * 
 * SYNOPSIS
 *    #include "cli.h" 
 *    static cli_record_t
 *    *cli_find_cmd(char  *name)
 *
 * DESCRIPTION
 *     An internal function to scan the current directory for the
 *     specified entry.
 *
 * INPUT PARAMETERS
 *     name       pointer to the string to look for (null terminated).
 *
 * RETURN VALUE
 *     NULL       string NOT found
 *     ptr        Pointer to entry record if a match was found
 *
 */
static cli_record_t
*cli_find_cmd (cli_internal_data_t* data, char  *name)
{
    cli_record_t  *cmd_rec;

    //DEBUG_PRINTF("\nAttempting to Find \"%s\" in directory [%s]\n",
    //        name, current_directory->name );

    /*
     * check for global command search  
     */
    if (*name == '!') {
        DEBUG_PRINTF(data, "\nGlobal command search! \r\n");

        name++;
        cmd_rec = data->list;
        while (cmd_rec != 0) {
            DEBUG_PRINTF(data, "\nglobal comparing \"%s\" with entry \"%s\"\r\n",
                      name, cmd_rec->name);

            if (str_exact(cmd_rec->name, name, CLI_ENTRY_LEN)) {
                DEBUG_PRINTF(data, "\nGlobal match found for -%s- \r\n", name);
                return (cmd_rec);
            }
            cmd_rec = cmd_rec->cmd_list;
        }

        cliprintf(data, "\n*Unknown entry \"%s\"\r\n", name);
        return (0);
    }

    /*
     * now compare to existing command and directory entries
     */
    cmd_rec = data->current_directory->link2subdir;
    while (cmd_rec != NULL) {
        DEBUG_PRINTF(data, "\ncomparing \"%s\" with entry \"%s\"\r\n",
                      name, cmd_rec->name);

        if (str_exact(cmd_rec->name, name, CLI_ENTRY_LEN)) { 
            DEBUG_PRINTF(data, "\nMatch found for -%s- \r\n", name);
            return (cmd_rec);
        }
        cmd_rec = cmd_rec->next_entry;
    }

    /*
     * check to see if the user wants to go back one directory
     */
    if (str_exact(name, CLI_UP_ONE, 2)) { 
        DEBUG_PRINTF(data, "\nGo up one dir level \r\n");
        data->current_directory = data->current_directory->parent_dir;
        return (0);
    }

    /*
     * check to see if user wants to go to the root directory
     */
    if (str_exact(name, CLI_ROOT_DIR, 1)) { 
        DEBUG_PRINTF(data, "\nGo to root \r\n");
        data->current_directory = &data->cli_root_element;
        return (0);
    }

    /*
     * check to see if user wants to list entries
     */
    if (str_exact(name, CLI_LIST_DIR, 2)) { 
        DEBUG_PRINTF(data, "\nList directory \r\n");
        list_directory(data);
        return (0);
    }

    if (str_exact(name, CLI_GLOBAL_LIST, 2)) { 
        DEBUG_PRINTF(data, "\nGlobal List \r\n");
        global_command_list(data);
        return (0);
    }

    if (str_exact(name, CLI_H, 1) ||  
        str_exact(name, CLI_HELP, 4) ||  
        str_exact(name, CLI_QUESTION, 1)) {
        cli_help(data);
        return (NULL);
    }

    /* did not find a match */
    cliprintf(data, "\n*Unknown entry \"%s\"\r\n", name);
    return (0);
}
/**
 * Process 'merge' command.
 *
 * @return error code (0 - no error)
 */
static int
process_merge (cli_state_t *cli_state_p, /**< cli state */
               int argc, /**< number of arguments */
               char *prog_name_p) /**< program name */
{
  jerry_init (JERRY_INIT_EMPTY);

  uint8_t *input_pos_p = input_buffer;

  cli_change_opts (cli_state_p, merge_opts);

  const uint32_t *merge_buffers[argc];
  size_t merge_buffer_sizes[argc];
  uint32_t number_of_files = 0;

  for (int id = cli_consume_option (cli_state_p); id != CLI_OPT_END; id = cli_consume_option (cli_state_p))
  {
    switch (id)
    {
      case OPT_MERGE_HELP:
      {
        cli_help (prog_name_p, "merge", merge_opts);
        return JERRY_STANDALONE_EXIT_CODE_OK;
      }
      case OPT_MERGE_OUT:
      {
        output_file_name_p = cli_consume_string (cli_state_p);
        break;
      }
      case CLI_OPT_DEFAULT:
      {
        const char *file_name_p = cli_consume_string (cli_state_p);

        if (cli_state_p->error == NULL)
        {
          size_t size = read_file (input_pos_p, file_name_p);

          if (size == 0)
          {
            return JERRY_STANDALONE_EXIT_CODE_FAIL;
          }

          merge_buffers[number_of_files] = (const uint32_t *) input_pos_p;
          merge_buffer_sizes[number_of_files] = size;

          number_of_files++;
          const uintptr_t mask = sizeof (uint32_t) - 1;
          input_pos_p = (uint8_t *) ((((uintptr_t) input_pos_p) + size + mask) & ~mask);
        }
        break;
      }
      default:
      {
        cli_state_p->error = "Internal error";
        break;
      }
    }
  }

  if (check_cli_error (cli_state_p))
  {
    return JERRY_STANDALONE_EXIT_CODE_FAIL;
  }

  if (number_of_files < 2)
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: at least two input files must be passed.\n");

    return JERRY_STANDALONE_EXIT_CODE_FAIL;
  }

  const char *error_p;
  size_t size = jerry_merge_snapshots (merge_buffers,
                                       merge_buffer_sizes,
                                       number_of_files,
                                       output_buffer,
                                       JERRY_BUFFER_SIZE,
                                       &error_p);

  if (size == 0)
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", error_p);
    return JERRY_STANDALONE_EXIT_CODE_FAIL;
  }

  FILE *file_p = fopen (output_file_name_p, "w");

  if (file_p != NULL)
  {
    fwrite (output_buffer, 1u, size, file_p);
    fclose (file_p);
  }
  else
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: '%s'\n", output_file_name_p);
  }

  return JERRY_STANDALONE_EXIT_CODE_OK;
} /* process_merge */
/**
 * Process 'generate' command.
 *
 * @return error code (0 - no error)
 */
static int
process_generate (cli_state_t *cli_state_p, /**< cli state */
                  int argc, /**< number of arguments */
                  char *prog_name_p) /**< program name */
{
  (void) argc;

  bool is_save_literals_mode_in_c_format = false;
  uint32_t snapshot_flags = 0;
  jerry_init_flag_t flags = JERRY_INIT_EMPTY;

  const char *file_name_p = NULL;
  uint8_t *source_p = input_buffer;
  size_t source_length = 0;
  const char *save_literals_file_name_p = NULL;

  cli_change_opts (cli_state_p, generate_opts);

  for (int id = cli_consume_option (cli_state_p); id != CLI_OPT_END; id = cli_consume_option (cli_state_p))
  {
    switch (id)
    {
      case OPT_GENERATE_HELP:
      {
        cli_help (prog_name_p, "generate", generate_opts);
        return JERRY_STANDALONE_EXIT_CODE_OK;
      }
      case OPT_GENERATE_STATIC:
      {
        snapshot_flags |= JERRY_SNAPSHOT_SAVE_STATIC;
        break;
      }
      case OPT_GENERATE_LITERAL_LIST:
      case OPT_GENERATE_LITERAL_C:
      {
        if (save_literals_file_name_p != NULL)
        {
          jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: literal file name already specified");
          return JERRY_STANDALONE_EXIT_CODE_FAIL;
        }

        is_save_literals_mode_in_c_format = (id == OPT_GENERATE_LITERAL_C);
        save_literals_file_name_p = cli_consume_string (cli_state_p);
        break;
      }
      case OPT_GENERATE_SHOW_OP:
      {
        if (check_feature (JERRY_FEATURE_PARSER_DUMP, cli_state_p->arg))
        {
          jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
          flags |= JERRY_INIT_SHOW_OPCODES;
        }
        break;
      }
      case OPT_GENERATE_OUT:
      {
        output_file_name_p = cli_consume_string (cli_state_p);
        break;
      }
      case CLI_OPT_DEFAULT:
      {
        if (file_name_p != NULL)
        {
          jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Exactly one input file must be specified\n");
          return JERRY_STANDALONE_EXIT_CODE_FAIL;
        }

        file_name_p = cli_consume_string (cli_state_p);

        if (cli_state_p->error == NULL)
        {
          source_length = read_file (source_p, file_name_p);

          if (source_length == 0)
          {
            jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Input file is empty\n");
            return JERRY_STANDALONE_EXIT_CODE_FAIL;
          }
        }
        break;
      }
      default:
      {
        cli_state_p->error = "Internal error";
        break;
      }
    }
  }

  if (check_cli_error (cli_state_p))
  {
    return JERRY_STANDALONE_EXIT_CODE_FAIL;
  }

  if (file_name_p == NULL)
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Exactly one input file must be specified\n");
    return JERRY_STANDALONE_EXIT_CODE_FAIL;
  }

  jerry_init (flags);

  if (!jerry_is_valid_utf8_string (source_p, (jerry_size_t) source_length))
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Input must be a valid UTF-8 string.\n");
    return JERRY_STANDALONE_EXIT_CODE_FAIL;
  }

  jerry_value_t snapshot_result;

  snapshot_result = jerry_generate_snapshot ((jerry_char_t *) file_name_p,
                                             (size_t) strlen (file_name_p),
                                             (jerry_char_t *) source_p,
                                             source_length,
                                             snapshot_flags,
                                             output_buffer,
                                             sizeof (output_buffer) / sizeof (uint32_t));

  if (jerry_value_has_error_flag (snapshot_result))
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Generating snapshot failed!\n");

    jerry_value_clear_error_flag (&snapshot_result);

    print_unhandled_exception (snapshot_result);

    jerry_release_value (snapshot_result);
    return JERRY_STANDALONE_EXIT_CODE_FAIL;
  }

  size_t snapshot_size = (size_t) jerry_get_number_value (snapshot_result);
  jerry_release_value (snapshot_result);

  FILE *snapshot_file_p = fopen (output_file_name_p, "w");
  if (snapshot_file_p == NULL)
  {
    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unable to write snapshot file: '%s'\n", output_file_name_p);
    return JERRY_STANDALONE_EXIT_CODE_FAIL;
  }

  fwrite (output_buffer, sizeof (uint8_t), snapshot_size, snapshot_file_p);
  fclose (snapshot_file_p);

  printf ("Created snapshot file: '%s' (%lu bytes)\n", output_file_name_p, (unsigned long) snapshot_size);

  if (save_literals_file_name_p != NULL)
  {
    const size_t literal_buffer_size = jerry_parse_and_save_literals ((jerry_char_t *) source_p,
                                                                      source_length,
                                                                      false,
                                                                      output_buffer,
                                                                      sizeof (output_buffer) / sizeof (uint32_t),
                                                                      is_save_literals_mode_in_c_format);
    if (literal_buffer_size == 0)
    {
      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Literal saving failed!\n");
      return JERRY_STANDALONE_EXIT_CODE_FAIL;
    }

    FILE *literal_file_p = fopen (save_literals_file_name_p, "w");

    if (literal_file_p == NULL)
    {
      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unable to write literal file: '%s'\n", save_literals_file_name_p);
      return JERRY_STANDALONE_EXIT_CODE_FAIL;
    }

    fwrite (output_buffer, sizeof (uint8_t), literal_buffer_size, literal_file_p);
    fclose (literal_file_p);

    printf ("Created literal file: '%s' (%lu bytes)\n", save_literals_file_name_p, (unsigned long) literal_buffer_size);
  }

  return 0;
} /* process_generate */