Home | History | Annotate | Download | only in libyasm
      1 /*
      2  * YASM associated data storage (libyasm internal use)
      3  *
      4  *  Copyright (C) 2003-2007  Peter Johnson
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
     16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
     19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  * POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 #include "util.h"
     28 
     29 #include "coretype.h"
     30 #include "assocdat.h"
     31 
     32 
     33 typedef struct assoc_data_item {
     34     const yasm_assoc_data_callback *callback;
     35     void *data;
     36 } assoc_data_item;
     37 
     38 struct yasm__assoc_data {
     39     assoc_data_item *vector;
     40     size_t size;
     41     size_t alloc;
     42 };
     43 
     44 
     45 yasm__assoc_data *
     46 yasm__assoc_data_create(void)
     47 {
     48     yasm__assoc_data *assoc_data = yasm_xmalloc(sizeof(yasm__assoc_data));
     49 
     50     assoc_data->size = 0;
     51     assoc_data->alloc = 2;
     52     assoc_data->vector = yasm_xmalloc(assoc_data->alloc *
     53                                       sizeof(assoc_data_item));
     54 
     55     return assoc_data;
     56 }
     57 
     58 void *
     59 yasm__assoc_data_get(yasm__assoc_data *assoc_data,
     60                      const yasm_assoc_data_callback *callback)
     61 {
     62     size_t i;
     63 
     64     if (!assoc_data)
     65         return NULL;
     66 
     67     for (i=0; i<assoc_data->size; i++) {
     68         if (assoc_data->vector[i].callback == callback)
     69             return assoc_data->vector[i].data;
     70     }
     71     return NULL;
     72 }
     73 
     74 yasm__assoc_data *
     75 yasm__assoc_data_add(yasm__assoc_data *assoc_data_arg,
     76                      const yasm_assoc_data_callback *callback, void *data)
     77 {
     78     yasm__assoc_data *assoc_data;
     79     assoc_data_item *item = NULL;
     80     size_t i;
     81 
     82     /* Create a new assoc_data if necessary */
     83     if (assoc_data_arg)
     84         assoc_data = assoc_data_arg;
     85     else
     86         assoc_data = yasm__assoc_data_create();
     87 
     88     /* See if there's already assocated data for this callback */
     89     for (i=0; i<assoc_data->size; i++) {
     90         if (assoc_data->vector[i].callback == callback)
     91             item = &assoc_data->vector[i];
     92     }
     93 
     94     /* No?  Then append a new one */
     95     if (!item) {
     96         assoc_data->size++;
     97         if (assoc_data->size > assoc_data->alloc) {
     98             assoc_data->alloc *= 2;
     99             assoc_data->vector =
    100                 yasm_xrealloc(assoc_data->vector,
    101                               assoc_data->alloc * sizeof(assoc_data_item));
    102         }
    103         item = &assoc_data->vector[assoc_data->size-1];
    104         item->callback = callback;
    105         item->data = NULL;
    106     }
    107 
    108     /* Delete existing data (if any) */
    109     if (item->data && item->data != data)
    110         item->callback->destroy(item->data);
    111 
    112     item->data = data;
    113 
    114     return assoc_data;
    115 }
    116 
    117 void
    118 yasm__assoc_data_destroy(yasm__assoc_data *assoc_data)
    119 {
    120     size_t i;
    121 
    122     if (!assoc_data)
    123         return;
    124 
    125     for (i=0; i<assoc_data->size; i++)
    126         assoc_data->vector[i].callback->destroy(assoc_data->vector[i].data);
    127     yasm_xfree(assoc_data->vector);
    128     yasm_xfree(assoc_data);
    129 }
    130 
    131 void
    132 yasm__assoc_data_print(const yasm__assoc_data *assoc_data, FILE *f,
    133                        int indent_level)
    134 {
    135     /*TODO*/
    136 }
    137