Home | History | Annotate | Line # | Download | only in intrinsics
ctime.c revision 1.1.1.2
      1      1.1  mrg /* Implementation of the CTIME and FDATE g77 intrinsics.
      2  1.1.1.2  mrg    Copyright (C) 2005-2020 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, &ltm))
     57      1.1  mrg 			 == 5,
     58      1.1  mrg 			 failed = localtime_r (&timev, &ltm) == NULL,
     59      1.1  mrg 			 failed = localtime_r (&timev, &ltm) != 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