The ASN.1/C compiler directives enable you to control the compiler output. They can be added to the ASN.1 schema files or can be included in a separate directive file.
Contents
The following table contains compiler directives listed by category. Note that a directive may belong to more than one category. Use the check boxes to display a particular group of directives: basic, advanced, or deprecated.
Compiler directives are case-sensitive and have the following format:
--<[prefix.]directive [absoluteReference] [operand1[, operand2]...]>--
absoluteReference specifies the ASN.1 input schema items that are affected by the directive.
Directives appear as comments to compilers that do not support them. The following examples illustrate three equivalent ways to specify directives:
--<OSS.NULLTERM>-- --<OSS.ROOT Module1>-- |
--<OSS.NULLTERM>-- --<OSS.ROOT Module1>-- |
--<OSS.NULLTERM>-- --<OSS.ROOT --Module1>-- |
When you do not specify directives, the compiler uses a default set of assumptions to generate the header and control/code file.
When you specify contradictory directives, the last one takes precedence.
There are three types of compiler directives:
Standard | OSS | Legacy | |
---|---|---|---|
Syntax | --<ASN1.directive...>-- |
--<OSS.directive... >-- |
--<directive...>-- |
Usage | General usage in the industry. | Unique to the OSS ASN.1 Tools. Everywhere, except in-line (next to an item). Inline usage is replaced with the ability to reference a particular item. | Historically used as in-line directives. OSS directives at a module or global level are a better alternative. Use the -genDirectives compiler option to save legacy directives into a .gen file to be used outside of the ASN.1 module. |
Example | --<ASN1.WorkingSet Mod>-- |
--<OSS.FLOAT Mod.TypeX>-- |
A ::= [1] REAL --<DOUBLE>-- |
If you use implementation-specific directives, note that the OSS ASN.1 compiler ignores them (for example: --<HP., --<TCSI. etc.), and issues warning messages during compilation.
When you have different scopes, local directives take precedence. The scopes can be:
An absolute reference uniquely specifies one or more components in ASN.1 syntax. The absolute reference notation is similar to the syntax used in many programming languages to access components within named structures and records. The outermost structure is listed first using its identifier followed by a dot ("."). A component of the outermost structure can be listed next. If the desired component is placed within a nested structure, a dot is added after the name of the containing structure, and then the desired component is listed.
To specify an ASN.1 component, you can:
For example, for the following ASN.1 definition:
MyMod DEFINITIONS ::= BEGIN Comp1 ::= SET OF SEQUENCE { a INTEGER, b OCTET STRING OPTIONAL, c CHOICE { nest1 BOOLEAN, nest2 BIT STRING } } Comp2 ::= IA5String END
The absolute reference for:
To access ASN.1 types located within CONSTRAINED BY clauses, you must specify the dollar sign ("$") followed by a number index indicating a particular CONSTRAINED BY. This number index can be optionally followed by a colon (":") and another number index or a component identifier which indicates a particular component within the CONSTRAINED BY braces. If the colon and the index or the identifier following it are left out, the first component within the CONSTRAINED BY is targeted by default.
To access ASN.1 types located within WITH COMPONENT or WITH COMPONENTS clauses, you must specify two dollar signs ("$$") followed by a number index indicating a particular WITH COMPONENT or WITH COMPONENTS.
The following example illustrates CONSTRAINED BY constraints applied within WITH COMPONENTS clauses:
--<OSS.FIELDNAME Mod.Type.$$1.data.$1:1.alt "my_alt">-- --<OSS.FIELDNAME Mod.Type.$$2.data.$1:1.fld "my_fld">-- Mod DEFINITIONS ::= BEGIN Type ::= SEQUENCE {data OCTET STRING } (WITH COMPONENTS{..., data (CONSTRAINED BY {CHOICE {alt BOOLEAN}})}) (WITH COMPONENTS{..., data (CONSTRAINED BY {SEQUENCE {fld INTEGER OPTIONAL}})}) END
In the above absolute reference, $$1.data.$1:1 refers to the type within the CONSTRAINED BY of the first WITH COMPONENTS clause. The first directive changes the name of the "alt" field to "my_alt". $$2.data.$1:1 refers to the type within the CONSTRAINED BY of the second WITH COMPONENTS clause. The second directive changes the name of the "fld" field to "my_fld".
The following example illustrates a CONTAINING constraint applied within WITH COMPONENTS clauses.
--<OSS.TYPENAME Mod.Type.$$1.bit.* "MyChoice">-- --<OSS.FIELDNAME Mod.Type.$$1.bit.*.alt "my_alt">-- --<OSS.FIELDNAME Mod.BaseType.other.fld "my_other_fld">-- Mod DEFINITIONS ::= BEGIN BaseType ::= SEQUENCE { bit BIT STRING OPTIONAL, other SEQUENCE { fld INTEGER OPTIONAL } OPTIONAL } Type ::= BaseType (WITH COMPONENTS {..., bit (CONTAINING CHOICE {alt INTEGER}) }) END
In the first absolute reference, $$1.bit.* refers to the CHOICE type within the CONTAINING clause of the first WITH COMPONENTS clause applied to Type. $$1.bit.*.alt refers to the field of the CHOICE type. Note that you can use the "$$ <num> " syntax only for components whose names are explicitly included in the WITH COMPONENTS syntax (that is, for the bit field in the above example). The absolute references of the fields within the original type, BaseType, apply to the names within the original type and also to the ones within all the types that are created when using contents constraints within WITH COMPONENTS. Therefore, to change the names that are not included in the WITH COMPONENTS clause of the derived type, Type, you would need to change the names of the original type, BaseType.
The following table contains examples of using absoluteReference:
ASN.1 module | absoluteReference |
---|---|
MyMod DEFINITIONS ::= BEGIN Comp1 ::= SET OF SEQUENCE { a INTEGER, b OCTET STRING OPTIONAL, c CHOICE { nest1 BOOLEAN, nest2 BIT STRING } } Comp2 ::= BOOLEAN (CONSTRAINED BY {--Just a comment--}) (CONSTRAINED BY { SET {con1 NULL, con2 REAL}}) END |
referencing entire module: MyMod referencing SET OF: MyMod.Comp1 referencing SEQUENCE series: MyMod.Comp1.* referencing b: MyMod.Comp1.*.b or MyMod.Comp1.*.2 referencing nest1: MyMod.Comp1.*.c.nest1 or MyMod.Comp1.*.c.1 referencing con1: MyMod.Comp2.$2.con1 |
Mod DEFINITIONS ::= BEGIN C ::= BOOLEAN (CONSTRAINED BY {}) (CONSTRAINED BY { INTEGER, -- "1st" parameter IA5String, CHOICE { f REAL (CONSTRAINED BY {SET {e NULL}}) } -- "3rd" parameter }) END |
referencing e: Mod.C.$2:3.f.$1.e |
Mod DEFINITIONS ::= BEGIN Type ::= SEQUENCE {data OCTET STRING } (WITH COMPONENTS{..., data -- "1st" inner subtype (CONSTRAINED BY { CHOICE { alt BOOLEAN } })}) ((WITH COMPONENTS{..., data -- "2nd" inner subtype (CONSTRAINED BY { SEQUENCE { fld1 INTEGER OPTIONAL } })}) | (WITH COMPONENTS{..., data -- "3d" inner subtype (CONSTRAINED BY { SEQUENCE OF SET { fld2 INTEGER OPTIONAL } })})) END |
referencing alt: Mod.Type.$$1.data.$1:1.alt referencing fld1: Mod.Type.$$2.data.$1:1.fld1 referencing fld2: Mod.Type.$$3.data.$1:1.*.fld2 |
When you apply a directive to a parameterized type definition, note that the directive is applied to each instance of the type.
For example, when the OSS.PDU directive is applied to a parameterized type, all instances of this type are treated as PDUs. Likewise, when the ASN1.WorkingSet directive is applied to a parameterized type, all instances of the type are included in the working set. An exception to this rule is the ASN1.Remove directive which must be explicitly applied to each instance of a parameterized type.
When you apply the OSS.FUNCNAME or the ASN1.ConstraintFunction directive to a parameterized assignment, note that the compiler generates names for the user-defined constraint functions which are post-fixed with a number (suffix) for each instance of the parameterized type other than the first instance.
--<OSS.FUNCNAME Test.Mouse "doggy">-- Test DEFINITIONS ::= BEGIN Mouse {Type} ::= SEQUENCE {t INTEGER} (CONSTRAINED BY {Type}) Rat1 ::= [2] Mouse{SEQUENCE {i INTEGER, b BOOLEAN}} Rat2 ::= [3] Mouse{SEQUENCE {i INTEGER, b BOOLEAN}} END
When you use the -userConstraints command-line option, the following code is generated in the header file:
/* doggy is user-defined constraint function for ASN.1 item Test.Rat1 */ extern int DLL_ENTRY doggy(struct ossGlobal *, Rat1 *, void **); /* doggy_1 is user-defined constraint function for ASN.1 item Test.Rat2 */ extern int DLL_ENTRY doggy_1(struct ossGlobal *, Rat2 *, void **);
When you apply a directive to an instance of a parameterized type, note that it affects only that particular instance.
--<ASN1.Nickname Test.S1 "Inst1_Seq">-- --<OSS.TYPENAME Test.S1.a "Inst1_Seq_a">-- --<OSS.DefineName Test.S1.a "Inst1_Seq_a_c">-- --<OSS.DefineName Test.S2.a.c "Inst2_Seq_a_c">-- Test DEFINITIONS ::= BEGIN Seq {Type} ::= SEQUENCE {a Type OPTIONAL} S1 ::= [2] Seq{SEQUENCE {b INTEGER}} S2 ::= [3] Seq{SEQUENCE {c BOOLEAN OPTIONAL}} END
The first three directives cause name changes only for the structure S1. The last directive affects the name in the second #define of S2:
typedef struct Inst1_Seq { unsigned char bit_mask; # define Inst1_Seq_a_c_present 0x80 struct Inst1_Seq_a { int b; } a; /* optional; set in bit_mask Inst1_Seq_a_c_present if present */ } Inst1_Seq; typedef struct S2 { unsigned char bit_mask; # define a_present 0x80 struct { unsigned char bit_mask; # define Inst2_Seq_a_c_present 0x80 ossBoolean c; /* optional; set in bit_mask Inst2_Seq_a_c_present * if present */ } a; /* optional; set in bit_mask a_present if present */ } S2;
Directives cannot be applied to types used as substitution types (in instances of parameterized types), to fields of such types, or to types that are parameters in parameterized types.
The following directives have no effect:
--<ASN1.Nickname Test.T3.bt2.at1 bt2_nickname>-- --<OSS.TYPENAME Test.T3.bt2 NewName-instance>-- --<OSS.TYPENAME Test.T2.bt2 NewName-param>-- Test DEFINITIONS ::= BEGIN T2 {X} ::= SEQUENCE {at2 BIT STRING, bt2 X OPTIONAL} T3 ::= T2 {T1} T1 ::= SET {at1 INTEGER, bt1 BOOLEAN} END
If you change the type for bt2 to a "non-direct" reference to the parameter X (SET OF X), the OSS.TYPENAME directives will succeed:
T2 {X} ::= SEQUENCE {at2 BIT STRING, bt2 SET OF X OPTIONAL}
This documentation applies to the OSS® ASN.1 Tools for C release 11.3 and later.
Copyright © 2024 OSS Nokalva, Inc. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means electronic, mechanical, photocopying, recording or otherwise, without the prior permission of OSS Nokalva, Inc.
Every distributed copy of the OSS® ASN.1 Tools for C is associated with a specific license and related unique license number. That license determines, among other things, what functions of the OSS ASN.1 Tools for C are available to you.