netcdf-c/ncdump/list.c
Dennis Heimbigner b02703aa24 This PR primarily addresses Issue https://github.com/Unidata/netcdf-c/issues/725.
After a long discussion, I implemented the rules at the end of that issue.
They are documented in nccopy.1.

Additionally, I added a new, per-variable, -c flag that allows
for the direct setting of the chunking parameters for a variable.
The form is
    -c var:c1,c2,...ck
where var is the name of the variable (possibly a fully qualified name)
and the ci are the chunksizes for that variable. It must be the case
that the rank of the variable is k. If the new form is used as well
as the old form, then the new form overrides the old form for the
specified variable. Note that multiple occurrences of the new form
-c flag may be specified.

Misc. Other fixes
1. Added -M <size> option to nccopy to specify the minimum
   allowable chunksize.
2. Removed the unused variables from bigmeta.c
   (Issue https://github.com/Unidata/netcdf-c/issues/1079)
3. Fixed failure of nc_test4/tst_filter.sh by using the new -M
   flag (#1) to allow filter test on a small chunk size.
2018-07-26 20:16:02 -06:00

222 lines
4.3 KiB
C

/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
See the COPYRIGHT file for more information. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "list.h"
int listnull(void* e) {return e == NULL;}
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define DEFAULTALLOC 16
#define ALLOCINCR 16
List* listnew(void)
{
List* l;
/*
if(!initialized) {
memset((void*)&DATANULL,0,sizeof(void*));
initialized = 1;
}
*/
l = (List*)malloc(sizeof(List));
if(l) {
l->alloc=0;
l->length=0;
l->content=NULL;
}
return l;
}
int
listfree(List* l)
{
if(l) {
l->alloc = 0;
if(l->content != NULL) {free(l->content); l->content = NULL;}
free(l);
}
return TRUE;
}
int
listsetalloc(List* l, unsigned long sz)
{
void** newcontent = NULL;
if(l == NULL) return FALSE;
if(sz <= 0) {sz = (l->length?2*l->length:DEFAULTALLOC);}
if(l->alloc >= sz) {return TRUE;}
newcontent=(void**)calloc(sz,sizeof(void*));
if(newcontent != NULL && l->alloc > 0 && l->length > 0 && l->content != NULL) {
memcpy((void*)newcontent,(void*)l->content,sizeof(void*)*l->length);
}
if(l->content != NULL) free(l->content);
l->content=newcontent;
l->alloc=sz;
return TRUE;
}
int
listsetlength(List* l, unsigned long sz)
{
if(l == NULL) return FALSE;
if(sz > l->alloc && !listsetalloc(l,sz)) return FALSE;
l->length = sz;
return TRUE;
}
void*
listget(List* l, unsigned long index)
{
if(l == NULL || l->length == 0) return NULL;
if(index >= l->length) return NULL;
return l->content[index];
}
int
listset(List* l, unsigned long index, void* 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
listinsert(List* l, unsigned long index, void* elem)
{
int i; /* do not make unsigned */
if(l == NULL) return FALSE;
if(index > l->length) return FALSE;
listsetalloc(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
listpush(List* l, void* elem)
{
if(l == NULL) return FALSE;
if(l->length >= l->alloc) listsetalloc(l,0);
l->content[l->length] = elem;
l->length++;
return TRUE;
}
void*
listpop(List* l)
{
if(l == NULL || l->length == 0) return NULL;
l->length--;
return l->content[l->length];
}
void*
listtop(List* l)
{
if(l == NULL || l->length == 0) return NULL;
return l->content[l->length - 1];
}
void*
listremove(List* l, unsigned long i)
{
unsigned long len;
void* elem;
if(l == NULL || (len=l->length) == 0) return NULL;
if(i >= len) return NULL;
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) */
void**
listdup(List* l)
{
void** result = (void**)malloc(sizeof(void*)*(l->length+1));
memcpy((void*)result,(void*)l->content,sizeof(void*)*l->length);
result[l->length] = (void*)0;
return result;
}
int
listcontains(List* l, void* elem)
{
unsigned long i;
for(i=0;i<listlength(l);i++) {
if(elem == listget(l,i)) return 1;
}
return 0;
}
/* Remove element by value; only removes first encountered */
int
listelemremove(List* l, void* elem)
{
unsigned long len;
unsigned long i;
int found = 0;
if(l == NULL || (len=l->length) == 0) return 0;
for(i=0;i<listlength(l);i++) {
void* 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 list to include a unique operator
which remove duplicate values; NULL values removed
return value is always 1.
*/
int
listunique(List* l)
{
unsigned long i,j,k,len;
void** content;
if(l == NULL || l->length == 0) return 1;
len = l->length;
content = l->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--;
}
}
}
l->length = len;
return 1;
}
List*
listclone(List* l)
{
List* clone = listnew();
*clone = *l;
clone->content = listdup(l);
return clone;
}