1 /* Copyright (C) 1989, 1995, 1998, 1999 Aladdin Enterprises. All rights reserved. 2 3 This file is part of AFPL Ghostscript. 4 5 AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or 6 distributor accepts any responsibility for the consequences of using it, or 7 for whether it serves any particular purpose or works at all, unless he or 8 she says so in writing. Refer to the Aladdin Free Public License (the 9 "License") for full details. 10 11 Every copy of AFPL Ghostscript must include a copy of the License, normally 12 in a plain ASCII text file named PUBLIC. The License grants you the right 13 to copy, modify and redistribute AFPL Ghostscript, but only under certain 14 conditions described in the License. Among other things, the License 15 requires that the copyright notice and this notice be preserved on all 16 copies. 17 */ 18 19 /*$Id: zstring.c,v 1.2 2000/09/19 19:00:55 lpd Exp $ */ 20 /* String operators */ 21 #include "memory_.h" 22 #include "ghost.h" 23 #include "gsutil.h" 24 #include "ialloc.h" 25 #include "iname.h" 26 #include "ivmspace.h" 27 #include "oper.h" 28 #include "store.h" 29 30 /* The generic operators (copy, get, put, getinterval, putinterval, */ 31 /* length, and forall) are implemented in zgeneric.c. */ 32 33 /* <int> .bytestring <bytestring> */ 34 private int 35 zbytestring(i_ctx_t *i_ctx_p) 36 { 37 os_ptr op = osp; 38 byte *sbody; 39 uint size; 40 41 check_int_leu(*op, max_int); 42 size = (uint)op->value.intval; 43 sbody = ialloc_bytes(size, ".bytestring"); 44 if (sbody == 0) 45 return_error(e_VMerror); 46 make_astruct(op, a_all | icurrent_space, sbody); 47 memset(sbody, 0, size); 48 return 0; 49 } 50 51 /* <int> string <string> */ 52 int 53 zstring(i_ctx_t *i_ctx_p) 54 { 55 os_ptr op = osp; 56 byte *sbody; 57 uint size; 58 59 check_int_leu(*op, max_string_size); 60 size = op->value.intval; 61 sbody = ialloc_string(size, "string"); 62 if (sbody == 0) 63 return_error(e_VMerror); 64 make_string(op, a_all | icurrent_space, size, sbody); 65 memset(sbody, 0, size); 66 return 0; 67 } 68 69 /* <name> .namestring <string> */ 70 private int 71 znamestring(i_ctx_t *i_ctx_p) 72 { 73 os_ptr op = osp; 74 75 check_type(*op, t_name); 76 name_string_ref(op, op); 77 return 0; 78 } 79 80 /* <string> <pattern> anchorsearch <post> <match> -true- */ 81 /* <string> <pattern> anchorsearch <string> -false- */ 82 private int 83 zanchorsearch(i_ctx_t *i_ctx_p) 84 { 85 os_ptr op = osp; 86 os_ptr op1 = op - 1; 87 uint size = r_size(op); 88 89 check_read_type(*op1, t_string); 90 check_read_type(*op, t_string); 91 if (size <= r_size(op1) && !memcmp(op1->value.bytes, op->value.bytes, size)) { 92 os_ptr op0 = op; 93 94 push(1); 95 *op0 = *op1; 96 r_set_size(op0, size); 97 op1->value.bytes += size; 98 r_dec_size(op1, size); 99 make_true(op); 100 } else 101 make_false(op); 102 return 0; 103 } 104 105 /* <string> <pattern> search <post> <match> <pre> -true- */ 106 /* <string> <pattern> search <string> -false- */ 107 private int 108 zsearch(i_ctx_t *i_ctx_p) 109 { 110 os_ptr op = osp; 111 os_ptr op1 = op - 1; 112 uint size = r_size(op); 113 uint count; 114 byte *pat; 115 byte *ptr; 116 byte ch; 117 118 check_read_type(*op1, t_string); 119 check_read_type(*op, t_string); 120 if (size > r_size(op1)) { /* can't match */ 121 make_false(op); 122 return 0; 123 } 124 count = r_size(op1) - size; 125 ptr = op1->value.bytes; 126 if (size == 0) 127 goto found; 128 pat = op->value.bytes; 129 ch = pat[0]; 130 do { 131 if (*ptr == ch && (size == 1 || !memcmp(ptr, pat, size))) 132 goto found; 133 ptr++; 134 } 135 while (count--); 136 /* No match */ 137 make_false(op); 138 return 0; 139 found: 140 op->tas.type_attrs = op1->tas.type_attrs; 141 op->value.bytes = ptr; 142 r_set_size(op, size); 143 push(2); 144 op[-1] = *op1; 145 r_set_size(op - 1, ptr - op[-1].value.bytes); 146 op1->value.bytes = ptr + size; 147 r_set_size(op1, count); 148 make_true(op); 149 return 0; 150 } 151 152 /* <obj> <pattern> .stringmatch <bool> */ 153 private int 154 zstringmatch(i_ctx_t *i_ctx_p) 155 { 156 os_ptr op = osp; 157 os_ptr op1 = op - 1; 158 bool result; 159 160 check_read_type(*op, t_string); 161 switch (r_type(op1)) { 162 case t_string: 163 check_read(*op1); 164 goto cmp; 165 case t_name: 166 name_string_ref(op1, op1); /* can't fail */ 167 cmp: 168 result = string_match(op1->value.const_bytes, r_size(op1), 169 op->value.const_bytes, r_size(op), 170 NULL); 171 break; 172 default: 173 result = (r_size(op) == 1 && *op->value.bytes == '*'); 174 } 175 make_bool(op1, result); 176 pop(1); 177 return 0; 178 } 179 180 /* ------ Initialization procedure ------ */ 181 182 const op_def zstring_op_defs[] = 183 { 184 {"1.bytestring", zbytestring}, 185 {"2anchorsearch", zanchorsearch}, 186 {"1.namestring", znamestring}, 187 {"2search", zsearch}, 188 {"1string", zstring}, 189 {"2.stringmatch", zstringmatch}, 190 op_def_end(0) 191 }; 192