#include "interpret.h" #include "lex.h" #include /* chdir (POSIX) */ #include /* mode_t (POSIX) */ #include /* umask (POSIX) */ #include /* opendir readdir closedir */ #include #include #include #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); } int main(int argc, char **argv) { int success = EXIT_FAILURE; DIR *dir = 0; struct dirent *de; struct int_array years = ARRAY_IDLE, months = ARRAY_IDLE, days = ARRAY_IDLE; int *y, *y_end; /* Get the years list as directories matching a year in order. */ errno = 0; if(argc != 2) { fprintf(stderr, "Needs journal location.\n" "(should contain //.txt)\n"); goto finally; } if(chdir(argv[1]) == -1 || !(dir = opendir("."))) goto catch; while((de = readdir(dir))) { struct stat st; int year, *p; if(!looks_like_year(de->d_name, &year)) continue; if(stat(de->d_name, &st)) goto catch; if(!S_ISDIR(st.st_mode)) continue; if(!(p = int_array_new(&years))) goto catch; *p = year; } closedir(dir), dir = 0; qsort(years.data, years.size, sizeof *years.data, &void_int_cmp); fprintf(stderr, "%s: %s.\n", argv[1], int_array_to_string(&years)); /* Go though each year. */ for(y = years.data, y_end = y + years.size; y < y_end; y++) { char temp[64]; int *m, *m_end; sprintf(temp, "%d", *y); /* Get the months as directories. */ if(chdir(temp) == -1 || !(dir = opendir("."))) goto catch; while((de = readdir(dir))) { struct stat st; int month, *p; if(!(month = looks_like_month(de->d_name))) continue; if(stat(de->d_name, &st)) goto catch; if(!S_ISDIR(st.st_mode)) continue; if(!(p = int_array_new(&months))) goto catch; *p = month; } closedir(dir), dir = 0; qsort(months.data, months.size, sizeof *months.data, &void_int_cmp); fprintf(stderr, "%s: %s.\n", temp, int_array_to_string(&months)); /* Go though each month. */ for(m = months.data, m_end = m + months.size; m < m_end; m++) { int *d, *d_end; sprintf(temp, "%.2d", *m); /* Get the days as files. */ if(chdir(temp) == -1 || !(dir = opendir("."))) goto catch; while((de = readdir(dir))) { struct stat st; int day, *p; /* fixme: Have yyyy-mm-dd to figure out how many days. */ if(!(day = looks_like_day(de->d_name))) continue; if(stat(de->d_name, &st)) goto catch; if(S_ISDIR(st.st_mode)) continue; if(!(p = int_array_new(&days))) goto catch; *p = day; } closedir(dir), dir = 0; qsort(days.data, days.size, sizeof *days.data, &void_int_cmp); fprintf(stderr, "%s: %s.\n", temp, int_array_to_string(&days)); for(d = days.data, d_end = d + days.size; d < d_end; d++) { printf("%d-%.2d-%.2d\n", *y, *m, *d); } int_array_clear(&days); if(chdir("..") == -1) goto catch; } int_array_clear(&months); if(chdir("..") == -1) goto catch; } { success = EXIT_SUCCESS; goto finally; } catch: perror("interpret"); finally: if(dir) closedir(dir); int_array_(&years); int_array_(&months); return EXIT_FAILURE; }