mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
774 lines
23 KiB
774 lines
23 KiB
Workitems for GPD parser:
|
|
----------------------
|
|
|
|
1) define data structures
|
|
a) optionextra data (see resolution options
|
|
as an example)
|
|
b) structures to hold data associated with defined keywords
|
|
|
|
|
|
2) harden the spec: for example what characters are allowed for
|
|
Symbols? What are the reserved chars and when
|
|
are they active?
|
|
|
|
3) implications for converter - what assumptions did Unidrv 4.0
|
|
make that need to be explicitly expressed in the GPD?
|
|
What data format differences will create conversion
|
|
problems? example: GPC used indexes to structures
|
|
a lot. These will no longer exist.
|
|
|
|
4) commands: we need a new set of commands and meta commands
|
|
that allow the GPD file to specify what is needed
|
|
to perform each task. Don't let driver
|
|
string together primitive commands to do this.
|
|
|
|
5) parsing and data storage constructs to accomodate
|
|
variable sized and structured data.
|
|
|
|
|
|
6) define parsing tasks.
|
|
|
|
|
|
--------------------------------------------
|
|
|
|
|
|
|
|
parsing tasks:
|
|
|
|
open file as memory? need to memcopy if *Includes exist.
|
|
|
|
*Include - insert contents of external file (nestable)
|
|
|
|
extracting included resources:
|
|
strings: we can add those to the heap.
|
|
icons: keep resource IDs and let UI code
|
|
extract the bitmaps when needed.
|
|
fontinfo: don't extract into GPD binary unless necessary.
|
|
|
|
issues of scope : redefinition of macros or globals.
|
|
may macros be defined/redefined inside of constructs?
|
|
if so how does this affect their scope? How does
|
|
the parser track this? Keep macros in a stack,
|
|
with each { pushing a bp marker onto a stack
|
|
and each } causing all macros defined since the { to
|
|
be cleared! Macros are resolved by looking at
|
|
the stack from newest to oldest, so if a macro has
|
|
been redefined, the newer redefinition will override
|
|
an older.
|
|
|
|
macro handling:
|
|
recognizing , converting hex substrings, storage in
|
|
temp buffers. Associating a scope (if needed.)
|
|
note: zhan specifies whitespace may bracket '='
|
|
|
|
|
|
|
|
forward references and resolution of.
|
|
|
|
Default initializers, reinitialization, global
|
|
initialization. Clarify these concepts and when
|
|
they occur. How does parser recognize them.
|
|
|
|
|
|
syntax definition: a set of rules for
|
|
the finite state machine.
|
|
Parsing methodology: not line based? maybe stream based?
|
|
|
|
character space, allowed characters for each syntax element,
|
|
special characters and their functions.
|
|
|
|
There will be lots of info stored in tables, like
|
|
lists of *Keywords, what type of values are allowed,
|
|
where the values will be stored, etc.
|
|
|
|
And dynamic lists like qualified names,
|
|
arrays of features.
|
|
|
|
Define the information needed, how it will be stored
|
|
and accessed.
|
|
|
|
|
|
Grouping constructs { and } when and where may they appear
|
|
how do they affect the syntax (substitute for newlines)
|
|
after which keywords, what state transition do they trigger?
|
|
|
|
*Feature
|
|
*Option
|
|
*Font
|
|
*UIGroup
|
|
*Switch / *Case
|
|
*Command
|
|
*Macros
|
|
*OEM
|
|
|
|
|
|
reconciliation of two concepts: syntax mirrors underlying
|
|
data structure to syntax allows user to define the
|
|
underlying data structure.
|
|
|
|
In general we can say the syntax mirrors the underlying data
|
|
but there are special operators and constructs which
|
|
can modify this default behavior and hence 'modify' the
|
|
effective format of the data.
|
|
|
|
|
|
concerns for a GPC to GPD converter.
|
|
---------------------------------------------------------------
|
|
Implementation of parser constructs:
|
|
|
|
How do we link everything
|
|
together?
|
|
|
|
even more parser constructs a generalized version of
|
|
our *group ing operators. The *switch construct can
|
|
be nested, and used almost anywhere, like
|
|
conditional macro constructs, it does not interfere
|
|
with the existing grouping. It does use the same
|
|
grouping operator {}, so you cannot have a switch statement
|
|
interwoven with other groups.
|
|
The *case group may contain one or more grouping constructs
|
|
in their entirety.
|
|
|
|
|
|
*switch:featureI
|
|
{
|
|
*case:optionA
|
|
{
|
|
*attribute:RASTER.*SpotDia:100
|
|
*OrderedCmd:drawdot
|
|
{
|
|
*invocation:"xlkdfow"
|
|
*OrderDependency:x y
|
|
}
|
|
}
|
|
*case:optionB
|
|
{
|
|
}
|
|
*case:*default
|
|
{
|
|
}
|
|
}
|
|
|
|
Note: only *case constructs allowed inside a *switch construct.
|
|
Almost anything is allowed inside a *case.
|
|
|
|
WRONG! only attributes and commands and FONTS
|
|
are allowed inside case constructs.
|
|
|
|
Note: the *switch and *case constructs serve to allow
|
|
attributes to be multivalued. For a specific configuration
|
|
you can 'evaluate' the *switch construct to see its
|
|
syntatical equivalent. That is the statements that
|
|
are actually executed.
|
|
|
|
Note: how do we implement the arbitrary complexity tree
|
|
that the switch construct permits?
|
|
Note all fields of internal structure would have to be mirrored
|
|
by a tag that says go consult tree for disposition of data.
|
|
|
|
|
|
a) decide what data gets to reside inside the optionextra structure.
|
|
b) decide what syntax we will use to make data multi-valued.
|
|
inside or outside of constructs?
|
|
|
|
*Feature:featureA
|
|
{
|
|
*Option:tat
|
|
{
|
|
standard attributes for this option
|
|
*attribute:RASTER.*
|
|
*Commands:RASTER.*Xmove:"lsdkfie"
|
|
*Switch:featureB
|
|
{
|
|
*case:option1
|
|
{
|
|
*standardattributes that are dependent on both
|
|
featureA and featureB
|
|
*attribute:RASTER.*SpotDia:100
|
|
}
|
|
*case:*default
|
|
{
|
|
*default values for attributes
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
merge switch constructs with *Feature/*Option constructs?
|
|
in the GPD syntax,
|
|
but regardless of the syntax, in the binary data, A
|
|
bunch of data structures of a type that is readable by the UI
|
|
is initialized at request time with the current configuration.
|
|
|
|
The source of all the data is a table mirroring
|
|
The data structures except where the data structures
|
|
have data the table has index/offset entries.
|
|
|
|
|
|
|
|
|
|
|
|
Wants a way to permit OEM customized data to be
|
|
stored in the binary structure. Do not attempt to
|
|
read special meanings into OEM section for backward
|
|
compatibility.
|
|
|
|
|
|
|
|
------
|
|
|
|
The simplest implementation of an arbitrary
|
|
treed data structure is to treat each data node in the
|
|
structure as not containing a value, but rather a tree
|
|
of values. Each node may have a different sized tree.
|
|
For example the node containing the modelname may have
|
|
a tree consisting of a pointer to the string.
|
|
On the other hand, the tree containg the spot diameter
|
|
may be 2 dimensional.
|
|
|
|
The tree is implemented by an array of structures
|
|
of the form:
|
|
|
|
struct TreeBranch
|
|
{
|
|
feature
|
|
option
|
|
DWORD nextOption ;
|
|
BOOL offsetmeans (NEXT_FEATURE, VALUE)
|
|
DWORD offset ;
|
|
}
|
|
|
|
No trees are shared between data nodes.
|
|
If a default initializer is supplied, this will appear
|
|
as feature #0 option 0 and appear in the front of the
|
|
list. So when the tree is searched for the current
|
|
config and this path does not exist, use the default
|
|
initializer.
|
|
|
|
|
|
|
|
the basic data element is that which is initialized by
|
|
a single statement. The tree shall point to a heap of
|
|
basic data elements. Each ptr shall point to just one
|
|
data element. Do not assume its an array of elements.
|
|
|
|
To minimize unecessary treeing, command structures
|
|
are treated as one unit.
|
|
|
|
Subfields of features need to be multi-valued.
|
|
(but currently the number and types of options will not change)
|
|
|
|
Subfields of options need to be multi-valued.
|
|
(command info inside options may be stored in the generic
|
|
command array!).
|
|
|
|
All commands and global attributes are treed.
|
|
Fonts etc. But the subfields of structures other than
|
|
feature and option are not treed. Thus the
|
|
nodes of the command tree are indicies to command
|
|
structures in an array of command structures.
|
|
Or offsets to the commands themselves. (to retain consistency
|
|
with other data.)
|
|
|
|
|
|
Tasks: define all data structures
|
|
and list functions and their purpose
|
|
in the goal of adding a data element
|
|
during parsing.
|
|
|
|
|
|
Default initializers, macro handling.
|
|
|
|
|
|
|
|
|
|
|
|
------ Installable option -----
|
|
|
|
The parser will synthesize a "configuration feature"
|
|
for every Installable option or feature. This
|
|
"configuration feature" tracks if the feature/option
|
|
is installed or not.
|
|
|
|
|
|
UI interface:
|
|
|
|
Installable Options:
|
|
UI constraints helper function will provide the
|
|
UI module with the info (for a given feature, which
|
|
options are disabled) needed to handle the
|
|
diabling/enabling of the installable option based
|
|
on the setting of the configuration feature associated
|
|
with the installable option.
|
|
|
|
InstallableFeature:
|
|
UI must be able to recognize an Installable Feature
|
|
since it must disable/enable it depending on the
|
|
state of the configuration feature. UI constraints
|
|
helper may return a special value to indicate this is
|
|
a disabled Installable Feature if the Feature is installed
|
|
it will treat the Feature as it would a normal feature
|
|
and provide info on the options.
|
|
|
|
Both:
|
|
|
|
UI must be able to identify the configuration features
|
|
and display them on the appropirate printer sticky property
|
|
page. Also these settings must be stored separately
|
|
from the doc sticky settings.
|
|
|
|
If User attempts to select a grayed out Feature or Option
|
|
UI must call the UI constraints helper function and
|
|
display an intelligble message based on the data returned
|
|
by the helper.
|
|
|
|
Tasks: define the UI constraints helper function.
|
|
There are several tasks:
|
|
|
|
a) given an option array from a devmode
|
|
check it for validity. If invalid, change some
|
|
settings to make everything consistent with
|
|
UI constraints.
|
|
|
|
b) given a feature index and the current options array,
|
|
return a boolean array indicating which options
|
|
are grayed out.
|
|
|
|
c) given a proposed option selection and the current options
|
|
array, explain what constraints the proposed option
|
|
conflicts with.
|
|
|
|
|
|
what parser does when encountering the *Installable
|
|
keyword in *Features construct:
|
|
|
|
a) synthesize a *Features construct that is used
|
|
to select whether the *Feature is installed or not.
|
|
Synthesize two options, "Installed" and "Not Installed".
|
|
This synthesized feature is called the configuration feature.
|
|
Establish a two way link between the configuration feature
|
|
and the *Feature that lead to its creation.
|
|
|
|
what parser does when encountering the *Installable
|
|
keyword in *Options construct:
|
|
|
|
a) synthesize a *Features construct that is used
|
|
to select whether the *Option is installed or not.
|
|
Synthesize two options, "Installed" and "Not Installed".
|
|
This synthesized feature is called the configuration feature.
|
|
Establish a two way link between the configuration feature
|
|
and the *Option that lead to its creation.
|
|
|
|
|
|
Tasks: add new fields to Features and Options that will
|
|
allow this link to be established.
|
|
|
|
sketch out code to parse and synthesize configration features.
|
|
|
|
|
|
|
|
To minimize updating of UI's version (snapshot)
|
|
of multi valued data, Parser supplies UI with
|
|
array of features marking those which if changed
|
|
can affect the snapshot. UI code can then call
|
|
the ssync function which returns an array of features
|
|
marking those which were affected.
|
|
|
|
Tasks: work out the specifics for this helper function.
|
|
What algorithm will you use to determine if the
|
|
snapshot needs to be updated? Which fields will be
|
|
updated?
|
|
|
|
|
|
|
|
-------
|
|
|
|
|
|
|
|
Implementation of switch inside Options and Features.
|
|
Switch and Case cannot enclose Options or Features.
|
|
|
|
Implementation of parsing in general
|
|
|
|
and Macros.
|
|
|
|
Data for UI code.
|
|
|
|
|
|
Command storage format.
|
|
OrderedCmds, simple commands.
|
|
|
|
Font info
|
|
|
|
UIGroup
|
|
|
|
Data Types.
|
|
|
|
|
|
-------------------------------------------------
|
|
|
|
Binary Data structures:
|
|
|
|
All internal data structures
|
|
are virtual. That is each element in the
|
|
structure actually points to a tree which points
|
|
to one or more nodes each containing a value
|
|
for that element which is valid under certain
|
|
conditions. (all values being mutually exclusive.)
|
|
Don't forget the default initializer. The one that exists
|
|
outside of any switch construct, which may in turn be overwritten
|
|
by the *Case:*Default entries.
|
|
|
|
|
|
|
|
The parser should provide a snapshot of all
|
|
GPD info for the control module to use.
|
|
Supply an entry pt. to allow control module to update
|
|
snapshot if devmode settings change like by ResetDC.
|
|
|
|
------
|
|
|
|
Implementation of *UIConstraints *Incompatible and *OrderDependency
|
|
see constraints for Installable options.
|
|
and NotUIConstraints and 2 parameter *InvalidCombinations
|
|
|
|
|
|
The option constraints imposed by *Constraints is stored in
|
|
a one dim array of contraint structures.
|
|
(also used to hold constraints defined by *InstalledConstrainsSelections
|
|
and *NotInstalledConstrainsSelections
|
|
in this case, feature may refer to the installed state of a feature
|
|
or option. Note also an installable option if not installed
|
|
will always constrain itself from being selected.)
|
|
|
|
{
|
|
WORD feature; // may reference an installable feature
|
|
WORD option ;
|
|
WORD next ; // 0xffff signifies end of constraint list.
|
|
}
|
|
|
|
|
|
The Constraints field in the options structure
|
|
may take on values like 0xffff to indicate this option
|
|
does not constrain any other . Otherwise this field contains
|
|
the index to start of constraints list for this option. The list is
|
|
interpreted as follows: if the option is selected, the following
|
|
list of options CANNOT be selected.
|
|
|
|
|
|
|
|
At parsing time, we must add two entries to the array for every
|
|
*constraints statement parsed since each statement is reflexive.
|
|
|
|
NotConstraints are parsed into multiple Constraints. Maybe
|
|
we can remove this construct since we have zhanw's LIST construct.
|
|
|
|
|
|
*InvalidCombinations:
|
|
|
|
|
|
{
|
|
WORD feature; // may reference an installable feature
|
|
WORD option ;
|
|
WORD nextElement ; // 0xffff signifies end of elements list.
|
|
WORD newCombination ; // 0xffff signifies no more constraints
|
|
// involving this element.
|
|
}INVALIDCOMBO ;
|
|
|
|
An element is a feature-option pair.
|
|
nextElement is the index to another INVALIDCOMBO structure
|
|
that contains another element which is incompatible with
|
|
the previous elements.
|
|
NewCombination points to the first element of another
|
|
invalidCombination list involving the element in question.
|
|
The first element in the new list is not necessarily the same
|
|
as the element in question.
|
|
|
|
Each option structure will contain an index to the
|
|
InvalidCombo array. A value of 0xffff indicates
|
|
this element is not involved in any invalidCombinations.
|
|
|
|
|
|
|
|
----- installable features and options ----
|
|
|
|
Whenever there are installable option or features
|
|
specified in the GPD file, the parser will create
|
|
a generic feature with two options "Installed" and
|
|
"Not Installed". The UI may display this set
|
|
of features during the printer sticky portion of setup.
|
|
This feature is also refered to as an "Installable Configuration
|
|
Feature" or a "synthesized feature".
|
|
|
|
Each installable option or feature structure
|
|
will have an index (say ConfigurationFeatureIndex)
|
|
that points to the synthesized feature.
|
|
|
|
The options array in the devmode should store the
|
|
state of the synthesized features as they
|
|
indicate whether the option is installed or not.
|
|
|
|
(ie: whether the env feeder is installed or not. Note this
|
|
is a separate bit of data from that indicating whether
|
|
the env feeder is Selected or not.)
|
|
|
|
|
|
|
|
If an option is marked *installable it will appear on
|
|
the selections UI as being enabled or grayed out.
|
|
If grayed out you can select it, else you cannot.
|
|
|
|
If all options in the feature are installable, there must
|
|
be one option that isn't. The default option will be
|
|
overridden if it points to an uninstalled option.
|
|
|
|
If a feature is marked installed, then all the options
|
|
enumerated there will be displayed just as if it were
|
|
a normal feature. If it is marked "Not Installed" then
|
|
the UI should consider the entire feature to be disabled.
|
|
There will still be a slot on the features array allocated
|
|
for its option selection however, but the control module
|
|
code should not access it.
|
|
|
|
-----
|
|
|
|
Constraints on Installation:
|
|
|
|
These are kept in a separate constraint array and
|
|
are defined by the keywords *InvalidInstallableCombination:
|
|
and *InstallRequires: .
|
|
The constraint array may only reference synthesized Features
|
|
indicies defining the configuration of installable options on the
|
|
printer.
|
|
|
|
The Constraints field in the option structure for
|
|
an Installable Configuration (synthesized) Feature will point to
|
|
this installConstraints array.
|
|
|
|
The InvalidCombo field will have no meaning for
|
|
an Installable Configuration Feature.
|
|
|
|
---------------------------------------------------------------------
|
|
|
|
Code emitting option invocations must check that the
|
|
Feature is Installed before emitting the strings.
|
|
|
|
Code checking for UI constraints may ignore entries
|
|
constraining Disabled Features.
|
|
|
|
Code evaluating all UI constraints must ignore effect
|
|
of Uninstalled Features.
|
|
Code displaying features must first check if the feature is
|
|
disabled.
|
|
|
|
-----
|
|
|
|
UIGroup: allowing the UI to group related features
|
|
together.
|
|
|
|
This may be implemented via A tree:
|
|
|
|
typedef struct
|
|
{
|
|
STRINGREF GroupName;
|
|
WORD NextGroup ; // (in same level)
|
|
WORD FirstSubGroups ;
|
|
BOOL SubGroupIsFeatureIndex ;
|
|
// set TRUE if there are no subgroups
|
|
// just a list of Features.
|
|
// this requires all Feature structures
|
|
// have a field called NextFeatureInGroup
|
|
// that holds the index of the next
|
|
// feature.
|
|
} GROUPTREE ;
|
|
|
|
lpGroupTree may be NULL if there are no grouping
|
|
constructs.
|
|
|
|
-------------------------------
|
|
|
|
Command storage format.
|
|
OrderedCmds, simple commands.
|
|
|
|
|
|
All Commands (regardless of the GPD syntax
|
|
used in their definition) will be stored in a structure
|
|
similiar to that shown below.
|
|
All command structures will be arranged as
|
|
a one dimensional array, accessible by an
|
|
array index. All Unidrv recognized commands
|
|
will be assigned a particular index value.
|
|
Other commands like option invocations may
|
|
be arbitrarily assigned index values outside
|
|
of the reserved range.
|
|
|
|
The reference to a command in the option structure
|
|
then becomes just a WORD - the index of the structure
|
|
containing that command.
|
|
|
|
Basic attributes for a command
|
|
based on Zhanw's GPD syntax.
|
|
|
|
typedef struct
|
|
{
|
|
STRINGREF invocation; // "binary string" %paramref "more binary string"
|
|
ORDERDEPENDENCY Order; // if defined, the command
|
|
// will end up enumerated in an order dependency list.
|
|
} BASIC_COMMAND
|
|
|
|
The invocation is of the form one or more binary strings
|
|
and parameter references concatenated together in any order.
|
|
White spaces may separate the binary strings from the parameter
|
|
reference.
|
|
(macros will have been resolved before storing the command.)
|
|
|
|
A binary string is of the form: any set of binary bytes
|
|
enclosed by double quotes. Note the % acts to escape itself
|
|
and the " in a binary string. Thus "%%" is really (%)
|
|
"%"" is really (") , "%%%"" is really (%"), "%a" is just (a).
|
|
A % preceeding any other character is ignored. All bytes between
|
|
the opening and closing " are part of the binary string.
|
|
|
|
A paramref is a % followed by one or more decimal digits representing
|
|
an index to the array of PARAMETERS.
|
|
Multiple PARAMETERS may be embedded into a command.
|
|
|
|
typedef struct
|
|
{
|
|
BYTE format; // The first letter after the %
|
|
BYTE digits; // only valid if format = 'd' or 'D'
|
|
BOOL MinUsed, MaxUsed , MaxRepeatUsed;
|
|
Long Min, Max ; // look here only if used.
|
|
DWORD MaxRepeat ;
|
|
|
|
WORD ValuesStack; // may contain refs to StandardVariables
|
|
// so Values may be composite of integer and boolean.
|
|
WORD OperatorStack; (Min, Max, +, -, *, / , MOD, HALT)
|
|
} PARAMETER
|
|
|
|
typedef struct
|
|
{
|
|
DWORD value;
|
|
BOOL valueIsSymbol ;
|
|
} VALUE ;
|
|
|
|
The value stack is an array of VALUEs.
|
|
The ValueStack field in PARAMETER is an index to the
|
|
an element in the Value stack. This value is considered
|
|
the top of the stack, the value at index n+1 is next on the stack
|
|
and so forth.
|
|
There is No end of stack indicator. You keep accessing the value
|
|
stack until the HALT operator is encountered.
|
|
Note if the value refers to an internal Unidrv variable
|
|
(valueIsSymbol == TRUE), you must use the current value of the
|
|
Unidrv varable.
|
|
|
|
The Operator Stack is simply an array of words.
|
|
Each operator is assigned an enumeration value.
|
|
Each operator starting from the top of the stack is
|
|
used to operate on the contents of the Value stack until
|
|
the HALT operator is encountered. The result on the
|
|
top of the value stack is formatted according to the
|
|
the format specifier and emitted in the command stream.
|
|
|
|
|
|
|
|
The orderDependency list is contained in an array of SEQUENCED_CMDS.
|
|
The structures in the array are arranged as 6 singly-linked
|
|
lists - one list for each section defined in the OrderDependency
|
|
construct. A command is referenced either by its Index in the
|
|
command array or if its an option invocation, by its FeatureIndex.
|
|
(If option invocation, the control module must determine
|
|
the correct option to emit. If its a pick many, it must
|
|
use the order specified in each option to emit the
|
|
options in the correct order.)
|
|
|
|
|
|
typedef struct
|
|
{
|
|
WORD IndexOfCommand ; (0xffff if not used)
|
|
WORD FeatureIndex ; (0xffff if not used)
|
|
WORD NextInSequence ;
|
|
}
|
|
SEQUENCED_CMDS
|
|
|
|
|
|
The following are indicies to the array of SEQUENCED_CMDS,
|
|
they point to the first Command to be emitted in each section.
|
|
|
|
WORD Job_Setup, Doc_Setup, Page_Setup, Page_Finish,
|
|
Doc_Finish, Job_Finish ;
|
|
|
|
----------------------------
|
|
|
|
Global Attributes: this refers to all
|
|
data not contained within *Feature, *Option constructs
|
|
or constructs not already discussed.
|
|
|
|
|
|
All Global Attributes will be stored in a single
|
|
structure and each element in the structure
|
|
will have a name similar to the description provided
|
|
in the GPD.
|
|
|
|
|
|
------------
|
|
|
|
Global attributes of type LIST()
|
|
will contain a WORD that indexes an array
|
|
of the proper data type.
|
|
|
|
Each element in the array will be
|
|
|
|
{
|
|
TYPE data ;
|
|
WORD nextItemInList;
|
|
} typeLIST_ELEMENT ;
|
|
|
|
where type is replaced by the required data type
|
|
WORDS, RECTS, POINTS etc. There will be one list
|
|
for each data type.
|
|
|
|
|
|
-----------------------------------------------
|
|
|
|
Parsing of variable data types:
|
|
is it a LIST or just one?
|
|
how do we anticipate a LIST appearing
|
|
in the middle of nowhere?
|
|
|
|
|
|
|
|
----------------------------
|
|
|
|
A note on use of *Switch/*Case constructs and nesting globals.
|
|
|
|
*Switch/*Case constructs may be used only within *Feature and
|
|
*Option constructs.
|
|
|
|
*Switch/*Case constructs may not contain *Option constructs.
|
|
|
|
Multiple *Switch/*Case constructs may be nested.
|
|
|
|
|
|
only Relocatable entries may be moved from their intrinsic
|
|
location to the inside of *Switch/*Case constructs.
|
|
|
|
Relocatable entries normally residing in a *Feature construct
|
|
may be moved inside a *Switch/*Case construct, but may not
|
|
be moved inside an *option construct.
|
|
|
|
|
|
Relocatable entries normally residing at the Root level
|
|
may be moved inside an *Option construct or inside a *Switch/*Case
|
|
construct that resides inside an *Option construct.
|
|
Zhanbing also wants relocateable Root entries to be placed inside
|
|
a *Switch/*Case construct that is at the root level.
|
|
|
|
Examples of non-relocatable entries include
|
|
any entries defining constraints, *Feature, *Option.
|
|
|
|
|
|
Note: making commands multi-valued implies OrderDependencies
|
|
must be resolved at runtime!
|
|
|