Update.
[libtasn1.git] / lib / ASN1.y
blob743ae75d247a9b8fef5ae6b069f8edc675bf7aad
1 /* Copyright (C) 2001, 2002 Fabio Fiorina
2 * Copyright (C) 2004 Simon Josefsson
4 * This file is part of LIBASN1.
6 * The LIBTASN1 library is free software; you can redistribute it and/or
7 * 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,
12 * but 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /*****************************************************/
23 /* File: x509_ASN.y */
24 /* Description: input file for 'bison' program. */
25 /* The output file is a parser (in C language) for */
26 /* ASN.1 syntax */
27 /*****************************************************/
31 #include <int.h>
32 #include <errors.h>
33 #include <parser_aux.h>
34 #include <structure.h>
37 static FILE *file_asn1; /* Pointer to file to parse */
38 static asn1_retCode result_parse; /* result of the parser
39 algorithm */
40 static node_asn *p_tree; /* pointer to the root of the
41 structure created by the
42 parser*/
43 static unsigned long lineNumber; /* line number describing the
44 parser position inside the
45 file */
46 static char lastToken[MAX_NAME_SIZE+1]; /* last token find in the file
47 to parse before the 'parse
48 error' */
49 extern char _asn1_identifierMissing[];
50 static const char *fileName; /* file to parse */
52 int _asn1_yyerror (char *);
53 int _asn1_yylex(void);
57 /* Prefix symbols and functions with _asn1_ */
58 %name-prefix="_asn1_yy"
60 %union {
61 unsigned int constant;
62 char str[MAX_NAME_SIZE+1];
63 node_asn* node;
67 %token ASSIG "::="
68 %token <str> NUM
69 %token <str> IDENTIFIER
70 %token OPTIONAL
71 %token INTEGER
72 %token SIZE
73 %token OCTET
74 %token STRING
75 %token SEQUENCE
76 %token BIT
77 %token UNIVERSAL
78 %token PRIVATE
79 %token APPLICATION
80 %token OPTIONAL
81 %token DEFAULT
82 %token CHOICE
83 %token OF
84 %token OBJECT
85 %token STR_IDENTIFIER
86 %token BOOLEAN
87 %token TRUE
88 %token FALSE
89 %token TOKEN_NULL
90 %token ANY
91 %token DEFINED
92 %token BY
93 %token SET
94 %token EXPLICIT
95 %token IMPLICIT
96 %token DEFINITIONS
97 %token TAGS
98 %token BEGIN
99 %token END
100 %token UTCTime
101 %token GeneralizedTime
102 %token GeneralString
103 %token FROM
104 %token IMPORTS
105 %token ENUMERATED
107 %type <node> octet_string_def constant constant_list type_assig_right
108 %type <node> integer_def type_assig type_assig_list sequence_def type_def
109 %type <node> bit_string_def default size_def choise_def object_def
110 %type <node> boolean_def any_def size_def2 obj_constant obj_constant_list
111 %type <node> constant_def type_constant type_constant_list definitions
112 %type <node> definitions_id Time bit_element bit_element_list set_def
113 %type <node> tag_type tag type_assig_right_tag generalstring_def
114 %type <node> type_assig_right_tag_default enumerated_def
115 %type <str> pos_num neg_num pos_neg_num pos_neg_identifier pos_neg_list
116 %type <str> num_identifier
117 %type <constant> class explicit_implicit
122 definitions: definitions_id
123 DEFINITIONS explicit_implicit TAGS "::=" BEGIN /* imports_def */
124 type_constant_list END
125 {$$=_asn1_add_node(TYPE_DEFINITIONS|$3);
126 _asn1_set_name($$,_asn1_get_name($1));
127 _asn1_set_name($1,"");
128 _asn1_set_right($1,$7);
129 _asn1_set_down($$,$1);
131 p_tree=$$;
135 pos_num : NUM {strcpy($$,$1);}
136 | '+' NUM {strcpy($$,$2);}
139 neg_num : '-' NUM {strcpy($$,"-");
140 strcat($$,$2);}
143 pos_neg_num : pos_num {strcpy($$,$1);}
144 | neg_num {strcpy($$,$1);}
147 num_identifier : NUM {strcpy($$,$1);}
148 | IDENTIFIER {strcpy($$,$1);}
151 pos_neg_identifier : pos_neg_num {strcpy($$,$1);}
152 | IDENTIFIER {strcpy($$,$1);}
155 constant: '(' pos_neg_num ')' {$$=_asn1_add_node(TYPE_CONSTANT);
156 _asn1_set_value($$,$2,strlen($2)+1);}
157 | IDENTIFIER'('pos_neg_num')' {$$=_asn1_add_node(TYPE_CONSTANT);
158 _asn1_set_name($$,$1);
159 _asn1_set_value($$,$3,strlen($3)+1);}
162 constant_list: constant {$$=$1;}
163 | constant_list ',' constant {$$=$1;
164 _asn1_set_right(_asn1_get_last_right($1),$3);}
167 obj_constant: num_identifier {$$=_asn1_add_node(TYPE_CONSTANT);
168 _asn1_set_value($$,$1,strlen($1)+1);}
169 | IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
170 _asn1_set_name($$,$1);
171 _asn1_set_value($$,$3,strlen($3)+1);}
174 obj_constant_list: obj_constant {$$=$1;}
175 | obj_constant_list obj_constant {$$=$1;
176 _asn1_set_right(_asn1_get_last_right($1),$2);}
179 class : UNIVERSAL {$$=CONST_UNIVERSAL;}
180 | PRIVATE {$$=CONST_PRIVATE;}
181 | APPLICATION {$$=CONST_APPLICATION;}
184 tag_type : '[' NUM ']' {$$=_asn1_add_node(TYPE_TAG);
185 _asn1_set_value($$,$2,strlen($2)+1);}
186 | '[' class NUM ']' {$$=_asn1_add_node(TYPE_TAG | $2);
187 _asn1_set_value($$,$3,strlen($3)+1);}
190 tag : tag_type {$$=$1;}
191 | tag_type EXPLICIT {$$=_asn1_mod_type($1,CONST_EXPLICIT);}
192 | tag_type IMPLICIT {$$=_asn1_mod_type($1,CONST_IMPLICIT);}
195 default : DEFAULT pos_neg_identifier {$$=_asn1_add_node(TYPE_DEFAULT);
196 _asn1_set_value($$,$2,strlen($2)+1);}
197 | DEFAULT TRUE {$$=_asn1_add_node(TYPE_DEFAULT|CONST_TRUE);}
198 | DEFAULT FALSE {$$=_asn1_add_node(TYPE_DEFAULT|CONST_FALSE);}
202 pos_neg_list: pos_neg_num
203 | pos_neg_list '|' pos_neg_num
207 integer_def: INTEGER {$$=_asn1_add_node(TYPE_INTEGER);}
208 | INTEGER'{'constant_list'}' {$$=_asn1_add_node(TYPE_INTEGER|CONST_LIST);
209 _asn1_set_down($$,$3);}
210 | INTEGER'(' pos_neg_list ')' {$$=_asn1_add_node(TYPE_INTEGER);}
211 | INTEGER'('num_identifier'.''.'num_identifier')'
212 {$$=_asn1_add_node(TYPE_INTEGER|CONST_MIN_MAX);
213 _asn1_set_down($$,_asn1_add_node(TYPE_SIZE));
214 _asn1_set_value(_asn1_get_down($$),$6,strlen($6)+1);
215 _asn1_set_name(_asn1_get_down($$),$3);}
218 boolean_def: BOOLEAN {$$=_asn1_add_node(TYPE_BOOLEAN);}
221 Time: UTCTime {$$=_asn1_add_node(TYPE_TIME|CONST_UTC);}
222 | GeneralizedTime {$$=_asn1_add_node(TYPE_TIME|CONST_GENERALIZED);}
225 size_def2: SIZE'('num_identifier')' {$$=_asn1_add_node(TYPE_SIZE|CONST_1_PARAM);
226 _asn1_set_value($$,$3,strlen($3)+1);}
227 | SIZE'('num_identifier'.''.'num_identifier')'
228 {$$=_asn1_add_node(TYPE_SIZE|CONST_MIN_MAX);
229 _asn1_set_value($$,$3,strlen($3)+1);
230 _asn1_set_name($$,$6);}
233 size_def: size_def2 {$$=$1;}
234 | '(' size_def2 ')' {$$=$2;}
237 generalstring_def: GeneralString {$$=_asn1_add_node(TYPE_GENERALSTRING);}
238 | GeneralString size_def {$$=_asn1_add_node(TYPE_GENERALSTRING|CONST_SIZE);
239 _asn1_set_down($$,$2);}
242 octet_string_def : OCTET STRING {$$=_asn1_add_node(TYPE_OCTET_STRING);}
243 | OCTET STRING size_def {$$=_asn1_add_node(TYPE_OCTET_STRING|CONST_SIZE);
244 _asn1_set_down($$,$3);}
247 bit_element : IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
248 _asn1_set_name($$,$1);
249 _asn1_set_value($$,$3,strlen($3)+1);}
252 bit_element_list : bit_element {$$=$1;}
253 | bit_element_list ',' bit_element {$$=$1;
254 _asn1_set_right(_asn1_get_last_right($1),$3);}
257 bit_string_def : BIT STRING {$$=_asn1_add_node(TYPE_BIT_STRING);}
258 | BIT STRING'{'bit_element_list'}'
259 {$$=_asn1_add_node(TYPE_BIT_STRING|CONST_LIST);
260 _asn1_set_down($$,$4);}
263 enumerated_def : ENUMERATED'{'bit_element_list'}'
264 {$$=_asn1_add_node(TYPE_ENUMERATED|CONST_LIST);
265 _asn1_set_down($$,$3);}
269 object_def : OBJECT STR_IDENTIFIER {$$=_asn1_add_node(TYPE_OBJECT_ID);}
272 type_assig_right: IDENTIFIER {$$=_asn1_add_node(TYPE_IDENTIFIER);
273 _asn1_set_value($$,$1,strlen($1)+1);}
274 | IDENTIFIER size_def {$$=_asn1_add_node(TYPE_IDENTIFIER|CONST_SIZE);
275 _asn1_set_value($$,$1,strlen($1)+1);
276 _asn1_set_down($$,$2);}
277 | integer_def {$$=$1;}
278 | enumerated_def {$$=$1;}
279 | boolean_def {$$=$1;}
280 | Time
281 | octet_string_def {$$=$1;}
282 | bit_string_def {$$=$1;}
283 | generalstring_def {$$=$1;}
284 | sequence_def {$$=$1;}
285 | object_def {$$=$1;}
286 | choise_def {$$=$1;}
287 | any_def {$$=$1;}
288 | set_def {$$=$1;}
289 | TOKEN_NULL {$$=_asn1_add_node(TYPE_NULL);}
292 type_assig_right_tag : type_assig_right {$$=$1;}
293 | tag type_assig_right {$$=_asn1_mod_type($2,CONST_TAG);
294 _asn1_set_right($1,_asn1_get_down($$));
295 _asn1_set_down($$,$1);}
298 type_assig_right_tag_default : type_assig_right_tag {$$=$1;}
299 | type_assig_right_tag default {$$=_asn1_mod_type($1,CONST_DEFAULT);
300 _asn1_set_right($2,_asn1_get_down($$));
301 _asn1_set_down($$,$2);}
302 | type_assig_right_tag OPTIONAL {$$=_asn1_mod_type($1,CONST_OPTION);}
305 type_assig : IDENTIFIER type_assig_right_tag_default {$$=_asn1_set_name($2,$1);}
308 type_assig_list : type_assig {$$=$1;}
309 | type_assig_list','type_assig {$$=$1;
310 _asn1_set_right(_asn1_get_last_right($1),$3);}
313 sequence_def : SEQUENCE'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SEQUENCE);
314 _asn1_set_down($$,$3);}
315 | SEQUENCE OF type_assig_right {$$=_asn1_add_node(TYPE_SEQUENCE_OF);
316 _asn1_set_down($$,$3);}
317 | SEQUENCE size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SEQUENCE_OF|CONST_SIZE);
318 _asn1_set_right($2,$4);
319 _asn1_set_down($$,$2);}
322 set_def : SET'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SET);
323 _asn1_set_down($$,$3);}
324 | SET OF type_assig_right {$$=_asn1_add_node(TYPE_SET_OF);
325 _asn1_set_down($$,$3);}
326 | SET size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SET_OF|CONST_SIZE);
327 _asn1_set_right($2,$4);
328 _asn1_set_down($$,$2);}
331 choise_def : CHOICE'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_CHOICE);
332 _asn1_set_down($$,$3);}
335 any_def : ANY {$$=_asn1_add_node(TYPE_ANY);}
336 | ANY DEFINED BY IDENTIFIER {$$=_asn1_add_node(TYPE_ANY|CONST_DEFINED_BY);
337 _asn1_set_down($$,_asn1_add_node(TYPE_CONSTANT));
338 _asn1_set_name(_asn1_get_down($$),$4);}
341 type_def : IDENTIFIER "::=" type_assig_right_tag {$$=_asn1_set_name($3,$1);}
344 constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
345 {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN);
346 _asn1_set_name($$,$1);
347 _asn1_set_down($$,$6);}
348 | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
349 {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
350 _asn1_set_name($$,$1);
351 _asn1_set_value($$,$2,strlen($2)+1);
352 _asn1_set_down($$,$5);}
353 | IDENTIFIER INTEGER "::=" pos_neg_num
354 {$$=_asn1_add_node(TYPE_INTEGER|CONST_ASSIGN);
355 _asn1_set_name($$,$1);
356 _asn1_set_value($$,$4,strlen($4)+1);}
359 type_constant: type_def {$$=$1;}
360 | constant_def {$$=$1;}
363 type_constant_list : type_constant {$$=$1;}
364 | type_constant_list type_constant {$$=$1;
365 _asn1_set_right(_asn1_get_last_right($1),$2);}
368 definitions_id : IDENTIFIER '{' obj_constant_list '}' {$$=_asn1_add_node(TYPE_OBJECT_ID);
369 _asn1_set_down($$,$3);
370 _asn1_set_name($$,$1);}
371 | IDENTIFIER '{' '}' {$$=_asn1_add_node(TYPE_OBJECT_ID);
372 _asn1_set_name($$,$1);}
376 identifier_list : IDENTIFIER {$$=_asn1_add_node(TYPE_IDENTIFIER);
377 _asn1_set_name($$,$1);}
378 | identifier_list IDENTIFIER
379 {$$=$1;
380 _asn1_set_right(_asn1_get_last_right($$),_asn1_add_node(TYPE_IDENTIFIER));
381 _asn1_set_name(_asn1_get_last_right($$),$2);}
385 imports_def : empty {$$=NULL;}
386 | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list
387 {$$=_asn1_add_node(TYPE_IMPORTS);
388 _asn1_set_down($$,_asn1_add_node(TYPE_OBJECT_ID));
389 _asn1_set_name(_asn1_get_down($$),$4);
390 _asn1_set_down(_asn1_get_down($$),$5);
391 _asn1_set_right($$,$2);}
395 explicit_implicit : EXPLICIT {$$=CONST_EXPLICIT;}
396 | IMPLICIT {$$=CONST_IMPLICIT;}
404 const char *key_word[]={"::=","OPTIONAL","INTEGER","SIZE","OCTET","STRING"
405 ,"SEQUENCE","BIT","UNIVERSAL","PRIVATE","OPTIONAL"
406 ,"DEFAULT","CHOICE","OF","OBJECT","IDENTIFIER"
407 ,"BOOLEAN","TRUE","FALSE","APPLICATION","ANY","DEFINED"
408 ,"SET","BY","EXPLICIT","IMPLICIT","DEFINITIONS","TAGS"
409 ,"BEGIN","END","UTCTime","GeneralizedTime"
410 ,"GeneralString","FROM","IMPORTS","NULL","ENUMERATED"};
411 const int key_word_token[]={ASSIG,OPTIONAL,INTEGER,SIZE,OCTET,STRING
412 ,SEQUENCE,BIT,UNIVERSAL,PRIVATE,OPTIONAL
413 ,DEFAULT,CHOICE,OF,OBJECT,STR_IDENTIFIER
414 ,BOOLEAN,TRUE,FALSE,APPLICATION,ANY,DEFINED
415 ,SET,BY,EXPLICIT,IMPLICIT,DEFINITIONS,TAGS
416 ,BEGIN,END,UTCTime,GeneralizedTime
417 ,GeneralString,FROM,IMPORTS,TOKEN_NULL,ENUMERATED};
419 /*************************************************************/
420 /* Function: _asn1_yylex */
421 /* Description: looks for tokens in file_asn1 pointer file. */
422 /* Return: int */
423 /* Token identifier or ASCII code or 0(zero: End Of File) */
424 /*************************************************************/
426 _asn1_yylex()
428 int c,counter=0,k,lastc;
429 char string[MAX_NAME_SIZE+1]; /* will contain the next token */
431 while(1)
433 while((c=fgetc(file_asn1))==' ' || c=='\t' || c=='\n')
434 if(c=='\n') lineNumber++;
436 if(c==EOF){
437 strcpy(lastToken,"End Of File");
438 return 0;
441 if(c=='(' || c==')' || c=='[' || c==']' ||
442 c=='{' || c=='}' || c==',' || c=='.' ||
443 c=='+' || c=='|'){
444 lastToken[0]=c;lastToken[1]=0;
445 return c;
447 if(c=='-'){ /* Maybe the first '-' of a comment */
448 if((c=fgetc(file_asn1))!='-'){
449 ungetc(c,file_asn1);
450 lastToken[0]='-';lastToken[1]=0;
451 return '-';
453 else{ /* Comments */
454 lastc=0;
455 counter=0;
456 /* A comment finishes at the next double hypen or the end of line */
457 while((c=fgetc(file_asn1))!=EOF && c!='\n' &&
458 (lastc!='-' || (lastc=='-' && c!='-')))
459 lastc=c;
460 if(c==EOF){
461 strcpy(lastToken,"End Of File");
462 return 0;
464 else{
465 if(c=='\n') lineNumber++;
466 continue; /* next char, please! (repeat the search) */
470 string[counter++]=c;
471 /* Till the end of the token */
472 while(!((c=fgetc(file_asn1))==EOF || c==' '|| c=='\t' || c=='\n' ||
473 c=='(' || c==')' || c=='[' || c==']' ||
474 c=='{' || c=='}' || c==',' || c=='.'))
476 if(counter>=MAX_NAME_SIZE){
477 result_parse=ASN1_NAME_TOO_LONG;
478 return 0;
480 string[counter++]=c;
482 ungetc(c,file_asn1);
483 string[counter]=0;
484 strcpy(lastToken,string);
486 /* Is STRING a number? */
487 for(k=0;k<counter;k++)
488 if(!isdigit(string[k])) break;
489 if(k>=counter)
491 strcpy(yylval.str,string);
492 return NUM; /* return the number */
495 /* Is STRING a keyword? */
496 for(k=0;k<(sizeof(key_word)/sizeof(char*));k++)
497 if(!strcmp(string,key_word[k])) return key_word_token[k];
499 /* STRING is an IDENTIFIER */
500 strcpy(yylval.str,string);
501 return IDENTIFIER;
506 /*************************************************************/
507 /* Function: _asn1_create_errorDescription */
508 /* Description: creates a string with the description of the*/
509 /* error. */
510 /* Parameters: */
511 /* error : error to describe. */
512 /* errorDescription: string that will contain the */
513 /* description. */
514 /*************************************************************/
515 void
516 _asn1_create_errorDescription(int error,char *errorDescription)
518 switch(error){
519 case ASN1_SUCCESS: case ASN1_FILE_NOT_FOUND:
520 if (errorDescription!=NULL) errorDescription[0]=0;
521 break;
522 case ASN1_SYNTAX_ERROR:
523 if (errorDescription!=NULL) {
524 strcpy(errorDescription,fileName);
525 strcat(errorDescription,":");
526 _asn1_ltostr(lineNumber,errorDescription+strlen(fileName)+1);
527 strcat(errorDescription,": parse error near '");
528 strcat(errorDescription,lastToken);
529 strcat(errorDescription,"'");
531 break;
532 case ASN1_NAME_TOO_LONG:
533 if (errorDescription!=NULL) {
534 strcpy(errorDescription,fileName);
535 strcat(errorDescription,":");
536 _asn1_ltostr(lineNumber,errorDescription+strlen(fileName)+1);
537 strcat(errorDescription,": name too long (more than ");
538 _asn1_ltostr(MAX_NAME_SIZE,errorDescription+strlen(errorDescription));
539 strcat(errorDescription," characters)");
541 break;
542 case ASN1_IDENTIFIER_NOT_FOUND:
543 if (errorDescription!=NULL) {
544 strcpy(errorDescription,fileName);
545 strcat(errorDescription,":");
546 strcat(errorDescription,": identifier '");
547 strcat(errorDescription,_asn1_identifierMissing);
548 strcat(errorDescription,"' not found");
550 break;
551 default:
552 if (errorDescription!=NULL) errorDescription[0]=0;
553 break;
560 * asn1_parser2tree - function used to start the parse algorithm.
561 * @file_name: specify the path and the name of file that contains
562 * ASN.1 declarations.
563 * @definitions: return the pointer to the structure created from
564 * "file_name" ASN.1 declarations.
565 * @errorDescription: return the error description or an empty
566 * string if success.
568 * Creates the structures needed to manage the definitions included
569 * in *FILE_NAME file.
571 * Returns:
573 * ASN1_SUCCESS: The file has a correct syntax and every identifier
574 * is known.
576 * ASN1_ELEMENT_NOT_EMPTY: *POINTER not ASN1_TYPE_EMPTY.
578 * ASN1_FILE_NOT_FOUND: An error occured while opening FILE_NAME.
580 * ASN1_SYNTAX_ERROR: The syntax is not correct.
582 * ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that
583 * is not defined.
585 * ASN1_NAME_TOO_LONG: In the file there is an identifier whith more
586 * than MAX_NAME_SIZE characters.
588 asn1_retCode
589 asn1_parser2tree(const char *file_name, ASN1_TYPE *definitions,
590 char *errorDescription){
592 p_tree=ASN1_TYPE_EMPTY;
594 if(*definitions != ASN1_TYPE_EMPTY)
595 return ASN1_ELEMENT_NOT_EMPTY;
597 *definitions=ASN1_TYPE_EMPTY;
599 fileName = file_name;
601 /* open the file to parse */
602 file_asn1=fopen(file_name,"r");
604 if(file_asn1==NULL){
605 result_parse=ASN1_FILE_NOT_FOUND;
607 else{
608 result_parse=ASN1_SUCCESS;
610 lineNumber=1;
611 yyparse();
613 fclose(file_asn1);
615 if(result_parse==ASN1_SUCCESS){ /* syntax OK */
616 /* set IMPLICIT or EXPLICIT property */
617 _asn1_set_default_tag(p_tree);
618 /* set CONST_SET and CONST_NOT_USED */
619 _asn1_type_set_config(p_tree);
620 /* check the identifier definitions */
621 result_parse=_asn1_check_identifier(p_tree);
622 if(result_parse==ASN1_SUCCESS){ /* all identifier defined */
623 /* Delete the list and keep the ASN1 structure */
624 _asn1_delete_list();
625 /* Convert into DER coding the value assign to INTEGER constants */
626 _asn1_change_integer_value(p_tree);
627 /* Expand the IDs of OBJECT IDENTIFIER constants */
628 _asn1_expand_object_id(p_tree);
630 *definitions=p_tree;
632 else /* some identifiers not defined */
633 /* Delete the list and the ASN1 structure */
634 _asn1_delete_list_and_nodes();
636 else /* syntax error */
637 /* Delete the list and the ASN1 structure */
638 _asn1_delete_list_and_nodes();
641 if (errorDescription!=NULL)
642 _asn1_create_errorDescription(result_parse,errorDescription);
644 return result_parse;
649 * asn1_parser2array - function that generates a C structure from an ASN1 file
650 * @inputFileName: specify the path and the name of file that
651 * contains ASN.1 declarations.
652 * @outputFileName: specify the path and the name of file that will
653 * contain the C vector definition.
654 * @vectorName: specify the name of the C vector.
655 * @errorDescription : return the error description or an empty
656 * string if success.
658 * Creates a file containing a C vector to use to manage the
659 * definitions included in *INPUTFILENAME file. If *INPUTFILENAME is
660 * "/aa/bb/xx.yy" and OUTPUTFILENAME is NULL, the file created is
661 * "/aa/bb/xx_asn1_tab.c". If VECTORNAME is NULL the vector name
662 * will be "xx_asn1_tab".
664 * Returns:
666 * ASN1_SUCCESS: The file has a correct syntax and every identifier
667 * is known.
669 * ASN1_FILE_NOT_FOUND: An error occured while opening FILE_NAME.
671 * ASN1_SYNTAX_ERROR: The syntax is not correct.
673 * ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that
674 * is not defined.
676 * ASN1_NAME_TOO_LONG: In the file there is an identifier whith more
677 * than MAX_NAME_SIZE characters.
679 int asn1_parser2array(const char *inputFileName,const char *outputFileName,
680 const char *vectorName,char *errorDescription){
681 char *file_out_name=NULL;
682 char *vector_name=NULL;
683 const char *char_p,*slash_p,*dot_p;
685 p_tree=NULL;
687 fileName = inputFileName;
689 /* open the file to parse */
690 file_asn1=fopen(inputFileName,"r");
692 if(file_asn1==NULL)
693 result_parse=ASN1_FILE_NOT_FOUND;
694 else{
695 result_parse=ASN1_SUCCESS;
697 lineNumber=1;
698 yyparse();
700 fclose(file_asn1);
702 if(result_parse==ASN1_SUCCESS){ /* syntax OK */
703 /* set IMPLICIT or EXPLICIT property */
704 _asn1_set_default_tag(p_tree);
705 /* set CONST_SET and CONST_NOT_USED */
706 _asn1_type_set_config(p_tree);
707 /* check the identifier definitions */
708 result_parse=_asn1_check_identifier(p_tree);
710 if(result_parse==ASN1_SUCCESS){ /* all identifier defined */
712 /* searching the last '/' and '.' in inputFileName */
713 char_p=inputFileName;
714 slash_p=inputFileName;
715 while((char_p=strchr(char_p,'/'))){
716 char_p++;
717 slash_p=char_p;
720 char_p=slash_p;
721 dot_p=inputFileName+strlen(inputFileName);
723 while((char_p=strchr(char_p,'.'))){
724 dot_p=char_p;
725 char_p++;
728 if(outputFileName == NULL){
729 /* file_out_name = inputFileName + _asn1_tab.c */
730 file_out_name=(char *)malloc(dot_p-inputFileName+1+
731 strlen("_asn1_tab.c"));
732 memcpy(file_out_name,inputFileName,dot_p-inputFileName);
733 file_out_name[dot_p-inputFileName]=0;
734 strcat(file_out_name,"_asn1_tab.c");
736 else{
737 /* file_out_name = inputFileName */
738 file_out_name=(char *)malloc(strlen(outputFileName)+1);
739 strcpy(file_out_name,outputFileName);
742 if(vectorName == NULL){
743 /* vector_name = file name + _asn1_tab */
744 vector_name=(char *)malloc(dot_p-slash_p+1+
745 strlen("_asn1_tab"));
746 memcpy(vector_name,slash_p,dot_p-slash_p);
747 vector_name[dot_p-slash_p]=0;
748 strcat(vector_name,"_asn1_tab");
750 else{
751 /* vector_name = vectorName */
752 vector_name=(char *)malloc(strlen(vectorName)+1);
753 strcpy(vector_name,vectorName);
756 /* Save structure in a file */
757 _asn1_create_static_structure(p_tree,
758 file_out_name,vector_name);
760 free(file_out_name);
761 free(vector_name);
762 } /* result == OK */
763 } /* result == OK */
765 /* Delete the list and the ASN1 structure */
766 _asn1_delete_list_and_nodes();
767 } /* inputFile exist */
769 if (errorDescription!=NULL)
770 _asn1_create_errorDescription(result_parse,errorDescription);
772 return result_parse;
776 /*************************************************************/
777 /* Function: _asn1_yyerror */
778 /* Description: function called when there are syntax errors*/
779 /* Parameters: */
780 /* char *s : error description */
781 /* Return: int */
782 /* */
783 /*************************************************************/
784 int _asn1_yyerror (char *s)
786 /* Sends the error description to the std_out */
788 #ifdef LIBTASN1_DEBUG_PARSER
789 _libtasn1_log("_asn1_yyerror:%s:%d: %s (Last Token:'%s')\n",fileName,
790 lineNumber,s,lastToken);
791 #endif
793 if(result_parse!=ASN1_NAME_TOO_LONG)
794 result_parse=ASN1_SYNTAX_ERROR;
796 return 0;