File: command_line_tools.e

package info (click to toggle)
smarteiffel 1.1-11
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 12,288 kB
  • ctags: 40,785
  • sloc: ansic: 35,791; lisp: 4,036; sh: 1,783; java: 895; ruby: 613; python: 209; makefile: 115; csh: 78; cpp: 50
file content (451 lines) | stat: -rw-r--r-- 13,067 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
-- This file is part of SmartEiffel The GNU Eiffel Compiler Tools and Libraries
--
-- SmartEiffel is  free software;  you can redistribute it and/or  modify it
-- under  the terms of the  GNU General Public License, as published by  the
-- Free Software Foundation; either version 2, or (at your option) any later
-- version.
-- SmartEiffel is distributed in the hope that it will be useful but WITHOUT 
-- ANY WARRANTY;  without  even the implied warranty  of MERCHANTABILITY  or
-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-- more details.  You should have received a copy of  the GNU General Public
-- License along with SmartEiffel;  see the file COPYING.  If not,  write to
-- the Free Software Foundation,  Inc., 59 Temple Place - Suite 330,  Boston, 
-- MA 02111-1307, USA.
--
-- Copyright(C) 1994-2002: INRIA - LORIA (INRIA Lorraine) - ESIAL U.H.P.
--			   - University of Nancy 1 - FRANCE
-- Copyright(C) 2003:      INRIA - LORIA (INRIA Lorraine) - I.U.T. Charlemagne
--			   - University of Nancy 2 - FRANCE
--
--		 Dominique COLNET, Suzanne COLLIN, Olivier ZENDRA,
--			   Philippe RIBET, Cyril ADRIAN
--
-- http://SmartEiffel.loria.fr - SmartEiffel@loria.fr
--
deferred class COMMAND_LINE_TOOLS
   --
   -- Some useful tools to handle command flags. Actually, this class is
   -- inherited by all command line tools of SmartEiffel (eg. "compile",
   -- "compile_to_c", "compile_to_jvm", "finder", "clean", "short",
   -- "pretty", and "install" as well).
   --

inherit
   GLOBALS
   VISITABLE

feature {COMMAND_LINE_TOOLS_VISITOR}

   accept(visitor: COMMAND_LINE_TOOLS_VISITOR) is
      deferred
      end

feature

   command_name: STRING is
	 -- Is supposed to return the name of the command itself (eg.
	 -- "compile", "compile_to_c", "finder", "clean", etc.).
      deferred
      end

   command_line_help_summary: STRING is
	 -- The traditional "-help" flag summary of information about
	 -- available options.
      deferred
      end

