home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #4 / amigaacscoverdisc1998-041998.iso / utilities / shareware / dev / ppcsmalleiffel / lib_se / position.e < prev    next >
Encoding:
Text File  |  1998-01-16  |  5.7 KB  |  248 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class POSITION
  17. --
  18. -- A position in an Eiffel base class text.
  19. --
  20.    
  21. inherit 
  22.    GLOBALS 
  23.       redefine is_equal, fill_tagged_out_memory 
  24.       end;
  25.    
  26. creation make
  27.    
  28. creation {CLASS_NAME} with
  29.    
  30. feature 
  31.    
  32.    base_class_name: CLASS_NAME;
  33.      -- The corresponding Eiffel text of the position.
  34.  
  35. feature {NONE}
  36.  
  37.    mem_line_column: INTEGER;
  38.      -- Line and Column on a single INTEGER value (column must
  39.      -- less than 999).
  40.  
  41. feature
  42.    
  43.    line: INTEGER is
  44.       do
  45.      Result := mem_line_column // 1000;
  46.       end;
  47.  
  48.    column: INTEGER is
  49.       do
  50.      Result := mem_line_column \\ 1000;
  51.       end;
  52.    
  53. feature {NONE}
  54.    
  55.    with(li, co: INTEGER; bcn: like base_class_name) is
  56.       require
  57.      li >= 1;
  58.      co >= 1;
  59.      bcn /= Void;
  60.       do
  61.      mem_line_column := li * 1000 + co;
  62.      base_class_name := bcn;
  63.       ensure     
  64.      line = li;
  65.      column = co;
  66.      base_class_name = bcn;
  67.       end;
  68.    
  69.    make(li, co: INTEGER) is
  70.       require
  71.      li >= 1;
  72.      co >= 1;
  73.      eiffel_parser.is_running
  74.       do
  75.      mem_line_column := li * 1000 + co;
  76.      base_class_name := eiffel_parser.current_class_name;
  77.       ensure
  78.      line = li;
  79.      column = co;
  80.      base_class_name /= Void
  81.       end;
  82.    
  83. feature    
  84.    
  85.    is_equal(other: like Current): BOOLEAN is
  86.       do
  87.      Result := 
  88.         ((line = other.line) and then
  89.          (column = other.column) and then
  90.          (base_class_name /= Void) and then
  91.          (other.base_class_name /= Void) and then
  92.          (base_class_name.to_string = other.base_class_name.to_string));
  93.       end;
  94.  
  95.    fill_tagged_out_memory is
  96.       do
  97.      line.append_in(tagged_out_memory);
  98.      tagged_out_memory.extend('/');
  99.      column.append_in(tagged_out_memory);
  100.      if path /= Void then
  101.         tagged_out_memory.extend(' ');
  102.         tagged_out_memory.append(path);
  103.      end;
  104.       end;
  105.  
  106.    before(other: like Current): BOOLEAN is
  107.      -- Is current position strictly before `other' (in 
  108.      -- the same base class).
  109.       require
  110.      base_class_name = other.base_class_name
  111.       do
  112.      if line < other.line then
  113.         Result := true;
  114.      elseif line = other.line then
  115.         Result := column < other.column;
  116.      end;
  117.       end;
  118.  
  119.    base_class: BASE_CLASS is
  120.       do
  121.      if eiffel_parser.is_running then
  122.         if base_class_name.to_string.empty then
  123.            fatal_error("Internal Error #1 in POSITION.");
  124.         elseif small_eiffel.is_used(base_class_name.to_string) then
  125.            Result := base_class_name.base_class;
  126.         else
  127.            fatal_error("Internal Error #2 in POSITION.");
  128.         end;
  129.      else
  130.         Result := base_class_name.base_class;
  131.      end;
  132.       end;
  133.    
  134.    path: STRING is
  135.       local
  136.      bcn: STRING;
  137.      bc: BASE_CLASS;
  138.       do
  139.      bcn := base_class_name.to_string;
  140.      if bcn /= Void then
  141.         if small_eiffel.is_used(bcn) then
  142.            bc := base_class_name.base_class;
  143.         elseif eiffel_parser.is_running then
  144.            if eiffel_parser.current_class_name.to_string = bcn then
  145.           bc := eiffel_parser.current_class;
  146.            end;
  147.         else
  148.            bc := base_class_name.base_class;
  149.         end;
  150.         if bc /= Void then
  151.            Result := bc.path; 
  152.         end;
  153.      end;
  154.       end;
  155.    
  156.    show is
  157.       local
  158.      c: INTEGER;
  159.      nb: INTEGER;
  160.      n, str, the_line: STRING;
  161.       do
  162.      n := base_class_name.to_string;
  163.      std_error.put_string("Line ");
  164.      std_error.put_integer(line);
  165.      std_error.put_string(" column ");
  166.      std_error.put_integer(column);
  167.      std_error.put_string(" in ");
  168.      std_error.put_string(n);
  169.      str := path; 
  170.      if str /= Void then
  171.         std_error.put_string(" (");
  172.         std_error.put_string(str);
  173.         std_error.put_character(')');
  174.      end;
  175.      std_error.put_string(" :%N");
  176.      the_line := get_line;
  177.      if the_line /= Void then
  178.         c := column;
  179.         std_error.put_string(the_line);
  180.         std_error.put_new_line;
  181.         from  
  182.            nb := 1;
  183.         until
  184.            nb = c
  185.         loop
  186.            if the_line.item(nb) = '%T' then
  187.           std_error.put_character('%T');
  188.            else
  189.           std_error.put_character(' ');
  190.            end;
  191.            nb := nb + 1;
  192.         end;
  193.         std_error.put_string("^%N");
  194.      else
  195.         std_error.put_string("SmallEiffel cannot load base class : ");
  196.         std_error.put_string(n);
  197.         std_error.put_string("%N");
  198.      end;
  199.       end;
  200.  
  201.    append_in(str: STRING) is
  202.       require
  203.      str /= Void
  204.       do
  205.      str.append("Line ");
  206.      line.append_in(str);
  207.      str.append(" column ");
  208.      column.append_in(str);
  209.      str.append(" in %"");
  210.      str.append(path);
  211.      str.append(fz_03);
  212.       end;
  213.  
  214. feature {EIFFEL_PARSER}
  215.  
  216.    set_line_column(li, co: INTEGER) is
  217.       do
  218.      mem_line_column := li * 1000 + co;
  219.       ensure 
  220.      line = li;
  221.      column = co
  222.       end;
  223.  
  224. feature {NONE}
  225.  
  226.    get_line: STRING is
  227.       local
  228.      p: like path;
  229.      i: INTEGER;
  230.       do
  231.      p := path;
  232.      if p /= Void then
  233.         tmp_file_read.connect_to(p);
  234.         from
  235.         until
  236.            i = line
  237.         loop
  238.            tmp_file_read.read_line;
  239.            i := i + 1;
  240.         end;
  241.         Result := tmp_file_read.last_string;
  242.         tmp_file_read.disconnect;
  243.      end;
  244.       end;
  245.  
  246. end -- POSITION
  247.  
  248.