dpdk: Add support for Mellanox ConnectX-4 devices
[vpp.git] / src / tools / g2 / props.c
1 /* 
2  *------------------------------------------------------------------
3  * Copyright (c) 1997-2016 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <stdio.h>
17 #include <ctype.h>
18 #include <malloc.h>
19 #include <time.h>
20 #include <gtk/gtk.h>
21 #include <string.h>
22
23 static char *sxerox (char *s);
24 void exit(int);
25
26 #define NBUCKETS 97
27
28 typedef struct prop_ {
29     struct prop_ *next;
30     char *name;
31     char *value;
32 } prop_t;
33
34 static prop_t *buckets [NBUCKETS];
35 static int hash_shifts[4] = {24, 16, 8, 0};
36
37 /*
38  * getprop 
39  */
40
41 char *getprop (char *name)
42 {
43     unsigned char *cp;
44     unsigned long hash=0;
45     prop_t *bp;
46     int i=0;
47
48     for (cp = (unsigned char *) name; *cp; cp++)
49         hash ^= (*cp)<<(hash_shifts[(i++)&0x3]);
50
51     bp = buckets [hash%NBUCKETS];
52
53     while (bp && strcmp (bp->name, name)) {
54         bp = bp->next;
55     }
56
57     if (bp == NULL)
58         return (0);
59     else
60         return (bp->value);
61 }
62
63 /*
64  * getprop_default
65  */
66
67 char *getprop_default (char *name, char *def)
68 {
69     char *rv;
70     rv = getprop (name);
71     if (rv)
72         return (rv);
73     else
74         return (def);
75 }
76
77 /*
78  * addprop
79  */
80
81 void addprop (char *name, char *value)
82 {
83     unsigned char *cp;
84     unsigned long hash=0;
85     prop_t **bpp;
86     prop_t *bp;
87     int i=0;
88
89     bp = (prop_t *)g_malloc (sizeof (prop_t));
90
91     bp->next = 0;
92     bp->name = sxerox (name);
93     bp->value = sxerox (value);
94
95     for (cp = (unsigned char *)name; *cp; cp++)
96         hash ^= (*cp)<<(hash_shifts[(i++)&0x3]);
97
98     bpp = &buckets [hash%NBUCKETS];
99
100     if (*bpp == NULL)
101         *bpp = bp;
102     else {
103         bp->next = *bpp;
104         *bpp = bp;
105     }
106 }
107
108 /*
109  * sxerox 
110  */
111
112 static char *sxerox (char *s)
113 {
114     char *rv = (char *) g_malloc (strlen (s) + 1);
115     strcpy (rv, s);
116     return rv;
117 }
118
119 /*
120  * readprops 
121  */
122
123 #define START 0
124 #define READNAME  1
125 #define READVALUE 2
126 #define C_COMMENT 3
127 #define CPP_COMMENT 4
128
129 int readprops (char *filename)
130 {
131     FILE *ifp;
132     unsigned char c;
133     int state=START;
134     int linenum=1;
135     char namebuf [128];
136     char valbuf [512];
137     int i;
138
139     ifp = fopen (filename, "r");
140
141     if (ifp == NULL)
142         return (-1);
143
144     while (1) {
145
146     readchar:
147         c = getc (ifp);
148
149     again:
150         switch (state) {
151         case START:
152             if (feof (ifp)) {
153                 fclose (ifp);
154                 return (0);
155             }
156
157             if (c == ' ' || c == '\t')
158                 goto readchar;
159
160             if (c == '\n') {
161                 linenum++;
162                 goto readchar;
163             }
164             if (isalpha (c) || (c == '_')) {
165                 state = READNAME;
166                 goto again;
167             }
168             if (c == '/') {
169                 c = getc (ifp);
170                 if (c == '/') {
171                     state = CPP_COMMENT;
172                     goto readchar;
173                 } else if (c == '*') {
174                     state = C_COMMENT;
175                     goto readchar;
176                 } else {
177                     fprintf (stderr, "unknown token '/' line %d\n",
178                              linenum);
179                     exit (1);
180                 }
181             }
182             fprintf (stderr, "unknown token '%c' line %d\n",
183                      c, linenum);
184             exit (1);
185             break;
186             
187         case CPP_COMMENT:
188             while (1) {
189                 c = getc (ifp);
190                 if (feof (ifp))
191                     return (0);
192                 if (c == '\n') {
193                     linenum++;
194                     state = START;
195                     goto readchar;
196                 }
197             }
198             break;
199
200         case C_COMMENT:
201             while (1) {
202                 c = getc (ifp);
203                 if (feof (ifp)) {
204                     fprintf (stderr, "unterminated comment, line %d\n",
205                              linenum);
206                     exit (1);
207                 }
208                 if (c == '*') {
209                 staragain:
210                     c = getc (ifp);
211                     if (c == '/') {
212                         state = START;
213                         goto readchar;
214                     }
215                     if (c == '*')
216                         goto staragain;
217                 }
218             }
219             break;
220                     
221         case READNAME:
222             i = 0;
223             namebuf[i++] = c;
224             while (1) {
225                 c = getc (ifp);
226                 if (feof (ifp)) {
227                     fprintf (stderr, "EOF while reading a name, line %d\n",
228                              linenum);
229                     exit (1);
230                 }
231                 if ((!isalnum (c)) && (c != '_')) {
232                     namebuf [i] = 0;
233                     state = READVALUE;
234                     goto again;
235                 }
236                 namebuf [i++] = c;
237             }
238             break;
239
240         case READVALUE:
241             i = 0;
242             while ((c == ' ') || (c == '\t') || (c == '=')) {
243                 c = getc (ifp);
244                 if (feof (ifp)) {
245                     fprintf (stderr, "EOF while reading a value, line %d\n",
246                              linenum);
247                     exit (1);
248                 }
249             }
250             goto firsttime;
251             while (1) {
252                 c = getc (ifp);
253
254             firsttime:
255                 if (c == '\\') {
256                     c = getc (ifp);
257                     if (feof (ifp)) {
258                         fprintf (stderr, "EOF after '\\', line %d\n",
259                                  linenum);
260                         exit (1);
261                     }
262                     valbuf[i++] = c;
263                     continue;
264                 }
265                 if (c == '\n') {
266                     linenum++;
267                     while (valbuf [i-1] == ' ' || valbuf[i-1] == '\t')
268                         i--;
269                     valbuf[i] = 0;
270                     addprop (namebuf, valbuf);
271                     state = START;
272                     goto readchar;
273                 }
274                 valbuf[i++] = c;
275             }
276
277         }
278     }
279 }