pipewire/src/pipewire/command.c

167 lines
4.2 KiB
C
Raw Normal View History

2017-05-23 19:15:33 +02:00
/* PipeWire
* Copyright (C) 2016 Axis Communications <dev-gstreamer@axis.com>
* @author Linus Svensson <linus.svensson@axis.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <string.h>
#include <stdio.h>
2017-07-11 15:57:20 +02:00
#include <pipewire/pipewire.h>
#include <pipewire/utils.h>
#include <pipewire/module.h>
#include "command.h"
#include "private.h"
2017-05-30 19:46:51 +02:00
/** \cond */
2017-05-26 18:19:51 +02:00
typedef bool(*pw_command_func_t) (struct pw_command *command, struct pw_core *core, char **err);
2017-05-26 08:05:01 +02:00
static bool execute_command_module_load(struct pw_command *command,
struct pw_core *core, char **err);
2017-05-26 08:05:01 +02:00
typedef struct pw_command *(*pw_command_parse_func_t) (const char *line, char **err);
2017-05-26 08:05:01 +02:00
static struct pw_command *parse_command_module_load(const char *line, char **err);
2017-05-23 19:15:33 +02:00
struct impl {
2017-05-26 08:05:01 +02:00
struct pw_command this;
2016-11-14 12:42:00 +01:00
2017-05-26 08:05:01 +02:00
pw_command_func_t func;
char **args;
int n_args;
2017-05-23 19:15:33 +02:00
};
2017-05-26 08:05:01 +02:00
struct command_parse {
const char *name;
pw_command_parse_func_t func;
2017-05-23 19:15:33 +02:00
};
2017-05-23 19:15:33 +02:00
static const struct command_parse parsers[] = {
2017-05-26 08:05:01 +02:00
{"load-module", parse_command_module_load},
{NULL, NULL}
};
static const char whitespace[] = " \t";
2017-05-30 19:46:51 +02:00
/** \endcond */
2017-05-26 08:05:01 +02:00
static struct pw_command *parse_command_module_load(const char *line, char **err)
{
2017-05-26 08:05:01 +02:00
struct impl *impl;
2017-05-26 08:05:01 +02:00
impl = calloc(1, sizeof(struct impl));
if (impl == NULL)
goto no_mem;
2017-05-26 08:05:01 +02:00
impl->func = execute_command_module_load;
impl->args = pw_split_strv(line, whitespace, 3, &impl->n_args);
2017-05-26 08:05:01 +02:00
if (impl->args[1] == NULL)
goto no_module;
2017-05-26 08:05:01 +02:00
impl->this.name = impl->args[0];
2017-05-26 08:05:01 +02:00
return &impl->this;
2017-05-26 08:05:01 +02:00
no_module:
asprintf(err, "%s requires a module name", impl->args[0]);
pw_free_strv(impl->args);
return NULL;
no_mem:
asprintf(err, "no memory");
return NULL;
}
2016-11-14 12:42:00 +01:00
static bool
2017-05-26 08:05:01 +02:00
execute_command_module_load(struct pw_command *command, struct pw_core *core, char **err)
{
2017-05-26 08:05:01 +02:00
struct impl *impl = SPA_CONTAINER_OF(command, struct impl, this);
if (pw_module_load(core, impl->args[1], impl->args[2]) == NULL) {
asprintf(err, "could not load module \"%s\"", impl->args[1]);
return false;
}
return true;
}
2017-05-30 19:46:51 +02:00
/** Free command
*
2017-05-30 19:46:51 +02:00
* \param command a command to free
*
* Free all resources assicated with \a command.
*
* \memberof pw_command
*/
2017-05-26 08:05:01 +02:00
void pw_command_free(struct pw_command *command)
{
2017-05-26 08:05:01 +02:00
struct impl *impl = SPA_CONTAINER_OF(command, struct impl, this);
2017-05-26 08:05:01 +02:00
spa_list_remove(&command->link);
pw_free_strv(impl->args);
free(impl);
}
2017-05-30 19:46:51 +02:00
/** Parses a command line
* \param line command line to parse
* \param[out] err Return location for an error
* \return The command or NULL when \a err is set.
*
2017-05-30 19:46:51 +02:00
* Parses a command line, \a line, and return the parsed command.
* A command can later be executed with \ref pw_command_run()
*
2017-05-30 19:46:51 +02:00
* \memberof pw_command
*/
2017-05-26 08:05:01 +02:00
struct pw_command *pw_command_parse(const char *line, char **err)
{
2017-05-26 08:05:01 +02:00
struct pw_command *command = NULL;
const struct command_parse *parse;
char *name;
size_t len;
len = strcspn(line, whitespace);
name = strndup(line, len);
for (parse = parsers; parse->name != NULL; parse++) {
if (strcmp(name, parse->name) == 0) {
command = parse->func(line, err);
goto out;
}
}
asprintf(err, "Command \"%s\" does not exist", name);
out:
free(name);
return command;
}
2017-05-30 19:46:51 +02:00
/** Run a command
*
2017-05-30 19:46:51 +02:00
* \param command: A \ref pw_command
* \param core: A \ref pw_core
* \param err: Return location for an error string, or NULL
* \return true if \a command was executed successfully, false otherwise.
*
2017-05-30 19:46:51 +02:00
* \memberof pw_command
*/
2017-05-26 18:19:51 +02:00
bool pw_command_run(struct pw_command *command, struct pw_core *core, char **err)
{
2017-05-26 08:05:01 +02:00
struct impl *impl = SPA_CONTAINER_OF(command, struct impl, this);
2017-05-26 08:05:01 +02:00
return impl->func(command, core, err);
}