aboutsummaryrefslogtreecommitdiff
path: root/libgm2
diff options
context:
space:
mode:
authorGaius Mulley <gaiusmod2@gmail.com>2023-08-05 17:35:12 +0100
committerGaius Mulley <gaiusmod2@gmail.com>2023-08-05 17:35:12 +0100
commit0826ebd633e38bd55abd161c15deb431420f82a3 (patch)
treec21e03c3a4b5bf1693305dc4b7f0d00ae0463d07 /libgm2
parent39f413fc4b6979d194f2f736bd663eb7f5045168 (diff)
downloadgcc-0826ebd633e38bd55abd161c15deb431420f82a3.zip
gcc-0826ebd633e38bd55abd161c15deb431420f82a3.tar.gz
gcc-0826ebd633e38bd55abd161c15deb431420f82a3.tar.bz2
PR modula2/110779 SysClock can not read the clock
This patch completes the implementation of the ISO module SysClock.mod. Three new testcases are provided. wrapclock.{cc,def} are new support files providing access to clock_settime, clock_gettime and glibc timezone variables. gcc/m2/ChangeLog: PR modula2/110779 * gm2-libs-iso/SysClock.mod: Re-implement using wrapclock. * gm2-libs-iso/wrapclock.def: New file. libgm2/ChangeLog: PR modula2/110779 * config.h.in: Regenerate. * configure: Regenerate. * configure.ac (GM2_CHECK_LIB): Check for clock_gettime and clock_settime. * libm2iso/Makefile.am (M2DEFS): Add wrapclock.def. * libm2iso/Makefile.in: Regenerate. * libm2iso/wraptime.cc: Replace HAVE_TIMEVAL with HAVE_STRUCT_TIMEVAL. * libm2iso/wrapclock.cc: New file. gcc/testsuite/ChangeLog: PR modula2/110779 * gm2/iso/run/pass/m2date.mod: New test. * gm2/iso/run/pass/testclock.mod: New test. * gm2/iso/run/pass/testclock2.mod: New test. Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
Diffstat (limited to 'libgm2')
-rw-r--r--libgm2/config.h.in9
-rwxr-xr-xlibgm2/configure147
-rw-r--r--libgm2/configure.ac4
-rw-r--r--libgm2/libm2iso/Makefile.am6
-rw-r--r--libgm2/libm2iso/Makefile.in11
-rw-r--r--libgm2/libm2iso/wrapclock.cc220
-rw-r--r--libgm2/libm2iso/wraptime.cc9
7 files changed, 393 insertions, 13 deletions
diff --git a/libgm2/config.h.in b/libgm2/config.h.in
index 443008e..8372055 100644
--- a/libgm2/config.h.in
+++ b/libgm2/config.h.in
@@ -9,6 +9,12 @@
/* function cfmakeraw exists */
#undef HAVE_CFMAKERAW
+/* function clock_gettime exists */
+#undef HAVE_CLOCK_GETTIME
+
+/* function clock_settime exists */
+#undef HAVE_CLOCK_SETTIME
+
/* function close exists */
#undef HAVE_CLOSE
@@ -180,6 +186,9 @@
/* Define to 1 if the system has the type `struct stat'. */
#undef HAVE_STRUCT_STAT
+/* Define to 1 if the system has the type `struct timespec'. */
+#undef HAVE_STRUCT_TIMESPEC
+
/* Define to 1 if the system has the type `struct timeval'. */
#undef HAVE_STRUCT_TIMEVAL
diff --git a/libgm2/configure b/libgm2/configure
index da3d3bd..488055b 100755
--- a/libgm2/configure
+++ b/libgm2/configure
@@ -16074,6 +16074,15 @@ _ACEOF
fi
+ac_fn_c_check_type "$LINENO" "struct timespec" "ac_cv_type_struct_timespec" "$ac_includes_default"
+if test "x$ac_cv_type_struct_timespec" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_TIMESPEC 1
+_ACEOF
+
+
+fi
ac_fn_c_check_type "$LINENO" "struct timeval" "ac_cv_type_struct_timeval" "$ac_includes_default"
if test "x$ac_cv_type_struct_timeval" = xyes; then :
@@ -16913,6 +16922,144 @@ $as_echo "#define HAVE_CFMAKERAW 1" >>confdefs.h
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for clock_gettime" >&5
+$as_echo_n "checking m2 front end checking c library for clock_gettime... " >&6; }
+ if test x$gcc_no_link != xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lc" >&5
+$as_echo_n "checking for clock_gettime in -lc... " >&6; }
+if ${ac_cv_lib_c_clock_gettime+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc $LIBS"
+if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_c_clock_gettime=yes
+else
+ ac_cv_lib_c_clock_gettime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_clock_gettime" >&5
+$as_echo "$ac_cv_lib_c_clock_gettime" >&6; }
+if test "x$ac_cv_lib_c_clock_gettime" = xyes; then :
+
+$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
+
+else
+
+ $as_echo "#undef HAVE_CLOCK_GETTIME" >>confdefs.h
+
+fi
+
+ else
+ if test "x$ac_cv_lib_c_clock_gettime" = xyes; then
+
+$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
+
+ elif test "x$ac_cv_func_clock_gettime" = xyes; then
+
+$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
+
+ else
+
+ $as_echo "#undef HAVE_CLOCK_GETTIME" >>confdefs.h
+
+ fi
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for clock_settime" >&5
+$as_echo_n "checking m2 front end checking c library for clock_settime... " >&6; }
+ if test x$gcc_no_link != xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_settime in -lc" >&5
+$as_echo_n "checking for clock_settime in -lc... " >&6; }
+if ${ac_cv_lib_c_clock_settime+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc $LIBS"
+if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_settime ();
+int
+main ()
+{
+return clock_settime ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_c_clock_settime=yes
+else
+ ac_cv_lib_c_clock_settime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_clock_settime" >&5
+$as_echo "$ac_cv_lib_c_clock_settime" >&6; }
+if test "x$ac_cv_lib_c_clock_settime" = xyes; then :
+
+$as_echo "#define HAVE_CLOCK_SETTIME 1" >>confdefs.h
+
+else
+
+ $as_echo "#undef HAVE_CLOCK_SETTIME" >>confdefs.h
+
+fi
+
+ else
+ if test "x$ac_cv_lib_c_clock_settime" = xyes; then
+
+$as_echo "#define HAVE_CLOCK_SETTIME 1" >>confdefs.h
+
+ elif test "x$ac_cv_func_clock_settime" = xyes; then
+
+$as_echo "#define HAVE_CLOCK_SETTIME 1" >>confdefs.h
+
+ else
+
+ $as_echo "#undef HAVE_CLOCK_SETTIME" >>confdefs.h
+
+ fi
+ fi
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for close" >&5
$as_echo_n "checking m2 front end checking c library for close... " >&6; }
if test x$gcc_no_link != xyes; then
diff --git a/libgm2/configure.ac b/libgm2/configure.ac
index c78c833..d64a8ee 100644
--- a/libgm2/configure.ac
+++ b/libgm2/configure.ac
@@ -187,7 +187,7 @@ else
multilib_arg=
fi
-AC_CHECK_TYPES([struct timezone, struct stat, struct timeval])
+AC_CHECK_TYPES([struct timezone, struct stat, struct timespec, struct timeval])
AC_LANG_C
# Check the compiler.
@@ -225,6 +225,8 @@ AC_DEFUN([GM2_CHECK_LIB],[
GM2_CHECK_LIB([c],[access],[ACCESS])
GM2_CHECK_LIB([c],[brk],[BRK])
GM2_CHECK_LIB([c],[cfmakeraw],[CFMAKERAW])
+GM2_CHECK_LIB([c],[clock_gettime],[CLOCK_GETTIME])
+GM2_CHECK_LIB([c],[clock_settime],[CLOCK_SETTIME])
GM2_CHECK_LIB([c],[close],[CLOSE])
GM2_CHECK_LIB([c],[ctime],[CTIME])
GM2_CHECK_LIB([c],[creat],[CREAT])
diff --git a/libgm2/libm2iso/Makefile.am b/libgm2/libm2iso/Makefile.am
index 8c70f5c..1386f15 100644
--- a/libgm2/libm2iso/Makefile.am
+++ b/libgm2/libm2iso/Makefile.am
@@ -136,8 +136,8 @@ M2DEFS = ChanConsts.def CharClass.def \
TERMINATION.def TextIO.def \
TextUtil.def \
WholeConv.def WholeIO.def \
- WholeStr.def wrapsock.def \
- wraptime.def
+ WholeStr.def wrapclock.def \
+ wrapsock.def wraptime.def
M2MODS = ChanConsts.mod CharClass.mod \
ClientSocket.mod ComplexMath.mod \
@@ -180,7 +180,7 @@ M2MODS = ChanConsts.mod CharClass.mod \
toolexeclib_LTLIBRARIES = libm2iso.la
libm2iso_la_SOURCES = $(M2MODS) \
- ErrnoCategory.cc wraptime.cc RTco.cc wrapsock.c
+ ErrnoCategory.cc RTco.cc wrapclock.cc wraptime.cc wrapsock.c
# wrapsock.cc
C_INCLUDES = -I.. -I$(toplevel_srcdir)/libiberty -I$(toplevel_srcdir)/include
diff --git a/libgm2/libm2iso/Makefile.in b/libgm2/libm2iso/Makefile.in
index 6787a5a..b939581 100644
--- a/libgm2/libm2iso/Makefile.in
+++ b/libgm2/libm2iso/Makefile.in
@@ -179,8 +179,8 @@ libm2iso_la_LIBADD =
@BUILD_ISOLIB_TRUE@ TextIO.lo TextUtil.lo WholeConv.lo \
@BUILD_ISOLIB_TRUE@ WholeIO.lo WholeStr.lo
@BUILD_ISOLIB_TRUE@am_libm2iso_la_OBJECTS = $(am__objects_1) \
-@BUILD_ISOLIB_TRUE@ ErrnoCategory.lo wraptime.lo RTco.lo \
-@BUILD_ISOLIB_TRUE@ libm2iso_la-wrapsock.lo
+@BUILD_ISOLIB_TRUE@ ErrnoCategory.lo RTco.lo wrapclock.lo \
+@BUILD_ISOLIB_TRUE@ wraptime.lo libm2iso_la-wrapsock.lo
libm2iso_la_OBJECTS = $(am_libm2iso_la_OBJECTS)
@BUILD_ISOLIB_TRUE@am_libm2iso_la_rpath = -rpath $(toolexeclibdir)
AM_V_P = $(am__v_P_@AM_V@)
@@ -513,8 +513,8 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS)
@BUILD_ISOLIB_TRUE@ TERMINATION.def TextIO.def \
@BUILD_ISOLIB_TRUE@ TextUtil.def \
@BUILD_ISOLIB_TRUE@ WholeConv.def WholeIO.def \
-@BUILD_ISOLIB_TRUE@ WholeStr.def wrapsock.def \
-@BUILD_ISOLIB_TRUE@ wraptime.def
+@BUILD_ISOLIB_TRUE@ WholeStr.def wrapclock.def \
+@BUILD_ISOLIB_TRUE@ wrapsock.def wraptime.def
@BUILD_ISOLIB_TRUE@M2MODS = ChanConsts.mod CharClass.mod \
@BUILD_ISOLIB_TRUE@ ClientSocket.mod ComplexMath.mod \
@@ -557,7 +557,7 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS)
@BUILD_ISOLIB_TRUE@toolexeclib_LTLIBRARIES = libm2iso.la
@BUILD_ISOLIB_TRUE@libm2iso_la_SOURCES = $(M2MODS) \
-@BUILD_ISOLIB_TRUE@ ErrnoCategory.cc wraptime.cc RTco.cc wrapsock.c
+@BUILD_ISOLIB_TRUE@ ErrnoCategory.cc RTco.cc wrapclock.cc wraptime.cc wrapsock.c
# wrapsock.cc
@BUILD_ISOLIB_TRUE@C_INCLUDES = -I.. -I$(toplevel_srcdir)/libiberty -I$(toplevel_srcdir)/include
@@ -658,6 +658,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ErrnoCategory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RTco.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libm2iso_la-wrapsock.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapclock.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wraptime.Plo@am__quote@
.c.o:
diff --git a/libgm2/libm2iso/wrapclock.cc b/libgm2/libm2iso/wrapclock.cc
new file mode 100644
index 0000000..7ee1f25
--- /dev/null
+++ b/libgm2/libm2iso/wrapclock.cc
@@ -0,0 +1,220 @@
+/* wrapclock.cc provides access to time related system calls.
+
+Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 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, or (at your option)
+any later version.
+
+GNU Modula-2 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include <m2rts.h>
+
+#define EXPORT(FUNC) m2iso ## _wrapclock_ ## FUNC
+#define M2EXPORT(FUNC) m2iso ## _M2_wrapclock_ ## FUNC
+#define M2LIBNAME "m2iso"
+
+#if defined(HAVE_STDLIB_H)
+#include "stdlib.h"
+#endif
+
+#if defined(HAVE_UNISTD_H)
+#include "unistd.h"
+#endif
+
+#if defined(HAVE_SYS_TYPES_H)
+#include "sys/types.h"
+#endif
+
+#if defined(HAVE_SYS_TIME_H)
+#include "sys/time.h"
+#endif
+
+#if defined(HAVE_TIME_H)
+#include "time.h"
+#endif
+
+#if defined(HAVE_MALLOC_H)
+#include "malloc.h"
+#endif
+
+#if defined(HAVE_LIMITS_H)
+#include "limits.h"
+#endif
+
+#if !defined(NULL)
+#define NULL (void *)0
+#endif
+
+
+extern "C" long int
+EXPORT(timezone) (void)
+{
+ struct tm result;
+ struct timespec ts;
+
+ if (clock_gettime (CLOCK_REALTIME, &ts) == 0)
+ {
+ time_t time = ts.tv_sec;
+ localtime_r (&time, &result);
+ return result.tm_gmtoff;
+ }
+ else
+ return timezone;
+}
+
+
+extern "C" int
+EXPORT(daylight) (void)
+{
+ return daylight;
+}
+
+
+/* isdst returns 1 if daylight saving time is currently in effect and
+ returns 0 if it is not. */
+
+extern "C" int
+EXPORT(isdst) (void)
+{
+ struct tm result;
+ struct timespec ts;
+
+ if (clock_gettime (CLOCK_REALTIME, &ts) == 0)
+ {
+ time_t time = ts.tv_sec;
+ localtime_r (&time, &result);
+ return result.tm_isdst;
+ }
+ else
+ return 0;
+}
+
+
+/* tzname returns the string associated with the local timezone.
+ The daylight value is 0 or 1. The value 0 returns the non
+ daylight saving timezone string and the value of 1 returns the
+ daylight saving timezone string. */
+
+extern "C" char *
+EXPORT(tzname) (int daylight)
+{
+ return tzname[daylight];
+}
+
+
+/* GetTimeRealtime performs return gettime (CLOCK_REALTIME, ts).
+ gettime returns 0 on success and -1 on failure. If the underlying
+ system does not have gettime then GetTimeRealtime returns 1. */
+
+extern "C" int
+EXPORT(GetTimeRealtime) (struct timespec *ts)
+{
+#if defined(HAVE_CLOCK_GETTIME)
+ return clock_gettime (CLOCK_REALTIME, ts);
+#else
+ return 1;
+#endif
+}
+
+
+/* SetTimeRealtime performs return settime (CLOCK_REALTIME, ts).
+ gettime returns 0 on success and -1 on failure. If the underlying
+ system does not have gettime then GetTimeRealtime returns 1. */
+
+extern "C" int
+EXPORT(SetTimeRealtime) (struct timespec *ts)
+{
+#if defined(HAVE_CLOCK_GETTIME)
+ return clock_settime (CLOCK_REALTIME, ts);
+#else
+ return 1;
+#endif
+}
+
+
+/* InitTimespec returns a newly created opaque type. */
+
+extern "C" struct timespec *
+EXPORT(InitTimespec) (void)
+{
+ return (struct timespec *)malloc (sizeof (struct timespec));
+}
+
+
+/* KillTimeval deallocates the memory associated with an opaque type. */
+
+extern "C" struct timespec *
+EXPORT(KillTimespec) (void *ts)
+{
+#if defined(HAVE_MALLOC_H)
+ free (ts);
+#endif
+ return NULL;
+}
+
+
+/* GetTimespec retrieves the number of seconds and nanoseconds from the
+ timespec. */
+
+extern "C" void
+EXPORT(GetTimespec) (timespec *ts, unsigned long *sec, unsigned long *nano)
+{
+ *sec = ts->tv_sec;
+ *nano = ts->tv_nsec;
+}
+
+
+/* SetTimespec sets the number of seconds and nanoseconds into timespec. */
+
+extern "C" void
+EXPORT(SetTimespec) (timespec *ts, unsigned long sec, unsigned long nano)
+{
+ ts->tv_sec = sec;
+ ts->tv_nsec = nano;
+}
+
+
+/* init - init/finish functions for the module */
+
+/* GNU Modula-2 linking hooks. */
+
+extern "C" void
+M2EXPORT(init) (int, char **, char **)
+{
+}
+
+extern "C" void
+M2EXPORT(fini) (int, char **, char **)
+{
+}
+
+extern "C" void
+M2EXPORT(dep) (void)
+{
+}
+
+extern "C" void __attribute__((__constructor__))
+M2EXPORT(ctor) (void)
+{
+ m2iso_M2RTS_RegisterModule ("wrapclock", M2LIBNAME,
+ M2EXPORT(init), M2EXPORT(fini),
+ M2EXPORT(dep));
+}
diff --git a/libgm2/libm2iso/wraptime.cc b/libgm2/libm2iso/wraptime.cc
index ffe85f1..f1158ae 100644
--- a/libgm2/libm2iso/wraptime.cc
+++ b/libgm2/libm2iso/wraptime.cc
@@ -55,9 +55,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define NULL (void *)0
#endif
+
/* InitTimeval returns a newly created opaque type. */
-#if defined(HAVE_TIMEVAL) && defined(HAVE_MALLOC_H)
+#if defined(HAVE_STRUCT_TIMEVAL) && defined(HAVE_MALLOC_H)
extern "C" struct timeval *
EXPORT(InitTimeval) (void)
{
@@ -174,7 +175,7 @@ EXPORT(settimeofday) (void *tv, void *tz)
/* wraptime_GetFractions - returns the tv_usec field inside the
timeval structure. */
-#if defined(HAVE_TIMEVAL)
+#if defined(HAVE_STRUCT_TIMEVAL)
extern "C" unsigned int
EXPORT(GetFractions) (struct timeval *tv)
{
@@ -193,7 +194,7 @@ EXPORT(GetFractions) (void *tv)
this procedure function expects, timeval, as its first parameter
and not a time_t (as expected by the posix equivalent). */
-#if defined(HAVE_TIMEVAL)
+#if defined(HAVE_STRUCT_TIMEVAL)
extern "C" struct tm *
EXPORT(localtime_r) (struct timeval *tv, struct tm *m)
{
@@ -366,7 +367,7 @@ EXPORT(SetTimezone) (void *tz, int zone, int minuteswest)
/* SetTimeval - sets the fields in tm, t, with: second, minute, hour,
day, month, year, fractions. */
-#if defined(HAVE_TIMEVAL)
+#if defined(HAVE_STRUCT_TIMEVAL)
extern "C" void
EXPORT(SetTimeval) (struct tm *t, unsigned int second, unsigned int minute,
unsigned int hour, unsigned int day, unsigned int month,