All pastes #521369 Raw Edit

Stuff

public text v1 · immutable
#521369 ·published 2007-05-30 05:10 UTC
rendered paste body
/*Noam Litman $Id: listmap.c,v 1.1 2007-05-29-07 nlitman - $*/

/*
* DESCRIPTION
*    Map and iterator represented as a list.
*/

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

#include "auxdefs.h"
#include "listmap.h"

#define xprintf (void) printf

static char *listmap_tag = "struct listmap";
static char *listmap_itor_tag = "struct listmap_itor";
static char *listmap_node_tag = "struct listmap_node";

typedef struct listmap_node *listmap_node_ref;

struct listmap {
   char *tag;
   listmap_node_ref head;
};

struct listmap_itor {
   char *tag;
   listmap_node_ref curr;
};

struct listmap_node {
   char *tag;
   map_key_t key;
   map_value_t value;
   listmap_node_ref link;
};

static bool is_listmap (listmap_ref map) {
   return map != NULL && map->tag == listmap_tag;
}

static bool isempty_listmap(listmap_ref map){
  return map->head == NULL;
}

listmap_ref new_listmap (void) {
   listmap_ref map = malloc (sizeof (struct listmap));
   assert (map != NULL);
   map->tag = listmap_tag;
   map->head = NULL;
   return map;
}
void free_listmap (listmap_ref map) {
   listmap_node_ref curr;
   listmap_node_ref temp;
   assert (is_listmap (map));
   curr = map->head;
   while(curr != NULL){
     temp = curr->link;
     free(curr->key);
     free(curr->value);
     free(curr);
     curr = temp;
   }
   bzero(map, sizeof(struct listmap));
   free(map);
}

map_value_t get_listmap (listmap_ref map, map_key_t key) {
   listmap_node_ref current;
   assert (is_listmap (map));
   current = map->head;
   while(current!= NULL){
     if(strcmp(current->key, key)==0){
       return current->value;
     }else{
       current = current->link;
     }
   }
   return NULL;
}
map_value_t get_listmap (listmap_ref map, map_key_t key) {
   listmap_node_ref current;
   assert (is_listmap (map));
   current = map->head;
   while(current!= NULL){
     if(strcmp(current->key, key)==0){
       return current->value;
     }else{
       current = current->link;
     }
   }
   return NULL;
}

map_value_t put_listmap (listmap_ref map, map_key_t key, map_value_t value) {
   /*set prev curr and new nodes */
   listmap_node_ref curr = NULL;
   listmap_node_ref prev = NULL;
   listmap_node_ref new;
   assert (is_listmap (map));
   /*assert the map is actually a map*/

   /*if the map is empty allocate a new node and insert it into the list
    *you must set its tag key and value and return NULL because there is
    *nothing to be found*/

   if(map->head == NULL && value != NULL){
     listmap_node_ref new = malloc(sizeof(struct listmap_node));
     assert(new != NULL);
     map->head = new;
     new->link = NULL;
     new->tag = listmap_node_tag;
     new->key = strdup(key);
     new->value = strdup(value);
     return NULL;
   }
   /*have curr point at the head of the map and while its not equal to null
    *compare the keys if its great then 0 break and insert if its equal
    *replace curr's value and duplicate the new value and set it too curr.
    *then return curr's old value*/
   curr = map->head;
   while (curr != NULL){
     if(strcmp(curr->key, key)>0){
         break;
     }
if(strcmp(curr->key, key)==0){
       if(value == NULL){
         char *oldvalue;
         if(prev!=NULL){
            prev ->link = curr->link;
         }else{
           map->head = curr->link;
         }
         oldvalue = curr->value;
         free(curr->key);
         free(curr);
         return oldvalue;
       }else{
        char *oldval = curr->value;
        curr->value = strdup(value);
        return oldval;
       }
     }
     prev = curr;
     curr = curr->link;
   }
   if(value == NULL){
     return NULL;
   }
   /*have new's link point to curr allocate it and set its key value and tag
    *if previous points to nothing then have the head of map point to new
    *otherwise the link of previous is goign to point to new. Return NULL
    *if nothing is found*/
   new = malloc(sizeof(struct listmap_node));
   new->key = strdup(key);
   new->tag = listmap_node_tag;
   new->value = strdup(value);
   new->link = curr;
   if(prev == NULL){
     map->head = new;
   }else{
     prev->link = new;
   }
   return NULL;
}
static bool is_listmap_itor (listmap_itor_ref itor) {
   return itor != NULL && itor->tag == listmap_itor_tag;
}

listmap_itor_ref new_listmap_itor (listmap_ref map) {
   listmap_itor_ref itor = malloc (sizeof (struct listmap_itor));
   assert (itor != NULL);
   itor->tag = listmap_itor_tag;
   itor->curr = map->head;
   return itor;
}

void free_listmap_itor (listmap_itor_ref itor) {
   assert (is_listmap_itor (itor));
   bzero (itor, sizeof (struct listmap_itor));
   free (itor);
}

bool hascurr_listmap_itor (listmap_itor_ref itor) {
   assert (is_listmap_itor (itor));
   return itor->curr != NULL;
}

void next_listmap_itor (listmap_itor_ref itor) {
   assert (is_listmap_itor (itor));
   itor->curr = itor->curr->link;
}

map_key_t get_key_listmap_itor (listmap_itor_ref itor) {
   assert (is_listmap_itor (itor));
   return itor->curr->key;
}

map_value_t get_value_listmap_itor (listmap_itor_ref itor) {
   assert (is_listmap_itor (itor));
   return itor->curr->value;
}

RCSC(LISTMAP_C,"$Id: listmap.c,v 1.1 2007-05-27 21:04:59-07 - - $")