summaryrefslogtreecommitdiff
path: root/shell/match.h
diff options
context:
space:
mode:
authorDenys Vlasenko2010-09-04 21:21:07 +0200
committerDenys Vlasenko2010-09-04 21:21:07 +0200
commit701e127f7d892909a58c6f3333e23588ccef9e22 (patch)
tree9d756fca6a1ef496dbf02529e090f2f711a6c261 /shell/match.h
parente298ce69baef029f3951dd1d5ed50fdbc6c55c80 (diff)
downloadbusybox-701e127f7d892909a58c6f3333e23588ccef9e22.zip
busybox-701e127f7d892909a58c6f3333e23588ccef9e22.tar.gz
hush: optimize #[#] and %[%] for speed. size -2 bytes.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'shell/match.h')
-rw-r--r--shell/match.h29
1 files changed, 15 insertions, 14 deletions
diff --git a/shell/match.h b/shell/match.h
index c022ceb..aa393ed 100644
--- a/shell/match.h
+++ b/shell/match.h
@@ -7,25 +7,26 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
//TODO! Why ash.c still uses internal version?!
-typedef char *(*scan_t)(char *string, char *match, bool match_at_left);
+enum {
+ SCAN_MOVE_FROM_LEFT = (1 << 0),
+ SCAN_MOVE_FROM_RIGHT = (1 << 1),
+ SCAN_MATCH_LEFT_HALF = (1 << 2),
+ SCAN_MATCH_RIGHT_HALF = (1 << 3),
+};
-char *scanleft(char *string, char *match, bool match_at_left);
-char *scanright(char *string, char *match, bool match_at_left);
+char* FAST_FUNC scan_and_match(char *string, const char *pattern, unsigned flags);
-static inline scan_t pick_scan(char op1, char op2, bool *match_at_left)
+static inline unsigned pick_scan(char op1, char op2)
{
- /* # - scanleft
- * ## - scanright
- * % - scanright
- * %% - scanleft
- */
+ unsigned scan_flags;
if (op1 == '#') {
- *match_at_left = true;
- return op1 == op2 ? scanright : scanleft;
- } else {
- *match_at_left = false;
- return op1 == op2 ? scanleft : scanright;
+ scan_flags = SCAN_MATCH_LEFT_HALF +
+ (op1 == op2 ? SCAN_MOVE_FROM_RIGHT : SCAN_MOVE_FROM_LEFT);
+ } else { /* % */
+ scan_flags = SCAN_MATCH_RIGHT_HALF +
+ (op1 == op2 ? SCAN_MOVE_FROM_LEFT : SCAN_MOVE_FROM_RIGHT);
}
+ return scan_flags;
}
POP_SAVED_FUNCTION_VISIBILITY