TOP

ASN.1/C++ Compiler Advanced Topics

Applies to: ASN.1/C++ 6.5

ASN.1 Macros

The OSS macro processor is a component of the ASN.1/C++ Compiler that

  • Expands all macro notation.
  • Performs full syntax checking of ASN.1 source files.
  • Produces source listings with all imported items expanded.
  • Generates diagnostic messages.

No preprocessing of the ASN.1 source is required before invoking the OSS macro processor.

Expansion of ASN.1 Macro Notation

A macro assigns a value to the local value reference (VALUE) and returns its ASN.1 type, which is used to determine how the macro should be expanded. So when VALUE has a single assignment in an instance of a macro, the type associated with that value is returned.

A CHOICE type is generated when a macro returns a type that is indeterminate because VALUE has zero or multiple assignments in the macro instance. When VALUE has no assignment, the resulting CHOICE contains every possible type that the macro could return. When VALUE has multiple assignments, the resulting CHOICE contains the types associated with those assignments.

An ANY type is generated when a macro returns a type that is completely indeterminate. For example, an argument assigned to VALUE is present only in a macro's VALUE NOTATION, but the macro is used strictly as a type, with no value specified.

Any macro instance that has an indeterminate returned type is non-standard; its use is discouraged. The compiler tolerates these types of macros only to support those already in existence. A warning message is issued for any use of non-standard macros.

Restrictions on User-Defined Macros

  • When defining one macro by another macro, define the latter first.

    In the following example, OPERATION must be defined before it can be used to define ABSTRACT-OPERATION:

    ABSTRACT-OPERATION MACRO ::= OPERATION
  • The "[" character is not supported in macros as an astring.
  • All macros must be defined before they are used.

    In the example below, A is acceptably defined since no argument is passed to ERROR. C is acceptably defined because ERROR is defined before being referenced by C. On the other hand, B is unacceptably defined since ERROR is referenced before being defined and arguments are passed to it.

    A ::= ERROR
     
    B ::= ERROR PARAMETER BOOLEAN
     
    ERROR MACRO ::= BEGIN
        TYPE NOTATION	::= Parameter
        VALUE NOTATION	::= value(VALUE CHOICE{
           localValue  INTEGER,
           globalValue OBJECT IDENTIFIER})
        Parameter    ::= "PARAMETER" NamedType | empty
        NamedType    ::= identifier type       | type
    END
    
    C ::= ERROR PARAMETER BOOLEAN
  • Macro arguments and values that have no effect on the return type are checked by the compiler for correct usage and have no effect on the compiler output. The compiler treats such parameters and values as formal comments whose meaning is understood only by the user. For example, using the ERROR definition specified above, you can create an instance of ERROR as follows:
     C ::= ERROR PARAMETER BOOLEAN

    NOTE: In the macro definition, the type of the value returned by ERROR is CHOICE {localValue INTEGER, globalValue OBJECT IDENTIFIER}; this type is independent of any parameter passed to ERROR. The compiler syntax-checks the parameters to ensure that whenever the word PARAMETER occurs immediately after ERROR, it is followed by a valid ASN.1 type. These parameters are then forgotten and have no further effect.

Examples of Macro Use

