Skip to content

Commit 8cc2d55

Browse files
committed
Rewrite using external functions from ModelicaTime.c
* Rewrite DateTime.'constructor'.fromEpoch to utilize ModelicaTime_localtime * Rewrite DateTime.'String'.formatted to utilize ModelicaTime_strftime * Rewrite DateTime.epoch to utilize ModelicaTime_difftime * Add DateTime.'constructor'.fromString utilizing ModelicaTime_strptime ModelicaTime.[ch] need to be integrated to ModelicaExternalC for later distribution. During development ModelicaTime.c is directly included by the external function declaration.
1 parent d222ae1 commit 8cc2d55

File tree

9 files changed

+971
-133
lines changed

9 files changed

+971
-133
lines changed

Modelica/Resources/BuildProjects/autotools/Makefile.am

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
lib_LTLIBRARIES = libzlib.la libModelicaExternalC.la libModelicaMatIO.la libModelicaIO.la libModelicaStandardTables.la
2-
libModelicaExternalC_la_SOURCES = ../../C-Sources/ModelicaFFT.c ../../C-Sources/ModelicaInternal.c ../../C-Sources/ModelicaRandom.c ../../C-Sources/ModelicaStrings.c
2+
libModelicaExternalC_la_SOURCES = ../../C-Sources/ModelicaFFT.c ../../C-Sources/ModelicaInternal.c ../../C-Sources/ModelicaRandom.c ../../C-Sources/ModelicaStrings.c ../../C-Sources/ModelicaTime.c
33
libModelicaExternalC_la_LIBADD = @LIBMATH@
44
libModelicaIO_la_SOURCES = ../../C-Sources/ModelicaIO.c
55
libModelicaIO_la_LIBADD = libModelicaMatIO.la

Modelica/Resources/BuildProjects/gcc/Makefile

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ EXTC_OBJS = \
1111
ModelicaFFT.o \
1212
ModelicaInternal.o \
1313
ModelicaRandom.o \
14-
ModelicaStrings.o
14+
ModelicaStrings.o \
15+
ModelicaTime.o
1516

