pstate->p = NULL;
}
+/* Special optimization: If the previous program was also a literal, reuse it
+ instead of creating a new program.
+ */
+static void create_literal(VAR_EXPAND_PARSER_STYPE *pstate,
+ const char *value)
+{
+ union var_expand_parameter_value ep_value = {
+ .str = value
+ };
+ if (pstate->pp != NULL && pstate->pp->only_literal) {
+ struct var_expand_parameter *param =
+ (struct var_expand_parameter *)pstate->pp->first->params;
+ /* just put it as extra value */
+ param->value.str = p_strconcat(pstate->plist->pool,
+ param->value.str, value, NULL);
+ return;
+ }
+ push_argument(pstate, VAR_EXPAND_PARAMETER_VALUE_TYPE_STRING, &ep_value);
+ push_function(pstate, "literal");
+ pstate->p->only_literal = TRUE;
+}
+
static union var_expand_parameter_value tmp_value;
%}
| expression_list expression { push_new_program(state); }
;
-expression: VALUE { i_zero(&tmp_value); tmp_value.str = str_c($1); push_argument(state, VAR_EXPAND_PARAMETER_VALUE_TYPE_STRING, &tmp_value); push_function(state, "literal"); state->p->only_literal = TRUE;}
- | OCBRACE filter_list CCBRACE
- | PERC { i_zero(&tmp_value); tmp_value.str = "%"; push_argument(state, VAR_EXPAND_PARAMETER_VALUE_TYPE_STRING, &tmp_value); push_function(state, "literal"); state->p->only_literal = TRUE; }
+expression: VALUE { create_literal(state, str_c($1)); }
+ | OCBRACE filter_list CCBRACE
+ | PERC { create_literal(state, "%"); }
| error { return -1; }
;