Re: Re: geant: notion of local variables
Eric Bezault <ericb-D6Qt/9opevxWk0Htik3J/[email protected]> Sat, 02 Feb 2008 14:22:32 +0100
| Newsgroups | gmane.comp.lang.eiffel.gobo.general |
|---|---|
| Message-ID | <[email protected]> |
Hi Jocelyn, Somehow I didn't receive the original message that you sent on January 31rst. I'm glad you copied it below. If Sven has no objection about this addition to geant, then I'm fine with it. Note that I didn't review your code below, but I guess that you know the code of geant better than I do these days. It has been a long time since we didn't hear from Sven in the Gobo mailing lists. Sven, are you still here? -- Eric Bezault mailto:ericb-D6Qt/9opevxWk0Htik3J/[email protected] http://www.gobosoft.com Jocelyn wrote: > Hi, > > Here is a potential patch to add local variable support to geant. > > Any comment ? > > Jocelyn > > On 1/31/2008 18:33 PM, Jocelyn wrote: >> Hi Gobo team >> >> Would this make sense to have "local" variables in geant scripts ? >> I think it would be nice, it would allow to make nicer scripts. >> >> I was wondering, anyone knows if this would be easy (and good idea) to >> introduce such "local" variable ? >> >> we could add <setlocal name="varname" value="val" /> and <unsetlocal >> name="varname" /> >> (maybe unsetlocal does not make sense .. since it is "local") >> pretty similar to <set .../> and <unset .../> >> >> I think this could be achieve without too much trouble, but I also >> know the inside of geant might be tricky related to variable, >> arguments, and so on ... >> >> Any comment ? >> Jocelyn >> >> >> >> >> > > > ---------- > > Index: command/geant_available_command.e > =================================================================== > --- command/geant_available_command.e (revision 6284) > +++ command/geant_available_command.e (working copy) > @@ -47,6 +47,9 @@ > variable_name: STRING > -- Name of variable to set > > + local_variable_name: STRING > + -- Name of local variable to set > + > true_value: STRING > -- Value to be set for variable named `variable_name' > -- in case `execute' evaluate a value of `True' > @@ -78,6 +81,17 @@ > variable_name_set: variable_name = a_variable_name > end > > + set_local_variable_name (a_variable_name: like local_variable_name) is > + -- Set `variable_name' to `a_variable_name'. > + require > + a_variable_name_not_void : a_variable_name /= Void > + a_variable_name_not_empty: a_variable_name.count > 0 > + do > + local_variable_name := a_variable_name > + ensure > + local_variable_name_set: local_variable_name = a_variable_name > + end > + > set_true_value (a_true_value: like true_value) is > -- Set `true_value' to `a_true_value'. > require > @@ -106,15 +120,23 @@ > -- Execute command. > local > a_from_file: STRING > + v: STRING > do > check is_file_executable: is_file_executable end > a_from_file := file_system.pathname_from_file_system (resource_name, unix_file_system) > > if file_system.file_exists (a_from_file) or else file_system.directory_exists (a_from_file) then > - project.variables.set_variable_value (variable_name, true_value) > + v := true_value > else > - project.variables.set_variable_value (variable_name, false_value) > + v := false_value > end > + > + if variable_name /= Void then > + project.variables.set_variable_value (variable_name, v) > + end > + if local_variable_name /= Void then > + project.current_target_locals.set_variable_value (local_variable_name, v) > + end > end > > end > Index: command/geant_exec_command.e > =================================================================== > --- command/geant_exec_command.e (revision 6284) > +++ command/geant_exec_command.e (working copy) > @@ -149,6 +149,7 @@ > if exit_code = 0 then > create a_string_interpreter.make > Project_variables_resolver.set_variables (project.variables) > + Project_variables_resolver.set_local_variables (project.current_target_locals) > a_string_interpreter.set_variable_resolver (Project_variables_resolver) > > fileset.execute > Index: command/geant_set_command.e > =================================================================== > --- command/geant_set_command.e (revision 6284) > +++ command/geant_set_command.e (working copy) > @@ -69,6 +69,13 @@ > -- Put variable in project variables pool. > do > project.trace (<<" [set] ", name, "=", value>>) > + if project.current_target.formal_arguments /= Void and then project.current_target.formal_arguments.has (name) then > + project.log (<<" [set] warning: conflict with argument variable %"", name, "%"">>) > + end > + if project.current_target_locals /= Void and then project.current_target_locals.has (name) then > + project.log (<<" [set] warning: conflict with local variable %"", name, "%"">>) > + end > + > project.variables.set_variable_value (name, value) > exit_code := 0 > end > Index: command/geant_setlocal_command.e > =================================================================== > --- command/geant_setlocal_command.e (revision 0) > +++ command/geant_setlocal_command.e (revision 0) > @@ -0,0 +1,81 @@ > +indexing > + > + description: > + > + "Setlocal commands" > + > + library: "Gobo Eiffel Ant" > + copyright: "Copyright (c) 2001, Sven Ehrke and others" > + license: "MIT License" > + date: "$Date$" > + revision: "$Revision$" > + > +class GEANT_SETLOCAL_COMMAND > + > +inherit > + > + GEANT_COMMAND > + > +create > + > + make > + > +feature -- Status report > + > + is_executable : BOOLEAN is > + -- Can command be executed? > + do > + Result := (name /= Void and then name.count > 0) and value /= Void > + ensure then > + name_not_void: Result implies name /= Void > + name_not_empty: Result implies name.count > 0 > + value_not_void: Result implies value /= Void > + end > + > +feature -- Access > + > + name: STRING > + -- Name of environment variable > + > + value: STRING > + -- Value of environment variable > + > +feature -- Setting > + > + set_name (a_name: like name) is > + -- Set `name' to `a_name'. > + require > + a_name_not_void: a_name /= Void > + a_name_not_empty: a_name.count > 0 > + do > + name := a_name > + ensure > + name_set: name = a_name > + end > + > + set_value (a_value: like value) is > + -- Set `value' to `a_value'. > + require > + a_value_not_void: a_value /= Void > + do > + value := a_value > + ensure > + value_set: value = a_value > + end > + > +feature -- Execution > + > + execute is > + -- Put variable in project variables pool. > + do > + project.trace (<<" [setlocal] ", name, "=", value>>) > + if project.current_target.formal_arguments /= Void and then project.current_target.formal_arguments.has (name) then > + project.log (<<" [set] warning: conflict with argument variable %"", name, "%"">>) > + end > + > + check current_locals_not_void: project.current_target_locals /= Void end > + project.current_target_locals.set_variable_value (name, value) > + exit_code := 0 > + end > + > +end > > Property changes on: command\geant_setlocal_command.e > ___________________________________________________________________ > Name: svn:keywords > + Author Date Id Revision > Name: svn:eol-style > + native > > Index: geant_project.e > =================================================================== > --- geant_project.e (revision 6284) > +++ geant_project.e (working copy) > @@ -54,6 +54,8 @@ > create a_tester > selected_targets.set_key_equality_tester (a_tester) > > + create {DS_ARRAYED_STACK [GEANT_TARGET]} targets_stack.make (10) > + > build_successful := True > ensure > variables_set: a_variables /= Void implies variables = a_variables > @@ -448,7 +450,9 @@ > else > a_execute_target := a_target > end > - current_target := a_execute_target > + > + targets_stack.force (a_execute_target) > + check current_target = a_execute_target end > if a_execute_target.project /= Current then > a_execute_target.project.execute_target (a_execute_target, a_arguments, a_force, a_polymorph) > else > @@ -456,9 +460,9 @@ > a_execute_target.execute > target_arguments_stack.remove > end > + targets_stack.remove > end > - > - current_target := old_current_target > + check current_target = old_current_target end > end > > feature -- Output > @@ -540,10 +544,49 @@ > > feature {GEANT_COMMAND} -- Access GEANT_COMMAND > > - current_target: GEANT_TARGET > + targets_stack: DS_STACK [GEANT_TARGET] > + -- Stack of targets > + > + current_target: GEANT_TARGET is > -- Currently executing target; > -- Set during processing `execute_target' > + do > + if not targets_stack.is_empty then > + Result := targets_stack.item > + end > + end > > +feature {GEANT_COMMAND, GEANT_INTERPRETING_ELEMENT} -- Access GEANT_INTERPRETING_ELEMENT > + > + current_target_locals: GEANT_VARIABLES is > + -- Locals of `current_target' > + local > + c: like current_target > + do > + c := current_target > + if c /= Void then > + Result := c.locals > + end > + end > + > + caller_target_locals: GEANT_VARIABLES is > + -- Locals of caller target > + local > + p, c: like current_target > + do > + if not targets_stack.is_empty then > + c := targets_stack.item > + targets_stack.remove > + if not targets_stack.is_empty then > + p := targets_stack.item > + if p /= Void then > + Result := p.locals > + end > + end > + targets_stack.force (c) > + end > + end > + > invariant > > name_not_void: name /= Void > Index: geant_project_variable_resolver.e > =================================================================== > --- geant_project_variable_resolver.e (revision 6284) > +++ geant_project_variable_resolver.e (working copy) > @@ -63,6 +63,14 @@ > end > end > > + if Result = Void then --and local_variables /= Void then > + -- Search local variables: > + local_variables.search (a_name) > + if local_variables.found then > + Result := local_variables.found_item > + end > + end > + > if Result = Void then > -- Search project variables: > variables.search (a_name) > @@ -133,6 +141,9 @@ > variables: GEANT_VARIABLES > -- Variables used for resolving > > + local_variables: GEANT_VARIABLES > + -- Local variables used for resolving > + > feature -- Status report > > has (a_name: STRING): BOOLEAN is > @@ -159,6 +170,12 @@ > Result := Commandline_variables.found > end > > + if not Result then --and local_variables /= Void then > + -- Search local project variables: > + local_variables.search (a_name) > + Result := local_variables.found > + end > + > if not Result then > -- Search project variables: > variables.search (a_name) > @@ -184,4 +201,12 @@ > variables_set: variables = a_variables > end > > + set_local_variables (a_variables: like local_variables) is > + -- Set `local_variables' to `a_variables'. > + do > + local_variables := a_variables > + ensure > + local_variables_set: local_variables = a_variables > + end > + > end > Index: geant_project_variables.e > =================================================================== > --- geant_project_variables.e (revision 6284) > +++ geant_project_variables.e (working copy) > @@ -39,9 +39,11 @@ > a_name: STRING > a_value: STRING > do > - precursor > + Precursor > -- Create built-in variables $GOBO_OS, $is_windows/$is_unix, $exe > Project_variables_resolver.set_variables (Current) > + Project_variables_resolver.set_local_variables (Void) > + > a_name := gobo_os_name > if not Project_variables_resolver.has (a_name) then > set_variable_value (a_name, Default_builtin_variables.value (a_name)) > Index: geant_shared_properties.e > =================================================================== > --- geant_shared_properties.e (revision 6284) > +++ geant_shared_properties.e (working copy) > @@ -33,8 +33,8 @@ > > KL_SHARED_FILE_SYSTEM > export {NONE} all end > - > > + > feature -- Access > > Commandline_variables: GEANT_VARIABLES is > @@ -142,7 +142,7 @@ > -- a_parent_project: GEANT_PROJECT > -- do > -- from > --- i := 1 > +-- i := 1 > -- until > -- i > system_parents.count or else Result > -- loop > @@ -171,7 +171,7 @@ > -- a_parent_project: GEANT_PROJECT > -- do > -- from > --- i := 1 > +-- i := 1 > -- until > -- i > system_parents.count or else Result > -- loop > @@ -270,7 +270,7 @@ > nice_string := False > end > end > - > + > if s.count > 0 then > if s.item (s.count) = a_delimiter then > s.keep_head (s.count - 1) > Index: geant_target.e > =================================================================== > --- geant_target.e (revision 6284) > +++ geant_target.e (working copy) > @@ -105,6 +105,7 @@ > end > end > > + create locals.make > end > > feature -- Access > @@ -244,6 +245,9 @@ > end > end > > + locals: GEANT_VARIABLES > + -- Local variables of Current target > + > feature -- Status report > > is_executed: BOOLEAN > @@ -493,6 +497,7 @@ > if xml_element.has_attribute_by_name (Dir_attribute_name) then > create a_string_interpreter.make > Project_variables_resolver.set_variables (project.variables) > + Project_variables_resolver.set_local_variables (project.caller_target_locals) > a_string_interpreter.set_variable_resolver (Project_variables_resolver) > a_new_target_cwd := a_string_interpreter.interpreted_string ( > xml_element.attribute_by_name (Dir_attribute_name).value.out) > @@ -514,6 +519,9 @@ > a_arguments := prepared_arguments_from_formal_arguments (a_arguments) > target_arguments_stack.force (a_arguments) > > + -- Prepare locals: > + create locals.make > + > -- Execute nested tasks: > cs := xml_element.new_cursor > from > @@ -609,6 +617,9 @@ > elseif STRING_.same_string (a_xml_element.name, Setenv_task_name) then > -- setenv > create {GEANT_SETENV_TASK} a_task.make (project, a_xml_element) > + elseif STRING_.same_string (a_xml_element.name, Setlocal_task_name) then > + -- setlocal > + create {GEANT_SETLOCAL_TASK} a_task.make (project, a_xml_element) > elseif STRING_.same_string (a_xml_element.name, Xslt_task_name) then > -- xslt > create {GEANT_XSLT_TASK} a_task.make (project, a_xml_element) > Index: parser/geant_element_names.e > =================================================================== > --- parser/geant_element_names.e (revision 6284) > +++ parser/geant_element_names.e (working copy) > @@ -214,6 +214,15 @@ > task_name_not_empty: Result.count > 0 > end > > + Setlocal_task_name: STRING is > + -- "setlocal" task name > + once > + Result := "setlocal" > + ensure > + task_name_not_void: Result /= Void > + task_name_not_empty: Result.count > 0 > + end > + > Xslt_task_name: STRING is > -- "xslt" task name > once > Index: parser/geant_interpreting_element.e > =================================================================== > --- parser/geant_interpreting_element.e (revision 6284) > +++ parser/geant_interpreting_element.e (working copy) > @@ -67,6 +67,8 @@ > do > -- TODO: improve efficiency: > Project_variables_resolver.set_variables (project.variables) > + Project_variables_resolver.set_local_variables (project.current_target_locals) > + > -- Set default execution conditions: > if_condition := true > unless_condition := false > @@ -104,22 +106,14 @@ > -- Value of attribue `an_attr_name' > local > a_string_interpreter: GEANT_STRING_INTERPRETER > - a_variable_resolver: GEANT_VARIABLES_VARIABLE_RESOLVER > do > Result := xml_element.attribute_by_name (an_attr_name).value > if Result.count > 0 then > create a_string_interpreter.make > - -- Search variable in arguments if any (TODO: make this more efficient) > - -- (NOTE: checking that the stack is not empty is only needed for GEANT startup): > - if target_arguments_stack.count > 0 then > - create a_variable_resolver.make > - a_string_interpreter.set_variable_resolver (a_variable_resolver) > - a_variable_resolver.set_variables (target_arguments_stack.item) > - Result := a_string_interpreter.interpreted_string (Result) > - end > > -- Search variable in project variables: > Project_variables_resolver.set_variables (project.variables) > + Project_variables_resolver.set_local_variables (project.current_target_locals) > a_string_interpreter.set_variable_resolver (Project_variables_resolver) > Result := a_string_interpreter.interpreted_string (Result) > end > Index: task/geant_available_task.e > =================================================================== > --- task/geant_available_task.e (revision 6284) > +++ task/geant_available_task.e (working copy) > @@ -62,6 +62,12 @@ > command.set_variable_name (a_value) > end > end > + if has_attribute (Local_variable_attribute_name) then > + a_value := attribute_value (Local_variable_attribute_name) > + if a_value.count > 0 then > + command.set_local_variable_name (a_value) > + end > + end > end > > feature -- Access > @@ -89,6 +95,15 @@ > atribute_name_not_empty: Result.count > 0 > end > > + Local_variable_attribute_name: STRING is > + -- Name of xml attribute for local_variable > + once > + Result := "local_variable" > + ensure > + attribute_name_not_void: Result /= Void > + atribute_name_not_empty: Result.count > 0 > + end > + > True_value_attribute_name: STRING is > -- Name of xml attribute for true_value > once > Index: task/geant_setlocal_task.e > =================================================================== > --- task/geant_setlocal_task.e (revision 0) > +++ task/geant_setlocal_task.e (revision 0) > @@ -0,0 +1,76 @@ > +indexing > + > + description: > + > + "Setlocal tasks" > + > + library: "Gobo Eiffel Ant" > + copyright: "Copyright (c) 2001, Sven Ehrke and others" > + license: "MIT License" > + date: "$Date$" > + revision: "$Revision$" > + > +class GEANT_SETLOCAL_TASK > + > +inherit > + > + GEANT_TASK > + rename > + make as task_make > + redefine > + command > + end > + > +create > + > + make > + > +feature {NONE} -- Initialization > + > + make (a_project: GEANT_PROJECT; an_xml_element: XM_ELEMENT) is > + -- Create a new task with information held in `an_element'. > + local > + a_value: STRING > + do > + create command.make (a_project) > + task_make (command, an_xml_element) > + -- name: > + if has_attribute (Name_attribute_name) then > + a_value := attribute_value (Name_attribute_name) > + if a_value.count > 0 then > + command.set_name (a_value) > + end > + end > + -- value: > + if has_attribute (Value_attribute_name) then > + a_value := attribute_value (Value_attribute_name) > + command.set_value (a_value) > + end > + end > + > +feature -- Access > + > + command: GEANT_SETLOCAL_COMMAND > + -- Setenv commands > + > +feature {NONE} -- Constants > + > + Name_attribute_name: STRING is > + -- "name" attribute name > + once > + Result := "name" > + ensure > + attribute_name_not_void: Result /= Void > + attribute_name_not_empty: Result.count > 0 > + end > + > + Value_attribute_name: STRING is > + -- Name of xml attribute for value > + once > + Result := "value" > + ensure > + attribute_name_not_void: Result /= Void > + atribute_name_not_empty: Result.count > 0 > + end > + > +end > > Property changes on: task\geant_setlocal_task.e > ___________________________________________________________________ > Name: svn:keywords > + Author Date Id Revision > Name: svn:eol-style > + native > > > > [Non-text portions of this message have been removed]