aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/src/asn1ct_gen.erl
AgeCommit message (Collapse)Author
2017-05-04Update copyright yearRaimo Niskanen
2017-03-15Remove default clauses that cause exceptions for internal errorsBjörn Gustavsson
Just crash if there is an internal error.
2017-03-14Clean up commentsBjörn Gustavsson
* Remove out-commented code * Fix obvious typos and bad grammar * Adhere to the conventions for when to use "%" and "%%".
2017-03-14Clean up asn1ct_gen:emit/1Björn Gustavsson
Remove blank lines between clauses; use matching instead of is_list/1 guards.
2017-03-14Remove unused clauses in asn1ct_gen:emit/1Björn Gustavsson
2017-03-14Remove the 'debug' optionBjörn Gustavsson
The debug option no longer serves any useful purpose.
2017-02-21encode/decode: Include the stack trace in error returnsBjörn Gustavsson
The generated encode/2 and decode/2 functions can return cryptic error messages. Consider this ASN.1 spec: T DEFINITIONS AUTOMATIC TAGS ::= BEGIN S ::= SEQUENCE { b BOOLEAN, i INTEGER (1..100), j INTEGER (0..7), s OCTET STRING } END In OTP 19, the error terms will look like this: Eshell V8.2 (abort with ^G) 1> asn1ct:compile('T', [ber]). ok 2> rr('T'). ['S'] 3> 'T':encode('S', #'S'{}). {error,{asn1,{encode_boolean,undefined}}} 4> 'T':encode('S', #'S'{b=false}). {error,{asn1,{encode_integer,undefined}}} 5> 'T':encode('S', #'S'{b=false,i=7,j=0}). {error,{asn1,function_clause}} Some error terms are clearer than other. In the first error term, it is clear that the error refers to the 'b' field, since there is only one BOOLEAN in 'S'. The second error term could refer to either 'i' or 'j'. The last error term... well... in this case we can infer that it must refer to 's'. The easiest way to provide more information is to include the stack trace with line numbers in the error term: 3> 'T':encode('S', #'S'{b=false}). {error,{asn1,{{encode_integer,undefined}, [{'T',encode_integer,2,[{file,"T.erl"},{line,240}]}, {'T',enc_S,2,[{file,"T.erl"},{line,102}]}, {'T',encode,2,[{file,"T.erl"},{line,36}]}, {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]}, {shell,exprs,7,[{file,"shell.erl"},{line,686}]}, {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]}, {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]}}} By looking at the generated Erlang code, we can see that encoding failed for 'i'. This is an compatible change. All that the documentation says is that the format of the error tuple is: {error,{asn1,Description}} With this change, Description is always a tuple: {ErrorDescription,StackTrace} Alternatives considered: Providing more information in the error term itself and make sure there can be no 'function_clause', 'badarg', or 'badmatch' exceptions. That would be possible, but it would require a lot of work and it would increase the size of the generated code and make it slower. Therefore, this solution was rejected.
2017-02-16asn1ct_gen: Clean up handling of dispatch generationBjörn Gustavsson
2017-02-16Package abstract code in a record for code generationBjörn Gustavsson
For now, do the packaging before call asn1ct_gen:pgen().
2017-02-16asn1ct_gen: Polish the file headerBjörn Gustavsson
2017-02-15asn1ct_gen: Clean up generation of .hrl file headerBjörn Gustavsson
Note that put(currmod, Mod) is not needed because it has already been done by the caller.
2017-02-15asn1ct_gen: Clean up generation records in .hrl fileBjörn Gustavsson
2017-02-15asn1ct_gen: Clean up generation of -export directivesBjörn Gustavsson
2017-02-15asn1ct_gen: Clean up generation of valuesBjörn Gustavsson
2017-02-06Teach the ASN.1 compiler the 'maps' optionBjörn Gustavsson
When the 'maps' option is given, the SEQUENCE and SET types are represented as maps instead of as records. Optional and default values must be not be given as asn1_NOVALUE or asn1_DEFAULT in a map passed to the M:encode/2 function; they must be omitted from the map. Similarly, when decoding missing values will be omitted from the map. No .hrl files will be generated when the 'maps' options is used. That means values in an ASN.1 module must be retrieved by calling the appropriate function in generated module. Since we one day hope to get rid of the options 'compact_bit_string', 'legacy_bit_string', and 'legacy_erlang_types', we will not allow them to be combined with the 'maps' option.
2017-02-03Refactor code generation optionsBjörn Gustavsson
Most options to the code generation pass are passed through the process dictionary. At the same time, an Erule or Erules argument is passed to most code generation functions. The Erule argument is only an atom indicating the encoding rules ('ber', 'per', or 'uper'). Introduce a new record #gen{} to contain code generation options and parameters. Pass it as the Erule argument (renaming it to Gen in functions that we will have to touch anyway). In this commit, eliminate the use of the variable 'encoding_options' in the process dictionary.
2016-03-15update copyright-yearHenrik Nord
2016-02-12asn1: Suppress warnings for improper lists in generated codeBjörn Gustavsson
2015-06-18Change license text to APLv2Bruce Yinhe
2015-03-12Merge branch 'maint'Björn Gustavsson
* maint: asn1ct_gen: Correct generation of .hrl files for multiple ellipses Fix BER code generation
2015-03-06asn1ct_gen: Correct generation of .hrl files for multiple ellipsesBjörn Gustavsson
2015-01-12Clean up use of asn1ct_gen:gen_types()Björn Gustavsson
asn1ct_gen:gen_types/3 is called by gen_encode_constructed/4 and generates encode *and* decode functions for any nested types. To faciliate future rewriting, where we might want to tweak code generation for encode and decode separately, refactor the code so that gen_encode_constructed/4 will only encode functions for nested types, and gen_deccode_constructed/4 will generate decode functions for nested types.
2014-06-05BER: Eliminate dialyzer warnings for specialized decode functionsBjörn Gustavsson
2014-06-05Correct OCTET STRING default when legacy_erlang_types is activeBjörn Gustavsson
The default value for an OCTET STRING when legacy_erlang_types was active would be a binary instead of a list.
2014-06-05Remove old DEFAULT-checking code made obsolete in the previous commitBjörn Gustavsson
2014-05-06BER: Suppress dialyzer warnings for encode_bit_string/4Björn Gustavsson
We don't want to touch the code used for encoding BIT STRINGs when 'legacy_erl_types' is active, since it will be removed within two or three major releases. But we do want to suppress the dialyzer warnings in the meantime. The easiest way is to call encode_bit_string/4 with unknown types from an exported function that is never actually called like this: -export(['dialyzer-suppressions'/0]). 'dialyzer-suppressions'(Arg) -> {A,B,C,D} = Arg, encode_bit_string(A, B, C, D), ok.
2014-04-16Remove unused arguments for asn1ct_gen_ber_bin_v2:gen_dec_prim()Björn Gustavsson
Make the source code a little bit cleaner.
2014-04-16Add missing newline in -export()Björn Gustavsson
A newline was forgotten.
2014-03-21Protect generated .hrl files from multiple inclusionsBjörn Gustavsson
2014-01-31asn1ct_gen: Silence dialyzer warnings for unmatched returnsBjörn Gustavsson
2014-01-24Add legacy_erlang_typesBjörn Gustavsson
2014-01-20Introduce asn1ct_gen:open_output_file/1Björn Gustavsson
2013-10-01Fix broken handling of default values for BIT STRINGsBjörn Gustavsson
For DER/PER/UPER, a value equal to the DEFAULT is not supposed to be encoded. BIT STRINGs values can be represented as Erlang terms in four different ways: as an integer, as a list of zeroes and ones, as a {Unused,Binary} tuple, or as an Erlang bitstring. When encoding a BIT STRING, only certain representations of BIT STRINGs values were recognized. All representations must be recognized. When decoding a DEFAULT value for a BIT STRING, the actual value given in the decoding would be either an integer or a list of zeroes and one (depending on how the literal was written in the specification). We expect that the default value should be in the same representation as any other BIT STRING value (i.e. by default an Erlang bitstring, or a list if the 'legacy_bitstring' option has been given, or as compact bitstring if 'compact_bitstring' has been given).
2013-09-27Teach the ASN.1 compiler the no_ok_wrapper optionBjörn Gustavsson
Add the no_ok_wrapper option so that the generated M:encode/2 and M:decode/2 functions will not wrap a successful return value in an {ok,...} tuple. Errors will cause exceptions. Eliminating the wrapping tuple allows simpler nesting of calls.
2013-09-27Optimize the generated decode/2 functionBjörn Gustavsson
Use 'try' instead of 'catch', and don't match anything that cannot actually be returned from the generated encoding code.
2013-09-18asn1ct_gen: Clean up process dictionary after generatingBjörn Gustavsson
Cleanliness.
2013-09-03PER, UPER: Optimize table constraintsBjörn Gustavsson
The generated code for table constraints has several problems: * For each object set, a function for getting an encoding or decoding fun is generated, regardless of whether it is actually used. In many specifications, the object set actually used is the union of several other object sets. That means that the code can become a lot bulkier than it would need to be. * The funs are not necessary. The funs just add to the code bloat and generate more unnecessary garbage at run-time. Also, one of the arguments of the fun is the name of the field in the class which is known at compile-time, and the fun for decoding has unused arguments. How to fix the problems: At each call site where an open type should be encoded/decoded, call a specific generated function specialized for the actual object set and the name of the field in the class. When generating the specialized functions, make sure that we re-use a previously generated function if possible.
2013-08-30PER,UPER: Get rid of unused 'telltype' argument in decoding functionsBjörn Gustavsson
2013-08-30Optimize the generated encode/2 functionBjörn Gustavsson
Use 'try' instead of 'catch', and don't match anything that cannot actually be returned from the generated encoding code.
2013-08-30Remove broken support for multiple UNIQUEBjörn Gustavsson
According to the ASN.1 standard, having multiple UNIQUE in class is allowed. For example: C ::= CLASS { &id1 INTEGER UNIQUE, &id2 INTEGER UNIQUE } In practice, no one uses multiple UNIQUE. The ASN.1 compiler will crash if a class with multiple UNIQUE is used, but the backends have half-hearted support for multiple UNIQUE in that they generate helper functions similar to: getenc_OBJECT_SET(id1, 42) -> fun enc_XXX/3; ... Since we have no plans to implement support for multiple UNIQUE (no one seems to have missed it), simplify the helper functions like this: getenc_OBJECT_SET(42) -> fun enc_XXX/3; ...
2013-05-31PER: Generate code for deep table constraints at compile-timeBjörn Gustavsson
For the PER backends, generate code for accessing deep table constraints at compile-time in the same way as is done for BER. While at it, remove the complicated indentation code. Also modernize the test suite and add a test for a deeper nested constraint.
2013-05-31Eliminate the {notype,_} return value from asn1ct_gen:type/1Björn Gustavsson
The last clause in asn1ct_gen:type/1 does a catched call to type2/1. If the type2/1 fails {notype,X} is returned. Since the body of type2/1 essentially is: case lists:member(X, [...]) of true -> {primitive,bif}; false -> case lists:member(X, [...]) of true -> {constructed,bif}; false -> {undefined,user} end end there is no way that type2/1 can fail. Therefore, we can eliminate the catch and put the body of type2/1 into the last clause of type/1. We can also eliminate the code in the callers of type/1 that match {notype,X}.
2013-05-31asn1ct, asn1ct_gen: Eliminate unused exportsBjörn Gustavsson
Stop export functions that are not called from outside their module. If the functions are not used at all, remove the functions too. The unused exports were found by running: xref:start(s). xref:add_application(s, code:lib_dir(asn1)). io:format("~p\n", [xref:analyze(s, exports_not_used)]).
2013-05-31Open the output file in raw mode with delayed writeBjörn Gustavsson
This change brings down the execution time on my computer for the entire asn1 test suite from about 340 seconds to 310 seconds.
2013-05-31Generate one call to io:put_chars/2 for each call to asn1ct_gen:emit/1Björn Gustavsson
asn1ct_gen:emit/1 used to make one call to io:put_chars/2 for each part of the term passed emit/1. By collecting all output into one iolist for each call emit/1 the time for running the entire asn1 test suite is reduced from about 460 seconds to 340 seconds on my computer.
2013-05-31Get rid of 'ANY' in the backendsBjörn Gustavsson
asn1ct_check has translated all occurrences of 'ANY' to 'ASN1_OPEN_TYPE'.
2013-05-31Eliminate general use of #typereference{}Björn Gustavsson
The record #typereference{} is only used internally within the asn1ct_parser2 module (the parser translates it to an #'Externaltypereference{} record).
2013-05-31PER/UPER: Share all code except encoding of primitivesBjörn Gustavsson
The only code that is really different between the PER and UPER backends is encoding of primitive types.
2013-02-14der: Correct code generation for checking of empty setsBjörn Gustavsson
The ASN.1 compiler would generate an Erlang module with incorrect syntax for: T DEFINITIONS AUTOMATIC TAGS ::= BEGIN Empty ::= SET { } S ::= SEQUENCE { e Empty DEFAULT {} } END
2013-01-25Update copyright yearsBjörn-Egil Dahlberg