"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.16.7/lib/isccc/sexpr.c" (4 Sep 2020, 7092 Bytes) of package /linux/misc/dns/bind9/9.16.7/bind-9.16.7.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sexpr.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  *
   11  * Portions Copyright (C) 2001 Nominum, Inc.
   12  *
   13  * Permission to use, copy, modify, and/or distribute this software for any
   14  * purpose with or without fee is hereby granted, provided that the above
   15  * copyright notice and this permission notice appear in all copies.
   16  *
   17  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL
   18  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY
   20  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   21  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   22  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   23  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   24  */
   25 
   26 /*! \file */
   27 
   28 #include <ctype.h>
   29 #include <stdbool.h>
   30 #include <stdlib.h>
   31 #include <string.h>
   32 
   33 #include <isc/assertions.h>
   34 #include <isc/print.h>
   35 
   36 #include <isccc/sexpr.h>
   37 #include <isccc/util.h>
   38 
   39 static isccc_sexpr_t sexpr_t = { ISCCC_SEXPRTYPE_T, { NULL } };
   40 
   41 #define CAR(s) (s)->value.as_dottedpair.car
   42 #define CDR(s) (s)->value.as_dottedpair.cdr
   43 
   44 isccc_sexpr_t *
   45 isccc_sexpr_cons(isccc_sexpr_t *car, isccc_sexpr_t *cdr) {
   46     isccc_sexpr_t *sexpr;
   47 
   48     sexpr = malloc(sizeof(*sexpr));
   49     if (sexpr == NULL) {
   50         return (NULL);
   51     }
   52     sexpr->type = ISCCC_SEXPRTYPE_DOTTEDPAIR;
   53     CAR(sexpr) = car;
   54     CDR(sexpr) = cdr;
   55 
   56     return (sexpr);
   57 }
   58 
   59 isccc_sexpr_t *
   60 isccc_sexpr_tconst(void) {
   61     return (&sexpr_t);
   62 }
   63 
   64 isccc_sexpr_t *
   65 isccc_sexpr_fromstring(const char *str) {
   66     isccc_sexpr_t *sexpr;
   67 
   68     sexpr = malloc(sizeof(*sexpr));
   69     if (sexpr == NULL) {
   70         return (NULL);
   71     }
   72     sexpr->type = ISCCC_SEXPRTYPE_STRING;
   73     sexpr->value.as_string = strdup(str);
   74     if (sexpr->value.as_string == NULL) {
   75         free(sexpr);
   76         return (NULL);
   77     }
   78 
   79     return (sexpr);
   80 }
   81 
   82 isccc_sexpr_t *
   83 isccc_sexpr_frombinary(const isccc_region_t *region) {
   84     isccc_sexpr_t *sexpr;
   85     unsigned int region_size;
   86 
   87     sexpr = malloc(sizeof(*sexpr));
   88     if (sexpr == NULL) {
   89         return (NULL);
   90     }
   91     sexpr->type = ISCCC_SEXPRTYPE_BINARY;
   92     region_size = REGION_SIZE(*region);
   93     /*
   94      * We add an extra byte when we malloc so we can NUL terminate
   95      * the binary data.  This allows the caller to use it as a C
   96      * string.  It's up to the caller to ensure this is safe.  We don't
   97      * add 1 to the length of the binary region, because the NUL is
   98      * not part of the binary data.
   99      */
  100     sexpr->value.as_region.rstart = malloc(region_size + 1);
  101     if (sexpr->value.as_region.rstart == NULL) {
  102         free(sexpr);
  103         return (NULL);
  104     }
  105     sexpr->value.as_region.rend = sexpr->value.as_region.rstart +
  106                       region_size;
  107     memmove(sexpr->value.as_region.rstart, region->rstart, region_size);
  108     /*
  109      * NUL terminate.
  110      */
  111     sexpr->value.as_region.rstart[region_size] = '\0';
  112 
  113     return (sexpr);
  114 }
  115 
  116 void
  117 isccc_sexpr_free(isccc_sexpr_t **sexprp) {
  118     isccc_sexpr_t *sexpr;
  119     isccc_sexpr_t *item;
  120 
  121     sexpr = *sexprp;
  122     *sexprp = NULL;
  123     if (sexpr == NULL) {
  124         return;
  125     }
  126     switch (sexpr->type) {
  127     case ISCCC_SEXPRTYPE_STRING:
  128         free(sexpr->value.as_string);
  129         break;
  130     case ISCCC_SEXPRTYPE_DOTTEDPAIR:
  131         item = CAR(sexpr);
  132         if (item != NULL) {
  133             isccc_sexpr_free(&item);
  134         }
  135         item = CDR(sexpr);
  136         if (item != NULL) {
  137             isccc_sexpr_free(&item);
  138         }
  139         break;
  140     case ISCCC_SEXPRTYPE_BINARY:
  141         free(sexpr->value.as_region.rstart);
  142         break;
  143     }
  144     free(sexpr);
  145 }
  146 
  147 static bool
  148 printable(isccc_region_t *r) {
  149     unsigned char *curr;
  150 
  151     curr = r->rstart;
  152     while (curr != r->rend) {
  153         if (!isprint(*curr)) {
  154             return (false);
  155         }
  156         curr++;
  157     }
  158 
  159     return (true);
  160 }
  161 
  162 void
  163 isccc_sexpr_print(isccc_sexpr_t *sexpr, FILE *stream) {
  164     isccc_sexpr_t *cdr;
  165     unsigned int size, i;
  166     unsigned char *curr;
  167 
  168     if (sexpr == NULL) {
  169         fprintf(stream, "nil");
  170         return;
  171     }
  172 
  173     switch (sexpr->type) {
  174     case ISCCC_SEXPRTYPE_T:
  175         fprintf(stream, "t");
  176         break;
  177     case ISCCC_SEXPRTYPE_STRING:
  178         fprintf(stream, "\"%s\"", sexpr->value.as_string);
  179         break;
  180     case ISCCC_SEXPRTYPE_DOTTEDPAIR:
  181         fprintf(stream, "(");
  182         do {
  183             isccc_sexpr_print(CAR(sexpr), stream);
  184             cdr = CDR(sexpr);
  185             if (cdr != NULL) {
  186                 fprintf(stream, " ");
  187                 if (cdr->type != ISCCC_SEXPRTYPE_DOTTEDPAIR) {
  188                     fprintf(stream, ". ");
  189                     isccc_sexpr_print(cdr, stream);
  190                     cdr = NULL;
  191                 }
  192             }
  193             sexpr = cdr;
  194         } while (sexpr != NULL);
  195         fprintf(stream, ")");
  196         break;
  197     case ISCCC_SEXPRTYPE_BINARY:
  198         size = REGION_SIZE(sexpr->value.as_region);
  199         curr = sexpr->value.as_region.rstart;
  200         if (printable(&sexpr->value.as_region)) {
  201             fprintf(stream, "'%.*s'", (int)size, curr);
  202         } else {
  203             fprintf(stream, "0x");
  204             for (i = 0; i < size; i++) {
  205                 fprintf(stream, "%02x", *curr++);
  206             }
  207         }
  208         break;
  209     default:
  210         INSIST(0);
  211         ISC_UNREACHABLE();
  212     }
  213 }
  214 
  215 isccc_sexpr_t *
  216 isccc_sexpr_car(isccc_sexpr_t *list) {
  217     REQUIRE(list->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
  218 
  219     return (CAR(list));
  220 }
  221 
  222 isccc_sexpr_t *
  223 isccc_sexpr_cdr(isccc_sexpr_t *list) {
  224     REQUIRE(list->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
  225 
  226     return (CDR(list));
  227 }
  228 
  229 void
  230 isccc_sexpr_setcar(isccc_sexpr_t *pair, isccc_sexpr_t *car) {
  231     REQUIRE(pair->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
  232 
  233     CAR(pair) = car;
  234 }
  235 
  236 void
  237 isccc_sexpr_setcdr(isccc_sexpr_t *pair, isccc_sexpr_t *cdr) {
  238     REQUIRE(pair->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
  239 
  240     CDR(pair) = cdr;
  241 }
  242 
  243 isccc_sexpr_t *
  244 isccc_sexpr_addtolist(isccc_sexpr_t **l1p, isccc_sexpr_t *l2) {
  245     isccc_sexpr_t *last, *elt, *l1;
  246 
  247     REQUIRE(l1p != NULL);
  248     l1 = *l1p;
  249     REQUIRE(l1 == NULL || l1->type == ISCCC_SEXPRTYPE_DOTTEDPAIR);
  250 
  251     elt = isccc_sexpr_cons(l2, NULL);
  252     if (elt == NULL) {
  253         return (NULL);
  254     }
  255     if (l1 == NULL) {
  256         *l1p = elt;
  257         return (elt);
  258     }
  259     for (last = l1; CDR(last) != NULL; last = CDR(last)) {
  260         /* Nothing */
  261     }
  262     CDR(last) = elt;
  263 
  264     return (elt);
  265 }
  266 
  267 bool
  268 isccc_sexpr_listp(isccc_sexpr_t *sexpr) {
  269     if (sexpr == NULL || sexpr->type == ISCCC_SEXPRTYPE_DOTTEDPAIR) {
  270         return (true);
  271     }
  272     return (false);
  273 }
  274 
  275 bool
  276 isccc_sexpr_emptyp(isccc_sexpr_t *sexpr) {
  277     if (sexpr == NULL) {
  278         return (true);
  279     }
  280     return (false);
  281 }
  282 
  283 bool
  284 isccc_sexpr_stringp(isccc_sexpr_t *sexpr) {
  285     if (sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_STRING) {
  286         return (true);
  287     }
  288     return (false);
  289 }
  290 
  291 bool
  292 isccc_sexpr_binaryp(isccc_sexpr_t *sexpr) {
  293     if (sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_BINARY) {
  294         return (true);
  295     }
  296     return (false);
  297 }
  298 
  299 char *
  300 isccc_sexpr_tostring(isccc_sexpr_t *sexpr) {
  301     REQUIRE(sexpr != NULL && (sexpr->type == ISCCC_SEXPRTYPE_STRING ||
  302                   sexpr->type == ISCCC_SEXPRTYPE_BINARY));
  303 
  304     if (sexpr->type == ISCCC_SEXPRTYPE_BINARY) {
  305         return ((char *)sexpr->value.as_region.rstart);
  306     }
  307     return (sexpr->value.as_string);
  308 }
  309 
  310 isccc_region_t *
  311 isccc_sexpr_tobinary(isccc_sexpr_t *sexpr) {
  312     REQUIRE(sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_BINARY);
  313     return (&sexpr->value.as_region);
  314 }