-- This file is part of SmartEiffel The GNU Eiffel Compiler.
-- Copyright (C) 1994-2002 LORIA - INRIA - U.H.P. Nancy 1 - FRANCE
-- Dominique COLNET and Suzanne COLLIN - SmartEiffel@loria.fr
-- http://SmartEiffel.loria.fr
-- 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.
--
class SHORT
--
-- The `short' command.
--
inherit COMMAND_LINE_TOOLS
creation make
feature
command_name: STRING is "short"
command_line_help_summary: STRING is "[
Usage: short [format] [options] <ClassName>
or: short [format] [options] <ACEfileName>.ace <ClassName>
Option summary:
Information:
-help Display this help information
-version Display SmartEiffel version information
-verbose Display detailed information about what the
program is doing
Warning levels:
-case_insensitive Make class and feature names case-insensitive
-no_style_warning Don't print warnings about style violations
-no_warning Don't print any warnings (implies -no_style_warning)
-sort Sort features alphabetically
-short Don't include inherited features
Formatting (specify at most one; default is -plain):
-plain, -pretty, -tex1, -tex2, -tex3, -html1, -html2
Specify the style of formatting (see short.txt)
Point of view:
-client <class> Specify the class whom the point of view is taken of
]"
feature {NONE}
format: STRING
-- The selected format directory to find hooks files.
parents: FIXED_ARRAY[BASE_CLASS] is
-- From `ace..root_class' up to ANY included.
once
!!Result.with_capacity(4)
end
run_class: RUN_CLASS
-- The corresponding one of the class to short.
run_feature_list: FIXED_ARRAY[RUN_FEATURE] is
-- To be printed by the short command.
once
!!Result.with_capacity(256)
end
sort: BOOLEAN
-- True if the -sort flag is used.
client: CLASS_NAME
-- The client for whom the class is short'ed (-client flag).
short: BOOLEAN
make is
local
bc: BASE_CLASS; cn: CLASS_NAME; i: INTEGER; ccl: CREATION_CLAUSE_LIST
arg: STRING
do
smart_eiffel.set_short_flag
if argument_count = 0 then
fatal_bad_usage
end
if not ace_file_mode then
from
i := 1
until
i > argument_count
loop
arg := argument(i)
if is_client_flag(arg) then
if i = argument_count then
fatal_bad_usage
else
arg := argument(i+1)
arg.to_upper
create client.unknown_position(string_aliaser.item(arg))
i := i + 1
end
elseif is_valid_argument_for_ace_mode(arg) then
end
i := i + 1
end
ace.command_line_parsed(command_name)
end
if help_flag then
die_with_code(exit_success_code)
end
if version_flag then
die_with_code(exit_success_code)
end
if ace.root_class_name = Void then
fatal_bad_usage
end
if client = Void then
create client.unknown_position(as_any)
else
-- force client class lookup:
bc := smart_eiffel.base_class(client)
end
create cn.unknown_position(ace.root_class_name)
bc := smart_eiffel.base_class(cn)
if smart_eiffel.no_file_for(bc.name.to_string) then
-- *** I may consider here to add an extra comment to
-- warn the user on the fact that this class has no file
-- and that this file is magically handled by the
-- compiler.
end
parents.add_last(bc)
if not short then
bc.up_to_any_in(parents)
end
if format = Void then
format := once "plain"
end
-- Prepare data:
compute_run_class(bc)
run_class.runnable_class_invariant
-- Print the class interface:
short_print.start(format,bc,run_class)
ccl := bc.creation_clause_list
if ccl = Void or else not ccl.short(client) then
short_print.hook(once "hook102")
end
compute_run_feature_list_for(client)
if sort then
short_print.hook_or(once "hook200",once "feature(s)%N")
sort_run_feature_list
from
i := 0
until
i > run_feature_list.upper
loop
short_print.a_run_feature(run_feature_list.item(i))
i := i + 1
end
short_print.hook(once "hook201")
end
short_print.finish
end
is_sort_flag(flag: STRING): BOOLEAN is
do
if flag_match(once "sort",flag) then
Result := true
sort := true
end
end
is_short_flag(flag: STRING): BOOLEAN is
do
if flag_match(once "short",flag) then
Result := true
short := true
end
end
is_client_flag(flag: STRING): BOOLEAN is
do
if flag_match(once "client",flag) then
Result := true
end
end
compute_run_class(bc: BASE_CLASS) is
local
fgl: FORMAL_GENERIC_LIST
bcn: STRING
sp: POSITION
t, ct: E_TYPE
gl: ARRAY[E_TYPE]
i: INTEGER
fga: FORMAL_GENERIC_ARG
do
bcn := bc.name.to_string
sp := bc.name.start_position
fgl := bc.formal_generic_list
if as_any = bcn then
create {TYPE_ANY} ct.make(sp)
elseif as_native_array = bcn then
create {TYPE_CHARACTER} t.make(sp)
create {TYPE_NATIVE_ARRAY} ct.make(sp,t)
elseif as_array = bcn then
create {TYPE_ANY} t.make(sp)
create {TYPE_ARRAY} ct.make(sp,t)
elseif as_integer_8 = bcn then
create {TYPE_INTEGER} ct.integer_8(sp)
elseif as_integer_16 = bcn then
create {TYPE_INTEGER} ct.integer_16(sp)
elseif as_integer_32 = bcn then
create {TYPE_INTEGER} ct.integer_32(sp)
elseif as_integer = bcn then
create {TYPE_INTEGER} ct.integer(sp)
elseif as_integer_64 = bcn then
create {TYPE_INTEGER} ct.integer_64(sp)
elseif as_integer_general = bcn then
create {TYPE_INTEGER} ct.integer_general(sp)
elseif as_real = bcn then
!TYPE_REAL!ct.make(sp)
elseif as_double = bcn then
!TYPE_DOUBLE!ct.make(sp)
elseif as_character = bcn then
!TYPE_CHARACTER!ct.make(sp)
elseif as_boolean = bcn then
!TYPE_BOOLEAN!ct.make(sp)
elseif as_pointer = bcn then
!TYPE_POINTER!ct.make(sp)
elseif as_string = bcn then
!TYPE_STRING!ct.make(sp)
elseif fgl /= Void then
from
i := 1
!!gl.with_capacity(fgl.count,1)
until
i > fgl.count
loop
fga := fgl.item(i)
if fga.constraint = Void then
!TYPE_ANY!t.make(sp)
else
t := fga.constraint
end
gl.add_last(t)
i := i + 1
end
!TYPE_GENERIC!ct.make(bc.name,gl)
else
!TYPE_CLASS!ct.make(bc.name)
end
run_class := ct.run_class
end
compute_run_feature_list_for(cn: CLASS_NAME) is
local
i: INTEGER
bc: BASE_CLASS
rc: RUN_CLASS
fcl: FEATURE_CLAUSE_LIST
do
from
i := parents.upper
rc := run_class
until
i < 0
loop
bc := parents.item(i)
fcl := bc.feature_clause_list
if fcl /= Void then
fcl.for_short(bc.name,sort,run_feature_list,rc,cn)
end
i := i - 1
end
end
sort_run_feature_list is
local
min, max, buble: INTEGER
moved: BOOLEAN
do
from
max := run_feature_list.upper
min := 0
moved := true
until
not moved
loop
moved := false
if max - min > 0 then
from
buble := min + 1
until
buble > max
loop
if gt(buble - 1,buble) then
run_feature_list.swap(buble - 1,buble)
moved := true
end
buble := buble + 1
end
max := max - 1
end
if moved and then max - min > 0 then
from
moved := false
buble := max - 1
until
buble < min
loop
if gt(buble,buble + 1) then
run_feature_list.swap(buble,buble + 1)
moved := true
end
buble := buble - 1
end
min := min + 1
end
end
end
gt(i,j: INTEGER): BOOLEAN is
local
n1, n2: STRING
do
n1 := run_feature_list.item(i).name.to_key
n2 := run_feature_list.item(j).name.to_key
Result := n1 > n2
end
fatal_bad_usage is
do
system_tools.bad_use_exit(Current)
end
is_valid_argument_for_ace_mode(arg: STRING): BOOLEAN is
-- Because of style options, this function always returns True.
-- Futhermore, this function is used for non ACE mode too.
do
Result := true
if is_version_flag(arg) then
elseif is_verbose_flag(arg) then
elseif is_help_flag(arg) then
elseif is_sort_flag(arg) then
elseif is_short_flag(arg) then
elseif is_case_insensitive_flag(arg) then
elseif is_no_warning_flag(arg) then
elseif is_no_style_warning_flag(arg) then
elseif arg.item(1) = '-' then
arg.remove_first(1)
format := arg
else
if arg.has_suffix(eiffel_suffix) then
arg.remove_suffix(eiffel_suffix)
end
ace.set_root_class_name_using(arg)
end
end
valid_argument_for_ace_mode: STRING is
"Only the -version, -help, -no_warning, and -no_style_warning are allowed in%N%
%ACE file mode.%N"
end -- SHORT -- The command.