1 // SPDX-License-Identifier: GPL-2.0-only
3 // Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>
15 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
17 static char *expand_string_with_args(const char *in
, int argc
, char *argv
[]);
18 static char *expand_string(const char *in
);
20 static void __attribute__((noreturn
)) pperror(const char *format
, ...)
24 fprintf(stderr
, "%s:%d: ", current_file
->name
, yylineno
);
26 vfprintf(stderr
, format
, ap
);
28 fprintf(stderr
, "\n");
34 * Environment variables
36 static LIST_HEAD(env_list
);
41 struct list_head node
;
44 static void env_add(const char *name
, const char *value
)
48 e
= xmalloc(sizeof(*e
));
49 e
->name
= xstrdup(name
);
50 e
->value
= xstrdup(value
);
52 list_add_tail(&e
->node
, &env_list
);
55 static void env_del(struct env
*e
)
63 /* The returned pointer must be freed when done */
64 static char *env_expand(const char *name
)
72 list_for_each_entry(e
, &env_list
, node
) {
73 if (!strcmp(name
, e
->name
))
74 return xstrdup(e
->value
);
82 * We need to remember all referenced environment variables.
83 * They will be written out to include/config/auto.conf.cmd
87 return xstrdup(value
);
90 void env_write_dep(FILE *f
, const char *autoconfig_name
)
94 list_for_each_entry_safe(e
, tmp
, &env_list
, node
) {
95 fprintf(f
, "ifneq \"$(%s)\" \"%s\"\n", e
->name
, e
->value
);
96 fprintf(f
, "%s: FORCE\n", autoconfig_name
);
97 fprintf(f
, "endif\n");
107 unsigned int min_args
;
108 unsigned int max_args
;
109 char *(*func
)(int argc
, char *argv
[]);
112 static char *do_error_if(int argc
, char *argv
[])
114 if (!strcmp(argv
[0], "y"))
115 pperror("%s", argv
[1]);
120 static char *do_filename(int argc
, char *argv
[])
122 return xstrdup(current_file
->name
);
125 static char *do_info(int argc
, char *argv
[])
127 printf("%s\n", argv
[0]);
132 static char *do_lineno(int argc
, char *argv
[])
136 sprintf(buf
, "%d", yylineno
);
141 static char *do_shell(int argc
, char *argv
[])
157 nread
= fread(buf
, 1, sizeof(buf
), p
);
158 if (nread
== sizeof(buf
))
161 /* remove trailing new lines */
162 while (nread
> 0 && buf
[nread
- 1] == '\n')
167 /* replace a new line with a space */
168 for (i
= 0; i
< nread
; i
++) {
173 if (pclose(p
) == -1) {
181 static char *do_warning_if(int argc
, char *argv
[])
183 if (!strcmp(argv
[0], "y"))
184 fprintf(stderr
, "%s:%d: %s\n",
185 current_file
->name
, yylineno
, argv
[1]);
190 static const struct function function_table
[] = {
191 /* Name MIN MAX Function */
192 { "error-if", 2, 2, do_error_if
},
193 { "filename", 0, 0, do_filename
},
194 { "info", 1, 1, do_info
},
195 { "lineno", 0, 0, do_lineno
},
196 { "shell", 1, 1, do_shell
},
197 { "warning-if", 2, 2, do_warning_if
},
200 #define FUNCTION_MAX_ARGS 16
202 static char *function_expand(const char *name
, int argc
, char *argv
[])
204 const struct function
*f
;
207 for (i
= 0; i
< ARRAY_SIZE(function_table
); i
++) {
208 f
= &function_table
[i
];
209 if (strcmp(f
->name
, name
))
212 if (argc
< f
->min_args
)
213 pperror("too few function arguments passed to '%s'",
216 if (argc
> f
->max_args
)
217 pperror("too many function arguments passed to '%s'",
220 return f
->func(argc
, argv
);
227 * Variables (and user-defined functions)
229 static LIST_HEAD(variable_list
);
234 enum variable_flavor flavor
;
236 struct list_head node
;
239 static struct variable
*variable_lookup(const char *name
)
243 list_for_each_entry(v
, &variable_list
, node
) {
244 if (!strcmp(name
, v
->name
))
251 static char *variable_expand(const char *name
, int argc
, char *argv
[])
256 v
= variable_lookup(name
);
260 if (argc
== 0 && v
->exp_count
)
261 pperror("Recursive variable '%s' references itself (eventually)",
264 if (v
->exp_count
> 1000)
265 pperror("Too deep recursive expansion");
269 if (v
->flavor
== VAR_RECURSIVE
)
270 res
= expand_string_with_args(v
->value
, argc
, argv
);
272 res
= xstrdup(v
->value
);
279 void variable_add(const char *name
, const char *value
,
280 enum variable_flavor flavor
)
286 v
= variable_lookup(name
);
288 /* For defined variables, += inherits the existing flavor */
289 if (flavor
== VAR_APPEND
) {
296 /* For undefined variables, += assumes the recursive flavor */
297 if (flavor
== VAR_APPEND
)
298 flavor
= VAR_RECURSIVE
;
300 v
= xmalloc(sizeof(*v
));
301 v
->name
= xstrdup(name
);
303 list_add_tail(&v
->node
, &variable_list
);
308 if (flavor
== VAR_SIMPLE
)
309 new_value
= expand_string(value
);
311 new_value
= xstrdup(value
);
314 v
->value
= xrealloc(v
->value
,
315 strlen(v
->value
) + strlen(new_value
) + 2);
316 strcat(v
->value
, " ");
317 strcat(v
->value
, new_value
);
320 v
->value
= new_value
;
324 static void variable_del(struct variable
*v
)
332 void variable_all_del(void)
334 struct variable
*v
, *tmp
;
336 list_for_each_entry_safe(v
, tmp
, &variable_list
, node
)
341 * Evaluate a clause with arguments. argc/argv are arguments from the upper
344 * Returned string must be freed when done
346 static char *eval_clause(const char *str
, size_t len
, int argc
, char *argv
[])
348 char *tmp
, *name
, *res
, *endptr
, *prev
, *p
;
350 char *new_argv
[FUNCTION_MAX_ARGS
];
355 tmp
= xstrndup(str
, len
);
358 * If variable name is '1', '2', etc. It is generally an argument
359 * from a user-function call (i.e. local-scope variable). If not
360 * available, then look-up global-scope variables.
362 n
= strtoul(tmp
, &endptr
, 10);
363 if (!*endptr
&& n
> 0 && n
<= argc
) {
364 res
= xstrdup(argv
[n
- 1]);
372 * The function name and arguments are separated by a comma.
373 * For example, if the function call is like this:
376 * The input string for this helper should be:
380 * new_argv[0] = 'foo'
381 * new_argv[1] = '$(x)'
382 * new_argv[2] = '$(y)'
385 if (nest
== 0 && *p
== ',') {
387 if (new_argc
>= FUNCTION_MAX_ARGS
)
388 pperror("too many function arguments");
389 new_argv
[new_argc
++] = prev
;
391 } else if (*p
== '(') {
393 } else if (*p
== ')') {
400 if (new_argc
>= FUNCTION_MAX_ARGS
)
401 pperror("too many function arguments");
402 new_argv
[new_argc
++] = prev
;
406 * new_argv[0] represents a function name or a variable name. Put it
407 * into 'name', then shift the rest of the arguments. This simplifies
410 name
= expand_string_with_args(new_argv
[0], argc
, argv
);
412 for (i
= 0; i
< new_argc
; i
++)
413 new_argv
[i
] = expand_string_with_args(new_argv
[i
+ 1],
416 /* Search for variables */
417 res
= variable_expand(name
, new_argc
, new_argv
);
421 /* Look for built-in functions */
422 res
= function_expand(name
, new_argc
, new_argv
);
426 /* Last, try environment variable */
428 res
= env_expand(name
);
435 for (i
= 0; i
< new_argc
; i
++)
445 * Expand a string that follows '$'
447 * For example, if the input string is
448 * ($(FOO)$($(BAR)))$(BAZ)
449 * this helper evaluates
451 * and returns a new string containing the expansion (note that the string is
452 * recursively expanded), also advancing 'str' to point to the next character
453 * after the corresponding closing parenthesis, in this case, *str will be
456 static char *expand_dollar_with_args(const char **str
, int argc
, char *argv
[])
458 const char *p
= *str
;
463 * In Kconfig, variable/function references always start with "$(".
464 * Neither single-letter variables as in $A nor curly braces as in ${CC}
465 * are supported. '$' not followed by '(' loses its special meaning.
477 } else if (*q
== ')') {
485 pperror("unterminated reference to '%s': missing ')'", p
);
487 /* Advance 'str' to after the expanded initial portion of the string */
490 return eval_clause(p
, q
- p
, argc
, argv
);
493 char *expand_dollar(const char **str
)
495 return expand_dollar_with_args(str
, 0, NULL
);
498 static char *__expand_string(const char **str
, bool (*is_end
)(char c
),
499 int argc
, char *argv
[])
502 char *expansion
, *out
;
503 size_t in_len
, out_len
;
515 expansion
= expand_dollar_with_args(&p
, argc
, argv
);
516 out_len
+= in_len
+ strlen(expansion
);
517 out
= xrealloc(out
, out_len
);
518 strncat(out
, in
, in_len
);
519 strcat(out
, expansion
);
533 out
= xrealloc(out
, out_len
);
534 strncat(out
, in
, in_len
);
536 /* Advance 'str' to the end character */
542 static bool is_end_of_str(char c
)
548 * Expand variables and functions in the given string. Undefined variables
549 * expand to an empty string.
550 * The returned string must be freed when done.
552 static char *expand_string_with_args(const char *in
, int argc
, char *argv
[])
554 return __expand_string(&in
, is_end_of_str
, argc
, argv
);
557 static char *expand_string(const char *in
)
559 return expand_string_with_args(in
, 0, NULL
);
562 static bool is_end_of_token(char c
)
564 return !(isalnum(c
) || c
== '_' || c
== '-');
568 * Expand variables in a token. The parsing stops when a token separater
569 * (in most cases, it is a whitespace) is encountered. 'str' is updated to
570 * point to the next character.
572 * The returned string must be freed when done.
574 char *expand_one_token(const char **str
)
576 return __expand_string(str
, is_end_of_token
, 0, NULL
);