Re: [PATCH] sim: common: modernize gennltvals.sh

Andrew Burgess
2021-01-18T10:00:32Z

* Mike Frysinger via Gdb-patches <gdb-patches@sourceware.org> [2021-01-17 05:10:44 -0500]:

> It's not 1996 anymore, so stop writing shell code like it is, and
> rewrite it with modern POSIX shell standards. This makes it much
> more user friendly.
>
> Then regenerate the file with latest newlib sources to verify.
>
> * Makefile.in (headers): Change args to gennltvals.sh.
> * gennltvals.sh: Rewrite from scratch.
> * gentvals.sh: Delete.
> * nltvals.def: Regen.
> ---
> sim/common/Makefile.in | 2 +-
> sim/common/gennltvals.sh | 313 +++++++++++++++++++++++++++------------
> sim/common/gentvals.sh | 74 ---------
> sim/common/nltvals.def | 7 +
> 4 files changed, 229 insertions(+), 167 deletions(-)
> delete mode 100755 sim/common/gentvals.sh
>
> diff --git a/sim/common/Makefile.in b/sim/common/Makefile.in
> index 4191b107e2fa..827cf1ef34b2 100644
> --- a/sim/common/Makefile.in
> +++ b/sim/common/Makefile.in
> @@ -82,7 +82,7 @@ headers:
> rootme=`pwd` ; \
> cd $(srcdir) ; \
> rm -f nltvals.new ; \
> - $(SHELL) $(abs_srcdir)/gennltvals.sh $(SHELL) $(srcroot) "$(CPP_FOR_TARGET)" > nltvals.new ; \
> + $(SHELL) $(abs_srcdir)/gennltvals.sh --cpp "$(CPP_FOR_TARGET)" $(srcroot) --output nltvals.new ; \
> $(SHELL) $(srcroot)/move-if-change nltvals.new nltvals.def
>
> .c.o:
> diff --git a/sim/common/gennltvals.sh b/sim/common/gennltvals.sh
> index 79180335b627..ce52cb3c55ca 100755
> --- a/sim/common/gennltvals.sh
> +++ b/sim/common/gennltvals.sh
> @@ -1,33 +1,135 @@
> #! /bin/sh
> -# Generate nltvals.def, a file that describes various newlib/libgloss
> -# target values used by the host/target interface.
> +# Copyright (C) 1996-2021 Free Software Foundation, Inc.
> #
> -# Syntax: /bin/sh gennltvals.sh shell srcroot cpp
> -
> -shell=$1
> -srcroot=$2
> -cpp=$3
> -
> -srccom=$srcroot/sim/common
> -if [ -d "${srcroot}/newlib" ]; then
> - # If newlib is manually in the same source tree, use it.
> - newlibroot=${srcroot}
> -else
> - # Else assume it's alongside the gdb/binutils repo.
> - newlibroot=${srcroot}/../newlib
> -fi
> -
> -echo '/* Newlib/libgloss macro values needed by remote target support. */'
> -echo '/* This file is machine generated by gennltvals.sh. */'
> -
> -$shell ${srccom}/gentvals.sh "" errno ${newlibroot}/newlib/libc/include \
> - "errno.h sys/errno.h" 'E[[:upper:][:digit:]]*' "${cpp}"
> -
> -$shell ${srccom}/gentvals.sh "" signal ${newlibroot}/newlib/libc/include \
> - "signal.h sys/signal.h" 'SIG[[:upper:][:digit:]]*' "${cpp}"
> -
> -$shell ${srccom}/gentvals.sh "" open ${newlibroot}/newlib/libc/include \
> - "fcntl.h sys/fcntl.h sys/_default_fcntl.h" 'O_[[:upper:][:digit:]]*' "${cpp}"

Shouldn't there be a Copyright line here. The old one was 1996-2021,
I guess even though this is a significant rewrite, its probably close
enough that the old date range should still apply.

Otherwise, LGTM.

