home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / zkuste / pascal / refer / PASCRF22.ZIP / PASCREF.PAS < prev    next >
Pascal/Delphi Source File  |  1996-12-26  |  18KB  |  638 lines

  1. { PASCREF.PAS : Pascal Cross-Reference generator
  2.  
  3.   Title   : PASCREF
  4.   Language: Borland Pascal v4.0 through 7.0, DOS real or protected mode
  5.   Version : 2.2
  6.   Date    : Dec 26,1996
  7.   Author  : J R Ferguson
  8.   Usage   : refer procedure Help
  9.   Download: http://www.xs4all.nl/~ferguson
  10.   E-mail  : j.r.ferguson@iname.com
  11.  
  12. This program and its source may be used and copied freely without charge,
  13. but  only  for non-commercial purposes. The author is not responsible for
  14. any damage or loss of data that may be caused by using it.
  15.  
  16. To compile this source file, you wil need  some  units  from  the  JRFPAS
  17. Pascal  routine  library by the same author, which can be downloaded from
  18. the Internet address mentioned above.
  19. }
  20.  
  21. {$V-}
  22. {$R+}
  23.  
  24. {$UNDEF OUTBUFHEAP}   { UNDEF to work around a BP 7.0 bug resulting in
  25.                         erroneous file output }
  26.  
  27. program PASCREF;
  28. Uses DefLib, ArgLib, StpLib, StfLib, ChrLib, TimLib, CvtLib;
  29.  
  30. const
  31.   PROGIDN   = 'PASCREF';
  32.   PROGVERS  = 'v2.2';
  33.   { Defaults: }
  34.   DFLCASE   = false;   { Case sensitive parsing }
  35.   DFLLINE   = true ;   { Line number references }
  36.   DFLOCNT   = false;   { Occurrence counts }
  37.   DFLPAGE   = true ;   { Page formatting }
  38.   DFLRESW   = false;   { Reserved words }
  39.   DFLSTDI   = false;   { Standard identifiers }
  40.   DFLINPT   = '.PAS';  { Input file type }
  41.   DFLOUTT   = '.CRF';  { Output file type }
  42.  
  43.   MAXFNAME  = 79; { Max filename length (including drive and path) }
  44.   CNTLEN    =  4; { Length of occurrence count field }
  45.   REFLEN    =  4; { Length of line number references }
  46.   MINIDN    = 20; { Minimum print width of identifier field }
  47.   MAXIDN    = 32; { Max nr of identifier characters recognized }
  48.  
  49.   LINLEN    = 80; { Characters per line (including left and right margins }
  50.   PAGLEN    = 66; { Lines per page Page (including top and bottom margins }
  51.   LEFMAR    =  2; { Left margin for page formatted output }
  52.   RIGMAR    =  2; { Right margin for page formatted output }
  53.   TOPMAR    =  2; { Page top line number for page formatted output }
  54.   BOTMAR    =  6; { Page bottom line number for page formatted output }
  55.  
  56.   INPBUFSIZ = 4096;
  57.   OUTBUFSIZ = 4096;
  58.  
  59.   { Error codes and messages: }
  60.   ERROK     = 0;
  61.   ERRARG    = 1;
  62.   ERRINP    = 2;
  63.   ERROUT    = 3;
  64.  
  65.   ERRMSG    : array[ERRARG..ERROUT] of StpTyp =
  66.  ('',
  67.   'File not found : ',
  68.   'Can''t open output : '
  69.  );
  70.  
  71. type
  72.   InpBufTyp = array[1..INPBUFSIZ] of char;   InpBufPtr = ^InpBufTyp;
  73.   OutBufTyp = array[1..OUTBUFSIZ] of char;   OutBufPtr = ^OutBufTyp;
  74.  
  75.   IdnStp    = string[MAXIDN];
  76.   IdnInd    = 0..MAXIDN;
  77.  
  78.   LstElm    = record
  79.                 num: integer;
  80.                 def: boolean;  { << not implemented >> : line number where defined }
  81.               end;
  82.   LstPtr    = ^LstEntry;
  83.   LstEntry  = record
  84.                 inh: LstElm;
  85.                 nxt: LstPtr;
  86.               end;
  87.   LstTyp    = record           { Linked List }
  88.                 head : LstPtr;
  89.                 tail : LstPtr;
  90.               end;
  91.  
  92.   TblElm    = record
  93.                 idn: IdnStp;
  94.                 cnt: integer;
  95.                 ref: LstTyp;
  96.               end;
  97.   TblPtr    = ^TblEntry;       { Binary Tree }
  98.   TblEntry  = record
  99.                 inh: TblElm;
  100.                 prv,
  101.                 nxt: TblPtr;
  102.               end;
  103.  
  104. var
  105.   InpFname,
  106.   InpFnameShort,
  107.   OutFname  : StpTyp;
  108.   InpFvar,
  109.   OutFvar   : Text;
  110.   InpBuf    : InpBufPtr;
  111. {$IFDEF OUTBUFHEAP}
  112.   OutBuf    : OutBufPtr;
  113. {$ELSE}
  114.   OutBuf    : OutBufTyp;
  115. {$ENDIF}
  116.   InpOpen,
  117.   OutOpen   : boolean;
  118.   ErrCod    : integer;
  119.   CurArg    : StpTyp;
  120.   OptCase,
  121.   OptLine,
  122.   OptOcnt,
  123.   OptPage,
  124.   OptResW,
  125.   OptStdI   : boolean;
  126.   PagCnt    : integer;   { Current page }
  127.   LinCnt,                { Current print line }
  128.   MinLin,                { First print line on page }
  129.   MaxLin    : integer;   { Last print line on page }
  130.   ColCnt,                { Current print column }
  131.   MinCol,                { First print column on line }
  132.   MaxCol,                { Last print column on line }
  133.   CntCol,                { Start column for occurrence count }
  134.   WrnCol,
  135.   IdnCol,                { Start column for identifier }
  136.   RefCol    : integer;   { Start column for line number references }
  137.   TimeStamp : StpTyp;
  138.  
  139.   ResWords1,
  140.   ResWords2,
  141.   StdIdents : StpTyp;
  142.   CrfTbl    : TblPtr;
  143.   CurLine   : StpTyp;
  144.   CurIdn    : IdnStp;
  145.   PrvIdn    : IdnStp;
  146.   CurNum    : integer;
  147.   CurDef    : boolean;
  148.   CurPos    : integer;
  149.   CurChr    : char;
  150.   SaveChr   : char;
  151.   SaveSta   : boolean;
  152.   EolnSta   : boolean;
  153.  
  154. {--- General routines ---}
  155.  
  156. procedure Help;
  157. begin
  158.   WriteLn('usage   : PASCREF inpfile [outfile] [/option[...] [...]]');
  159.   WriteLn('defaults: inpfile type = .PAS');
  160.   WriteLn('          outfile name = inpfile name');
  161.   WriteLn('                  type = .CRF');
  162.   WriteLn('');
  163.   WriteLn('options : s[+] or s-, where switch s is one of the following:');
  164.   WriteLn('');
  165.   WriteLn('   switch  default  meaning');
  166.   WriteLn('   ------  -------  ---------------------------------');
  167.   WriteLn('     C        -     case sensitive identifier-parsing');
  168.   WriteLn('     L        +     line reference numbers');
  169.   WriteLn('     O        -     occurrence count');
  170.   WriteLn('     P        +     page formattting');
  171.   WriteLn('     R        -     include reserved words');
  172.   WriteLn('     S        -     include standard identifiers');
  173.   WriteLn('');
  174.   WriteLn('remarks : - No recognition of scope');
  175.   WriteLn('          - No recognition of declaration vs. reference');
  176.   WriteLn('          - With the /C option a ">" warns for an identifier');
  177.   WriteLn('            matching the previous one in uppercase');
  178. end;
  179.  
  180. procedure GetTimeStamp;
  181. var date: TimDateRec; time: TimTimeRec;
  182.   function ItoS(num,len: integer): StpTyp;
  183.   var tmp: StpTyp;
  184.   begin ItoABl(num,tmp,10,len); ItoS:= tmp; end;
  185. begin { GetTimeStamp }
  186.   TimGetDate(date); TimGetTime(time);
  187.   with date,time do begin
  188.     TimeStamp:= ItoS(day,2)  + '-' + ItoS(month,2)   + '-' + ItoS(year,4)
  189.         + ' ' + ItoS(hours,2) + ':' + ItoS(minutes,2);
  190.   end;
  191. end; { GetTimeStamp }
  192.  
  193. {--- Command Line parsing routines ---}
  194.  
  195. procedure ReadSwitch(var option: boolean);
  196. begin
  197.   case StpcRet(CurArg,1) of
  198.    '-' : begin option:= false; StpDel(CurArg,1,1); end;
  199.    '+' : begin option:= true ; StpDel(CurArg,1,1); end;
  200.    else  option:= true;
  201.   end;
  202. end;
  203.  
  204. procedure ReadOpt;
  205. begin
  206.   StpDel(CurArg,1,1); if StpEmpty(CurArg) then ErrCod:= ERRARG;
  207.   while (ErrCod = ERROK) and not StpEmpty(CurArg) do
  208.   case StpcGet(CurArg) of
  209.     'C' : ReadSwitch(OptCase);
  210.     'L' : ReadSwitch(OptLine);
  211.     'O' : ReadSwitch(OptOcnt);
  212.     'P' : ReadSwitch(OptPage);
  213.     'R' : ReadSwitch(OptResW);
  214.     'S' : ReadSwitch(OptStdI);
  215.     else ErrCod:= ERRARG;
  216.   end;
  217. end;
  218.  
  219. procedure ReadArgs;
  220. var i   : ArgInd;
  221.     p   : StpInd;
  222. begin
  223.   StpCreate(InpFname); StpCreate(OutFname);
  224.   GetArgs;
  225.   i:= 0;
  226.   while (i < ArgC) and (ErrCod = ERROK) do begin
  227.     Inc(i); StpCpy(CurArg,ArgV[i]); StpUpp(CurArg);
  228.     if      StpcRet(CurArg,1) = '/' then ReadOpt
  229.     else if StpEmpty(InpFname)      then StpNCpy(InpFname,CurArg,MAXFNAME)
  230.     else if StpEmpty(OutFname)      then StpNCpy(OutFname,CurArg,MAXFNAME)
  231.     else ErrCod:= ERRARG;
  232.   end;
  233.   if StpEmpty(InpFname) then ErrCod:= ERRARG
  234.   else begin
  235.     if StpcPos(InpFname,'.')=0 then StpCat(InpFname,DFLINPT);
  236.     StpCpy(InpFnameShort,InpFname);
  237.     StpDel(InpFnameShort,1,StpcRPos(InpFnameShort,'\'));
  238.     if StpEmpty(OutFname) then StpBefore(OutFname,InpFnameShort,'.');
  239.     if StpcPos(OutFname,'.')=0 then StpCat(OutFname,DFLOUTT);
  240.   end;
  241. end;
  242.  
  243. {--- I/O routines ---}
  244.  
  245. procedure OpenInp;
  246. begin
  247.   Assign(InpFvar,InpFname); new(InpBuf); SetTextBuf(InpFvar,InpBuf^);
  248.   {$I-} reset(InpFvar) {$I+};
  249.   if IOresult <> 0 then ErrCod:= ERRINP else InpOpen:= true;
  250. end;
  251.  
  252. procedure CloseInp;
  253. begin if InpOpen then begin
  254.   Close(InpFvar); dispose(InpBuf); InpOpen:= false;
  255. end end;
  256.  
  257. procedure OpenOut;
  258. begin
  259.   Assign(OutFvar,OutFname);
  260. {$IFDEF OUTBUFHEAP}
  261.   new(OutBuf); SetTextBuf(OutFvar,OutBuf^);
  262. {$ELSE}
  263.   SetTextBuf(OutFvar,OutBuf);
  264. {$ENDIF}
  265.   {$I-} rewrite(OutFvar) {$I+};
  266.   if IOresult <> 0 then ErrCod:= ERROUT else OutOpen:= true;
  267. end;
  268.  
  269. procedure CloseOut;
  270. begin if OutOpen then begin
  271.   Close(OutFvar);
  272. {$IFDEF OUTBUFHEAP}
  273.   dispose(OutBuf);
  274. {$ENDIF}
  275.   OutOpen:= false;
  276. end end;
  277.  
  278. procedure PushChr;
  279. begin SaveSta:= true; SaveChr:= CurChr; end;
  280.  
  281. function PopChr: boolean;
  282. begin
  283.   if SaveSta then begin
  284.     CurChr:= SaveChr; SaveSta:= false;
  285.     PopChr:= true;
  286.   end
  287.   else PopChr:= false;
  288. end;
  289.  
  290. function NxtChr: char;
  291. begin
  292.   if not PopChr then begin
  293.     if EolnSta then begin
  294.       if eof(InpFvar) then StpCreate(CurLine) else ReadLn(InpFvar,CurLine);
  295.       CurNum:= CurNum + 1; CurPos:= 0; EolnSta:= false;
  296.     end;
  297.     if CurPos < StpLen(CurLine) then begin
  298.       CurPos:= CurPos + 1;
  299.       CurChr:= StpcRet(CurLine,CurPos);
  300.     end
  301.     else begin
  302.       EolnSta:= true;
  303.       CurChr := ' ';
  304.     end;
  305.   end;
  306.   if not OptCase then CurChr:= ToUpper(CurChr);
  307.   NxtChr:= CurChr;
  308. end;
  309.  
  310. procedure GetChr;
  311. var Skipping: boolean;
  312. begin
  313.   case NxtChr of
  314.     '''': begin
  315.             Skipping:= true;
  316.             while Skipping do begin
  317.               if NxtChr = '''' then
  318.                 if NxtChr <> '''' then begin PushChr; Skipping:= false end;
  319.             end;
  320.             CurChr:= ' ';
  321.           end;
  322.     '{' : begin
  323.             repeat CurChr:= NxtChr until CurChr = '}';
  324.             CurChr:= ' ';
  325.           end;
  326.     '(' : if NxtChr='*' then begin
  327.             Skipping:= true;
  328.             while Skipping do
  329.               if NxtChr = '*' then Skipping:= NxtChr <> ')';
  330.             CurChr:= ' ';
  331.           end
  332.           else begin
  333.             PushChr;
  334.             CurChr:= '(';
  335.           end;
  336.   end;
  337. end;
  338.  
  339. procedure GetIdn;
  340. begin
  341.   while not (CurChr in ['A'..'Z','a'..'z','_']) and not eof(InpFvar) do
  342.     GetChr;
  343.   StpCreate(CurIdn);
  344.   while CurChr in ['A'..'Z','a'..'z','_','0'..'9'] do begin
  345.     if StpLen(CurIdn) < MAXIDN then StpcCat(CurIdn,CurChr);
  346.     GetChr;
  347.   end;
  348.   CurDef:= false;   { << not yet implemented >> }
  349. end;
  350.  
  351. procedure NewLine; forward;
  352.  
  353. procedure WriteChr(c: char);
  354. begin Write(OutFvar,c); Inc(ColCnt); end;
  355.  
  356. procedure WriteStp(str: StpTyp);
  357. begin Write(OutFvar,str); Inc(ColCnt,StpLen(str)); end;
  358.  
  359. procedure WriteInt(value: integer; width: integer);
  360. begin Write(OutFvar,value:width); Inc(ColCnt,width); end;
  361.  
  362. procedure SkipToCol(col: integer);
  363. begin
  364.   if ColCnt > col then NewLine;
  365.   Write(OutFvar,'':col-ColCnt); ColCnt:= col;
  366. end;
  367.  
  368. procedure SkipToLin(lin: integer);
  369. begin
  370.   while LinCnt < lin do begin WriteLn(OutFvar); Inc(LinCnt); end;
  371.   ColCnt:=0; SkipToCol(MinCol);
  372. end;
  373.  
  374. procedure PageHeader;
  375. begin
  376.   if PagCnt > 1 then Write(OutFvar,chr(AsciiFF));
  377.   SkipToLin(MinLin);
  378.   WriteStp('Pascal Cross-Reference   '+InpFnameShort+'   '+TimeStamp);
  379.   SkipToCol(MaxCol - 8); WriteStp('Page '); WriteInt(PagCnt,1); NewLine;
  380.   if OptCase then WriteStp('Case sensitive.  ');
  381.   if OptResW then WriteStp('Reserved words included.  ');
  382.   if OptStdI then WriteStp('Standard identifiers included.');
  383.   NewLine;
  384.   NewLine;
  385.   NewLine;
  386.   if OptOcnt then begin SkipToCol(CntCol); WriteStp(' Cnt'); end;
  387.                         SkipToCol(IdnCol); WriteStp('Identifier');
  388.   if OptLine then begin SkipToCol(RefCol); WriteStp('Referenced'); end;
  389.   NewLine;
  390.   if OptOcnt then begin SkipToCol(CntCol); WriteStp(' ---'); end;
  391.                         SkipToCol(IdnCol); WriteStp('----------');
  392.   if OptLine then begin SkipToCol(RefCol); WriteStp('----------'); end;
  393.   NewLine;
  394. end;
  395.  
  396. procedure NewPage;
  397. begin Inc(PagCnt); LinCnt:= 0; ColCnt:= 0; if OptPage then PageHeader; end;
  398.  
  399. procedure NewLine;
  400. begin
  401.   WriteLn(OutFvar); Inc(LinCnt); ColCnt:= 0;
  402.   if LinCnt > MaxLin then NewPage;
  403.   SkipToCol(MinCol);
  404. end;
  405.  
  406. {--- Reference list handling routines ---}
  407.  
  408. procedure LstCreate(var ref: LstTyp);
  409. begin with ref do begin head:= nil; tail:= nil; end end;
  410.  
  411. procedure LstDispose(var ref: LstTyp);
  412. var p: LstPtr;
  413. begin with ref do begin
  414.   while head <> nil do begin
  415.     p:= head^.nxt;
  416.     dispose(head);
  417.     head:= p;
  418.   end;
  419.   tail:= nil;
  420. end end;
  421.  
  422. procedure LstAppend(var ref: LstTyp; number: integer; defined: boolean);
  423. var p: LstPtr;
  424. begin
  425.   new(p);
  426.   with p^ do begin
  427.     inh.num:= number;
  428.     inh.def:= defined;
  429.     nxt    := nil;
  430.   end;
  431.   with ref do begin
  432.     if head=nil then head:= p else tail^.nxt:= p;
  433.     tail:= p;
  434.   end;
  435. end;
  436.  
  437. procedure LstWriteElm(var elm: LstElm);
  438. begin
  439.   if ColCnt + REFLEN + 2 > MaxCol then begin NewLine; SkipToCol(RefCol) end;
  440.   if elm.def then WriteChr('*') else WriteChr(' ');
  441.   WriteInt(elm.num,REFLEN);
  442.   WriteChr(' ');
  443. end;
  444.  
  445. procedure LstWrite(var ref: LstTyp);
  446. var p: LstPtr;
  447. begin
  448.   p:= ref.head;
  449.   while p<>nil do begin
  450.     LstWriteElm(p^.inh);
  451.     p:= p^.nxt;
  452.   end;
  453. end;
  454.  
  455. {--- Table handling routines ---}
  456.  
  457. function TblOrder(idn1,idn2: IdnStp): integer;
  458. { result < 0 if idn1 < idn2, 0 if idn1 = idn2, > 0 if idn1 > idn2 }
  459. var order: integer;
  460. begin
  461.   if OptCase then begin     { alphabet first, then upper/lower case }
  462.     order:= StpUppCmp(idn1,idn2);
  463.     if order = 0 then order:= StpCmp(idn1,idn2);
  464.     TblOrder:= order;
  465.   end
  466.   else TblOrder:= StpCmp(idn1,idn2);
  467. end;
  468.  
  469. procedure TblCreate(var tbl: TblPtr);
  470. begin tbl:= nil end;
  471.  
  472. procedure TblDispose(var tbl: TblPtr);
  473. begin if tbl<>nil then begin
  474.   with tbl^ do begin
  475.     if OptLine then LstDispose(inh.ref);
  476.     TblDispose(prv);
  477.     TblDispose(nxt);
  478.   end;
  479.   dispose(tbl);
  480. end; end;
  481.  
  482. procedure TblInsert(var tbl    : TblPtr;
  483.                     var ident  : IdnStp;
  484.                         number : integer;
  485.                         defined: boolean);
  486. var order: integer;
  487.   procedure TblIns(var p: TblPtr);
  488.   begin
  489.     if p=nil then begin
  490.       new(p);
  491.       with p^ do begin
  492.         with inh do begin
  493.           idn:= ident;
  494.           cnt:= 1;
  495.           if OptLine then begin
  496.             LstCreate(ref);
  497.             LstAppend(ref, number, defined);
  498.           end;
  499.         end;
  500.         prv:= nil;
  501.         nxt:= nil;
  502.       end;
  503.     end
  504.     else with p^ do begin
  505.       order:= TblOrder(ident,inh.idn);
  506.       if        order < 0 then   TblIns(prv)
  507.       else   if order > 0 then   TblIns(nxt)
  508.       else { if order = 0 then } with inh do begin
  509.         Inc(cnt);
  510.     if OptLine then LstAppend(ref, number, defined);
  511.       end;
  512.     end;
  513.   end;
  514. begin { TblInsert }
  515.   TblIns(tbl);
  516. end;
  517.  
  518. procedure TblWriteElm(var elm: TblElm);
  519. begin with elm do begin
  520.   if OptOcnt then begin
  521.     SkipToCol(CntCol);
  522.     WriteInt(cnt,CNTLEN);
  523.   end;
  524.   if OptCase then begin
  525.     SkipToCol(WrnCol);
  526.     if StpUppCmp(idn,PrvIdn) = 0 then WriteChr('>') else WriteChr(' ');
  527.     PrvIdn:= idn;
  528.   end;
  529.   SkipToCol(IdnCol); WriteStp(idn);
  530.   if OptLine then begin SkipToCol(RefCol); LstWrite(ref); end;
  531. end end;
  532.  
  533. procedure TblWrite(var tbl: TblPtr);
  534. begin if tbl<>nil then with tbl^ do begin
  535.   TblWrite(prv);
  536.   TblWriteElm(inh);
  537.   TblWrite(nxt);
  538. end end;
  539.  
  540. {--- Main Line ---}
  541.  
  542. procedure ReadTable;
  543.   function Included(var wrd: IdnStp): boolean;
  544.   var tmp: StpTyp;
  545.   begin
  546.     tmp:= ' ' + StfUpp(wrd) + ' ';
  547.     Included:=
  548.          ( OptStdI or ( Pos(tmp,StdIdents)                      = 0 ) )
  549.      and ( OptResW or ( Pos(tmp,ResWords1) + Pos(tmp,ResWords2) = 0 ) )
  550.   end;
  551. begin { ReadTable }
  552.   OpenInp;
  553.   if ErrCod = ERROK then begin
  554.     TblCreate(CrfTbl);
  555.     CurNum := 0; EolnSta:= true; SaveSta:= false;
  556.     GetChr;
  557.     while not eof(InpFvar) do begin
  558.       GetIdn;
  559.       if Included(CurIdn) then TblInsert(CrfTbl,CurIdn,CurNum,CurDef);
  560.     end;
  561.     CloseInp;
  562.   end;
  563. end;
  564.  
  565. procedure WriteTable;
  566. begin
  567.   OpenOut;
  568.   if ErrCod = ERROK then begin
  569.     StpCreate(PrvIdn); PagCnt:= 0;
  570.     NewPage;
  571.     TblWrite(CrfTbl);
  572.     TblDispose(CrfTbl);
  573.     CloseOut;
  574.   end;
  575. end;
  576.  
  577. procedure MainInit;
  578. begin
  579.   ResWords1:=' ABSOLUTE AND ARRAY ASM BEGIN CASE CONST CONSTRUCTOR DESTRUCTOR '
  580.            + 'DIV DO DOWNTO ELSE END EXPORTS EXTERNAL FILE FOR FORWARD FUNCTIO'
  581.            + 'N GOTO IF IMPLEMENTATION IN INHERITED INLINE INTERFACE INTERRUPT'
  582.            + ' LABEL LIBRARY MOD NIL NOT OBJECT OF OR PACKED PROCEDURE PROGRAM';
  583.   ResWords2:=' RECORD REPEAT SET SHL SHR STRING THEN TO TYPE UNIT UNTIL USES V'
  584.            + 'AR WHILE WITH XOR ';
  585.   StdIdents:=' ABS ARCTAN BOOLEAN CHAR CHR COS DISPOSE EOF EOLN EXP FALSE GET '
  586.            + 'INPUT INTEGER LN MAXINT NEW ODD ORD OUTPUT PACK PAGE PRED PUT RE'
  587.            + 'AD READLN REAL RESET REWRITE ROUND SIN SQR SQRT SUCC TEXT TRUE T'
  588.            + 'RUNC UNPACK WRITE WRITELN ';
  589.   ErrCod := ERROK;
  590.   InpOpen:= false; OutOpen:= false;
  591.   OptCase:= DFLCASE; OptLine:= DFLLINE; OptOcnt:= DFLOCNT;
  592.   OptPage:= DFLPAGE; OptResW:= DFLRESW; OptStdI:= DFLSTDI;
  593.   ReadArgs;
  594.   if ErrCod=ERROK then begin
  595.     MinLin:= 0; MaxLin:= PAGLEN;
  596.     MinCol:= 0; MaxCol:= LINLEN;
  597.     if OptPage then begin
  598.       Inc(MinLin,TOPMAR); Dec(MaxLin,BOTMAR);
  599.       Inc(MinCol,LEFMAR); Dec(MaxCol,RIGMAR);
  600.     end;
  601.     CntCol:= MinCol;
  602.     WrnCol:= CntCol; if OptOcnt then Inc(WrnCol,CNTLEN+1);
  603.     IdnCol:= WrnCol; if OptCase then Inc(IdnCol,1);
  604.     RefCol:= IdnCol + MINIDN + 1;
  605.   end;
  606. end;
  607.  
  608.  
  609. procedure MainExit;
  610. begin
  611.   if ErrCod <> ERROK then begin
  612.     Write(ERRMSG[ErrCod]);
  613.     case ErrCod of
  614.       ERRARG : Help;
  615.       ERRINP : WriteLn(InpFname);
  616.       ERROUT : WriteLn(OutFname);
  617.     end;
  618.   end;
  619. end;
  620.  
  621.  
  622. begin { Main program }
  623.   WriteLn(PROGIDN+' '+PROGVERS+' : Pascal Cross-Reference generator');
  624.   MainInit;
  625.   if ErrCod = ERROK then begin
  626.     Write(InpFname,' ==> ',OutFname);
  627.     GetTimeStamp;
  628.     Write('  Reading ');
  629.     ReadTable;
  630.     if ErrCod = ERROK then begin
  631.       Write(', Writing ');
  632.       WriteTable;
  633.       WriteLn(', Done.');
  634.     end;
  635.   end;
  636.   MainExit;
  637. end.
  638.