gcc/libgm2/libm2iso/wraptime.cc
Gaius Mulley d1a1f7e9f0 PR modula2/115276 bugfix libgm2 wraptime.InitTM returns NIL
This patch fixes libgm2/libm2iso/wraptime.cc:InitTM so that
it does not always return NULL.  The incorrect autoconf macro
was used (inside InitTM) and the function short circuited
to return NULL.  The fix is to use HAVE_SYS_TIME_H and use
AC_HEADER_TIME in libgm2/configure.ac.

libgm2/ChangeLog:

	PR modula2/115276
	* config.h.in: Regenerate.
	* configure: Regenerate.
	* configure.ac: Use AC_HEADER_TIME.
	* libm2iso/wraptime.cc (InitTM): Check HAVE_SYS_TIME_H
	before using struct tm to obtain the size.

gcc/testsuite/ChangeLog:

	PR modula2/115276
	* gm2/isolib/run/pass/testinittm.mod: New test.

Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
2024-05-29 17:26:59 +01:00

423 lines
8.6 KiB
C++

/* wraptime.c 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 ## _wraptime_ ## FUNC
#define M2EXPORT(FUNC) m2iso ## _M2_wraptime_ ## FUNC
#define M2LIBNAME "m2iso"
#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
/* InitTimeval returns a newly created opaque type. */
#if defined(HAVE_STRUCT_TIMEVAL) && defined(HAVE_MALLOC_H)
extern "C" struct timeval *
EXPORT(InitTimeval) (void)
{
return (struct timeval *)malloc (sizeof (struct timeval));
}
#else
extern "C" void *
EXPORT(InitTimeval) (void)
{
return NULL;
}
#endif
/* KillTimeval deallocates the memory associated with an opaque type. */
extern "C" struct timeval *
EXPORT(KillTimeval) (void *tv)
{
#if defined(HAVE_MALLOC_H)
free (tv);
#endif
return NULL;
}
/* InitTimezone returns a newly created opaque type. */
#if defined(HAVE_STRUCT_TIMEZONE) && defined(HAVE_MALLOC_H)
extern "C" struct timezone *
EXPORT(InitTimezone) (void)
{
return (struct timezone *)malloc (sizeof (struct timezone));
}
#else
extern "C" void *
EXPORT(InitTimezone) (void)
{
return NULL;
}
#endif
/* KillTimezone - deallocates the memory associated with an opaque
type. */
extern "C" struct timezone *
EXPORT(KillTimezone) (struct timezone *tv)
{
#if defined(HAVE_MALLOC_H)
free (tv);
#endif
return NULL;
}
/* InitTM - returns a newly created opaque type. */
#if defined(HAVE_SYS_TIME_H) && defined(HAVE_MALLOC_H)
extern "C" struct tm *
EXPORT(InitTM) (void)
{
return (struct tm *)malloc (sizeof (struct tm));
}
#else
extern "C" void *
EXPORT(InitTM) (void)
{
return NULL;
}
#endif
/* KillTM - deallocates the memory associated with an opaque type. */
extern "C" struct tm *
EXPORT(KillTM) (struct tm *tv)
{
#if defined(HAVE_MALLOC_H)
free (tv);
#endif
return NULL;
}
/* gettimeofday - calls gettimeofday(2) with the same parameters, tv,
and, tz. It returns 0 on success. */
#if defined(HAVE_STRUCT_TIMEZONE) && defined(HAVE_GETTIMEOFDAY)
extern "C" int
EXPORT(gettimeofday) (void *tv, struct timezone *tz)
{
return gettimeofday ((struct timeval *) tv, tz);
}
#else
extern "C" int
EXPORT(gettimeofday) (void *tv, void *tz)
{
return -1;
}
#endif
/* settimeofday - calls settimeofday(2) with the same parameters, tv,
and, tz. It returns 0 on success. */
#if defined(HAVE_STRUCT_TIMEZONE) && defined(HAVE_SETTIMEOFDAY)
extern "C" int
EXPORT(settimeofday) (void *tv, struct timezone *tz)
{
return settimeofday ((struct timeval *) tv, tz);
}
#else
extern "C" int
EXPORT(settimeofday) (void *tv, void *tz)
{
return -1;
}
#endif
/* wraptime_GetFractions - returns the tv_usec field inside the
timeval structure. */
#if defined(HAVE_STRUCT_TIMEVAL)
extern "C" unsigned int
EXPORT(GetFractions) (struct timeval *tv)
{
return (unsigned int)tv->tv_usec;
}
#else
extern "C" unsigned int
EXPORT(GetFractions) (void *tv)
{
return (unsigned int)-1;
}
#endif
/* localtime_r - returns the tm parameter, m, after it has been
assigned with appropriate contents determined by, tv. Notice that
this procedure function expects, timeval, as its first parameter
and not a time_t (as expected by the posix equivalent). */
#if defined(HAVE_STRUCT_TIMEVAL)
extern "C" struct tm *
EXPORT(localtime_r) (struct timeval *tv, struct tm *m)
{
return localtime_r (&tv->tv_sec, m);
}
#else
extern "C" struct tm *
EXPORT(localtime_r) (void *tv, struct tm *m)
{
return m;
}
#endif
/* wraptime_GetYear - returns the year from the structure, m. */
#if defined(HAVE_STRUCT_TM)
extern "C" unsigned int
EXPORT(GetYear) (struct tm *m)
{
return m->tm_year;
}
#else
extern "C" unsigned int
EXPORT(GetYear) (void *m)
{
return (unsigned int)-1;
}
#endif
/* wraptime_GetMonth - returns the month from the structure, m. */
#if defined(HAVE_STRUCT_TM)
extern "C" unsigned int
EXPORT(GetMonth) (struct tm *m)
{
return m->tm_mon;
}
#else
extern "C" unsigned int
EXPORT(GetMonth) (void *m)
{
return (unsigned int)-1;
}
#endif
/* wraptime_GetDay - returns the day of the month from the structure,
m. */
#if defined(HAVE_STRUCT_TM)
extern "C" unsigned int
EXPORT(GetDay) (struct tm *m)
{
return m->tm_mday;
}
#else
extern "C" unsigned int
EXPORT(GetDay) (void *m)
{
return (unsigned int)-1;
}
#endif
/* wraptime_GetHour - returns the hour of the day from the structure,
m. */
#if defined(HAVE_STRUCT_TM)
extern "C" unsigned int
EXPORT(GetHour) (struct tm *m)
{
return m->tm_hour;
}
#else
extern "C" unsigned int
EXPORT(GetHour) (void *m)
{
return (unsigned int)-1;
}
#endif
/* wraptime_GetMinute - returns the minute within the hour from the
structure, m. */
#if defined(HAVE_STRUCT_TM)
extern "C" unsigned int
EXPORT(GetMinute) (struct tm *m)
{
return m->tm_min;
}
#else
extern "C" unsigned int
EXPORT(GetMinute) (void *m)
{
return (unsigned int)-1;
}
#endif
/* wraptime_GetSecond - returns the seconds in the minute from the
structure, m. The return value will always be in the range 0..59.
A leap minute of value 60 will be truncated to 59. */
#if defined(HAVE_STRUCT_TM)
extern "C" unsigned int
EXPORT(GetSecond) (struct tm *m)
{
if (m->tm_sec == 60)
return 59;
else
return m->tm_sec;
}
#else
extern "C" unsigned int
EXPORT(GetSecond) (void *m)
{
return (unsigned int)-1;
}
#endif
/* wraptime_GetSummerTime - returns true if summer time is in effect. */
#if defined(HAVE_STRUCT_TIMEZONE)
extern "C" bool
EXPORT(GetSummerTime) (struct timezone *tz)
{
return tz->tz_dsttime != 0;
}
#else
extern "C" bool
EXPORT(GetSummerTime) (void *tz)
{
return false;
}
#endif
/* wraptime_GetDST - returns the number of minutes west of GMT. */
#if defined(HAVE_STRUCT_TIMEZONE)
extern "C" int
EXPORT(GetDST) (struct timezone *tz)
{
return tz->tz_minuteswest;
}
#else
extern "C" int
EXPORT(GetDST) (void *tz)
{
#if defined(INT_MIN)
return INT_MIN;
#else
return (int)((unsigned int)-1);
#endif
}
#endif
/* SetTimezone - set the timezone field inside timeval, tv. */
#if defined(HAVE_STRUCT_TIMEZONE)
extern "C" void
EXPORT(SetTimezone) (struct timezone *tz, int zone, int minuteswest)
{
tz->tz_dsttime = zone;
tz->tz_minuteswest = minuteswest;
}
#else
extern "C" void
EXPORT(SetTimezone) (void *tz, int zone, int minuteswest)
{
}
#endif
/* SetTimeval - sets the fields in tm, t, with: second, minute, hour,
day, month, year, fractions. */
#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,
unsigned int year, unsigned int yday, unsigned int wday,
unsigned int isdst)
{
t->tm_sec = second;
t->tm_min = minute;
t->tm_hour = hour;
t->tm_mday = day;
t->tm_mon = month;
t->tm_year = year;
t->tm_yday = yday;
t->tm_wday = wday;
t->tm_isdst = isdst;
}
#else
extern "C" void
EXPORT(SetTimeval) (void *t, unsigned int second, unsigned int minute,
unsigned int hour, unsigned int day, unsigned int month,
unsigned int year, unsigned int yday, unsigned int wday,
unsigned int isdst)
{
}
#endif
/* 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 ("wraptime", M2LIBNAME,
M2EXPORT(init), M2EXPORT(fini),
M2EXPORT(dep));
}