aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2021-11-08 02:13:57 +0100
committerPřemysl Eric Janouch <p@janouch.name>2021-11-08 06:07:04 +0100
commit4598c45d2f0279a2003fdab361685f8cba4eb38a (patch)
tree8a138385eebf857f433ac9861af9f2cbee1feb97
parent66c77c3f8d77019f53675ab392eb26c20b39f457 (diff)
downloadnncmpp-4598c45d2f0279a2003fdab361685f8cba4eb38a.tar.gz
nncmpp-4598c45d2f0279a2003fdab361685f8cba4eb38a.tar.xz
nncmpp-4598c45d2f0279a2003fdab361685f8cba4eb38a.zip
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.
-rw-r--r--CMakeLists.txt16
-rw-r--r--config.h.in5
-rw-r--r--nncmpp.actions71
-rw-r--r--nncmpp.c116
4 files changed, 93 insertions, 115 deletions
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);
}
}