From e2f912dc5bbfad3a6f4b5e1dbfbe51be148b3232 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 28 Jul 2009 09:32:36 +0100 Subject: [PATCH] [script] Add cvi, cvr, mod Add implementations of convert-to-integer, convert-to-real and modulus supplied by Zack Weinberg . --- util/cairo-script/cairo-script-operators.c | 95 +++++++++++++++++++++- util/cairo-script/cairo-script-private.h | 3 + util/cairo-script/cairo-script-scanner.c | 6 +- 3 files changed, 100 insertions(+), 4 deletions(-) diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c index b1f287eb3..81bbe7647 100644 --- a/util/cairo-script/cairo-script-operators.c +++ b/util/cairo-script/cairo-script-operators.c @@ -1108,6 +1108,78 @@ _curve_to (csi_t *ctx) return CSI_STATUS_SUCCESS; } +static csi_status_t +_cvi (csi_t *ctx) +{ + csi_object_t *val, obj; + + check (1); + + val = _csi_peek_ostack (ctx, 0); + + switch ((int) csi_object_get_type (val)) { + case CSI_OBJECT_TYPE_INTEGER: + return CSI_STATUS_SUCCESS; + + case CSI_OBJECT_TYPE_REAL: + pop (1); + return _csi_push_ostack_integer (ctx, val->datum.real); + + case CSI_OBJECT_TYPE_STRING: + if (! _csi_parse_number (&obj, + val->datum.string->string, + val->datum.string->len)) + { + return _csi_error (CSI_STATUS_INVALID_SCRIPT); + } + + pop (1); + if (csi_object_get_type (&obj) == CSI_OBJECT_TYPE_INTEGER) + return push (&obj); + else + return _csi_push_ostack_integer (ctx, obj.datum.real); + + default: + return _csi_error (CSI_STATUS_INVALID_SCRIPT); + } +} + +static csi_status_t +_cvr (csi_t *ctx) +{ + csi_object_t *val, obj; + + check (1); + + val = _csi_peek_ostack (ctx, 0); + + switch ((int) csi_object_get_type (val)) { + case CSI_OBJECT_TYPE_REAL: + return CSI_STATUS_SUCCESS; + + case CSI_OBJECT_TYPE_INTEGER: + pop (1); + return _csi_push_ostack_real (ctx, val->datum.integer); + + case CSI_OBJECT_TYPE_STRING: + if (! _csi_parse_number (&obj, + val->datum.string->string, + val->datum.string->len)) + { + return _csi_error (CSI_STATUS_INVALID_SCRIPT); + } + + pop (1); + if (csi_object_get_type (&obj) == CSI_OBJECT_TYPE_REAL) + return push (&obj); + else + return _csi_push_ostack_real (ctx, obj.datum.integer); + + default: + return _csi_error (CSI_STATUS_INVALID_SCRIPT); + } +} + static csi_status_t _def (csi_t *ctx) { @@ -3241,6 +3313,25 @@ _matrix (csi_t *ctx) return push (&matrix); } +static csi_status_t +_mod (csi_t *ctx) +{ + csi_integer_t x, y; + csi_status_t status; + + check (2); + + status = _csi_ostack_get_integer (ctx, 0, &y); + if (_csi_unlikely (status)) + return status; + status = _csi_ostack_get_integer (ctx, 1, &x); + if (_csi_unlikely (status)) + return status; + + pop (2); + return _csi_push_ostack_integer (ctx, x % y); +} + static csi_status_t _move_to (csi_t *ctx) { @@ -5548,6 +5639,8 @@ _defs[] = { { "count", NULL }, { "count-to-mark", NULL }, { "curve-to", _curve_to }, + { "cvi", _cvi }, + { "cvr", _cvr }, { "def", _def }, { "device-to-user", NULL }, { "device-to-user-distance", NULL }, @@ -5601,7 +5694,7 @@ _defs[] = { { "mark", _mark }, { "mask", _mask }, { "matrix", _matrix }, - { "mod", NULL }, + { "mod", _mod }, { "move-to", _move_to }, { "mul", _mul }, { "multiply", NULL }, diff --git a/util/cairo-script/cairo-script-private.h b/util/cairo-script/cairo-script-private.h index 54a840f2f..1fd8125df 100644 --- a/util/cairo-script/cairo-script-private.h +++ b/util/cairo-script/cairo-script-private.h @@ -824,6 +824,9 @@ _csi_translate_file (csi_t *ctx, csi_private void _csi_scanner_fini (csi_t *ctx, csi_scanner_t *scanner); +csi_private csi_boolean_t +_csi_parse_number (csi_object_t *obj, const char *s, int len); + /* cairo-script-stack.c */ csi_private csi_status_t diff --git a/util/cairo-script/cairo-script-scanner.c b/util/cairo-script/cairo-script-scanner.c index 1d717f4b5..fb2ce9a94 100644 --- a/util/cairo-script/cairo-script-scanner.c +++ b/util/cairo-script/cairo-script-scanner.c @@ -228,8 +228,8 @@ token_add_unchecked (csi_scanner_t *scan, int c) buffer_add (&scan->buffer, c); } -static csi_boolean_t -parse_number (csi_object_t *obj, const char *s, int len) +csi_boolean_t +_csi_parse_number (csi_object_t *obj, const char *s, int len) { int radix = 0; long long mantissa = 0; @@ -464,7 +464,7 @@ token_end (csi_t *ctx, csi_scanner_t *scan, csi_file_t *src) if (_csi_unlikely (status)) longjmp (scan->jmpbuf, status); } else { - if (! parse_number (&obj, s, len)) { + if (! _csi_parse_number (&obj, s, len)) { status = csi_name_new (ctx, &obj, s, len); if (_csi_unlikely (status)) longjmp (scan->jmpbuf, status);