2011 C anonymous unions

This commit is contained in:
Neil 2022-03-31 23:09:02 -07:00
parent bd53cf2ccc
commit a97980ef59

View File

@ -1,3 +1,5 @@
/** @std GNU C11 */
#include "lex.h"
#include <unistd.h> /* chdir (POSIX) */
#include <sys/types.h> /* mode_t (POSIX) */
@ -6,6 +8,7 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#if INT_MAX >= 100000000000
#error int_to_string requires truncation on this compiler.
@ -64,11 +67,16 @@ static int leap(int y) {
if(!(y % 4)) return 1;
return 0;
}
/** Not defined for some implementations. */
struct date32 { unsigned year : 23, month : 4, day : 5; };
/** Not defined for some implementations. (I think the standard also doesn't
say which order they should be, that's a problem.) */
union date32 {
uint32_t i32;
struct { unsigned year : 23, month : 4, day : 5; };
/* This is unsetting. Obv. it should be `struct anonymous {};`. */
};
/** Convert or narrower type or return zero. */
static struct date32 date_to_32(const int y, const int m, const int d) {
struct date32 d32 = { 0, 0, 0 };
static union date32 date_to_32(const int y, const int m, const int d) {
union date32 d32 = { 0 };
/* Leap year calculations only work at y>=1 and Gregorian Calendar and max
23 bits. */
if(y < 1582 || y > 8388607 || m < 1 || m > 12 || d < 1 || d > 31)
@ -84,7 +92,7 @@ static struct date32 date_to_32(const int y, const int m, const int d) {
}
/** Tomohiko Sakamoto comp.lang.c 1993-04-10. */
static unsigned weekday(struct date32 d) {
static unsigned weekday(union date32 d) {
d.year -= d.month < 3;
return (d.year + d.year / 4 - d.year / 100 + d.year / 400
+ "-bed=pen+mad."[d.month] + d.day) % 7;
@ -94,7 +102,7 @@ static unsigned weekday(struct date32 d) {
#define ARRAY_TYPE struct lex
#include "array.h"
struct page {
struct date32 date;
union date32 date;
struct char_array entry;
struct lex_array lexx;
};
@ -127,6 +135,7 @@ int main(int argc, char **argv) {
*p = year;
}
closedir(dir), dir = 0;
/* Sort the years for sensible ordering of parsing. */
qsort(years.data, years.size, sizeof *years.data, &void_int_cmp);
fprintf(stderr, "Files in %s: %s.\n", argv[1], int_array_to_string(&years));