home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / system_tools.e < prev    next >
Text File  |  1999-06-08  |  42KB  |  1,318 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 SYSTEM_TOOLS
  17.    --
  18.    -- Singleton object to handle system dependant information.
  19.    -- This singleton is shared via the GLOBALS.`system_tools' once function.
  20.    --
  21.    -- Only this object is supposed to handle contents of the `SmallEiffel'
  22.    -- system environment variable.
  23.    --
  24.    -- You may also want to customize this class in order to support a
  25.    -- new operating system (please let us know).
  26.    --
  27.  
  28. inherit GLOBALS;
  29.  
  30. creation make
  31.  
  32. creation {INSTALL} install
  33.  
  34. feature {NONE}
  35.  
  36.    -- Currently handled system list :
  37.    amiga_system:       STRING is "Amiga";
  38.    beos_system:        STRING is "BeOS";
  39.    dos_system:         STRING is "DOS";
  40.    macintosh_system:   STRING is "Macintosh";
  41.    os2_system:         STRING is "OS2";
  42.    unix_system:        STRING is "UNIX";
  43.    vms_system:         STRING is "VMS";
  44.    windows_system:     STRING is "Windows";
  45.  
  46.    -- Currently handled C compiler list :
  47.    gcc:                STRING is "gcc";
  48.    lcc_win32:          STRING is "lcc-win32";
  49.    cc:                 STRING is "cc";
  50.    wcl386:             STRING is "wcl386";
  51.    bcc32:              STRING is "bcc32";
  52.    bcc32i:             STRING is "bcc32i";
  53.    cl:                 STRING is "cl";
  54.    sas_c:              STRING is "sc";
  55.  
  56. feature {INSTALL}
  57.  
  58.    system_list: ARRAY[STRING] is
  59.       once
  60.          Result := << amiga_system,
  61.                       beos_system,
  62.                       dos_system,
  63.                       macintosh_system,
  64.                       os2_system,
  65.                       unix_system,
  66.                       vms_system,
  67.                       windows_system
  68.                       >>;
  69.       end;
  70.  
  71.    compiler_list: ARRAY[STRING] is
  72.       once
  73.          Result := <<gcc, lcc_win32, cc, wcl386, bcc32, bcc32i, cl, sas_c>>;
  74.       end;
  75.  
  76. feature {INSTALL}
  77.  
  78.    system_name: STRING;
  79.  
  80.    sys_directory: STRING;
  81.          -- The SmallEiffel/sys directory computed with the value of
  82.          -- the environment variable `SmallEiffel'.
  83.          -- For example, under UNIX: "/usr/lib/SmallEiffel/sys/"
  84.  
  85.    bin_directory: STRING;
  86.          -- For example, under UNIX: "/usr/lib/SmallEiffel/bin/"
  87.  
  88. feature {NONE}
  89.  
  90.    install is
  91.       do
  92.       end;
  93.  
  94. feature {INSTALL}
  95.  
  96.    make is
  97.       local
  98.          system_se_path: STRING;
  99.          i: INTEGER;
  100.       do
  101.          system_se_path := get_environment_variable(fz_se);
  102.          if system_se_path = Void then
  103.             system_se_path := fz_se.twin;
  104.             system_se_path.to_upper;
  105.             system_se_path := get_environment_variable(system_se_path);
  106.             if system_se_path = Void then
  107.                echo.put_string(
  108.                   "System environment variable %"SmallEiffel%" not set.%N%
  109.                   %Trying default value: %"");
  110.                system_se_path := "/usr/lib/SmallEiffel/sys/system.se";
  111.                echo.put_string(system_se_path);
  112.                echo.put_string(fz_03);
  113.             end;
  114.          end;
  115.          if system_se_path.has_suffix(fz_system_se) then
  116.             echo.sfr_connect(tmp_file_read,system_se_path);
  117.          else
  118.             echo.put_string(
  119.                "You should update the value of the %"SmallEiffel%" %
  120.                %system environment variable.%N%
  121.                %Since release -0.79, the %"SmallEiffel%" system %
  122.                %environment variable must be the absolute path of %
  123.                %the %"system.se%" file.%N%
  124.                %For example %"/usr/lib/SmallEiffel/sys/system.se%" %
  125.                %under Unix like system.%N");
  126.             if system_se_path.has('/') then
  127.                echo.put_string("%"Hope this is a Unix like system.%N");
  128.                tmp_path.copy(system_se_path);
  129.                tmp_path.set_last('/');
  130.                tmp_path.append(fz_sys);
  131.                tmp_path.extend('/');
  132.                tmp_path.append(fz_system_se);
  133.                echo.sfr_connect(tmp_file_read,tmp_path);
  134.             end;
  135.             if not tmp_file_read.is_connected then
  136.                if system_se_path.has('\') then
  137.                   echo.put_string("%"Hope this is a DOS or Windows like system.%N");
  138.                   tmp_path.copy(system_se_path);
  139.                   tmp_path.set_last('\');
  140.                   tmp_path.append(fz_sys);
  141.                   tmp_path.extend('\');
  142.                   tmp_path.append(fz_system_se);
  143.                   echo.sfr_connect(tmp_file_read,tmp_path);
  144.                end;
  145.             end;
  146.             if not tmp_file_read.is_connected then
  147.                if system_se_path.has(':') then
  148.                   echo.put_string("%"Hope this is a Macintosh like system.%N");
  149.                   tmp_path.copy(system_se_path);
  150.                   tmp_path.set_last(':');
  151.                   tmp_path.append(fz_sys);
  152.                   tmp_path.extend(':');
  153.                   tmp_path.append(fz_system_se);
  154.                   echo.sfr_connect(tmp_file_read,tmp_path);
  155.                end;
  156.             end;
  157.             if not tmp_file_read.is_connected then
  158.                if system_se_path.has(']') then
  159.                   echo.put_string("%"Hope this is a VMS system.%N");
  160.                   tmp_path.copy(system_se_path);
  161.                   tmp_path.set_last(']');
  162.                   tmp_path.remove_last(1);
  163.                   tmp_path.extend('.');
  164.                   tmp_path.append(fz_sys);
  165.                   tmp_path.extend(']');
  166.                   tmp_path.append(fz_system_se);
  167.                   echo.sfr_connect(tmp_file_read,tmp_path);
  168.                end;
  169.             end;
  170.             if not tmp_file_read.is_connected then
  171.                echo.put_string("%"Last chance.%N");
  172.                tmp_path.copy(system_se_path);
  173.                tmp_path.append(fz_system_se);
  174.                echo.sfr_connect(tmp_file_read,tmp_path);
  175.             end;
  176.          end;
  177.          if not tmp_file_read.is_connected then
  178.             echo.w_put_string(
  179.                "Unable to find file %"system.se%".%N%
  180.                %Please, set the environment variable %"SmallEiffel%" %
  181.                %with the appropriate absolute path to this file.%N%
  182.                %Example for Unix: %"/usr/lib/SmallEiffel/sys/system.se%"%N%
  183.                %Example for DOS/Windows: %"C:\SmallEiffel\sys\system.se%"%N");
  184.             die_with_code(exit_failure_code);
  185.          end;
  186.          tmp_file_read.read_line;
  187.          system_name := tmp_file_read.last_string;
  188.          i := system_list.index_of(system_name);
  189.          if i > system_list.upper then
  190.             echo.w_put_string("Unknown system name in file%N%"");
  191.             echo.w_put_string(tmp_file_read.path);
  192.             echo.w_put_string("%".%NCurrently handled system names :%N");
  193.             from
  194.                i := 1;
  195.             until
  196.                i > system_list.upper
  197.             loop
  198.                echo.w_put_string(system_list.item(i));
  199.                echo.w_put_character('%N');
  200.                i := i + 1;
  201.             end;
  202.             die_with_code(exit_failure_code);
  203.          else
  204.             system_name := system_list.item(i);
  205.             echo.put_string("System is %"");
  206.             echo.put_string(system_name);
  207.             echo.put_string(fz_b0);
  208.          end;
  209.          sys_directory := tmp_file_read.path.twin;
  210.          sys_directory.remove_suffix(fz_system_se);
  211.          tmp_file_read.disconnect;
  212.          bin_directory := sys_directory.twin;
  213.          parent_directory(bin_directory);
  214.          add_directory(bin_directory,fz_bin);
  215.       end;
  216.  
  217. feature {COMPILE}
  218.  
  219.    command_path_in(command, command_name: STRING) is
  220.          -- Append in `command' the correct path for `command_name'.
  221.       do
  222.          if windows_system /= system_name then
  223.             command.append(bin_directory);
  224.          end;
  225.          command.append(command_name);
  226.          command.append(x_suffix);
  227.       end;
  228.  
  229.    cygnus_bug(make_file: STD_FILE_READ; make_script_name: STRING) is
  230.          -- Because of a bug in cygnus on windows 95/NT.
  231.       local
  232.          time_out: INTEGER;
  233.       do
  234.          make_file.connect_to(make_script_name);
  235.          if c_compiler = gcc then
  236.             if system_name = windows_system then
  237.                time_out := 2000;
  238.             elseif system_name = dos_system then
  239.                time_out := 2000;
  240.             end;
  241.          end;
  242.          from
  243.             time_out := 2000;
  244.          until
  245.             time_out = 0 or else make_file.is_connected
  246.          loop
  247.             make_file.connect_to(make_script_name);
  248.             time_out := time_out - 1;
  249.          end;
  250.  
  251.       end;
  252.  
  253. feature {COMPILE,CLEAN}
  254.  
  255.    remove_make_script: STRING is
  256.          -- Compute the corresponding make file script name and remove
  257.          -- the old one if any.
  258.       do
  259.          Result := path_h;
  260.          Result.remove_suffix(h_suffix);
  261.          if c_compiler = sas_c then
  262.             Result.append(lnk_suffix);
  263.             echo.file_removing(Result);
  264.             Result.remove_suffix(lnk_suffix);
  265.          end;
  266.          Result.append(make_suffix);
  267.          echo.file_removing(Result);
  268.       end;
  269.  
  270. feature {SMALL_EIFFEL}
  271.  
  272.    read_loading_path_in(lp: ARRAY[STRING]) is
  273.       do
  274.          loading_path_add(lp,fz_loadpath_se,1);
  275.          tmp_path.copy(sys_directory);
  276.          tmp_path.append("loadpath.");
  277.          tmp_path.append(system_name);
  278.          loading_path_add(lp,tmp_path,1);
  279.       end;
  280.  
  281.    append_lp_in(str: STRING; lp: ARRAY[STRING]) is
  282.       local
  283.          i: INTEGER;
  284.          sed: STRING;
  285.       do
  286.          str.append("%NLoading path is:%N[%N");
  287.          from
  288.             i := lp.lower;
  289.          until
  290.             i > lp.upper
  291.          loop
  292.             str.extend(' ');
  293.             str.extend('%"');
  294.             str.append(lp.item(i));
  295.             str.extend('%"');
  296.             str.extend('%N');
  297.             i := i + 1;
  298.          end;
  299.          str.append("]%NEnvironment Variable %"SmallEiffel%" is:%N");
  300.          sed := get_environment_variable(fz_se);
  301.          if sed = Void then
  302.             str.append("not set.%N");
  303.          else
  304.             str.append(" %"");
  305.             str.append(sed);
  306.             str.append("%".%N");
  307.          end;
  308.       end;
  309.  
  310. feature {GC_HANDLER}
  311.  
  312.    put_mark_stack_and_registers is
  313.          -- Add customized assembly code to mark registers.
  314.       local
  315.          architecture: STRING;
  316.       do
  317.          tmp_path.copy(sys_directory);
  318.          tmp_path.append(fz_gc);
  319.          echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  320.          architecture := echo.read_word_in(tmp_file_read);
  321.          tmp_file_read.disconnect;
  322.          if as_none.is_equal(architecture) then
  323.             eh.append(
  324.                "Assembly Code for Garbage Collector not selected in %"");
  325.             eh.append(tmp_path);
  326.             eh.append(
  327.                "%". Default generic (hazardous) C code is provided.");
  328.             eh.print_as_warning;
  329.             architecture := "generic.c";
  330.          end;
  331.          tmp_path.copy(sys_directory);
  332.          add_directory(tmp_path,fz_gc_lib);
  333.          tmp_path.append(architecture);
  334.          echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  335.          cpp.put_c_file(tmp_file_read);
  336.       end;
  337.  
  338. feature {SHORT_PRINT}
  339.  
  340.    format_directory(format: STRING): STRING is
  341.       require
  342.          format /= Void
  343.       do
  344.          !!Result.make(sys_directory.count + 10);
  345.          Result.copy(sys_directory);
  346.          parent_directory(Result);
  347.          add_directory(Result,"short");
  348.          add_directory(Result,format);
  349.       end;
  350.  
  351. feature
  352.  
  353.    bad_use_exit(command_name: STRING) is
  354.       require
  355.          command_name /= Void
  356.       do
  357.          echo.w_put_string("Bad use of command `");
  358.          echo.w_put_string(command_name);
  359.          echo.w_put_string("'.%N");
  360.          tmp_path.copy(sys_directory);
  361.          parent_directory(tmp_path);
  362.          add_directory(tmp_path,"man");
  363.          tmp_path.append(command_name);
  364.          tmp_path.append(help_suffix);
  365.          echo.w_put_string("See documentation in file:%N   ");
  366.          echo.w_put_string(tmp_path);
  367.          echo.w_put_character('%N');
  368.          die_with_code(exit_failure_code);
  369.       end;
  370.  
  371. feature {JVM}
  372.  
  373.    class_file_path(path, directory, class_file_name: STRING) is
  374.          -- Prepare `path' using `directory' and `class_file_name'.
  375.       do
  376.          path.clear;
  377.          if vms_system = system_name then
  378.             if directory.first /= '[' then
  379.                path.extend('[');
  380.             end;
  381.          end;
  382.          path.append(directory);
  383.          if slash_separator then
  384.             path.set_last('/');
  385.          elseif backslash_separator then
  386.             path.set_last('\');
  387.          elseif macintosh_system = system_name then
  388.             path.set_last(':');
  389.          elseif amiga_system = system_name then
  390.             path.set_last('/');
  391.          elseif vms_system = system_name then
  392.             path.set_last(']');
  393.          end;
  394.          path.append(class_file_name);
  395.          path.append(class_suffix);
  396.       end;
  397.  
  398. feature
  399.  
  400.    make_suffix: STRING is
  401.       -- Suffix for make file produced by `compile_to_c'.
  402.       once
  403.          if dos_system = system_name then
  404.             Result := ".BAT";
  405.          elseif windows_system = system_name then
  406.             Result := ".bat";
  407.          elseif vms_system = system_name then
  408.             Result := ".COM";
  409.          elseif os2_system = system_name then
  410.             Result := ".CMD";
  411.          else
  412.             Result := ".make";
  413.          end;
  414.       end;
  415.  
  416.    x_suffix: STRING is
  417.          -- Executable files suffix.
  418.       once
  419.          if dos_system = system_name then
  420.             Result := exe_suffix;
  421.             Result.to_upper;
  422.          elseif vms_system = system_name then
  423.             Result := exe_suffix;
  424.             Result.to_upper;
  425.          elseif os2_system = system_name then
  426.             Result := exe_suffix;
  427.          elseif windows_system = system_name then
  428.             Result := exe_suffix;
  429.          else
  430.             Result := "";
  431.          end;
  432.       ensure
  433.          Result /= Void
  434.       end;
  435.  
  436.    object_suffix: STRING is
  437.          -- Of object File produced by the C Compiler.
  438.       once
  439.          if c_compiler = gcc then
  440.             Result := o_suffix;
  441.          elseif c_compiler = lcc_win32 then
  442.             Result := obj_suffix;
  443.          elseif c_compiler = cc then
  444.             if system_name = vms_system then
  445.                Result := obj_suffix;
  446.                Result.to_upper;
  447.             else
  448.                Result := o_suffix;
  449.             end;
  450.          elseif c_compiler = wcl386 then
  451.             Result := obj_suffix;
  452.          elseif c_compiler = bcc32 then
  453.             Result := obj_suffix;
  454.          elseif c_compiler = bcc32i then
  455.             Result := obj_suffix;
  456.          elseif c_compiler = cl then
  457.             Result := obj_suffix;
  458.          elseif c_compiler = sas_c then
  459.             Result := o_suffix;
  460.          end;
  461.       end;
  462.  
  463. feature {NATIVE_SMALL_EIFFEL}
  464.  
  465.    add_lib_math is
  466.       once
  467.          if c_compiler = gcc then
  468.             list_add(external_lib,libm);
  469.          elseif c_compiler = bcc32 then
  470.             list_add(external_lib,libm);
  471.          elseif c_compiler = bcc32i then
  472.             list_add(external_lib,libm);
  473.          elseif c_compiler = cl then
  474.             list_add(external_lib,libm);
  475.          elseif c_compiler = sas_c then
  476.             list_add(external_lib,"Lib LIB:scm.lib");
  477.          end;
  478.       end;
  479.  
  480. feature {COMPILE,COMPILE_TO_C}
  481.  
  482.    extra_arg(arg: STRING; argi: INTEGER; next_arg: STRING): INTEGER is
  483.       require
  484.          arg /= Void;
  485.          argi >= 1
  486.       do
  487.          if arg.item(1) /= '-' then
  488.             if arg.has_suffix(object_suffix) then
  489.                list_add(external_object_files,arg);
  490.                Result := argi + 1;
  491.             elseif arg.has_suffix(c_suffix) then
  492.                list_add(external_c_files,arg);
  493.                Result := argi + 1;
  494.             elseif arg.has_suffix(".a") then
  495.                list_add(external_lib,arg);
  496.                Result := argi + 1;
  497.             elseif arg.has_suffix(".lib") then
  498.                list_add(external_lib,arg);
  499.                Result := argi + 1;
  500.             elseif run_control.root_class = Void then
  501.                run_control.compute_root_class(arg);
  502.                Result := argi + 1;
  503.                if next_arg /= Void then
  504.                   if next_arg.item(1) /= '-' then
  505.                      if next_arg.has_suffix(object_suffix) then
  506.                      elseif next_arg.has_suffix(c_suffix) then
  507.                      else
  508.                         run_control.set_root_procedure(next_arg);
  509.                         Result := argi + 2;
  510.                      end;
  511.                   end;
  512.                end;
  513.             else
  514.                list_add(c_compiler_options,arg);
  515.                Result := argi + 1;
  516.             end;
  517.          elseif arg.has_prefix("-l") then
  518.             list_add(external_lib,arg);
  519.             Result := argi + 1;
  520.          elseif arg.has_prefix("-L") then
  521.             list_add(external_lib_path,arg);
  522.             if ("-L").is_equal(arg) then
  523.                if next_arg /= Void then
  524.                   list_add(external_lib_path,next_arg);
  525.                   Result := argi + 2;
  526.                end;
  527.             else
  528.                Result := argi + 1;
  529.             end;
  530.          elseif ("-subsystem").is_equal(arg) then
  531.             list_add(linker_options,arg);
  532.             if next_arg /= Void then
  533.                list_add(linker_options,next_arg);
  534.                Result := argi + 2;
  535.             else
  536.                Result := argi + 1;
  537.             end;
  538.          else
  539.             list_add(c_compiler_options,arg);
  540.             Result := argi + 1;
  541.          end;
  542.       ensure
  543.          Result > old argi
  544.       end;
  545.  
  546. feature {COMPILE,COMPILE_TO_C,CLEAN}
  547.  
  548.    set_c_compiler(cc_arg: STRING) is
  549.       local
  550.          i: INTEGER;
  551.          sd: STRING;
  552.          c: CHARACTER;
  553.       do
  554.          if cc_arg /= Void then
  555.             i := compiler_list.index_of(cc_arg);
  556.             if i > compiler_list.upper then
  557.                echo.w_put_string("compile_to_c: ");
  558.                echo.w_put_string(cc_arg);
  559.                echo.w_put_string(" : unknown compiler name after -cc flag.%N");
  560.                show_compiler_list_then_exit;
  561.             end;
  562.             c_compiler := compiler_list.item(i);
  563.          else
  564.             sd := sys_directory;
  565.             tmp_path.copy(sd);
  566.             tmp_path.append("compiler.se");
  567.             echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  568.             c_compiler := echo.read_word_in(tmp_file_read);
  569.             i := compiler_list.index_of(c_compiler);
  570.             if i > compiler_list.upper then
  571.                echo.w_put_string("Unknown compiler name in file%N%"");
  572.                echo.w_put_string(tmp_file_read.path);
  573.                echo.w_put_string("%".%N");
  574.                show_compiler_list_then_exit;
  575.             end;
  576.             c_compiler := compiler_list.item(i);
  577.             if not tmp_file_read.end_of_input then
  578.                from
  579.                   c := tmp_file_read.last_character;
  580.                until
  581.                   c = '%N' or else c ='%R'
  582.                loop
  583.                   c_compiler_options.extend(c);
  584.                   tmp_file_read.read_character;
  585.                   if not tmp_file_read.end_of_input then
  586.                      c := tmp_file_read.last_character;
  587.                   end;
  588.                end;
  589.             end;
  590.             tmp_file_read.disconnect;
  591.          end;
  592.       ensure
  593.          compiler_list.fast_has(c_compiler)
  594.       end;
  595.  
  596. feature {COMPILE_TO_C}
  597.  
  598.    set_no_strip is
  599.       do
  600.          no_strip := true;
  601.       end;
  602.  
  603. feature {C_PRETTY_PRINTER}
  604.  
  605.    put_c_main_function_type(out_c: STD_FILE_WRITE) is
  606.       do
  607.          if vms_system = system_name then
  608.             out_c.put_string(fz_void);
  609.          else
  610.             out_c.put_string(fz_int);
  611.          end;
  612.       end;
  613.  
  614.    put_c_main_function_exit(out_c: STD_FILE_WRITE) is
  615.       do
  616.          out_c.put_string("}%Nexit(0);%N");
  617.          if vms_system = system_name then
  618.             out_c.put_string("return;}%N");
  619.          else
  620.             out_c.put_string("return 0;}%N");
  621.          end;
  622.       end;
  623.  
  624.    sys_runtime(name: STRING; suffix: CHARACTER) is
  625.          -- Prepare `tmp_file_read' to access the corresponding file
  626.          -- in the SmallEiffel/sys/runtime directory.
  627.       require
  628.          name /= Void;
  629.          suffix = 'c' or suffix = 'h'
  630.       do
  631.          tmp_path.copy(sys_directory);
  632.          add_directory(tmp_path,fz_runtime);
  633.          tmp_path.append(name);
  634.          tmp_path.extend('.');
  635.          tmp_path.extend(suffix);
  636.          echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  637.       ensure
  638.          tmp_file_read.is_connected
  639.       end;
  640.  
  641.    path_h: STRING is
  642.          -- Create a new STRING which is the name of the
  643.          -- main *.h file.
  644.       do
  645.          Result := run_control.root_class.twin;
  646.          Result.to_lower;
  647.          if dos_system = system_name then
  648.             from
  649.             until
  650.                Result.count <= 4
  651.             loop
  652.                Result.remove_last(1);
  653.             end;
  654.          end;
  655.          Result.append(h_suffix);
  656.       end;
  657.  
  658.    strip_executable(cmd: STRING): BOOLEAN is
  659.       local
  660.          output_name: STRING;
  661.       do
  662.          cmd.clear;
  663.          if not no_strip then
  664.             output_name := cpp.output_name;
  665.             if unix_system = system_name then
  666.                Result := true;
  667.                cmd.append("strip ");
  668.                if output_name = Void then
  669.                   cmd.append("a.out");
  670.                else
  671.                   cmd.append(output_name);
  672.                end;
  673.             elseif os2_system = system_name then
  674.                Result := true;
  675.                cmd.append("emxbind -qs ");
  676.                if output_name = Void then
  677.                   cmd.append("a.exe");
  678.                else
  679.                   cmd.append(output_name);
  680.                end;
  681.             end;
  682.          end;
  683.       end;
  684.  
  685. feature {C_PRETTY_PRINTER,INSTALL}
  686.  
  687.    split_mode_c_compiler_command(cmd, c_file_name: STRING) is
  688.       do
  689.          cmd.clear;
  690.          if c_compiler = gcc then
  691.             cmd.append(gcc);
  692.             cmd.append(c_compiler_options);
  693.             cmd.append(c_flag);
  694.             list_add(cmd,c_file_name);
  695.          elseif c_compiler = lcc_win32 then
  696.             cmd.append(lcc);
  697.             cmd.append(c_compiler_options);
  698.             list_add(cmd,c_file_name);
  699.          elseif c_compiler = cc then
  700.             cmd.append(cc);
  701.             cmd.append(c_compiler_options);
  702.             cmd.append(c_flag);
  703.             list_add(cmd,c_file_name);
  704.          elseif c_compiler = wcl386 then
  705.             cmd.append(wcl386);
  706.             list_add(cmd,"/ox /fp5");
  707.             cmd.append(c_compiler_options);
  708.             cmd.append(c_flag);
  709.             list_add(cmd,c_file_name);
  710.          elseif c_compiler = bcc32 then
  711.             cmd.append(bcc32);
  712.             list_add(cmd,"-5 -w-aus -w-par -w-rvl -O2 -O-v");
  713.             cmd.append(c_flag);
  714.             list_add(cmd,c_file_name);
  715.          elseif c_compiler = bcc32i then
  716.             cmd.append(bcc32i);
  717.             list_add(cmd,"-5 -w-aus -w-par -w-rvl -O2");
  718.             cmd.append(c_flag);
  719.             list_add(cmd,c_file_name);
  720.          elseif c_compiler = cl then
  721.             cmd.append(cl);
  722.             list_add(cmd,"-O2 -nologo -D%"WIN32%"");
  723.             cmd.append(c_flag);
  724.             list_add(cmd,c_file_name);
  725.          elseif c_compiler = sas_c then
  726.             cmd.append(sas_c);
  727.             cmd.append(c_compiler_options);
  728.             list_add(cmd,c_file_name);
  729.          end;
  730.       end;
  731.  
  732.    split_mode_linker_command(cmd, c_name: STRING; max: INTEGER) is
  733.       do
  734.          cmd.clear;
  735.          if c_compiler = gcc then
  736.             cmd.append(gcc);
  737.             cmd.append(c_compiler_options);
  738.             cmd.append(linker_options);
  739.             cmd.append(external_lib_path);
  740.             add_output_name(cmd);
  741.             add_objects(cmd,c_name,max);
  742.             cmd.append(external_c_files);
  743.             cmd.append(external_object_files);
  744.             cmd.append(external_lib);
  745.          elseif c_compiler = lcc_win32 then
  746.             cmd.append(lcclnk);
  747.             if not no_strip then
  748.                cmd.append(" -s");
  749.             end;
  750.             cmd.append(linker_options);
  751.             add_output_name(cmd);
  752.             add_objects(cmd,c_name,max);
  753.             cmd.append(external_object_files);
  754.             cmd.append(external_lib);
  755.          elseif c_compiler = cc then
  756.             cmd.append(cc);
  757.             cmd.append(c_compiler_options);
  758.             cmd.append(linker_options);
  759.             cmd.append(external_lib_path);
  760.             add_output_name(cmd);
  761.             add_objects(cmd,c_name,max);
  762.             cmd.append(external_c_files);
  763.             cmd.append(external_object_files);
  764.             cmd.append(external_lib);
  765.          elseif c_compiler = wcl386 then
  766.             cmd.append(wcl386);
  767.             list_add(cmd,"/ox /fp5");
  768.             cmd.append(c_compiler_options);
  769.             cmd.append(linker_options);
  770.             cmd.append(external_lib_path);
  771.             add_output_name(cmd);
  772.             add_objects(cmd,c_name,max);
  773.             cmd.append(external_c_files);
  774.             cmd.append(external_object_files);
  775.             cmd.append(external_lib);
  776.          elseif c_compiler = bcc32 then
  777.             cmd.append(bcc32);
  778.             list_add(cmd,"-5 -w-aus -w-par -w-rvl -O2 -O-v");
  779.             cmd.append(c_compiler_options);
  780.             cmd.append(linker_options);
  781.             cmd.append(external_lib_path);
  782.             add_output_name(cmd);
  783.             add_objects(cmd,c_name,max);
  784.             cmd.append(external_c_files);
  785.             cmd.append(external_object_files);
  786.             cmd.append(external_lib);
  787.             add_lib_math;
  788.          elseif c_compiler = bcc32i then
  789.             cmd.append(bcc32i);
  790.             list_add(cmd,"-5 -w-aus -w-par -w-rvl -O2");
  791.             cmd.append(c_compiler_options);
  792.             cmd.append(linker_options);
  793.             cmd.append(external_lib_path);
  794.             add_output_name(cmd);
  795.             add_objects(cmd,c_name,max);
  796.             cmd.append(external_c_files);
  797.             cmd.append(external_object_files);
  798.             cmd.append(external_lib);
  799.             add_lib_math;
  800.          elseif c_compiler = cl then
  801.             cmd.append(cl);
  802.             list_add(cmd,"-O2 -nologo -D%"WIN32%"");
  803.             cmd.append(c_compiler_options);
  804.             cmd.append(linker_options);
  805.             cmd.append(external_lib_path);
  806.             add_output_name(cmd);
  807.             add_objects(cmd,c_name,max);
  808.             cmd.append(external_c_files);
  809.             cmd.append(external_object_files);
  810.             cmd.append(external_lib);
  811.             add_lib_math;
  812.          elseif c_compiler = sas_c then
  813.             cmd.append(sas_c);
  814.             cmd.append(c_compiler_options);
  815.             cmd.append(" Link");
  816.             cmd.append(linker_options);
  817.             cmd.append(" ");
  818.             cmd.append(c_name);
  819.             cmd.append("#1#2#3#4#5#6#7#8#9#?.o");
  820.             cmd.append(external_c_files);
  821.             cmd.append(external_object_files);
  822.             cmd.append(external_lib);
  823.             add_output_name(cmd);
  824.             if not no_strip then
  825.                cmd.append(" StripDebug");
  826.             end;
  827.          end;
  828.       end;
  829.  
  830.    no_split_mode_command(cmd, c_file_name: STRING) is
  831.       do
  832.          cmd.clear;
  833.          if c_compiler = gcc then
  834.             cmd.append(gcc);
  835.             cmd.append(c_compiler_options);
  836.             cmd.append(linker_options);
  837.             cmd.append(external_lib_path);
  838.             add_output_name(cmd);
  839.             list_add(cmd,c_file_name);
  840.             cmd.append(external_c_files);
  841.             cmd.append(external_object_files);
  842.             cmd.append(external_lib);
  843.          elseif c_compiler = lcc_win32 then
  844.             cmd.append(lcc);
  845.             cmd.append(c_compiler_options);
  846.             list_add(cmd,c_file_name);
  847.             cpp.echo_make;
  848.             cmd.clear;
  849.             cmd.append(lcclnk);
  850.             if not no_strip then
  851.                cmd.append(" -s");
  852.             end;
  853.             cmd.append(linker_options);
  854.             add_output_name(cmd);
  855.             c_file_name.remove_last(2);
  856.             c_file_name.append(object_suffix);
  857.             list_add(cmd,c_file_name);
  858.             cmd.append(external_object_files);
  859.             cmd.append(external_lib);
  860.          elseif c_compiler = cc then
  861.             cmd.append(cc);
  862.             cmd.append(c_compiler_options);
  863.             cmd.append(linker_options);
  864.             cmd.append(external_lib_path);
  865.             add_output_name(cmd);
  866.             list_add(cmd,c_file_name);
  867.             cmd.append(external_c_files);
  868.             cmd.append(external_object_files);
  869.             cmd.append(external_lib);
  870.          elseif c_compiler = wcl386 then
  871.             cmd.append(wcl386);
  872.             list_add(cmd,"/ox /fp5");
  873.             cmd.append(c_compiler_options);
  874.             cmd.append(linker_options);
  875.             cmd.append(external_lib_path);
  876.             add_output_name(cmd);
  877.             list_add(cmd,c_file_name);
  878.             cmd.append(external_c_files);
  879.             cmd.append(external_object_files);
  880.             cmd.append(external_lib);
  881.          elseif c_compiler = bcc32 then
  882.             cmd.append(bcc32);
  883.             list_add(cmd,"-5 -w-aus -w-par -w-rvl -O2 -O-v");
  884.             cmd.append(c_compiler_options);
  885.             cmd.append(linker_options);
  886.             cmd.append(external_lib_path);
  887.             add_output_name(cmd);
  888.             list_add(cmd,c_file_name);
  889.             cmd.append(external_c_files);
  890.             cmd.append(external_object_files);
  891.             cmd.append(external_lib);
  892.             add_lib_math;
  893.          elseif c_compiler = bcc32i then
  894.             cmd.append(bcc32i);
  895.             list_add(cmd,"-5 -w-aus -w-par -w-rvl -O2");
  896.             cmd.append(c_compiler_options);
  897.             cmd.append(linker_options);
  898.             cmd.append(external_lib_path);
  899.             add_output_name(cmd);
  900.             list_add(cmd,c_file_name);
  901.             cmd.append(external_c_files);
  902.             cmd.append(external_object_files);
  903.             cmd.append(external_lib);
  904.             add_lib_math;
  905.          elseif c_compiler = cl then
  906.             cmd.append(cl);
  907.             list_add(cmd,"-O2 -nologo -D%"WIN32%"");
  908.             cmd.append(c_compiler_options);
  909.             cmd.append(linker_options);
  910.             cmd.append(external_lib_path);
  911.             add_output_name(cmd);
  912.             list_add(cmd,c_file_name);
  913.             cmd.append(external_c_files);
  914.             cmd.append(external_object_files);
  915.             cmd.append(external_lib);
  916.             add_lib_math;
  917.          elseif c_compiler = sas_c then
  918.             cmd.append(sas_c);
  919.             cmd.append(c_compiler_options);
  920.             cmd.append(external_lib_path);
  921.             list_add(cmd,c_file_name);
  922.             cmd.append(external_c_files);
  923.             cmd.append(external_object_files);
  924.             cmd.append(external_lib);
  925.             cmd.append(" link");
  926.             add_output_name(cmd);
  927.          end;
  928.       end;
  929.  
  930. feature {NONE}
  931.  
  932.    c_compiler: STRING;
  933.          -- One item of `compiler_list'.
  934.  
  935.    c_compiler_options: STRING is "";
  936.          -- C compiler options including extra include path,
  937.          -- optimization flags, etc.
  938.  
  939.    external_object_files: STRING is "";
  940.          -- External object files.
  941.  
  942.    external_c_files: STRING is "";
  943.          -- External c files.
  944.  
  945.    external_lib_path: STRING is "";
  946.          -- External libraries path to be added at link time.
  947.  
  948.    external_lib: STRING is "";
  949.          -- External libraries to be added at link time.
  950.  
  951.    linker_options: STRING is "";
  952.          -- Those options are only to be passed to the linker.
  953.  
  954.    list_add(list, token: STRING) is
  955.       do
  956.          list.extend(' ');
  957.          list.append(token);
  958.       end;
  959.  
  960.    backslash_separator: BOOLEAN is
  961.       do
  962.          if windows_system = system_name then
  963.             Result := true;
  964.          elseif dos_system = system_name then
  965.             Result := true;
  966.          elseif os2_system = system_name then
  967.             Result := true;
  968.          end;
  969.       end;
  970.  
  971.    fz_loadpath_se: STRING is "loadpath.se";
  972.  
  973.    loading_path_add(lp: ARRAY[STRING]; path: STRING; level: INTEGER) is
  974.       local
  975.          file: STD_FILE_READ;
  976.          line: STRING;
  977.       do
  978.          if level > 5 or else lp.count > 1024 then
  979.             echo.w_put_string(
  980.                "Eiffel source loading path too long or infinite %
  981.                %loadpath.se includes.%N");
  982.             !!line.make(1024);
  983.             append_lp_in(line,lp);
  984.             echo.w_put_string(line);
  985.             die_with_code(exit_failure_code);
  986.          end;
  987.          !!file.make;
  988.          echo.sfr_connect(file,path);
  989.          if file.is_connected then
  990.             from
  991.                echo.put_string("Append contents of  %"");
  992.                echo.put_string(path);
  993.                echo.put_string("%" to loading path.%N");
  994.             until
  995.                file.end_of_input
  996.             loop
  997.                file.read_line;
  998.                line := file.last_string.twin;
  999.                environment_variable_substitution(path,line);
  1000.                if line.has_suffix(fz_loadpath_se) then
  1001.                   loading_path_add(lp,line,level + 1);
  1002.                elseif line.empty then
  1003.                   if not file.end_of_input then
  1004.                      lp.add_last(line);
  1005.                   end;
  1006.                else
  1007.                   lp.add_last(line);
  1008.                end;
  1009.             end;
  1010.             file.disconnect;
  1011.          end;
  1012.       end;
  1013.  
  1014. feature {INSTALL}
  1015.  
  1016.    add_directory(path, dir: STRING) is
  1017.       require
  1018.          path.count > 0;
  1019.          dir.count > 0
  1020.       local
  1021.          last: CHARACTER;
  1022.       do
  1023.          if slash_separator then
  1024.             path.set_last('/');
  1025.             path.append(dir);
  1026.             path.set_last('/');
  1027.          elseif backslash_separator then
  1028.             path.set_last('\');
  1029.             path.append(dir);
  1030.             path.set_last('\');
  1031.          elseif macintosh_system = system_name then
  1032.             path.set_last(':');
  1033.             path.append(dir);
  1034.             path.set_last(':');
  1035.          elseif amiga_system = system_name then
  1036.             last := path.last;
  1037.             if last /= '/' and then last /= ':' then
  1038.                path.set_last('/');
  1039.             end;
  1040.             path.append(dir);
  1041.             path.set_last('/');
  1042.          elseif vms_system = system_name then
  1043.             path.set_last(']');
  1044.             path.remove_last(1);
  1045.             path.set_last('.');
  1046.             path.append(dir);
  1047.             path.set_last(']');
  1048.          else
  1049.             check
  1050.                false
  1051.             end;
  1052.          end;
  1053.       end;
  1054.  
  1055.    parent_directory(path: STRING) is
  1056.          -- Remove the last sub-directory of `path' (assume `path' is a
  1057.          -- combination of more than one directory).
  1058.       require
  1059.          path.count > 0
  1060.       do
  1061.          if slash_separator then
  1062.             from
  1063.                path.remove_last(1);
  1064.             until
  1065.                path.last = '/'
  1066.             loop
  1067.                path.remove_last(1);
  1068.             end;
  1069.          elseif backslash_separator then
  1070.             from
  1071.                path.remove_last(1);
  1072.             until
  1073.                path.last = '\'
  1074.             loop
  1075.                path.remove_last(1);
  1076.             end;
  1077.          elseif macintosh_system = system_name then
  1078.             from
  1079.                path.remove_last(1);
  1080.             until
  1081.                path.last = ':'
  1082.             loop
  1083.                path.remove_last(1);
  1084.             end;
  1085.          elseif amiga_system = system_name then
  1086.             from
  1087.                path.remove_last(1);
  1088.             until
  1089.                path.empty or else ("/:").has(path.last)
  1090.             loop
  1091.                path.remove_last(1);
  1092.             end;
  1093.          elseif vms_system = system_name then
  1094.             from
  1095.                path.remove_last(1);
  1096.             until
  1097.                path.last = '.'
  1098.             loop
  1099.                path.remove_last(1);
  1100.             end;
  1101.             path.remove_last(1);
  1102.             path.extend(']');
  1103.          else
  1104.             check
  1105.                false
  1106.             end;
  1107.          end;
  1108.       ensure
  1109.          path.count > 0;
  1110.          path.count < (old path.count)
  1111.       end;
  1112.  
  1113. feature {NONE}
  1114.  
  1115.    environment_variable_substitution(path, line: STRING) is
  1116.          -- If any, substitute some environment variable by it's value.
  1117.          -- The only one accepted notation is :
  1118.          --                                        ${...}
  1119.       local
  1120.          i, state, mem1, mem2: INTEGER;
  1121.          c: CHARACTER;
  1122.          value, variable: STRING;
  1123.       do
  1124.          from
  1125.             i := 1;
  1126.          until
  1127.             i > line.count
  1128.          loop
  1129.             c := line.item(i);
  1130.             inspect
  1131.                state
  1132.             when 0 then -- Initial state.
  1133.                if c = '$' then
  1134.                   state := 1;
  1135.                   mem1 := i;
  1136.                end;
  1137.             when 1 then -- "$" read.
  1138.                if c = '{' then
  1139.                   state := 2;
  1140.                   !!variable.make(8);
  1141.                else
  1142.                   state := 0;
  1143.                end;
  1144.             when 2 then -- "${" read.
  1145.                if c = '}' then
  1146.                   state := 3;
  1147.                   mem2 := i;
  1148.                else
  1149.                   variable.extend(c);
  1150.                end;
  1151.             else -- First correct variable found.
  1152.             end;
  1153.             i := i + 1;
  1154.          end;
  1155.          if state = 3 then
  1156.             value := get_environment_variable(variable);
  1157.             if value = Void then
  1158.                echo.w_put_string("Environment variable ${");
  1159.                echo.w_put_string(variable);
  1160.                echo.w_put_string("} of %"");
  1161.                echo.w_put_string(path);
  1162.                echo.w_put_string("%" is not set.%N");
  1163.             else
  1164.                variable.copy(line);
  1165.                line.head(mem1 - 1);
  1166.                line.append(value);
  1167.                variable.remove_first(mem2);
  1168.                line.append(variable);
  1169.                environment_variable_substitution(path,line)
  1170.             end;
  1171.          end;
  1172.       end;
  1173.  
  1174.    slash_separator: BOOLEAN is
  1175.       do
  1176.          if unix_system = system_name then
  1177.             Result := true;
  1178.          elseif beos_system = system_name then
  1179.             Result := true;
  1180.          end;
  1181.       end;
  1182.  
  1183.    show_compiler_list_then_exit is
  1184.       local
  1185.          i: INTEGER;
  1186.       do
  1187.          echo.w_put_string("Currently handled compiler names:%N");
  1188.          from
  1189.             i := 1;
  1190.          until
  1191.             i > compiler_list.upper
  1192.          loop
  1193.             echo.w_put_string(compiler_list.item(i));
  1194.             echo.w_put_character('%N');
  1195.             i := i + 1;
  1196.          end;
  1197.          die_with_code(exit_failure_code);
  1198.       end;
  1199.  
  1200.    add_output_name(cmd: STRING) is
  1201.       local
  1202.          output_name: STRING;
  1203.       do
  1204.          output_name := cpp.output_name;
  1205.          if output_name = Void then
  1206.             output_name := run_control.root_class.twin;
  1207.             output_name.to_lower;
  1208.             if c_compiler = lcc_win32 then
  1209.                cmd.append(o_flag);
  1210.                list_add(cmd,output_name);
  1211.                add_x_suffix(cmd);
  1212.             elseif c_compiler = bcc32 then
  1213.                cmd.append(e_flag);
  1214.                cmd.append(output_name);
  1215.                add_x_suffix(cmd);
  1216.             elseif c_compiler = bcc32i then
  1217.                cmd.append(e_flag);
  1218.                cmd.append(output_name);
  1219.                add_x_suffix(cmd);
  1220.             elseif c_compiler = sas_c then
  1221.                output_name := run_control.root_class.twin;
  1222.                output_name.to_lower;
  1223.                cmd.append(" To ");
  1224.                cmd.append(output_name);
  1225.             end;
  1226.          elseif c_compiler = gcc then
  1227.             cmd.append(o_flag);
  1228.             list_add(cmd,output_name);
  1229.             add_x_suffix(cmd);
  1230.          elseif c_compiler = lcc_win32 then
  1231.             cmd.append(o_flag);
  1232.             list_add(cmd,output_name);
  1233.             add_x_suffix(cmd);
  1234.          elseif c_compiler = cc then
  1235.             cmd.append(o_flag);
  1236.             list_add(cmd,output_name);
  1237.             add_x_suffix(cmd);
  1238.          elseif c_compiler = wcl386 then
  1239.             cmd.append(" /fe=");
  1240.             cmd.append(output_name);
  1241.             add_x_suffix(cmd);
  1242.          elseif c_compiler = bcc32 then
  1243.             cmd.append(e_flag);
  1244.             cmd.append(output_name);
  1245.             add_x_suffix(cmd);
  1246.          elseif c_compiler = bcc32i then
  1247.             cmd.append(e_flag);
  1248.             cmd.append(output_name);
  1249.             add_x_suffix(cmd);
  1250.          elseif c_compiler = cl then
  1251.             cmd.append(o_flag);
  1252.             cmd.append(output_name);
  1253.             add_x_suffix(cmd);
  1254.          elseif c_compiler = sas_c then
  1255.             cmd.append(" To ");
  1256.             list_add(cmd,output_name);
  1257.          end;
  1258.       end;
  1259.  
  1260.    no_strip: BOOLEAN;
  1261.  
  1262.    add_objects(cmd, c_name: STRING; max: INTEGER) is
  1263.       local
  1264.          i: INTEGER;
  1265.       do
  1266.          from
  1267.             i := 1;
  1268.          until
  1269.             i > max
  1270.          loop
  1271.             list_add(cmd,c_name);
  1272.             i.append_in(cmd);
  1273.             cmd.append(object_suffix);
  1274.             i := i + 1;
  1275.          end;
  1276.       end;
  1277.  
  1278.    add_x_suffix(cmd: STRING) is
  1279.       local
  1280.          suffix: STRING;
  1281.       do
  1282.          suffix := x_suffix;
  1283.          if not cmd.has_suffix(suffix) then
  1284.             cmd.append(suffix);
  1285.          end;
  1286.       end;
  1287.  
  1288.    exe_suffix: STRING is ".exe";
  1289.  
  1290.    o_suffix: STRING is ".o";
  1291.  
  1292.    obj_suffix: STRING is ".obj";
  1293.  
  1294.    c_flag: STRING is " -c";
  1295.  
  1296.    o_flag: STRING is " -o";
  1297.  
  1298.    e_flag: STRING is " -e";
  1299.  
  1300.    lcc: STRING is "lcc";
  1301.  
  1302.    lcclnk: STRING is "lcclnk";
  1303.  
  1304.    lnk_suffix: STRING is ".lnk";
  1305.  
  1306.    libm: STRING is "-lm";
  1307.  
  1308.    singleton_memory: SYSTEM_TOOLS is
  1309.       once
  1310.          Result := Current;
  1311.       end;
  1312.  
  1313. invariant
  1314.  
  1315.    is_real_singleton: Current = singleton_memory
  1316.  
  1317. end -- SYSTEM_TOOLS
  1318.