initial revision
[ucgine.git] / lib / cmd / ucg_cmd_parse_string.c
1 /*
2  * Copyright (c) 2009-2015, Olivier MATZ <zer0@droids-corp.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /*-
29  * Copyright (c) <2010>, Intel Corporation
30  * All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * - Redistributions of source code must retain the above copyright
37  *   notice, this list of conditions and the following disclaimer.
38  *
39  * - Redistributions in binary form must reproduce the above copyright
40  *   notice, this list of conditions and the following disclaimer in
41  *   the documentation and/or other materials provided with the
42  *   distribution.
43  *
44  * - Neither the name of Intel Corporation nor the names of its
45  *   contributors may be used to endorse or promote products derived
46  *   from this software without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
51  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
52  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
53  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
54  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
55  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
57  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
59  * OF THE POSSIBILITY OF SUCH DAMAGE.
60  */
61
62 #include <stdio.h>
63 #include <inttypes.h>
64 #include <ctype.h>
65 #include <string.h>
66
67 #include "ucg_cmd_parse.h"
68 #include "ucg_cmd_parse_string.h"
69
70 #define MULTISTRING_HELP "Mul-choice STRING"
71 #define ANYSTRING_HELP   "Any STRING"
72 #define FIXEDSTRING_HELP "Fixed STRING"
73
74 static unsigned int
75 get_token_len(const char *s)
76 {
77         char c;
78         unsigned int i=0;
79
80         c = s[i];
81         while (c!='#' && c!='\0') {
82                 i++;
83                 c = s[i];
84         }
85         return i;
86 }
87
88 static const char *
89 get_next_token(const char *s)
90 {
91         unsigned int i;
92         i = get_token_len(s);
93         if (s[i] == '#')
94                 return s+i+1;
95         return NULL;
96 }
97
98 static int
99 parse_fixed_string(struct ucg_cmd_tk_string_data *sd,
100         const char *buf, unsigned token_len)
101 {
102         unsigned int conf_token_len;
103         const char *str;
104
105         str = sd->str;
106         for (str = sd->str; str != NULL ; str = get_next_token(str)) {
107
108                 conf_token_len = get_token_len(str);
109
110                 /* if token from config is too big... */
111                 if (conf_token_len >= UCG_STR_TOKEN_SIZE - 1)
112                         continue;
113
114                 /* compare conf token and user token */
115                 if (token_len == conf_token_len &&
116                         strncmp(buf, str, token_len) == 0)
117                         return 0;
118         }
119
120         return -1;
121 }
122
123 static int
124 cmd_parse_string(ucg_cmd_tk_hdr_t *tk,
125         const char *buf, void *res, unsigned ressize)
126 {
127         struct ucg_cmd_tk_string *tk2 =
128                 (struct ucg_cmd_tk_string *)tk;
129         struct ucg_cmd_tk_string_data *sd = &tk2->string_data;;
130         unsigned int token_len;
131
132         if (res && ressize < UCG_STR_TOKEN_SIZE)
133                 return -1;
134
135         token_len = strlen(buf);
136
137         if (token_len >= (UCG_STR_TOKEN_SIZE - 1) || token_len == 0)
138                 return -1;
139
140         /* fixed string */
141         if (sd->str) {
142                 if (parse_fixed_string(sd, buf, token_len) < 0)
143                         return -1;
144         }
145
146         /* we already checked that token_len is < STR_TOKEN_SIZE-1 */
147         if (res)
148                 strcpy(res, buf);
149
150         return 0;
151 }
152
153 static int
154 cmd_complete_string_start(ucg_cmd_tk_hdr_t *tk,
155         __attribute__((unused)) const char *tokstr,
156         void **opaque)
157 {
158         struct ucg_cmd_tk_string *tk2 =
159                 (struct ucg_cmd_tk_string *)tk;
160         struct ucg_cmd_tk_string_data *sd = &tk2->string_data;;
161         const char *str;
162
163         str = sd->str;
164         *opaque = (void *)str;
165         if (str == NULL)
166                 return -1; /* no completion */
167         return 0;
168 }
169
170 static int
171 cmd_complete_string_iterate(ucg_cmd_tk_hdr_t *tk, void **opaque,
172         char *dstbuf, unsigned int size)
173 {
174         const char *s;
175         unsigned int len;
176
177         (void)tk;
178         s = *opaque;
179         if (s == NULL)
180                 return -1;
181         *opaque = (void *)get_next_token(s);
182
183         len = get_token_len(s);
184         if (len > size - 1)
185                 return -1;
186
187         memcpy(dstbuf, s, len);
188         dstbuf[len] = '\0';
189         return 0;
190 }
191
192 static int
193 cmd_help_string(ucg_cmd_tk_hdr_t *tk, char *dstbuf,
194         unsigned int size)
195 {
196         (void)tk;
197         snprintf(dstbuf, size, "<string>");
198         return 0;
199 }
200
201 struct ucg_cmd_tk_ops ucg_cmd_tk_string_ops = {
202         .parse = cmd_parse_string,
203         .complete_start = cmd_complete_string_start,
204         .complete_iterate = cmd_complete_string_iterate,
205         .complete_end = NULL,
206         .help = cmd_help_string,
207 };