121 static const unsigned char token_to_tag[
NR__TOKENS] = {
156 static const char asn1_classes[4][5] = {
163 static const char asn1_methods[2][5] = {
168 static const char *
const asn1_universal_tags[32] = {
204 static const char *grammar_name;
205 static const char *outputname;
206 static const char *headername;
209 #define _(X) [DIRECTIVE_##X] = #X
300 static struct action *action_list;
301 static unsigned nr_actions;
312 static struct token *token_list;
313 static unsigned nr_tokens;
315 static int directive_compare(
const void *_key,
const void *_pdir)
318 const char *
const *pdir = _pdir, *
dir = *pdir;
323 clen = (dlen < token->
size) ? dlen : token->
size;
335 if (dlen == token->
size) {
340 return dlen - token->
size;
346 static void tokenise(
char *
buffer,
char *
end)
355 token_list = tokens = calloc((end - buffer) / 2,
sizeof(
struct token));
363 while (buffer < end) {
367 nl =
memchr(line,
'\n', end - buffer);
378 while ((p =
memchr(p,
'-', nl - p))) {
382 while ((q =
memchr(q,
'-', nl - q))) {
418 while (q < nl && (
isalnum(*q) || *q ==
'-' || *q ==
'_'))
420 tokens[tix].
size = q -
p;
434 dir =
bsearch(&tokens[tix], directives,
435 sizeof(directives) /
sizeof(directives[1]),
436 sizeof(directives[1]),
439 tokens[tix++].token_type = dir - directives;
451 while (q < nl && (
isdigit(*q)))
453 tokens[tix].
size = q -
p;
460 if (
memcmp(p,
"::=", 3) == 0) {
462 tokens[tix].
size = 3;
469 if (
memcmp(p,
"({", 2) == 0) {
471 tokens[tix].
size = 2;
475 if (
memcmp(p,
"})", 2) == 0) {
477 tokens[tix].
size = 2;
484 tokens[tix].
size = 1;
511 fprintf(stderr,
"%s:%u: Unknown character in grammar: '%c'\n",
518 printf(
"Extracted %u tokens\n", nr_tokens);
523 for (n = 0; n < nr_tokens; n++)
524 printf(
"Token %3u: '%*.*s'\n",
526 (
int)token_list[n].
size, (
int)token_list[n].size,
527 token_list[n].value);
532 static void build_type_list(
void);
533 static void parse(
void);
534 static void render(FILE *
out, FILE *
hdr);
548 fprintf(stderr,
"Format: %s <grammar-file> <c-file> <hdr-file>\n",
554 outputname = argv[2];
555 headername = argv[3];
563 if (fstat(fd, &st) < 0) {
573 if ((readlen =
read(fd, buffer, st.
st_size)) < 0) {
589 p = p ? p + 1 : argv[1];
590 grammar_name = strdup(p);
595 p =
strchr(grammar_name,
'.');
600 tokenise(buffer, buffer + readlen);
604 out = fopen(outputname,
"w");
610 hdr = fopen(headername,
"w");
618 if (fclose(out) < 0) {
623 if (fclose(hdr) < 0) {
659 #define ELEMENT_IMPLICIT 0x0001
660 #define ELEMENT_EXPLICIT 0x0002
661 #define ELEMENT_MARKED 0x0004
662 #define ELEMENT_RENDERED 0x0008
663 #define ELEMENT_SKIPPABLE 0x0010
664 #define ELEMENT_CONDITIONAL 0x0020
673 #define TYPE_STOP_MARKER 0x0001
674 #define TYPE_BEGIN 0x0002
677 static struct type *type_list;
678 static struct type **type_index;
679 static unsigned nr_types;
681 static int type_index_compare(
const void *_a,
const void *_b)
683 const struct type *
const *
a = _a, *
const *
b = _b;
685 if ((*a)->name->size != (*b)->name->size)
686 return (*a)->name->size - (*b)->name->size;
688 return memcmp((*a)->name->value, (*b)->name->value,
692 static int type_finder(
const void *_key,
const void *_ti)
694 const struct token *token = _key;
695 const struct type *
const *ti = _ti;
698 if (token->
size != type->
name->size)
699 return token->
size - type->
name->size;
708 static void build_type_list(
void)
714 for (n = 0; n < nr_tokens - 1; n++)
725 types = type_list = calloc(nr + 1,
sizeof(type_list[0]));
730 type_index = calloc(nr,
sizeof(type_index[0]));
738 for (n = 0; n < nr_tokens - 1; n++) {
741 types[
t].
name = &token_list[
n];
742 type_index[
t] = &types[
t];
746 types[
t].
name = &token_list[n + 1];
749 qsort(type_index, nr,
sizeof(type_index[0]), type_index_compare);
751 printf(
"Extracted %u types\n", nr_types);
753 for (n = 0; n < nr_types; n++) {
754 struct type *type = type_index[
n];
756 (
int)type->
name->size,
757 (
int)type->
name->size,
763 static struct element *parse_type(
struct token **_cursor,
struct token *
stop,
769 static void parse(
void)
771 struct token *cursor;
787 if (cursor != type[1].
name) {
788 fprintf(stderr,
"%s:%d: Parse error at token '%*.*s'\n",
796 printf(
"Extracted %u actions\n", nr_actions);
799 static struct element *element_list;
801 static struct element *alloc_elem(
struct token *type)
803 struct element *
e = calloc(1,
sizeof(*e));
813 static struct element *parse_compound(
struct token **_cursor,
struct token *end,
819 static struct element *parse_type(
struct token **_cursor,
struct token *end,
824 struct token *cursor = *_cursor;
827 int labelled = 0, implicit = 0;
829 top = element = alloc_elem(cursor);
832 element->
tag = token_to_tag[cursor->token_type];
840 switch (cursor->token_type) {
857 fprintf(stderr,
"%s:%d: Unrecognised tag class token '%*.*s'\n",
866 fprintf(stderr,
"%s:%d: Missing tag number '%*.*s'\n",
872 element->
tag &= ~0x1f;
873 element->
tag |= strtoul(cursor->
value, &p, 10);
881 fprintf(stderr,
"%s:%d: Missing closing square bracket '%*.*s'\n",
910 element->
children = alloc_elem(cursor);
914 element->
tag = token_to_tag[cursor->token_type];
919 element->
type = cursor;
920 switch (cursor->token_type) {
922 element->compound =
ANY;
980 ref =
bsearch(cursor, type_index, nr_types,
sizeof(type_index[0]),
983 fprintf(stderr,
"%s:%d: Type '%*.*s' undefined\n",
994 element->compound =
CHOICE;
996 element->
children = parse_compound(&cursor, end, 1);
1012 element->
children = parse_compound(&cursor, end, 0);
1017 element->compound =
SET;
1023 element->compound =
SET_OF;
1029 element->
children = parse_compound(&cursor, end, 1);
1034 fprintf(stderr,
"%s:%d: Token '%*.*s' does not introduce a type\n",
1053 fprintf(stderr,
"%s:%d: Token '%*.*s' is not an action function name\n",
1059 action =
malloc(
sizeof(
struct action) + cursor->
size + 1);
1068 for (ppaction = &action_list;
1070 ppaction = &(*ppaction)->
next
1072 int cmp =
strcmp(action->
name, (*ppaction)->name);
1079 action->
next = *ppaction;
1096 fprintf(stderr,
"%s:%d: Missing close action, got '%*.*s'\n",
1108 fprintf(stderr,
"%s:%d: Unexpected token '%*.*s'\n",
1121 static struct element *parse_compound(
struct token **_cursor,
struct token *end,
1125 struct token *cursor = *_cursor, *
name;
1128 fprintf(stderr,
"%s:%d: Expected compound to start with brace not '%*.*s'\n",
1138 fprintf(stderr,
"%s:%d: Empty compound\n",
1152 element = parse_type(&cursor, end, name);
1157 child_p = &element->
next;
1171 fprintf(stderr,
"%s:%d: Expected compound closure, got '%*.*s'\n",
1186 static void render_element(FILE *
out,
struct element *e,
struct element *
tag);
1187 static void render_out_of_line_list(FILE *
out);
1189 static int nr_entries;
1190 static int render_depth = 1;
1191 static struct element *render_list, **render_list_p = &render_list;
1194 static
void render_opcode(FILE *
out,
const char *
fmt, ...)
1199 fprintf(out,
"\t[%4d] =%*s", nr_entries, render_depth,
"");
1208 static
void render_more(FILE *
out,
const char *
fmt, ...)
1222 static void render(FILE *out, FILE *
hdr)
1230 fprintf(hdr,
" * Automatically generated by asn1_compiler. Do not edit\n");
1232 fprintf(hdr,
" * ASN.1 parser for %s\n", grammar_name);
1234 fprintf(hdr,
"#include <linux/asn1_decoder.h>\n");
1236 fprintf(hdr,
"extern const struct asn1_decoder %s_decoder;\n", grammar_name);
1243 fprintf(out,
" * Automatically generated by asn1_compiler. Do not edit\n");
1245 fprintf(out,
" * ASN.1 parser for %s\n", grammar_name);
1247 fprintf(out,
"#include <linux/asn1_ber_bytecode.h>\n");
1248 fprintf(out,
"#include \"%s-asn1.h\"\n", grammar_name);
1258 for (action = action_list;
action; action = action->
next) {
1259 action->
index = index++;
1261 "extern int %s(void *, size_t, unsigned char,"
1262 " const void *, size_t);\n",
1267 fprintf(out,
"enum %s_actions {\n", grammar_name);
1268 for (action = action_list;
action; action = action->
next)
1269 fprintf(out,
"\tACT_%s = %u,\n",
1271 fprintf(out,
"\tNR__%s_actions = %u\n", grammar_name, nr_actions);
1275 fprintf(out,
"static const asn1_action_t %s_action_table[NR__%s_actions] = {\n",
1276 grammar_name, grammar_name);
1277 for (action = action_list;
action; action = action->
next)
1289 root = &type_list[0];
1291 render_opcode(
NULL,
"ASN1_OP_COMPLETE,\n");
1292 render_out_of_line_list(
NULL);
1300 fprintf(out,
"static const unsigned char %s_machine[] = {\n",
1304 root = &type_list[0];
1306 render_opcode(out,
"ASN1_OP_COMPLETE,\n");
1307 render_out_of_line_list(out);
1312 fprintf(out,
"const struct asn1_decoder %s_decoder = {\n", grammar_name);
1313 fprintf(out,
"\t.machine = %s_machine,\n", grammar_name);
1314 fprintf(out,
"\t.machlen = sizeof(%s_machine),\n", grammar_name);
1315 fprintf(out,
"\t.actions = %s_action_table,\n", grammar_name);
1322 static void render_out_of_line_list(FILE *out)
1324 struct element *
e, *
ce;
1328 while ((e = render_list)) {
1331 render_list_p = &render_list;
1333 render_more(out,
"\n");
1337 render_element(out, ce,
NULL);
1340 act = e->
action ?
"_ACT" :
"";
1341 switch (e->compound) {
1343 render_opcode(out,
"ASN1_OP_END_SEQ%s,\n", act);
1346 render_opcode(out,
"ASN1_OP_END_SEQ_OF%s,\n", act);
1347 render_opcode(out,
"_jump_target(%u),\n", entry);
1350 render_opcode(out,
"ASN1_OP_END_SET%s,\n", act);
1353 render_opcode(out,
"ASN1_OP_END_SET_OF%s,\n", act);
1354 render_opcode(out,
"_jump_target(%u),\n", entry);
1358 render_opcode(out,
"_action(ACT_%s),\n",
1360 render_opcode(out,
"ASN1_OP_RETURN,\n");
1367 static void render_element(FILE *out,
struct element *e,
struct element *
tag)
1370 const char *
cond, *act;
1371 int entry, skippable = 0, outofline = 0;
1382 render_more(out,
"\t// %*.*s\n",
1390 act = e->
action ?
"_ACT" :
"";
1391 switch (e->compound) {
1393 render_opcode(out,
"ASN1_OP_%sMATCH_ANY%s,", cond, act);
1395 render_more(out,
"\t\t// %*.*s",
1396 (
int)e->
name->size, (
int)e->
name->size,
1398 render_more(out,
"\n");
1399 goto dont_render_tag;
1402 render_element(out, e->
children, e);
1409 render_opcode(out,
"ASN1_OP_%sMATCH%s%s,",
1411 outofline ?
"_JUMP" :
"",
1412 skippable ?
"_OR_SKIP" :
"");
1416 goto dont_render_tag;
1420 goto dont_render_tag;
1422 render_opcode(out,
"ASN1_OP_%sMATCH%s%s,",
1424 skippable ?
"_OR_SKIP" :
"");
1429 render_more(out,
"\t\t// %*.*s",
1430 (
int)e->
name->size, (
int)e->
name->size,
1432 render_more(out,
"\n");
1441 render_opcode(out,
"_tag(%s, %s, %s),\n",
1442 asn1_classes[tag->class],
1443 asn1_methods[tag->method | e->method],
1444 asn1_universal_tags[tag->
tag]);
1446 render_opcode(out,
"_tagn(%s, %s, %2u),\n",
1447 asn1_classes[tag->class],
1448 asn1_methods[tag->method | e->method],
1454 switch (e->compound) {
1456 render_element(out, e->
type->type->element, tag);
1458 render_opcode(out,
"ASN1_OP_ACT,\n");
1465 render_opcode(out,
"_jump_target(%u),", e->
entry_index);
1467 render_more(out,
"\t\t// --> %*.*s",
1471 render_more(out,
"\n");
1482 render_element(out, ec,
NULL);
1484 render_opcode(out,
"ASN1_OP_END_SEQ%s,\n", act);
1493 render_opcode(out,
"_jump_target(%u),", e->
entry_index);
1495 render_more(out,
"\t\t// --> %*.*s",
1499 render_more(out,
"\n");
1513 render_opcode(out,
"ASN1_OP_END_SEQ_OF%s,\n", act);
1515 render_opcode(out,
"ASN1_OP_END_SET_OF%s,\n", act);
1516 render_opcode(out,
"_jump_target(%u),\n", entry);
1527 fprintf(stderr,
"The ASN.1 SET type is not currently supported.\n");
1532 render_element(out, ec,
NULL);
1534 render_opcode(out,
"ASN1_OP_COND_FAIL,\n");
1536 render_opcode(out,
"ASN1_OP_ACT,\n");
1544 render_opcode(out,
"_action(ACT_%s),\n", e->
action->name);