print clustering information for testing
[actl.git] / parse.y
blob7a5fdb47471c8e8f8201de3741299e62eca8ab87
1 /*
2 * Copyright (c) 2016 Mohamed Aslan <maslan@sce.carleton.ca>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <stdarg.h>
21 #include <string.h>
22 #include <err.h>
23 #include <errno.h>
24 #include <sys/queue.h>
26 #include "conf.h"
28 /* types */
29 SIMPLEQ_HEAD(list, list_item);
30 struct list_item {
31 char *val;
32 SIMPLEQ_ENTRY(list_item) next;
35 /* lex vars */
36 extern FILE *yyin;
37 extern int yylineno;
38 extern int yylex(void);
39 /* global vars */
40 int yyerror(const char *, ...);
41 static ofp_fptr check_ofp_version(const char *);
42 static char *filename;
43 static struct config *conf;
46 %union {
47 int i;
48 char *s;
49 struct list *l;
52 %token ID
53 %token LISTEN ON
54 %token CONTROLLER
55 %token IP PORT
56 %token REPLICAS
57 %token OPENFLOW VERSION
58 %token APPLICATION
59 %token ADAPT EVERY SEC MIN
60 %token LEARN FOR
61 %token LOG TO
62 %token COMMA LCBRACKET RCBRACKET
64 %token<i> BOOL
65 %token<i> NUMBER
66 %token<s> VAR
67 %token<s> STRING
69 %token<s> IPADDR
71 %type<l> str_list
72 %type<l> param_list
76 main :
77 | main id
78 | main listen
79 | main controller
80 | main replicas
81 | main openflow
82 | main application
83 | main adapt
84 | main learn
85 | main log
88 id : ID STRING {
89 conf->c_nodeid = strdup($2);
93 listen : LISTEN ON PORT NUMBER {
94 conf->c_co_port = $4;
98 controller : CONTROLLER STRING IP STRING PORT NUMBER {
99 //printf("CONTROLLER: %s, ip addr=%s, port=%d\n", $2, $4, $6);
101 | CONTROLLER STRING IP STRING {
102 //printf("CONTROLLER: %s, ip addr=%s\n", $2, $4);
106 replicas : REPLICAS NUMBER {
107 conf->c_nreplicas = $2;
111 openflow : OPENFLOW VERSION STRING {
112 if ((conf->c_ofp = check_ofp_version($3)) == NULL) {
113 yyerror("OpenFlow version '%s' not supported.", $3);
114 YYABORT;
116 conf->c_ofp_verstr = strdup($3);
118 | OPENFLOW LISTEN ON PORT NUMBER {
119 conf->c_sw_port = $5;
123 str_list : STRING {
124 struct list_item *s = (struct list *)malloc(sizeof(struct list));
126 s->val = strdup($1);
127 SIMPLEQ_INIT($$);
128 SIMPLEQ_INSERT_TAIL($$, s, next);
130 | str_list COMMA STRING {
131 struct list_item *s = (struct list *)malloc(sizeof(struct list));
133 s->val = strdup($3);
134 SIMPLEQ_INSERT_TAIL($1, s, next);
138 param_list : VAR STRING {
139 struct list_item *p, *q;
141 p = (struct list *)malloc(sizeof(struct list));
142 q = (struct list *)malloc(sizeof(struct list));
143 asprintf(&p->val, "--%s", $1);
144 q->val = strdup($2);
145 SIMPLEQ_INIT($$);
146 SIMPLEQ_INSERT_TAIL($$, p, next);
147 SIMPLEQ_INSERT_TAIL($$, q, next);
149 | param_list COMMA VAR STRING {
150 struct list_item *p, *q;
152 p = (struct list *)malloc(sizeof(struct list));
153 q = (struct list *)malloc(sizeof(struct list));
154 asprintf(&p->val, "--%s", $3);
155 q->val = strdup($4);
156 SIMPLEQ_INSERT_TAIL($1, p, next);
157 SIMPLEQ_INSERT_TAIL($1, q, next);
159 | param_list COMMA VAR LCBRACKET str_list RCBRACKET {
160 struct list_item *p, *q;
162 while (!SIMPLEQ_EMPTY($5)) {
163 p = (struct list *)malloc(sizeof(struct list));
164 asprintf(&p->val, "--%s", $3);
165 SIMPLEQ_INSERT_TAIL($1, p, next);
166 q = SIMPLEQ_FIRST($5);
167 SIMPLEQ_REMOVE_HEAD($5, next);
168 SIMPLEQ_INSERT_TAIL($1, q, next);
173 application : APPLICATION STRING {
174 conf->c_app_name = strdup($2);
176 | APPLICATION STRING LCBRACKET param_list RCBRACKET {
177 int i = 0;
178 int argc = 0;
179 char **argv;
180 struct list_item *p;
182 conf->c_app_name = strdup($2);
183 SIMPLEQ_FOREACH(p, $4, next)
184 ++argc;
185 ++argc;
186 argv = (char **)reallocarray(NULL, argc, sizeof(char *));
187 argv[0] = strdup($2);
188 while (!SIMPLEQ_EMPTY($4)) {
189 p = SIMPLEQ_FIRST($4);
190 argv[++i] = p->val;
191 SIMPLEQ_REMOVE_HEAD($4, next);
192 free(p);
194 conf->c_app_argc = argc;
195 conf->c_app_argv = argv;
199 adapt : ADAPT EVERY NUMBER SEC {
200 if ($3 < 1) {
201 yyerror("adaptation time must be > 1.");
202 YYABORT;
204 conf->c_atime = $3;
206 | ADAPT EVERY NUMBER MIN {
207 if ($3 < 1) {
208 yyerror("adaptation time must be > 1.");
209 YYABORT;
211 conf->c_atime = $3 * 60;
215 learn : LEARN FOR NUMBER SEC {
216 if ($3 < 30) {
217 yyerror("learning time must be >= 30 sec.");
218 YYABORT;
220 conf->c_ltime = $3;
222 | LEARN FOR NUMBER MIN {
223 if ($3 < 1) {
224 yyerror("use you may use seconds for learning time.");
225 YYABORT;
227 conf->c_ltime = $3 * 60;
231 log : LOG TO STRING {
232 conf->c_logfile = strdup($3);
237 static ofp_fptr
238 check_ofp_version(const char *ver)
240 int i;
242 for (i = 0 ; i < N_OFP_VERS ; i++)
243 if (!strcmp(ver, ofp_vers[i].ver))
244 return ofp_vers[i].func;
245 return NULL;
249 yyerror(const char *fmt, ...)
251 va_list ap;
253 va_start(ap, fmt);
254 fprintf(stdout, "%s:%d: ", filename, yylineno);
255 vfprintf(stdout, fmt, ap);
256 fprintf(stdout, "\n");
257 va_end(ap);
259 return 0;
263 parse_config(struct config *c, const char *file)
265 int ret;
267 if (c == NULL)
268 errx(1, "parse_config");
269 if ((yyin = fopen(file, "r")) == NULL) {
270 errx(1, "failed to load config file");
272 filename = strdup(file);
273 conf = c;
274 conf->c_app_name = NULL;
275 conf->c_logfile = NULL;
276 ret = yyparse();
277 fclose(yyin);
279 return ret;