Replace use of alloca with malloc.
[libtasn1.git] / lib / ASN1.y
blob7fac39ec6a5b2cd2130533ff469c90e16d5af4a9
1 /*
2 * Copyright (C) 2004, 2005, 2006, 2008 Free Software Foundation, Inc.
3 * Copyright (C) 2001, 2002 Fabio Fiorina
5 * This file is part of LIBTASN1.
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
24 /*****************************************************/
25 /* File: x509_ASN.y */
26 /* Description: input file for 'bison' program. */
27 /* The output file is a parser (in C language) for */
28 /* ASN.1 syntax */
29 /*****************************************************/
33 #include <int.h>
34 #include <errors.h>
35 #include <parser_aux.h>
36 #include <structure.h>
39 static FILE *file_asn1; /* Pointer to file to parse */
40 static asn1_retCode result_parse; /* result of the parser
41 algorithm */
42 static node_asn *p_tree; /* pointer to the root of the
43 structure created by the
44 parser*/
45 static unsigned long lineNumber; /* line number describing the
46 parser position inside the
47 file */
48 static char lastToken[MAX_NAME_SIZE+1]; /* last token find in the file
49 to parse before the 'parse
50 error' */
51 extern char _asn1_identifierMissing[];
52 static const char *fileName; /* file to parse */
54 int _asn1_yyerror (char *);
55 int _asn1_yylex(void);
59 /* Prefix symbols and functions with _asn1_ */
60 %name-prefix="_asn1_yy"
62 %union {
63 unsigned int constant;
64 char str[MAX_NAME_SIZE+1];
65 node_asn* node;
69 %token ASSIG "::="
70 %token <str> NUM
71 %token <str> IDENTIFIER
72 %token OPTIONAL
73 %token INTEGER
74 %token SIZE
75 %token OCTET
76 %token STRING
77 %token SEQUENCE
78 %token BIT
79 %token UNIVERSAL
80 %token PRIVATE
81 %token APPLICATION
82 %token OPTIONAL
83 %token DEFAULT
84 %token CHOICE
85 %token OF
86 %token OBJECT
87 %token STR_IDENTIFIER
88 %token BOOLEAN
89 %token TRUE
90 %token FALSE
91 %token TOKEN_NULL
92 %token ANY
93 %token DEFINED
94 %token BY
95 %token SET
96 %token EXPLICIT
97 %token IMPLICIT
98 %token DEFINITIONS
99 %token TAGS
100 %token BEGIN
101 %token END
102 %token UTCTime
103 %token GeneralizedTime
104 %token GeneralString
105 %token FROM
106 %token IMPORTS
107 %token ENUMERATED
109 %type <node> octet_string_def constant constant_list type_assig_right
110 %type <node> integer_def type_assig type_assig_list sequence_def type_def
111 %type <node> bit_string_def default size_def choise_def object_def
112 %type <node> boolean_def any_def size_def2 obj_constant obj_constant_list
113 %type <node> constant_def type_constant type_constant_list definitions
114 %type <node> definitions_id Time bit_element bit_element_list set_def
115 %type <node> tag_type tag type_assig_right_tag generalstring_def
116 %type <node> type_assig_right_tag_default enumerated_def
117 %type <str> pos_num neg_num pos_neg_num pos_neg_identifier pos_neg_list
118 %type <str> num_identifier
119 %type <constant> class explicit_implicit
124 definitions: definitions_id
125 DEFINITIONS explicit_implicit TAGS "::=" BEGIN /* imports_def */
126 type_constant_list END
127 {$$=_asn1_add_node(TYPE_DEFINITIONS|$3);
128 _asn1_set_name($$,_asn1_get_name($1));
129 _asn1_set_name($1,"");
130 _asn1_set_right($1,$7);
131 _asn1_set_down($$,$1);
133 p_tree=$$;
137 pos_num : NUM {strcpy($$,$1);}
138 | '+' NUM {strcpy($$,$2);}
141 neg_num : '-' NUM {strcpy($$,"-");
142 strcat($$,$2);}
145 pos_neg_num : pos_num {strcpy($$,$1);}
146 | neg_num {strcpy($$,$1);}
149 num_identifier : NUM {strcpy($$,$1);}
150 | IDENTIFIER {strcpy($$,$1);}
153 pos_neg_identifier : pos_neg_num {strcpy($$,$1);}
154 | IDENTIFIER {strcpy($$,$1);}
157 constant: '(' pos_neg_num ')' {$$=_asn1_add_node(TYPE_CONSTANT);
158 _asn1_set_value($$,$2,strlen($2)+1);}
159 | IDENTIFIER'('pos_neg_num')' {$$=_asn1_add_node(TYPE_CONSTANT);
160 _asn1_set_name($$,$1);
161 _asn1_set_value($$,$3,strlen($3)+1);}
164 constant_list: constant {$$=$1;}
165 | constant_list ',' constant {$$=$1;
166 _asn1_set_right(_asn1_get_last_right($1),$3);}
169 obj_constant: num_identifier {$$=_asn1_add_node(TYPE_CONSTANT);
170 _asn1_set_value($$,$1,strlen($1)+1);}
171 | IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
172 _asn1_set_name($$,$1);
173 _asn1_set_value($$,$3,strlen($3)+1);}
176 obj_constant_list: obj_constant {$$=$1;}
177 | obj_constant_list obj_constant {$$=$1;
178 _asn1_set_right(_asn1_get_last_right($1),$2);}
181 class : UNIVERSAL {$$=CONST_UNIVERSAL;}
182 | PRIVATE {$$=CONST_PRIVATE;}
183 | APPLICATION {$$=CONST_APPLICATION;}
186 tag_type : '[' NUM ']' {$$=_asn1_add_node(TYPE_TAG);
187 _asn1_set_value($$,$2,strlen($2)+1);}
188 | '[' class NUM ']' {$$=_asn1_add_node(TYPE_TAG | $2);
189 _asn1_set_value($$,$3,strlen($3)+1);}
192 tag : tag_type {$$=$1;}
193 | tag_type EXPLICIT {$$=_asn1_mod_type($1,CONST_EXPLICIT);}
194 | tag_type IMPLICIT {$$=_asn1_mod_type($1,CONST_IMPLICIT);}
197 default : DEFAULT pos_neg_identifier {$$=_asn1_add_node(TYPE_DEFAULT);
198 _asn1_set_value($$,$2,strlen($2)+1);}
199 | DEFAULT TRUE {$$=_asn1_add_node(TYPE_DEFAULT|CONST_TRUE);}
200 | DEFAULT FALSE {$$=_asn1_add_node(TYPE_DEFAULT|CONST_FALSE);}
204 pos_neg_list: pos_neg_num
205 | pos_neg_list '|' pos_neg_num
209 integer_def: INTEGER {$$=_asn1_add_node(TYPE_INTEGER);}
210 | INTEGER'{'constant_list'}' {$$=_asn1_add_node(TYPE_INTEGER|CONST_LIST);
211 _asn1_set_down($$,$3);}
212 | integer_def'(' pos_neg_list ')' {$$=_asn1_add_node(TYPE_INTEGER);}
213 | integer_def'('num_identifier'.''.'num_identifier')'
214 {$$=_asn1_add_node(TYPE_INTEGER|CONST_MIN_MAX);
215 _asn1_set_down($$,_asn1_add_node(TYPE_SIZE));
216 _asn1_set_value(_asn1_get_down($$),$6,strlen($6)+1);
217 _asn1_set_name(_asn1_get_down($$),$3);}
220 boolean_def: BOOLEAN {$$=_asn1_add_node(TYPE_BOOLEAN);}
223 Time: UTCTime {$$=_asn1_add_node(TYPE_TIME|CONST_UTC);}
224 | GeneralizedTime {$$=_asn1_add_node(TYPE_TIME|CONST_GENERALIZED);}
227 size_def2: SIZE'('num_identifier')' {$$=_asn1_add_node(TYPE_SIZE|CONST_1_PARAM);
228 _asn1_set_value($$,$3,strlen($3)+1);}
229 | SIZE'('num_identifier'.''.'num_identifier')'
230 {$$=_asn1_add_node(TYPE_SIZE|CONST_MIN_MAX);
231 _asn1_set_value($$,$3,strlen($3)+1);
232 _asn1_set_name($$,$6);}
235 size_def: size_def2 {$$=$1;}
236 | '(' size_def2 ')' {$$=$2;}
239 generalstring_def: GeneralString {$$=_asn1_add_node(TYPE_GENERALSTRING);}
240 | GeneralString size_def {$$=_asn1_add_node(TYPE_GENERALSTRING|CONST_SIZE);
241 _asn1_set_down($$,$2);}
244 octet_string_def : OCTET STRING {$$=_asn1_add_node(TYPE_OCTET_STRING);}
245 | OCTET STRING size_def {$$=_asn1_add_node(TYPE_OCTET_STRING|CONST_SIZE);
246 _asn1_set_down($$,$3);}
249 bit_element : IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
250 _asn1_set_name($$,$1);
251 _asn1_set_value($$,$3,strlen($3)+1);}
254 bit_element_list : bit_element {$$=$1;}
255 | bit_element_list ',' bit_element {$$=$1;
256 _asn1_set_right(_asn1_get_last_right($1),$3);}
259 bit_string_def : BIT STRING {$$=_asn1_add_node(TYPE_BIT_STRING);}
260 | BIT STRING size_def {$$=_asn1_add_node(TYPE_BIT_STRING|CONST_SIZE);}
261 | BIT STRING'{'bit_element_list'}'
262 {$$=_asn1_add_node(TYPE_BIT_STRING|CONST_LIST);
263 _asn1_set_down($$,$4);}
266 enumerated_def : ENUMERATED'{'bit_element_list'}'
267 {$$=_asn1_add_node(TYPE_ENUMERATED|CONST_LIST);
268 _asn1_set_down($$,$3);}
272 object_def : OBJECT STR_IDENTIFIER {$$=_asn1_add_node(TYPE_OBJECT_ID);}
275 type_assig_right: IDENTIFIER {$$=_asn1_add_node(TYPE_IDENTIFIER);
276 _asn1_set_value($$,$1,strlen($1)+1);}
277 | IDENTIFIER size_def {$$=_asn1_add_node(TYPE_IDENTIFIER|CONST_SIZE);
278 _asn1_set_value($$,$1,strlen($1)+1);
279 _asn1_set_down($$,$2);}
280 | integer_def {$$=$1;}
281 | enumerated_def {$$=$1;}
282 | boolean_def {$$=$1;}
283 | Time
284 | octet_string_def {$$=$1;}
285 | bit_string_def {$$=$1;}
286 | generalstring_def {$$=$1;}
287 | sequence_def {$$=$1;}
288 | object_def {$$=$1;}
289 | choise_def {$$=$1;}
290 | any_def {$$=$1;}
291 | set_def {$$=$1;}
292 | TOKEN_NULL {$$=_asn1_add_node(TYPE_NULL);}
295 type_assig_right_tag : type_assig_right {$$=$1;}
296 | tag type_assig_right {$$=_asn1_mod_type($2,CONST_TAG);
297 _asn1_set_right($1,_asn1_get_down($$));
298 _asn1_set_down($$,$1);}
301 type_assig_right_tag_default : type_assig_right_tag {$$=$1;}
302 | type_assig_right_tag default {$$=_asn1_mod_type($1,CONST_DEFAULT);
303 _asn1_set_right($2,_asn1_get_down($$));
304 _asn1_set_down($$,$2);}
305 | type_assig_right_tag OPTIONAL {$$=_asn1_mod_type($1,CONST_OPTION);}
308 type_assig : IDENTIFIER type_assig_right_tag_default {$$=_asn1_set_name($2,$1);}
311 type_assig_list : type_assig {$$=$1;}
312 | type_assig_list','type_assig {$$=$1;
313 _asn1_set_right(_asn1_get_last_right($1),$3);}
316 sequence_def : SEQUENCE'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SEQUENCE);
317 _asn1_set_down($$,$3);}
318 | SEQUENCE OF type_assig_right {$$=_asn1_add_node(TYPE_SEQUENCE_OF);
319 _asn1_set_down($$,$3);}
320 | SEQUENCE size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SEQUENCE_OF|CONST_SIZE);
321 _asn1_set_right($2,$4);
322 _asn1_set_down($$,$2);}
325 set_def : SET'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SET);
326 _asn1_set_down($$,$3);}
327 | SET OF type_assig_right {$$=_asn1_add_node(TYPE_SET_OF);
328 _asn1_set_down($$,$3);}
329 | SET size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SET_OF|CONST_SIZE);
330 _asn1_set_right($2,$4);
331 _asn1_set_down($$,$2);}
334 choise_def : CHOICE'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_CHOICE);
335 _asn1_set_down($$,$3);}
338 any_def : ANY {$$=_asn1_add_node(TYPE_ANY);}
339 | ANY DEFINED BY IDENTIFIER {$$=_asn1_add_node(TYPE_ANY|CONST_DEFINED_BY);
340 _asn1_set_down($$,_asn1_add_node(TYPE_CONSTANT));
341 _asn1_set_name(_asn1_get_down($$),$4);}
344 type_def : IDENTIFIER "::=" type_assig_right_tag {$$=_asn1_set_name($3,$1);}
347 constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
348 {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN);
349 _asn1_set_name($$,$1);
350 _asn1_set_down($$,$6);}
351 | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
352 {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
353 _asn1_set_name($$,$1);
354 _asn1_set_value($$,$2,strlen($2)+1);
355 _asn1_set_down($$,$5);}
356 | IDENTIFIER INTEGER "::=" pos_neg_num
357 {$$=_asn1_add_node(TYPE_INTEGER|CONST_ASSIGN);
358 _asn1_set_name($$,$1);
359 _asn1_set_value($$,$4,strlen($4)+1);}
362 type_constant: type_def {$$=$1;}
363 | constant_def {$$=$1;}
366 type_constant_list : type_constant {$$=$1;}
367 | type_constant_list type_constant {$$=$1;
368 _asn1_set_right(_asn1_get_last_right($1),$2);}
371 definitions_id : IDENTIFIER '{' obj_constant_list '}' {$$=_asn1_add_node(TYPE_OBJECT_ID);
372 _asn1_set_down($$,$3);
373 _asn1_set_name($$,$1);}
374 | IDENTIFIER '{' '}' {$$=_asn1_add_node(TYPE_OBJECT_ID);
375 _asn1_set_name($$,$1);}
379 identifier_list : IDENTIFIER {$$=_asn1_add_node(TYPE_IDENTIFIER);
380 _asn1_set_name($$,$1);}
381 | identifier_list IDENTIFIER
382 {$$=$1;
383 _asn1_set_right(_asn1_get_last_right($$),_asn1_add_node(TYPE_IDENTIFIER));
384 _asn1_set_name(_asn1_get_last_right($$),$2);}
388 imports_def : empty {$$=NULL;}
389 | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list
390 {$$=_asn1_add_node(TYPE_IMPORTS);
391 _asn1_set_down($$,_asn1_add_node(TYPE_OBJECT_ID));
392 _asn1_set_name(_asn1_get_down($$),$4);
393 _asn1_set_down(_asn1_get_down($$),$5);
394 _asn1_set_right($$,$2);}
398 explicit_implicit : EXPLICIT {$$=CONST_EXPLICIT;}
399 | IMPLICIT {$$=CONST_IMPLICIT;}
407 const char *key_word[]={"::=","OPTIONAL","INTEGER","SIZE","OCTET","STRING"
408 ,"SEQUENCE","BIT","UNIVERSAL","PRIVATE","OPTIONAL"
409 ,"DEFAULT","CHOICE","OF","OBJECT","IDENTIFIER"
410 ,"BOOLEAN","TRUE","FALSE","APPLICATION","ANY","DEFINED"
411 ,"SET","BY","EXPLICIT","IMPLICIT","DEFINITIONS","TAGS"
412 ,"BEGIN","END","UTCTime","GeneralizedTime"
413 ,"GeneralString","FROM","IMPORTS","NULL","ENUMERATED"};
414 const int key_word_token[]={ASSIG,OPTIONAL,INTEGER,SIZE,OCTET,STRING
415 ,SEQUENCE,BIT,UNIVERSAL,PRIVATE,OPTIONAL
416 ,DEFAULT,CHOICE,OF,OBJECT,STR_IDENTIFIER
417 ,BOOLEAN,TRUE,FALSE,APPLICATION,ANY,DEFINED
418 ,SET,BY,EXPLICIT,IMPLICIT,DEFINITIONS,TAGS
419 ,BEGIN,END,UTCTime,GeneralizedTime
420 ,GeneralString,FROM,IMPORTS,TOKEN_NULL,ENUMERATED};
422 /*************************************************************/
423 /* Function: _asn1_yylex */
424 /* Description: looks for tokens in file_asn1 pointer file. */
425 /* Return: int */
426 /* Token identifier or ASCII code or 0(zero: End Of File) */
427 /*************************************************************/
429 _asn1_yylex()
431 int c,counter=0,k,lastc;
432 char string[MAX_NAME_SIZE+1]; /* will contain the next token */
434 while(1)
436 while((c=fgetc(file_asn1))==' ' || c=='\t' || c=='\n')
437 if(c=='\n') lineNumber++;
439 if(c==EOF){
440 strcpy(lastToken,"End Of File");
441 return 0;
444 if(c=='(' || c==')' || c=='[' || c==']' ||
445 c=='{' || c=='}' || c==',' || c=='.' ||
446 c=='+' || c=='|'){
447 lastToken[0]=c;lastToken[1]=0;
448 return c;
450 if(c=='-'){ /* Maybe the first '-' of a comment */
451 if((c=fgetc(file_asn1))!='-'){
452 ungetc(c,file_asn1);
453 lastToken[0]='-';lastToken[1]=0;
454 return '-';
456 else{ /* Comments */
457 lastc=0;
458 counter=0;
459 /* A comment finishes at the next double hypen or the end of line */
460 while((c=fgetc(file_asn1))!=EOF && c!='\n' &&
461 (lastc!='-' || (lastc=='-' && c!='-')))
462 lastc=c;
463 if(c==EOF){
464 strcpy(lastToken,"End Of File");
465 return 0;
467 else{
468 if(c=='\n') lineNumber++;
469 continue; /* next char, please! (repeat the search) */
473 string[counter++]=c;
474 /* Till the end of the token */
475 while(!((c=fgetc(file_asn1))==EOF || c==' '|| c=='\t' || c=='\n' ||
476 c=='(' || c==')' || c=='[' || c==']' ||
477 c=='{' || c=='}' || c==',' || c=='.'))
479 if(counter>=MAX_NAME_SIZE){
480 result_parse=ASN1_NAME_TOO_LONG;
481 return 0;
483 string[counter++]=c;
485 ungetc(c,file_asn1);
486 string[counter]=0;
487 strcpy(lastToken,string);
489 /* Is STRING a number? */
490 for(k=0;k<counter;k++)
491 if(!isdigit(string[k])) break;
492 if(k>=counter)
494 strcpy(yylval.str,string);
495 return NUM; /* return the number */
498 /* Is STRING a keyword? */
499 for(k=0;k<(sizeof(key_word)/sizeof(char*));k++)
500 if(!strcmp(string,key_word[k])) return key_word_token[k];
502 /* STRING is an IDENTIFIER */
503 strcpy(yylval.str,string);
504 return IDENTIFIER;
509 /*************************************************************/
510 /* Function: _asn1_create_errorDescription */
511 /* Description: creates a string with the description of the*/
512 /* error. */
513 /* Parameters: */
514 /* error : error to describe. */
515 /* errorDescription: string that will contain the */
516 /* description. */
517 /*************************************************************/
518 void
519 _asn1_create_errorDescription(int error,char *errorDescription)
521 switch(error){
522 case ASN1_SUCCESS: case ASN1_FILE_NOT_FOUND:
523 if (errorDescription!=NULL) errorDescription[0]=0;
524 break;
525 case ASN1_SYNTAX_ERROR:
526 if (errorDescription!=NULL) {
527 strcpy(errorDescription,fileName);
528 strcat(errorDescription,":");
529 _asn1_ltostr(lineNumber,errorDescription+strlen(fileName)+1);
530 strcat(errorDescription,": parse error near '");
531 strcat(errorDescription,lastToken);
532 strcat(errorDescription,"'");
534 break;
535 case ASN1_NAME_TOO_LONG:
536 if (errorDescription!=NULL) {
537 strcpy(errorDescription,fileName);
538 strcat(errorDescription,":");
539 _asn1_ltostr(lineNumber,errorDescription+strlen(fileName)+1);
540 strcat(errorDescription,": name too long (more than ");
541 _asn1_ltostr(MAX_NAME_SIZE,errorDescription+strlen(errorDescription));
542 strcat(errorDescription," characters)");
544 break;
545 case ASN1_IDENTIFIER_NOT_FOUND:
546 if (errorDescription!=NULL) {
547 strcpy(errorDescription,fileName);
548 strcat(errorDescription,":");
549 strcat(errorDescription,": identifier '");
550 strcat(errorDescription,_asn1_identifierMissing);
551 strcat(errorDescription,"' not found");
553 break;
554 default:
555 if (errorDescription!=NULL) errorDescription[0]=0;
556 break;
563 * asn1_parser2tree - function used to start the parse algorithm.
564 * @file_name: specify the path and the name of file that contains
565 * ASN.1 declarations.
566 * @definitions: return the pointer to the structure created from
567 * "file_name" ASN.1 declarations.
568 * @errorDescription: return the error description or an empty
569 * string if success.
571 * Creates the structures needed to manage the definitions included
572 * in *FILE_NAME file.
574 * Returns:
576 * ASN1_SUCCESS: The file has a correct syntax and every identifier
577 * is known.
579 * ASN1_ELEMENT_NOT_EMPTY: *POINTER not ASN1_TYPE_EMPTY.
581 * ASN1_FILE_NOT_FOUND: An error occured while opening FILE_NAME.
583 * ASN1_SYNTAX_ERROR: The syntax is not correct.
585 * ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that
586 * is not defined.
588 * ASN1_NAME_TOO_LONG: In the file there is an identifier whith more
589 * than MAX_NAME_SIZE characters.
591 asn1_retCode
592 asn1_parser2tree(const char *file_name, ASN1_TYPE *definitions,
593 char *errorDescription){
595 p_tree=ASN1_TYPE_EMPTY;
597 if(*definitions != ASN1_TYPE_EMPTY)
598 return ASN1_ELEMENT_NOT_EMPTY;
600 *definitions=ASN1_TYPE_EMPTY;
602 fileName = file_name;
604 /* open the file to parse */
605 file_asn1=fopen(file_name,"r");
607 if(file_asn1==NULL){
608 result_parse=ASN1_FILE_NOT_FOUND;
610 else{
611 result_parse=ASN1_SUCCESS;
613 lineNumber=1;
614 yyparse();
616 fclose(file_asn1);
618 if(result_parse==ASN1_SUCCESS){ /* syntax OK */
619 /* set IMPLICIT or EXPLICIT property */
620 _asn1_set_default_tag(p_tree);
621 /* set CONST_SET and CONST_NOT_USED */
622 _asn1_type_set_config(p_tree);
623 /* check the identifier definitions */
624 result_parse=_asn1_check_identifier(p_tree);
625 if(result_parse==ASN1_SUCCESS){ /* all identifier defined */
626 /* Delete the list and keep the ASN1 structure */
627 _asn1_delete_list();
628 /* Convert into DER coding the value assign to INTEGER constants */
629 _asn1_change_integer_value(p_tree);
630 /* Expand the IDs of OBJECT IDENTIFIER constants */
631 _asn1_expand_object_id(p_tree);
633 *definitions=p_tree;
635 else /* some identifiers not defined */
636 /* Delete the list and the ASN1 structure */
637 _asn1_delete_list_and_nodes();
639 else /* syntax error */
640 /* Delete the list and the ASN1 structure */
641 _asn1_delete_list_and_nodes();
644 if (errorDescription!=NULL)
645 _asn1_create_errorDescription(result_parse,errorDescription);
647 return result_parse;
652 * asn1_parser2array - function that generates a C structure from an ASN1 file
653 * @inputFileName: specify the path and the name of file that
654 * contains ASN.1 declarations.
655 * @outputFileName: specify the path and the name of file that will
656 * contain the C vector definition.
657 * @vectorName: specify the name of the C vector.
658 * @errorDescription : return the error description or an empty
659 * string if success.
661 * Creates a file containing a C vector to use to manage the
662 * definitions included in *INPUTFILENAME file. If *INPUTFILENAME is
663 * "/aa/bb/xx.yy" and OUTPUTFILENAME is NULL, the file created is
664 * "/aa/bb/xx_asn1_tab.c". If VECTORNAME is NULL the vector name
665 * will be "xx_asn1_tab".
667 * Returns:
669 * ASN1_SUCCESS: The file has a correct syntax and every identifier
670 * is known.
672 * ASN1_FILE_NOT_FOUND: An error occured while opening FILE_NAME.
674 * ASN1_SYNTAX_ERROR: The syntax is not correct.
676 * ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that
677 * is not defined.
679 * ASN1_NAME_TOO_LONG: In the file there is an identifier whith more
680 * than MAX_NAME_SIZE characters.
682 int asn1_parser2array(const char *inputFileName,const char *outputFileName,
683 const char *vectorName,char *errorDescription){
684 char *file_out_name=NULL;
685 char *vector_name=NULL;
686 const char *char_p,*slash_p,*dot_p;
688 p_tree=NULL;
690 fileName = inputFileName;
692 /* open the file to parse */
693 file_asn1=fopen(inputFileName,"r");
695 if(file_asn1==NULL)
696 result_parse=ASN1_FILE_NOT_FOUND;
697 else{
698 result_parse=ASN1_SUCCESS;
700 lineNumber=1;
701 yyparse();
703 fclose(file_asn1);
705 if(result_parse==ASN1_SUCCESS){ /* syntax OK */
706 /* set IMPLICIT or EXPLICIT property */
707 _asn1_set_default_tag(p_tree);
708 /* set CONST_SET and CONST_NOT_USED */
709 _asn1_type_set_config(p_tree);
710 /* check the identifier definitions */
711 result_parse=_asn1_check_identifier(p_tree);
713 if(result_parse==ASN1_SUCCESS){ /* all identifier defined */
715 /* searching the last '/' and '.' in inputFileName */
716 char_p=inputFileName;
717 slash_p=inputFileName;
718 while((char_p=strchr(char_p,'/'))){
719 char_p++;
720 slash_p=char_p;
723 char_p=slash_p;
724 dot_p=inputFileName+strlen(inputFileName);
726 while((char_p=strchr(char_p,'.'))){
727 dot_p=char_p;
728 char_p++;
731 if(outputFileName == NULL){
732 /* file_out_name = inputFileName + _asn1_tab.c */
733 file_out_name=(char *)malloc(dot_p-inputFileName+1+
734 strlen("_asn1_tab.c"));
735 memcpy(file_out_name,inputFileName,dot_p-inputFileName);
736 file_out_name[dot_p-inputFileName]=0;
737 strcat(file_out_name,"_asn1_tab.c");
739 else{
740 /* file_out_name = inputFileName */
741 file_out_name=(char *)malloc(strlen(outputFileName)+1);
742 strcpy(file_out_name,outputFileName);
745 if(vectorName == NULL){
746 /* vector_name = file name + _asn1_tab */
747 vector_name=(char *)malloc(dot_p-slash_p+1+
748 strlen("_asn1_tab"));
749 memcpy(vector_name,slash_p,dot_p-slash_p);
750 vector_name[dot_p-slash_p]=0;
751 strcat(vector_name,"_asn1_tab");
753 else{
754 /* vector_name = vectorName */
755 vector_name=(char *)malloc(strlen(vectorName)+1);
756 strcpy(vector_name,vectorName);
759 /* Save structure in a file */
760 _asn1_create_static_structure(p_tree,
761 file_out_name,vector_name);
763 free(file_out_name);
764 free(vector_name);
765 } /* result == OK */
766 } /* result == OK */
768 /* Delete the list and the ASN1 structure */
769 _asn1_delete_list_and_nodes();
770 } /* inputFile exist */
772 if (errorDescription!=NULL)
773 _asn1_create_errorDescription(result_parse,errorDescription);
775 return result_parse;
779 /*************************************************************/
780 /* Function: _asn1_yyerror */
781 /* Description: function called when there are syntax errors*/
782 /* Parameters: */
783 /* char *s : error description */
784 /* Return: int */
785 /* */
786 /*************************************************************/
787 int _asn1_yyerror (char *s)
789 /* Sends the error description to the std_out */
791 #ifdef LIBTASN1_DEBUG_PARSER
792 _libtasn1_log("_asn1_yyerror:%s:%d: %s (Last Token:'%s')\n",fileName,
793 lineNumber,s,lastToken);
794 #endif
796 if(result_parse!=ASN1_NAME_TOO_LONG)
797 result_parse=ASN1_SYNTAX_ERROR;
799 return 0;