1617
TABLES_OBJS = \
1718
ModelicaStandardTables.o \
@@ -93,6 +94,9 @@ ModelicaRandom.o: ../../C-Sources/ModelicaRandom.c
9394
ModelicaStrings.o: ../../C-Sources/ModelicaStrings.c
9495
$(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c -o $@ $<
9596

97+
ModelicaTime.o: ../../C-Sources/ModelicaTime.c
98+
$(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c -o $@ $<
99+
96100
%.o: ../../C-Sources/zlib/%.c
97101
$(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c -o $@ $<
98102

+210
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/* ModelicaTime.c - External functions for Modelica.Utilities.Time
2+
3+
Copyright (C) 2020, Modelica Association and contributors
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice,
10+
this list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright
13+
notice, this list of conditions and the following disclaimer in the
14+
documentation and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
// TODO: Remove when ModelicaTime.c will become part of ModelicaExternalC
33+
#if defined(DYMOSIM)
34+
#pragma once
35+
#endif
36+
37+
#include "ModelicaTime.h"
38+
39+
#include <math.h>
40+
#include <stdlib.h>
41+
#include <time.h>
42+
#include "ModelicaUtilities.h"
43+
#if !defined(__APPLE_CC__)
44+
#include "strptime.h"
45+
#endif
46+
47+
#if !defined(NO_TIME)
48+
time_t epoch(int sec, int min, int hour, int mday, int mon, int year) {
49+
struct tm tlocal;
50+
time_t calendarTime;
51+
52+
memset(&tlocal, 0, sizeof(struct tm));
53+
tlocal.tm_sec = sec;
54+
tlocal.tm_min = min;
55+
tlocal.tm_hour = hour;
56+
tlocal.tm_mday = mday;
57+
tlocal.tm_mon = mon - 1;
58+
tlocal.tm_year = year - 1900;
59+
60+
calendarTime = mktime(&tlocal);
61+
if (-1 == calendarTime) {
62+
ModelicaFormatError("Not possible to convert \"%4i-%02i-%02i %02i:%02i:%02i\" "
63+
"to time_t type in local time zone.\n", year, mon, mday, hour, min, sec);
64+
}
65+
return calendarTime;
66+
}
67+
#endif
68+
69+
double ModelicaTime_difftime(int sec, int min, int hour, int mday, int mon,
70+
int year, int refYear) {
71+
/* Get elapsed seconds w.r.t. reference year */
72+
#if defined(NO_TIME)
73+
return 0.0;
74+
#else
75+
const time_t endTime = epoch(sec, min, hour, mday, mon, year);
76+
if (1970 == refYear) {
77+
/* Avoid calling mktime for New Year 1970 in local time zone */
78+
const time_t startTime = epoch(0, 0, 0, 2, 1, 1970);
79+
return difftime(endTime, startTime) + 86400.0;
80+
}
81+
else {
82+
const time_t startTime = epoch(0, 0, 0, 1, 1, refYear);
83+
return difftime(endTime, startTime);
84+
}
85+
#endif
86+
}
87+
88+
void ModelicaTime_localtime(_Out_ int* ms, _Out_ int* sec, _Out_ int* min,
89+
_Out_ int* hour, _Out_ int* mday, _Out_ int* mon,
90+
_Out_ int* year, double seconds, int refYear) {
91+
/* Convert elapsed seconds w.r.t. reference year */
92+
#if defined(NO_TIME)
93+
*ms = 0;
94+
*sec = 0;
95+
*min = 0;
96+
*hour = 0;
97+
*mday = 0;
98+
*mon = 0;
99+
*year = 0;
100+
#else
101+
struct tm* tlocal;
102+
time_t calendarTime;
103+
double intPartOfSeconds;
104+
double fracPartOfSeconds;
105+
#if defined(_POSIX_) || (defined(_MSC_VER) && _MSC_VER >= 1400)
106+
struct tm tres;
107+
#endif
108+
109+
fracPartOfSeconds = modf(seconds, &intPartOfSeconds);
110+
calendarTime = (time_t)intPartOfSeconds;
111+
112+
if (1970 == refYear) {
113+
/* Avoid calling mktime for New Year 1970 in local time zone */
114+
calendarTime = calendarTime + epoch(0, 0, 0, 2, 1, 1970) - (time_t)86400;
115+
}
116+
else {
117+
calendarTime = calendarTime + epoch(0, 0, 0, 1, 1, refYear);
118+
}
119+
120+
#if defined(_POSIX_)
121+
tlocal = localtime_r(&calendarTime, &tres); /* Time fields in local time zone */
122+
#elif defined(_MSC_VER) && _MSC_VER >= 1400
123+
localtime_s(&tres, &calendarTime); /* Time fields in local time zone */
124+
tlocal = &tres;
125+
#else
126+
tlocal = localtime(&calendarTime); /* Time fields in local time zone */
127+
#endif
128+
129+
/* Do not memcpy as you do not know which sizes are in the struct */
130+
*ms = (int)(fracPartOfSeconds*1000.0 + 0.5);
131+
*sec = tlocal->tm_sec;
132+
*min = tlocal->tm_min;
133+
*hour = tlocal->tm_hour;
134+
*mday = tlocal->tm_mday;
135+
*mon = 1 + tlocal->tm_mon; /* Correct for month starting at 1 */
136+
*year = 1900 + tlocal->tm_year; /* Correct for 4-digit year */
137+
#endif
138+
}
139+
140+
_Ret_z_ const char* ModelicaTime_strftime(int sec, int min, int hour, int mday, int mon,
141+
int year, _In_z_ const char* format, int _maxSize) {
142+
/* Formatted time to string conversion */
143+
#if defined(NO_TIME)
144+
return "";
145+
#else
146+
size_t retLen;
147+
struct tm* tlocal;
148+
const size_t maxSize = (size_t)_maxSize;
149+
char* timePtr = ModelicaAllocateString(maxSize);
150+
time_t calendarTime = epoch(sec, min, hour, mday, mon, year);
151+
#if defined(_POSIX_) || (defined(_MSC_VER) && _MSC_VER >= 1400)
152+
struct tm tres;
153+
#endif
154+
155+
#if defined(_POSIX_)
156+
tlocal = localtime_r(&calendarTime, &tres); /* Time fields in local time zone */
157+
#elif defined(_MSC_VER) && _MSC_VER >= 1400
158+
localtime_s(&tres, &calendarTime); /* Time fields in local time zone */
159+
tlocal = &tres;
160+
#else
161+
tlocal = localtime(&calendarTime); /* Time fields in local time zone */
162+
#endif
163+
164+
retLen = strftime(timePtr, maxSize, format, tlocal);
165+
if (retLen > 0 && retLen <= maxSize) {
166+
return (const char*)timePtr;
167+
}
168+
else {
169+
return "";
170+
}
171+
#endif
172+
}
173+
174+
void ModelicaTime_strptime(_Out_ int* ms, _Out_ int* sec, _Out_ int* min,
175+
_Out_ int* hour, _Out_ int* mday, _Out_ int* mon,
176+
_Out_ int* year, _In_z_ const char* buf,
177+
_In_z_ const char* format) {
178+
/* Formatted string to time conversion */
179+
#if defined(NO_TIME)
180+
*ms = 0;
181+
*sec = 0;
182+
*min = 0;
183+
*hour = 0;
184+
*mday = 0;
185+
*mon = 0;
186+
*year = 0;
187+
#else
188+
struct tm tlocal;
189+
190+
memset(&tlocal, 0, sizeof(struct tm));
191+
if (strptime(buf, format, &tlocal)) {
192+
/* Do not memcpy as you do not know which sizes are in the struct */
193+
*sec = tlocal.tm_sec;
194+
*min = tlocal.tm_min;
195+
*hour = tlocal.tm_hour;
196+
*mday = tlocal.tm_mday;
197+
*mon = 1 + tlocal.tm_mon; /* Correct for month starting at 1 */
198+
*year = 1900 + tlocal.tm_year; /* Correct for 4-digit year */
199+
}
200+
else {
201+
*sec = 0;
202+
*min = 0;
203+
*hour = 0;
204+
*mday = 0;
205+
*mon = 0;
206+
*year = 0;
207+
}
208+
*ms = 0;
209+
#endif
210+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/* ModelicaTime.h - External functions for Modelica.Utilities.Time
2+
3+
Copyright (C) 2020, Modelica Association and contributors
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice,
10+
this list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright
13+
notice, this list of conditions and the following disclaimer in the
14+
documentation and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
/* The following #define's are available.
33+
34+
NO_TIME : Functions localtime and mktime are not present
35+
MODELICA_EXPORT: Prefix used for function calls. If not defined, blank is used
36+
Useful definition:
37+
- "__declspec(dllexport)" if included in a DLL and the
38+
functions shall be visible outside of the DLL
39+
*/
40+
41+
#ifndef MODELICA_TIME_H_
42+
#define MODELICA_TIME_H_
43+
44+
#if !defined(MODELICA_EXPORT)
45+
#if defined(__cplusplus)
46+
#define MODELICA_EXPORT extern "C"
47+
#else
48+
#define MODELICA_EXPORT
49+
#endif
50+
#endif
51+
52+
/*
53+
* Non-null pointers and esp. null-terminated strings need to be passed to
54+
* external functions.
55+
*
56+
* The following macros handle nonnull attributes for GNU C and Microsoft SAL.
57+
*/
58+
#undef MODELICA_NONNULLATTR
59+
#undef MODELICA_RETURNNONNULLATTR
60+
#if defined(__GNUC__)
61+
#define MODELICA_NONNULLATTR __attribute__((nonnull))
62+
#if defined(__GNUC_MINOR__) && (__GNUC__ > 3 && __GNUC_MINOR__ > 8)
63+
#define MODELICA_RETURNNONNULLATTR __attribute__((returns_nonnull))
64+
#else
65+
#define MODELICA_RETURNNONNULLATTR
66+
#endif
67+
#elif defined(__ATTR_SAL)
68+
#define MODELICA_NONNULLATTR
69+
#define MODELICA_RETURNNONNULLATTR _Ret_z_ /* _Ret_notnull_ and null-terminated */
70+
#else
71+
#define MODELICA_NONNULLATTR
72+
#define MODELICA_RETURNNONNULLATTR
73+
#endif
74+
#if !defined(__ATTR_SAL)
75+
#undef _In_z_
76+
#undef _Out_
77+
#undef _Ret_z_
78+
#define _In_z_
79+
#define _Out_
80+
#define _Ret_z_
81+
#endif
82+
83+
MODELICA_EXPORT double ModelicaTime_difftime(int sec, int min, int hour,
84+
int mday, int mon, int year, int refYear);
85+
MODELICA_EXPORT void ModelicaTime_localtime(_Out_ int* ms, _Out_ int* sec,
86+
_Out_ int* min, _Out_ int* hour, _Out_ int* mday, _Out_ int* mon,
87+
_Out_ int* year, double seconds, int refYear) MODELICA_NONNULLATTR;
88+
MODELICA_EXPORT MODELICA_RETURNNONNULLATTR const char* ModelicaTime_strftime(
89+
int sec, int min, int hour, int mday, int mon, int year,
90+
_In_z_ const char* format, int _maxSize) MODELICA_NONNULLATTR;
91+
MODELICA_EXPORT void ModelicaTime_strptime(_Out_ int* ms, _Out_ int* sec,
92+
_Out_ int* min, _Out_ int* hour, _Out_ int* mday, _Out_ int* mon,
93+
_Out_ int* year, _In_z_ const char* buf,
94+
_In_z_ const char* format) MODELICA_NONNULLATTR;
95+
96+
#endif

Modelica/Resources/C-Sources/readme.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ to the following object libraries
66
ModelicaInternal.c
77
ModelicaRandom.c
88
ModelicaStrings.c
9+
ModelicaTime.c
910
win32_dirent.c (for Visual C++ on Windows)
1011

1112
- ModelicaIO (.lib, .dll, .a, .so, depending on tool and OS) containing:
@@ -53,4 +54,4 @@ Additionally, a tool vendor has to provide library "lapack"
5354
and this library should be used in the linker when a model is compiled
5455
that uses this library in its library annotation.
5556

56-
January 05, 2018.
57+
April 11, 2020.

0 commit comments

Comments
 (0)