home *** CD-ROM | disk | FTP | other *** search
-
- PROGRAM pformat (INPUT, OUTPUT);
-
- {----------------------------------------------------------------------------}
- { Compiler Directives Follow }
- {$X+} {Array Optimization ON ... This PGM is Very-Much-So Array Driven}
- {$U-} {Non-User-Interruptible}
- {$K-} {NO Stack Checking}
- {$C-} {KeyBoard CTRL-<char> Interp OFF}
- {$R-} {NO Index Range Checking}
- {$V-} {Var Parameter Type Checking OFF}
- {----------------------------------------------------------------------------}
-
- { ========================================================================
-
- pFORMAT version 2.0.2
- ~~~~~~~~~~~~~~~~~~~~~
- AUTHOR: andy j s decepida 26-AUG-85
- 416 Perth Avenue, Toronto, Ontario, CANADA M6P 3Y6
-
- DESCRIPTION: Reads in a .PAS text file and, depending on the user's
- choice/s, generates a copy with alterations in the case of
- the contained text.
- Modifications
- (2.0.0) : File Attributes routine has been changed;
- prior algorithm worked only for Turbo Pascal
- compiler release 2.xx; the current one accomodates
- both 2.xx & 3.xx;
- (2.0.0) : Reserved Words Table has been expanded to accomodate
- new ones in Turbo Pascal 3.0;
- (2.0.1) : Disabled Routing to Printer which was primitive (no
- Pagination) anyway;
- (2.0.1) : Added handling of hexadecimal literals
- (preceded by '$' and composed of '0'..'9', 'A'..'F')
- --- these literals will be made uppercase (only letters
- 'A'..'F' of course)
- (2.0.1) : Added handling of CommandLine Parameters
- When present, the 1st Parm is the InputFile
- the 2nd Parm is the OutputFile
- (2.0.2) : Prior versions would mishandle a line that has
- more than one comment in it ... the comment/s subsequent
- to the first is/are treated as executable; this has
- been corrected.
- (2.0.2) : Corrected an incipient bug in keypress-to-signal-run-abort
- option (scenario: when option is active and the user,
- intentionally or not, presses key "Y" the abort-confirm
- hesitation query would already have been answered);
- Correction implemented by changing function getc to
- use the DOS call $0C to clear KBD buffer then let the
- same chain to DOS call $07 (stdin w/o input)
-
- As distributed, the source for pFORMAT.PAS has been submitted to pformat
- itself. All ISO-PASCAL words are in caps and the Turbo-Extensions are
- in mixed-case while user-defined words are in lower-case.
-
- I am also providing this source indented following the laudable indenting
- guidelines suggested by Robert E. Heckert in his article "A Pascal
- Indentation Philosophy" published in Computer Language magazine of
- Sept 1985 (v2,#9).
-
- ======================================================================= }
-
- CONST
- {$I tblsize.inc}
- alphabet : SET OF CHAR = ['a'..'z', 'A'..'Z'];
- nullstr = '';
- space = ' ';
- apostrophe = '''';
- period = '.';
- stdextns = '.PAS';
-
- TYPE
- charset = SET OF CHAR;
- cursorsize = (full, half, normal, invisible);
- s255 = STRING[255];
- casetype = (upper, lower, asis);
-
- VAR
- iobuf, linebuf, legend, mask,
- srcharg, tempstr, infnam,
- outfnam : s255;
- inf,
- outf : TEXT[$1000];
- token : ARRAY [1..tbl_size] OF STRING[20];
- case4reserved,
- case4nonreserved: casetype;
- strt, endd, posn, indx,
- parmcnt,
- len, cnt : INTEGER;
- reservedcount,
- linecount, charcount,
- commentcount: REAL;
- resp, prior,
- next : CHAR;
- mixedcase, abortable,
- commentactive, tokenfound,
- ok : BOOLEAN;
- {-----------------------------------------------------------------------------}
- PROCEDURE initarray;
- {-----------------------------------------------------------------------------}
- {
- initialize the reserved word array
- }
- BEGIN
- {$I TOKEN.INC}
- END; {initarray}
- {-----------------------------------------------------------------------------}
- PROCEDURE makecursor (size : cursorsize);
- {-----------------------------------------------------------------------------}
- {
- crsr is set according to the passed Size ... IBM-PC specific!
- }
- TYPE
- regpack = RECORD
- ax, bx, cx, dx, bp, si, di, es, flags : INTEGER;
- END; {of RegPack}
- VAR
- reg : regpack;
-
- BEGIN
- reg.ax := $0100; {set crsr type service code ... cf A-47 of
- Hardware Technical Reference Manual}
- CASE size OF
- full : reg.cx := $000D;
- half : reg.cx := $070C;
- normal : reg.cx := $0B0C;
- invisible: reg.cx := $2000
- END; {CASE Size OF}
- Intr ($10, reg) {call video I/O ROM call}
- END;
- {-----------------------------------------------------------------------------}
- FUNCTION isdelimited (ch : CHAR) : BOOLEAN;
- {-----------------------------------------------------------------------------}
- {
- TRUE if Ch is a valid delimiter for a substring pattern that matches that
- of a reserved word
- }
- BEGIN
- isdelimited := (ORD(ch) IN [32, 39..47, 58..62, 91, 93, 123, 125])
- END;
- {-----------------------------------------------------------------------------}
- FUNCTION lowcase (ch : CHAR) : CHAR;
- {-----------------------------------------------------------------------------}
- {
- returns lower case of an alpha char
- }
- BEGIN
- IF (ch IN ['A'..'Z'])
- THEN
- ch := CHR (ORD(ch) - ORD('A') + ORD('a'));
- lowcase := ch
- END;
- {-----------------------------------------------------------------------------}
- FUNCTION upstrg (strg : s255) : s255;
- {-----------------------------------------------------------------------------}
- {
- returns a string with alpha chars in capitals
- }
- VAR
- slot : INTEGER;
- BEGIN
- FOR slot := 1 TO Length(strg)
- DO
- strg[slot] := UpCase(strg[slot]);
- upstrg := strg
- END;
- {-----------------------------------------------------------------------------}
- FUNCTION lowstrg (strg : s255) : s255;
- {-----------------------------------------------------------------------------}
- {
- returns a string with alpha chars in lower-case
- }
- VAR
- slot : INTEGER;
- BEGIN
- FOR slot := 1 TO Length(strg)
- DO
- strg[slot] := lowcase(strg[slot]);
- lowstrg := strg;
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE alarm;
- {-----------------------------------------------------------------------------}
- {
- ! sounds an alarm
- }
- BEGIN
- Sound (100);
- Delay (60);
- NoSound;
- Sound (50);
- Delay (3);
- NoSound
- END;
- {-----------------------------------------------------------------------------}
- FUNCTION getc (legalchar : charset) : CHAR;
- {-----------------------------------------------------------------------------}
- {
- waits for a CHAR input belonging in set legalchar, we are using
- a DOS service call because we need a workaround to the bug
- described in the prologue comment regarding keypress-to-signal-run-abort
- feature
- }
- TYPE
- regpack = RECORD
- ax, bx, cx, dx, bp, si, di, es, flags : INTEGER;
- END; {of RegPack}
- CONST
- bks = 8;
- VAR
- inchr : CHAR;
- reg : regpack;
-
- BEGIN
- WRITE ('[ ]');
- WRITE (CHR(bks), CHR(bks), space,CHR(bks));
- REPEAT
- makecursor (full);
- reg.ax := $0C07; {Clear keyboard buffer & invoke DOS stdin w/o echo}
- MsDos (reg);
- inchr := CHR(Lo(reg.ax));
- inchr := UpCase (inchr);
- IF NOT (inchr IN legalchar)
- THEN
- alarm;
- UNTIL (inchr IN legalchar);
- makecursor (normal);
- getc := inchr
- END;
- {-----------------------------------------------------------------------------}
- FUNCTION yes : BOOLEAN;
- {-----------------------------------------------------------------------------}
- {
- waits for a y/Y or n/N CHAR input
- }
- VAR
- reply : CHAR;
- BEGIN
- WRITE (' [y/n] ■ ');
- LowVideo;
- yes := (getc(['Y','N']) = 'Y')
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE trim (VAR tempstr : s255);
- {-----------------------------------------------------------------------------}
- {
- strip leading spaces from a string
- }
- BEGIN
- WHILE Pos(space, tempstr) = 1
- DO
- Delete (tempstr, 1, 1)
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE userquits;
- {-----------------------------------------------------------------------------}
- {
- when the pgm gets here, the user has indicated his/her intentions
- }
- BEGIN
- Window (1,1,80,25);
- GoToXY (1, 1);
- LowVideo;
- makecursor (normal);
- ClrScr;
- {$I-}
- Close (inf);
- Close (outf);
- {$I+}
- HALT
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE confirm (confirmation : s255; reserved : BOOLEAN);
- {-----------------------------------------------------------------------------}
- {
- evaluate / confirm user's pick
- }
- PROCEDURE setto (userchoice : casetype);
- {-----------------------------------------------------------------------------}
- {
- "setto" is nested in confirm !!!
- change case4reserved & case4nonreserved settings as per userchoice
- }
- BEGIN
- IF reserved
- THEN
- case4reserved := userchoice
- ELSE
- case4nonreserved := userchoice
- END;
-
- BEGIN {confirm}
- WRITELN;
- WRITE (' You chose ');
- TextColor (Black);
- TextBackGround (White);
- CASE resp OF
- 'U' : BEGIN
- WRITE ('Upper-case');
- setto (upper)
- END;
- 'L' : BEGIN
- WRITE ('Lower-case');
- setto (lower)
- END;
- 'A' : BEGIN
- WRITE ('As-Is');
- setto (asis)
- END;
- 'Q' : userquits
- END; {CASE}
- LowVideo;
- WRITELN (space,confirmation);
- WRITE (' Is this correct? ')
- END; {confirm}
- {-----------------------------------------------------------------------------}
- PROCEDURE altersettings;
- {-----------------------------------------------------------------------------}
- BEGIN {altersettings}
- WRITELN;
- REPEAT
- WRITELN; WRITELN;
- WRITELN (' ■ PASCAL reserved words.');
- WRITE (' Options are : U(pper-case, L(ower-case, A(s-Is, Q(uit');
- resp := getc (['U','L','A','Q']);
- confirm ('for the RESERVED words.', TRUE)
- UNTIL yes;
- WRITELN; WRITELN; WRITELN;
- WRITELN (' ■ Turbo Pascal Extensions.');
- WRITELN (' Would you like to have the Borland extensions written ');
- WRITELN (' in "Mixed Case" (e.g., "GotoXY" instead of "GOTOXY"');
- WRITE (' or "gotoxy"?');
- mixedcase := yes;
- WRITELN;
- REPEAT
- WRITELN; WRITELN;
- WRITELN (' ■ Non-Reserved Words.');
- WRITE (' Options are : U(pper-case, L(ower-case, A(s-is, Q(uit');
- resp := getc (['U','L','A','Q']);
- confirm (' for the user defined identifiers.',FALSE);
- UNTIL yes
- END; {altersettings}
- {-----------------------------------------------------------------------------}
- PROCEDURE makemixedcase (VAR extension : s255);
- {-----------------------------------------------------------------------------}
- {
- when user selects the option for mixed-case formatting of reserved words,
- this proc will be invoked;
- }
- BEGIN {makemixedcase}
- CASE indx OF
- {$I EXTNS.INC}
- END; {CASE Indx OF}
- END; {makemixedcase}
- {-----------------------------------------------------------------------------}
- PROCEDURE findmatch;
- {-----------------------------------------------------------------------------}
- VAR
- place : INTEGER;
- {-----------------------------------------------------------------------------}
- FUNCTION isreserved : BOOLEAN;
- {-----------------------------------------------------------------------------}
- {
- returns true if token is properly delimited
- }
- BEGIN
- IF (place + Length(token[indx])) < len
- THEN { there is at least 1 }
- next := Copy(linebuf, { more character beyond }
- (place + (Length(token[indx]))), 1) { the pattern match }
- ELSE
- next := period; {the pattern match is end of the line ...so}
- {force Next to be a valid delimiter }
- IF place > 1
- THEN { the pattern is not at the start of the line }
- BEGIN
- prior := Copy(linebuf, place - 1, 1);
- isreserved := ((isdelimited(prior)) AND (isdelimited(next)))
- END
- ELSE
- IF place = 1
- THEN { the pattern is at the start of the line }
- isreserved := (isdelimited(next))
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE doreserved;
- {-----------------------------------------------------------------------------}
- BEGIN
- reservedcount := reservedcount + 1;
- srcharg := token[indx];
- CASE case4reserved OF
- lower : BEGIN
- Delete (iobuf, place, Length(token[indx]));
- srcharg := lowstrg (srcharg);
- IF mixedcase
- THEN
- makemixedcase (srcharg);
- Insert (srcharg, iobuf, place)
- END;
- upper : BEGIN
- Delete (iobuf, place, Length(token[indx]));
- IF mixedcase
- THEN
- makemixedcase (srcharg);
- Insert (srcharg, iobuf, place)
- END;
- asis : IF mixedcase
- THEN
- BEGIN
- Delete (iobuf, place, Length(token[indx]));
- makemixedcase (srcharg);
- Insert (srcharg, iobuf, place)
- END
- END {CASE case4reserved OF}
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE searchtable (arg : s255; VAR key : INTEGER; VAR found : BOOLEAN);
- {-----------------------------------------------------------------------------}
- {
- this is your basic binary table search algorithm ... no magic here
- }
- VAR
- lohalf,
- uphalf,
- centre : INTEGER;
-
- BEGIN {searchtable}
- lohalf := 1;
- uphalf := tbl_size;
- found := FALSE;
- WHILE (uphalf >= lohalf) AND (NOT found)
- DO
- BEGIN
- centre := (lohalf + uphalf) DIV 2;
- IF arg = token[centre]
- THEN
- BEGIN
- found := TRUE;
- key := centre
- END
- ELSE
- IF arg > token[centre]
- THEN
- lohalf := centre + 1
- ELSE
- uphalf := centre - 1
- END {WHILE}
- END; {searchtable}
- {-----------------------------------------------------------------------------}
- PROCEDURE buildarg;
- {-----------------------------------------------------------------------------}
- {
- step thru the string until a non-alphabetic char is encountered
- }
- VAR
- done : BOOLEAN;
-
- BEGIN {buildarg}
- REPEAT
- IF linebuf[posn] IN alphabet
- THEN
- srcharg := srcharg + linebuf[posn];
- done := ((NOT (linebuf[posn] IN alphabet)) OR (posn = len));
- IF NOT done
- THEN
- posn := SUCC(posn);
- UNTIL done
- END; {buildarg}
-
- {-------------------------------------------}
- BEGIN {findmatch}
- posn := 1;
- REPEAT {till the string is exhausted}
- srcharg := nullstr;
- place := posn;
- buildarg;
- IF Length(srcharg) > 1
- THEN
- BEGIN
- searchtable (srcharg, indx, tokenfound);
- IF tokenfound AND (isreserved)
- THEN
- doreserved
- END
- ELSE
- posn := SUCC(posn)
- UNTIL posn > len;
- IF abortable
- THEN {check for interrupt from keyboard}
- IF KeyPressed
- THEN
- BEGIN
- TextColor (Yellow);
- TextBackGround (Black);
- GoToXY (15, 11);
- WRITE ('Abort pFORMAT of file ',infnam,'?');
- IF yes
- THEN
- userquits
- ELSE
- BEGIN
- DelLine;
- makecursor (invisible)
- END
- END;
- LowVideo
- END; {findmatch}
- {-----------------------------------------------------------------------------}
- PROCEDURE mask_comments_strings;
- {-----------------------------------------------------------------------------}
- {
- find then mask out comments & strings so as-is chars can be restored from
- tempstr onto iobuf
- }
- {-----------------------------------------------------------------------------}
- PROCEDURE maskmatch (commentlen : INTEGER);
- {-----------------------------------------------------------------------------}
- VAR
- slot : INTEGER;
-
- BEGIN {maskmatch}
- tempstr := Copy (linebuf, strt, commentlen);
- FOR slot := 1 TO Length(tempstr)
- DO
- tempstr[slot] := space;
- Delete (linebuf, strt, commentlen);
- Insert (tempstr, linebuf, strt)
- END; {maskmatch}
-
- BEGIN {mask_comments_strings}
- REPEAT {do strings}
- strt := Pos(apostrophe, linebuf);
- IF strt <> 0
- THEN
- linebuf[strt] := space;
- endd := Pos (apostrophe, linebuf);
- IF endd <> 0
- THEN
- linebuf[endd] := space;
- IF ((endd <> 0) AND (strt <> 0))
- THEN
- maskmatch (endd - strt + 1)
- UNTIL ((endd = 0) OR (strt = 0));
-
- REPEAT
- strt := Pos('{', linebuf);
- IF strt = 0 {check again for alternative delimiter}
- THEN
- strt := Pos ('(*', linebuf);
- endd := Pos('}', linebuf);
- IF endd = 0 {check again for alternate delimiter}
- THEN
- endd := Pos('*)', linebuf);
- IF strt <> 0
- THEN
- BEGIN
- commentactive := TRUE;
- commentcount := commentcount + 1
- END;
- IF endd <> 0
- THEN
- commentactive := FALSE;
- IF strt = 0
- THEN
- IF endd = 0 {no end-comment nor begin-comment}
- THEN
- IF commentactive {continued multiline comment}
- THEN
- BEGIN
- strt := 1;
- maskmatch (len - strt + 1)
- END
- ELSE {no active comment}
- BEGIN {do nothing}
- END
- ELSE {end-comment found but no begin-comment}
- BEGIN {multiline comment being terminated on current line}
- strt := 1;
- maskmatch (endd - strt + 1)
- END
- ELSE {begin-comment found}
- IF endd <> 0
- THEN {line has begin-comment & end-comment}
- maskmatch (endd - strt + 1) {regular single line comment}
- ELSE {line has begin-comment but no end-comment}
- maskmatch (len - strt + 1) {start of a multiline comment}
- UNTIL ((endd = 0) OR (strt = 0));
- END; {mask_comments_strings}
- {-----------------------------------------------------------------------------}
- PROCEDURE parse;
- {-----------------------------------------------------------------------------}
- VAR
- slot : INTEGER;
- {-----------------------------------------------------------------------------}
- PROCEDURE fixhex (VAR subject : s255);
- {-----------------------------------------------------------------------------}
- {
- Ensure that the HexaDecimal Literals ( ::= (prefixed by a $) |0..9|
- A..F ) stand out better by having the occurrences of A..F xlat to
- uppercase unconditionally --- if you don't want this feature see
- main block of parse which calls this PROC
- }
- CONST
- hexset : SET OF CHAR = ['0'..'9', 'A'..'F'];
- hexprefix = '$';
- VAR
- from,
- num,
- len,
- step,
- place : INTEGER;
- hold,
- tmp,
- newstrg: s255;
- done : BOOLEAN;
- {-----------------------------------------------------------------------------}
- PROCEDURE fixhexinit;
- {-----------------------------------------------------------------------------}
- BEGIN
- hold := subject;
- from := 1;
- len := Length(hold);
- newstrg := nullstr;
- tmp := nullstr;
- END;
- {-----------------------------------------------------------------------------}
- FUNCTION ishexstr : BOOLEAN;
- {-----------------------------------------------------------------------------}
- BEGIN
- place := Pos (hexprefix, hold);
- ishexstr := place <> 0;
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE fixhex1;
- {-----------------------------------------------------------------------------}
- BEGIN
- num := place - from + 1;
- step := place + 1;
- tmp := newstrg;
- newstrg := Copy (hold, from, num);
- newstrg := tmp + newstrg;
- hold [place] := space;
- END;
-
- BEGIN {fixhex}
- fixhexinit;
- IF NOT ishexstr
- THEN
- Exit;
- WHILE ishexstr
- DO
- BEGIN
- fixhex1;
- done := FALSE;
- WHILE NOT done
- DO
- BEGIN
- IF UpCase(hold[step]) IN hexset
- THEN
- BEGIN
- IF step <= len {concat}
- THEN
- BEGIN
- newstrg := newstrg + UpCase(hold[step]);
- step := SUCC(step)
- END
- ELSE {a stray $ is at end of string ... concat done}
- done := TRUE;
- END
- ELSE
- done := TRUE
- END; {WHILE NOT done}
- from := step;
- END; {WHILE ishexstr}
- IF Length (newstrg) < len
- THEN {copy rest of the string}
- BEGIN
- from := step;
- hold := Copy (subject, from, len - from+1);
- subject := newstrg+hold
- END
- ELSE
- subject := newstrg;
- END;
-
- BEGIN {parse}
- linebuf := iobuf;
- len := Length (iobuf);
- charcount := charcount + len;
- mask_comments_strings;
- linebuf := upstrg (linebuf);
- tempstr := iobuf;
- IF case4nonreserved = upper
- THEN
- iobuf := upstrg (iobuf)
- ELSE
- IF case4nonreserved = lower
- THEN
- iobuf := lowstrg (iobuf);
- FOR slot := 1 TO Length(iobuf)
- DO
- IF linebuf[slot] = space
- THEN
- iobuf[slot] := tempstr[slot];
- fixhex (iobuf); {--- comment this out if you don't want hex literals in caps}
- findmatch
- END; {parse}
- {-----------------------------------------------------------------------------}
- PROCEDURE banner;
- {-----------------------------------------------------------------------------}
- CONST
- title = 'pFormat [v2.0.2] (C) Andy Decepida 1985-Aug-26';
-
- BEGIN
- Window (1, 1, 80, 25);
- GoToXY (1, 1);
- ClrScr;
- NormVideo;
- FOR cnt := 1 TO 80
- DO
- WRITE ('═');
- LowVideo;
- WRITELN (title:((80 + Length(title)) DIV 2));
- NormVideo;
- FOR cnt := 1 TO 80
- DO
- WRITE ('═');
- LowVideo;
- Window (1, 5, 80, 25);
- GoToXY (1, 1);
- WRITELN;
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE checksettings;
- {-----------------------------------------------------------------------------}
- BEGIN
- WRITELN; WRITELN;
- ClrScr; banner;
- TextColor (Brown);
- WRITELN ('Output File ',outfnam,apostrophe,'s default attributes are :');
- LowVideo;
- WRITELN (' ■ TurboPASCAL key/reserved words are in UPPER-case letters and');
- WRITELN (' ■ Other alphabetic characters are written as is.');
- WRITELN;
- WRITE ('Care to change these defaults ? ');
- IF yes
- THEN
- altersettings
- ELSE
- BEGIN
- case4reserved := upper;
- case4nonreserved := asis;
- END;
- NormVideo;
- WRITELN;
- WRITELN;
- WRITE ('Would you like to be able to abort this run with a keypress ?');
- abortable := yes;
- LowVideo
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE get_attr (fd : s255);
- {-----------------------------------------------------------------------------}
- {
- Get the File Attributes for displaying to user ... for confirmation
- purposes ... IBM-PC specific
- }
- TYPE
- filelist = RECORD
- name : STRING[13];
- attrib : Byte;
- size : REAL;
- date,
- time : s255;
- END;
- regpack = RECORD
- ax,bx,cx,dx,bp,si,di,ds,es,flags: INTEGER
- END;
- wrkstr = STRING[80];
-
- VAR
- list: filelist;
- sizestr,
- filemask: wrkstr;
- x,total: Byte;
- recpack: regpack;
- hidden,system,readonly,normal,archive,dircty: BOOLEAN;
- {-----------------------------------------------------------------------------}
- PROCEDURE directory(filemask: wrkstr; VAR list: filelist; VAR total: Byte);
- {-----------------------------------------------------------------------------}
- VAR
- dta: STRING[44];
- {-----------------------------------------------------------------------------}
- FUNCTION filesiz: REAL; { decipher the File's Size in Bytes }
- {-----------------------------------------------------------------------------}
- VAR size: REAL;
- byte1,byte2,byte3,byte4: Byte;
- BEGIN
- byte1 := ORD(Copy(dta,28,1));
- byte2 := ORD(Copy(dta,27,1));
- byte3 := ORD(Copy(dta,29,1));
- byte4 := ORD(Copy(dta,30,1));
- size := byte1 ShL 8+byte2;
- IF size< 0
- THEN
- size := size+65536.0; { adjust for negative values }
- size := (byte3 ShL 8+byte4)*256.0+size;
- filesiz := size;
- END; { filesiz }
- {-----------------------------------------------------------------------------}
- FUNCTION filedate: wrkstr; { decipher the File's Date Stamp }
- {-----------------------------------------------------------------------------}
- VAR day,month,year: wrkstr;
- mon : STRING[3];
- temp: INTEGER;
- byte1,byte2: Byte;
- BEGIN
- byte1 := ORD(Copy(dta,25,1));
- byte2 := ORD(Copy(dta,26,1));
- Str(byte1 AND 31:2,day);
- temp := (byte1 ShR 5) AND 7+(byte2 AND 1) ShL 3;
- CASE temp OF
- 01 : mon := 'Jan'; 02 : mon := 'Feb'; 03 : mon := 'Mar';
- 04 : mon := 'Apr'; 05 : mon := 'May'; 06 : mon := 'Jun';
- 07 : mon := 'Jul'; 08 : mon := 'Aug'; 09 : mon := 'Sep';
- 10 : mon := 'Oct'; 11 : mon := 'Nov'; 12 : mon := 'Dec'
- END;
- Str((byte2 ShR 1)+80: 2,year);
- IF day[1]= space
- THEN
- day[1] := '0';
- IF year[1]= space
- THEN
- year[1] := '0';
- filedate := day+'-'+mon+'-'+year
- END; { filedate }
- {-----------------------------------------------------------------------------}
- FUNCTION filetime: wrkstr; { decipher the File's Time Stamp }
- {-----------------------------------------------------------------------------}
- VAR hour,min,ampm: wrkstr;
- temp: INTEGER;
- byte1,byte2: Byte;
- BEGIN
- byte1 := ORD(Copy(dta,23,1));
- byte2 := ORD(Copy(dta,24,1));
- temp := (byte1 ShR 5) AND 7+(byte2 AND 7) ShL 3;
- Str(temp:2,min);
- temp := byte2 ShR 3;
- IF temp<13
- THEN
- ampm := 'am'
- ELSE
- BEGIN
- temp := temp-12;
- ampm := 'pm'
- END;
- Str(temp:2,hour);
- WHILE (Pos(space, hour) <> 0)
- DO
- Delete (hour,1,1);
- IF min[1]= space
- THEN
- min[1] := '0';
- filetime := hour+':'+min+ampm
- END; { filetime }
- {-----------------------------------------------------------------------------}
- PROCEDURE fillrecord(recno: Byte); { fill List.[RecNo] with file info }
- {-----------------------------------------------------------------------------}
- BEGIN
- WITH list
- DO
- BEGIN
- name := Copy(dta,31,13);
- attrib := ORD(Copy(dta,22,1));
- size := filesiz;
- date := filedate;
- time := filetime;
- IF (name[1]<>period) AND (Pos(period,name)<>0)
- THEN
- BEGIN { line up the file ext.}
- WHILE Pos(period,name)<9
- DO
- Insert(space,name,Pos(period,name));
- name[Pos(period,name)] := space;
- END;
- END;
- END; { fillrecord }
- {-----------------------------------------------------------------------------}
- PROCEDURE filldirlist;
- {-----------------------------------------------------------------------------}
- BEGIN
- total := 1;
- fillrecord(total);
- REPEAT
- recpack.ax := $4F ShL 8;
- MsDos(recpack);
- IF (recpack.ax<>18) AND (recpack.ax<>2)
- THEN
- BEGIN
- total := total+1;
- fillrecord(total)
- END { repeat filling until no more }
- UNTIL (recpack.flags AND 1)<>0;{ files are found }
- END; { filldirlist }
-
- BEGIN { Directory }
- total := 0;
- dta := ' ';
- filemask := filemask+#0;
- WITH recpack
- DO
- BEGIN { First, Set aside the DTA }
- ax := $1A ShL 8; { or Data Transfer Area, }
- ds := Seg(dta);
- dx := Ofs(dta)+1; { call $1A then call $4E to }
- MsDos(recpack); { find the First Match. Set }
- ax := $4E ShL 8; { set Cx to 23 to include all }
- ds := Seg(filemask);
- dx := Ofs(filemask)+1; { hidden files. Then up above }
- cx := 23; { call $4F to find subsequent }
- MsDos(recpack); { matches, filling List. }
- IF (flags AND 1)=0
- THEN
- filldirlist
- END
- END; { directory }
-
- BEGIN
- directory(fd,list,total); { if available }
- WRITELN;
- WITH list
- DO
- BEGIN
- Str(size:15:0, sizestr);
- WHILE (Pos(space,sizestr) <> 0)
- DO
- Delete (sizestr,1,1);
- WRITE ('The ', sizestr, '-byte file ');
- HighVideo;
- WRITE (fd);
- LowVideo;
- WRITE (' was saved on ', date);
- WRITE (' at ', time);
- END;
- WRITELN;
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE checkinput;
- {-----------------------------------------------------------------------------}
- BEGIN
- IF Length (infnam) < 1
- THEN
- userquits;
- IF (Pos (period, infnam) = 0)
- AND (Pos (stdextns, infnam) = 0)
- THEN
- infnam := infnam+stdextns;
- Assign (inf, infnam);
- {$I-}
- RESET (inf)
- {$I+};
- ok := (IOResult = 0);
- IF ok
- THEN
- BEGIN {open of an existing file is successful}
- get_attr (infnam);
- WRITELN;
- NormVideo;
- WRITE ('Is this the file you really want to submit? ');
- IF NOT yes
- THEN
- ok := FALSE;
- LowVideo
- END
- ELSE
- BEGIN
- alarm; alarm; alarm;
- WRITELN; WRITELN;
- WRITE (' ... Cannot find file ');
- NormVideo;
- WRITE (infnam);
- LowVideo;
- WRITELN(' ... PRESS ',CHR(17),'┘');
- WRITELN;
- makecursor (invisible);
- READLN (KBD);
- END
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE getinfnam;
- {-----------------------------------------------------------------------------}
- BEGIN {getinfnam}
- ok := FALSE;
- WHILE NOT ok
- DO
- BEGIN
- WRITELN;
- LowVideo;
- WRITE ('Name of TurboPASCAL source text file : ');
- makecursor (full);
- READLN (infnam);
- makecursor(invisible);
- trim (infnam);
- infnam := upstrg (infnam);
- checkinput;
- END; {WHILE}
- makecursor (normal)
- END; {getinfnam}
- {-----------------------------------------------------------------------------}
- PROCEDURE checkoutput;
- {-----------------------------------------------------------------------------}
- BEGIN
- outfnam := upstrg (outfnam);
- IF Length (outfnam) < 1
- THEN
- userquits;
- IF (Pos (period, outfnam) = 0) {concat (.PAS) only if }
- AND (Pos (stdextns, outfnam) = 0) {there is no supplied extns}
- THEN
- outfnam := outfnam+stdextns;
- IF outfnam = infnam
- THEN
- BEGIN
- TextColor (Yellow);
- makecursor (invisible);
- WRITELN;
- alarm; alarm; alarm;
- WRITELN ('You have PERILOUSLY designated the same file_name for both your');
- WRITELN (' input and your output file !!! ');
- WRITELN;
- WRITELN(' PRESS ',CHR(17),'┘ ... ');
- WRITELN;
- WRITELN(' And then give an output file name that is different from the input.');
- alarm;
- READLN (KBD);
- LowVideo;
- ok := FALSE;
- Exit;
- END;
- Assign (outf, outfnam);
- {$I-}
- RESET (outf); {check & see if destination file}
- {$I+} { already exists}
- ok := (IOResult = 0);
- IF ok
- THEN
- BEGIN
- WRITELN; WRITELN;
- TextColor (Black);
- TextBackGround (White);
- WRITELN (' ■ ',outfnam,' already exists ...');
- LowVideo;
- alarm; alarm; alarm;
- get_attr(outfnam);
- alarm;
- WRITELN;
- TextColor (Yellow);
- WRITE (' ■ Do you want to go ahead and write over it ');
- IF yes
- THEN
- Close (outf)
- ELSE
- BEGIN
- ok := FALSE;
- Exit
- END
- END;
- Assign (outf, outfnam);
- {$I-}
- REWRITE (outf);
- {$I+};
- ok := (IOResult = 0);
- IF NOT ok
- THEN
- BEGIN
- alarm; alarm; alarm;
- WRITELN; WRITELN;
- makecursor (full);
- alarm;
- NormVideo;
- WRITE (' ... Unable to open file ',outfnam, ' ... PRESS ',CHR(17),'┘ ');
- READLN;
- makecursor (invisible);
- LowVideo
- END
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE getoutfnam;
- {-----------------------------------------------------------------------------}
- BEGIN {getoutfnam};
- REPEAT
- ClrScr;
- banner;
- outfnam := nullstr;
- WRITELN;
- NormVideo;
- WRITELN (' pFORMAT will generate a copy of ',infnam);
- LowVideo;
- get_attr (infnam);
- WRITELN;
- WRITELN (' Options :');
- WRITELN (' ■ You may enter a DOS file name to capture the copy on disk,');
- WRITELN (' ■ OR, you may quit by pressing a lone ',CHR(17),'┘');
- WRITE (' --- Please designate a destination for the pFORMAT copy : ');
- makecursor (full);
- READLN (outfnam);
- trim (outfnam);
- checkoutput;
- UNTIL ok;
- makecursor (normal)
- END; {getinfnam}
- {-----------------------------------------------------------------------------}
- PROCEDURE preamble;
- {-----------------------------------------------------------------------------}
- PROCEDURE oneparm;
- {-----------------------------------------------------------------------------}
- BEGIN
- ok := TRUE;
- infnam := upstrg(ParamStr(1));
- checkinput;
- IF NOT ok
- THEN
- getinfnam;
- getoutfnam;
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE twoparms;
- {-----------------------------------------------------------------------------}
- BEGIN
- ok := TRUE;
- infnam := upstrg(ParamStr(1));
- outfnam:= upstrg(ParamStr(2));
- checkinput;
- IF NOT ok
- THEN
- getinfnam;
- checkoutput;
- IF NOT ok
- THEN
- BEGIN
- getoutfnam;
- parmcnt := 0;
- END;
- END;
-
- BEGIN
- {___ initialize global variables ___}
- mixedcase := FALSE; commentactive := FALSE;
- case4reserved := upper; case4nonreserved := lower;
- reservedcount := 0; linecount := 0;
- charcount := 0; commentcount:= 0;
- LowVideo;
- ClrScr; banner;
- WRITE (
- ' To quit, press a lone ',CHR(17),
- '┘ in response to the prompts for file names.');
- WRITELN;
- IF parmcnt = 0
- THEN
- BEGIN {no Command Line Parms}
- getinfnam;
- getoutfnam;
- END
- ELSE
- IF parmcnt = 1
- THEN
- oneparm
- ELSE
- twoparms;
- checksettings;
- TextColor (Black);
- TextBackGround (White);
- legend := Concat ('Reading ',infnam,' & generating ',outfnam);
- ClrScr;
- banner;
- WRITELN;
- IF (Length (legend) <= 80)
- THEN {centre if it fits 80-char line}
- WRITE (legend:((80 + Length(legend)) DIV 2))
- ELSE
- WRITE (legend);
- WRITELN;
- NormVideo;
- FOR cnt := 1 TO 80
- DO
- WRITE ('═');
- LowVideo;
- makecursor (invisible);
- NormVideo;
- GoToXY (25, 5); WRITE (' Lines processed : ');
- GoToXY (25, 6); WRITE (' Characters encountered : ');
- GoToXY (25, 7); WRITE (' Reserved words processed : ');
- GoToXY (25, 8); WRITE (' Comments encountered : ');
- LowVideo
- END;
-
- {-----------------------------------------------------------------------------}
- PROCEDURE task;
- {-----------------------------------------------------------------------------}
- BEGIN
- preamble;
- WHILE NOT (EOF(inf))
- DO
- BEGIN
- iobuf := nullstr;
- READLN (inf, iobuf);
- IF Length(iobuf) <> 0
- THEN
- parse;
- linecount := linecount + 1;
- GoToXY (56, 5); WRITE (linecount:7:0);
- GoToXY (56, 6); WRITE (charcount:7:0);
- GoToXY (56, 7); WRITE (reservedcount:7:0);
- GoToXY (56, 8); WRITE (commentcount:7:0);
- WRITELN(outf, iobuf)
- END;
- alarm; alarm; alarm;
- makecursor (normal);
- alarm;
- Close (inf);
- Close (outf);
- END;
-
- {-- pFORMAT begins here --------------------------------------------------}
- BEGIN
- TextMode;
- initarray;
- infnam := nullstr;
- parmcnt := ParamCount;
- ok := TRUE;
- REPEAT
- task;
- WRITELN; WRITELN; WRITELN;
- parmcnt := 0;
- WRITE (' Quit pFORMAT?')
- UNTIL yes;
- userquits
- END. {---------------------------------------------------------------pFormat}