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) Lumiera.org
5  2008, Christian Thaeter <ct@pipapo.org>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
23 
33 #include "include/logging.h"
34 #include "lib/error.h"
35 #include "lib/tmpbuf.h"
36 
37 
38 #include "common/config.h"
39 
40 extern LumieraConfig lumiera_global_config;
41 
42 
46 const char*
47 lumiera_config_wordlist_get_nth (const char* key, unsigned nth, const char* delims)
48 {
49  const char* value;
50  size_t len;
51 
52  if (!lumiera_config_wordlist_get (key, &value))
53  return NULL;
54 
55  for (;;)
56  {
57  value += strspn (value, delims);
58  len = strcspn (value, delims);
59  if (!nth && *value)
60  break;
61 
62  --nth;
63  value += len;
64 
65  if (!*value)
66  return NULL;
67  }
68 
69  return lumiera_tmpbuf_strndup (value, len);
70 }
71 
72 
73 int
74 lumiera_config_wordlist_find (const char* key, const char* value, const char* delims)
75 {
76  const char* itr;
77  size_t vlen = strlen (value);
78  size_t len;
79 
80  if (!lumiera_config_wordlist_get (key, &itr))
81  return -1;
82 
83  for (int idx = 0; *itr; itr += len, ++idx)
84  {
85  itr += strspn (itr, delims);
86  len = strcspn (itr, delims);
87 
88  if (len == vlen && !strncmp (itr, value, vlen))
89  return idx;
90  }
91 
92  return -1;
93 }
94 
95 
96 const char*
97 lumiera_config_wordlist_replace (const char* key, const char* value, const char* subst1, const char* subst2, const char* delims)
98 {
99  const char* wordlist;
100  const char* str = NULL;
101  size_t vlen = strlen (value);
102  size_t len;
103 
104  if (!value)
105  return NULL;
106 
107  LUMIERA_MUTEX_SECTION (mutex_sync, &lumiera_global_config->lock)
108  {
109  if (lumiera_config_get (key, &wordlist))
110  {
111  const char* start = wordlist + strspn (wordlist, " \t,;");
112 
113  for (const char* itr = start; *itr; itr += len)
114  {
115  const char* left_end = itr;
116  itr += strspn (itr, delims);
117  len = strcspn (itr, delims);
118 
119  if (len == vlen && !strncmp (itr, value, vlen))
120  {
121  /* step over the word */
122  itr += len;
123  itr += strspn (itr, delims);
124 
125  /* getting the delimiters right for the corner cases looks ugly, want to refactor it? just do it */
126  str = lumiera_tmpbuf_snprintf (SIZE_MAX,
127  "%.*s%.*s%.1s%s%.1s%s%.1s%s",
128  start - wordlist, wordlist,
129  left_end - start, start,
130  (left_end - start && subst1 && *subst1) ? delims : "",
131  (subst1 && *subst1) ? subst1 : "",
132  ((left_end - start || (subst1 && *subst1)) && subst2 && *subst2) ? delims : "",
133  (subst2 && *subst2) ? subst2 : "",
134  ((left_end - start || (subst1 && *subst1) || (subst2 && *subst2)) && *itr) ? delims : "",
135  itr
136  );
137 
138  if (!lumiera_config_set (key, lumiera_tmpbuf_snprintf (SIZE_MAX, "=%s", str)))
139  str = NULL;
140 
141  break;
142  }
143  }
144  }
145  }
146 
147  return str;
148 }
149 
150 
151 const char*
152 lumiera_config_wordlist_add (const char* key, const char* value, const char* delims)
153 {
154  const char* wordlist = NULL;
155 
156  if (value && *value)
157  {
158  LUMIERA_MUTEX_SECTION (mutex_sync, &lumiera_global_config->lock)
159  {
160  if (lumiera_config_get (key, &wordlist))
161  {
162  size_t vlen = strlen (value);
163  size_t len;
164 
165  for (const char* itr = wordlist; *itr; itr += len)
166  {
167  itr += strspn (itr, delims);
168  len = strcspn (itr, delims);
169 
170  if (len == vlen && !strncmp (itr, value, vlen))
171  goto end;
172  }
173 
174  wordlist = lumiera_tmpbuf_snprintf (SIZE_MAX, "%s%.1s%s",
175  wordlist,
176  wordlist[strspn (wordlist, delims)] ? delims : "",
177  value);
178 
179  if (!lumiera_config_set (key, lumiera_tmpbuf_snprintf (SIZE_MAX, "=%s", wordlist)))
180  wordlist = NULL;
181  }
182  end:;
183  }
184  }
185 
186  return wordlist;
187 }
188 
189 
190 #if 0
191 
192 const char*
193 lumiera_config_wordlist_remove_nth (const char* key, unsigned nth)
194 {
195 }
196 
197 
198 LumieraConfigitem
199 lumiera_config_wordlist_append (const char* key, const char** value, unsigned nth)
200 {
201 }
202 
203 
204 LumieraConfigitem
205 lumiera_config_wordlist_preprend (const char* key, const char** value, unsigned nth)
206 {
207 }
208 #endif
209 
210 
211 
212 /*
213 // Local Variables:
214 // mode: C
215 // c-file-style: "gnu"
216 // indent-tabs-mode: nil
217 // End:
218 */
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:111
Interface for a lumiera configuration system (draft).
#define LUMIERA_MUTEX_SECTION(nobugflag, mtx)
Mutual exclusive section.
Definition: mutex.h:41
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:245
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:232
char * lumiera_tmpbuf_snprintf(size_t size, const char *fmt,...)
Construct a string in a tmpbuf.
Definition: tmpbuf.c:125