maint: Use gnulib modules in src/ tools. Closes: #37.

Partially reverts 9b6c6519.

Signed-off-by: Simon Josefsson <simon@josefsson.org>
diff --git a/.gitignore b/.gitignore
index d96a4d0..f726bcd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -165,6 +165,7 @@
 /src/asn1Parser
 /src/asn1Parser.o
 /src/benchmark.o
+/src/gl/
 /stamp-h1
 /tags
 /tests-gl/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 81611de..1ea42df 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -182,6 +182,7 @@
       - build/tests/*/*.log
 
 gnutls:
+  when: manual # takes ~1 hour...
   image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
   script:
   - yum remove -y libtasn1-devel
diff --git a/Makefile.am b/Makefile.am
index 86cca65..87ac3c6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,7 +35,7 @@
 
 include $(top_srcdir)/aminclude_static.am
 
-ACLOCAL_AMFLAGS = -I m4
+ACLOCAL_AMFLAGS = -I m4 -I src/gl/m4
 
 ABIDW_COMMON = --no-show-locs --no-corpus-path
 ABIGNORE_FILE = "$(top_srcdir)/devel/libtasn1.abignore"
diff --git a/NEWS b/NEWS
index 7ce3b1b..f2ab665 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 - Improve GTK-DOC manual.  Closes: #35.
+- Improve --help and --version for tools with gnulib.  Closes: #37.
 
 * Noteworthy changes in release 4.17.0 (2021-05-13) [stable]
 - Print deprecation messages for deprecated macros, thanks to Tim Rühsen.
diff --git a/bootstrap.conf b/bootstrap.conf
index 514988c..64e64f5 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -39,6 +39,13 @@
 valgrind-tests
 "
 
+src_gnulib_modules="
+gettime
+progname
+read-file
+version-etc-fsf
+"
+
 # Build prerequisites
 buildreq="\
 autoconf   2.64
@@ -62,6 +69,8 @@
 
 bootstrap_post_import_hook ()
 {
+  ${GNULIB_SRCDIR}/gnulib-tool --import --libtool --m4-base=src/gl/m4 --macro-prefix=sgl --lib=libsgl --source-base=src/gl --local-dir=src/gl --tests-base=src/gl/tests --no-conditional-dependencies --without-tests $src_gnulib_modules
+
   # Automake requires that ChangeLog exist.
   touch ChangeLog || return 1
 }
diff --git a/configure.ac b/configure.ac
index bb33e23..5389656 100644
--- a/configure.ac
+++ b/configure.ac
@@ -44,6 +44,7 @@
 
 AC_PROG_CC
 gl_EARLY
+sgl_EARLY
 AC_PROG_YACC
 
 AC_ARG_ENABLE(doc,
@@ -61,6 +62,7 @@
 AC_CHECK_SIZEOF(unsigned int, 4)
 
 gl_INIT
+sgl_INIT
 
 AX_CODE_COVERAGE
 
@@ -123,6 +125,7 @@
   lib/includes/libtasn1.h
   lib/libtasn1.pc
   src/Makefile
+  src/gl/Makefile
   tests/Makefile
 ])
 AC_OUTPUT
diff --git a/gnulib b/gnulib
index 8f7615a..e20b35c 160000
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit 8f7615ad790cb837e1888dc4064c6540ecb1f72d
+Subproject commit e20b35c9167ff7c051d0314b356d7e7a304f828f
diff --git a/src/Makefile.am b/src/Makefile.am
index a172947..d0e84d5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,11 +16,18 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS) $(CODE_COVERAGE_CFLAGS)
-AM_CPPFLAGS = -I$(top_builddir)/lib/includes -I$(top_srcdir)/lib/includes \
- -I$(top_builddir)/lib/gl -I$(top_srcdir)/lib/gl $(CODE_COVERAGE_CPPFLAGS)
+SUBDIRS = gl
 
-LDADD = ../lib/libtasn1.la ../lib/gl/libgnu.la
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+AM_CPPFLAGS = -I$(top_builddir)/lib/includes -I$(top_srcdir)/lib/includes
+AM_CPPFLAGS += -I$(top_builddir)/lib/gl -I$(top_srcdir)/lib/gl
+AM_CPPFLAGS += -I$(builddir)/gl -I$(srcdir)/gl
+
+AM_CFLAGS += $(CODE_COVERAGE_CFLAGS)
+AM_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS)
+
+LDADD = ../lib/libtasn1.la ../lib/gl/libgnu.la gl/libsgl.la
+LDADD += $(LIB_CLOCK_GETTIME) $(LTLIBINTL)
 AM_LDFLAGS = $(CODE_COVERAGE_LDFLAGS)
 
 bin_PROGRAMS = asn1Parser asn1Coding asn1Decoding
diff --git a/src/asn1Coding.c b/src/asn1Coding.c
index 9b54a75..e8927a8 100644
--- a/src/asn1Coding.c
+++ b/src/asn1Coding.c
@@ -29,7 +29,8 @@
 
 #include <libtasn1.h>
 
-#define program_name "asn1Coding"
+#include "progname.h"
+#include "version-etc.h"
 
 /* This feature is available in gcc versions 2.5 and later.  */
 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
