1 /* apparam.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: apparam.c
27 *
28 * Author: Sergei Egorov
29 *
30 * Version Creation Date: 9/23/94
31 *
32 * $Revision: 6.1 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44
45 #include <apparam.h>
46
APArrayIndexKey(CharPtr key,Int4 i)47 CharPtr APArrayIndexKey (CharPtr key, Int4 i)
48 {
49 static Char buf[41];
50 if (key == NULL)
51 sprintf (buf,"_%ld", (long)i);
52 else
53 sprintf (buf,"%.30s_%ld", (char *)key, (long)i);
54 return buf;
55 }
56
APOpenSection(CharPtr file,CharPtr sect,APSectPtr sp)57 Boolean APOpenSection (CharPtr file, CharPtr sect, APSectPtr sp)
58 {
59 if (file == NULL || sect == NULL || sp == NULL) return FALSE;
60 StringNCpy_0 (&sp->base[0], file, MAX_APS_BASE); sp->base[MAX_APS_BASE] = '\0';
61 StringNCpy_0 (&sp->sect[0], sect, MAX_APS_SECT); sp->sect[MAX_APS_SECT] = '\0';
62 return TRUE;
63 }
64
65 /* empty string or NULL does not work as default??? */
66 static CharPtr default_string = "@[#$*-=%^'#$(%^)&";
67 static CharPtr deleted_ss_string = "<deleted>";
68
69 #define APV_ABSENT 0
70 #define APV_DELETED 1
71 #define APV_FOUND 2
72
73
ap_delete_section(APSectPtr sp)74 static Boolean ap_delete_section (APSectPtr sp)
75 {
76 if (sp == NULL) return FALSE;
77 return SetAppParam (&sp->base[0], &sp->sect[0], NULL, NULL);
78 }
79
ap_delete_key(APSectPtr sp,CharPtr key)80 static Boolean ap_delete_key (APSectPtr sp, CharPtr key)
81 {
82 Char buf [MAX_APS_VALUE+1];
83 if (sp == NULL || key == NULL) return FALSE;
84 /* don't delete if config file already has no (empty) value - JK */
85 if (! GetAppParam (&sp->base[0], &sp->sect[0], key, "", buf, MAX_APS_VALUE)) {
86 return TRUE;
87 }
88 return SetAppParam (&sp->base[0], &sp->sect[0], key, NULL);
89 }
90
ap_get_value(APSectPtr sp,CharPtr key,CharPtr PNTR pval)91 static Int2 ap_get_value (APSectPtr sp, CharPtr key, CharPtr PNTR pval)
92 {
93 static Char val_buf [MAX_APS_VALUE+1];
94 Int2 nchars;
95 if (sp == NULL || key == NULL) return APV_ABSENT; /*???*/
96 nchars = GetAppParam (&sp->base[0], &sp->sect[0], key, default_string,
97 val_buf, MAX_APS_VALUE);
98 if (pval != NULL) *pval = val_buf;
99 if (nchars == 0) {
100 StringNCpy_0 (val_buf, default_string, MAX_APS_VALUE); /* JK */
101 }
102 if (StrCmp (val_buf, default_string) == 0)
103 return APV_ABSENT;
104 else if (StrCmp (val_buf, deleted_ss_string) == 0)
105 return APV_DELETED;
106 else
107 return APV_FOUND;
108 }
109
ap_set_value(APSectPtr sp,CharPtr key,CharPtr val)110 static Boolean ap_set_value (APSectPtr sp, CharPtr key, CharPtr val)
111 {
112 Char buf [MAX_APS_VALUE+1];
113 if (sp == NULL || key == NULL || val == NULL) return FALSE;
114 /* don't write if config file already contains proper value - JK */
115 if (GetAppParam (&sp->base[0], &sp->sect[0], key, default_string, buf, MAX_APS_VALUE)) {
116 if (StrCmp (buf, val) == 0) {
117 return TRUE;
118 }
119 }
120 return SetAppParam (&sp->base[0], &sp->sect[0], key, val);
121 }
122
gen_ss_key(APSectPtr sp,Int2 i)123 static CharPtr gen_ss_key (APSectPtr sp, Int2 i)
124 {
125 static Char buf[41];
126 if (sp == NULL)
127 sprintf (buf,"#%d", (int)i);
128 else
129 sprintf (buf,"%.30s#%d", (char *)(&sp->sect[0]), (int)i);
130 return buf;
131 }
132
fill_ssp(APSectPtr ssp,APSectPtr sp,CharPtr sskey)133 static Boolean fill_ssp (APSectPtr ssp, APSectPtr sp, CharPtr sskey)
134 {
135 if (ssp == NULL || sp == NULL || sskey == NULL) return FALSE; /*???*/
136 StringNCpy_0 (&ssp->base[0], &sp->base[0], MAX_APS_BASE); ssp->base[MAX_APS_BASE] = '\0';
137 StringNCpy_0 (&ssp->sect[0], sskey, MAX_APS_SECT); ssp->sect[MAX_APS_SECT] = '\0';
138 return TRUE;
139 }
140
141
142 /* subsections */
143
144 /* arbitrary limit to number of subsections */
145 /* (to ensure that app won't hang up if something isn't working) */
146 #define MAX_SS_INDEX 456
147
APCreateSubsection(APSectPtr sp,CharPtr ss,APSectPtr ssp)148 Boolean APCreateSubsection (APSectPtr sp, CharPtr ss, APSectPtr ssp)
149 {
150 Int2 i; CharPtr sskey; Int2 deleted_i = -1;
151 if (sp == NULL || ss == NULL || ssp == NULL) return FALSE;
152 for (i = 0; i < MAX_SS_INDEX; i++) {
153 CharPtr name;
154 sskey = gen_ss_key (sp, i);
155 switch (ap_get_value (sp, sskey, &name)) {
156 case APV_ABSENT:
157 if (deleted_i >= 0) i = deleted_i;
158 if (i >= MAX_SS_INDEX) return FALSE;
159 sskey = gen_ss_key (sp, i);
160 return (ap_set_value (sp, sskey, ss) && fill_ssp (ssp, sp, sskey));
161 case APV_DELETED:
162 deleted_i = i;
163 break;
164 case APV_FOUND:
165 if (StrICmp (name, ss) == 0)
166 return fill_ssp (ssp, sp, sskey);
167 break;
168 default: return FALSE; /*????*/
169 }
170 }
171 Message(MSG_ERROR, "in APCreateSubsection");
172 return FALSE; /*????*/
173 }
174
175
APLookupSubsection(APSectPtr sp,CharPtr ss,APSectPtr ssp)176 Boolean APLookupSubsection (APSectPtr sp, CharPtr ss, APSectPtr ssp)
177 {
178 Int2 i;
179 if (sp == NULL || ss == NULL || ssp == NULL) return FALSE;
180 for (i = 0; i < MAX_SS_INDEX; i++) {
181 CharPtr name;
182 CharPtr sskey = gen_ss_key (sp, i);
183 switch (ap_get_value (sp, sskey, &name)) {
184 case APV_ABSENT:
185 return FALSE;
186 case APV_DELETED:
187 break;
188 case APV_FOUND:
189 if (StrICmp (name, ss) == 0)
190 return fill_ssp (ssp, sp, sskey);
191 break;
192 default: return FALSE; /*????*/
193 }
194 }
195 Message(MSG_ERROR, "in APLookupSubsection");
196 return FALSE; /*????*/
197 }
198
199
APDeleteSubsection(APSectPtr sp,CharPtr ss)200 Boolean APDeleteSubsection (APSectPtr sp, CharPtr ss)
201 {
202 Int2 i; APSect sbs;
203 if (sp == NULL || ss == NULL) return FALSE;
204 for (i = 0; i < MAX_SS_INDEX; i++) {
205 CharPtr name;
206 CharPtr sskey = gen_ss_key (sp, i);
207 switch (ap_get_value (sp, sskey, &name)) {
208 case APV_ABSENT:
209 return FALSE;
210 case APV_DELETED:
211 break;
212 case APV_FOUND:
213 if (StrCmp (name, ss) == 0)
214 return (ap_set_value (sp, sskey, deleted_ss_string)
215 && fill_ssp (&sbs, sp, sskey)
216 && ap_delete_section (&sbs));
217 break;
218 default: return FALSE; /*????*/
219 }
220 }
221 Message(MSG_ERROR, "in APDeleteSubsection");
222 return FALSE; /*????*/
223 }
224
APForEachSubsection(APSectPtr sp,void (* proc)(CharPtr ss))225 void APForEachSubsection (APSectPtr sp, void (*proc) (CharPtr ss))
226 {
227 Int2 i;
228 if (sp == NULL || proc == NULL) return;
229 for (i = 0; i < MAX_SS_INDEX; i++) {
230 CharPtr name;
231 CharPtr sskey = gen_ss_key (sp, i);
232 switch (ap_get_value (sp, sskey, &name)) {
233 case APV_ABSENT:
234 return;
235 case APV_DELETED:
236 break;
237 case APV_FOUND:
238 proc (name);
239 }
240 }
241 Message(MSG_ERROR, "in APForEachParamSubsection");
242 }
243
244
245 /* special font dir hacks ??? */
246
APFindEntry(APSectPtr sp,CharPtr ss,Int2Ptr pindex)247 Boolean APFindEntry (APSectPtr sp, CharPtr ss, Int2Ptr pindex)
248 {
249 Int2 i;
250 if (sp == NULL || ss == NULL) return FALSE;
251 for (i = 0; i < MAX_SS_INDEX; i++) {
252 CharPtr name;
253 CharPtr sskey = gen_ss_key (sp, i);
254 switch (ap_get_value (sp, sskey, &name)) {
255 case APV_ABSENT:
256 return FALSE;
257 case APV_DELETED:
258 break;
259 case APV_FOUND:
260 if (StrICmp (name, ss) == 0) {
261 if (pindex != NULL) *pindex = i;
262 return TRUE;
263 }
264 break;
265 default: return FALSE; /*????*/
266 }
267 }
268 Message(MSG_ERROR, "in APFindEntry");
269 return FALSE; /*????*/
270 }
271
APEntrySubsection(APSectPtr sp,Int2 index,APSectPtr ssp)272 Boolean APEntrySubsection (APSectPtr sp, Int2 index, APSectPtr ssp)
273 {
274 CharPtr sskey = gen_ss_key (sp, index);
275 CharPtr name;
276 if (ap_get_value (sp, sskey, &name) == APV_FOUND)
277 return fill_ssp (ssp, sp, sskey);
278 else
279 return FALSE;
280 }
281
282
283 static Char format_buf [120];
284
285 /* basic operations */
286
APForEachKey(APSectPtr sp,void (* proc)(CharPtr key))287 void APForEachKey (APSectPtr sp, void (*proc) (CharPtr key))
288 {
289 return; /* NYI */
290 }
291
APDeleteSection(APSectPtr sp)292 Boolean APDeleteSection (APSectPtr sp)
293 {
294 return ap_delete_section (sp);
295 }
296
APFindKey(APSectPtr sp,CharPtr key)297 Boolean APFindKey (APSectPtr sp, CharPtr key)
298 {
299 if (sp == NULL || key == NULL) return FALSE;
300 return (ap_get_value (sp, key, NULL) == APV_FOUND);
301 }
302
APDeleteKey(APSectPtr sp,CharPtr key)303 Boolean APDeleteKey (APSectPtr sp, CharPtr key)
304 {
305 return ap_delete_key (sp, key);
306 }
307
APGetKeyValue(APSectPtr sp,CharPtr key,CharPtr PNTR pval)308 Boolean APGetKeyValue (APSectPtr sp, CharPtr key, CharPtr PNTR pval)
309 {
310 if (sp == NULL || key == NULL || pval == NULL) return FALSE;
311 return (ap_get_value (sp, key, pval) == APV_FOUND);
312 }
313
APSetKeyValue(APSectPtr sp,CharPtr key,CharPtr val)314 Boolean APSetKeyValue (APSectPtr sp, CharPtr key, CharPtr val)
315 {
316 return ap_set_value (sp, key, val);
317 }
318
319
320 /* parameter read/write */
321
APArchiveBoolean(Boolean writep,APSectPtr sp,CharPtr key,BoolPtr pb)322 Boolean APArchiveBoolean (Boolean writep, APSectPtr sp, CharPtr key, BoolPtr pb)
323 {
324 CharPtr val;
325 if (writep) {
326 if (pb == NULL) return FALSE;
327 return ap_set_value (sp, key, *pb ? "TRUE" : "FALSE");
328 }
329 if (ap_get_value (sp, key, &val) == APV_FOUND) {
330 if (pb != NULL) *pb = (StrICmp(val, "FALSE") == 0) ? FALSE : TRUE;
331 return TRUE;
332 }
333 return FALSE;
334 }
335
APArchiveEnum(Boolean writep,APSectPtr sp,CharPtr key,UIEnumPtr pe)336 Boolean APArchiveEnum (Boolean writep, APSectPtr sp, CharPtr key, UIEnumPtr pe)
337 {
338 CharPtr val;
339 if (writep) {
340 if (pe == NULL) return FALSE;
341 sprintf (format_buf, "%ld", (long) *pe);
342 return ap_set_value (sp, key, format_buf);
343 }
344 if (ap_get_value (sp, key, &val) == APV_FOUND) {
345 long l;
346 if (sscanf (val, "%ld", &l) != 1) return FALSE;
347 if (pe != NULL) *pe = (UIEnum)l;
348 return TRUE;
349 }
350 return FALSE;
351 }
352
APArchiveInt2(Boolean writep,APSectPtr sp,CharPtr key,Int2Ptr pi2)353 Boolean APArchiveInt2 (Boolean writep, APSectPtr sp, CharPtr key, Int2Ptr pi2)
354 {
355 CharPtr val;
356 if (writep) {
357 if (pi2 == NULL) return FALSE;
358 sprintf (format_buf, "%d", (int) *pi2);
359 return ap_set_value (sp, key, format_buf);
360 }
361 if (ap_get_value (sp, key, &val) == APV_FOUND) {
362 int i;
363 if (sscanf (val, "%d", &i) != 1) return FALSE;
364 if (pi2 != NULL) *pi2 = (Int2)i;
365 return TRUE;
366 }
367 return FALSE;
368 }
369
APArchiveUint2(Boolean writep,APSectPtr sp,CharPtr key,Uint2Ptr pu2)370 Boolean APArchiveUint2 (Boolean writep, APSectPtr sp, CharPtr key, Uint2Ptr pu2)
371 {
372 CharPtr val;
373 if (writep) {
374 if (pu2 == NULL) return FALSE;
375 sprintf (format_buf, "%u", (unsigned int) *pu2);
376 return ap_set_value (sp, key, format_buf);
377 }
378 if (ap_get_value (sp, key, &val) == APV_FOUND) {
379 unsigned int u;
380 if (sscanf (val, "%u", &u) != 1) return FALSE;
381 if (pu2 != NULL) *pu2 = (Uint2)u;
382 return TRUE;
383 }
384 return FALSE;
385 }
386
APArchiveInt4(Boolean writep,APSectPtr sp,CharPtr key,Int4Ptr pi4)387 Boolean APArchiveInt4 (Boolean writep, APSectPtr sp, CharPtr key, Int4Ptr pi4)
388 {
389 CharPtr val;
390 if (writep) {
391 if (pi4 == NULL) return FALSE;
392 sprintf (format_buf, "%ld", (long) *pi4);
393 return ap_set_value (sp, key, format_buf);
394 }
395 if (ap_get_value (sp, key, &val) == APV_FOUND) {
396 long l;
397 if (sscanf (val, "%ld", &l) != 1) return FALSE;
398 if (pi4 != NULL) *pi4 = (Int4)l;
399 return TRUE;
400 }
401 return FALSE;
402 }
403
APArchiveUint4(Boolean writep,APSectPtr sp,CharPtr key,Uint4Ptr pu4)404 Boolean APArchiveUint4 (Boolean writep, APSectPtr sp, CharPtr key, Uint4Ptr pu4)
405 {
406 CharPtr val;
407 if (writep) {
408 if (pu4 == NULL) return FALSE;
409 sprintf (format_buf, "%lu", (unsigned long) *pu4);
410 return ap_set_value (sp, key, format_buf);
411 }
412 if (ap_get_value (sp, key, &val) == APV_FOUND) {
413 unsigned long lu;
414 if (sscanf (val, "%lu", &lu) != 1) return FALSE;
415 if (pu4 != NULL) *pu4 = (Uint4)lu;
416 return TRUE;
417 }
418 return FALSE;
419 }
420
APArchiveString(Boolean writep,APSectPtr sp,CharPtr key,CharPtr psb,Int2 bsz)421 Boolean APArchiveString (Boolean writep, APSectPtr sp, CharPtr key, CharPtr psb, Int2 bsz)
422 {
423 CharPtr val;
424 if (writep) return ap_set_value (sp, key, psb);
425 if (ap_get_value (sp, key, &val) == APV_FOUND) {
426 if (psb != NULL && bsz >= 0) StringNCpy_0 (psb, val, bsz);
427 return TRUE;
428 }
429 return FALSE;
430 }
431
432