00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <config.h>
00037
00038 #include <stdlib.h>
00039 #include <string.h>
00040
00041 #include <isccc/alist.h>
00042 #include <isc/assertions.h>
00043 #include <isccc/result.h>
00044 #include <isccc/sexpr.h>
00045 #include <isccc/util.h>
00046
00047 #define CAR(s) (s)->value.as_dottedpair.car
00048 #define CDR(s) (s)->value.as_dottedpair.cdr
00049
00050 #define ALIST_TAG "*alist*"
00051 #define MAX_INDENT 64
00052
00053 static char spaces[MAX_INDENT + 1] =
00054 " ";
00055
00056 isccc_sexpr_t *
00057 isccc_alist_create(void)
00058 {
00059 isccc_sexpr_t *alist, *tag;
00060
00061 tag = isccc_sexpr_fromstring(ALIST_TAG);
00062 if (tag == NULL)
00063 return (NULL);
00064 alist = isccc_sexpr_cons(tag, NULL);
00065 if (alist == NULL) {
00066 isccc_sexpr_free(&tag);
00067 return (NULL);
00068 }
00069
00070 return (alist);
00071 }
00072
00073 isc_boolean_t
00074 isccc_alist_alistp(isccc_sexpr_t *alist)
00075 {
00076 isccc_sexpr_t *car;
00077
00078 if (alist == NULL || alist->type != ISCCC_SEXPRTYPE_DOTTEDPAIR)
00079 return (ISC_FALSE);
00080 car = CAR(alist);
00081 if (car == NULL || car->type != ISCCC_SEXPRTYPE_STRING)
00082 return (ISC_FALSE);
00083 if (strcmp(car->value.as_string, ALIST_TAG) != 0)
00084 return (ISC_FALSE);
00085 return (ISC_TRUE);
00086 }
00087
00088 isc_boolean_t
00089 isccc_alist_emptyp(isccc_sexpr_t *alist)
00090 {
00091 REQUIRE(isccc_alist_alistp(alist));
00092
00093 if (CDR(alist) == NULL)
00094 return (ISC_TRUE);
00095 return (ISC_FALSE);
00096 }
00097
00098 isccc_sexpr_t *
00099 isccc_alist_first(isccc_sexpr_t *alist)
00100 {
00101 REQUIRE(isccc_alist_alistp(alist));
00102
00103 return (CDR(alist));
00104 }
00105
00106 isccc_sexpr_t *
00107 isccc_alist_assq(isccc_sexpr_t *alist, const char *key)
00108 {
00109 isccc_sexpr_t *car, *caar;
00110
00111 REQUIRE(isccc_alist_alistp(alist));
00112
00113
00114
00115
00116 alist = CDR(alist);
00117
00118 while (alist != NULL) {
00119 INSIST(alist->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
00120 car = CAR(alist);
00121 INSIST(car->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
00122 caar = CAR(car);
00123 if (caar->type == ISCCC_SEXPRTYPE_STRING &&
00124 strcmp(caar->value.as_string, key) == 0)
00125 return (car);
00126 alist = CDR(alist);
00127 }
00128
00129 return (NULL);
00130 }
00131
00132 void
00133 isccc_alist_delete(isccc_sexpr_t *alist, const char *key)
00134 {
00135 isccc_sexpr_t *car, *caar, *rest, *prev;
00136
00137 REQUIRE(isccc_alist_alistp(alist));
00138
00139 prev = alist;
00140 rest = CDR(alist);
00141 while (rest != NULL) {
00142 INSIST(rest->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
00143 car = CAR(rest);
00144 INSIST(car != NULL && car->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
00145 caar = CAR(car);
00146 if (caar->type == ISCCC_SEXPRTYPE_STRING &&
00147 strcmp(caar->value.as_string, key) == 0) {
00148 CDR(prev) = CDR(rest);
00149 CDR(rest) = NULL;
00150 isccc_sexpr_free(&rest);
00151 break;
00152 }
00153 prev = rest;
00154 rest = CDR(rest);
00155 }
00156 }
00157
00158 isccc_sexpr_t *
00159 isccc_alist_define(isccc_sexpr_t *alist, const char *key, isccc_sexpr_t *value)
00160 {
00161 isccc_sexpr_t *kv, *k, *elt;
00162
00163 kv = isccc_alist_assq(alist, key);
00164 if (kv == NULL) {
00165
00166
00167
00168 k = isccc_sexpr_fromstring(key);
00169 if (k == NULL)
00170 return (NULL);
00171 kv = isccc_sexpr_cons(k, value);
00172 if (kv == NULL) {
00173 isccc_sexpr_free(&kv);
00174 return (NULL);
00175 }
00176 elt = isccc_sexpr_addtolist(&alist, kv);
00177 if (elt == NULL) {
00178 isccc_sexpr_free(&kv);
00179 return (NULL);
00180 }
00181 } else {
00182
00183
00184
00185 isccc_sexpr_free(&CDR(kv));
00186 CDR(kv) = value;
00187 }
00188
00189 return (kv);
00190 }
00191
00192 isccc_sexpr_t *
00193 isccc_alist_definestring(isccc_sexpr_t *alist, const char *key, const char *str)
00194 {
00195 isccc_sexpr_t *v, *kv;
00196
00197 v = isccc_sexpr_fromstring(str);
00198 if (v == NULL)
00199 return (NULL);
00200 kv = isccc_alist_define(alist, key, v);
00201 if (kv == NULL)
00202 isccc_sexpr_free(&v);
00203
00204 return (kv);
00205 }
00206
00207 isccc_sexpr_t *
00208 isccc_alist_definebinary(isccc_sexpr_t *alist, const char *key, isccc_region_t *r)
00209 {
00210 isccc_sexpr_t *v, *kv;
00211
00212 v = isccc_sexpr_frombinary(r);
00213 if (v == NULL)
00214 return (NULL);
00215 kv = isccc_alist_define(alist, key, v);
00216 if (kv == NULL)
00217 isccc_sexpr_free(&v);
00218
00219 return (kv);
00220 }
00221
00222 isccc_sexpr_t *
00223 isccc_alist_lookup(isccc_sexpr_t *alist, const char *key)
00224 {
00225 isccc_sexpr_t *kv;
00226
00227 kv = isccc_alist_assq(alist, key);
00228 if (kv != NULL)
00229 return (CDR(kv));
00230 return (NULL);
00231 }
00232
00233 isc_result_t
00234 isccc_alist_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp)
00235 {
00236 isccc_sexpr_t *kv, *v;
00237
00238 kv = isccc_alist_assq(alist, key);
00239 if (kv != NULL) {
00240 v = CDR(kv);
00241 if (isccc_sexpr_stringp(v)) {
00242 if (strp != NULL)
00243 *strp = isccc_sexpr_tostring(v);
00244 return (ISC_R_SUCCESS);
00245 } else
00246 return (ISC_R_EXISTS);
00247 }
00248
00249 return (ISC_R_NOTFOUND);
00250 }
00251
00252 isc_result_t
00253 isccc_alist_lookupbinary(isccc_sexpr_t *alist, const char *key, isccc_region_t **r)
00254 {
00255 isccc_sexpr_t *kv, *v;
00256
00257 kv = isccc_alist_assq(alist, key);
00258 if (kv != NULL) {
00259 v = CDR(kv);
00260 if (isccc_sexpr_binaryp(v)) {
00261 if (r != NULL)
00262 *r = isccc_sexpr_tobinary(v);
00263 return (ISC_R_SUCCESS);
00264 } else
00265 return (ISC_R_EXISTS);
00266 }
00267
00268 return (ISC_R_NOTFOUND);
00269 }
00270
00271 void
00272 isccc_alist_prettyprint(isccc_sexpr_t *sexpr, unsigned int indent, FILE *stream)
00273 {
00274 isccc_sexpr_t *elt, *kv, *k, *v;
00275
00276 if (isccc_alist_alistp(sexpr)) {
00277 fprintf(stream, "{\n");
00278 indent += 4;
00279 for (elt = isccc_alist_first(sexpr);
00280 elt != NULL;
00281 elt = CDR(elt)) {
00282 kv = CAR(elt);
00283 INSIST(isccc_sexpr_listp(kv));
00284 k = CAR(kv);
00285 v = CDR(kv);
00286 INSIST(isccc_sexpr_stringp(k));
00287 fprintf(stream, "%.*s%s => ", (int)indent, spaces,
00288 isccc_sexpr_tostring(k));
00289 isccc_alist_prettyprint(v, indent, stream);
00290 if (CDR(elt) != NULL)
00291 fprintf(stream, ",");
00292 fprintf(stream, "\n");
00293 }
00294 indent -= 4;
00295 fprintf(stream, "%.*s}", (int)indent, spaces);
00296 } else if (isccc_sexpr_listp(sexpr)) {
00297 fprintf(stream, "(\n");
00298 indent += 4;
00299 for (elt = sexpr;
00300 elt != NULL;
00301 elt = CDR(elt)) {
00302 fprintf(stream, "%.*s", (int)indent, spaces);
00303 isccc_alist_prettyprint(CAR(elt), indent, stream);
00304 if (CDR(elt) != NULL)
00305 fprintf(stream, ",");
00306 fprintf(stream, "\n");
00307 }
00308 indent -= 4;
00309 fprintf(stream, "%.*s)", (int)indent, spaces);
00310 } else
00311 isccc_sexpr_print(sexpr, stream);
00312 }