switch.c \
timeout.c \
tmpl.c \
- variable.c \
xlat.c \
xlat_alloc.c \
xlat_builtin.c \
unlang_edit_init();
unlang_timeout_init();
unlang_limit_init();
- unlang_variable_init();
instance_count++;
#include "edit_priv.h"
#include "timeout_priv.h"
#include "limit_priv.h"
-#include "variable_priv.h"
#define UNLANG_IGNORE ((unlang_t *) -1)
case UNLANG_TYPE_RETURN:
case UNLANG_TYPE_TMPL:
case UNLANG_TYPE_XLAT:
- case UNLANG_TYPE_VARIABLE:
DEBUG("%.*s%s", depth, unlang_spaces, c->debug_name);
break;
}
* Definitions which are adjacent to one another are automatically merged
* into one larger variable definition.
*/
-static unlang_t *compile_variable(unlang_t *parent, unlang_compile_t *unlang_ctx, unlang_t **prev, CONF_PAIR *cp, tmpl_rules_t *t_rules)
+static unlang_t *compile_variable(unlang_t *parent, unlang_compile_t *unlang_ctx, CONF_PAIR *cp, tmpl_rules_t *t_rules)
{
- unlang_variable_t *var, *var_free;
- unlang_t *c = NULL, *out = UNLANG_IGNORE;
+ unlang_variable_t *var;
fr_type_t type;
char const *attr, *value;
fr_dict_attr_t const *da;
+ unlang_group_t *group;
fr_dict_attr_flags_t flags = {
.internal = true,
.local = true,
};
- c = *prev;
- var = var_free = NULL;
-
- if (c && (c->type == UNLANG_TYPE_VARIABLE)) {
- var = unlang_generic_to_variable(c);
+ /*
+ * The variables exist in the parent block.
+ */
+ group = unlang_generic_to_group(parent);
+ if (group->variables) {
+ var = group->variables;
} else {
- var = talloc_zero(parent, unlang_variable_t);
+ group->variables = var = talloc_zero(parent, unlang_variable_t);
if (!var) return NULL;
- c = out = unlang_variable_to_generic(var);
- c->parent = parent;
- c->next = NULL;
- c->name = cf_pair_value(cp);
- c->debug_name = c->name;
- c->type = UNLANG_TYPE_VARIABLE;
- c->ci = CF_TO_ITEM(cp);
-
- var_free = var;
-
var->dict = fr_dict_protocol_alloc(unlang_ctx->rules->attr.dict_def);
if (!var->dict) {
talloc_free(var);
type = fr_table_value_by_str(fr_type_table, attr, FR_TYPE_NULL);
if (type == FR_TYPE_NULL) {
invalid_type:
- talloc_free(var_free);
cf_log_err(cp, "Invalid data type '%s'", attr);
return NULL;
}
*/
da = fr_dict_attr_by_name(NULL, fr_dict_root(t_rules->parent->attr.dict_def), value);
if (da) {
- talloc_free(var_free);
cf_log_err(cp, "Local variable '%s' duplicates a dictionary attribute.", value);
return NULL;
}
*/
da = fr_dict_attr_by_name(NULL, var->root, value);
if (da) {
- talloc_free(var_free);
cf_log_err(cp, "Duplicate variable name '%s'.", value);
return NULL;
}
if (fr_dict_attr_add(var->dict, var->root, value, var->max_attr, type, &flags) < 0) {
- talloc_free(var_free);
cf_log_err(cp, "Failed adding variable '%s'", value);
return NULL;
}
var->max_attr++;
- *prev = c;
-
- return out;
+ return UNLANG_IGNORE;
}
/*
bool was_if = false;
char const *skip_else = NULL;
unlang_t *edit = NULL;
- unlang_t *var = NULL;
unlang_compile_t *unlang_ctx;
unlang_compile_t unlang_ctx2;
tmpl_rules_t t_rules;
* Variable definition.
*/
if (cf_pair_operator(cp) == T_OP_CMP_TRUE) {
- single = compile_variable(c, unlang_ctx, &var, cp, &t_rules);
+ single = compile_variable(c, unlang_ctx, cp, &t_rules);
if (!single) {
talloc_free(c);
return NULL;
goto add_child;
}
- var = NULL;
-
/*
* Bare "foo = bar" is disallowed.
*/
UNLANG_TYPE_XLAT, //!< Represents one level of an xlat expansion.
UNLANG_TYPE_TMPL, //!< asynchronously expand a tmpl_t
UNLANG_TYPE_EDIT, //!< edit VPs in place. After 20 years!
- UNLANG_TYPE_VARIABLE, //!< local variables
UNLANG_TYPE_MAX
} unlang_type_t;
char const *type_name; //!< Talloc type name.
} unlang_ext_t;
+typedef struct {
+ fr_dict_t *dict; //!< our dictionary
+ fr_dict_attr_t const *root; //!< the root of our dictionary
+ int max_attr; //!< 1..N local attributes have been defined
+} unlang_variable_t;
+
/** Generic representation of a grouping
*
* Can represent IF statements, maps, update sections etc...
unlang_t **tail; //!< pointer to the tail which gets updated
CONF_SECTION *cs;
int num_children;
+
+ unlang_variable_t *variables; //!< rarely used, so we don't usually need it
} unlang_group_t;
/** A naked xlat
void unlang_limit_init(void);
-void unlang_variable_init(void);
/** @} */
#ifdef __cplusplus
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-/**
- * $Id$
- *
- * @file unlang/variable.c
- * @brief Unlang local "variable"s
- *
- * @copyright 2022 Network RADIUS SAS (legal@networkradius.com)
- */
-RCSID("$Id$")
-
-#include "group_priv.h"
-#include "variable_priv.h"
-
-static unlang_action_t unlang_variable(UNUSED rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
-{
- unlang_variable_t *var;
-
- var = unlang_generic_to_variable(frame->instruction);
-
- RDEBUG3("Creating varible max %d", var->max_attr);
-
- return UNLANG_ACTION_CALCULATE_RESULT;
-}
-
-
-void unlang_variable_init(void)
-{
- unlang_register(UNLANG_TYPE_VARIABLE,
- &(unlang_op_t){
- .name = "variable",
- .interpret = unlang_variable,
- });
-}
+++ /dev/null
-#pragma once
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/**
- * $Id$
- *
- * @file unlang/variable_priv.h
- *
- * @copyright 2022 Network RADIUS SAS (legal@networkradius.com)
- */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "unlang_priv.h"
-
-typedef struct {
- unlang_t self;
- fr_dict_t *dict;
- fr_dict_attr_t const *root;
- int max_attr;
-} unlang_variable_t;
-
-/** Cast a generic structure to the edit extension
- *
- */
-static inline unlang_variable_t *unlang_generic_to_variable(unlang_t const *p)
-{
- fr_assert(p->type == UNLANG_TYPE_VARIABLE);
- return UNCONST(unlang_variable_t *, talloc_get_type_abort_const(p, unlang_variable_t));
-}
-
-static inline unlang_t *unlang_variable_to_generic(unlang_variable_t const *p)
-{
- return UNCONST(unlang_t *, p);
-}
-
-#ifdef __cplusplus
-}
-#endif