Fix make check for objdir != srcdir, reported by Bernard Leak <bernard@brenda-arkle...
[libtasn1.git] / lib / ASN1.y
blobe521120e42ebdbab550943a7ba9ef653501a0b5e
1 /* Copyright (C) 2001, 2002 Fabio Fiorina
2 * Copyright (C) 2004, 2005 Simon Josefsson
4 * This file is part of LIBTASN1.
6 * The LIBTASN1 library is free software; you can redistribute it
7 * and/or modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301, USA
23 /*****************************************************/
24 /* File: x509_ASN.y */
25 /* Description: input file for 'bison' program. */
26 /* The output file is a parser (in C language) for */
27 /* ASN.1 syntax */
28 /*****************************************************/
32 #include <int.h>
33 #include <errors.h>
34 #include <parser_aux.h>
35 #include <structure.h>
38 static FILE *file_asn1; /* Pointer to file to parse */
39 static asn1_retCode result_parse; /* result of the parser
40 algorithm */
41 static node_asn *p_tree; /* pointer to the root of the
42 structure created by the
43 parser*/
44 static unsigned long lineNumber; /* line number describing the
45 parser position inside the
46 file */
47 static char lastToken[MAX_NAME_SIZE+1]; /* last token find in the file
48 to parse before the 'parse
49 error' */
50 extern char _asn1_identifierMissing[];
51 static const char *fileName; /* file to parse */
53 int _asn1_yyerror (char *);
54 int _asn1_yylex(void);
58 /* Prefix symbols and functions with _asn1_ */
59 %name-prefix="_asn1_yy"
61 %union {
62 unsigned int constant;
63 char str[MAX_NAME_SIZE+1];
64 node_asn* node;
68 %token ASSIG "::="
69 %token <str> NUM
70 %token <str> IDENTIFIER
71 %token OPTIONAL
72 %token INTEGER
73 %token SIZE
74 %token OCTET
75 %token STRING
76 %token SEQUENCE
77 %token BIT
78 %token UNIVERSAL
79 %token PRIVATE
80 %token APPLICATION
81 %token OPTIONAL
82 %token DEFAULT
83 %token CHOICE
84 %token OF
85 %token OBJECT
86 %token STR_IDENTIFIER
87 %token BOOLEAN
88 %token TRUE
89 %token FALSE
90 %token TOKEN_NULL
91 %token ANY
92 %token DEFINED
93 %token BY
94 %token SET
95 %token EXPLICIT
96 %token IMPLICIT
97 %token DEFINITIONS
98 %token TAGS
99 %token BEGIN
100 %token END
101 %token UTCTime
102 %token GeneralizedTime
103 %token GeneralString
104 %token FROM
105 %token IMPORTS
106 %token ENUMERATED
108 %type <node> octet_string_def constant constant_list type_assig_right
109 %type <node> integer_def type_assig type_assig_list sequence_def type_def
110 %type <node> bit_string_def default size_def choise_def object_def
111 %type <node> boolean_def any_def size_def2 obj_constant obj_constant_list
112 %type <node> constant_def type_constant type_constant_list definitions
113 %type <node> definitions_id Time bit_element bit_element_list set_def
114 %type <node> tag_type tag type_assig_right_tag generalstring_def
115 %type <node> type_assig_right_tag_default enumerated_def
116 %type <str> pos_num neg_num pos_neg_num pos_neg_identifier pos_neg_list
117 %type <str> num_identifier
118 %type <constant> class explicit_implicit
123 definitions: definitions_id
124 DEFINITIONS explicit_implicit TAGS "::=" BEGIN /* imports_def */
125 type_constant_list END
126 {$$=_asn1_add_node(TYPE_DEFINITIONS|$3);
127 _asn1_set_name($$,_asn1_get_name($1));
128 _asn1_set_name($1,"");
129 _asn1_set_right($1,$7);
130 _asn1_set_down($$,$1);
132 p_tree=$$;
136 pos_num : NUM {strcpy($$,$1);}
137 | '+' NUM {strcpy($$,$2);}
140 neg_num : '-' NUM {strcpy($$,"-");
141 strcat($$,$2);}
144 pos_neg_num : pos_num {strcpy($$,$1);}
145 | neg_num {strcpy($$,$1);}
148 num_identifier : NUM {strcpy($$,$1);}
149 | IDENTIFIER {strcpy($$,$1);}
152 pos_neg_identifier : pos_neg_num {strcpy($$,$1);}
153 | IDENTIFIER {strcpy($$,$1);}
156 constant: '(' pos_neg_num ')' {$$=_asn1_add_node(TYPE_CONSTANT);
157 _asn1_set_value($$,$2,strlen($2)+1);}
158 | IDENTIFIER'('pos_neg_num')' {$$=_asn1_add_node(TYPE_CONSTANT);
159 _asn1_set_name($$,$1);
160 _asn1_set_value($$,$3,strlen($3)+1);}
163 constant_list: constant {$$=$1;}
164 | constant_list ',' constant {$$=$1;
165 _asn1_set_right(_asn1_get_last_right($1),$3);}
168 obj_constant: num_identifier {$$=_asn1_add_node(TYPE_CONSTANT);
169 _asn1_set_value($$,$1,strlen($1)+1);}
170 | IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
171 _asn1_set_name($$,$1);
172 _asn1_set_value($$,$3,strlen($3)+1);}
175 obj_constant_list: obj_constant {$$=$1;}
176 | obj_constant_list obj_constant {$$=$1;
177 _asn1_set_right(_asn1_get_last_right($1),$2);}
180 class : UNIVERSAL {$$=CONST_UNIVERSAL;}
181 | PRIVATE {$$=CONST_PRIVATE;}
182 | APPLICATION {$$=CONST_APPLICATION;}
185 tag_type : '[' NUM ']' {$$=_asn1_add_node(TYPE_TAG);
186 _asn1_set_value($$,$2,strlen($2)+1);}
187 | '[' class NUM ']' {$$=_asn1_add_node(TYPE_TAG | $2);
188 _asn1_set_value($$,$3,strlen($3)+1);}
191 tag : tag_type {$$=$1;}
192 | tag_type EXPLICIT {$$=_asn1_mod_type($1,CONST_EXPLICIT);}
193 | tag_type IMPLICIT {$$=_asn1_mod_type($1,CONST_IMPLICIT);}
196 default : DEFAULT pos_neg_identifier {$$=_asn1_add_node(TYPE_DEFAULT);
197 _asn1_set_value($$,$2,strlen($2)+1);}
198 | DEFAULT TRUE {$$=_asn1_add_node(TYPE_DEFAULT|CONST_TRUE);}
199 | DEFAULT FALSE {$$=_asn1_add_node(TYPE_DEFAULT|CONST_FALSE);}
203 pos_neg_list: pos_neg_num
204 | pos_neg_list '|' pos_neg_num
208 integer_def: INTEGER {$$=_asn1_add_node(TYPE_INTEGER);}
209 | INTEGER'{'constant_list'}' {$$=_asn1_add_node(TYPE_INTEGER|CONST_LIST);
210 _asn1_set_down($$,$3);}
211 | INTEGER'(' pos_neg_list ')' {$$=_asn1_add_node(TYPE_INTEGER);}
212 | INTEGER'('num_identifier'.''.'num_identifier')'
213 {$$=_asn1_add_node(TYPE_INTEGER|CONST_MIN_MAX);
214 _asn1_set_down($$,_asn1_add_node(TYPE_SIZE));
215 _asn1_set_value(_asn1_get_down($$),$6,strlen($6)+1);
216 _asn1_set_name(_asn1_get_down($$),$3);}
219 boolean_def: BOOLEAN {$$=_asn1_add_node(TYPE_BOOLEAN);}
222 Time: UTCTime {$$=_asn1_add_node(TYPE_TIME|CONST_UTC);}
223 | GeneralizedTime {$$=_asn1_add_node(TYPE_TIME|CONST_GENERALIZED);}
226 size_def2: SIZE'('num_identifier')' {$$=_asn1_add_node(TYPE_SIZE|CONST_1_PARAM);
227 _asn1_set_value($$,$3,strlen($3)+1);}
228 | SIZE'('num_identifier'.''.'num_identifier')'
229 {$$=_asn1_add_node(TYPE_SIZE|CONST_MIN_MAX);
230 _asn1_set_value($$,$3,strlen($3)+1);
231 _asn1_set_name($$,$6);}
234 size_def: size_def2 {$$=$1;}
235 | '(' size_def2 ')' {$$=$2;}
238 generalstring_def: GeneralString {$$=_asn1_add_node(TYPE_GENERALSTRING);}
239 | GeneralString size_def {$$=_asn1_add_node(TYPE_GENERALSTRING|CONST_SIZE);
240 _asn1_set_down($$,$2);}
243 octet_string_def : OCTET STRING {$$=_asn1_add_node(TYPE_OCTET_STRING);}
244 | OCTET STRING size_def {$$=_asn1_add_node(TYPE_OCTET_STRING|CONST_SIZE);
245 _asn1_set_down($$,$3);}
248 bit_element : IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
249 _asn1_set_name($$,$1);
250 _asn1_set_value($$,$3,strlen($3)+1);}
253 bit_element_list : bit_element {$$=$1;}
254 | bit_element_list ',' bit_element {$$=$1;
255 _asn1_set_right(_asn1_get_last_right($1),$3);}
258 bit_string_def : BIT STRING {$$=_asn1_add_node(TYPE_BIT_STRING);}
259 | BIT STRING'{'bit_element_list'}'
260 {$$=_asn1_add_node(TYPE_BIT_STRING|CONST_LIST);
261 _asn1_set_down($$,$4);}
264 enumerated_def : ENUMERATED'{'bit_element_list'}'
265 {$$=_asn1_add_node(TYPE_ENUMERATED|CONST_LIST);
266 _asn1_set_down($$,$3);}
270 object_def : OBJECT STR_IDENTIFIER {$$=_asn1_add_node(TYPE_OBJECT_ID);}
273 type_assig_right: IDENTIFIER {$$=_asn1_add_node(TYPE_IDENTIFIER);
274 _asn1_set_value($$,$1,strlen($1)+1);}
275 | IDENTIFIER size_def {$$=_asn1_add_node(TYPE_IDENTIFIER|CONST_SIZE);
276 _asn1_set_value($$,$1,strlen($1)+1);
277 _asn1_set_down($$,$2);}
278 | integer_def {$$=$1;}
279 | enumerated_def {$$=$1;}
280 | boolean_def {$$=$1;}
281 | Time
282 | octet_string_def {$$=$1;}
283 | bit_string_def {$$=$1;}
284 | generalstring_def {$$=$1;}
285 | sequence_def {$$=$1;}
286 | object_def {$$=$1;}
287 | choise_def {$$=$1;}
288 | any_def {$$=$1;}
289 | set_def {$$=$1;}
290 | TOKEN_NULL {$$=_asn1_add_node(TYPE_NULL);}
293 type_assig_right_tag : type_assig_right {$$=$1;}
294 | tag type_assig_right {$$=_asn1_mod_type($2,CONST_TAG);
295 _asn1_set_right($1,_asn1_get_down($$));
296 _asn1_set_down($$,$1);}
299 type_assig_right_tag_default : type_assig_right_tag {$$=$1;}
300 | type_assig_right_tag default {$$=_asn1_mod_type($1,CONST_DEFAULT);
301 _asn1_set_right($2,_asn1_get_down($$));
302 _asn1_set_down($$,$2);}
303 | type_assig_right_tag OPTIONAL {$$=_asn1_mod_type($1,CONST_OPTION);}
306 type_assig : IDENTIFIER type_assig_right_tag_default {$$=_asn1_set_name($2,$1);}
309 type_assig_list : type_assig {$$=$1;}
310 | type_assig_list','type_assig {$$=$1;
311 _asn1_set_right(_asn1_get_last_right($1),$3);}
314 sequence_def : SEQUENCE'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SEQUENCE);
315 _asn1_set_down($$,$3);}
316 | SEQUENCE OF type_assig_right {$$=_asn1_add_node(TYPE_SEQUENCE_OF);
317 _asn1_set_down($$,$3);}
318 | SEQUENCE size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SEQUENCE_OF|CONST_SIZE);
319 _asn1_set_right($2,$4);
320 _asn1_set_down($$,$2);}
323 set_def : SET'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SET);
324 _asn1_set_down($$,$3);}
325 | SET OF type_assig_right {$$=_asn1_add_node(TYPE_SET_OF);
326 _asn1_set_down($$,$3);}
327 | SET size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SET_OF|CONST_SIZE);
328 _asn1_set_right($2,$4);
329 _asn1_set_down($$,$2);}
332 choise_def : CHOICE'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_CHOICE);
333 _asn1_set_down($$,$3);}
336 any_def : ANY {$$=_asn1_add_node(TYPE_ANY);}
337 | ANY DEFINED BY IDENTIFIER {$$=_asn1_add_node(TYPE_ANY|CONST_DEFINED_BY);
338 _asn1_set_down($$,_asn1_add_node(TYPE_CONSTANT));
339 _asn1_set_name(_asn1_get_down($$),$4);}
342 type_def : IDENTIFIER "::=" type_assig_right_tag {$$=_asn1_set_name($3,$1);}
345 constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
346 {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN);
347 _asn1_set_name($$,$1);
348 _asn1_set_down($$,$6);}
349 | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
350 {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
351 _asn1_set_name($$,$1);
352 _asn1_set_value($$,$2,strlen($2)+1);
353 _asn1_set_down($$,$5);}
354 | IDENTIFIER INTEGER "::=" pos_neg_num
355 {$$=_asn1_add_node(TYPE_INTEGER|CONST_ASSIGN);
356 _asn1_set_name($$,$1);
357 _asn1_set_value($$,$4,strlen($4)+1);}
360 type_constant: type_def {$$=$1;}
361 | constant_def {$$=$1;}
364 type_constant_list : type_constant {$$=$1;}
365 | type_constant_list type_constant {$$=$1;
366 _asn1_set_right(_asn1_get_last_right($1),$2);}
369 definitions_id : IDENTIFIER '{' obj_constant_list '}' {$$=_asn1_add_node(TYPE_OBJECT_ID);
370 _asn1_set_down($$,$3);
371 _asn1_set_name($$,$1);}
372 | IDENTIFIER '{' '}' {$$=_asn1_add_node(TYPE_OBJECT_ID);
373 _asn1_set_name($$,$1);}
377 identifier_list : IDENTIFIER {$$=_asn1_add_node(TYPE_IDENTIFIER);
378 _asn1_set_name($$,$1);}
379 | identifier_list IDENTIFIER
380 {$$=$1;
381 _asn1_set_right(_asn1_get_last_right($$),_asn1_add_node(TYPE_IDENTIFIER));
382 _asn1_set_name(_asn1_get_last_right($$),$2);}
386 imports_def : empty {$$=NULL;}
387 | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list
388 {$$=_asn1_add_node(TYPE_IMPORTS);
389 _asn1_set_down($$,_asn1_add_node(TYPE_OBJECT_ID));
390 _asn1_set_name(_asn1_get_down($$),$4);
391 _asn1_set_down(_asn1_get_down($$),$5);
392 _asn1_set_right($$,$2);}
396 explicit_implicit : EXPLICIT {$$=CONST_EXPLICIT;}
397 | IMPLICIT {$$=CONST_IMPLICIT;}
405 const char *key_word[]={"::=","OPTIONAL","INTEGER","SIZE","OCTET","STRING"
406 ,"SEQUENCE","BIT","UNIVERSAL","PRIVATE","OPTIONAL"
407 ,"DEFAULT","CHOICE","OF","OBJECT","IDENTIFIER"
408 ,"BOOLEAN","TRUE","FALSE","APPLICATION","ANY","DEFINED"
409 ,"SET","BY","EXPLICIT","IMPLICIT","DEFINITIONS","TAGS"
410 ,"BEGIN","END","UTCTime","GeneralizedTime"
411 ,"GeneralString","FROM","IMPORTS","NULL","ENUMERATED"};
412 const int key_word_token[]={ASSIG,OPTIONAL,INTEGER,SIZE,OCTET,STRING
413 ,SEQUENCE,BIT,UNIVERSAL,PRIVATE,OPTIONAL
414 ,DEFAULT,CHOICE,OF,OBJECT,STR_IDENTIFIER
415 ,BOOLEAN,TRUE,FALSE,APPLICATION,ANY,DEFINED
416 ,SET,BY,EXPLICIT,IMPLICIT,DEFINITIONS,TAGS
417 ,BEGIN,END,UTCTime,GeneralizedTime
418 ,GeneralString,FROM,IMPORTS,TOKEN_NULL,ENUMERATED};
420 /*************************************************************/
421 /* Function: _asn1_yylex */
422 /* Description: looks for tokens in file_asn1 pointer file. */
423 /* Return: int */
424 /* Token identifier or ASCII code or 0(zero: End Of File) */
425 /*************************************************************/
427 _asn1_yylex()
429 int c,counter=0,k,lastc;
430 char string[MAX_NAME_SIZE+1]; /* will contain the next token */
432 while(1)
434 while((c=fgetc(file_asn1))==' ' || c=='\t' || c=='\n')
435 if(c=='\n') lineNumber++;
437 if(c==EOF){
438 strcpy(lastToken,"End Of File");
439 return 0;
442 if(c=='(' || c==')' || c=='[' || c==']' ||
443 c=='{' || c=='}' || c==',' || c=='.' ||
444 c=='+' || c=='|'){
445 lastToken[0]=c;lastToken[1]=0;
446 return c;
448 if(c=='-'){ /* Maybe the first '-' of a comment */
449 if((c=fgetc(file_asn1))!='-'){
450 ungetc(c,file_asn1);
451 lastToken[0]='-';lastToken[1]=0;
452 return '-';
454 else{ /* Comments */
455 lastc=0;
456 counter=0;
457 /* A comment finishes at the next double hypen or the end of line */
458 while((c=fgetc(file_asn1))!=EOF && c!='\n' &&
459 (lastc!='-' || (lastc=='-' && c!='-')))
460 lastc=c;
461 if(c==EOF){
462 strcpy(lastToken,"End Of File");
463 return 0;
465 else{
466 if(c=='\n') lineNumber++;
467 continue; /* next char, please! (repeat the search) */
471 string[counter++]=c;
472 /* Till the end of the token */
473 while(!((c=fgetc(file_asn1))==EOF || c==' '|| c=='\t' || c=='\n' ||
474 c=='(' || c==')' || c=='[' || c==']' ||
475 c=='{' || c=='}' || c==',' || c=='.'))
477 if(counter>=MAX_NAME_SIZE){
478 result_parse=ASN1_NAME_TOO_LONG;
479 return 0;
481 string[counter++]=c;
483 ungetc(c,file_asn1);
484 string[counter]=0;
485 strcpy(lastToken,string);
487 /* Is STRING a number? */
488 for(k=0;k<counter;k++)
489 if(!isdigit(string[k])) break;
490 if(k>=counter)
492 strcpy(yylval.str,string);
493 return NUM; /* return the number */
496 /* Is STRING a keyword? */
497 for(k=0;k<(sizeof(key_word)/sizeof(char*));k++)
498 if(!strcmp(string,key_word[k])) return key_word_token[k];
500 /* STRING is an IDENTIFIER */
501 strcpy(yylval.str,string);
502 return IDENTIFIER;
507 /*************************************************************/
508 /* Function: _asn1_create_errorDescription */
509 /* Description: creates a string with the description of the*/
510 /* error. */
511 /* Parameters: */
512 /* error : error to describe. */
513 /* errorDescription: string that will contain the */
514 /* description. */
515 /*************************************************************/
516 void
517 _asn1_create_errorDescription(int error,char *errorDescription)
519 switch(error){
520 case ASN1_SUCCESS: case ASN1_FILE_NOT_FOUND:
521 if (errorDescription!=NULL) errorDescription[0]=0;
522 break;
523 case ASN1_SYNTAX_ERROR:
524 if (errorDescription!=NULL) {
525 strcpy(errorDescription,fileName);
526 strcat(errorDescription,":");
527 _asn1_ltostr(lineNumber,errorDescription+strlen(fileName)+1);
528 strcat(errorDescription,": parse error near '");
529 strcat(errorDescription,lastToken);
530 strcat(errorDescription,"'");
532 break;
533 case ASN1_NAME_TOO_LONG:
534 if (errorDescription!=NULL) {
535 strcpy(errorDescription,fileName);
536 strcat(errorDescription,":");
537 _asn1_ltostr(lineNumber,errorDescription+strlen(fileName)+1);
538 strcat(errorDescription,": name too long (more than ");
539 _asn1_ltostr(MAX_NAME_SIZE,errorDescription+strlen(errorDescription));
540 strcat(errorDescription," characters)");
542 break;
543 case ASN1_IDENTIFIER_NOT_FOUND:
544 if (errorDescription!=NULL) {
545 strcpy(errorDescription,fileName);
546 strcat(errorDescription,":");
547 strcat(errorDescription,": identifier '");
548 strcat(errorDescription,_asn1_identifierMissing);
549 strcat(errorDescription,"' not found");
551 break;
552 default:
553 if (errorDescription!=NULL) errorDescription[0]=0;
554 break;
561 * asn1_parser2tree - function used to start the parse algorithm.
562 * @file_name: specify the path and the name of file that contains
563 * ASN.1 declarations.
564 * @definitions: return the pointer to the structure created from
565 * "file_name" ASN.1 declarations.
566 * @errorDescription: return the error description or an empty
567 * string if success.
569 * Creates the structures needed to manage the definitions included
570 * in *FILE_NAME file.
572 * Returns:
574 * ASN1_SUCCESS: The file has a correct syntax and every identifier
575 * is known.
577 * ASN1_ELEMENT_NOT_EMPTY: *POINTER not ASN1_TYPE_EMPTY.
579 * ASN1_FILE_NOT_FOUND: An error occured while opening FILE_NAME.
581 * ASN1_SYNTAX_ERROR: The syntax is not correct.
583 * ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that
584 * is not defined.
586 * ASN1_NAME_TOO_LONG: In the file there is an identifier whith more
587 * than MAX_NAME_SIZE characters.
589 asn1_retCode
590 asn1_parser2tree(const char *file_name, ASN1_TYPE *definitions,
591 char *errorDescription){
593 p_tree=ASN1_TYPE_EMPTY;
595 if(*definitions != ASN1_TYPE_EMPTY)
596 return ASN1_ELEMENT_NOT_EMPTY;
598 *definitions=ASN1_TYPE_EMPTY;
600 fileName = file_name;
602 /* open the file to parse */
603 file_asn1=fopen(file_name,"r");
605 if(file_asn1==NULL){
606 result_parse=ASN1_FILE_NOT_FOUND;
608 else{
609 result_parse=ASN1_SUCCESS;
611 lineNumber=1;
612 yyparse();
614 fclose(file_asn1);
616 if(result_parse==ASN1_SUCCESS){ /* syntax OK */
617 /* set IMPLICIT or EXPLICIT property */
618 _asn1_set_default_tag(p_tree);
619 /* set CONST_SET and CONST_NOT_USED */
620 _asn1_type_set_config(p_tree);
621 /* check the identifier definitions */
622 result_parse=_asn1_check_identifier(p_tree);
623 if(result_parse==ASN1_SUCCESS){ /* all identifier defined */
624 /* Delete the list and keep the ASN1 structure */
625 _asn1_delete_list();
626 /* Convert into DER coding the value assign to INTEGER constants */
627 _asn1_change_integer_value(p_tree);
628 /* Expand the IDs of OBJECT IDENTIFIER constants */
629 _asn1_expand_object_id(p_tree);
631 *definitions=p_tree;
633 else /* some identifiers not defined */
634 /* Delete the list and the ASN1 structure */
635 _asn1_delete_list_and_nodes();
637 else /* syntax error */
638 /* Delete the list and the ASN1 structure */
639 _asn1_delete_list_and_nodes();
642 if (errorDescription!=NULL)
643 _asn1_create_errorDescription(result_parse,errorDescription);
645 return result_parse;
650 * asn1_parser2array - function that generates a C structure from an ASN1 file
651 * @inputFileName: specify the path and the name of file that
652 * contains ASN.1 declarations.
653 * @outputFileName: specify the path and the name of file that will
654 * contain the C vector definition.
655 * @vectorName: specify the name of the C vector.
656 * @errorDescription : return the error description or an empty
657 * string if success.
659 * Creates a file containing a C vector to use to manage the
660 * definitions included in *INPUTFILENAME file. If *INPUTFILENAME is
661 * "/aa/bb/xx.yy" and OUTPUTFILENAME is NULL, the file created is
662 * "/aa/bb/xx_asn1_tab.c". If VECTORNAME is NULL the vector name
663 * will be "xx_asn1_tab".
665 * Returns:
667 * ASN1_SUCCESS: The file has a correct syntax and every identifier
668 * is known.
670 * ASN1_FILE_NOT_FOUND: An error occured while opening FILE_NAME.
672 * ASN1_SYNTAX_ERROR: The syntax is not correct.
674 * ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that
675 * is not defined.
677 * ASN1_NAME_TOO_LONG: In the file there is an identifier whith more
678 * than MAX_NAME_SIZE characters.
680 int asn1_parser2array(const char *inputFileName,const char *outputFileName,
681 const char *vectorName,char *errorDescription){
682 char *file_out_name=NULL;
683 char *vector_name=NULL;
684 const char *char_p,*slash_p,*dot_p;
686 p_tree=NULL;
688 fileName = inputFileName;
690 /* open the file to parse */
691 file_asn1=fopen(inputFileName,"r");
693 if(file_asn1==NULL)
694 result_parse=ASN1_FILE_NOT_FOUND;
695 else{
696 result_parse=ASN1_SUCCESS;
698 lineNumber=1;
699 yyparse();
701 fclose(file_asn1);
703 if(result_parse==ASN1_SUCCESS){ /* syntax OK */
704 /* set IMPLICIT or EXPLICIT property */
705 _asn1_set_default_tag(p_tree);
706 /* set CONST_SET and CONST_NOT_USED */
707 _asn1_type_set_config(p_tree);
708 /* check the identifier definitions */
709 result_parse=_asn1_check_identifier(p_tree);
711 if(result_parse==ASN1_SUCCESS){ /* all identifier defined */
713 /* searching the last '/' and '.' in inputFileName */
714 char_p=inputFileName;
715 slash_p=inputFileName;
716 while((char_p=strchr(char_p,'/'))){
717 char_p++;
718 slash_p=char_p;
721 char_p=slash_p;
722 dot_p=inputFileName+strlen(inputFileName);
724 while((char_p=strchr(char_p,'.'))){
725 dot_p=char_p;
726 char_p++;
729 if(outputFileName == NULL){
730 /* file_out_name = inputFileName + _asn1_tab.c */
731 file_out_name=(char *)malloc(dot_p-inputFileName+1+
732 strlen("_asn1_tab.c"));
733 memcpy(file_out_name,inputFileName,dot_p-inputFileName);
734 file_out_name[dot_p-inputFileName]=0;
735 strcat(file_out_name,"_asn1_tab.c");
737 else{
738 /* file_out_name = inputFileName */
739 file_out_name=(char *)malloc(strlen(outputFileName)+1);
740 strcpy(file_out_name,outputFileName);
743 if(vectorName == NULL){
744 /* vector_name = file name + _asn1_tab */
745 vector_name=(char *)malloc(dot_p-slash_p+1+
746 strlen("_asn1_tab"));
747 memcpy(vector_name,slash_p,dot_p-slash_p);
748 vector_name[dot_p-slash_p]=0;
749 strcat(vector_name,"_asn1_tab");
751 else{
752 /* vector_name = vectorName */
753 vector_name=(char *)malloc(strlen(vectorName)+1);
754 strcpy(vector_name,vectorName);
757 /* Save structure in a file */
758 _asn1_create_static_structure(p_tree,
759 file_out_name,vector_name);
761 free(file_out_name);
762 free(vector_name);
763 } /* result == OK */
764 } /* result == OK */
766 /* Delete the list and the ASN1 structure */
767 _asn1_delete_list_and_nodes();
768 } /* inputFile exist */
770 if (errorDescription!=NULL)
771 _asn1_create_errorDescription(result_parse,errorDescription);
773 return result_parse;
777 /*************************************************************/
778 /* Function: _asn1_yyerror */
779 /* Description: function called when there are syntax errors*/
780 /* Parameters: */
781 /* char *s : error description */
782 /* Return: int */
783 /* */
784 /*************************************************************/
785 int _asn1_yyerror (char *s)
787 /* Sends the error description to the std_out */
789 #ifdef LIBTASN1_DEBUG_PARSER
790 _libtasn1_log("_asn1_yyerror:%s:%d: %s (Last Token:'%s')\n",fileName,
791 lineNumber,s,lastToken);
792 #endif
794 if(result_parse!=ASN1_NAME_TOO_LONG)
795 result_parse=ASN1_SYNTAX_ERROR;
797 return 0;