Lumiera  0.pre.03
»edit your freedom«
config-wordlist.c
Go to the documentation of this file.
1 /*
2  Config-wordlist - Lumiera wordlist access functions
3 
4  Copyright (C)
5  2008, Christian Thaeter <ct@pipapo.org>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
14 
24 #include "include/logging.h"
25 #include "lib/error.h"
26 #include "lib/tmpbuf.h"
27 
28 
29 #include "common/config.h"
30 
31 extern LumieraConfig lumiera_global_config;
32 
33 
37 const char*
38 lumiera_config_wordlist_get_nth (const char* key, unsigned nth, const char* delims)
39 {
40  const char* value;
41  size_t len;
42 
43  if (!lumiera_config_wordlist_get (key, &value))
44  return NULL;
45 
46  for (;;)
47  {
48  value += strspn (value, delims);
49  len = strcspn (value, delims);
50  if (!nth && *value)
51  break;
52 
53  --nth;
54  value += len;
55 
56  if (!*value)
57  return NULL;
58  }
59 
60  return lumiera_tmpbuf_strndup (value, len);
61 }
62 
63 
64 int
65 lumiera_config_wordlist_find (const char* key, const char* value, const char* delims)
66 {
67  const char* itr;
68  size_t vlen = strlen (value);
69  size_t len;
70 
71  if (!lumiera_config_wordlist_get (key, &itr))
72  return -1;
73 
74  for (int idx = 0; *itr; itr += len, ++idx)
75  {
76  itr += strspn (itr, delims);
77  len = strcspn (itr, delims);
78 
79  if (len == vlen && !strncmp (itr, value, vlen))
80  return idx;
81  }
82 
83  return -1;
84 }
85 
86 
87 const char*
88 lumiera_config_wordlist_replace (const char* key, const char* value, const char* subst1, const char* subst2, const char* delims)
89 {
90  const char* wordlist;
91  const char* str = NULL;
92  size_t vlen = strlen (value);
93  size_t len;
94 
95  if (!value)
96  return NULL;
97 
98  LUMIERA_MUTEX_SECTION (mutex_sync, &lumiera_global_config->lock)
99  {
100  if (lumiera_config_get (key, &wordlist))
101  {
102  const char* start = wordlist + strspn (wordlist, " \t,;");
103 
104  for (const char* itr = start; *itr; itr += len)
105  {
106  const char* left_end = itr;
107  itr += strspn (itr, delims);
108  len = strcspn (itr, delims);
109 
110  if (len == vlen && !strncmp (itr, value, vlen))
111  {
112  /* step over the word */
113  itr += len;
114  itr += strspn (itr, delims);
115 
116  /* getting the delimiters right for the corner cases looks ugly, want to refactor it? just do it */
117  str = lumiera_tmpbuf_snprintf (SIZE_MAX,
118  "%.*s%.*s%.1s%s%.1s%s%.1s%s",
119  start - wordlist, wordlist,
120  left_end - start, start,
121  (left_end - start && subst1 && *subst1) ? delims : "",
122  (subst1 && *subst1) ? subst1 : "",
123  ((left_end - start || (subst1 && *subst1)) && subst2 && *subst2) ? delims : "",
124  (subst2 && *subst2) ? subst2 : "",
125  ((left_end - start || (subst1 && *subst1) || (subst2 && *subst2)) && *itr) ? delims : "",
126  itr
127  );
128 
129  if (!lumiera_config_set (key, lumiera_tmpbuf_snprintf (SIZE_MAX, "=%s", str)))
130  str = NULL;
131 
132  break;
133  }
134  }
135  }
136  }
137 
138  return str;
139 }
140 
141 
142 const char*
143 lumiera_config_wordlist_add (const char* key, const char* value, const char* delims)
144 {
145  const char* wordlist = NULL;
146 
147  if (value && *value)
148  {
149  LUMIERA_MUTEX_SECTION (mutex_sync, &lumiera_global_config->lock)
150  {
151  if (lumiera_config_get (key, &wordlist))
152  {
153  size_t vlen = strlen (value);
154  size_t len;
155 
156  for (const char* itr = wordlist; *itr; itr += len)
157  {
158  itr += strspn (itr, delims);
159  len = strcspn (itr, delims);
160 
161  if (len == vlen && !strncmp (itr, value, vlen))
162  goto end;
163  }
164 
165  wordlist = lumiera_tmpbuf_snprintf (SIZE_MAX, "%s%.1s%s",
166  wordlist,
167  wordlist[strspn (wordlist, delims)] ? delims : "",
168  value);
169 
170  if (!lumiera_config_set (key, lumiera_tmpbuf_snprintf (SIZE_MAX, "=%s", wordlist)))
171  wordlist = NULL;
172  }
173  end:;
174  }
175  }
176 
177  return wordlist;
178 }
179 
180 
181 #if 0
182 
183 const char*
184 lumiera_config_wordlist_remove_nth (const char* key, unsigned nth)
185 {
186 }
187 
188 
189 LumieraConfigitem
190 lumiera_config_wordlist_append (const char* key, const char** value, unsigned nth)
191 {
192 }
193 
194 
195 LumieraConfigitem
196 lumiera_config_wordlist_preprend (const char* key, const char** value, unsigned nth)
197 {
198 }
199 #endif
200 
201 
202 
203 /*
204 // Local Variables:
205 // mode: C
206 // c-file-style: "gnu"
207 // indent-tabs-mode: nil
208 // End:
209 */
const char * lumiera_config_wordlist_replace(const char *key, const char *value, const char *subst1, const char *subst2, const char *delims)
Universal word replacement function.
char * lumiera_tmpbuf_strndup(const char *src, size_t size)
Duplicate string to a tmpbuf.
Definition: tmpbuf.c:102
Interface for a lumiera configuration system (draft).
#define LUMIERA_MUTEX_SECTION(nobugflag, mtx)
Mutual exclusive section.
Definition: mutex.h:32
This header is for including and configuring NoBug.
Round robin temporary buffers.
Lumiera error handling (C interface).
int lumiera_config_wordlist_find(const char *key, const char *value, const char *delims)
Find the index of a word in a wordlist.
const char * lumiera_config_wordlist_get_nth(const char *key, unsigned nth, const char *delims)
return nth word of a wordlist
const char * lumiera_config_wordlist_get(const char *key, const char **value)
Wordlist words delimited by any of " \t,;".
Definition: config-typed.c:236
const char * lumiera_config_wordlist_add(const char *key, const char *value, const char *delims)
Add a word to the end of a wordlist if it doesn&#39;t exist already.
LumieraConfigitem lumiera_config_set(const char *key, const char *delim_value)
Definition: config.c:223
char * lumiera_tmpbuf_snprintf(size_t size, const char *fmt,...)
Construct a string in a tmpbuf.
Definition: tmpbuf.c:116