1 /* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
4 * We are making the OpenFlow specification and associated documentation
5 * (Software) available for public use and benefit with the expectation
6 * that others will use, modify and enhance the Software and contribute
7 * those enhancements back to the community. However, since we would
8 * like to make the Software available for broadest use, with as few
9 * restrictions as possible permission is hereby granted, free of
10 * charge, to any person obtaining a copy of this Software to deal in
11 * the Software under the copyrights without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sublicense, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 * The name and trademarks of copyright holder(s) may NOT be used in
30 * advertising or publicity pertaining to the Software or any
31 * derivatives without specific, written prior permission.
40 #include "dynamic-string.h"
43 #define THIS_MODULE VLM_svec
47 svec_init(struct svec *svec)
55 svec_destroy(struct svec *svec)
62 svec_clear(struct svec *svec)
66 for (i = 0; i < svec->n; i++) {
73 svec_add(struct svec *svec, const char *name)
75 svec_add_nocopy(svec, xstrdup(name));
79 svec_expand(struct svec *svec)
81 if (svec->n >= svec->allocated) {
82 svec->names = x2nrealloc(svec->names, &svec->allocated,
88 svec_add_nocopy(struct svec *svec, char *name)
91 svec->names[svec->n++] = name;
95 svec_append(struct svec *svec, const struct svec *other)
98 for (i = 0; i < other->n; i++) {
99 svec_add(svec, other->names[i]);
104 svec_terminate(struct svec *svec)
107 svec->names[svec->n] = NULL;
111 compare_strings(const void *a_, const void *b_)
115 return strcmp(*a, *b);
119 svec_sort(struct svec *svec)
121 qsort(svec->names, svec->n, sizeof *svec->names, compare_strings);
125 svec_unique(struct svec *svec)
127 assert(svec_is_sorted(svec));
129 /* This algorithm is lazy and sub-optimal, but it's "obviously correct"
130 * and asymptotically optimal . */
135 svec_add(&tmp, svec->names[0]);
136 for (i = 1; i < svec->n; i++) {
137 if (strcmp(svec->names[i - 1], svec->names[i])) {
138 svec_add(&tmp, svec->names[i]);
141 svec_swap(&tmp, svec);
147 svec_diff(const struct svec *a, const struct svec *b,
148 struct svec *a_only, struct svec *both, struct svec *b_only)
152 assert(svec_is_sorted(a));
153 assert(svec_is_sorted(b));
163 for (i = j = 0; i < a->n && j < b->n; ) {
164 int cmp = strcmp(a->names[i], b->names[j]);
167 svec_add(a_only, a->names[i]);
170 } else if (cmp > 0) {
172 svec_add(b_only, b->names[j]);
177 svec_add(both, a->names[i]);
184 for (; i < a->n; i++) {
185 svec_add(a_only, a->names[i]);
189 for (; j < b->n; j++) {
190 svec_add(b_only, b->names[j]);
196 svec_contains(const struct svec *svec, const char *name)
198 assert(svec_is_sorted(svec));
199 return bsearch(&name, svec->names, svec->n, sizeof *svec->names,
200 compare_strings) != NULL;
204 svec_is_sorted(const struct svec *svec)
208 for (i = 1; i < svec->n; i++) {
209 if (strcmp(svec->names[i - 1], svec->names[i]) > 0) {
217 svec_swap(struct svec *a, struct svec *b)
219 struct svec tmp = *a;
225 svec_print(const struct svec *svec, const char *title)
229 printf("%s:\n", title);
230 for (i = 0; i < svec->n; i++) {
231 printf("\"%s\"\n", svec->names[i]);
235 /* Breaks 'words' into words at white space, respecting shell-like quoting
236 * conventions, and appends the words to 'svec'. */
238 svec_parse_words(struct svec *svec, const char *words)
240 struct ds word = DS_EMPTY_INITIALIZER;
243 for (p = words; *p != '\0'; p = q) {
246 while (isspace((unsigned char) *p)) {
254 for (q = p; *q != '\0'; q++) {
257 } else if (*q == '\'' || *q == '"') {
259 } else if (*q == '\\' && (!quote || quote == '"')) {
262 VLOG_WARN("%s: ends in trailing backslash", words);
265 ds_put_char(&word, *q);
266 } else if (isspace((unsigned char) *q) && !quote) {
270 ds_put_char(&word, *q);
273 svec_add(svec, ds_cstr(&word));
275 VLOG_WARN("%s: word ends inside quoted string", words);
282 svec_equal(const struct svec *a, const struct svec *b)
289 for (i = 0; i < a->n; i++) {
290 if (strcmp(a->names[i], b->names[i])) {