Don't depend on a standalone C preprocessor
And get rid of the sed insanity.
This commit is contained in:
parent
a167ae40b3
commit
5cda848f94
|
@ -10,6 +10,14 @@ endif ()
|
||||||
# For custom modules
|
# For custom modules
|
||||||
set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/liberty/cmake)
|
set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/liberty/cmake)
|
||||||
|
|
||||||
|
# Collect important build toggles for our simple preprocessor
|
||||||
|
# (cpp(1) isn't part of POSIX, otherwise we could reuse config.h)
|
||||||
|
set (options)
|
||||||
|
macro (add_option variable help value)
|
||||||
|
option (${ARGV})
|
||||||
|
list (APPEND options "${variable}=$<BOOL:${${variable}}>")
|
||||||
|
endmacro ()
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
find_package (Ncursesw REQUIRED)
|
find_package (Ncursesw REQUIRED)
|
||||||
find_package (PkgConfig REQUIRED)
|
find_package (PkgConfig REQUIRED)
|
||||||
|
@ -19,7 +27,7 @@ pkg_check_modules (curl REQUIRED libcurl)
|
||||||
include (AddThreads)
|
include (AddThreads)
|
||||||
|
|
||||||
find_package (Termo QUIET NO_MODULE)
|
find_package (Termo QUIET NO_MODULE)
|
||||||
option (USE_SYSTEM_TERMO
|
add_option (USE_SYSTEM_TERMO
|
||||||
"Don't compile our own termo library, use the system one" ${Termo_FOUND})
|
"Don't compile our own termo library, use the system one" ${Termo_FOUND})
|
||||||
if (USE_SYSTEM_TERMO)
|
if (USE_SYSTEM_TERMO)
|
||||||
if (NOT Termo_FOUND)
|
if (NOT Termo_FOUND)
|
||||||
|
@ -41,7 +49,7 @@ else ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
pkg_check_modules (fftw fftw3 fftw3f)
|
pkg_check_modules (fftw fftw3 fftw3f)
|
||||||
option (WITH_FFTW "Use FFTW to enable spectrum visualisation" ${fftw_FOUND})
|
add_option (WITH_FFTW "Use FFTW to enable spectrum visualisation" ${fftw_FOUND})
|
||||||
if (WITH_FFTW)
|
if (WITH_FFTW)
|
||||||
if (NOT fftw_FOUND)
|
if (NOT fftw_FOUND)
|
||||||
message (FATAL_ERROR "FFTW not found")
|
message (FATAL_ERROR "FFTW not found")
|
||||||
|
@ -50,7 +58,8 @@ if (WITH_FFTW)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
pkg_check_modules (libpulse libpulse)
|
pkg_check_modules (libpulse libpulse)
|
||||||
option (WITH_PULSE "Enable control of PulseAudio sink volume" ${libpulse_FOUND})
|
add_option (WITH_PULSE
|
||||||
|
"Enable PulseAudio sink volume control" ${libpulse_FOUND})
|
||||||
if (WITH_PULSE)
|
if (WITH_PULSE)
|
||||||
if (NOT libpulse_FOUND)
|
if (NOT libpulse_FOUND)
|
||||||
message (FATAL_ERROR "libpulse not found")
|
message (FATAL_ERROR "libpulse not found")
|
||||||
|
@ -59,7 +68,7 @@ if (WITH_PULSE)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
pkg_check_modules (x11 x11 xrender xft fontconfig)
|
pkg_check_modules (x11 x11 xrender xft fontconfig)
|
||||||
option (WITH_X11 "Use FFTW to enable spectrum visualisation" ${x11_FOUND})
|
add_option (WITH_X11 "Use FFTW to enable spectrum visualisation" ${x11_FOUND})
|
||||||
if (WITH_X11)
|
if (WITH_X11)
|
||||||
if (NOT x11_FOUND)
|
if (NOT x11_FOUND)
|
||||||
message (FATAL_ERROR "Some X11 libraries were not found")
|
message (FATAL_ERROR "Some X11 libraries were not found")
|
||||||
|
@ -99,20 +108,13 @@ configure_file (${PROJECT_SOURCE_DIR}/config.h.in
|
||||||
${PROJECT_BINARY_DIR}/config.h)
|
${PROJECT_BINARY_DIR}/config.h)
|
||||||
include_directories (${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR})
|
include_directories (${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR})
|
||||||
|
|
||||||
# Assuming a Unix-compatible system with a standalone preprocessor
|
|
||||||
set (actions_list ${PROJECT_SOURCE_DIR}/nncmpp.actions)
|
set (actions_list ${PROJECT_SOURCE_DIR}/nncmpp.actions)
|
||||||
|
set (actions_awk ${PROJECT_SOURCE_DIR}/nncmpp.actions.awk)
|
||||||
set (actions ${PROJECT_BINARY_DIR}/nncmpp-actions.h)
|
set (actions ${PROJECT_BINARY_DIR}/nncmpp-actions.h)
|
||||||
add_custom_command (OUTPUT ${actions}
|
add_custom_command (OUTPUT ${actions}
|
||||||
COMMAND cpp -I${PROJECT_BINARY_DIR} -P ${actions_list}
|
COMMAND env LC_ALL=C ${options}
|
||||||
| grep . | tr [[\n]] ^ | sed -ne [[h; s/,[^^]*/,/g]] -e [[s/$/COUNT/]]
|
awk -f ${actions_awk} ${actions_list} > ${actions}
|
||||||
-e [[s/[^^]*/\tACTION_&/g]] -e [[s/.*/enum action {\n&\n};\n/p]]
|
DEPENDS ${actions_awk} ${actions_list} VERBATIM)
|
||||||
-e [[g; s/,[^^]*//g; y/_/-/]] -e [[s/[^^]\{1,\}/\t"&",/g]]
|
|
||||||
-e [[s/.*/static const char *g_action_names[] = {\n&};\n/p]]
|
|
||||||
-e [[g; s/[^^]*, *//g;]] -e [[s/[^^]\{1,\}/\t"&",/g]]
|
|
||||||
-e [[s/.*/static const char *g_action_descriptions[] = {\n&};/p]]
|
|
||||||
| tr ^ [[\n]] > ${actions}
|
|
||||||
COMMAND test -s ${actions}
|
|
||||||
DEPENDS ${actions_list} ${PROJECT_BINARY_DIR}/config.h VERBATIM)
|
|
||||||
|
|
||||||
# Build the main executable and link it
|
# Build the main executable and link it
|
||||||
add_executable (${PROJECT_NAME} ${PROJECT_NAME}.c ${actions})
|
add_executable (${PROJECT_NAME} ${PROJECT_NAME}.c ${actions})
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
NONE, Do nothing
|
NONE, Do nothing
|
||||||
|
|
||||||
QUIT, Quit
|
QUIT, Quit
|
||||||
|
@ -28,11 +26,11 @@ MPD_CONSUME, Toggle consume
|
||||||
MPD_UPDATE_DB, Update MPD database
|
MPD_UPDATE_DB, Update MPD database
|
||||||
MPD_COMMAND, Send raw command to MPD
|
MPD_COMMAND, Send raw command to MPD
|
||||||
|
|
||||||
#ifdef WITH_PULSE
|
.ifdef WITH_PULSE
|
||||||
PULSE_VOLUME_UP, Increase PulseAudio volume
|
PULSE_VOLUME_UP, Increase PulseAudio volume
|
||||||
PULSE_VOLUME_DOWN, Decrease PulseAudio volume
|
PULSE_VOLUME_DOWN, Decrease PulseAudio volume
|
||||||
PULSE_MUTE, Toggle PulseAudio sink mute
|
PULSE_MUTE, Toggle PulseAudio sink mute
|
||||||
#endif
|
.endif
|
||||||
|
|
||||||
CHOOSE, Choose item
|
CHOOSE, Choose item
|
||||||
DELETE, Delete item
|
DELETE, Delete item
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
# nncmpp.actions.awk: produce C code for a list of user actions
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, Přemysl Eric Janouch <p@janouch.name>
|
||||||
|
# SPDX-License-Identifier: 0BSD
|
||||||
|
#
|
||||||
|
# Usage: env LC_ALL=C A=0 B=1 awk -f nncmpp.actions.awk \
|
||||||
|
# nncmpp.actions > nncmpp-actions.h
|
||||||
|
|
||||||
|
# --- Preprocessor -------------------------------------------------------------
|
||||||
|
|
||||||
|
function fatal(message) {
|
||||||
|
print "// " FILENAME ":" FNR ": fatal error: " message
|
||||||
|
print FILENAME ":" FNR ": fatal error: " message > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function condition(pass, passing, a, i) {
|
||||||
|
split(substr($0, RSTART + RLENGTH), a, /[[:space:]]+/)
|
||||||
|
if (!(1 in a))
|
||||||
|
fatal("missing condition")
|
||||||
|
|
||||||
|
passing = 0
|
||||||
|
for (i in a)
|
||||||
|
if (a[i] && !pass == !ENVIRON[a[i]])
|
||||||
|
passing = 1
|
||||||
|
|
||||||
|
while (getline > 0) {
|
||||||
|
if (match($0, /^[[:space:]]*[.]endif[[:space:]]*$/))
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if (match($0, /^[[:space:]]*[.]else[[:space:]]*$/))
|
||||||
|
passing = !passing
|
||||||
|
else if (!directive() && passing)
|
||||||
|
process()
|
||||||
|
}
|
||||||
|
|
||||||
|
fatal("unterminated condition body")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Multiple arguments mean logical OR, multiple directives mean logical AND.
|
||||||
|
# Similar syntax is also used by Exim, BSD make, or various assemblers.
|
||||||
|
#
|
||||||
|
# Looking at what others have picked for their preprocessor syntax:
|
||||||
|
# {OpenGL, FreeBASIC} reuse #ifdef, which would be confusing with C code around,
|
||||||
|
# {Mental Ray, RapidQ and UniVerse BASIC} use $ifdef, NSIS has !ifdef,
|
||||||
|
# and Verilog went for `ifdef. Not much more can be easily found.
|
||||||
|
function directive() {
|
||||||
|
sub(/#.*/, "")
|
||||||
|
if (match($0, /^[[:space:]]*[.]ifdef[[:space:]]+/))
|
||||||
|
return condition(1)
|
||||||
|
if (match($0, /^[[:space:]]*[.]ifndef[[:space:]]+/))
|
||||||
|
return condition(0)
|
||||||
|
if (/^[[:space:]]*[.]/)
|
||||||
|
fatal("unexpected or unsupported directive")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
!directive() {
|
||||||
|
process()
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Postprocessor ------------------------------------------------------------
|
||||||
|
|
||||||
|
function strip(string) {
|
||||||
|
gsub(/^[[:space:]]*|[[:space:]]*$/, "", string)
|
||||||
|
return string
|
||||||
|
}
|
||||||
|
|
||||||
|
function process( constant, name, description) {
|
||||||
|
if (match($0, /,/)) {
|
||||||
|
constant = name = strip(substr($0, 1, RSTART - 1))
|
||||||
|
description = strip(substr($0, RSTART + RLENGTH))
|
||||||
|
gsub(/_/, "-", name)
|
||||||
|
|
||||||
|
N++
|
||||||
|
Constants[N] = constant
|
||||||
|
Names[N] = tolower(name)
|
||||||
|
Descriptions[N] = description
|
||||||
|
} else if (/[^[:space:]]/) {
|
||||||
|
fatal("invalid action definition syntax")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function tocstring(string) {
|
||||||
|
gsub(/\\/, "\\\\", string)
|
||||||
|
gsub(/"/, "\\\"", string)
|
||||||
|
return "\"" string "\""
|
||||||
|
}
|
||||||
|
|
||||||
|
END {
|
||||||
|
print "enum action {"
|
||||||
|
for (i in Constants)
|
||||||
|
print "\t" "ACTION_" Constants[i] ","
|
||||||
|
print "\t" "ACTION_COUNT"
|
||||||
|
print "};"
|
||||||
|
print ""
|
||||||
|
print "static const char *g_action_names[] = {"
|
||||||
|
for (i in Names)
|
||||||
|
print "\t" tocstring(Names[i]) ","
|
||||||
|
print "};"
|
||||||
|
print ""
|
||||||
|
print "static const char *g_action_descriptions[] = {"
|
||||||
|
for (i in Descriptions)
|
||||||
|
print "\t" tocstring(Descriptions[i]) ","
|
||||||
|
print "};"
|
||||||
|
}
|
5
nncmpp.c
5
nncmpp.c
|
@ -4168,9 +4168,8 @@ help_tab_on_action (enum action action)
|
||||||
|
|
||||||
if (action == ACTION_DESCRIBE)
|
if (action == ACTION_DESCRIBE)
|
||||||
{
|
{
|
||||||
char *name = xstrdup (g_action_names[a]);
|
app_show_message (xstrdup ("Configuration name: "),
|
||||||
cstr_transform (name, tolower_ascii);
|
xstrdup (g_action_names[a]));
|
||||||
app_show_message (xstrdup ("Configuration name: "), name);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (action != ACTION_CHOOSE || a == ACTION_CHOOSE /* avoid recursion */)
|
if (action != ACTION_CHOOSE || a == ACTION_CHOOSE /* avoid recursion */)
|
||||||
|
|
Loading…
Reference in New Issue