Beispiel #1
0
/* Dispatch actions according to program flags (NOT commands or
 * command options).
 */
static void
cli_context_flag_dispatch (cli_context_t *ctx, gint in_argc, gchar **in_argv)
{
	command_t *cmd;
	gboolean check;

	GOptionEntry flagdefs[] = {
		{ "help",    'h', 0, G_OPTION_ARG_NONE, NULL,
		  _("Display this help and exit."), NULL },
		{ "version", 'v', 0, G_OPTION_ARG_NONE, NULL,
		  _("Output version information and exit."), NULL },
		{ NULL }
	};

	/* Include one command token as a workaround for the bug that
	 * the option parser does not parse commands starting with a
	 * flag properly (e.g. "-p foo arg1"). Will be skipped by the
	 * command utils. */
	cmd = command_new (flagdefs, in_argc + 1, in_argv - 1);

	if (!cmd) {
		/* An error message has already been printed, so we just return. */
		return;
	}

	if (command_flag_boolean_get (cmd, "help", &check) && check) {
		if (command_arg_count (cmd) >= 1) {
			help_command (ctx, cli_context_command_names (ctx),
			              command_argv_get (cmd), command_arg_count (cmd),
			              CMD_TYPE_COMMAND);
		} else {
			/* FIXME: explain -h and -v flags here (reuse help_command code?) */
			g_printf (_("usage: xmms2 [<command> [args]]\n\n"));
			g_printf (_("XMMS2 CLI, the awesome command-line XMMS2 client from the future, "
			            "v" XMMS_VERSION ".\n\n"));
			g_printf (_("If given a command, runs it inline and exit.\n"));
			g_printf (_("If not, enters a shell-like interface to execute commands.\n\n"));
			g_printf (_("Type 'help <command>' for detailed help about a command.\n"));
		}
	} else if (command_flag_boolean_get (cmd, "version", &check) && check) {
		g_printf (_("XMMS2 CLI version " XMMS_VERSION "\n"));
		g_printf (_("Copyright (C) 2008-2014 XMMS2 Team\n"));
		g_printf (_("This is free software; see the source for copying conditions.\n"));
		g_printf (_("There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n"
		            "PARTICULAR PURPOSE.\n"));
		/* FIXME: compiled against? use RL_READLINE_VERSION? */
		g_printf (_(" Using readline version %s\n"), rl_library_version);
	} else {
		/* Call help to print the "no such command" error */
		/* FIXME: Could be a more helpful "invalid flag"?*/
		help_command (ctx, cli_context_command_names (ctx),
		              in_argv, in_argc, CMD_TYPE_COMMAND);
	}

	command_free (cmd);
}
Beispiel #2
0
gboolean
cli_help (cli_context_t *ctx, command_t *cmd)
{
	cmd_type_t cmdtype;
	GList *names;
	gint num_args;
	gboolean alias;

	num_args = command_arg_count (cmd);

	if (command_flag_boolean_get (cmd, "alias", &alias) && alias) {
		names = cli_context_alias_names (ctx);
		cmdtype = CMD_TYPE_ALIAS;
	} else {
		names = cli_context_command_names (ctx);
		cmdtype = CMD_TYPE_COMMAND;
	}

	/* No argument, display the list of commands */
	if (num_args == 0) {
		help_list (names, NULL, cmdtype);
	} else {
		help_command (ctx, names, command_argv_get (cmd), num_args, cmdtype);
	}

	/* No data pending */
	return FALSE;
}
Beispiel #3
0
gboolean
cli_jump (cli_context_t *ctx, command_t *cmd)
{
	xmmsc_connection_t *conn = cli_context_xmms_sync (ctx);
	xmmsv_t *query;
	gboolean backward = FALSE;
	playlist_positions_t *positions;

	command_flag_boolean_get (cmd, "backward", &backward);

	/* Select by positions */
	if (command_arg_positions_get (cmd, 0, &positions, cli_context_current_position (ctx))) {
		gint pos;
		if (playlist_positions_get_single (positions, &pos)) {
			XMMS_CALL_CHAIN (XMMS_CALL_P (xmmsc_playlist_set_next, conn, pos),
			                 XMMS_CALL_P (xmmsc_playback_tickle, conn));
		} else {
			g_printf (_("Cannot jump to several positions!\n"));
		}
		playlist_positions_free (positions);
		/* Select by pattern */
	} else if (command_arg_pattern_get (cmd, 0, &query, TRUE)) {
		query = xmmsv_coll_intersect_with_playlist (query, XMMS_ACTIVE_PLAYLIST);
		XMMS_CALL_CHAIN (XMMS_CALL_P (xmmsc_coll_query_ids, conn, query, NULL, 0, 0),
		                 FUNC_CALL_P (cli_jump_relative, ctx, (backward ? -1 : 1), XMMS_PREV_VALUE));
		xmmsv_unref (query);
	}

	return FALSE;
}
Beispiel #4
0
static void
cli_context_command_dispatch (cli_context_t *ctx, gint in_argc, gchar **in_argv)
{
	command_action_t *action;
	command_trie_match_type_t match;
	gint argc;
	gchar *tmp_argv[in_argc+1];
	gchar **argv;

	/* The arguments will be updated by command_trie_find and
	 * init_context_from_args, so we make a copy. */
	memcpy (tmp_argv, in_argv, in_argc * sizeof (gchar *));
	tmp_argv[in_argc] = NULL;

	argc = in_argc;
	argv = tmp_argv;

	/* This updates argv and argc so that they start at the first non-command
	 * token. */
	match = cli_context_find_command (ctx, &argv, &argc, &action);
	if (match == COMMAND_TRIE_MATCH_ACTION) {
		gboolean help;
		gboolean need_io;
		command_t *cmd;

		/* Include one command token as a workaround for the bug that
		 * the option parser does not parse commands starting with a
		 * flag properly (e.g. "-p foo arg1"). Will be skipped by the
		 * command utils. */
		cmd = command_new (action->argdefs, argc + 1, argv - 1);

		if (cmd) {
			if (command_flag_boolean_get (cmd, "help", &help) && help) {
				/* Help flag passed, bypass action and show help */
				/* FIXME(g): select aliasnames list if it's an alias */
				help_command (ctx, cli_context_command_names (ctx),
				              in_argv, in_argc, CMD_TYPE_COMMAND);
			} else if (cli_context_command_runnable (ctx, action)) {
				/* All fine, run the command */
				command_name_set (cmd, action->name);
				cli_context_loop_suspend (ctx);
				need_io = action->callback (ctx, cmd);
				if (!need_io) {
					cli_context_loop_resume (ctx);
				}
			}

			command_free (cmd);
		}
	} else {
		/* Call help to print the "no such command" error */
		help_command (ctx, cli_context_command_names (ctx),
		              in_argv, in_argc, CMD_TYPE_COMMAND);
	}
}
Beispiel #5
0
void
command_dispatch (cli_infos_t *infos, gint in_argc, gchar **in_argv)
{
	command_action_t *action;
	command_trie_match_type_t match;
	gint argc;
	gchar **argv;

	gboolean auto_complete;

	/* The arguments will be updated by command_trie_find. */
	argc = in_argc;
	argv = in_argv;
	auto_complete = configuration_get_boolean (infos->config,
	                                           "AUTO_UNIQUE_COMPLETE");
	match = command_trie_find (infos->commands, &argv, &argc,
	                            auto_complete, &action);

	if (match == COMMAND_TRIE_MATCH_ACTION) {

		gboolean help;
		gboolean need_io;
		command_context_t *ctx;

		/* Include one command token as a workaround for the bug that
		 * the option parser does not parse commands starting with a
		 * flag properly (e.g. "-p foo arg1"). Will be skipped by the
		 * command utils. */
		ctx = init_context_from_args (action->argdefs, argc + 1, argv - 1);
		ctx->name = g_strdup (action->name);

		if (command_flag_boolean_get (ctx, "help", &help) && help) {
			/* Help flag passed, bypass action and show help */
			/* FIXME(g): select aliasnames list if it's an alias */
			help_command (infos, infos->cmdnames, in_argv, in_argc, CMD_TYPE_COMMAND);
		} else if (command_runnable (infos, action)) {
			/* All fine, run the command */
			cli_infos_loop_suspend (infos);
			need_io = action->callback (infos, ctx);
			if (!need_io) {
				cli_infos_loop_resume (infos);
			}
		}

		command_context_free (ctx);
	} else {
		/* Call help to print the "no such command" error */
		help_command (infos, infos->cmdnames, in_argv, in_argc, CMD_TYPE_COMMAND);
	}
}
Beispiel #6
0
static gboolean
cmd_flag_pos_get_playlist (cli_context_t *ctx, command_t *cmd,
                           gint *pos, const gchar *playlist)
{
	gboolean next, at_isset;
	gint at;
	gint tmp = -1;

	at_isset = command_flag_int_get (cmd, "at", &at);
	command_flag_boolean_get (cmd, "next", &next);

	if (next && at_isset) {
		g_printf (_("Error: --next and --at are mutually exclusive!\n"));
		return FALSE;
	} else if (next) {
		playlist_currpos_get (ctx, playlist, &tmp);
		if (tmp == -1) {
			/* no current position, next == append */
			if (!playlist_length_get (ctx, playlist, pos)) {
				return FALSE;
			}
		} else {
			*pos = tmp + 1;
		}
	} else if (at_isset) {
		if (!playlist_length_get (ctx, playlist, &tmp)) {
			return FALSE;
		}

		if (at == 0 || (at > 0 && at > tmp + 1)) {
			g_printf (_("Error: specified position is outside the playlist!\n"));
			return FALSE;
		} else {
			*pos = at - 1;  /* playlist ids start at 0 */
		}
	} else {
		/* default to append */
		playlist_length_get (ctx, playlist, pos);
	}

	return TRUE;
}