386BSD 0.1 development
[unix-history] / usr / othersrc / public / ghostscript-2.4.1 / zstring.c
CommitLineData
43f6ba4a
WJ
1/* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved.
2 Distributed by Free Software Foundation, Inc.
3
4This file is part of Ghostscript.
5
6Ghostscript is distributed in the hope that it will be useful, but
7WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
8to anyone for the consequences of using it or for whether it serves any
9particular purpose or works at all, unless he says so in writing. Refer
10to the Ghostscript General Public License for full details.
11
12Everyone is granted permission to copy, modify and redistribute
13Ghostscript, but only under the conditions described in the Ghostscript
14General Public License. A copy of this license is supposed to have been
15given to you along with Ghostscript so you can know your rights and
16responsibilities. It should be in a file named COPYING. Among other
17things, the copyright notice and this notice must be preserved on all
18copies. */
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 */
36extern int ztoken_file(P1(os_ptr));
37
38/* string */
39int
40zstring(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 */
55int
56zanchorsearch(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 */
75int
76zsearch(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 */
112int
113zstringmatch(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);
126cmp: 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 */
138int
139ztoken(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
173op_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};