@@ -57,7 +58,7 @@
   -o, --output=FILE     output file\n\
   -h, --help            display this help and exit\n\
   -v, --version         output version information and exit\n");
-     printf ("Report bugs to "PACKAGE_BUGREPORT);
+      emit_bug_reporting_address ();
     }
   exit (status);
 }
@@ -152,6 +153,8 @@
   int k;
   int last_ra;
 
+  set_program_name (argv[0]);
+
   opterr = 0;			/* disable error messages from getopt */
 
   while (1)
@@ -170,9 +173,8 @@
 	  usage (EXIT_SUCCESS);
 	  break;
 	case 'v':		/* VERSION */
-	  printf(program_name" "PACKAGE" " VERSION"\n");
-	  printf("Copyright (C) 2017-2021 Free Software Foundation, Inc.\n\n");
-	  printf("Written by Fabio Fiorina\n");
+	  version_etc (stdout, program_name, PACKAGE, VERSION,
+		       "Fabio Fiorina", NULL);
 	  free (outputFileName);
 	  exit (0);
 	  break;
diff --git a/src/asn1Decoding.c b/src/asn1Decoding.c
index f16c5b9..c453cb3 100644
--- a/src/asn1Decoding.c
+++ b/src/asn1Decoding.c
@@ -32,7 +32,9 @@
 
 #include "benchmark.h"
 
-#define program_name "asn1Decoding"
+#include "progname.h"
+#include "read-file.h"
+#include "version-etc.h"
 
 static int decode (asn1_node definitions, const char *typeName, void *der,
 		   int der_len, int benchmark, int strict);
@@ -63,51 +65,11 @@
   -t, --no-time-strict  use strict DER decoding but not in time fields\n\
   -h, --help            display this help and exit\n\
   -v, --version         output version information and exit\n");
-     printf ("Report bugs to "PACKAGE_BUGREPORT);
+      emit_bug_reporting_address ();
     }
   exit (status);
 }
 
-static char *read_binary_file(const char *file, size_t *l)
-{
-  FILE *fp;
-  struct stat st;
-  char *out;
-
-  if (stat(file, &st) == -1)
-    {
-      fprintf(stderr, "Error reading file size!\n");
-      exit(1);
-    }
-
-  fp = fopen(file, "rb");
-  if (fp == NULL)
-    {
-      fprintf(stderr, "Error reading file!\n");
-      exit(1);
-    }
-
-  out = malloc(st.st_size+1);
-  if (out == NULL)
-    {
-      fprintf(stderr, "Memory error!\n");
-      exit(1);
-    }
-
-  *l = fread(out, 1, st.st_size, fp);
-  if ((off_t)*l != st.st_size)
-    {
-      fprintf(stderr, "Error reading contents (got: %ld, expected %ld)!\n",
-              (long)*l, (long)st.st_size);
-      exit(1);
-    }
-
-  out[*l] = 0;
-
-  fclose(fp);
-  return out;
-}
-
 int
 main (int argc, char *argv[])
 {
@@ -133,6 +95,8 @@
   int flags = 0, debug = 0;
   /* FILE *outputFile; */
 
+  set_program_name (argv[0]);
+
   opterr = 0;			/* disable error messages from getopt */
 
   while (1)
@@ -162,9 +126,8 @@
 	    flags |= ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME;
 	  break;
 	case 'v':		/* VERSION */
-	  printf(program_name" "PACKAGE" " VERSION"\n");
-	  printf("Copyright (C) 2017-2021 Free Software Foundation, Inc.\n\n");
-	  printf("Written by Fabio Fiorina\n");
+	  version_etc (stdout, program_name, PACKAGE, VERSION,
+		       "Fabio Fiorina", NULL);
 	  exit (0);
 	  break;
 	case '?':		/* UNKNOW OPTION */
@@ -231,7 +194,7 @@
 
   {
     size_t tmplen;
-    der = (unsigned char *) read_binary_file (inputFileDerName, &tmplen);
+    der = (unsigned char *) read_file (inputFileDerName, RF_BINARY, &tmplen);
     der_len = tmplen;
   }
 
diff --git a/src/asn1Parser.c b/src/asn1Parser.c
index adb1274..fdcca68 100644
--- a/src/asn1Parser.c
+++ b/src/asn1Parser.c
@@ -29,7 +29,8 @@
 
 #include <libtasn1.h>
 
-#define program_name "asn1Parser"
+#include "progname.h"
+#include "version-etc.h"
 
 /* This feature is available in gcc versions 2.5 and later.  */
 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
@@ -58,7 +59,7 @@
   -n, --name=NAME       array name\n\
   -h, --help            display this help and exit\n\
   -v, --version         output version information and exit\n");
-     printf ("Report bugs to "PACKAGE_BUGREPORT);
+      emit_bug_reporting_address ();
     }
   exit (status);
 }
