Age | Commit message (Collapse) | Author |
|
|
|
Change to new error handling system and cover with tests.
|
|
All errors were not reported. Furthermore, get_referenced_type/2
will report errors if any module is missing, so the attempt to
report additional errors in chained_import/4 would not find any
errors.
|
|
The internal representation for constraints (and object sets)
as produced by the parser was awkward, making further processing
convoluted. Here follows some examples of the old representation
for INTEGER constraints.
The constraint 1..2 is represented as:
{'ValueRange',{1,2}}
If we extend the constraint like this:
1..2, ...,
or like this:
1..2, ..., 3
the representation would be:
{{'ValueRange',{1,2}},[]}
and
{{'ValueRange',{1,2}},{'SingleValue',3}}
respectively. Note that the pattern {A,B} will match all these
constraints.
When combining constraints using set operators:
1..2 | 3..4 ^ 5..6
the representation will no longer be a tuple but a list:
[{'ValueRange',{1..2}} union
{'ValueRange',{3..4}} intersection
{'ValueRange',{5..6}}]
The parse has full knowledge of the operator precedence; unfortunately,
the following pass (asn1ct_check) must also have the same knowledge
in order to correctly evaluate the constraints.
If we would change the order of the evaulation with round brackets:
(1..2 | 3..4) ^ 5..6
there would be a nested listed in the representation:
[[{'ValueRange',{1..2}} union {'ValueRange',{3..4}}]
intersection {'ValueRange',{5..6}}]
We will change the representation to make it more explicit.
At the outer level, a constraint is always represented as
{element_set,Root,Extension}
Extension will be 'none' if there is no extension, and 'empty' if
there is an empty extension. Root may also be 'empty' in an object set
if there are no objects in the root. Thus the constraints:
1..2
1..2, ...
1..2, ..., 3
will be represented as:
{element_set,{'ValueRange',{1,2}},none}
{element_set,{'ValueRange',{1,2}},empty}
{element_set,{'ValueRange',{1,2}},{'SingleValue',3}}
We will change the set operators too. This constraint:
1..2 | 3..4 ^ 5..6
will be represented as:
{element_set,
{union,
{'ValueRange',{1,2}},
{intersection,
{'ValueRange',{3,4}},
{'ValueRange',{5,6}}},
none}}
which is trivial to understand and evaluate. Similarly:
(1..2 | 3..4) ^ 5..6
will be represented as:
{element_set,
{intersection,
{union,{'ValueRange',{1,2}},{'ValueRange',{3,4}}},
{'ValueRange',{5,6}}},
none}
|
|
Fixes needed to avoid a compiling asn1 files in order.
For example the x420 directory in test now compiles with
erlc *.asn
Do not save class records without module information in asn1db files.
Use recursive get_referenced_type in get_objclass_fields/2
|
|
|
|
|
|
The ObjectSetFromObjects construct is implemented using
the object_set_from_objects() function, which is similar
to get_fieldname_element(). Rewrite the ObjectSetFromObjects
handling to use get_fieldname_element() to share more code.
|
|
|
|
|
|
a1260b2ffa60581ce3af0728320b593cca3fd7b0 fixed a problem with
expansion of parameterized types, but it didn't go all the way.
The compiler would still crash if we attempted to define a value
using the instantiated type.
|
|
Introduce match_parameter/2 for matching a single parameter and
match_parameters/2 for matching all of them.
|
|
The constraint_member/2 function is used for looking up 'simpletable'
and 'componentrelation' constraints. Both parts of its name are
misleading. The "constraint" part makes you think that it is a general
function for constraints, but it is not - it can only search for
'simpletable' and 'componentrelation'. The "member" part makes you
think that it would return a boolean, but it returns either
{true,Tuple} or false, making it more similar to lists:keysearch/3.
Use lists:keyfind/3 (or lists:keymember/3) instead of
constraint_member/2. Also use lists:keyfind/3 in one place where
there was a direct matching of a 'simpletable' constraint.
|
|
|
|
There is no reason to handle tags differently depending on the
back-end. The PER back-end will simply ignore tags.
There is also a bug in tags the ABSTRACT-SYNTAX and TYPE-IDENTIFIER
pre-defined classes. So far it has not caused problems, but it could
do in a future commit, such as the next commit...
|
|
|
|
To be sure that indirect references to classes are solved.
|
|
|
|
The parser handled the builtin ABSTRACT-SYNTAX and TYPE-IDENTIFIER
classes specially, which caused problems. It turns out that there
is no longer any need to handle those classes specially.
|
|
|
|
An optional group must not contain mandatory class fields. All
mandatory fields must be included in the simplified syntax.
|
|
|
|
Besides simplifying the code and doing better error checking
and error reporting, fix the following bugs:
Support retrieving an OBJECT IDENTIFIER/RELATIVE-OID from an
object. Example:
oid OBJECT IDENTIFIER ::= some-object.&some-field
Allow an integer constant first in an OBJECT IDENTIFIER:
integer INTEGER ::= 0
oid OBJECT IDENTIFIER ::= {integer 1}
|
|
Wrong fields in the record where checked when sorting, which caused
duplicate objects to exist in constructed object sets and later caused
an error.
|
|
|
|
Also add proper error handling.
|
|
File names and line number information was not reliable available
when producing error messages. Some items have embedded line number
information, and sometimes the S#state.type and/or S#state.value
could be used to retrieve the line number information.
To make sure that we can always retrieve at least an approximate
error location, store the top-level construct being checked in
S#state.error_context. Example of top-level constructs:
Seq ::= SEQUENCE {...}
i INTEGER ::= 42
This is a short-term solution. In the long term, we would want the
parser to include line number information in all items.
|
|
Rewrite the confusing and buggy matching of an object definition
against the simplified syntax.
While we are at it, we will also add proper error handling.
|
|
When the parser sees:
something SOMETHING ::= {}
it has no way of knowing whether 'something' is an value or an
object. It depends on how SOMETHING is defined. For example:
SOMETHING ::= SEQUENCE {}
or
SOMETHING ::= CLASS { &id OPTIONAL }
Because of that ambiguity, there is no way to avoid a special case
when we check an object definition. However, there is no need to
invent an entire new checking function for this special case. It is
much easier to just pretend that the parser gave us
{object,defaultsyntax,[]} and let check_objectdefn/3 check it in the
usual way.
|
|
An #'Externavaluereference'{} may either be a value or an object.
In places where objects are expected, we will need to call
object_to_check/1 to convert an #'Externavaluereference'{} to an
object. It was forgotten in two places.
|
|
Refactor and clean up code. While at it, add error handling and
test cases. (Also add test cases for the existing values in
ValueTest.asn while we are it.)
Add support for defining INTEGER constants by extracting
fields from objects. Example:
int-from-object INTEGER ::= object.&id
When extracting values from objects in constraints, only one
level of extraction would work. That is, the following would
work:
SomeName ::= INTEGER (object.&int)
but not:
SomeName ::= INTEGER (object.&obj.&int)
|
|
There is duplicated effort in that validate_integer() checks
whether the integer value is valid, and then normalize_integer()
does mostly the same work in order to convert the value to an
integer.
Eliminate the validate_integer() function and incorporate
its checks into normalize_integer(). Also produce proper
error messages.
|
|
Class names must start with an uppercase letter and only contain
uppercase letters, digits, or hyphens. The parser will not allow
class names that don't start with an uppercase letter, so we don't
have to check that.
|
|
Don't build a record using the tuple syntax. It is bad in case
we would want to change the record definition later.
|
|
|
|
* dgud/asn1/fix-seqtag/OTP-12326:
asn1: Fix EXTERNAL (1994 variant) type conversion
|
|
Missed to add seqtag handling for EXTERNAL type conversion,
bug introduced in c266196c016fc1156c7a18cfeec4920ee4075519
|
|
This patch fixes a bug with compliance to X.680 (200811) s31.2.7
Basically, when TagDefault is AUTOMATIC then
tags are IMPLICIT unless EXPLICIT is given.
|
|
The following type of code would crash the compiler:
OSET SOME-CLASS ::= {OSET1, ..., OSET2}
|
|
The previous code looked at the actual parameters supplied when
instantiating the type to determine the type of the argument; the
correct way is to determine the type by looking at the governor and
case of the formal parameter.
|
|
Check the formal parameters for a parameterized type definition.
If the governor for a formal parameter is absent, the formal parameter
must be in upper case.
|
|
Definitions for parameterized types are verified once very early,
and one more time when they are instantiated.
Errors found during the first check were ignored, so errors for
unused parameterized types were not reported.
|
|
Before classes were fully implemented, there was support for
ABSTRACT-SYNTAX and TYPE-IDENTIFIER. Some of that code is still
there and is no longer used. Get rid of it and correct comments.
|
|
Attempting to compile:
SomeType{SOME-CLASS-NAME, SOME-CLASS-NAME:SomeSet} ::= ...
SEQUENCE {
something SOME-CLASS-NAME.&id({SomeSet})
}
would crash the compiler, because the actual parameter for
SOME-CLASS-NAME was not substituted into the governor for
the SomeSet parameter.
While we are at it, combine the functionality of is_class/2
and get_class_def/2 (eliminating is_class/2). Most callers
call both function.
|
|
If we want construct an #'Externaltypereference'{} from
a #classdef{} record, we will need the module name.
|
|
The only remaining use of #identifier{} in asn1ct_check was in a
temporary packaging of a value that would be ultimately be put
into #valuedef{}.
Therefore we can eliminate that last usage but putting the value
directly into a #valuedef{} and we can move the record definition
into asn1ct_parser2.
|
|
When parsing ASN.1, certain constructs can only be understood in
the full context of the entire ASN.1 module.
For instance, the value following ID in this simplified excerpt
from MTSAbstractService88:
administration-88 PORT ::= {
ID {id-pt-administration 88}
}
the value following "ID" can be interpreted either as value
for:
SEQUENCE {
id-pt-administration INTEGER
}
or as an OBJECT IDENTIFIER.
Our ASN.1 parser assumes that a SEQUENCE is meant, and if that
later turns out to be wrong, the SEQUENCE value is rewritten to
an OBJECT IDENTIFIER. The problem is that at the time of the
rewrite, we no longer know in which ASN.1 module id-pt-administration
was defined in, and we have to use the module name in the state{}
record. Unfortunately, the module name in the state{} record may
not always be correct.
While there are attempts in the code to keep the module name
up-to-date when checking imported types, it is not done consistently,
and it seems to be a difficult and error-prone task to attempt
to make it consistent.
A safer and less error-prone approach is to make sure that we
don't lose the module name while parsing. To make it clear what
we are doing, we will introduce a new #seqtag{} record that
are used for tags in SEQUENCE values. The name is based on its
primary use. The record also contains the module in case it happens
to be an OBJECT IDENTIFIER.
|
|
Make sure that we continue to follow external references until
we find a real type.
|
|
|
|
|