]>
Commit | Line | Data |
---|---|---|
bac41a7b A |
1 | /* |
2 | * compiler/core/val_parser.c | |
3 | * given a string with txt ASN.1 value notation, the length of | |
4 | * the string and the ASN.1 type the value notion defines a value | |
5 | * for, return a Value that contains the internal version | |
6 | * | |
7 | * | |
8 | * currently limited to parsing OBJECT IDENTIFIERs. | |
9 | * should be easy to extend for other values as needed | |
10 | * | |
11 | * Copyright (C) 1991, 1992 Michael Sample | |
12 | * and the University of British Columbia | |
13 | * | |
14 | * This program is free software; you can redistribute it and/or modify | |
15 | * it under the terms of the GNU General Public License as published by | |
16 | * the Free Software Foundation; either version 2 of the License, or | |
17 | * (at your option) any later version. | |
18 | * | |
a66d0d4a | 19 | * $Header: /cvs/root/Security/SecuritySNACCRuntime/compiler/core/Attic/val-parser.c,v 1.1 2001/06/20 21:27:59 dmitch Exp $ |
bac41a7b A |
20 | * $Log: val-parser.c,v $ |
21 | * Revision 1.1 2001/06/20 21:27:59 dmitch | |
22 | * Adding missing snacc compiler files. | |
23 | * | |
24 | * Revision 1.1.1.1 1999/03/16 18:06:53 aram | |
25 | * Originals from SMIME Free Library. | |
26 | * | |
27 | * Revision 1.4 1997/10/10 13:43:16 wan | |
28 | * Corrected bug in generic table decoder wrt. indefinite length elements | |
29 | * Corrected compiler access to freed memory (bug reported by Markku Savela) | |
30 | * Broke asnwish.c into two pieces so that one can build ones on wish | |
31 | * Added beredit tool (based on asnwish, allowes to edit BER messages) | |
32 | * | |
33 | * Revision 1.3 1995/07/25 19:41:46 rj | |
34 | * changed `_' to `-' in file names. | |
35 | * | |
36 | * Revision 1.2 1994/09/01 00:47:33 rj | |
37 | * snacc_config.h removed; val_parser.h includet. | |
38 | * | |
39 | * Revision 1.1 1994/08/28 09:49:44 rj | |
40 | * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. | |
41 | * | |
42 | */ | |
43 | ||
44 | ||
45 | ||
46 | #include <ctype.h> /* for isalpha, isdigit etc macros */ | |
47 | #include <stdio.h> | |
48 | ||
49 | #include "asn-incl.h" | |
50 | #include "asn1module.h" | |
51 | #include "mem.h" | |
52 | #include "snacc-util.h" | |
53 | #include "oid.h" /* arcname->number mapping */ | |
54 | #include "val-parser.h" | |
55 | ||
56 | /* | |
57 | * a bunch of macros for 'standard' parse routines | |
58 | */ | |
59 | #define P_LOCALS\ | |
60 | char *startStr | |
61 | ||
62 | #define SAVE_POS()\ | |
63 | startStr = *vStr; | |
64 | ||
65 | #define RESTORE_POS()\ | |
66 | *vStr = startStr; | |
67 | ||
68 | #define AT_EOF()\ | |
69 | (*vStr == eof) | |
70 | ||
71 | #define FAIL()\ | |
72 | {\ | |
73 | if (*vStr > farthestPosG)\ | |
74 | farthestPosG = *vStr;\ | |
75 | RESTORE_POS();\ | |
76 | return FALSE;\ | |
77 | } | |
78 | ||
79 | #define SUCCEED()\ | |
80 | return TRUE; | |
81 | ||
82 | #define FATAL_ERR()\ | |
83 | parseValuesErrG = 1; | |
84 | ||
85 | /* | |
86 | * a couple macros for errmsg generation | |
87 | */ | |
88 | #define PRINT_ERR_LOC(m, vd)\ | |
89 | fprintf (stderr,"file \"%s\", line %d (or near): ", m->asn1SrcFileName, valLineNoG); | |
90 | ||
91 | ||
92 | #define PRINT_VAL(vd)\ | |
93 | PrintValueDef (stderr, vd); | |
94 | ||
95 | /* | |
96 | * globals | |
97 | */ | |
98 | static ValueDefList *newValsG; | |
99 | static int parseValuesErrG; | |
100 | static unsigned long valLineNoG; | |
101 | static char *farthestPosG; | |
102 | ||
103 | /* | |
104 | * prototypes for non-exported routines | |
105 | */ | |
106 | char *StripComments PROTO ((char *asn1Str, int len)); | |
107 | Value *ParseValue PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char *valueNotation, int len)); | |
108 | ||
109 | Value *ParseValueInternal PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char **valueNotation, char *eof)); | |
110 | ||
111 | int ParseOidValue PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char **valueNotation, char *eof, Value **result)); | |
112 | ||
113 | void SkipWht PROTO ((char **vStr, char *eof)); | |
114 | int ParseIdentifier PROTO ((char **valueNotation, char *eof, char **result)); | |
115 | int ParseNum PROTO ((char **valueNotation, char *eof, char **result)); | |
116 | void AddNewValueDef PROTO ((ValueDefList *vdl, char *name, Value *value)); | |
117 | ||
118 | ||
119 | ||
120 | /* | |
121 | * returns 0 if no parse errors occurred | |
122 | * otherwise returns non-zero | |
123 | */ | |
124 | int | |
125 | ParseValues PARAMS ((mods, m), | |
126 | ModuleList *mods _AND_ | |
127 | Module *m) | |
128 | { | |
129 | ValueDef *v; | |
130 | Value *pv; | |
131 | ||
132 | newValsG = AsnListNew (sizeof (void*)); | |
133 | ||
134 | FOR_EACH_LIST_ELMT (v, m->valueDefs) | |
135 | { | |
136 | if (v->value->basicValue->choiceId == BASICVALUE_VALUENOTATION) | |
137 | { | |
138 | valLineNoG = v->value->lineNo; | |
139 | pv = ParseValue (mods, m, v, v->value->type, v->value->basicValue->a.valueNotation->octs, v->value->basicValue->a.valueNotation->octetLen); | |
140 | ||
141 | /* replace value notation value with parsed version */ | |
142 | if (pv != NULL) | |
143 | { | |
144 | pv->lineNo = v->value->lineNo; | |
145 | pv->type = v->value->type; | |
146 | Free (v->value->basicValue->a.valueNotation->octs); | |
147 | Free (v->value->basicValue->a.valueNotation); | |
148 | Free (v->value->basicValue); | |
149 | Free (v->value); | |
150 | v->value = pv; | |
151 | } | |
152 | } | |
153 | } | |
154 | ||
155 | /* | |
156 | * should traverse type structures for default values etc | |
157 | * that need parsing | |
158 | */ | |
159 | ||
160 | /* add any new value defs */ | |
161 | m->valueDefs = AsnListConcat (m->valueDefs, newValsG); | |
162 | Free (newValsG); | |
163 | ||
164 | return parseValuesErrG; | |
165 | ||
166 | } /* ParseValues */ | |
167 | ||
168 | ||
169 | ||
170 | /* | |
171 | * returns the Value that resuls from parsing the given | |
172 | * value notation string | |
173 | */ | |
174 | Value* | |
175 | ParseValue PARAMS ((mods, m, vd, t, valueNotationStr, vnLen), | |
176 | ModuleList *mods _AND_ | |
177 | Module *m _AND_ | |
178 | ValueDef *vd _AND_ | |
179 | Type *t _AND_ | |
180 | char *valueNotationStr _AND_ | |
181 | int vnLen) | |
182 | { | |
183 | char *vStr; | |
184 | char *vStrOrig; | |
185 | int vStrLen; | |
186 | Value *retVal; | |
187 | ||
188 | /* make copy of value notation with ASN.1 comments zapped */ | |
189 | vStrOrig = vStr = StripComments (valueNotationStr, vnLen); | |
190 | vStrLen = strlen (vStr); | |
191 | ||
192 | retVal = ParseValueInternal (mods, m, vd, t, &vStr, (vStr + vStrLen)); | |
193 | ||
194 | /* use original since parsing has changed vStr */ | |
195 | free (vStrOrig); | |
196 | ||
197 | return retVal; | |
198 | } | |
199 | ||
200 | /* | |
201 | * vStr is a handle to a commentless ASN.1 value string, | |
202 | * eof is a char * to character after the last valid character | |
203 | * in vStr. vStr will be advanced to the current parse location. | |
204 | */ | |
205 | Value* | |
206 | ParseValueInternal PARAMS ((mods, m, vd, t, vStr, eof), | |
207 | ModuleList *mods _AND_ | |
208 | Module *m _AND_ | |
209 | ValueDef *vd _AND_ | |
210 | Type *t _AND_ | |
211 | char **vStr _AND_ | |
212 | char *eof) | |
213 | { | |
214 | Type *dT; | |
215 | Value *retVal; | |
216 | int parseResult = FALSE; | |
217 | ||
218 | dT = ParanoidGetType (t); /* skip type refs to get defining type */ | |
219 | ||
220 | if (dT == NULL) | |
221 | return NULL; | |
222 | ||
223 | retVal = NULL; | |
224 | ||
225 | switch (dT->basicType->choiceId) | |
226 | { | |
227 | case BASICTYPE_SEQUENCE: | |
228 | case BASICTYPE_SET: | |
229 | case BASICTYPE_CHOICE: | |
230 | case BASICTYPE_SEQUENCEOF: | |
231 | case BASICTYPE_SETOF: | |
232 | /* don't do constructed types yet */ | |
233 | break; | |
234 | ||
235 | ||
236 | case BASICTYPE_SELECTION: | |
237 | case BASICTYPE_COMPONENTSOF: | |
238 | case BASICTYPE_ANYDEFINEDBY: | |
239 | case BASICTYPE_UNKNOWN: | |
240 | case BASICTYPE_ANY: | |
241 | /* don't do weird types */ | |
242 | break; | |
243 | ||
244 | ||
245 | /* | |
246 | * The following simple types will need to be filled in | |
247 | * when the constructed types are parsed. | |
248 | * (ie ParseValueInternal becomes recursive) | |
249 | * (currenly all simple types not in {}'s are parsed | |
250 | * in the main yacc parser.) | |
251 | */ | |
252 | ||
253 | case BASICTYPE_BOOLEAN: | |
254 | break; | |
255 | ||
256 | case BASICTYPE_INTEGER: | |
257 | case BASICTYPE_ENUMERATED: | |
258 | break; | |
259 | ||
260 | case BASICTYPE_REAL: | |
261 | break; | |
262 | ||
263 | case BASICTYPE_BITSTRING: | |
264 | break; | |
265 | ||
266 | case BASICTYPE_NULL: | |
267 | break; | |
268 | ||
269 | case BASICTYPE_OCTETSTRING: | |
270 | break; | |
271 | ||
272 | ||
273 | /* assume all macro values in {}'s are OID values */ | |
274 | case BASICTYPE_OID: | |
275 | case BASICTYPE_MACROTYPE: | |
276 | parseResult = ParseOidValue (mods, m, vd, t, vStr, eof, &retVal); | |
277 | if (!parseResult) | |
278 | FATAL_ERR(); | |
279 | break; | |
280 | ||
281 | ||
282 | default: | |
283 | break; | |
284 | } | |
285 | ||
286 | if (parseResult) | |
287 | return retVal; | |
288 | else | |
289 | return NULL; | |
290 | ||
291 | } /* ParseValueInternal */ | |
292 | ||
293 | ||
294 | /* | |
295 | * Strips ASN.1 comments from the given string. | |
296 | * returns a null terminated malloc'd copy without the comments | |
297 | */ | |
298 | char* | |
299 | StripComments PARAMS ((s, len), | |
300 | char *s _AND_ | |
301 | int len) | |
302 | { | |
303 | char *cpy; | |
304 | int sIndex, cpyIndex; | |
305 | int inComment; | |
306 | ||
307 | cpy = (char*)Malloc (len +1); | |
308 | cpyIndex = 0; | |
309 | for (sIndex = 0; sIndex < len; ) | |
310 | { | |
311 | if ((s[sIndex] == '-') && | |
312 | ((sIndex+1) < len) && (s[sIndex+1]== '-')) | |
313 | { | |
314 | /* eat comment body */ | |
315 | for (sIndex += 2; sIndex < len; ) | |
316 | { | |
317 | if ((s[sIndex] == '-') && | |
318 | ((sIndex+1) < len) && (s[sIndex+1]== '-')) | |
319 | { | |
320 | sIndex += 2; | |
321 | break; /* exit for */ | |
322 | } | |
323 | else if (s[sIndex] == '\n') | |
324 | { | |
325 | sIndex++; | |
326 | break; /* exit for */ | |
327 | } | |
328 | else | |
329 | sIndex++; | |
330 | } | |
331 | } | |
332 | else /* not in or start of comment */ | |
333 | cpy[cpyIndex++] = s[sIndex++]; | |
334 | } | |
335 | ||
336 | cpy[cpyIndex] == '\0'; /* add NULL terminator */ | |
337 | return cpy; | |
338 | } /* StripComments */ | |
339 | ||
340 | ||
341 | ||
342 | ||
343 | /* | |
344 | * Returns TRUE if successfully parsed an OID | |
345 | * otherwise returns FALSE. Puts the resulting OID Value in | |
346 | * result if successful. | |
347 | * The result Value's type is BASICVALUE_LINKEDOID | |
348 | * | |
349 | * Pseudo reg expr of the expected oid format: | |
350 | * "{" | |
351 | * (oid_val_ref)? | |
352 | *(defined_oid_elmt_name | digit+ | int_or_enum_val_ref |name"(" digit")")* | |
353 | * "}" | |
354 | * | |
355 | * Does not attempt to link/lookup referenced values | |
356 | * | |
357 | * eg | |
358 | * for { ccitt foo (1) bar bell (bunt) 2 } | |
359 | * | |
360 | * ccitt | |
361 | * arcnum is set to number from oid table (oid.c) | |
362 | * foo (1) | |
363 | * - arcnum set to 1 | |
364 | * - sets up a new integer value def "foo" | |
365 | * defined as 1 *CHANGED -see changes* | |
366 | * - makes oid valueref a value ref to foo (doesn't link it tho) | |
367 | * bar | |
368 | * - makes oid valueref a value ref to bar (doesn't link it tho) | |
369 | * bell (bunt) | |
370 | * - sets up a new integer value def "bell" defined | |
371 | * as a val ref to "bunt" *CHANGED -see changes* | |
372 | * - makes oid valueref a value ref to bell (doesn't link it tho) | |
373 | * 2 | |
374 | * -arc num is set to 2 | |
375 | * | |
376 | * CHANGES: | |
377 | * 93/05/03 - named arcs such as foo (1) or bell (bunt) handling | |
378 | * changed. The names (foo and bell) are now ignored | |
379 | * and *do not* define new integer values. | |
380 | * The old way led to problems of defining some values | |
381 | * more than once. E.g. in X.500 the { .. ds (5) } | |
382 | * arc name is used everywhere - "ds INTEGER ::= 5" | |
383 | * was defined multiple times as a result. | |
384 | * Then the snacc error checker halted the compilation | |
385 | * since the integer value "ds" was mulitply defined. | |
386 | * | |
387 | */ | |
388 | int | |
389 | ParseOidValue PARAMS ((mods, m, vd, t, vStr, eof, result), | |
390 | ModuleList *mods _AND_ | |
391 | Module *m _AND_ | |
392 | ValueDef *vd _AND_ | |
393 | Type *t _AND_ | |
394 | char **vStr _AND_ | |
395 | char *eof _AND_ | |
396 | Value **result) | |
397 | { | |
398 | Value *newVal; | |
399 | Type *newType; | |
400 | Value *oidVal; | |
401 | OID *parsedOid; | |
402 | OID **nextOid; | |
403 | char *id; | |
404 | char *id2; | |
405 | char *id3; | |
406 | char *num; | |
407 | int arcNum; | |
408 | int namedNumVal; | |
409 | P_LOCALS; | |
410 | ||
411 | ||
412 | SAVE_POS(); | |
413 | ||
414 | if (AT_EOF()) | |
415 | { | |
416 | PRINT_ERR_LOC (m, vd); | |
417 | fprintf (stderr,"ERROR - expecting more data in OBJECT IDENTIFER value\n"); | |
418 | FAIL(); | |
419 | } | |
420 | ||
421 | SkipWht (vStr, eof); | |
422 | ||
423 | if (**vStr != '{') | |
424 | { | |
425 | PRINT_ERR_LOC (m, vd); | |
426 | fprintf (stderr,"ERROR - OBJECT IDENTIFER values must begin with an \"{\".\n"); | |
427 | FAIL(); | |
428 | } | |
429 | else | |
430 | (*vStr)++; /* skip opening { */ | |
431 | ||
432 | SkipWht (vStr, eof); | |
433 | ||
434 | parsedOid = NULL; | |
435 | nextOid = &parsedOid; | |
436 | ||
437 | while (**vStr != '}') | |
438 | { | |
439 | if (ParseIdentifier (vStr, eof, &id)) | |
440 | { | |
441 | /* | |
442 | * check for named number ident (num) or ident (valref) | |
443 | * make a new value def with the name ident if is name | |
444 | * and number form | |
445 | */ | |
446 | SkipWht (vStr, eof); | |
447 | if (**vStr == '(') | |
448 | { | |
449 | ||
450 | (*vStr)++; /* skip opening ( */ | |
451 | SkipWht (vStr, eof); | |
452 | ||
453 | arcNum = NULL_OID_ARCNUM; | |
454 | /* | |
455 | * ident (num)/ident (valref) yields a new value definition | |
456 | * ident. The oid then refences this new value def. | |
457 | */ | |
458 | ||
459 | /* | |
460 | * first case check if of form | |
461 | * { ... ident (valref) ... } | |
462 | */ | |
463 | if (ParseIdentifier (vStr, eof, &id2)) | |
464 | { | |
465 | id3 = NULL; | |
466 | /* check if modname.val format */ | |
467 | if (**vStr == '.') | |
468 | { | |
469 | (*vStr)++; | |
470 | if (!ParseIdentifier (vStr, eof, &id3)) | |
471 | { | |
472 | PRINT_ERR_LOC (m, vd); | |
473 | fprintf (stderr,"ERROR - missing a module name after the \"%s.\" value reference", id2); | |
474 | FAIL(); | |
475 | } | |
476 | } | |
477 | ||
478 | /* grab closing ) */ | |
479 | SkipWht (vStr, eof); | |
480 | if (**vStr == ')') | |
481 | (*vStr)++; | |
482 | else | |
483 | { | |
484 | PRINT_ERR_LOC (m, vd); | |
485 | fprintf (stderr,"ERROR - missing a closing \")\", after the \"%s\" value reference.\n", id2); | |
486 | FAIL(); | |
487 | } | |
488 | ||
489 | if (id3 != NULL) /* modname.val format */ | |
490 | { | |
491 | SetupValue (&newVal, BASICVALUE_IMPORTVALUEREF,valLineNoG); | |
492 | newVal->basicValue->a.importValueRef = | |
493 | (ValueRef*)Malloc (sizeof (ValueRef)); | |
494 | newVal->basicValue->a.importValueRef->valueName = id2; | |
495 | newVal->basicValue->a.importValueRef->moduleName = id3; | |
496 | ||
497 | AddPrivateImportElmt (m, id2, id3, valLineNoG); | |
498 | ||
499 | } | |
500 | else | |
501 | { | |
502 | SetupValue (&newVal, BASICVALUE_LOCALVALUEREF,valLineNoG); | |
503 | newVal->basicValue->a.localValueRef = | |
504 | (ValueRef*)Malloc (sizeof (ValueRef)); | |
505 | newVal->basicValue->a.localValueRef->valueName = id2; | |
506 | } | |
507 | ||
508 | } | |
509 | /* check this form { ... ident (2)...}*/ | |
510 | else if (ParseNum (vStr, eof, &num)) | |
511 | { | |
512 | /* grab closing ) */ | |
513 | SkipWht (vStr, eof); | |
514 | if (**vStr == ')') | |
515 | (*vStr)++; | |
516 | else | |
517 | { | |
518 | PRINT_ERR_LOC (m, vd); | |
519 | fprintf (stderr,"ERROR - missing a closing \")\" after the \"%s (%s\".\n", id2, num); | |
520 | Free (num); | |
521 | FAIL(); | |
522 | } | |
523 | arcNum = atoi (num); | |
524 | Free (num); | |
525 | newVal = NULL; | |
526 | } | |
527 | else /* neither an ident or num after the "(" */ | |
528 | { | |
529 | PRINT_ERR_LOC (m, vd); | |
530 | fprintf (stderr,"ERROR - expecting either a value reference or number after the \"(\".\n"); | |
531 | FAIL(); | |
532 | } | |
533 | ||
534 | *nextOid = (OID*) Malloc (sizeof (OID)); | |
535 | (*nextOid)->valueRef = newVal; | |
536 | (*nextOid)->arcNum = arcNum; | |
537 | nextOid = &(*nextOid)->next; | |
538 | ||
539 | } /* end of ident (num) and ident (ident) form */ | |
540 | ||
541 | else /* value ref: { ... ident .... } */ | |
542 | { | |
543 | *nextOid = (OID*) Malloc (sizeof (OID)); | |
544 | (*nextOid)->arcNum = NULL_OID_ARCNUM; | |
545 | ||
546 | /* | |
547 | * check if special defined oid elmt name | |
548 | * like joint-iso-ccitt, iso, standard etc. | |
549 | */ | |
550 | ||
551 | arcNum = OidArcNameToNum (id); | |
552 | if (arcNum != -1) | |
553 | { | |
554 | (*nextOid)->arcNum = arcNum; | |
555 | } | |
556 | else /* value reference */ | |
557 | { | |
558 | SetupValue (&newVal, BASICVALUE_LOCALVALUEREF,valLineNoG); | |
559 | newVal->basicValue->a.localValueRef = | |
560 | (ValueRef*)Malloc (sizeof (ValueRef)); | |
561 | newVal->basicValue->a.localValueRef->valueName = id; | |
562 | ||
563 | (*nextOid)->valueRef = newVal; | |
564 | } | |
565 | nextOid = &(*nextOid)->next; | |
566 | } | |
567 | } | |
568 | else if (ParseNum (vStr, eof, &num)) /* { .. 2 .. } */ | |
569 | { | |
570 | *nextOid = (OID*) Malloc (sizeof (OID)); | |
571 | (*nextOid)->arcNum = atoi (num); | |
572 | nextOid = &(*nextOid)->next; | |
573 | Free (num); | |
574 | } | |
575 | else | |
576 | { | |
577 | PRINT_ERR_LOC (m, vd); | |
578 | fprintf (stderr,"ERROR - bady formed arc number\n"); | |
579 | FAIL(); | |
580 | } | |
581 | ||
582 | SkipWht (vStr, eof); | |
583 | } | |
584 | ||
585 | (*vStr)++; /* move over closing } */ | |
586 | ||
587 | SetupValue (&oidVal, BASICVALUE_LINKEDOID, valLineNoG); | |
588 | oidVal->basicValue->a.linkedOid = parsedOid; | |
589 | *result = oidVal; | |
590 | SUCCEED(); | |
591 | } | |
592 | ||
593 | ||
594 | void | |
595 | SkipWht PARAMS ((vStr, eof), | |
596 | char **vStr _AND_ | |
597 | char *eof) | |
598 | { | |
599 | while (!AT_EOF()) | |
600 | switch (**vStr) | |
601 | { | |
602 | case '\n': /* newline */ | |
603 | case '\f': /* form feed ?*/ | |
604 | case '\v': /* vertical tab ?*/ | |
605 | case '\r': valLineNoG++; /* carriage return */ | |
606 | case '\t': /* tab */ | |
607 | case ' ': /* space */ | |
608 | case '\007': /* bell? */ | |
609 | case '\b': /* back spc */ | |
610 | (*vStr)++; | |
611 | break; | |
612 | ||
613 | default: | |
614 | return; | |
615 | } | |
616 | } | |
617 | ||
618 | ||
619 | /* | |
620 | * advances the vStr over ASN.1 identifier, returns a copy | |
621 | * in result, and returns TRUE. otherwise returns FALSE | |
622 | * | |
623 | * ASN.1 identifier is: lowercase letter followed by a | |
624 | * string of letters (upper and lower case allowed), digtits, or single | |
625 | * hyphens. last char cannot be a hyphen. | |
626 | */ | |
627 | int | |
628 | ParseIdentifier PARAMS ((vStr, eof, result), | |
629 | char **vStr _AND_ | |
630 | char *eof _AND_ | |
631 | char **result) | |
632 | { | |
633 | char *start; | |
634 | int len; | |
635 | P_LOCALS; | |
636 | ||
637 | SAVE_POS(); | |
638 | ||
639 | if (AT_EOF()) | |
640 | FAIL(); | |
641 | ||
642 | start = *vStr; | |
643 | if (!islower (**vStr)) | |
644 | FAIL(); | |
645 | ||
646 | (*vStr)++; | |
647 | ||
648 | while (!AT_EOF()) | |
649 | { | |
650 | /* allow letters, digits and single hyphens */ | |
651 | if ((isalpha (**vStr)) || isdigit (**vStr) || | |
652 | ((**vStr == '-') && !(*(*vStr - 1) == '-'))) | |
653 | (*vStr)++; | |
654 | else | |
655 | break; /* exit for loop */ | |
656 | ||
657 | } | |
658 | ||
659 | /* don't allow hyphens on the end */ | |
660 | if (*(*vStr - 1) == '-') | |
661 | (*vStr)--; | |
662 | ||
663 | len = *vStr - start; | |
664 | *result = Malloc (len +1); | |
665 | strncpy (*result, start, len); | |
666 | (*result)[len] = '\0'; /* null terminate */ | |
667 | ||
668 | SUCCEED(); | |
669 | } /* ParseIdentifier */ | |
670 | ||
671 | ||
672 | ||
673 | /* | |
674 | * advances the vStr over ASN.1 number, returns a | |
675 | * null terminated ascii copy of the number | |
676 | * in result, and returns TRUE. otherwise returns FALSE | |
677 | */ | |
678 | int | |
679 | ParseNum PARAMS ((vStr, eof, result), | |
680 | char **vStr _AND_ | |
681 | char *eof _AND_ | |
682 | char **result) | |
683 | { | |
684 | P_LOCALS; | |
685 | char *start; | |
686 | int len; | |
687 | ||
688 | SAVE_POS(); | |
689 | ||
690 | if (AT_EOF()) | |
691 | FAIL(); | |
692 | ||
693 | start = *vStr; | |
694 | ||
695 | while (!AT_EOF()) | |
696 | { | |
697 | if (isdigit (**vStr)) | |
698 | (*vStr)++; | |
699 | else | |
700 | break; /* exit for loop */ | |
701 | } | |
702 | len = *vStr - start; | |
703 | ||
704 | if (len == 0) | |
705 | FAIL(); | |
706 | ||
707 | *result = Malloc (len +1); | |
708 | strncpy (*result, start, len); | |
709 | (*result)[len] = '\0'; /* null terminate */ | |
710 | ||
711 | SUCCEED(); | |
712 | } /* ParseNum */ | |
713 | ||
714 | /* | |
715 | * adds a new value def to the vdl. Used | |
716 | * when parsing oid's that defined arc values | |
717 | * eg { 1 2 foo (3) } --> defined foo INTEGER ::= 3 | |
718 | * (should be foo INTEGER (0..MAX) ::= 3) | |
719 | */ | |
720 | void | |
721 | AddNewValueDef PARAMS ((vdl, name, value), | |
722 | ValueDefList *vdl _AND_ | |
723 | char *name _AND_ | |
724 | Value *value) | |
725 | { | |
726 | ValueDef *vd; | |
727 | ValueDef **tmpVd; | |
728 | ||
729 | vd = (ValueDef*)Malloc (sizeof (ValueDef)); | |
730 | vd->definedName = name; | |
731 | vd->value = value; | |
732 | tmpVd = (ValueDef**)AsnListAppend (vdl); | |
733 | *tmpVd = vd; | |
734 | } /* AddNewValueDef */ |