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