Introduced ASN1_ETYPE_UTC_TIME and ASN1_ETYPE_GENERALIZED_TIME
[platform/upstream/libtasn1.git] / lib / ASN1.y
1 %{
2 /*
3  * Copyright (C) 2001-2012 Free Software Foundation, Inc.
4  *
5  * This file is part of LIBTASN1.
6  *
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.
11  *
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.
16  *
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
21  */
22
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 /*****************************************************/
29
30 #include <int.h>
31 #include <parser_aux.h>
32 #include <structure.h>
33 #include <libtasn1.h>
34
35 static FILE *file_asn1;                 /* Pointer to file to parse */
36 static int result_parse = 0;    /* result of the parser
37                                            algorithm */
38 static asn1_node p_tree;                /* pointer to the root of the
39                                            structure created by the
40                                            parser*/
41 static unsigned int line_number;        /* line number describing the
42                                            parser position inside the
43                                            file */
44 static char last_error[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
45 static char last_error_token[ASN1_MAX_NAME_SIZE+1] = ""; /* used when expected errors occur */
46 static char last_token[ASN1_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 *file_name;           /* file to parse */
51
52 static void _asn1_yyerror (const char *);
53 static int _asn1_yylex(void);
54
55 %}
56
57 /* Prefix symbols and functions with _asn1_ */
58 /* %define parse.lac full */
59 %error-verbose
60 %name-prefix="_asn1_yy"
61
62 %union {
63   unsigned int constant;
64   char str[ASN1_MAX_NAME_SIZE+1];
65   asn1_node node;
66 }
67
68
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 DEFAULT
83 %token CHOICE
84 %token OF
85 %token OBJECT
86 %token STR_IDENTIFIER
87 %token BOOLEAN
88 %token ASN1_TRUE
89 %token ASN1_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 NumericString
105 %token IA5String
106 %token TeletexString
107 %token PrintableString
108 %token UniversalString
109 %token BMPString
110 %token UTF8String
111 %token VisibleString
112
113 %token FROM
114 %token IMPORTS
115 %token ENUMERATED
116
117 %type <node> octet_string_def constant constant_list type_assig_right
118 %type <node> integer_def type_assig type_assig_list sequence_def type_def
119 %type <node> bit_string_def default size_def choise_def object_def
120 %type <node> boolean_def any_def size_def2 obj_constant obj_constant_list
121 %type <node> constant_def type_constant type_constant_list definitions
122 %type <node> definitions_id Time bit_element bit_element_list set_def
123 %type <node> tag_type tag type_assig_right_tag generalstring_def
124 %type <node> numericstring_def ia5string_def printablestring_def universalstring_def
125 %type <node> bmpstring_def utf8string_def visiblestring_def teletexstring_def
126 %type <node> type_assig_right_tag_default enumerated_def
127 %type <str>  pos_num neg_num pos_neg_num pos_neg_identifier pos_neg_list
128 %type <str>  num_identifier
129 %type <constant> class explicit_implicit
130
131 %%
132
133
134 definitions:   definitions_id
135                DEFINITIONS explicit_implicit TAGS "::=" BEGIN  /* imports_def */
136                type_constant_list END
137                    {$$=_asn1_add_static_node(ASN1_ETYPE_DEFINITIONS|$3);
138                     _asn1_set_name($$,_asn1_get_name($1));
139                     _asn1_set_name($1,"");
140                     _asn1_set_right($1,$7);
141                     _asn1_set_down($$,$1);
142
143                     p_tree=$$;
144                     }
145 ;
146
147 pos_num :   NUM       {strcpy($$,$1);}
148           | '+' NUM   {strcpy($$,$2);}
149 ;
150
151 neg_num : '-' NUM     {strcpy($$,"-");
152                        strcat($$,$2);}
153 ;
154
155 pos_neg_num :  pos_num  {strcpy($$,$1);}
156              | neg_num  {strcpy($$,$1);}
157 ;
158
159 num_identifier :  NUM            {strcpy($$,$1);}
160                 | IDENTIFIER     {strcpy($$,$1);}
161 ;
162
163 pos_neg_identifier :  pos_neg_num    {strcpy($$,$1);}
164                     | IDENTIFIER     {strcpy($$,$1);}
165 ;
166
167 constant: '(' pos_neg_num ')'         {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
168                                        _asn1_set_value($$,$2,strlen($2)+1);}
169         | IDENTIFIER'('pos_neg_num')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
170                                        _asn1_set_name($$,$1);
171                                        _asn1_set_value($$,$3,strlen($3)+1);}
172 ;
173
174 constant_list:  constant                   {$$=$1;}
175               | constant_list ',' constant {$$=$1;
176                                             _asn1_set_right(_asn1_get_last_right($1),$3);}
177 ;
178
179 obj_constant:  num_identifier     {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
180                                    _asn1_set_value($$,$1,strlen($1)+1);}
181              | IDENTIFIER'('NUM')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
182                                     _asn1_set_name($$,$1);
183                                     _asn1_set_value($$,$3,strlen($3)+1);}
184 ;
185
186 obj_constant_list:  obj_constant                   {$$=$1;}
187                   | obj_constant_list obj_constant {$$=$1;
188                                                     _asn1_set_right(_asn1_get_last_right($1),$2);}
189 ;
190
191 class :  UNIVERSAL    {$$=CONST_UNIVERSAL;}
192        | PRIVATE      {$$=CONST_PRIVATE;}
193        | APPLICATION  {$$=CONST_APPLICATION;}
194 ;
195
196 tag_type :  '[' NUM ']'    {$$=_asn1_add_static_node(ASN1_ETYPE_TAG);
197                             _asn1_set_value($$,$2,strlen($2)+1);}
198           | '[' class NUM ']'  {$$=_asn1_add_static_node(ASN1_ETYPE_TAG | $2);
199                                 _asn1_set_value($$,$3,strlen($3)+1);}
200 ;
201
202 tag :  tag_type           {$$=$1;}
203      | tag_type EXPLICIT  {$$=_asn1_mod_type($1,CONST_EXPLICIT);}
204      | tag_type IMPLICIT  {$$=_asn1_mod_type($1,CONST_IMPLICIT);}
205 ;
206
207 default :  DEFAULT pos_neg_identifier {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT);
208                                        _asn1_set_value($$,$2,strlen($2)+1);}
209          | DEFAULT ASN1_TRUE           {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_TRUE);}
210          | DEFAULT ASN1_FALSE          {$$=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_FALSE);}
211 ;
212
213
214 pos_neg_list:  pos_neg_num
215             |  pos_neg_list '|' pos_neg_num
216 ;
217
218
219 integer_def: INTEGER                    {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER);}
220            | INTEGER'{'constant_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_LIST);
221                                          _asn1_set_down($$,$3);}
222            | integer_def'(' pos_neg_list ')' {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER);}
223            | integer_def'('num_identifier'.''.'num_identifier')'
224                                         {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_MIN_MAX);
225                                          _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_SIZE));
226                                          _asn1_set_value(_asn1_get_down($$),$6,strlen($6)+1);
227                                          _asn1_set_name(_asn1_get_down($$),$3);}
228 ;
229
230 boolean_def: BOOLEAN   {$$=_asn1_add_static_node(ASN1_ETYPE_BOOLEAN);}
231 ;
232
233 Time:   UTCTime          {$$=_asn1_add_static_node(ASN1_ETYPE_UTC_TIME);}
234       | GeneralizedTime  {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALIZED_TIME);}
235 ;
236
237 size_def2: SIZE'('num_identifier')'  {$$=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_1_PARAM);
238                                       _asn1_set_value($$,$3,strlen($3)+1);}
239         | SIZE'('num_identifier'.''.'num_identifier')'
240                                      {$$=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_MIN_MAX);
241                                       _asn1_set_value($$,$3,strlen($3)+1);
242                                       _asn1_set_name($$,$6);}
243 ;
244
245 size_def:   size_def2          {$$=$1;}
246           | '(' size_def2 ')'  {$$=$2;}
247 ;
248
249 generalstring_def: GeneralString {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING);}
250                 | GeneralString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING|CONST_SIZE);
251                                           _asn1_set_down($$,$2);}
252 ;
253
254 numericstring_def: NumericString {$$=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_UNIVERSAL);}
255                 | NumericString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_SIZE);
256                                           _asn1_set_down($$,$2);}
257 ;
258
259 ia5string_def: IA5String {$$=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING);}
260                 | IA5String size_def {$$=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING|CONST_SIZE);
261                                           _asn1_set_down($$,$2);}
262 ;
263
264 teletexstring_def: TeletexString {$$=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING);}
265                 | TeletexString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING|CONST_SIZE);
266                                           _asn1_set_down($$,$2);}
267 ;
268
269 printablestring_def: PrintableString {$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING);}
270                 | PrintableString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING|CONST_SIZE);
271                                           _asn1_set_down($$,$2);}
272 ;
273
274 universalstring_def: UniversalString {$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING);}
275                 | UniversalString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING|CONST_SIZE);
276                                           _asn1_set_down($$,$2);}
277 ;
278
279 bmpstring_def: BMPString {$$=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING);}
280                 | BMPString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING|CONST_SIZE);
281                                           _asn1_set_down($$,$2);}
282 ;
283
284 utf8string_def: UTF8String {$$=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING);}
285                 | UTF8String size_def {$$=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING|CONST_SIZE);
286                                           _asn1_set_down($$,$2);}
287 ;
288
289 visiblestring_def: VisibleString {$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING);}
290                 | VisibleString size_def {$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING|CONST_SIZE);
291                                           _asn1_set_down($$,$2);}
292 ;
293
294 octet_string_def : OCTET STRING           {$$=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING);}
295                  | OCTET STRING size_def  {$$=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING|CONST_SIZE);
296                                            _asn1_set_down($$,$3);}
297 ;
298
299 bit_element :  IDENTIFIER'('NUM')' {$$=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
300                                    _asn1_set_name($$,$1);
301                                     _asn1_set_value($$,$3,strlen($3)+1);}
302 ;
303
304 bit_element_list :  bit_element   {$$=$1;}
305                   | bit_element_list ',' bit_element  {$$=$1;
306                                                        _asn1_set_right(_asn1_get_last_right($1),$3);}
307 ;
308
309 bit_string_def : BIT STRING    {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING);}
310                | BIT STRING size_def {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_SIZE);}
311                | BIT STRING'{'bit_element_list'}'
312                                {$$=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_LIST);
313                                 _asn1_set_down($$,$4);}
314 ;
315
316 enumerated_def : ENUMERATED'{'bit_element_list'}'
317                                {$$=_asn1_add_static_node(ASN1_ETYPE_ENUMERATED|CONST_LIST);
318                                 _asn1_set_down($$,$3);}
319 ;
320
321
322 object_def :  OBJECT STR_IDENTIFIER {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);}
323 ;
324
325 type_assig_right: IDENTIFIER          {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER);
326                                        _asn1_set_value($$,$1,strlen($1)+1);}
327                 | IDENTIFIER size_def {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER|CONST_SIZE);
328                                        _asn1_set_value($$,$1,strlen($1)+1);
329                                        _asn1_set_down($$,$2);}
330                 | integer_def         {$$=$1;}
331                 | enumerated_def      {$$=$1;}
332                 | boolean_def         {$$=$1;}
333                 | Time
334                 | octet_string_def    {$$=$1;}
335                 | bit_string_def      {$$=$1;}
336                 | generalstring_def   {$$=$1;}
337                 | numericstring_def   {$$=$1;}
338                 | ia5string_def       {$$=$1;}
339                 | teletexstring_def   {$$=$1;}
340                 | printablestring_def {$$=$1;}
341                 | universalstring_def {$$=$1;}
342                 | bmpstring_def       {$$=$1;}
343                 | utf8string_def      {$$=$1;}
344                 | visiblestring_def   {$$=$1;}
345                 | sequence_def        {$$=$1;}
346                 | object_def          {$$=$1;}
347                 | choise_def          {$$=$1;}
348                 | any_def             {$$=$1;}
349                 | set_def             {$$=$1;}
350                 | TOKEN_NULL          {$$=_asn1_add_static_node(ASN1_ETYPE_NULL);}
351 ;
352
353 type_assig_right_tag :   type_assig_right     {$$=$1;}
354                        | tag type_assig_right {$$=_asn1_mod_type($2,CONST_TAG);
355                                                _asn1_set_right($1,_asn1_get_down($$));
356                                                _asn1_set_down($$,$1);}
357 ;
358
359 type_assig_right_tag_default : type_assig_right_tag   {$$=$1;}
360                       | type_assig_right_tag default  {$$=_asn1_mod_type($1,CONST_DEFAULT);
361                                                        _asn1_set_right($2,_asn1_get_down($$));
362                                                        _asn1_set_down($$,$2);}
363                       | type_assig_right_tag OPTIONAL {$$=_asn1_mod_type($1,CONST_OPTION);}
364 ;
365
366 type_assig : IDENTIFIER type_assig_right_tag_default  {$$=_asn1_set_name($2,$1);}
367 ;
368
369 type_assig_list : type_assig                   {$$=$1;}
370                 | type_assig_list','type_assig {$$=$1;
371                                                 _asn1_set_right(_asn1_get_last_right($1),$3);}
372 ;
373
374 sequence_def : SEQUENCE'{'type_assig_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE);
375                                               _asn1_set_down($$,$3);}
376    | SEQUENCE OF type_assig_right            {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE_OF);
377                                               _asn1_set_down($$,$3);}
378    | SEQUENCE size_def OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE_OF|CONST_SIZE);
379                                             _asn1_set_right($2,$4);
380                                             _asn1_set_down($$,$2);}
381 ;
382
383 set_def :  SET'{'type_assig_list'}' {$$=_asn1_add_static_node(ASN1_ETYPE_SET);
384                                      _asn1_set_down($$,$3);}
385    | SET OF type_assig_right        {$$=_asn1_add_static_node(ASN1_ETYPE_SET_OF);
386                                      _asn1_set_down($$,$3);}
387    | SET size_def OF type_assig_right {$$=_asn1_add_static_node(ASN1_ETYPE_SET_OF|CONST_SIZE);
388                                        _asn1_set_right($2,$4);
389                                        _asn1_set_down($$,$2);}
390 ;
391
392 choise_def :   CHOICE'{'type_assig_list'}'  {$$=_asn1_add_static_node(ASN1_ETYPE_CHOICE);
393                                              _asn1_set_down($$,$3);}
394 ;
395
396 any_def :  ANY                         {$$=_asn1_add_static_node(ASN1_ETYPE_ANY);}
397          | ANY DEFINED BY IDENTIFIER   {$$=_asn1_add_static_node(ASN1_ETYPE_ANY|CONST_DEFINED_BY);
398                                         _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_CONSTANT));
399                                         _asn1_set_name(_asn1_get_down($$),$4);}
400 ;
401
402 type_def : IDENTIFIER "::=" type_assig_right_tag  {$$=_asn1_set_name($3,$1);}
403               /* below should match: BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING etc*/
404               | error "::=" type_assig_right_tag {$$=_asn1_set_name($3, last_error_token);}
405 ;
406
407 constant_def :  IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
408                         {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN);
409                          _asn1_set_name($$,$1);
410                          _asn1_set_down($$,$6);}
411               | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
412                         {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
413                          _asn1_set_name($$,$1);
414                          _asn1_set_value($$,$2,strlen($2)+1);
415                          _asn1_set_down($$,$5);}
416               | IDENTIFIER INTEGER "::=" pos_neg_num
417                         {$$=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_ASSIGN);
418                          _asn1_set_name($$,$1);
419                          _asn1_set_value($$,$4,strlen($4)+1);}
420 ;
421
422 type_constant:   type_def     {$$=$1;}
423                | constant_def {$$=$1;}
424 ;
425
426 type_constant_list :   type_constant    {$$=$1;}
427                      | type_constant_list type_constant  {$$=$1;
428                                                           _asn1_set_right(_asn1_get_last_right($1),$2);}
429 ;
430
431 definitions_id  :  IDENTIFIER  '{' obj_constant_list '}' {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
432                                                           _asn1_set_down($$,$3);
433                                                           _asn1_set_name($$,$1);}
434                  | IDENTIFIER  '{' '}'                   {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
435                                                           _asn1_set_name($$,$1);}
436                  | IDENTIFIER                            {$$=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
437                                                           _asn1_set_name($$,$1);}
438 ;
439
440 /*
441 identifier_list  :  IDENTIFIER  {$$=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER);
442                                  _asn1_set_name($$,$1);}
443                   | identifier_list IDENTIFIER
444                                 {$$=$1;
445                                  _asn1_set_right(_asn1_get_last_right($$),_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER));
446                                  _asn1_set_name(_asn1_get_last_right($$),$2);}
447 ;
448
449
450 imports_def :    empty   {$$=NULL;}
451               | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list
452                         {$$=_asn1_add_static_node(ASN1_ETYPE_IMPORTS);
453                          _asn1_set_down($$,_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID));
454                          _asn1_set_name(_asn1_get_down($$),$4);
455                          _asn1_set_down(_asn1_get_down($$),$5);
456                          _asn1_set_right($$,$2);}
457 ;
458 */
459
460 explicit_implicit :  EXPLICIT  {$$=CONST_EXPLICIT;}
461                    | IMPLICIT  {$$=CONST_IMPLICIT;}
462 ;
463
464
465 %%
466
467
468
469 static const char *key_word[] = {
470   "::=","OPTIONAL","INTEGER","SIZE","OCTET","STRING",
471   "SEQUENCE","BIT","UNIVERSAL","PRIVATE","OPTIONAL",
472   "DEFAULT","CHOICE","OF","OBJECT","IDENTIFIER",
473   "BOOLEAN","TRUE","FALSE","APPLICATION","ANY","DEFINED",
474   "SET","BY","EXPLICIT","IMPLICIT","DEFINITIONS","TAGS",
475   "BEGIN","END","UTCTime","GeneralizedTime",
476   "GeneralString","FROM","IMPORTS","NULL","ENUMERATED",
477   "NumericString", "IA5String", "TeletexString", "PrintableString",
478   "UniversalString", "BMPString", "UTF8String", "VisibleString"};
479
480 static const int key_word_token[] = {
481   ASSIG, OPTIONAL, INTEGER, SIZE, OCTET, STRING, SEQUENCE, BIT, UNIVERSAL,
482       PRIVATE, OPTIONAL, DEFAULT, CHOICE, OF, OBJECT, STR_IDENTIFIER,
483       BOOLEAN, ASN1_TRUE, ASN1_FALSE, APPLICATION, ANY, DEFINED, SET, BY,
484       EXPLICIT, IMPLICIT, DEFINITIONS, TAGS, BEGIN, END, UTCTime,
485       GeneralizedTime, GeneralString, FROM, IMPORTS, TOKEN_NULL,
486       ENUMERATED, NumericString, IA5String, TeletexString, PrintableString,
487       UniversalString, BMPString, UTF8String, VisibleString
488 };
489
490 /*************************************************************/
491 /*  Function: _asn1_yylex                                    */
492 /*  Description: looks for tokens in file_asn1 pointer file. */
493 /*  Return: int                                              */
494 /*    Token identifier or ASCII code or 0(zero: End Of File) */
495 /*************************************************************/
496 static int
497 _asn1_yylex ()
498 {
499   int c, counter = 0, k, lastc;
500   char string[ASN1_MAX_NAME_SIZE + 1];  /* will contain the next token */
501   size_t i;
502
503   while (1)
504     {
505       while ((c = fgetc (file_asn1)) == ' ' || c == '\t' || c == '\n')
506         if (c == '\n')
507           line_number++;
508
509       if (c == EOF)
510         {
511           strcpy (last_token, "End Of File");
512           return 0;
513         }
514
515       if (c == '(' || c == ')' || c == '[' || c == ']' ||
516           c == '{' || c == '}' || c == ',' || c == '.' ||
517           c == '+' || c == '|')
518         {
519           last_token[0] = c;
520           last_token[1] = 0;
521           return c;
522         }
523       if (c == '-')
524         {                       /* Maybe the first '-' of a comment */
525           if ((c = fgetc (file_asn1)) != '-')
526             {
527               ungetc (c, file_asn1);
528               last_token[0] = '-';
529               last_token[1] = 0;
530               return '-';
531             }
532           else
533             {                   /* Comments */
534               lastc = 0;
535               counter = 0;
536               /* A comment finishes at the next double hypen or the end of line */
537               while ((c = fgetc (file_asn1)) != EOF && c != '\n' &&
538                      (lastc != '-' || (lastc == '-' && c != '-')))
539                 lastc = c;
540               if (c == EOF)
541                 {
542                   strcpy (last_token, "End Of File");
543                   return 0;
544                 }
545               else
546                 {
547                   if (c == '\n')
548                     line_number++;
549                   continue;     /* next char, please! (repeat the search) */
550                 }
551             }
552         }
553       string[counter++] = c;
554       /* Till the end of the token */
555       while (!
556              ((c = fgetc (file_asn1)) == EOF || c == ' ' || c == '\t'
557               || c == '\n' || c == '(' || c == ')' || c == '[' || c == ']'
558               || c == '{' || c == '}' || c == ',' || c == '.'))
559         {
560           if (counter >= ASN1_MAX_NAME_SIZE)
561             {
562               result_parse = ASN1_NAME_TOO_LONG;
563               return 0;
564             }
565           string[counter++] = c;
566         }
567       ungetc (c, file_asn1);
568       string[counter] = 0;
569       strcpy (last_token, string);
570
571       /* Is STRING a number? */
572       for (k = 0; k < counter; k++)
573         if (!isdigit (string[k]))
574           break;
575       if (k >= counter)
576         {
577           strcpy (yylval.str, string);
578           return NUM;           /* return the number */
579         }
580
581       /* Is STRING a keyword? */
582       for (i = 0; i < (sizeof (key_word) / sizeof (char *)); i++)
583         if (!strcmp (string, key_word[i]))
584           return key_word_token[i];
585
586       /* STRING is an IDENTIFIER */
587       strcpy (yylval.str, string);
588       return IDENTIFIER;
589     }
590 }
591
592 /*************************************************************/
593 /*  Function: _asn1_create_errorDescription                  */
594 /*  Description: creates a string with the description of the*/
595 /*    error.                                                 */
596 /*  Parameters:                                              */
597 /*    error : error to describe.                             */
598 /*    error_desc: string that will contain the         */
599 /*                      description.                         */
600 /*************************************************************/
601 static void
602 _asn1_create_errorDescription (int error, char *error_desc)
603 {
604   if (error_desc == NULL)
605     return;
606
607
608   switch (error)
609     {
610     case ASN1_FILE_NOT_FOUND:
611       snprintf(error_desc, ASN1_MAX_ERROR_DESCRIPTION_SIZE, "%s file was not found", file_name);
612       break;
613     case ASN1_SYNTAX_ERROR:
614       strcpy(error_desc, last_error);
615       break;
616     case ASN1_NAME_TOO_LONG:
617       snprintf (error_desc, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
618                 "%s:%u: name too long (more than %u characters)", file_name,
619                 line_number, ASN1_MAX_NAME_SIZE);
620       break;
621     case ASN1_IDENTIFIER_NOT_FOUND:
622       snprintf (error_desc, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
623                 "%s:: identifier '%s' not found", file_name,
624                 _asn1_identifierMissing);
625       break;
626     default:
627       error_desc[0] = 0;
628       break;
629     }
630
631 }
632
633 /**
634  * asn1_parser2tree:
635  * @file: specify the path and the name of file that contains
636  *   ASN.1 declarations.
637  * @definitions: return the pointer to the structure created from
638  *   "file" ASN.1 declarations.
639  * @error_desc: return the error description or an empty
640  * string if success.
641  *
642  * Function used to start the parse algorithm.  Creates the structures
643  * needed to manage the definitions included in @file file.
644  *
645  * Returns: %ASN1_SUCCESS if the file has a correct syntax and every
646  *   identifier is known, %ASN1_ELEMENT_NOT_EMPTY if @definitions not
647  *   %NULL, %ASN1_FILE_NOT_FOUND if an error occured while
648  *   opening @file, %ASN1_SYNTAX_ERROR if the syntax is not
649  *   correct, %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an
650  *   identifier that is not defined, %ASN1_NAME_TOO_LONG if in the
651  *   file there is an identifier whith more than %ASN1_MAX_NAME_SIZE
652  *   characters.
653  **/
654 int
655 asn1_parser2tree (const char *file, asn1_node * definitions,
656                   char *error_desc)
657 {
658
659   p_tree = NULL;
660
661   if (*definitions != NULL)
662     return ASN1_ELEMENT_NOT_EMPTY;
663
664   *definitions = NULL;
665
666   file_name = file;
667
668   /* open the file to parse */
669   file_asn1 = fopen (file, "r");
670
671   if (file_asn1 == NULL)
672     {
673       result_parse = ASN1_FILE_NOT_FOUND;
674     }
675   else
676     {
677       result_parse = ASN1_SUCCESS;
678
679       line_number = 1;
680       yyparse ();
681
682       fclose (file_asn1);
683
684       if (result_parse == ASN1_SUCCESS)
685         {                       /* syntax OK */
686           /* set IMPLICIT or EXPLICIT property */
687           _asn1_set_default_tag (p_tree);
688           /* set CONST_SET and CONST_NOT_USED */
689           _asn1_type_set_config (p_tree);
690           /* check the identifier definitions */
691           result_parse = _asn1_check_identifier (p_tree);
692           if (result_parse == ASN1_SUCCESS)
693             {                   /* all identifier defined */
694               /* Delete the list and keep the ASN1 structure */
695               _asn1_delete_list ();
696               /* Convert into DER coding the value assign to INTEGER constants */
697               _asn1_change_integer_value (p_tree);
698               /* Expand the IDs of OBJECT IDENTIFIER constants */
699               _asn1_expand_object_id (p_tree);
700
701               *definitions = p_tree;
702             }
703           else                  /* some identifiers not defined */
704             /* Delete the list and the ASN1 structure */
705             _asn1_delete_list_and_nodes ();
706         }
707       else                      /* syntax error */
708         /* Delete the list and the ASN1 structure */
709         _asn1_delete_list_and_nodes ();
710     }
711
712   _asn1_create_errorDescription (result_parse, error_desc);
713
714   return result_parse;
715 }
716
717 /**
718  * asn1_parser2array:
719  * @inputFileName: specify the path and the name of file that
720  *   contains ASN.1 declarations.
721  * @outputFileName: specify the path and the name of file that will
722  *   contain the C vector definition.
723  * @vectorName: specify the name of the C vector.
724  * @error_desc : return the error description or an empty
725  *   string if success.
726  *
727  * Function that generates a C structure from an ASN1 file.  Creates a
728  * file containing a C vector to use to manage the definitions
729  * included in @inputFileName file. If @inputFileName is
730  * "/aa/bb/xx.yy" and @outputFileName is %NULL, the file created is
731  * "/aa/bb/xx_asn1_tab.c".  If @vectorName is %NULL the vector name
732  * will be "xx_asn1_tab".
733  *
734  * Returns: %ASN1_SUCCESS if the file has a correct syntax and every
735  *   identifier is known, %ASN1_FILE_NOT_FOUND if an error occured
736  *   while opening @inputFileName, %ASN1_SYNTAX_ERROR if the syntax is
737  *   not correct, %ASN1_IDENTIFIER_NOT_FOUND if in the file there is
738  *   an identifier that is not defined, %ASN1_NAME_TOO_LONG if in the
739  *   file there is an identifier whith more than %ASN1_MAX_NAME_SIZE
740  *   characters.
741  **/
742 int
743 asn1_parser2array (const char *inputFileName, const char *outputFileName,
744                    const char *vectorName, char *error_desc)
745 {
746   char *file_out_name = NULL;
747   char *vector_name = NULL;
748   const char *char_p, *slash_p, *dot_p;
749
750   p_tree = NULL;
751
752   file_name = inputFileName;
753
754   /* open the file to parse */
755   file_asn1 = fopen (inputFileName, "r");
756
757   if (file_asn1 == NULL)
758     result_parse = ASN1_FILE_NOT_FOUND;
759   else
760     {
761       result_parse = ASN1_SUCCESS;
762
763       line_number = 1;
764       yyparse ();
765
766       fclose (file_asn1);
767
768       if (result_parse == ASN1_SUCCESS)
769         {                       /* syntax OK */
770           /* set IMPLICIT or EXPLICIT property */
771           _asn1_set_default_tag (p_tree);
772           /* set CONST_SET and CONST_NOT_USED */
773           _asn1_type_set_config (p_tree);
774           /* check the identifier definitions */
775           result_parse = _asn1_check_identifier (p_tree);
776
777           if (result_parse == ASN1_SUCCESS)
778             {                   /* all identifier defined */
779
780               /* searching the last '/' and '.' in inputFileName */
781               char_p = inputFileName;
782               slash_p = inputFileName;
783               while ((char_p = strchr (char_p, '/')))
784                 {
785                   char_p++;
786                   slash_p = char_p;
787                 }
788
789               char_p = slash_p;
790               dot_p = inputFileName + strlen (inputFileName);
791
792               while ((char_p = strchr (char_p, '.')))
793                 {
794                   dot_p = char_p;
795                   char_p++;
796                 }
797
798               if (outputFileName == NULL)
799                 {
800                   /* file_out_name = inputFileName + _asn1_tab.c */
801                   file_out_name = malloc (dot_p - inputFileName + 1 +
802                                           strlen ("_asn1_tab.c"));
803                   memcpy (file_out_name, inputFileName,
804                           dot_p - inputFileName);
805                   file_out_name[dot_p - inputFileName] = 0;
806                   strcat (file_out_name, "_asn1_tab.c");
807                 }
808               else
809                 {
810                   /* file_out_name = inputFileName */
811                   file_out_name =
812                       (char *) malloc (strlen (outputFileName) + 1);
813                   strcpy (file_out_name, outputFileName);
814                 }
815
816               if (vectorName == NULL)
817                 {
818                   /* vector_name = file name + _asn1_tab */
819                   vector_name = malloc (dot_p - slash_p + 1 +
820                                         strlen ("_asn1_tab"));
821                   memcpy (vector_name, slash_p, dot_p - slash_p);
822                   vector_name[dot_p - slash_p] = 0;
823                   strcat (vector_name, "_asn1_tab");
824                 }
825               else
826                 {
827                   /* vector_name = vectorName */
828                   vector_name = (char *) malloc (strlen (vectorName) + 1);
829                   strcpy (vector_name, vectorName);
830                 }
831
832               /* Save structure in a file */
833               _asn1_create_static_structure (p_tree,
834                                              file_out_name, vector_name);
835
836               free (file_out_name);
837               free (vector_name);
838             }                   /* result == OK */
839         }                       /* result == OK */
840
841       /* Delete the list and the ASN1 structure */
842       _asn1_delete_list_and_nodes ();
843     }                           /* inputFile exist */
844
845   _asn1_create_errorDescription (result_parse, error_desc);
846
847   return result_parse;
848 }
849
850 /*************************************************************/
851 /*  Function: _asn1_yyerror                                  */
852 /*  Description: function called when there are syntax errors*/
853 /*  Parameters:                                              */
854 /*    char *s : error description                            */
855 /*  Return: int                                              */
856 /*                                                           */
857 /*************************************************************/
858 static void
859 _asn1_yyerror (const char *s)
860 {
861   /* Sends the error description to the std_out */
862
863   if (strcmp (last_token, "VisibleString") == 0 ||
864       strcmp (last_token, "PrintableString") == 0 ||
865       strcmp (last_token, "UniversalString") == 0 ||
866       strcmp (last_token, "IA5String") == 0 ||
867       strcmp (last_token, "UTF8String") == 0 ||
868       strcmp (last_token, "NumericString") == 0 ||
869       strcmp (last_token, "TeletexString") == 0 ||
870       strcmp (last_token, "BMPString") == 0)
871     {
872       snprintf (last_error_token, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
873                 "%s", last_token);
874       fprintf(stderr, 
875                "%s:%u: Warning: %s is a built-in ASN.1 type.\n",
876                file_name, line_number, last_token);
877       return;
878     }
879   last_error_token[0] = 0;
880
881   if (result_parse != ASN1_NAME_TOO_LONG)
882     {
883       snprintf (last_error, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
884                 "%s:%u: Error: %s near '%s'", file_name,
885                 line_number, s, last_token);
886       result_parse = ASN1_SYNTAX_ERROR;
887     }
888
889   return;
890 }