~ubuntu-branches/ubuntu/intrepid/asn1c/intrepid

« back to all changes in this revision

Viewing changes to libasn1parser/asn1p_ref.c

  • Committer: Bazaar Package Importer
  • Author(s): W. Borgert
  • Date: 2005-05-28 12:36:42 UTC
  • Revision ID: james.westby@ubuntu.com-20050528123642-3h6kstws5u0xcovl
Tags: upstream-0.9.14
ImportĀ upstreamĀ versionĀ 0.9.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#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
 */
 
12
asn1p_ref_t *
 
13
asn1p_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
 
 
24
void
 
25
asn1p_ref_free(asn1p_ref_t *ref) {
 
26
        if(ref) {
 
27
                if(ref->components) {
 
28
                        int i = ref->comp_count;
 
29
                        while(i--) {
 
30
                                if(ref->components[i].name)
 
31
                                free(ref->components[i].name);
 
32
                                ref->components[i].name = 0;
 
33
                        }
 
34
                        free(ref->components);
 
35
                        ref->components = 0;
 
36
                }
 
37
 
 
38
                free(ref);
 
39
        }
 
40
}
 
41
 
 
42
static enum asn1p_ref_lex_type_e
 
43
asn1p_ref_name2lextype(char *name) {
 
44
        enum asn1p_ref_lex_type_e lex_type;
 
45
        int has_lowercase = 0;
 
46
 
 
47
        if(*name == '&') {
 
48
                if(name[1] >= 'A' && name[1] <= 'Z') {
 
49
                        lex_type = RLT_AmpUppercase;
 
50
                } else {
 
51
                        lex_type = RLT_Amplowercase;
 
52
                }
 
53
        } else if(*name >= 'A' && *name <= 'Z') {
 
54
                char *p;
 
55
 
 
56
                for(p = name; *p; p++) {
 
57
                        if(*p >= 'a' && *p <= 'z') {
 
58
                                has_lowercase = 1;
 
59
                                break;
 
60
                        }
 
61
                }
 
62
 
 
63
                if(has_lowercase) {
 
64
                        lex_type = RLT_Uppercase;
 
65
                } else {
 
66
                        lex_type = RLT_CAPITALS;
 
67
                }
 
68
        } else if(*name == '@') {
 
69
                if(name[1] == '.')
 
70
                        lex_type = RLT_AtDotlowercase;
 
71
                else
 
72
                        lex_type = RLT_Atlowercase;
 
73
        } else {
 
74
                lex_type = RLT_lowercase;
 
75
        }
 
76
 
 
77
        return lex_type;
 
78
}
 
79
 
 
80
int
 
81
asn1p_ref_add_component(asn1p_ref_t *ref, char *name, enum asn1p_ref_lex_type_e lex_type) {
 
82
 
 
83
        if(!ref || !name
 
84
        || (int)lex_type < RLT_UNKNOWN || lex_type >= RLT_MAX) {
 
85
                errno = EINVAL;
 
86
                return -1;
 
87
        }
 
88
 
 
89
        if(ref->comp_count == ref->comp_size) {
 
90
                int newsize = ref->comp_size?(ref->comp_size<<2):4;
 
91
                void *p = realloc(ref->components,
 
92
                        newsize * sizeof(ref->components[0]));
 
93
                if(p) {
 
94
                        ref->components = p;
 
95
                        ref->comp_size = newsize;
 
96
                } else {
 
97
                        return -1;
 
98
                }
 
99
 
 
100
        }
 
101
 
 
102
        if(lex_type == RLT_UNKNOWN) {
 
103
                lex_type = asn1p_ref_name2lextype(name);
 
104
        } else {
 
105
                assert(lex_type == asn1p_ref_name2lextype(name));
 
106
        }
 
107
 
 
108
        ref->components[ref->comp_count].name = strdup(name);
 
109
        ref->components[ref->comp_count].lex_type = lex_type;
 
110
        if(ref->components[ref->comp_count].name) {
 
111
                ref->comp_count++;
 
112
                return 0;
 
113
        } else {
 
114
                return -1;
 
115
        }
 
116
}
 
117
 
 
118
asn1p_ref_t *
 
119
asn1p_ref_clone(asn1p_ref_t *ref) {
 
120
        asn1p_ref_t *newref;
 
121
 
 
122
        newref = asn1p_ref_new(ref->_lineno);
 
123
        if(newref) {
 
124
                int i;
 
125
                for(i = 0; i < ref->comp_count; i++) {
 
126
                        if(asn1p_ref_add_component(newref,
 
127
                                ref->components[i].name,
 
128
                                ref->components[i].lex_type
 
129
                        )) {
 
130
                                asn1p_ref_free(newref);
 
131
                                newref = NULL;
 
132
                                break;
 
133
                        }
 
134
                }
 
135
        }
 
136
 
 
137
        return newref;
 
138
}