/* target is in current directory: entries_single/ entries_multi/ is either [0-9_]{5} or _____ or brken opens files in source directory: 01_Flags 02_Nachname 03_Vorname 04_Zusaetze 07_Strasse 08_Hausnummer 09_Verweise 10_Postleitzahl 11_Ort 12_Vorwahl 13_Rufnummer 14_15_Email_Webadresse 16_Koordinaten appends to all of the above dirs plus 00_Jahr */ #include #include #include #include #include #include #include enum { F_00, F_01, F_10, F_02, F_03, F_04, F_07, F_08, F_09, F_11, F_12, F_13, F_14, F_15, F_16, F_COUNT }; static char *g_filenames[] = { "00_Jahr", "01_Flags", "10_Postleitzahl", "02_Nachname", "03_Vorname", "04_Zusaetze", "07_Strasse", "08_Hausnummer", "09_Verweise", "11_Ort", "12_Vorwahl", "13_Rufnummer", "14_Webadresse", "15_Email", "16_Koordinaten" }; typedef struct { char plz[8]; FILE * file; } outhandle; static outhandle g_outhandles[32*1024]; static int g_outhandle_count; FILE * fopen_prefix(char *prefix, int file_id, int readonly) { char filename[1024]; snprintf( filename, sizeof(filename), "%s/%s", prefix, g_filenames[file_id]); return fopen(filename, readonly ? "r" : "a"); } /* This function gives us a binary search that returns a pointer, even if no exact match is found. In that case it sets exactmatch 0 and gives calling functions the chance to insert data */ void *binary_search( const void * const key, const void * base, const size_t member_count, const size_t member_size, size_t compare_size, int *exactmatch ) { size_t interval = member_count; while( interval ) { uint8_t *lookat = ((uint8_t*)base) + member_size * ( interval / 2 ); int cmp = memcmp( lookat, key, compare_size ); if(cmp == 0 ) { base = lookat; break; } if(cmp < 0) { base = lookat + member_size; interval--; } interval /= 2; } *exactmatch = interval; return (void*)base; } FILE * get_file_for_postleitzahl(char *plz) { int exactmatch = 0; outhandle * oh = (outhandle *)binary_search(plz, g_outhandles, g_outhandle_count, sizeof(outhandle), 5, &exactmatch); if (!exactmatch) { size_t s = (g_outhandles + g_outhandle_count) - oh; memmove(oh + 1, oh, s * sizeof(outhandle)); oh->file = fopen(plz, "a"); if (!oh->file) errx( 1, "Couldn't open file %s for writing\n", plz); memcpy(oh->plz, plz, 5); g_outhandle_count++; } return oh->file; } int main(int argc, char **args) { FILE * in_handles[F_COUNT] = { NULL }; FILE * out_handle = NULL; char flags[4], outfile[6]; int i, in_multi = 0; char *input = malloc(1024); size_t input_size = 1024; /* First open all input files */ for (i=F_01; i '9') && input[i] != '.') { broken = 1; break; } outfile[i] = input[i]; if (outfile[i] == '.') outfile[i] = '_'; } outfile[5] = 0; if (broken) strcpy(outfile, "brken"); } else strcpy(outfile, "brken"); out_handle = get_file_for_postleitzahl(outfile); fputs(args[1], out_handle); // write Jahr fputc(10, out_handle); fwrite(flags, 3, 1, out_handle); // copy Flags verbatim fputs(input, out_handle); // copy Postleitzahl verbatim fputc(10, out_handle); for (i=F_02; i