gwenhywfar  5.10.1
stringlist.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Thu Apr 03 2003
3  copyright : (C) 2021 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #define DISABLE_DEBUGLOG
31 
32 
33 #include <gwenhywfar/gwenhywfarapi.h>
34 #include <gwenhywfar/misc.h>
35 #include <gwenhywfar/text.h>
36 
37 #include "stringlist_p.h"
38 #include "debug.h"
39 
40 #include <stdlib.h>
41 #include <assert.h>
42 #include <ctype.h>
43 #include <string.h>
44 #ifdef HAVE_STRINGS_H
45 # include <strings.h>
46 #endif
47 
48 
49 
51 {
52  GWEN_STRINGLIST *sl;
53 
55  assert(sl);
56  sl->ignoreRefCount=1;
57  return sl;
58 }
59 
60 
61 
63 {
64  GWEN_STRINGLISTENTRY *curr, *next;
65 
66  if (sl) {
67  curr=sl->first;
68  while (curr) {
69  next=curr->next;
71  curr=next;
72  } /* while */
73  GWEN_FREE_OBJECT(sl);
74  }
75 }
76 
77 
78 
80 {
81  assert(sl);
82  sl->senseCase=i;
83 }
84 
85 
86 
88 {
89  assert(sl);
90  sl->ignoreRefCount=i;
91 }
92 
93 
94 
96 {
98 
100  assert(sl);
101  sl->refCount=1;
102  if (s) {
103  if (take)
104  sl->data=s;
105  else
106  sl->data=strdup(s);
107  }
108  return sl;
109 }
110 
111 
112 
114  const char *s,
115  int take)
116 {
117  assert(e);
118  if (e->data)
119  free((void *)(e->data));
120  if (take)
121  e->data=s;
122  else
123  e->data=strdup(s);
124 }
125 
126 
127 
129 {
130  if (sl) {
131  if (sl->data)
132  free((void *)(sl->data));
133  GWEN_FREE_OBJECT(sl);
134  }
135 }
136 
137 
138 
141 {
142  GWEN_STRINGLISTENTRY *curr;
143 
144  assert(sl);
145  assert(se);
146 
147  curr=sl->first;
148  if (!curr) {
149  sl->first=se;
150  }
151  else {
152  while (curr->next) {
153  curr=curr->next;
154  }
155  curr->next=se;
156  }
157  sl->count++;
158 }
159 
160 
161 
162 GWEN_STRINGLIST *GWEN_StringList_fromTabString(const char *s, int checkDup)
163 {
164  GWEN_STRINGLIST *sl;
165 
166  sl=GWEN_StringList_new();
167  if (s && *s) {
168  while (*s) {
169  const char *t;
170  char *tmpStr;
171 
172  t=strchr(s, '\t');
173  if (t) {
174  int len;
175 
176  len=(t-s);
177  tmpStr=(char *) malloc(len+1);
178  assert(tmpStr);
179  memmove(tmpStr, s, len);
180  tmpStr[len]=0;
181  /* add partial string, take it over */
182  GWEN_StringList_AppendString(sl, tmpStr, 1, checkDup);
183  s=t+1;
184  }
185  else {
186  /* just add the remaining string (don't take over, copy!) */
187  GWEN_StringList_AppendString(sl, s, 0, checkDup);
188  break;
189  }
190  }
191  }
192 
193  return sl;
194 }
195 
196 
197 
200 {
201  GWEN_STRINGLISTENTRY *curr;
202 
203  assert(sl);
204  assert(se);
205 
206  curr=sl->first;
207  if (curr) {
208  if (curr==se) {
209  sl->first=curr->next;
210  if (sl->count)
211  sl->count--;
212  }
213  else {
214  while (curr->next!=se) {
215  curr=curr->next;
216  }
217  if (curr) {
218  curr->next=se->next;
219  if (sl->count)
220  sl->count--;
221  }
222  }
223  }
224 }
225 
226 
227 
229 {
230  GWEN_STRINGLISTENTRY *se, *next;
231 
232  assert(sl);
233  se=sl->first;
234  sl->first=0;
235  sl->count=0;
236  while (se) {
237  next=se->next;
239  se=next;
240  } /* while */
241 }
242 
243 
244 
246  const char *s,
247  int take,
248  int checkDouble)
249 {
251 
252  if (checkDouble) {
253  se=sl->first;
254  if (sl->senseCase) {
255  while (se) {
256  if (strcmp(se->data, s)==0) {
257  if (take)
258  free((char *)s);
259  se->refCount++;
260  return 0;
261  }
262  se=se->next;
263  } /* while */
264  }
265  else {
266  while (se) {
267  if (strcasecmp(se->data, s)==0) {
268  if (take)
269  free((char *)s);
270  se->refCount++;
271  return 0;
272  }
273  se=se->next;
274  } /* while */
275  }
276  } /* if checkdouble */
277 
278  se=GWEN_StringListEntry_new(s, take);
280  return 1;
281 }
282 
283 
284 
286  const char *s,
287  int take,
288  int checkDouble)
289 {
291 
292  if (checkDouble) {
293  se=sl->first;
294  if (sl->senseCase) {
295  while (se) {
296  if (strcmp(se->data, s)==0) {
297  if (take)
298  free((char *)s);
299  se->refCount++;
300  return 0;
301  }
302  se=se->next;
303  } /* while */
304  }
305  else {
306  while (se) {
307  if (strcasecmp(se->data, s)==0) {
308  if (take)
309  free((char *)s);
310  se->refCount++;
311  return 0;
312  }
313  se=se->next;
314  } /* while */
315  }
316  } /* if checkdouble */
317  se=GWEN_StringListEntry_new(s, take);
318  se->next=sl->first;
319  sl->first=se;
320  sl->count++;
321  return 1;
322 }
323 
324 
325 
327 {
329 
330  se=sl->first;
331  if (sl->senseCase) {
332  while (se) {
333  if (strcmp(se->data, s)==0) {
334  assert(se->refCount);
335  se->refCount--;
336  if (sl->ignoreRefCount)
338  else {
339  if (se->refCount==0)
341  }
342  return 1;
343  }
344  se=se->next;
345  } /* while */
346  return 0;
347  }
348  else {
349  while (se) {
350  if (strcasecmp(se->data, s)==0) {
351  assert(se->refCount);
352  se->refCount--;
353  if (sl->ignoreRefCount)
355  else {
356  if (se->refCount==0)
358  }
359  return 1;
360  }
361  se=se->next;
362  } /* while */
363  return 0;
364  }
365 }
366 
367 
368 
370 {
372 
373  assert(sl);
374  se=sl->first;
375  if (se) {
376  assert(se->refCount);
377 
378  se->refCount--;
379  if (sl->ignoreRefCount)
381  else {
382  if (se->refCount==0)
384  }
385  }
386 }
387 
388 
389 
391 {
392  assert(sl);
393  return sl->first;
394 }
395 
396 
397 
399 {
400  assert(se);
401  return se->next;
402 }
403 
404 
405 
407 {
408  assert(se);
409  return se->data;
410 }
411 
412 
413 
415 {
416  assert(se);
417  if (se->data)
418  free((void *)(se->data));
419  if (s)
420  se->data=strdup(s);
421  else
422  se->data=NULL;
423 }
424 
425 
426 
427 unsigned int GWEN_StringList_Count(const GWEN_STRINGLIST *sl)
428 {
429  assert(sl);
430  return sl->count;
431 }
432 
433 
434 
436  const char *s)
437 {
439 
440  assert(sl);
441  se=sl->first;
442  if (sl->senseCase) {
443  while (se) {
444  if (strcmp(se->data, s)==0) {
445  return 1;
446  }
447  se=se->next;
448  } /* while */
449  return 0;
450  }
451  else {
452  while (se) {
453  if (strcasecmp(se->data, s)==0) {
454  return 1;
455  }
456  se=se->next;
457  } /* while */
458  return 0;
459  }
460 }
461 
462 
463 
464 int GWEN_StringList_GetStringPos(const GWEN_STRINGLIST *sl, const char *s)
465 {
467  int i;
468 
469  assert(sl);
470  se=sl->first;
471  if (sl->senseCase) {
472  i=0;
473  while (se) {
474  if (strcmp(se->data, s)==0) {
475  return i;
476  }
477  i++;
478  se=se->next;
479  } /* while */
480  return -1;
481  }
482  else {
483  i=0;
484  while (se) {
485  if (strcasecmp(se->data, s)==0) {
486  return i;
487  }
488  i++;
489  se=se->next;
490  } /* while */
491  return -1;
492  }
493 }
494 
495 
496 
498 {
500  int i;
501 
502  assert(sl);
503  se=sl->first;
504  if (sl->senseCase) {
505  i=0;
506  while (se) {
507  if (strcmp(se->data, s)==0) {
508  return se;
509  }
510  i++;
511  se=se->next;
512  } /* while */
513  return NULL;
514  }
515  else {
516  i=0;
517  while (se) {
518  if (strcasecmp(se->data, s)==0) {
519  return se;
520  }
521  i++;
522  se=se->next;
523  } /* while */
524  return NULL;
525  }
526 }
527 
528 
529 
531 {
533  GWEN_STRINGLIST *newsl;
534 
535  assert(sl);
536  newsl=GWEN_StringList_new();
537 
538  se=sl->first;
539  while (se) {
540  GWEN_STRINGLISTENTRY *newse;
541 
542  newse=GWEN_StringListEntry_new(se->data, 0);
543  GWEN_StringList_AppendEntry(newsl, newse);
544  se=se->next;
545  } /* while */
546 
547  return newsl;
548 }
549 
550 
552  void *(*func)(const char *s, void *u),
553  void *user_data)
554 {
556  const char *el;
557  void *result = 0;
558  assert(l);
559 
561  if (!it)
562  return 0;
563  while (it) {
564  el = GWEN_StringListEntry_Data(it);
565  result = func(el, user_data);
566  if (result) {
567  return result;
568  }
569  it = GWEN_StringListEntry_Next(it);
570  }
571  return 0;
572 }
573 
574 
575 
577 {
578  assert(l);
579  if (l->first==0)
580  return 0;
581  return l->first->data;
582 }
583 
584 
585 
586 static int GWEN_StringList__compar_asc_nocase(const void *a, const void *b)
587 {
588  const GWEN_STRINGLISTENTRY *const *pse1 = a, * const * pse2 = b;
589  const GWEN_STRINGLISTENTRY *se1 = *pse1, *se2 = *pse2;
590  if (se1 && se2 && se1->data && se2->data)
591  return strcmp(se1->data, se2->data);
592  else
593  return 0;
594 }
595 static int GWEN_StringList__compar_desc_nocase(const void *a, const void *b)
596 {
597  const GWEN_STRINGLISTENTRY *const *pse1 = a, * const * pse2 = b;
598  const GWEN_STRINGLISTENTRY *se1 = *pse1, *se2 = *pse2;
599  if (se1 && se2 && se1->data && se2->data)
600  return strcmp(se2->data, se1->data);
601  else
602  return 0;
603 }
604 static int GWEN_StringList__compar_asc_case(const void *a, const void *b)
605 {
606  const GWEN_STRINGLISTENTRY *const *pse1 = a, * const * pse2 = b;
607  const GWEN_STRINGLISTENTRY *se1 = *pse1, *se2 = *pse2;
608  if (se1 && se2 && se1->data && se2->data)
609  return strcasecmp(se1->data, se2->data);
610  else
611  return 0;
612 }
613 static int GWEN_StringList__compar_desc_case(const void *a, const void *b)
614 {
615  const GWEN_STRINGLISTENTRY *const *pse1 = a, * const * pse2 = b;
616  const GWEN_STRINGLISTENTRY *se1 = *pse1, *se2 = *pse2;
617  if (se1 && se2 && se1->data && se2->data)
618  return strcasecmp(se2->data, se1->data);
619  else
620  return 0;
621 }
622 
623 static int GWEN_StringList__compar_asc_int(const void *a, const void *b)
624 {
625  const GWEN_STRINGLISTENTRY *const *pse1 = a, * const * pse2 = b;
626  const GWEN_STRINGLISTENTRY *se1 = *pse1, *se2 = *pse2;
627  if (se1 && se2 && se1->data && se2->data) {
628  int i1, i2;
629 
630  i1=atoi(se1->data);
631  i2=atoi(se2->data);
632  return (i1>i2) - (i1<i2);
633  }
634  else
635  return 0;
636 }
637 
638 static int GWEN_StringList__compar_desc_int(const void *a, const void *b)
639 {
640  const GWEN_STRINGLISTENTRY *const *pse1 = a, * const * pse2 = b;
641  const GWEN_STRINGLISTENTRY *se1 = *pse1, *se2 = *pse2;
642  if (se1 && se2 && se1->data && se2->data) {
643  int i1, i2;
644 
645  i1=atoi(se1->data);
646  i2=atoi(se2->data);
647  return (i2>i1) - (i2<i1);
648  }
649  else
650  return 0;
651 }
652 
653 
654 
656  int ascending,
657  GWEN_STRINGLIST_SORT_MODE sortMode)
658 {
659  GWEN_STRINGLISTENTRY **tmpEntries;
660  GWEN_STRINGLISTENTRY *sentry;
661  GWEN_STRINGLISTENTRY **psentry;
662 
663  if (l->count<2)
664  return;
665 
666  /* sort entries into a linear pointer list */
667  tmpEntries=(GWEN_STRINGLISTENTRY **)malloc((l->count+1)*
668  sizeof(GWEN_STRINGLISTENTRY *));
669  assert(tmpEntries);
670  sentry=l->first;
671  psentry=tmpEntries;
672  while (sentry) {
673  *(psentry++)=sentry;
674  sentry=sentry->next;
675  } /* while */
676  *psentry=0;
677 
678  /* sort */
679  switch (sortMode) {
681  if (ascending)
682  qsort(tmpEntries, l->count, sizeof(GWEN_STRINGLISTENTRY *),
684  else
685  qsort(tmpEntries, l->count, sizeof(GWEN_STRINGLISTENTRY *),
687  break;
688 
690  if (ascending)
691  qsort(tmpEntries, l->count, sizeof(GWEN_STRINGLISTENTRY *),
693  else
694  qsort(tmpEntries, l->count, sizeof(GWEN_STRINGLISTENTRY *),
696  break;
697 
699  if (ascending)
700  qsort(tmpEntries, l->count, sizeof(GWEN_STRINGLISTENTRY *),
702  else
703  qsort(tmpEntries, l->count, sizeof(GWEN_STRINGLISTENTRY *),
705  break;
706 
707  default:
708  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown sortmode %d", sortMode);
709  }
710 
711  /* sort entries back into GWEN_STRINGLIST */
712  psentry=tmpEntries;
713  sentry=0;
714  while (*psentry) {
715  if (sentry)
716  sentry->next=*psentry;
717  else
718  l->first=*psentry;
719  sentry=*psentry;
720  psentry++;
721  } /* while */
722  sentry->next=NULL;
723 
724  free(tmpEntries);
725 
726 }
727 
728 
729 
730 const char *GWEN_StringList_StringAt(const GWEN_STRINGLIST *sl, int idx)
731 {
733 
734  assert(sl);
735  se=sl->first;
736  while (se) {
737  if (idx--==0)
738  return se->data;
739  se=se->next;
740  } /* while */
741  return 0;
742 }
743 
744 
745 
746 GWEN_STRINGLIST *GWEN_StringList_fromString(const char *str, const char *delimiters, int checkDouble)
747 {
748  if (str && *str) {
749  GWEN_STRINGLIST *sl;
750  const unsigned char *s;
751 
752  sl=GWEN_StringList_new();
753  s=(const unsigned char *)str;
754 
755  while (*s) {
756  /* skip blanks */
757  while (*s && *s<33)
758  s++;
759 
760  if (*s) {
761  const unsigned char *pStart;
762  int len;
763 
764  /* read word */
765  pStart=s;
766  //s++;
767  while (*s && strchr(delimiters, *s)==NULL)
768  s++;
769  len=s-pStart;
770 
771  if (len) {
772  char *toAdd;
773 
774  toAdd=(char *) malloc(len+1);
775  assert(toAdd);
776 
777  memmove(toAdd, pStart, len);
778  toAdd[len]=0;
779 
780  GWEN_StringList_AppendString(sl, toAdd, 1, checkDouble);
781  }
782  }
783 
784  if (*s==0)
785  break;
786  s++;
787  }
788 
789  if (GWEN_StringList_Count(sl)==0) {
791  return NULL;
792  }
793  return sl;
794  }
795  else
796  return NULL;
797 }
798 
799 
800 
801 GWEN_STRINGLIST *GWEN_StringList_fromString2(const char *str, const char *delimiters, int checkDouble, uint32_t flags)
802 {
803  if (str && *str) {
804  GWEN_STRINGLIST *sl;
805  const char *s;
806  GWEN_BUFFER *wbuf;
807 
808  sl=GWEN_StringList_new();
809  s=(const char *)str;
810 
811  wbuf=GWEN_Buffer_new(0, 256, 0, 1);
812  while (*s) {
813  char *copyOfWord;
814 
815  while (*s && isspace((int)*s))
816  s++;
817  if (!(*s))
818  break;
819 
820  DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading word from here: [%s] (delimiters: [%s])", s, delimiters);
821  if (GWEN_Text_GetWordToBuffer(s, delimiters, wbuf, flags, &s))
822  break;
823 
824  copyOfWord=strdup(GWEN_Buffer_GetStart(wbuf));
825  GWEN_StringList_AppendString(sl, copyOfWord, 1, checkDouble);
826  GWEN_Buffer_Reset(wbuf);
827  if (*s)
828  s++;
829  } /* while */
830  GWEN_Buffer_free(wbuf);
831 
832  if (GWEN_StringList_Count(sl)==0) {
834  return NULL;
835  }
836  return sl;
837  }
838 
839  return NULL;
840 }
841 
842 
843 
844 int GWEN_StringList_toBuffer(const GWEN_STRINGLIST *sl, const char *delimiter, GWEN_BUFFER *outBuffer)
845 {
846  int entriesAdded=0;
847 
848  if (sl) {
850 
851  se=sl->first;
852  while (se) {
853  if (se->data && *(se->data)) {
854  if (entriesAdded && delimiter && *delimiter)
855  GWEN_Buffer_AppendString(outBuffer, delimiter);
856  GWEN_Buffer_AppendString(outBuffer, se->data);
857  entriesAdded++;
858  }
859  se=se->next;
860  } /* while */
861  }
862  return entriesAdded;
863 }
864 
865 
866 
868 {
871 
874 
875  while(se1 && se2) {
876  GWEN_STRINGLISTENTRY *se1Next;
877  GWEN_STRINGLISTENTRY *se2Next;
878  const char *s1;
879  const char *s2;
880 
881  se1Next=GWEN_StringListEntry_Next(se1);
882  se2Next=GWEN_StringListEntry_Next(se2);
883 
886  if (!(s1 && *s1 && s2 && *s2 && strcasecmp(s1, s2)==0))
887  break;
888  GWEN_StringList_RemoveEntry(sl1, se1);
889  GWEN_StringList_RemoveEntry(sl2, se2);
890 
891  se1=se1Next;
892  se2=se2Next;
893  }
894 }
895 
896 
897 
898 void GWEN_StringList_AppendStringList(GWEN_STRINGLIST *slDest, const GWEN_STRINGLIST *slSource, int checkDouble)
899 {
900  if (slSource) {
902 
903  se=slSource->first;
904  while (se) {
905  if (se->data && *(se->data))
906  GWEN_StringList_AppendString(slDest, se->data, 0, checkDouble);
907  se=se->next;
908  } /* while */
909  }
910 }
911 
912 
913 
GWEN_STRINGLIST * GWEN_StringList_fromString2(const char *str, const char *delimiters, int checkDouble, uint32_t flags)
Definition: stringlist.c:801
void * GWEN_StringList_ForEach(const GWEN_STRINGLIST *l, void *(*func)(const char *s, void *u), void *user_data)
Definition: stringlist.c:551
GWEN_STRINGLIST * GWEN_StringList_fromTabString(const char *s, int checkDup)
Definition: stringlist.c:162
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:53
void GWEN_StringListEntry_ReplaceString(GWEN_STRINGLISTENTRY *e, const char *s, int take)
Definition: stringlist.c:113
int GWEN_StringList_GetStringPos(const GWEN_STRINGLIST *sl, const char *s)
Definition: stringlist.c:464
void GWEN_StringList_Clear(GWEN_STRINGLIST *sl)
Definition: stringlist.c:228
GWEN_STRINGLISTENTRY * GWEN_StringList_FindStringEntry(const GWEN_STRINGLIST *sl, const char *s)
Definition: stringlist.c:497
void GWEN_StringList_Sort(GWEN_STRINGLIST *l, int ascending, GWEN_STRINGLIST_SORT_MODE sortMode)
Definition: stringlist.c:655
static int GWEN_StringList__compar_asc_int(const void *a, const void *b)
Definition: stringlist.c:623
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
GWEN_STRINGLIST_SORT_MODE
Definition: stringlist.h:41
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:224
int GWEN_StringList_InsertString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition: stringlist.c:285
static int GWEN_StringList__compar_asc_nocase(const void *a, const void *b)
Definition: stringlist.c:586
void GWEN_StringList_SetSenseCase(GWEN_STRINGLIST *sl, int i)
Definition: stringlist.c:79
int GWEN_StringList_toBuffer(const GWEN_STRINGLIST *sl, const char *delimiter, GWEN_BUFFER *outBuffer)
Definition: stringlist.c:844
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_StringList_RemoveEntry(GWEN_STRINGLIST *sl, GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:198
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
const char * GWEN_StringList_StringAt(const GWEN_STRINGLIST *sl, int idx)
Definition: stringlist.c:730
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:390
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:406
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:62
static int GWEN_StringList__compar_asc_case(const void *a, const void *b)
Definition: stringlist.c:604
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition: stringlist.c:245
void GWEN_StringListEntry_free(GWEN_STRINGLISTENTRY *sl)
Definition: stringlist.c:128
static int GWEN_StringList__compar_desc_nocase(const void *a, const void *b)
Definition: stringlist.c:595
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56
int GWEN_StringList_RemoveString(GWEN_STRINGLIST *sl, const char *s)
Definition: stringlist.c:326
GWEN_STRINGLIST * GWEN_StringList_fromString(const char *str, const char *delimiters, int checkDouble)
Definition: stringlist.c:746
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_new(const char *s, int take)
Definition: stringlist.c:95
void GWEN_StringList_AppendStringList(GWEN_STRINGLIST *slDest, const GWEN_STRINGLIST *slSource, int checkDouble)
Definition: stringlist.c:898
GWEN_STRINGLIST * GWEN_StringList_dup(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:530
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
unsigned int GWEN_StringList_Count(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:427
static int GWEN_StringList__compar_desc_case(const void *a, const void *b)
Definition: stringlist.c:613
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
const char * GWEN_StringList_FirstString(const GWEN_STRINGLIST *l)
Definition: stringlist.c:576
int GWEN_StringList_HasString(const GWEN_STRINGLIST *sl, const char *s)
Definition: stringlist.c:435
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:398
void GWEN_StringList_AppendEntry(GWEN_STRINGLIST *sl, GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:139
int GWEN_Text_GetWordToBuffer(const char *src, const char *delims, GWEN_BUFFER *buf, uint32_t flags, const char **next)
Definition: text.c:226
void GWEN_StringListEntry_SetData(GWEN_STRINGLISTENTRY *se, const char *s)
Definition: stringlist.c:414
void GWEN_StringList_RemoveFirstString(GWEN_STRINGLIST *sl)
Definition: stringlist.c:369
static int GWEN_StringList__compar_desc_int(const void *a, const void *b)
Definition: stringlist.c:638
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition: stringlist.c:50
void GWEN_StringList_SetIgnoreRefCount(GWEN_STRINGLIST *sl, int i)
Definition: stringlist.c:87
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
void GWEN_StringList_RemoveCommonFirstEntries(GWEN_STRINGLIST *sl1, GWEN_STRINGLIST *sl2)
Definition: stringlist.c:867