/**************************************************************************** ** ** This file is part of GAP, a system for computational discrete algebra. ** ** Copyright of GAP belongs to its developers, whose names are too numerous ** to list here. Please refer to the COPYRIGHT file for details. ** ** SPDX-License-Identifier: GPL-2.0-or-later **
*/
/**************************************************************************** ** *V SyDefaultRootPath ** ** Default initial root path. Default is the current directory, if we have ** no other idea, for backwards compatibility.
*/ char SyDefaultRootPath[GAP_PATH_MAX] = "./";
/**************************************************************************** ** *V SyGapRootPaths . . . . . . . . . . . . . . . . . . . array of root paths ** ** 'SyGapRootPaths' contains the names of the directories where the GAP ** files are located. ** ** It is modified by the command line option -l. ** ** It is copied into the GAP variable 'GAPInfo.RootPaths' and used by ** 'SyFindGapRootFile'. ** ** Each entry must end with the pathname separator, e.g. if 'init.g' is the ** name of a library file 'strcat( SyGapRootPaths[i], "lib/init.g" );' must ** be a valid filename.
*/ enum { MAX_GAP_DIRS = 16 }; staticChar SyGapRootPaths[MAX_GAP_DIRS][GAP_PATH_MAX];
/**************************************************************************** ** *F SyFindGapRootFile( <filename>, <buf>, <size> ) . find file in system area ** ** <buf> must point to a buffer of at least <size> characters. This function ** then searches for a readable file with the name <filename> in the system ** area. If sich a file is found then its absolute path is copied into ** <buf>, and <buf> is returned. If no file is found or if <buf> is not big ** enough, then <buf> is set to an empty string and NULL is returned.
*/ Char * SyFindGapRootFile(constChar * filename, Char * buf, size_t size)
{ for (int k = 0; k < ARRAY_SIZE(SyGapRootPaths); k++) { if (SyGapRootPaths[k][0]) { if (gap_strlcpy(buf, SyGapRootPaths[k], size) >= size) continue; if (gap_strlcat(buf, filename, size) >= size) continue; if (SyIsReadableFile(buf) == 0) { return buf;
}
}
}
buf[0] = '\0'; return 0;
}
/**************************************************************************** ** *F SySetGapRootPath( <string> ) . . . . . . . . . set the root directories ** ** 'SySetGapRootPath' takes a string and modifies a list of root directories ** in 'SyGapRootPaths'. ** ** A leading semicolon in <string> means that the list of directories in ** <string> is appended to the existing list of root paths. A trailing ** semicolon means they are prepended. If there is no leading or trailing ** semicolon, then the root paths are overwritten. ** ** This function assumes that the system uses '/' as path separator. ** Currently, we support nothing else. For Windows (or rather: Cygwin), we ** rely on a small hack which converts the path separator '\' used there ** on '/' on the fly. Put differently: Systems that use completely different ** path separators, or none at all, are currently not supported.
*/ void SySetGapRootPath(constChar * string)
{ constChar * p; Char * q; Int i; Int n;
// set string to a default value if unset if (string == 0 || *string == 0) {
string = "./";
}
// check if we append, prepend or overwrite. if (string[0] == ';') { // Count the number of root directories already present.
n = 0; while (SyGapRootPaths[n][0] != '\0')
n++;
// Skip leading semicolon.
string++;
} elseif (string[strlen(string) - 1] == ';') { // Count the number of directories in 'string'.
n = 0;
p = string; while (*p) if (*p++ == ';')
n++;
// Find last root path. for (i = 0; i < MAX_GAP_DIRS; i++) if (SyGapRootPaths[i][0] == '\0') break;
i--;
#ifdef HPCGAP
n *= 2; // for each root <ROOT> we also add <ROOT/hpcgap> as a root #endif
// Move existing root paths to the back if (i + n >= MAX_GAP_DIRS) return; while (i >= 0) {
memcpy(SyGapRootPaths[i + n], SyGapRootPaths[i], sizeof(SyGapRootPaths[i + n]));
i--;
}
n = 0;
} else { // Make sure to wipe out all possibly existing root paths for (i = 0; i < MAX_GAP_DIRS; i++)
SyGapRootPaths[i][0] = '\0';
n = 0;
}
// unpack the argument
p = string; while (*p) { if (n >= MAX_GAP_DIRS) return;
#ifdef SYS_IS_CYGWIN32 // change backslash to slash for Windows if (*q == '\\')
*q = '/'; #endif
q++;
} if (q == SyGapRootPaths[n]) {
strxcpy(SyGapRootPaths[n], "./", sizeof(SyGapRootPaths[n]));
} elseif (q[-1] != '/') {
*q++ = '/';
*q = '\0';
} else {
*q = '\0';
} if (*p) {
p++;
}
n++; #ifdef HPCGAP // for each root <ROOT> to be added, we first add <ROOT/hpcgap> as a root if (n < MAX_GAP_DIRS) {
gap_strlcpy(SyGapRootPaths[n], SyGapRootPaths[n - 1], sizeof(SyGapRootPaths[n]));
}
strxcat(SyGapRootPaths[n - 1], "hpcgap/", sizeof(SyGapRootPaths[n - 1]));
n++; #endif
}
// replace leading tilde ~ by HOME environment variable // TODO; instead of iterating over all entries each time, just // do this for the new entries char * userhome = getenv("HOME"); if (!userhome || !*userhome) return; const UInt userhomelen = strlen(userhome); for (i = 0; i < MAX_GAP_DIRS && SyGapRootPaths[i][0]; i++) { const UInt pathlen = strlen(SyGapRootPaths[i]); if (SyGapRootPaths[i][0] == '~' &&
userhomelen + pathlen < sizeof(SyGapRootPaths[i])) {
SyMemmove(SyGapRootPaths[i] + userhomelen, // don't copy the ~ but the trailing '\0'
SyGapRootPaths[i] + 1, pathlen);
memcpy(SyGapRootPaths[i], userhome, userhomelen);
}
}
}
/**************************************************************************** ** *F SyGetGapRootPaths()
*/
Obj SyGetGapRootPaths(void)
{
Obj tmp = NEW_PLIST_IMM(T_PLIST, MAX_GAP_DIRS); for (int i = 0; i < MAX_GAP_DIRS; i++) { if (SyGapRootPaths[i][0]) {
PushPlist(tmp, MakeImmString(SyGapRootPaths[i]));
}
}
MakeImmutableNoRecurse(tmp); return tmp;
}
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.