3286bb4f9ce11687212bcc49035d31b3c4370a80
[platform/upstream/cairo.git] / util / cairo-script / cairo-script-private.h
1 /*
2  * Copyright © 2008 Chris Wilson <chris@chris-wilson.co.uk>
3  *
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.
11  *
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
17  *
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/
22  *
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.
26  *
27  * The Original Code is the cairo graphics library.
28  *
29  * The Initial Developer of the Original Code is Chris Wilson.
30  *
31  * Contributor(s):
32  *      Chris Wilson <chris@chris-wilson.co.uk>
33  */
34
35 #ifndef CAIRO_SCRIPT_PRIVATE_H
36 #define CAIRO_SCRIPT_PRIVATE_H
37
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41
42 #include "cairo-script-interpreter.h"
43
44 #include <setjmp.h>
45
46 #ifdef _MSC_VER
47 #undef inline
48 #define inline __inline
49 #endif
50
51 #ifndef FALSE
52 #define FALSE 0
53 #endif
54
55 #ifndef TRUE
56 #define TRUE (!FALSE)
57 #endif
58
59 #ifndef NULL
60 #define NULL (void *) 0
61 #endif
62
63 #if   HAVE_STDINT_H
64 # include <stdint.h>
65 #elif HAVE_INTTYPES_H
66 # include <inttypes.h>
67 #elif HAVE_SYS_INT_TYPES_H
68 # include <sys/int_types.h>
69 #elif defined(_MSC_VER)
70   typedef __int8 int8_t;
71   typedef unsigned __int8 uint8_t;
72   typedef __int16 int16_t;
73   typedef unsigned __int16 uint16_t;
74   typedef __int32 int32_t;
75   typedef unsigned __int32 uint32_t;
76   typedef __int64 int64_t;
77   typedef unsigned __int64 uint64_t;
78 # ifndef HAVE_UINT64_T
79 #  define HAVE_UINT64_T 1
80 # endif
81 #else
82 #error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
83 #endif
84
85 #if HAVE_BYTESWAP_H
86 # include <byteswap.h>
87 #endif
88 #ifndef bswap_16
89 # define bswap_16(p) \
90         (((((uint16_t)(p)) & 0x00ff) << 8) | \
91           (((uint16_t)(p))           >> 8))
92 #endif
93 #ifndef bswap_32
94 # define bswap_32(p) \
95          (((((uint32_t)(p)) & 0x000000ff) << 24) | \
96           ((((uint32_t)(p)) & 0x0000ff00) << 8)  | \
97           ((((uint32_t)(p)) & 0x00ff0000) >> 8)  | \
98           ((((uint32_t)(p)))              >> 24))
99 #endif
100
101
102 #if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun)
103 # define slim_hidden_proto(name)                slim_hidden_proto1(name, slim_hidden_int_name(name)) csi_private
104 # define slim_hidden_proto_no_warn(name)        slim_hidden_proto1(name, slim_hidden_int_name(name)) csi_private_no_warn
105 # define slim_hidden_def(name)                  slim_hidden_def1(name, slim_hidden_int_name(name))
106 # define slim_hidden_int_name(name) INT_##name
107 # define slim_hidden_proto1(name, internal)                             \
108   extern __typeof (name) name                                           \
109         __asm__ (slim_hidden_asmname (internal))
110 # define slim_hidden_def1(name, internal)                               \
111   extern __typeof (name) EXT_##name __asm__(slim_hidden_asmname(name))  \
112         __attribute__((__alias__(slim_hidden_asmname(internal))))
113 # define slim_hidden_ulp                slim_hidden_ulp1(__USER_LABEL_PREFIX__)
114 # define slim_hidden_ulp1(x)            slim_hidden_ulp2(x)
115 # define slim_hidden_ulp2(x)            #x
116 # define slim_hidden_asmname(name)      slim_hidden_asmname1(name)
117 # define slim_hidden_asmname1(name)     slim_hidden_ulp #name
118 #else
119 # define slim_hidden_proto(name)                int _csi_dummy_prototype(void)
120 # define slim_hidden_proto_no_warn(name)        int _csi_dummy_prototype(void)
121 # define slim_hidden_def(name)                  int _csi_dummy_prototype(void)
122 #endif
123
124 #if __GNUC__ >= 3
125 #define csi_pure __attribute__((pure))
126 #define csi_const __attribute__((const))
127 #else
128 #define csi_pure
129 #define csi_const
130 #endif
131
132 #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
133 #define _CSI_BOOLEAN_EXPR(expr)                   \
134  __extension__ ({                               \
135    int _csi_boolean_var_;                         \
136    if (expr)                                    \
137       _csi_boolean_var_ = 1;                      \
138    else                                         \
139       _csi_boolean_var_ = 0;                      \
140    _csi_boolean_var_;                             \
141 })
142 #define _csi_likely(expr) (__builtin_expect (_CSI_BOOLEAN_EXPR(expr), 1))
143 #define _csi_unlikely(expr) (__builtin_expect (_CSI_BOOLEAN_EXPR(expr), 0))
144 #else
145 #define _csi_likely(expr) (expr)
146 #define _csi_unlikely(expr) (expr)
147 #endif
148
149 #ifdef __GNUC__
150 #ifndef offsetof
151 #define offsetof(type, member) \
152     ((char *) &((type *) 0)->member - (char *) 0)
153 #endif
154 #define csi_container_of(ptr, type, member) ({ \
155     const typeof(((type *) 0)->member) *mptr__ = (ptr); \
156     (type *) ((char *) mptr__ - offsetof (type, member)); \
157 })
158 #else
159 #define csi_container_of(ptr, type, member) \
160     (type *)((char *) (ptr) - (char *) &((type *)0)->member)
161 #endif
162
163 /* slim_internal.h */
164 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun)
165 #define csi_private_no_warn     __attribute__((__visibility__("hidden")))
166 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
167 #define csi_private_no_warn     __hidden
168 #else /* not gcc >= 3.3 and not Sun Studio >= 8 */
169 #define csi_private_no_warn
170 #endif
171
172 #undef  ARRAY_LENGTH
173 #define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
174
175 #ifndef WARN_UNUSED_RESULT
176 #define WARN_UNUSED_RESULT
177 #endif
178 /* Add attribute(warn_unused_result) if supported */
179 #define csi_warn            WARN_UNUSED_RESULT
180 #define csi_private         csi_private_no_warn csi_warn
181
182 #define CSI_BITSWAP8(c) ((((c) * 0x0802LU & 0x22110LU) | ((c) * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16)
183 #ifdef WORDS_BIGENDIAN
184 #define CSI_BITSWAP8_IF_LITTLE_ENDIAN(c) (c)
185 #else
186 #define CSI_BITSWAP8_IF_LITTLE_ENDIAN(c) CSI_BITSWAP8(c)
187 #endif
188
189 typedef enum _csi_status {
190     CSI_STATUS_SUCCESS = CAIRO_STATUS_SUCCESS,
191     CSI_STATUS_NO_MEMORY = CAIRO_STATUS_NO_MEMORY,
192     CSI_STATUS_INVALID_RESTORE = CAIRO_STATUS_INVALID_RESTORE,
193     CSI_STATUS_INVALID_POP_GROUP = CAIRO_STATUS_INVALID_POP_GROUP,
194     CSI_STATUS_NO_CURRENT_POINT = CAIRO_STATUS_NO_CURRENT_POINT,
195     CSI_STATUS_INVALID_MATRIX = CAIRO_STATUS_INVALID_MATRIX,
196     CSI_STATUS_INVALID_STATUS = CAIRO_STATUS_INVALID_STATUS,
197     CSI_STATUS_NULL_POINTER = CAIRO_STATUS_NULL_POINTER,
198     CSI_STATUS_INVALID_STRING = CAIRO_STATUS_INVALID_STRING,
199     CSI_STATUS_INVALID_PATH_DATA = CAIRO_STATUS_INVALID_PATH_DATA,
200     CSI_STATUS_READ_ERROR = CAIRO_STATUS_READ_ERROR,
201     CSI_STATUS_WRITE_ERROR = CAIRO_STATUS_WRITE_ERROR,
202     CSI_STATUS_SURFACE_FINISHED = CAIRO_STATUS_SURFACE_FINISHED,
203     CSI_STATUS_SURFACE_TYPE_MISMATCH = CAIRO_STATUS_SURFACE_TYPE_MISMATCH,
204     CSI_STATUS_PATTERN_TYPE_MISMATCH = CAIRO_STATUS_PATTERN_TYPE_MISMATCH,
205     CSI_STATUS_INVALID_CONTENT = CAIRO_STATUS_INVALID_CONTENT,
206     CSI_STATUS_INVALID_FORMAT = CAIRO_STATUS_INVALID_FORMAT,
207     CSI_STATUS_INVALID_VISUAL = CAIRO_STATUS_INVALID_VISUAL,
208     CSI_STATUS_FILE_NOT_FOUND = CAIRO_STATUS_FILE_NOT_FOUND,
209     CSI_STATUS_INVALID_DASH = CAIRO_STATUS_INVALID_DASH,
210     CSI_STATUS_INVALID_DSC_COMMENT = CAIRO_STATUS_INVALID_DSC_COMMENT,
211     CSI_STATUS_INVALID_INDEX = CAIRO_STATUS_INVALID_INDEX,
212     CSI_STATUS_CLIP_NOT_REPRESENTABLE = CAIRO_STATUS_CLIP_NOT_REPRESENTABLE,
213     CSI_STATUS_TEMP_FILE_ERROR = CAIRO_STATUS_TEMP_FILE_ERROR,
214     CSI_STATUS_INVALID_STRIDE = CAIRO_STATUS_INVALID_STRIDE,
215     CSI_STATUS_FONT_TYPE_MISMATCH = CAIRO_STATUS_FONT_TYPE_MISMATCH,
216     CSI_STATUS_USER_FONT_IMMUTABLE = CAIRO_STATUS_USER_FONT_IMMUTABLE,
217     CSI_STATUS_USER_FONT_ERROR = CAIRO_STATUS_USER_FONT_ERROR,
218     CSI_STATUS_NEGATIVE_COUNT = CAIRO_STATUS_NEGATIVE_COUNT,
219     CSI_STATUS_INVALID_CLUSTERS = CAIRO_STATUS_INVALID_CLUSTERS,
220     CSI_STATUS_INVALID_SLANT = CAIRO_STATUS_INVALID_SLANT,
221     CSI_STATUS_INVALID_WEIGHT = CAIRO_STATUS_INVALID_WEIGHT,
222
223     /* cairo-script-interpreter specific errors */
224
225     CSI_STATUS_INVALID_SCRIPT,
226     CSI_STATUS_SCRIPT_INVALID_TYPE,
227     CSI_STATUS_SCRIPT_INVALID_INDEX,
228     CSI_STATUS_SCRIPT_UNDEFINED_NAME,
229     CSI_STATUS_INTERPRETER_FINISHED,
230
231     _CSI_STATUS_SCRIPT_LAST_ERROR,
232     CSI_INT_STATUS_UNSUPPORTED
233 } csi_status_t;
234
235 typedef enum {
236     CSI_OBJECT_TYPE_NULL = 0,
237
238     /* atomics */
239     CSI_OBJECT_TYPE_BOOLEAN,
240     CSI_OBJECT_TYPE_INTEGER,
241     CSI_OBJECT_TYPE_MARK,
242     CSI_OBJECT_TYPE_NAME,
243     CSI_OBJECT_TYPE_OPERATOR,
244     CSI_OBJECT_TYPE_REAL,
245
246     /* compound */
247     CSI_OBJECT_TYPE_ARRAY = 0x8,
248     CSI_OBJECT_TYPE_DICTIONARY,
249     CSI_OBJECT_TYPE_FILE,
250     CSI_OBJECT_TYPE_MATRIX,
251     CSI_OBJECT_TYPE_STRING,
252
253     /* cairo */
254     CSI_OBJECT_TYPE_CONTEXT = 0x10,
255     CSI_OBJECT_TYPE_FONT,
256     CSI_OBJECT_TYPE_PATTERN,
257     CSI_OBJECT_TYPE_SCALED_FONT,
258     CSI_OBJECT_TYPE_SURFACE
259 } csi_object_type_t;
260
261 #define CSI_OBJECT_IS_ATOM(OBJ) (((OBJ)->type & CSI_OBJECT_TYPE_MASK) < 0x08)
262 #define CSI_OBJECT_IS_COMPOUND(OBJ) ((OBJ)->type & 0x08)
263 #define CSI_OBJECT_IS_CAIRO(OBJ) ((OBJ)->type & 0x10)
264
265 enum { /* attributes */
266     CSI_OBJECT_ATTR_EXECUTABLE = 1 << 6,
267     CSI_OBJECT_ATTR_WRITABLE   = 1 << 7
268 };
269 #define CSI_OBJECT_ATTR_MASK (CSI_OBJECT_ATTR_EXECUTABLE | \
270                               CSI_OBJECT_ATTR_WRITABLE)
271 #define CSI_OBJECT_TYPE_MASK (~CSI_OBJECT_ATTR_MASK)
272
273 typedef struct _cairo_script_interpreter csi_t;
274
275 typedef cairo_bool_t csi_boolean_t;
276 typedef csi_status_t (*csi_operator_t) (csi_t *);
277 typedef float csi_real_t;
278 typedef long csi_integer_t;
279 typedef long csi_name_t;
280 typedef struct _csi_array csi_array_t;
281 typedef struct _csi_buffer csi_buffer_t;
282 typedef struct _csi_compound_object csi_compound_object_t;
283 typedef struct _csi_dictionary csi_dictionary_t;
284 typedef struct _csi_file csi_file_t;
285 typedef struct _csi_hash_entry csi_hash_entry_t;
286 typedef struct _csi_hash_table csi_hash_table_t;
287 typedef struct _csi_hash_table_arrangement csi_hash_table_arrangement_t;
288 typedef struct _csi_list csi_list_t;
289 typedef struct _csi_matrix csi_matrix_t;
290 typedef struct _csi_object csi_object_t;
291 typedef struct _csi_scanner csi_scanner_t;
292 typedef struct _csi_stack csi_stack_t;
293 typedef struct _csi_string csi_string_t;
294
295 typedef cairo_bool_t
296 (*csi_hash_predicate_func_t) (void *entry);
297
298 typedef void
299 (*csi_hash_callback_func_t) (void *entry,
300                              void *closure);
301
302 typedef cairo_bool_t
303 (*csi_hash_keys_equal_func_t) (const void *key_a, const void *key_b);
304
305 struct _csi_object {
306     csi_object_type_t type;
307     union {
308         cairo_t *cr;
309         cairo_font_face_t *font_face;
310         cairo_pattern_t *pattern;
311         cairo_scaled_font_t *scaled_font;
312         cairo_surface_t *surface;
313         csi_array_t *array;
314         csi_boolean_t boolean;
315         csi_compound_object_t *object;
316         csi_dictionary_t *dictionary;
317         csi_file_t *file;
318         csi_integer_t integer;
319         csi_matrix_t *matrix;
320         csi_operator_t op;
321         csi_name_t name;
322         csi_real_t real;
323         csi_string_t *string;
324         void *ptr;
325     } datum;
326 };
327
328 struct _csi_compound_object {
329     csi_object_type_t type;
330     unsigned int ref;
331 };
332
333 struct _csi_hash_entry {
334     unsigned long hash;
335 };
336
337 struct _csi_hash_table_arrangement {
338     unsigned long high_water_mark;
339     unsigned long size;
340     unsigned long rehash;
341 };
342
343 struct _csi_hash_table {
344     csi_hash_keys_equal_func_t keys_equal;
345
346     const csi_hash_table_arrangement_t *arrangement;
347     csi_hash_entry_t **entries;
348
349     unsigned long live_entries;
350     unsigned long used_entries;
351     unsigned long iterating;   /* Iterating, no insert, no resize */
352 };
353
354
355 /* simple, embedded doubly-linked links */
356 struct _csi_list {
357     struct _csi_list *next, *prev;
358 };
359
360 struct _csi_buffer {
361     char *base, *ptr, *end;
362     unsigned int size;
363 };
364
365 struct _csi_stack {
366     csi_object_t *objects;
367     csi_integer_t len;
368     csi_integer_t size;
369 };
370
371 struct _csi_array {
372     csi_compound_object_t base;
373     csi_stack_t stack;
374 };
375
376 typedef struct _csi_dictionary_entry {
377     csi_hash_entry_t hash_entry;
378     csi_object_t value;
379 } csi_dictionary_entry_t;
380
381 struct _csi_dictionary {
382     csi_compound_object_t base;
383     csi_hash_table_t hash_table;
384 };
385
386 struct _csi_matrix {
387     csi_compound_object_t base;
388     cairo_matrix_t matrix;
389 };
390
391 struct _csi_string {
392     csi_compound_object_t base;
393     csi_integer_t len;
394     csi_integer_t deflate;
395     char *string;
396 };
397
398 typedef struct _csi_filter_funcs {
399     int (*filter_getc) (csi_file_t *);
400     void (*filter_putc) (csi_file_t *, int);
401     int (*filter_read) (csi_file_t *, uint8_t *, int);
402     void (*filter_destroy) (csi_t *, void *);
403 } csi_filter_funcs_t;
404
405 struct _csi_file {
406     csi_compound_object_t base;
407     enum {
408         STDIO,
409         BYTES,
410         PROCEDURE,
411         FILTER
412     } type;
413     unsigned int flags;
414     void *src;
415     void *data;
416     uint8_t *bp;
417     int rem;
418     const csi_filter_funcs_t *filter;
419 };
420
421 union _csi_union_object {
422     void *ptr[2];
423     csi_stack_t stack;
424     csi_array_t arry;
425     csi_dictionary_t dictionary;
426     csi_matrix_t matrix;
427     csi_string_t string;
428     csi_file_t file;
429     csi_object_t object;
430 };
431
432 struct _csi_scanner {
433     jmp_buf jmpbuf;
434     int depth;
435
436     int bind;
437     csi_status_t (*push) (csi_t *ctx, csi_object_t *obj);
438     csi_status_t (*execute) (csi_t *ctx, csi_object_t *obj);
439     void *closure;
440
441     csi_buffer_t buffer;
442     csi_stack_t procedure_stack;
443     csi_object_t build_procedure;
444
445     unsigned int accumulator;
446     unsigned int accumulator_count;
447
448     unsigned int line_number;
449 };
450
451 typedef cairo_script_interpreter_hooks_t csi_hooks_t;
452
453 typedef struct _csi_chunk {
454     struct _csi_chunk *next;
455     int rem;
456     char *ptr;
457 } csi_chunk_t;
458
459 struct _cairo_script_interpreter {
460     int ref_count;
461     csi_status_t status;
462
463     unsigned int finished : 1;
464
465     csi_hooks_t hooks;
466
467     csi_hash_table_t strings;
468
469     csi_stack_t ostack;
470     csi_stack_t dstack;
471
472     csi_scanner_t scanner;
473
474     csi_chunk_t *perm_chunk;
475     struct {
476         csi_chunk_t *chunk;
477         void *free_list;
478     } slabs[16];
479     csi_array_t *free_array;
480     csi_dictionary_t *free_dictionary;
481     csi_string_t *free_string;
482
483     csi_operator_t opcode[256];
484
485     /* caches of live data */
486     csi_list_t *_images;
487     csi_list_t *_faces;
488 };
489
490 typedef struct _csi_operator_def {
491     const char *name;
492     csi_operator_t op;
493 } csi_operator_def_t;
494
495 typedef struct _csi_integer_constant_def {
496     const char *name;
497     csi_integer_t value;
498 } csi_integer_constant_def_t;
499
500 typedef struct _csi_real_constant_def {
501     const char *name;
502     csi_real_t value;
503 } csi_real_constant_def_t;
504
505 /* cairo-script-file.c */
506
507 csi_private csi_status_t
508 csi_file_new (csi_t *ctx,
509               csi_object_t *obj,
510               const char *path, const char *mode);
511
512 csi_private csi_status_t
513 csi_file_new_for_stream (csi_t *ctx,
514                          csi_object_t *obj,
515                          FILE *stream);
516
517 csi_private csi_status_t
518 csi_file_new_for_bytes (csi_t *ctx,
519                         csi_object_t *obj,
520                         const char *bytes,
521                         unsigned int length);
522
523 csi_private csi_status_t
524 csi_file_new_from_string (csi_t *ctx,
525                           csi_object_t *obj,
526                           csi_string_t *src);
527
528 csi_private csi_status_t
529 csi_file_new_ascii85_decode (csi_t *ctx,
530                              csi_object_t *obj,
531                              csi_dictionary_t *dict,
532                              csi_object_t *src);
533
534 csi_private csi_status_t
535 csi_file_new_deflate_decode (csi_t *ctx,
536                              csi_object_t *obj,
537                              csi_dictionary_t *dict,
538                              csi_object_t *src);
539
540 csi_private csi_status_t
541 _csi_file_execute (csi_t *ctx, csi_file_t *obj);
542
543 csi_private int
544 csi_file_getc (csi_file_t *obj);
545
546 csi_private int
547 csi_file_read (csi_file_t *obj, void *buf, int len);
548
549 csi_private void
550 csi_file_putc (csi_file_t *obj, int c);
551
552 csi_private void
553 csi_file_flush (csi_file_t *obj);
554
555 csi_private void
556 csi_file_close (csi_t *ctx, csi_file_t *obj);
557
558 csi_private void
559 _csi_file_free (csi_t *ctx, csi_file_t *obj);
560
561 csi_private csi_status_t
562 _csi_file_as_string (csi_t *ctx,
563                      csi_file_t *file,
564                      csi_object_t *obj);
565
566 /* cairo-script-hash.c */
567
568 csi_private csi_status_t
569 _csi_hash_table_init (csi_hash_table_t *hash_table,
570                       csi_hash_keys_equal_func_t keys_equal);
571
572 csi_private void
573 _csi_hash_table_fini (csi_hash_table_t *hash_table);
574
575 csi_private void *
576 _csi_hash_table_lookup (csi_hash_table_t  *hash_table,
577                         csi_hash_entry_t  *key);
578
579 csi_private csi_status_t
580 _csi_hash_table_insert (csi_hash_table_t *hash_table,
581                         csi_hash_entry_t *entry);
582
583 csi_private void
584 _csi_hash_table_remove (csi_hash_table_t *hash_table,
585                         csi_hash_entry_t *key);
586
587 csi_private void
588 _csi_hash_table_foreach (csi_hash_table_t             *hash_table,
589                          csi_hash_callback_func_t  hash_callback,
590                          void                         *closure);
591
592 /* cairo-script-interpreter.c */
593
594 csi_private void *
595 _csi_alloc (csi_t *ctx, int size);
596
597 csi_private void *
598 _csi_alloc0 (csi_t *ctx, int size);
599
600 csi_private void *
601 _csi_realloc (csi_t *ctx, void *ptr, int size);
602
603 csi_private void
604 _csi_free (csi_t *ctx, void *ptr);
605
606 csi_private void *
607 _csi_slab_alloc (csi_t *ctx, int size);
608
609 csi_private void *
610 _csi_perm_alloc (csi_t *ctx, int size);
611
612 csi_private void
613 _csi_slab_free (csi_t *ctx, void *ptr, int size);
614
615 csi_private csi_status_t
616 csi_push_ostack (csi_t *ctx, csi_object_t *obj);
617
618 csi_private csi_status_t
619 _csi_name_define (csi_t *ctx, csi_name_t name, csi_object_t *obj);
620
621 csi_private csi_status_t
622 _csi_name_lookup (csi_t *ctx, csi_name_t name, csi_object_t *obj);
623
624 csi_private csi_status_t
625 _csi_name_undefine (csi_t *ctx, csi_name_t name);
626
627 csi_private csi_status_t
628 _csi_intern_string (csi_t *ctx, const char **str_inout, int len);
629
630 csi_private csi_status_t
631 _csi_error (csi_status_t status);
632
633 /* cairo-script-objects.c */
634
635 csi_private csi_status_t
636 csi_array_new (csi_t *ctx,
637                csi_integer_t initial_size,
638                csi_object_t *obj);
639
640 csi_private csi_status_t
641 _csi_array_execute (csi_t *ctx, csi_array_t *array);
642
643 csi_private csi_status_t
644 csi_array_get (csi_t *ctx,
645                csi_array_t *array,
646                long elem,
647                csi_object_t *value);
648
649 csi_private csi_status_t
650 csi_array_put (csi_t *ctx,
651                csi_array_t *array,
652                csi_integer_t elem,
653                csi_object_t *value);
654
655 csi_private csi_status_t
656 csi_array_append (csi_t *ctx,
657                   csi_array_t *array,
658                   csi_object_t *obj);
659
660 csi_private void
661 csi_array_free (csi_t *ctx, csi_array_t *array);
662
663 static inline void
664 csi_boolean_new (csi_object_t *obj,
665                  csi_boolean_t v)
666 {
667     obj->type = CSI_OBJECT_TYPE_BOOLEAN;
668     obj->datum.boolean = v;
669 }
670
671 csi_private csi_status_t
672 csi_dictionary_new (csi_t *ctx,
673                     csi_object_t *obj);
674
675 csi_private csi_status_t
676 csi_dictionary_put (csi_t *ctx,
677                     csi_dictionary_t *dict,
678                     csi_name_t name,
679                     csi_object_t *value);
680
681 csi_private csi_status_t
682 csi_dictionary_get (csi_t *ctx,
683                     csi_dictionary_t *dict,
684                     csi_name_t name,
685                     csi_object_t *value);
686
687 csi_private csi_boolean_t
688 csi_dictionary_has (csi_dictionary_t *dict,
689                     csi_name_t name);
690
691 csi_private void
692 csi_dictionary_remove (csi_t *ctx,
693                        csi_dictionary_t *dict,
694                        csi_name_t name);
695
696 csi_private void
697 csi_dictionary_free (csi_t *ctx,
698                      csi_dictionary_t *dict);
699
700 static inline void
701 csi_integer_new (csi_object_t *obj,
702                  csi_integer_t v)
703 {
704     obj->type = CSI_OBJECT_TYPE_INTEGER;
705     obj->datum.integer = v;
706 }
707
708
709 csi_private csi_status_t
710 csi_matrix_new (csi_t *ctx,
711                 csi_object_t *obj);
712
713 csi_private csi_status_t
714 csi_matrix_new_from_array (csi_t *ctx,
715                            csi_object_t *obj,
716                            csi_array_t *array);
717
718 csi_private csi_status_t
719 csi_matrix_new_from_matrix (csi_t *ctx,
720                             csi_object_t *obj,
721                             const cairo_matrix_t *m);
722
723 csi_private csi_status_t
724 csi_matrix_new_from_values (csi_t *ctx,
725                             csi_object_t *obj,
726                             double v[6]);
727
728 csi_private void
729 csi_matrix_free (csi_t *ctx,
730                  csi_matrix_t *obj);
731
732 csi_private csi_status_t
733 csi_name_new (csi_t *ctx,
734               csi_object_t *obj,
735               const char *str,
736               int len);
737
738 csi_private csi_status_t
739 csi_name_new_static (csi_t *ctx,
740                      csi_object_t *obj,
741                      const char *str);
742
743 static inline void
744 csi_operator_new (csi_object_t *obj,
745                   csi_operator_t op)
746 {
747     obj->type = CSI_OBJECT_TYPE_OPERATOR | CSI_OBJECT_ATTR_EXECUTABLE;
748     obj->datum.op = op;
749 }
750
751 static inline void
752 csi_real_new (csi_object_t *obj,
753               csi_real_t v)
754 {
755     obj->type = CSI_OBJECT_TYPE_REAL;
756     obj->datum.real = v;
757 }
758
759 csi_private csi_status_t
760 csi_string_new (csi_t *ctx,
761                 csi_object_t *obj,
762                 const char *str,
763                 int len);
764
765 csi_private csi_status_t
766 csi_string_deflate_new (csi_t *ctx,
767                         csi_object_t *obj,
768                         void *bytes,
769                         int in_len,
770                         int out_len);
771
772 csi_private csi_status_t
773 csi_string_new_from_bytes (csi_t *ctx,
774                            csi_object_t *obj,
775                            char *bytes,
776                            unsigned int len);
777
778 csi_private void
779 csi_string_free (csi_t *ctx, csi_string_t *string);
780
781 csi_private csi_status_t
782 csi_object_execute (csi_t *ctx, csi_object_t *obj);
783
784 csi_private csi_object_t *
785 csi_object_reference (csi_object_t *obj);
786
787 csi_private void
788 csi_object_free (csi_t *ctx,
789                  csi_object_t *obj);
790
791 csi_private csi_status_t
792 csi_object_as_file (csi_t *ctx,
793                     csi_object_t *src,
794                     csi_object_t *file);
795
796 csi_private csi_boolean_t
797 csi_object_eq (csi_object_t *a,
798                csi_object_t *b);
799
800 csi_private csi_status_t
801 csi_object_compare (csi_object_t *a,
802                     csi_object_t *b,
803                     int          *out_cmp);
804
805 /* cairo-script-operators.c */
806
807 csi_private const csi_operator_def_t *
808 _csi_operators (void);
809
810 csi_private const csi_integer_constant_def_t *
811 _csi_integer_constants (void);
812
813 csi_private const csi_real_constant_def_t *
814 _csi_real_constants (void);
815
816 /* cairo-script-scanner.c */
817
818 csi_private csi_status_t
819 _csi_scanner_init (csi_t *ctx, csi_scanner_t *scanner);
820
821 csi_private csi_status_t
822 _csi_scan_file (csi_t *ctx, csi_file_t *src);
823
824 csi_private csi_status_t
825 _csi_translate_file (csi_t *ctx,
826                      csi_file_t *file,
827                      cairo_write_func_t write_func,
828                      void *closure);
829
830 csi_private void
831 _csi_scanner_fini (csi_t *ctx, csi_scanner_t *scanner);
832
833 csi_private csi_boolean_t
834 _csi_parse_number (csi_object_t *obj, const char *s, int len);
835
836 /* cairo-script-stack.c */
837
838 csi_private csi_status_t
839 _csi_stack_init (csi_t *ctx, csi_stack_t *stack, csi_integer_t size);
840
841 csi_private void
842 _csi_stack_fini (csi_t *ctx, csi_stack_t *stack);
843
844 csi_private csi_status_t
845 _csi_stack_roll (csi_t *ctx,
846                  csi_stack_t *stack,
847                  csi_integer_t mod,
848                  csi_integer_t n);
849
850 csi_private csi_status_t
851 _csi_stack_grow (csi_t *ctx, csi_stack_t *stack, csi_integer_t cnt);
852
853 csi_private csi_status_t
854 _csi_stack_push_internal (csi_t *ctx, csi_stack_t *stack,
855                           const csi_object_t *obj);
856
857 csi_private csi_object_t *
858 _csi_stack_peek (csi_stack_t *stack, csi_integer_t i);
859
860 csi_private void
861 _csi_stack_pop (csi_t *ctx, csi_stack_t *stack, csi_integer_t count);
862
863 csi_private csi_status_t
864 _csi_stack_exch (csi_stack_t *stack);
865
866 static inline csi_object_type_t
867 csi_object_get_type (const csi_object_t *obj)
868 {
869     return obj->type & CSI_OBJECT_TYPE_MASK;
870 }
871
872 static inline csi_boolean_t
873 csi_object_is_procedure (const csi_object_t *obj)
874 {
875     return obj->type == (CSI_OBJECT_TYPE_ARRAY | CSI_OBJECT_ATTR_EXECUTABLE);
876 }
877
878 static inline csi_boolean_t
879 csi_object_is_number (const csi_object_t *obj)
880 {
881     int type = csi_object_get_type (obj);
882     switch (type) {
883     case CSI_OBJECT_TYPE_BOOLEAN:
884     case CSI_OBJECT_TYPE_INTEGER:
885     case CSI_OBJECT_TYPE_REAL:
886         return 1;
887     default:
888         return 0;
889     }
890 }
891
892 static inline double
893 csi_number_get_value (const csi_object_t *obj)
894 {
895     int type = csi_object_get_type (obj);
896     switch (type) {
897     case CSI_OBJECT_TYPE_BOOLEAN: return obj->datum.boolean;
898     case CSI_OBJECT_TYPE_INTEGER: return obj->datum.integer;
899     case CSI_OBJECT_TYPE_REAL: return obj->datum.real;
900     default: return 0.;
901     }
902 }
903
904 static inline csi_status_t
905 _csi_stack_push (csi_t *ctx, csi_stack_t *stack,
906                  const csi_object_t *obj)
907 {
908     if (_csi_unlikely (stack->len == stack->size))
909         return _csi_stack_push_internal (ctx, stack, obj);
910
911     stack->objects[stack->len++] = *obj;
912     return CSI_STATUS_SUCCESS;
913 }
914
915 static inline csi_boolean_t
916 _csi_check_ostack (csi_t *ctx, csi_integer_t count)
917 {
918     return ctx->ostack.len >= count;
919 }
920
921 static inline csi_object_t *
922 _csi_peek_ostack (csi_t *ctx, csi_integer_t i)
923 {
924     return &ctx->ostack.objects[ctx->ostack.len - i -1];
925 }
926
927 static inline void
928 _csi_pop_ostack (csi_t *ctx, csi_integer_t count)
929 {
930     do
931         csi_object_free (ctx, &ctx->ostack.objects[--ctx->ostack.len]);
932     while (--count);
933 }
934
935 static inline csi_status_t
936 _csi_push_ostack_copy (csi_t *ctx, csi_object_t *obj)
937 {
938     return _csi_stack_push (ctx, &ctx->ostack, csi_object_reference (obj));
939 }
940
941 static inline csi_status_t
942 _csi_push_ostack (csi_t *ctx, csi_object_t *obj)
943 {
944     return _csi_stack_push (ctx, &ctx->ostack, obj);
945 }
946
947 static inline csi_status_t
948 _csi_push_ostack_boolean (csi_t *ctx, csi_boolean_t v)
949 {
950     csi_object_t obj;
951     obj.type = CSI_OBJECT_TYPE_BOOLEAN;
952     obj.datum.boolean = v;
953     return _csi_stack_push (ctx, &ctx->ostack, &obj);
954 }
955 static inline csi_status_t
956 _csi_push_ostack_integer (csi_t *ctx, csi_integer_t v)
957 {
958     csi_object_t obj;
959     obj.type = CSI_OBJECT_TYPE_INTEGER;
960     obj.datum.integer = v;
961     return _csi_stack_push (ctx, &ctx->ostack, &obj);
962 }
963 static inline csi_status_t
964 _csi_push_ostack_mark (csi_t *ctx)
965 {
966     csi_object_t obj;
967     obj.type = CSI_OBJECT_TYPE_MARK;
968     return _csi_stack_push (ctx, &ctx->ostack, &obj);
969 }
970 static inline csi_status_t
971 _csi_push_ostack_null (csi_t *ctx)
972 {
973     csi_object_t obj;
974     obj.type = CSI_OBJECT_TYPE_NULL;
975     return _csi_stack_push (ctx, &ctx->ostack, &obj);
976 }
977 static inline csi_status_t
978 _csi_push_ostack_real (csi_t *ctx, csi_real_t v)
979 {
980     csi_object_t obj;
981     obj.type = CSI_OBJECT_TYPE_REAL;
982     obj.datum.real = v;
983     return _csi_stack_push (ctx, &ctx->ostack, &obj);
984 }
985
986 slim_hidden_proto_no_warn (cairo_script_interpreter_destroy);
987 slim_hidden_proto_no_warn (cairo_script_interpreter_reference);
988
989 #endif /* CAIRO_SCRIPT_PRIVATE_H */