diff options
Diffstat (limited to 'Build/source/texk/dvipdfm-x/dpxutil.c')
-rw-r--r-- | Build/source/texk/dvipdfm-x/dpxutil.c | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/Build/source/texk/dvipdfm-x/dpxutil.c b/Build/source/texk/dvipdfm-x/dpxutil.c index e16ab74e563..8f884b98219 100644 --- a/Build/source/texk/dvipdfm-x/dpxutil.c +++ b/Build/source/texk/dvipdfm-x/dpxutil.c @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2017 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> @@ -69,6 +69,114 @@ max4 (double x1, double x2, double x3, double x4) return v; } + +#if defined(_MSC_VER) +#define strtoll _strtoi64 +#endif + +/* If an environment variable SOURCE_DATE_EPOCH is correctly defined like + * SOURCE_DATE_EPOCH=1456304492, then returns this value, to be used as the + * 'current time', otherwise returns INVALID_EPOCH_VALUE (= (time_t)-1). + * In the case of Microsoft Visual Studio 2010, the value should be less + * than 32535291600. + */ + +time_t +dpx_util_get_unique_time_if_given(void) +{ + const char *source_date_epoch; + int64_t epoch; + char *endptr; + time_t ret = INVALID_EPOCH_VALUE; + + source_date_epoch = getenv("SOURCE_DATE_EPOCH"); + if (source_date_epoch) { + errno = 0; + epoch = strtoll(source_date_epoch, &endptr, 10); + if (!(epoch < 0 || *endptr != '\0' || errno != 0)) { + ret = (time_t) epoch; +#if defined(_MSC_VER) + if (ret > 32535291599ULL) + ret = 32535291599ULL; +#endif + } + } + return ret; +} + + +#ifndef HAVE_TM_GMTOFF +#ifndef HAVE_TIMEZONE + +/* auxiliary function to compute timezone offset on + systems that do not support the tm_gmtoff in struct tm, + or have a timezone variable. Such as i386-solaris. */ + +static int32_t +compute_timezone_offset() +{ + time_t now; + struct tm tm; + struct tm local; + time_t gmtoff; + + now = get_unique_time_if_given(); + if (now == INVALID_EPOCH_VALUE) { + now = time(NULL); + localtime_r(&now, &local); + gmtime_r(&now, &tm); + return (mktime(&local) - mktime(&tm)); + } else { + return(0); + } +} + +#endif /* HAVE_TIMEZONE */ +#endif /* HAVE_TM_GMTOFF */ + +/* + * Docinfo + */ +int +dpx_util_format_asn_date (char *date_string, int need_timezone) +{ + int32_t tz_offset; + time_t current_time; + struct tm *bd_time; + + current_time = dpx_util_get_unique_time_if_given(); + if (current_time == INVALID_EPOCH_VALUE) { + time(¤t_time); + bd_time = localtime(¤t_time); + +#ifdef HAVE_TM_GMTOFF + tz_offset = bd_time->tm_gmtoff; +#else +# ifdef HAVE_TIMEZONE + tz_offset = -timezone; +# else + tz_offset = compute_timezone_offset(); +# endif /* HAVE_TIMEZONE */ +#endif /* HAVE_TM_GMTOFF */ + } else { + bd_time = gmtime(¤t_time); + tz_offset = 0; + } + if (need_timezone) { + sprintf(date_string, "D:%04d%02d%02d%02d%02d%02d%c%02d'%02d'", + bd_time->tm_year + 1900, bd_time->tm_mon + 1, bd_time->tm_mday, + bd_time->tm_hour, bd_time->tm_min, bd_time->tm_sec, + (tz_offset > 0) ? '+' : '-', abs(tz_offset) / 3600, + (abs(tz_offset) / 60) % 60); + } else { + sprintf(date_string, "D:%04d%02d%02d%02d%02d%02d", + bd_time->tm_year + 1900, bd_time->tm_mon + 1, bd_time->tm_mday, + bd_time->tm_hour, bd_time->tm_min, bd_time->tm_sec); + } + + return strlen(date_string); +} + void skip_white_spaces (unsigned char **s, unsigned char *endptr) { |