Difference between revisions of "V4 DB Record Instance Syntax"

From EPICSWIKI
 
(12 intermediate revisions by 2 users not shown)
Line 1: Line 1:
: '''This page still being worked on...'''
2005-11-02 MRK


The syntax used for record instances has to change in EPICS V4, since we now have to support structured data. While it would have been possible to modify the V3 syntax to allow for this, a complete redesign of the syntax has been done to help improve parsing, and to provide commonality between the syntax of a DB file and the string representation of structured data values passed through Channel Access.
= Overview =
 
 
The syntax used for record instances has to change in EPICS V4,
since we now have to support structured data.
A complete redesign of the syntax has been done to help improve parsing, and to provide commonality between the syntax of a DB file and the string representation of structured data values passed through Channel Access.
 
<b>NOTE:</b> See the note at the beginning of the "V4 DBD Statement Syntax"
concerning the syntax for link and struct fields.
 
= Document Conventions =


This syntax is presented below in the form of a grammar. The conventions I'm using are as follows:
This syntax is presented below in the form of a grammar. The conventions I'm using are as follows:
Line 7: Line 17:
;''symbolBeingDefined:''
;''symbolBeingDefined:''
: ''otherSymbol''
: ''otherSymbol''
: ''alternateSymbol'' <tt>literal</tt>
: ''alternateSymbolFollowedBy'' <tt>literal</tt>
: ''one of:'' <tt>list of posible literal values</tt>


= General Symbols =


These symbols are used but not defined in the grammar:
= Common Symbols =


;''integerConstant:''
The symbols described in this section are used in the grammar, but may be implemented as lexical tokens.
;''floatingConstant:''
: Standard format numbers


;''identifier:''
;''identifier:''
: A legal C99 identifier. Note that C99 permits implementations to allow extended characters to be used in identifiers, but does not require it, so the use of extended characters may reduce portability and is not recommended.
: A legal C99 identifier. Note that C99 permits implementations to allow extended characters to be used in identifiers, but does not require it, so the use of extended characters may reduce portability and is not recommended.
== Integer Constants ==
;''integerConstant:''
: ''positiveInteger''
;''positiveInteger:''
: ''octalConstant''
: ''hexConstant''
: ''decimalConstant''
;''octalConstant:''
: <tt>0</tt>
: ''octalConstant'' ''octalDigit''
;''octalDigit:''
: ''one of:'' <tt>0-7</tt>
;''hexConstant:''
: <tt>0x</tt> ''hexDigit''
: <tt>0X</tt> ''hexDigit''
: ''hexConstant'' ''hexDigit''
;''hexDigit:''
: ''one of:'' <tt>0-9 a-f A-F</tt>
;''decimalConstant:''
: ''one of:'' <tt>1-9</tt>
: ''decimalConstant'' ''decimalDigit''
;''decimalDigit:''
: ''one of:'' <tt>0-9</tt>
This was meant to be a description of the C99 standard integer representation, but I made it up myself so it may be flawed.  Note that we will not accept the C99 numeric suffixes u/U and l/L since (unlike a C compiler) we know the type of the number we're expecting.
== Floating Point Constants ==
;''realConstant:''
:'' positiveReal''
: <tt>-</tt> ''positiveReal''
;''positiveReal:''
: ''digitSequence''
: ''digitSequence'' <tt>.</tt>
: ''digitSequence'' <tt>.</tt> ''exponentPart''
: ''digitSequence'' <tt>.</tt> ''digitSequence''
: ''digitSequence'' <tt>.</tt> ''digitSequence'' ''exponentPart''
: <tt>.</tt> ''digitSequence''
: <tt>.</tt> ''digitSequence'' ''exponentPart''
: ''digitSequence'' ''exponentPart''
;''digitSequence:''
: ''decimalDigit''
: ''digitSequence'' ''decimalDigit''
;''exponentPart:''
: <tt>e</tt> ''signedExponent''
: <tt>E</tt> ''signedExponent''
;''signedExponent:''
: <tt>-</tt> ''digitSequence''
: <tt>+</tt> ''digitSequence''
: ''digitSequence''
In ANSI C source code, a sequence of decimal digits with neither a decimal point nor an exponent is an integer constant, not a floating-point constant.  We will permit this however, since we always know the field type in advance.
== Boolean Constants ==
We can afford to be generous in what we accept as a boolean value:
;''booleanConstant:''
: ''booleanTrue''
: <tt>"</tt> ''booleanTrue'' <tt>"</tt>
: ''booleanFalse''
: <tt>"</tt> ''booleanFalse'' <tt>"</tt>
;''booleanTrue:''
: ''one of:'' <tt>1 T TRUE t true True Y YES Yes y yes</tt>
;''booleanFalse:''
: ''one of:'' <tt>0 F FALSE f false False N NO No n no</tt>
'''I'm proposing all these possibilities for true/false as they are all obvious in meaning, and will allow a CA Put of any of these strings to a boolean field. We might even want to allow registration of boolean strings in other languages...'''
== String Constants ==


