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 <ctype.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041
00042 #include <isc/assertions.h>
00043 #include <isccc/sexpr.h>
00044 #include <isccc/util.h>
00045
00046 static isccc_sexpr_t sexpr_t = { ISCCC_SEXPRTYPE_T, { NULL } };
00047
00048 #define CAR(s) (s)->value.as_dottedpair.car
00049 #define CDR(s) (s)->value.as_dottedpair.cdr
00050
00051 isccc_sexpr_t *
00052 isccc_sexpr_cons(isccc_sexpr_t *car, isccc_sexpr_t *cdr)
00053 {
00054 isccc_sexpr_t *sexpr;
00055
00056 sexpr = malloc(sizeof(*sexpr));
00057 if (sexpr == NULL)
00058 return (NULL);
00059 sexpr->type = ISCCC_SEXPRTYPE_DOTTEDPAIR;
00060 CAR(sexpr) = car;
00061 CDR(sexpr) = cdr;
00062
00063 return (sexpr);
00064 }
00065
00066 isccc_sexpr_t *
00067 isccc_sexpr_tconst(void)
00068 {
00069 return (&sexpr_t);
00070 }
00071
00072 isccc_sexpr_t *
00073 isccc_sexpr_fromstring(const char *str)
00074 {
00075 isccc_sexpr_t *sexpr;
00076
00077 sexpr = malloc(sizeof(*sexpr));
00078 if (sexpr == NULL)
00079 return (NULL);
00080 sexpr->type = ISCCC_SEXPRTYPE_STRING;
00081 sexpr->value.as_string = strdup(str);
00082 if (sexpr->value.as_string == NULL) {
00083 free(sexpr);
00084 return (NULL);
00085 }
00086
00087 return (sexpr);
00088 }
00089
00090 isccc_sexpr_t *
00091 isccc_sexpr_frombinary(const isccc_region_t *region)
00092 {
00093 isccc_sexpr_t *sexpr;
00094 unsigned int region_size;
00095
00096 sexpr = malloc(sizeof(*sexpr));
00097 if (sexpr == NULL)
00098 return (NULL);
00099 sexpr->type = ISCCC_SEXPRTYPE_BINARY;
00100 region_size = REGION_SIZE(*region);
00101
00102
00103
00104
00105
00106
00107
00108 sexpr->value.as_region.rstart = malloc(region_size + 1);
00109 if (sexpr->value.as_region.rstart == NULL) {
00110 free(sexpr);
00111 return (NULL);
00112 }
00113 sexpr->value.as_region.rend = sexpr->value.as_region.rstart +
00114 region_size;
00115 memmove(sexpr->value.as_region.rstart, region->rstart, region_size);
00116
00117
00118
00119 sexpr->value.as_region.rstart[region_size] = '\0';
00120
00121 return (sexpr);
00122 }
00123
00124 void
00125 isccc_sexpr_free(isccc_sexpr_t **sexprp)
00126 {
00127 isccc_sexpr_t *sexpr;
00128 isccc_sexpr_t *item;
00129
00130 sexpr = *sexprp;
00131 if (sexpr == NULL)
00132 return;
00133 switch (sexpr->type) {
00134 case ISCCC_SEXPRTYPE_STRING:
00135 free(sexpr->value.as_string);
00136 break;
00137 case ISCCC_SEXPRTYPE_DOTTEDPAIR:
00138 item = CAR(sexpr);
00139 if (item != NULL)
00140 isccc_sexpr_free(&item);
00141 item = CDR(sexpr);
00142 if (item != NULL)
00143 isccc_sexpr_free(&item);
00144 break;
00145 case ISCCC_SEXPRTYPE_BINARY:
00146 free(sexpr->value.as_region.rstart);
00147 break;
00148 }
00149 free(sexpr);
00150
00151 *sexprp = NULL;
00152 }
00153
00154 static isc_boolean_t
00155 printable(isccc_region_t *r)
00156 {
00157 unsigned char *curr;
00158
00159 curr = r->rstart;
00160 while (curr != r->rend) {
00161 if (!isprint(*curr))
00162 return (ISC_FALSE);
00163 curr++;
00164 }
00165
00166 return (ISC_TRUE);
00167 }
00168
00169 void
00170 isccc_sexpr_print(isccc_sexpr_t *sexpr, FILE *stream)
00171 {
00172 isccc_sexpr_t *cdr;
00173 unsigned int size, i;
00174 unsigned char *curr;
00175
00176 if (sexpr == NULL) {
00177 fprintf(stream, "nil");
00178 return;
00179 }
00180
00181 switch (sexpr->type) {
00182 case ISCCC_SEXPRTYPE_T:
00183 fprintf(stream, "t");
00184 break;
00185 case ISCCC_SEXPRTYPE_STRING:
00186 fprintf(stream, "\"%s\"", sexpr->value.as_string);
00187 break;
00188 case ISCCC_SEXPRTYPE_DOTTEDPAIR:
00189 fprintf(stream, "(");
00190 do {
00191 isccc_sexpr_print(CAR(sexpr), stream);
00192 cdr = CDR(sexpr);
00193 if (cdr != NULL) {
00194 fprintf(stream, " ");
00195 if (cdr->type != ISCCC_SEXPRTYPE_DOTTEDPAIR) {
00196 fprintf(stream, ". ");
00197 isccc_sexpr_print(cdr, stream);
00198 cdr = NULL;
00199 }
00200 }
00201 sexpr = cdr;
00202 } while (sexpr != NULL);
00203 fprintf(stream, ")");
00204 break;
00205 case ISCCC_SEXPRTYPE_BINARY:
00206 size = REGION_SIZE(sexpr->value.as_region);
00207 curr = sexpr->value.as_region.rstart;
00208 if (printable(&sexpr->value.as_region)) {
00209 fprintf(stream, "'%.*s'", (int)size, curr);
00210 } else {
00211 fprintf(stream, "0x");
00212 for (i = 0; i < size; i++)
00213 fprintf(stream, "%02x", *curr++);
00214 }
00215 break;
00216 default:
00217 INSIST(0);
00218 }
00219 }
00220
00221 isccc_sexpr_t *
00222 isccc_sexpr_car(isccc_sexpr_t *list)
00223 {
00224 REQUIRE(list->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
00225
00226 return (CAR(list));
00227 }
00228
00229 isccc_sexpr_t *
00230 isccc_sexpr_cdr(isccc_sexpr_t *list)
00231 {
00232 REQUIRE(list->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
00233
00234 return (CDR(list));
00235 }
00236
00237 void
00238 isccc_sexpr_setcar(isccc_sexpr_t *pair, isccc_sexpr_t *car)
00239 {
00240 REQUIRE(pair->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
00241
00242 CAR(pair) = car;
00243 }
00244
00245 void
00246 isccc_sexpr_setcdr(isccc_sexpr_t *pair, isccc_sexpr_t *cdr)
00247 {
00248 REQUIRE(pair->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
00249
00250 CDR(pair) = cdr;
00251 }
00252
00253 isccc_sexpr_t *
00254 isccc_sexpr_addtolist(isccc_sexpr_t **l1p, isccc_sexpr_t *l2)
00255 {
00256 isccc_sexpr_t *last, *elt, *l1;
00257
00258 REQUIRE(l1p != NULL);
00259 l1 = *l1p;
00260 REQUIRE(l1 == NULL || l1->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
00261
00262 elt = isccc_sexpr_cons(l2, NULL);
00263 if (elt == NULL)
00264 return (NULL);
00265 if (l1 == NULL) {
00266 *l1p = elt;
00267 return (elt);
00268 }
00269 for (last = l1; CDR(last) != NULL; last = CDR(last))
00270 ;
00271 CDR(last) = elt;
00272
00273 return (elt);
00274 }
00275
00276 isc_boolean_t
00277 isccc_sexpr_listp(isccc_sexpr_t *sexpr)
00278 {
00279 if (sexpr == NULL || sexpr->type == ISCCC_SEXPRTYPE_DOTTEDPAIR)
00280 return (ISC_TRUE);
00281 return (ISC_FALSE);
00282 }
00283
00284 isc_boolean_t
00285 isccc_sexpr_emptyp(isccc_sexpr_t *sexpr)
00286 {
00287 if (sexpr == NULL)
00288 return (ISC_TRUE);
00289 return (ISC_FALSE);
00290 }
00291
00292 isc_boolean_t
00293 isccc_sexpr_stringp(isccc_sexpr_t *sexpr)
00294 {
00295 if (sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_STRING)
00296 return (ISC_TRUE);
00297 return (ISC_FALSE);
00298 }
00299
00300 isc_boolean_t
00301 isccc_sexpr_binaryp(isccc_sexpr_t *sexpr)
00302 {
00303 if (sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_BINARY)
00304 return (ISC_TRUE);
00305 return (ISC_FALSE);
00306 }
00307
00308 char *
00309 isccc_sexpr_tostring(isccc_sexpr_t *sexpr)
00310 {
00311 REQUIRE(sexpr != NULL &&
00312 (sexpr->type == ISCCC_SEXPRTYPE_STRING ||
00313 sexpr->type == ISCCC_SEXPRTYPE_BINARY));
00314
00315 if (sexpr->type == ISCCC_SEXPRTYPE_BINARY)
00316 return ((char *)sexpr->value.as_region.rstart);
00317 return (sexpr->value.as_string);
00318 }
00319
00320 isccc_region_t *
00321 isccc_sexpr_tobinary(isccc_sexpr_t *sexpr)
00322 {
00323 REQUIRE(sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_BINARY);
00324 return (&sexpr->value.as_region);
00325 }