feature {NONE}

   flag_match(flag, arg: STRING): BOOLEAN is
	 -- Does `arg' smoothly match with the `flag' model?
	 -- Where `arg' can be like -`flag' or  --`flag' as well as
	 -- the classic Windows notation  /`flag' too.
      require
	 not flag.is_empty and arg /= Void
      local
	 i_flag, i_arg: INTEGER
      do
	 i_arg := arg.count
	 if i_arg >= 2 then
	    from
	       i_flag := flag.count
	       inspect
		  arg.first
	       when '-' then
		  if arg.item(2) = '-' then
		     Result :=  i_flag + 2 = i_arg
		  else
		     Result := i_flag + 1 = i_arg
		  end
	       when '/' then
		  Result := i_flag + 1 = i_arg
	       else
	       end
	    until
	       not Result or else i_flag = 0
	    loop
	       if flag.item(i_flag).same_as(arg.item(i_arg)) then
		  i_arg := i_arg - 1
		  i_flag := i_flag - 1
	       else
		  Result := false
	       end
	    end
	 end
      end

   is_valid_argument_for_ace_mode(arg: STRING): BOOLEAN is
	 -- Is the `arg' command line argument allowed in ACE file mode ?
      require
	 arg /= Void
      deferred
      end

   valid_argument_for_ace_mode: STRING is
	 -- An explanation to be given to the user when the call to
	 -- `is_valid_argument_for_ace_mode' returns false.
      deferred
      end

   is_help_flag(flag: STRING): BOOLEAN is
	 -- Is it like some traditional help `flag'?
      do
         if (flag_match(fz_help,flag)
	     or else
	     flag_match(once "h",flag)
	     or else
	     (once "?").is_equal(flag))
	  then
	    if not help_flag then
	       std_output.put_string(command_line_help_summary)
	    end
	    inspect
	       argument_count
	    when 1 then
	       die_with_code(exit_success_code)
	    when 2 then
	       if version_flag then
		  die_with_code(exit_success_code)
	       end
	    else
	    end
	    help_flag := true
            Result := true
         end
      end

   help_flag: BOOLEAN
	 -- Memory of `is_help_flag'.

   search_for_verbose_flag is
         -- Seach the -verbose flag amongs arguments in order to
         -- become verbose as soon as possible (should be called
         -- first when the command accept this flag).
      local
         i: INTEGER
      do
         from
            i := argument_count
         until
            i = 0
         loop
            if is_verbose_flag(argument(i)) then end
	    i := i - 1
         end
         echo.put_string(smart_eiffel.copyright)
      end

   search_for_cc_flag(argc: INTEGER) is
         -- To know about the C compiler as soon as possible.
      local
         i: INTEGER
         c_compiler: STRING
      do
         from
            i := 1
         until
            i > argc
         loop
            if flag_match(fz_cc,argument(i)) then
               if i < argc then
                  i := i + 1
                  c_compiler := argument(i)
                  i := argc + 1
               end
            end
            i := i + 1
         end
         system_tools.set_c_compiler(c_compiler)
      end

   ace_file_mode: BOOLEAN is
         -- Search for some ACE file name in the command line arguments.
         -- When some argument has the appropriate suffix (ie. ".ace" or
         -- ".ACE"), the `ace' parser is automatically launched in order to
         -- parse this configuration file. The caller is then notified
         -- that we are now in ACE mode (the result is true). When we are
         -- in ACE mode, remainings allowed argument are automatically
         -- handled.
      local
         i: INTEGER
	 arg: STRING
      do
         -- Be sure system_tools is intanciated before reading the ACE file
         -- (otherwise we have a buffer conflict)
         system_tools.do_nothing

	 -- First, search for some *.ace or *.ACE file name:
	 from
            i := argument_count
         until
            Result or else i = 0
         loop
	    arg := argument(i)
            if arg.has_suffix(once ".ace") or else arg.has_suffix(once ".ACE") then
	       Result := True
	       ace.analyse_ace_file(arg)
            end
	    i := i - 1
         end
	 if Result then
	    -- Second, check that other arguments are allowed in ACE
	    -- file mode:
	    from
	       i := 1
	    until
	       i > argument_count
	    loop
	       arg := argument(i)
	       if arg = ace.file_path then
	       elseif is_valid_argument_for_ace_mode(arg) then
	       else
		  echo.w_put_string("Flag or argument %"")
		  echo.w_put_string(arg)
		  echo.w_put_string("%" is not allowed when an ACE file (")
		  echo.w_put_string(ace.file_path)
		  echo.w_put_string(") is used.%N")
		  echo.w_put_string(valid_argument_for_ace_mode)
		  system_tools.bad_use_exit(Current)
	       end
	       i := i + 1
	    end
	 end
      end

   is_some_flag(arg: STRING): BOOLEAN is
      do
	 if not arg.is_empty then
	    Result := (arg.first = '-' or else arg.first = '?')
	 end
      end

   is_case_insensitive_flag(flag: STRING): BOOLEAN is
      do
         if flag_match(fz_case_insensitive,flag) then
            Result := true
            eiffel_parser.set_case_insensitive
         end
      end

   is_no_style_warning_flag(flag: STRING): BOOLEAN is
      do
         if flag_match(fz_no_style_warning,flag) then
            Result := true
            eiffel_parser.set_no_style_warning
         end
      end

   is_no_warning_flag(flag: STRING): BOOLEAN is
      do
         if flag_match(fz_no_warning,flag) then
            Result := true
            error_handler.set_no_warning
         end
      end

   is_trace_flag(flag: STRING): BOOLEAN is
      do
         if flag_match(fz_sedb,flag) then
            Result := true
         end
         if flag_match(fz_trace,flag) then
	    std_output.put_string(command_name)
	    std_output.put_string(once
	    ": the new name of the %"-trace%" flag is now %"-sedb%".%N")
            Result := true
         end
         if Result then
            ace.set_default_trace
         end
      end

   is_verbose_flag(flag: STRING): BOOLEAN is
      do
         if flag_match(fz_verbose,flag) then
	    echo.set_verbose
            Result := true
         end
      end

   is_clean_flag(flag: STRING): BOOLEAN is
      do
         if flag_match(fz_clean,flag) then
	    ace.set_clean(true)
            Result := true
         end
      end

   is_version_flag(flag: STRING): BOOLEAN is
      do
         if flag_match(fz_version,flag) or else flag_match(once "v",flag) then
	    if not version_flag then
	       std_output.put_string(once "Version of command %"")
	       std_output.put_string(command_name)
	       std_output.put_string(once "%" is:%N")
	       std_output.put_string(smart_eiffel.copyright)
	    end
	    inspect
	       argument_count
	    when 1 then
	       die_with_code(exit_success_code)
	    when 2 then
	       if help_flag then
		  die_with_code(exit_success_code)
	       end
	    else
	    end
	    version_flag := true
            Result := true
         end
      end

   version_flag: BOOLEAN
	 -- Memory of `is_version_flag'.

   is_a_compilation_level_flag(flag: STRING): BOOLEAN is
	 -- Is the `flag' one of this list: "-boost", "-no_check",
	 -- "-require_check", "-ensure_check", "-invariant_check",
	 -- "-loop_check", "-all_check", or "-debug_check" ?
      do
         if flag_match(fz_boost,flag) then
            Result := true
            ace.set_boost
	 elseif flag_match(fz_no_check,flag) then
            Result := true
            ace.set_no_check
	 elseif flag_match(fz_conf_require_check,flag) then
            Result := true
            ace.set_require_check
	 elseif flag_match(fz_conf_ensure_check,flag) then
            Result := true
            ace.set_ensure_check
	 elseif flag_match(fz_conf_invariant_check,flag) then
            Result := true
            ace.set_invariant_check
	 elseif flag_match(fz_conf_loop_check,flag) then
            Result := true
            ace.set_loop_check
	 elseif flag_match(fz_conf_all_check,flag) then
            Result := true
            ace.set_all_check
	 elseif flag_match(fz_conf_debug_check,flag) then
            Result := true
            ace.set_debug_check
         end
	 if Result then
	    check_for_level(flag)
	 end
      end

   is_cecil_flag(flag: STRING; argi, argc: INTEGER): BOOLEAN is
      do
         if flag_match(fz_cecil,flag) then
            Result := true
            if argi < argc then
               cecil_pool.add_file(argument(argi + 1))
            else
               echo.w_put_string(command_name)
               echo.w_put_string(": missing file name after -cecil flag.%N")
               die_with_code(exit_failure_code)
            end
         end
      end

   is_o_flag(flag: STRING; argi, argc: INTEGER ): BOOLEAN is
      local
         executable_name: STRING
      do
         if fz_o.is_equal(flag) then
            Result := true
            if argi < argc then
               executable_name := argument(argi + 1)
               if executable_name.has_suffix(eiffel_suffix) then
                  echo.w_put_string("Bad executable name: %"")
                  echo.w_put_string(executable_name)
                  echo.w_put_string(
                  "%". Must not use Eiffel source file suffix %
                   %with option %"-o <executable_name>%".")
                  die_with_code(exit_failure_code)
               end
               ace.set_executable_name(executable_name)
            else
               echo.w_put_string(command_name)
               echo.w_put_string(": missing output name after -o flag.%N")
               die_with_code(exit_failure_code)
            end
         end
      end

   is_safety_check_flag(flag: STRING): BOOLEAN is
      do
         if flag_match(fz_safety_check,flag) then
	    ace.set_safety_check
            Result := true
         end
      end

   is_manifest_string_trace_flag(flag: STRING): BOOLEAN is
      do
         if flag_match(fz_manifest_string_trace,flag) then
	    ace.set_manifest_string_trace
            Result := true
         end
      end

   is_high_memory_compiler(flag: STRING): BOOLEAN is
      do
         if flag_match(fz_high_memory_compiler,flag) then
	    ace.set_high_memory_compiler
            Result := true
         end
      end

   level_flag: STRING

   check_for_level(new_level_flag: STRING) is
      do
         if level_flag /= Void then
            if not level_flag.same_as(new_level_flag) then
               echo.w_put_string(command_name)
               echo.w_put_string(": level is already set to ")
               echo.w_put_string(level_flag)
               echo.w_put_string(". Bad flag ")
               echo.w_put_string(new_level_flag)
               echo.w_put_string(fz_b0)
               die_with_code(exit_failure_code)
            end
         else
            level_flag := new_level_flag
         end
      end

   unknown_flag_exit(flag: STRING) is
      do
         echo.w_put_string(command_name)
         echo.w_put_string(": unknown flag %"")
         echo.w_put_string(flag)
         echo.w_put_string("%".%N")
         system_tools.bad_use_exit(Current)
      end

end -- COMMAND_LINE_TOOLS