interpret/src/journal.re.c

89 lines
2.3 KiB
C

#include "../src/journal.h"
#include "../src/text.h"
#include <inttypes.h> /* C99 */
#include <stdio.h>
#include <limits.h>
#include <assert.h>
/** 1. reverse ordering, 2. uint32_t is a valid union type,
3. C11 or GNU anonymous unions. */
union date32 {
struct { uint32_t day : 5, month : 4, year : 23; };
uint32_t u32;
};
static void date32_to_string(const union date32 d, char (*const z)[12]) {
assert(d.year < 10000 && d.month && d.month <= 31 && d.day && d.day <= 31);
sprintf(*z, "%u-%2.2u-%2.2u", d.year % 10000, d.month, d.day);
}
static int page_compare(const union date32 a, const union date32 b)
{ return a.u32 > b.u32; }
static void page_to_string(const union date32 d, char (*const z)[12])
{ date32_to_string(d, z); }
static void page_to_string(const struct page_tree_entry entry,
char (*const z)[12]) { date32_to_string(*entry.key, z); }
#define TREE_NAME page
#define TREE_KEY union date32
#define TREE_VALUE char *
#define TREE_COMPARE
#define TREE_TO_STRING
#include "../src/tree.h"
/*!re2c
re2c:yyfill:enable = 0;
re2c:define:YYCTYPE = char;
*/
/** "-"? [1-9][0-9]*$, within the range of `INT_MAX`. */
static int looks_like_year(const char *const a, int *const year) {
const char *YYCURSOR = a, *YYMARKER = a, *s0;
/*!stags:re2c format = 'const char *@@;\n'; */
assert(a && year);
/*!re2c /**/
@s0 ("-"? [1-9][0-9]* | "0") "\x00" {
int sign = 1, mag;
if(*s0 == '-') { sign = -1; s0++; }
for(mag = 0; *s0 != '\0'; s0++) {
int d = *s0 - '0';
if((INT_MAX - d) / 10 < mag) return 0;
mag = mag * 10 + d;
}
*year = sign * mag;
return 1;
}
* { return 0; }
*/
}
/** 1 <= [0-1][0-9]$ <= 12 */
static unsigned looks_like_month(const char *const a) {
const char *YYCURSOR = a, *YYMARKER = a, *s0;
/*!stags:re2c format = 'const char *@@;\n'; */
(void)yyt1;
assert(a);
/*!re2c /**/
@s0 [0-1][0-9] "\x00" {
unsigned val = 10u * (unsigned)(s0[0] - '0') + (unsigned)(s0[1] - '0');
return val < 1 || val > 12 ? 0 : val;
}
* { return 0; }
*/
}
/** 1 <= [0-3][0-9].txt$ <= 31 */
static unsigned looks_like_day(const char *const a) {
const char *YYCURSOR = a, *YYMARKER = a, *s0;
/*!stags:re2c format = 'const char *@@;\n'; */
(void)yyt1;
assert(a);
/*!re2c /**/
@s0 [0-3][0-9] ".txt\x00" {
unsigned val = 10u * (unsigned)(s0[0] - '0') + (unsigned)(s0[1] - '0');
return val < 1 || val > 31 ? 0 : val;
}
* { return 0; }
*/
}