2 * Copyright (C) 2004, 2005, 2006 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
24 /*****************************************************/
25 /* File: x509_ASN.y */
26 /* Description: input file for 'bison' program. */
27 /* The output file is a parser (in C language) for */
29 /*****************************************************/
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
42 static node_asn
*p_tree
; /* pointer to the root of the
43 structure created by the
45 static unsigned long lineNumber
; /* line number describing the
46 parser position inside the
48 static char lastToken
[MAX_NAME_SIZE
+1]; /* last token find in the file
49 to parse before the 'parse
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"
63 unsigned int constant
;
64 char str
[MAX_NAME_SIZE
+1];
71 %token
<str
> IDENTIFIER
103 %token GeneralizedTime
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);
137 pos_num
: NUM
{strcpy
($$
,$1);}
138 |
'+' NUM
{strcpy
($$
,$2);}
141 neg_num
: '-' NUM
{strcpy
($$
,"-");
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
'(' pos_neg_list
')' {$$
=_asn1_add_node
(TYPE_INTEGER
);}
213 | INTEGER
'('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;}
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;}
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
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. */
426 /* Token identifier or ASCII code or 0(zero: End Of File) */
427 /*************************************************************/
431 int c
,counter
=0,k
,lastc
;
432 char string[MAX_NAME_SIZE
+1]; /* will contain the next token */
436 while
((c
=fgetc
(file_asn1
))==' ' || c
=='\t' || c
=='\n')
437 if
(c
=='\n') lineNumber
++;
440 strcpy
(lastToken
,"End Of File");
444 if
(c
=='(' || c
==')' || c
=='[' || c
==']' ||
445 c
=='{' || c
=='}' || c
==',' || c
=='.' ||
447 lastToken
[0]=c
;lastToken
[1]=0;
450 if
(c
=='-'){ /* Maybe the first '-' of a comment */
451 if
((c
=fgetc
(file_asn1
))!='-'){
453 lastToken
[0]='-';lastToken
[1]=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
!='-')))
464 strcpy
(lastToken
,"End Of File");
468 if
(c
=='\n') lineNumber
++;
469 continue
; /* next char, please! (repeat the search) */
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
;
487 strcpy
(lastToken
,string);
489 /* Is STRING a number? */
490 for
(k
=0;k
<counter
;k
++)
491 if
(!isdigit
(string[k
])) break
;
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);
509 /*************************************************************/
510 /* Function: _asn1_create_errorDescription */
511 /* Description: creates a string with the description of the*/
514 /* error : error to describe. */
515 /* errorDescription: string that will contain the */
517 /*************************************************************/
519 _asn1_create_errorDescription
(int error,char *errorDescription
)
522 case ASN1_SUCCESS
: case ASN1_FILE_NOT_FOUND
:
523 if
(errorDescription
!=NULL
) errorDescription
[0]=0;
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
,"'");
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)");
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");
555 if
(errorDescription
!=NULL
) errorDescription
[0]=0;
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
571 * Creates the structures needed to manage the definitions included
572 * in *FILE_NAME file.
576 * ASN1_SUCCESS: The file has a correct syntax and every identifier
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
588 * ASN1_NAME_TOO_LONG: In the file there is an identifier whith more
589 * than MAX_NAME_SIZE characters.
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");
608 result_parse
=ASN1_FILE_NOT_FOUND
;
611 result_parse
=ASN1_SUCCESS
;
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 */
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
);
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
);
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
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".
669 * ASN1_SUCCESS: The file has a correct syntax and every identifier
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
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
;
690 fileName
= inputFileName
;
692 /* open the file to parse */
693 file_asn1
=fopen
(inputFileName
,"r");
696 result_parse
=ASN1_FILE_NOT_FOUND
;
698 result_parse
=ASN1_SUCCESS
;
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
,'/'))){
724 dot_p
=inputFileName
+strlen
(inputFileName
);
726 while
((char_p
=strchr
(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");
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");
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
);
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
);
779 /*************************************************************/
780 /* Function: _asn1_yyerror */
781 /* Description: function called when there are syntax errors*/
783 /* char *s : error description */
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
);
796 if
(result_parse
!=ASN1_NAME_TOO_LONG
)
797 result_parse
=ASN1_SYNTAX_ERROR
;