home *** CD-ROM | disk | FTP | other *** search
- PROGRAM UpConv;
- {$B-} {shortcut Boolean}
- {$D-} {no debug}
- {$L-} {no local symbols}
- {$S-} {no stack checking}
- {$V-} {no VAR-string checking}
-
- Uses Dos,Strings; {v1.3 for all the wildcard stuff
- v1.8 STRINGS.TPU for some string stuff}
-
- { DEFINE NO_OVERWRITE} {this enables .FMT file existence checking.
- I suggest you leave it .. that keeps the
- system from trying to reformat earlier
- .FMT files during a wildcard run where the user
- specified *.* or something equally dumb!
- }
-
- {
- Original based on a bulletin board program by Jeff Firestone
- This version based on a program by Douglas S. Stivison in his book:
- 'Turbo Pascal Library' published by Sybex.
-
- One peculiarity about the comment-handling: Anything within the usual
- '}{' comments is skipped over; anything within the "parenthesis asterisk"
- type comment IS processed! So .. put real comments within '}{' comments,
- and commented-out code within the '(* *)' type comments.
-
-
-
- v1.8, Toad Hall, 20 Nov 89
- - Adding ability to use user-selected reserved word .DAT data files
- (from the command line).
- Default data file will be CONV_P.DAT.
- - Totally rewrote TOK_STR to handle multiple reserved word text files
- to build a reserved word .DAT file.
- We don't have sorted reserved words any more (but that's ok).
- - Using STRINGS.TPU for some string-related functions.
- - Rebuilt Args into records of strings and filename type
- (to handle cmdline switches, data files, source files).
- - Using newer (slightly tweaked) POSBM2 POS() replacement.
-
- v1.7, Toad Hall, 25 Oct 89
- - Bug in TOK_STR.PAS (missing tokens when a concatenated token
- string reached max length). Fixed.
- - No changes in UPCONV itself, just in the TOKENS.DAT file
- TOK_STR.EXE produces. Replace your existing TOKENS.DAT with
- the new one and UPCONV16 will run just fine.
-
- v1.6, Toad Hall, 20 Oct 89
- - Moved the reserved word strings to an external file (UPCONV.DAT),
- created by the TOK_STR utility.
- - Now uses linked lists of string pointers to dynamic reserved
- word strings (rather than the previous "hard-coded" typed constant
- array of reserved word strings).
- - Add a couple more missing reserved words (ParamCnt, ParamStr),
- changed 'Assign' to "ASSIGN".
- - Executable is now smaller, loads faster, runs faster.
-
- v1.5, Toad Hall, 13 Oct 89
- - Adding some missing reserved words (LongInt, Word)
- - Added a modicum of file write error-trapping.
-
- v1.4, Toad Hall, 15 Jun 89
- - Added some missing reserved words (FillChar, FOR, FUNCTION).
- - Adding faster replacement for the POS() function (POSBM).
- - Made Args array dynamic (e.g., via pointers)
- - Buffering string reads, writes via two dynamic buffers to reduce
- disk thrashing, slightly speed up program (maybe 10%).
- (Not doing any memory testing yet, so I hope your system
- has sufficient memory.)
- - Writing a terminating ^Z to our output file
- (just to be neat, keep same file size, etc.).
-
- v1.3, Toad Hall, 14 Apr 89
- - Tweaking for Turbo Pascal v5.0
- - Adding a bunch of TP 4.0 and 5.0 Borland words.
- - Tightening up a little.
- - Added commandline multiple filename/wildcard capability.
- - Added '/L' switch for Pascal (non-Borland) reserved word
- lowercase conversion.
- - Building formatted output string (WorkLine). Saved only a little
- processing time, but did cut out about 60-70 bytes of code.
- time size
- $DEFINE: 1:16.35 12160 bytes
- No DEFINE: 1:15.79 12096 bytes
- - Tried a Move instruction to concatenate strings to WorkLine
- (vs. WorkLine := WorkLine + String); gained no time, only saved
- 16 bytes .. not worth the obtuseness.
- - Adding chars to WorkLine the hard way (see code) vs. normal way
- (WorkLine := WorkLine + char) saved code, time:
- 1:17.34 12208 bytes
-
- v1.2, Toad Hall, 12 Oct 88
- - Bug in Scan_Till procedure. Fixed.
- - Isn't leaving quoted strings alone. Fixed.
-
- v1.1 Toad Hall Tweak, Sep 88
- - Added command line filename input.
- - Moved Identifier char set to a global typed constant.
- - Changed simple Reserved Word uppercasing to include Turbo Pascal
- formatted reserved words.
- - Added more reserved words for Turbo Pascal. (Complete thru v3.0,
- I think .. don't have 4.0, so that should be added.)
- - Command line switch ('-U') to force all reserved words to uppercase
- (e.g., ignore Turbo Pascal format).
- - Considering how to change other text (non-quoted, non-comments)
- to all-upper, all-lower, As-Is, like PFORMAT.PAS does.
- - Still suspect a fancy hash procedure to confirm a RamWord as a
- reserved word would be better than this "if word is in line"
- business. Later.
-
- v1.0
- - Found in SIMTEL20's PD1:<MSDOS.TURBOPAS>UPCONV.ARC.
- Original author unknown.
-
- David Kirschbaum
- Toad Hall
- kirsch@arsocomvax.socom.mil
- }
-
-
- CONST
- Default_DataName : STRING[12] = 'CONV_P.DAT'; {default data file v1.8}
-
- TYPE
- StrPtr = ^Str_Rec; {v1.6}
- Str_Rec = RECORD
- S : STRING;
- next : Pointer;
- END;
- VAR
- ReservedWords : StrPtr; {v1.6 pointer to first dynamic
- reserved word string record}
- UCReserved : StrPtr; {v1.6 pointer to first dynamic
- uppercase reserved word string record}
- curr,curruc : StrPtr; {for current normal and uppercased
- str recs v1.8}
-
-
- CONST
- APOS = #39; {This is the ' symbol.}
- OPENCOMMENT = '{';
- CLOSECOMMENT = '}';
-
- {Note: These are the only valid characters that can be used in Turbo
- identifiers.}
- Identifier : SET OF CHAR = ['A'..'Z', '0'..'9', '_'];
-
- VAR
- charpsn,
- linenum : Word;
-
- GotData, {flag true if we have a /I file on cmdline v1.8}
- Lower, {If TRUE, all Pascal reserved words v1.3
- lowercased (but not the Borland ones!)}
- AllUpper : BOOLEAN; {if TRUE, ALL reserved words uppercased
- (Borland ones also)}
-
- UcWord, {possible keyword, uppercased}
- Padded : STRING[20]; {UcWord, padded with spaces}
-
- WorkLine, {v1.3 Build formatted output line}
- ProgLine : STRING; {v1.3 STRING[128]}
- worklen : Byte Absolute WorkLine; {v1.3}
-
- RamWord : STRING [100];
-
- InFile,
- OutFile : TEXT;
-
-
- { Multiple cmdline parm/wildcard stuff }
- CONST
- MAXARGS = 10; {change as you like}
-
- TYPE
- ArgType = (switch,data,source); {v1.8 types of files}
- ArgRec = RECORD
- Pth : PathStr; {filename}
- Typ : ArgType; {whether it's data, source,}
- END; { or a -L or -U switch}
-
- VAR
- Ok : BOOLEAN;
- argv, argc : Byte;
- Args : ARRAY[1..MAXARGS] {v1.4 array of cmdline parm ptrs}
- OF ArgRec; {v1.8}
-
- Dir : DirStr; {STRING[79]}
- Name: NameStr; {STRING[8]}
- Ext : ExtStr; {STRING[4]}
-
- OutName : PathStr; {STRING[79]}
-
- {SearchRec is declared in the Dos unit:}
- (*
- TYPE SearchRec = RECORD
- fill : ARRAY[1..21] OF Byte;
- Attr : Byte;
- Time : LongInt;
- size : LongInt;
- Name : STRING[12];
- END;
- *)
- SrchRec : SearchRec;
-
-
- CONST
- MAXBUFFLINES = 256; {v1.4 seems a likely number}
-
- {v1.4 Our new read/write string buffers}
-
- TYPE
- BuffPtr = ^STRING; {v1.4}
- Buffer = ARRAY[1..MAXBUFFLINES] OF BuffPtr;
-
- VAR
- InBuff,OutBuff : Buffer;
- inlines,
- currin, currout : Word;
-
-
- PROCEDURE Usage;
- {Give user help, terminate.
- Happens on cmd line of '?', '-?', '/?', '-h', '/h', or empty.
- }
- BEGIN
- WRITELN(
- 'CONV_P v1.8 - Convert Pascal reserved words to uppercase,');
- WRITELN(
- ' If Turbo Pascal reserved words, convert to Borland style');
- WRITELN(
- 'Usage: UPCONV [[-][/]U][L] [/Idatafile.typ] [/I...] file1[.typ]');
- WRITELN( 'Switches:');
- WRITELN(
- ' -u, -U, /u, or /U : uppercase ALL reserved words');
- WRITELN(
- ' (overriding the Borland Style)');
- WRITELN(
- ' -l, -L, /l, or /L : lowercase Pascal (non-Borland) reserved words');
- WRITELN( {v1.8}
- ' /I : Use this text file (with YOUR set of reserved words)');
- WRITELN(
- ' instead of the default CONV_P.DAT reserved word data file.');
- WRITELN(
- 'Source filename file1 will be forced to .PAS if no type is given.');
- WRITELN(
- 'Formatted output filename forced to .FMT type.');
- WRITELN('Wildcards may be used for file1.typ');
- HALT;
- END; {of Usage}
-
- {v1.4 Replacement for POS() function
- Dr Dobbs, Jul 89
- }
- {Link in the POSBM Boyer-Moore function }
-
- {$F+}
- {$L POSBM2} {v1.8}
-
- FUNCTION posBM(Pat,S : STRING) : Byte; EXTERNAL;
- {$F-}
-
-
- PROCEDURE Uc_Str(VAR S : STRING);
- {v1.3 Same as STRINGS' Uppercase, but changes the string "in place".}
- BEGIN
- InLine(
- $8C/$DB/ { mov bx,DS ;preserve DS}
- $C5/$B6/>S/ { lds si,>S[bp] ;get the VAR addr}
- $31/$C0/ { xor ax,ax}
- $8A/$04/ { mov al,[si] ;snarf the length}
- $89/$C1/ { mov cx,ax ;loop counter}
- $E3/$0E/ { jcxz Exit ;zero length, forget it}
- {;}
- $BA/$61/$20/ { mov dx,$2061 ;DL='a',DH=$20}
- {L1:}
- $46/ { inc si ;next char}
- $8A/$04/ { mov al,[si] ;snarf the char}
- $38/$D0/ { cmp al,dl}
- $72/$02/ { jb S1 ;already uppercase}
- $28/$34/ { sub [si],dh ;uppercase it}
- {S1:}
- $E2/$F5/ { loop L1}
- {Exit:}
- $8E/$DB); { mov DS,bx ;restore DS}
- END; {of Uc_Str}
-
-
- PROCEDURE Lo_Str (VAR S : STRING);
- {v1.3 Lowercase a string}
- BEGIN
- InLine(
- $1E/ { push DS}
- $C5/$B6/>S/ { lds si,>S[bp]}
- $31/$C0/ { xor ax,ax}
- $8A/$04/ { mov al,[si];snarf the length}
- $09/$C0/ { or ax,ax ;0 length?}
- $74/$16/ { je Exit ;yep, exit}
-
- $89/$C1/ { mov cx,ax}
- $BA/$41/$5A/ { mov dx,$5A41 ;DL='A',DH='Z'}
- $B4/$20/ { mov ah,$20 ;handy constant}
- {L1:}
- $46/ { inc si ;next char}
- $8A/$04/ { mov al,[si];snarf the char}
- $38/$D0/ { cmp al,dl ;<'A'?}
- $72/$06/ { jb S1 ;yep}
- $38/$F0/ { cmp al,dh ;>'Z'?}
- $77/$02/ { ja S1 ;yep}
- $00/$24/ { add [si],ah ;lowercase}
- {S1:}
- $E2/$F1/ { loop L1}
- {Exit:}
- $1F); { pop DS ;restore}
-
- END; {of Lo_Str}
-
-
- FUNCTION ReadLn_B(VAR S : STRING) : BOOLEAN;
- {v1.4 Returns a string from our input buffer.
- If buffer is exhausted, refills from InFile.
- Returns FALSE IF (1) buffer is exhausted, and
- (2) EOF(InFile)
- Else returns TRUE.
- }
- BEGIN
- ReadLn_B := TRUE; {assume success}
- Inc(currin); {bump to next line}
- IF currin <= inlines THEN BEGIN {we still have lines in buffer}
- S := InBuff[currin]^; {return the string}
- Exit; {done}
- END;
-
- {We've hit buffer end .. read in a new buffer full
- (or as much as is available).
- }
- currin := 1; {start at InBuff[1]}
- inlines := 0; {init input buffer string counter}
- WHILE NOT EOF(InFile) {stop at EOF}
- AND (inlines < MAXBUFFLINES) {or when input buffer is full}
- DO BEGIN
- Inc(inlines); {bump input buffer string counter}
- READLN(InFile,InBuff[inlines]^); {Read in a buffer string}
- {(Let Turbo handle any errors for now)}
- END;
- IF inlines > 0 {we did read at least one line}
- THEN S := InBuff[currin]^
- ELSE ReadLn_B := FALSE; {EOF, no lines read}
- END; {of ReadLn_B}
-
-
- PROCEDURE WriteLn_B(S : STRING);
- {v1.4 Buffered string output.
- Move S to our output buffer OutBuff.
- If OutBuff is full, write it to disk.
- }
- VAR err : INTEGER; {v1.5}
- BEGIN
- Inc(currout); {bump output line counter}
- IF currout > MAXBUFFLINES {output buffer's full}
- THEN BEGIN
- FOR currout := 1 TO MAXBUFFLINES DO BEGIN
- {$I-}
- WRITELN(OutFile,OutBuff[currout]^); {write to file}
- {(Let Turbo handle any errors for now)}
- err := IOResult; {v1.5}
- {$I+}
- IF err <> 0 THEN BEGIN
- WRITELN('File Write Error');
- HALT(err);
- END;
- END;
-
- currout := 1; {back to output buffer start}
- END;
- OutBuff[currout]^ := S; {move string into output buffer}
- END; {of Writeln_B}
-
-
- PROCEDURE Flush_OutBuff;
- {v1.4 If any output strings are left in our output buffer,
- write them to disk.
- (We really should test to see if we've written ANYTHING
- to our output file, and delete it if it's empty (or something).
- Not messing with that for now (since you can't do a FileSize
- on text files, and we'd have to reopen as some other type, etc.).
- }
- VAR
- i : Word;
- err : INTEGER;
- BEGIN
- IF currout > 0 {if there are any buffer lines}
- THEN FOR i := 1 TO currout DO BEGIN {write them all out}
- {$I-}
- WRITELN(OutFile,OutBuff[i]^);
- err := IOResult; {v1.5}
- {$I+}
- IF err <> 0 THEN BEGIN
- WRITELN('File Write Error');
- HALT(err);
- END;
-
- END;
- WRITE(OutFile,^Z); {v1.4 terminating ^Z}
-
- {$I-}
- CLOSE(InFile);
- CLOSE(OutFile); {close up}
- {$I+}
- IF IOResult <> 0 THEN ; {we don't care}
-
- END; {of Flush_OutBuff}
-
-
- PROCEDURE Get_Args;
- {v1.4 Process command line for all target filenames.
- Move them into an array of Args records.
- v1.8 We may have "/IDATAFILE.DAT" data files on the cmdline.
- Move them (if any) into that same Args record array,
- but flag the file type as "data" rather than "source".
- }
- CONST
- HelpArgs : STRING[13] = ' -? /? -H /H '; {v1.8}
- SwitchArgs : STRING[13] = ' -U /U -L /L '; {v1.8}
- VAR
- Ch : CHAR;
- TStr : STRING;
- p : Byte;
-
- BEGIN
- argc := ParamCount;
- IF (argc = 0) {no parms at all}
- OR (argc > MAXARGS) {or more than we can handle}
- THEN Usage; {display help, die}
-
-
- Lower := FALSE; {assume no switches}
- AllUpper := FALSE;
- GotData := FALSE; {and no /I data file}
-
- FOR argv := 1 TO argc DO BEGIN {process args}
-
- Args[argv].Pth := Uppercase(ParamStr(argv)); {snarf parm, uppercased}
- Args[argv].Typ := source; {assume source file v1.8}
-
- { The first arg could've been a '-U' or '/U', or a '-L' or '/L'.
- Check that out now. If so, we set the arg type to switch
- so we can skip that arg when it comes time to open files.
- }
-
- IF Args[argv].Pth[1] IN ['-','/'] {may be a switch}
- THEN BEGIN {so let's see what kind}
- TStr := ' ' + Args[argv].Pth + ' '; {pad with spaces}
-
- IF posBM(TStr, HelpArgs) <> 0 {help arg? v1.8}
- THEN Usage; {help, die}
-
- p := posBM(TStr,SwitchArgs); {see if any switches}
- IF p <> 0 THEN BEGIN {we have a /U or /L switch}
- Args[argv].Typ := switch; {flag as a switch}
- IF p < 7 THEN AllUpper := TRUE {-U or /U}
- ELSE Lower := TRUE; {-L or /L}
- END
- {Not a lower/upper switch, might be a '/I' switch}
- ELSE IF Args[argv].Pth[2] = 'I' {'/I switch}
- THEN BEGIN {it's an input data file}
- DELETE(Args[argv].Pth,1,2); {delete the '/I' chars}
- Args[argv].Typ := data; {flag as data file}
- GotData := TRUE; {flag we got one}
- END;
- END; {if first char is '-/'
- {Else this Arg is flagged as a source file}
- END; {argc loop}
-
- END; {of Get_Args}
-
-
- {$IFDEF NO_OVERWRITE} {v1.3 only if we want no overwriting}
-
- FUNCTION Exists(Name : PathStr) : BOOLEAN;
- {Returns TRUE if Name exists on current drive:\dir}
- VAR F : TEXT;
- BEGIN
- ASSIGN(F, Name);
- {$I-} RESET (F); {$I+}
- IF IOResult = 0 THEN BEGIN
- Exists := TRUE;
- CLOSE(F);
- END
- ELSE Exists := FALSE;
- END; {of Exists}
-
- {$ENDIF}
-
-
- FUNCTION Open_Files : BOOLEAN;
- {Works FindNext if appropriate, else uses a new Arg string.
- v1.4 Returns TRUE or FALSE per success/failure.
- }
- VAR FName : PathStr;
- BEGIN
- Open_Files := FALSE; {v1.4 assume failure}
-
- IF SrchRec.Name = '' THEN BEGIN {time for a new name}
-
- REPEAT
- Inc(argv); {bump for first/next name}
- IF argv > argc THEN Exit; {all done, return FALSE v1.8}
- UNTIL Args[argv].Typ = source; {until we get a new source file v1.8}
-
- FSplit(Args[argv].Pth, Dir, Name, Ext); {split up the new name v1.4}
- IF Ext = '' THEN Ext := '.PAS'; {force to .PAS type}
- FName := Dir + Name + Ext; {build new name}
- FindFirst(FName,ReadOnly OR Archive,SrchRec) {first time thru}
- END
- ELSE FindNext(SrchRec); {working a wildcard}
-
- Ok := (DosError = 0); {from FindFirst or FindNext}
- IF NOT Ok THEN BEGIN {not found}
- SrchRec.Name := ''; {Flag we need a new arg
- and FindFirst}
- Exit; {v1.4 return FALSE}
- END;
-
- FName := Dir + SrchRec.Name; {new name from FindFirst/FindNext}
- Args[argv].Pth := FName; {Update Args for outside display v1.8}
-
- {v1.3 We'll always force the '.FMT' file type for output.}
-
- FSplit(FName, Dir, Name, Ext);
-
- OutName := Name + '.FMT'; {build a new output path
- (current drive:\directory) }
-
- {$IFDEF NO_OVERWRITE}
-
- IF Exists(OutName) THEN BEGIN {If .FMT file already exists...}
- WRITELN(Outname + ' already exists .. skipping!');
- Exit; {v1.4 return FALSE}
- END;
- {$ENDIF}
-
- ASSIGN(InFile, FName);
- RESET(InFile); {open input file}
-
- ASSIGN(OutFile, OutName);
- {$I-} REWRITE (OutFile); {$I+}
- Ok := (IOResult = 0);
- IF NOT Ok THEN BEGIN
- CLOSE(InFile); {be neat}
- WRITELN('Unable to open file [' + OutName + ']');
- END {v1.4 return FALSE}
- ELSE BEGIN
- currin := 0; {init input string buffer ptr}
- currout := 0; {init output string buffer ptr}
- inlines := 0; {insure initial input buffer fill}
-
- Open_Files := TRUE; {v1.4 return TRUE}
- END;
- END; {of Open_Files}
-
-
- PROCEDURE Build_Reserved_Arrays;
- {v1.6 Read in our file of reserved word strings.
- Create two linked lists of string records:
- one normal (Borland and Pascal reserved words with mixed case),
- one all uppercased).
- We just do this once.
- }
-
- PROCEDURE Read_DataFile(DataName : PathStr);
- VAR
- p : StrPtr; {working string record pointer}
- TokenFile : TEXT; {file of reserved word strings}
- BEGIN
- ASSIGN(TokenFile,DataName); {file of reserved word strings v1.8}
- {$I-} RESET(TokenFile); {$I+} {open it}
- IF IOResult <> 0 THEN BEGIN {not found .. die}
- WRITELN(DataName + ' file not found. Aborting!'); {v1.8}
- HALT(1); {die}
- END;
-
- WHILE NOT EOF(TokenFile) DO BEGIN {read in all the strings}
- READLN(TokenFile,curr^.S); {read in string}
- NEW(p); {allocate new normal record}
- curr^.next := p; {point THIS record to next one}
- curruc^.S := Uppercase(curr^.S); {create uppercased reserve word}
- curr := p; {bump to next normal record}
-
- NEW(p); {allocate new uppercased record}
- curruc^.next := p; {assume no next uppercase rec}
- curruc := p; {bump to next uppercase rec}
- END;
- curr^.S := ''; {last string is empty}
- curr^.next := NIL; {..and points nowhere}
- curruc^ := curr^; {also empty}
-
- {$I-} CLOSE(TokenFile); {$I+} {close up}
- IF IOResult <> 0 THEN ; {we don't care}
- END; {of Read_DataFile}
-
- BEGIN {Build_Reserved_Arrays}
-
- NEW(ReservedWords); {allocate first reserved string
- record}
- ReservedWords^.S := ''; {build first string ptr}
- ReservedWords^.next := NIL; {no next}
-
- NEW(UcReserved); {create first dynamic uppercased
- string ptr}
- UcReserved^ := ReservedWords^; {initialize it also}
-
- curr := ReservedWords; {point to first string ptr}
- curruc := UcReserved; {and first uppercased str ptr}
-
- IF NOT GotData {no arg was a data filename v1.8}
- THEN Read_DataFile(Default_DataName) {so use default v1.8}
- ELSE BEGIN
- FOR argv := 1 TO argc DO {check all the arg filenames v1.8}
- IF Args[argv].Typ = data {ok, it's a data type v1.8}
- THEN Read_DataFile(Args[argv].Pth); {so read THAT data file in v1.8}
- END; {using arg datafile name}
- END; {of Build_Reserved_Arrays}
-
-
- PROCEDURE Test_For_Reserved_Words;
- {Test if the current word (RamWord) is a reserved word.
- If so, write its equivalent (uppercased or Turbo Pascal format)
- out to our output file.
- Else just write it as it is.
- }
- VAR
- p,len : Word;
- BEGIN
- Padded := ' ' + Uppercase(RamWord) + ' '; {Uppercase, bracket with spaces}
- len := LENGTH(RamWord); {v1.3}
-
- curruc := UcReserved; {ptr to first dynamic uppercased
- reserved word string record}
- IF NOT AllUpper {not just uppercase}
- THEN curr := ReservedWords {use Borland/normal case array also}
- ELSE curr := UcReserved;
-
- WHILE curruc^.next <> NIL DO BEGIN {check all the reserved words}
- p := posBM(Padded, curruc^.S); {v1.6 is this uppercased, padded
- word in the reserved word line?}
- IF p > 0 THEN BEGIN {yep}
- Inc(p); {bump past the space}
- IF AllUpper {converting to uppercase..}
- THEN Padded := COPY(curruc^.S, {..so move in the uppercased word}
- p, len)
- ELSE BEGIN {more processing}
- Padded := COPY(curr^.S, {word per our Reserved table}
- p, len); {uppercase or Borlandized}
- IF Lower
- THEN IF Padded = Uppercase(Padded) {If the mixed-case Table word
- matches the uppercased word..
- it's non-Borland...}
- THEN Lo_Str(Padded); {..so lowercase it}
- END;
- WorkLine := WorkLine + Padded; {v1.3 build in WorkLine}
- Exit; {don't look at any more lines}
- END; {if Padded in line}
- curruc := curruc^.next; {point to next uppercased reserved
- word string record}
- curr := curr^.next; {point to next normal string}
- END; {line-checking loop}
-
- {We checked all the lines, didn't find our RamWord as a Reserved word}
-
- WorkLine := WorkLine + RamWord; {v1.3 build WorkLine with orig word}
-
- END; {of Test_For_Reserved_Words}
-
-
- PROCEDURE Process_A_Word;
- VAR
- len : Byte; {v1.3}
- strt : Word; {v1.3}
- BEGIN
- strt := charpsn; {v1.3 remember where we started}
- WHILE (UpCase (ProgLine [charpsn]) IN Identifier) {it's a legal char}
- AND (charpsn <= LENGTH (ProgLine) ) {and line isn't done}
- DO Inc(charpsn); {v1.3 bump ProgLine ptr}
-
- len := (charpsn - strt); {v1.3 nr chars in word}
- RamWord[0] := CHAR(len); {v1.3 force string length}
- Move(ProgLine[strt], RamWord[1], len); {v1.3 copy portion of ProgLine}
-
- Test_For_Reserved_Words; {check RamWord for reserved
- words, write out}
- END; {of Process_A_Word}
-
-
- PROCEDURE Scan_Till (SearchChar: CHAR);
- VAR
- Ch : CHAR; {v1.2}
- BEGIN
- REPEAT
- IF charpsn > LENGTH (ProgLine) THEN BEGIN
-
- WriteLn_B(WorkLIne); {v1.4 Write the Workline we have
- (Buffered string output)
- (Ok if it's empty) }
-
- IF NOT ReadLn_B(ProgLine) {v1.4 If we have another input line
- (buffered string input) }
- THEN Exit; {FALSE means EOF}
-
- charpsn := 1;
- WorkLine := ''; {v1.3 Reinit WorkLine}
- END;
-
- IF ProgLine <> '' THEN BEGIN {do non-blank lines}
- Ch := ProgLine[charpsn]; {v1.2 remember what this char was}
-
- Inc(worklen); {v1.3 bump workline length}
- WorkLine[worklen] := Ch; {v1.3 stuff char in line}
- (* same as
- WorkLine := WorkLine + Ch;
- but faster, tighter
- *)
- Inc(charpsn); {v1.3 bump char ptr}
- END
- ELSE Ch := #0; {v1.2 blank line, clear Ch}
- UNTIL (Ch = SearchChar); {v1.2 the LAST char was end of
- quoted string or comment}
- {v1.4 If we hit EOF, we exit above}
- END; {of Scan_Till}
-
-
- PROCEDURE Convert;
- VAR Ch : CHAR;
- BEGIN
- WRITE('Converting ', Args[argv].Pth, ' => ', OutName, {v1.4}
- ', Processing line: ');
-
- linenum := 0;
-
- WHILE ReadLn_B(ProgLine) DO BEGIN {v1.4 buffered string input
- FALSE means EOF}
- charpsn := 1;
- WorkLine := ''; {v1.3 clear WorkLine string}
-
- IF LENGTH(ProgLine) <> 0 THEN BEGIN {v1.3 nonblank line}
- REPEAT
- Ch := UpCase(ProgLine[charpsn]);
- IF Ch IN Identifier {could be a reserved word}
- THEN Process_A_Word {so process it}
- ELSE BEGIN
-
- Inc(worklen); {v1.3 bump WorkLine length}
- WorkLine[worklen] := Ch; {v1.3 stuff char in WorkLine}
- (* Same as
- WorkLine := WorkLine + Ch;
- but tighter, faster
- *)
- Inc(charpsn); {v1.3 bump ptr}
- IF Ch = OPENCOMMENT
- THEN Scan_Till(CLOSECOMMENT) {v1.2 write until
- closing comment}
- ELSE IF Ch = APOS
- THEN Scan_Till(APOS); {v1.2 write until 2d '}
- END;
- UNTIL (charpsn > LENGTH (ProgLine));
- END; {If nonblank}
-
- Writeln_B(WorkLine); {v1.4 Output Workline
- (buffered string output)
- (Ok if blank) }
-
- WRITE(linenum:6,^H^H^H^H^H^H); {display, back up}
-
- Inc(linenum); {v1.3 bump linenr}
- END; {While}
-
- WRITELN; {v1.3 clean up screen}
-
- Flush_OutBuff; {v1.4 flush output buffer,
- close up everything}
- END; {of Convert}
-
-
- BEGIN {main}
-
- Get_Args; {process cmdline args
- (may die)}
-
- Build_Reserved_Arrays; {v1.6 build two linked lists
- of reserved word records
- (one normal, one uppercased) }
-
- {v1.4 So far, so good. Initialize our dynamic input and output
- buffer array pointers.
- Later, check for avail memory, constrain buffers, etc.
- }
-
- FOR currin := 1 TO MAXBUFFLINES DO
- NEW(InBuff[currin]);
- FOR currout := 1 TO MAXBUFFLINES DO
- NEW(OutBuff[currout]);
-
- {Now we go into our file loop.
- We continue until FindNext returns no more files.
- Get_Args set argv appropriately.
- }
-
- SrchRec.Name := ''; {clear for first file}
- argv := 0; {start with first arg}
-
- WHILE (SrchRec.Name <> '') {we're working a wildcard}
- OR (argv < argc) {no wildcard, but still got args}
- DO BEGIN
-
- IF Open_Files {v1.4 open InFile,OutFile}
- THEN Convert; {v1.4 files open, do the conversion}
-
- END; {until all done}
-
- END.