#include #include // clock_* #include // rename is in here... also remove #include #include #include #include // mkstemp bool older_than(const struct timespec older, const struct timespec newer) { if(older.tv_sec < newer.tv_sec) return true; if(older.tv_sec > newer.tv_sec) return false; if(older.tv_nsec < newer.tv_nsec) return true; return false; } int main(int argc, char *argv[]) { if(argc != 2) return 1; const char* destname = argv[1]; size_t destlen = strlen(argv[1]); { /* Only rebuild .generated.mk once every 60 seconds at most */ struct stat statinfo; if(0 == stat(destname, &statinfo)) { struct timespec then; clock_gettime(CLOCK_REALTIME, &then); then.tv_sec -= 60; if(older_than(statinfo.st_mtim, then)) { puts("Skipping."); exit(0); } } } char tempname[] = ".tmpXXXXXX"; #define tempnamelen (sizeof(tempname)-1) int tempfd = mkstemp(tempname); FILE* out = fdopen(tempfd,"wt"); if(!out) return 2; #define PUTS(s, len) fwrite(s, len, 1, out) #define PUTLIT(lit) PUTS(lit, sizeof(lit)-1) PUTLIT("PRODUCTS :="); bool started = false; DIR* d = opendir("."); struct dirent* e; while((e = readdir(d))) { size_t len = strlen(e->d_name); if(len < 4) continue; if(e->d_name[0] == '.' && e->d_name[0] == 't' && e->d_name[0] == 'm' && e->d_name[0] == 'p') { if(!(len == tempnamelen && (0 == memcmp(e->d_name, tempname, tempnamelen)))) { remove(e->d_name); continue; } } if(e->d_name[len-3] != '.') continue; if(e->d_name[len-2] != 'm') continue; if(e->d_name[len-1] != 'd') continue; PUTLIT(" \\\n\thtml/"); PUTS(e->d_name, len - 3); PUTLIT(".html"); } fclose(out); rename(tempname,destname); return 0; }