Browse code

cfg framework: cfg_select() and cfg_reset() added

cfg_select("group_name", "var_name") can be used to move a group
handle to a specifig group instance in the script. Evey variable
access within that group will be made from the new group instance
until the handle is reset, practically until the end of the script
unless cfg_reset("group_name") is explicitely called.
This is true both for custom, module, and core variables, i.e. every
configuration group can have multiple set of values.

Miklos Tirpak authored on 04/10/2010 13:35:59
Showing 5 changed files
... ...
@@ -93,6 +93,7 @@
93 93
 #endif
94 94
 #include "switch.h"
95 95
 #include "events.h"
96
+#include "cfg/cfg_struct.h"
96 97
 
97 98
 #include <sys/types.h>
98 99
 #include <sys/socket.h>
... ...
@@ -1463,6 +1464,40 @@ match_cleanup:
1463 1464
 			msg->rpl_send_flags.f|= SND_F_CON_CLOSE;
1464 1465
 			ret=1; /* continue processing */
1465 1466
 			break;
1467
+		case CFG_SELECT_T:
1468
+			if (a->val[0].type != CFG_GROUP_ST) {
1469
+				BUG("unsupported parameter in CFG_SELECT_T: %d\n",
1470
+						a->val[0].type);
1471
+				ret=-1;
1472
+				goto error;
1473
+			}
1474
+			switch(a->val[1].type) {
1475
+				case NUMBER_ST:
1476
+					v=(int)a->val[1].u.number;
1477
+					break;
1478
+				case RVE_ST:
1479
+					if (rval_expr_eval_int(h, msg, &v, (struct rval_expr*)a->val[1].u.data) < 0) {
1480
+						ret=-1;
1481
+						goto error;
1482
+					}
1483
+					break;
1484
+				default:
1485
+					BUG("unsupported group id type in CFG_SELECT_T: %d\n",
1486
+							a->val[1].type);
1487
+					ret=-1;
1488
+					goto error;
1489
+			}
1490
+			ret=(cfg_select((cfg_group_t*)a->val[0].u.data, v) == 0) ? 1 : -1;
1491
+			break;
1492
+		case CFG_RESET_T:
1493
+			if (a->val[0].type != CFG_GROUP_ST) {
1494
+				BUG("unsupported parameter in CFG_RESET_T: %d\n",
1495
+						a->val[0].type);
1496
+				ret=-1;
1497
+				goto error;
1498
+			}
1499
+			ret=(cfg_reset((cfg_group_t*)a->val[0].u.data) == 0) ? 1 : -1;
1500
+			break;
1466 1501
 /*
1467 1502
 		default:
1468 1503
 			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
... ...
@@ -251,6 +251,9 @@ WHILE			"while"
251 251
 
252 252
 INCLUDEFILE     "include_file"
253 253
 
254
+CFG_SELECT	"cfg_select"
255
+CFG_RESET	"cfg_reset"
256
+
254 257
 /*ACTION LVALUES*/
255 258
 URIHOST			"uri:host"
256 259
 URIPORT			"uri:port"
... ...
@@ -635,6 +638,9 @@ SUBST       subst
635 638
 
636 639
 <INITIAL>{INCLUDEFILE}  { count(); BEGIN(INCLF); }
637 640
 
641
+<INITIAL>{CFG_SELECT}	{ count(); yylval.strval=yytext; return CFG_SELECT; }
642
+<INITIAL>{CFG_RESET}	{ count(); yylval.strval=yytext; return CFG_RESET; }
643
+
638 644
 <INITIAL>{URIHOST}	{ count(); yylval.strval=yytext; return URIHOST; }
639 645
 <INITIAL>{URIPORT}	{ count(); yylval.strval=yytext; return URIPORT; }
640 646
 
... ...
@@ -101,7 +101,7 @@
101 101
  * 2010-02-17  added blacklist imask (DST_BLST_*_IMASK) support (andrei)
102 102
 */
103 103
 
104
-%expect 5
104
+%expect 6
105 105
 
