1
0
mirror of https://frontier.innolan.net/rainlance/amiga-tz.git synced 2025-11-21 15:18:30 +00:00
Files
amiga-tz/scheck.c
Paul Eggert f0133dd86a Port to NetBSD, where, e.g., 'time_t' is wider than 'long'.
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.
2013-05-27 21:26:18 -07:00

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;
}