static csi_status_t _csi_file_new_filter (csi_t *ctx, csi_object_t *obj, csi_object_t *src, const csi_filter_funcs_t *funcs, void *data) { csi_file_t *file; csi_object_t src_file; csi_status_t status; file = _csi_slab_alloc (ctx, sizeof (csi_file_t)); if (file == NULL) return _csi_error (CAIRO_STATUS_NO_MEMORY); obj->type = CSI_OBJECT_TYPE_FILE; obj->datum.file = file; file->base.type = CSI_OBJECT_TYPE_FILE; file->base.ref = 1; file->type = FILTER; file->data = data; file->filter = funcs; status = csi_object_as_file (ctx, src, &src_file); if (status) { csi_object_free (ctx, obj); return status; } file->src = src_file.datum.file; return CAIRO_STATUS_SUCCESS; }
void _csi_stack_pop (csi_t *ctx, csi_stack_t *stack, csi_integer_t count) { if (_csi_unlikely (stack->len < count)) count = stack->len; while (count--) csi_object_free (ctx, &stack->objects[--stack->len]); }
void _csi_stack_fini (csi_t *ctx, csi_stack_t *stack) { csi_integer_t n; for (n = 0; n < stack->len; n++) csi_object_free (ctx, &stack->objects[n]); _csi_free (ctx, stack->objects); }
cairo_status_t cairo_script_interpreter_run (csi_t *ctx, const char *filename) { csi_object_t file; if (ctx->status) return ctx->status; ctx->status = csi_file_new (ctx, &file, filename, "r"); if (ctx->status) return ctx->status; file.type |= CSI_OBJECT_ATTR_EXECUTABLE; ctx->status = csi_object_execute (ctx, &file); csi_object_free (ctx, &file); return ctx->status; }
cairo_status_t cairo_script_interpreter_feed_stream (csi_t *ctx, FILE *stream) { csi_object_t file; if (ctx->status) return ctx->status; if (ctx->finished) return ctx->status = CSI_STATUS_INTERPRETER_FINISHED; ctx->status = csi_file_new_for_stream (ctx, &file, stream); if (ctx->status) return ctx->status; file.type |= CSI_OBJECT_ATTR_EXECUTABLE; ctx->status = csi_object_execute (ctx, &file); csi_object_free (ctx, &file); return ctx->status; }
cairo_status_t cairo_script_interpreter_feed_string (csi_t *ctx, const char *line, int len) { csi_object_t file; if (ctx->status) return ctx->status; if (len < 0) len = strlen (line); ctx->status = csi_file_new_for_bytes (ctx, &file, line, len); if (ctx->status) return ctx->status; file.type |= CSI_OBJECT_ATTR_EXECUTABLE; ctx->status = csi_object_execute (ctx, &file); csi_object_free (ctx, &file); return ctx->status; }
cairo_status_t cairo_script_interpreter_translate_stream (FILE *stream, cairo_write_func_t write_func, void *closure) { csi_t ctx; csi_object_t src; csi_status_t status; _csi_init (&ctx); status = csi_file_new_for_stream (&ctx, &src, stream); if (status) goto BAIL; status = _csi_translate_file (&ctx, src.datum.file, write_func, closure); BAIL: csi_object_free (&ctx, &src); _csi_fini (&ctx); return status; }
csi_status_t csi_file_new_from_stream (csi_t *ctx, FILE *file, csi_object_t **out) { csi_file_t *obj; obj = (csi_file_t *) _csi_object_new (ctx, CSI_OBJECT_TYPE_FILE); if (obj == NULL) return _csi_error (CAIRO_STATUS_NO_MEMORY); obj->type = STDIO; obj->src = file; obj->data = _csi_alloc (ctx, CHUNK_SIZE); if (obj->data == NULL) { csi_object_free (&obj->base); return _csi_error (CAIRO_STATUS_UNDEFINED_FILENAME_ERROR); } obj->bp = obj->data; obj->rem = 0; *out = &obj->base; return CAIRO_STATUS_SUCCESS; }