manage 'INTEGER(1 | 2)' syntax
[libtasn1.git] / lib / ASN1.y
blob136deac11c41b8b246f7534a90ae8bf4293b9260
1 /* Copyright (C) 2001, 2002 Fabio Fiorina
3 * This file is part of LIBASN1.
5 * The LIBTASN1 library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /*****************************************************/
22 /* File: x509_ASN.y */
23 /* Description: input file for 'bison' program. */
24 /* The output file is a parser (in C language) for */
25 /* ASN.1 syntax */
26 /*****************************************************/
29 %{
30 #include <int.h>
31 #include <errors.h>
32 #include <parser_aux.h>
33 #include <structure.h>
36 static FILE *file_asn1; /* Pointer to file to parse */
37 static asn1_retCode result_parse; /* result of the parser algorithm */
38 static node_asn *p_tree; /* pointer to the root of the structure
39 created by the parser*/
40 static unsigned long lineNumber; /* line number describing the parser position
41 inside the file */
42 static char lastToken[MAX_NAME_SIZE+1]; /* last token find in the file to
43 parse before the 'parse error' */
44 extern char _asn1_identifierMissing[];
45 static const char *fileName; /* file to parse */
47 int _asn1_yyerror (char *);
48 int _asn1_yylex(void);
52 /* Prefix symbols and functions with _asn1_ */
53 %name-prefix="_asn1_yy"
55 %union {
56 unsigned int constant;
57 char str[MAX_NAME_SIZE+1];
58 node_asn* node;
62 %token ASSIG "::="
63 %token <str> NUM
64 %token <str> IDENTIFIER
65 %token OPTIONAL
66 %token INTEGER
67 %token SIZE
68 %token OCTET
69 %token STRING
70 %token SEQUENCE
71 %token BIT
72 %token UNIVERSAL
73 %token PRIVATE
74 %token APPLICATION
75 %token OPTIONAL
76 %token DEFAULT
77 %token CHOICE
78 %token OF
79 %token OBJECT
80 %token STR_IDENTIFIER
81 %token BOOLEAN
82 %token TRUE
83 %token FALSE
84 %token TOKEN_NULL
85 %token ANY
86 %token DEFINED
87 %token BY
88 %token SET
89 %token EXPLICIT
90 %token IMPLICIT
91 %token DEFINITIONS
92 %token TAGS
93 %token BEGIN
94 %token END
95 %token UTCTime
96 %token GeneralizedTime
97 %token GeneralString
98 %token FROM
99 %token IMPORTS
100 %token ENUMERATED
102 %type <node> octet_string_def constant constant_list type_assig_right
103 %type <node> integer_def type_assig type_assig_list sequence_def type_def
104 %type <node> bit_string_def default size_def choise_def object_def
105 %type <node> boolean_def any_def size_def2 obj_constant obj_constant_list
106 %type <node> constant_def type_constant type_constant_list definitions
107 %type <node> definitions_id Time bit_element bit_element_list set_def
108 %type <node> tag_type tag type_assig_right_tag generalstring_def
109 %type <node> type_assig_right_tag_default enumerated_def
110 %type <str> pos_num neg_num pos_neg_num pos_neg_identifier pos_neg_list
111 %type <str> num_identifier
112 %type <constant> class explicit_implicit
117 definitions: definitions_id
118 DEFINITIONS explicit_implicit TAGS "::=" BEGIN /* imports_def */
119 type_constant_list END
120 {$$=_asn1_add_node(TYPE_DEFINITIONS|$3);
121 _asn1_set_name($$,_asn1_get_name($1));
122 _asn1_set_name($1,"");
123 _asn1_set_right($1,$7);
124 _asn1_set_down($$,$1);
126 p_tree=$$;
130 pos_num : NUM {strcpy($$,$1);}
131 | '+' NUM {strcpy($$,$2);}
134 neg_num : '-' NUM {strcpy($$,"-");
135 strcat($$,$2);}
138 pos_neg_num : pos_num {strcpy($$,$1);}
139 | neg_num {strcpy($$,$1);}
142 num_identifier : NUM {strcpy($$,$1);}
143 | IDENTIFIER {strcpy($$,$1);}
146 pos_neg_identifier : pos_neg_num {strcpy($$,$1);}
147 | IDENTIFIER {strcpy($$,$1);}
150 constant: '(' pos_neg_num ')' {$$=_asn1_add_node(TYPE_CONSTANT);
151 _asn1_set_value($$,$2,strlen($2)+1);}
152 | IDENTIFIER'('pos_neg_num')' {$$=_asn1_add_node(TYPE_CONSTANT);
153 _asn1_set_name($$,$1);
154 _asn1_set_value($$,$3,strlen($3)+1);}
157 constant_list: constant {$$=$1;}
158 | constant_list ',' constant {$$=$1;
159 _asn1_set_right(_asn1_get_last_right($1),$3);}
162 obj_constant: num_identifier {$$=_asn1_add_node(TYPE_CONSTANT);
163 _asn1_set_value($$,$1,strlen($1)+1);}
164 | IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
165 _asn1_set_name($$,$1);
166 _asn1_set_value($$,$3,strlen($3)+1);}
169 obj_constant_list: obj_constant {$$=$1;}
170 | obj_constant_list obj_constant {$$=$1;
171 _asn1_set_right(_asn1_get_last_right($1),$2);}
174 class : UNIVERSAL {$$=CONST_UNIVERSAL;}
175 | PRIVATE {$$=CONST_PRIVATE;}
176 | APPLICATION {$$=CONST_APPLICATION;}
179 tag_type : '[' NUM ']' {$$=_asn1_add_node(TYPE_TAG);
180 _asn1_set_value($$,$2,strlen($2)+1);}
181 | '[' class NUM ']' {$$=_asn1_add_node(TYPE_TAG | $2);
182 _asn1_set_value($$,$3,strlen($3)+1);}
185 tag : tag_type {$$=$1;}
186 | tag_type EXPLICIT {$$=_asn1_mod_type($1,CONST_EXPLICIT);}
187 | tag_type IMPLICIT {$$=_asn1_mod_type($1,CONST_IMPLICIT);}
190 default : DEFAULT pos_neg_identifier {$$=_asn1_add_node(TYPE_DEFAULT);
191 _asn1_set_value($$,$2,strlen($2)+1);}
192 | DEFAULT TRUE {$$=_asn1_add_node(TYPE_DEFAULT|CONST_TRUE);}
193 | DEFAULT FALSE {$$=_asn1_add_node(TYPE_DEFAULT|CONST_FALSE);}
197 pos_neg_list: pos_neg_num
198 | pos_neg_list '|' pos_neg_num
202 integer_def: INTEGER {$$=_asn1_add_node(TYPE_INTEGER);}
203 | INTEGER'{'constant_list'}' {$$=_asn1_add_node(TYPE_INTEGER|CONST_LIST);
204 _asn1_set_down($$,$3);}
205 | INTEGER'(' pos_neg_list ')' {$$=_asn1_add_node(TYPE_INTEGER);}
206 | INTEGER'('num_identifier'.''.'num_identifier')'
207 {$$=_asn1_add_node(TYPE_INTEGER|CONST_MIN_MAX);
208 _asn1_set_down($$,_asn1_add_node(TYPE_SIZE));
209 _asn1_set_value(_asn1_get_down($$),$6,strlen($6)+1);
210 _asn1_set_name(_asn1_get_down($$),$3);}
213 boolean_def: BOOLEAN {$$=_asn1_add_node(TYPE_BOOLEAN);}
216 Time: UTCTime {$$=_asn1_add_node(TYPE_TIME|CONST_UTC);}
217 | GeneralizedTime {$$=_asn1_add_node(TYPE_TIME|CONST_GENERALIZED);}
220 size_def2: SIZE'('num_identifier')' {$$=_asn1_add_node(TYPE_SIZE|CONST_1_PARAM);
221 _asn1_set_value($$,$3,strlen($3)+1);}
222 | SIZE'('num_identifier'.''.'num_identifier')'
223 {$$=_asn1_add_node(TYPE_SIZE|CONST_MIN_MAX);
224 _asn1_set_value($$,$3,strlen($3)+1);
225 _asn1_set_name($$,$6);}
228 size_def: size_def2 {$$=$1;}
229 | '(' size_def2 ')' {$$=$2;}
232 generalstring_def: GeneralString {$$=_asn1_add_node(TYPE_GENERALSTRING);}
233 | GeneralString size_def {$$=_asn1_add_node(TYPE_GENERALSTRING|CONST_SIZE);
234 _asn1_set_down($$,$2);}
237 octet_string_def : OCTET STRING {$$=_asn1_add_node(TYPE_OCTET_STRING);}
238 | OCTET STRING size_def {$$=_asn1_add_node(TYPE_OCTET_STRING|CONST_SIZE);
239 _asn1_set_down($$,$3);}
242 bit_element : IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
243 _asn1_set_name($$,$1);
244 _asn1_set_value($$,$3,strlen($3)+1);}
247 bit_element_list : bit_element {$$=$1;}
248 | bit_element_list ',' bit_element {$$=$1;
249 _asn1_set_right(_asn1_get_last_right($1),$3);}
252 bit_string_def : BIT STRING {$$=_asn1_add_node(TYPE_BIT_STRING);}
253 | BIT STRING'{'bit_element_list'}'
254 {$$=_asn1_add_node(TYPE_BIT_STRING|CONST_LIST);
255 _asn1_set_down($$,$4);}
258 enumerated_def : ENUMERATED'{'bit_element_list'}'
259 {$$=_asn1_add_node(TYPE_ENUMERATED|CONST_LIST);
260 _asn1_set_down($$,$3);}
264 object_def : OBJECT STR_IDENTIFIER {$$=_asn1_add_node(TYPE_OBJECT_ID);}
267 type_assig_right: IDENTIFIER {$$=_asn1_add_node(TYPE_IDENTIFIER);
268 _asn1_set_value($$,$1,strlen($1)+1);}
269 | IDENTIFIER size_def {$$=_asn1_add_node(TYPE_IDENTIFIER|CONST_SIZE);
270 _asn1_set_value($$,$1,strlen($1)+1);
271 _asn1_set_down($$,$2);}
272 | integer_def {$$=$1;}
273 | enumerated_def {$$=$1;}
274 | boolean_def {$$=$1;}
275 | Time
276 | octet_string_def {$$=$1;}
277 | bit_string_def {$$=$1;}
278 | generalstring_def {$$=$1;}
279 | sequence_def {$$=$1;}
280 | object_def {$$=$1;}
281 | choise_def {$$=$1;}
282 | any_def {$$=$1;}
283 | set_def {$$=$1;}
284 | TOKEN_NULL {$$=_asn1_add_node(TYPE_NULL);}
287 type_assig_right_tag : type_assig_right {$$=$1;}
288 | tag type_assig_right {$$=_asn1_mod_type($2,CONST_TAG);
289 _asn1_set_right($1,_asn1_get_down($$));
290 _asn1_set_down($$,$1);}
293 type_assig_right_tag_default : type_assig_right_tag {$$=$1;}
294 | type_assig_right_tag default {$$=_asn1_mod_type($1,CONST_DEFAULT);
295 _asn1_set_right($2,_asn1_get_down($$));
296 _asn1_set_down($$,$2);}
297 | type_assig_right_tag OPTIONAL {$$=_asn1_mod_type($1,CONST_OPTION);}
300 type_assig : IDENTIFIER type_assig_right_tag_default {$$=_asn1_set_name($2,$1);}
303 type_assig_list : type_assig {$$=$1;}
304 | type_assig_list','type_assig {$$=$1;
305 _asn1_set_right(_asn1_get_last_right($1),$3);}
308 sequence_def : SEQUENCE'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SEQUENCE);
309 _asn1_set_down($$,$3);}
310 | SEQUENCE OF type_assig_right {$$=_asn1_add_node(TYPE_SEQUENCE_OF);
311 _asn1_set_down($$,$3);}
312 | SEQUENCE size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SEQUENCE_OF|CONST_SIZE);
313 _asn1_set_right($2,$4);
314 _asn1_set_down($$,$2);}
317 set_def : SET'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SET);
318 _asn1_set_down($$,$3);}
319 | SET OF type_assig_right {$$=_asn1_add_node(TYPE_SET_OF);
320 _asn1_set_down($$,$3);}
321 | SET size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SET_OF|CONST_SIZE);
322 _asn1_set_right($2,$4);
323 _asn1_set_down($$,$2);}
326 choise_def : CHOICE'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_CHOICE);
327 _asn1_set_down($$,$3);}
330 any_def : ANY {$$=_asn1_add_node(TYPE_ANY);}
331 | ANY DEFINED BY IDENTIFIER {$$=_asn1_add_node(TYPE_ANY|CONST_DEFINED_BY);
332 _asn1_set_down($$,_asn1_add_node(TYPE_CONSTANT));
333 _asn1_set_name(_asn1_get_down($$),$4);}
336 type_def : IDENTIFIER "::=" type_assig_right_tag {$$=_asn1_set_name($3,$1);}
339 constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
340 {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN);
341 _asn1_set_name($$,$1);
342 _asn1_set_down($$,$6);}
343 | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
344 {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
345 _asn1_set_name($$,$1);
346 _asn1_set_value($$,$2,strlen($2)+1);
347 _asn1_set_down($$,$5);}
348 | IDENTIFIER INTEGER "::=" pos_neg_num
349 {$$=_asn1_add_node(TYPE_INTEGER|CONST_ASSIGN);
350 _asn1_set_name($$,$1);
351 _asn1_set_value($$,$4,strlen($4)+1);}
354 type_constant: type_def {$$=$1;}
355 | constant_def {$$=$1;}
358 type_constant_list : type_constant {$$=$1;}
359 | type_constant_list type_constant {$$=$1;
360 _asn1_set_right(_asn1_get_last_right($1),$2);}
363 definitions_id : IDENTIFIER '{' obj_constant_list '}' {$$=_asn1_add_node(TYPE_OBJECT_ID);
364 _asn1_set_down($$,$3);
365 _asn1_set_name($$,$1);}
366 | IDENTIFIER '{' '}' {$$=_asn1_add_node(TYPE_OBJECT_ID);
367 _asn1_set_name($$,$1);}
371 identifier_list : IDENTIFIER {$$=_asn1_add_node(TYPE_IDENTIFIER);
372 _asn1_set_name($$,$1);}
373 | identifier_list IDENTIFIER
374 {$$=$1;
375 _asn1_set_right(_asn1_get_last_right($$),_asn1_add_node(TYPE_IDENTIFIER));
376 _asn1_set_name(_asn1_get_last_right($$),$2);}
380 imports_def : empty {$$=NULL;}
381 | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list
382 {$$=_asn1_add_node(TYPE_IMPORTS);
383 _asn1_set_down($$,_asn1_add_node(TYPE_OBJECT_ID));
384 _asn1_set_name(_asn1_get_down($$),$4);
385 _asn1_set_down(_asn1_get_down($$),$5);
386 _asn1_set_right($$,$2);}
390 explicit_implicit : EXPLICIT {$$=CONST_EXPLICIT;}
391 | IMPLICIT {$$=CONST_IMPLICIT;}
399 const char *key_word[]={"::=","OPTIONAL","INTEGER","SIZE","OCTET","STRING"
400 ,"SEQUENCE","BIT","UNIVERSAL","PRIVATE","OPTIONAL"
401 ,"DEFAULT","CHOICE","OF","OBJECT","IDENTIFIER"
402 ,"BOOLEAN","TRUE","FALSE","APPLICATION","ANY","DEFINED"
403 ,"SET","BY","EXPLICIT","IMPLICIT","DEFINITIONS","TAGS"
404 ,"BEGIN","END","UTCTime","GeneralizedTime"
405 ,"GeneralString","FROM","IMPORTS","NULL","ENUMERATED"};
406 const int key_word_token[]={ASSIG,OPTIONAL,INTEGER,SIZE,OCTET,STRING
407 ,SEQUENCE,BIT,UNIVERSAL,PRIVATE,OPTIONAL
408 ,DEFAULT,CHOICE,OF,OBJECT,STR_IDENTIFIER
409 ,BOOLEAN,TRUE,FALSE,APPLICATION,ANY,DEFINED
410 ,SET,BY,EXPLICIT,IMPLICIT,DEFINITIONS,TAGS
411 ,BEGIN,END,UTCTime,GeneralizedTime
412 ,GeneralString,FROM,IMPORTS,TOKEN_NULL,ENUMERATED};
414 /*************************************************************/
415 /* Function: _asn1_yylex */
416 /* Description: looks for tokens in file_asn1 pointer file. */
417 /* Return: int */
418 /* Token identifier or ASCII code or 0(zero: End Of File) */
419 /*************************************************************/
420 int
421 _asn1_yylex()
423 int c,counter=0,k,lastc;
424 char string[MAX_NAME_SIZE+1]; /* will contain the next token */
426 while(1)
428 while((c=fgetc(file_asn1))==' ' || c=='\t' || c=='\n')
429 if(c=='\n') lineNumber++;
431 if(c==EOF){
432 strcpy(lastToken,"End Of File");
433 return 0;
436 if(c=='(' || c==')' || c=='[' || c==']' ||
437 c=='{' || c=='}' || c==',' || c=='.' ||
438 c=='+' || c=='|'){
439 lastToken[0]=c;lastToken[1]=0;
440 return c;
442 if(c=='-'){ /* Maybe the first '-' of a comment */
443 if((c=fgetc(file_asn1))!='-'){
444 ungetc(c,file_asn1);
445 lastToken[0]='-';lastToken[1]=0;
446 return '-';
448 else{ /* Comments */
449 lastc=0;
450 counter=0;
451 /* A comment finishes at the next double hypen or the end of line */
452 while((c=fgetc(file_asn1))!=EOF && c!='\n' &&
453 (lastc!='-' || (lastc=='-' && c!='-')))
454 lastc=c;
455 if(c==EOF){
456 strcpy(lastToken,"End Of File");
457 return 0;
459 else{
460 if(c=='\n') lineNumber++;
461 continue; /* next char, please! (repeat the search) */
465 string[counter++]=c;
466 /* Till the end of the token */
467 while(!((c=fgetc(file_asn1))==EOF || c==' '|| c=='\t' || c=='\n' ||
468 c=='(' || c==')' || c=='[' || c==']' ||
469 c=='{' || c=='}' || c==',' || c=='.'))
471 if(counter>=MAX_NAME_SIZE){
472 result_parse=ASN1_NAME_TOO_LONG;
473 return 0;
475 string[counter++]=c;
477 ungetc(c,file_asn1);
478 string[counter]=0;
479 strcpy(lastToken,string);
481 /* Is STRING a number? */
482 for(k=0;k<counter;k++)
483 if(!isdigit(string[k])) break;
484 if(k>=counter)
486 strcpy(yylval.str,string);
487 return NUM; /* return the number */
490 /* Is STRING a keyword? */
491 for(k=0;k<(sizeof(key_word)/sizeof(char*));k++)
492 if(!strcmp(string,key_word[k])) return key_word_token[k];
494 /* STRING is an IDENTIFIER */
495 strcpy(yylval.str,string);
496 return IDENTIFIER;
501 /*************************************************************/
502 /* Function: _asn1_create_errorDescription */
503 /* Description: creates a string with the description of the*/
504 /* error. */
505 /* Parameters: */
506 /* error : error to describe. */
507 /* errorDescription: string that will contain the */
508 /* description. */
509 /*************************************************************/
510 void
511 _asn1_create_errorDescription(int error,char *errorDescription)
513 switch(error){
514 case ASN1_SUCCESS: case ASN1_FILE_NOT_FOUND:
515 if (errorDescription!=NULL) errorDescription[0]=0;
516 break;
517 case ASN1_SYNTAX_ERROR:
518 if (errorDescription!=NULL) {
519 strcpy(errorDescription,fileName);
520 strcat(errorDescription,":");
521 _asn1_ltostr(lineNumber,errorDescription+strlen(fileName)+1);
522 strcat(errorDescription,": parse error near '");
523 strcat(errorDescription,lastToken);
524 strcat(errorDescription,"'");
526 break;
527 case ASN1_NAME_TOO_LONG:
528 if (errorDescription!=NULL) {
529 strcpy(errorDescription,fileName);
530 strcat(errorDescription,":");
531 _asn1_ltostr(lineNumber,errorDescription+strlen(fileName)+1);
532 strcat(errorDescription,": name too long (more than ");
533 _asn1_ltostr(MAX_NAME_SIZE,errorDescription+strlen(errorDescription));
534 strcat(errorDescription," characters)");
536 break;
537 case ASN1_IDENTIFIER_NOT_FOUND:
538 if (errorDescription!=NULL) {
539 strcpy(errorDescription,fileName);
540 strcat(errorDescription,":");
541 strcat(errorDescription,": identifier '");
542 strcat(errorDescription,_asn1_identifierMissing);
543 strcat(errorDescription,"' not found");
545 break;
546 default:
547 if (errorDescription!=NULL) errorDescription[0]=0;
548 break;
555 * asn1_parser2tree - function used to start the parse algorithm.
556 * @file_name: specify the path and the name of file that contains ASN.1 declarations.
557 * @definitions: return the pointer to the structure created from
558 * "file_name" ASN.1 declarations.
559 * @errorDescription : return the error description or an empty string if success.
560 * Description:
562 * Creates the structures needed to manage the definitions included in *FILE_NAME file.
564 * Returns:
566 * ASN1_SUCCESS\: the file has a correct syntax and every identifier is known.
568 * ASN1_ELEMENT_NOT_EMPTY\: *POINTER not ASN1_TYPE_EMPTY.
570 * ASN1_FILE_NOT_FOUND\: an error occured while opening FILE_NAME.
572 * ASN1_SYNTAX_ERROR\: the syntax is not correct.
574 * ASN1_IDENTIFIER_NOT_FOUND\: in the file there is an identifier that is not defined.
575 * ASN1_NAME_TOO_LONG\: in the file there is an identifier whith more than MAX_NAME_SIZE characters.
577 asn1_retCode
578 asn1_parser2tree(const char *file_name,ASN1_TYPE *definitions,char *errorDescription){
580 p_tree=ASN1_TYPE_EMPTY;
582 if(*definitions != ASN1_TYPE_EMPTY)
583 return ASN1_ELEMENT_NOT_EMPTY;
585 *definitions=ASN1_TYPE_EMPTY;
587 fileName = file_name;
589 /* open the file to parse */
590 file_asn1=fopen(file_name,"r");
592 if(file_asn1==NULL){
593 result_parse=ASN1_FILE_NOT_FOUND;
595 else{
596 result_parse=ASN1_SUCCESS;
598 lineNumber=1;
599 yyparse();
601 fclose(file_asn1);
603 if(result_parse==ASN1_SUCCESS){ /* syntax OK */
604 /* set IMPLICIT or EXPLICIT property */
605 _asn1_set_default_tag(p_tree);
606 /* set CONST_SET and CONST_NOT_USED */
607 _asn1_type_set_config(p_tree);
608 /* check the identifier definitions */
609 result_parse=_asn1_check_identifier(p_tree);
610 if(result_parse==ASN1_SUCCESS){ /* all identifier defined */
611 /* Delete the list and keep the ASN1 structure */
612 _asn1_delete_list();
613 /* Convert into DER coding the value assign to INTEGER constants */
614 _asn1_change_integer_value(p_tree);
615 /* Expand the IDs of OBJECT IDENTIFIER constants */
616 _asn1_expand_object_id(p_tree);
618 *definitions=p_tree;
620 else /* some identifiers not defined */
621 /* Delete the list and the ASN1 structure */
622 _asn1_delete_list_and_nodes();
624 else /* syntax error */
625 /* Delete the list and the ASN1 structure */
626 _asn1_delete_list_and_nodes();
629 if (errorDescription!=NULL)
630 _asn1_create_errorDescription(result_parse,errorDescription);
632 return result_parse;
637 * asn1_parser2array - function that generates a C structure from an ASN1 file
638 * @inputFileName: specify the path and the name of file that contains ASN.1 declarations.
639 * @outputFileName: specify the path and the name of file that will contain the C vector definition.
640 * @vectorName: specify the name of the C vector.
641 * @errorDescription : return the error description or an empty string if success.
642 * Description:
644 * Creates a file containing a C vector to use to manage the definitions included in
645 * *INPUTFILENAME file. If *INPUTFILENAME is "/aa/bb/xx.yy" and OUTPUTFILENAME is NULL, the file created is "/aa/bb/xx_asn1_tab.c".
646 * If VECTORNAME is NULL the vector name will be "xx_asn1_tab".
648 * Returns:
650 * ASN1_SUCCESS\: the file has a correct syntax and every identifier is known.
652 * ASN1_FILE_NOT_FOUND\: an error occured while opening FILE_NAME.
654 * ASN1_SYNTAX_ERROR\: the syntax is not correct.
656 * ASN1_IDENTIFIER_NOT_FOUND\: in the file there is an identifier that is not defined.
657 * ASN1_NAME_TOO_LONG\: in the file there is an identifier whith more than MAX_NAME_SIZE characters.
659 int asn1_parser2array(const char *inputFileName,const char *outputFileName,
660 const char *vectorName,char *errorDescription){
661 char *file_out_name=NULL;
662 char *vector_name=NULL;
663 const char *char_p,*slash_p,*dot_p;
665 p_tree=NULL;
667 fileName = inputFileName;
669 /* open the file to parse */
670 file_asn1=fopen(inputFileName,"r");
672 if(file_asn1==NULL)
673 result_parse=ASN1_FILE_NOT_FOUND;
674 else{
675 result_parse=ASN1_SUCCESS;
677 lineNumber=1;
678 yyparse();
680 fclose(file_asn1);
682 if(result_parse==ASN1_SUCCESS){ /* syntax OK */
683 /* set IMPLICIT or EXPLICIT property */
684 _asn1_set_default_tag(p_tree);
685 /* set CONST_SET and CONST_NOT_USED */
686 _asn1_type_set_config(p_tree);
687 /* check the identifier definitions */
688 result_parse=_asn1_check_identifier(p_tree);
690 if(result_parse==ASN1_SUCCESS){ /* all identifier defined */
692 /* searching the last '/' and '.' in inputFileName */
693 char_p=inputFileName;
694 slash_p=inputFileName;
695 while((char_p=strchr(char_p,'/'))){
696 char_p++;
697 slash_p=char_p;
700 char_p=slash_p;
701 dot_p=inputFileName+strlen(inputFileName);
703 while((char_p=strchr(char_p,'.'))){
704 dot_p=char_p;
705 char_p++;
708 if(outputFileName == NULL){
709 /* file_out_name = inputFileName + _asn1_tab.c */
710 file_out_name=(char *)malloc(dot_p-inputFileName+1+
711 strlen("_asn1_tab.c"));
712 memcpy(file_out_name,inputFileName,dot_p-inputFileName);
713 file_out_name[dot_p-inputFileName]=0;
714 strcat(file_out_name,"_asn1_tab.c");
716 else{
717 /* file_out_name = inputFileName */
718 file_out_name=(char *)malloc(strlen(outputFileName)+1);
719 strcpy(file_out_name,outputFileName);
722 if(vectorName == NULL){
723 /* vector_name = file name + _asn1_tab */
724 vector_name=(char *)malloc(dot_p-slash_p+1+
725 strlen("_asn1_tab"));
726 memcpy(vector_name,slash_p,dot_p-slash_p);
727 vector_name[dot_p-slash_p]=0;
728 strcat(vector_name,"_asn1_tab");
730 else{
731 /* vector_name = vectorName */
732 vector_name=(char *)malloc(strlen(vectorName)+1);
733 strcpy(vector_name,vectorName);
736 /* Save structure in a file */
737 _asn1_create_static_structure(p_tree,
738 file_out_name,vector_name);
740 free(file_out_name);
741 free(vector_name);
742 } /* result == OK */
743 } /* result == OK */
745 /* Delete the list and the ASN1 structure */
746 _asn1_delete_list_and_nodes();
747 } /* inputFile exist */
749 if (errorDescription!=NULL)
750 _asn1_create_errorDescription(result_parse,errorDescription);
752 return result_parse;
756 /*************************************************************/
757 /* Function: _asn1_yyerror */
758 /* Description: function called when there are syntax errors*/
759 /* Parameters: */
760 /* char *s : error description */
761 /* Return: int */
762 /* */
763 /*************************************************************/
764 int _asn1_yyerror (char *s)
766 /* Sends the error description to the std_out */
768 #ifdef LIBTASN1_DEBUG_PARSER
769 _libtasn1_log("_asn1_yyerror:%s:%d: %s (Last Token:'%s')\n",fileName,
770 lineNumber,s,lastToken);
771 #endif
773 if(result_parse!=ASN1_NAME_TOO_LONG)
774 result_parse=ASN1_SYNTAX_ERROR;
776 return 0;