106 106
 %{
107 107
 
... ...
@@ -347,6 +347,8 @@ extern char *finame;
347 347
 %token CASE
348 348
 %token DEFAULT
349 349
 %token WHILE
350
+%token CFG_SELECT
351
+%token CFG_RESET
350 352
 %token URIHOST
351 353
 %token URIPORT
352 354
 %token MAX_LEN
... ...
@@ -3259,6 +3261,19 @@ cmd:
3259 3261
 	| SET_RPL_CLOSE	{
3260 3262
 		$$=mk_action(SET_RPL_CLOSE_T, 0); set_cfg_pos($$);
3261 3263
 	}
3264
+	| CFG_SELECT LPAREN STRING COMMA NUMBER RPAREN {
3265
+		$$=mk_action(CFG_SELECT_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$);
3266
+	}
3267
+	| CFG_SELECT LPAREN STRING COMMA rval_expr RPAREN {
3268
+		$$=mk_action(CFG_SELECT_T, 2, STRING_ST, $3, RVE_ST, $5); set_cfg_pos($$);
3269
+	}
3270
+	| CFG_SELECT error { $$=0; yyerror("missing '(' or ')' ?"); }
3271
+	| CFG_SELECT LPAREN error RPAREN { $$=0; yyerror("bad arguments, string and number expected"); }
3272
+	| CFG_RESET LPAREN STRING RPAREN {
3273
+		$$=mk_action(CFG_RESET_T, 1, STRING_ST, $3); set_cfg_pos($$);
3274
+	}
3275
+	| CFG_RESET error { $$=0; yyerror("missing '(' or ')' ?"); }
3276
+	| CFG_RESET LPAREN error RPAREN { $$=0; yyerror("bad arguments, string expected"); }
3262 3277
 	| ID {mod_func_action = mk_action(MODULE0_T, 2, MODEXP_ST, NULL, NUMBER_ST,
3263 3278
 			0); } LPAREN func_params RPAREN	{
3264 3279
 		mod_func_action->val[0].u.data =
... ...
@@ -94,6 +94,7 @@
94 94
 #include "ut.h"
95 95
 #include "rvalue.h"
96 96
 #include "switch.h"
97
+#include "cfg/cfg_struct.h"
97 98
 
98 99
 #define RT_HASH_SIZE	8 /* route names hash */
99 100
 
... ...
@@ -1149,6 +1150,60 @@ int fix_actions(struct action* a)
1149 1150
 					goto error;
1150 1151
 				}
1151 1152
 				break;
1153
+			case CFG_SELECT_T:
1154
+				if (t->val[1].type == RVE_ST) {
1155
+					rve = t->val[1].u.data;
1156
+					if (rve_is_constant(rve)) {
1157
+						/* if expression is constant => evaluate it
1158
+						   as integer and replace it with the corresp.
1159
+						   int */
1160
+						rv = rval_expr_eval(0, 0, rve);
1161
+						if (rv == 0 ||
1162
+								rval_get_int( 0, 0, &i, rv, 0) < 0 ) {
1163
+							ERR("failed to fix constant rve");
1164
+							if (rv) rval_destroy(rv);
1165
+							ret = E_BUG;
1166
+							goto error;
1167
+						}
1168
+						rval_destroy(rv);
1169
+						rve_destroy(rve);
1170
+						t->val[1].type = NUMBER_ST;
1171
+						t->val[1].u.number = i;
1172
+					} else {
1173
+						/* expression is not constant => fixup &
1174
+						   optimize it */
1175
+						if ((ret=fix_rval_expr(rve))
1176
+								< 0) {
1177
+							ERR("rve fixup failed\n");
1178
+							ret = E_BUG;
1179
+							goto error;
1180
+						}
1181
+					}
1182
+				} else if (t->val[1].type != NUMBER_ST) {
1183
+					BUG("invalid subtype %d for cfg_select()\n",
1184
+								t->val[1].type);
1185
+					ret = E_BUG;
1186
+					goto error;
1187
+				}
1188
+
1189
+			case CFG_RESET_T:
1190
+				if (t->val[0].type != STRING_ST) {
1191
+					BUG("invalid subtype %d for cfg_select() or cfg_reset()\n",
1192
+								t->val[0].type);
1193
+					ret = E_BUG;
1194
+					goto error;
1195
+				}
1196
+				tmp_p = (void *)cfg_lookup_group(t->val[0].u.string, strlen(t->val[0].u.string));
1197
+				if (!tmp_p) {
1198
+					ERR("configuration group \"%s\" not found\n",
1199
+						t->val[0].u.string);
1200
+					ret = E_SCRIPT;
1201
+					goto error;
1202
+				}
1203
+				pkg_free(t->val[0].u.string);
1204
+				t->val[0].u.data = tmp_p;
1205
+				t->val[0].type = CFG_GROUP_ST;
1206
+				break;
1152 1207
 			default:
1153 1208
 				/* no fixup required for the rest */
1154 1209
 				break;
... ...
@@ -115,7 +115,9 @@ enum action_type{
115 115
 		SET_FWD_NO_CONNECT_T,
116 116
 		SET_RPL_NO_CONNECT_T,
117 117
 		SET_FWD_CLOSE_T,
118
-		SET_RPL_CLOSE_T
118
+		SET_RPL_CLOSE_T,
119
+		CFG_SELECT_T,
120
+		CFG_RESET_T
119 121
 };
120 122
 /* parameter types for actions or types for expression right operands
121 123
    (WARNING right operands only, not working for left operands) */
... ...
@@ -130,7 +132,8 @@ enum _operand_subtype{
130 132
 		SELECT_UNFIXED_ST,
131 133
 		STRING_RVE_ST /* RVE converted to a string (fparam hack) */,
132 134
 		RVE_FREE_FIXUP_ST /* (str)RVE fixed up by a reversable fixup */,
133
-		FPARAM_DYN_ST /* temporary only (fparam hack) */
135
+		FPARAM_DYN_ST /* temporary only (fparam hack) */,
136
+		CFG_GROUP_ST
134 137
 };
135 138
 
136 139
 typedef enum _expr_l_type expr_l_type;