;''stringConstant:''
;''stringConstant:''
Line 29: Line 122:
: ''simpleEscapeSequence''
: ''simpleEscapeSequence''
: ''octalEscapeSequence''
: ''octalEscapeSequence''
: ''hexadecimalEscapeSequence''
: ''hexEscapeSequence''
: ''universalCharacterName''
: ''universalCharacterName''


;''simpleEscapeSequence:''
;''simpleEscapeSequence:''
: ''one of:'' <tt>\ \" \? \\ \a \b \f \n \r \t \v</tt>
: ''one of:'' <tt>\' \" \? \\ \a \b \f \n \r \t \v</tt>


;''octalEscapeSequence:''
;''octalEscapeSequence:''
Line 40: Line 133:
: <tt>\</tt> ''octalDigit'' ''octalDigit'' ''octalDigit''
: <tt>\</tt> ''octalDigit'' ''octalDigit'' ''octalDigit''


;''octalDigit:''
;''hexEscapeSequence:''
: ''one of:'' <tt>0 1 2 3 4 5 6 7</tt>
 
;''hexadecimalEscapeSequence:''
: <tt>\x</tt> ''hexDigit''
: <tt>\x</tt> ''hexDigit''
: ''hexadecimalEscapeSequence'' ''hexDigit''
: ''hexEscapeSequence'' ''hexDigit''


;''hexDigit:''
Note: C99 does not limit the number of hexadecimal digits that can appear in a ''hexEscapeSequence'', but it does state that the behaviour is undefined if the resulting character value exceeds that of the largest character.
: ''one of:'' <tt>0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F</tt>


;''universalCharacterName:''
;''universalCharacterName:''
Line 56: Line 145:
;''hexQuad:''
;''hexQuad:''
: ''hexDigit'' ''hexDigit'' ''hexDigit'' ''hexDigit''
: ''hexDigit'' ''hexDigit'' ''hexDigit'' ''hexDigit''
The following symbols are like identifier, but may have a different set of legal characters TBD (but which cannot include space).
;''recordName:''
: '''Currently record names may contain <tt>A-Z a-z _ - ; : < > [ ]</tt>. We should probably allow non-ASCII Unicode/UTF-8 characters, but no new ASCII characters.'''
;''linkType:''
;''deviceType:''
: '''I'd like these two to have to be valid C99 identifiers, but we could probably add some other ASCII characters if desired. No spaces, brackets or braces, for syntax reasons.'''
We could afford to be generous in what we accept as a boolean value:
;''booleanConstant:''
: ''booleanTrue''
: <tt>"</tt> ''booleanTrue'' <tt>"</tt>
: ''booleanFalse''
: <tt>"</tt> ''booleanFalse'' <tt>"</tt>
;''booleanTrue:''
: ''one of:'' <tt>1 T TRUE True t true Y YES Yes y yes</tt>
;''booleanFalse:''
: ''one of:'' <tt>0 F FALSE False f false N NO No n no</tt>




