blob: 79e32aaf3914757f306466689785bac8fbf30d9f [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <errno.h>
5#include <assert.h>
6
7#include "asn1parser.h"
8
9/*
10 * Construct a new empty reference.
11 */
12asn1p_ref_t *
13asn1p_ref_new(int _lineno) {
14 asn1p_ref_t *ref;
15
16 ref = calloc(1, sizeof *ref);
17 if(ref) {
18 ref->_lineno = _lineno;
19 }
20
21 return ref;
22}
23
24void
25asn1p_ref_free(asn1p_ref_t *ref) {
26 if(ref) {
27 if(ref->components) {
28 int i = ref->comp_count;
29 while(i--) {
Lev Walkinf15320b2004-06-03 03:38:44 +000030 free(ref->components[i].name);
31 ref->components[i].name = 0;
32 }
33 free(ref->components);
34 ref->components = 0;
35 }
36
37 free(ref);
38 }
39}
40
41static enum asn1p_ref_lex_type_e
42asn1p_ref_name2lextype(char *name) {
43 enum asn1p_ref_lex_type_e lex_type;
44 int has_lowercase = 0;
45
46 if(*name == '&') {
47 if(name[1] >= 'A' && name[1] <= 'Z') {
48 lex_type = RLT_AmpUppercase;
49 } else {
50 lex_type = RLT_Amplowercase;
51 }
52 } else if(*name >= 'A' && *name <= 'Z') {
53 char *p;
54
55 for(p = name; *p; p++) {
56 if(*p >= 'a' && *p <= 'z') {
57 has_lowercase = 1;
58 break;
59 }
60 }
61
62 if(has_lowercase) {
63 lex_type = RLT_Uppercase;
64 } else {
65 lex_type = RLT_CAPITALS;
66 }
67 } else if(*name == '@') {
68 if(name[1] == '.')
69 lex_type = RLT_AtDotlowercase;
70 else
71 lex_type = RLT_Atlowercase;
72 } else {
73 lex_type = RLT_lowercase;
74 }
75
76 return lex_type;
77}
78
79int
80asn1p_ref_add_component(asn1p_ref_t *ref, char *name, enum asn1p_ref_lex_type_e lex_type) {
81
Lev Walkind9bd7752004-06-05 08:17:50 +000082 if(!ref || !name
83 || (int)lex_type < RLT_UNKNOWN || lex_type >= RLT_MAX) {
Lev Walkinf15320b2004-06-03 03:38:44 +000084 errno = EINVAL;
85 return -1;
86 }
87
88 if(ref->comp_count == ref->comp_size) {
89 int newsize = ref->comp_size?(ref->comp_size<<2):4;
90 void *p = realloc(ref->components,
91 newsize * sizeof(ref->components[0]));
92 if(p) {
93 ref->components = p;
94 ref->comp_size = newsize;
95 } else {
96 return -1;
97 }
98
99 }
100
101 if(lex_type == RLT_UNKNOWN) {
102 lex_type = asn1p_ref_name2lextype(name);
103 } else {
104 assert(lex_type == asn1p_ref_name2lextype(name));
105 }
106
107 ref->components[ref->comp_count].name = strdup(name);
108 ref->components[ref->comp_count].lex_type = lex_type;
109 if(ref->components[ref->comp_count].name) {
110 ref->comp_count++;
111 return 0;
112 } else {
113 return -1;
114 }
115}
116
117asn1p_ref_t *
118asn1p_ref_clone(asn1p_ref_t *ref) {
119 asn1p_ref_t *newref;
120
121 newref = asn1p_ref_new(ref->_lineno);
122 if(newref) {
123 int i;
124 for(i = 0; i < ref->comp_count; i++) {
125 if(asn1p_ref_add_component(newref,
126 ref->components[i].name,
127 ref->components[i].lex_type
128 )) {
129 asn1p_ref_free(newref);
130 newref = NULL;
131 break;
132 }
133 }
134 }
135
136 return newref;
137}