Adding a new Xace option PreviousNext

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.

Updating the documentation

The first thing to do is to describe the new option in the documentation. All Xace options are specified in this file:

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.

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.

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:

NAME: <put the option name here>

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

	<some value> -> <some translated notation>
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:
ISE Ace:
	<some value> -> <some translated Ace notation>
	<some value> -> <some translated ECF notation>
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.

Option names and values

The name of the option should be declared in class ET_XACE_OPTION_NAMES. For example, if the name of the option is "assertion", then the following feature will be added:

assertion_name: STRING is "assertion"
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 assertion_code. The table option_codes 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.

Then, information about the new option should be added to class ET_XACE_OPTIONS. The first feature to add is declared_foo 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:

declared_foo: UT_TRISTATE
		-- Declared value for 'foo' option
When the option can have several simultaneous values, such as "debug_tag", the feature will look like that:
declared_foo: DS_HASH_SET [STRING]
		-- Declared values for 'foo' option
Otherwise it will look like that:
declared_foo: STRING
		-- Declared value for 'foo' option
Note that some option may expect some non-negative integer values. In that case the declaration will look like that:
declared_foo: INTEGER
		-- Declared value for 'foo' option
and its value will be set to -1 in the creation procedure of ET_XACE_OPTIONS.

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

For options whose values can be among a fixed set of possible values, a feature like the following will also be added to class ET_XACE_OPTIONS:

valid_dead_code_removal: DS_HASH_SET [STRING] is
		-- Valid values for 'dead_code_removal' option
		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)
		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
It will be used in assertions. The values inserted in the set are those that have been declared earlier in class ET_XACE_OPTION_NAMES.

There remains four features to be added to class ET_XACE_OPTIONS. Feature is_foo_declared indicates whether this option has been explicitly specified in the Xace file. Its implementation depends on the kind of option. Typically, having declared_foo set to Void is a good indication that this option has not been specified in the Xace file. The feature unset_foo will do what is necessary to make sure that is_foo_declared returns False. The feature foo will either return declared_foo when this option has been explicitly specifed in the Xace file, or default_foo otherwise. And finally, feature set_foo 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.

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 ET_XACE_OPTIONS when adding a new option.

Xace parser

The next step is to let the parser of Xace files recognize the new option. This is done in class ET_XACE_PARSER_SKELETON. In feature fill_options 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:

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)
		error_handler.report_boolean_expected_error (an_element, uc_value, a_value, a_position_table.item (an_element))
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:
when foo_code then
	if an_option.valid_foo.has (a_value) then
		an_option.set_foo (a_value)
		error_handler.report_wrong_attribute_value_error (an_element, uc_value, a_value, an_option.valid_foo, a_position_table.item (an_element))
And for unconstrained options, we will just call the feature set_foo directly.

Translation to other Eiffel configuration notations

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 ET_XACE_<notation>_GENERATOR needs to be updated. These classes will typically have features of the form print_options, print_cluster_options, print_class_options, print_feature_options or print_settings. Please have a look at them.

Gobo Eiffel toolset

If the new option is supported by the Gobo Eiffel toolset, then the classes ET_XACE_SYSTEM and ET_XACE_SYSTEM_PARSER will need to be updated accordingly.

Copyright 2010, Eric Bezault
Last Updated: 27 December 2016