home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / client_list.e < prev    next >
Text File  |  1999-06-05  |  7KB  |  257 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://SmallEiffel.loria.fr
  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 CLIENT_LIST
  17.    --
  18.    -- To store a list of clients class like : {FOO,BAR}
  19.    --
  20.  
  21. inherit GLOBALS;
  22.  
  23. creation make, omitted, merge
  24.  
  25. feature
  26.  
  27.    start_position: POSITION;
  28.          -- Of the the opening bracket when list is really written.
  29.  
  30. feature {CLIENT_LIST}
  31.  
  32.    list: CLASS_NAME_LIST;
  33.  
  34. feature {NONE}
  35.  
  36.    make(sp: like start_position; l: like list) is
  37.          -- When the client list is really written.
  38.          --
  39.          -- Note : {NONE} has the same meaning as {}.
  40.       require
  41.          sp /= Void
  42.       do
  43.          start_position := sp;
  44.          list := l;
  45.       ensure
  46.          start_position = sp;
  47.          list = l
  48.       end;
  49.  
  50.    omitted is
  51.          -- When the client list is omitted.
  52.          --
  53.          -- Note : it has the same meaning as {ANY}.
  54.       do
  55.       end;
  56.  
  57.    merge(sp: like start_position; l1, l2: like list) is
  58.       require
  59.          sp /= Void
  60.       do
  61.          start_position := sp;
  62.          !!list.merge(l1,l2);
  63.       end;
  64.  
  65. feature
  66.  
  67.    is_omitted: BOOLEAN is
  68.       do
  69.          Result := start_position = Void;
  70.       end;
  71.  
  72.    pretty_print is
  73.       do
  74.          if is_omitted then
  75.             if fmt.zen_mode then
  76.             else
  77.                fmt.put_string("{ANY} ");
  78.             end
  79.          else
  80.             if list = Void then
  81.                if fmt.zen_mode then
  82.                   fmt.put_string("{} ");
  83.                else
  84.                   fmt.put_string("{NONE} ");
  85.                end;
  86.             else
  87.                fmt.put_character('{');
  88.                fmt.set_indent_level(2);
  89.                list.pretty_print;
  90.                fmt.put_character('}');
  91.                fmt.put_character(' ');
  92.             end;
  93.          end;
  94.       end;
  95.  
  96.    gives_permission_to(cn: CLASS_NAME): BOOLEAN is
  97.          -- True if the client list give permission to `cn'.
  98.          -- When false, `eh' is preloaded with beginning of
  99.          -- error message.
  100.       require
  101.          cn /= Void
  102.       do
  103.          if is_omitted then
  104.             -- It is as {ANY} :
  105.             Result := true;
  106.          elseif list = Void then
  107.             -- Because it is as : {NONE}.
  108.          else
  109.             Result := list.gives_permission_to(cn);
  110.          end;
  111.          gives_permission_error(Result,cn.to_string);
  112.       end;
  113.  
  114. feature {EXPORT_LIST}
  115.  
  116.    merge_with(other: like Current): like current is
  117.       require
  118.          other /= Void
  119.       local
  120.          sp: POSITION;
  121.       do
  122.          if gives_permission_to_any then
  123.             Result := Current;
  124.          elseif other.gives_permission_to_any then
  125.             Result := other;
  126.          else
  127.             sp := start_position;
  128.             if sp = Void then
  129.                sp := other.start_position;
  130.             end;
  131.             !!Result.merge(sp,list,other.list);
  132.          end;
  133.       end;
  134.  
  135. feature {PARENT_LIST}
  136.  
  137.    append(other: like Current): like Current is
  138.       require
  139.          other /= Void
  140.       do
  141.          if Current = other or else is_omitted then
  142.             Result := Current;
  143.          else
  144.             if gives_permission_to_any then
  145.                Result := Current;
  146.             else
  147.                eh.cancel;
  148.                if other.is_omitted then
  149.                   Result := other;
  150.                elseif other.gives_permission_to_any then
  151.                   Result := other;
  152.                else
  153.                   eh.cancel;
  154.                   !!Result.merge(start_position,list,other.list);
  155.                end;
  156.             end;
  157.          end;
  158.       end;
  159.  
  160. feature
  161.  
  162.    gives_permission_to_any: BOOLEAN is
  163.       do
  164.          if is_omitted then
  165.             Result := true;
  166.             -- Because it is as : {ANY}.
  167.          elseif list = Void then
  168.             -- Because it is as : {NONE}.
  169.          else
  170.             Result := list.gives_permission_to_any;
  171.          end;
  172.          gives_permission_error(Result,as_any);
  173.       end;
  174.  
  175. feature {RUN_FEATURE}
  176.  
  177.    vape_check(call_site: POSITION; other: like Current) is
  178.          -- To enforce VAPE, all clients of Current object must
  179.          -- be allowed by `other'.
  180.       require
  181.          run_control.require_check;
  182.          other /= Void
  183.       local
  184.          vape: BOOLEAN;
  185.          i: INTEGER;
  186.          caller: RUN_FEATURE;
  187.          cn: CLASS_NAME;
  188.       do
  189.          if is_omitted then
  190.             -- It is as {ANY}
  191.             vape := other.gives_permission_to_any;
  192.          elseif list = Void then
  193.             -- It is {NONE}
  194.             vape := true;
  195.             eh.cancel;
  196.          else
  197.             from
  198.                vape := true;
  199.                i := list.count;
  200.             until
  201.                not vape or else i = 0
  202.             loop
  203.                cn := list.item(i);
  204.                vape := other.gives_permission_to(cn);
  205.                i := i - 1;
  206.             end;
  207.          end;
  208.          if not vape then
  209.             if cn /= Void then
  210.                eh.add_position(cn.start_position);
  211.             else
  212.                eh.add_position(start_position);
  213.             end;
  214.             eh.add_position(call_site);
  215.             eh.append("Invalid require assertion (VAPE).");
  216.             eh.print_as_error;
  217.             eh.add_position(call_site);
  218.             eh.add_position(other.start_position);
  219.             caller := small_eiffel.top_rf;
  220.             eh.append(caller.current_type.run_time_mark);
  221.             eh.append(" is the validation-context of the call. %
  222.                       %This feature cannot be called in this %
  223.                       %require clause (VAPE).");
  224.             eh.print_as_error;
  225.             eh.append("VAPE error in require clause of ");
  226.             if cn /= Void then
  227.                eh.add_position(cn.start_position);
  228.             else
  229.                eh.add_position(start_position);
  230.             end;
  231.             eh.add_position(caller.start_position);
  232.             eh.append(caller.name.to_string);
  233.             eh.print_as_fatal_error;
  234.          end;
  235.       end;
  236.  
  237. feature {NONE}
  238.  
  239.    gives_permission_error(no_error: BOOLEAN; cn: STRING) is
  240.       do
  241.          if no_error then
  242.             eh.cancel;
  243.          else
  244.             if start_position = Void then
  245.                if list /= Void then
  246.                   eh.add_position(list.item(1).start_position);
  247.                end;
  248.             else
  249.                eh.add_position(start_position);
  250.             end;
  251.             eh.append(cn);
  252.             eh.append(" is not allowed to use this feature. ");
  253.          end;
  254.       end;
  255.  
  256. end -- CLIENT_LIST
  257.