Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement platform-independent signal lists #1206

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ pcp-htop
# all object files
*.o

# intermediate signal lists
/signals/SignalList.in.i
/signals/SignalList.in.sorted

# skip all backups
*.bak
*~
Expand Down
21 changes: 21 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ dist_man_MANS = htop.1
EXTRA_DIST = \
$(dist_man_MANS) \
autogen.sh \
signals/ParseSignals.sed \
signals/PrintSignals.sed \
signals/SignalList.in.c \
htop.desktop \
htop.png \
htop.svg \
Expand Down Expand Up @@ -438,6 +441,24 @@ myhtopplatsources = $(unsupported_platform_sources)
myhtopplatheaders = $(unsupported_platform_headers)
endif

# Sorting the signal list at build time
# -------------------------------------

SUFFIXES = .i
# Preprocessing a list of signals to get their numbers from the headers.
.c.i:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.c.i:
signals/SignalList.in.i: signals/SignalList.in.c

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the suggested form, this won't work with out-of-tree builds. Why not use the suffix rule? I believe that suffix rules are idiomatic for Automake and the recipe is generic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The suffix rule would affect all files with the same extension in the build tree. Since we have just one file that needs such preprocessing, a suffix rule would be a bad idea.

And yes, the dependency line should be $(srcdir)/signals/SignalList.in.c instead.

$(AM_V_GEN)$(CPP) $(AM_CPPFLAGS) $(CPPFLAGS) -o $@ $<

MOSTLYCLEANFILES = signals/SignalList.in.i signals/SignalList.in.sorted
# Sorting the list of signals by the signal number.
signals/SignalList.in.sorted: signals/SignalList.in.i $(srcdir)/signals/ParseSignals.sed $(srcdir)/signals/PrintSignals.sed
$(AM_V_GEN)$(SED) -f $(srcdir)/signals/ParseSignals.sed signals/SignalList.in.i | LC_COLLATE=C $(SORT) -t' ' -k1n,1 -k2 | $(SED) -f $(srcdir)/signals/PrintSignals.sed > $@

# Building the sorted signal list.
# This should only add a dependency without inadvertently overriding any
# Automake-generated rules, because SignalList.o is built using a suffix rule.
signals/SignalList.$(OBJEXT): signals/SignalList.in.sorted

# ----

htop_SOURCES = $(myhtopplatprogram) $(myhtopheaders) $(myhtopplatheaders) $(myhtopsources) $(myhtopplatsources)
Expand Down
11 changes: 11 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,23 @@ AC_USE_SYSTEM_EXTENSIONS

AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_CPP
m4_version_prereq([2.70], [], [AC_PROG_CC_C99])
AS_IF([test "x$ac_cv_prog_cc_c99" = xno], [AC_MSG_ERROR([htop is written in C99. A newer compiler is required.])])

# ----------------------------------------------------------------------


# ----------------------------------------------------------------------
# Checks for common tools.
# ----------------------------------------------------------------------

AC_PROG_SED
AC_PATH_PROG([SORT], [sort], [sort])

# ----------------------------------------------------------------------


# ----------------------------------------------------------------------
# Checks for static build.
# ----------------------------------------------------------------------
Expand Down
99 changes: 99 additions & 0 deletions signals/ParseSignals.sed
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# htop - signals/ParseSignals.sed
# (C) 2023 htop dev team
# Released under the GNU GPLv2+, see the COPYING file
# in the source distribution for its full text.

# Parse a preprocessed C file with a list of signal numbers and names; output
# the numbers and names in a sortable format.

# The reason why this script exists at all is that the preprocessed C output
# doesn't correspond line-to-line with the original source file. Among other
# issues, it contains preprocessor directives with line numbers, which break
# up the output. To allow sorting the file by signal name at compile time,
# the preprocessed output has to be "parsed" and reformatted.

# The script should be relatively robust wrt. C compiler output, but it should
# still be considered a hack. It is possible that unforeseen input breaks it.

