summaryrefslogtreecommitdiffstats
path: root/scripts/unifdef.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-14 23:12:18 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-14 23:12:18 +0200
commit45e3e1935e2857c54783291107d33323b3ef33c8 (patch)
tree26a6e3228b52d0f96f6e56e5879ca898fe909592 /scripts/unifdef.c
parentMerge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rol... (diff)
parent.gitignore: ignore *.lzma files (diff)
downloadlinux-45e3e1935e2857c54783291107d33323b3ef33c8.tar.xz
linux-45e3e1935e2857c54783291107d33323b3ef33c8.zip
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next: (53 commits) .gitignore: ignore *.lzma files kbuild: add generic --set-str option to scripts/config kbuild: simplify argument loop in scripts/config kbuild: handle non-existing options in scripts/config kallsyms: generalize text region handling kallsyms: support kernel symbols in Blackfin on-chip memory documentation: make version fix kbuild: fix a compile warning gitignore: Add GNU GLOBAL files to top .gitignore kbuild: fix delay in setlocalversion on readonly source README: fix misleading pointer to the defconf directory vmlinux.lds.h update kernel-doc: cleanup perl script Improve vmlinux.lds.h support for arch specific linker scripts kbuild: fix headers_exports with boolean expression kbuild/headers_check: refine extern check kbuild: fix "Argument list too long" error for "make headers_check", ignore *.patch files Remove bashisms from scripts menu: fix embedded menu presentation ...
Diffstat (limited to 'scripts/unifdef.c')
-rw-r--r--scripts/unifdef.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/scripts/unifdef.c b/scripts/unifdef.c
index 05a31a6c7e1b..30d459fb0709 100644
--- a/scripts/unifdef.c
+++ b/scripts/unifdef.c
@@ -678,8 +678,10 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp)
if (*cp == '!') {
debug("eval%d !", ops - eval_ops);
cp++;
- if (eval_unary(ops, valp, &cp) == LT_IF)
+ if (eval_unary(ops, valp, &cp) == LT_IF) {
+ *cpp = cp;
return (LT_IF);
+ }
*valp = !*valp;
} else if (*cp == '(') {
cp++;
@@ -700,13 +702,16 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp)
return (LT_IF);
cp = skipcomment(cp);
sym = findsym(cp);
- if (sym < 0)
- return (LT_IF);
- *valp = (value[sym] != NULL);
cp = skipsym(cp);
cp = skipcomment(cp);
if (*cp++ != ')')
return (LT_IF);
+ if (sym >= 0)
+ *valp = (value[sym] != NULL);
+ else {
+ *cpp = cp;
+ return (LT_IF);
+ }
keepthis = false;
} else if (!endsym(*cp)) {
debug("eval%d symbol", ops - eval_ops);
@@ -741,11 +746,11 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
const struct op *op;
const char *cp;
int val;
+ Linetype lhs, rhs;
debug("eval%d", ops - eval_ops);
cp = *cpp;
- if (ops->inner(ops+1, valp, &cp) == LT_IF)
- return (LT_IF);
+ lhs = ops->inner(ops+1, valp, &cp);
for (;;) {
cp = skipcomment(cp);
for (op = ops->op; op->str != NULL; op++)
@@ -755,14 +760,32 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
break;
cp += strlen(op->str);
debug("eval%d %s", ops - eval_ops, op->str);
- if (ops->inner(ops+1, &val, &cp) == LT_IF)
- return (LT_IF);
- *valp = op->fn(*valp, val);
+ rhs = ops->inner(ops+1, &val, &cp);
+ if (op->fn == op_and && (lhs == LT_FALSE || rhs == LT_FALSE)) {
+ debug("eval%d: and always false", ops - eval_ops);
+ if (lhs == LT_IF)
+ *valp = val;
+ lhs = LT_FALSE;
+ continue;
+ }
+ if (op->fn == op_or && (lhs == LT_TRUE || rhs == LT_TRUE)) {
+ debug("eval%d: or always true", ops - eval_ops);
+ if (lhs == LT_IF)
+ *valp = val;
+ lhs = LT_TRUE;
+ continue;
+ }
+ if (rhs == LT_IF)
+ lhs = LT_IF;
+ if (lhs != LT_IF)
+ *valp = op->fn(*valp, val);
}
*cpp = cp;
debug("eval%d = %d", ops - eval_ops, *valp);
- return (*valp ? LT_TRUE : LT_FALSE);
+ if (lhs != LT_IF)
+ lhs = (*valp ? LT_TRUE : LT_FALSE);
+ return lhs;
}
/*
@@ -773,12 +796,15 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
static Linetype
ifeval(const char **cpp)
{
+ const char *cp = *cpp;
int ret;
int val;
debug("eval %s", *cpp);
keepthis = killconsts ? false : true;
- ret = eval_table(eval_ops, &val, cpp);
+ ret = eval_table(eval_ops, &val, &cp);
+ if (ret != LT_IF)
+ *cpp = cp;
debug("eval = %d", val);
return (keepthis ? LT_IF : ret);
}