class EL_OS_COMMAND_BASE_I
Basis for class EL_OS_COMMAND_I
note
description: "Basis for class ${EL_OS_COMMAND_I}"
author: "Finnian Reilly"
copyright: "Copyright (c) 2001-2022 Finnian Reilly"
contact: "finnian at eiffel hyphen loop dot com"
license: "MIT license (See: en.wikipedia.org/wiki/MIT_License)"
date: "2025-03-29 12:04:56 GMT (Saturday 29th March 2025)"
revision: "2"
deferred class
EL_OS_COMMAND_BASE_I
inherit
EVC_SERIALIZEABLE_AS_ZSTRING
rename
as_text as system_command
export
{NONE} all
undefine
context_item, has_variable
redefine
make_default, system_command
end
EVC_REFLECTIVE_EIFFEL_CONTEXT
rename
escaped_field as unescaped_field
undefine
make_default, new_getter_functions
end
EL_REFLECTIVELY_SETTABLE
rename
field_included as is_any_field,
foreign_naming as eiffel_naming
export
{NONE} all
undefine
is_equal
redefine
make_default, new_transient_fields
end
EL_COMMAND
EL_OS_DEPENDENT
EL_MODULE_DIRECTORY; EL_MODULE_EXECUTABLE; EL_MODULE_LIO; EL_MODULE_NAMING
EL_OS_COMMAND_CONSTANTS
EL_SHARED_OPERATING_ENVIRON
feature {NONE} -- Initialization
make_default
--
do
Precursor {EL_REFLECTIVELY_SETTABLE}
Precursor {EVC_SERIALIZEABLE_AS_ZSTRING}
end
feature -- Contract Support
template_has (name: READABLE_STRING_8): BOOLEAN
-- `True' if `template' has reference to variable `name'
local
index: INTEGER
do
across << "$", "${" >> as list until Result loop
if attached list.item as symbol and then attached (symbol + name) as name_reference then
index := template.substring_index (name_reference, 1)
if index > 0 then
index := index + name_reference.count
inspect symbol.count
when 2 then
Result := template.valid_index (index) implies template [index] = '}'
else
Result := template.valid_index (index) implies not template [index].is_alpha_numeric
end
end
end
end
end
feature {NONE} -- Factory
new_error: EL_ERROR_DESCRIPTION
do
create Result.make_code (Execution_environment.return_code)
end
new_temporary_file_path (a_extension: STRING): FILE_PATH
-- uniquely numbered temporary file in temporary area set by env label "TEMP"
do
Result := Temporary_path_format #$ [
Operating_environ.temp_directory_name, Executable.user_qualified_name,
new_temporary_name, a_extension
]
-- check if directory already exists with root ownership (perhaps created by installer program)
-- (Using sudo command does not mean that the user name changes to root)
if Result.parent.exists and then not File_system.is_writeable_directory (Result.parent) then
Result.set_parent_path (Result.parent.to_string + "-2")
end
Result := Result.next_version_path
end
new_temporary_name: ZSTRING
do
Result := generator
end
feature {NONE} -- Implementation
display (lines: LIST [ZSTRING])
-- display word wrapped command
local
current_working_directory, printable_line, prompt, blank_prompt: ZSTRING
max_width: INTEGER; words: EL_ZSTRING_SPLIT_INTERVALS; name: STRING
do
current_working_directory := Directory.current_working
if attached Naming.new_class_words (Current) as class_words then
class_words.remove_el_prefix
class_words.remove_suffix (IMP_COMMAND_suffix)
name := class_words.as_word_string
create blank_prompt.make_filled (' ', name.count)
prompt := name
end
max_width := 100 - prompt.count - 2
create printable_line.make (200)
across lines as line loop
line.item.replace_substring_all (current_working_directory, Variable_cwd)
line.item.left_adjust
create words.make (line.item, ' ')
from words.start until words.after loop
if words.item_count > 0 then
if not printable_line.is_empty then
printable_line.append_character (' ')
end
printable_line.append_substring (line.item, words.item_lower, words.item_upper)
if printable_line.count > max_width then
printable_line.remove_tail (words.item_count)
lio.put_labeled_string (prompt, printable_line)
lio.put_new_line
printable_line.wipe_out
printable_line.append_substring (line.item, words.item_lower, words.item_upper)
prompt := blank_prompt
end
end
words.forth
end
end
lio.put_labeled_string (prompt, printable_line)
lio.put_new_line
end
new_transient_fields: STRING
do
Result := Precursor + "[
, dry_run, getter_functions, internal_error_list, is_forked,
has_error, on_encoding_change, encoding_other, output_path, template_path
]"
end
on_error (error: EL_ERROR_DESCRIPTION)
do
end
system_command: ZSTRING
do
Result := Precursor
Result.left_adjust
end
feature {NONE} -- Evolicity reflection
get_boolean_option (field: EL_REFLECTED_BOOLEAN_REF): BOOLEAN_REF
do
Result := field.value (Current)
end
get_escaped_path (field: EL_REFLECTED_PATH): ZSTRING
do
Result := field.value (Current).escaped
end
getter_function_table: like getter_functions
--
do
create Result.make (11)
across field_list as list loop
if attached list.item as field and then not field.is_expanded then
if attached {EL_REFLECTED_PATH} field as path_field then
Result [field.name] := agent get_escaped_path (path_field)
elseif field.type_id = Class_id.EL_BOOLEAN_OPTION
and then attached {EL_REFLECTED_BOOLEAN_REF} field as option_field
then
Result [field.name + Enabled_suffix] := agent get_boolean_option (option_field)
end
end
end
end
feature {NONE} -- Deferred implementation
command_prefix: ZSTRING
-- For Windows to force unicode output using "cmd /U /C"
-- Empty in Unix
deferred
end
new_output_lines (file_path: FILE_PATH): EL_PLAIN_TEXT_LINE_SOURCE
require
path_exists: file_path.exists
deferred
end
null_redirection: ZSTRING
deferred
end
run_as_administrator (command_parts: EL_ZSTRING_LIST)
deferred
end
end