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 1463
 			msg->rpl_send_flags.f|= SND_F_CON_CLOSE;
1464 1464
 			ret=1; /* continue processing */
1465 1465
 			break;
1466
+		case CFG_SELECT_T:
1467
+			if (a->val[0].type != CFG_GROUP_ST) {
1468
+				BUG("unsupported parameter in CFG_SELECT_T: %d\n",
1469
+						a->val[0].type);
1470
+				ret=-1;
1471
+				goto error;
1472
+			}
1473
+			switch(a->val[1].type) {
1474
+				case NUMBER_ST:
1475
+					v=(int)a->val[1].u.number;
1476
+					break;
1477
+				case RVE_ST:
1478
+					if (rval_expr_eval_int(h, msg, &v, (struct rval_expr*)a->val[1].u.data) < 0) {
1479
+						ret=-1;
1480
+						goto error;
1481
+					}
1482
+					break;
1483
+				default:
1484
+					BUG("unsupported group id type in CFG_SELECT_T: %d\n",
1485
+							a->val[1].type);
1486
+					ret=-1;
1487
+					goto error;
1488
+			}
1489
+			ret=(cfg_select((cfg_group_t*)a->val[0].u.data, v) == 0) ? 1 : -1;
1490
+			break;
1491
+		case CFG_RESET_T:
1492
+			if (a->val[0].type != CFG_GROUP_ST) {
1493
+				BUG("unsupported parameter in CFG_RESET_T: %d\n",
1494
+						a->val[0].type);
1495
+				ret=-1;
1496
+				goto error;
1497
+			}
1498
+			ret=(cfg_reset((cfg_group_t*)a->val[0].u.data) == 0) ? 1 : -1;
1499
+			break;
1466 1500
 /*
1467 1501
 		default:
1468 1502
 			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 635
 
636 636
 <INITIAL>{INCLUDEFILE}  { count(); BEGIN(INCLF); }
637 637
 
638
+<INITIAL>{CFG_SELECT}	{ count(); yylval.strval=yytext; return CFG_SELECT; }
639
+<INITIAL>{CFG_RESET}	{ count(); yylval.strval=yytext; return CFG_RESET; }
640
+
638 641
 <INITIAL>{URIHOST}	{ count(); yylval.strval=yytext; return URIHOST; }
639 642
 <INITIAL>{URIPORT}	{ count(); yylval.strval=yytext; return URIPORT; }
640 643
 
... ...
@@ -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 3259
 	| SET_RPL_CLOSE	{
3260 3260
 		$$=mk_action(SET_RPL_CLOSE_T, 0); set_cfg_pos($$);
3261 3261
 	}
3262
+	| CFG_SELECT LPAREN STRING COMMA NUMBER RPAREN {
3263
+		$$=mk_action(CFG_SELECT_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$);
3264
+	}
3265
+	| CFG_SELECT LPAREN STRING COMMA rval_expr RPAREN {
3266
+		$$=mk_action(CFG_SELECT_T, 2, STRING_ST, $3, RVE_ST, $5); set_cfg_pos($$);
3267
+	}
3268
+	| CFG_SELECT error { $$=0; yyerror("missing '(' or ')' ?"); }
3269
+	| CFG_SELECT LPAREN error RPAREN { $$=0; yyerror("bad arguments, string and number expected"); }
3270
+	| CFG_RESET LPAREN STRING RPAREN {
3271
+		$$=mk_action(CFG_RESET_T, 1, STRING_ST, $3); set_cfg_pos($$);
3272
+	}
3273
+	| CFG_RESET error { $$=0; yyerror("missing '(' or ')' ?"); }
3274
+	| CFG_RESET LPAREN error RPAREN { $$=0; yyerror("bad arguments, string expected"); }
3262 3275
 	| ID {mod_func_action = mk_action(MODULE0_T, 2, MODEXP_ST, NULL, NUMBER_ST,
3263 3276
 			0); } LPAREN func_params RPAREN	{
3264 3277
 		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 1149
 					goto error;
1150 1150
 				}
1151 1151
 				break;
1152
+			case CFG_SELECT_T:
1153
+				if (t->val[1].type == RVE_ST) {
1154
+					rve = t->val[1].u.data;
1155
+					if (rve_is_constant(rve)) {
1156
+						/* if expression is constant => evaluate it
1157
+						   as integer and replace it with the corresp.
1158
+						   int */
1159
+						rv = rval_expr_eval(0, 0, rve);
1160
+						if (rv == 0 ||
1161
+								rval_get_int( 0, 0, &i, rv, 0) < 0 ) {
1162
+							ERR("failed to fix constant rve");
1163
+							if (rv) rval_destroy(rv);
1164
+							ret = E_BUG;
1165
+							goto error;
1166
+						}
1167
+						rval_destroy(rv);
1168
+						rve_destroy(rve);
1169
+						t->val[1].type = NUMBER_ST;
1170
+						t->val[1].u.number = i;
1171
+					} else {
1172
+						/* expression is not constant => fixup &
1173
+						   optimize it */
1174
+						if ((ret=fix_rval_expr(rve))
1175
+								< 0) {
1176
+							ERR("rve fixup failed\n");
1177
+							ret = E_BUG;
1178
+							goto error;
1179
+						}
1180
+					}
1181
+				} else if (t->val[1].type != NUMBER_ST) {
1182
+					BUG("invalid subtype %d for cfg_select()\n",
1183
+								t->val[1].type);
1184
+					ret = E_BUG;
1185
+					goto error;
1186
+				}
1187
+
1188
+			case CFG_RESET_T:
1189
+				if (t->val[0].type != STRING_ST) {
1190
+					BUG("invalid subtype %d for cfg_select() or cfg_reset()\n",
1191
+								t->val[0].type);
1192
+					ret = E_BUG;
1193
+					goto error;
1194
+				}
1195
+				tmp_p = (void *)cfg_lookup_group(t->val[0].u.string, strlen(t->val[0].u.string));
1196
+				if (!tmp_p) {
1197
+					ERR("configuration group \"%s\" not found\n",
1198
+						t->val[0].u.string);
1199
+					ret = E_SCRIPT;
1200
+					goto error;
1201
+				}
1202
+				pkg_free(t->val[0].u.string);
1203
+				t->val[0].u.data = tmp_p;
1204
+				t->val[0].type = CFG_GROUP_ST;
1205
+				break;
1152 1206
 			default:
1153 1207
 				/* no fixup required for the rest */
1154 1208
 				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 130
 		SELECT_UNFIXED_ST,
131 131
 		STRING_RVE_ST /* RVE converted to a string (fparam hack) */,
132 132
 		RVE_FREE_FIXUP_ST /* (str)RVE fixed up by a reversable fixup */,
133
-		FPARAM_DYN_ST /* temporary only (fparam hack) */
133
+		FPARAM_DYN_ST /* temporary only (fparam hack) */,
134
+		CFG_GROUP_ST
134 135
 };
135 136
 
136 137
 typedef enum _expr_l_type expr_l_type;