Coverage Report

Created: 2023-05-28 06:42

/src/netcdf-c/libdispatch/nclist.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright 2018, UCAR/Unidata and OPeNDAP, Inc.
2
   See the COPYRIGHT file for more information. */
3
#include <stdlib.h>
4
#include <stdio.h>
5
#include <string.h>
6
7
#include "nclist.h"
8
9
#if defined(_WIN32) && !defined(__MINGW32__)
10
#define strcasecmp _stricmp
11
#endif
12
13
0
int nclistisnull(void* e) {return e == NULL;}
14
15
#ifndef TRUE
16
1.35k
#define TRUE 1
17
#endif
18
#ifndef FALSE
19
0
#define FALSE 0
20
#endif
21
22
1
#define DEFAULTALLOC 16
23
#define ALLOCINCR 16
24
25
NClist* nclistnew(void)
26
669
{
27
669
  NClist* l;
28
/*
29
  if(!ncinitialized) {
30
    memset((void*)&ncDATANULL,0,sizeof(void*));
31
    ncinitialized = 1;
32
  }
33
*/
34
669
  l = (NClist*)malloc(sizeof(NClist));
35
669
  if(l) {
36
669
    l->alloc=0;
37
669
    l->length=0;
38
669
    l->content=NULL;
39
669
  }
40
669
  return l;
41
669
}
42
43
int
44
nclistfree(NClist* l)
45
783
{
46
783
  if(l) {
47
669
    l->alloc = 0;
48
669
    if(l->content != NULL) {free(l->content); l->content = NULL;}
49
669
    free(l);
50
669
  }
51
783
  return TRUE;
52
783
}
53
54
/*
55
Free a list and its contents
56
*/
57
int
58
nclistfreeall(NClist* l)
59
343
{
60
343
    nclistclearall(l);
61
343
    return nclistfree(l);
62
343
}
63
64
/*
65
Free the contents of a list
66
*/
67
int
68
nclistclearall(NClist* l)
69
343
{
70
343
  size_t i,len;
71
343
  if(l == NULL) return TRUE;
72
229
  len = l->length;
73
229
  for(i=0;i<len;i++) {
74
0
      void* value = l->content[i];
75
0
      if(value != NULL) free(value);
76
0
  }
77
229
  nclistsetlength(l,0);
78
229
  return TRUE;
79
343
}
80
81
int
82
nclistsetalloc(NClist* l, size_t sz)
83
1
{
84
1
  void** newcontent = NULL;
85
1
  if(l == NULL) return FALSE;
86
1
  if(sz <= 0) {sz = (l->length?2*l->length:DEFAULTALLOC);}
87
1
  if(l->alloc >= sz) {return TRUE;}
88
1
  newcontent=(void**)calloc(sz,sizeof(void*));
89
1
  if(newcontent != NULL && l->alloc > 0 && l->length > 0 && l->content != NULL) {
90
0
    memcpy((void*)newcontent,(void*)l->content,sizeof(void*)*l->length);
91
0
  }
92
1
  if(l->content != NULL) free(l->content);
93
1
  l->content=newcontent;
94
1
  l->alloc=sz;
95
1
  return TRUE;
96
1
}
97
98
int
99
nclistsetlength(NClist* l, size_t newlen)
100
229
{
101
229
  if(l == NULL) return FALSE;
102
229
  if(newlen > l->alloc && !nclistsetalloc(l,newlen)) return FALSE;
103
229
  if(newlen > l->length) {
104
      /* clear any extension */
105
0
      memset(&l->content[l->length],0,(newlen - l->length)*sizeof(void*));
106
0
  }
107
229
  l->length = newlen;
108
229
  return TRUE;
109
229
}
110
111
void*
112
nclistget(const NClist* l, size_t index)
113
1
{
114
1
  if(l == NULL || l->length == 0) return NULL;
115
1
  if(index >= l->length) return NULL;
116
1
  return l->content[index];
117
1
}
118
119
/* Insert at position i of l; will overwrite previous value;
120
   guarantees alloc and length
121
*/
122
int
123
nclistset(NClist* l, size_t index, void* elem)
124
0
{
125
0
  if(l == NULL) return FALSE;
126
0
  if(!nclistsetalloc(l,index+1)) return FALSE;
127
0
  if(index >= l->length) {
128
0
      if(!nclistsetlength(l,index+1)) return FALSE;
129
0
  }
130
0
  l->content[index] = elem;
131
0
  return TRUE;
132
0
}
133
134
/* Insert at position i of l; will push up elements i..|seq|. */
135
int
136
nclistinsert(NClist* l, size_t index, void* elem)
137
0
{
138
0
  long i; /* do not make unsigned */
139
0
  if(l == NULL) return FALSE;
140
0
  if(index > l->length) return FALSE;
141
0
  nclistsetalloc(l,0);
142
0
  for(i=(long)l->length;i>index;i--) l->content[i] = l->content[i-1];
143
0
  l->content[index] = elem;
144
0
  l->length++;
145
0
  return TRUE;
146
0
}
147
148
int
149
nclistpush(NClist* l, const void* elem)
150
1
{
151
1
  if(l == NULL) return FALSE;
152
1
  if(l->length >= l->alloc) nclistsetalloc(l,0);
153
1
  l->content[l->length] = (void*)elem;
154
1
  l->length++;
155
1
  return TRUE;
156
1
}
157
158
void*
159
nclistpop(NClist* l)
160
0
{
161
0
  if(l == NULL || l->length == 0) return NULL;
162
0
  l->length--;
163
0
  return l->content[l->length];
164
0
}
165
166
void*
167
nclisttop(NClist* l)
168
0
{
169
0
  if(l == NULL || l->length == 0) return NULL;
170
0
  return l->content[l->length - 1];
171
0
}
172
173
void*
174
nclistremove(NClist* l, size_t i)
175
0
{
176
0
  size_t len;
177
0
  void* elem;
178
0
  if(l == NULL || (len=l->length) == 0) return NULL;
179
0
  if(i >= len) return NULL;
180
0
  elem = l->content[i];
181
0
  for(i+=1;i<len;i++) l->content[i-1] = l->content[i];
182
0
  l->length--;
183
0
  return elem;
184
0
}
185
186
/* Match on == */
187
int
188
nclistcontains(NClist* l, void* elem)
189
0
{
190
0
    size_t i;
191
0
    for(i=0;i<nclistlength(l);i++) {
192
0
  if(elem == nclistget(l,i)) return 1;
193
0
    }
194
0
    return 0;
195
0
}
196
197
/* Match on str(case)cmp */
198
int
199
nclistmatch(NClist* l, const char* elem, int casesensitive)
200
0
{
201
0
    size_t i;
202
0
    for(i=0;i<nclistlength(l);i++) {
203
0
  const char* candidate = (const char*)nclistget(l,i);
204
0
  int match;
205
0
  if(casesensitive)
206
0
      match = strcmp(elem,candidate);
207
0
  else
208
0
      match = strcasecmp(elem,candidate);
209
0
  if(match == 0) return 1;
210
0
    }
211
0
    return 0;
212
0
}
213
214
/* Remove element by value; only removes first encountered */
215
int
216
nclistelemremove(NClist* l, void* elem)
217
0
{
218
0
  size_t len;
219
0
  size_t i;
220
0
  int found = 0;
221
0
  if(l == NULL || (len=l->length) == 0) return 0;
222
0
  for(i=0;i<nclistlength(l);i++) {
223
0
    void* candidate = l->content[i];
224
0
    if(elem == candidate) {
225
0
      for(i+=1;i<len;i++) l->content[i-1] = l->content[i];
226
0
      l->length--;
227
0
      found = 1;
228
0
      break;
229
0
    }
230
0
  }
231
0
  return found;
232
0
}
233
234
/* Extends nclist to include a unique operator
235
   which remove duplicate values; NULL values removed
236
   return value is always 1.
237
*/
238
239
int
240
nclistunique(NClist* l)
241
0
{
242
0
    size_t i,j,k,len;
243
0
    void** content;
244
0
    if(l == NULL || l->length == 0) return 1;
245
0
    len = l->length;
246
0
    content = l->content;
247
0
    for(i=0;i<len;i++) {
248
0
        for(j=i+1;j<len;j++) {
249
0
      if(content[i] == content[j]) {
250
    /* compress out jth element */
251
0
                for(k=j+1;k<len;k++) content[k-1] = content[k];
252
0
    len--;
253
0
      }
254
0
  }
255
0
    }
256
0
    l->length = len;
257
0
    return 1;
258
0
}
259
260
/* Duplicate a list and if deep is true, assume the contents
261
   are char** and duplicate those also */
