ctime.c revision 1.1.1.3 1 1.1 mrg /* Implementation of the CTIME and FDATE g77 intrinsics.
2 1.1.1.3 mrg Copyright (C) 2005-2022 Free Software Foundation, Inc.
3 1.1 mrg Contributed by Franois-Xavier Coudert <coudert (at) clipper.ens.fr>
4 1.1 mrg
5 1.1 mrg This file is part of the GNU Fortran runtime library (libgfortran).
6 1.1 mrg
7 1.1 mrg Libgfortran is free software; you can redistribute it and/or
8 1.1 mrg modify it under the terms of the GNU General Public
9 1.1 mrg License as published by the Free Software Foundation; either
10 1.1 mrg version 3 of the License, or (at your option) any later version.
11 1.1 mrg
12 1.1 mrg Libgfortran is distributed in the hope that it will be useful,
13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 mrg GNU General Public License for more details.
16 1.1 mrg
17 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
18 1.1 mrg permissions described in the GCC Runtime Library Exception, version
19 1.1 mrg 3.1, as published by the Free Software Foundation.
20 1.1 mrg
21 1.1 mrg You should have received a copy of the GNU General Public License and
22 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
23 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 1.1 mrg <http://www.gnu.org/licenses/>. */
25 1.1 mrg
26 1.1 mrg #include "libgfortran.h"
27 1.1 mrg
28 1.1 mrg #include "time_1.h"
29 1.1 mrg
30 1.1 mrg #include <string.h>
31 1.1 mrg
32 1.1 mrg
33 1.1 mrg /* Maximum space a ctime-like string might need. A "normal" ctime
34 1.1 mrg string is 26 bytes, and in our case 24 bytes as we don't include
35 1.1 mrg the trailing newline and null. However, the longest possible year
36 1.1 mrg number is -2,147,481,748 (1900 - 2,147,483,648, since tm_year is a
37 1.1 mrg 32-bit signed integer) so an extra 7 bytes are needed. */
38 1.1 mrg #define CTIME_BUFSZ 31
39 1.1 mrg
40 1.1 mrg
41 1.1 mrg /* Thread-safe ctime-like function that fills a Fortran
42 1.1 mrg string. ctime_r is a portability headache and marked as obsolescent
43 1.1 mrg in POSIX 2008, which recommends strftime in its place. However,
44 1.1 mrg strftime(..., "%c",...) doesn't produce ctime-like output on
45 1.1 mrg MinGW, so do it manually with snprintf. */
46 1.1 mrg
47 1.1 mrg static int
48 1.1 mrg gf_ctime (char *s, size_t max, const time_t timev)
49 1.1 mrg {
50 1.1 mrg struct tm ltm;
51 1.1 mrg int failed;
52 1.1 mrg char buf[CTIME_BUFSZ + 1];
53 1.1 mrg /* Some targets provide a localtime_r based on a draft of the POSIX
54 1.1 mrg standard where the return type is int rather than the
55 1.1 mrg standardized struct tm*. */
56 1.1 mrg __builtin_choose_expr (__builtin_classify_type (localtime_r (&timev, <m))
57 1.1 mrg == 5,
58 1.1 mrg failed = localtime_r (&timev, <m) == NULL,
59 1.1 mrg failed = localtime_r (&timev, <m) != 0);
60 1.1 mrg if (failed)
61 1.1 mrg goto blank;
62 1.1 mrg int n = snprintf (buf, sizeof (buf),
63 1.1 mrg "%3.3s %3.3s%3d %.2d:%.2d:%.2d %d",
64 1.1 mrg "SunMonTueWedThuFriSat" + ltm.tm_wday * 3,
65 1.1 mrg "JanFebMarAprMayJunJulAugSepOctNovDec" + ltm.tm_mon * 3,
66 1.1 mrg ltm.tm_mday, ltm.tm_hour, ltm.tm_min, ltm.tm_sec,
67 1.1 mrg 1900 + ltm.tm_year);
68 1.1 mrg if (n < 0)
69 1.1 mrg goto blank;
70 1.1 mrg if ((size_t) n <= max)
71 1.1 mrg {
72 1.1 mrg cf_strcpy (s, max, buf);
73 1.1 mrg return n;
74 1.1 mrg }
75 1.1 mrg blank:
76 1.1 mrg memset (s, ' ', max);
77 1.1 mrg return 0;
78 1.1 mrg }
79 1.1 mrg
80 1.1 mrg
81 1.1 mrg extern void fdate (char **, gfc_charlen_type *);
82 1.1 mrg export_proto(fdate);
83 1.1 mrg
84 1.1 mrg void
85 1.1 mrg fdate (char ** date, gfc_charlen_type * date_len)
86 1.1 mrg {
87 1.1 mrg time_t now = time(NULL);
88 1.1 mrg *date = xmalloc (CTIME_BUFSZ);
89 1.1 mrg *date_len = gf_ctime (*date, CTIME_BUFSZ, now);
90 1.1 mrg }
91 1.1 mrg
92 1.1 mrg
93 1.1 mrg extern void fdate_sub (char *, gfc_charlen_type);
94 1.1 mrg export_proto(fdate_sub);
95 1.1 mrg
96 1.1 mrg void
97 1.1 mrg fdate_sub (char * date, gfc_charlen_type date_len)
98 1.1 mrg {
99 1.1 mrg time_t now = time(NULL);
100 1.1 mrg gf_ctime (date, date_len, now);
101 1.1 mrg }
102 1.1 mrg
103 1.1 mrg
104 1.1 mrg
105 1.1 mrg extern void PREFIX(ctime) (char **, gfc_charlen_type *, GFC_INTEGER_8);
106 1.1 mrg export_proto_np(PREFIX(ctime));
107 1.1 mrg
108 1.1 mrg void
109 1.1 mrg PREFIX(ctime) (char ** date, gfc_charlen_type * date_len, GFC_INTEGER_8 t)
110 1.1 mrg {
111 1.1 mrg time_t now = t;
112 1.1 mrg *date = xmalloc (CTIME_BUFSZ);
113 1.1 mrg *date_len = gf_ctime (*date, CTIME_BUFSZ, now);
114 1.1 mrg }
115 1.1 mrg
116 1.1 mrg
117 1.1 mrg extern void ctime_sub (GFC_INTEGER_8 *, char *, gfc_charlen_type);
118 1.1 mrg export_proto(ctime_sub);
119 1.1 mrg
120 1.1 mrg void
121 1.1 mrg ctime_sub (GFC_INTEGER_8 * t, char * date, gfc_charlen_type date_len)
122 1.1 mrg {
123 1.1 mrg time_t now = *t;
124 1.1 mrg gf_ctime (date, date_len, now);
125 1.1 mrg }
126