Thanks,
Andrew

> +# This file is part of the GNU simulators.
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +# Display the tool usage and exit.
> +usage() {
> + cat <<EOF
> +Usage: $0 [path to newlib source tree]
> +
> +Generate nltvals.def, a file that describes various newlib/libgloss target
> +values used by the host/target interface. This needs to be rerun whenever
> +the newlib source changes. Developers manually run it.
> +
> +If the path to newlib is not specified, it will be searched for in:
> +- the root of this source tree
> +- alongside this source tree
> +
> +Options:
> + -o, --output <file> Write to the specified file instead of stdout.
> + --cpp <cpp> The preprocessor to use.
> + -h, --help This text you're reading!
> +EOF
> + if [ $# -gt 0 ]; then
> + error "$*"
> + fi
> + exit 0
> +}
> +
> +# Show an error message and exit.
> +error() {
> + echo "$0: error: $*" >&2
> + exit 1
> +}
> +
> +ARG_CPP="cpp"
> +ARG_NEWLIB=""
> +ARG_OUTPUT=""
> +
> +# Emit the header for this generated def file.
> +gen_header() {
> + cat <<EOF
> +/* Newlib/libgloss macro values needed by remote target support. */
> +/* This file is machine generated by gennltvals.sh. */
> +EOF
> +}
> +
> +# Extract constants from the specified files using a regular expression and the
> +# preprocessor.
> +gentvals() {
> + target=$1
> + type=$2
> + dir=$3
> + # FIXME: Would be nice to process #include's in these files.
> + files=$4
> + pattern=$5
> +
> + # Require all files exist in order to regenerate properly.
> + for f in ${files}; do
> + if [ ! -f "${dir}/${f}" ]; then
> + error "file does not exist: ${dir}/${f}"
> + fi
> + done
> +
> + if [ -z "${target}" ]; then
> + echo "#ifdef ${type}_defs"
> + else
> + echo "#ifdef NL_TARGET_${target}"
> + echo "#ifdef ${type}_defs"
> + fi
> +
> + printf "/* from %s */\n" ${files}
> +
> + if [ -z "${target}" ]; then
> + echo "/* begin ${type} target macros */"
> + else
> + echo "/* begin ${target} ${type} target macros */"
> + fi
> +
> + # Extract all the symbols.
> + (
> + printf '#include <%s>\n' ${files}
> + for f in ${files}; do
> + sed -E -n -e "/^# *define[[:space:]]${pattern}/{\
> + s|# *define[[:space:]](${pattern})[[:space:]]*([^[:space:]][^[:space:]]*).*$|\1|; \
> + p}" \
> + "${dir}/${f}"
> + done |
> + sort -u |
> + while read sym; do
> + echo "#ifdef ${sym}"
> + echo "DEFVAL { \"${sym}\", ${sym} },"
> + echo "#endif"
> + done
> + ) |
> + ${ARG_CPP} -E -I"${dir}" |
> + sed -E -n -e '/^DEFVAL/{s/DEFVAL//; s/[[:space:]]+/ /; p}'
> +
> + if [ -z "${target}" ]; then
> + echo "/* end ${type} target macros */"
> + echo "#endif"
> + else
> + echo "/* end ${target} ${type} target macros */"
> + echo "#endif"
> + echo "#endif"
> + fi
> +}
> +
> +# Generate the common C library constants. No arch should override these.
> +gen_common() {
> + gentvals "" errno ${ARG_NEWLIB}/newlib/libc/include \
> + "errno.h sys/errno.h" 'E[[:upper:][:digit:]]*'
> +
> + gentvals "" signal ${ARG_NEWLIB}/newlib/libc/include \
> + "signal.h sys/signal.h" 'SIG[[:upper:][:digit:]]*'
> +
> + gentvals "" open ${ARG_NEWLIB}/newlib/libc/include \
> + "fcntl.h sys/fcntl.h sys/_default_fcntl.h" 'O_[[:upper:][:digit:]]*'
> +}
>
> # Unfortunately, each newlib/libgloss port has seen fit to define their own
> # syscall.h file. This means that system call numbers can vary for each port.
> @@ -35,67 +137,94 @@ $shell ${srccom}/gentvals.sh "" open ${newlibroot}/newlib/libc/include \
> # If you want to try to improve this, please do, but don't break anything.
> # Note that there is a standard syscall.h file (libgloss/syscall.h) now which
> # hopefully more targets can use.
> -
> -dir=libgloss target=bfin
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=newlib/libc/sys/d10v/sys target=d10v
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -# OBSOLETE dir=libgloss target=d30v
> -# OBSOLETE $shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> -# OBSOLETE "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss/cr16/sys target=cr16
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss target=fr30
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss target=frv
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss/i960 target=i960
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss target=m32r
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss/mcore target=mcore
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss target=mn10200
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss target=mn10300
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss target=msp430
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss target=sparc
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss/v850/sys target=v850
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss target=lm32
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> -
> -dir=libgloss target=pru
> -$shell ${srccom}/gentvals.sh $target sys ${newlibroot}/$dir \
> - "syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
> +#
> +# NB: New ports should use libgloss, not newlib.
> +gen_arch() {
> + target="$1"
> + dir="${2:-libgloss}"
> + gentvals "${target}" sys "${ARG_NEWLIB}/${dir}" "syscall.h" 'SYS_[_[:alnum:]]*'
> +}
> +
> +gen_arches() {
> + gen_arch bfin
> + gen_arch d10v newlib/libc/sys/d10v/sys
> + gen_arch cr16 libgloss/cr16/sys
> + gen_arch fr30
> + gen_arch frv
> + gen_arch i960 libgloss/i960
> + gen_arch m32r
> + gen_arch mcore libgloss/mcore
> + gen_arch mn10200
> + gen_arch mn10300
> + gen_arch msp430
> + gen_arch sparc
> + gen_arch v850 libgloss/v850/sys
> + gen_arch lm32
> + gen_arch pru
> +}
> +
> +# Process the script command line options.
> +parse_opts() {
> + for arg in "$@"; do
> + case ${arg} in
> + --cpp)
> + ARG_CPP="$2"
> + shift
> + ;;
> + -o|--output)
> + ARG_OUTPUT="$2"
> + shift
> + ;;
> + -h|--help)
> + usage
> + ;;
> + --)
> + shift
> + break
> + ;;
> + -*)
> + usage "unknown option: $1"
> + ;;
> + *)
> + break
> + ;;
> + esac
> + shift
> + done
> +
> + if [ $# -gt 2 ]; then
> + error "too many arguments: $*"
> + elif [ $# -eq 1 ]; then
> + ARG_NEWLIB="$1"
> + fi
> +
> + # Try to find newlib relative to our source tree.
> + if [ -z "${ARG_NEWLIB}" ]; then
> + srcroot="$(dirname "$0")/../.."
> + if [ -d "${srcroot}/newlib" ]; then
> + # If newlib is manually in the same source tree, use it.
> + ARG_NEWLIB="${srcroot}/newlib"
> + elif [ -d "${srcroot}/../newlib" ]; then
> + # Or see if it's alongside the gdb/binutils repo.
> + ARG_NEWLIB="${srcroot}/../newlib"
> + else
> + error "unable to find newlib"
> + fi
> + fi
> +}
> +
> +main() {
> + # The error checking isn't perfect, but should be good enough for this script.
> + set -e
> +
> + parse_opts "$@"
> +
> + if [ -n "${ARG_OUTPUT}" ]; then
> + exec >"${ARG_OUTPUT}" || exit 1
> + fi
> +
> + gen_header
> + gen_common
> + gen_arches
> +}
> +main "$@"
> diff --git a/sim/common/gentvals.sh b/sim/common/gentvals.sh
> deleted file mode 100755
> index 6dd7315f30aa..000000000000
> --- a/sim/common/gentvals.sh
> +++ /dev/null
> @@ -1,74 +0,0 @@
> -#!/bin/sh
> -# Usage: gentvals.sh target type dir files pattern cpp
> -
> -target=$1
> -type=$2
> -dir=$3
> -# FIXME: Would be nice to process #include's in these files.
> -files=$4
> -pattern=$5
> -cpp=$6
> -
> -# FIXME: need trap to remove tmp files.
> -
> -rm -f tmpvals.list tmpvals.uniq
> -for f in $files
> -do
> - if test -f $dir/$f ; then
> - grep "#define[ ]$pattern" $dir/$f | sed -e "s/^.*#define[ ]\($pattern\)[ ]*\([^ ][^ ]*\).*$/\1/" >> tmpvals.list
> - fi
> -done
> -
> -sort <tmpvals.list | uniq >tmpvals.uniq
> -
> -rm -f tmpvals.h
> -for f in $files
> -do
> - if test -f $dir/$f ; then
> - echo "#include <$f>" >>tmpvals.h
> - fi
> -done
> -
> -cat tmpvals.uniq |
> -while read sym
> -do
> - echo "#ifdef $sym" >>tmpvals.h
> - echo 'DEFVAL { "'$sym'", '$sym ' },' >>tmpvals.h
> - echo "#endif" >>tmpvals.h
> -done
> -
> -if test -z "$target"
> -then
> - echo "#ifdef ${type}_defs"
> -else
> - echo "#ifdef NL_TARGET_$target"
> - echo "#ifdef ${type}_defs"
> -fi
> -
> -for f in $files
> -do
> - if test -f $dir/$f ; then
> - echo "/* from $f */"
> - fi
> -done
> -
> -if test -z "$target"
> -then
> - echo "/* begin $type target macros */"
> -else
> - echo "/* begin $target $type target macros */"
> -fi
> -
> -$cpp -I$dir tmpvals.h | grep DEFVAL | sed -e 's/DEFVAL//' -e 's/ / /'
> -
> -if test -z "$target"
> -then
> - echo "/* end $type target macros */"
> - echo "#endif"
> -else
> - echo "/* end $target $type target macros */"
> - echo "#endif"
> - echo "#endif"
> -fi
> -
> -rm -f tmpvals.list tmpvals.uniq tmpvals.h
> diff --git a/sim/common/nltvals.def b/sim/common/nltvals.def
> index 92ccc9aded8b..08df7d5c4598 100644
> --- a/sim/common/nltvals.def
> +++ b/sim/common/nltvals.def
> @@ -115,6 +115,7 @@
> { "SIGPROF", 27 },
> { "SIGQUIT", 3 },
> { "SIGSEGV", 11 },
> + { "SIGSTKSZ", 8192 },
> { "SIGSTOP", 17 },
> { "SIGSYS", 12 },
> { "SIGTERM", 15 },
> @@ -138,12 +139,18 @@
> /* begin open target macros */
> { "O_ACCMODE", (0|1|2) },
> { "O_APPEND", 0x0008 },
> + { "O_CLOEXEC", 0x40000 },
> { "O_CREAT", 0x0200 },
> + { "O_DIRECT", 0x80000 },
> + { "O_DIRECTORY", 0x200000 },
> { "O_EXCL", 0x0800 },
> + { "O_EXEC", 0x400000 },
> { "O_NOCTTY", 0x8000 },
> + { "O_NOFOLLOW", 0x100000 },
> { "O_NONBLOCK", 0x4000 },
> { "O_RDONLY", 0 },
> { "O_RDWR", 2 },
> + { "O_SEARCH", 0x400000 },
> { "O_SYNC", 0x2000 },
> { "O_TRUNC", 0x0400 },
> { "O_WRONLY", 1 },
> --
> 2.28.0
>