Skip to content

Commit

Permalink
Add cmd line argument handling
Browse files Browse the repository at this point in the history
  • Loading branch information
lgoettgens committed Dec 18, 2024
1 parent 99e7acb commit ab3806c
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 6 deletions.
16 changes: 11 additions & 5 deletions lib/package.gi
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,9 @@ InstallGlobalFunction( InitializePackagesInfoRecords, function( arg )
if pkgdirs <> fail then
pkgdirs:= Filtered( pkgdirs, dir -> not dir in GAPInfo.PackageDirectories );
if not IsEmpty(pkgdirs) then
APPEND_LIST_INTR( GAPInfo.PackageDirectories, pkgdirs );
GAPInfo.PackageDirectories:= MakeImmutable(
Concatenation( GAPInfo.PackageDirectories, pkgdirs )
);
fi;
fi;

Expand Down Expand Up @@ -337,7 +339,9 @@ InstallGlobalFunction( InitializePackagesInfoRecords, function( arg )
# remove the packages listed in `NOAUTO' files from GAP's suggested
# packages, and unite the information for the directories.
for pkgdir in GAPInfo.PackageDirectories do

if not IsDirectory(pkgdir) then
pkgdir:= Directory(pkgdir);
fi;
if IsBound( GAPInfo.ExcludeFromAutoload ) then
UniteSet( GAPInfo.ExcludeFromAutoload,
List( RECORDS_FILE( Filename( pkgdir, "NOAUTO" ) ),
Expand Down Expand Up @@ -1973,20 +1977,22 @@ InstallGlobalFunction( ExtendRootDirectories, function( rootpaths )
#F ExtendPackageDirectories( <paths_or_dirs> )
##
InstallGlobalFunction( ExtendPackageDirectories, function( paths_or_dirs )
local p, changed;
local p, changed, pkgdirs;
changed:= false;
pkgdirs:= ShallowCopy( GAPInfo.PackageDirectories );
for p in paths_or_dirs do
if IsString( p ) then
p:= Directory( p );
elif not IsDirectory( p ) then
Error("input must be a list of path strings or directory objects");
fi;
if not p in GAPInfo.PackageDirectories then
Add( GAPInfo.PackageDirectories, p );
if not p in pkgdirs then
Add( pkgdirs, p );
changed:= true;
fi;
od;
if changed then
GAPInfo.PackageDirectories:= MakeImmutable( pkgdirs );
# Reread the package information.
if IsBound( GAPInfo.PackagesInfoInitialized ) and
GAPInfo.PackagesInfoInitialized = true then
Expand Down
5 changes: 4 additions & 1 deletion lib/system.g
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ BIND_GLOBAL( "GAPInfo", rec(
"directories to the end/start of existing list",
"of root paths" ] ),
rec( short:= "r", default := false, help := ["disable/enable user GAP root dir", "GAPInfo.UserGapRoot"] ),
rec( long := "package-dirs", default := [], arg := "<paths>",
help := [ "set or modify the GAP directory paths",
"Directories are separated using ';'." ] ),
,
rec( section:= ["Loading:"] ),
rec( short:= "A", default := false, help := ["disable/enable autoloading of suggested", "GAP packages"] ),
Expand Down Expand Up @@ -302,7 +305,7 @@ CallAndInstallPostRestore( function()

# paths
GAPInfo.RootPaths:= GAPInfo.KernelInfo.GAP_ROOT_PATHS;
GAPInfo.PackageDirectories := [];
GAPInfo.PackageDirectories:= GAPInfo.KernelInfo.GAP_PKG_PATHS; # TODO: convert paths to dirs
if IsBound(GAPInfo.SystemEnvironment.HOME) then
GAPInfo.UserHome := GAPInfo.SystemEnvironment.HOME;
else
Expand Down
1 change: 1 addition & 0 deletions src/gap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,7 @@ static Obj FuncKERNEL_INFO(Obj self)
AssPRec(res, RNamName("BUILD_DATETIME"), MakeImmString(SyBuildDateTime));
AssPRec(res, RNamName("RELEASEDAY"), MakeImmString(SyReleaseDay));
AssPRec(res, RNamName("GAP_ROOT_PATHS"), SyGetGapRootPaths());
AssPRec(res, RNamName("GAP_PKG_PATHS"), SyGetGapPkgPaths());
AssPRec(res, RNamName("DOT_GAP_PATH"), MakeImmString(SyDotGapPath()));

// Get OS Kernel Release info
Expand Down
115 changes: 115 additions & 0 deletions src/sysroots.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@
enum { MAX_GAP_DIRS = 16 };
static Char SyGapRootPaths[MAX_GAP_DIRS][GAP_PATH_MAX];

/****************************************************************************
**
*V SyGapPkgPaths . . . . . . . . . . . . . . . . . . array of package paths
**
** 'SyGapPkgPaths' contains the names of the directories where GAP looks
** for packages.
**
** It is modified by the command line option --package-dirs.
**
** It is copied into the GAP variable 'GAPInfo.PackageDirectories'.
**
** Each entry must end with the pathname separator.
*/
enum { MAX_GAP_PKG_DIRS = 256 };
static Char SyGapPkgPaths[MAX_GAP_PKG_DIRS][GAP_PATH_MAX];


/****************************************************************************
**
Expand Down Expand Up @@ -224,3 +240,102 @@ Obj SyGetGapRootPaths(void)
MakeImmutableNoRecurse(tmp);
return tmp;
}


/****************************************************************************
**
*F SySetGapPkgPaths( <string> ) . . . . . . . . .set the package directories
**
** 'SySetGapPkgPaths' takes a string and replaces a list of package
** directories in 'SyGapPkgPaths'.
**
** 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 SySetGapPkgPaths(const Char * string)
{
const Char * p;
Char * q;
Int i;
Int n;

// set string to a default value if unset
if (string == 0 || *string == 0) {
string = "";
}

// Make sure to wipe out all possibly existing pkg paths
for (i = 0; i < MAX_GAP_PKG_DIRS; i++)
SyGapPkgPaths[i][0] = '\0';
n = 0;

// unpack the argument
p = string;
while (*p) {
if (n >= MAX_GAP_PKG_DIRS)
return;

q = SyGapPkgPaths[n];
while (*p && *p != ';') {
*q = *p++;

#ifdef SYS_IS_CYGWIN32
// change backslash to slash for Windows
if (*q == '\\')
*q = '/';
#endif

q++;
}
if (q == SyGapPkgPaths[n]) {
strxcpy(SyGapPkgPaths[n], "./", sizeof(SyGapPkgPaths[n]));
}
else if (q[-1] != '/') {
*q++ = '/';
*q = '\0';
}
else {
*q = '\0';
}
if (*p) {
p++;
}
n++;
}

// replace leading tilde ~ by HOME environment variable
char * userhome = getenv("HOME");
if (!userhome || !*userhome)
return;
const UInt userhomelen = strlen(userhome);
for (i = 0; i < MAX_GAP_PKG_DIRS && SyGapPkgPaths[i][0]; i++) {
const UInt pathlen = strlen(SyGapPkgPaths[i]);
if (SyGapPkgPaths[i][0] == '~' &&
userhomelen + pathlen < sizeof(SyGapPkgPaths[i])) {
SyMemmove(SyGapPkgPaths[i] + userhomelen,
// don't copy the ~ but the trailing '\0'
SyGapPkgPaths[i] + 1, pathlen);
memcpy(SyGapPkgPaths[i], userhome, userhomelen);
}
}
}


/****************************************************************************
**
*F SyGetGapPkgPaths()
*/
Obj SyGetGapPkgPaths(void)
{
Obj tmp = NEW_PLIST_IMM(T_PLIST, MAX_GAP_PKG_DIRS);
for (int i = 0; i < MAX_GAP_PKG_DIRS; i++) {
if (SyGapPkgPaths[i][0]) {
PushPlist(tmp, MakeImmString(SyGapPkgPaths[i]));
}
}
MakeImmutableNoRecurse(tmp);
return tmp;
}
20 changes: 20 additions & 0 deletions src/sysroots.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,24 @@ Char * SyFindGapRootFile(const Char * filename, Char * buf, size_t size);
Obj SyGetGapRootPaths(void);


/****************************************************************************
**
*F SySetGapPkgPaths( <string> ) . . . . . . . . set the package directories
**
** 'SySetGapPkgPaths' takes a string and replaces a list of package
** directories in 'SyGapPkgPaths'.
*/
void SySetGapPkgPaths(const Char * string);


/****************************************************************************
**
*F SyGetGapPkgPaths() . . . . . . . . return the list of package directories
**
** Returns a plain list containing absolute paths of the package directories
** as string objects.
*/
Obj SyGetGapPkgPaths(void);


#endif // GAP_SYSROOTS_H
7 changes: 7 additions & 0 deletions src/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,12 @@ static Int setGapRootPath( Char **argv, void *Dummy)
return 1;
}

static Int setGapPkgPaths( Char **argv, void *Dummy)
{
SySetGapPkgPaths( argv[0] );
return 1;
}


#ifndef GAP_MEM_CHECK
// Provide stub with helpful error message
Expand Down Expand Up @@ -503,6 +509,7 @@ static const struct optInfo options[] = {
{ 'f', "", forceLineEditing, (void *)2, 0 }, // probably library now
{ 'E', "", toggle, &SyUseReadline, 0 }, // kernel
{ 'l', "roots", setGapRootPath, 0, 1}, // kernel
{ 0 , "package-dirs", setGapPkgPaths, 0, 1}, // kernel
#ifdef USE_GASMAN
{ 'm', "", storeMemory2, &SyStorMin, 1 }, // kernel
#endif
Expand Down

0 comments on commit ab3806c

Please sign in to comment.