Loading...
Searching...
No Matches
feResource.cc
Go to the documentation of this file.
/****************************************
* Computer Algebra System SINGULAR *
****************************************/
/*
* ABSTRACT: management of resources
*/
#include "singular_resourcesconfig.h"
#include "feResource.h"
#include "omFindExec.h"
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/param.h>
VAR char* feArgv0 = NULL;
//char* feResource(const char id, int warn = -1);
//char* feResource(const char* key, int warn = -1);
// define RESOURCE_DEBUG for chattering about resource management
// #define RESOURCE_DEBUG
#define SINGULAR_DEFAULT_DIR PREFIX
/*****************************************************************
*
* Declarations: Data structures
*
*****************************************************************/
// feSprintf transforms format strings as follows:
// 1.) substrings of the form %c (c being a letter) are replaced by respective resource value
// 2.) substrings of the form $string are replaced by value of resp. env variable
// feCleanResource makes furthermore the following transformations (except for URL resources)
// 1.) '/' characters are replaced by respective directory - separators
// 2.) ';' characters are replaced by respective path separators
VAR feResourceConfig_s feResourceConfigs[] =
{
{"SearchPath", 's', feResPath, NULL,
"$SINGULARPATH;"
"%D/singular/LIB;"
"%r/share/singular/LIB;"
"%b/../share/singular/LIB;"
// gftables:
"%D/singular/factory;"
"%r/share/singular/factory;"
////"%b/LIB;"
////"%b/../LIB;" // not installed, shared is in .libs/Singular
"%b/../share/singular/factory;"
////"%b/../../factory;" // not installed, shared is in .libs/Singular
// path for dynamic modules, should match ProcDir:
////"%b/MOD;"
////"%b/../MOD;" // Singular in .libs/Singular
"%r/lib/singular/MOD;"
LIB_DIR "/singular/MOD;"
"%b;"
///"%b/..", // Singular in .libs/Singular
,(char *)""},
{"Singular", 'S', feResBinary,"SINGULAR_EXECUTABLE", "%d/Singular", (char *)""},
{"BinDir", 'b', feResDir, "SINGULAR_BIN_DIR", "", (char *)""},
// should be changed to %b/../lib/singular/pProcs/:
{"ProcDir", 'P', feResPath, "SINGULAR_PROCS_DIR",
"%b/MOD;"
////"%b/../MOD;" // Singular in .libs/Singular
////"%b/..;" // Singular in .libs/Singular, programs in .
"%r/lib/singular/MOD;"
LIB_DIR "/singular/MOD;"
,(char *)""},
{"RootDir", 'r', feResDir, "SINGULAR_ROOT_DIR", "%b/..", (char *)""},
{"DataDir", 'D', feResDir, "SINGULAR_DATA_DIR", "%b/../share/", (char *)""},
{"DefaultDir",'d', feResDir, "SINGULAR_DEFAULT_DIR", SINGULAR_DEFAULT_DIR, (char *)""},
{"InfoFile", 'i', feResFile, "SINGULAR_INFO_FILE", "%D/info/singular.info", (char *)""},
{"IdxFile", 'x', feResFile, "SINGULAR_IDX_FILE", "%D/singular/singular.idx", (char *)""},
{"HtmlDir", 'h', feResDir, "SINGULAR_HTML_DIR", DATA_TO_HTML_DIR, (char *)""},
{"ManualUrl", 'u', feResUrl, "SINGULAR_URL", "https://www.singular.uni-kl.de/Manual/", (char *)""},
{"ExDir", 'm', feResDir, "SINGULAR_EXAMPLES_DIR","%r/examples", (char *)""},
{"Path", 'p', feResPath, NULL, "%b;%P;$PATH", (char *)""},
#ifdef __CYGWIN__
{"emacs", 'E', feResBinary,"ESINGULAR_EMACS", "%b/emacs.exe", (char *)""},
{"xemacs", 'A', feResBinary,"ESINGULAR_EMACS", "%b/xemacs.exe", (char *)""},
{"SingularEmacs",'M', feResBinary,"ESINGULAR_SINGULAR", "%b/Singular.exe", (char *)""},
#else
{"emacs", 'E', feResBinary,"ESINGULAR_EMACS", "%b/emacs", (char *)""},
{"xemacs", 'A', feResBinary,"ESINGULAR_EMACS", "%b/xemacs", (char *)""},
{"SingularEmacs",'M', feResBinary,"ESINGULAR_SINGULAR", "%b/Singular", (char *)""},
#endif
{"EmacsLoad", 'l', feResFile, "ESINGULAR_EMACS_LOAD", "%e/.emacs-singular", (char *)""},
{"EmacsDir", 'e', feResDir, "ESINGULAR_EMACS_DIR", "%D/singular/emacs", (char *)""},
{"SingularXterm",'M', feResBinary,"TSINGULAR_SINGULAR", "%b/Singular", (char *)""},
#ifdef __CYGWIN__
{"rxvt", 'X', feResBinary,"RXVT", "%b/rxvt", (char *)""},
#else
{"xterm", 'X', feResBinary,"XTERM", "%b/xterm", (char *)""},
#endif
{"EmacsDir", 'e', feResDir, "SINGULAR_EMACS_DIR", "%r/emacs", (char *)""},
{NULL, 0, feResUndef, NULL, NULL, NULL}, // must be the last record
};
/*****************************************************************
*
* Declarations: Local variables / functions
*
*****************************************************************/
#define MAXRESOURCELEN 5*MAXPATHLEN
static feResourceConfig feGetResourceConfig(const char id);
static feResourceConfig feGetResourceConfig(const char* key);
static char* feResource(feResourceConfig config, int warn);
static char* feResourceDefault(feResourceConfig config);
static char* feInitResource(feResourceConfig config, int warn);
static char* feGetExpandedExecutable();
static int feVerifyResourceValue(feResourceType type, char* value);
static char* feCleanResourceValue(feResourceType type, char* value);
static char* feCleanUpFile(char* fname);
static char* feCleanUpPath(char* path);
static void mystrcpy(char* d, char* s);
static char* feSprintf(char* s, const char* fmt, int warn = -1);
#if defined(__CYGWIN__) && defined(__GNUC__)
// utility function of Cygwin32:
extern "C" int cygwin32_posix_path_list_p (const char *path);
#endif
/*****************************************************************
*
* Public functions
*
*****************************************************************/
char* feResource(const char* key, int warn)
{
return feResource(feGetResourceConfig(key), warn);
}
char* feResource(const char id, int warn)
{
return feResource(feGetResourceConfig(id), warn);
}
char* feGetResource(const char id, int warn)
{
return feResource(feGetResourceConfig(id), warn);
}
char* feResourceDefault(const char id)
{
return feResourceDefault(feGetResourceConfig(id));
}
char* feResourceDefault(const char* key)
{
return feResourceDefault(feGetResourceConfig(key));
}
void feInitResources(const char* argv0)
{
if (argv0==NULL)
{
//WarnS("illegal argv[0]==NULL");
feArgv0 = (char*)malloc(MAXPATHLEN+strlen("/Singular"));
getcwd(feArgv0, MAXPATHLEN);
strcat(feArgv0,"/Singular");
}
else
feArgv0 = strdup(argv0);
#ifdef RESOURCE_DEBUG
printf("feInitResources(argv0: '%s'): entering...\n", feArgv0);
#endif
// init some Resources
feResource('b');
feResource('r');
// don't complain about stuff when initializing SingularPath
feResource('s',0);
feResource('P');
}
void feReInitResources()
{
int i = 0;
while (feResourceConfigs[i].key != NULL)
{
if ((feResourceConfigs[i].value != NULL)
&& (feResourceConfigs[i].value[0] != '\0'))
{
free(feResourceConfigs[i].value);
feResourceConfigs[i].value = (char *)"";
}
i++;
}
#ifdef RESOURCE_DEBUG
printf("feInitResources(): entering...\n");
#endif
// init some Resources
feResource('b');
feResource('r');
// don't complain about stuff when initializing SingularPath
feResource('s',0);
}
/*****************************************************************
*
* Local functions
*
*****************************************************************/
static feResourceConfig feGetResourceConfig(const char id)
{
int i = 0;
while (feResourceConfigs[i].key != NULL)
{
if (feResourceConfigs[i].id == id) return &(feResourceConfigs[i]);
i++;
}
return NULL;
}
static feResourceConfig feGetResourceConfig(const char* key)
{
int i = 0;
while (feResourceConfigs[i].key != NULL)
{
if (strcmp(feResourceConfigs[i].key, key) == 0)
return &(feResourceConfigs[i]);
i++;
}
return NULL;
}
static char* feResource(feResourceConfig config, int warn)
{
if (config == NULL) return NULL;
if (config->value != NULL && *(config->value) != '\0') return config->value;
return feInitResource(config, warn);
}
static char* feResourceDefault(feResourceConfig config)
{
if (config == NULL) return NULL;
char* value = (char*) malloc(MAXRESOURCELEN);
feSprintf(value, config->fmt, -1);
return value;
}
static char* feInitResource(feResourceConfig config, int warn)
{
/*assume(config != NULL);*/
#ifdef RESOURCE_DEBUG
printf("feInitResource(config->key: '%s', warn: '%d') : entering ...\n", config->key, warn);
#endif
char value[MAXRESOURCELEN];
// now we have to work
// First, check Environment variable
if (config->env != NULL)
{
char* evalue = getenv(config->env);
if (evalue != NULL)
{
#ifdef RESOURCE_DEBUG
printf("feInitResource(config,warn): Found value from env:%s\n", evalue);
#endif
strcpy(value, evalue);
if (config->type == feResBinary // do not verify binaries
||
feVerifyResourceValue(config->type,
feCleanResourceValue(config->type, value)))
{
#ifdef RESOURCE_DEBUG
printf("feInitResource(config,warn): Set value of config (with key: '%s') to '%s'\n", config->key, value);
#endif
config->value = strdup(value);
return config->value;
}
}
}
*value = '\0';
// Special treatment of executable
if (config->id == 'S')
{
char* executable = feGetExpandedExecutable();
if (executable != NULL)
{
#ifdef RESOURCE_DEBUG
printf("exec:%s\n", executable);
#endif
strcpy(value, executable);
#ifdef RESOURCE_DEBUG
printf("value:%s\n", value);
#endif
free(executable);
}
}
// and bindir
else if (config->id == 'b')
{
char* executable = feResource('S');
#ifdef RESOURCE_DEBUG
printf("feInitResource(config,warn): Get '%s' from \"%s\"\n", config->key, executable);
#endif
if (executable != NULL)
{
strcpy(value, executable);
executable = strrchr(value, DIR_SEP);
if (executable != NULL) *executable = '\0';
}
}
#ifdef RESOURCE_DEBUG
printf("value:%s\n", value);
#endif
if (*value == '\0' && config->fmt != NULL )
{
feSprintf(value, config->fmt, warn);
}
else if (config->fmt == NULL)
{
printf("Bug >>Wrong Resource Specification of '%s'<< at \"%s:%d\"\n",config->key,__FILE__,__LINE__);
// TODO: printf -> WarnS???
return NULL;
}
// Clean and verify
if (feVerifyResourceValue(config->type,
feCleanResourceValue(config->type, value)))
{
#ifdef RESOURCE_DEBUG
printf("feInitResource(config,warn): Set value of '%s' to \"%s\"\n", config->key, value);
#endif
config->value = strdup(value);
return config->value;
}
else if (config->type == feResBinary)
{
// for binaries, search through PATH once more
char* executable = omFindExec(config->key, value);
if (executable != NULL)
{
if (feVerifyResourceValue(config->type,
feCleanResourceValue(config->type, value)))
{
config->value = strdup(value);
#ifdef RESOURCE_DEBUG
printf("feInitResource(config,warn): Set value of '%s' to \"%s\"\n", config->key, config->value);
#endif
return config->value;
}
}
}
// issue warning if explicitely requested, or if
// this value is gotten for the first time
if (warn > 0 || (warn < 0 && config->value != NULL))
{
printf("// ** Could not get '%s'.\n", config->key);
printf("// ** Either set environment variable '%s' to '%s',\n",
config->env, config->key);
feSprintf(value, config->fmt, warn);
printf("// ** or make sure that '%s' is at \"%s\"\n", config->key, value);
}
#ifdef RESOURCE_DEBUG
printf("feInitResource(config,warn): Set value of '%s' to NULL", config->key);
#endif
config->value = NULL;
return NULL;
}
static char* feGetExpandedExecutable()
{
if (feArgv0 == NULL || *feArgv0 == '\0')
{
if (feArgv0 == NULL)
printf("Bug >>feArgv0 == NULL<< at %s:%d\n",__FILE__,__LINE__);
else
printf("Bug >>feArgv0 == ''<< at %s:%d\n",__FILE__,__LINE__);
return NULL;
}
#ifdef __CYGWIN__ // stupid WINNT sometimes gives you argv[0] within ""
if (*feArgv0 == '"')
{
int l = strlen(feArgv0);
if (feArgv0[l-1] == '"')
{
feArgv0[l-1] = '\0';
feArgv0++;
}
}
#endif
#ifdef RESOURCE_DEBUG
printf("feGetExpandedExecutable: calling find_exec with \"%s\"\n", feArgv0);
#endif
char executable[MAXRESOURCELEN];
char* value = omFindExec(feArgv0, executable);
#ifdef RESOURCE_DEBUG
printf("feGetExpandedExecutable: find_exec exited with \"%s\": %d\n", executable, access(executable, X_OK));
#endif
if (value == NULL)
{
printf("Bug >>Could not get expanded executable from \"%s\"<< at %s:%d\n",feArgv0,__FILE__,__LINE__);
return NULL;
}
return strdup(value);
}
static int feVerifyResourceValue(feResourceType type, char* value)
{
#ifdef RESOURCE_DEBUG
printf("feVerifyResourceValue(type: %d, value: \"%s\"): entering\n", (int)type, value);
printf("Access: ROK: %d, XOK: %d\n", access(value, R_OK), access(value, X_OK));
#endif
switch(type)
{
case feResUrl:
case feResPath:
return 1;
case feResFile:
return ! access(value, R_OK);
case feResBinary:
case feResDir:
return ! access(value, X_OK);
default:
return 0;
}
}
/*****************************************************************
*
* Cleaning/Transformations of resource values
*
*****************************************************************/
static char* feCleanResourceValue(feResourceType type, char* value)
{
if (value == NULL || *value == '\0') return value;
#ifdef RESOURCE_DEBUG
printf("Clean value:%s\n", value);
#endif
#ifdef __CYGWIN__
#ifdef RESOURCE_DEBUG
printf("Clean WINNT value:%s\n", value);
#endif
if (type == feResBinary)
{
int l = strlen(value);
if (l < 4 || (strcmp(&value[l-4], ".exe") != 0 &&
strcmp(&value[l-4], ".EXE") != 0))
strcat(value, ".exe");
}
#endif
if (type == feResFile || type == feResBinary || type == feResDir)
return feCleanUpFile(value);
if (type == feResPath)
return feCleanUpPath(value);
return value;
}
static char* feCleanUpFile(char* fname)
{
char* fn;
#ifdef RESOURCE_DEBUG
printf("feCleanUpFile: entering with =%s=\n", fname);
#endif
// Remove unnecessary .. and //
for (fn = fname; *fn != '\0'; fn++)
{
if (*fn == '/')
{
if (*(fn+1) == '\0')
{
if (fname != fn) *fn = '\0';
break;
}
if (*(fn + 1) == '/' && (fname != fn))
{
mystrcpy(fn, fn+1);
fn--;
}
else if (*(fn+1) == '.')
{
if (*(fn+2) == '.' && (*(fn + 3) == '/' || *(fn + 3) == '\0'))
{
#if 0
// this does not work: ./../../mmm will be changed to ./../mmm
// but we only want to change ././mmm to ./mmm
*fn = '\0';
s = strrchr(fname, '/');
if (s != NULL)
{
mystrcpy(s+1, fn + (*(fn + 3) != '\0' ? 4 : 3));
fn = s-1;
}
else
{
*fn = '/';
}
#endif
}
else if (*(fn+2) == '/' || *(fn+2) == '\0')
{
mystrcpy(fn+1, fn+3);
fn--;
}
}
}
}
#ifdef RESOURCE_DEBUG
printf("feCleanUpFile: leaving with =%s=\n", fname);
#endif
return fname;
}
// remove duplicates dir resp. those which do not exist
static char* feCleanUpPath(char* path)
{
#ifdef RESOURCE_DEBUG
printf("feCleanUpPath: entering with: =%s=\n", path);
#endif
if (path == NULL) return path;
int n_comps = 1, i, j;
char* opath = path;
char** path_comps;
for (; *path != '\0'; path++)
{
if (*path == fePathSep) n_comps++;
else if (*path == ';')
{
*path = fePathSep;
n_comps++;
}
}
path_comps = (char**) malloc(n_comps*sizeof(char*));
path_comps[0]=opath;
path=opath;
i = 1;
if (i < n_comps)
{
while (1)
{
if (*path == fePathSep)
{
*path = '\0';
path_comps[i] = path+1;
i++;
if (i == n_comps) break;
}
path++;
}
}
for (i=0; i<n_comps; i++)
path_comps[i] = feCleanUpFile(path_comps[i]);
#ifdef RESOURCE_DEBUG
printf("feCleanUpPath: after CleanUpName: ");
for (i=0; i<n_comps; i++)
printf("%s:", path_comps[i]);
printf("\n");
#endif
for (i=0; i<n_comps;)
{
#ifdef RESOURCE_DEBUG
if (access(path_comps[i], X_OK | R_OK))
printf("feCleanUpPath: remove %d:%s -- can not access\n", i, path_comps[i]);
#endif
if ( ! access(path_comps[i], X_OK | R_OK))
{
// x- permission is granted -- we assume that it is a dir
for (j=0; j<i; j++)
{
if (strcmp(path_comps[j], path_comps[i]) == 0)
{
// found a duplicate
#ifdef RESOURCE_DEBUG
printf("feCleanUpPath: remove %d:%s -- equal to %d:%s\n", j, path_comps[j], i, path_comps[i]);
#endif
j = i+1;
break;
}
}
if (j == i)
{
i++;
continue;
}
}
// now we can either not access or found a duplicate
path_comps[i] = NULL;
for (j=i+1; j<n_comps; j++)
path_comps[j-1] = path_comps[j];
n_comps--;
}
// assemble everything again
for (path=opath, i=0;i<n_comps-1;i++)
{
mystrcpy(path, path_comps[i]);
path += strlen(path);
*path = fePathSep;
path++;
}
if (n_comps)
{
mystrcpy(path, path_comps[i]);
}
else
{
*opath = '\0';
}
free(path_comps);
#ifdef RESOURCE_DEBUG
printf("feCleanUpPath: leaving with path=%s=\n", opath);
#endif
return opath;
}
// strcpy where source and destination may overlap
static void mystrcpy(char* d, char* s)
{
/*assume(d != NULL && s != NULL);*/
while (*s != '\0')
{
*d = *s;
d++;
s++;
}
*d = '\0';
}
/*****************************************************************
*
* feSprintf
*
*****************************************************************/
static char* feSprintf(char* s, const char* fmt, int warn)
{
char* s_in = s;
if (fmt == NULL) return NULL;
while (*fmt != '\0')
{
*s = *fmt;
if (*fmt == '%' && *(fmt + 1) != '\0')
{
fmt++;
char* r = feResource(*fmt, warn);
if (r != NULL)
{
strcpy(s, r);
s += strlen(r) - 1;
}
else
{
s++;
*s = *fmt;
}
}
else if (*fmt == '$' && *(fmt + 1) != '\0')
{
fmt++;
char* v = s + 1;
while (*fmt == '_' ||
(*fmt >= 'A' && *fmt <= 'Z') ||
(*fmt >= 'a' && *fmt <= 'z'))
{
*v = *fmt;
v++;
fmt++;
}
fmt--;
*v = '\0';
v = getenv(s + 1);
if (v != NULL) strcpy(s, v);
s += strlen(s) - 1;
}
s++;
fmt++;
}
*s = '\0';
return s_in;
}
l
int l
Definition cfEzgcd.cc:100
i
int i
Definition cfEzgcd.cc:132
argv0
char * argv0
Definition coeffs_test_runner.cpp:14
s
const CanonicalForm int s
Definition facAbsFact.cc:51
v
const Variable & v
< [in] a sqrfree bivariate poly
Definition facBivar.h:39
j
int j
Definition facHensel.cc:110
feCleanUpFile
static char * feCleanUpFile(char *fname)
Definition feResource.cc:466
feGetResourceConfig
static feResourceConfig feGetResourceConfig(const char id)
Definition feResource.cc:210
feResourceDefault
static char * feResourceDefault(feResourceConfig config)
Definition feResource.cc:240
feReInitResources
void feReInitResources()
Definition feResource.cc:182
feArgv0
VAR char * feArgv0
Definition feResource.cc:19
feSprintf
static char * feSprintf(char *s, const char *fmt, int warn=-1)
Definition feResource.cc:650
feResourceConfigs
VAR feResourceConfig_s feResourceConfigs[]
Definition feResource.cc:41
feInitResource
static char * feInitResource(feResourceConfig config, int warn)
Definition feResource.cc:248
feCleanUpPath
static char * feCleanUpPath(char *path)
Definition feResource.cc:524
feResource
static char * feResource(feResourceConfig config, int warn)
Definition feResource.cc:233
feInitResources
void feInitResources(const char *argv0)
Definition feResource.cc:160
feGetExpandedExecutable
static char * feGetExpandedExecutable()
Definition feResource.cc:373
feCleanResourceValue
static char * feCleanResourceValue(feResourceType type, char *value)
Definition feResource.cc:441
feVerifyResourceValue
static int feVerifyResourceValue(feResourceType type, char *value)
Definition feResource.cc:411
feGetResource
char * feGetResource(const char id, int warn)
Definition feResource.cc:145
MAXRESOURCELEN
#define MAXRESOURCELEN
Definition feResource.cc:111
SINGULAR_DEFAULT_DIR
#define SINGULAR_DEFAULT_DIR
Definition feResource.cc:27
mystrcpy
static void mystrcpy(char *d, char *s)
Definition feResource.cc:633
feResource.h
fePathSep
const char fePathSep
Definition feResource.h:58
DIR_SEP
#define DIR_SEP
Definition feResource.h:6
feResourceConfig
feResourceConfig_s * feResourceConfig
Definition feResource.h:31
feResourceType
feResourceType
Definition feResource.h:20
feResBinary
@ feResBinary
Definition feResource.h:20
feResPath
@ feResPath
Definition feResource.h:20
feResDir
@ feResDir
Definition feResource.h:20
feResUrl
@ feResUrl
Definition feResource.h:20
feResUndef
@ feResUndef
Definition feResource.h:20
feResFile
@ feResFile
Definition feResource.h:20
feResourceConfig_s
Definition feResource.h:23
getenv
char * getenv()
VAR
#define VAR
Definition globaldefs.h:5
free
#define free
Definition omAllocFunc.c:14
strdup
#define strdup
Definition omAllocFunc.c:18
malloc
#define malloc
Definition omAllocFunc.c:12
omFindExec
char * omFindExec(const char *name, char *exec)
Definition omFindExec.c:315
omFindExec.h
NULL
#define NULL
Definition omList.c:12
MAXPATHLEN
#define MAXPATHLEN
Definition omRet2Info.c:22