Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1989, 1995, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: zstring.c,v 1.6 2004/08/04 19:36:13 stefan Exp $ */
18
/* String operators */
19
#include "memory_.h"
20
#include "ghost.h"
21
#include "gsutil.h"
22
#include "ialloc.h"
23
#include "iname.h"
24
#include "ivmspace.h"
25
#include "oper.h"
26
#include "store.h"
27
 
28
/* The generic operators (copy, get, put, getinterval, putinterval, */
29
/* length, and forall) are implemented in zgeneric.c. */
30
 
31
/* <int> .bytestring <bytestring> */
32
private int
33
zbytestring(i_ctx_t *i_ctx_p)
34
{
35
    os_ptr op = osp;
36
    byte *sbody;
37
    uint size;
38
 
39
    check_int_leu(*op, max_int);
40
    size = (uint)op->value.intval;
41
    sbody = ialloc_bytes(size, ".bytestring");
42
    if (sbody == 0)
43
	return_error(e_VMerror);
44
    make_astruct(op, a_all | icurrent_space, sbody);
45
    memset(sbody, 0, size);
46
    return 0;
47
}
48
 
49
/* <int> string <string> */
50
int
51
zstring(i_ctx_t *i_ctx_p)
52
{
53
    os_ptr op = osp;
54
    byte *sbody;
55
    uint size;
56
 
57
    check_int_leu(*op, max_string_size);
58
    size = op->value.intval;
59
    sbody = ialloc_string(size, "string");
60
    if (sbody == 0)
61
	return_error(e_VMerror);
62
    make_string(op, a_all | icurrent_space, size, sbody);
63
    memset(sbody, 0, size);
64
    return 0;
65
}
66
 
67
/* <name> .namestring <string> */
68
private int
69
znamestring(i_ctx_t *i_ctx_p)
70
{
71
    os_ptr op = osp;
72
 
73
    check_type(*op, t_name);
74
    name_string_ref(imemory, op, op);
75
    return 0;
76
}
77
 
78
/* <string> <pattern> anchorsearch <post> <match> -true- */
79
/* <string> <pattern> anchorsearch <string> -false- */
80
private int
81
zanchorsearch(i_ctx_t *i_ctx_p)
82
{
83
    os_ptr op = osp;
84
    os_ptr op1 = op - 1;
85
    uint size = r_size(op);
86
 
87
    check_read_type(*op1, t_string);
88
    check_read_type(*op, t_string);
89
    if (size <= r_size(op1) && !memcmp(op1->value.bytes, op->value.bytes, size)) {
90
	os_ptr op0 = op;
91
 
92
	push(1);
93
	*op0 = *op1;
94
	r_set_size(op0, size);
95
	op1->value.bytes += size;
96
	r_dec_size(op1, size);
97
	make_true(op);
98
    } else
99
	make_false(op);
100
    return 0;
101
}
102
 
103
/* <string> <pattern> search <post> <match> <pre> -true- */
104
/* <string> <pattern> search <string> -false- */
105
private int
106
zsearch(i_ctx_t *i_ctx_p)
107
{
108
    os_ptr op = osp;
109
    os_ptr op1 = op - 1;
110
    uint size = r_size(op);
111
    uint count;
112
    byte *pat;
113
    byte *ptr;
114
    byte ch;
115
 
116
    check_read_type(*op1, t_string);
117
    check_read_type(*op, t_string);
118
    if (size > r_size(op1)) {	/* can't match */
119
	make_false(op);
120
	return 0;
121
    }
122
    count = r_size(op1) - size;
123
    ptr = op1->value.bytes;
124
    if (size == 0)
125
	goto found;
126
    pat = op->value.bytes;
127
    ch = pat[0];
128
    do {
129
	if (*ptr == ch && (size == 1 || !memcmp(ptr, pat, size)))
130
	    goto found;
131
	ptr++;
132
    }
133
    while (count--);
134
    /* No match */
135
    make_false(op);
136
    return 0;
137
found:
138
    op->tas.type_attrs = op1->tas.type_attrs;
139
    op->value.bytes = ptr;
140
    r_set_size(op, size);
141
    push(2);
142
    op[-1] = *op1;
143
    r_set_size(op - 1, ptr - op[-1].value.bytes);
144
    op1->value.bytes = ptr + size;
145
    r_set_size(op1, count);
146
    make_true(op);
147
    return 0;
148
}
149
 
150
/* <string> <charstring> .stringbreak <int|null> */
151
private int
152
zstringbreak(i_ctx_t *i_ctx_p)
153
{
154
    os_ptr op = osp;
155
    uint i, j;
156
 
157
    check_read_type(op[-1], t_string);
158
    check_read_type(*op, t_string);
159
    /* We can't use strpbrk here, because C doesn't allow nulls in strings. */
160
    for (i = 0; i < r_size(op - 1); ++i)
161
	for (j = 0; j < r_size(op); ++j)
162
	    if (op[-1].value.const_bytes[i] == op->value.const_bytes[j]) {
163
		make_int(op - 1, i);
164
		goto done;
165
	    }
166
    make_null(op - 1);
167
 done:
168
    pop(1);
169
    return 0;
170
}
171
 
172
/* <obj> <pattern> .stringmatch <bool> */
173
private int
174
zstringmatch(i_ctx_t *i_ctx_p)
175
{
176
    os_ptr op = osp;
177
    os_ptr op1 = op - 1;
178
    bool result;
179
 
180
    check_read_type(*op, t_string);
181
    switch (r_type(op1)) {
182
	case t_string:
183
	    check_read(*op1);
184
	    goto cmp;
185
	case t_name:
186
	    name_string_ref(imemory, op1, op1);	/* can't fail */
187
cmp:
188
	    result = string_match(op1->value.const_bytes, r_size(op1),
189
				  op->value.const_bytes, r_size(op),
190
				  NULL);
191
	    break;
192
	default:
193
	    result = (r_size(op) == 1 && *op->value.bytes == '*');
194
    }
195
    make_bool(op1, result);
196
    pop(1);
197
    return 0;
198
}
199
 
200
/* ------ Initialization procedure ------ */
201
 
202
const op_def zstring_op_defs[] =
203
{
204
    {"1.bytestring", zbytestring},
205
    {"2anchorsearch", zanchorsearch},
206
    {"1.namestring", znamestring},
207
    {"2search", zsearch},
208
    {"1string", zstring},
209
    {"2.stringbreak", zstringbreak},
210
    {"2.stringmatch", zstringmatch},
211
    op_def_end(0)
212
};