Much simpler years.
This commit is contained in:
parent
b87906bb49
commit
39b6e01243
@ -11,6 +11,29 @@
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
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
|
||||
re2c:yyfill:enable = 0;
|
||||
re2c:define:YYCTYPE = char;
|
||||
re2c:flags:tags = 1;
|
||||
@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) { printf("ov\n"); return 0; }
|
||||
mag = mag * 10 + d;
|
||||
}
|
||||
*year = sign * mag;
|
||||
return 1;
|
||||
}
|
||||
* { return 0; }
|
||||
*/
|
||||
}
|
||||
|
||||
/* This defines `enum condition`. */
|
||||
/*!types:re2c*/
|
||||
enum symbol { END, TEXT, BANG, WHITE, MAP };
|
||||
@ -29,9 +52,6 @@ struct scanner {
|
||||
};
|
||||
|
||||
/*!re2c
|
||||
re2c:yyfill:enable = 0;
|
||||
re2c:flags:tags = 1;
|
||||
re2c:define:YYCTYPE = char;
|
||||
re2c:define:YYCURSOR = s->cursor;
|
||||
re2c:define:YYMARKER = s->marker;
|
||||
re2c:define:YYCTXMARKER = s->ctx_marker;
|
||||
@ -82,57 +102,21 @@ scan:
|
||||
*/
|
||||
}
|
||||
|
||||
/*#define POOL_NAME char
|
||||
#define POOL_TYPE char
|
||||
#include "../src/pool.h"*/
|
||||
|
||||
struct year_listlink;
|
||||
static int year_link_compare(const struct year_listlink *,
|
||||
const struct year_listlink *);
|
||||
static void yearlist_to_string(const struct year_listlink *, char (*)[12]);
|
||||
#define LIST_NAME year
|
||||
#define LIST_EXPECT_TRAIT
|
||||
#include "../src/list.h"
|
||||
#define LIST_COMPARE &year_link_compare
|
||||
#define LIST_EXPECT_TRAIT
|
||||
#include "../src/list.h"
|
||||
#define LIST_TO_STRING &yearlist_to_string
|
||||
#include "../src/list.h"
|
||||
struct year {
|
||||
struct year_listlink link;
|
||||
int year;
|
||||
char as_string[8];
|
||||
};
|
||||
static const size_t year_string_size = sizeof ((struct year *)0)->as_string;
|
||||
static int year_link_compare(const struct year_listlink *const al,
|
||||
const struct year_listlink *const bl) {
|
||||
const struct year *const a = (const struct year *)al,
|
||||
*const b = (const struct year *)bl;
|
||||
return (b->year < a->year) - (a->year < b->year);
|
||||
}
|
||||
#define POOL_NAME year
|
||||
#define POOL_TYPE struct year
|
||||
#include "../src/pool.h"
|
||||
static unsigned hash_year(const struct year *const year)
|
||||
{ return (unsigned)(year->year - INT_MIN); }
|
||||
static int year_is_equal(const struct year *const a, const struct year *const b)
|
||||
{ return a->year == b->year; }
|
||||
static void year_to_string(const struct year *const y, char (*const a)[12])
|
||||
{ strncpy(*a, y->as_string, sizeof(*a) - 1), (*a)[sizeof(*a) - 1] = '\0'; }
|
||||
static void yearlist_to_string(const struct year_listlink *const y,
|
||||
char (*const a)[12]) { year_to_string((const struct year *)y, a); }
|
||||
#define TABLE_NAME year
|
||||
#define TABLE_KEY struct year *
|
||||
#define TABLE_UINT unsigned
|
||||
#define TABLE_HASH &hash_year
|
||||
#define TABLE_IS_EQUAL &year_is_equal
|
||||
#define TABLE_EXPECT_TRAIT
|
||||
#include "../src/table.h"
|
||||
#define TABLE_DEFAULT 0
|
||||
#define TABLE_EXPECT_TRAIT
|
||||
#include "../src/table.h"
|
||||
#define TABLE_TO_STRING &year_to_string
|
||||
#include "../src/table.h"
|
||||
#if INT_MAX >= 100000000000
|
||||
#error int_to_string requires truncation on this compiler.
|
||||
#endif
|
||||
static void int_to_string(const int *const n,
|
||||
char (*const a)[12]) { sprintf(*a, "%d", *n); }
|
||||
#define ARRAY_NAME int
|
||||
#define ARRAY_TYPE int
|
||||
#define ARRAY_EXPECT_TRAIT
|
||||
#include "../src/array.h"
|
||||
#define ARRAY_TO_STRING &int_to_string
|
||||
#include "../src/array.h"
|
||||
static int int_cmp(const int *const a, const int *const b)
|
||||
{ return (*b < *a) - (*a < *b); }
|
||||
static int void_int_cmp(const void *const a, const void *const b)
|
||||
{ return int_cmp(a, b); }
|
||||
|
||||
#include <unistd.h> /* chdir (POSIX) */
|
||||
#include <sys/types.h> /* mode_t (POSIX) */
|
||||
@ -144,42 +128,31 @@ int main(int argc, char **argv) {
|
||||
int success = EXIT_FAILURE;
|
||||
DIR *year_dir;
|
||||
struct dirent *year_de;
|
||||
struct year_pool year_pool = POOL_IDLE;
|
||||
struct year_list order;
|
||||
struct year_table years = TABLE_IDLE;
|
||||
struct int_array years = ARRAY_IDLE;
|
||||
|
||||
/* Get the years list. fixme: this is way overkill; `int_array`. */
|
||||
/* Get the years list as directories matching a year in order. */
|
||||
errno = 0;
|
||||
year_list_clear(&order);
|
||||
if(argc != 2) { fprintf(stderr, "Needs journal location.\n"
|
||||
"(should contain <year>/<month>/<day>.txt)\n"); goto finally; }
|
||||
if(chdir(argv[1]) == -1 || !(year_dir = opendir("."))) goto catch;
|
||||
while((year_de = readdir(year_dir))) {
|
||||
struct stat st;
|
||||
char *const start = year_de->d_name, *end;
|
||||
long year = strtol(start, &end, 0); /* Need better. */
|
||||
struct year *y;
|
||||
if(errno || *end != '\0' || (size_t)(end - start) >= year_string_size
|
||||
|| year < INT_MIN || year > INT_MAX)
|
||||
{ /*fprintf(stderr, "%s: doesn't look like a year.\n",
|
||||
year_de->d_name);*/ errno = 0; continue; }
|
||||
int year, *p;
|
||||
if(!looks_like_year(year_de->d_name, &year)) continue;
|
||||
if(stat(year_de->d_name, &st)) goto catch;
|
||||
if(!S_ISDIR(st.st_mode)) { /*fprintf(stderr,
|
||||
"%s: isn't a directory.\n", year_de->d_name);*/ continue; }
|
||||
if(!(y = year_pool_new(&year_pool))) goto catch;
|
||||
y->year = (int)year;
|
||||
strcpy(y->as_string, year_de->d_name);
|
||||
year_list_push(&order, &y->link);
|
||||
if(!S_ISDIR(st.st_mode)) continue;
|
||||
if(!(p = int_array_new(&years))) goto catch;
|
||||
*p = year;
|
||||
}
|
||||
year_list_sort(&order);
|
||||
fprintf(stderr, "Years: %s\n", year_list_to_string(&order));
|
||||
qsort(years.data, years.size, sizeof *years.data, &void_int_cmp);
|
||||
fprintf(stderr, "Years: %s, size %lu.\n",
|
||||
int_array_to_string(&years), (unsigned long)years.size);
|
||||
|
||||
/* Go though each of the years, in order, and extract meta-information. */
|
||||
{ success = EXIT_SUCCESS; goto finally; }
|
||||
catch:
|
||||
perror("interpret");
|
||||
finally:
|
||||
year_table_(&years);
|
||||
year_pool_(&year_pool);
|
||||
int_array_(&years);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user