<?xml version="1.0"?> 

<!--
	description:

		"Adding a new Xace option"

	library: "Gobo Eiffel Tools Library"
	copyright: "Copyright (c) 2010-2016, Eric Bezault and others"
	license: "MIT License"
	date: "$Date$"
	revision: "$Revision$"
-->

<chapter xmlns="http://www.gobosoft.com/eiffel/gobo/documentation" id="tools/new_xace_option">
<chapterinfo>
	<copyright>
		<year>2010</year>
		<holder>Eric Bezault</holder>
	</copyright>
	<author>
		<firstname>Eric</firstname><surname>Bezault</surname>
	</author>
	<email>ericb@gobosoft.com</email>
	<date>27 December 2016</date>
</chapterinfo>

<title>Adding a new Xace option</title>

<para>
The following sections will describe step by step what needs to be done
in order to let the library recognize a new option in Xace.
</para>

<section><title>Updating the documentation</title>
<para>
The first thing to do is to describe the new option in the documentation.
All Xace options are specified in this file:
<blockquote>
	<filename>$GOBO/tool/gexace/doc/options.txt</filename>
</blockquote>
The file is divided in four sections: "System options", "Cluster options",
"Class options" and "Feature options". Note that some options are applicable
to several of these sections. This is for example the case for the option
'assertion' which can be set at the system level, at the cluster level or
at the class level. In that case the description of this option is repeated
in each applicable section.
</para>

<para>
There are three categories of options. Boolean options are options whose only
possible values are "true" or "false". For example 'multithreaded' is a boolean
option. Other options may have a fixed set of possible values. For example the
option 'garbage_collector' can only have one of the following values: "none",
"internal" or "boehm". The remaining options have no such constraints. This is
for example the case of the option 'exclude' which specifies the pathnames to
be ignored when looking for Eiffel files in clusters.
</para>

<para>
All these kinds of options are described thanks to the compulsory entries
"Name", "Values", "Default" and "Description", and optional "Note" entries.
Then follows a short description of how the given option is translated to
Eiffel compiler specific configuration notation. The template is as follows:
<blockquote><programlisting>
NAME: &lt;put the option name here&gt;

VALUES: &lt;possible values&gt;
DEFAULT: &lt;put the default value here, or just "no default"&gt;
DESCRIPTION: &lt;put the description here&gt;
NOTE: &lt;optional note. There might be several of them.&gt;

ISE:
	&lt;some value> -&gt; &lt;some translated notation&gt;
...
</programlisting></blockquote>
Note that if an Eiffel compiler suports several notations, the translation for
each notation should be specified. This is for example the case with ISE which
supports both Ace and ECF files. In that case the template will look something
like that:
<blockquote><programlisting>
ISE Ace:
	&lt;some value> -&gt; &lt;some translated Ace notation&gt;
ISE ECF:
	&lt;some value> -&gt; &lt;some translated ECF notation&gt;
</programlisting></blockquote>
The best thing to do is to have a look at already specified options as examples.
Please keep the options sorted in alphabetical order within each section of the
documentation for easier reference.
</para>
</section>

<section><title>Option names and values</title>
<para>
The name of the option should be declared in class <classname>ET_XACE_OPTION_NAMES</classname>.
For example, if the name of the option is "assertion", then the following feature will be added:
<blockquote><programlisting>
assertion_name: STRING is "assertion"
</programlisting></blockquote>
Each option is associated with a unique code which should be declared in the same class.
For the option "assertion", the feature to be added will be <featurename>assertion_code</featurename>.
The table <featurename>option_codes</featurename> should be updated accordingly. Don't forget
to increase the size of the table.
When the given option can have a fixed set of possible values, these values are also
listed in the class. Please keep all entries in each feature clause in alphabetic order.
</para>

<para>
Then, information about the new option should be added to class <classname>ET_XACE_OPTIONS</classname>.
The first feature to add is <featurename>declared_foo</featurename> where "foo" is the name of the option.
This represents the value for this option if explicitly specified in the Xace file. For boolean option, it will
look like that:
<blockquote><programlisting>
declared_foo: UT_TRISTATE
		-- Declared value for 'foo' option
</programlisting></blockquote>
When the option can have several simultaneous values, such as "debug_tag", the feature will look like that:
<blockquote><programlisting>
declared_foo: DS_HASH_SET [STRING]
		-- Declared values for 'foo' option
</programlisting></blockquote>
Otherwise it will look like that:
<blockquote><programlisting>
declared_foo: STRING
		-- Declared value for 'foo' option
</programlisting></blockquote>
Note that some option may expect some non-negative integer values. In that case the declaration will look
like that:
<blockquote><programlisting>
declared_foo: INTEGER
		-- Declared value for 'foo' option
</programlisting></blockquote>
and its value will be set to -1 in the creation procedure of <classname>ET_XACE_OPTIONS</classname>.
</para>

