Commit | Line | Data |
---|---|---|
43f6ba4a WJ |
1 | /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. |
2 | Distributed by Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of Ghostscript. | |
5 | ||
6 | Ghostscript is distributed in the hope that it will be useful, but | |
7 | WITHOUT ANY WARRANTY. No author or distributor accepts responsibility | |
8 | to anyone for the consequences of using it or for whether it serves any | |
9 | particular purpose or works at all, unless he says so in writing. Refer | |
10 | to the Ghostscript General Public License for full details. | |
11 | ||
12 | Everyone is granted permission to copy, modify and redistribute | |
13 | Ghostscript, but only under the conditions described in the Ghostscript | |
14 | General Public License. A copy of this license is supposed to have been | |
15 | given to you along with Ghostscript so you can know your rights and | |
16 | responsibilities. It should be in a file named COPYING. Among other | |
17 | things, the copyright notice and this notice must be preserved on all | |
18 | copies. */ | |
19 | ||
20 | /* zstring.c */ | |
21 | /* String operators for GhostScript */ | |
22 | #include "memory_.h" | |
23 | #include "ghost.h" | |
24 | #include "alloc.h" | |
25 | #include "errors.h" | |
26 | #include "iutil.h" | |
27 | #include "name.h" | |
28 | #include "oper.h" | |
29 | #include "store.h" | |
30 | #include "stream.h" | |
31 | ||
32 | /* The generic operators (copy, get, put, getinterval, putinterval, */ | |
33 | /* length, and forall) are implemented in zgeneric.c. */ | |
34 | ||
35 | /* Imported operators */ | |
36 | extern int ztoken_file(P1(os_ptr)); | |
37 | ||
38 | /* string */ | |
39 | int | |
40 | zstring(register os_ptr op) | |
41 | { byte *sbody; | |
42 | uint size; | |
43 | check_type(*op, t_integer); | |
44 | if ( op->value.intval < 0 || (ulong)(op->value.intval) > max_uint ) | |
45 | return e_rangecheck; | |
46 | size = op->value.intval; | |
47 | sbody = (byte *)alloc(size, 1, "string"); | |
48 | if ( sbody == 0 ) return e_VMerror; | |
49 | make_tasv(op, t_string, a_all, size, bytes, sbody); | |
50 | memset(sbody, 0, size); | |
51 | return 0; | |
52 | } | |
53 | ||
54 | /* anchorsearch */ | |
55 | int | |
56 | zanchorsearch(register os_ptr op) | |
57 | { os_ptr op1 = op - 1; | |
58 | uint size = r_size(op); | |
59 | check_read_type(*op1, t_string); | |
60 | check_read_type(*op, t_string); | |
61 | if ( size <= r_size(op1) && !memcmp(op1->value.bytes, op->value.bytes, size) ) | |
62 | { *op = *op1; | |
63 | r_set_size(op, size); | |
64 | op1->value.bytes += size; | |
65 | r_inc_size(op1, -size); | |
66 | push(1); | |
67 | make_bool(op, 1); | |
68 | } | |
69 | else | |
70 | make_bool(op, 0); | |
71 | return 0; | |
72 | } | |
73 | ||
74 | /* search */ | |
75 | int | |
76 | zsearch(register os_ptr op) | |
77 | { os_ptr op1 = op - 1; | |
78 | uint size = r_size(op); | |
79 | uint count; | |
80 | byte *ptr; | |
81 | check_read_type(*op1, t_string); | |
82 | check_read_type(*op, t_string); | |
83 | if ( size > r_size(op1) ) /* can't match */ | |
84 | { make_bool(op, 0); | |
85 | return 0; | |
86 | } | |
87 | count = r_size(op1) - size; | |
88 | ptr = op1->value.bytes; | |
89 | do | |
90 | { if ( !memcmp(ptr, op->value.bytes, size) ) | |
91 | { op->tas.type_attrs = op1->tas.type_attrs; | |
92 | op->value.bytes = ptr; | |
93 | r_set_size(op, size); | |
94 | push(1); | |
95 | *op = *op1; | |
96 | r_set_size(op, ptr - op->value.bytes); | |
97 | op1->value.bytes = ptr + size; | |
98 | r_set_size(op1, count); | |
99 | push(1); | |
100 | make_bool(op, 1); | |
101 | return 0; | |
102 | } | |
103 | ptr++; | |
104 | } | |
105 | while ( count-- ); | |
106 | /* No match */ | |
107 | make_bool(op, 0); | |
108 | return 0; | |
109 | } | |
110 | ||
111 | /* stringmatch */ | |
112 | int | |
113 | zstringmatch(register os_ptr op) | |
114 | { os_ptr op1 = op - 1; | |
115 | int result; | |
116 | ref stref; | |
117 | check_read_type(*op, t_string); | |
118 | switch ( r_type(op1) ) | |
119 | { | |
120 | case t_string: | |
121 | check_read(*op1); | |
122 | ref_assign(&stref, op1); | |
123 | goto cmp; | |
124 | case t_name: | |
125 | name_string_ref(op1, &stref); | |
126 | cmp: result = string_match(stref.value.bytes, r_size(&stref), | |
127 | op->value.bytes, r_size(op), 0); | |
128 | break; | |
129 | default: | |
130 | result = (r_size(op) == 1 && *op->value.bytes == '*'); | |
131 | } | |
132 | make_bool(op1, result); | |
133 | pop(1); | |
134 | return 0; | |
135 | } | |
136 | ||
137 | /* token */ | |
138 | int | |
139 | ztoken(register os_ptr op) | |
140 | { stream st; | |
141 | stream *s = &st; | |
142 | int code; | |
143 | ref token; | |
144 | switch ( r_type(op) ) | |
145 | { | |
146 | default: return e_typecheck; | |
147 | case t_file: return ztoken_file(op); | |
148 | case t_string: ; | |
149 | } | |
150 | check_read(*op); | |
151 | sread_string(s, op->value.bytes, r_size(op)); | |
152 | switch ( code = scan_token(s, 1, &token) ) | |
153 | { | |
154 | case 0: /* read a token */ | |
155 | { uint pos = stell(s); | |
156 | op->value.bytes += pos; | |
157 | r_inc_size(op, -pos); | |
158 | } | |
159 | push(2); | |
160 | op[-1] = token; | |
161 | make_bool(op, 1); | |
162 | return 0; | |
163 | case 1: /* no tokens */ | |
164 | make_bool(op, 0); | |
165 | return 0; | |
166 | default: /* error */ | |
167 | return code; | |
168 | } | |
169 | } | |
170 | ||
171 | /* ------ Initialization procedure ------ */ | |
172 | ||
173 | op_def zstring_op_defs[] = { | |
174 | {"2anchorsearch", zanchorsearch}, | |
175 | {"2search", zsearch}, | |
176 | {"1string", zstring}, | |
177 | {"2stringmatch", zstringmatch}, | |
178 | {"1token", ztoken}, | |
179 | op_def_end(0) | |
180 | }; |