#include "libpspp/message.h"
#include "libpspp/str.h"
#include "libpspp/string-array.h"
-#include "libpspp/string-map.h"
+#include "libpspp/stringi-map.h"
#include "libpspp/stringi-set.h"
#include "gl/c-ctype.h"
const struct macro *macro;
struct macro_tokens **args;
enum segmenter_mode segmenter_mode;
+ struct stringi_map *vars;
bool *expand;
};
int nesting_countdown;
const struct macro_expander *me;
const struct macro_expansion_stack *stack;
- struct string_map *vars;
bool *expand;
};
static void
macro_expand (const struct macro_tokens *, int nesting_countdown,
- const struct macro_expander *, struct string_map *vars,
+ const struct macro_expander *,
const struct macro_expansion_stack *stack,
bool *break_, struct macro_tokens *exp);
return 2;
}
- if (ctx->vars)
+ const char *value = stringi_map_find__ (ctx->me->vars,
+ token->string.string,
+ token->string.length);
+ if (value)
{
- const char *value = string_map_find__ (ctx->vars,
- token->string.string,
- token->string.length);
- if (value)
- {
- ds_put_cstr (farg, value);
- return 1;
- }
+ ds_put_cstr (farg, value);
+ return 1;
}
struct parse_macro_function_ctx subctx = {
.nesting_countdown = ctx->nesting_countdown,
.me = ctx->me,
.stack = ctx->stack,
- .vars = ctx->vars,
};
size_t subinput_consumed;
if (expand_macro_function (&subctx, farg, &subinput_consumed))
macro_tokens_from_string__ (&mts, ss_cstr (args.strings[0]),
ctx->me->segmenter_mode, ctx->stack);
struct macro_tokens exp = { .n = 0 };
- macro_expand (&mts, ctx->nesting_countdown - 1, ctx->me, ctx->vars,
+ macro_expand (&mts, ctx->nesting_countdown - 1, ctx->me,
&(struct macro_expansion_stack) {
.name = "!EVAL",
.next = ctx->stack,
int nesting_countdown;
const struct macro_expander *me;
const struct macro_expansion_stack *stack;
- struct string_map *vars;
};
static char *macro_evaluate_or (const struct expr_context *ctx,
.nesting_countdown = ctx->nesting_countdown,
.me = ctx->me,
.stack = ctx->stack,
- .vars = ctx->vars,
};
struct string function_output = DS_EMPTY_INITIALIZER;
size_t function_consumed = parse_function_arg (&fctx, 0, &function_output);
macro_evaluate_expression (const struct macro_token **tokens, size_t n_tokens,
int nesting_countdown,
const struct macro_expander *me,
- const struct macro_expansion_stack *stack,
- struct string_map *vars)
+ const struct macro_expansion_stack *stack)
{
const struct expr_context ctx = {
.nesting_countdown = nesting_countdown,
.me = me,
.stack = stack,
- .vars = vars,
};
return macro_evaluate_or (&ctx, tokens, *tokens + n_tokens);
}
int nesting_countdown,
const struct macro_expander *me,
const struct macro_expansion_stack *stack,
- struct string_map *vars, double *number)
+ double *number)
{
char *s = macro_evaluate_expression (tokens, n_tokens, nesting_countdown,
- me, stack, vars);
+ me, stack);
if (!s)
return false;
macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
int nesting_countdown, const struct macro_expander *me,
const struct macro_expansion_stack *stack,
- struct string_map *vars,
bool *break_, struct macro_tokens *exp)
{
const struct macro_token *p = tokens;
p++;
char *result = macro_evaluate_expression (&p, end - p, nesting_countdown,
- me, stack, vars);
+ me, stack);
if (!result)
return 0;
bool b = strcmp (result, "0");
.mts = CONST_CAST (struct macro_token *, start),
.n = n,
};
- macro_expand (&mts, nesting_countdown, me, vars,
+ macro_expand (&mts, nesting_countdown, me,
&(struct macro_expansion_stack) {
.name = "!IF",
.next = stack,
static size_t
macro_parse_let (const struct macro_token *tokens, size_t n_tokens,
int nesting_countdown, const struct macro_expander *me,
- const struct macro_expansion_stack *stack,
- struct string_map *vars)
+ const struct macro_expansion_stack *stack)
{
const struct macro_token *p = tokens;
const struct macro_token *end = tokens + n_tokens;
p++;
char *value = macro_evaluate_expression (&p, end - p, nesting_countdown,
- me, stack, vars);
+ me, stack);
if (!value)
return 0;
- string_map_replace_nocopy (vars, ss_xstrdup (var_name), value);
+ stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name), value);
return p - tokens;
}
macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
int nesting_countdown, const struct macro_expander *me,
const struct macro_expansion_stack *stack,
- struct string_map *vars, struct macro_tokens *exp)
+ struct macro_tokens *exp)
{
const struct macro_token *p = tokens;
const struct macro_token *end = tokens + n_tokens;
{
p++;
char *list = macro_evaluate_expression (&p, end - p, nesting_countdown,
- me, &next_stack, vars);
+ me, &next_stack);
if (!list)
return 0;
miterate);
break;
}
- string_map_replace_nocopy (vars, ss_xstrdup (var_name),
- ss_xstrdup (items.mts[i].representation));
+ stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name),
+ ss_xstrdup (items.mts[i].representation));
bool break_ = false;
macro_expand (&inner, nesting_countdown,
- me, vars, &next_stack, &break_, exp);
+ me, &next_stack, &break_, exp);
if (break_)
break;
}
p++;
double first;
if (!macro_evaluate_number (&p, end - p, nesting_countdown,
- me, &next_stack, vars, &first))
+ me, &next_stack, &first))
return 0;
if (p >= end || p->token.type != T_MACRO_ID
double last;
if (!macro_evaluate_number (&p, end - p, nesting_countdown,
- me, &next_stack, vars, &last))
+ me, &next_stack, &last))
return 0;
double by = 1.0;
{
p++;
if (!macro_evaluate_number (&p, end - p, nesting_countdown,
- me, &next_stack, vars, &by))
+ me, &next_stack, &by))
return 0;
if (by == 0.0)
char index_s[DBL_BUFSIZE_BOUND];
c_dtoastr (index_s, sizeof index_s, 0, 0, index);
- string_map_replace_nocopy (vars, ss_xstrdup (var_name),
- xstrdup (index_s));
+ stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name),
+ xstrdup (index_s));
bool break_ = false;
macro_expand (&inner, nesting_countdown,
- me, vars, &next_stack, &break_, exp);
+ me, &next_stack, &break_, exp);
if (break_)
break;
}
static void
macro_expand (const struct macro_tokens *mts, int nesting_countdown,
- const struct macro_expander *me, struct string_map *vars,
+ const struct macro_expander *me,
const struct macro_expansion_stack *stack,
bool *break_, struct macro_tokens *exp)
{
return;
}
- struct string_map own_vars = STRING_MAP_INITIALIZER (own_vars);
- if (!vars)
- vars = &own_vars;
-
for (size_t i = 0; i < mts->n && (!break_ || !*break_); i++)
{
const struct macro_token *mt = &mts->mts[i];
const struct macro_tokens *arg = me->args[param - me->macro->params];
if (*me->expand && param->expand_arg)
{
+ struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
struct macro_expander subme = {
.macros = me->macros,
.macro = NULL,
.args = NULL,
.segmenter_mode = me->segmenter_mode,
.expand = me->expand,
+ .vars = &vars,
};
- macro_expand (arg, nesting_countdown, &subme, NULL,
+ macro_expand (arg, nesting_countdown, &subme,
&(struct macro_expansion_stack) {
.name = param->name,
.next = stack,
}, break_, exp);
+ stringi_map_destroy (&vars);
}
else
for (size_t i = 0; i < arg->n; i++)
const struct macro_tokens *arg = me->args[j];
if (*me->expand && param->expand_arg)
{
+ struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
struct macro_expander subme = {
.macros = me->macros,
.macro = NULL,
.args = NULL,
.segmenter_mode = me->segmenter_mode,
.expand = me->expand,
+ .vars = &vars,
};
- macro_expand (arg, nesting_countdown, &subme, NULL,
+ macro_expand (arg, nesting_countdown, &subme,
&(struct macro_expansion_stack) {
.name = "!*",
.next = stack,
}, break_, exp);
+ stringi_map_destroy (&vars);
}
else
for (size_t k = 0; k < arg->n; k++)
size_t n = macro_expand_if (&mts->mts[i], mts->n - i,
nesting_countdown, me, stack,
- vars, break_, exp);
+ break_, exp);
if (n > 0)
{
i += n - 1;
}
}
- if (token->type == T_MACRO_ID && vars)
+ if (token->type == T_MACRO_ID)
{
- const char *value = string_map_find__ (vars, token->string.string,
- token->string.length);
+ const char *value = stringi_map_find__ (me->vars,
+ token->string.string,
+ token->string.length);
if (value)
{
macro_tokens_from_string__ (exp, ss_cstr (value),
if (retval > 0)
{
i += retval - 1;
+ struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
struct macro_expander subme = {
.macros = submc->macros,
.macro = submc->macro,
.args = submc->args,
.segmenter_mode = me->segmenter_mode,
.expand = me->expand,
+ .vars = &vars,
};
macro_expand (&submc->macro->body, nesting_countdown - 1,
- &subme, NULL, &(struct macro_expansion_stack) {
+ &subme, &(struct macro_expansion_stack) {
.name = submc->macro->name,
.file_name = submc->macro->file_name,
.first_line = submc->macro->first_line,
.next = stack,
}, break_, exp);
macro_call_destroy (submc);
+ stringi_map_destroy (&vars);
continue;
}
.nesting_countdown = nesting_countdown,
.me = me,
.stack = stack,
- .vars = vars,
};
struct string function_output = DS_EMPTY_INITIALIZER;
size_t function_consumed;
size_t n = macro_parse_let (&mts->mts[i], mts->n - i,
nesting_countdown,
- me, stack, vars);
+ me, stack);
if (n > 0)
{
i += n - 1;
}
n = macro_expand_do (&mts->mts[i], mts->n - i, nesting_countdown, me,
- stack, vars, exp);
+ stack, exp);
if (n > 0)
{
i += n - 1;
else
macro_tokens_add (exp, mt);
}
- if (vars == &own_vars)
- string_map_destroy (&own_vars);
}
void
assert (mc->state == MC_FINISHED);
bool expand = true;
+ struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
struct macro_expander me = {
.macros = mc->macros,
.macro = mc->macro,
.args = mc->args,
.segmenter_mode = segmenter_mode,
.expand = &expand,
+ .vars = &vars,
};
struct macro_expansion_stack stack = {
.last_line = mc->macro->last_line,
};
macro_expand (&mc->macro->body, settings_get_mnest (),
- &me, NULL, &stack, NULL, exp);
+ &me, &stack, NULL, exp);
+
+ stringi_map_destroy (&vars);
}