= Database File =
= Database File =


I need to define these, which are really preprocessor objects:
This section will eventually define what can appear in a .db file.  That currently means:


* record instances
* comments
* comments
* substitution macros
* macro instances, including where they will be allowed
* templates and ports
* template files and substitution macro definitions
* port definitions for template instances
* data for tools such as VDCT, that will not be discarded by .db processing tools.


The templates, macros and ports design should be very similar to the ideas produced for R3.14 VDCT templates.


= Record Instances =
= Record Definitions =


;''recordDefinition:''
;''recordDefinition:''
Line 97: Line 167:
;''recordType:''
;''recordType:''
: ''identifier''
: ''identifier''
;''recordName:''
: ''recordNameChar''
: ''recordName'' ''recordNameChar''
;''recordNameChar:''
: ''one of:'' <tt>0-9 A-Z a-z _ - : ; < > [ ]</tt>
: Any Unicode/UTF-8 character outside of the Basic Latin set
This extends the character set available to a V3 record name, adding all possible multi-byte characters.  However, EPICS sites are strongly advised to confirm that such record names can be processed using all of their database and CA client tools before actually making use of this particular extension.


;''recordBody:''
;''recordBody:''
Line 102: Line 182:
: ''recordBody'' ''recordBodyItem''
: ''recordBody'' ''recordBodyItem''


Record definitions will look very similar to a C99 structure definition with initialization in EPICS V4. For example:
Record instance definitions in EPICS V4 look very similar to a C99 structure definition with initialization. For example:


   ai foo:bar:temperature = {
   ai foo:bar:temperature = {
Line 108: Line 188:
   }
   }


Inside the body of the record definition, there are three possible kinds of statements, similar to a C assignment statement.  Note these statements must all be terminated with a semi-colon (which is different from inside a struct).
Inside the body of the record definition, there are three possible kinds of statements, similar to a C assignment statement.  Note these statements must be terminated with a semi-colon (which is different from inside a struct).  The reason for this difference is to prevent database instance files from becoming dependent on the order of fields in a record; if we permit record instances to be created from a single comma-separated list of field values without the field names, it could lead to significant confusion if the field order ever changes.


;''recordBodyItem:''
;''recordBodyItem:''
Line 114: Line 194:
: ''fieldAssignment''
: ''fieldAssignment''
: ''extraFieldAssigment''
: ''extraFieldAssigment''
== Information Fields ==


;''infoAssignment:''
;''infoAssignment:''
Line 127: Line 209:
   info restorePhase = "1";
   info restorePhase = "1";
   info "my favourite things" = "raindrops on roses";
   info "my favourite things" = "raindrops on roses";
== Field Assignment ==


;''fieldAssignment:''
;''fieldAssignment:''
Line 136: Line 220:
;''initializer:''
;''initializer:''
: ''constant''
: ''constant''
: <tt>{</tt> ''structAssignmentList'' <tt>}</tt>
: ''structInitializer''
: <tt>{</tt> ''arrayAssignmentList'' <tt>}</tt>
: ''arrayInitializer''
: ''arrayType'' <tt>{</tt> ''arrayAssignmentList'' <tt>}</tt>
: ''linkInitializer''
: <tt>[</tt> ''arrayCapacity'' <tt>] {</tt> ''arrayAssignmentList'' <tt>}</tt>
 
: ''arrayType'' <tt>[</tt> ''arrayCapacity'' <tt>] {</tt> ''arrayAssignmentList'' <tt>}</tt>
;''initializerList:''
: ''linkType'' <tt>{</tt> ''structAssignmentList'' <tt>}</tt>
: ''initializer''
: ''deviceType'' <tt>{</tt> ''structAssignmentList'' <tt>}</tt>
: ''initializerList'' <tt>,</tt> ''initializer''
 
