home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / TURBOPAS / ZXREF.LBR / XREF2.IQC / XREF2.INC
Text File  |  2000-06-30  |  15KB  |  593 lines

  1.  
  2. (***************************************************)
  3. (*-------> Include file   #2  for XREF.PAS <-------*)
  4. (***************************************************)
  5.  
  6. (* v. 0200pm, sun, 28.Sep.86, Glen Ellis *)
  7.  
  8. (*-------> primary procedure is pBuildTree *)
  9.  
  10.  
  11. (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  12. (*                                                                    *)
  13. (*  Primary procedure     >>   BuildTree    <<                        *)
  14. (*                                                                    *)
  15. (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  16.  
  17.  
  18. procedure   pBuildTree
  19.  ( var tree : treepointer; var InFile : GenStr; BTkeyModeChar : string1 );
  20.  
  21. var
  22. CurrentWord : alfa;
  23. fin : text;                   { local input file }
  24. currchar,                     { Current operative character }
  25. nextchar      : charinfo;     { Look-ahead character }
  26. flushing      : (KNOT, DBL, STD, LIT, SCANFN, SCANFN2);
  27. fname         : string[30];
  28. doInclude     : boolean;      { true IF we discovered include file }
  29. fbuffer       : string[255];  { format buffer - before final Print }
  30. LineIn        : string[255];
  31. LineInLast    : string[255];
  32. cp            : 0..255;
  33. xeof,                         { EOF status AFTER a read }
  34. xeoln         : BOOLEAN;      { EOLN status after a read }
  35.  
  36.  
  37. (*----------------------------*)
  38. (* sub procedure of pReadWord *)
  39.  
  40. procedure pFindInReserve
  41.  (var fWord: alfa ;
  42.   var fFindInReserve : boolean ;
  43.   FRkeyModeChar : string1 ) ;
  44.  
  45. Label Return;
  46.  
  47. var
  48. low, high, mid : integer;
  49. KeyRefStr : string[20];
  50.  
  51. begin
  52.  
  53.    low  := 1;
  54.    high := NumKeys;
  55.  
  56.    WHILE (low <= high)
  57.    do
  58.    begin
  59.  
  60.    mid := (low+high) div 2;
  61.  
  62.    IF (FRkeyModeChar <> 'T') and (FRkeyModeChar <> 'D')
  63.       then Halt; (* emergency trap sanity *)
  64.  
  65.  
  66.    (*---------------------*)
  67.    (* Turbo Pascal Search *)
  68.    if FRkeyModeChar = 'T' then
  69.    begin
  70.  
  71.       IF fWord < key[mid]  (**)
  72.       then
  73.       begin
  74.          high := mid - 1 ;
  75.       end
  76.       else
  77.       IF fWord > key[mid]  (**)
  78.       then
  79.       begin
  80.          low  := mid + 1;
  81.       end
  82.       else
  83.       begin
  84.          fFindInReserve := true;
  85.          goto Return; (* flakey exit ! *)
  86.       end;
  87.    end;
  88.    (* Turbo Pascal Search *)
  89.  
  90.  
  91.    (*--------------*)
  92.    (* dBASE search *)
  93.    if FRkeyModeChar = 'D' then
  94.    begin
  95.  
  96.       (* prep reference string *)  (* leftstring method *)
  97.       KeyRefStr := copy(Key[mid],1,length(fWord)); (**)
  98.  
  99.       IF fWord < KeyRefStr (**) (* leftstring method *)
  100.       then
  101.       begin
  102.          high := mid - 1 ;
  103.       end
  104.       else
  105.       IF fWord > KeyRefStr (**) (* leftstring method *)
  106.       then
  107.       begin
  108.          low  := mid + 1;
  109.       end
  110.       else
  111.       begin
  112.          fFindInReserve := true;
  113.          goto Return; (* flakey exit ! *)
  114.       end;
  115.    end;
  116.    (* dBASE search *)
  117.  
  118.  
  119.    end;
  120.    (* WHILE *)
  121.  
  122.    fFindInReserve := false;
  123.  
  124.    Return: (* label *)
  125.  
  126. End;   (* procedure pFindInReserve *)
  127.  
  128.  
  129.  
  130. (*------------------------------*)
  131. (*  sub procedure of pBuildTree *)
  132.  
  133. procedure pEnterTree
  134. (var subtree: treepointer; Word   : alfa; line   :counter);
  135.  
  136. var
  137. nextitem : Queuepointer;
  138.  
  139. begin
  140.  
  141.    IF subtree=nil then
  142.    begin {create a new entry}
  143.       new(subtree);
  144.  
  145.       WITH subtree^ do
  146.       begin
  147.          left := nil;
  148.          right := nil;
  149.  
  150.          WITH entry do
  151.          begin
  152.             Wordvalue := Word;
  153.             new(FirstInQueue);
  154.             LastinQueue := FirstInQueue;
  155.  
  156.             WITH FirstInQueue^ do
  157.             begin
  158.                linenumber := line;
  159.                NextInQueue := nil;
  160.             end; {with FirstInQueue}
  161.  
  162.          end; {with entry}
  163.  
  164.       end; {with subtree}
  165.  
  166.    end {create a new entry}
  167.    ELSE {append a list item}
  168.  
  169.    WITH subtree^, entry do
  170.  
  171.    IF Word=Wordvalue then
  172.    begin
  173.       IF lastinQueue^.linenumber <> line then
  174.       begin
  175.          new(nextitem);
  176.  
  177.          WITH Nextitem^ do
  178.          begin
  179.             linenumber := line;
  180.             NextInQueue := nil;
  181.          end;{WITH}
  182.  
  183.          lastinQueue^.NextInQueue := Nextitem;
  184.          lastinQueue := nextitem;
  185.       end;
  186.  
  187.    end (* if *)
  188.  
  189.    ELSE
  190.  
  191.    IF Word < Wordvalue
  192.       then pEnterTree(left,Word,line)
  193.    ELSE
  194.    pEnterTree(right,Word,line);
  195.  
  196. end; {pEnterTree}
  197.  
  198. (*$W2*)
  199.  
  200.  
  201. (*---------------------------*)
  202. (* sub procedure of pGetLine *)
  203.  
  204. procedure pReadChar
  205. ({updating} var nextchar : charinfo; {returning}var currchar : charinfo );
  206.  
  207. var
  208. Look          : char; { Character read in from File }
  209. RKeyModeChar : string1 ;
  210.  
  211. begin  (*+++> File status module. <+++*)
  212.    (* Stores file status "AFTER" a read.
  213.    (* NOTE this play on words - after one char is
  214.    (* actually "PRIOR TO" the next character     *)
  215.    IF xeoln then
  216.    begin
  217.  
  218.       LineInLast := LineIn;
  219.  
  220.       IF (not EOF(fin)) then
  221.       begin
  222.          readln(fin, LineIn);
  223.          cp := 0;
  224.          xeoln := false;
  225.       end
  226.       else
  227.       xeof := true;
  228.    end;
  229.  
  230.    IF cp >= length(LineIn) then
  231.    begin
  232.       xeoln := true;
  233.       xeof  := EOF(fin);
  234.       Look  := ' ';
  235.    end
  236.    else
  237.    begin
  238.       cp := cp + 1;
  239.       Look := LineIn[cp];
  240.    End;
  241.  
  242.    {+++ current operative character module +++}
  243.    currchar := nextchar;
  244.  
  245.    {+++ ClassIFy the character just read +++}
  246.    WITH nextchar
  247.    do
  248.    begin { the Look-ahead character name module }
  249.  
  250.       IF xeof
  251.          then name := FileMark
  252.       ELSE
  253.       IF xeoln
  254.          then name := EndofLine
  255.       ELSE
  256.       IF Look IN ['a'..'z']
  257.          then {lower case plus}
  258.       name := lletter
  259.       ELSE
  260.       IF Look IN ['^','$','y','A'..'Z']
  261.          then {upper case} name := uletter
  262.       ELSE
  263.       IF Look IN ['0'..'9']
  264.          then {digit} name := digit
  265.       ELSE
  266.       IF Look = ''''
  267.          then name := quote
  268.       ELSE
  269.       IF Look = TabChar
  270.          then name := aTabChar
  271.       ELSE
  272.       IF Look = space
  273.          then name := blank
  274.       ELSE
  275.       name := otherchar;
  276.  
  277.       CASE name of{ store character value module } EndofLine,
  278.  
  279.          FileMark:
  280.          Valu := space;
  281.  
  282.          lletter:
  283.          Valu := upcase(look);       { Cnvrt to uppcase }
  284.  
  285.          ELSE
  286.          valu := look;
  287.  
  288.       end { case name of };
  289.  
  290.    End { Look-ahead character name module };
  291.  
  292. end; {of pReadChar}
  293.  
  294.  
  295. (*-----------------------------*)
  296. (* sub procedure of pBuildTree *)
  297.  
  298. procedure pGetLine( var fbuffer : GenStr );
  299.  
  300. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  301. {+      Get a line of text into users buffer.           +}
  302. {+      Flushes comment lines:                          +}
  303. {+      Flushes lines of Literals:  'this is it'        +}
  304. {+      Ignores special characters & Tabs:              +}
  305. {+      Recognizes End of File and End of Line.         +}
  306. {+                                                      +}
  307. {+GLOBAL                                                +}
  308. {+      flushing : (KNOT, DBL, STD, LIT, SCANFN);       +}
  309. {+      LLmax   = 0..Max Line length;                   +}
  310. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  311.  
  312. var
  313. state : (scanning, terminal, overflow);
  314. SawDot : boolean;
  315. GKeyModeChar : string1;
  316.  
  317. begin { pGetLine }
  318.    fbuffer := '';
  319.    fname := '';
  320.    FatalErrorStatus := false;
  321.    state := scanning;
  322.  
  323.    REPEAT
  324.  
  325.       (* CALL *)
  326.       pReadChar(nextchar, currchar);
  327.  
  328.       IF (length(fbuffer) >= LLmax) then { exceeded length of buffer }
  329.       begin{ reset EOLN }
  330.          FatalErrorStatus := true;
  331.          state := overflow;
  332.          fbuffer := '';
  333.          write(bell);
  334.          writeln('EXCEEDED LENGTH OF INPUT BUFFER');
  335.       end
  336.  
  337.       ELSE
  338.       begin
  339.  
  340.          IF (currchar.name IN [FileMark,EndofLine])
  341.             then state:=terminal { end of line or end of file };
  342.  
  343.          CASE flushing of
  344.  
  345.             KNOT:
  346.             CASE currchar.name of
  347.  
  348.                lletter, uletter, digit, blank:
  349.                begin{ store }
  350.                   fbuffer := concat(FBUFFER,CURRCHAR.VALU) ;
  351.                end;
  352.  
  353.                aTabChar, quote, otherchar:
  354.                begin{   Flush comments -convert
  355.                   TabChars & other chars to spaces }
  356.                   IF (currchar.valu='(')
  357.                      and (nextchar.valu='*')
  358.                      then flushing := DBL
  359.                   ELSE
  360.                   IF (currchar.valu='{')
  361.                      then flushing := STD
  362.                   ELSE
  363.                   IF currchar.name=quote
  364.                      then flushing := LIT;
  365.                   { convert to a space }
  366.                   fbuffer := concat(fbuffer,GapChar);
  367.                end;
  368.  
  369.                ELSE  { end of line -or- file mark }
  370.                fbuffer := concat(fbuffer,currchar.valu)
  371.  
  372.             end{ case currchar name of };
  373.  
  374.             DBL:
  375.             { scanning for a closing  - double comment }
  376.             IF (currchar.valu ='*')
  377.                and (nextchar.valu =')')
  378.                then flushing := KNOT;
  379.  
  380.             STD:
  381.             begin { scanning for a closing curley  }
  382.                IF currchar.valu = '}'
  383.                   then flushing := KNOT;
  384.                { Check IF incl }
  385.                IF (currchar.valu = '$')
  386.                   and (nextchar.valu = 'I')
  387.                   then flushing := SCANFN;
  388.             end;
  389.  
  390.             LIT:  { scanning for a closing quote }
  391.             IF currchar.name = quote
  392.                then flushing := KNOT;
  393.  
  394.             SCANFN:
  395.             IF (nextchar.valu<>' ')
  396.                and (nextchar.valu<>TabChar) then
  397.             begin
  398.                flushing := SCANFN2;
  399.                SawDot := false;
  400.             end;
  401.  
  402.             SCANFN2:
  403.             IF (currchar.valu in ['A'..'Z','0'..'9','.']) then
  404.             begin
  405.                fname := concat(fname, currchar.valu);
  406.                IF currchar.valu = '.'
  407.                   then SawDot := true;
  408.             end
  409.             ELSE
  410.             begin
  411.                IF length(fname) = 0
  412.                   then { Make sure we ignore $I-}
  413.                doInclude := false { compiler directive }
  414.                else
  415.                begin
  416.                   IF not SawDot
  417.                      then fname := Concat(fname, '.PAS');
  418.                   doInclude := true;
  419.                end;
  420.                flushing := STD;
  421.  
  422.             end;
  423.  
  424.          end { flushing case }
  425.  
  426.       end { ELSE }
  427.  
  428.    UNTIL (state<>scanning);
  429.  
  430. end; {of pGetLine}
  431.  
  432.  
  433.  
  434. (*-----------------------------*)
  435. (* sub procedure of pBuildTree *)
  436.  
  437. procedure pReadWord( RWkeyModeChar : string1 );
  438.  
  439. {++++++++++++++++++++++++++++++++++++++++++++++++}
  440. {+                                              +}
  441. {+       Analyze the Line into "words"          +}
  442. {+                                              +}
  443. {++++++++++++++++++++++++++++++++++++++++++++++++}
  444.  
  445. LABEL   1;
  446.  
  447. var
  448. ix,              {temp indexer}
  449. idlen,           {length of the word}
  450. Cpos : BYTE;     { Current Position pointer }
  451. FindInReserve : boolean; (* logic for Search *)
  452.  
  453. begin{ pReadWord }
  454.    Cpos := 1; { start at the beginning of a line }
  455.  
  456.    WHILE Cpos < length(fbuffer) do
  457.    begin {Cpos<length(fbuffer)}
  458.  
  459.       WHILE (Cpos < length(fbuffer))
  460.          and (fbuffer[Cpos]=space)
  461.       do
  462.       Cpos:=Cpos + 1;    {--- skip spaces ---}
  463.       idlen := 0;
  464.  
  465.       WHILE (Cpos < length(fbuffer))
  466.          and (fbuffer[Cpos ] <> space)
  467.       do
  468.       begin{ accept only non-spaces }
  469.          IF idlen < MaxWordlen then
  470.          begin
  471.             idlen := idlen + 1;
  472.             CurrentWord[idlen] := fbuffer[Cpos];
  473.          end;
  474.          Cpos := Cpos +1;
  475.       end { WHILE };
  476.  
  477.       CurrentWord[0] := chr(idlen);
  478.  
  479.       IF length(CurrentWord)=0 (* no word was found *)
  480.          then GOTO 1; (* label *)
  481.  
  482.       (* function binary search for CurrentWord *)
  483.       (* returns logic FindInReserve for CurrentWord *)
  484.       (* uses    string1 IKeyModeChar during search *)
  485.  
  486.       pFindInReserve
  487.       ( CurrentWord, FindInReserve, RWkeyModeChar );
  488.  
  489.       IF ( not FindInReserve)
  490.          and (not (CurrentWord[1] in ['0'..'9'])) (* not num.const *)
  491.       then
  492.       begin
  493.  
  494.          (* Glen Ellis utility tracer *)
  495.          IF XrefTrace then write(currentword,':'); (**)
  496.  
  497.          (* Required by program ! *)
  498.          pEnterTree(tree,CurrentWord,Currentline);
  499.  
  500.       end;
  501.  
  502.       1: (* label *)
  503.       {Here is no word <length of word=0>};
  504.  
  505.    end; { WHILE Cpos<length(fbuffer) }
  506.  
  507. end; { of pReadWord }
  508.  
  509.  
  510.  
  511. (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  512. (*                                                                    *)
  513. (*  Primary procedure     >>   BuildTree    <<                        *)
  514. (*                                                                    *)
  515. (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
  516.  
  517. begin      (* primary procedure BuildTree *)
  518.  
  519.  
  520.    flushing := KNOT { flushing } ;
  521.  
  522.    doInclude := false;
  523.    xeoln := true;
  524.    xeof  := false;
  525.    LineIn := '';
  526.  
  527.    ASSIGN(fin,InFile);
  528.    RESET(fin);
  529.  
  530.    IF IOresult <> 0 then
  531.    begin
  532.       write(BELL);
  533.       writeln('File ',InFile,' not found !!!!!!');
  534.       FatalErrorStatus := true;
  535.    end;
  536.  
  537.    nextchar.name := blank;       { Initialize next char to a space }
  538.    nextchar.valu := space;
  539.  
  540.    pReadChar
  541.    ({update} nextchar, { Initialize current char to space }
  542.    {returning} currchar);
  543.    { First char from file in nextchar }
  544.  
  545.    write ('.');
  546.  
  547.    WHILE ((currchar.name<>filemark)
  548.       and (not FatalErrorStatus))
  549.    do
  550.    begin
  551.  
  552.       Currentline := Currentline + 1;
  553.  
  554.       pGetLine(fbuffer);  (* Attempt to Read the First Line *)
  555.  
  556.       (* currentline:4 will be truncated at 9,999 lines *)
  557.       writeln(Fout, Currentline,': ',LineInLast); (**)
  558.  
  559.       IF listing
  560.          then
  561.       begin;
  562.          writeln; (**) (* closes print line of new xref words *)
  563.          writeln(Currentline,': ',LineInLast);
  564.       end
  565.       else
  566.       begin
  567.          IF (CurrentLine mod 50) = 0
  568.             then writeln(' ',Currentline:0,' lines read');
  569.          write ('.');
  570.       end;
  571.  
  572.       (* else IF (Currentline mod 100) = 0 then *)
  573.       (* writeln('ON LINE : ',Currentline:0);   *)
  574.  
  575.       pReadWord(BTkeyModeChar);
  576.       (* Analyze the Text into single 'words' *)
  577.  
  578.       IF doInclude then
  579.       begin
  580.          pBuildTree(tree, fname, BTkeyModeChar);
  581.          (* recursively do include *)
  582.          doInclude := false;
  583.       end;
  584.  
  585.    end; {While}
  586.  
  587.    close(fin);
  588.    writeln (' ',Currentline:0,' total lines read');
  589.  
  590. end; { of pBuildTree }    { CLOSE(PRNyID); }
  591.  
  592. (*----------------------------------------------------------------------*)
  593.