mirror of
https://frontier.innolan.net/rainlance/amiga-tz.git
synced 2025-11-21 15:18:30 +00:00
I audited the code and fixed as many width-asssumptions as I could find, including several places where the code assumed that 'time_t' was no wider than 'long'; this assumption is not true on 32-bit NetBSD platforms. This caught every problem that is already fixed in the NetBSD zic.c, and caught quite a few more. * Makefile: Add comments re HAVE_DOS_FILE_NAMES and HAVE_INTTYPES_H. * date.c (checkfinal, netsettime): Don't use 'long' where 'int' will do. * difftime.c (difftime): Mark with ATTRIBUTE_CONST. Use uintmax_t, not unsigned long, for the widest unsigned integer type. Use long double, not double, if time_t is wider than uintmax_t; this can in theory help on nonstandard platforms, such as GCC with 64-bit uintmax_t and 128-bit __int128_t. * localtime.c (struct ttinfo.tt_gmtoff, struct rule.r_time) (detzcode, getsecs, getoffset, gmtsub, localsub, increment_overflow32) (normalize_overflow32, time1, time2, timesub, transtime, tzparse) (time2sub, timeoff, gtime): * tzfile.h (SECSPERDAY): * zdump.c (SECSPERDAY): * zic.c (convert, puttzcode): Use int_fast32_t, not long, when all we care is that values up to 2**31 can be stored. This doesn't fix any bugs, but it allows more opportunity for compiler optimization. (struct lsinfo.ls_corr, timesub, leapcorr): Use int_fast64_t, not long, when values up to 2**63 can be stored. (timesub): Make it clearer when we are truncating 0.5 to 0. (increment_overflow32): Rename from long_increment_overflow. All uses changed. (normalize_overflow32): Rename from long_normalize_overflow. All uses changed. * private.h (HAVE_INTTYPES_H, ATTRIBUTE_CONST): New macros. Include <inttypes.h> if HAVE_INTTYPES_H. (INT_FAST64_MIN, INT_FAST64_MAX, SCNdFAST64, int_fast32_t, PRIdMAX) (uintmax_t, PRIuMAX, _Noreturn): Define to reasonable values if it's an older compiler. * scheck.c (scheck): Add support for arbitrary formats, such as those that SCNdFAST64 can expand to, at the price of no longer supporting weird conversion specs like "%[%]". * strftime.c (_fmt): Use intmax_t and uintmax_t to format time_t, not long and unsigned long. * zdump.c (int_fast32_t, intmax_t, PRIdMAX, SCNdMAX): Define for pre-C99 compilers, like private.h does. (delta, yeartot, main): Use intmax_t, not long. (hunt): Use time_t, not long, since the diff must be nonnegative. (tformat): Allow for time_t wider than long. * zic.c (ZIC_MIN, ZIC_MAX, SCNdZIC): New macros. (OFFSET_STRLEN_MAXIMUM, RULE_STRLEN_MAXIMUM): Remove. (struct rule): Make r_loyear, r_hiyear, r_tod, r_stdoff, z_gmtoff, z_stdoff zic_t, not long. (addtype, gethms, oadd, rpytime, tadd, gmtoffs, corr, inleap) (stringoffset, stringrule, outzone, addtype, adjleap, rpytime) (LDAYSPERWEEK): Use zic_t, not long. (leapminyear, leapmaxyear, min_year, max_year, rulesub, updateminmax) (outzone, rpytime): Use zic_t, not int. (usage): Now _Noreturn. (main): Use S_IWGRP, not 'unix', to determine whether to call umask. (writezone): Omit unnecessary cast. (mkdirs): Use HAVE_DOS_FILE_NAMES, not 'unix', to determine whether to parse DOS file anmes. (eitol): Remove; no longer needed.
65 lines
1.2 KiB
C
65 lines
1.2 KiB
C
/*
|
|
** This file is in the public domain, so clarified as of
|
|
** 2006-07-17 by Arthur David Olson.
|
|
*/
|
|
|
|
/*LINTLIBRARY*/
|
|
|
|
#include "private.h"
|
|
|
|
const char *
|
|
scheck(const char *const string, const char *const format)
|
|
{
|
|
register char * fbuf;
|
|
register const char * fp;
|
|
register char * tp;
|
|
register int c;
|
|
register const char * result;
|
|
char dummy;
|
|
|
|
result = "";
|
|
if (string == NULL || format == NULL)
|
|
return result;
|
|
fbuf = malloc(2 * strlen(format) + 4);
|
|
if (fbuf == NULL)
|
|
return result;
|
|
fp = format;
|
|
tp = fbuf;
|
|
|
|
/*
|
|
** Copy directives, suppressing each conversion that is not
|
|
** already suppressed. Scansets containing '%' are not
|
|
** supported; e.g., the conversion specification "%[%]" is not
|
|
** supported. Also, multibyte characters containing a
|
|
** non-leading '%' byte are not supported.
|
|
*/
|
|
while ((*tp++ = c = *fp++) != '\0') {
|
|
if (c != '%')
|
|
continue;
|
|
if (is_digit(*fp)) {
|
|
char const *f = fp;
|
|
char *t = tp;
|
|
do {
|
|
*t++ = c = *f++;
|
|
} while (is_digit(c));
|
|
if (c == '$') {
|
|
fp = f;
|
|
tp = t;
|
|
}
|
|
}
|
|
*tp++ = '*';
|
|
if (*fp == '*')
|
|
++fp;
|
|
if ((*tp++ = *fp++) == '\0')
|
|
break;
|
|
}
|
|
|
|
*(tp - 1) = '%';
|
|
*tp++ = 'c';
|
|
*tp = '\0';
|
|
if (sscanf(string, fbuf, &dummy) != 1)
|
|
result = format;
|
|
free(fbuf);
|
|
return result;
|
|
}
|