zusparam.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. /* Copyright (C) 1996, 2000 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: zusparam.c,v 1.13 2004/08/04 19:36:13 stefan Exp $ */
  14. /* User and system parameter operators */
  15. #include "memory_.h"
  16. #include "string_.h"
  17. #include "ghost.h"
  18. #include "oper.h"
  19. #include "gscdefs.h"
  20. #include "gsstruct.h" /* for gxht.h */
  21. #include "gsfont.h" /* for user params */
  22. #include "gxht.h" /* for user params */
  23. #include "gsutil.h"
  24. #include "estack.h"
  25. #include "ialloc.h" /* for imemory for status */
  26. #include "icontext.h" /* for set_user_params prototype */
  27. #include "idict.h"
  28. #include "idparam.h"
  29. #include "iparam.h"
  30. #include "dstack.h"
  31. #include "iname.h"
  32. #include "itoken.h"
  33. #include "iutil2.h"
  34. #include "ivmem2.h"
  35. #include "store.h"
  36. /* The (global) font directory */
  37. extern gs_font_dir *ifont_dir; /* in zfont.c */
  38. /* Define an individual user or system parameter. */
  39. /* Eventually this will be made public. */
  40. #define param_def_common\
  41. const char *pname
  42. typedef struct param_def_s {
  43. param_def_common;
  44. } param_def_t;
  45. typedef struct long_param_def_s {
  46. param_def_common;
  47. long min_value, max_value;
  48. long (*current)(i_ctx_t *);
  49. int (*set)(i_ctx_t *, long);
  50. } long_param_def_t;
  51. #if arch_sizeof_long > arch_sizeof_int
  52. # define MAX_UINT_PARAM max_uint
  53. #else
  54. # define MAX_UINT_PARAM max_long
  55. #endif
  56. typedef struct bool_param_def_s {
  57. param_def_common;
  58. bool (*current)(i_ctx_t *);
  59. int (*set)(i_ctx_t *, bool);
  60. } bool_param_def_t;
  61. typedef struct string_param_def_s {
  62. param_def_common;
  63. void (*current)(i_ctx_t *, gs_param_string *);
  64. int (*set)(i_ctx_t *, gs_param_string *);
  65. } string_param_def_t;
  66. /* Define a parameter set (user or system). */
  67. typedef struct param_set_s {
  68. const long_param_def_t *long_defs;
  69. uint long_count;
  70. const bool_param_def_t *bool_defs;
  71. uint bool_count;
  72. const string_param_def_t *string_defs;
  73. uint string_count;
  74. } param_set;
  75. /* Forward references */
  76. private int setparams(i_ctx_t *, gs_param_list *, const param_set *);
  77. private int currentparams(i_ctx_t *, const param_set *);
  78. private int currentparam1(i_ctx_t *, const param_set *);
  79. /* ------ Passwords ------ */
  80. /* <string|int> .checkpassword <0|1|2> */
  81. private int
  82. zcheckpassword(i_ctx_t *i_ctx_p)
  83. {
  84. os_ptr op = osp;
  85. ref params[2];
  86. array_param_list list;
  87. gs_param_list *const plist = (gs_param_list *)&list;
  88. int result = 0;
  89. int code = name_ref(imemory, (const byte *)"Password", 8, &params[0], 0);
  90. password pass;
  91. if (code < 0)
  92. return code;
  93. params[1] = *op;
  94. array_param_list_read(&list, params, 2, NULL, false, iimemory);
  95. if (dict_read_password(&pass, systemdict, "StartJobPassword") >= 0 &&
  96. param_check_password(plist, &pass) == 0
  97. )
  98. result = 1;
  99. if (dict_read_password(&pass, systemdict, "SystemParamsPassword") >= 0 &&
  100. param_check_password(plist, &pass) == 0
  101. )
  102. result = 2;
  103. iparam_list_release(&list);
  104. make_int(op, result);
  105. return 0;
  106. }
  107. /* ------ System parameters ------ */
  108. /* Integer values */
  109. private long
  110. current_BuildTime(i_ctx_t *i_ctx_p)
  111. {
  112. return gs_buildtime;
  113. }
  114. private long
  115. current_MaxFontCache(i_ctx_t *i_ctx_p)
  116. {
  117. return gs_currentcachesize(ifont_dir);
  118. }
  119. private int
  120. set_MaxFontCache(i_ctx_t *i_ctx_p, long val)
  121. {
  122. return gs_setcachesize(ifont_dir,
  123. (uint)(val < 0 ? 0 : val > max_uint ? max_uint :
  124. val));
  125. }
  126. private long
  127. current_CurFontCache(i_ctx_t *i_ctx_p)
  128. {
  129. uint cstat[7];
  130. gs_cachestatus(ifont_dir, cstat);
  131. return cstat[0];
  132. }
  133. private long
  134. current_MaxGlobalVM(i_ctx_t *i_ctx_p)
  135. {
  136. gs_memory_gc_status_t stat;
  137. gs_memory_gc_status(iimemory_global, &stat);
  138. return stat.max_vm;
  139. }
  140. private int
  141. set_MaxGlobalVM(i_ctx_t *i_ctx_p, long val)
  142. {
  143. gs_memory_gc_status_t stat;
  144. gs_memory_gc_status(iimemory_global, &stat);
  145. stat.max_vm = max(val, 0);
  146. gs_memory_set_gc_status(iimemory_global, &stat);
  147. return 0;
  148. }
  149. private long
  150. current_Revision(i_ctx_t *i_ctx_p)
  151. {
  152. return gs_revision;
  153. }
  154. private const long_param_def_t system_long_params[] =
  155. {
  156. {"BuildTime", min_long, max_long, current_BuildTime, NULL},
  157. {"MaxFontCache", 0, MAX_UINT_PARAM, current_MaxFontCache, set_MaxFontCache},
  158. {"CurFontCache", 0, MAX_UINT_PARAM, current_CurFontCache, NULL},
  159. {"Revision", min_long, max_long, current_Revision, NULL},
  160. /* Extensions */
  161. {"MaxGlobalVM", 0, max_long, current_MaxGlobalVM, set_MaxGlobalVM}
  162. };
  163. /* Boolean values */
  164. private bool
  165. current_ByteOrder(i_ctx_t *i_ctx_p)
  166. {
  167. return !arch_is_big_endian;
  168. }
  169. private const bool_param_def_t system_bool_params[] =
  170. {
  171. {"ByteOrder", current_ByteOrder, NULL}
  172. };
  173. /* String values */
  174. private void
  175. current_RealFormat(i_ctx_t *i_ctx_p, gs_param_string * pval)
  176. {
  177. #if arch_floats_are_IEEE
  178. static const char *const rfs = "IEEE";
  179. #else
  180. static const char *const rfs = "not IEEE";
  181. #endif
  182. pval->data = (const byte *)rfs;
  183. pval->size = strlen(rfs);
  184. pval->persistent = true;
  185. }
  186. private const string_param_def_t system_string_params[] =
  187. {
  188. {"RealFormat", current_RealFormat, NULL}
  189. };
  190. /* The system parameter set */
  191. private const param_set system_param_set =
  192. {
  193. system_long_params, countof(system_long_params),
  194. system_bool_params, countof(system_bool_params),
  195. system_string_params, countof(system_string_params)
  196. };
  197. /* <dict> .setsystemparams - */
  198. private int
  199. zsetsystemparams(i_ctx_t *i_ctx_p)
  200. {
  201. os_ptr op = osp;
  202. int code;
  203. dict_param_list list;
  204. gs_param_list *const plist = (gs_param_list *)&list;
  205. password pass;
  206. check_type(*op, t_dictionary);
  207. code = dict_param_list_read(&list, op, NULL, false, iimemory);
  208. if (code < 0)
  209. return code;
  210. code = dict_read_password(&pass, systemdict, "SystemParamsPassword");
  211. if (code < 0)
  212. return code;
  213. code = param_check_password(plist, &pass);
  214. if (code != 0) {
  215. if (code > 0)
  216. code = gs_note_error(e_invalidaccess);
  217. goto out;
  218. }
  219. code = param_read_password(plist, "StartJobPassword", &pass);
  220. switch (code) {
  221. default: /* invalid */
  222. goto out;
  223. case 1: /* missing */
  224. break;
  225. case 0:
  226. code = dict_write_password(&pass, systemdict,
  227. "StartJobPassword",
  228. ! i_ctx_p->LockFilePermissions);
  229. if (code < 0)
  230. goto out;
  231. }
  232. code = param_read_password(plist, "SystemParamsPassword", &pass);
  233. switch (code) {
  234. default: /* invalid */
  235. goto out;
  236. case 1: /* missing */
  237. break;
  238. case 0:
  239. code = dict_write_password(&pass, systemdict,
  240. "SystemParamsPassword",
  241. ! i_ctx_p->LockFilePermissions);
  242. if (code < 0)
  243. goto out;
  244. }
  245. code = setparams(i_ctx_p, plist, &system_param_set);
  246. out:
  247. iparam_list_release(&list);
  248. if (code < 0)
  249. return code;
  250. pop(1);
  251. return 0;
  252. }
  253. /* - .currentsystemparams <name1> <value1> ... */
  254. private int
  255. zcurrentsystemparams(i_ctx_t *i_ctx_p)
  256. {
  257. return currentparams(i_ctx_p, &system_param_set);
  258. }
  259. /* <name> .getsystemparam <value> */
  260. private int
  261. zgetsystemparam(i_ctx_t *i_ctx_p)
  262. {
  263. return currentparam1(i_ctx_p, &system_param_set);
  264. }
  265. /* ------ User parameters ------ */
  266. /* Integer values */
  267. private long
  268. current_JobTimeout(i_ctx_t *i_ctx_p)
  269. {
  270. return 0;
  271. }
  272. private int
  273. set_JobTimeout(i_ctx_t *i_ctx_p, long val)
  274. {
  275. return 0;
  276. }
  277. private long
  278. current_MaxFontItem(i_ctx_t *i_ctx_p)
  279. {
  280. return gs_currentcacheupper(ifont_dir);
  281. }
  282. private int
  283. set_MaxFontItem(i_ctx_t *i_ctx_p, long val)
  284. {
  285. return gs_setcacheupper(ifont_dir, val);
  286. }
  287. private long
  288. current_MinFontCompress(i_ctx_t *i_ctx_p)
  289. {
  290. return gs_currentcachelower(ifont_dir);
  291. }
  292. private int
  293. set_MinFontCompress(i_ctx_t *i_ctx_p, long val)
  294. {
  295. return gs_setcachelower(ifont_dir, val);
  296. }
  297. private long
  298. current_MaxOpStack(i_ctx_t *i_ctx_p)
  299. {
  300. return ref_stack_max_count(&o_stack);
  301. }
  302. private int
  303. set_MaxOpStack(i_ctx_t *i_ctx_p, long val)
  304. {
  305. return ref_stack_set_max_count(&o_stack, val);
  306. }
  307. private long
  308. current_MaxDictStack(i_ctx_t *i_ctx_p)
  309. {
  310. return ref_stack_max_count(&d_stack);
  311. }
  312. private int
  313. set_MaxDictStack(i_ctx_t *i_ctx_p, long val)
  314. {
  315. return ref_stack_set_max_count(&d_stack, val);
  316. }
  317. private long
  318. current_MaxExecStack(i_ctx_t *i_ctx_p)
  319. {
  320. return ref_stack_max_count(&e_stack);
  321. }
  322. private int
  323. set_MaxExecStack(i_ctx_t *i_ctx_p, long val)
  324. {
  325. return ref_stack_set_max_count(&e_stack, val);
  326. }
  327. private long
  328. current_MaxLocalVM(i_ctx_t *i_ctx_p)
  329. {
  330. gs_memory_gc_status_t stat;
  331. gs_memory_gc_status(iimemory_local, &stat);
  332. return stat.max_vm;
  333. }
  334. private int
  335. set_MaxLocalVM(i_ctx_t *i_ctx_p, long val)
  336. {
  337. gs_memory_gc_status_t stat;
  338. gs_memory_gc_status(iimemory_local, &stat);
  339. stat.max_vm = max(val, 0);
  340. gs_memory_set_gc_status(iimemory_local, &stat);
  341. return 0;
  342. }
  343. private long
  344. current_VMReclaim(i_ctx_t *i_ctx_p)
  345. {
  346. gs_memory_gc_status_t gstat, lstat;
  347. gs_memory_gc_status(iimemory_global, &gstat);
  348. gs_memory_gc_status(iimemory_local, &lstat);
  349. return (!gstat.enabled ? -2 : !lstat.enabled ? -1 : 0);
  350. }
  351. private long
  352. current_VMThreshold(i_ctx_t *i_ctx_p)
  353. {
  354. gs_memory_gc_status_t stat;
  355. gs_memory_gc_status(iimemory_local, &stat);
  356. return stat.vm_threshold;
  357. }
  358. private long
  359. current_WaitTimeout(i_ctx_t *i_ctx_p)
  360. {
  361. return 0;
  362. }
  363. private int
  364. set_WaitTimeout(i_ctx_t *i_ctx_p, long val)
  365. {
  366. return 0;
  367. }
  368. private long
  369. current_MinScreenLevels(i_ctx_t *i_ctx_p)
  370. {
  371. return gs_currentminscreenlevels();
  372. }
  373. private int
  374. set_MinScreenLevels(i_ctx_t *i_ctx_p, long val)
  375. {
  376. gs_setminscreenlevels((uint) val);
  377. return 0;
  378. }
  379. private long
  380. current_AlignToPixels(i_ctx_t *i_ctx_p)
  381. {
  382. return gs_currentaligntopixels(ifont_dir);
  383. }
  384. private int
  385. set_AlignToPixels(i_ctx_t *i_ctx_p, long val)
  386. {
  387. gs_setaligntopixels(ifont_dir, (uint)val);
  388. return 0;
  389. }
  390. private long
  391. current_GridFitTT(i_ctx_t *i_ctx_p)
  392. {
  393. return gs_currentgridfittt(ifont_dir);
  394. }
  395. private int
  396. set_GridFitTT(i_ctx_t *i_ctx_p, long val)
  397. {
  398. gs_setgridfittt(ifont_dir, (uint)val);
  399. return 0;
  400. }
  401. private const long_param_def_t user_long_params[] =
  402. {
  403. {"JobTimeout", 0, MAX_UINT_PARAM,
  404. current_JobTimeout, set_JobTimeout},
  405. {"MaxFontItem", 0, MAX_UINT_PARAM,
  406. current_MaxFontItem, set_MaxFontItem},
  407. {"MinFontCompress", 0, MAX_UINT_PARAM,
  408. current_MinFontCompress, set_MinFontCompress},
  409. {"MaxOpStack", 0, MAX_UINT_PARAM,
  410. current_MaxOpStack, set_MaxOpStack},
  411. {"MaxDictStack", 0, MAX_UINT_PARAM,
  412. current_MaxDictStack, set_MaxDictStack},
  413. {"MaxExecStack", 0, MAX_UINT_PARAM,
  414. current_MaxExecStack, set_MaxExecStack},
  415. {"MaxLocalVM", 0, max_long,
  416. current_MaxLocalVM, set_MaxLocalVM},
  417. {"VMReclaim", -2, 0,
  418. current_VMReclaim, set_vm_reclaim},
  419. {"VMThreshold", -1, max_long,
  420. current_VMThreshold, set_vm_threshold},
  421. {"WaitTimeout", 0, MAX_UINT_PARAM,
  422. current_WaitTimeout, set_WaitTimeout},
  423. /* Extensions */
  424. {"MinScreenLevels", 0, MAX_UINT_PARAM,
  425. current_MinScreenLevels, set_MinScreenLevels},
  426. {"AlignToPixels", 0, 1,
  427. current_AlignToPixels, set_AlignToPixels},
  428. {"GridFitTT", 0, 3,
  429. current_GridFitTT, set_GridFitTT}
  430. };
  431. /* Boolean values */
  432. private bool
  433. current_AccurateScreens(i_ctx_t *i_ctx_p)
  434. {
  435. return gs_currentaccuratescreens();
  436. }
  437. private int
  438. set_AccurateScreens(i_ctx_t *i_ctx_p, bool val)
  439. {
  440. gs_setaccuratescreens(val);
  441. return 0;
  442. }
  443. /* Boolean values */
  444. private bool
  445. current_UseWTS(i_ctx_t *i_ctx_p)
  446. {
  447. return gs_currentusewts();
  448. }
  449. private int
  450. set_UseWTS(i_ctx_t *i_ctx_p, bool val)
  451. {
  452. gs_setusewts(val);
  453. return 0;
  454. }
  455. private bool
  456. current_LockFilePermissions(i_ctx_t *i_ctx_p)
  457. {
  458. return i_ctx_p->LockFilePermissions;
  459. }
  460. private int
  461. set_LockFilePermissions(i_ctx_t *i_ctx_p, bool val)
  462. {
  463. /* allow locking even if already locked */
  464. if (i_ctx_p->LockFilePermissions && !val)
  465. return_error(e_invalidaccess);
  466. i_ctx_p->LockFilePermissions = val;
  467. return 0;
  468. }
  469. private const bool_param_def_t user_bool_params[] =
  470. {
  471. {"AccurateScreens", current_AccurateScreens, set_AccurateScreens},
  472. {"UseWTS", current_UseWTS, set_UseWTS},
  473. {"LockFilePermissions", current_LockFilePermissions, set_LockFilePermissions}
  474. };
  475. /* The user parameter set */
  476. private const param_set user_param_set =
  477. {
  478. user_long_params, countof(user_long_params),
  479. user_bool_params, countof(user_bool_params),
  480. 0, 0
  481. };
  482. /* <dict> .setuserparams - */
  483. /* We break this out for use when switching contexts. */
  484. int
  485. set_user_params(i_ctx_t *i_ctx_p, const ref *paramdict)
  486. {
  487. dict_param_list list;
  488. int code;
  489. check_type(*paramdict, t_dictionary);
  490. code = dict_param_list_read(&list, paramdict, NULL, false, iimemory);
  491. if (code < 0)
  492. return code;
  493. code = setparams(i_ctx_p, (gs_param_list *)&list, &user_param_set);
  494. iparam_list_release(&list);
  495. return code;
  496. }
  497. private int
  498. zsetuserparams(i_ctx_t *i_ctx_p)
  499. {
  500. os_ptr op = osp;
  501. int code = set_user_params(i_ctx_p, op);
  502. if (code >= 0) {
  503. /* Update cached scanner options. */
  504. i_ctx_p->scanner_options =
  505. ztoken_scanner_options(op, i_ctx_p->scanner_options);
  506. pop(1);
  507. }
  508. return code;
  509. }
  510. /* - .currentuserparams <name1> <value1> ... */
  511. private int
  512. zcurrentuserparams(i_ctx_t *i_ctx_p)
  513. {
  514. return currentparams(i_ctx_p, &user_param_set);
  515. }
  516. /* <name> .getuserparam <value> */
  517. private int
  518. zgetuserparam(i_ctx_t *i_ctx_p)
  519. {
  520. return currentparam1(i_ctx_p, &user_param_set);
  521. }
  522. /* ------ Initialization procedure ------ */
  523. const op_def zusparam_op_defs[] =
  524. {
  525. /* User and system parameters are accessible even in Level 1 */
  526. /* (if this is a Level 2 system). */
  527. {"0.currentsystemparams", zcurrentsystemparams},
  528. {"0.currentuserparams", zcurrentuserparams},
  529. {"1.getsystemparam", zgetsystemparam},
  530. {"1.getuserparam", zgetuserparam},
  531. {"1.setsystemparams", zsetsystemparams},
  532. {"1.setuserparams", zsetuserparams},
  533. /* The rest of the operators are defined only in Level 2. */
  534. op_def_begin_level2(),
  535. {"1.checkpassword", zcheckpassword},
  536. op_def_end(0)
  537. };
  538. /* ------ Internal procedures ------ */
  539. /* Set the values of a parameter set from a parameter list. */
  540. /* We don't attempt to back out if anything fails. */
  541. private int
  542. setparams(i_ctx_t *i_ctx_p, gs_param_list * plist, const param_set * pset)
  543. {
  544. int i, code;
  545. for (i = 0; i < pset->long_count; i++) {
  546. const long_param_def_t *pdef = &pset->long_defs[i];
  547. long val;
  548. if (pdef->set == NULL)
  549. continue;
  550. code = param_read_long(plist, pdef->pname, &val);
  551. switch (code) {
  552. default: /* invalid */
  553. return code;
  554. case 1: /* missing */
  555. break;
  556. case 0:
  557. if (val < pdef->min_value || val > pdef->max_value)
  558. return_error(e_rangecheck);
  559. code = (*pdef->set)(i_ctx_p, val);
  560. if (code < 0)
  561. return code;
  562. }
  563. }
  564. for (i = 0; i < pset->bool_count; i++) {
  565. const bool_param_def_t *pdef = &pset->bool_defs[i];
  566. bool val;
  567. if (pdef->set == NULL)
  568. continue;
  569. code = param_read_bool(plist, pdef->pname, &val);
  570. if (code == 0)
  571. code = (*pdef->set)(i_ctx_p, val);
  572. if (code < 0)
  573. return code;
  574. }
  575. /****** WE SHOULD DO STRINGS AND STRING ARRAYS, BUT WE DON'T YET ******/
  576. return 0;
  577. }
  578. /* Get the current values of a parameter set to the stack. */
  579. private bool
  580. pname_matches(const char *pname, const ref * psref)
  581. {
  582. return
  583. (psref == 0 ||
  584. !bytes_compare((const byte *)pname, strlen(pname),
  585. psref->value.const_bytes, r_size(psref)));
  586. }
  587. private int
  588. current_param_list(i_ctx_t *i_ctx_p, const param_set * pset,
  589. const ref * psref /*t_string */ )
  590. {
  591. stack_param_list list;
  592. gs_param_list *const plist = (gs_param_list *)&list;
  593. int i;
  594. stack_param_list_write(&list, &o_stack, NULL, iimemory);
  595. for (i = 0; i < pset->long_count; i++) {
  596. const char *pname = pset->long_defs[i].pname;
  597. if (pname_matches(pname, psref)) {
  598. long val = (*pset->long_defs[i].current)(i_ctx_p);
  599. int code = param_write_long(plist, pname, &val);
  600. if (code < 0)
  601. return code;
  602. }
  603. }
  604. for (i = 0; i < pset->bool_count; i++) {
  605. const char *pname = pset->bool_defs[i].pname;
  606. if (pname_matches(pname, psref)) {
  607. bool val = (*pset->bool_defs[i].current)(i_ctx_p);
  608. int code = param_write_bool(plist, pname, &val);
  609. if (code < 0)
  610. return code;
  611. }
  612. }
  613. for (i = 0; i < pset->string_count; i++) {
  614. const char *pname = pset->string_defs[i].pname;
  615. if (pname_matches(pname, psref)) {
  616. gs_param_string val;
  617. int code;
  618. (*pset->string_defs[i].current)(i_ctx_p, &val);
  619. code = param_write_string(plist, pname, &val);
  620. if (code < 0)
  621. return code;
  622. }
  623. }
  624. return 0;
  625. }
  626. /* Get the current values of a parameter set to the stack. */
  627. private int
  628. currentparams(i_ctx_t *i_ctx_p, const param_set * pset)
  629. {
  630. return current_param_list(i_ctx_p, pset, NULL);
  631. }
  632. /* Get the value of a single parameter to the stack, or signal an error. */
  633. private int
  634. currentparam1(i_ctx_t *i_ctx_p, const param_set * pset)
  635. {
  636. os_ptr op = osp;
  637. ref sref;
  638. int code;
  639. check_type(*op, t_name);
  640. check_ostack(2);
  641. name_string_ref(imemory, (const ref *)op, &sref);
  642. code = current_param_list(i_ctx_p, pset, &sref);
  643. if (code < 0)
  644. return code;
  645. if (osp == op)
  646. return_error(e_undefined);
  647. /* We know osp == op + 2. */
  648. ref_assign(op, op + 2);
  649. pop(2);
  650. return code;
  651. }