PROGRAM trimline; {$e+} {Program to read a file, trim the rightmost columns, } {then trim trailing blanks, and then output into a } {second file. } CONST version = '1.0'; maxline = 255; {longest line we can handle} TYPE byte = 0..255; char12 = PACKED ARRAY [1..12] OF CHAR; STRING0 = STRING 0; STRING255 = STRING 255; line_string = STRING maxline; VAR status :INTEGER; flag :BOOLEAN; trim_flag :BOOLEAN; list_flag :BOOLEAN; debug_flag :BOOLEAN; inf_name :char12; inf_file :TEXT; {input file variable} outf_name :char12; outf_file :TEXT; {output file variable} rec_count, rec_thousands :INTEGER; this_line :line_string; trunc_length :INTEGER; {truncate lines to this length} {-----------------------------------------------------------} {-----------------------------------------------------------} {-----------------------------------------------------------} FUNCTION LENGTH ( str: STRING255) :INTEGER; EXTERNAL; FUNCTION INDEX ( stra, strb :STRING255 ):INTEGER; EXTERNAL; PROCEDURE SETLENGTH (VAR str :STRING0; len :INTEGER); EXTERNAL; {-----------------------------------------------------------} PROCEDURE trim_blanks ( VAR this_line :line_string ); {Trim trailing blanks } VAR col :INTEGER; flag :BOOLEAN; BEGIN{PROCEDURE} col := LENGTH (this_line); flag := FALSE; WHILE (col>0) AND (NOT flag) DO BEGIN IF this_line[col] = ' ' THEN BEGIN col := col - 1; END ELSE BEGIN flag := TRUE; END{IF}; END{WHILE}; SETLENGTH (this_line, col); IF debug_flag THEN BEGIN col := LENGTH (this_line); WRITELN ('%exit trim_blanks: length=', col:4); WRITELN (this_line); END{IF}; END{PROCEDURE}; {--------------------------------------------------------} PROCEDURE truncate_line (VAR this_line :line_string); VAR len :INTEGER; BEGIN{PROCEDURE} len := LENGTH (this_line); IF len > trunc_length THEN BEGIN SETLENGTH (this_line, trunc_length); END{IF}; IF debug_flag THEN BEGIN len := LENGTH (this_line); WRITELN ('%exit trunc_line: length=', len:4); WRITELN (this_line); END{IF}; END{PROCEDURE}; {--------------------------------------------------------} FUNCTION upper_case (in_char :CHAR) :CHAR; BEGIN upper_case := in_char; IF in_char IN ['a'..'z'] THEN BEGIN upper_case := CHR( ORD(in_char) - 32 ); END{IF}; END{FUNCTION}; {--------------------------------------------------------} FUNCTION ask_yes_or_no :BOOLEAN; VAR flag :BOOLEAN; response :CHAR; BEGIN{FUNCTION} flag := FALSE; WHILE NOT flag DO BEGIN WRITE ('(Y or N)'); READLN(response); response := upper_case (response); IF (response='Y') OR (response='N') THEN BEGIN flag := TRUE; END ELSE BEGIN WRITELN('Try again. '); END{IF}; END{WHILE}; ask_yes_or_no := response='Y'; END{FUNCTION}; {--------------------------------------------------------} FUNCTION get_open :INTEGER; VAR result :INTEGER; BEGIN{FUNCTION}; result := 0; WRITE ('Enter the input file name: '); READLN (inf_name); RESET (inf_name, inf_file); IF EOF(inf_file) THEN result := -1; get_open := result; END{FUNCTION}; {--------------------------------------------------------} FUNCTION get_close :INTEGER; BEGIN{FUNCTION} get_close := 0; END{FUNCTION}; {--------------------------------------------------------} FUNCTION get_line (VAR this_line :line_string) :INTEGER; VAR result :INTEGER; len :INTEGER; BEGIN{FUNCTION} result := 0; IF EOF(inf_file) THEN BEGIN result := -1; SETLENGTH (this_line, 0); END ELSE BEGIN READLN (inf_file, this_line); IF debug_flag THEN BEGIN len := LENGTH (this_line); WRITELN ('Input line: status=', result:4, ' length=', len:3); WRITELN (this_line); END{IF}; END{IF}; get_line := result; END{FUNCTION}; {--------------------------------------------------------} FUNCTION put_open :INTEGER; VAR result :INTEGER; BEGIN{FUNCTION}; result := 0; WRITE ('Enter the output file name: '); READLN (outf_name); REWRITE (outf_name, outf_file); rec_count := 0; rec_thousands := 0; put_open := result; END{FUNCTION}; {-----------------------------------------------------------} FUNCTION put_close :INTEGER; VAR result :INTEGER; BEGIN{FUNCTION} result := 0; WRITELN (rec_thousands:4, ',', rec_count:3, ' output records in file ', outf_name ); put_close := result; END{FUNCTION}; {--------------------------------------------------------} FUNCTION put_line (VAR this_line :line_string ) :INTEGER; VAR result :INTEGER; len :INTEGER; BEGIN{FUNCTION} result := 0; IF list_flag and debug_flag THEN BEGIN len := LENGTH (this_line); WRITE (len:2, ' '); END{IF}; IF list_flag THEN WRITELN (this_line ); WRITELN (outf_file, this_line ); rec_count := rec_count + 1; IF rec_count >= 1000 THEN BEGIN rec_thousands := rec_thousands + 1; rec_count := 0; END{IF}; put_line := result; END{FUNCTION}; {-------------------------------------------------------} {-------------------------------------------------------} {-------------------------------------------------------} BEGIN{PROGRAM} WRITELN ('Trim File Program Version ', version); WRITELN ('This program reads an input file, trims the '); WRITELN ('last N columns from the lines, then trims any'); WRITELN ('trailing blanks,'); WRITELN ('and writes lines into output file.'); WRITE('Debugging on? '); debug_flag := ask_yes_or_no; IF debug_flag THEN WRITELN('Debug is on.'); WRITE('List the lines as they are read? '); list_flag := ask_yes_or_no; flag := FALSE; WHILE NOT flag DO BEGIN WRITE ('Enter column# to which we will truncate: '); READLN (trunc_length); IF (trunc_length < 1) OR (trunc_length > 255) THEN BEGIN WRITELN ('*** Too small or too big. Try again.'); END ELSE BEGIN WRITELN ('Lines longer than ', trunc_length:3, ' will be truncated.'); flag := TRUE; END{IF}; END{WHILE}; WRITE('Trim trailing blanks from output lines? '); trim_flag := ask_yes_or_no; status := get_open; IF status <> 0 THEN WRITELN ('Cannot open input file.'); IF status=0 THEN BEGIN status := put_open; IF status <>0 THEN WRITELN ('Cannot open output file.'); END{IF}; IF status=0 THEN BEGIN WHILE status = 0 DO BEGIN status := get_line (this_line); IF status = 0 THEN BEGIN truncate_line (this_line); IF trim_flag THEN trim_blanks (this_line); status := put_line (this_line); END{IF}; END{WHILE}; END{IF}; status := get_close; status := put_close; WRITELN('End of Trim'); END{PROGRAM} . .