|
|
1.1 root 1: #include <libc.h>
2: #include <fio.h>
3: #include <string.h>
4: #include "dbtypes.h"
5:
6: /*
7: * free the value and type of an attribute
8: */
9: Attribute::~Attribute()
10: {
11: if(value){
12: free(value);
13: }
14: if(type){
15: free(type);
16: }
17: }
18:
19: /*
20: * Parse a linear version of an attribute. Anything ending in an
21: * the wildcard character specifies that this attribute is a key matching
22: * anything following the wildcard position.
23: *
24: * Any unrooted domain name is treated has a '.' attached and is treated
25: * as if it ended in a wild card.
26: */
27: Attribute::Attribute(char *str, Tuple *t, char wildcard)
28: {
29: char *ttype;
30: char *wildp;
31: char *p;
32:
33: ttype = strchr(str, ',');
34: if(ttype){
35: *ttype++ = '\0';
36: type = strdup(ttype);
37: } else
38: type = (char *)0;
39:
40: wildp = str+strlen(str)-1;
41: if(*wildp==wildcard){
42: *wildp = '\0';
43: wild = 1;
44: } else
45: wild = 0;
46:
47: if(fstrcmp(type, "dom")==0){
48: /*
49: * domains are case insensitive, convert to lower
50: */
51: for(p = str; *p; p++)
52: *p = tolower(*p);
53:
54: /*
55: * root the wild card
56: */
57: if(wildcard && type && !wild && *wildp!='.'){
58: *(wildp+1) = '.';
59: *(wildp+2) = '\0';
60: wild = 1;
61: }
62: }
63: value = strdup(str);
64: tuple = t;
65: next = 0;
66: }
67:
68: /*
69: * Compute the distance between two attributes. The distance measure is at
70: * most MAXDISTANCE and depends on the type of the attributes. Only attributes
71: * of the same type match.
72: */
73: Attribute::distance(Attribute *origin)
74: {
75: if(type==0 || fstrcmp(origin->type, type)!=0)
76: return MAXDISTANCE;
77: else if(fstrcmp(origin->type, "dom")==0)
78: return dom_distance(value, origin->value);
79: else if(fstrcmp(origin->type, "dk")==0)
80: return dk_distance(value, origin->value);
81: return MAXDISTANCE;
82: }
83:
84: /*
85: * output a linear version of the attribute on fd
86: */
87: int
88: Attribute::simpleprint(int fd)
89: {
90: if(type)
91: return Fprint(fd, "%s,%s ", value, type);
92: else
93: return Fprint(fd, "%s ", value);
94: }
95: void
96: Attribute::print(int fd)
97: {
98: simpleprint(fd);
99: if(tuple){
100: Fprint(fd, " -> ");
101: tuple->print(fd);
102: }
103: }
104:
105: /*
106: * return true if this is a key attribute
107: */
108: int
109: Attribute::iskey()
110: {
111: return fstrcmp(type, "org")!=0;
112: }
113:
114: /*
115: * compare 2 attributes. the key may have the type "name" which matches
116: * only an empty type.
117: */
118: Attribute::compare(Ordered *o)
119: {
120: register rv;
121: Attribute *pattern=(Attribute *)o;
122:
123: if(pattern->wild)
124: rv = strncmp(value, pattern->value, strlen(pattern->value));
125: else
126: rv = fstrcmp(value, pattern->value);
127: if(rv==0){
128: if(pattern->type && strcmp(pattern->type, "name")!=0){
129: if(type)
130: rv = fstrcmp(type, pattern->type);
131: else
132: rv = -1;
133: } else {
134: if(type && pattern->type)
135: rv = -1;
136: }
137: }
138: return rv;
139: }
140:
141: /*
142: * Compare 2 attributes. If they have matching values, return non-zero.
143: */
144: Attribute::compatible(Ordered *o)
145: {
146: Attribute *pattern=(Attribute *)o;
147:
148: if(pattern->wild)
149: return !strncmp(value, pattern->value, strlen(pattern->value));
150: else
151: return !fstrcmp(value, pattern->value);
152: }
153:
154: /*
155: * Print the value if attribute type == t. Return 0 if a value
156: * is printed.
157: */
158: int
159: Attribute::printvalue(int fd, char *t)
160: {
161: if(type){
162: if (strcmp(t, type)==0){
163: Fprint(fd, "\t%s\n", value);
164: return 0;
165: }
166: } else if(strcmp(t, "name")==0){
167: Fprint(fd, "\t%s\n", value);
168: return 0;
169: }
170: return -1;
171: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.