@@ -84,6 +85,8 @@
   char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
   int parse_result = ASN1_SUCCESS;
 
+  set_program_name (argv[0]);
+
   opterr = 0;			/* disable error messages from getopt */
 
   while (1)
@@ -109,9 +112,8 @@
 	  usage (EXIT_SUCCESS);
 	  break;
 	case 'v':		/* VERSION */
-	  printf(program_name" "PACKAGE" " VERSION"\n");
-	  printf("Copyright (C) 2017-2021 Free Software Foundation, Inc.\n\n");
-	  printf("Written by Fabio Fiorina\n");
+	  version_etc (stdout, program_name, PACKAGE, VERSION,
+		       "Fabio Fiorina", NULL);
 	  free (outputFileName);
 	  free (vectorName);
 	  exit (0);
diff --git a/src/benchmark.c b/src/benchmark.c
index 3f8ef41..d5802cc 100644
--- a/src/benchmark.c
+++ b/src/benchmark.c
@@ -87,12 +87,8 @@
 #ifndef _WIN32
   st->old_handler = signal (SIGALRM, alarm_handler);
 #endif
+  gettime (&st->start);
 
-#ifdef HAVE_CLOCK_GETTIME
-  clock_gettime (CLOCK_MONOTONIC, &st->start);
-#else
-  gettimeofday(&st->start, NULL);
-#endif
   benchmark_must_finish = 0;
 
 #if defined _WIN32
@@ -127,11 +123,7 @@
 {
   double secs;
   unsigned long lsecs;
-#ifdef HAVE_CLOCK_GETTIME
   struct timespec stop;
-#else
-  struct timeval stop;
-#endif
   double dspeed, ddata;
   char imetric[16];
 
@@ -144,17 +136,10 @@
   signal (SIGALRM, st->old_handler);
 #endif
 
-#ifdef HAVE_CLOCK_GETTIME
-  clock_gettime (CLOCK_MONOTONIC, &stop);
+  gettime (&stop);
   lsecs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) -
 	   (st->start.tv_sec * 1000 + st->start.tv_nsec / (1000 * 1000)));
 
-#else
-  gettimeofday(&stop, NULL);
-  lsecs = (stop.tv_sec * 1000 + stop.tv_usec / (1000) -
-	   (st->start.tv_sec * 1000 + st->start.tv_usec / (1000)));
-#endif
-
   secs = lsecs;
   secs /= 1000;
 
diff --git a/src/benchmark.h b/src/benchmark.h
index 05cea9c..52ed1a4 100644
--- a/src/benchmark.h
+++ b/src/benchmark.h
@@ -20,7 +20,6 @@
 #ifndef BENCHMARK_H
 # define BENCHMARK_H
 
-#include <config.h>
 #include <sys/time.h>
 #include <time.h>
 #include <signal.h>
@@ -28,16 +27,13 @@
 #include <windows.h>
 #endif
 #include <time.h>
+#include "timespec.h"          /* gnulib gettime */
 
 typedef void (*sighandler_t) (int);
 
 struct benchmark_st
 {
-#ifdef HAVE_CLOCK_GETTIME
   struct timespec start;
-#else
-  struct timeval start;
-#endif
   unsigned long size;
   sighandler_t old_handler;
 #if defined _WIN32