diff options
author | Lev Walkin <vlm@lionet.info> | 2004-06-03 03:38:44 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2004-06-03 03:38:44 +0000 |
commit | f15320bf6b50a0c02636405561ac8323ae901abd (patch) | |
tree | 33461d45122896c6dde35f82f5c7d19b62004a6b /libasn1parser/asn1p_ref.c | |
parent | 746cb60bbccf47019563665f4aec4b6c462c4163 (diff) |
Initial revision
Diffstat (limited to 'libasn1parser/asn1p_ref.c')
-rw-r--r-- | libasn1parser/asn1p_ref.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/libasn1parser/asn1p_ref.c b/libasn1parser/asn1p_ref.c new file mode 100644 index 00000000..4ac2b32d --- /dev/null +++ b/libasn1parser/asn1p_ref.c @@ -0,0 +1,137 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> + +#include "asn1parser.h" + +/* + * Construct a new empty reference. + */ +asn1p_ref_t * +asn1p_ref_new(int _lineno) { + asn1p_ref_t *ref; + + ref = calloc(1, sizeof *ref); + if(ref) { + ref->_lineno = _lineno; + } + + return ref; +} + +void +asn1p_ref_free(asn1p_ref_t *ref) { + if(ref) { + if(ref->components) { + int i = ref->comp_count; + while(i--) { + if(ref->components[i].name) + free(ref->components[i].name); + ref->components[i].name = 0; + } + free(ref->components); + ref->components = 0; + } + + free(ref); + } +} + +static enum asn1p_ref_lex_type_e +asn1p_ref_name2lextype(char *name) { + enum asn1p_ref_lex_type_e lex_type; + int has_lowercase = 0; + + if(*name == '&') { + if(name[1] >= 'A' && name[1] <= 'Z') { + lex_type = RLT_AmpUppercase; + } else { + lex_type = RLT_Amplowercase; + } + } else if(*name >= 'A' && *name <= 'Z') { + char *p; + + for(p = name; *p; p++) { + if(*p >= 'a' && *p <= 'z') { + has_lowercase = 1; + break; + } + } + + if(has_lowercase) { + lex_type = RLT_Uppercase; + } else { + lex_type = RLT_CAPITALS; + } + } else if(*name == '@') { + if(name[1] == '.') + lex_type = RLT_AtDotlowercase; + else + lex_type = RLT_Atlowercase; + } else { + lex_type = RLT_lowercase; + } + + return lex_type; +} + +int +asn1p_ref_add_component(asn1p_ref_t *ref, char *name, enum asn1p_ref_lex_type_e lex_type) { + + if(!ref || !name || lex_type < RLT_UNKNOWN || lex_type >= RLT_MAX) { + errno = EINVAL; + return -1; + } + + if(ref->comp_count == ref->comp_size) { + int newsize = ref->comp_size?(ref->comp_size<<2):4; + void *p = realloc(ref->components, + newsize * sizeof(ref->components[0])); + if(p) { + ref->components = p; + ref->comp_size = newsize; + } else { + return -1; + } + + } + + if(lex_type == RLT_UNKNOWN) { + lex_type = asn1p_ref_name2lextype(name); + } else { + assert(lex_type == asn1p_ref_name2lextype(name)); + } + + ref->components[ref->comp_count].name = strdup(name); + ref->components[ref->comp_count].lex_type = lex_type; + if(ref->components[ref->comp_count].name) { + ref->comp_count++; + return 0; + } else { + return -1; + } +} + +asn1p_ref_t * +asn1p_ref_clone(asn1p_ref_t *ref) { + asn1p_ref_t *newref; + + newref = asn1p_ref_new(ref->_lineno); + if(newref) { + int i; + for(i = 0; i < ref->comp_count; i++) { + if(asn1p_ref_add_component(newref, + ref->components[i].name, + ref->components[i].lex_type + )) { + asn1p_ref_free(newref); + newref = NULL; + break; + } + } + } + + return newref; +} |