The ''initializer'' in a field assignment is also the exact same syntax that will be used when converting a string value from a CA client for example into a field value that is being put into a field.
 
=== Basic and Enumerated Initializers ===


;''constant:''
;''constant:''
: ''booleanConstant''
: ''booleanConstant''
: ''integerConstant''
: ''integerConstant''
: ''floatingConstant''
: ''realConstant''
: ''stringConstant''
: ''stringConstant''


The syntax for setting field values depends on the data type represented by fieldName.  Basic types (numeric or string) should need no comment other than to note that numeric values should not be given inside quotes:
The syntax for the field initializer depends on the data type represented by fieldName.  Basic types (numeric or string) should need no comment other than to note that values for numeric fields must not be given inside quotes (unlike EPICS V3).  Menu field values may be given as either a string or an integer. For enum fields, if the related field that contains the strings is defined first, the enum field may be specified using a string; otherwise it can only be set using an integer value.


Examples:
   ai foo:bar:temperature = {
   ai foo:bar:temperature = {
       inputSmoothing = 0.98;
       inputSmoothing = 0.98;
       invalidValue = 1000;
       invalidValue = 1000;
       units = "Celcius";
       units = "Celcius";
      scan = "Interrupt";
       ...
       ...
   }
   }
=== Structure Initializers ===
;''structInitializer:''
: <tt>{</tt> ''structAssignmentList'' <tt>}</tt>


;''structAssignmentList:''
;''structAssignmentList:''
Line 163: Line 259:
: ''fieldName'' <tt>=</tt> ''initializerList''
: ''fieldName'' <tt>=</tt> ''initializerList''
: ''structAssignmentList'' <tt>;</tt> ''fieldName'' <tt>=</tt> ''initializerList''
: ''structAssignmentList'' <tt>;</tt> ''fieldName'' <tt>=</tt> ''initializerList''
;''initializerList:''
: ''initializer''
: ''initializerList'' <tt>,</tt> ''initializer''


