summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--Makefile.am72
-rw-r--r--TODO4
-rwxr-xr-xautogen.sh8
-rw-r--r--configure.ac33
-rw-r--r--m4/.gitignore10
-rw-r--r--m4/ax_append_flag.m431
-rw-r--r--m4/ax_cflags_warn_all.m4180
-rw-r--r--m4/ax_check_compile_flag.m431
-rw-r--r--m4/ax_compiler_vendor.m4119
-rw-r--r--m4/ax_prepend_flag.m451
-rw-r--r--m4/gcc_version.m434
-rw-r--r--m4/gl_manywarnings.m4281
-rw-r--r--m4/gl_warnings.m4118
-rw-r--r--man/.gitignore1
-rw-r--r--man/atsign.1in41
-rw-r--r--man/local.mk43
-rw-r--r--po/.gitignore11
-rw-r--r--po/Makevars26
-rw-r--r--po/POTFILES.in2
-rwxr-xr-xscripts/update-m4.sh30
-rw-r--r--src/datetime.c130
-rw-r--r--src/datetime.h6
-rw-r--r--src/formats.h2
-rw-r--r--src/i18n.h11
-rw-r--r--src/local.mk3
-rw-r--r--src/main.c84
-rwxr-xr-xtests/formats.sh2
-rw-r--r--tests/local.mk1
-rwxr-xr-xtests/parse.sh34
30 files changed, 885 insertions, 519 deletions
diff --git a/.gitignore b/.gitignore
index cd341c2..3c7427f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,8 @@
*~
*.orig
-# Files generated by aclocal, autoconf, and automake
+# Files generated by gettextize, aclocal, autoconf, and automake
+/ABOUT-NLS
/aclocal.m4
/autom4te.cache/
/configure
@@ -28,7 +29,7 @@ Makefile
.dirstamp
*.o
/version.c
-/@
+/atsign
/test-suite.log
/atsign-*.tar*
/atsign-*/
diff --git a/Makefile.am b/Makefile.am
index 0048520..b53c109 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
# Process this file with automake to produce an input makefile.
#
-# Copyright (C) 2013, 2014, 2017, 2018, 2021 P. J. McDermott
+# Copyright (C) 2013, 2014, 2017, 2018, 2021, 2022 P. J. McDermott
#
# This file is part of @
#
@@ -40,33 +40,39 @@ endif
# * Our release target
PACKAGE_STRING = $(PACKAGE_NAME) $(PACKAGE_VERSION)$(PACKAGE_VERSION_GIT)
-bin_PROGRAMS = @
+# Automake lib/am/check.am since version 1.16.3 defines this with single quotes,
+# which breaks PACKAGE_VERSION_GIT above.
+AM_TESTSUITE_SUMMARY_HEADER = " for $(PACKAGE_STRING)"
-@_SOURCES =
-@_CFLAGS = \
+bin_PROGRAMS = atsign
+
+atsign_SOURCES =
+atsign_CFLAGS = \
$(WARN_CFLAGS) \
$(ASAN_CFLAGS)
-@_CPPFLAGS = \
+atsign_CPPFLAGS = \
$(SDL_CFLAGS) \
$(SDL_TTF_CFLAGS) \
-DABS_BUILDDIR=\"$(abs_builddir)\" \
- -DFONTSDIR=\"$(fontsdir)\"
-@_LDADD = \
+ -DLOCALEDIR=\"$(localedir)\"
+atsign_LDADD = \
$(ASAN_CFLAGS) \
$(SDL_LIBS) \
$(SDL_TTF_LIBS)
-@_LINK = $(LINK) version.c
-EXTRA_@_DEPENDENCIES = version.c
+atsign_LINK = $(LINK) version.c
+EXTRA_atsign_DEPENDENCIES = version.c
CLEANFILES = version.c
CONFIG_CLEAN_FILES =
-EXTRA_DIST = autogen.sh FORMATS
+EXTRA_DIST = build-aux/config.rpath autogen.sh
V_REDIR = $(V_REDIR_$(V))
V_REDIR_ = $(V_REDIR_$(AM_DEFAULT_VERBOSITY))
V_REDIR_0 = 1>/dev/null 2>&1
V_REDIR_1 =
-version.c: $(@_OBJECTS) $(@_DEPENDENCIES)
+SUFFIXES =
+
+version.c: $(atsign_OBJECTS) $(atsign_DEPENDENCIES)
$(AM_V_GEN)printf 'const char *PACKAGE_VERSION_GIT = "%s";\n' \
"$(PACKAGE_VERSION_GIT)" >version.c
@@ -77,7 +83,37 @@ really-clean: distclean
$(srcdir)/build-aux/ $(srcdir)/INSTALL $(srcdir)/Makefile.in \
$(srcdir)/ChangeLog
+if ENABLE_SYMLINK
+install-exec-hook:
+ @set -e; \
+ dir="$(DESTDIR)$(bindir)"; \
+ dst="$$(printf 'atsign' | \
+ sed '$(transform); s/$$/$(EXEEXT)/')"; \
+ src='@$(EXEEXT)'; \
+ echo " (cd '$${dir}' && $(LN_S) '$${dst}' '$${src}')"; \
+ (cd "$${dir}" && $(LN_S) "$${dst}" "$${src}")
+install-data-hook:
+ @set -e; \
+ dir="$(DESTDIR)$(man1dir)"; \
+ dst="$$(printf 'atsign' | \
+ sed '$(transform); s/$$/$(EXEEXT)/').1"; \
+ src='@$(EXEEXT).1'; \
+ echo " (cd '$${dir}' && $(LN_S) '$${dst}' '$${src}')"; \
+ (cd "$${dir}" && $(LN_S) "$${dst}" "$${src}")
+uninstall-hook:
+ echo " rm -f '$(DESTDIR)$(bindir)/@$(EXEEXT)'"
+ rm -f "$(DESTDIR)$(bindir)/@$(EXEEXT)"
+endif
+
+if ENABLE_TESTS
+if CROSS_COMPILING
dist-hook:
+else !CROSS_COMPILING
+dist-hook: atsign$(EXEEXT)
+endif !CROSS_COMPILING
+else !ENABLE_TESTS
+dist-hook:
+endif !ENABLE_TESTS
if IN_GIT
printf 'Generated file. Do not edit.\n\n' 1>'$(distdir)/ChangeLog~'
GIT_DIR='$(srcdir)/.git' git log --stat --color=never \
@@ -86,16 +122,21 @@ if IN_GIT
endif
if ENABLE_TESTS
if CROSS_COMPILING
- if ! [ -f 'FORMATS' ]; then \
+ if [ -f 'FORMATS' ]; then \
+ cp -p 'FORMATS' '$(distdir)/FORMATS'; \
+ else \
printf 'Error: "FORMATS" file cannot be generated when %s' \
'cross compiling' 1>&2; \
exit 1; \
fi
else !CROSS_COMPILING
- $(srcdir)/@ -d '1969-12-31 19:00:01' -F 1>FORMATS
+ $(builddir)/atsign$(EXEEXT) -d '1969-12-31 19:00:01' -F \
+ 1>'$(distdir)/FORMATS'
endif !CROSS_COMPILING
else !ENABLE_TESTS
- if ! [ -f 'FORMATS' ]; then \
+ if [ -f 'FORMATS' ]; then \
+ cp -p 'FORMATS' '$(distdir)/FORMATS'; \
+ else \
printf 'Error: "FORMATS" file cannot be generated without %s' \
'test suite support' 1>&2; \
exit 1; \
@@ -127,4 +168,7 @@ release:
files@files.pehjota.net:files/pub/$(PACKAGE)/$(VERSION)/
include $(top_srcdir)/src/local.mk
+include $(top_srcdir)/man/local.mk
include $(top_srcdir)/tests/local.mk
+
+SUBDIRS = . po
diff --git a/TODO b/TODO
index b8f4d77..6396ebe 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,4 @@
+try to fix dst bug
test with other libc's (newlib? musl? fbsd? obsd?)
`./@ 7:00 PM` doesn't work with musl strptime()
test other times
-update copyright years
-distcheck
-gettext?
diff --git a/autogen.sh b/autogen.sh
index c80fde1..d11efe6 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -2,7 +2,7 @@
#
# Script to generate the build system.
#
-# Copyright (C) 2013 P. J. McDermott
+# Copyright (C) 2013, 2019 P. J. McDermott
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
@@ -19,6 +19,12 @@ srcdir="${0%/*}"
cat >ChangeLog <<-EOF
This file is generated upon release. Run \`git log\` for a list of changes.
EOF
+ # Force gettextize to be non-interactive. Stupid but necessary.
+ LC_ALL=C expect -f - <<-EOF
+ spawn gettextize --force --no-changelog
+ expect "Press Return to acknowledge the previous * paragraphs."
+ send "\n"
+ EOF
aclocal
autoconf
autoheader
diff --git a/configure.ac b/configure.ac
index cb1f0ce..5b527de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
# Process this file with autoconf to produce a configure script.
#
-# Copyright (C) 2013, 2017, 2019, 2021 P. J. McDermott
+# Copyright (C) 2013, 2017, 2019, 2021, 2022 P. J. McDermott
#
# This file is part of @
#
@@ -32,6 +32,12 @@ AM_CONDITIONAL([OUT_OF_TREE], [test x"${srcdir}" != x'.' ])
AM_CONDITIONAL([CROSS_COMPILING], [! test x"${build_alias}" = x"${host_alias}"])
+GETTEXT_PACKAGE="${PACKAGE}"
+AC_SUBST([GETTEXT_PACKAGE])
+AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["${GETTEXT_PACKAGE}"],
+ [Define the gettext package to be used.])
+AM_GNU_GETTEXT([external])
+
save_CFLAGS="${CFLAGS-}"
AC_PROG_CC()
AM_PROG_CC_C_O()
@@ -42,7 +48,7 @@ AC_CHECK_FUNCS(
[\
calloc difftime fprintf fputs free isspace localtime mktime \
printf realloc setvbuf sleep strerror strlen strftime strptime \
- time timegm
+ time
],
[],
[funcs_missing=true])
@@ -56,17 +62,26 @@ if ${funcs_missing}; then
AC_MSG_ERROR([required functions are missing])
fi
+AC_PROG_LN_S()
+AC_ARG_ENABLE([symlink],
+ [AS_HELP_STRING([--disable-symlink],
+ [don't install \`@' symbolic link])],
+ [case "${enableval}" in yes|no) symlink=${enableval};;
+ *) AC_MSG_ERROR(
+ [bad value ${enableval} for symlink option]);;
+ esac],
+ [symlink=yes]
+)
+AM_CONDITIONAL([ENABLE_SYMLINK], [test x"${symlink}" = x'yes'])
+
AC_ARG_ENABLE([tests],
- [AS_HELP_STRING([--enable-tests],
- [include test suite support in executable])],
+ [AS_HELP_STRING([--disable-tests],
+ [exclude test suite support from executable])],
[case "${enableval}" in yes|no) tests=${enableval};;
*) AC_MSG_ERROR(
[bad value ${enableval} for tests option]);;
esac],
- [
- tests=no
- test -d "${srcdir}/.git" && tests=yes
- ]
+ [tests=yes]
)
if test x"${tests}" = x'yes'; then
AC_DEFINE([ENABLE_TESTS], [1],
@@ -142,6 +157,6 @@ for flag in -Os -fno-unwind-tables -fno-asynchronous-unwind-tables \
AX_CHECK_COMPILE_FLAG([${flag}], [AX_APPEND_FLAG([${flag}])])
done
-AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([Makefile po/Makefile.in])
AC_CONFIG_HEADERS([config.h])
AC_OUTPUT()
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644
index 0000000..a9c97ca
--- /dev/null
+++ b/m4/.gitignore
@@ -0,0 +1,10 @@
+/*.m4
+!/ax_append_flag.m4
+!/ax_cflags_warn_all.m4
+!/ax_check_compile_flag.m4
+!/ax_compiler_vendor.m4
+!/ax_prepend_flag.m4
+!/ax_require_defined.m4
+!/gcc_version.m4
+!/gl_manywarnings.m4
+!/gl_warnings.m4
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
index e8c5312..dd6d8b6 100644
--- a/m4/ax_append_flag.m4
+++ b/m4/ax_append_flag.m4
@@ -23,33 +23,12 @@
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
-# 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 <https://www.gnu.org/licenses/>.
-#
-# As a special exception, the respective Autoconf Macro's copyright owner
-# gives unlimited permission to copy, distribute and modify the configure
-# scripts that are the output of Autoconf when processing the Macro. You
-# need not follow the terms of the GNU General Public License when using
-# or distributing such scripts, even though portions of the text of the
-# Macro appear in them. The GNU General Public License (GPL) does govern
-# all other use of the material that constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the Autoconf
-# Macro released by the Autoconf Archive. When you make and distribute a
-# modified version of the Autoconf Macro, you may extend this special
-# exception to the GPL to apply to your modified version as well.
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
-#serial 7
+#serial 8
AC_DEFUN([AX_APPEND_FLAG],
[dnl
diff --git a/m4/ax_cflags_warn_all.m4 b/m4/ax_cflags_warn_all.m4
index 094577e..9235a18 100644
--- a/m4/ax_cflags_warn_all.m4
+++ b/m4/ax_cflags_warn_all.m4
@@ -4,33 +4,54 @@
#
# SYNOPSIS
#
-# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
-# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
-# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+# AX_CFLAGS_WARN_ALL [(shellvar[, default[, action-if-found[, action-if-not-found]]])]
+# AX_CXXFLAGS_WARN_ALL [(shellvar[, default[, action-if-found[, action-if-not-found]]])]
+# AX_FCFLAGS_WARN_ALL [(shellvar[, default[, action-if-found[, action-if-not-found]]])]
#
# DESCRIPTION
#
-# Try to find a compiler option that enables most reasonable warnings.
+# Specify compiler options that enable most reasonable warnings. For the
+# GNU Compiler Collection (GCC), for example, it will be "-Wall". The
+# result is added to shellvar, one of CFLAGS, CXXFLAGS or FCFLAGS if the
+# first parameter is not specified.
#
-# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
-# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
+# Each of these macros accepts the following optional arguments:
#
-# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
-# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
-# Intel compilers. For a given compiler, the Fortran flags are much more
-# experimental than their C equivalents.
+# - $1 - shellvar
+# shell variable to use (CFLAGS, CXXFLAGS or FCFLAGS if not
+# specified, depending on macro)
#
-# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
-# - $2 add-value-if-not-found : nothing
-# - $3 action-if-found : add value to shellvariable
-# - $4 action-if-not-found : nothing
+# - $2 - default
+# value to use for flags if compiler vendor cannot be determined (by
+# default, "")
#
-# NOTE: These macros depend on AX_APPEND_FLAG.
+# - $3 - action-if-found
+# action to take if the compiler vendor has been successfully
+# determined (by default, add the appropriate compiler flags to
+# shellvar)
+#
+# - $4 - action-if-not-found
+# action to take if the compiler vendor has not been determined or
+# is unknown (by default, add the default flags, or "" if not
+# specified, to shellvar)
+#
+# These macros use AX_COMPILER_VENDOR to determine which flags should be
+# returned for a given compiler. Not all compilers currently have flags
+# defined for them; patches are welcome. If need be, compiler flags may
+# be made language-dependent: use a construct like the following:
+#
+# [vendor_name], [m4_if(_AC_LANG_PREFIX,[C], VAR="--relevant-c-flags",dnl
+# m4_if(_AC_LANG_PREFIX,[CXX], VAR="--relevant-c++-flags",dnl
+# m4_if(_AC_LANG_PREFIX,[FC], VAR="--relevant-fortran-flags",dnl
+# VAR="$2"; FOUND="no")))],
+#
+# Note: These macros also depend on AX_PREPEND_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com>
+# Copyright (c) 2018 John Zaitseff <J.Zaitseff@zap.org.au>
#
# 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
@@ -58,65 +79,80 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
-#serial 16
+#serial 25
+
+AC_DEFUN([AX_FLAGS_WARN_ALL], [
+ AX_REQUIRE_DEFINED([AX_PREPEND_FLAG])dnl
+ AC_REQUIRE([AX_COMPILER_VENDOR])dnl
+
+ AS_VAR_PUSHDEF([FLAGS], [m4_default($1,_AC_LANG_PREFIX[]FLAGS)])dnl
+ AS_VAR_PUSHDEF([VAR], [ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
+ AS_VAR_PUSHDEF([FOUND], [ac_save_[]_AC_LANG_ABBREV[]flags_warn_all_found])dnl
+
+ AC_CACHE_CHECK([FLAGS for most reasonable warnings], VAR, [
+ VAR=""
+ FOUND="yes"
+ dnl Cases are listed in the order found in ax_compiler_vendor.m4
+ AS_CASE("$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor",
+ [intel], [VAR="-w2"],
+ [ibm], [VAR="-qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd"],
+ [pathscale], [],
+ [clang], [VAR="-Wall"],
+ [cray], [VAR="-h msglevel 2"],
+ [fujitsu], [],
+ [sdcc], [],
+ [sx], [VAR="-pvctl[,]fullmsg"],
+ [portland], [],
+ [gnu], [VAR="-Wall"],
+ [sun], [VAR="-v"],
+ [hp], [VAR="+w1"],
+ [dec], [VAR="-verbose -w0 -warnprotos"],
+ [borland], [],
+ [comeau], [],
+ [kai], [],
+ [lcc], [],
+ [sgi], [VAR="-fullwarn"],
+ [microsoft], [],
+ [metrowerks], [],
+ [watcom], [],
+ [tcc], [],
+ [unknown], [
+ VAR="$2"
+ FOUND="no"
+ ],
+ [
+ AC_MSG_WARN([Unknown compiler vendor returned by [AX_COMPILER_VENDOR]])
+ VAR="$2"
+ FOUND="no"
+ ]
+ )
+
+ AS_IF([test "x$FOUND" = "xyes"], [dnl
+ m4_default($3, [AS_IF([test "x$VAR" != "x"], [AX_PREPEND_FLAG([$VAR], [FLAGS])])])
+ ], [dnl
+ m4_default($4, [m4_ifval($2, [AX_PREPEND_FLAG([$VAR], [FLAGS])], [true])])
+ ])dnl
+ ])dnl
-AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
-AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
-AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
-AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
-VAR,[VAR="no, unknown"
-ac_save_[]FLAGS="$[]FLAGS"
-for ac_arg dnl
-in "-warn all % -warn all" dnl Intel
- "-pedantic % -Wall" dnl GCC
- "-xstrconst % -v" dnl Solaris C
- "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
- "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
- "-ansi -ansiE % -fullwarn" dnl IRIX
- "+ESlit % +w1" dnl HP-UX C
- "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
- "-h conform % -h msglevel 2" dnl Cray C (Unicos)
- #
-do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
- [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
-done
-FLAGS="$ac_save_[]FLAGS"
-])
-AS_VAR_POPDEF([FLAGS])dnl
-AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
-case ".$VAR" in
- .ok|.ok,*) m4_ifvaln($3,$3) ;;
- .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
- *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
-esac
-AS_VAR_POPDEF([VAR])dnl
+ AS_VAR_POPDEF([FOUND])dnl
+ AS_VAR_POPDEF([VAR])dnl
+ AS_VAR_POPDEF([FLAGS])dnl
])dnl AX_FLAGS_WARN_ALL
-dnl implementation tactics:
-dnl the for-argument contains a list of options. The first part of
-dnl these does only exist to detect the compiler - usually it is
-dnl a global option to enable -ansi or -extrawarnings. All other
-dnl compilers will fail about it. That was needed since a lot of
-dnl compilers will give false positives for some option-syntax
-dnl like -Woption or -Xoption as they think of it is a pass-through
-dnl to later compile stages or something. The "%" is used as a
-dnl delimiter. A non-option comment can be given after "%%" marks
-dnl which will be shown but not added to the respective C/CXXFLAGS.
-AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
-AC_LANG_PUSH([C])
-AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
-AC_LANG_POP([C])
-])
+AC_DEFUN([AX_CFLAGS_WARN_ALL], [dnl
+ AC_LANG_PUSH([C])
+ AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+ AC_LANG_POP([C])
+])dnl
-AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
-AC_LANG_PUSH([C++])
-AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
-AC_LANG_POP([C++])
-])
+AC_DEFUN([AX_CXXFLAGS_WARN_ALL], [dnl
+ AC_LANG_PUSH([C++])
+ AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+ AC_LANG_POP([C++])
+])dnl
-AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
-AC_LANG_PUSH([Fortran])
-AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
-AC_LANG_POP([Fortran])
-])
+AC_DEFUN([AX_FCFLAGS_WARN_ALL], [dnl
+ AC_LANG_PUSH([Fortran])
+ AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+ AC_LANG_POP([Fortran])
+])dnl
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
index dcabb92..bd753b3 100644
--- a/m4/ax_check_compile_flag.m4
+++ b/m4/ax_check_compile_flag.m4
@@ -29,33 +29,12 @@
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
-# 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 <https://www.gnu.org/licenses/>.
-#
-# As a special exception, the respective Autoconf Macro's copyright owner
-# gives unlimited permission to copy, distribute and modify the configure
-# scripts that are the output of Autoconf when processing the Macro. You
-# need not follow the terms of the GNU General Public License when using
-# or distributing such scripts, even though portions of the text of the
-# Macro appear in them. The GNU General Public License (GPL) does govern
-# all other use of the material that constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the Autoconf
-# Macro released by the Autoconf Archive. When you make and distribute a
-# modified version of the Autoconf Macro, you may extend this special
-# exception to the GPL to apply to your modified version as well.
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
-#serial 5
+#serial 6
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
diff --git a/m4/ax_compiler_vendor.m4 b/m4/ax_compiler_vendor.m4
new file mode 100644
index 0000000..039f99d
--- /dev/null
+++ b/m4/ax_compiler_vendor.m4
@@ -0,0 +1,119 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_COMPILER_VENDOR
+#
+# DESCRIPTION
+#
+# Determine the vendor of the C, C++ or Fortran compiler. The vendor is
+# returned in the cache variable $ax_cv_c_compiler_vendor for C,
+# $ax_cv_cxx_compiler_vendor for C++ or $ax_cv_fc_compiler_vendor for
+# (modern) Fortran. The value is one of "intel", "ibm", "pathscale",
+# "clang" (LLVM), "cray", "fujitsu", "sdcc", "sx", "nvhpc" (NVIDIA HPC
+# Compiler), "portland" (PGI), "gnu" (GCC), "sun" (Oracle Developer
+# Studio), "hp", "dec", "borland", "comeau", "kai", "lcc", "sgi",
+# "microsoft", "metrowerks", "watcom", "tcc" (Tiny CC) or "unknown" (if
+# the compiler cannot be determined).
+#
+# To check for a Fortran compiler, you must first call AC_FC_PP_SRCEXT
+# with an appropriate preprocessor-enabled extension. For example:
+#
+# AC_LANG_PUSH([Fortran])
+# AC_PROG_FC
+# AC_FC_PP_SRCEXT([F])
+# AX_COMPILER_VENDOR
+# AC_LANG_POP([Fortran])
+#
+# LICENSE
+#
+# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+# Copyright (c) 2008 Matteo Frigo
+# Copyright (c) 2018-19 John Zaitseff <J.Zaitseff@zap.org.au>
+#
+# 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 <https://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 32
+
+AC_DEFUN([AX_COMPILER_VENDOR], [dnl
+ AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, [dnl
+ dnl If you modify this list of vendors, please add similar support
+ dnl to ax_compiler_version.m4 if at all possible.
+ dnl
+ dnl Note: Do NOT check for GCC first since some other compilers
+ dnl define __GNUC__ to remain compatible with it. Compilers that
+ dnl are very slow to start (such as Intel) are listed first.
+
+ vendors="
+ intel: __ICC,__ECC,__INTEL_COMPILER
+ ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__,__ibmxl__
+ pathscale: __PATHCC__,__PATHSCALE__
+ clang: __clang__
+ cray: _CRAYC
+ fujitsu: __FUJITSU
+ sdcc: SDCC,__SDCC
+ sx: _SX
+ nvhpc: __NVCOMPILER
+ portland: __PGI
+ gnu: __GNUC__
+ sun: __SUNPRO_C,__SUNPRO_CC,__SUNPRO_F90,__SUNPRO_F95
+ hp: __HP_cc,__HP_aCC
+ dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER
+ borland: __BORLANDC__,__CODEGEARC__,__TURBOC__
+ comeau: __COMO__
+ kai: __KCC
+ lcc: __LCC__
+ sgi: __sgi,sgi
+ microsoft: _MSC_VER
+ metrowerks: __MWERKS__
+ watcom: __WATCOMC__
+ tcc: __TINYC__
+ unknown: UNKNOWN
+ "
+ for ventest in $vendors; do
+ case $ventest in
+ *:)
+ vendor=$ventest
+ continue
+ ;;
+ *)
+ vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")"
+ ;;
+ esac
+
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[
+#if !($vencpp)
+ thisisanerror;
+#endif
+ ]])], [break])
+ done
+
+ ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1`
+ ])
+])dnl
diff --git a/m4/ax_prepend_flag.m4 b/m4/ax_prepend_flag.m4
new file mode 100644
index 0000000..adac8c5
--- /dev/null
+++ b/m4/ax_prepend_flag.m4
@@ -0,0 +1,51 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_prepend_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PREPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+# FLAG is added to the front of the FLAGS-VARIABLE shell variable, with a
+# space added in between.
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
+# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+# FLAG.
+#
+# NOTE: Implementation based on AX_APPEND_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+# Copyright (c) 2018 John Zaitseff <J.Zaitseff@zap.org.au>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 2
+
+AC_DEFUN([AX_PREPEND_FLAG],
+[dnl
+AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
+AS_VAR_SET_IF(FLAGS,[
+ AS_CASE([" AS_VAR_GET(FLAGS) "],
+ [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
+ [
+ FLAGS="$1 $FLAGS"
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+ ],
+ [
+ AS_VAR_SET(FLAGS,[$1])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_PREPEND_FLAG
diff --git a/m4/gcc_version.m4 b/m4/gcc_version.m4
index 9e16450..703973c 100644
--- a/m4/gcc_version.m4
+++ b/m4/gcc_version.m4
@@ -1,22 +1,18 @@
-dnl Copied from GNU Coreutils configure.ac
-dnl
-dnl The 17 lines are probably too trivial to be copyrightable, but just in case:
-dnl
-dnl Copyright (C) 1991-2017 Free Software Foundation, Inc.
-dnl
-dnl This program is free software: you can redistribute it and/or modify
-dnl it under the terms of the GNU General Public License as published by
-dnl the Free Software Foundation, either version 3 of the License, or
-dnl (at your option) any later version.
-dnl
-dnl This program is distributed in the hope that it will be useful,
-dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-dnl GNU General Public License for more details.
-dnl
-dnl You should have received a copy of the GNU General Public License
-dnl along with this program. If not, see <https://www.gnu.org/licenses/>.
-dnl
+# Copyright (C) 1991-2023 Free Software Foundation, Inc.
+
+# 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 <https://www.gnu.org/licenses/>.
+
dnl Written by Jim Meyering.
# gl_GCC_VERSION_IFELSE([major], [minor], [run-if-found], [run-if-not-found])
diff --git a/m4/gl_manywarnings.m4 b/m4/gl_manywarnings.m4
index d10bcd0..a06f26f 100644
--- a/m4/gl_manywarnings.m4
+++ b/m4/gl_manywarnings.m4
@@ -1,11 +1,13 @@
-# manywarnings.m4 serial 13
-dnl Copyright (C) 2008-2017 Free Software Foundation, Inc.
+# manywarnings.m4 serial 24
+dnl Copyright (C) 2008-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Simon Josefsson
+AC_PREREQ([2.64])
+
# gl_MANYWARN_COMPLEMENT(OUTVAR, LISTVAR, REMOVEVAR)
# --------------------------------------------------
# Copy LISTVAR to OUTVAR except for the entries in REMOVEVAR.
@@ -21,7 +23,7 @@ AC_DEFUN([gl_MANYWARN_COMPLEMENT],
*" $gl_warn_item "*)
;;
*)
- gl_warn_set="$gl_warn_set $gl_warn_item"
+ AS_VAR_APPEND([gl_warn_set], [" $gl_warn_item"])
;;
esac
done
@@ -39,291 +41,166 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC],
[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)])
# Specialization for _AC_LANG = C.
-# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
-m4_defun([gl_MANYWARN_ALL_GCC(C)],
+AC_DEFUN([gl_MANYWARN_ALL_GCC(C)],
[
AC_LANG_PUSH([C])
dnl First, check for some issues that only occur when combining multiple
dnl gcc warning categories.
AC_REQUIRE([AC_PROG_CC])
- if test -n "$GCC"; then
-
- dnl Check if -W -Werror -Wno-missing-field-initializers is supported
- dnl with the current $CC $CFLAGS $CPPFLAGS.
- AC_MSG_CHECKING([whether -Wno-missing-field-initializers is supported])
- AC_CACHE_VAL([gl_cv_cc_nomfi_supported], [
- gl_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -W -Werror -Wno-missing-field-initializers"
- AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM([[]], [[]])],
- [gl_cv_cc_nomfi_supported=yes],
- [gl_cv_cc_nomfi_supported=no])
- CFLAGS="$gl_save_CFLAGS"])
- AC_MSG_RESULT([$gl_cv_cc_nomfi_supported])
-
- if test "$gl_cv_cc_nomfi_supported" = yes; then
- dnl Now check whether -Wno-missing-field-initializers is needed
- dnl for the { 0, } construct.
- AC_MSG_CHECKING([whether -Wno-missing-field-initializers is needed])
- AC_CACHE_VAL([gl_cv_cc_nomfi_needed], [
- gl_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -W -Werror"
- AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM(
- [[int f (void)
- {
- typedef struct { int a; int b; } s_t;
- s_t s1 = { 0, };
- return s1.b;
- }
- ]],
- [[]])],
- [gl_cv_cc_nomfi_needed=no],
- [gl_cv_cc_nomfi_needed=yes])
- CFLAGS="$gl_save_CFLAGS"
- ])
- AC_MSG_RESULT([$gl_cv_cc_nomfi_needed])
- fi
+ AS_IF([test -n "$GCC"], [
+ AC_CACHE_CHECK([whether -Wno-missing-field-initializers is needed],
+ [gl_cv_cc_nomfi_needed],
+ [gl_cv_cc_nomfi_needed=no
+ gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wextra -Werror"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[struct file_data { int desc, name; };
+ struct cmp { struct file_data file[1]; };
+ void f (struct cmp *r)
+ {
+ typedef struct { int a; int b; } s_t;
+ s_t s1 = { 0, };
+ struct cmp cmp = { .file[0].desc = r->file[0].desc + s1.a };
+ *r = cmp;
+ }
+ ]],
+ [[]])],
+ [],
+ [CFLAGS="$CFLAGS -Wno-missing-field-initializers"
+ AC_COMPILE_IFELSE([],
+ [gl_cv_cc_nomfi_needed=yes])])
+ CFLAGS="$gl_save_CFLAGS"
+ ])
dnl Next, check if -Werror -Wuninitialized is useful with the
dnl user's choice of $CFLAGS; some versions of gcc warn that it
dnl has no effect if -O is not also used
- AC_MSG_CHECKING([whether -Wuninitialized is supported])
- AC_CACHE_VAL([gl_cv_cc_uninitialized_supported], [
- gl_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -Werror -Wuninitialized"
- AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM([[]], [[]])],
- [gl_cv_cc_uninitialized_supported=yes],
- [gl_cv_cc_uninitialized_supported=no])
- CFLAGS="$gl_save_CFLAGS"])
- AC_MSG_RESULT([$gl_cv_cc_uninitialized_supported])
-
- fi
+ AC_CACHE_CHECK([whether -Wuninitialized is supported],
+ [gl_cv_cc_uninitialized_supported],
+ [gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror -Wuninitialized"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
+ [gl_cv_cc_uninitialized_supported=yes],
+ [gl_cv_cc_uninitialized_supported=no])
+ CFLAGS="$gl_save_CFLAGS"
+ ])
+ ])
# List all gcc warning categories.
# To compare this list to your installed GCC's, run this Bash command:
#
# comm -3 \
- # <(sed -n 's/^ *\(-[^ ]*\) .*/\1/p' manywarnings.m4 | sort) \
- # <(gcc --help=warnings | sed -n 's/^ \(-[^ ]*\) .*/\1/p' | sort |
- # grep -v -x -F -f <(
- # awk '/^[^#]/ {print $1}' ../build-aux/gcc-warning.spec))
+ # <((sed -n 's/^ *\(-[^ 0-9][^ ]*\).*/\1/p' manywarnings.m4; \
+ # awk '/^[^#]/ {print $1}' ../build-aux/gcc-warning.spec) | sort) \
+ # <(LC_ALL=C gcc --help=warnings | sed -n 's/^ \(-[^ ]*\) .*/\1/p' | sort)
- gl_manywarn_set=
- for gl_manywarn_item in -fno-common \
- -W \
- -Wabi \
- -Waddress \
- -Waggressive-loop-optimizations \
+ $1=
+ for gl_manywarn_item in -fanalyzer -fstrict-flex-arrays \
-Wall \
- -Wattributes \
+ -Warith-conversion \
-Wbad-function-cast \
- -Wbool-compare \
- -Wbool-operation \
- -Wbuiltin-declaration-mismatch \
- -Wbuiltin-macro-redefined \
- -Wcast-align \
- -Wchar-subscripts \
- -Wchkp \
- -Wclobbered \
- -Wcomment \
- -Wcomments \
- -Wcoverage-mismatch \
- -Wcpp \
- -Wdangling-else \
+ -Wcast-align=strict \
-Wdate-time \
- -Wdeprecated \
- -Wdeprecated-declarations \
- -Wdesignated-init \
-Wdisabled-optimization \
- -Wdiscarded-array-qualifiers \
- -Wdiscarded-qualifiers \
- -Wdiv-by-zero \
-Wdouble-promotion \
-Wduplicated-branches \
-Wduplicated-cond \
- -Wduplicate-decl-specifier \
- -Wempty-body \
- -Wendif-labels \
- -Wenum-compare \
- -Wexpansion-to-defined \
-Wextra \
- -Wformat-contains-nul \
- -Wformat-extra-args \
- -Wformat-nonliteral \
- -Wformat-security \
-Wformat-signedness \
- -Wformat-y2k \
- -Wformat-zero-length \
- -Wframe-address \
- -Wfree-nonheap-object \
- -Whsa \
- -Wignored-attributes \
- -Wignored-qualifiers \
- -Wimplicit \
- -Wimplicit-function-declaration \
- -Wimplicit-int \
- -Wincompatible-pointer-types \
-Winit-self \
-Winline \
- -Wint-conversion \
- -Wint-in-bool-context \
- -Wint-to-pointer-cast \
- -Winvalid-memory-model \
-Winvalid-pch \
- -Wjump-misses-init \
- -Wlogical-not-parentheses \
-Wlogical-op \
- -Wmain \
- -Wmaybe-uninitialized \
- -Wmemset-elt-size \
- -Wmemset-transposed-args \
- -Wmisleading-indentation \
- -Wmissing-braces \
-Wmissing-declarations \
- -Wmissing-field-initializers \
-Wmissing-include-dirs \
- -Wmissing-parameter-type \
-Wmissing-prototypes \
- -Wmultichar \
- -Wnarrowing \
-Wnested-externs \
- -Wnonnull \
- -Wnonnull-compare \
-Wnull-dereference \
- -Wodr \
- -Wold-style-declaration \
-Wold-style-definition \
-Wopenmp-simd \
- -Woverflow \
-Woverlength-strings \
- -Woverride-init \
-Wpacked \
- -Wpacked-bitfield-compat \
- -Wparentheses \
-Wpointer-arith \
- -Wpointer-compare \
- -Wpointer-sign \
- -Wpointer-to-int-cast \
- -Wpragmas \
- -Wpsabi \
- -Wrestrict \
- -Wreturn-local-addr \
- -Wreturn-type \
- -Wscalar-storage-order \
- -Wsequence-point \
-Wshadow \
- -Wshift-count-negative \
- -Wshift-count-overflow \
- -Wshift-negative-value \
- -Wsizeof-array-argument \
- -Wsizeof-pointer-memaccess \
-Wstack-protector \
- -Wstrict-aliasing \
+ -Wstrict-flex-arrays \
-Wstrict-overflow \
-Wstrict-prototypes \
+ -Wsuggest-attribute=cold \
-Wsuggest-attribute=const \
-Wsuggest-attribute=format \
+ -Wsuggest-attribute=malloc \
-Wsuggest-attribute=noreturn \
-Wsuggest-attribute=pure \
-Wsuggest-final-methods \
-Wsuggest-final-types \
- -Wswitch \
- -Wswitch-bool \
- -Wswitch-default \
- -Wswitch-unreachable \
-Wsync-nand \
-Wsystem-headers \
- -Wtautological-compare \
-Wtrampolines \
- -Wtrigraphs \
- -Wtype-limits \
-Wuninitialized \
-Wunknown-pragmas \
-Wunsafe-loop-optimizations \
- -Wunused \
- -Wunused-but-set-parameter \
- -Wunused-but-set-variable \
- -Wunused-function \
- -Wunused-label \
- -Wunused-local-typedefs \
-Wunused-macros \
- -Wunused-parameter \
- -Wunused-result \
- -Wunused-value \
- -Wunused-variable \
- -Wvarargs \
-Wvariadic-macros \
-Wvector-operation-performance \
-Wvla \
- -Wvolatile-register-var \
-Wwrite-strings \
\
; do
- gl_manywarn_set="$gl_manywarn_set $gl_manywarn_item"
+ AS_VAR_APPEND([$1], [" $gl_manywarn_item"])
done
# gcc --help=warnings outputs an unusual form for these options; list
# them here so that the above 'comm' command doesn't report a false match.
- # Would prefer "min (PTRDIFF_MAX, SIZE_MAX)", but it must be a literal.
- # Also, AC_COMPUTE_INT requires it to fit in a long; it is 2**63 on
- # the only platforms where it does not fit in a long, so make that
- # a special case.
- AC_MSG_CHECKING([max safe object size])
- AC_COMPUTE_INT([gl_alloc_max],
- [LONG_MAX < (PTRDIFF_MAX < (size_t) -1 ? PTRDIFF_MAX : (size_t) -1)
- ? -1
- : PTRDIFF_MAX < (size_t) -1 ? (long) PTRDIFF_MAX : (long) (size_t) -1],
- [[#include <limits.h>
- #include <stddef.h>
- #include <stdint.h>
- ]],
- [gl_alloc_max=2147483647])
- case $gl_alloc_max in
- -1) gl_alloc_max=9223372036854775807;;
- esac
- AC_MSG_RESULT([$gl_alloc_max])
- gl_manywarn_set="$gl_manywarn_set -Walloc-size-larger-than=$gl_alloc_max"
- gl_manywarn_set="$gl_manywarn_set -Warray-bounds=2"
- gl_manywarn_set="$gl_manywarn_set -Wformat-overflow=2"
- gl_manywarn_set="$gl_manywarn_set -Wformat-truncation=2"
- gl_manywarn_set="$gl_manywarn_set -Wimplicit-fallthrough=5"
- gl_manywarn_set="$gl_manywarn_set -Wnormalized=nfc"
- gl_manywarn_set="$gl_manywarn_set -Wshift-overflow=2"
- gl_manywarn_set="$gl_manywarn_set -Wstringop-overflow=2"
- gl_manywarn_set="$gl_manywarn_set -Wunused-const-variable=2"
- gl_manywarn_set="$gl_manywarn_set -Wvla-larger-than=4031"
+ AS_VAR_APPEND([$1], [' -Warray-bounds=2'])
+ AS_VAR_APPEND([$1], [' -Wattribute-alias=2'])
+ AS_VAR_APPEND([$1], [' -Wbidi-chars=any,ucn'])
+ AS_VAR_APPEND([$1], [' -Wformat-overflow=2'])
+ AS_VAR_APPEND([$1], [' -Wformat=2'])
+ AS_VAR_APPEND([$1], [' -Wformat-truncation=2'])
+ AS_VAR_APPEND([$1], [' -Wimplicit-fallthrough=5'])
+ AS_VAR_APPEND([$1], [' -Wshift-overflow=2'])
+ AS_VAR_APPEND([$1], [' -Wuse-after-free=3'])
+ AS_VAR_APPEND([$1], [' -Wunused-const-variable=2'])
+ AS_VAR_APPEND([$1], [' -Wvla-larger-than=4031'])
# These are needed for older GCC versions.
- if test -n "$GCC"; then
- case `($CC --version) 2>/dev/null` in
+ if test -n "$GCC" && gl_gcc_version=`($CC --version) 2>/dev/null`; then
+ case $gl_gcc_version in
'gcc (GCC) '[[0-3]].* | \
'gcc (GCC) '4.[[0-7]].*)
- gl_manywarn_set="$gl_manywarn_set -fdiagnostics-show-option"
- gl_manywarn_set="$gl_manywarn_set -funit-at-a-time"
+ AS_VAR_APPEND([$1], [' -fdiagnostics-show-option'])
+ AS_VAR_APPEND([$1], [' -funit-at-a-time'])
+ ;;
+ esac
+ case $gl_gcc_version in
+ 'gcc (GCC) '[[0-9]].*)
+ AS_VAR_APPEND([$1], [' -fno-common'])
;;
esac
fi
# Disable specific options as needed.
if test "$gl_cv_cc_nomfi_needed" = yes; then
- gl_manywarn_set="$gl_manywarn_set -Wno-missing-field-initializers"
+ AS_VAR_APPEND([$1], [' -Wno-missing-field-initializers'])
fi
if test "$gl_cv_cc_uninitialized_supported" = no; then
- gl_manywarn_set="$gl_manywarn_set -Wno-uninitialized"
+ AS_VAR_APPEND([$1], [' -Wno-uninitialized'])
fi
- $1=$gl_manywarn_set
+ # This warning have too many false alarms in GCC 11.2.1.
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101713
+ AS_VAR_APPEND([$1], [' -Wno-analyzer-malloc-leak'])
AC_LANG_POP([C])
])
# Specialization for _AC_LANG = C++.
-# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
-m4_defun([gl_MANYWARN_ALL_GCC(C++)],
+AC_DEFUN([gl_MANYWARN_ALL_GCC(C++)],
[
gl_MANYWARN_ALL_GCC_CXX_IMPL([$1])
])
diff --git a/m4/gl_warnings.m4 b/m4/gl_warnings.m4
index 870472b..9433cb5 100644
--- a/m4/gl_warnings.m4
+++ b/m4/gl_warnings.m4
@@ -1,19 +1,12 @@
-# warnings.m4 serial 13
-dnl Copyright (C) 2008-2017 Free Software Foundation, Inc.
+# warnings.m4 serial 19
+dnl Copyright (C) 2008-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Simon Josefsson
-# gl_AS_VAR_APPEND(VAR, VALUE)
-# ----------------------------
-# Provide the functionality of AS_VAR_APPEND if Autoconf does not have it.
-m4_ifdef([AS_VAR_APPEND],
-[m4_copy([AS_VAR_APPEND], [gl_AS_VAR_APPEND])],
-[m4_define([gl_AS_VAR_APPEND],
-[AS_VAR_SET([$1], [AS_VAR_GET([$1])$2])])])
-
+AC_PREREQ([2.64])
# gl_COMPILER_OPTION_IF(OPTION, [IF-SUPPORTED], [IF-NOT-SUPPORTED],
# [PROGRAM = AC_LANG_PROGRAM()])
@@ -23,8 +16,6 @@ m4_ifdef([AS_VAR_APPEND],
# The effects of this macro depend on the current language (_AC_LANG).
AC_DEFUN([gl_COMPILER_OPTION_IF],
[
-dnl FIXME: gl_Warn must be used unquoted until we can assume Autoconf
-dnl 2.64 or newer.
AS_VAR_PUSHDEF([gl_Warn], [gl_cv_warn_[]_AC_LANG_ABBREV[]_$1])dnl
AS_VAR_PUSHDEF([gl_Flags], [_AC_LANG_PREFIX[]FLAGS])dnl
AS_LITERAL_IF([$1],
@@ -34,13 +25,13 @@ case $gl_positive in
-Wno-*) gl_positive=-W`expr "X$gl_positive" : 'X-Wno-\(.*\)'` ;;
esac
m4_pushdef([gl_Positive], [$gl_positive])])dnl
-AC_CACHE_CHECK([whether _AC_LANG compiler handles $1], m4_defn([gl_Warn]), [
+AC_CACHE_CHECK([whether _AC_LANG compiler handles $1], [gl_Warn], [
gl_save_compiler_FLAGS="$gl_Flags"
- gl_AS_VAR_APPEND(m4_defn([gl_Flags]),
+ AS_VAR_APPEND(m4_defn([gl_Flags]),
[" $gl_unknown_warnings_are_errors ]m4_defn([gl_Positive])["])
- AC_LINK_IFELSE([m4_default([$4], [AC_LANG_PROGRAM([])])],
- [AS_VAR_SET(gl_Warn, [yes])],
- [AS_VAR_SET(gl_Warn, [no])])
+ AC_LINK_IFELSE([m4_default([$4], [AC_LANG_PROGRAM([[]])])],
+ [AS_VAR_SET([gl_Warn], [yes])],
+ [AS_VAR_SET([gl_Warn], [no])])
gl_Flags="$gl_save_compiler_FLAGS"
])
AS_VAR_IF(gl_Warn, [yes], [$2], [$3])
@@ -59,8 +50,7 @@ AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS],
[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)])
# Specialization for _AC_LANG = C. This macro can be AC_REQUIREd.
-# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
-m4_defun([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C)],
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C)],
[
AC_LANG_PUSH([C])
gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL
@@ -68,14 +58,21 @@ m4_defun([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C)],
])
# Specialization for _AC_LANG = C++. This macro can be AC_REQUIREd.
-# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
-m4_defun([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C++)],
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C++)],
[
AC_LANG_PUSH([C++])
gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL
AC_LANG_POP([C++])
])
+# Specialization for _AC_LANG = Objective C. This macro can be AC_REQUIREd.
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS(Objective C)],
+[
+ AC_LANG_PUSH([Objective C])
+ gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL
+ AC_LANG_POP([Objective C])
+])
+
AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL],
[gl_COMPILER_OPTION_IF([-Werror -Wunknown-warning-option],
[gl_unknown_warnings_are_errors='-Wunknown-warning-option -Werror'],
@@ -84,16 +81,18 @@ AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL],
# gl_WARN_ADD(OPTION, [VARIABLE = WARN_CFLAGS/WARN_CXXFLAGS],
# [PROGRAM = AC_LANG_PROGRAM()])
# -----------------------------------------------------------
-# Adds parameter to WARN_CFLAGS/WARN_CXXFLAGS if the compiler supports it
-# when compiling PROGRAM. For example, gl_WARN_ADD([-Wparentheses]).
+# Adds OPTION to VARIABLE (which defaults to WARN_CFLAGS or WARN_CXXFLAGS)
+# if the compiler supports it when compiling PROGRAM.
#
# If VARIABLE is a variable name, AC_SUBST it.
#
# The effects of this macro depend on the current language (_AC_LANG).
+#
+# Example: gl_WARN_ADD([-Wparentheses]).
AC_DEFUN([gl_WARN_ADD],
[AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS(]_AC_LANG[)])
gl_COMPILER_OPTION_IF([$1],
- [gl_AS_VAR_APPEND(m4_if([$2], [], [[WARN_]_AC_LANG_PREFIX[FLAGS]], [[$2]]), [" $1"])],
+ [AS_VAR_APPEND(m4_if([$2], [], [[WARN_]_AC_LANG_PREFIX[FLAGS]], [[$2]]), [" $1"])],
[],
[$3])
m4_ifval([$2],
@@ -101,6 +100,77 @@ m4_ifval([$2],
[AC_SUBST([WARN_]_AC_LANG_PREFIX[FLAGS])])dnl
])
+
+# gl_CC_INHIBIT_WARNINGS
+# sets and substitutes a variable GL_CFLAG_INHIBIT_WARNINGS, to a $(CC) option
+# that reverts all preceding -W* options, if available.
+# This is expected to be '-w' at least on gcc, clang, AIX xlc, xlclang, Sun cc,
+# "compile cl" (MSVC), "compile clang-cl" (MSVC-compatible clang). Or it can be
+# empty.
+AC_DEFUN([gl_CC_INHIBIT_WARNINGS],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_CACHE_CHECK([for C compiler option to inhibit all warnings],
+ [gl_cv_cc_winhibit],
+ [rm -f conftest*
+ echo 'int dummy;' > conftest.c
+ AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c 2>conftest1.err]) >/dev/null
+ AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -w -c conftest.c 2>conftest2.err]) >/dev/null
+ if test $? = 0 && test `wc -l < conftest1.err` = `wc -l < conftest2.err`; then
+ gl_cv_cc_winhibit='-w'
+ else
+ gl_cv_cc_winhibit=none
+ fi
+ rm -f conftest*
+ ])
+ case "$gl_cv_cc_winhibit" in
+ none) GL_CFLAG_INHIBIT_WARNINGS='' ;;
+ *)
+ GL_CFLAG_INHIBIT_WARNINGS="$gl_cv_cc_winhibit"
+ dnl If all warnings are inhibited, there's no point in having the GCC
+ dnl analyzer enabled. This saves RAM requirements and CPU consumption.
+ gl_WARN_ADD([-fno-analyzer], [GL_CFLAG_INHIBIT_WARNINGS])
+ ;;
+ esac
+ AC_SUBST([GL_CFLAG_INHIBIT_WARNINGS])
+])
+
+# gl_CXX_INHIBIT_WARNINGS
+# sets and substitutes a variable GL_CXXFLAG_INHIBIT_WARNINGS, to a $(CC) option
+# that reverts all preceding -W* options, if available.
+AC_DEFUN([gl_CXX_INHIBIT_WARNINGS],
+[
+ dnl Requires AC_PROG_CXX or gl_PROG_ANSI_CXX.
+ if test -n "$CXX" && test "$CXX" != no; then
+ AC_CACHE_CHECK([for C++ compiler option to inhibit all warnings],
+ [gl_cv_cxx_winhibit],
+ [rm -f conftest*
+ echo 'int dummy;' > conftest.cc
+ AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -c conftest.cc 2>conftest1.err]) >/dev/null
+ AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -w -c conftest.cc 2>conftest2.err]) >/dev/null
+ if test $? = 0 && test `wc -l < conftest1.err` = `wc -l < conftest2.err`; then
+ gl_cv_cxx_winhibit='-w'
+ else
+ gl_cv_cxx_winhibit=none
+ fi
+ rm -f conftest*
+ ])
+ case "$gl_cv_cxx_winhibit" in
+ none) GL_CXXFLAG_INHIBIT_WARNINGS='' ;;
+ *)
+ GL_CXXFLAG_INHIBIT_WARNINGS="$gl_cv_cxx_winhibit"
+ dnl If all warnings are inhibited, there's no point in having the GCC
+ dnl analyzer enabled. This saves RAM requirements and CPU consumption.
+ gl_WARN_ADD([-fno-analyzer], [GL_CXXFLAG_INHIBIT_WARNINGS])
+ ;;
+ esac
+ else
+ GL_CXXFLAG_INHIBIT_WARNINGS=''
+ fi
+ AC_SUBST([GL_CXXFLAG_INHIBIT_WARNINGS])
+])
+
+
# Local Variables:
# mode: autoconf
# End:
diff --git a/man/.gitignore b/man/.gitignore
new file mode 100644
index 0000000..ba0d22a
--- /dev/null
+++ b/man/.gitignore
@@ -0,0 +1 @@
+*.?
diff --git a/man/atsign.1in b/man/atsign.1in
new file mode 100644
index 0000000..6cc1123
--- /dev/null
+++ b/man/atsign.1in
@@ -0,0 +1,41 @@
+.TH ATSIGN "1" "2023-10-14" "@PACKAGE_STRING@"
+
+.SH NAME
+@ATSIGN@ \- delay until a specified time
+
+.SH SYNOPSIS
+.B @ATSIGN@
+[\fI\,date\/\fR]\fI\,time\/\fR
+
+.SH OPTIONS
+
+.TP
+\fB\-F\fR, \fB\-\-list\-formats\fR
+List all supported date and time formats
+
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Show this help information
+
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+Show version information
+
+.SH "REPORTING BUGS"
+Report bugs to <@PACKAGE_BUGREPORT@>.
+
+.SH COPYRIGHT
+Copyright \(co 2023 P. J. McDermott
+.PP
+@ 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.
+.PP
+@ 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.
+.PP
+You should have received a copy of the GNU General Public License
+along with @. If not, see <http://www.gnu.org/licenses/>.
diff --git a/man/local.mk b/man/local.mk
new file mode 100644
index 0000000..65814fe
--- /dev/null
+++ b/man/local.mk
@@ -0,0 +1,43 @@
+# Process this file with automake to produce an input makefile.
+#
+# Copyright (C) 2018, 2023 P. J. McDermott
+#
+# This file is part of @
+#
+# @ 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.
+#
+# @ 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 @. If not, see <http://www.gnu.org/licenses/>.
+
+man1_sources = \
+ %reldir%/atsign.1in
+man1_MANS = $(man1_sources:.1in=.1)
+
+CLEANFILES += \
+ $(man1_MANS)
+EXTRA_DIST += \
+ $(man1_sources)
+
+if ENABLE_SYMLINK
+atsign = @$(EXEEXT)
+else !ENABLE_SYMLINK
+atsign = $$(printf 'atsign' | sed '$(transform); s/$$/$(EXEEXT)/')
+endif
+man_subst = sed \
+ -e "s|[@]PACKAGE_STRING[@]|$(PACKAGE_STRING)|g" \
+ -e "s|[@]PACKAGE_BUGREPORT[@]|$(PACKAGE_BUGREPORT)|g" \
+ -e "s|[@]ATSIGN[@]|$(atsign)|g"
+
+SUFFIXES += .1in .1
+
+.1in.1:
+ $(AM_V_GEN)$(MKDIR_P) "$$(dirname $@)"
+ $(AM_V_at)$(man_subst) $< >$@
diff --git a/po/.gitignore b/po/.gitignore
new file mode 100644
index 0000000..532f823
--- /dev/null
+++ b/po/.gitignore
@@ -0,0 +1,11 @@
+/Makefile.in.in
+/Makevars.template
+/Rules-quot
+/*.sed
+/POTFILES
+/*.pot
+/*.po
+/*.mo
+/*@boldquot.header
+/*@quot.header
+/stamp-po
diff --git a/po/Makevars b/po/Makevars
new file mode 100644
index 0000000..1753e43
--- /dev/null
+++ b/po/Makevars
@@ -0,0 +1,26 @@
+# Variables to be inserted into Makefile
+
+DOMAIN = $(PACKAGE)
+
+subdir = po
+top_builddir = ..
+
+XGETTEXT_OPTIONS = --add-comments=TRANSLATORS --keyword=_
+
+COPYRIGHT_HOLDER = P. J. McDermott
+
+PACKAGE_GNU = no
+
+MSGID_BUGS_ADDRESS = mailto:pj@pehjota.net
+
+EXTRA_LOCALE_CATEGORIES =
+
+USE_MSGCTXT = no
+
+MSGMERGE_OPTIONS =
+
+MSGINIT_OPTIONS =
+
+PO_DEPENDS_ON_POT = yes
+
+DIST_DEPENDS_ON_UPDATE_PO = yes
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644
index 0000000..5472064
--- /dev/null
+++ b/po/POTFILES.in
@@ -0,0 +1,2 @@
+src/datetime.c
+src/main.c
diff --git a/scripts/update-m4.sh b/scripts/update-m4.sh
new file mode 100755
index 0000000..e0d500d
--- /dev/null
+++ b/scripts/update-m4.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# Script to update M4 files from Gnulib, GNU Autoconf Archive, and GNU Coreutils
+#
+# Copyright (C) 2023 P. J. McDermott
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered as-is,
+# without any warranty.
+
+set -eu
+
+SV_CGIT='https://git.savannah.gnu.org/cgit'
+
+for f in m4/gl_*.m4; do
+ wget -O "${f}" "${SV_CGIT}/gnulib.git/plain/m4/${f#m4/gl_}"
+done
+
+for f in m4/ax_*.m4; do
+ wget -O "${f}" "${SV_CGIT}/autoconf-archive.git/plain/${f}"
+done
+
+wget -O - "${SV_CGIT}/coreutils.git/plain/configure.ac" | sed -n '
+ /^# Copyright /,/^dnl Written /{
+ p;
+ s/^dnl Written .*$//p;
+ };
+ /^# gl_GCC_VERSION_IFELSE/,/^$/p;
+ ' | sed '$d' 1>'m4/gcc_version.m4'
diff --git a/src/datetime.c b/src/datetime.c
index f7cdb89..72f0219 100644
--- a/src/datetime.c
+++ b/src/datetime.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 P. J. McDermott
+ * Copyright (C) 2021, 2022 P. J. McDermott
*
* This file is part of @
*
@@ -18,6 +18,9 @@
*/
#define _XOPEN_SOURCE
+/* glibc requires these for timegm(): */
+#define _DEFAULT_SOURCE
+#define _BSD_SOURCE
#include <ctype.h>
#include <errno.h>
@@ -29,18 +32,7 @@
#include <time.h>
#include "datetime.h"
#include "formats.h"
-
-static struct tm DATETIME_EPOCH_ = {
- .tm_sec = 0,
- .tm_min = 0,
- .tm_hour = 0,
- .tm_mday = 1,
- .tm_mon = 0,
- .tm_year = 70,
- .tm_wday = 4,
- .tm_yday = 0,
- .tm_isdst = -1,
-};
+#include "i18n.h"
static void
_datetime_buf_cpy_p(char *dst, const char *src)
@@ -83,7 +75,13 @@ _datetime_reset_tm(struct tm *tm)
static void
_datetime_normalize(struct tm *now_tm, struct tm *arg_tm, time_t *arg_sec)
{
- int wday;
+ int days_in_mon[12] = {31, 28, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31};
+
+ if (now_tm->tm_year % 4 == 0 && (now_tm->tm_year % 100 != 0 ||
+ now_tm->tm_year % 400 == 0)) {
+ days_in_mon[1] = 29;
+ }
if (arg_tm->tm_sec == INT_MIN) {
arg_tm->tm_sec = 0;
@@ -95,36 +93,44 @@ _datetime_normalize(struct tm *now_tm, struct tm *arg_tm, time_t *arg_sec)
arg_tm->tm_mday = now_tm->tm_mday;
arg_tm->tm_wday = now_tm->tm_wday;
*arg_sec = mktime(arg_tm);
- if (*arg_sec <= mktime(now_tm)) {
+ if (difftime(*arg_sec, mktime(now_tm)) <= 0) {
/* Specified time already happened today; use tomorrow.
- * Adding the number of seconds in a day is a shortcut
- * that ignores leap seconds. One better method would
- * be to increment tm_mday % days in tm_mon, etc. */
- *arg_sec += 60 * 60 * 24;
- now_tm = localtime(arg_sec);
- arg_tm->tm_year = now_tm->tm_year;
- arg_tm->tm_mon = now_tm->tm_mon;
- arg_tm->tm_mday = now_tm->tm_mday;
+ */
+ ++arg_tm->tm_mday;
+ arg_tm->tm_wday = (arg_tm->tm_wday + 1) % 7;
+ if (arg_tm->tm_mday > days_in_mon[arg_tm->tm_mon]) {
+ arg_tm->tm_mday = 1;
+ ++arg_tm->tm_mon;
+ if (arg_tm->tm_mon >= 12) {
+ arg_tm->tm_mon = 0;
+ ++arg_tm->tm_year;
+ }
+ }
*arg_sec = mktime(arg_tm);
}
} else if (arg_tm->tm_mday == INT_MIN) {
- /* Only a weekday specified; try tomorrow or next week. Uses
- * same shortcut as above. */
- wday = arg_tm->tm_wday;
+ /* Only a weekday specified; try tomorrow or next week. */
arg_tm->tm_year = now_tm->tm_year;
arg_tm->tm_mon = now_tm->tm_mon;
arg_tm->tm_mday = now_tm->tm_mday;
- arg_tm->tm_wday = now_tm->tm_wday;
- if (wday <= now_tm->tm_wday) {
- wday += 7;
+ if (arg_tm->tm_wday <= now_tm->tm_wday) {
+ arg_tm->tm_mday += 7;
+ }
+ arg_tm->tm_mday += arg_tm->tm_wday - now_tm->tm_wday;
+ if (arg_tm->tm_mday > days_in_mon[arg_tm->tm_mon]) {
+ arg_tm->tm_mday -= days_in_mon[arg_tm->tm_mon];
+ ++arg_tm->tm_mon;
+ if (arg_tm->tm_mon >= 12) {
+ arg_tm->tm_mon = 0;
+ ++arg_tm->tm_year;
+ }
}
*arg_sec = mktime(arg_tm);
- *arg_sec += (60 * 60 * 24) * (wday - now_tm->tm_wday);
} else if (arg_tm->tm_year == INT_MIN) {
/* No year specified; try this year. */
arg_tm->tm_year = now_tm->tm_year;
*arg_sec = mktime(arg_tm);
- if (*arg_sec <= mktime(now_tm)) {
+ if (difftime(*arg_sec, mktime(now_tm)) <= 0) {
/* Specified time already happened this year; use next
* year. */
++arg_tm->tm_year;
@@ -136,7 +142,8 @@ _datetime_normalize(struct tm *now_tm, struct tm *arg_tm, time_t *arg_sec)
}
int
-datetime_parse(struct tm *now_tm, const char *input, time_t *arg_sec)
+datetime_parse(struct tm *now_tm, const char *input,
+ struct tm *arg_tm, time_t *arg_sec)
{
int date_fmt_len;
int time_fmt_len;
@@ -146,7 +153,6 @@ datetime_parse(struct tm *now_tm, const char *input, time_t *arg_sec)
size_t d;
size_t t;
char *end;
- struct tm arg_tm;
time_t sec;
bool got;
@@ -159,20 +165,20 @@ datetime_parse(struct tm *now_tm, const char *input, time_t *arg_sec)
}
fmt_buf = calloc(fmt_len + 1, sizeof(*fmt_buf));
if (fmt_buf == NULL) {
- fprintf(stderr, "Failed to allocate buffer: %s\n",
+ fprintf(stderr, _("Failed to allocate buffer: %s\n"),
strerror(errno));
return -1;
}
sec = *arg_sec; /* GCC is dumb. */
got = false;
- for (t = 0; t < sizeof(FORMATS_TIME) / sizeof(FORMATS_TIME[0]) ; ++t) {
+ for (t = 0; t < sizeof(FORMATS_TIME) / sizeof(FORMATS_TIME[0]); ++t) {
_datetime_buf_cpy_p(fmt_buf, FORMATS_TIME[t]);
- _datetime_reset_tm(&arg_tm);
- end = strptime(input, fmt_buf, &arg_tm);
+ _datetime_reset_tm(arg_tm);
+ end = strptime(input, fmt_buf, arg_tm);
if (end != NULL && *end == '\0') {
- _datetime_normalize(now_tm, &arg_tm, arg_sec);
- if (datetime_diff_epoch(*arg_sec) >= 0) {
+ _datetime_normalize(now_tm, arg_tm, arg_sec);
+ if (arg_tm->tm_year >= 0) {
free(fmt_buf);
return 0;
}
@@ -189,11 +195,11 @@ datetime_parse(struct tm *now_tm, const char *input, time_t *arg_sec)
++t) {
_datetime_buf_cpy_p(fmt_buf + date_fmt_len,
FORMATS_TIME[t]);
- _datetime_reset_tm(&arg_tm);
- end = strptime(input, fmt_buf, &arg_tm);
+ _datetime_reset_tm(arg_tm);
+ end = strptime(input, fmt_buf, arg_tm);
if (end != NULL && *end == '\0') {
- _datetime_normalize(now_tm, &arg_tm, arg_sec);
- if (datetime_diff_epoch(*arg_sec) >= 0) {
+ _datetime_normalize(now_tm, arg_tm, arg_sec);
+ if (arg_tm->tm_year >= 0) {
free(fmt_buf);
return 0;
}
@@ -211,11 +217,11 @@ datetime_parse(struct tm *now_tm, const char *input, time_t *arg_sec)
}
_datetime_buf_cpy_p(fmt_buf + time_fmt_len,
FORMATS_DATE[d]);
- _datetime_reset_tm(&arg_tm);
- end = strptime(input, fmt_buf, &arg_tm);
+ _datetime_reset_tm(arg_tm);
+ end = strptime(input, fmt_buf, arg_tm);
if (end != NULL && *end == '\0') {
- _datetime_normalize(now_tm, &arg_tm, arg_sec);
- if (datetime_diff_epoch(*arg_sec) >= 0) {
+ _datetime_normalize(now_tm, arg_tm, arg_sec);
+ if (arg_tm->tm_year >= 0) {
free(fmt_buf);
return 0;
}
@@ -224,13 +230,13 @@ datetime_parse(struct tm *now_tm, const char *input, time_t *arg_sec)
}
}
}
- for (d = 0; d < sizeof(FORMATS_MISC) / sizeof(FORMATS_MISC[0]) ; ++d) {
+ for (d = 0; d < sizeof(FORMATS_MISC) / sizeof(FORMATS_MISC[0]); ++d) {
_datetime_buf_cpy_p(fmt_buf, FORMATS_MISC[d]);
- _datetime_reset_tm(&arg_tm);
- end = strptime(input, fmt_buf, &arg_tm);
+ _datetime_reset_tm(arg_tm);
+ end = strptime(input, fmt_buf, arg_tm);
if (end != NULL && *end == '\0') {
- _datetime_normalize(now_tm, &arg_tm, arg_sec);
- if (datetime_diff_epoch(*arg_sec) >= 0) {
+ _datetime_normalize(now_tm, arg_tm, arg_sec);
+ if (arg_tm->tm_year >= 0) {
free(fmt_buf);
return 0;
}
@@ -244,7 +250,7 @@ datetime_parse(struct tm *now_tm, const char *input, time_t *arg_sec)
free(fmt_buf);
return 0;
} else {
- fputs("Unknown date format\n", stderr);
+ fputs(_("Unknown date format\n"), stderr);
free(fmt_buf);
return -1;
}
@@ -289,13 +295,13 @@ _datetime_strftime(const char *fmts[], const struct tm *tm, char **out,
*buf_sz = strlen(fmts[0]) + 1;
*buf = calloc(*buf_sz, sizeof(**buf));
if (*buf == NULL) {
- fprintf(stderr, "Failed to allocate buffer: %s\n",
+ fprintf(stderr, _("Failed to allocate buffer: %s\n"),
strerror(errno));
return -1;
}
*out = calloc(*buf_sz, sizeof(**out));
if (*out == NULL) {
- fprintf(stderr, "Failed to allocate buffer: %s\n",
+ fprintf(stderr, _("Failed to allocate buffer: %s\n"),
strerror(errno));
return -1;
}
@@ -315,7 +321,7 @@ _datetime_strftime(const char *fmts[], const struct tm *tm, char **out,
++*buf_sz;
*buf = realloc(*buf, *buf_sz * sizeof(**buf));
if (*buf == NULL) {
- fprintf(stderr, "Failed to allocate buffer: %s\n",
+ fprintf(stderr, _("Failed to allocate buffer: %s\n"),
strerror(errno));
return -1;
}
@@ -324,7 +330,7 @@ _datetime_strftime(const char *fmts[], const struct tm *tm, char **out,
if (resized > 0) {
*out = realloc(*out, *buf_sz * sizeof(**out));
if (*out == NULL) {
- fprintf(stderr, "Failed to allocate buffer: %s\n",
+ fprintf(stderr, _("Failed to allocate buffer: %s\n"),
strerror(errno));
return -1;
}
@@ -386,13 +392,3 @@ datetime_strftime_misc(const struct tm *tm, char **out, size_t *buf_sz,
return _datetime_strftime(FORMATS_MISC, tm, out, buf_sz, buf, i);
}
-
-double
-datetime_diff_epoch(time_t t)
-{
- time_t epoch;
-
- epoch = timegm(&DATETIME_EPOCH_);
-
- return difftime(t, epoch);
-}
diff --git a/src/datetime.h b/src/datetime.h
index e225b52..1094cf8 100644
--- a/src/datetime.h
+++ b/src/datetime.h
@@ -23,7 +23,8 @@
#include <time.h>
int
-datetime_parse(struct tm *now_tm, const char *input, time_t *arg_sec);
+datetime_parse(struct tm *now_tm, const char *input,
+ struct tm *arg_tm, time_t *arg_sec);
int
datetime_strftime_date(const struct tm *tm, char **out, size_t *out_sz,
@@ -37,7 +38,4 @@ int
datetime_strftime_misc(const struct tm *tm, char **out, size_t *out_sz,
char **buf, size_t *i);
-double
-datetime_diff_epoch(time_t t);
-
#endif /* DATETIME_H_ */
diff --git a/src/formats.h b/src/formats.h
index 262912e..c88f731 100644
--- a/src/formats.h
+++ b/src/formats.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021-2022 P. J. McDermott
+ * Copyright (C) 2021, 2022 P. J. McDermott
*
* This file is part of @
*
diff --git a/src/i18n.h b/src/i18n.h
new file mode 100644
index 0000000..4d8ee76
--- /dev/null
+++ b/src/i18n.h
@@ -0,0 +1,11 @@
+#ifdef ENABLE_NLS
+
+#include <libintl.h>
+
+#define _(msgid) gettext(msgid)
+
+#else
+
+#define _(msgid) (msgid)
+
+#endif
diff --git a/src/local.mk b/src/local.mk
index 9992269..1012945 100644
--- a/src/local.mk
+++ b/src/local.mk
@@ -1,5 +1,6 @@
-@_SOURCES += \
+atsign_SOURCES += \
%reldir%/datetime.c \
%reldir%/datetime.h \
%reldir%/formats.h \
+ %reldir%/i18n.h \
%reldir%/main.c
diff --git a/src/main.c b/src/main.c
index 01a0a4c..0ff76c9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -17,16 +17,21 @@
* along with @. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "config.h"
+
+#ifdef ENABLE_NLS
+#include <locale.h>
+#endif
+
#include <errno.h>
-#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
-#include "config.h"
#include "datetime.h"
+#include "i18n.h"
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
#include <getopt.h>
@@ -60,22 +65,23 @@ static const struct option LONGOPTS_[] = {
static void
_print_usage(FILE *stream, const char *program_name)
{
- fprintf(stream, "Usage: %s [date]time\n", program_name);
+ fprintf(stream, _("Usage: %s [date]time\n"), program_name);
}
static void
_print_help(const char *program_name)
{
_print_usage(stdout, program_name);
- puts("Options:");
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
- puts("\t-F, --list-formats List all supported date and time formats");
- puts("\t-h, --help Show this help information");
- puts("\t-V, --version Show version information");
+ puts(_("Options:\n"
+ " -F, --list-formats List all supported date and time formats\n"
+ " -h, --help Show this help information\n"
+ " -V, --version Show version information"));
#else
- puts("\t-F List all supported date and time formats");
- puts("\t-h Show this help information");
- puts("\t-V Show version information");
+ puts(_("Options:\n"
+ " -F List all supported date and time formats\n"
+ " -h Show this help information\n"
+ " -V Show version information"));
#endif
}
@@ -111,31 +117,31 @@ _list_formats(const struct tm *tm)
char *buf;
size_t i;
- puts("Time formats:");
+ puts(_("Time formats:"));
i = 0;
while (datetime_strftime_time(tm, &out, &buf_sz, &buf, &i) > 0) {
if (out[0] == '\0') {
continue;
}
- printf(" * %s\n", out);
+ printf(_(" * %s\n"), out);
}
- puts("Date formats:");
+ puts(_("Date formats:"));
i = 0;
while (datetime_strftime_date(tm, &out, &buf_sz, &buf, &i) > 0) {
if (out[0] == '\0') {
continue;
}
- printf(" * %s\n", out);
+ printf(_(" * %s\n"), out);
}
- puts("Additional formats:");
+ puts(_("Additional formats:"));
i = 0;
while (datetime_strftime_misc(tm, &out, &buf_sz, &buf, &i) > 0) {
if (out[0] == '\0') {
continue;
}
- printf(" * %s\n", out);
+ printf(_(" * %s\n"), out);
}
}
@@ -143,13 +149,12 @@ static void
_print_version(void)
{
printf("@ (atsign) %s%s\n", PACKAGE_VERSION, PACKAGE_VERSION_GIT);
- puts("Copyright (C) 2021-2022 P. J. McDermott");
- puts("License GPLv3+: GNU GPL version 3 or later "
- "<http://gnu.org/licenses/gpl.html>.");
- puts("This is free software: you are free to change and redistribute "
- "it.");
- puts("There is NO WARRANTY, to the extent permitted by law.\n");
- printf("Please report bugs to <%s>.\n", PACKAGE_BUGREPORT);
+ puts(_("Copyright (C) 2021, 2022 P. J. McDermott\n"
+ "License GPLv3+: GNU GPL version 3 or later "
+ "<http://gnu.org/licenses/gpl.html>.\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n"));
+ printf(_("Please report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
}
static char *
@@ -168,7 +173,7 @@ _concat_args(int argc, char * const argv[])
buf = calloc(buf_l, sizeof(*buf));
if (buf == NULL) {
- fprintf(stderr, "Failed to allocate buffer: %s\n",
+ fprintf(stderr, _("Failed to allocate buffer: %s\n"),
strerror(errno));
return NULL;
}
@@ -196,9 +201,19 @@ main(int argc, char * const argv[])
char *buf;
time_t now;
struct tm *now_tm;
+ struct tm arg_tm;
time_t arg;
double dif;
+#ifdef ENABLE_NLS
+ bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+ bind_textdomain_codeset(PACKAGE, "UTF-8");
+#endif
+ textdomain(PACKAGE);
+ setlocale(LC_ALL, "");
+#endif
+
#if defined(ENABLE_TESTS) && ENABLE_TESTS
dbg = false;
#endif
@@ -243,11 +258,11 @@ main(int argc, char * const argv[])
default:
_print_usage(stderr, argv[0]);
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
- fprintf(stderr, "Try '%s --help' for more "
- "information.\n", argv[0]);
+ fprintf(stderr, _("Try '%s --help' for more "
+ "information.\n"), argv[0]);
#else
- fprintf(stderr, "Try '%s -h' for more "
- "information.\n", argv[0]);
+ fprintf(stderr, _("Try '%s -h' for more "
+ "information.\n"), argv[0]);
#endif
return EXIT_FAILURE;
}
@@ -265,7 +280,7 @@ main(int argc, char * const argv[])
return EXIT_FAILURE;
}
- if (datetime_parse(now_tm, buf, &arg) < 0) {
+ if (datetime_parse(now_tm, buf, &arg_tm, &arg) < 0) {
free(buf);
return EXIT_FAILURE;
}
@@ -273,8 +288,13 @@ main(int argc, char * const argv[])
#if defined(ENABLE_TESTS) && ENABLE_TESTS
if (dbg == true) {
- dif = datetime_diff_epoch(arg);
- printf("%" PRId64 "\n", (int64_t) dif);
+ printf("%04d-%02d-%02d %02d:%02d:%02d\n",
+ arg_tm.tm_year + 1900,
+ arg_tm.tm_mon + 1,
+ arg_tm.tm_mday,
+ arg_tm.tm_hour,
+ arg_tm.tm_min,
+ arg_tm.tm_sec);
return EXIT_SUCCESS;
}
#endif
@@ -282,7 +302,7 @@ main(int argc, char * const argv[])
now = time(NULL);
dif = difftime(arg, now);
if (dif >= 1000 * 24 * 60 * 60) {
- fputs("Date too far in the future\n", stderr);
+ fputs(_("Date too far in the future\n"), stderr);
return EXIT_FAILURE;
}
diff --git a/tests/formats.sh b/tests/formats.sh
index a0c4188..576b96a 100755
--- a/tests/formats.sh
+++ b/tests/formats.sh
@@ -24,7 +24,7 @@ set -eu
plan_ 1
exp="$(cat "${0%.sh}.exp")"
-got="$("${TOP_BUILDDIR}/@" -d '1970-01-02 03:04:05' -F)"
+got="$("${TOP_BUILDDIR}/atsign" -d '1970-01-02 03:04:05' -F)"
if [ x"${got}" = x"${exp}" ]; then
ok_ -- 'formats list'
diff --git a/tests/local.mk b/tests/local.mk
index 9124d94..84eb79e 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -16,5 +16,6 @@ SH_LOG_DRIVER = \
EXTRA_DIST += \
$(tests) \
%reldir%/disabled.sh \
+ %reldir%/formats.exp \
$(top_srcdir)/build-aux/tap-driver.sh \
%reldir%/aux/tap-functions.sh
diff --git a/tests/parse.sh b/tests/parse.sh
index 1150f28..eadd2cf 100755
--- a/tests/parse.sh
+++ b/tests/parse.sh
@@ -21,7 +21,10 @@ set -eu
. "${TOP_SRCDIR}/tests/aux/tap-functions.sh"
-fmts="$(TZ=UTC0 "${TOP_BUILDDIR}/@" -d '1970-01-01 00:00:00' -F)"
+now='1969-12-31 23:59:30'
+tgt='1970-01-01 00:00:00'
+
+fmts="$(TZ=UTC0 "${TOP_BUILDDIR}/atsign" -d "${tgt}" -F)"
time_fmts="$(printf '%s\n' "${fmts}" | \
sed -n '/^Time formats:$/,/^Date formats:$/s/^ \* //p')"
date_fmts="$(printf '%s\n' "${fmts}" | \
@@ -44,30 +47,31 @@ for fmt in $(printf '%s\n' "${fmts}"); do
diag_ "${fmt}"
done
-run_test()
+test_fmt()
{
- datetime="${1}"
- shift 1
+ now="${1}"
+ tgt="${2}"
+ fmt="${3}"
+ shift 3
- got="$(TZ=UTC0 "${TOP_BUILDDIR}/@" -d '1969-12-31 23:59:30' \
- "${datetime}" 2>&1)" || :
- if [ x"${got}" = x'0' ]; then
- ok_ -- "${datetime}"
+ got="$(TZ=UTC0 "${TOP_BUILDDIR}/atsign" -d "${now}" "${fmt}" 2>&1)" || :
+ if [ x"${got}" = x"${tgt}" ]; then
+ ok_ -- "${fmt}"
else
- not_ok_ -- "${datetime}"
- diag_ " Failed test '${datetime}'"
+ not_ok_ -- "${fmt}"
+ diag_ " Failed test '${fmt}'"
diag_ " got: '${got}'"
- diag_ " expected: '0'"
+ diag_ " expected: '${tgt}'"
fi
}
for time_fmt in ${time_fmts}; do
- run_test "${time_fmt}"
+ test_fmt "${now}" "${tgt}" "${time_fmt}"
for date_fmt in ${date_fmts}; do
- run_test "${date_fmt} ${time_fmt}"
- run_test "${time_fmt} ${date_fmt}"
+ test_fmt "${now}" "${tgt}" "${date_fmt} ${time_fmt}"
+ test_fmt "${now}" "${tgt}" "${time_fmt} ${date_fmt}"
done
done
for misc_fmt in ${misc_fmts}; do
- run_test "${misc_fmt}"
+ test_fmt "${now}" "${tgt}" "${misc_fmt}"
done