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 * asn1p_ref_new(int _lineno)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 24 void asn1p_ref_free(asn1p_ref_t * ref)25asn1p_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 asn1p_ref_name2lextype(char * name)43asn1p_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 asn1p_ref_add_component(asn1p_ref_t * ref,char * name,enum asn1p_ref_lex_type_e lex_type)81asn1p_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 * asn1p_ref_clone(asn1p_ref_t * ref)119asn1p_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 } 139