ftp.nice.ch/pub/next/unix/developer/pcn.2.0.s.tar.gz#/contrib/utils/make-states/assoc.c

This is assoc.c in view mode; [Download] [Up]

/* 
 * Basic associative array utilities
 */
#include <stdio.h>
#include "assoc.h"
#ifdef ANSI_PROTOTYPING
static int assoc_alloc_entry(AssocArray *a, char *name);
#else  /* ANSI_PROTOTYPING */
static int assoc_alloc_entry();
#endif /* ANSI_PROTOTYPING */

#ifndef NULL
#define NULL 0
#endif

#ifndef INITIAL_SIZE
#define INITIAL_SIZE 0
#endif

#ifndef INITIAL_ALLOC_SIZE
#define INITIAL_ALLOC_SIZE 1
#endif


AssocArray *assoc_new()
{
    AssocArray *a;
    int num;

    a = (AssocArray *) malloc(sizeof(AssocArray));
    a->name = NULL;

    num = INITIAL_SIZE;
    
    a->nEntriesAlloc = num;
    a->nEntries = 0;
    a->entries = (AssocArrayEntry *) malloc(sizeof(AssocArrayEntry) * num);
    
    return a;
}

#ifdef ANSI_PROTOTYPING
int assoc_name_array(AssocArray *a, char *name)
#else  /* ANSI_PROTOTYPING */
int assoc_name_array(a, name)
AssocArray *a;
char *name;
#endif /* ANSI_PROTOTYPING */
{
    a->name = (char *) malloc(strlen(name) + 1);
    strcpy(a->name, name);
}

#ifdef ANSI_PROTOTYPING
int assoc_lookup_entry_idx(AssocArray *a, char *name)
#else  /* ANSI_PROTOTYPING */
int assoc_lookup_entry_idx(a, name)
AssocArray *a;
char *name;
#endif /* ANSI_PROTOTYPING */
{
    int i;
    AssocArrayEntry *ent = NULL;

    for (i = 0; i < a->nEntries; i++)
    {
	if (strcmp(a->entries[i].name, name) == 0)
	    return i;
    }

    return -1;
}

#ifdef ANSI_PROTOTYPING
void assoc_assign(AssocArray *a, char *name, void *val)
#else  /* ANSI_PROTOTYPING */
void assoc_assign(a, name, val)
AssocArray *a;
char *name;
void *val;
#endif /* ANSI_PROTOTYPING */
{
    int idx;

    idx = assoc_lookup_entry_idx(a, name);
    if (idx == -1)
    {
	idx = assoc_alloc_entry(a, name);
    }
    a->entries[idx].value = val;
}

#ifdef ANSI_PROTOTYPING
void *assoc_lookup(AssocArray *a, char *name)
#else  /* ANSI_PROTOTYPING */
void *assoc_lookup(a, name)
AssocArray *a;
char *name;
#endif /* ANSI_PROTOTYPING */
{
    int idx;

    idx = assoc_lookup_entry_idx(a, name);
    if (idx == -1)
	return NULL;

    return a->entries[idx].value;
}

#ifdef ANSI_PROTOTYPING
void *assoc_delete(AssocArray *a, char *name)
#else  /* ANSI_PROTOTYPING */
void *assoc_delete(a, name)
AssocArray *a;
char *name;
#endif /* ANSI_PROTOTYPING */
{
    int idx;
    int i;
    void *val;

    idx = assoc_lookup_entry_idx(a, name);
    if (idx == -1)
	return;

    val = a->entries[idx].value;

    for (i = idx; i < a->nEntries - 1; i++)
    {
	free(a->entries[i].name);
	a->entries[i] = a->entries[i+1];
    }
    a->nEntries--;
    return val;
}

#ifdef ANSI_PROTOTYPING
void assoc_dump(AssocArray *a, FILE *fp)
#else  /* ANSI_PROTOTYPING */
void assoc_dump(a, fp)
AssocArray *a;
FILE *fp;
#endif /* ANSI_PROTOTYPING */
{
    int i;

    fprintf(fp, "Dumping associative array '%s'. nEntries=%d nEntriesAlloc=%d\n",
	    a->name ? a->name : "<<<UNNAMED>>>",
	    a->nEntries, a->nEntriesAlloc);
    for (i = 0; i < a->nEntries; i++)
	fprintf(fp, "    %d: name='%s' val='%x'\n",
		i, a->entries[i].name, a->entries[i].value);
}	

#ifdef ANSI_PROTOTYPING
static int assoc_alloc_entry(AssocArray *a, char *name)
#else  /* ANSI_PROTOTYPING */
static int assoc_alloc_entry(a, name)
AssocArray *a;
char *name;
#endif /* ANSI_PROTOTYPING */
{
    int idx;
    AssocArrayEntry *ent;

    if (a->nEntries == a->nEntriesAlloc)
    {
	int num;
	int i;
	AssocArrayEntry *oldEntries = a->entries;

	num = (a->nEntriesAlloc > 0) ? (a->nEntriesAlloc * 2) : INITIAL_ALLOC_SIZE;

	a->entries = (AssocArrayEntry *) malloc(sizeof(AssocArrayEntry) * num);
	if (a->entries == NULL)
	{
	    printf("MALLOC FAILED in assoc_alloc_entry\n");
	    exit(1);
	}
	a->nEntriesAlloc = num;

	for (i = 0; i < a->nEntries; i++)
	    a->entries[i] = oldEntries[i];
	    
	free(oldEntries);
    }

    idx = a->nEntries++;

    ent = &a->entries[idx];
    
    ent->name = (char *) malloc(strlen(name) + 1);
    strcpy(ent->name, name);

    return idx;
}
    
#ifdef ANSI_PROTOTYPING
AssocState *assoc_iter_init(AssocArray *a)
#else  /* ANSI_PROTOTYPING */
AssocState *assoc_iter_init(a)
AssocArray *a;
#endif /* ANSI_PROTOTYPING */
{
    AssocState *s = (AssocState *) malloc(sizeof (AssocState));
    s->a = a;
    s->n = 0;
    return s;
}

#ifdef ANSI_PROTOTYPING
AssocState *assoc_iter_next(AssocState *s)
#else  /* ANSI_PROTOTYPING */
AssocState *assoc_iter_next(s)
AssocState *s;
#endif /* ANSI_PROTOTYPING */
{
    s->n++;
    if (s->n >= s->a->nEntries)
	return NULL;
    else
	return s;
}

#ifdef ANSI_PROTOTYPING
char *assoc_this_key(AssocState *s)
#else  /* ANSI_PROTOTYPING */
char *assoc_this_key(s)
AssocState *s;
#endif /* ANSI_PROTOTYPING */
{
    return s->a->entries[s->n].name;
}

#ifdef ANSI_PROTOTYPING
void *assoc_this_value(AssocState *s)
#else  /* ANSI_PROTOTYPING */
void *assoc_this_value(s)
AssocState *s;
#endif /* ANSI_PROTOTYPING */
{
    return s->a->entries[s->n].value;
}


    

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.