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 - - $")