"Fossies" - the Fresh Open Source Software Archive

Member "udunits-2.2.28/lib/systemMap.c" (7 Dec 2020, 4085 Bytes) of package /linux/privat/udunits-2.2.28.tar.gz:


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 "systemMap.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.2.26_vs_2.2.28.

    1 /*
    2  * Copyright 2020 University Corporation for Atmospheric Research
    3  *
    4  * This file is part of the UDUNITS-2 package.  See the file COPYRIGHT
    5  * in the top-level source-directory of the package for copying and
    6  * redistribution conditions.
    7  */
    8 /*
    9  * Module for system-to-pointer maps.
   10  *
   11  * This module is thread-compatible but not thread-safe.
   12  */
   13 
   14 /*LINTLIBRARY*/
   15 
   16 #include "config.h"
   17 
   18 #include "systemMap.h"
   19 #include "udunits2.h"
   20 
   21 #ifdef _MSC_VER
   22 #include "tsearch.h"
   23 #else
   24 #include <search.h>
   25 #endif
   26 #include <stdlib.h>
   27 
   28 struct SystemMap {
   29     void*   tree;
   30 };
   31 
   32 typedef struct {
   33     const ut_system*    system;
   34     void*       ptr;
   35 } Entry;
   36 
   37 
   38 /*
   39  * Compares two entries according to their unit-system pointers.
   40  *
   41  * Arguments:
   42  *  entry1  Pointer to the first entry.
   43  *  entry2  Pointer to the second entry.
   44  * Returns:
   45  *  -1  The first entry's key is less than the second's.
   46  *   0  The first entry's key is equal to the second's.
   47  *   1  The first entry's key is greater than the second's.
   48  */
   49 static int
   50 compareEntries(
   51     const void* entry1,
   52     const void* entry2)
   53 {
   54     const ut_system* const  system1 = ((Entry*)entry1)->system;
   55     const ut_system* const  system2 = ((Entry*)entry2)->system;
   56 
   57     return system1 < system2 ? -1 : system1 == system2 ? 0 : 1;
   58 }
   59 
   60 
   61 /*
   62  * Returns a new instance of a system-map.
   63  *
   64  * Arguments:
   65  *  compare Function for comparing keys.
   66  * Returns:
   67  *  NULL    Operating-system failure.  See "errno".
   68  *  else    Pointer to the new map.
   69  */
   70 SystemMap*
   71 smNew()
   72 {
   73     SystemMap*  map = (SystemMap*)malloc(sizeof(SystemMap));
   74 
   75     if (map != NULL)
   76     map->tree = NULL;
   77 
   78     return map;
   79 }
   80 
   81 
   82 /*
   83  * Returns the address of the pointer to which a unit-system maps.
   84  *
   85  * Arguments:
   86  *  map Pointer to the system-map.
   87  *  system  Pointer to the unit-system.
   88  * Returns:
   89  *  NULL    There is no pointer associated with "system".
   90  *  else    Address of the pointer to which "system" maps.
   91  */
   92 void**
   93 smFind(
   94     const SystemMap* const  map,
   95     const void* const       system)
   96 {
   97     Entry   targetEntry;
   98     Entry** treeEntry;
   99 
  100     targetEntry.system = system;
  101     treeEntry = tfind(&targetEntry, (void**)&map->tree, compareEntries);
  102 
  103     return
  104     treeEntry == NULL
  105         ? NULL
  106         : &(*treeEntry)->ptr;
  107 }
  108 
  109 
  110 /*
  111  * Returns the address of the pointer to which a unit-system maps -- creating a
  112  * new entry if necessary.  If a new entry is created, then the pointer whose
  113  * address is returned will be NULL.
  114  *
  115  * Arguments:
  116  *  map Pointer to the system-map.
  117  *  system  Pointer to the unit-system.
  118  * Returns:
  119  *  NULL    Operating system failure.  See "errno".
  120  *  else    Address of the pointer to which "system" maps.
  121  */
  122 void**
  123 smSearch(
  124     SystemMap* const    map,
  125     const void*     system)
  126 {
  127     void**  addr = NULL;        /* failure */
  128     Entry*  targetEntry = (Entry*)malloc(sizeof(Entry));
  129 
  130     if (targetEntry != NULL) {
  131     Entry** treeEntry;
  132 
  133     targetEntry->system = system;
  134     targetEntry->ptr = NULL;
  135     treeEntry = tsearch(targetEntry, &map->tree, compareEntries);
  136 
  137     if (treeEntry == NULL) {
  138         free(targetEntry);
  139     }
  140     else {
  141         addr = &(*treeEntry)->ptr;
  142 
  143         if (targetEntry != *treeEntry)
  144         free(targetEntry);
  145     }
  146     }
  147 
  148     return addr;
  149 }
  150 
  151 
  152 /*
  153  * Removes the system-map entry that corresponds to a unit-system.
  154  *
  155  * Arguments:
  156  *  map Pointer to the map.
  157  *  system  Pointer to the unit-system.
  158  */
  159 void
  160 smRemove(
  161     SystemMap* const    map,
  162     const void* const   system)
  163 {
  164     Entry   targetEntry;
  165     Entry** treeEntry;
  166 
  167     targetEntry.system = system;
  168     treeEntry = tfind(&targetEntry, &map->tree, compareEntries);
  169 
  170     if (treeEntry != NULL) {
  171     Entry*  entry = *treeEntry;
  172 
  173     (void)tdelete(entry, &map->tree, compareEntries);
  174     free(entry);
  175     }
  176 }
  177 
  178 
  179 /*
  180  * Frees a system-map.  This function should be called when a system-map is no
  181  * longer needed.
  182  *
  183  * Arguments:
  184  *  map Pointer to the system-map to be freed or NULL.  Use of "map"
  185  *      upon return results in undefined behavior.
  186  */
  187 void
  188 smFree(
  189     SystemMap* const    map)
  190 {
  191     if (map != NULL) {
  192     while (map->tree != NULL) {
  193         Entry*  entry = *(Entry**)map->tree;
  194 
  195         tdelete(entry, &map->tree, compareEntries);
  196         free(entry);
  197     }
  198 
  199     free(map);
  200     }
  201 }