# It works by building up each multiline signal entry (number and name) in the
# hold space until it is complete, postprocessing and printing it. The entry
# is recognized by the htop_sig{start,mid,end} markers, because these are all
# but guaranteed not to be mangled or duplicated by the preprocessing, unlike
# e.g. parens, braces or semicolons.


# Skip preprocessor directives. This breaks the relationship between input and
# output files, but it makes sorting easy.
/^#/ d
vidraj marked this conversation as resolved.
Show resolved Hide resolved

:start

# Only process data between htop_sigstart and htop_sigend, deleting the rest.
/htop_sigstart/ {
# Skip the start marker itself.
# We can't write simply `s/.*htop_sigstart[[:space:]]*//`, because the
# initial star is eager, so it would happily consume multiple start
# markers. This should never happen, but the script should be robust
# just in case.
# Solution: Rename the first start marker to a temporary name and
# delete using the new name.
/htop_delsigstart/ i\
#error "The sed input contains `htop_sigdelstart`, which is a reserved marker."
s/htop_sigstart/htop_delsigstart/
s/.*htop_delsigstart[[:space:]]*//

:loop
# Read input until we see the end marker.

# The end marker has been seen, we can go on with processing.
/htop_sigend/ {
# We need to save the rest of the line for further processing,
# so store the whole line and deal with that later.
h

# Delete the end marker and the rest of the line, keeping just
# the signal definition.
/htop_sigdelend/ i\
#error "The sed input contains 'htop_sigdelend', which is a reserved marker."
s/htop_sigend/htop_sigdelend/
s/htop_sigdelend.*//

# Normalize spaces to get rid of tabs and newlines and clean
# up the output.
s/[[:space:]][[:space:]]*/ /g
s/^[[:space:]]*//
s/[[:space:]]*$//

# Replace the separator between the signal number and name
# with a tab for sorting.
s/ htop_sigmid / /
# TODO test whether the above succeeded and report error otherwise.

# Test whether the signal number is actually a number, as it
# would not be sortable otherwise.
/^[0-9][0-9]* / !i\
#warning "Encountered non-numeric signal number; sorting may be broken."

# Print the signal definition.
p

# Process the rest of the line.
g
s/htop_sigend/htop_sigdelend/
s/.*htop_sigdelend//
b start
}

:dprep
# The end marker was not seen yet, read one more line.
N
# If the next line is a preprocessor directive, delete it, read
# another one and test for preprocessor directives again.
s/\n#.*//
t dprep
# Test for the end marker again.
b loop
}

# The line is outside a range marked as signal definition, suppress it.
d
9 changes: 9 additions & 0 deletions signals/PrintSignals.sed
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# htop - signals/PrintSignals.sed
# (C) 2023 htop dev team
# Released under the GNU GPLv2+, see the COPYING file
# in the source distribution for its full text.

# Single digit, justify name by one space.
s/^\([0-9]\) "\(.*\)"$/{ .number=(\1), .name=(" \1 \2") },/
# Multiple digits or a complex expression, don't justify.
s/^\(.*\) "\(.*\)"$/{ .number=(\1), .name=("\1 \2") },/
170 changes: 170 additions & 0 deletions signals/SignalList.in.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
htop - signals/SignalList.in.c
(C) 2023 htop dev team
Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/

#include <signal.h>

#define HTOP_SIGENTRY(x) htop_sigstart x htop_sigmid #x htop_sigend


HTOP_SIGENTRY(SIGABRT)

HTOP_SIGENTRY(SIGALRM)

HTOP_SIGENTRY(SIGBUS)

/* On Solaris. */
#ifdef SIGCANCEL
HTOP_SIGENTRY(SIGCANCEL)
#endif

#ifdef SIGCHLD
HTOP_SIGENTRY(SIGCHLD)
#endif

