17dd7cddfSDavid du Colombier /* Copyright (C) 1989, 1995, 1998, 1999 Aladdin Enterprises. All rights reserved.
27dd7cddfSDavid du Colombier
3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier implied.
57dd7cddfSDavid du Colombier
6*593dc095SDavid du Colombier This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier
10*593dc095SDavid du Colombier For more information about licensing, please refer to
11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier
17*593dc095SDavid du Colombier /* $Id: zstring.c,v 1.6 2004/08/04 19:36:13 stefan Exp $ */
187dd7cddfSDavid du Colombier /* String operators */
197dd7cddfSDavid du Colombier #include "memory_.h"
207dd7cddfSDavid du Colombier #include "ghost.h"
217dd7cddfSDavid du Colombier #include "gsutil.h"
227dd7cddfSDavid du Colombier #include "ialloc.h"
237dd7cddfSDavid du Colombier #include "iname.h"
247dd7cddfSDavid du Colombier #include "ivmspace.h"
257dd7cddfSDavid du Colombier #include "oper.h"
267dd7cddfSDavid du Colombier #include "store.h"
277dd7cddfSDavid du Colombier
287dd7cddfSDavid du Colombier /* The generic operators (copy, get, put, getinterval, putinterval, */
297dd7cddfSDavid du Colombier /* length, and forall) are implemented in zgeneric.c. */
307dd7cddfSDavid du Colombier
317dd7cddfSDavid du Colombier /* <int> .bytestring <bytestring> */
327dd7cddfSDavid du Colombier private int
zbytestring(i_ctx_t * i_ctx_p)337dd7cddfSDavid du Colombier zbytestring(i_ctx_t *i_ctx_p)
347dd7cddfSDavid du Colombier {
357dd7cddfSDavid du Colombier os_ptr op = osp;
367dd7cddfSDavid du Colombier byte *sbody;
377dd7cddfSDavid du Colombier uint size;
387dd7cddfSDavid du Colombier
397dd7cddfSDavid du Colombier check_int_leu(*op, max_int);
407dd7cddfSDavid du Colombier size = (uint)op->value.intval;
417dd7cddfSDavid du Colombier sbody = ialloc_bytes(size, ".bytestring");
427dd7cddfSDavid du Colombier if (sbody == 0)
437dd7cddfSDavid du Colombier return_error(e_VMerror);
447dd7cddfSDavid du Colombier make_astruct(op, a_all | icurrent_space, sbody);
457dd7cddfSDavid du Colombier memset(sbody, 0, size);
467dd7cddfSDavid du Colombier return 0;
477dd7cddfSDavid du Colombier }
487dd7cddfSDavid du Colombier
497dd7cddfSDavid du Colombier /* <int> string <string> */
507dd7cddfSDavid du Colombier int
zstring(i_ctx_t * i_ctx_p)517dd7cddfSDavid du Colombier zstring(i_ctx_t *i_ctx_p)
527dd7cddfSDavid du Colombier {
537dd7cddfSDavid du Colombier os_ptr op = osp;
547dd7cddfSDavid du Colombier byte *sbody;
557dd7cddfSDavid du Colombier uint size;
567dd7cddfSDavid du Colombier
577dd7cddfSDavid du Colombier check_int_leu(*op, max_string_size);
587dd7cddfSDavid du Colombier size = op->value.intval;
597dd7cddfSDavid du Colombier sbody = ialloc_string(size, "string");
607dd7cddfSDavid du Colombier if (sbody == 0)
617dd7cddfSDavid du Colombier return_error(e_VMerror);
627dd7cddfSDavid du Colombier make_string(op, a_all | icurrent_space, size, sbody);
637dd7cddfSDavid du Colombier memset(sbody, 0, size);
647dd7cddfSDavid du Colombier return 0;
657dd7cddfSDavid du Colombier }
667dd7cddfSDavid du Colombier
677dd7cddfSDavid du Colombier /* <name> .namestring <string> */
687dd7cddfSDavid du Colombier private int
znamestring(i_ctx_t * i_ctx_p)697dd7cddfSDavid du Colombier znamestring(i_ctx_t *i_ctx_p)
707dd7cddfSDavid du Colombier {
717dd7cddfSDavid du Colombier os_ptr op = osp;
727dd7cddfSDavid du Colombier
737dd7cddfSDavid du Colombier check_type(*op, t_name);
74*593dc095SDavid du Colombier name_string_ref(imemory, op, op);
757dd7cddfSDavid du Colombier return 0;
767dd7cddfSDavid du Colombier }
777dd7cddfSDavid du Colombier
787dd7cddfSDavid du Colombier /* <string> <pattern> anchorsearch <post> <match> -true- */
797dd7cddfSDavid du Colombier /* <string> <pattern> anchorsearch <string> -false- */
807dd7cddfSDavid du Colombier private int
zanchorsearch(i_ctx_t * i_ctx_p)817dd7cddfSDavid du Colombier zanchorsearch(i_ctx_t *i_ctx_p)
827dd7cddfSDavid du Colombier {
837dd7cddfSDavid du Colombier os_ptr op = osp;
847dd7cddfSDavid du Colombier os_ptr op1 = op - 1;
857dd7cddfSDavid du Colombier uint size = r_size(op);
867dd7cddfSDavid du Colombier
877dd7cddfSDavid du Colombier check_read_type(*op1, t_string);
887dd7cddfSDavid du Colombier check_read_type(*op, t_string);
897dd7cddfSDavid du Colombier if (size <= r_size(op1) && !memcmp(op1->value.bytes, op->value.bytes, size)) {
907dd7cddfSDavid du Colombier os_ptr op0 = op;
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier push(1);
937dd7cddfSDavid du Colombier *op0 = *op1;
947dd7cddfSDavid du Colombier r_set_size(op0, size);
957dd7cddfSDavid du Colombier op1->value.bytes += size;
967dd7cddfSDavid du Colombier r_dec_size(op1, size);
977dd7cddfSDavid du Colombier make_true(op);
987dd7cddfSDavid du Colombier } else
997dd7cddfSDavid du Colombier make_false(op);
1007dd7cddfSDavid du Colombier return 0;
1017dd7cddfSDavid du Colombier }
1027dd7cddfSDavid du Colombier
1037dd7cddfSDavid du Colombier /* <string> <pattern> search <post> <match> <pre> -true- */
1047dd7cddfSDavid du Colombier /* <string> <pattern> search <string> -false- */
1057dd7cddfSDavid du Colombier private int
zsearch(i_ctx_t * i_ctx_p)1067dd7cddfSDavid du Colombier zsearch(i_ctx_t *i_ctx_p)
1077dd7cddfSDavid du Colombier {
1087dd7cddfSDavid du Colombier os_ptr op = osp;
1097dd7cddfSDavid du Colombier os_ptr op1 = op - 1;
1107dd7cddfSDavid du Colombier uint size = r_size(op);
1117dd7cddfSDavid du Colombier uint count;
1127dd7cddfSDavid du Colombier byte *pat;
1137dd7cddfSDavid du Colombier byte *ptr;
1147dd7cddfSDavid du Colombier byte ch;
1157dd7cddfSDavid du Colombier
1167dd7cddfSDavid du Colombier check_read_type(*op1, t_string);
1177dd7cddfSDavid du Colombier check_read_type(*op, t_string);
1187dd7cddfSDavid du Colombier if (size > r_size(op1)) { /* can't match */
1197dd7cddfSDavid du Colombier make_false(op);
1207dd7cddfSDavid du Colombier return 0;
1217dd7cddfSDavid du Colombier }
1227dd7cddfSDavid du Colombier count = r_size(op1) - size;
1237dd7cddfSDavid du Colombier ptr = op1->value.bytes;
1247dd7cddfSDavid du Colombier if (size == 0)
1257dd7cddfSDavid du Colombier goto found;
1267dd7cddfSDavid du Colombier pat = op->value.bytes;
1277dd7cddfSDavid du Colombier ch = pat[0];
1287dd7cddfSDavid du Colombier do {
1297dd7cddfSDavid du Colombier if (*ptr == ch && (size == 1 || !memcmp(ptr, pat, size)))
1307dd7cddfSDavid du Colombier goto found;
1317dd7cddfSDavid du Colombier ptr++;
1327dd7cddfSDavid du Colombier }
1337dd7cddfSDavid du Colombier while (count--);
1347dd7cddfSDavid du Colombier /* No match */
1357dd7cddfSDavid du Colombier make_false(op);
1367dd7cddfSDavid du Colombier return 0;
1377dd7cddfSDavid du Colombier found:
1387dd7cddfSDavid du Colombier op->tas.type_attrs = op1->tas.type_attrs;
1397dd7cddfSDavid du Colombier op->value.bytes = ptr;
1407dd7cddfSDavid du Colombier r_set_size(op, size);
1417dd7cddfSDavid du Colombier push(2);
1427dd7cddfSDavid du Colombier op[-1] = *op1;
1437dd7cddfSDavid du Colombier r_set_size(op - 1, ptr - op[-1].value.bytes);
1447dd7cddfSDavid du Colombier op1->value.bytes = ptr + size;
1457dd7cddfSDavid du Colombier r_set_size(op1, count);
1467dd7cddfSDavid du Colombier make_true(op);
1477dd7cddfSDavid du Colombier return 0;
1487dd7cddfSDavid du Colombier }
1497dd7cddfSDavid du Colombier
150*593dc095SDavid du Colombier /* <string> <charstring> .stringbreak <int|null> */
151*593dc095SDavid du Colombier private int
zstringbreak(i_ctx_t * i_ctx_p)152*593dc095SDavid du Colombier zstringbreak(i_ctx_t *i_ctx_p)
153*593dc095SDavid du Colombier {
154*593dc095SDavid du Colombier os_ptr op = osp;
155*593dc095SDavid du Colombier uint i, j;
156*593dc095SDavid du Colombier
157*593dc095SDavid du Colombier check_read_type(op[-1], t_string);
158*593dc095SDavid du Colombier check_read_type(*op, t_string);
159*593dc095SDavid du Colombier /* We can't use strpbrk here, because C doesn't allow nulls in strings. */
160*593dc095SDavid du Colombier for (i = 0; i < r_size(op - 1); ++i)
161*593dc095SDavid du Colombier for (j = 0; j < r_size(op); ++j)
162*593dc095SDavid du Colombier if (op[-1].value.const_bytes[i] == op->value.const_bytes[j]) {
163*593dc095SDavid du Colombier make_int(op - 1, i);
164*593dc095SDavid du Colombier goto done;
165*593dc095SDavid du Colombier }
166*593dc095SDavid du Colombier make_null(op - 1);
167*593dc095SDavid du Colombier done:
168*593dc095SDavid du Colombier pop(1);
169*593dc095SDavid du Colombier return 0;
170*593dc095SDavid du Colombier }
171*593dc095SDavid du Colombier
1727dd7cddfSDavid du Colombier /* <obj> <pattern> .stringmatch <bool> */
1737dd7cddfSDavid du Colombier private int
zstringmatch(i_ctx_t * i_ctx_p)1747dd7cddfSDavid du Colombier zstringmatch(i_ctx_t *i_ctx_p)
1757dd7cddfSDavid du Colombier {
1767dd7cddfSDavid du Colombier os_ptr op = osp;
1777dd7cddfSDavid du Colombier os_ptr op1 = op - 1;
1787dd7cddfSDavid du Colombier bool result;
1797dd7cddfSDavid du Colombier
1807dd7cddfSDavid du Colombier check_read_type(*op, t_string);
1817dd7cddfSDavid du Colombier switch (r_type(op1)) {
1827dd7cddfSDavid du Colombier case t_string:
1837dd7cddfSDavid du Colombier check_read(*op1);
1847dd7cddfSDavid du Colombier goto cmp;
1857dd7cddfSDavid du Colombier case t_name:
186*593dc095SDavid du Colombier name_string_ref(imemory, op1, op1); /* can't fail */
1877dd7cddfSDavid du Colombier cmp:
1887dd7cddfSDavid du Colombier result = string_match(op1->value.const_bytes, r_size(op1),
1897dd7cddfSDavid du Colombier op->value.const_bytes, r_size(op),
1907dd7cddfSDavid du Colombier NULL);
1917dd7cddfSDavid du Colombier break;
1927dd7cddfSDavid du Colombier default:
1937dd7cddfSDavid du Colombier result = (r_size(op) == 1 && *op->value.bytes == '*');
1947dd7cddfSDavid du Colombier }
1957dd7cddfSDavid du Colombier make_bool(op1, result);
1967dd7cddfSDavid du Colombier pop(1);
1977dd7cddfSDavid du Colombier return 0;
1987dd7cddfSDavid du Colombier }
1997dd7cddfSDavid du Colombier
2007dd7cddfSDavid du Colombier /* ------ Initialization procedure ------ */
2017dd7cddfSDavid du Colombier
2027dd7cddfSDavid du Colombier const op_def zstring_op_defs[] =
2037dd7cddfSDavid du Colombier {
2047dd7cddfSDavid du Colombier {"1.bytestring", zbytestring},
2057dd7cddfSDavid du Colombier {"2anchorsearch", zanchorsearch},
2067dd7cddfSDavid du Colombier {"1.namestring", znamestring},
2077dd7cddfSDavid du Colombier {"2search", zsearch},
2087dd7cddfSDavid du Colombier {"1string", zstring},
209*593dc095SDavid du Colombier {"2.stringbreak", zstringbreak},
2107dd7cddfSDavid du Colombier {"2.stringmatch", zstringmatch},
2117dd7cddfSDavid du Colombier op_def_end(0)
2127dd7cddfSDavid du Colombier };
213