123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- /* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
- See the COPYRIGHT file for more information. */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "nclist.h"
- static ncelem ncDATANULL = (ncelem)0;
- /*static int ncinitialized=0;*/
- int nclistnull(ncelem e) {return e == ncDATANULL;}
- #ifndef TRUE
- #define TRUE 1
- #endif
- #ifndef FALSE
- #define FALSE 0
- #endif
- #define DEFAULTALLOC 16
- #define ALLOCINCR 16
- NClist* nclistnew(void)
- {
- NClist* l;
- /*
- if(!ncinitialized) {
- memset((void*)&ncDATANULL,0,sizeof(ncelem));
- ncinitialized = 1;
- }
- */
- l = (NClist*)malloc(sizeof(NClist));
- if(l) {
- l->alloc=0;
- l->length=0;
- l->content=NULL;
- }
- return l;
- }
- int
- nclistfree(NClist* l)
- {
- if(l) {
- l->alloc = 0;
- if(l->content != NULL) {free(l->content); l->content = NULL;}
- free(l);
- }
- return TRUE;
- }
- int
- nclistsetalloc(NClist* l, unsigned int sz)
- {
- ncelem* newcontent;
- if(l == NULL) return FALSE;
- if(sz <= 0) {sz = (l->length?2*l->length:DEFAULTALLOC);}
- if(l->alloc >= sz) {return TRUE;}
- newcontent=(ncelem*)calloc(sz,sizeof(ncelem));
- if(l->alloc > 0 && l->length > 0 && l->content != NULL) {
- memcpy((void*)newcontent,(void*)l->content,sizeof(ncelem)*l->length);
- }
- if(l->content != NULL) free(l->content);
- l->content=newcontent;
- l->alloc=sz;
- return TRUE;
- }
- int
- nclistsetlength(NClist* l, unsigned int sz)
- {
- if(l == NULL) return FALSE;
- if(sz > l->alloc && !nclistsetalloc(l,sz)) return FALSE;
- l->length = sz;
- return TRUE;
- }
- ncelem
- nclistget(NClist* l, unsigned int index)
- {
- if(l == NULL || l->length == 0) return ncDATANULL;
- if(index >= l->length) return ncDATANULL;
- return l->content[index];
- }
- int
- nclistset(NClist* l, unsigned int index, ncelem elem)
- {
- if(l == NULL) return FALSE;
- if(index >= l->length) return FALSE;
- l->content[index] = elem;
- return TRUE;
- }
- /* Insert at position i of l; will push up elements i..|seq|. */
- int
- nclistinsert(NClist* l, unsigned int index, ncelem elem)
- {
- int i; /* do not make unsigned */
- if(l == NULL) return FALSE;
- if(index > l->length) return FALSE;
- nclistsetalloc(l,0);
- for(i=(int)l->length;i>index;i--) l->content[i] = l->content[i-1];
- l->content[index] = elem;
- l->length++;
- return TRUE;
- }
- int
- nclistpush(NClist* l, ncelem elem)
- {
- if(l == NULL) return FALSE;
- if(l->length >= l->alloc) nclistsetalloc(l,0);
- l->content[l->length] = elem;
- l->length++;
- return TRUE;
- }
- ncelem
- nclistpop(NClist* l)
- {
- if(l == NULL || l->length == 0) return ncDATANULL;
- l->length--;
- return l->content[l->length];
- }
- ncelem
- nclisttop(NClist* l)
- {
- if(l == NULL || l->length == 0) return ncDATANULL;
- return l->content[l->length - 1];
- }
- ncelem
- nclistremove(NClist* l, unsigned int i)
- {
- unsigned int len;
- ncelem elem;
- if(l == NULL || (len=l->length) == 0) return ncDATANULL;
- if(i >= len) return ncDATANULL;
- elem = l->content[i];
- for(i+=1;i<len;i++) l->content[i-1] = l->content[i];
- l->length--;
- return elem;
- }
- /* Duplicate and return the content (null terminate) */
- ncelem*
- nclistdup(NClist* l)
- {
- ncelem* result = (ncelem*)malloc(sizeof(ncelem)*(l->length+1));
- memcpy((void*)result,(void*)l->content,sizeof(ncelem)*l->length);
- result[l->length] = (ncelem)0;
- return result;
- }
- int
- nclistcontains(NClist* list, ncelem elem)
- {
- unsigned int i;
- for(i=0;i<nclistlength(list);i++) {
- if(elem == nclistget(list,i)) return 1;
- }
- return 0;
- }
- /* Remove element by value; only removes first encountered */
- int
- nclistelemremove(NClist* l, ncelem elem)
- {
- unsigned int len;
- unsigned int i;
- int found = 0;
- if(l == NULL || (len=l->length) == 0) return ncDATANULL;
- for(i=0;i<nclistlength(l);i++) {
- ncelem candidate = l->content[i];
- if(elem == candidate) {
- for(i+=1;i<len;i++) l->content[i-1] = l->content[i];
- l->length--;
- found = 1;
- break;
- }
- }
- return found;
- }
- /* Extends nclist to include a unique operator
- which remove duplicate values; NULL values removed
- return value is always 1.
- */
- int
- nclistunique(NClist* list)
- {
- unsigned int i,j,k,len;
- ncelem* content;
- if(list == NULL || list->length == 0) return 1;
- len = list->length;
- content = list->content;
- for(i=0;i<len;i++) {
- for(j=i+1;j<len;j++) {
- if(content[i] == content[j]) {
- /* compress out jth element */
- for(k=j+1;k<len;k++) content[k-1] = content[k];
- len--;
- }
- }
- }
- list->length = len;
- return 1;
- }
- NClist*
- nclistclone(NClist* list)
- {
- NClist* clone = nclistnew();
- *clone = *list;
- clone->content = nclistdup(list);
- return clone;
- }
|