#ifndef lint static char sccsid[] = "@(#)cvrs.c 9.2 88/01/19"; #endif /* * Copyright (c) 1987 by Sun Microsystems, Inc. * * cvrs.c: convert radixed number to string * * Mon May 26 20:51:07 PDT 1986 * * Jerry Farrell * Sun Microsystems * * + other string operators (JAG) */ #ifdef REF #include #include #endif #include "PostScript.h" #define error_return(code) {ee->error_code = code; return;} static char digs[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static struct object null_object; static struct object cvrs_internal(); /* n r str CVRS substr */ static cvrs(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop; register int radix, num; struct object ret; if (optop[-1].type != string_type ) /* str */ error_return(typecheck_error_code); if (body_of(optop - 1)->readonly) error_return(invalidaccess_error_code); switch (optop[-2].type) { /* radix */ case fixed_type: radix = cfloorfr(optop[-2].value.fixed); break; case real_type: radix = optop[-2].value.real; break; default: error_return(typecheck_error_code); } if (radix < 2 || radix > 36) error_return(rangecheck_error_code); switch (optop[-3].type) { /* num */ case fixed_type: num = cfloorfr(optop[-3].value.fixed); break; case real_type: num = optop[-3].value.real; break; default: error_return(typecheck_error_code); } ret = cvrs_internal(num, radix, optop - 1); if (ret.type == null_type) error_return(limitcheck_error_code); optop[-3] = ret; ee->optop -= 2; return; /* reset ee->error_code? */ } #define BUFSIZE ((sizeof(int)*8)+2) static struct object cvrs_internal(num, radix, s_obj) register int num; register short radix; register struct object *s_obj; { register int i, limit, negative = 0; register char *c_ptr; register struct body *p; char buf[BUFSIZE + 1]; struct object ret; p = body_of(s_obj); ret = *s_obj; limit = p->body.string.size; if (limit > BUFSIZE) limit = BUFSIZE; if (num < 0) { negative = 1; limit--; num = -num; } i = 0; do { buf[i++] = digs[num % radix]; if (i > limit) { clear_object(&ret); return ret; } num /= radix; } while (num > 0); ret.value.substring.start = 0; ret.value.substring.length = i + negative; c_ptr = p->body.string.chars; if (negative) *c_ptr++ = '-'; while (i > 0) { *c_ptr++ = buf[--i]; } return ret; } static search(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop; int anchored = ee->execee.value.def->index; int seekl; struct body *stringb, *seekb; register char *string, *seek; char *string0, *limit; if (optop[-1].type != string_type || optop[-2].type != string_type) error_return(typecheck_error_code); stringb = body_of(optop - 2); string = stringb->body.string.chars + optop[-2].value.substring.start; seekb = body_of(optop - 1); seek = seekb->body.string.chars + optop[-1].value.substring.start; seekl = optop[-1].value.substring.length; if (optop[-1].value.substring.length > optop[-2].value.substring.length) goto match_failed; if (anchored) if (strncmp(string, seek, optop[-1].value.substring.length) == 0) { optop[-1] = optop[-2]; optop[-1].value.substring.length = seekl; optop[-2].value.substring.length -= seekl; optop[-2].value.substring.start += seekl; match_suceeded: incref(stringb); set_typed_object(optop, boolean_type); optop[0].value.fixed = fracti(1); optop++; ee->optop = optop; decref(seekb); return; } else goto match_failed; string0 = string; limit = string + optop[-2].value.substring.length - seekl; while (string <= limit) if (*string++ == *seek && strncmp(string - 1, seek, seekl) == 0) { int prelen = string - 1 - string0; optop[-1] = optop[-2]; optop[0] = optop[-2]; optop[-2].value.substring.start += prelen + seekl; optop[-2].value.substring.length -= prelen + seekl; optop[-1].value.substring.start += prelen; optop[-1].value.substring.length = seekl; optop[0].value.substring.length = prelen; optop++; incref(stringb); goto match_suceeded; } match_failed: set_typed_object(optop - 1, boolean_type); optop[-1].value.fixed = 0; decref(seekb); } initialize_cvrs() { define_operator("cvrs", cvrs, 0, 3, 1); define_operator("search", search, 0, 2, 4); define_operator("anchorsearch", search, 1, 2, 4); }