1 // SPDX-License-Identifier: GPL-2.0
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
[]);
19 static void __attribute__((noreturn
)) pperror(const char *format
, ...)
23 fprintf(stderr
, "%s:%d: ", current_file
->name
, yylineno
);
25 vfprintf(stderr
, format
, ap
);
27 fprintf(stderr
, "\n");
33 * Environment variables
35 static LIST_HEAD(env_list
);
40 struct list_head node
;
43 static void env_add(const char *name
, const char *value
)
47 e
= xmalloc(sizeof(*e
));
48 e
->name
= xstrdup(name
);
49 e
->value
= xstrdup(value
);
51 list_add_tail(&e
->node
, &env_list
);
54 static void env_del(struct env
*e
)
62 /* The returned pointer must be freed when done */
63 static char *env_expand(const char *name
)
71 list_for_each_entry(e
, &env_list
, node
) {
72 if (!strcmp(name
, e
->name
))
73 return xstrdup(e
->value
);
81 * We need to remember all referenced environment variables.
82 * They will be written out to include/config/auto.conf.cmd
86 return xstrdup(value
);
89 void env_write_dep(FILE *f
, const char *autoconfig_name
)
93 list_for_each_entry_safe(e
, tmp
, &env_list
, node
) {
94 fprintf(f
, "ifneq \"$(%s)\" \"%s\"\n", e
->name
, e
->value
);
95 fprintf(f
, "%s: FORCE\n", autoconfig_name
);
96 fprintf(f
, "endif\n");
106 unsigned int min_args
;
107 unsigned int max_args
;
108 char *(*func
)(int argc
, char *argv
[]);
111 static char *do_error_if(int argc
, char *argv
[])
113 if (!strcmp(argv
[0], "y"))
114 pperror("%s", argv
[1]);
119 static char *do_filename(int argc
, char *argv
[])
121 return xstrdup(current_file
->name
);
124 static char *do_info(int argc
, char *argv
[])
126 printf("%s\n", argv
[0]);
131 static char *do_lineno(int argc
, char *argv
[])
135 sprintf(buf
, "%d", yylineno
);
140 static char *do_shell(int argc
, char *argv
[])
156 nread
= fread(buf
, 1, sizeof(buf
), p
);
157 if (nread
== sizeof(buf
))
160 /* remove trailing new lines */
161 while (nread
> 0 && buf
[nread
- 1] == '\n')
166 /* replace a new line with a space */
167 for (i
= 0; i
< nread
; i
++) {
172 if (pclose(p
) == -1) {
180 static char *do_warning_if(int argc
, char *argv
[])
182 if (!strcmp(argv
[0], "y"))
183 fprintf(stderr
, "%s:%d: %s\n",
184 current_file
->name
, yylineno
, argv
[1]);
189 static const struct function function_table
[] = {
190 /* Name MIN MAX Function */
191 { "error-if", 2, 2, do_error_if
},
192 { "filename", 0, 0, do_filename
},
193 { "info", 1, 1, do_info
},
194 { "lineno", 0, 0, do_lineno
},
195 { "shell", 1, 1, do_shell
},
196 { "warning-if", 2, 2, do_warning_if
},
199 #define FUNCTION_MAX_ARGS 16
201 static char *function_expand(const char *name
, int argc
, char *argv
[])
203 const struct function
*f
;
206 for (i
= 0; i
< ARRAY_SIZE(function_table
); i
++) {
207 f
= &function_table
[i
];
208 if (strcmp(f
->name
, name
))
211 if (argc
< f
->min_args
)
212 pperror("too few function arguments passed to '%s'",
215 if (argc
> f
->max_args
)
216 pperror("too many function arguments passed to '%s'",
219 return f
->func(argc
, argv
);
226 * Variables (and user-defined functions)
228 static LIST_HEAD(variable_list
);
233 enum variable_flavor flavor
;
235 struct list_head node
;
238 static struct variable
*variable_lookup(const char *name
)
242 list_for_each_entry(v
, &variable_list
, node
) {
243 if (!strcmp(name
, v
->name
))
250 static char *variable_expand(const char *name
, int argc
, char *argv
[])
255 v
= variable_lookup(name
);
259 if (argc
== 0 && v
->exp_count
)
260 pperror("Recursive variable '%s' references itself (eventually)",
263 if (v
->exp_count
> 1000)
264 pperror("Too deep recursive expansion");
268 if (v
->flavor
== VAR_RECURSIVE
)
269 res
= expand_string_with_args(v
->value
, argc
, argv
);
271 res
= xstrdup(v
->value
);
278 void variable_add(const char *name
, const char *value
,
279 enum variable_flavor flavor
)
285 v
= variable_lookup(name
);
287 /* For defined variables, += inherits the existing flavor */
288 if (flavor
== VAR_APPEND
) {
295 /* For undefined variables, += assumes the recursive flavor */
296 if (flavor
== VAR_APPEND
)
297 flavor
= VAR_RECURSIVE
;
299 v
= xmalloc(sizeof(*v
));
300 v
->name
= xstrdup(name
);
302 list_add_tail(&v
->node
, &variable_list
);
307 if (flavor
== VAR_SIMPLE
)
308 new_value
= expand_string(value
);
310 new_value
= xstrdup(value
);
313 v
->value
= xrealloc(v
->value
,
314 strlen(v
->value
) + strlen(new_value
) + 2);
315 strcat(v
->value
, " ");
316 strcat(v
->value
, new_value
);
319 v
->value
= new_value
;
323 static void variable_del(struct variable
*v
)
331 void variable_all_del(void)
333 struct variable
*v
, *tmp
;
335 list_for_each_entry_safe(v
, tmp
, &variable_list
, node
)
340 * Evaluate a clause with arguments. argc/argv are arguments from the upper
343 * Returned string must be freed when done
345 static char *eval_clause(const char *str
, size_t len
, int argc
, char *argv
[])
347 char *tmp
, *name
, *res
, *endptr
, *prev
, *p
;
349 char *new_argv
[FUNCTION_MAX_ARGS
];
354 tmp
= xstrndup(str
, len
);
357 * If variable name is '1', '2', etc. It is generally an argument
358 * from a user-function call (i.e. local-scope variable). If not
359 * available, then look-up global-scope variables.
361 n
= strtoul(tmp
, &endptr
, 10);
362 if (!*endptr
&& n
> 0 && n
<= argc
) {
363 res
= xstrdup(argv
[n
- 1]);
371 * The function name and arguments are separated by a comma.
372 * For example, if the function call is like this:
375 * The input string for this helper should be:
379 * new_argv[0] = 'foo'
380 * new_argv[1] = '$(x)'
381 * new_argv[2] = '$(y)'
384 if (nest
== 0 && *p
== ',') {
386 if (new_argc
>= FUNCTION_MAX_ARGS
)
387 pperror("too many function arguments");
388 new_argv
[new_argc
++] = prev
;
390 } else if (*p
== '(') {
392 } else if (*p
== ')') {
398 new_argv
[new_argc
++] = prev
;
402 * new_argv[0] represents a function name or a variable name. Put it
403 * into 'name', then shift the rest of the arguments. This simplifies
406 name
= expand_string_with_args(new_argv
[0], argc
, argv
);
408 for (i
= 0; i
< new_argc
; i
++)
409 new_argv
[i
] = expand_string_with_args(new_argv
[i
+ 1],
412 /* Search for variables */
413 res
= variable_expand(name
, new_argc
, new_argv
);
417 /* Look for built-in functions */
418 res
= function_expand(name
, new_argc
, new_argv
);
422 /* Last, try environment variable */
424 res
= env_expand(name
);
431 for (i
= 0; i
< new_argc
; i
++)
441 * Expand a string that follows '$'
443 * For example, if the input string is
444 * ($(FOO)$($(BAR)))$(BAZ)
445 * this helper evaluates
447 * and returns a new string containing the expansion (note that the string is
448 * recursively expanded), also advancing 'str' to point to the next character
449 * after the corresponding closing parenthesis, in this case, *str will be
452 static char *expand_dollar_with_args(const char **str
, int argc
, char *argv
[])
454 const char *p
= *str
;
459 * In Kconfig, variable/function references always start with "$(".
460 * Neither single-letter variables as in $A nor curly braces as in ${CC}
461 * are supported. '$' not followed by '(' loses its special meaning.
473 } else if (*q
== ')') {
481 pperror("unterminated reference to '%s': missing ')'", p
);
483 /* Advance 'str' to after the expanded initial portion of the string */
486 return eval_clause(p
, q
- p
, argc
, argv
);
489 char *expand_dollar(const char **str
)
491 return expand_dollar_with_args(str
, 0, NULL
);
494 static char *__expand_string(const char **str
, bool (*is_end
)(char c
),
495 int argc
, char *argv
[])
498 char *expansion
, *out
;
499 size_t in_len
, out_len
;
511 expansion
= expand_dollar_with_args(&p
, argc
, argv
);
512 out_len
+= in_len
+ strlen(expansion
);
513 out
= xrealloc(out
, out_len
);
514 strncat(out
, in
, in_len
);
515 strcat(out
, expansion
);
529 out
= xrealloc(out
, out_len
);
530 strncat(out
, in
, in_len
);
532 /* Advance 'str' to the end character */
538 static bool is_end_of_str(char c
)
544 * Expand variables and functions in the given string. Undefined variables
545 * expand to an empty string.
546 * The returned string must be freed when done.
548 static char *expand_string_with_args(const char *in
, int argc
, char *argv
[])
550 return __expand_string(&in
, is_end_of_str
, argc
, argv
);
553 char *expand_string(const char *in
)
555 return expand_string_with_args(in
, 0, NULL
);
558 static bool is_end_of_token(char c
)
560 return !(isalnum(c
) || c
== '_' || c
== '-');
564 * Expand variables in a token. The parsing stops when a token separater
565 * (in most cases, it is a whitespace) is encountered. 'str' is updated to
566 * point to the next character.
568 * The returned string must be freed when done.
570 char *expand_one_token(const char **str
)
572 return __expand_string(str
, is_end_of_token
, 0, NULL
);