From 671fc51d270d375eb756d7f13e5343cb54021cc5 Mon Sep 17 00:00:00 2001 From: Jonas Holmberg Date: Wed, 15 Jun 2022 16:00:22 +0200 Subject: [PATCH] pw-cli: Work without readline too Build and install pw-cli using getline() (standardized in POSIX.1-2008) if readline is not found. --- meson.build | 1 + src/tools/meson.build | 12 +++++------- src/tools/pw-cli.c | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/meson.build b/meson.build index 972a55771..d21fc8f61 100644 --- a/meson.build +++ b/meson.build @@ -266,6 +266,7 @@ if not readline_dep.found() endif summary({'readline (for pw-cli)': readline_dep.found()}, bool_yn: true, section: 'Misc dependencies') +cdata.set('HAVE_READLINE', readline_dep.found()) ncurses_dep = dependency('ncursesw', required : false) sndfile_dep = dependency('sndfile', version : '>= 1.0.20', required : get_option('sndfile')) summary({'sndfile': sndfile_dep.found()}, bool_yn: true, section: 'pw-cat/pw-play/pw-dump/filter-chain') diff --git a/src/tools/meson.build b/src/tools/meson.build index 02514c253..9f058da97 100644 --- a/src/tools/meson.build +++ b/src/tools/meson.build @@ -17,13 +17,11 @@ foreach t : tools_sources ) endforeach -if readline_dep.found() - executable('pw-cli', - 'pw-cli.c', - install: true, - dependencies: [pipewire_dep, readline_dep] - ) -endif +executable('pw-cli', + 'pw-cli.c', + install: true, + dependencies: [pipewire_dep, readline_dep] +) if ncurses_dep.found() executable('pw-top', diff --git a/src/tools/pw-cli.c b/src/tools/pw-cli.c index 71b3f071e..f45d10887 100644 --- a/src/tools/pw-cli.c +++ b/src/tools/pw-cli.c @@ -22,6 +22,8 @@ * DEALINGS IN THE SOFTWARE. */ +#include "config.h" + #include #include #include @@ -33,8 +35,10 @@ #endif #include #include +#ifdef HAVE_READLINE #include #include +#endif #include #if !defined(FNM_EXTMATCH) @@ -307,7 +311,12 @@ static void on_core_info(void *_data, const struct pw_core_info *info) static void set_prompt(struct remote_data *rd) { snprintf(prompt, sizeof(prompt), "%s>> ", rd->name); +#ifdef HAVE_READLINE rl_set_prompt(prompt); +#else + printf("%s", prompt); + fflush(stdout); +#endif } static void on_core_done(void *_data, uint32_t id, int seq) @@ -3040,18 +3049,20 @@ static bool parse(struct data *data, char *buf, char **error) } /* We need a global variable, readline doesn't have a closure arg */ -static struct data *readline_dataptr; +static struct data *input_dataptr; -static void readline_process_line(char *line) +static void input_process_line(char *line) { - struct data *d = readline_dataptr; + struct data *d = input_dataptr; char *error; if (!line) line = strdup("quit"); if (line[0] != '\0') { +#ifdef HAVE_READLINE add_history(line); +#endif if (!parse(d, line, &error)) { fprintf(stderr, "Error: \"%s\"\n", error); free(error); @@ -3065,8 +3076,21 @@ static void do_input(void *data, int fd, uint32_t mask) struct data *d = data; if (mask & SPA_IO_IN) { - readline_dataptr = d; + input_dataptr = d; +#ifdef HAVE_READLINE rl_callback_read_char(); +#else + { + char *line = NULL; + size_t s = 0; + + if (getline(&line, &s, stdin) < 0) { + free(line); + line = NULL; + } + input_process_line(line); + } +#endif if (d->current == NULL) pw_main_loop_quit(d->loop); @@ -3078,6 +3102,7 @@ static void do_input(void *data, int fd, uint32_t mask) } } +#ifdef HAVE_READLINE static char * readline_match_command(const char *text, int state) { @@ -3119,13 +3144,14 @@ readline_command_completion(const char *text, int start, int end) static void readline_init() { rl_attempted_completion_function = readline_command_completion; - rl_callback_handler_install(">> ", readline_process_line); + rl_callback_handler_install(">> ", input_process_line); } static void readline_cleanup() { rl_callback_handler_remove(); } +#endif static void do_quit_on_signal(void *data, int signal_number) { @@ -3232,13 +3258,17 @@ int main(int argc, char *argv[]) printf("Welcome to PipeWire version %s. Type 'help' for usage.\n", pw_get_library_version()); +#ifdef HAVE_READLINE readline_init(); +#endif pw_loop_add_io(l, STDIN_FILENO, SPA_IO_IN|SPA_IO_HUP, false, do_input, &data); pw_main_loop_run(data.loop); +#ifdef HAVE_READLINE readline_cleanup(); +#endif } else { char buf[4096], *p, *error;