Most of these examples are drawn from the X.208 and X.410 ITU-T Recommendations.

  1. Example of a macro whose returned type is independent of the instance of the type and value notation.

    ERROR macro definition:

    ERROR MACRO ::= BEGIN
       TYPE NOTATION    ::= "PARAMETER" NamedType | empty
       VALUE NOTATION   ::= value(VALUE INTEGER)
       NamedType        ::= identifier type       | type
    END

    Used as follows:

    ErrorRecord ::= SEQUENCE {
       rectype        ERROR PARAMETER VisibleString,
       sector         INTEGER
    }

    Regardless of the parameter passed to the macro, the following definition is always implied because the type returned by the macro is always INTEGER:

    ErrorRecord ::= SEQUENCE {
       rectype        INTEGER,
       sector         INTEGER
    }

  2. Example of another macro whose returned type is independent of the instance of the type and value notation.

    OPERATION macro definition:

    OPERATION MACRO ::= BEGIN
       TYPE NOTATION   ::= "ARGUMENT" NamedType
                  Result Errors      | empty
       VALUE NOTATION  ::= value(VALUE INTEGER)
       Result          ::= empty           | "RESULT" NamedType
       Errors          ::= empty           | "ERRORS" "{"ErrorNames"}"
       NamedType       ::= identifier type | type
       ErrorNames      ::= empty           | IdentifierList
       IdentifierList  ::= identifier      | IdentifierList  "," identifier
    END

    Used as follows:

    cancel OPERATION
       ARGUMENT jobname IA5String
       RESULT   jobCancelled NULL
       ERRORS {jobNotFound, unauthorizedCancel} ::= 1
      
    Message   ::= SEQUENCE {
       invokeID   INTEGER,
            OPERATION,
       argument   ANY
    } 

    Regardless of the parameters passed to the macro, the following code is always generated because the type returned by the macro is always INTEGER:

    lookup INTEGER ::= 1
     
    Message ::= SEQUENCE {
       invokeID   INTEGER,
                  INTEGER,
       argument   ANY
    }

  3. Example of a macro whose returned type is independent of the value notation instance, but is dependent on the type notation instance.

    PAIR macro definition:

    PAIR MACRO ::= BEGIN
    
       TYPE NOTATION ::= 
          "TYPEX" "=" type(LocalType1)
          "TYPEY" "=" type(LocalType2)
       VALUE NOTATION ::=
          "("
          "X" "=" value(LocalValue1 LocalType1)
          ","
          "Y" "=" value(LocalValue2 LocalType2)
          <VALUE SEQUENCE {LocalType1, LocalType2} ::= 
             {LocalValue1, LocalValue2}>
          ")"
    END

    Used as follows:

    AgeAndMarried ::= PAIR
       TYPEX = INTEGER
       TYPEY = BOOLEAN
          
    serena AgeAndMarried ::= (X = 2, Y = FALSE)

    In the generated code, the types are generated based on the macro parameters:

    AgeAndMarried ::= SEQUENCE {
       INTEGER,
       BOOLEAN
       }
    
    serena AgeAndMarried ::= {2, FALSE}

  4. Example of a macro whose returned type depends on the instance of the type and value notation and contains multiple VALUE assignments.

    BIND macro definition:

    BIND MACRO ::= BEGIN
    
       TYPE NOTATION	::= Argument  Result  Error
       VALUE NOTATION	::= Argument-value | Result-value | Error-value
    
       Argument        ::= empty | "ARGUMENT"   Name type(Argument-type)
       Result          ::= empty | "RESULT"     Name type(Result-type)
       Error           ::= empty | "BIND-ERROR" Name type(Error-type)
       Name            ::= empty | identifier
       
       Argument-value	::= empty | "ARGUMENT"
                value(Arg-value Argument-type)
       <VALUE [16] EXPLICIT Argument-type ::= Arg-value>
    
       Result-value::= empty | "RESULT"
                value(Res-value Result-type)
       <VALUE [17] EXPLICIT Result-type   ::= Res-value>
    
       Error-value::= empty | "ERROR"
                value(Err-value Error-type)
       <VALUE [18] EXPLICIT Error-type    ::= Err-value>
    END 

    Used as follows:

    BindA ::= BIND
    BindB ::= BIND RESULT INTEGER
    b BIND ARGUMENT INTEGER ::= ARGUMENT 2

    Warning messages are issued for BindA and BindB, and the following code is generated:

    BindA ::= CHOICE {
    [16] ANY,
    [17] ANY,
    [18] ANY
    }
    
    BindB ::= [17] INTEGER
    
    b [16] INTEGER ::= 2

Backward Compatibility

These compiler -compat flags can be used to restore the behavior of earlier versions of the OSS ASN.1/C++ Tools. Click on a flag name for more information about that flag, or go directly to the ASN.1/C++ Compiler -compat Flags Reference.

Name Description
allowBadDEFAULTValues Silently truncate a size-constrained DEFAULT value that is too long, and issue a warning message.
externIntConst Always generate extern constants for named values, even when they consist of INTEGER and ENUMERATED types.
genericOpenTypes Always use the OssOpen class to represent open types.
UTF8StringasBMPString Use the OssBMPString class to represent UTF8Strings.
v2.0
v2.0.0
Provides compatibility with version 2.0.0 of the compiler.
v3.0
v3.0.0
Provides compatibility with version 3.0.0 of the compiler.
v3.1
v3.1.0
Provides compatibility with version 3.1.0 of the compiler.
v3.1.1 Provides compatibility with version 3.1.1 of the compiler.
v3.1.2 Provides compatibility with version 3.1.2 of the compiler.
v3.1.3 Provides compatibility with version 3.1.3 of the compiler.
v4.0
v4.0.0
Provides compatibility with version 4.0.0 of the compiler.
v4.0.1 Provides compatibility with version 4.0.1 of the compiler.
v4.0.2 Provides compatibility with version 4.0.2 of the compiler.
v4.1
v4.1.0
Provides compatibility with version 4.1.0 of the compiler.
v4.2
v4.2.0
Provides compatibility with version 4.2.0 of the compiler.
v4.2.1 Provides compatibility with version 4.2.1 of the compiler.
v4.3
v4.3.0
Provides compatibility with version 4.3.0 of the compiler.
v4.3.1 Provides compatibility with version 4.3.1 of the compiler.
v4.3.2 Provides compatibility with version 4.3.2 of the compiler.
v4.3.3 Provides compatibility with version 4.3.3 of the compiler.
v4.3FalseExtendedConstraintEncoding Restores pre-4.3.1 version mishandling of some extensible constraints.
v4.3TableConstraintForExtensibleObjectSets Restores pre-4.3.1 version mishandling of table and component relation constraint violations for extensible object sets.
v4.3reservedWords Restores pre-5.0 version compiler behavior in that "SID" and "small" are not considered reserved words and are not mangled when used as identifiers.
v4.3NoEnumSharing Restores pre-5.0 version compiler behavior when generating common C++ classes for different ASN.1 types having identical C++ representations.
v5.0
v5.0.0
Provides compatibility with version 5.0.0 of the compiler.
v5.0reservedWords Restores pre-6.0 version compiler behavior in that "floor" and "send" are not considered reserved words and are not mangled when used as identifiers.
v6.0
v6.0.0
Provides compatibility with version 6.0.0 of the compiler.
v6.0Sharing Restores pre-6.1 version compiler behavior as to sharing constructed types with recursive definitions.
v6.0valueTruncation Restores pre-6.1 version compiler behavior in that certain values of SEQUENCE OF and SET OF types will not be truncated.

This documentation applies to release 6.5 and later of the OSS® ASN.1 Tools for C++.

Copyright © 2017 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.