diff options
author | Chris Liddell <chris.liddell@artifex.com> | 2019-05-03 13:40:48 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2019-05-24 13:09:53 +0100 |
commit | 1552c8f7b223f77d6de2c0595bb50f2e27a3a2d8 (patch) | |
tree | d0fd1202305d9a47ff6809090a06a95f0609fafd | |
parent | a9d2fc1651055d76b6881a2feca19df2a36a0228 (diff) | |
download | ghostpdl-1552c8f7b223f77d6de2c0595bb50f2e27a3a2d8.tar.gz |
Add a non-standard string 'reverse search" operator
The search operator searches for the first occurrence of a character code in a
string (i.e. searches forwards from the start of the string), 'rsearch' finds
the last instance of a character code (i.e. search backwards from the end of
the string).
-rw-r--r-- | psi/zstring.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/psi/zstring.c b/psi/zstring.c index 24afcc6e4..fac72fa86 100644 --- a/psi/zstring.c +++ b/psi/zstring.c @@ -103,10 +103,10 @@ zanchorsearch(i_ctx_t *i_ctx_p) return 0; } -/* <string> <pattern> search <post> <match> <pre> -true- */ -/* <string> <pattern> search <string> -false- */ +/* <string> <pattern> (r)search <post> <match> <pre> -true- */ +/* <string> <pattern> (r)search <string> -false- */ static int -zsearch(i_ctx_t *i_ctx_p) +search_impl(i_ctx_t *i_ctx_p, bool forward) { os_ptr op = osp; os_ptr op1 = op - 1; @@ -115,6 +115,7 @@ zsearch(i_ctx_t *i_ctx_p) byte *pat; byte *ptr; byte ch; + int incr = forward ? 1 : -1; check_read_type(*op1, t_string); check_read_type(*op, t_string); @@ -126,12 +127,14 @@ zsearch(i_ctx_t *i_ctx_p) ptr = op1->value.bytes; if (size == 0) goto found; + if (!forward) + ptr += count; pat = op->value.bytes; ch = pat[0]; do { if (*ptr == ch && (size == 1 || !memcmp(ptr, pat, size))) goto found; - ptr++; + ptr += incr; } while (count--); /* No match */ @@ -145,11 +148,25 @@ found: op[-1] = *op1; r_set_size(op - 1, ptr - op[-1].value.bytes); op1->value.bytes = ptr + size; - r_set_size(op1, count); + r_set_size(op1, count + (!forward ? (size - 1) : 0)); make_true(op); return 0; } +/* Search from the start of the string */ +static int +zsearch(i_ctx_t *i_ctx_p) +{ + return search_impl(i_ctx_p, true); +} + +/* Search from the end of the string */ +static int +zrsearch(i_ctx_t *i_ctx_p) +{ + return search_impl(i_ctx_p, false); +} + /* <string> <charstring> .stringbreak <int|null> */ static int zstringbreak(i_ctx_t *i_ctx_p) @@ -208,6 +225,7 @@ const op_def zstring_op_defs[] = {"2anchorsearch", zanchorsearch}, {"1.namestring", znamestring}, {"2search", zsearch}, + {"2rsearch", zrsearch}, {"1string", zstring}, {"2.stringbreak", zstringbreak}, {"2.stringmatch", zstringmatch}, |