1 /* Copyright (C) 1999 artofcode LLC. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify it
4 under the terms of the GNU General Public License as published by the
5 Free Software Foundation; either version 2 of the License, or (at your
6 option) any later version.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along
14 with this program; if not, write to the Free Software Foundation, Inc.,
15 59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16
17 */
18
19 /*$Id: gsparamx.c,v 1.4.2.1.2.1 2003/01/17 00:49:03 giles Exp $ */
20 /* Extended parameter dictionary utilities */
21 #include "string_.h"
22 #include "gserror.h"
23 #include "gserrors.h"
24 #include "gstypes.h"
25 #include "gsmemory.h"
26 #include "gsparam.h"
27 #include "gsparamx.h"
28
29 /* Compare a C string and a gs_param_string. */
30 bool
gs_param_string_eq(const gs_param_string * pcs,const char * str)31 gs_param_string_eq(const gs_param_string * pcs, const char *str)
32 {
33 return (strlen(str) == pcs->size &&
34 !strncmp(str, (const char *)pcs->data, pcs->size));
35 }
36
37 /* Put an enumerated value. */
38 int
param_put_enum(gs_param_list * plist,gs_param_name param_name,int * pvalue,const char * const pnames[],int ecode)39 param_put_enum(gs_param_list * plist, gs_param_name param_name,
40 int *pvalue, const char *const pnames[], int ecode)
41 {
42 gs_param_string ens;
43 int code = param_read_name(plist, param_name, &ens);
44
45 switch (code) {
46 case 1:
47 return ecode;
48 case 0:
49 {
50 int i;
51
52 for (i = 0; pnames[i] != 0; ++i)
53 if (gs_param_string_eq(&ens, pnames[i])) {
54 *pvalue = i;
55 return 0;
56 }
57 }
58 code = gs_error_rangecheck;
59 default:
60 ecode = code;
61 param_signal_error(plist, param_name, code);
62 }
63 return code;
64 }
65
66 /* Put a Boolean value. */
67 int
param_put_bool(gs_param_list * plist,gs_param_name param_name,bool * pval,int ecode)68 param_put_bool(gs_param_list * plist, gs_param_name param_name,
69 bool * pval, int ecode)
70 {
71 int code;
72
73 switch (code = param_read_bool(plist, param_name, pval)) {
74 default:
75 ecode = code;
76 param_signal_error(plist, param_name, ecode);
77 case 0:
78 case 1:
79 break;
80 }
81 return ecode;
82 }
83
84 /* Put an integer value. */
85 int
param_put_int(gs_param_list * plist,gs_param_name param_name,int * pval,int ecode)86 param_put_int(gs_param_list * plist, gs_param_name param_name,
87 int *pval, int ecode)
88 {
89 int code;
90
91 switch (code = param_read_int(plist, param_name, pval)) {
92 default:
93 ecode = code;
94 param_signal_error(plist, param_name, ecode);
95 case 0:
96 case 1:
97 break;
98 }
99 return ecode;
100 }
101
102 /* Put a long value. */
103 int
param_put_long(gs_param_list * plist,gs_param_name param_name,long * pval,int ecode)104 param_put_long(gs_param_list * plist, gs_param_name param_name,
105 long *pval, int ecode)
106 {
107 int code;
108
109 switch (code = param_read_long(plist, param_name, pval)) {
110 default:
111 ecode = code;
112 param_signal_error(plist, param_name, ecode);
113 case 0:
114 case 1:
115 break;
116 }
117 return ecode;
118 }
119
120 /* Copy one parameter list to another, recursively if necessary. */
121 int
param_list_copy(gs_param_list * plto,gs_param_list * plfrom)122 param_list_copy(gs_param_list *plto, gs_param_list *plfrom)
123 {
124 gs_param_enumerator_t key_enum;
125 gs_param_key_t key;
126 /*
127 * If plfrom and plto use different allocators, we must copy
128 * aggregate values even if they are "persistent".
129 */
130 bool copy_persists = plto->memory == plfrom->memory;
131 int code;
132
133 param_init_enumerator(&key_enum);
134 while ((code = param_get_next_key(plfrom, &key_enum, &key)) == 0) {
135 char string_key[256]; /* big enough for any reasonable key */
136 gs_param_typed_value value;
137 gs_param_collection_type_t coll_type;
138 gs_param_typed_value copy;
139
140 if (key.size > sizeof(string_key) - 1) {
141 code = gs_note_error(gs_error_rangecheck);
142 break;
143 }
144 memcpy(string_key, key.data, key.size);
145 string_key[key.size] = 0;
146 if ((code = param_read_typed(plfrom, string_key, &value)) != 0) {
147 code = (code > 0 ? gs_note_error(gs_error_unknownerror) : code);
148 break;
149 }
150 gs_param_list_set_persistent_keys(plto, key.persistent);
151 switch (value.type) {
152 case gs_param_type_dict:
153 coll_type = gs_param_collection_dict_any;
154 goto cc;
155 case gs_param_type_dict_int_keys:
156 coll_type = gs_param_collection_dict_int_keys;
157 goto cc;
158 case gs_param_type_array:
159 coll_type = gs_param_collection_array;
160 cc:
161 copy.value.d.size = value.value.d.size;
162 if ((code = param_begin_write_collection(plto, string_key,
163 ©.value.d,
164 coll_type)) < 0 ||
165 (code = param_list_copy(copy.value.d.list,
166 value.value.d.list)) < 0 ||
167 (code = param_end_write_collection(plto, string_key,
168 ©.value.d)) < 0)
169 break;
170 code = param_end_read_collection(plfrom, string_key,
171 &value.value.d);
172 break;
173 case gs_param_type_string:
174 value.value.s.persistent &= copy_persists; goto ca;
175 case gs_param_type_name:
176 value.value.n.persistent &= copy_persists; goto ca;
177 case gs_param_type_int_array:
178 value.value.ia.persistent &= copy_persists; goto ca;
179 case gs_param_type_float_array:
180 value.value.fa.persistent &= copy_persists; goto ca;
181 case gs_param_type_string_array:
182 value.value.sa.persistent &= copy_persists;
183 ca:
184 default:
185 code = param_write_typed(plto, string_key, &value);
186 }
187 if (code < 0)
188 break;
189 }
190 return code;
191 }
192