home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TPFORMAT.ZIP / PFORMAT.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1993-01-04  |  26.9 KB  |  993 lines

  1. PROGRAM pFormat (INPUT, OUTPUT);
  2. {
  3.   AUTHOR:  andy j s decepida
  4.            16 Nov 1984
  5.  
  6.   DESCRIPTION: Reads in a .PAS text file and, depending on the user's
  7.                choice/s, generates a copy with alterations in the case of
  8.                the contained text.
  9. }
  10.  
  11. CONST
  12.   Array_Size  =  177;
  13.  
  14. TYPE
  15.   Answer_Set  =  SET OF CHAR;
  16.  
  17.   Cursor_Size =  (Full, Half, Minimum, Invisible);
  18.  
  19.   Global_Strg =  STRING[255];
  20.  
  21.   Case_Types  =  (Upper,
  22.                  Lower,
  23.                  AsIs);
  24.  
  25. VAR
  26.   IO_Template,
  27.   Work_Template,
  28.   Proc_Label,
  29.   Mask,
  30.   Temp,
  31.   Temp_String,
  32.   In_File_Name,
  33.   Out_File_Name : Global_Strg;
  34.  
  35.   Text_File,
  36.   Pretty_Output : TEXT;
  37.  
  38.   Token         : ARRAY [1..Array_Size] OF STRING[20];
  39.  
  40.   Res_Case,
  41.   Non_Res_Case  : Case_Types;
  42.  
  43.   Strt,
  44.   Endd,
  45.   Indx,
  46.   Token_Locn,
  47.   Len,
  48.   Cnt           : INTEGER;
  49.  
  50.   CD_Char,
  51.   Prior,
  52.   Next          : CHAR;
  53.  
  54.   Borland_Convention,
  55.   Interruptable,
  56.   Comment_Active,
  57.   Ok            : BOOLEAN;
  58.  
  59. {*****************************************************************************}
  60.  
  61.   PROCEDURE Init_Array;
  62.   {
  63.     initialize the reserved word array
  64.  
  65.   Warning: because the primitive parsing method employed here centred
  66.   crucially on this array it is NOT recommended that you alter the
  67.   contents and sequence of the entries.  My apologies non MS-DOS users
  68.   for not including the reserved words that their TurboPascal editions do
  69.   support.  Should you, as say as CP/M Turbo programmer, wish to alter
  70.   this table keep in mind two things:
  71.  
  72.  
  73.   ■ Do_Turbo_Extension uses the index (INDX) corresponding to the table
  74.     entry of a found reserved word to assign the Borland type setting style
  75.     to the output substring ... ergo, keep the new array indices in synch
  76.     with the CASE selectors in Do_Turbo_Extension.
  77.  
  78.   ■ Since pFORMAT sequentially steps through this array to find a corresponding
  79.     pattern occurrences in the text line currently being processed, it
  80.     becomes important to keep the shorter reserved words that are embedded in
  81.     other, longer reserved words as substrings towards the bottom of the
  82.     array!
  83. }
  84.   BEGIN {Init_Array}
  85.     Token [  1] := 'ABSOLUTE';
  86.     Token [  2] := 'ARCTAN';
  87.     Token [  3] := 'ASSIGN';
  88.     Token [  4] := 'AUXINPTR';
  89.     Token [  5] := 'AUXOUTPTR';
  90.     Token [  6] := 'BLOCKREAD';
  91.     Token [  7] := 'BLOCKWRITE';
  92.     Token [  8] := 'BOOLEAN';
  93.     Token [  9] := 'BUFLEN';
  94.     Token [ 10] := 'CLREOL';
  95.     Token [ 11] := 'CLRSCR';
  96.     Token [ 12] := 'CONCAT';
  97.     Token [ 13] := 'CONINPTR';
  98.     Token [ 14] := 'CONOUTPTR';
  99.     Token [ 15] := 'CONSTPTR';
  100.     Token [ 16] := 'CRTEXIT';
  101.     Token [ 17] := 'CRTINIT';
  102.     Token [ 18] := 'DELETE';
  103.     Token [ 19] := 'DELLINE';
  104.     Token [ 20] := 'DOWNTO';
  105.     Token [ 21] := 'EXECUTE';
  106.     Token [ 22] := 'EXTERNAL';
  107.     Token [ 23] := 'FILEPOS';
  108.     Token [ 24] := 'FILESIZE';
  109.     Token [ 25] := 'FILLCHAR';
  110.     Token [ 26] := 'FORWARD';
  111.     Token [ 27] := 'FREEMEM';
  112.     Token [ 28] := 'FUNCTION';
  113.     Token [ 29] := 'GETMEM';
  114.     Token [ 30] := 'GOTOXY';
  115.     Token [ 31] := 'GRAPHBACKGROUND';
  116.     Token [ 32] := 'GRAPHCOLORMODE';
  117.     Token [ 33] := 'GRAPHMODE';
  118.     Token [ 34] := 'GRAPHWINDOW';
  119.     Token [ 35] := 'HEAPSTR';
  120.     Token [ 36] := 'HIRESCOLOR';
  121.     Token [ 37] := 'INLINE';
  122.     Token [ 38] := 'INSERT';
  123.     Token [ 39] := 'INSLINE';
  124.     Token [ 40] := 'INTEGER';
  125.     Token [ 41] := 'IORESULT';
  126.     Token [ 42] := 'KEYPRESSED';
  127.     Token [ 43] := 'LENGTH';
  128.     Token [ 44] := 'LONGFILEPOS';
  129.     Token [ 45] := 'LONGFILESIZE';
  130.     Token [ 46] := 'LONGSEEK';
  131.     Token [ 47] := 'LOWVIDEO';
  132.     Token [ 48] := 'LSTOUTPTR';
  133.     Token [ 49] := 'MAXAVAIL';
  134.     Token [ 50] := 'MAXINT';
  135.     Token [ 51] := 'MEMAVAIL';
  136.     Token [ 52] := 'NORMVIDEO';
  137.     Token [ 53] := 'NOSOUND';
  138.     Token [ 54] := 'OUTPUT';
  139.     Token [ 55] := 'PACKED';
  140.     Token [ 56] := 'PALETTE';
  141.     Token [ 57] := 'PROCEDURE';
  142.     Token [ 58] := 'PROGRAM';
  143.     Token [ 59] := 'RANDOMIZE';
  144.     Token [ 60] := 'RANDOM';
  145.     Token [ 61] := 'READLN';
  146.     Token [ 62] := 'RECORD';
  147.     Token [ 63] := 'RELEASE';
  148.     Token [ 64] := 'RENAME';
  149.     Token [ 65] := 'REPEAT';
  150.     Token [ 66] := 'REWRITE';
  151.     Token [ 67] := 'SIZEOF';
  152.     Token [ 68] := 'STRING';
  153.     Token [ 69] := 'TEXTBACKGROUND';
  154.     Token [ 70] := 'TEXTCOLOR';
  155.     Token [ 71] := 'TEXTMODE';
  156.     Token [ 72] := 'UPCASE';
  157.     Token [ 73] := 'USRINPTR';
  158.     Token [ 74] := 'USROUTPTR';
  159.     Token [ 75] := 'WHEREX';
  160.     Token [ 76] := 'WHEREY';
  161.     Token [ 77] := 'WINDOW';
  162.     Token [ 78] := 'WRITELN';
  163.     Token [ 79] := 'ARRAY';
  164.     Token [ 80] := 'BEGIN';
  165.     Token [ 81] := 'CHAIN';
  166.     Token [ 82] := 'CLOSE';
  167.     Token [ 83] := 'CONST';
  168.     Token [ 84] := 'DELAY';
  169.     Token [ 85] := 'ERASE';
  170.     Token [ 86] := 'FALSE';
  171.     Token [ 87] := 'FLUSH';
  172.     Token [ 88] := 'HIRES';
  173.     Token [ 89] := 'INPUT';
  174.     Token [ 90] := 'LABEL';
  175.     Token [ 91] := 'MSDOS';
  176.     Token [ 92] := 'PORTW';
  177.     Token [ 93] := 'RESET';
  178.     Token [ 94] := 'ROUND';
  179.     Token [ 95] := 'SOUND';
  180.     Token [ 96] := 'TRUNC';
  181.     Token [ 97] := 'UNTIL';
  182.     Token [ 98] := 'WHILE';
  183.     Token [ 99] := 'WRITE';
  184.     Token [100] := 'ADDR';
  185.     Token [101] := 'BYTE';
  186.     Token [102] := 'CASE';
  187.     Token [103] := 'CHAR';
  188.     Token [104] := 'COPY';
  189.     Token [105] := 'CSEG';
  190.     Token [106] := 'DRAW';
  191.     Token [107] := 'DSEG';
  192.     Token [108] := 'ELSE';
  193.     Token [109] := 'EOLN';
  194.     Token [110] := 'FILE';
  195.     Token [111] := 'FRAC';
  196.     Token [112] := 'GOTO';
  197.     Token [113] := 'HALT';
  198.     Token [114] := 'INTR';
  199.     Token [115] := 'MARK';
  200.     Token [116] := 'MEMW';
  201.     Token [117] := 'MOVE';
  202.     Token [118] := 'PLOT';
  203.     Token [119] := 'PORT';
  204.     Token [120] := 'PRED';
  205.     Token [121] := 'READ';
  206.     Token [122] := 'REAL';
  207.     Token [123] := 'SEEK';
  208.     Token [124] := 'SQRT';
  209.     Token [125] := 'SSEG';
  210.     Token [126] := 'SUCC';
  211.     Token [127] := 'SWAP';
  212.     Token [128] := 'TEXT';
  213.     Token [129] := 'THEN';
  214.     Token [130] := 'TRUE';
  215.     Token [131] := 'TYPE';
  216.     Token [132] := 'WITH';
  217.     Token [133] := 'AND';
  218.     Token [134] := 'AUX';
  219.     Token [135] := 'CHR';
  220.     Token [136] := 'CON';
  221.     Token [137] := 'COS';
  222.     Token [138] := 'DIV';
  223.     Token [139] := 'END';
  224.     Token [140] := 'EOF';
  225.     Token [141] := 'EXP';
  226.     Token [142] := 'FOR';
  227.     Token [143] := 'INT';
  228.     Token [144] := 'KBD';
  229.     Token [145] := 'LST';
  230.     Token [146] := 'MEM';
  231.     Token [147] := 'MOD';
  232.     Token [148] := 'NEW';
  233.     Token [149] := 'NIL';
  234.     Token [150] := 'NOT';
  235.     Token [151] := 'ODD';
  236.     Token [152] := 'OFS';
  237.     Token [153] := 'ORD';
  238.     Token [154] := 'POS';
  239.     Token [155] := 'PTR';
  240.     Token [156] := 'SEG';
  241.     Token [157] := 'SET';
  242.     Token [158] := 'SHL';
  243.     Token [159] := 'SHR';
  244.     Token [160] := 'SIN';
  245.     Token [161] := 'SQR';
  246.     Token [162] := 'STR';
  247.     Token [163] := 'TRM';
  248.     Token [164] := 'USR';
  249.     Token [165] := 'VAL';
  250.     Token [166] := 'VAR';
  251.     Token [167] := 'XOR';
  252.     Token [168] := 'DO';
  253.     Token [169] := 'HI';
  254.     Token [170] := 'IF';
  255.     Token [171] := 'IN';
  256.     Token [172] := 'LN';
  257.     Token [173] := 'LO';
  258.     Token [174] := 'OF';
  259.     Token [175] := 'OR';
  260.     Token [176] := 'PI';
  261.     Token [177] := 'TO';
  262.   END;  {Init_Array}
  263.  
  264. {*****************************************************************************}
  265.  
  266. {  I added this procedure in order to have the cursor restore itself properly
  267.    on my AT clone.  If you don't need this "extra" cursor procedure, feel free
  268.    to delete it.   Phil Johnston  --- Springfield, Missouri
  269. }
  270.  
  271. procedure cursor_on(status : boolean);
  272. type
  273.   registers = record
  274.       ax, bx, cx, dx, bp, si, di, ds, es, flags : integer; { word if TP 4.0 }
  275.   end;
  276.  
  277. var
  278.   reg : registers;
  279.  
  280. begin
  281.   if status then
  282.      if mem[0:$449] = 7 then
  283.         reg.cx := $0c0d
  284.      else reg.cx := $0607                                   { $0c0d for EGA }
  285.   else reg.cx := $2000;
  286.   reg.ax := $0100;
  287.   intr($10,reg);                  { intr($10,Dos.Registers(reg)); if TP 4.0 }
  288. end;
  289.  
  290. {*****************************************************************************}
  291.   PROCEDURE Set_Cursor (Size : Cursor_Size);
  292.   {
  293.     cursor is set according to the passed Size ... IBM-PC specific!
  294.   }
  295.  
  296.   TYPE
  297.     Reg_Pack    =  RECORD
  298.                     AX, BX, CX, DX, BP, SI, DI, ES, Flags : INTEGER;
  299.     END; {of Reg_Pack}
  300.  
  301.   VAR
  302.     Rec_Pack    :  Reg_Pack;
  303.  
  304.   BEGIN
  305.     Rec_Pack.AX := $0100;     {set cursor type service code ... cf A-47 of
  306.                               Hardware Technical Reference Manual}
  307.     CASE Size OF
  308.       Full     : Rec_Pack.CX := $000D;
  309.       Half     : Rec_Pack.CX := $070C;
  310.       Minimum  : Rec_Pack.CX := $0B0C;
  311.       Invisible: Rec_Pack.CX := $2000;
  312.     END; {CASE Size OF}
  313.  
  314.     Intr ($10, Rec_Pack)      {call video I/O ROM call}
  315.   END;
  316.  
  317. {*****************************************************************************}
  318.  
  319.   FUNCTION Is_Special_Char (Ch : CHAR) : BOOLEAN;
  320.   {
  321.     TRUE if Ch is a special char
  322.   }
  323.  
  324.   BEGIN
  325.     Is_Special_Char := (ORD(Ch) IN [32, 39..47, 58..62, 91, 93, 123, 125])
  326.   END;
  327.  
  328. {*****************************************************************************}
  329.  
  330.   FUNCTION Lo_Case (Ch : CHAR) : CHAR;
  331.   {
  332.     returns lower case of an alpha char
  333.   }
  334.  
  335.   BEGIN
  336.     IF (Ch IN ['A'..'Z']) THEN
  337.       Ch := CHR (ORD(Ch) - ORD('A') + ORD('a'));
  338.     Lo_Case := Ch
  339.   END;
  340.  
  341. {*****************************************************************************}
  342.  
  343.   PROCEDURE Up_Strg (VAR Strg : Global_Strg);
  344.  
  345.   VAR
  346.     Slot : INTEGER;
  347.  
  348.   BEGIN
  349.     IF (LENGTH(Strg) > 0) THEN
  350.       FOR Slot := 1 TO LENGTH(Strg) DO
  351.         Strg[Slot] := UpCase(Strg[Slot])
  352.   END;
  353.  
  354. {*****************************************************************************}
  355.  
  356.   PROCEDURE Lo_Strg (VAR Strg : Global_Strg);
  357.  
  358.   VAR
  359.     Slot : INTEGER;
  360.  
  361.   BEGIN
  362.     IF (LENGTH(Strg) > 0) THEN
  363.       FOR Slot := 1 TO LENGTH(Strg) DO
  364.         Strg[Slot] := Lo_Case(Strg[Slot])
  365.   END;
  366.  
  367. {*****************************************************************************}
  368.  
  369.   FUNCTION Get_Char (Legal_Commands : Answer_Set) : CHAR;
  370.   {
  371.     waits for a CHAR input belonging in Legal_Commands
  372.   }
  373.  
  374.   CONST
  375.     Bks = 8;
  376.  
  377.   VAR
  378.     Ch_In : CHAR;
  379.  
  380.   BEGIN
  381.     WRITE ('[ ]');
  382.     WRITE (CHR(Bks), CHR(Bks), ' ',CHR(Bks));
  383.     REPEAT
  384.       Set_Cursor (Full);
  385.       READ (KBD, Ch_In);
  386.       Ch_In := UpCase (Ch_In);
  387.       IF NOT (Ch_In IN Legal_Commands) THEN
  388.         BEGIN
  389.           Sound (8900);
  390.           Delay (10);
  391.           NoSound;
  392.           Sound (90);
  393.           Delay (30);
  394.           NoSound;
  395.         END;
  396.     UNTIL (Ch_In IN Legal_Commands);
  397.     Set_Cursor (Minimum);
  398.     Get_Char := Ch_In;
  399.   END;
  400.  
  401. {*****************************************************************************}
  402.  
  403.   FUNCTION User_Says_YES : BOOLEAN;
  404.   {
  405.     waits for a y/Y or n/N CHAR input
  406.   }
  407.  
  408.   VAR
  409.     Reply : CHAR;
  410.  
  411.   BEGIN
  412.     WRITE (' [y/n] ■ ');
  413.     User_Says_YES := (Get_Char(['Y','N']) = 'Y')
  414.   END;
  415.  
  416. {*****************************************************************************}
  417.  
  418.   PROCEDURE Trim_Off (VAR TempStr : Global_Strg);
  419.  
  420.   BEGIN
  421.     WHILE POS(' ', TempStr) = 1 DO
  422.       DELETE (TempStr, 1, 1);
  423.   END;
  424.  
  425. {*****************************************************************************}
  426.  
  427.   PROCEDURE User_Quits;
  428.  
  429.   BEGIN
  430.     Set_Cursor (Half);
  431.     Cursor_On(true);
  432.     CrtExit;
  433.     ClrScr;
  434.     HALT;
  435.   END;
  436.  
  437. {*****************************************************************************}
  438.  
  439.   PROCEDURE Evaluate_User_Choice (ConfirmationTail : Global_Strg;
  440.                                           Reserved : BOOLEAN);
  441.   BEGIN {Evaluate_User_Choice}
  442.     WRITELN;
  443.     WRITE (' You chose ');
  444.     TextColor (8); TextBackGround (7);
  445.     CASE CD_Char OF
  446.       'U' : BEGIN
  447.               WRITE ('Upper-case');
  448.               IF Reserved THEN
  449.                 Res_Case := Upper
  450.               ELSE
  451.                 Non_Res_Case := Upper
  452.             END;
  453.       'L' : BEGIN
  454.               WRITE ('Lower-case');
  455.               IF Reserved THEN
  456.                 Res_Case := Lower
  457.               ELSE
  458.                 Non_Res_Case := Lower
  459.              END;
  460.       'A' : BEGIN
  461.               WRITE ('As-Is');
  462.               IF Reserved THEN
  463.                 Res_Case := AsIs
  464.               ELSE
  465.                 Non_Res_Case := AsIs
  466.             END;
  467.       'B' : BEGIN
  468.               WRITE ('Borland type setting');
  469.               Borland_Convention := TRUE;
  470.             END;
  471.       'Q' : User_Quits;
  472.     END;
  473.     LowVideo;
  474.     WRITELN (' ',ConfirmationTail);
  475.     WRITE   (' Is this correct? ');
  476.   END; {Evaluate_User_Choice}
  477.  
  478. {*****************************************************************************}
  479.  
  480.    PROCEDURE Change_Defaults;
  481.  
  482.     BEGIN {Change_Defaults}
  483.       WRITELN;
  484.       REPEAT
  485.         WRITELN;
  486.         WRITELN;
  487.         WRITELN (' ■ PASCAL reserved words.');
  488.         WRITE   ('   Options are : U(pper-case, L(ower-case, A(s-Is, Q(uit');
  489.         CD_Char := Get_Char (['U','L','A','Q']);
  490.         Evaluate_User_Choice ('for the RESERVED words.', TRUE);
  491.       UNTIL User_Says_YES;
  492.  
  493.       WRITELN;
  494.       REPEAT
  495.         WRITELN;
  496.         WRITELN;
  497.         WRITELN (' ■ Turbo Pascal Extensions.');
  498.         WRITE   ('   Options are : U(pper, L(ower, As-Is, B(o',
  499.                  'rland type setting, Q(uit');
  500.         CD_Char := Get_Char (['U','L','A','B','Q']);
  501.         Evaluate_User_Choice ('for the Turbo Pascal Extensions.', TRUE);
  502.       UNTIL User_Says_Yes;
  503.  
  504.       WRITELN;
  505.       REPEAT
  506.         WRITELN;
  507.         WRITELN;
  508.         WRITELN (' ■ Non-Reserved Words.');
  509.         WRITE   ('   Options are : U(pper-case, L(ower-case, A(s-is, Q(uit');
  510.         CD_Char := Get_Char (['U','L','A','Q']);
  511.         Evaluate_User_Choice (' for the user defined identifiers.',
  512.                            FALSE);
  513.       UNTIL User_Says_YES;
  514.     END; {Change_Defaults}
  515.  
  516. {*****************************************************************************}
  517.  
  518.   FUNCTION Is_A_Token : BOOLEAN;
  519.   {
  520.     returns TRUE if the pattern found is properly delimited
  521.   }
  522.   BEGIN {Is_A_Token}
  523.     IF (Token_Locn + LENGTH(Token[Indx])) < Len THEN
  524.       Next := COPY (Work_Template,
  525.                   (Token_Locn + (LENGTH(Token[Indx]))), 1)
  526.     ELSE
  527.       Next := '.';
  528.  
  529.     IF Token_Locn > 1 THEN
  530.       BEGIN
  531.         Prior := COPY (Work_Template, Token_Locn - 1, 1);
  532.         Is_A_Token := ((Is_Special_Char(Prior)) AND (Is_Special_Char(Next)));
  533.       END
  534.     ELSE
  535.       IF Token_Locn = 1 THEN
  536.         Is_A_Token := (Is_Special_Char (Next));
  537.   END; {Is_A_Token}
  538.  
  539. {*****************************************************************************}
  540.  
  541.   PROCEDURE Mask_Out (KeyWord : Global_Strg);
  542.   {
  543.     mask out a pattern match ... to enable multi-occurrences
  544.   }
  545.   VAR
  546.     Slot : INTEGER;
  547.  
  548.   BEGIN {Mask_Out}
  549.     DELETE (Work_Template, Token_Locn, LENGTH(Token[Indx]));
  550.     Mask := KeyWord;
  551.     FOR Slot := 1 TO LENGTH(KeyWord) DO
  552.       Mask[Slot] := '\';
  553.     INSERT (Mask, Work_Template, Token_Locn)
  554.   END;  {Mask_Out}
  555.  
  556. {*****************************************************************************}
  557.  
  558.  PROCEDURE Do_Turbo_Extension (VAR Extension : Global_Strg);
  559.  
  560.  BEGIN {Do_Turbo_Extension}
  561.    CASE Indx OF
  562.       1 : Extension := 'Absolute';
  563.       3 : Extension := 'Assign';
  564.       4 : Extension := 'AuxInPtr';
  565.       5 : Extension := 'AuxOutPtr';
  566.       9 : Extension := 'BufLen';
  567.      10 : Extension := 'ClrEol';
  568.      11 : Extension := 'ClrScr';
  569.      13 : Extension := 'ConInPtr';
  570.      14 : Extension := 'ConOutPtr';
  571.      15 : Extension := 'ConstPtr';
  572.      16 : Extension := 'CrtExit';
  573.      17 : Extension := 'CrtInit';
  574.      19 : Extension := 'DelLine';
  575.      21 : Extension := 'Execute';
  576.      23 : Extension := 'FilePos';
  577.      24 : Extension := 'FileSize';
  578.      25 : Extension := 'FillChar';
  579.      27 : Extension := 'FreeMem';
  580.      29 : Extension := 'GetMem';
  581.      30 : Extension := 'GotoXY';
  582.      31 : Extension := 'GraphBackGround';
  583.      32 : Extension := 'GraphColorMode';
  584.      33 : Extension := 'GraphMode';
  585.      34 : Extension := 'GraphWindow';
  586.      35 : Extension := 'HeapStr';
  587.      36 : Extension := 'HiResColor';
  588.      37 : Extension := 'InLine';
  589.      39 : Extension := 'InsLine';
  590.      41 : Extension := 'IOResult';
  591.      42 : Extension := 'KeyPressed';
  592.      44 : Extension := 'LongFilePos';
  593.      45 : Extension := 'LongFileSize';
  594.      46 : Extension := 'LongSeek';
  595.      47 : Extension := 'LowVideo';
  596.      48 : Extension := 'LstOutPtr';
  597.      49 : Extension := 'MaxAvail';
  598.      52 : Extension := 'NormVideo';
  599.      53 : Extension := 'NoSound';
  600.      56 : Extension := 'Palette';
  601.      59 : Extension := 'Randomize';
  602.      60 : Extension := 'Random';
  603.      64 : Extension := 'Rename';
  604.      69 : Extension := 'TextBackGround';
  605.      70 : Extension := 'TextColor';
  606.      71 : Extension := 'TextMode';
  607.      72 : Extension := 'UpCase';
  608.      73 : Extension := 'UsrInPtr';
  609.      74 : Extension := 'UsrOutPtr';
  610.      75 : Extension := 'WhereX';
  611.      76 : Extension := 'WhereY';
  612.      77 : Extension := 'Window';
  613.      81 : Extension := 'Chain';
  614.      84 : Extension := 'Delay';
  615.      85 : Extension := 'Erase';
  616.      87 : Extension := 'Flush';
  617.      88 : Extension := 'HiRes';
  618.      91 : Extension := 'MSDos';
  619.      92 : Extension := 'PortW';
  620.      95 : Extension := 'Sound';
  621.     100 : Extension := 'Addr';
  622.     101 : Extension := 'Byte';
  623.     105 : Extension := 'CSeg';
  624.     106 : Extension := 'Draw';
  625.     107 : Extension := 'DSeg';
  626.     111 : Extension := 'Frac';
  627.     114 : Extension := 'Intr';
  628.     116 : Extension := 'MemW';
  629.     117 : Extension := 'Move';
  630.     118 : Extension := 'Plot';
  631.     119 : Extension := 'Port';
  632.     123 : Extension := 'Seek';
  633.     124 : Extension := 'Sqrt';
  634.     125 : Extension := 'SSeg';
  635.     127 : Extension := 'Swap';
  636.     134 : Extension := 'Aux';
  637.     136 : Extension := 'Con';
  638.     144 : Extension := 'Kbd';
  639.     145 : Extension := 'Lst';
  640.     146 : Extension := 'Mem';
  641.     152 : Extension := 'Ofs';
  642.     155 : Extension := 'Ptr';
  643.     156 : Extension := 'Seg';
  644.     158 : Extension := 'ShL';
  645.     159 : Extension := 'ShR';
  646.     163 : Extension := 'Trm';
  647.     164 : Extension := 'Usr';
  648.     167 : Extension := 'XOr';
  649.     169 : Extension := 'Hi';
  650.     173 : Extension := 'Lo';
  651.     176 : Extension := 'Pi';
  652.    END; {CASE Indx OF}
  653.  END;  {Do_Turbo_Extension}
  654.  
  655. {*****************************************************************************}
  656.  
  657.    PROCEDURE Do_Reserved_Word;
  658.  
  659.    BEGIN
  660.      Temp := Token [Indx];
  661.      DELETE (IO_Template, Token_Locn, LENGTH(Token[Indx]));
  662.      IF Res_Case = Lower THEN
  663.        Lo_Strg (Temp);
  664.      IF Borland_Convention THEN
  665.        Do_Turbo_Extension (Temp);
  666.      INSERT (Temp, IO_Template, Token_Locn);
  667.    END;
  668.  
  669. {*****************************************************************************}
  670.  
  671.    PROCEDURE TableSearch;
  672.  
  673.    BEGIN
  674.      Indx := 1;
  675.      REPEAT
  676.        Token_Locn := POS (Token[Indx], Work_Template);
  677.        IF (Token_Locn <> 0) AND Is_A_Token THEN
  678.          BEGIN                    {pattern match is reserved word}
  679.            IF Res_Case <> AsIs THEN
  680.              Do_Reserved_Word;
  681.            Mask_Out (Token[Indx]);
  682.            TableSearch            {recurse!!!}
  683.          END;
  684.        IF Token_Locn <> 0 THEN    {pattern match NOT reserved}
  685.          Mask_Out (Token[Indx]);
  686.        IF Token_Locn = 0 THEN     {no pattern match}
  687.          Indx := Indx + 1;
  688.      UNTIL ( (Indx > Array_Size) AND (Token_Locn = 0) );
  689.    END;
  690.  
  691. {*****************************************************************************}
  692.  
  693.    PROCEDURE Find_Token_Match;
  694.  
  695.    BEGIN {Find_Token_Match}
  696.      REPEAT      {exhaust all keyword occurrences in a line of text}
  697.        TableSearch;
  698.        IF Interruptable THEN
  699.          IF KeyPressed THEN
  700.            BEGIN
  701.              TextColor (24); TextBackGround (1);
  702.              WRITELN;
  703.              WRITE ('Abort pFORMAT of ',In_File_Name,'? ');
  704.              IF User_Says_YES THEN
  705.                User_Quits
  706.              ELSE
  707.                DelLine;
  708.              LowVideo;
  709.            END;
  710.      UNTIL Token_Locn = 0;
  711.    END;  {Find_Token_Match}
  712.  
  713. {*****************************************************************************}
  714.  
  715.   PROCEDURE Fix_Comment_Strings;
  716.   {
  717.     mask out comments & strings so as-is chars can be restored from
  718.     Temp_String onto IO_Template
  719.   }
  720.  
  721.     PROCEDURE Mask_String (Len_Comment : INTEGER);
  722.  
  723.     VAR
  724.       Slot : INTEGER;
  725.  
  726.     BEGIN
  727.       Temp_String := COPY (Work_Template, Strt, Len_Comment);
  728.       FOR Slot := 1 TO LENGTH(Temp_String) DO
  729.         Temp_String[Slot] := ' ';
  730.       DELETE (Work_Template, Strt, Len_Comment);
  731.       INSERT (Temp_String, Work_Template, Strt);
  732.     END;
  733.  
  734.   BEGIN {Fix_Comment_Strings}
  735.     {do strings}
  736.     REPEAT
  737.       Strt := POS('''', Work_Template);
  738.       IF Strt <> 0 THEN
  739.         Work_Template[Strt] := ' ';
  740.       Endd := POS ('''', Work_Template);
  741.       IF Endd <> 0 THEN
  742.         Work_Template[Endd] := ' ';
  743.       IF ((Endd <> 0) AND (Strt <> 0)) THEN
  744.         Mask_String (Endd - Strt + 1);
  745.     UNTIL ((Endd = 0) OR (Strt = 0));
  746.  
  747.     Strt := POS('{', Work_Template);
  748.     IF Strt = 0 THEN {check again for alternative delimiter}
  749.       Strt := POS ('(*', Work_Template);
  750.  
  751.     Endd := POS('}', Work_Template);
  752.     IF Endd = 0 THEN {check again for alternate delimiter}
  753.       Endd := POS('*)', Work_Template);
  754.  
  755.     IF Strt <> 0 THEN
  756.       Comment_Active := TRUE;
  757.  
  758.     IF Endd <> 0 THEN
  759.       Comment_Active := FALSE;
  760.  
  761.     IF Strt = 0 THEN
  762.       IF Endd = 0 THEN
  763.         IF Comment_Active THEN
  764.           BEGIN
  765.             Strt := 1;
  766.             Mask_String (Len - Strt + 1)
  767.           END
  768.         ELSE {no active comment}
  769.           BEGIN
  770.             {do nothing}
  771.           END
  772.       ELSE  {endd <> 0}
  773.         BEGIN
  774.           Strt := 1;
  775.           Mask_String (Endd - Strt + 1)
  776.         END
  777.     ELSE    {strt <> 0}
  778.       IF Endd <> 0 THEN
  779.         Mask_String (Endd - Strt + 1)
  780.       ELSE
  781.         Mask_String (Len - Strt + 1);
  782.   END; {Fix_Comment_Strings}
  783.  
  784. {*****************************************************************************}
  785.  
  786.   PROCEDURE Parse;
  787.  
  788.   VAR
  789.     Slot : INTEGER;
  790.  
  791.   BEGIN
  792.     Work_Template := IO_Template;
  793.     Len := LENGTH (IO_Template);
  794.  
  795.     Fix_Comment_Strings;
  796.  
  797.     Up_Strg (Work_Template);
  798.  
  799.     Temp_String := IO_Template;
  800.  
  801.     IF Non_Res_Case = Upper THEN
  802.       Up_Strg (IO_Template)
  803.     ELSE
  804.       IF Non_Res_Case = Lower THEN
  805.         Lo_Strg (IO_Template);
  806.  
  807.     FOR Slot := 1 TO LENGTH(IO_Template) DO
  808.       IF Work_Template[Slot] = ' ' THEN
  809.         IO_Template[Slot] := Temp_String[Slot];
  810.  
  811.     Find_Token_Match;
  812.   END;
  813.  
  814. {*****************************************************************************}
  815.  
  816.   PROCEDURE Verify_Default_Settings;
  817.  
  818.   BEGIN
  819.     GotoXY (1,3);
  820.     WRITELN;
  821.     TextColor (1); TextBackGround (1);
  822.     WRITELN ('Output File ',Out_File_Name,'''','s default attributes are :');
  823.     LowVideo;
  824.     WRITELN (' ■ TurboPASCAL key/reserved words are in UPPER-case letters and');
  825.     WRITELN (' ■ Other alphabetic characters are written as is.');
  826.     WRITELN;
  827.     WRITE   ('Would you like to change these defaults ? ');
  828.     IF User_Says_YES THEN
  829.       Change_Defaults
  830.     ELSE
  831.       BEGIN
  832.         Res_Case := Upper;
  833.         Non_Res_Case := Lower;
  834.       END;
  835.   END;
  836.  
  837. {*****************************************************************************}
  838.  
  839.   PROCEDURE Banner;
  840.  
  841.   BEGIN
  842.     ClrScr;
  843.     TextColor (8); TextBackGround (7);
  844.     WRITELN (
  845. '                  Turbo Format [1.01]  by Andy  J. S. Decepedia              '
  846.             );
  847.   END;
  848.  
  849. {*****************************************************************************}
  850.  
  851.   PROCEDURE Get_Input_Name;
  852.  
  853.   BEGIN {Get_Input_Name}
  854.     REPEAT
  855.       WRITELN;
  856.       WRITE  ('Name of TurboPASCAL source text file  » ');
  857.       READLN (In_File_Name);
  858.       Trim_Off (In_File_Name);
  859.       Up_Strg (In_File_Name);
  860.  
  861.       IF LENGTH(In_File_Name) < 1 THEN
  862.         User_Quits;
  863.  
  864.       ASSIGN (Text_File, In_File_Name);
  865.       {$I-} RESET (Text_File) {$I+};
  866.       Ok := (IOResult = 0);
  867.       IF NOT Ok THEN
  868.         BEGIN
  869.           Sound (6099);
  870.           Delay (500);
  871.           Sound (600);
  872.           NoSound;
  873.           WRITE ('Cannot find file ');
  874.           NormVideo;
  875.           WRITE (In_File_Name);
  876.           LowVideo;
  877.         END
  878.     UNTIL Ok;
  879.   END; {Get_Input_Name}
  880.  
  881. {*****************************************************************************}
  882.  
  883.   PROCEDURE Get_Output_Name;
  884.  
  885.   BEGIN {Get_Output_Name};
  886.     REPEAT
  887.       WRITELN;
  888.       WRITE  ('Name of pFORMAT generated file        » ');
  889.       READLN (Out_File_Name);
  890.       Trim_Off (Out_File_Name);
  891.       Up_Strg (Out_File_Name);
  892.  
  893.       IF LENGTH (Out_File_Name) < 1 THEN
  894.         User_Quits;
  895.  
  896.       ASSIGN  (Pretty_Output, Out_File_Name);
  897.       {$I-} REWRITE (Pretty_Output) {$I+};
  898.  
  899.       Ok := (IOResult = 0);
  900.  
  901.       IF NOT Ok THEN
  902.         BEGIN
  903.           WRITELN;
  904.           Sound (6099);
  905.           Delay (500);
  906.           Sound (600);
  907.           NoSound;
  908.           WRITE ('Unable to open file ');
  909.           NormVideo;
  910.           WRITE (Out_File_Name);
  911.           LowVideo;
  912.         END;
  913.     UNTIL Ok;
  914.   END; {Get_Input_Name}
  915.  
  916. {*****************************************************************************}
  917.  
  918. BEGIN {--------------------------------------------------------------- pFormat}
  919.   Init_Array;
  920.  
  921.   REPEAT
  922.     Window (1, 1, 80, 25);
  923.     GotoXY (1,1);
  924.     ClrScr;
  925.     Borland_Convention := FALSE;
  926.     Comment_Active     := FALSE;
  927.  
  928.     Banner;
  929.  
  930.     Window (1, 2, 80, 24);
  931.     ClrScr;
  932.     LowVideo;
  933.     WRITELN;
  934.     WRITE   ('■ To quit, press a lone ',CHR(17),'┘ in response to the prompts');
  935.     WRITELN (' for file names.');
  936.     WRITELN;
  937.  
  938.     Get_Input_Name;
  939.     Get_Output_Name;
  940.  
  941.     Window (1, 1, 80, 24);
  942.     GotoXY (1,1);
  943.     Banner;
  944.  
  945.     Window (1, 2, 80, 24);
  946.     Verify_Default_Settings;
  947.     NormVideo;
  948.     WRITELN;
  949.     WRITELN;
  950.     WRITE ('Would you like to be able to abort this run with a keypress?');
  951.     Interruptable := User_Says_YES;
  952.     LowVideo;
  953.     Window (1, 1, 80, 24);
  954.     GotoXY (1,1);
  955.     Banner;
  956.  
  957.     GotoXY (1,3);
  958.     TextColor (16); TextBackGround (1);
  959.     Proc_Label := CONCAT ('Reading ',In_File_Name,' & generating ',
  960.                                    Out_File_Name);
  961.  
  962.     IF (LENGTH (Proc_Label) <= 80) THEN {centre if it fits 80-char line}
  963.       WRITE (Proc_Label:((80 + LENGTH(Proc_Label)) DIV 2))
  964.     ELSE
  965.       WRITE (Proc_Label);
  966.     GotoXY (1,5);
  967.     NormVideo;
  968.     FOR Cnt  := 1 TO 80 DO
  969.       WRITE ('═');
  970.  
  971.     LowVideo;
  972.     Window (1, 6, 80, 23);
  973.     ClrScr;
  974.     Set_Cursor (Invisible);
  975.  
  976.     WHILE NOT (EOF(Text_File)) DO
  977.       BEGIN
  978.         READLN  (Text_File, IO_Template);
  979.         Parse;
  980.         WRITELN (IO_Template);
  981.         WRITELN (Pretty_Output, IO_Template);
  982.       END;
  983.     CLOSE (Text_File);
  984.     CLOSE (Pretty_Output);
  985.     Set_Cursor(Full);
  986.     {Cursor_on(true);}
  987.     ClrScr;
  988.     WRITELN;
  989.     WRITE ('Quit pFORMAT');
  990.   UNTIL User_Says_YES;
  991.   cursor_on(true);
  992. END.  {---------------------------------------------------------------pFormat}
  993.