262
NClist*
263
nclistclone(const NClist* l, int deep)
264
0
{
265
0
    NClist* clone = NULL;
266
0
    if(l == NULL) goto done;
267
0
    clone = nclistnew();
268
0
    nclistsetalloc(clone,l->length+1); /* make room for final null */
269
0
    if(!deep) {
270
0
        nclistsetlength(clone,l->length);
271
0
        memcpy((void*)clone->content,(void*)l->content,sizeof(void*)*l->length);
272
0
    } else { /*deep*/
273
0
  int i;
274
0
  for(i=0;i<nclistlength(l);i++) {
275
0
      char* dups = strdup(nclistget(l,i));
276
0
      if(dups == NULL) {nclistfreeall(clone); clone = NULL; goto done;}
277
0
      nclistpush(clone,dups);     
278
0
  }
279
0
    }
280
0
    clone->content[l->length] = (void*)0;
281
0
done:
282
0
    return clone;
283
0
}
284
285
286
void*
287
nclistextract(NClist* l)
288
0
{
289
0
    void* result = l->content;
290
0
    l->alloc = 0;
291
0
    l->length = 0;
292
0
    l->content = NULL;
293
0
    return result;
294
0
}
295
296
/* Extends nclist to include a NULL that is not included
297
   in list length.
298
   return value is always 1.
299
*/
300
int
301
nclistnull(NClist* l)
302
0
{
303
0
    if(l == NULL || l->length == 0) return 1;
304
0
    nclistpush(l,NULL);
305
0
    nclistsetlength(l,l->length-1);
306
0
    return 1;
307
0
}
308