My Project
Loading...
Searching...
No Matches
feResource.cc
Go to the documentation of this file.
1/****************************************
2* Computer Algebra System SINGULAR *
3****************************************/
4/*
5* ABSTRACT: management of resources
6*/
7
8#include "singular_resourcesconfig.h"
9#include "feResource.h"
10#include "omFindExec.h"
11
12#include <stdlib.h>
13#include <unistd.h>
14#include <string.h>
15#include <stdio.h>
16#include <sys/param.h>
17
18
20
21//char* feResource(const char id, int warn = -1);
22//char* feResource(const char* key, int warn = -1);
23
24// define RESOURCE_DEBUG for chattering about resource management
25// #define RESOURCE_DEBUG
26
27#define SINGULAR_DEFAULT_DIR PREFIX
28
29/*****************************************************************
30 *
31 * Declarations: Data structures
32 *
33 *****************************************************************/
34// feSprintf transforms format strings as follows:
35// 1.) substrings of the form %c (c being a letter) are replaced by respective resource value
36// 2.) substrings of the form $string are replaced by value of resp. env variable
37
38// feCleanResource makes furthermore the following transformations (except for URL resources)
39// 1.) '/' characters are replaced by respective directory - separators
40// 2.) ';' characters are replaced by respective path separators
42{
43 {"SearchPath", 's', feResPath, NULL,
44 "$SINGULARPATH;"
45 "%D/singular/LIB;"
46 "%r/share/singular/LIB;"
47 "%b/../share/singular/LIB;"
48 // gftables:
49 "%D/factory;"
50 "%r/share/factory;"
51 "%b/LIB;"
52 "%b/../LIB;" // not installed, shared is in .libs/Singular
53 "%b/../factory;"
54 "%b/../../factory;" // not installed, shared is in .libs/Singular
55 // path for dynamic modules, should match ProcDir:
56 "%b/MOD;"
57 "%b/../MOD;" // Singular in .libs/Singular
58 "%r/lib/singular/MOD;"
59 "%r/libexec/singular/MOD;"
60 LIB_DIR "/singular/MOD;"
61 LIBEXEC_DIR "/singular/MOD;"
62 "%b;"
63 "%b/..", // Singular in .libs/Singular
64 (char *)""},
65 {"Singular", 'S', feResBinary,"SINGULAR_EXECUTABLE", "%d/Singular", (char *)""},
66 {"BinDir", 'b', feResDir, "SINGULAR_BIN_DIR", "", (char *)""},
67 // should be changed to %b/../lib/singular/pProcs/:
68 {"ProcDir", 'P', feResPath, "SINGULAR_PROCS_DIR",
69 "%b/MOD;"
70 "%b/../MOD;" // Singular in .libs/Singular
71 "%b/..;" // Singular in .libs/Singular, programs in .
72 "%r/lib/singular/MOD;"
73 "%r/libexec/singular/MOD;"
74 LIB_DIR "/singular/MOD;" /*debian: -> /usr/lib/singular/MOD */
75 LIBEXEC_DIR "/singular/MOD" , (char *)""},
76 {"RootDir", 'r', feResDir, "SINGULAR_ROOT_DIR", "%b/..", (char *)""},
77 {"DataDir", 'D', feResDir, "SINGULAR_DATA_DIR", "%b/../share/", (char *)""},
78 {"DefaultDir",'d', feResDir, "SINGULAR_DEFAULT_DIR", SINGULAR_DEFAULT_DIR, (char *)""},
79 {"InfoFile", 'i', feResFile, "SINGULAR_INFO_FILE", "%D/info/singular.info", (char *)""},
80 {"IdxFile", 'x', feResFile, "SINGULAR_IDX_FILE", "%D/singular/singular.idx", (char *)""},
81 {"HtmlDir", 'h', feResDir, "SINGULAR_HTML_DIR", DATA_TO_HTML_DIR, (char *)""},
82 {"ManualUrl", 'u', feResUrl, "SINGULAR_URL", "https://www.singular.uni-kl.de/Manual/", (char *)""},
83 {"ExDir", 'm', feResDir, "SINGULAR_EXAMPLES_DIR","%r/examples", (char *)""},
84 {"Path", 'p', feResPath, NULL, "%b;%P;$PATH", (char *)""},
85
86#ifdef __CYGWIN__
87 {"emacs", 'E', feResBinary,"ESINGULAR_EMACS", "%b/emacs.exe", (char *)""},
88 {"xemacs", 'A', feResBinary,"ESINGULAR_EMACS", "%b/xemacs.exe", (char *)""},
89 {"SingularEmacs",'M', feResBinary,"ESINGULAR_SINGULAR", "%b/Singular.exe", (char *)""},
90#else
91 {"emacs", 'E', feResBinary,"ESINGULAR_EMACS", "%b/emacs", (char *)""},
92 {"xemacs", 'A', feResBinary,"ESINGULAR_EMACS", "%b/xemacs", (char *)""},
93 {"SingularEmacs",'M', feResBinary,"ESINGULAR_SINGULAR", "%b/Singular", (char *)""},
94#endif
95 {"EmacsLoad", 'l', feResFile, "ESINGULAR_EMACS_LOAD", "%e/.emacs-singular", (char *)""},
96 {"EmacsDir", 'e', feResDir, "ESINGULAR_EMACS_DIR", "%D/singular/emacs", (char *)""},
97 {"SingularXterm",'M', feResBinary,"TSINGULAR_SINGULAR", "%b/Singular", (char *)""},
98#ifdef __CYGWIN__
99 {"rxvt", 'X', feResBinary,"RXVT", "%b/rxvt", (char *)""},
100#else
101 {"xterm", 'X', feResBinary,"XTERM", "%b/xterm", (char *)""},
102#endif
103 {"EmacsDir", 'e', feResDir, "SINGULAR_EMACS_DIR", "%r/emacs", (char *)""},
104 {NULL, 0, feResUndef, NULL, NULL, NULL}, // must be the last record
105};
106
107
108/*****************************************************************
109 *
110 * Declarations: Local variables / functions
111 *
112 *****************************************************************/
113
114#define MAXRESOURCELEN 5*MAXPATHLEN
115
116static feResourceConfig feGetResourceConfig(const char id);
117static feResourceConfig feGetResourceConfig(const char* key);
118static char* feResource(feResourceConfig config, int warn);
119static char* feResourceDefault(feResourceConfig config);
120static char* feInitResource(feResourceConfig config, int warn);
121static char* feGetExpandedExecutable();
122static int feVerifyResourceValue(feResourceType type, char* value);
123static char* feCleanResourceValue(feResourceType type, char* value);
124static char* feCleanUpFile(char* fname);
125static char* feCleanUpPath(char* path);
126static void mystrcpy(char* d, char* s);
127static char* feSprintf(char* s, const char* fmt, int warn = -1);
128#if defined(__CYGWIN__) && defined(__GNUC__)
129// utility function of Cygwin32:
130extern "C" int cygwin32_posix_path_list_p (const char *path);
131#endif
132
133/*****************************************************************
134 *
135 * Public functions
136 *
137 *****************************************************************/
138char* feResource(const char* key, int warn)
139{
140 return feResource(feGetResourceConfig(key), warn);
141}
142
143char* feResource(const char id, int warn)
144{
145 return feResource(feGetResourceConfig(id), warn);
146}
147
148char* feGetResource(const char id, int warn)
149{
150 return feResource(feGetResourceConfig(id), warn);
151}
152
153char* feResourceDefault(const char id)
154{
156}
157
158char* feResourceDefault(const char* key)
159{
161}
162
163void feInitResources(const char* argv0)
164{
165 if (argv0==NULL)
166 {
167 //WarnS("illegal argv[0]==NULL");
168 feArgv0 = (char*)malloc(MAXPATHLEN+strlen("/Singular"));
169 getcwd(feArgv0, MAXPATHLEN);
170 strcat(feArgv0,"/Singular");
171 }
172 else
173 feArgv0 = strdup(argv0);
174#ifdef RESOURCE_DEBUG
175 printf("feInitResources(argv0: '%s'): entering...\n", feArgv0);
176#endif
177 // init some Resources
178 feResource('b');
179 feResource('r');
180 // don't complain about stuff when initializing SingularPath
181 feResource('s',0);
182 feResource('P');
183}
184
186{
187 int i = 0;
188 while (feResourceConfigs[i].key != NULL)
189 {
190 if ((feResourceConfigs[i].value != NULL)
191 && (feResourceConfigs[i].value[0] != '\0'))
192 {
193 free(feResourceConfigs[i].value);
194 feResourceConfigs[i].value = (char *)"";
195 }
196 i++;
197 }
198#ifdef RESOURCE_DEBUG
199 printf("feInitResources(): entering...\n");
200#endif
201 // init some Resources
202 feResource('b');
203 feResource('r');
204 // don't complain about stuff when initializing SingularPath
205 feResource('s',0);
206}
207
208/*****************************************************************
209 *
210 * Local functions
211 *
212 *****************************************************************/
214{
215 int i = 0;
216 while (feResourceConfigs[i].key != NULL)
217 {
218 if (feResourceConfigs[i].id == id) return &(feResourceConfigs[i]);
219 i++;
220 }
221 return NULL;
222}
223
225{
226 int i = 0;
227 while (feResourceConfigs[i].key != NULL)
228 {
229 if (strcmp(feResourceConfigs[i].key, key) == 0)
230 return &(feResourceConfigs[i]);
231 i++;
232 }
233 return NULL;
234}
235
236static char* feResource(feResourceConfig config, int warn)
237{
238 if (config == NULL) return NULL;
239 if (config->value != NULL && *(config->value) != '\0') return config->value;
240 return feInitResource(config, warn);
241}
242
244{
245 if (config == NULL) return NULL;
246 char* value = (char*) malloc(MAXRESOURCELEN);
247 feSprintf(value, config->fmt, -1);
248 return value;
249}
250
251static char* feInitResource(feResourceConfig config, int warn)
252{
253 /*assume(config != NULL);*/
254#ifdef RESOURCE_DEBUG
255 printf("feInitResource(config->key: '%s', warn: '%d') : entering ...\n", config->key, warn);
256#endif
257
258 char value[MAXRESOURCELEN];
259 // now we have to work
260 // First, check Environment variable
261 if (config->env != NULL)
262 {
263 char* evalue = getenv(config->env);
264 if (evalue != NULL)
265 {
266#ifdef RESOURCE_DEBUG
267 printf("feInitResource(config,warn): Found value from env:%s\n", evalue);
268#endif
269 strcpy(value, evalue);
270 if (config->type == feResBinary // do not verify binaries
271 ||
272 feVerifyResourceValue(config->type,
273 feCleanResourceValue(config->type, value)))
274 {
275#ifdef RESOURCE_DEBUG
276 printf("feInitResource(config,warn): Set value of config (with key: '%s') to '%s'\n", config->key, value);
277#endif
278 config->value = strdup(value);
279 return config->value;
280 }
281 }
282 }
283
284 *value = '\0';
285 // Special treatment of executable
286 if (config->id == 'S')
287 {
288 char* executable = feGetExpandedExecutable();
289 if (executable != NULL)
290 {
291#ifdef RESOURCE_DEBUG
292 printf("exec:%s\n", executable);
293#endif
294 strcpy(value, executable);
295#ifdef RESOURCE_DEBUG
296 printf("value:%s\n", value);
297#endif
298 free(executable);
299 }
300 }
301 // and bindir
302 else if (config->id == 'b')
303 {
304 char* executable = feResource('S');
305#ifdef RESOURCE_DEBUG
306 printf("feInitResource(config,warn): Get '%s' from \"%s\"\n", config->key, executable);
307#endif
308 if (executable != NULL)
309 {
310 strcpy(value, executable);
311 executable = strrchr(value, DIR_SEP);
312 if (executable != NULL) *executable = '\0';
313 }
314 }
315
316#ifdef RESOURCE_DEBUG
317 printf("value:%s\n", value);
318#endif
319
320 if (*value == '\0' && config->fmt != NULL )
321 {
322 feSprintf(value, config->fmt, warn);
323 }
324 else if (config->fmt == NULL)
325 {
326 printf("Bug >>Wrong Resource Specification of '%s'<< at \"%s:%d\"\n",config->key,__FILE__,__LINE__);
327 // TODO: printf -> WarnS???
328 return NULL;
329 }
330
331 // Clean and verify
332 if (feVerifyResourceValue(config->type,
333 feCleanResourceValue(config->type, value)))
334 {
335#ifdef RESOURCE_DEBUG
336 printf("feInitResource(config,warn): Set value of '%s' to \"%s\"\n", config->key, value);
337#endif
338 config->value = strdup(value);
339 return config->value;
340 }
341 else if (config->type == feResBinary)
342 {
343 // for binaries, search through PATH once more
344 char* executable = omFindExec(config->key, value);
345 if (executable != NULL)
346 {
347 if (feVerifyResourceValue(config->type,
348 feCleanResourceValue(config->type, value)))
349 {
350 config->value = strdup(value);
351#ifdef RESOURCE_DEBUG
352 printf("feInitResource(config,warn): Set value of '%s' to \"%s\"\n", config->key, config->value);
353#endif
354 return config->value;
355 }
356 }
357 }
358
359 // issue warning if explicitely requested, or if
360 // this value is gotten for the first time
361 if (warn > 0 || (warn < 0 && config->value != NULL))
362 {
363 printf("// ** Could not get '%s'.\n", config->key);
364 printf("// ** Either set environment variable '%s' to '%s',\n",
365 config->env, config->key);
366 feSprintf(value, config->fmt, warn);
367 printf("// ** or make sure that '%s' is at \"%s\"\n", config->key, value);
368 }
369#ifdef RESOURCE_DEBUG
370 printf("feInitResource(config,warn): Set value of '%s' to NULL", config->key);
371#endif
372 config->value = NULL;
373 return NULL;
374}
375
377{
378 if (feArgv0 == NULL || *feArgv0 == '\0')
379 {
380 if (feArgv0 == NULL)
381 printf("Bug >>feArgv0 == NULL<< at %s:%d\n",__FILE__,__LINE__);
382 else
383 printf("Bug >>feArgv0 == ''<< at %s:%d\n",__FILE__,__LINE__);
384 return NULL;
385 }
386#ifdef __CYGWIN__ // stupid WINNT sometimes gives you argv[0] within ""
387 if (*feArgv0 == '"')
388 {
389 int l = strlen(feArgv0);
390 if (feArgv0[l-1] == '"')
391 {
392 feArgv0[l-1] = '\0';
393 feArgv0++;
394 }
395 }
396#endif
397#ifdef RESOURCE_DEBUG
398 printf("feGetExpandedExecutable: calling find_exec with \"%s\"\n", feArgv0);
399#endif
400 char executable[MAXRESOURCELEN];
401 char* value = omFindExec(feArgv0, executable);
402#ifdef RESOURCE_DEBUG
403 printf("feGetExpandedExecutable: find_exec exited with \"%s\": %d\n", executable, access(executable, X_OK));
404#endif
405 if (value == NULL)
406 {
407 printf("Bug >>Could not get expanded executable from \"%s\"<< at %s:%d\n",feArgv0,__FILE__,__LINE__);
408 return NULL;
409 }
410 return strdup(value);
411}
412
413
414static int feVerifyResourceValue(feResourceType type, char* value)
415{
416#ifdef RESOURCE_DEBUG
417 printf("feVerifyResourceValue(type: %d, value: \"%s\"): entering\n", (int)type, value);
418 printf("Access: ROK: %d, XOK: %d\n", access(value, R_OK), access(value, X_OK));
419#endif
420 switch(type)
421 {
422 case feResUrl:
423 case feResPath:
424 return 1;
425
426 case feResFile:
427 return ! access(value, R_OK);
428
429 case feResBinary:
430 case feResDir:
431 return ! access(value, X_OK);
432
433 default:
434 return 0;
435 }
436}
437
438/*****************************************************************
439 *
440 * Cleaning/Transformations of resource values
441 *
442 *****************************************************************/
443
444static char* feCleanResourceValue(feResourceType type, char* value)
445{
446 if (value == NULL || *value == '\0') return value;
447#ifdef RESOURCE_DEBUG
448 printf("Clean value:%s\n", value);
449#endif
450#ifdef __CYGWIN__
451#ifdef RESOURCE_DEBUG
452 printf("Clean WINNT value:%s\n", value);
453#endif
454 if (type == feResBinary)
455 {
456 int l = strlen(value);
457 if (l < 4 || (strcmp(&value[l-4], ".exe") != 0 &&
458 strcmp(&value[l-4], ".EXE") != 0))
459 strcat(value, ".exe");
460 }
461#endif
462 if (type == feResFile || type == feResBinary || type == feResDir)
463 return feCleanUpFile(value);
464 if (type == feResPath)
465 return feCleanUpPath(value);
466 return value;
467}
468
469static char* feCleanUpFile(char* fname)
470{
471 char* fn;
472
473#ifdef RESOURCE_DEBUG
474 printf("feCleanUpFile: entering with =%s=\n", fname);
475#endif
476 // Remove unnecessary .. and //
477 for (fn = fname; *fn != '\0'; fn++)
478 {
479 if (*fn == '/')
480 {
481 if (*(fn+1) == '\0')
482 {
483 if (fname != fn) *fn = '\0';
484 break;
485 }
486 if (*(fn + 1) == '/' && (fname != fn))
487 {
488 mystrcpy(fn, fn+1);
489 fn--;
490 }
491 else if (*(fn+1) == '.')
492 {
493 if (*(fn+2) == '.' && (*(fn + 3) == '/' || *(fn + 3) == '\0'))
494 {
495 #if 0
496 // this does not work: ./../../mmm will be changed to ./../mmm
497 // but we only want to change ././mmm to ./mmm
498 *fn = '\0';
499 s = strrchr(fname, '/');
500 if (s != NULL)
501 {
502 mystrcpy(s+1, fn + (*(fn + 3) != '\0' ? 4 : 3));
503 fn = s-1;
504 }
505 else
506 {
507 *fn = '/';
508 }
509 #endif
510 }
511 else if (*(fn+2) == '/' || *(fn+2) == '\0')
512 {
513 mystrcpy(fn+1, fn+3);
514 fn--;
515 }
516 }
517 }
518 }
519
520#ifdef RESOURCE_DEBUG
521 printf("feCleanUpFile: leaving with =%s=\n", fname);
522#endif
523 return fname;
524}
525
526// remove duplicates dir resp. those which do not exist
527static char* feCleanUpPath(char* path)
528{
529#ifdef RESOURCE_DEBUG
530 printf("feCleanUpPath: entering with: =%s=\n", path);
531#endif
532 if (path == NULL) return path;
533
534 int n_comps = 1, i, j;
535 char* opath = path;
536 char** path_comps;
537
538 for (; *path != '\0'; path++)
539 {
540 if (*path == fePathSep) n_comps++;
541 else if (*path == ';')
542 {
543 *path = fePathSep;
544 n_comps++;
545 }
546 }
547
548 path_comps = (char**) malloc(n_comps*sizeof(char*));
549 path_comps[0]=opath;
550 path=opath;
551 i = 1;
552
553 if (i < n_comps)
554 {
555 while (1)
556 {
557 if (*path == fePathSep)
558 {
559 *path = '\0';
560 path_comps[i] = path+1;
561 i++;
562 if (i == n_comps) break;
563 }
564 path++;
565 }
566 }
567
568 for (i=0; i<n_comps; i++)
569 path_comps[i] = feCleanUpFile(path_comps[i]);
570#ifdef RESOURCE_DEBUG
571 printf("feCleanUpPath: after CleanUpName: ");
572 for (i=0; i<n_comps; i++)
573 printf("%s:", path_comps[i]);
574 printf("\n");
575#endif
576
577 for (i=0; i<n_comps;)
578 {
579#ifdef RESOURCE_DEBUG
580 if (access(path_comps[i], X_OK | R_OK))
581 printf("feCleanUpPath: remove %d:%s -- can not access\n", i, path_comps[i]);
582#endif
583 if ( ! access(path_comps[i], X_OK | R_OK))
584 {
585 // x- permission is granted -- we assume that it is a dir
586 for (j=0; j<i; j++)
587 {
588 if (strcmp(path_comps[j], path_comps[i]) == 0)
589 {
590 // found a duplicate
591#ifdef RESOURCE_DEBUG
592 printf("feCleanUpPath: remove %d:%s -- equal to %d:%s\n", j, path_comps[j], i, path_comps[i]);
593#endif
594 j = i+1;
595 break;
596 }
597 }
598 if (j == i)
599 {
600 i++;
601 continue;
602 }
603 }
604 // now we can either not access or found a duplicate
605 path_comps[i] = NULL;
606 for (j=i+1; j<n_comps; j++)
607 path_comps[j-1] = path_comps[j];
608 n_comps--;
609 }
610
611
612 // assemble everything again
613 for (path=opath, i=0;i<n_comps-1;i++)
614 {
615 mystrcpy(path, path_comps[i]);
616 path += strlen(path);
617 *path = fePathSep;
618 path++;
619 }
620 if (n_comps)
621 {
622 mystrcpy(path, path_comps[i]);
623 }
624 else
625 {
626 *opath = '\0';
627 }
628 free(path_comps);
629#ifdef RESOURCE_DEBUG
630 printf("feCleanUpPath: leaving with path=%s=\n", opath);
631#endif
632 return opath;
633}
634
635// strcpy where source and destination may overlap
636static void mystrcpy(char* d, char* s)
637{
638 /*assume(d != NULL && s != NULL);*/
639 while (*s != '\0')
640 {
641 *d = *s;
642 d++;
643 s++;
644 }
645 *d = '\0';
646}
647
648/*****************************************************************
649 *
650 * feSprintf
651 *
652 *****************************************************************/
653static char* feSprintf(char* s, const char* fmt, int warn)
654{
655 char* s_in = s;
656 if (fmt == NULL) return NULL;
657
658 while (*fmt != '\0')
659 {
660 *s = *fmt;
661
662 if (*fmt == '%' && *(fmt + 1) != '\0')
663 {
664 fmt++;
665 char* r = feResource(*fmt, warn);
666 if (r != NULL)
667 {
668 strcpy(s, r);
669 s += strlen(r) - 1;
670 }
671 else
672 {
673 s++;
674 *s = *fmt;
675 }
676 }
677 else if (*fmt == '$' && *(fmt + 1) != '\0')
678 {
679 fmt++;
680 char* v = s + 1;
681 while (*fmt == '_' ||
682 (*fmt >= 'A' && *fmt <= 'Z') ||
683 (*fmt >= 'a' && *fmt <= 'z'))
684 {
685 *v = *fmt;
686 v++;
687 fmt++;
688 }
689 fmt--;
690 *v = '\0';
691 v = getenv(s + 1);
692 if (v != NULL) strcpy(s, v);
693 s += strlen(s) - 1;
694 }
695 s++;
696 fmt++;
697 }
698 *s = '\0';
699 return s_in;
700}
701
int l
Definition: cfEzgcd.cc:100
int i
Definition: cfEzgcd.cc:132
const CanonicalForm int s
Definition: facAbsFact.cc:51
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:39
int j
Definition: facHensel.cc:110
static char * feCleanUpFile(char *fname)
Definition: feResource.cc:469
static feResourceConfig feGetResourceConfig(const char id)
Definition: feResource.cc:213
static char * feResourceDefault(feResourceConfig config)
Definition: feResource.cc:243
void feReInitResources()
Definition: feResource.cc:185
VAR char * feArgv0
Definition: feResource.cc:19
static char * feSprintf(char *s, const char *fmt, int warn=-1)
Definition: feResource.cc:653
VAR feResourceConfig_s feResourceConfigs[]
Definition: feResource.cc:41
static char * feInitResource(feResourceConfig config, int warn)
Definition: feResource.cc:251
static char * feCleanUpPath(char *path)
Definition: feResource.cc:527
static char * feResource(feResourceConfig config, int warn)
Definition: feResource.cc:236
void feInitResources(const char *argv0)
Definition: feResource.cc:163
static char * feGetExpandedExecutable()
Definition: feResource.cc:376
static char * feCleanResourceValue(feResourceType type, char *value)
Definition: feResource.cc:444
static int feVerifyResourceValue(feResourceType type, char *value)
Definition: feResource.cc:414
char * feGetResource(const char id, int warn)
Definition: feResource.cc:148
#define MAXRESOURCELEN
Definition: feResource.cc:114
#define SINGULAR_DEFAULT_DIR
Definition: feResource.cc:27
static void mystrcpy(char *d, char *s)
Definition: feResource.cc:636
const char fePathSep
Definition: feResource.h:58
#define DIR_SEP
Definition: feResource.h:6
feResourceType
Definition: feResource.h:20
@ feResBinary
Definition: feResource.h:20
@ feResPath
Definition: feResource.h:20
@ feResDir
Definition: feResource.h:20
@ feResUrl
Definition: feResource.h:20
@ feResUndef
Definition: feResource.h:20
@ feResFile
Definition: feResource.h:20
char * getenv()
#define VAR
Definition: globaldefs.h:5
#define free
Definition: omAllocFunc.c:14
#define strdup
Definition: omAllocFunc.c:18
#define malloc
Definition: omAllocFunc.c:12
char * omFindExec(const char *name, char *exec)
Definition: omFindExec.c:315
#define NULL
Definition: omList.c:12
#define MAXPATHLEN
Definition: omRet2Info.c:22