summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Deutschmann <whissi@gentoo.org>2019-10-15 12:24:12 +0200
committerThomas Deutschmann <whissi@gentoo.org>2020-08-13 11:26:55 +0200
commite088156d5b620e5e639580dacf85c6dc13823c74 (patch)
tree57f5c025e203279944da512166c20bc0521d8ccd /psi/zstring.c
downloadghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.tar.gz
ghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.tar.bz2
ghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.zip
Import Ghostscript 9.50ghostscript-9.50
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Diffstat (limited to 'psi/zstring.c')
-rw-r--r--psi/zstring.c233
1 files changed, 233 insertions, 0 deletions
diff --git a/psi/zstring.c b/psi/zstring.c
new file mode 100644
index 00000000..fac72fa8
--- /dev/null
+++ b/psi/zstring.c
@@ -0,0 +1,233 @@
+/* Copyright (C) 2001-2019 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
+
+/* String operators */
+#include "memory_.h"
+#include "ghost.h"
+#include "gsutil.h"
+#include "ialloc.h"
+#include "iname.h"
+#include "ivmspace.h"
+#include "oper.h"
+#include "store.h"
+
+/* The generic operators (copy, get, put, getinterval, putinterval, */
+/* length, and forall) are implemented in zgeneric.c. */
+
+/* <int> .bytestring <bytestring> */
+static int
+zbytestring(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ byte *sbody;
+ uint size;
+
+ check_int_leu(*op, max_int);
+ size = (uint)op->value.intval;
+ sbody = ialloc_bytes(size, ".bytestring");
+ if (sbody == 0)
+ return_error(gs_error_VMerror);
+ make_astruct(op, a_all | icurrent_space, sbody);
+ memset(sbody, 0, size);
+ return 0;
+}
+
+/* <int> string <string> */
+int
+zstring(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ byte *sbody;
+ uint size;
+
+ check_type(*op, t_integer);
+ if (op->value.intval < 0 )
+ return_error(gs_error_rangecheck);
+ if (op->value.intval > max_string_size )
+ return_error(gs_error_limitcheck); /* to match Distiller */
+ size = op->value.intval;
+ sbody = ialloc_string(size, "string");
+ if (sbody == 0)
+ return_error(gs_error_VMerror);
+ make_string(op, a_all | icurrent_space, size, sbody);
+ memset(sbody, 0, size);
+ return 0;
+}
+
+/* <name> .namestring <string> */
+static int
+znamestring(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+
+ check_type(*op, t_name);
+ name_string_ref(imemory, op, op);
+ return 0;
+}
+
+/* <string> <pattern> anchorsearch <post> <match> -true- */
+/* <string> <pattern> anchorsearch <string> -false- */
+static int
+zanchorsearch(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ os_ptr op1 = op - 1;
+ uint size = r_size(op);
+
+ check_read_type(*op, t_string);
+ check_read_type(*op1, t_string);
+ if (size <= r_size(op1) && !memcmp(op1->value.bytes, op->value.bytes, size)) {
+ os_ptr op0 = op;
+
+ push(1);
+ *op0 = *op1;
+ r_set_size(op0, size);
+ op1->value.bytes += size;
+ r_dec_size(op1, size);
+ make_true(op);
+ } else
+ make_false(op);
+ return 0;
+}
+
+/* <string> <pattern> (r)search <post> <match> <pre> -true- */
+/* <string> <pattern> (r)search <string> -false- */
+static int
+search_impl(i_ctx_t *i_ctx_p, bool forward)
+{
+ os_ptr op = osp;
+ os_ptr op1 = op - 1;
+ uint size = r_size(op);
+ uint count;
+ byte *pat;
+ byte *ptr;
+ byte ch;
+ int incr = forward ? 1 : -1;
+
+ check_read_type(*op1, t_string);
+ check_read_type(*op, t_string);
+ if (size > r_size(op1)) { /* can't match */
+ make_false(op);
+ return 0;
+ }
+ count = r_size(op1) - size;
+ 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 += incr;
+ }
+ while (count--);
+ /* No match */
+ make_false(op);
+ return 0;
+found:
+ op->tas.type_attrs = op1->tas.type_attrs;
+ op->value.bytes = ptr;
+ r_set_size(op, size);
+ push(2);
+ op[-1] = *op1;
+ r_set_size(op - 1, ptr - op[-1].value.bytes);
+ op1->value.bytes = ptr + size;
+ 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)
+{
+ os_ptr op = osp;
+ uint i, j;
+
+ check_read_type(op[-1], t_string);
+ check_read_type(*op, t_string);
+ /* We can't use strpbrk here, because C doesn't allow nulls in strings. */
+ for (i = 0; i < r_size(op - 1); ++i)
+ for (j = 0; j < r_size(op); ++j)
+ if (op[-1].value.const_bytes[i] == op->value.const_bytes[j]) {
+ make_int(op - 1, i);
+ goto done;
+ }
+ make_null(op - 1);
+ done:
+ pop(1);
+ return 0;
+}
+
+/* <obj> <pattern> .stringmatch <bool> */
+static int
+zstringmatch(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ os_ptr op1 = op - 1;
+ bool result;
+
+ check_read_type(*op, t_string);
+ switch (r_type(op1)) {
+ case t_string:
+ check_read(*op1);
+ goto cmp;
+ case t_name:
+ name_string_ref(imemory, op1, op1); /* can't fail */
+cmp:
+ result = string_match(op1->value.const_bytes, r_size(op1),
+ op->value.const_bytes, r_size(op),
+ NULL);
+ break;
+ default:
+ result = (r_size(op) == 1 && *op->value.bytes == '*');
+ }
+ make_bool(op1, result);
+ pop(1);
+ return 0;
+}
+
+/* ------ Initialization procedure ------ */
+
+const op_def zstring_op_defs[] =
+{
+ {"1.bytestring", zbytestring},
+ {"2anchorsearch", zanchorsearch},
+ {"1.namestring", znamestring},
+ {"2search", zsearch},
+ {"2rsearch", zrsearch},
+ {"1string", zstring},
+ {"2.stringbreak", zstringbreak},
+ {"2.stringmatch", zstringmatch},
+ op_def_end(0)
+};