summaryrefslogtreecommitdiff
path: root/psi/iapi.c
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2020-07-30 19:16:13 +0100
committerRobin Watts <Robin.Watts@artifex.com>2020-08-03 18:02:41 +0100
commitbf6884134c244c4766d13c76264fa4372eab4056 (patch)
treeab1af05f3c1ae6b8f76545def0c41770701d71f0 /psi/iapi.c
parent49a4fede913a12a61fd6649898cf5999030f4b69 (diff)
downloadghostpdl-bf6884134c244c4766d13c76264fa4372eab4056.tar.gz
gsapi_set_param improvements.
Allow for a 'parsed' param type; this leverages the functions in gsparaml.c to parse an input string into a param list, coping with dictionaries and arrays. We update those functions to improve behaviour on more exotically formed numbers ("- 0.3e-10" etc), on 'tricksy' inputs (e.g. "<< /Foo (>>) >>" etc) and to cope without relying on whitespace (e.g. "<</Foo/Bar/Baz[1 0]/Fizz<1234>/Bang(A)>>" etc). Update pl_implementation set_param entrypoint so that the language interface itself is based upon param lists, rather than typed params. Update both implementations of gsapi_set_params so that if we are too early in the setup process stuff goes into the list and is held until we have devices/languages to pass it to. Also add a flag to allow for 'more to come' so that we can effectively set multiple params at once.
Diffstat (limited to 'psi/iapi.c')
-rw-r--r--psi/iapi.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/psi/iapi.c b/psi/iapi.c
index 36d3d0150..ffa9ac8cf 100644
--- a/psi/iapi.c
+++ b/psi/iapi.c
@@ -402,10 +402,103 @@ gsapi_exit(void *instance)
GSDLLEXPORT int GSDLLAPI
gsapi_set_param(void *lib, gs_set_param_type type, const char *param, const void *value)
{
+ int code = 0;
+ gs_param_string str_value;
+ bool bval;
+ int more_to_come = type & gs_spt_more_to_come;
+ gs_main_instance *minst;
+ gs_c_param_list *params;
gs_lib_ctx_t *ctx = (gs_lib_ctx_t *)lib;
+
if (lib == NULL)
return gs_error_Fatal;
- return psapi_set_param(ctx, (psapi_sptype)type, param, value);
+ minst = get_minst_from_memory(ctx->memory);
+
+ /* First off, ensure we have a param list to work with. */
+ params = minst->param_list;
+ if (params == NULL) {
+ params = minst->param_list =
+ gs_c_param_list_alloc(minst->heap, "gs_main_instance_param_list");
+ if (params == NULL)
+ return_error(gs_error_VMerror);
+ gs_c_param_list_write(params, minst->heap);
+ gs_param_list_set_persistent_keys((gs_param_list *)params, false);
+ }
+
+ type &= ~gs_spt_more_to_come;
+
+ /* Set the passed param in the device params */
+ gs_c_param_list_write_more(params);
+ switch (type)
+ {
+ case gs_spt_null:
+ code = param_write_null((gs_param_list *) params,
+ param);
+ break;
+ case gs_spt_bool:
+ bval = (value != NULL);
+ code = param_write_bool((gs_param_list *) params,
+ param, &bval);
+ break;
+ case gs_spt_int:
+ code = param_write_int((gs_param_list *) params,
+ param, (int *)value);
+ break;
+ case gs_spt_float:
+ code = param_write_float((gs_param_list *) params,
+ param, (float *)value);
+ break;
+ case gs_spt_name:
+ param_string_from_transient_string(str_value, value);
+ code = param_write_name((gs_param_list *) params,
+ param, &str_value);
+ break;
+ case gs_spt_string:
+ param_string_from_transient_string(str_value, value);
+ code = param_write_string((gs_param_list *) params,
+ param, &str_value);
+ break;
+ case gs_spt_long:
+ code = param_write_long((gs_param_list *) params,
+ param, (long *)value);
+ break;
+ case gs_spt_i64:
+ code = param_write_i64((gs_param_list *) params,
+ param, (int64_t *)value);
+ break;
+ case gs_spt_size_t:
+ code = param_write_size_t((gs_param_list *) params,
+ param, (size_t *)value);
+ break;
+ case gs_spt_parsed:
+ code = gs_param_list_add_parsed_value((gs_param_list *)params,
+ param, (void *)value);
+ break;
+ default:
+ code = gs_note_error(gs_error_rangecheck);
+ }
+ if (code < 0) {
+ gs_c_param_list_release(params);
+ return code;
+ }
+ gs_c_param_list_read(params);
+
+ if (more_to_come) {
+ /* Leave it in the param list for later. */
+ return 0;
+ }
+
+ /* Send it to the device. */
+ code = psapi_set_device_param(ctx, (gs_param_list *)params);
+ if (code < 0)
+ return code;
+
+ /* Send it to the language */
+ code = psapi_set_param(ctx, (gs_param_list *)params);
+
+ gs_c_param_list_release(params);
+
+ return code;
}
GSDLLEXPORT int GSDLLAPI