From: Michael Orlitzky Date: Sun, 13 Nov 2022 00:10:19 +0000 (-0500) Subject: utils/parse_macros: simplify and posixify. X-Git-Tag: v0.4~8 X-Git-Url: https://gitweb.michael.orlitzky.com/?p=nagios-mode.git;a=commitdiff_plain;h=13a9ddce3994dda86585ff9435a7cbdf89f7be5f utils/parse_macros: simplify and posixify. Update this script to be POSIX compliant, and to run under /bin/sh instead of /bin/bash. In addition it now prints its output to stdout rather than a named output file, and creates its temporary file more sanely and securely. --- diff --git a/utils/parse_macros b/utils/parse_macros index 186ef61..2f63b73 100755 --- a/utils/parse_macros +++ b/utils/parse_macros @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # # Parse the macro names out of Nagios' include/macros.h. # @@ -8,67 +8,57 @@ EXIT_USAGE=1 EXIT_INPUT_FILE_DOESNT_EXIST=2 -EXIT_OUTPUT_FILE_EXISTS=3 -EXIT_TEMP_FILE_EXISTS=4 -if [ $# -lt 2 ]; then - echo "Usage: $0 " +posix_mktemp(){ + # Securely create a temporary file under ${TMPDIR} using the + # template "tmpXXXXXX", and echo the result to stdout. This works + # around the absence of "mktemp" in the POSIX standard. + printf 'mkstemp(template)' | m4 -D template="${TMPDIR:-/tmp}/tmpXXXXXX" +} + +if [ $# -lt 1 ]; then + echo "Usage: $0 " exit $EXIT_USAGE fi INFILE="$1" OUTFILE="$2" -TEMPFILE="${OUTFILE}.tmp" +TEMPFILE="$(posix_mktemp)" if [ ! -f "$INFILE" ]; then echo "Error: input file $INFILE doesn't exist." exit $EXIT_INPUT_FILE_DOESNT_EXIST fi -if [ -f "$OUTFILE" ]; then - echo "Error: output file $OUTFILE already exists." - exit $EXIT_OUTPUT_FILE_EXISTS -fi - -if [ -f "$TEMPFILE" ]; then - echo "Error: temporary file $TEMPFILE already exists." - exit $EXIT_TEMP_FILE_EXISTS -fi - -# Common options. Color screws up the output. -GREP="grep --extended-regexp --color=never" - -# Grep grabs all of the "#define MACRO..." lines, except for -# MACRO_X_COUNT and MACRO_ENV_VAR_PREFIX which aren't real macros. -# Sed just removes the "MACRO_" prefixes. -$GREP --only-matching '[[:space:]]MACRO_[[:alnum:]_]+' "$INFILE" \ - | $GREP -v 'MACRO_X_COUNT' \ - | $GREP -v 'MACRO_ENV_VAR_PREFIX' \ - | sed 's/ MACRO_//g' >> "$OUTFILE" +# Grabs all of the "#define MACRO..." lines, except for MACRO_X_COUNT +# and MACRO_ENV_VAR_PREFIX which aren't real macros, and outputs the +# macro name (everything after "MACRO_") enclosed in quotes and dollar +# signs, appropriate to be copy/pasted directly into nagios-mode.el. +MACRO_REGEX='#define[[:space:]]\{1,\}MACRO_\([^[:space:]]\{1,\}\)[[:space:]]\{1,\}.*' +sed -n "s/${MACRO_REGEX}/\"\$\1\$\"/p" "${INFILE}" \ + | sed '/X_COUNT\|ENV_VAR_PREFIX/d' \ + >> "${TEMPFILE}" -# We need to include ARG1, ARG2... ARG, -# where the maximum is defined in macros.h. -MAXARG=`$GREP 'MAX_COMMAND_ARGUMENTS' "$INFILE" \ - | $GREP --only-matching '[[:digit:]]+'` +# Add "$ARG1$", "$ARG2$",... "$ARG$" to the list, where is +# defined in macros.h. +MAXARG_REGEX='#define[[:space:]]\{1,\}MAX_COMMAND_ARGUMENTS[[:space:]]\{1,\}\([1-9][0-9]*\).*' +MAXARG=$(sed -n "s/${MAXARG_REGEX}/\1/p" "${INFILE}") for argnum in `seq 1 $MAXARG`; do - echo "ARG${argnum}" >> "$OUTFILE" + echo "\"\$ARG${argnum}\$\"" >> "${TEMPFILE}" done -# And, the USER1, USER2... USER macros. -# Same as above. -MAXUSER=`$GREP 'MAX_USER_MACROS' "$INFILE" \ - | $GREP --only-matching '[[:digit:]]+'` +# Also the "$USER$" macros, similar to the above. +MAXUSER_REGEX='#define[[:space:]]\{1,\}MAX_USER_MACROS[[:space:]]\{1,\}\([1-9][0-9]*\).*' +MAXUSER=$(sed -n "s/${MAXUSER_REGEX}/\1/p" "${INFILE}") for argnum in `seq 1 $MAXUSER`; do - echo "USER${argnum}" >> "$OUTFILE" + echo "\"\$USER${argnum}\$\"" >> "${TEMPFILE}" done -# Now, we sort the thing. -sort "$OUTFILE" > "$TEMPFILE" +# Finally, sort the list and print it. +sort < "${TEMPFILE}" -# Add quotes and '\\$' before and after each macro. This just -# makes it easy to cut-and-pase into nagios-mode.el. -sed -e 's/^/\"\$/g' -e 's/$/\$\"/g' "$TEMPFILE" > "$OUTFILE" -rm "$TEMPFILE" +# ... and clean up +rm "${TEMPFILE}"