Skip to content

Commit

Permalink
Merge pull request #172 from v0-e/class-default-syntax-support
Browse files Browse the repository at this point in the history
Class default syntax support
  • Loading branch information
mouse07410 authored Feb 2, 2024
2 parents 648f0bc + a7d3249 commit a6bdcd2
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 22 deletions.
97 changes: 83 additions & 14 deletions libasn1fix/asn1fix_cws.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,6 @@ asn1f_check_class_object(arg_t *arg) {
return 0;
}

if(!eclass->with_syntax) {
DEBUG("Can't process classes without %s just yet",
"WITH SYNTAX");
return 0;
}

row = asn1p_ioc_row_new(eclass);
assert(row);

Expand Down Expand Up @@ -266,12 +260,6 @@ asn1f_parse_class_object(arg_t *arg) {
DEBUG("Value %s of CLASS %s found at line %d",
expr->Identifier, eclass->Identifier, expr->_lineno);

if(!eclass->with_syntax) {
DEBUG("Can't process classes without %s just yet",
"WITH SYNTAX");
return 0;
}

struct parse_object_key key = {
.arg = arg,
.expr = expr,
Expand Down Expand Up @@ -308,10 +296,70 @@ asn1f_parse_class_object(arg_t *arg) {
return 0;
}

#define SKIPSPACES for(; buf < bend && isspace(*buf); buf++)
#define SKIPSPACES \
for(; buf < bend && isspace(*buf); buf++)

static int
_asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
_asn1f_parse_class_object_data_default_syntx(arg_t *arg, asn1p_expr_t *eclass,
struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
const uint8_t *buf, const uint8_t *bend,
int optional_mode, const uint8_t **newpos, int counter) {
int ret;

/* Default syntax: { FieldSetting , * }
* where, FieldSetting ::= PrimitiveFieldName Setting
* and, FieldSetting is a reference and Setting is not
* Contrary to with the defined WITH SYNTAX,
* FieldSetting's can appear in any order */

asn1p_expr_t* cm;
SKIPSPACES;
for (; buf < bend; ++buf) {
/* find possible literal PrimitiveFieldName */
if(*buf != '&') {
continue;
}
TQ_FOR(cm, &(eclass->members), next) {
/* PrimitiveFieldName */
int id_len = strlen(cm->Identifier);
if(id_len > (bend - buf)) {
continue;
}
if(memcmp(buf, cm->Identifier, id_len) == 0) {
buf += strlen(cm->Identifier);
SKIPSPACES;

/* Setting */
const uint8_t *p = 0;
for(p = buf; p < bend && (*p) != ','; p++) {}

struct asn1p_ioc_cell_s *cell;
cell = asn1p_ioc_row_cell_fetch(row,
cm->Identifier);
if(cell == NULL) {
if(newpos) *newpos = buf;
return -1;
}
DEBUG("Reference %s satisfied by %s (%d)",
cm->Identifier,
buf, p - buf);
ret = _asn1f_assign_cell_value(arg, cell, buf, p, counter);
if(ret) return ret;
buf = p;
SKIPSPACES;
if(newpos) *newpos = buf;

break;
}
}
}

if(newpos) *newpos = buf;
return 0;
}

static int
_asn1f_parse_class_object_data_defined_syntx(arg_t *arg, asn1p_expr_t *eclass,
struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
const uint8_t *buf, const uint8_t *bend,
int optional_mode, const uint8_t **newpos, int counter) {
Expand Down Expand Up @@ -391,6 +439,27 @@ _asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
return 0;
}

static int
_asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax,
const uint8_t *buf, const uint8_t *bend,
int optional_mode, const uint8_t **newpos, int counter) {

if(!eclass->with_syntax) {
/* Assume default syntax */
return
_asn1f_parse_class_object_data_default_syntx(
arg, eclass, row, syntax, buf, bend,
optional_mode, newpos, counter);
} else {
/* WITH SYNTAX {} */
return
_asn1f_parse_class_object_data_defined_syntx(
arg, eclass, row, syntax, buf, bend,
optional_mode, newpos, counter);
}
}


static int
_asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell,
Expand Down
46 changes: 46 additions & 0 deletions libasn1parser/asn1p_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,52 @@ asn1p_wsyntx_clone(asn1p_wsyntx_t *wx) {
return nw;
}

asn1p_wsyntx_t*
asn1p_wsyntx_default(const struct asn1p_expr_s *eclass) {
/*
* Default syntax: { &literal field , * }
*/
asn1p_wsyntx_t *syntax;
asn1p_expr_t *member;
asn1p_wsyntx_chunk_t *chunk;

syntax = asn1p_wsyntx_new();
if(!syntax) {
return NULL;
}

#define ADD_DC(ctype, ctoken) \
do { \
chunk = asn1p_wsyntx_chunk_new(); \
if(!chunk) { \
asn1p_wsyntx_free(syntax); \
return NULL; \
} \
chunk->type = ctype; \
chunk->content.token = strdup(ctoken); \
TQ_ADD(&(syntax->chunks), chunk, next); \
} while(0)

TQ_FOR(member, (&eclass->members), next) {

/* &literal */
ADD_DC(WC_LITERAL, member->Identifier);

/* whitespace */
ADD_DC(WC_WHITESPACE, " ");

/* field */
ADD_DC(WC_FIELD, member->Identifier);

/* comma separator */
if(TQ_NEXT(member, next)) {
ADD_DC(WC_LITERAL, ",");
}
}

return syntax;
}

asn1p_wsyntx_chunk_t *
asn1p_wsyntx_chunk_fromstring(char *token, int do_copy) {
asn1p_wsyntx_chunk_t *wc;
Expand Down
4 changes: 4 additions & 0 deletions libasn1parser/asn1p_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ asn1p_wsyntx_chunk_t *asn1p_wsyntx_chunk_clone(asn1p_wsyntx_chunk_t *);
asn1p_wsyntx_t *asn1p_wsyntx_new(void);
void asn1p_wsyntx_free(asn1p_wsyntx_t *);
asn1p_wsyntx_t *asn1p_wsyntx_clone(asn1p_wsyntx_t *);
/*
* Creates a default syntax of some class
*/
asn1p_wsyntx_t *asn1p_wsyntx_default(const struct asn1p_expr_s *eclass);

/*
* RETURN VALUES:
Expand Down
40 changes: 40 additions & 0 deletions tests/tests-asn1c-compiler/164-class-default-syntax-OK.asn1
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
-- OK: Everything is fine

-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
-- .spelio.software.asn1c.test (9363.1.5.1)
-- .164

ModuleClassDefaultSyntax
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 164 }
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN

DCLASS ::= CLASS {
&id INTEGER,
&Type
}

Ordered DCLASS ::= {
{&id 1, &Type UTF8String} |
{&id 2, &Type OCTET STRING}
}

Unordered DCLASS ::= {
{&Type UTF8String, &id 17} |
{&id 8, &Type OCTET STRING}
}

A ::= SEQUENCE
{
a-Ordered-id DCLASS.&id ({Ordered}),
a-Ordered-val DCLASS.&Type ({Ordered}{@a-Ordered-id})
}

B ::= SEQUENCE
{
b-Unordered-id DCLASS.&id ({Unordered}),
b-Unordered-val DCLASS.&Type ({Unordered}{@b-Unordered-id})
}

END
4 changes: 0 additions & 4 deletions tests/tests-asn1c-compiler/18-class-OK.asn1
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,13 @@ BEGIN
&code INTEGER (0..MAX) UNIQUE,
&Alphabet IA5String DEFAULT {AlphaNumeric},
&ArgType ,
&SupportedArguments &ArgType OPTIONAL,
&ResultType DEFAULT NULL,
&result-if-error &ResultType DEFAULT NULL,
&associated-function FUNCTION OPTIONAL
}

operator-plus FUNCTION ::= {
&ArgType Pair,
&SupportedArguments { PosPair | NegPair }
&ResultType INTEGER,
&result-if-error 0,
&code 1
}

Expand Down
4 changes: 0 additions & 4 deletions tests/tests-asn1c-compiler/18-class-OK.asn1.+-E_-F
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,13 @@ FUNCTION ::= CLASS {
&code INTEGER (0..MAX) UNIQUE,
&Alphabet IA5String DEFAULT {AlphaNumeric},
&ArgType ,
&SupportedArguments &ArgType OPTIONAL,
&ResultType DEFAULT NULL,
&result-if-error &ResultType DEFAULT NULL,
&associated-function FUNCTION OPTIONAL
}

operator-plus FUNCTION ::= {
&ArgType Pair,
&SupportedArguments { PosPair | NegPair }
&ResultType INTEGER,
&result-if-error 0,
&code 1
}

Expand Down
1 change: 1 addition & 0 deletions tests/tests-c-compiler/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ TESTS += check-src/check-92.-findirect-choice.c
TESTS += check-src/check-92.c
TESTS += check-src/check-158.-fcompound-names.c
TESTS += check-src/check-159.c
TESTS += check-src/check-164.c

if TEST_64BIT
TESTS += check-src/check64-134.-gen-UPER.c
Expand Down
33 changes: 33 additions & 0 deletions tests/tests-c-compiler/check-src/check-164.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>

#include <A.h>
#include <B.h>

int
main(int ac, char **av) {
A_t a;
B_t b;

(void)ac; /* Unused argument */
(void)av; /* Unused argument */

memset(&a, 0, sizeof(a));
memset(&b, 0, sizeof(b));

/* Check existence of the following enum values */
assert(a_Ordered_val_PR_UTF8String);
assert(a_Ordered_val_PR_OCTET_STRING);
assert(b_Unordered_val_PR_UTF8String);
assert(b_Unordered_val_PR_OCTET_STRING);

/*
* No plans to fill it up: just checking whether it compiles or not.
*/

return 0;
}

0 comments on commit a6bdcd2

Please sign in to comment.