program CompTab; {dollar H+} uses exists2; const cisla:set of char = ['0'..'9']; TOWNS_MARK = '# TOWNS'; CONN_MARK = '# CONN'; CONNS_MARK = '# CONNS'; DEP_MARK = '# DEP'; NOTES_MARK = '# NOTES'; BREM_MARK = '# BREM'; RREM_MARK = '# RREM'; CORP_MARK = '# CORP'; days:array [1..12] of integer = (31,28,31,30,31,30,31,31,30,31,30,31); DONT_USE_EXISTS2:boolean = false; type my_int = longint; PNote = ^TNote; TNote = record id : my_int; name : string; next : PNote; end; TId = record id : my_int; pos : my_int; end; PStation = ^TStation; TStation = record name : string; note : TNote; arrival : my_int; departure : my_int; distance : my_int; id : TId; next : PStation; end; PTrain = ^TTrain; TTrain = record name : string; counts : my_int; countbn : my_int; countrn : my_int; countcn : my_int; stations : PStation; bnotes : PNote; rnotes : PNote; cnotes : PNote; id : my_int; next : PTrain; end; PQueue = ^TQueue; TQueue = record data : Pointer; ID : TID; next : PQueue; end; TQInfo = record start : PQueue; actual : PQueue; prev_actual : PQueue; count : my_int; end; TDate = record year : my_int; month : my_int; day : my_int; hour : my_int; minute : my_int; end; var ttz_file, tti_file : Text; default_uncertain : boolean; (* * *************** * Print functions * *************** *) procedure print_info; begin writeln(stderr, 'CompTab - extracts some info from compressed timetable file'); writeln(stderr, 'Usage:'); writeln(stderr, '-l ttz_file - list all towns'); writeln(stderr, '-L ttz_file - list all connection names'); writeln(stderr, '-C ttz_file conn_name - find all connections of given name'); writeln(stderr, '-a ttz_file tti_file town_name date1 time1 date2 time2 - find all trains going through town_name at '); writeln(stderr, '-b ttz_file tti_file town1_name date1 time1 date2 time2 town2_name - find all trains going through town1 towards town2 at '); writeln(stderr, '-A and -B do the same work as -a and -b, but when some remark can''t be parsed, the train is not displayed (as -a and -b do)'); halt(1); end; { print_info } function ptime(time : my_int): string; var s, t : string; a : my_int; begin str(time div 60, s); s:=s+':'; a:=time mod 60; if a<10 then s:=s+'0'; str(a, t); s:=s+t; ptime:=s; end; { ptime } procedure print_train(train : PTrain); var st : PStation; nt : PNote; begin writeln('# ',train^.name); st:=train^.stations; write(#9, ptime(st^.departure-1500), #9); if st^.note.id<>0 then write(st^.note.name); writeln(#9, st^.distance, #9, st^.name); st:=st^.next; while st<>nil do begin if st^.next<>nil then write(ptime(st^.arrival-1500),#9,ptime(st^.departure-1500), #9) else write(ptime(st^.arrival-1500),#9#9); if st^.note.id<>0 then write(st^.note.name); write(#9,st^.distance, #9); writeln(st^.name); st:=st^.next; end; nt:=train^.bnotes; while nt<>nil do begin writeln('B', nt^.name); nt:=nt^.next; end; nt:=train^.rnotes; while nt<>nil do begin writeln('R', nt^.name); nt:=nt^.next; end; nt:=train^.cnotes; while nt<>nil do begin writeln('C', nt^.name); nt:=nt^.next; end; end; { print_train } procedure print_trains(train : PTrain); begin while train<>nil do begin print_train(train); train:=train^.next; end; end; { print_trains } (* * ************** * Error handling * ************** *) procedure error(s : string); begin writeln(stderr, s); halt(1); end; (* * *************** * Queue functions * *************** *) procedure create_queue(var qinfo : TQInfo); var q : PQueue; begin new(q); q^.next:=nil; qinfo.start:=q; qinfo.actual:=nil; qinfo.count:=0; qinfo.prev_actual:=q; qinfo.start^.id.id:=-100; end; { init_queue } procedure init_queue(var qinfo : TQInfo); begin qinfo.actual:=nil; qinfo.count:=0; qinfo.prev_actual:=qinfo.start; end; { init_queue } procedure dispose_queue(var qinfo : TQInfo); begin dispose(qinfo.start); end; { dispose_queue } procedure add_to_queue(var qinfo : TQInfo; what : pointer; id, pos, cur_id, cur_pos : my_int); var prev, cur, q : PQueue; m_id, m_pos : my_int; begin new(q); q^.data:=what; q^.id.id:=id; q^.id.pos:=pos; q^.next:=nil; inc(qinfo.count); if (id>cur_id) or ((id=cur_id) and (pos>cur_pos)) then {We can read it in this turn} if qinfo.actual=nil then begin cur:=qinfo.start; while cur^.next<>nil do begin cur:=cur^.next; end; cur^.next:=q; qinfo.actual:=q; qinfo.prev_actual:=cur; end else begin cur:=qinfo.actual; m_id:=cur^.id.id; m_pos:=cur^.id.pos; prev:=qinfo.prev_actual; while (cur<>nil) and ((m_idnil then begin m_id:=cur^.id.id; m_pos:=cur^.id.pos; end; end; q^.next:=cur; if prev=qinfo.prev_actual then begin prev^.next:=q; qinfo.actual:=q; end else prev^.next:=q; end else begin cur:=qinfo.start; m_id:=cur^.id.id; m_pos:=cur^.id.pos; while (cur<>qinfo.actual) and ((m_idnil then begin m_id:=cur^.id.id; m_pos:=cur^.id.pos; end; end; q^.next:=cur; prev^.next:=q; if cur=qinfo.actual then qinfo.prev_actual:=q; end; end; { add_to_queue } function get_from_queue(var qinfo : TQInfo; disp : boolean) : pointer; var a : PQueue; begin a:=qinfo.actual; if a=nil then get_from_queue:=nil else begin qinfo.actual:=qinfo.actual^.next; qinfo.prev_actual^.next:=qinfo.actual; dec(qinfo.count); get_from_queue:=a^.data; if disp then dispose(a); end; end; { get_from_queue } procedure make_actual(var qinfo : TQInfo); begin qinfo.actual:=qinfo.start^.next; qinfo.prev_actual:=qinfo.start; end; { make_actual } (* * *************** * Basic functions * *************** *) function my_val(s:string):my_int; var tmp : my_int; i : my_int; begin i:=1; while s[i] in cisla do inc(i); dec(i); s:=copy(s,1,i); val(s,tmp,i); if i=0 then my_val:=tmp; end; { my_val } function my_eol(var f : text) : boolean; var c : char; begin read(f, c); if c=#10 then my_eol:=true else my_eol:=false; end; { my_eol } procedure open(var fl : Text; f : string); begin {$I-} assign(fl, f); reset(fl); {$I+} if ioresult<>0 then error('File not found or disk error.'); end; { open } function rline : string; var s:string; begin readln(ttz_file, s); rline:=s; end; {If there are problems with reading input file, try this function} {-----\/----- EXCLUDED -----\/----- function rline : string; var c:char; s:string; begin s:=''; read(ttz_file, c); while (c<>#10) and (c<>#26) do begin s:=s+c; read(ttz_file, c); end; rline:=s; end; -----/\----- EXCLUDED -----/\-----} function rnum : my_int; var s : string; i, res : my_int; c : char; begin s:=''; read(ttz_file, c); while c in cisla do begin s:=s+c; read(ttz_file, c); end; val(s, i, res); rnum:=i; end; { rnum } procedure init_train(var train : PTrain); begin with train^ do begin stations:=nil; bnotes:=nil; rnotes:=nil; cnotes:=nil; id:=0; next:=nil; end; end; (* * ****************************** * Date & time handling functions * ****************************** *) function time(D : TDate): my_int; begin time:=60*D.hour + D.minute; end; { time } function equ(D1, D2 : TDate): boolean; begin if (D1.year=D2.year) and (D1.month=D2.month) and (D1.day=D2.day) then equ:=true else equ:=false; end; { equ } function is_interval(D1, D2 : TDate): boolean; begin is_interval:=((D1.year0 then error('Bad format of date/time. Use 5.6.2001 14:05'); end; { str2date } function remark_control(D : TDate; r : string ):boolean; var s : string; begin if (r='') or DONT_USE_EXISTS2 then begin remark_control:=true; exit; end; s:=date2str(D)+#9+r; case jede(s) of 'Y' : remark_control:=true; 'N' : remark_control:=false; else remark_control:=default_uncertain; end; end; { remark_control } function leap_year(y : my_int): boolean; begin leap_year:=(((y mod 4)=0) and ((y mod 100) <> 0)) or ((y mod 400)=0); end; { leap_year } procedure next_day(var D : TDate); begin inc(D.day); if D.day>days[D.month] then begin if leap_year(D.year) and (D.month=2) and (D.day=29) then exit; inc(D.month); D.day:=1; if D.month>12 then begin inc(D.year); D.month:=1; end; end; end; { next_day } procedure prev_day(var D : TDate); begin dec(D.day); if D.day=0 then begin dec(D.month); if D.month=0 then begin D.month:=12; D.day:=days[D.month]; dec(D.year); end else if D.month=2 then begin if leap_year(D.year) then D.day:=29 else D.day:=28; end else D.day:=days[D.month]; end; end; { prev_day } function exists(D1, D2, now : TDate; remark : string): boolean; var b1, b2 : boolean; begin exists:=false; b1:=false; b2:=false; if time(D1)<=time(now) then if remark_control(D1, remark) then b1:=true; if time(now)<=time(D2) then if remark_control(D2, remark) then b2:=true; if equ(D1, D2) then begin if b1 and b2 then begin exists:=true; exit; end; end else if b1 or b2 then begin exists:=true; exit; end; b1:=false; next_day(D1); prev_day(D2); if not is_interval(D1, D2) then exit; now:=D1; while (not equ(now, D2)) and (not b1) do begin if remark_control(now, remark) then b1:=true; next_day(now); end; exists:=b1; if remark_control(now, remark) then exists:=true; end; (* * ******************** * Some other functions * ******************** *) function find_station_by_name(station : PStation; name : string): PStation; var st : PStation; begin st:=station; find_station_by_name:=nil; while st<>nil do begin if st^.name=name then begin find_station_by_name:=st; exit; end; st:=st^.next; end; end; { find_station_by_name } procedure make_absolute(train : PTrain); var st : PStation; ptime, time, dist : my_int; begin st:=train^.stations; time:=st^.departure; dist:=st^.distance; st:=st^.next; while st<>nil do begin if st^.next=nil then st^.departure:=0; if st^.arrival<1500 then begin time:=time+st^.arrival; ptime:=st^.arrival; st^.arrival:=time; end else time:=st^.arrival; if st^.departure<1500 then begin time:=time+st^.departure; st^.departure:=time; end else time:=st^.departure; if ptime=0 then st^.arrival:=time; dist:=dist+st^.distance; st^.distance:=dist; st:=st^.next; ptime:=1000; end; end; { make_absolute } procedure make_tr_absolute(train : PTrain); var id : my_int; tr : PTrain; begin tr:=train; id:=tr^.id; inc(id); tr^.id:=id; tr:=tr^.next; while tr<>nil do begin id:=id+tr^.id+1; tr^.id:=id; tr:=tr^.next; end; end; { make_tr_absolute } procedure make_tr_relative(train : PTrain); var i, id : my_int; tr : PTrain; begin tr:=train; id:=tr^.id; tr^.id:=id-1; tr:=tr^.next; while tr<>nil do begin i:=tr^.id; tr^.id:=tr^.id-id-1; id:=i; tr:=tr^.next; end; end; { make_tr_relative } (* * ************************** * Non specific I/O functions * ************************** *) procedure read_count(count: my_int); var i : my_int; s : string; begin for i:=1 to count do readln(ttz_file, s); end; { read_count } function read_until(tag : string; print : boolean) : my_int; var s : string; i : my_int; begin i:=1; s:=rline; while s<>tag do begin if print then writeln(s); s:=rline; inc(i); end; read_until:=i; end; { read_until } function read_same(tag, end_mark : string) : my_int; var count : my_int; s : string; begin count:=0; s:=rline; while (tag<>s) and (s<>end_mark) do begin inc(count); s:=rline; end; if s=end_mark then read_same:=-1 else read_same:=count; end; { read_same } (* * *************** * .tti procedures * *************** *) procedure create_from_tti(var train : PTrain; id : my_int); var p, q : PTrain; i : my_int; c : char; begin reset(tti_file); for i:=1 to id do readln(tti_file); new(train); init_train(train); p:=train; read(tti_file, c); read(tti_file, p^.id); dec(p^.id); i:=1; while not my_eol(tti_file) do begin read(tti_file, id); if id>0 then begin new(q); init_train(q); inc(i); q^.id:=id-1; p^.next:=q; p:=q; end; end; p^.next:=nil; end; { create_from_tti } (* * ********************** * Specific I/O functions * ********************** *) procedure find_departure(id, pos : my_int); var a,i : my_int; begin a:=rnum; while a<>id do begin rline; a:=rnum; end; for i:=1 to pos-1 do rline; rnum; end; { find_departure } function read_remark_id : my_int; var s : string; c : char; begin s:=''; read(ttz_file, c); while (c<>';') and (c<>#9) do begin s:=s+c; read(ttz_file, c); end; if c=#9 then read_remark_id:=-1 else if s='0' then begin read(ttz_file, c); {skipt on #9} read_remark_id:=-1; end else read_remark_id:=my_val(s); end; { read_remark_id } function read_remarks(var prem : PNote): my_int; var p, q : PNote; rem,i : my_int; begin i:=0; read_remarks:=0; rem:=read_remark_id; if rem=-1 then exit; new(p); prem:=p; while rem<>-1 do begin p^.id:=rem; inc(i); rem:=read_remark_id; if rem<>-1 then begin new(q); p^.next:=q; p:=q; end; end; p^.next:=nil; read_remarks:=i; end; procedure find_dep(id, count : my_int); var i, a : my_int; begin read(ttz_file, a); while a<>id do begin rline; read(ttz_file, a); end; for i:=1 to count-1 do begin rline; read(ttz_file, a); end; end; {-----\/----- EXCLUDED -----\/----- procedure find_dep(id, count : my_int); var i, a : my_int; begin for i:=1 to count do begin read(ttz_file, a); while (a<>id) do begin rline; read(ttz_file, a); end; end; end; -----/\----- EXCLUDED -----/\-----} function read_conns(var train : PTrain; conn_name : string): boolean; var i,a : my_int; p,q : PTrain; begin i:=0; read_conns:=false; read_until(CONN_MARK, false); a:=read_same(conn_name, BREM_MARK); if a=-1 then exit; {Given connection not found} read_conns:=true; new(train); init_train(train); p:=train; while a<>-1 do begin inc(i); p^.name:=conn_name; p^.id:=a; a:=read_same(conn_name, BREM_MARK); if a<>-1 then begin new(q); init_train(q); p^.next:=q; p:=q; end; end; p^.next:=nil; end; { read_conns } procedure read_all_conn_names(train : PTrain); var i : my_int; s : string; begin read_until(CONN_MARK, false); while train<>nil do begin for i:=1 to train^.id do readln(ttz_file, s); readln(ttz_file, s); train^.name:=s; train:=train^.next; end; end; { read_all_conn_names } procedure read_train_head(var train : TTrain); var i,pos, n_id, st_id, dep : my_int; c : char; st, q : PStation; begin i:=2; read(ttz_file, st_id, dep, n_id); read(ttz_file, c); {Skip one #9} new(st); train.stations:=st; st^.departure:=dep; st^.note.id:=n_id; st^.id.id:=st_id; st^.arrival:=0; st^.distance:=0; { read remark ids } train.countbn:=read_remarks(train.bnotes); train.countrn:=read_remarks(train.rnotes); train.countcn:=read_remarks(train.cnotes); { read departure positions } read(ttz_file, pos); st^.id.pos:=pos; new(q); st^.next:=q; st:=q; while not my_eol(ttz_file) do begin read(ttz_file, pos); st^.id.pos:=pos; new(q); st^.next:=q; st:=q; inc(i); end; st^.next:=nil; train.counts:=i; end; { read_train_head } procedure read_all_heads(train : PTrain); var tr : PTrain; begin read_until(CONNS_MARK, false); tr:=train; while tr<>nil do begin read_count(tr^.id); read_train_head(tr^); tr:=tr^.next; end; end; { read_all_heads } procedure read_towns(var qinfo : TQInfo); var a : my_int; s : string; st : PStation; begin read_until(TOWNS_MARK, false); a:=0; s:=''; st:=PStation(get_from_queue(qinfo, true)); while st<>nil do begin if st^.id.id=a then st^.name:=s else begin read_count(st^.id.id-a-1); s:=rline; st^.name:=s; a:=st^.id.id; end; st:=PStation(get_from_queue(qinfo, true)); end; end; { read_towns } procedure read_all_station_names(train : PTrain); var tr : PTrain; st : PStation; qinfo : TQInfo; begin create_queue(qinfo); tr:=train; while tr<>nil do begin st:=tr^.stations; while st<>nil do begin add_to_queue(qinfo, st, st^.id.id, 1, 0, 0); st:=st^.next; end; tr:=tr^.next; end; read_towns(qinfo); dispose_queue(qinfo); end; { read_all_station_names } procedure read_notes(var qinfo : TQInfo; mark : string); var a : my_int; s : string; nt : PNote; begin read_until(mark, false); a:=0; s:=''; nt:=PNote(get_from_queue(qinfo, true)); while nt<>nil do begin if nt^.id=a then nt^.name:=s else begin read_count(nt^.id-a-1); s:=rline; nt^.name:=s; a:=nt^.id; end; nt:=PNote(get_from_queue(qinfo, true)); end; end; { read_notes } procedure read_all_notes(train : PTrain); var qinfo : TQInfo; tr : PTrain; nt : PNote; begin tr:=train; create_queue(qinfo); while tr<>nil do begin nt:=tr^.bnotes; while nt<>nil do begin add_to_queue(qinfo, nt, nt^.id, 1, 0, 0); nt:=nt^.next; end; tr:=tr^.next end; read_notes(qinfo, BREM_MARK); tr:=train; init_queue(qinfo); while tr<>nil do begin nt:=tr^.rnotes; while nt<>nil do begin add_to_queue(qinfo, nt, nt^.id, 1, 0, 0); nt:=nt^.next; end; tr:=tr^.next end; read_notes(qinfo, RREM_MARK); tr:=train; init_queue(qinfo); while tr<>nil do begin nt:=tr^.cnotes; while nt<>nil do begin add_to_queue(qinfo, nt, nt^.id, 1, 0, 0); nt:=nt^.next; end; tr:=tr^.next end; read_notes(qinfo, CORP_MARK); dispose_queue(qinfo); end; { read_all_notes } procedure read_st_notes(var qinfo : TQInfo); var a : my_int; s : string; nt : PNote; begin read_until(NOTES_MARK, false); a:=0; s:=''; nt:=PNote(get_from_queue(qinfo, true)); while nt<>nil do begin if nt^.id=a then nt^.name:=s else begin read_count(nt^.id-a-1); s:=rline; nt^.name:=s; a:=nt^.id; end; nt:=PNote(get_from_queue(qinfo, true)); end; end; { read_towns } procedure read_all_st_notes(train : PTrain); var tr : PTrain; st : PStation; qinfo : TQInfo; begin create_queue(qinfo); tr:=train; while tr<>nil do begin st:=tr^.stations; while st<>nil do begin if st^.note.id<>0 then add_to_queue(qinfo, @st^.note, st^.note.id, 1, 0, 0); st:=st^.next; end; tr:=tr^.next; end; read_st_notes(qinfo); dispose_queue(qinfo); end; { read_all_st_notes } procedure read_deps(var qinfo : TQInfo); var a,b : my_int; ptr, ptrtmp : PStation; begin read_until(DEP_MARK, false); a:=-1; b:=-1; ptr:=PStation(get_from_queue(qinfo, true)); while ptr<>nil do begin if ptr^.id.id=a then begin if ptr^.id.pos=b then begin with ptr^.next^ do begin departure:=ptrtmp^.next^.departure; arrival:=ptrtmp^.next^.arrival; distance:=ptrtmp^.next^.distance; id.id:=ptrtmp^.next^.id.id; note.id:=ptrtmp^.next^.note.id; end end else begin find_dep(ptr^.id.id, ptr^.id.pos-b); read(ttz_file, ptr^.next^.departure, ptr^.next^.arrival, ptr^.next^.distance, ptr^.next^.id.id, ptr^.next^.note.id); b:=ptr^.id.pos; ptrtmp:=ptr; end end else begin find_dep(ptr^.id.id, ptr^.id.pos); a:=ptr^.id.id; b:=ptr^.id.pos; read(ttz_file, ptr^.next^.departure, ptr^.next^.arrival, ptr^.next^.distance, ptr^.next^.id.id, ptr^.next^.note.id); ptrtmp:=ptr; end; if ptr^.next^.next<>nil then { if the train isn't already full } add_to_queue(qinfo, ptr^.next, ptr^.next^.id.id, ptr^.next^.id.pos, a, b); ptr:=PStation(get_from_queue(qinfo, true)); end; end; { read_deps } procedure read_all_deps(train : PTrain); var qinfo : TQInfo; tr : PTrain; i : my_int; begin i:=0; create_queue(qinfo); tr:=train; while tr<>nil do begin add_to_queue(qinfo, tr^.stations, tr^.stations^.id.id, tr^.stations^.id.pos, 0,0); tr:=tr^.next; end; repeat inc(i); write(stderr, 'loop #',i, #13); reset(ttz_file); make_actual(qinfo); read_deps(qinfo); until qinfo.count=0; writeln(stderr); dispose_queue(qinfo); end; (* * *************** * Main procedures * *************** *) procedure print_towns; begin read_until(TOWNS_MARK, false); read_until(CONN_MARK, true); end; { print_towns } procedure print_conn_names; begin read_until(CONN_MARK, false); read_until(BREM_MARK, true); end; { print_conn_names } procedure find_connections_by_name(conn_name : string); var tr, train : PTrain; begin if not read_conns(train, conn_name) then error('Given connection doesn''t exists'); writeln(stderr, 'Reading connection heads'); read_all_heads(train); reset(ttz_file); writeln(stderr, 'Reading stations'); read_all_deps(train); reset(ttz_file); writeln(stderr, 'Reading station names'); read_all_station_names(train); writeln(stderr, 'Reading train remarks'); read_all_notes(train); writeln(stderr, 'Reading station remarks'); read_all_st_notes(train); tr:=train; while tr<>nil do begin make_absolute(tr); tr:=tr^.next; end; print_trains(train); end; { find_connections_by_name } procedure find_connections_by_station(st_name, dat1, tim1, dat2, tim2, st2_name : string; du : boolean); var id : my_int; prev, p, q, train, train2 : PTrain; D1, D2, now : TDate; nt : PNote; suitable : boolean; st : PStation; qinfo1, qinfo2 : TQInfo; begin default_uncertain:=du; str2date(dat1, tim1, D1); str2date(dat2, tim2, D2); writeln(stderr, 'Searching for given stations in .tti'); read_until(TOWNS_MARK, false); id:=read_same(st_name, CONN_MARK); if id=-1 then error('Given station doesn''t exists'); create_from_tti(train, id); if st2_name<>'' then begin create_queue(qinfo1); create_queue(qinfo2); reset(ttz_file); read_until(TOWNS_MARK, false); id:=read_same(st2_name, CONN_MARK); if id=-1 then error('Given station doesn''t exists'); create_from_tti(train2, id); make_tr_absolute(train); make_tr_absolute(train2); p:=train; while p<>nil do begin add_to_queue(qinfo1, p, p^.id, 0, 0, 0); p:=p^.next; end; p:=train2; while p<>nil do begin add_to_queue(qinfo2, p, p^.id, 0, 0, 0); p:=p^.next; end; p:=get_from_queue(qinfo1, true); q:=get_from_queue(qinfo2, true); new(train); train^.next:=nil; prev:=train; repeat if p^.idnil do begin make_absolute(p); st:=find_station_by_name(p^.stations, st_name); now.hour:=(st^.departure-1500) div 60; now.minute:=(st^.departure-1500) mod 60; suitable:=exists(D1, D2, now, ''); if st2_name<>'' then if find_station_by_name(st, st2_name)=nil then suitable:=false; nt:=p^.rnotes; while nt<>nil do begin if not exists(D1, D2, now, nt^.name) then suitable:=false; nt:=nt^.next; end; if not suitable then begin if prev=nil then train:=train^.next else prev^.next:=p^.next; end else prev:=p; p:=p^.next; end; print_trains(train); end; { find_connections_by_station } (* * ************ * Main program * ************ *) begin default_uncertain:=false; if (paramcount<2) or (length(paramstr(1))<2) then print_info; case paramstr(1)[2] of 'l', 'L' : if paramcount<>2 then print_info; 'c' : if paramcount<>3 then print_info; 'A', 'a' : if paramcount<>8 then print_info; 'B', 'b' : if paramcount<>9 then print_info; else print_info; end; { case } open(ttz_file, paramstr(2)); if paramcount>=4 then open(tti_file, paramstr(3)); case paramstr(1)[2] of 'l' : print_towns; 'L' : print_conn_names; 'c' : find_connections_by_name(paramstr(3)); 'A' : find_connections_by_station(paramstr(4), paramstr(5), paramstr(6), paramstr(7), paramstr(8), '', false); 'B' : find_connections_by_station(paramstr(4), paramstr(5), paramstr(6), paramstr(7), paramstr(8), paramstr(9), false); 'a' : find_connections_by_station(paramstr(4), paramstr(5), paramstr(6), paramstr(7), paramstr(8), '', true); 'b' : find_connections_by_station(paramstr(4), paramstr(5), paramstr(6), paramstr(7), paramstr(8), paramstr(9), true); end; { case } end.