/* menu.c - Created by Giampiero Caprino This program is part of Train Director. Train Director is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Train Director is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Train Director; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This program is used to process train timetables * as returned by the web site http://bahn.hafas.de * * wmatch *.htm extracts info from the arrival/departure * page of a station. * wmatch -l file creates a shell script with the list * of trains arriving/departing from a station * ... then run the shell script to get the info for * each individual train. * wmatch -t *.tr creates a timetable file for use * by Train Director. * The file must then be edited to insert * entry and exit point. */ #include #include struct statn { struct statn *next; char *name; char *ref; } *stations; char *text; int curtxt, maxtxt; char buff[2048]; char train[256]; char dest[256]; char stop[256]; char hour[256]; char dep[256]; int fgetline(char *buff, int size, FILE *fp) { int l; if(!fgets(buff, size, fp)) return 0; buff[size - 1] = 0; l = strlen(buff); if(l > 0 && buff[l - 1] == '\n') --l; if(l > 0 && buff[l - 1] == '\r') --l; if(l > 0 && buff[l - 1] == '\r') --l; buff[l] = 0; return 1; } int get_file(FILE *fi) { int l; curtxt = 0; while(fgetline(buff, sizeof(buff), fi)) { l = strlen(buff); if(curtxt + l + 2 > maxtxt) { maxtxt = curtxt + l + 1000; if(!text) text = (char *)malloc(maxtxt); else text = (char *)realloc(text, maxtxt); if(!text) { printf("Not enough memory for page of %d bytes\n", maxtxt); return 0; } } memcpy(text + curtxt, buff, l + 1); curtxt += l + 1; } text[curtxt] = 0x7f; /* EOF */ return 1; } char *find_match0(char *p, char *str) { int l; if(!p) return 0; l = strlen(str); while(strncmp(p, str, l)) { while(*p != 0x7f && *p) ++p; /* go to next line */ if(*p) /* reached end of file */ return 0; ++p; } return p + l; } char *find_match(char *p, char *str) { int l; if(!p || *p == 0x7f) return 0; l = strlen(str); while(strncmp(p, str, l)) { if(*++p == 0x7f) /* reached end of file */ return 0; } return p + l; } void remove_html(char *p) { char *d; if(!strncmp(p, "'); if(!d) return; while(*p++ = *++d); } } void remove_spaces(char *p) { char *d; for(d = p; *p; ++p) { if(*p == ' ') continue; *d++ = *p; } *d = 0; } char *parse_hour(char *p) { int i; if(!p || *p == 0x7f) return 0; i = 0; while(*p == ' ') ++p; while(*p >= '0' && *p <= '9') hour[i++] = *p++; if(*p == ':') hour[i++] = *p++; while(*p >= '0' && *p <= '9') hour[i++] = *p++; hour[i] = 0; return p; } char *parse_train(char *p) { int i; char *p1; char buff[256]; char buff1[256]; if(!p || *p == 0x7f) return 0; i = 0; while(!*p || *p == ' ') ++p; while(*p != 0x7f && strncmp(p, "", 4) && i < sizeof(train) - 1) if(*p) train[i++] = *p++; else ++p; train[i] = 0; if(*p == 0x7f) return 0; if(!strncmp(train, "", 4)) if(*p) *dst++ = *p++; else ++p; *dst = 0; remove_html(tp); if(*p == 0x7f) return 0; return p + 4; } struct statn *record_station(char *p) { struct statn *st; for(st = stations; st; st = st->next) { if(!strcmp(p, st->name)) return st; } st = (struct statn *)malloc(sizeof(struct statn)); memset(st, 0, sizeof(struct statn)); st->name = strdup(p); st->next = stations; stations = st; return(st); } int parse_station_file(FILE *fi) { char *p; if(!get_file(fi)) return 0; p = find_match0(text, "Platform"); agn: p = find_match0(p, ""); if(!p) return 0; p = find_match(p, ""); p = parse_hour(p); strcpy(dep, hour); p = find_match(p, ""); p = parse_train(p); p = find_match(p, ""); p = parse_dest(dest, p); p = find_match(p, "
"); if(!p) return 0; printf("Train: %s\n", train); printf("\tHour: %s\n", dep); printf("\tFrom/to: %s\n", dest); record_station(dest); while(strncmp(p, "
", 4)) { while(*p == ' ') ++p; if(!*p) { ++p; continue; } if(!strncmp(p, "", 7)) { p += 7; continue; } if(!strncmp(p, "", 5)) { p += 5; break; } p = parse_dest(stop, p); p = parse_hour(p); printf("\t\t%s %s\n", hour, stop); if(!strncmp(p, " - ", 3)) p += 3; if(!strncmp(p, " ", 6)) p += 6; if(!strncmp(p, ""); goto agn; } int parse_train_info(FILE *fi) { char *p, *p1; char arr[64]; if(!get_file(fi)) return 0; p = find_match(text, "Departure"); p = find_match(p, "Train"); p = find_match(p, "COLSPAN="); p = find_match(p, ""); p = parse_dest(stop, p); p = find_match0(p, ""); strcpy(hour, "0:00"); if(strncmp(p, " ", 6)) { /* no departure! */ p = find_match(p, ""); p = parse_hour(p); } p = find_match0(p, ""); p1 = find_match(p, ""); if(!p1) return; if(p1 - p >= sizeof(train)) { printf("##Can't find train name!\n"); return 0; } strncpy(train, p, p1 - p); train[p1 - p] = 0; if((p1 = strchr(train, '<'))) *p1 = 0; remove_spaces(train); printf("Train: %s\n\tEnter: %s, %s\n", train, hour, stop); for(;;) { p = find_match(p, "COLSPAN"); p = find_match(p, ""); if(!p || !*p) break; p = parse_dest(dest, p); p = find_match(p, "ALIGN=RIGHT>"); if(strncmp(p, " ", 6)) { p = find_match(p, ""); p = parse_hour(p); strncpy(arr, hour, sizeof(arr) - 1); arr[sizeof(arr) - 1] = 0; p = find_match(p, "ALIGN=RIGHT>"); if(!strncmp(p, " ", 6)) {/* arrival st. has no departure time */ printf("\t\t%s, -, %s\n", arr, dest); continue; } p = find_match(p, ""); p = parse_hour(p); printf("\t\t%s, %s, %s\n", arr, hour, dest); } else { p = find_match(p, "ALIGN=RIGHT>"); if(!strncmp(p, " ", 6))/* no arrival, no departure-ignore*/ continue; p = find_match(p, ""); p = parse_hour(p); printf("\t\t%s, %s, %s\n", hour, hour, dest); } } puts("."); } void dump_stations(void) { struct statn *st; for(st = stations; st; st = st->next) printf("#<%s\n", st->name); } void parse_train_list(FILE *fp) { char buff[256]; int l; char *p; struct statn *sp; while(fgetline(buff, sizeof(buff), fp)) { l = strlen(buff); if(!l) continue; if(buff[0] != '#' || buff[1] != '\'') continue; if(!(p = strchr(buff, ' '))) continue; *p = 0; while(*++p == ' '); sp = record_station(buff + 2); if(!sp->ref) sp->ref = strdup(p); } for(sp = stations; sp; sp = sp->next) printf("wget http://bahn.hafas.de%s > %s.tr\n", sp->ref, sp->name); } int main(int argc, char *argv[]) { FILE *fi; int l; int istrain, istlist; if(argc < 2) return parse_station_file(stdin); istrain = 0; istlist = 0; if(!strcmp(argv[1], "-t")) { istrain = 1; argv[1] = argv[0]; ++argv; --argc; } else if(!strcmp(argv[1], "-l")) { istlist = 1; argv[1] = argv[0]; ++argv; --argc; } printf("#!trdir\n"); for(l = 1; l < argc; ++l) { if(!(fi = fopen(argv[l], "r"))) { perror(argv[l]); continue; } if(istrain) parse_train_info(fi); else if(istlist) parse_train_list(fi); else parse_station_file(fi); fclose(fi); } if(!istlist && !istrain) dump_stations(); return 0; }