{+ Extract Comments Program GETRNO +L Prog. Name : GETRNO File Name : GETRNO.PAS Programmer : S. G. Smith E Systems Melpar Division 7700 Arlington Blvd Falls Church VA 22046 (703) 560 5000 X2390 Version : 1 Rev. 0 Date : 10 September 1982 Current Rev No. : 1 Latest Rev Date : 1 December 1982 -L Description This program extracts flagged comment fields from a source file and sends them to a RUNOFF source file. Other Resources Required +h Runtime In manual input mode only, the file DK:HEADER.RNO. In command file input mode, the command file, formatted as described under "Operation". Compile Time These files must be present on device SRC: +l GETRNO.PAS Main source file GETGLO.PAS Globals for all source files STRING.DEC Procedure declarations for string functions -l Link Time +l GETRNO.OBJ Main source OUTRNO.OBJ Procedure Write_Runoff_File STRING.OBJ String functions SY:PASCAL.OBJ Normal PASCAL compiler library -l -h Operation GETRNO is started by RUN GETRNO. The program will prompt for a command file name. If you enter a name, the output filename, the header filename, and the input filenames will be taken from that file. If you enter a blank line, the program will prompt you for the names of the output and input files, and the header information will be taken from the file DK:HEADER.RNO. The program will keep asking for more source files until you enter a blank line. On all input files, the extension MUST be one of the following: +L .RNO RUNOFF/General Text .MAC MACRO .SAL SAL11 .ASM MC6809 .S09 MC6809 .PAS PASCAL .FOR FORTRAN .FLX FLEX .COM RT-11 Command Files -L If the extension is not one of the above, the program will print a warning message and continue. Command File Format The files MUST be in the order listed. Blank lines ARE significant. +L Output file name (the default type is .RNO) Header file name Input file name . . . Input file name Blank line -L The extension of the input files must be one of those listed above. Header file The header file contains the initial setup to pass to RUNOFF and a .TITLE command, if desired. This file is a normal RUNOFF source file, and the first thing in the file must be a "+" command to enable GETRNO to send it to the output file. Source File Structure Commands start in the first column of the comment (regardless of where the comment occurs on the line). The first character of the command is one of the commands listed below. The options available with each command are shown after the command. Commands (except the Auto Header Level) will be sent to the source file regardless of whether or not text output is enabled. +L FORMATTER COMMANDS: "+" '+' turns an option on or increments a counter '+ ' Start Output. Any text becomes a subtitle. If text is present, it starts a new page. +L, +l Literal Output On. On => comment text is passed directly +H, +h Increment the current header level by 1. "-" '-' turns an option off or decrements a counter '- ' Start/Stop Output -L, -l Literal Output On/Off. On => comment text is passed directly -H, -h Decrement the current header level by 1 ";" ';' Immediate literal indicator. The line will appear "as is" in the output. "!" '!' indicates a general command that doesn't change any status '!.' indicates a RUNOFF command. It is passed directly out. !Hn, !hn Set header level to N. Valid values are 1..5 " " x If the first character of a comment line is blank and the second is any nonblank character, then the rest of the line is passed to a header command at the current header level. -L Blank comment lines are passed out directly. RUNOFF's case control and underlining characters have no effect within normal or literal text, but they are still effective in commands that take a string as argument, such as the header level. Bugs +h Main routine The filename input is awkward. SAL11/MACRO Input Any part of a line with a ";" character preceeding it will be flagged as a comment. This is true even if it is in a quoted string. PASCAL Input GETRNO cannot handle completely general comments. Problems happen when two or more seperate comments are on a line, and when a quoted string contains an opening comment character. In general, the last comment opening character on a line is the only one that is used. -h -} {+ Changes : +h ^&1 December 1982\& Added FOR and COM file handling. Added startup info line. -h -} %INCLUDE SRC:GETGLO.PAS; {Global Declarations} %INCLUDE SRC:STRING.DEC; {Declare string functions} PROCEDURE Write_Runoff_File(FUNCTION Strip_Com(VAR S : String) : BOOLEAN); EXTERNAL; PROCEDURE Get_Command_File; BEGIN WRITE('Command File Name --> '); ReadString(INPUT, Name); From_File := Name.Len > 2; IF From_File THEN RESET(Com_File, Name.Ch, 'GETRNO.SRC'); END; PROCEDURE Get_Out_File(VAR Name : String); BEGIN IF From_File THEN ReadString(Com_File, Name) ELSE BEGIN WRITE('Output File Name --> '); ReadString(INPUT, Name); END; END; FUNCTION Get_Filename(VAR Name : String;VAR Type_No : INTEGER) : BOOLEAN; TYPE Ch4 = PACKED ARRAY[1..4] OF CHAR; VAR I : INTEGER; FUNCTION Is_Type(ty : Ch4) : Boolean; VAR T : String; BEGIN Clear(T); T.Len := 4; T.Ch[1] := ty[1]; T.Ch[2] := ty[2]; T.Ch[3] := ty[3]; T.Ch[4] := ty[4]; Is_Type := Search(Name, T, 1) <> 0; END; BEGIN IF First AND NOT From_File THEN BEGIN Name.Len := 16; FOR I := 1 TO 16 DO Name.Ch[I] := First_File[I]; Type_No := 0; {.RNO File} END ELSE BEGIN IF From_File THEN ReadString(Com_File, Name) ELSE BEGIN WRITE('Input File Name --> '); ReadString(INPUT, Name) END; FOR I := 1 TO Name.Len DO IF Name.Ch[I] IN ['a'..'z'] THEN Name.Ch[I] := CHR(ORD(Name.Ch[I]) - 32); IF Is_type('.RNO') THEN Type_No := 0 {Runoff Source} ELSE IF Is_Type('.SAL') THEN Type_No := 1 {SAL11 Source} ELSE IF Is_Type('.MAC') THEN Type_No := 1 {MACRO Source} ELSE IF Is_Type('.S09') THEN Type_No := 1 {6809 Source} ELSE IF Is_Type('.ASM') THEN Type_No := 1 {6809 Source} ELSE IF Is_Type('.PAS') THEN Type_No := 2 {PASCAL Source} ELSE IF Is_Type('.FOR') THEN Type_No := 3 {FORTRAN Source} ELSE IF Is_Type('.FLX') THEN Type_No := 3 {FLEX Source} ELSE IF Is_Type('.COM') THEN Type_No := 4 {Command Source} ELSE Type_No := 999; {Unknown file type} Get_Filename := Name.Len > 2; END; First := FALSE; END; FUNCTION Get_RNO_Lines(VAR S : String) : BOOLEAN; BEGIN Get_RNO_Lines := TRUE; {All lines go out} END; FUNCTION Set_Off(VAR S : String; Delimiter : CHAR) : BOOLEAN; VAR Srch : String; L : INTEGER; BEGIN Clear(Srch); Srch.Len := 1; Srch.Ch[1] := Delimiter; L := Search(S, Srch, 1); {Find comment delimiter} Delete(S, 1, L); {Delete non comment portion of line} Set_Off := L <> 0; {TRUE if line has a comment} IF (L <> 0) AND (S.Len = 0) THEN S.Len := 1; {Blank line has length of 1} END; FUNCTION Get_SAL_Lines(VAR S : String) : BOOLEAN; BEGIN Get_SAL_Lines := Set_Off(S, ';'); END; FUNCTION Get_PAS_Lines(VAR S : String) : BOOLEAN; PROCEDURE Replace_Comment(VAR S : String); VAR T, U : String; Pos : INTEGER; PROCEDURE Replace; BEGIN REPEAT Pos := Search(S, T, 1); IF Pos <> 0 THEN BEGIN Delete(S, Pos, 2); Insert(S, U, Pos); END; UNTIL Pos = 0; END; BEGIN Clear(T); T.Len := 2; T.Ch[1] := '('; T.Ch[2] := '*'; Clear(U); U.Len := 1; U.Ch[1] := '{'; Replace; T.Ch[1] := '*'; T.Ch[2] := ')'; U.Ch[1] := '}'; Replace; END; FUNCTION Find_Start(VAR S : String) : BOOLEAN; VAR T : String; Start_Pos, Last_Pos, Pos1, Pos2 : INTEGER; BEGIN Clear(T); T.Len := 1; T.Ch[1] := '{'; Start_Pos := 0; REPEAT Last_Pos := Start_Pos; Start_Pos := Search(S, T, Last_Pos + 1); UNTIL Start_Pos = 0; SubString(T, S, Last_Pos, -StringMax); {Get non comment portion} Delete(S, Last_Pos+1, -StringMax); Find_Start := Last_Pos <> 0; END; FUNCTION Find_End(VAR S : String) : BOOLEAN; VAR T1 : String; Pos : INTEGER; BEGIN Clear(T1); T1.Len := 1; T1.Ch[1] := '}'; Pos := Search(S,T1,1); IF Pos <> 0 THEN Delete(S,Pos,StringMax); Find_End := (Pos <> 0) AND (S.Len > 0); END; BEGIN Replace_Comment(S); IF Comment_Flag THEN BEGIN Comment_Flag := NOT Find_End(S); Get_PAS_Lines := S.Len > 0; END ELSE BEGIN Comment_Flag := Find_Start(S); Get_PAS_Lines := Comment_Flag; IF Comment_Flag THEN Comment_Flag := NOT Find_End(S); END; END; FUNCTION Get_FOR_Lines(VAR S : String) : BOOLEAN; VAR Comment : BOOLEAN; BEGIN Comment := (S.Ch[1] = 'c') OR (S.Ch[1] = 'C'); IF Comment THEN Delete(S, 1, 1); Get_FOR_Lines := Comment; END; FUNCTION Get_COM_Lines(VAR S : String) : BOOLEAN; BEGIN Get_COM_Lines := Set_Off(S, '!'); END; PROCEDURE Unknown_Type; BEGIN WRITE('>>> Bad File Type in File '); WriteString(OUTPUT, Name); WRITELN; END; BEGIN WRITELN('Extract flagged comments to RUNOFF file 1 December 1982'); First := TRUE; Get_Command_File; Get_Out_File(Name); REWRITE(Out_File, Name.Ch, '.RNO'); WHILE Get_Filename(Name, File_Type) DO BEGIN RESET(Inp_File, Name.Ch, Name.Ch, L); CASE File_Type OF 0: Write_Runoff_File(Get_RNO_Lines); {Header or RUNOFF source} 1: Write_Runoff_File(Get_SAL_Lines); {SAL11 or MACRO source file} 2: Write_Runoff_File(GET_PAS_Lines); {PASCAL source file} 3: Write_Runoff_File(GET_FOR_Lines); {FORTRAN/FLEX source file} 4: Write_Runoff_File(GET_COM_Lines); {Command source file} OTHERWISE Unknown_Type; END; {Case} CLOSE(Inp_File); END; CLOSE(Out_File); END.