home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / TURBOPAS / PH.ZIP / PH.PAS
Encoding:
Pascal/Delphi Source File  |  1985-12-28  |  8.2 KB  |  395 lines

  1. (*
  2.  * pheir - generate pascal heirarchy listing from
  3.  *         output of pcrf utility
  4.  *
  5.  * shs 23-aug-85
  6.  *
  7.  * usage:  pcrf SOURCE | pheir >OUTPUT
  8.  *
  9.  *)
  10.  
  11. {$g1024,p128,d-,c-}
  12.  
  13. const
  14.  
  15.    linelen =      100;
  16.    maxlines =     2000;
  17.  
  18. type
  19.    def_type =     (defined,
  20.                    referenced);
  21.  
  22.    anystring =    string [linelen];
  23.  
  24.    def_ptr =      ^def_rec;
  25.    ref_ptr =      ^ref_rec;
  26.  
  27.    def_rec =      record
  28.          first_ref:     ref_ptr;
  29.          def_ident:     string [41];
  30.          stat:          def_type;
  31.          next:          def_ptr;
  32.    end;
  33.  
  34.    ref_rec =      record
  35.          ref_def_ptr:   def_ptr;
  36.          next:          ref_ptr;
  37.    end;
  38.  
  39. var
  40.    first_def:     def_ptr;
  41.    maxlevel:      integer;    {number of levels to show in the heirarchy}
  42.    nomore:        boolean;
  43.  
  44.  
  45.  
  46. function trim (s:             anystring): anystring;
  47.    var
  48.       ident:         anystring;
  49.  
  50.    begin
  51.       ident := s;
  52.  
  53.       while ident [length (ident)]= ' ' do
  54.          ident := copy (ident, 1, length (ident)- 1);
  55.  
  56.       trim := ident;
  57.    end;
  58.  
  59.  
  60. function stoupper (s:  anystring): anystring;
  61.    var
  62.       u:  anystring;
  63.       i:  integer;
  64.    begin
  65.       u := s;
  66.       for i := 1 to length(s) do
  67.          u[i] := upcase(s[i]);
  68.       stoupper := u;
  69.    end;
  70.  
  71.  
  72.  
  73. procedure new_definition (var cur_def:   def_ptr;
  74.                           ident:         anystring;
  75.                           new_stat:      def_type);
  76.    var
  77.       definition:    def_ptr;
  78.       new_def:       def_ptr;
  79.       prev_def:      def_ptr;
  80.       c:             char;
  81.  
  82.    begin
  83.  
  84.       if keypressed then
  85.       begin
  86.          read(kbd,c);
  87.          if c = ^C then
  88.          begin
  89.             writeln(con,'** ^C');
  90.             halt;
  91.          end;
  92.       end;
  93.  
  94.  
  95. (* search for the desired proc *)
  96.  
  97.       definition := first_def;
  98.       prev_def := nil;
  99.  
  100.       while (definition <> nil) do
  101.       begin
  102.  
  103.          if definition^.def_ident = ident then
  104.          begin
  105.  
  106.             if new_stat = defined then
  107.                definition^.stat := new_stat;
  108.  
  109.             cur_def := definition;         {make it the current one if found}
  110.             exit;
  111.          end;
  112.  
  113.          if (definition^.next = nil) or
  114.             (stoupper(definition^.def_ident) > stoupper(ident)) then
  115.  
  116.          begin
  117.             new(new_def);              {insert a new one in sorted position}
  118.  
  119.  
  120.             if prev_def = nil then
  121.             begin
  122.                new_def^.next := first_def;
  123.                first_def := new_def;
  124.             end
  125.             else
  126.             begin
  127.                prev_def^.next := new_def;
  128.                new_def^.next := definition;
  129.             end;
  130.  
  131.             new_def^.def_ident := ident;
  132.             new_def^.first_ref := nil;
  133.             new_def^.stat := new_stat;
  134.             cur_def := new_def;
  135.             exit;
  136.          end;
  137.  
  138.          prev_def := definition;
  139.          definition := definition^.next;
  140.       end;
  141.    end;
  142.  
  143.  
  144. procedure new_reference (var cur_def:   def_ptr;
  145.                          ident:         anystring);
  146.    var
  147.       new_ref:       ref_ptr;
  148.       reference:     ref_ptr;
  149.       prev_ref:      ref_ptr;
  150.       definition:    def_ptr;
  151.  
  152.    begin
  153.  
  154.  
  155. (* create a new procedure for this reference if needed *)
  156.       new_definition(definition, ident, referenced);
  157.  
  158.  
  159. (* search for a matching reference node -
  160.    nothing to do if already referenced *)
  161.  
  162.       reference := cur_def^.first_ref;
  163.       prev_ref := nil;
  164.  
  165.       while reference <> nil do
  166.       begin
  167.  
  168.          if reference^.ref_def_ptr^.def_ident = ident then
  169.             exit;
  170.  
  171.          if stoupper(reference^.ref_def_ptr^.def_ident) > stoupper(ident) then
  172.          begin
  173.             new(new_ref);
  174.  
  175.             if prev_ref = nil then
  176.             begin
  177.                new_ref^.next := reference;
  178.                cur_def^.first_ref := new_ref;
  179.             end
  180.             else
  181.             begin
  182.                new_ref^.next := prev_ref^.next;
  183.                prev_ref^.next := new_ref;
  184.             end;
  185.  
  186.             new_ref^.ref_def_ptr := definition;
  187.             exit;
  188.          end;
  189.  
  190.          prev_ref := reference;
  191.          reference := reference^.next;
  192.       end;
  193.  
  194.       if prev_ref = nil then
  195.       begin
  196.          new(new_ref);
  197.          cur_def^.first_ref := new_ref;
  198.          new_ref^.next := nil;
  199.          new_ref^.ref_def_ptr := definition;
  200.          exit;
  201.       end;
  202.  
  203.       new(new_ref);
  204.       new_ref^.next := prev_ref^.next;
  205.       prev_ref^.next := new_ref;
  206.       new_ref^.ref_def_ptr := definition;
  207.    end;
  208.  
  209.  
  210. procedure build_reftab;
  211.    var
  212.       buf:           anystring;
  213.       cur_def:       def_ptr;
  214.       line:          integer;
  215.  
  216.    begin
  217.       new(first_def);
  218.       cur_def := first_def;
  219.       cur_def^.next := nil;
  220.       cur_def^.first_ref := nil;
  221.       cur_def^.def_ident := '';
  222.       cur_def^.stat := referenced;
  223.       line := 0;
  224.  
  225.       while not eof (input) do
  226.       begin
  227.          readln(input, buf);
  228.          new_definition(cur_def, trim (copy (buf, 41, 40)), defined);
  229.          new_reference(cur_def, trim (copy (buf, 1, 40)));
  230.  
  231.          line := line + 1;
  232.          if (line mod 16) = 1 then
  233.             write(con, #13, line);
  234.       end;
  235.  
  236.       writeln(con, #13, line,' input lines');
  237.    end;
  238.  
  239.  
  240. procedure indent_to(level: integer);
  241.    const
  242.       TAB = ^I;
  243.    var
  244.       i:  integer;
  245.    begin
  246.       for i := 1 to level do
  247.          write(TAB);
  248.    end;
  249.  
  250.  
  251. procedure display_definition_of (definition:    def_ptr;
  252.                    level:         integer);
  253.    var
  254.       reference:     ref_ptr;
  255.       c:             char;
  256.  
  257.    begin
  258.  
  259.       if keypressed then
  260.       begin
  261.          read(kbd,c);
  262.          if c = ^C then
  263.          begin
  264.             writeln(con,'** ^C');
  265.             halt;
  266.          end;
  267.       end;
  268.  
  269.  
  270.       indent_to(level);
  271.       writeln(definition^.def_ident);
  272.  
  273.       if definition^.first_ref = nil then
  274.          exit;
  275.  
  276.       if level < maxlevel then
  277.       begin
  278.          reference := definition^.first_ref;
  279.  
  280.          while reference <> nil do
  281.          begin
  282.  
  283.             if reference^.ref_def_ptr <> definition then
  284.                display_definition_of(reference^.ref_def_ptr, level + 1);
  285.  
  286.             reference := reference^.next;
  287.          end;
  288.       end
  289.       else
  290.  
  291.       if nomore = false then
  292.       begin
  293.  
  294.          indent_to(level);
  295.          writeln('   --(more)');
  296.       end;
  297.    end;
  298.  
  299.  
  300. procedure walk_procs;
  301.    var
  302.       definition:    def_ptr;
  303.  
  304.    begin
  305.       definition := first_def;
  306.  
  307.       while definition <> nil do
  308.       begin
  309.  
  310.          if definition^.stat = defined then
  311.          begin
  312.             writeln('---------------------------------------------');
  313.             display_definition_of(definition, 0);
  314.             writeln;
  315.          end;
  316.  
  317.          definition := definition^.next;
  318.       end;
  319.  
  320.       writeln('---------------------------------------------');
  321.       writeln(' External symbols:');
  322.       definition := first_def;
  323.  
  324.       while definition <> nil do
  325.       begin
  326.  
  327.          if definition^.stat = referenced then
  328.             display_definition_of(definition, 1);
  329.  
  330.          definition := definition^.next;
  331.       end;
  332.    end;
  333.  
  334.  
  335. function atoi(s: anystring): integer;
  336. var
  337.    i:  integer;
  338.    v:  integer;
  339.  
  340. begin
  341.    v := 0;
  342.    for i := 1 to length(s) do
  343.    begin
  344.       if s[i] in ['0'..'9'] then
  345.          v := v * 10 + ord(s[i]) - ord('0')
  346.       else
  347.       begin
  348.          writeln(con,'Invalid number: ',s);
  349.          halt;
  350.       end;
  351.    end;
  352.  
  353.    atoi := v;
  354. end;
  355.  
  356.  
  357.  
  358.  
  359. var
  360.    i:  integer;
  361.  
  362. begin                         {main}
  363.  
  364.    nomore := false; {default print --more at limit}
  365.    maxlevel := 3;   {default level limit}
  366.  
  367.    i := 1;
  368.    while i <= paramcount do
  369.    begin
  370.       if paramstr(i) = '-nomore' then
  371.          nomore := true
  372.       else
  373.  
  374.       if paramstr(i) = '-limit' then
  375.       begin
  376.          i := i + 1;
  377.          maxlevel := atoi(paramstr(i));
  378.       end
  379.       else
  380.  
  381.       begin
  382.          writeln(con,'Invalid option: ',paramstr(i));
  383.          writeln(con,'Usage: ph [-nomore] [-limit N]  <INFILE >OUTFILE');
  384.          halt;
  385.       end;
  386.  
  387.       i := i + 1;
  388.    end;
  389.  
  390.  
  391.    build_reftab;
  392.    walk_procs;
  393.  
  394. end.
  395.