2 * Copyright © 2008 Chris Wilson <chris@chris-wilson.co.uk>
4 * This library is free software; you can redistribute it and/or
5 * modify it either under the terms of the GNU Lesser General Public
6 * License version 2.1 as published by the Free Software Foundation
7 * (the "LGPL") or, at your option, under the terms of the Mozilla
8 * Public License Version 1.1 (the "MPL"). If you do not alter this
9 * notice, a recipient may use your version of this file under either
10 * the MPL or the LGPL.
12 * You should have received a copy of the LGPL along with this library
13 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
15 * You should have received a copy of the MPL along with this library
16 * in the file COPYING-MPL-1.1
18 * The contents of this file are subject to the Mozilla Public License
19 * Version 1.1 (the "License"); you may not use this file except in
20 * compliance with the License. You may obtain a copy of the License at
21 * http://www.mozilla.org/MPL/
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
24 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
25 * the specific language governing rights and limitations.
27 * The Original Code is the cairo graphics library.
29 * The Initial Developer of the Original Code is Chris Wilson.
32 * Chris Wilson <chris@chris-wilson.co.uk>
35 #include "cairo-script-private.h"
37 #include <limits.h> /* INT_MAX */
38 #include <math.h> /* pow */
39 #include <stdio.h> /* EOF */
40 #include <stdint.h> /* for {INT,UINT}*_{MIN,MAX} */
41 #include <stdlib.h> /* malloc/free */
42 #include <string.h> /* memset */
47 #include <lzo/lzo2a.h>
53 #define le16(x) bswap_16 (x)
54 #define le32(x) bswap_32 (x)
61 #define be16(x) bswap_16 (x)
62 #define be32(x) bswap_32 (x)
63 #define to_be32(x) bswap_32 (x)
75 * ( = 28, ) = 29 - literal strings
76 * < = 3C, > = 3E - hex/base85 strings, dictionary name
77 * [ = 5B, ] = 5D - array
78 * { = 7B, } = 7C - procedure
79 * / = 5C - literal marker
84 fprintf_obj (FILE *stream, csi_t *ctx, const csi_object_t *obj)
86 switch (csi_object_get_type (obj)) {
87 case CSI_OBJECT_TYPE_NULL:
88 fprintf (stream, "NULL\n");
92 case CSI_OBJECT_TYPE_BOOLEAN:
93 fprintf (stream, "boolean: %s\n",
94 obj->datum.boolean ? "true" : "false");
96 case CSI_OBJECT_TYPE_INTEGER:
97 fprintf (stream, "integer: %ld\n", obj->datum.integer);
99 case CSI_OBJECT_TYPE_MARK:
100 fprintf (stream, "mark\n");
102 case CSI_OBJECT_TYPE_NAME:
103 fprintf (stream, "name: %s\n", (char *) obj->datum.name);
105 case CSI_OBJECT_TYPE_OPERATOR:
106 fprintf (stream, "operator: %p\n", obj->datum.ptr);
108 case CSI_OBJECT_TYPE_REAL:
109 fprintf (stream, "real: %g\n", obj->datum.real);
113 case CSI_OBJECT_TYPE_ARRAY:
114 fprintf (stream, "array\n");
116 case CSI_OBJECT_TYPE_DICTIONARY:
117 fprintf (stream, "dictionary\n");
119 case CSI_OBJECT_TYPE_FILE:
120 fprintf (stream, "file\n");
122 case CSI_OBJECT_TYPE_MATRIX:
123 fprintf (stream, "matrix: [%g %g %g %g %g %g]\n",
124 obj->datum.matrix->matrix.xx,
125 obj->datum.matrix->matrix.yx,
126 obj->datum.matrix->matrix.xy,
127 obj->datum.matrix->matrix.yy,
128 obj->datum.matrix->matrix.x0,
129 obj->datum.matrix->matrix.y0);
131 case CSI_OBJECT_TYPE_STRING:
132 fprintf (stream, "string: len=%ld, defate=%ld, method=%d\n",
133 obj->datum.string->len, obj->datum.string->deflate, obj->datum.string->method);
137 case CSI_OBJECT_TYPE_CONTEXT:
138 fprintf (stream, "context\n");
140 case CSI_OBJECT_TYPE_FONT:
141 fprintf (stream, "font\n");
143 case CSI_OBJECT_TYPE_PATTERN:
144 fprintf (stream, "pattern\n");
146 case CSI_OBJECT_TYPE_SCALED_FONT:
147 fprintf (stream, "scaled-font\n");
149 case CSI_OBJECT_TYPE_SURFACE:
150 fprintf (stream, "surface\n");
155 /* takes ownership of obj */
156 static inline csi_status_t
157 scan_push (csi_t *ctx, csi_object_t *obj)
159 return ctx->scanner.push (ctx, obj);
162 static inline csi_status_t
163 scan_execute (csi_t *ctx, csi_object_t *obj)
165 return ctx->scanner.execute (ctx, obj);
168 static cairo_status_t
169 buffer_init (csi_t *ctx, csi_buffer_t *buffer)
171 cairo_status_t status = CSI_STATUS_SUCCESS;
173 buffer->size = 16384;
174 buffer->base = _csi_alloc (ctx, buffer->size);
175 if (_csi_unlikely (buffer->base == NULL)) {
176 status = _csi_error (CSI_STATUS_NO_MEMORY);
180 buffer->ptr = buffer->base;
181 buffer->end = buffer->base + buffer->size;
187 buffer_fini (csi_t *ctx, csi_buffer_t *buffer)
189 _csi_free (ctx, buffer->base);
193 _buffer_grow (csi_t *ctx, csi_scanner_t *scan)
199 if (_csi_unlikely (scan->buffer.size > INT_MAX / 2))
200 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_NO_MEMORY));
202 offset = scan->buffer.ptr - scan->buffer.base;
203 newsize = scan->buffer.size * 2;
204 base = _csi_realloc (ctx, scan->buffer.base, newsize);
205 if (_csi_unlikely (base == NULL))
206 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_NO_MEMORY));
208 scan->buffer.base = base;
209 scan->buffer.ptr = base + offset;
210 scan->buffer.end = base + newsize;
211 scan->buffer.size = newsize;
215 buffer_check (csi_t *ctx, csi_scanner_t *scan, int count)
217 if (_csi_unlikely (scan->buffer.ptr + count > scan->buffer.end))
218 _buffer_grow (ctx, scan);
222 buffer_add (csi_buffer_t *buffer, int c)
228 buffer_reset (csi_buffer_t *buffer)
230 buffer->ptr = buffer->base;
234 token_start (csi_scanner_t *scan)
236 buffer_reset (&scan->buffer);
240 token_add (csi_t *ctx, csi_scanner_t *scan, int c)
242 buffer_check (ctx, scan, 1);
243 buffer_add (&scan->buffer, c);
247 token_add_unchecked (csi_scanner_t *scan, int c)
249 buffer_add (&scan->buffer, c);
253 _csi_parse_number (csi_object_t *obj, const char *s, int len)
256 long long mantissa = 0;
260 int exponent_sign = 0;
261 const char * const end = s + len;
290 if (_csi_unlikely (radix))
292 if (_csi_unlikely (decimal != -1))
294 if (_csi_unlikely (exponent_sign))
298 } else if (*s == '!') {
299 if (_csi_unlikely (radix))
301 if (_csi_unlikely (decimal != -1))
303 if (_csi_unlikely (exponent_sign))
309 if (_csi_unlikely (radix < 2 || radix > 36))
313 } else if (*s <= '9') {
315 if (_csi_unlikely (radix && v >= radix))
319 exponent = 10 * exponent + v;
322 mantissa = radix * mantissa + v;
324 mantissa = 10 * mantissa + v;
328 } else if (*s == 'E' || * s== 'e') {
330 if (_csi_unlikely (s + 1 == end))
337 } else if (s[1] == '+')
342 if (_csi_unlikely (v >= radix))
345 mantissa = radix * mantissa + v;
347 } else if (*s < 'A') {
349 } else if (*s <= 'Z') {
350 int v = *s - 'A' + 0xA;
352 if (_csi_unlikely (v >= radix))
355 mantissa = radix * mantissa + v;
356 } else if (*s < 'a') {
358 } else if (*s <= 'z') {
359 int v = *s - 'a' + 0xa;
361 if (_csi_unlikely (v >= radix))
364 mantissa = radix * mantissa + v;
369 if (exponent_sign || decimal != -1) {
371 obj->type = CSI_OBJECT_TYPE_REAL;
372 obj->datum.real = 0.;
379 e = exponent * exponent_sign;
383 case -7: v *= 0.0000001; break;
384 case -6: v *= 0.000001; break;
385 case -5: v *= 0.00001; break;
386 case -4: v *= 0.0001; break;
387 case -3: v *= 0.001; break;
388 case -2: v *= 0.01; break;
389 case -1: v *= 0.1; break;
391 case 1: v *= 10; break;
392 case 2: v *= 100; break;
393 case 3: v *= 1000; break;
394 case 4: v *= 10000; break;
395 case 5: v *= 100000; break;
396 case 6: v *= 1000000; break;
398 v *= pow (10, e); /* XXX */
402 obj->type = CSI_OBJECT_TYPE_REAL;
403 obj->datum.real = sign * v;
407 obj->type = CSI_OBJECT_TYPE_INTEGER;
408 obj->datum.integer = sign * mantissa;
414 token_end (csi_t *ctx, csi_scanner_t *scan, csi_file_t *src)
416 cairo_status_t status;
422 * Any token that consists entirely of regular characters and
423 * cannot be interpreted as a number is treated as a name object
424 * (more precisely, an executable name). All characters except
425 * delimiters and white-space characters can appear in names,
426 * including characters ordinarily considered to be punctuation.
429 if (_csi_unlikely (scan->buffer.ptr == scan->buffer.base))
432 s = scan->buffer.base;
433 len = scan->buffer.ptr - scan->buffer.base;
435 if (_csi_likely (! scan->bind)) {
436 if (s[0] == '{') { /* special case procedures */
437 if (scan->build_procedure.type != CSI_OBJECT_TYPE_NULL) {
438 status = _csi_stack_push (ctx,
439 &scan->procedure_stack,
440 &scan->build_procedure);
441 if (_csi_unlikely (status))
442 longjmp (scan->jmpbuf, status);
445 status = csi_array_new (ctx, 0, &scan->build_procedure);
446 if (_csi_unlikely (status))
447 longjmp (scan->jmpbuf, status);
449 scan->build_procedure.type |= CSI_OBJECT_ATTR_EXECUTABLE;
451 } else if (s[0] == '}') {
453 (scan->build_procedure.type == CSI_OBJECT_TYPE_NULL))
455 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
458 if (scan->procedure_stack.len) {
461 next = _csi_stack_peek (&scan->procedure_stack, 0);
463 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_NULL_POINTER));
467 status = csi_array_append (ctx, next->datum.array,
468 &scan->build_procedure);
469 scan->build_procedure = *next;
470 scan->procedure_stack.len--;
472 status = scan_push (ctx, &scan->build_procedure);
473 scan->build_procedure.type = CSI_OBJECT_TYPE_NULL;
475 if (_csi_unlikely (status))
476 longjmp (scan->jmpbuf, status);
483 if (len >= 2 && s[1] == '/') { /* substituted name */
484 status = csi_name_new (ctx, &obj, s + 2, len - 2);
485 if (_csi_unlikely (status))
486 longjmp (scan->jmpbuf, status);
488 status = _csi_name_lookup (ctx, obj.datum.name, &obj);
489 } else { /* literal name */
490 status = csi_name_new (ctx, &obj, s + 1, len - 1);
492 if (_csi_unlikely (status))
493 longjmp (scan->jmpbuf, status);
495 if (! _csi_parse_number (&obj, s, len)) {
496 status = csi_name_new (ctx, &obj, s, len);
497 if (_csi_unlikely (status))
498 longjmp (scan->jmpbuf, status);
500 obj.type |= CSI_OBJECT_ATTR_EXECUTABLE;
504 /* consume whitespace after token, before calling the interpreter */
505 if (scan->build_procedure.type != CSI_OBJECT_TYPE_NULL) {
506 status = csi_array_append (ctx,
507 scan->build_procedure.datum.array,
509 } else if (obj.type & CSI_OBJECT_ATTR_EXECUTABLE) {
510 status = scan_execute (ctx, &obj);
511 csi_object_free (ctx, &obj);
513 status = scan_push (ctx, &obj);
515 if (_csi_unlikely (status))
516 longjmp (scan->jmpbuf, status);
520 string_add (csi_t *ctx, csi_scanner_t *scan, int c)
522 buffer_check (ctx, scan, 1);
523 buffer_add (&scan->buffer, c);
527 string_end (csi_t *ctx, csi_scanner_t *scan)
530 cairo_status_t status;
532 status = csi_string_new (ctx,
535 scan->buffer.ptr - scan->buffer.base);
536 if (_csi_unlikely (status))
537 longjmp (scan->jmpbuf, status);
539 if (scan->build_procedure.type != CSI_OBJECT_TYPE_NULL)
540 status = csi_array_append (ctx,
541 scan->build_procedure.datum.array,
544 status = scan_push (ctx, &obj);
545 if (_csi_unlikely (status))
546 longjmp (scan->jmpbuf, status);
560 return c - 'a' + 0xa;
565 hex_add (csi_t *ctx, csi_scanner_t *scan, int c)
567 if (scan->accumulator_count == 0) {
568 scan->accumulator |= hex_value (c) << 4;
569 scan->accumulator_count = 1;
571 scan->accumulator |= hex_value (c) << 0;
572 buffer_check (ctx, scan, 1);
573 buffer_add (&scan->buffer, scan->accumulator);
575 scan->accumulator = 0;
576 scan->accumulator_count = 0;
581 hex_end (csi_t *ctx, csi_scanner_t *scan)
584 cairo_status_t status;
586 if (scan->accumulator_count)
587 hex_add (ctx, scan, '0');
589 status = csi_string_new (ctx,
592 scan->buffer.ptr - scan->buffer.base);
593 if (_csi_unlikely (status))
594 longjmp (scan->jmpbuf, status);
596 if (scan->build_procedure.type != CSI_OBJECT_TYPE_NULL)
597 status = csi_array_append (ctx,
598 scan->build_procedure.datum.array,
601 status = scan_push (ctx, &obj);
602 if (_csi_unlikely (status))
603 longjmp (scan->jmpbuf, status);
607 base85_add (csi_t *ctx, csi_scanner_t *scan, int c)
610 if (_csi_unlikely (scan->accumulator_count != 0))
611 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
613 buffer_check (ctx, scan, 4);
614 buffer_add (&scan->buffer, 0);
615 buffer_add (&scan->buffer, 0);
616 buffer_add (&scan->buffer, 0);
617 buffer_add (&scan->buffer, 0);
618 } else if (_csi_unlikely (c < '!' || c > 'u')) {
619 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
621 scan->accumulator = scan->accumulator*85 + c - '!';
622 if (++scan->accumulator_count == 5) {
623 buffer_check (ctx, scan, 4);
624 buffer_add (&scan->buffer, (scan->accumulator >> 24) & 0xff);
625 buffer_add (&scan->buffer, (scan->accumulator >> 16) & 0xff);
626 buffer_add (&scan->buffer, (scan->accumulator >> 8) & 0xff);
627 buffer_add (&scan->buffer, (scan->accumulator >> 0) & 0xff);
629 scan->accumulator = 0;
630 scan->accumulator_count = 0;
636 base85_end (csi_t *ctx, csi_scanner_t *scan, cairo_bool_t deflate)
639 cairo_status_t status;
641 buffer_check (ctx, scan, 4);
643 switch (scan->accumulator_count) {
647 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
651 scan->accumulator = scan->accumulator * (85*85*85) + 85*85*85 -1;
652 buffer_add (&scan->buffer, (scan->accumulator >> 24) & 0xff);
655 scan->accumulator = scan->accumulator * (85*85) + 85*85 -1;
656 buffer_add (&scan->buffer, (scan->accumulator >> 24) & 0xff);
657 buffer_add (&scan->buffer, (scan->accumulator >> 16) & 0xff);
660 scan->accumulator = scan->accumulator * 85 + 84;
661 buffer_add (&scan->buffer, (scan->accumulator >> 24) & 0xff);
662 buffer_add (&scan->buffer, (scan->accumulator >> 16) & 0xff);
663 buffer_add (&scan->buffer, (scan->accumulator >> 8) & 0xff);
668 uLongf len = be32 (*(uint32_t *) scan->buffer.base);
669 Bytef *source = (Bytef *) (scan->buffer.base + sizeof (uint32_t));
671 status = csi_string_deflate_new (ctx, &obj,
673 (Bytef *) scan->buffer.ptr - source,
675 if (_csi_unlikely (status))
676 longjmp (scan->jmpbuf, status);
678 status = csi_string_new (ctx,
681 scan->buffer.ptr - scan->buffer.base);
682 if (_csi_unlikely (status))
683 longjmp (scan->jmpbuf, status);
686 if (scan->build_procedure.type != CSI_OBJECT_TYPE_NULL)
687 status = csi_array_append (ctx,
688 scan->build_procedure.datum.array,
691 status = scan_push (ctx, &obj);
692 if (_csi_unlikely (status))
693 longjmp (scan->jmpbuf, status);
697 base64_add (csi_t *ctx, csi_scanner_t *scan, int c)
701 /* Convert Base64 character to its 6 bit nibble */
702 val = scan->accumulator;
704 val = (val << 6) | 63;
705 } else if (c =='+') {
706 val = (val << 6) | 62;
707 } else if (c >='A' && c <='Z') {
708 val = (val << 6) | (c -'A');
709 } else if (c >='a' && c <='z') {
710 val = (val << 6) | (c -'a' + 26);
711 } else if (c >='0' && c <='9') {
712 val = (val << 6) | (c -'0' + 52);
715 buffer_check (ctx, scan, 1);
716 switch (scan->accumulator_count++) {
721 buffer_add (&scan->buffer, (val >> 4) & 0xFF);
726 buffer_add (&scan->buffer, (val >> 2) & 0xFF);
731 buffer_add (&scan->buffer, (val >> 0) & 0xFF);
732 scan->accumulator_count = 0;
738 scan->accumulator_count = 0;
739 scan->accumulator = 0;
741 scan->accumulator = val;
746 base64_end (csi_t *ctx, csi_scanner_t *scan)
749 cairo_status_t status;
751 switch (scan->accumulator_count) {
755 base64_add (ctx, scan, (scan->accumulator << 2) & 0x3f);
756 base64_add (ctx, scan, '=');
759 base64_add (ctx, scan, (scan->accumulator << 4) & 0x3f);
760 base64_add (ctx, scan, '=');
761 base64_add (ctx, scan, '=');
765 status = csi_string_new (ctx,
768 scan->buffer.ptr - scan->buffer.base);
769 if (_csi_unlikely (status))
770 longjmp (scan->jmpbuf, status);
772 if (scan->build_procedure.type != CSI_OBJECT_TYPE_NULL)
773 status = csi_array_append (ctx,
774 scan->build_procedure.datum.array,
777 status = scan_push (ctx, &obj);
778 if (_csi_unlikely (status))
779 longjmp (scan->jmpbuf, status);
783 scan_read (csi_scanner_t *scan, csi_file_t *src, void *ptr, int len)
787 int ret = csi_file_read (src, data, len);
788 if (_csi_unlikely (ret == 0))
789 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_READ_ERROR));
792 } while (_csi_unlikely (len));
796 string_read (csi_t *ctx,
805 status = csi_string_new (ctx, obj, NULL, len);
806 if (_csi_unlikely (status))
807 longjmp (scan->jmpbuf, status);
811 scan_read (scan, src, &u32, 4);
812 obj->datum.string->deflate = be32 (u32);
813 obj->datum.string->method = compressed;
816 if (_csi_likely (len))
817 scan_read (scan, src, obj->datum.string->string, len);
818 obj->datum.string->string[len] = '\0';
822 _scan_file (csi_t *ctx, csi_file_t *src)
824 csi_scanner_t *scan = &ctx->scanner;
839 while ((c = csi_file_getc (src)) != EOF) {
840 csi_object_t obj = { CSI_OBJECT_TYPE_NULL };
849 case 0x20: /* ignore whitespace */
858 case '[': /* needs special case */
863 token_add_unchecked (scan, c);
864 token_end (ctx, scan, src);
868 next = csi_file_getc (src);
871 csi_file_putc (src, '<');
874 /* dictionary name */
876 token_add_unchecked (scan, '<');
877 token_add_unchecked (scan, '<');
878 token_end (ctx, scan, src);
887 csi_file_putc (src, next);
894 #define MSB_UINT8 129
895 #define MSB_INT16 130
896 #define MSB_UINT16 131
897 #define MSB_INT32 132
898 #define LSB_INT8 MSB_INT8
899 #define LSB_UINT8 MSB_UINT8
900 #define LSB_INT16 133
901 #define LSB_UINT16 134
902 #define LSB_INT32 135
903 #define MSB_FLOAT32 140
904 #define LSB_FLOAT32 141
906 scan_read (scan, src, &u.i8, 1);
907 csi_integer_new (&obj, u.i8);
910 scan_read (scan, src, &u.u8, 1);
911 csi_integer_new (&obj, u.u8);
914 scan_read (scan, src, &u.i16, 2);
915 csi_integer_new (&obj, be16 (u.i16));
918 scan_read (scan, src, &u.i16, 2);
919 csi_integer_new (&obj, le16 (u.i16));
922 scan_read (scan, src, &u.u16, 2);
923 csi_integer_new (&obj, be16 (u.u16));
926 scan_read (scan, src, &u.u16, 2);
927 csi_integer_new (&obj, le16 (u.u16));
930 scan_read (scan, src, &u.i32, 4);
931 csi_integer_new (&obj, be32 (u.i32));
934 scan_read (scan, src, &u.i32, 4);
935 csi_integer_new (&obj, le32 (u.i32));
938 case 136: /* 16.16 msb */
939 scan_read (scan, src, &u.i32, 4);
940 csi_real_new (&obj, be32 (u.i32) / 65536.);
942 case 137: /* 16.16 lsb */
943 scan_read (scan, src, &u.i32, 4);
944 csi_real_new (&obj, le32 (u.i32) / 65536.);
946 case 138: /* 24.8 msb */
947 scan_read (scan, src, &u.i32, 4);
948 csi_real_new (&obj, be32 (u.i32) / 256.);
950 case 139: /* 24.8 lsb */
951 scan_read (scan, src, &u.i32, 4);
952 csi_real_new (&obj, le32 (u.i32) / 256.);
955 scan_read (scan, src, &u.i32, 4);
956 u.i32 = be32 (u.i32);
957 csi_real_new (&obj, u.f);
960 scan_read (scan, src, &u.i32, 4);
961 u.i32 = le32 (u.i32);
962 csi_real_new (&obj, u.f);
966 #define STRING_2_MSB 144
967 #define STRING_2_LSB 146
968 #define STRING_4_MSB 148
969 #define STRING_4_LSB 150
970 #define STRING_DEFLATE 1
972 case STRING_1 | STRING_DEFLATE:
973 scan_read (scan, src, &u.u8, 1);
974 string_read (ctx, scan, src, u.u8, c & STRING_DEFLATE, &obj);
977 case STRING_2_MSB | STRING_DEFLATE:
978 scan_read (scan, src, &u.u16, 2);
979 string_read (ctx, scan, src, be16 (u.u16), c & STRING_DEFLATE, &obj);
982 case STRING_2_LSB | STRING_DEFLATE:
983 scan_read (scan, src, &u.u16, 2);
984 string_read (ctx, scan, src, le16 (u.u16), c & STRING_DEFLATE, &obj);
987 case STRING_4_MSB | STRING_DEFLATE:
988 scan_read (scan, src, &u.u32, 4);
989 string_read (ctx, scan, src, be32 (u.u32), c & STRING_DEFLATE, &obj);
992 case STRING_4_LSB | STRING_DEFLATE:
993 scan_read (scan, src, &u.u32, 4);
994 string_read (ctx, scan, src, le32 (u.u32), c & STRING_DEFLATE, &obj);
999 scan_read (scan, src, &u.u8, 1);
1000 csi_operator_new (&obj, ctx->opcode[u.u8]);
1004 scan_read (scan, src, &u.u8, 1);
1005 csi_operator_new (&obj, ctx->opcode[u.u8]);
1006 obj.type &= ~CSI_OBJECT_ATTR_EXECUTABLE;
1009 #define STRING_LZO 154
1011 scan_read (scan, src, &u.u32, 4);
1012 string_read (ctx, scan, src, be32 (u.u32), LZO, &obj);
1021 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
1023 case '#': /* PDF 1.2 escape code */
1025 int c_hi = csi_file_getc (src);
1026 int c_lo = csi_file_getc (src);
1027 c = (hex_value (c_hi) << 4) | hex_value (c_lo);
1032 token_add_unchecked (scan, c);
1036 if (obj.type != CSI_OBJECT_TYPE_NULL) {
1037 cairo_status_t status;
1039 if (scan->build_procedure.type != CSI_OBJECT_TYPE_NULL) {
1040 status = csi_array_append (ctx,
1041 scan->build_procedure.datum.array,
1043 } else if (obj.type & CSI_OBJECT_ATTR_EXECUTABLE) {
1044 status = scan_execute (ctx, &obj);
1045 csi_object_free (ctx, &obj);
1047 status = scan_push (ctx, &obj);
1049 if (_csi_unlikely (status))
1050 longjmp (scan->jmpbuf, status);
1056 while ((c = csi_file_getc (src)) != EOF) {
1059 scan->line_number++;
1065 token_end (ctx, scan, src);
1068 /* syntax delimiters */
1070 token_end (ctx, scan, src);
1074 token_end (ctx, scan, src);
1076 /* XXX syntax error? */
1078 token_end (ctx, scan, src);
1081 /* need to special case '^//?' */
1082 if (scan->buffer.ptr > scan->buffer.base+1 ||
1083 scan->buffer.base[0] != '/')
1085 token_end (ctx, scan, src);
1088 token_add_unchecked (scan, '/');
1094 token_end (ctx, scan, src);
1096 token_add_unchecked (scan, c);
1097 token_end (ctx, scan, src);
1101 csi_file_putc (src, '<');
1102 token_end (ctx, scan, src);
1105 case '#': /* PDF 1.2 escape code */
1107 int c_hi = csi_file_getc (src);
1108 int c_lo = csi_file_getc (src);
1109 c = (hex_value (c_hi) << 4) | hex_value (c_lo);
1113 token_add (ctx, scan, c);
1117 token_end (ctx, scan, src);
1121 /* discard until newline */
1122 while ((c = csi_file_getc (src)) != EOF) {
1125 scan->line_number++;
1133 buffer_reset (&scan->buffer);
1135 while ((c = csi_file_getc (src)) != EOF) {
1137 case '\\': /* escape */
1138 next = csi_file_getc (src);
1141 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
1144 string_add (ctx, scan, '\n');
1147 string_add (ctx, scan, '\r');
1150 string_add (ctx, scan, '\t');
1153 string_add (ctx, scan, '\b');
1156 string_add (ctx, scan, '\f');
1159 string_add (ctx, scan, '\\');
1162 string_add (ctx, scan, '(');
1165 string_add (ctx, scan, ')');
1168 case '0': case '1': case '2': case '3':
1169 case '4': case '5': case '6': case '7':
1170 { /* octal code: \d{1,3} */
1175 for (i = 0; i < 2; i++) {
1176 next = csi_file_getc (src);
1181 case '0': case '1': case '2': case '3':
1182 case '4': case '5': case '6': case '7':
1187 csi_file_putc (src, next);
1188 goto octal_code_done;
1192 string_add (ctx, scan, c);
1197 /* skip the newline */
1198 next = csi_file_getc (src); /* might be compound LFCR */
1205 csi_file_putc (src, next);
1208 scan->line_number++;
1214 /* ignore the '\' */
1221 string_add (ctx, scan, c);
1225 if (--string_p == 0) {
1226 string_end (ctx, scan);
1231 string_add (ctx, scan, c);
1235 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
1238 buffer_reset (&scan->buffer);
1239 scan->accumulator_count = 0;
1240 scan->accumulator = 0;
1241 while ((c = csi_file_getc (src)) != EOF) {
1244 scan->line_number++;
1249 case 0x20: /* ignore whitespace */
1253 hex_end (ctx, scan); /* fixup odd digit with '0' */
1278 hex_add (ctx, scan, c);
1282 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
1285 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
1288 buffer_reset (&scan->buffer);
1289 scan->accumulator = 0;
1290 scan->accumulator_count = 0;
1291 while ((c = csi_file_getc (src)) != EOF) {
1294 next = csi_file_getc (src);
1300 base85_end (ctx, scan, deflate);
1304 csi_file_putc (src, next);
1308 base85_add (ctx, scan, c);
1312 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
1315 buffer_reset (&scan->buffer);
1316 scan->accumulator = 0;
1317 scan->accumulator_count = 0;
1318 while ((c = csi_file_getc (src)) != EOF) {
1321 next = csi_file_getc (src);
1327 base64_end (ctx, scan);
1330 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
1333 base64_add (ctx, scan, c);
1337 longjmp (scan->jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
1341 _scan_push (csi_t *ctx, csi_object_t *obj)
1344 fprintf (stderr, "push ");
1345 fprintf_obj (stderr, ctx, obj);
1347 return _csi_push_ostack (ctx, obj);
1351 _scan_execute (csi_t *ctx, csi_object_t *obj)
1354 fprintf (stderr, "exec ");
1355 fprintf_obj (stderr, ctx, obj);
1357 return csi_object_execute (ctx, obj);
1361 _csi_scanner_init (csi_t *ctx, csi_scanner_t *scanner)
1363 csi_status_t status;
1365 memset (scanner, 0, sizeof (csi_scanner_t));
1367 status = buffer_init (ctx, &scanner->buffer);
1371 status = _csi_stack_init (ctx, &scanner->procedure_stack, 4);
1376 scanner->push = _scan_push;
1377 scanner->execute = _scan_execute;
1379 return CSI_STATUS_SUCCESS;
1383 _csi_scanner_fini (csi_t *ctx, csi_scanner_t *scanner)
1385 buffer_fini (ctx, &scanner->buffer);
1386 _csi_stack_fini (ctx, &scanner->procedure_stack);
1387 if (scanner->build_procedure.type != CSI_OBJECT_TYPE_NULL)
1388 csi_object_free (ctx, &scanner->build_procedure);
1392 _csi_scan_file (csi_t *ctx, csi_file_t *src)
1394 csi_status_t status;
1395 int old_line_number;
1397 /* This function needs to be reentrant to handle recursive scanners.
1398 * i.e. one script executes a second.
1401 if (ctx->scanner.depth++ == 0) {
1402 if ((status = setjmp (ctx->scanner.jmpbuf))) {
1403 ctx->scanner.depth = 0;
1408 old_line_number = ctx->scanner.line_number;
1409 ctx->scanner.line_number = 0;
1411 _scan_file (ctx, src);
1413 ctx->scanner.line_number = old_line_number;
1415 --ctx->scanner.depth;
1416 return CSI_STATUS_SUCCESS;
1419 struct _translate_closure {
1420 csi_dictionary_t *opcodes;
1421 cairo_write_func_t write_func;
1426 _translate_name (csi_t *ctx,
1428 csi_boolean_t executable,
1429 struct _translate_closure *closure)
1432 csi_dictionary_entry_t *entry;
1435 /* Bind executable names.
1436 * XXX This may break some scripts that overload system operators.
1438 entry = _csi_hash_table_lookup (&closure->opcodes->hash_table,
1439 (csi_hash_entry_t *) &name);
1443 u16 = entry->value.datum.integer;
1445 closure->write_func (closure->closure, (unsigned char *) &u16, 2);
1447 closure->write_func (closure->closure, (unsigned char *) "/", 1);
1449 closure->write_func (closure->closure,
1450 (unsigned char *) name,
1451 strlen ((char *) name));
1452 closure->write_func (closure->closure, (unsigned char *) "\n", 1);
1455 return CSI_STATUS_SUCCESS;
1459 _translate_operator (csi_t *ctx,
1461 csi_boolean_t executable,
1462 struct _translate_closure *closure)
1464 csi_dictionary_entry_t *entry;
1467 entry = _csi_hash_table_lookup (&closure->opcodes->hash_table,
1468 (csi_hash_entry_t *) &op);
1470 return _csi_error (CSI_STATUS_INVALID_SCRIPT);
1472 u16 = entry->value.datum.integer;
1476 closure->write_func (closure->closure, (unsigned char *) &u16, 2);
1478 return CSI_STATUS_SUCCESS;
1482 _translate_integer (csi_t *ctx,
1484 struct _translate_closure *closure)
1498 if (i < INT16_MIN) {
1502 } else if (i < INT8_MIN) {
1510 } else if (i <= UINT8_MAX) {
1514 } else if (i <= UINT16_MAX) {
1524 if (i < INT16_MIN) {
1528 } else if (i < INT8_MIN) {
1536 } else if (i <= UINT8_MAX) {
1540 } else if (i <= UINT16_MAX) {
1551 closure->write_func (closure->closure, (unsigned char *) &hdr, 1);
1552 closure->write_func (closure->closure, (unsigned char *) &u, len);
1554 return CSI_STATUS_SUCCESS;
1558 _translate_real (csi_t *ctx,
1560 struct _translate_closure *closure)
1564 if (real >= INT32_MIN && real <= INT32_MAX && (int) real == real)
1565 return _translate_integer (ctx, real, closure);
1572 closure->write_func (closure->closure, (unsigned char *) &hdr, 1);
1573 closure->write_func (closure->closure, (unsigned char *) &real, 4);
1575 return CSI_STATUS_SUCCESS;
1579 _translate_string (csi_t *ctx,
1580 csi_string_t *string,
1581 struct _translate_closure *closure)
1590 unsigned long hdr_len, buf_len, deflate;
1593 buf = string->string;
1594 buf_len = string->len;
1595 deflate = string->deflate;
1596 method = string->method;
1599 if (method == NONE && buf_len > 16) {
1600 unsigned long mem_len = 2*string->len > LZO2A_999_MEM_COMPRESS ? 2*string->len : LZO2A_999_MEM_COMPRESS;
1601 void *mem = malloc (mem_len);
1602 void *work = malloc(LZO2A_999_MEM_COMPRESS);
1606 return CSI_STATUS_NO_MEMORY;
1609 if (lzo2a_999_compress ((lzo_bytep) buf, buf_len,
1610 (lzo_bytep) mem, &mem_len,
1612 8+2*mem_len < buf_len)
1627 if (method == ZLIB) {
1628 buf_len = string->deflate;
1629 buf = malloc (string->deflate);
1630 if (uncompress ((Bytef *) buf, &buf_len,
1631 (Bytef *) string->string, string->len) == Z_OK)
1633 if (buf_len <= 8 + 2*string->len) {
1637 unsigned long mem_len = 2*string->deflate;
1638 void *mem = malloc (mem_len);
1639 void *work = malloc(LZO2A_999_MEM_COMPRESS);
1643 return CSI_STATUS_NO_MEMORY;
1646 if (lzo2a_999_compress ((lzo_bytep) buf, buf_len,
1647 (lzo_bytep) mem, &mem_len,
1650 if (8 + mem_len > buf_len) {
1667 buf = string->string;
1668 buf_len = string->len;
1677 buf = string->string;
1678 buf_len = string->len;
1684 if (method == LZO) {
1686 u.u32 = to_be32 (buf_len);
1690 if (buf_len <= UINT8_MAX) {
1694 } else if (buf_len <= UINT16_MAX) {
1704 if (buf_len <= UINT8_MAX) {
1708 } else if (buf_len <= UINT16_MAX) {
1719 assert (method == ZLIB);
1720 hdr |= STRING_DEFLATE;
1724 closure->write_func (closure->closure, (unsigned char *) &hdr, 1);
1725 closure->write_func (closure->closure, (unsigned char *) &u, hdr_len);
1727 uint32_t u32 = to_be32 (deflate);
1728 closure->write_func (closure->closure, (unsigned char *) &u32, 4);
1730 closure->write_func (closure->closure, (unsigned char *) buf, buf_len);
1732 if (buf != string->string)
1735 return CSI_STATUS_SUCCESS;
1739 _translate_push (csi_t *ctx, csi_object_t *obj)
1741 struct _translate_closure *closure = ctx->scanner.closure;
1744 fprintf (stderr, "push ");
1745 fprintf_obj (stderr, ctx, obj);
1748 switch (csi_object_get_type (obj)) {
1749 case CSI_OBJECT_TYPE_NAME:
1750 return _translate_name (ctx, obj->datum.name, FALSE, closure);
1752 case CSI_OBJECT_TYPE_OPERATOR:
1753 return _translate_operator (ctx, obj->datum.op, FALSE, closure);
1755 case CSI_OBJECT_TYPE_INTEGER:
1756 return _translate_integer (ctx, obj->datum.integer, closure);
1758 case CSI_OBJECT_TYPE_REAL:
1759 return _translate_real (ctx, obj->datum.real, closure);
1761 case CSI_OBJECT_TYPE_STRING:
1762 return _translate_string (ctx, obj->datum.string, closure);
1764 case CSI_OBJECT_TYPE_NULL:
1765 case CSI_OBJECT_TYPE_BOOLEAN:
1766 case CSI_OBJECT_TYPE_MARK:
1767 case CSI_OBJECT_TYPE_ARRAY:
1768 case CSI_OBJECT_TYPE_DICTIONARY:
1769 case CSI_OBJECT_TYPE_FILE:
1770 case CSI_OBJECT_TYPE_MATRIX:
1771 case CSI_OBJECT_TYPE_CONTEXT:
1772 case CSI_OBJECT_TYPE_FONT:
1773 case CSI_OBJECT_TYPE_PATTERN:
1774 case CSI_OBJECT_TYPE_SCALED_FONT:
1775 case CSI_OBJECT_TYPE_SURFACE:
1776 longjmp (ctx->scanner.jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
1780 csi_object_free (ctx, obj);
1781 return CSI_STATUS_SUCCESS;
1785 _translate_execute (csi_t *ctx, csi_object_t *obj)
1787 struct _translate_closure *closure = ctx->scanner.closure;
1790 fprintf (stderr, "exec ");
1791 fprintf_obj (stderr, ctx, obj);
1794 switch (csi_object_get_type (obj)) {
1795 case CSI_OBJECT_TYPE_NAME:
1796 return _translate_name (ctx, obj->datum.name, TRUE, closure);
1798 case CSI_OBJECT_TYPE_OPERATOR:
1799 return _translate_operator (ctx, obj->datum.op, TRUE, closure);
1801 case CSI_OBJECT_TYPE_INTEGER:
1802 return _translate_integer (ctx, obj->datum.integer, closure);
1804 case CSI_OBJECT_TYPE_REAL:
1805 return _translate_real (ctx, obj->datum.real, closure);
1807 case CSI_OBJECT_TYPE_STRING:
1808 return _translate_string (ctx, obj->datum.string, closure);
1810 case CSI_OBJECT_TYPE_NULL:
1811 case CSI_OBJECT_TYPE_BOOLEAN:
1812 case CSI_OBJECT_TYPE_MARK:
1813 case CSI_OBJECT_TYPE_ARRAY:
1814 case CSI_OBJECT_TYPE_DICTIONARY:
1815 case CSI_OBJECT_TYPE_FILE:
1816 case CSI_OBJECT_TYPE_MATRIX:
1817 case CSI_OBJECT_TYPE_CONTEXT:
1818 case CSI_OBJECT_TYPE_FONT:
1819 case CSI_OBJECT_TYPE_PATTERN:
1820 case CSI_OBJECT_TYPE_SCALED_FONT:
1821 case CSI_OBJECT_TYPE_SURFACE:
1822 longjmp (ctx->scanner.jmpbuf, _csi_error (CSI_STATUS_INVALID_SCRIPT));
1826 return CSI_STATUS_SUCCESS;
1830 build_opcodes (csi_t *ctx, csi_dictionary_t **out)
1833 csi_dictionary_t *dict;
1834 const csi_operator_def_t *def;
1835 csi_status_t status;
1836 int opcode = OPCODE << 8;
1838 status = csi_dictionary_new (ctx, &obj);
1839 if (_csi_unlikely (status))
1842 dict = obj.datum.dictionary;
1844 csi_integer_new (&obj, opcode++);
1845 status = csi_dictionary_put (ctx, dict, 0, &obj);
1846 if (_csi_unlikely (status))
1849 for (def = _csi_operators (); def->name != NULL; def++) {
1851 csi_dictionary_entry_t *entry;
1854 entry = _csi_hash_table_lookup (&dict->hash_table,
1855 (csi_hash_entry_t *) &def->op);
1856 if (entry == NULL) {
1858 csi_integer_new (&obj, code);
1859 status = csi_dictionary_put (ctx, dict, (csi_name_t) def->op, &obj);
1860 if (_csi_unlikely (status))
1863 code = entry->value.datum.integer;
1864 csi_integer_new (&obj, code);
1866 assert (ctx->opcode[code & 0xff] == def->op);
1868 status = csi_name_new_static (ctx, &name, def->name);
1869 if (_csi_unlikely (status))
1872 status = csi_dictionary_put (ctx, dict, name.datum.name, &obj);
1873 if (_csi_unlikely (status))
1878 return CSI_STATUS_SUCCESS;
1881 csi_dictionary_free (ctx, dict);
1886 _csi_translate_file (csi_t *ctx,
1888 cairo_write_func_t write_func,
1891 csi_status_t status;
1892 struct _translate_closure translator;
1894 if ((status = setjmp (ctx->scanner.jmpbuf)))
1897 status = build_opcodes (ctx, &translator.opcodes);
1898 if (_csi_unlikely (status))
1901 translator.write_func = write_func;
1902 translator.closure = closure;
1903 ctx->scanner.closure = &translator;
1905 ctx->scanner.bind = 1;
1906 ctx->scanner.push = _translate_push;
1907 ctx->scanner.execute = _translate_execute;
1909 _scan_file (ctx, file);
1911 ctx->scanner.bind = 0;
1912 ctx->scanner.push = _scan_push;
1913 ctx->scanner.execute = _scan_execute;
1915 csi_dictionary_free (ctx, translator.opcodes);
1917 return CSI_STATUS_SUCCESS;