[tz] [PROPOSED 4/5] Avoid C macros when this is easy
Paul Eggert
eggert at cs.ucla.edu
Tue Jul 12 16:14:06 UTC 2022
Some compiler debugging formats do not represent C macros,
making it more of a pain to debug at the source-code level.
The macros in question mostly predate C89 when macros were
more portable than enums, but it’s safe to use enums now.
* asctime.c (ASCTIME_FMT, ASCTIME_FMT_B, STD_ASCTIME_BUF_SIZE):
* date.c (INCR):
* localtime.c (lclptr, gmtptr) [!ALL_STATE]:
* private.h (SECSPERMIN, MINSPERHOUR, HOURSPERDAY)
(DAYSPERWEEK, DAYSPERNYEAR, DAYSPERLYEAR, SECSPERHOUR)
(MONSPERYEAR, YEARSPERREPEAT, TM_SUNDAY, TM_MONDAY, TM_TUESDAY)
(TM_WEDNESDAY, TM_THURSDAY, TM_FRIDAY, TM_SATURDAY, TM_JANUARY)
(TM_FEBRUARY, TM_MARCH, TM_APRIL, TM_MAY, TM_JUNE, TM_JULY)
(TM_AUGUST, TM_SEPTEMBER, TM_OCTOBER, TM_NOVEMBER, TM_DECEMBER)
(TM_YEAR_BASE, TM_WDAY_BASE, EPOCH_YEAR, EPOCH_WDAY):
* strftime.c (Locale, DIVISOR):
* zdump.c (DIVISOR):
* zic.c (DC_DOM, DC_DOWGEQ, DC_DOWLEQ, LC_RULE, LC_ZONE)
(LC_LINK, LC_LEAP, LC_EXPIRES, ZF_NAME, ZF_STDOFF, ZF_RULE)
(ZF_FORMAT, ZF_TILYEAR, ZF_TILMONTH, ZF_TILDAY, ZF_TILTIME)
(ZONE_MINFIELDS, ZONE_MAXFIELDS, ZFC_STDOFF, ZFC_RULE)
(ZFC_FORMAT, ZFC_TILYEAR, ZFC_TILMONTH, ZFC_TILDAY, ZFC_TILTIME)
(ZONEC_MINFIELDS, ZONEC_MAXFIELDS, RF_NAME, RF_LOYEAR)
(RF_HIYEAR, RF_COMMAND, RF_MONTH, RF_DAY, RF_TOD, RF_SAVE)
(RF_ABBRVAR, RULE_FIELDS, LF_TARGET, LF_LINKNAME, LINK_FIELDS)
(LP_YEAR, LP_MONTH, LP_DAY, LP_TIME, LP_CORR, LP_ROLL)
(LEAP_FIELDS, EXPIRES_FIELDS, MAX_FIELDS, YR_MINIMUM)
(YR_MAXIMUM, YR_ONLY, TIME_T_BITS_IN_FILE):
Replace macros with ordinary identifiers when this is easy.
* asctime.c (MAX_ASCTIME_BUF_SIZE):
* localtime.c (OPEN_MODE):
Remove these macros. All uses removed.
* localtime.c (O_BINARY): Define to 0 if not defined.
---
asctime.c | 26 +++++-----
date.c | 3 +-
localtime.c | 15 +++---
private.h | 78 ++++++++++++++++--------------
strftime.c | 6 +--
zdump.c | 2 +-
zic.c | 135 ++++++++++++++++++++++++++++++----------------------
7 files changed, 143 insertions(+), 122 deletions(-)
diff --git a/asctime.c b/asctime.c
index 68fbb80..fd3b038 100644
--- a/asctime.c
+++ b/asctime.c
@@ -35,10 +35,10 @@
** but many implementations pad anyway; most likely the standards are buggy.
*/
#ifdef __GNUC__
-# define ASCTIME_FMT "%s %s%3d %2.2d:%2.2d:%2.2d %-4s\n"
-#else /* !defined __GNUC__ */
-# define ASCTIME_FMT "%s %s%3d %02.2d:%02.2d:%02.2d %-4s\n"
-#endif /* !defined __GNUC__ */
+static char const ASCTIME_FMT[] = "%s %s%3d %2.2d:%2.2d:%2.2d %-4s\n";
+#else
+static char const ASCTIME_FMT[] = "%s %s%3d %02.2d:%02.2d:%02.2d %-4s\n";
+#endif
/*
** For years that are more than four digits we put extra spaces before the year
** so that code trying to overwrite the newline won't end up overwriting
@@ -46,12 +46,12 @@
** that no output is better than wrong output).
*/
#ifdef __GNUC__
-# define ASCTIME_FMT_B "%s %s%3d %2.2d:%2.2d:%2.2d %s\n"
-#else /* !defined __GNUC__ */
-# define ASCTIME_FMT_B "%s %s%3d %02.2d:%02.2d:%02.2d %s\n"
-#endif /* !defined __GNUC__ */
+static char const ASCTIME_FMT_B[] = "%s %s%3d %2.2d:%2.2d:%2.2d %s\n";
+#else
+static char const ASCTIME_FMT_B[] = "%s %s%3d %02.2d:%02.2d:%02.2d %s\n";
+#endif
-#define STD_ASCTIME_BUF_SIZE 26
+enum { STD_ASCTIME_BUF_SIZE = 26 };
/*
** Big enough for something such as
** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
@@ -59,12 +59,10 @@
** seven explicit spaces, two explicit colons, a newline,
** and a trailing NUL byte).
** The values above are for systems where an int is 32 bits and are provided
-** as an example; the define below calculates the maximum for the system at
+** as an example; the size expression below is a bound for the system at
** hand.
*/
-#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1)
-
-static char buf_asctime[MAX_ASCTIME_BUF_SIZE];
+static char buf_asctime[2*3 + 5*INT_STRLEN_MAXIMUM(int) + 7 + 2 + 1 + 1];
char *
asctime_r(register const struct tm *timeptr, char *buf)
@@ -79,7 +77,7 @@ asctime_r(register const struct tm *timeptr, char *buf)
register const char * wn;
register const char * mn;
char year[INT_STRLEN_MAXIMUM(int) + 2];
- char result[MAX_ASCTIME_BUF_SIZE];
+ char result[sizeof buf_asctime];
if (timeptr == NULL) {
errno = EINVAL;
diff --git a/date.c b/date.c
index 5c511ba..56e6c87 100644
--- a/date.c
+++ b/date.c
@@ -180,8 +180,6 @@ display(char const *format, time_t now)
}
}
-#define INCR 1024
-
static void
timeout(FILE *fp, char const *format, struct tm const *tmp)
{
@@ -189,6 +187,7 @@ timeout(FILE *fp, char const *format, struct tm const *tmp)
size_t result;
size_t size;
struct tm tm;
+ int INCR = 1024;
if (!tmp) {
fprintf(stderr, _("date: error: time out of range\n"));
diff --git a/localtime.c b/localtime.c
index 6380146..7de9d9d 100644
--- a/localtime.c
+++ b/localtime.c
@@ -42,15 +42,12 @@ static void unlock(void) { }
#endif /* !defined TZ_ABBR_ERR_CHAR */
/*
-** SunOS 4.1.1 headers lack O_BINARY.
+** Support non-POSIX platforms that distinguish between text and binary files.
*/
-#ifdef O_BINARY
-# define OPEN_MODE (O_RDONLY | O_BINARY)
-#endif /* defined O_BINARY */
#ifndef O_BINARY
-# define OPEN_MODE O_RDONLY
-#endif /* !defined O_BINARY */
+# define O_BINARY 0
+#endif
#ifndef WILDABBR
/*
@@ -171,8 +168,8 @@ static struct state * gmtptr;
#ifndef ALL_STATE
static struct state lclmem;
static struct state gmtmem;
-# define lclptr (&lclmem)
-# define gmtptr (&gmtmem)
+static struct state *const lclptr = &lclmem;
+static struct state *const gmtptr = &gmtmem;
#endif /* State Farm */
#ifndef TZ_STRLEN_MAX
@@ -451,7 +448,7 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
}
if (doaccess && access(name, R_OK) != 0)
return errno;
- fid = open(name, OPEN_MODE);
+ fid = open(name, O_RDONLY | O_BINARY);
if (fid < 0)
return errno;
diff --git a/private.h b/private.h
index ff98608..9b9389f 100644
--- a/private.h
+++ b/private.h
@@ -742,47 +742,55 @@ char *ctime_r(time_t const *, char *);
/* Handy macros that are independent of tzfile implementation. */
-#define SECSPERMIN 60
-#define MINSPERHOUR 60
-#define HOURSPERDAY 24
-#define DAYSPERWEEK 7
-#define DAYSPERNYEAR 365
-#define DAYSPERLYEAR 366
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+enum {
+ SECSPERMIN = 60,
+ MINSPERHOUR = 60,
+ SECSPERHOUR = SECSPERMIN * MINSPERHOUR,
+ HOURSPERDAY = 24,
+ DAYSPERWEEK = 7,
+ DAYSPERNYEAR = 365,
+ DAYSPERLYEAR = DAYSPERNYEAR + 1,
+ MONSPERYEAR = 12,
+ YEARSPERREPEAT = 400 /* years before a Gregorian repeat */
+};
+
#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR 12
-#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
#define DAYSPERREPEAT ((int_fast32_t) 400 * 365 + 100 - 4 + 1)
#define SECSPERREPEAT ((int_fast64_t) DAYSPERREPEAT * SECSPERDAY)
#define AVGSECSPERYEAR (SECSPERREPEAT / YEARSPERREPEAT)
-#define TM_SUNDAY 0
-#define TM_MONDAY 1
-#define TM_TUESDAY 2
-#define TM_WEDNESDAY 3
-#define TM_THURSDAY 4
-#define TM_FRIDAY 5
-#define TM_SATURDAY 6
-
-#define TM_JANUARY 0
-#define TM_FEBRUARY 1
-#define TM_MARCH 2
-#define TM_APRIL 3
-#define TM_MAY 4
-#define TM_JUNE 5
-#define TM_JULY 6
-#define TM_AUGUST 7
-#define TM_SEPTEMBER 8
-#define TM_OCTOBER 9
-#define TM_NOVEMBER 10
-#define TM_DECEMBER 11
-
-#define TM_YEAR_BASE 1900
-#define TM_WDAY_BASE TM_MONDAY
-
-#define EPOCH_YEAR 1970
-#define EPOCH_WDAY TM_THURSDAY
+enum {
+ TM_SUNDAY,
+ TM_MONDAY,
+ TM_TUESDAY,
+ TM_WEDNESDAY,
+ TM_THURSDAY,
+ TM_FRIDAY,
+ TM_SATURDAY
+};
+
+enum {
+ TM_JANUARY,
+ TM_FEBRUARY,
+ TM_MARCH,
+ TM_APRIL,
+ TM_MAY,
+ TM_JUNE,
+ TM_JULY,
+ TM_AUGUST,
+ TM_SEPTEMBER,
+ TM_OCTOBER,
+ TM_NOVEMBER,
+ TM_DECEMBER
+};
+
+enum {
+ TM_YEAR_BASE = 1900,
+ TM_WDAY_BASE = TM_MONDAY,
+ EPOCH_YEAR = 1970,
+ EPOCH_WDAY = TM_THURSDAY
+};
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
diff --git a/strftime.c b/strftime.c
index 7425a64..deba2b5 100644
--- a/strftime.c
+++ b/strftime.c
@@ -56,8 +56,6 @@ struct lc_time_T {
const char * date_fmt;
};
-#define Locale (&C_time_locale)
-
static const struct lc_time_T C_time_locale = {
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
@@ -164,6 +162,8 @@ static char *
_fmt(const char *format, const struct tm *t, char *pt,
const char *ptlim, enum warn *warnp)
{
+ struct lc_time_T const *Locale = &C_time_locale;
+
for ( ; *format; ++format) {
if (*format == '%') {
label:
@@ -626,7 +626,7 @@ _yconv(int a, int b, bool convert_top, bool convert_yy,
register int lead;
register int trail;
-#define DIVISOR 100
+ int DIVISOR = 100;
trail = a % DIVISOR + b % DIVISOR;
lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR;
trail %= DIVISOR;
diff --git a/zdump.c b/zdump.c
index b153812..a63a343 100644
--- a/zdump.c
+++ b/zdump.c
@@ -1193,6 +1193,7 @@ dumptime(register const struct tm *timeptr)
};
register int lead;
register int trail;
+ int DIVISOR = 10;
/*
** The packaged localtime_rz and gmtime_r never put out-of-range
@@ -1208,7 +1209,6 @@ dumptime(register const struct tm *timeptr)
? mon_name[timeptr->tm_mon] : "???"),
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec);
-#define DIVISOR 10
trail = timeptr->tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR;
lead = timeptr->tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR +
trail / DIVISOR;
diff --git a/zic.c b/zic.c
index 7742422..a29f679 100644
--- a/zic.c
+++ b/zic.c
@@ -96,12 +96,13 @@ struct rule {
};
/*
-** r_dycode r_dayofmonth r_wday
+** r_dycode r_dayofmonth r_wday
*/
-
-#define DC_DOM 0 /* 1..31 */ /* unused */
-#define DC_DOWGEQ 1 /* 1..31 */ /* 0..6 (Sun..Sat) */
-#define DC_DOWLEQ 2 /* 1..31 */ /* 0..6 (Sun..Sat) */
+enum {
+ DC_DOM, /* 1..31 */ /* unused */
+ DC_DOWGEQ, /* 1..31 */ /* 0..6 (Sun..Sat) */
+ DC_DOWLEQ /* 1..31 */ /* 0..6 (Sun..Sat) */
+};
struct zone {
const char * z_filename;
@@ -213,89 +214,107 @@ static int unspecifiedtype;
** Line codes.
*/
-#define LC_RULE 0
-#define LC_ZONE 1
-#define LC_LINK 2
-#define LC_LEAP 3
-#define LC_EXPIRES 4
+enum {
+ LC_RULE,
+ LC_ZONE,
+ LC_LINK,
+ LC_LEAP,
+ LC_EXPIRES
+};
/*
** Which fields are which on a Zone line.
*/
-#define ZF_NAME 1
-#define ZF_STDOFF 2
-#define ZF_RULE 3
-#define ZF_FORMAT 4
-#define ZF_TILYEAR 5
-#define ZF_TILMONTH 6
-#define ZF_TILDAY 7
-#define ZF_TILTIME 8
-#define ZONE_MINFIELDS 5
-#define ZONE_MAXFIELDS 9
+enum {
+ ZF_NAME = 1,
+ ZF_STDOFF,
+ ZF_RULE,
+ ZF_FORMAT,
+ ZF_TILYEAR,
+ ZF_TILMONTH,
+ ZF_TILDAY,
+ ZF_TILTIME,
+ ZONE_MAXFIELDS,
+ ZONE_MINFIELDS = ZF_TILYEAR
+};
/*
** Which fields are which on a Zone continuation line.
*/
-#define ZFC_STDOFF 0
-#define ZFC_RULE 1
-#define ZFC_FORMAT 2
-#define ZFC_TILYEAR 3
-#define ZFC_TILMONTH 4
-#define ZFC_TILDAY 5
-#define ZFC_TILTIME 6
-#define ZONEC_MINFIELDS 3
-#define ZONEC_MAXFIELDS 7
+enum {
+ ZFC_STDOFF,
+ ZFC_RULE,
+ ZFC_FORMAT,
+ ZFC_TILYEAR,
+ ZFC_TILMONTH,
+ ZFC_TILDAY,
+ ZFC_TILTIME,
+ ZONEC_MAXFIELDS,
+ ZONEC_MINFIELDS = ZFC_TILYEAR
+};
/*
** Which files are which on a Rule line.
*/
-#define RF_NAME 1
-#define RF_LOYEAR 2
-#define RF_HIYEAR 3
-#define RF_COMMAND 4
-#define RF_MONTH 5
-#define RF_DAY 6
-#define RF_TOD 7
-#define RF_SAVE 8
-#define RF_ABBRVAR 9
-#define RULE_FIELDS 10
+enum {
+ RF_NAME = 1,
+ RF_LOYEAR,
+ RF_HIYEAR,
+ RF_COMMAND,
+ RF_MONTH,
+ RF_DAY,
+ RF_TOD,
+ RF_SAVE,
+ RF_ABBRVAR,
+ RULE_FIELDS
+};
/*
** Which fields are which on a Link line.
*/
-#define LF_TARGET 1
-#define LF_LINKNAME 2
-#define LINK_FIELDS 3
+enum {
+ LF_TARGET = 1,
+ LF_LINKNAME,
+ LINK_FIELDS
+};
/*
** Which fields are which on a Leap line.
*/
-#define LP_YEAR 1
-#define LP_MONTH 2
-#define LP_DAY 3
-#define LP_TIME 4
-#define LP_CORR 5
-#define LP_ROLL 6
-#define LEAP_FIELDS 7
-
-/* Expires lines are like Leap lines, except without CORR and ROLL fields. */
-#define EXPIRES_FIELDS 5
+enum {
+ LP_YEAR = 1,
+ LP_MONTH,
+ LP_DAY,
+ LP_TIME,
+ LP_CORR,
+ LP_ROLL,
+ LEAP_FIELDS,
+
+ /* Expires lines are like Leap lines, except without CORR and ROLL fields. */
+ EXPIRES_FIELDS = LP_TIME + 1
+};
-/* The maximum number of fields on any of the above lines. */
-#define MAX_FIELDS RULE_FIELDS
+/* The maximum number of fields on any of the above lines.
+ (The "+"s pacify gcc -Wenum-compare.) */
+enum {
+ MAX_FIELDS = max(max(+RULE_FIELDS, +LINK_FIELDS),
+ max(+LEAP_FIELDS, +EXPIRES_FIELDS))
+};
/*
** Year synonyms.
*/
-#define YR_MINIMUM 0
-#define YR_MAXIMUM 1
-#define YR_ONLY 2
+enum {
+ YR_MINIMUM,
+ YR_MAXIMUM,
+ YR_ONLY
+};
static struct rule * rules;
static ptrdiff_t nrules; /* number of rules */
@@ -671,7 +690,7 @@ check_for_signal(void)
}
}
-#define TIME_T_BITS_IN_FILE 64
+enum { TIME_T_BITS_IN_FILE = 64 };
/* The minimum and maximum values representable in a TZif file. */
static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
--
2.34.1
More information about the tz
mailing list