/* A synonym for SIGCHLD on Linux/MIPS, original name on SysV, omitting
if SIGCHLD is also defined, since confusion is unlikely. */
#ifndef SIGCHLD
HTOP_SIGENTRY(SIGCLD)
#endif

HTOP_SIGENTRY(SIGCONT)

/* On BSDs and Alpha, Sparc and MIPS Linuxes. */
#ifdef SIGEMT
HTOP_SIGENTRY(SIGEMT)
#endif

HTOP_SIGENTRY(SIGFPE)

/* On Solaris. */
#ifdef SIGFREEZE
HTOP_SIGENTRY(SIGFREEZE)
#endif

HTOP_SIGENTRY(SIGHUP)

HTOP_SIGENTRY(SIGILL)

/* On Solaris. Also a synonym for SIGPWR on Linux/Alpha. */
#ifdef SIGINFO
HTOP_SIGENTRY(SIGINFO)
#endif

HTOP_SIGENTRY(SIGINT)

HTOP_SIGENTRY(SIGIO)

/* A synonym for SIGABRT on Linux and Solaris, found on OpenBSD and NetBSD,
* not on FreeBSD.
*/
#ifdef SIGIOT
HTOP_SIGENTRY(SIGIOT)
#endif

/* On Solaris. */
#ifdef SIGJVM1
HTOP_SIGENTRY(SIGJVM1)
#endif

/* On Solaris. */
#ifdef SIGJVM2
HTOP_SIGENTRY(SIGJVM2)
#endif

HTOP_SIGENTRY(SIGKILL)

/* On FreeBSD. */
#ifdef SIGLIBRT
HTOP_SIGENTRY(SIGLIBRT)
#endif

/* On Solaris and Linux/SPARC. */
#ifdef SIGLOST
HTOP_SIGENTRY(SIGLOST)
#endif

/* On Solaris. */
#ifdef SIGLWP
HTOP_SIGENTRY(SIGLWP)
#endif

HTOP_SIGENTRY(SIGPIPE)

/* A synonym for SIGIO on Linux and Solaris. */
#ifdef SIGPOLL
HTOP_SIGENTRY(SIGPOLL)
#endif

HTOP_SIGENTRY(SIGPROF)

/* Linux, NetBSD and SysV. */
#ifdef SIGPWR
HTOP_SIGENTRY(SIGPWR)
#endif

HTOP_SIGENTRY(SIGQUIT)

HTOP_SIGENTRY(SIGSEGV)

/* Not on BSDs. */
#ifdef SIGSTKFLT
HTOP_SIGENTRY(SIGSTKFLT)
#endif

HTOP_SIGENTRY(SIGSTOP)

HTOP_SIGENTRY(SIGSYS)

HTOP_SIGENTRY(SIGTERM)

/* On Solaris. */
#ifdef SIGTHAW
HTOP_SIGENTRY(SIGTHAW)
#endif

/* On FreeBSD and OpenBSD. */
#ifdef SIGTHR
HTOP_SIGENTRY(SIGTHR)
#endif

HTOP_SIGENTRY(SIGTRAP)

HTOP_SIGENTRY(SIGTSTP)

HTOP_SIGENTRY(SIGTTIN)

HTOP_SIGENTRY(SIGTTOU)

/* A synonym for SIGSYS on Linux, deprecated.
#ifdef SIGUNUSED
HTOP_SIGENTRY(SIGUNUSED)
#endif
*/

HTOP_SIGENTRY(SIGURG)

HTOP_SIGENTRY(SIGUSR1)

HTOP_SIGENTRY(SIGUSR2)

HTOP_SIGENTRY(SIGVTALRM)

HTOP_SIGENTRY(SIGXCPU)

HTOP_SIGENTRY(SIGXFSZ)

/* On Solaris. */
#ifdef SIGXRES
HTOP_SIGENTRY(SIGXRES)
#endif

/* On Solaris. */
#ifdef SIGWAITING
HTOP_SIGENTRY(SIGWAITING)
#endif

HTOP_SIGENTRY(SIGWINCH)