Initializers for a structure field look similar to a nested record body, but the rules are slightly different:
Initializers for a structure field look similar to a nested record body, but the rules are slightly different:
Line 174: Line 266:
For example:
For example:


   ai foo:bar:temperature = {
   ai foo:temperature:sensor = {
       linearConvert = {
       linearConvert = {
           mode = "Linear";
           mode = "Linear";
Line 183: Line 275:
   }
   }


=== Link Initializer ===
;''linkInitializer:''
: ''support(choiceName) supportStructName'' <tt>{</tt> ''structAssignmentList'' <tt>}</tt>
;''choiceName:''
: ''identifier''
;''supportStructName:''
: ''identifier''
These select a particular link support and interface for the field, and set its address according to the structure type defined for that link type.
  calcout foo:temperature:controller = {
      block = true
      output = support(outputLink) OutputLink{
                pvname = "fum:baz:heater";
                process = true;
                wait = true;
      }
      input = [2] {
          {  link = {
                  support(monitorLink) MonitorLink{
                      pvname = "foo:temperature:setpoint";
                      process = false
                  }
              }
          }
          {  block=true
              link = {
                  support(inputLink) InputLink {
                      pvname = "foo:temperature:sensor";
                      process = true;
                      wait = true;
                      inheritSeverity = true
                  }
              }
          }
      };
      expression = "(B - A) > 0";
      ...
  }
  mbbi foo:bar:door = {
      input = support(acro9440) VME{0, 5};
      ...
  }
<b>QUESTION</b> There is nothing that allows a DVT to prompt a user
with a valid set if support for a particular link. Should there be?
=== Array Initializers ===
;''arrayInitializer:''
: <tt>{</tt> ''arrayAssignmentList'' <tt>}</tt>
: ''arrayType'' <tt>{</tt> ''arrayAssignmentList'' <tt>}</tt>
: <tt>[</tt> ''arrayCapacity'' <tt>] {</tt> ''arrayAssignmentList'' <tt>}</tt>
: ''arrayType'' <tt>[</tt> ''arrayCapacity'' <tt>] {</tt> ''arrayAssignmentList'' <tt>}</tt>


;''arrayAssignmentList:''
;''arrayAssignmentList:''
Line 190: Line 341:


;''arrayType:''
;''arrayType:''
: <tt>bool</tt>
: ''one of:'' <tt>bool</tt> <tt>int16</tt> <tt>uint16</tt> <tt>int32</tt> <tt>uint32</tt>
: <tt>int16</tt>
: ''one of:'' <tt>float32</tt> <tt>float64</tt> <tt>octet</tt> <tt>string</tt>
: <tt>uint16</tt>
: <tt>int32</tt>
: <tt>uint32</tt>
: <tt>float32</tt>
: <tt>float64</tt>
: <tt>octet</tt>
: <tt>string</tt>


;''arrayCapacity:''
;''arrayCapacity:''
: ''integerConstant''
: ''integerConstant''
: ''integerConstant'' <tt>,</tt> ''arrayCapacity''
: ''arrayCapacity'' <tt>,</tt> ''integerConstant''


Need some comments here about array initialization...
If the definition of the array field being set did not do so, an array field initialization must include the size of the array and/or the type of the data stored in it. Inside the braces data values are given in a comma-separated list; the index can also be set to initialize individual values, and any mixture of the two can be used as desired:


  mbbi foo:bar:door = {
      stateNames = [4] {"Broken", "Closed", "Open", "Moving"};
      stateSeverity = [4] {"Major"; [3] = "Minor"};
      ...
  }


;''extraFieldAssigment:''
For multi-dimensional arrays, data values can only appear inside the inner-most sets of braces, although index settings are permitted outside of these.  These two definitions give the same result:
: ''extraField'' <tt>=</tt> ''extraInitializer'' <tt>;</tt>


This section not yet completed.
  matrix identity1 = {
      value = float32 [3,3] { {1, 0, 0}, {0, 1, 0}, {1, 0, 0}};
  }
  matrix identity2 = {
      value = float32 [3,3] { {1}, {[1] = 1}, {[2] = 1}};
  }

Latest revision as of 19:50, 2 November 2005

2005-11-02 MRK

Overview

The syntax used for record instances has to change in EPICS V4, since we now have to support structured data. A complete redesign of the syntax has been done to help improve parsing, and to provide commonality between the syntax of a DB file and the string representation of structured data values passed through Channel Access.

NOTE: See the note at the beginning of the "V4 DBD Statement Syntax" concerning the syntax for link and struct fields.

Document Conventions

This syntax is presented below in the form of a grammar. The conventions I'm using are as follows:

symbolBeingDefined:
otherSymbol
alternateSymbolFollowedBy literal
one of: list of posible literal values


Common Symbols

The symbols described in this section are used in the grammar, but may be implemented as lexical tokens.

identifier:
A legal C99 identifier. Note that C99 permits implementations to allow extended characters to be used in identifiers, but does not require it, so the use of extended characters may reduce portability and is not recommended.

Integer Constants

integerConstant:
positiveInteger
positiveInteger:
octalConstant
hexConstant
decimalConstant
octalConstant:
0
octalConstant octalDigit
octalDigit:
one of: 0-7
hexConstant:
0x hexDigit
0X hexDigit
hexConstant hexDigit
hexDigit:
one of: 0-9 a-f A-F
decimalConstant:
one of: 1-9
decimalConstant decimalDigit
decimalDigit:
one of: 0-9

This was meant to be a description of the C99 standard integer representation, but I made it up myself so it may be flawed. Note that we will not accept the C99 numeric suffixes u/U and l/L since (unlike a C compiler) we know the type of the number we're expecting.

Floating Point Constants

realConstant:
positiveReal
- positiveReal
positiveReal:
digitSequence
digitSequence .
digitSequence . exponentPart
digitSequence . digitSequence
digitSequence . digitSequence exponentPart
. digitSequence
. digitSequence exponentPart
digitSequence exponentPart
digitSequence:
decimalDigit
digitSequence decimalDigit
exponentPart:
e signedExponent
E signedExponent
signedExponent:
- digitSequence
+ digitSequence
digitSequence

In ANSI C source code, a sequence of decimal digits with neither a decimal point nor an exponent is an integer constant, not a floating-point constant. We will permit this however, since we always know the field type in advance.

Boolean Constants

We can afford to be generous in what we accept as a boolean value:

booleanConstant:
booleanTrue
" booleanTrue "
booleanFalse
" booleanFalse "
booleanTrue:
one of: 1 T TRUE t true True Y YES Yes y yes
booleanFalse:
one of: 0 F FALSE f false False N NO No n no

I'm proposing all these possibilities for true/false as they are all obvious in meaning, and will allow a CA Put of any of these strings to a boolean field. We might even want to allow registration of boolean strings in other languages...

String Constants

stringConstant:
" escapedCharacterList "
escapedCharacterList:
A series of characters, using the C99 escapeSequence syntax defined below:
escapeSequence:
simpleEscapeSequence
octalEscapeSequence
hexEscapeSequence
universalCharacterName
simpleEscapeSequence:
one of: \' \" \? \\ \a \b \f \n \r \t \v
octalEscapeSequence:
\ octalDigit
\ octalDigit octalDigit
\ octalDigit octalDigit octalDigit
hexEscapeSequence:
\x hexDigit
hexEscapeSequence hexDigit

Note: C99 does not limit the number of hexadecimal digits that can appear in a hexEscapeSequence, but it does state that the behaviour is undefined if the resulting character value exceeds that of the largest character.

universalCharacterName:
\u hexQuad
\U hexQuad hexQuad
hexQuad:
hexDigit hexDigit hexDigit hexDigit


Database File

This section will eventually define what can appear in a .db file. That currently means:

  • record instances
  • comments
  • macro instances, including where they will be allowed
  • template files and substitution macro definitions
  • port definitions for template instances
  • data for tools such as VDCT, that will not be discarded by .db processing tools.

The templates, macros and ports design should be very similar to the ideas produced for R3.14 VDCT templates.

Record Definitions

recordDefinition:
recordType recordName = { recordBody }
recordType:
identifier
recordName:
recordNameChar
recordName recordNameChar
recordNameChar:
one of: 0-9 A-Z a-z _ - : ; < > [ ]
Any Unicode/UTF-8 character outside of the Basic Latin set

This extends the character set available to a V3 record name, adding all possible multi-byte characters. However, EPICS sites are strongly advised to confirm that such record names can be processed using all of their database and CA client tools before actually making use of this particular extension.

recordBody:
recordBodyItem
recordBody recordBodyItem

Record instance definitions in EPICS V4 look very similar to a C99 structure definition with initialization. For example:

  ai foo:bar:temperature = {
      ...
  }

Inside the body of the record definition, there are three possible kinds of statements, similar to a C assignment statement. Note these statements must be terminated with a semi-colon (which is different from inside a struct). The reason for this difference is to prevent database instance files from becoming dependent on the order of fields in a record; if we permit record instances to be created from a single comma-separated list of field values without the field names, it could lead to significant confusion if the field order ever changes.

recordBodyItem:
infoAssignment
fieldAssignment
extraFieldAssigment

Information Fields

infoAssignment:
info infoName = stringConstant ;
infoName:
identifier
stringConstant

Info items provide additional configuration data about this record that can be accessed by other software running on the IOC.

  info savePeriod = "30.0";
  info restorePhase = "1";
  info "my favourite things" = "raindrops on roses";

Field Assignment

fieldAssignment:
fieldName = initializer ;
fieldName:
identifier
initializer:
constant
structInitializer
arrayInitializer
linkInitializer
initializerList:
initializer
initializerList , initializer

The initializer in a field assignment is also the exact same syntax that will be used when converting a string value from a CA client for example into a field value that is being put into a field.

Basic and Enumerated Initializers

constant:
booleanConstant
integerConstant
realConstant
stringConstant

The syntax for the field initializer depends on the data type represented by fieldName. Basic types (numeric or string) should need no comment other than to note that values for numeric fields must not be given inside quotes (unlike EPICS V3). Menu field values may be given as either a string or an integer. For enum fields, if the related field that contains the strings is defined first, the enum field may be specified using a string; otherwise it can only be set using an integer value.

Examples:

  ai foo:bar:temperature = {
      inputSmoothing = 0.98;
      invalidValue = 1000;
      units = "Celcius";
      scan = "Interrupt";
      ...
  }


Structure Initializers

structInitializer:
{ structAssignmentList }
structAssignmentList:
initializerList
fieldName = initializerList
structAssignmentList ; fieldName = initializerList

Initializers for a structure field look similar to a nested record body, but the rules are slightly different:

  • You can give a series of values for adjacent items using a simple comma-separated list (for a record body, you must name each field)
  • Semi-colons are required between a value and a following named item.

For example:

  ai foo:temperature:sensor = {
      linearConvert = {
          mode = "Linear";
          low = -12.5, 133.5
      };
      displayLimit = { 0, 100 };
      ...
  }

Link Initializer

linkInitializer:
support(choiceName) supportStructName { structAssignmentList }
choiceName:
identifier
supportStructName:
identifier

These select a particular link support and interface for the field, and set its address according to the structure type defined for that link type.

  calcout foo:temperature:controller = {
      block = true
      output = support(outputLink) OutputLink{
               pvname = "fum:baz:heater";
               process = true;
               wait = true;
      }
      input = [2] {
          {   link = {
                  support(monitorLink) MonitorLink{
                      pvname = "foo:temperature:setpoint";
                      process = false
                  }
              }
          }
          {  block=true
             link = {
                  support(inputLink) InputLink {
                      pvname = "foo:temperature:sensor";
                      process = true;
                      wait = true;
                      inheritSeverity = true
                  }
             }
          }
      };
      expression = "(B - A) > 0";
      ...
  }
  mbbi foo:bar:door = {
      input = support(acro9440) VME{0, 5};
      ...
  }

QUESTION There is nothing that allows a DVT to prompt a user with a valid set if support for a particular link. Should there be?

Array Initializers

arrayInitializer:
{ arrayAssignmentList }
arrayType { arrayAssignmentList }
[ arrayCapacity ] { arrayAssignmentList }
arrayType [ arrayCapacity ] { arrayAssignmentList }
arrayAssignmentList:
initializerList
[ integerConstant ] = initializerList
arrayAssignmentList ; [ integerConstant ] = initializerList
arrayType:
one of: bool int16 uint16 int32 uint32
one of: float32 float64 octet string
arrayCapacity:
integerConstant
arrayCapacity , integerConstant

If the definition of the array field being set did not do so, an array field initialization must include the size of the array and/or the type of the data stored in it. Inside the braces data values are given in a comma-separated list; the index can also be set to initialize individual values, and any mixture of the two can be used as desired:

  mbbi foo:bar:door = {
      stateNames = [4] {"Broken", "Closed", "Open", "Moving"};
      stateSeverity = [4] {"Major"; [3] = "Minor"};
      ...
  }

For multi-dimensional arrays, data values can only appear inside the inner-most sets of braces, although index settings are permitted outside of these. These two definitions give the same result:

  matrix identity1 = {
      value = float32 [3,3] { {1, 0, 0}, {0, 1, 0}, {1, 0, 0}};
  }
  matrix identity2 = {
      value = float32 [3,3] { {1}, {[1] = 1}, {[2] = 1}};
  }