From 4598c45d2f0279a2003fdab361685f8cba4eb38a Mon Sep 17 00:00:00 2001 From: Přemysl Eric Janouch Date: Mon, 8 Nov 2021 02:13:57 +0100 Subject: Generate actions from a text file Mostly because I wanted to nest preprocessing. This makes the build more complex and slightly less portable, but the code itself is much cleaner. --- CMakeLists.txt | 16 +++++++- config.h.in | 5 +-- nncmpp.actions | 71 +++++++++++++++++++++++++++++++++++ nncmpp.c | 116 +++------------------------------------------------------ 4 files changed, 93 insertions(+), 115 deletions(-) create mode 100644 nncmpp.actions diff --git a/CMakeLists.txt b/CMakeLists.txt index 17c70ec..12bc35a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,8 +90,22 @@ configure_file (${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_BINARY_DIR}/config.h) include_directories (${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}) +# Assuming a Unix-compatible system with a standalone preprocessor +set (actions ${PROJECT_BINARY_DIR}/nncmpp-actions.h) +add_custom_command (OUTPUT ${actions} + COMMAND cpp -I${PROJECT_BINARY_DIR} -P ${PROJECT_SOURCE_DIR}/nncmpp.actions + | grep . | tr [[\n]] [[\t]] | sed -ne [[y/\t/\n/]] > ${actions} + -e [[h; s/,[^\n]*/,/g]] -e [[s/$/COUNT/]] + -e [[s/[^\n]*/\tACTION_&/g]] -e [[s/.*/enum action {\n&\n};\n/p]] + -e [[g; s/,[^\n]*//g; y/_/-/]] -e [[s/[^\n]\{1,\}/\t"&",/g]] + -e [[s/.*/static const char *g_action_names[] = {\n&};\n/p]] + -e [[g; s/[^\n]*, //g;]] -e [[s/[^\n]\{1,\}/\t"&",/g]] + -e [[s/.*/static const char *g_action_descriptions[] = {\n&};/p]] + COMMAND test -s ${actions} + DEPENDS ${PROJECT_BINARY_DIR}/config.h VERBATIM) + # Build the main executable and link it -add_executable (${PROJECT_NAME} ${PROJECT_NAME}.c) +add_executable (${PROJECT_NAME} ${PROJECT_NAME}.c ${actions}) target_link_libraries (${PROJECT_NAME} ${Unistring_LIBRARIES} ${Ncursesw_LIBRARIES} termo-static ${curl_LIBRARIES} ${extra_libraries}) add_threads (${PROJECT_NAME}) diff --git a/config.h.in b/config.h.in index 14c3759..d0ab65d 100644 --- a/config.h.in +++ b/config.h.in @@ -1,12 +1,11 @@ #ifndef CONFIG_H #define CONFIG_H -#define PROGRAM_NAME "${CMAKE_PROJECT_NAME}" +#define PROGRAM_NAME "${PROJECT_NAME}" #define PROGRAM_VERSION "${PROJECT_VERSION}" #cmakedefine HAVE_RESIZETERM #cmakedefine WITH_FFTW #cmakedefine WITH_PULSE -#endif // ! CONFIG_H - +#endif /* ! CONFIG_H */ diff --git a/nncmpp.actions b/nncmpp.actions new file mode 100644 index 0000000..6790e75 --- /dev/null +++ b/nncmpp.actions @@ -0,0 +1,71 @@ +#include "config.h" + +NONE, Do nothing + +QUIT, Quit +REDRAW, Redraw screen +TAB_HELP, Switch to help tab +TAB_LAST, Switch to last tab +TAB_PREVIOUS, Switch to previous tab +TAB_NEXT, Switch to next tab + +MPD_TOGGLE, Toggle play/pause +MPD_STOP, Stop playback +MPD_PREVIOUS, Previous song +MPD_NEXT, Next song +MPD_BACKWARD, Seek backwards +MPD_FORWARD, Seek forwards +MPD_VOLUME_UP, Increase volume +MPD_VOLUME_DOWN, Decrease volume + +MPD_SEARCH, Global search +MPD_ADD, Add selection to playlist +MPD_REPLACE, Replace playlist +MPD_REPEAT, Toggle repeat +MPD_RANDOM, Toggle random playback +MPD_SINGLE, Toggle single song playback +MPD_CONSUME, Toggle consume +MPD_UPDATE_DB, Update MPD database +MPD_COMMAND, Send raw command to MPD + +#ifdef WITH_PULSE +PULSE_VOLUME_UP, Increase PulseAudio volume +PULSE_VOLUME_DOWN, Decrease PulseAudio volume +PULSE_MUTE, Toggle mute of MPD PulseAudio sink +#endif + +CHOOSE, Choose item +DELETE, Delete item +UP, Go up a level +MULTISELECT, Toggle multiselect + +SCROLL_UP, Scroll up +SCROLL_DOWN, Scroll down +MOVE_UP, Move selection up +MOVE_DOWN, Move selection down + +GOTO_TOP, Go to top +GOTO_BOTTOM, Go to bottom +GOTO_ITEM_PREVIOUS, Go to previous item +GOTO_ITEM_NEXT, Go to next item +GOTO_PAGE_PREVIOUS, Go to previous page +GOTO_PAGE_NEXT, Go to next page + +GOTO_VIEW_TOP, Select top item +GOTO_VIEW_CENTER, Select center item +GOTO_VIEW_BOTTOM, Select bottom item + +EDITOR_CONFIRM, Confirm input + +EDITOR_B_CHAR, Go back a character +EDITOR_F_CHAR, Go forward a character +EDITOR_B_WORD, Go back a word +EDITOR_F_WORD, Go forward a word +EDITOR_HOME, Go to start of line +EDITOR_END, Go to end of line + +EDITOR_B_DELETE, Delete last character +EDITOR_F_DELETE, Delete next character +EDITOR_B_KILL_WORD, Delete last word +EDITOR_B_KILL_LINE, Delete everything up to BOL +EDITOR_F_KILL_LINE, Delete everything up to EOL diff --git a/nncmpp.c b/nncmpp.c index e302890..766723d 100644 --- a/nncmpp.c +++ b/nncmpp.c @@ -2235,117 +2235,14 @@ app_goto_tab (int tab_index) // --- Actions ----------------------------------------------------------------- -#ifdef WITH_PULSE -#define WITH_PULSE_01 1 -#else -#define WITH_PULSE_01 0 -#endif - -// TODO: use the C preprocessor and a tool to generate this from nncmpp.actions -#define ACTIONS(XX) \ - XX( 1, NONE, Do nothing ) \ - \ - XX( 1, QUIT, Quit ) \ - XX( 1, REDRAW, Redraw screen ) \ - XX( 1, TAB_HELP, Switch to help tab ) \ - XX( 1, TAB_LAST, Switch to last tab ) \ - XX( 1, TAB_PREVIOUS, Switch to previous tab ) \ - XX( 1, TAB_NEXT, Switch to next tab ) \ - \ - XX( 1, MPD_TOGGLE, Toggle play/pause ) \ - XX( 1, MPD_STOP, Stop playback ) \ - XX( 1, MPD_PREVIOUS, Previous song ) \ - XX( 1, MPD_NEXT, Next song ) \ - XX( 1, MPD_BACKWARD, Seek backwards ) \ - XX( 1, MPD_FORWARD, Seek forwards ) \ - XX( 1, MPD_VOLUME_UP, Increase volume ) \ - XX( 1, MPD_VOLUME_DOWN, Decrease volume ) \ - \ - XX( 1, MPD_SEARCH, Global search ) \ - XX( 1, MPD_ADD, Add selection to playlist ) \ - XX( 1, MPD_REPLACE, Replace playlist ) \ - XX( 1, MPD_REPEAT, Toggle repeat ) \ - XX( 1, MPD_RANDOM, Toggle random playback ) \ - XX( 1, MPD_SINGLE, Toggle single song playback ) \ - XX( 1, MPD_CONSUME, Toggle consume ) \ - XX( 1, MPD_UPDATE_DB, Update MPD database ) \ - XX( 1, MPD_COMMAND, Send raw command to MPD ) \ - \ - XX( WITH_PULSE_01, PULSE_VOLUME_UP, Increase PulseAudio volume ) \ - XX( WITH_PULSE_01, PULSE_VOLUME_DOWN, Decrease PulseAudio volume ) \ - XX( WITH_PULSE_01, PULSE_MUTE, Toggle mute of MPD PulseAudio sink ) \ - \ - XX( 1, CHOOSE, Choose item ) \ - XX( 1, DELETE, Delete item ) \ - XX( 1, UP, Go up a level ) \ - XX( 1, MULTISELECT, Toggle multiselect ) \ - \ - XX( 1, SCROLL_UP, Scroll up ) \ - XX( 1, SCROLL_DOWN, Scroll down ) \ - XX( 1, MOVE_UP, Move selection up ) \ - XX( 1, MOVE_DOWN, Move selection down ) \ - \ - XX( 1, GOTO_TOP, Go to top ) \ - XX( 1, GOTO_BOTTOM, Go to bottom ) \ - XX( 1, GOTO_ITEM_PREVIOUS, Go to previous item ) \ - XX( 1, GOTO_ITEM_NEXT, Go to next item ) \ - XX( 1, GOTO_PAGE_PREVIOUS, Go to previous page ) \ - XX( 1, GOTO_PAGE_NEXT, Go to next page ) \ - \ - XX( 1, GOTO_VIEW_TOP, Select top item ) \ - XX( 1, GOTO_VIEW_CENTER, Select center item ) \ - XX( 1, GOTO_VIEW_BOTTOM, Select bottom item ) \ - \ - XX( 1, EDITOR_CONFIRM, Confirm input ) \ - \ - XX( 1, EDITOR_B_CHAR, Go back a character ) \ - XX( 1, EDITOR_F_CHAR, Go forward a character ) \ - XX( 1, EDITOR_B_WORD, Go back a word ) \ - XX( 1, EDITOR_F_WORD, Go forward a word ) \ - XX( 1, EDITOR_HOME, Go to start of line ) \ - XX( 1, EDITOR_END, Go to end of line ) \ - \ - XX( 1, EDITOR_B_DELETE, Delete last character ) \ - XX( 1, EDITOR_F_DELETE, Delete next character ) \ - XX( 1, EDITOR_B_KILL_WORD, Delete last word ) \ - XX( 1, EDITOR_B_KILL_LINE, Delete everything up to BOL ) \ - XX( 1, EDITOR_F_KILL_LINE, Delete everything up to EOL ) - -enum action -{ -#define XX(usable, name, description) ACTION_ ## name, - ACTIONS (XX) -#undef XX - ACTION_COUNT -}; - -static struct action_info -{ - const char *name; ///< Name for user bindings - const char *description; ///< Human-readable description - bool usable; ///< Usable? -} -g_actions[] = -{ -#define XX(usable, name, description) { #name, #description, usable }, - ACTIONS (XX) -#undef XX -}; - -/// Accept a more human format of action-name instead of ACTION_NAME -static int action_toupper (int c) { return c == '-' ? '_' : toupper_ascii (c); } +#include "nncmpp-actions.h" static int action_resolve (const char *name) { - const unsigned char *s = (const unsigned char *) name; for (int i = 0; i < ACTION_COUNT; i++) - { - const char *target = g_actions[i].name; - for (size_t k = 0; action_toupper (s[k]) == target[k]; k++) - if (!s[k] && !target[k]) - return i; - } + if (!strcasecmp_ascii (g_action_names[i], name)) + return i; return -1; } @@ -3943,9 +3840,6 @@ help_tab_group (struct binding *keys, size_t len, struct strv *out, { for (enum action i = 0; i < ACTION_COUNT; i++) { - if (!g_actions[i].usable) - continue; - struct strv ass = strv_make (); for (size_t k = 0; k < len; k++) if (keys[k].action == i) @@ -3954,7 +3848,7 @@ help_tab_group (struct binding *keys, size_t len, struct strv *out, { char *joined = strv_join (&ass, ", "); strv_append_owned (out, xstrdup_printf - (" %-30s %s", g_actions[i].description, joined)); + (" %-30s %s", g_action_descriptions[i], joined)); free (joined); bound[i] = true; @@ -3971,7 +3865,7 @@ help_tab_unbound (struct strv *out, bool bound[ACTION_COUNT]) if (!bound[i]) { strv_append_owned (out, - xstrdup_printf (" %-30s", g_actions[i].description)); + xstrdup_printf (" %-30s", g_action_descriptions[i])); help_tab_assign_action (i); } } -- cgit v1.2.3-70-g09d2