<para>
The next feature to add to class <classname>ET_XACE_OPTIONS</classname> is the feature
<featurename>default_foo</featurename> representing the default value for this option.
It will be of type <classname>BOOLEAN</classname> for boolean options,
<classname>INTEGER</classname> when the option can have non-negative integer values,
<classname>DS_HASH_SET [STRING]</classname> when the option can have several values
simultaneously, and <classname>STRING</classname> otherwise.
</para>

<para>
For options whose values can be among a fixed set of possible values, a feature like
the following will also be added to class <classname>ET_XACE_OPTIONS</classname>:
<blockquote><programlisting>
valid_dead_code_removal: DS_HASH_SET [STRING] is
		-- Valid values for 'dead_code_removal' option
	once
		create Result.make (5)
		Result.set_equality_tester (string_equality_tester)
		Result.put_last (options.none_value)
		Result.put_last (options.low_level_value)
		Result.put_last (options.feature_value)
		Result.put_last (options.class_value)
		Result.put_last (options.all_value)
	ensure
		valid_dead_code_removal_not_void: Result /= Void
		valid_dead_code_removal_not_empty: not Result.is_empty
		no_void_value: not Result.has_void
		-- all_lower: forall v in Result, v.is_lower
	end
</programlisting></blockquote>
It will be used in assertions. The values inserted in the set are those that have
been declared earlier in class <classname>ET_XACE_OPTION_NAMES</classname>.
</para>

<para>
There remains four features to be added to class <classname>ET_XACE_OPTIONS</classname>.
Feature <featurename>is_foo_declared</featurename> indicates whether this option
has been explicitly specified in the Xace file. Its implementation depends on the 
kind of option. Typically, having <featurename>declared_foo</featurename> set to
Void is a good indication that this option has not been specified in the Xace file.
The feature <featurename>unset_foo</featurename> will do what is necessary to make sure
that <featurename>is_foo_declared</featurename> returns False.
The feature <featurename>foo</featurename> will either return
<featurename>declared_foo</featurename> when this option has been explicitly specifed
in the Xace file, or <featurename>default_foo</featurename> otherwise. And finally,
feature <featurename>set_foo</featurename> will indicate that the value passed
as argument has been explicitly specified in the Xace file. It will either replace
any other previously specified value, or add it to the set of values when the
corresponding option can have several values simultaneously.
</para>

<para>
All these features should be kept in alphabetic order in their respective feature clauses.
It is recommended to have a look at the set of features for existing options of the same kind
in class <classname>ET_XACE_OPTIONS</classname> when adding a new option.
</para>
</section>

<section><title>Xace parser</title>
<para>
The next step is to let the parser of Xace files recognize the new option. This is
done in class <classname>ET_XACE_PARSER_SKELETON</classname>. In feature
<featurename>fill_options</featurename> there is a big inspect instruction
corresponding to all possible options that can be found in an Xace file. For
boolean option, the following will need to be added:
<blockquote><programlisting>
when foo_code then
	if is_true (a_value) then
		an_option.set_foo (True)
	elseif is_false (a_value) then
		an_option.set_foo (False)
	else
		error_handler.report_boolean_expected_error (an_element, uc_value, a_value, a_position_table.item (an_element))
	end
</programlisting></blockquote>
still assuming that the option name is "foo". For options whose values can only
be one of a fixed set of possible values, we will have that:
<blockquote><programlisting>
when foo_code then
	if an_option.valid_foo.has (a_value) then
		an_option.set_foo (a_value)
	else
		error_handler.report_wrong_attribute_value_error (an_element, uc_value, a_value, an_option.valid_foo, a_position_table.item (an_element))
	end
</programlisting></blockquote>
And for unconstrained options, we will just call the feature <featurename>set_foo</featurename> directly.
</para>
</section>

<section><title>Translation to other Eiffel configuration notations</title>
<para>
The tool gexace is able to translate Xace files to other configuration notations supported
by various Eiffel compilers, such as Ace files or ECF files. If the given option is supported
by the targetted notation, then the corresponding generator class
<classname>ET_XACE_&lt;notation&gt;_GENERATOR</classname> needs to be updated. These classes
will typically have features of the form <featurename>print_options</featurename>,
<featurename>print_cluster_options</featurename>,
<featurename>print_class_options</featurename>,
<featurename>print_feature_options</featurename> or
<featurename>print_settings</featurename>. Please have a look at them.
</para>
</section>

<section><title>Gobo Eiffel toolset</title>
<para>
If the new option is supported by the Gobo Eiffel toolset, then the classes
<classname>ET_XACE_SYSTEM</classname> and <classname>ET_XACE_SYSTEM_PARSER</classname>
will need to be updated accordingly.
</para>
</section>

</chapter>
