+ * New path handling stuff for the Combined System (tm)
+ * ------------------------------------------------------------------------*/
+
+char installDir[N_INSTALLDIR];
+
+/* Sets installDir to $STGHUGSDIR, and ensures there is a trailing
+ slash at the end.
+*/
+void setInstallDir ( String argv_0 )
+{
+ int i;
+ char* r = getenv("STGHUGSDIR");
+ if (!r) {
+ fprintf(stderr,
+ "%s: installation error: environment variable STGHUGSDIR is not set.\n",
+ argv_0 );
+ fprintf(stderr,
+ "%s: pls set it to be the directory where STGHugs98 is installed.\n\n",
+ argv_0 );
+ exit(2);
+
+ }
+
+ if (strlen(r) > N_INSTALLDIR-30 ) {
+ fprintf(stderr,
+ "%s: environment variable STGHUGSDIR is suspiciously long; pls remedy\n\n",
+ argv_0 );
+ exit(2);
+ }
+
+ strcpy ( installDir, r );
+ i = strlen(installDir);
+ if (installDir[i-1] != SLASH) installDir[i++] = SLASH;
+ installDir[i] = 0;
+}
+
+
+Bool findFilesForModule (
+ String modName,
+ String* path,
+ String* sExt,
+ Bool* sAvail, Time* sTime, Long* sSize,
+ Bool* oiAvail, Time* oiTime, Long* oSize, Long* iSize
+ )
+{
+ /* Let the module name given be M.
+ For each path entry P,
+ a s(rc) file will be P/M.hs or P/M.lhs
+ an i(nterface) file will be P/M.hi
+ an o(bject) file will be P/M.o
+ If there is a s file or (both i and o files)
+ use P to fill in the path names.
+ Otherwise, move on to the next path entry.
+ If all path entries are exhausted, return False.
+
+ If in standalone, only look for (and succeed for) source modules.
+ Caller free()s path. sExt is statically allocated.
+ srcExt is only set if a valid source file is found.
+ */
+ Int nPath;
+ Bool literate;
+ String peStart, peEnd;
+ String augdPath; /* .:hugsPath:installDir/../lib/std:installDir/lib */
+ Time oTime, iTime;
+ Bool oAvail, iAvail;
+
+ *path = *sExt = NULL;
+ *sAvail = *oiAvail = oAvail = iAvail = FALSE;
+ *sSize = *oSize = *iSize = 0;
+
+ augdPath = malloc( 2*(10+3+strlen(installDir))
+ +strlen(hugsPath) +50/*paranoia*/);
+ if (!augdPath)
+ internal("moduleNameToFileNames: malloc failed(2)");
+
+ augdPath[0] = 0;
+ strcat(augdPath, ".");
+ strcat(augdPath, PATHSEP_STR);
+
+ strcat(augdPath, hugsPath);
+ strcat(augdPath, PATHSEP_STR);
+
+ if (combined) {
+ strcat(augdPath, installDir);
+ strcat(augdPath, "..");
+ strcat(augdPath, SLASH_STR);
+ strcat(augdPath, "lib");
+ strcat(augdPath, SLASH_STR);
+ strcat(augdPath, "std");
+ strcat(augdPath, PATHSEP_STR);
+ }
+
+ strcat(augdPath, installDir);
+ strcat(augdPath, "lib");
+ strcat(augdPath, PATHSEP_STR);
+
+ /* fprintf ( stderr, "augdpath = `%s'\n", augdPath ); */
+
+ peEnd = augdPath-1;
+ while (1) {
+ /* Advance peStart and peEnd very paranoically, giving up at
+ the first sign of mutancy in the path string.
+ */
+ if (peEnd >= augdPath && !(*peEnd)) { free(augdPath); return FALSE; }
+ peStart = peEnd+1;
+ peEnd = peStart;
+ while (*peEnd && *peEnd != PATHSEP) peEnd++;
+
+ /* Now peStart .. peEnd-1 bracket the next path element. */
+ nPath = peEnd-peStart;
+ if (nPath + strlen(modName) + 10 /*slush*/ > FILENAME_MAX) {
+ ERRMSG(0) "Hugs path \"%s\" contains excessively long component",
+ hugsPath
+ EEND;
+ free(augdPath);
+ return FALSE;
+ }
+
+ strncpy(searchBuf, peStart, nPath);
+ searchBuf[nPath] = 0;
+ if (nPath > 0 && !isSLASH(searchBuf[nPath-1]))
+ searchBuf[nPath++] = SLASH;
+
+ strcpy(searchBuf+nPath, modName);
+ nPath += strlen(modName);
+
+ /* searchBuf now holds 'P/M'. Try out the various endings. */
+ *path = *sExt = NULL;
+ *sAvail = *oiAvail = oAvail = iAvail = FALSE;
+ *sSize = *oSize = *iSize = 0;
+
+ if (combined) {
+ strcpy(searchBuf+nPath, DLL_ENDING);
+ if (readable(searchBuf)) {
+ oAvail = TRUE;
+ getFileInfo(searchBuf, &oTime, oSize);
+ }
+ strcpy(searchBuf+nPath, HI_ENDING);
+ if (readable(searchBuf)) {
+ iAvail = TRUE;
+ getFileInfo(searchBuf, &iTime, iSize);
+ }
+ if (oAvail && iAvail) {
+ *oiAvail = TRUE;
+ *oiTime = whicheverIsLater ( oTime, iTime );
+ }
+ }
+
+ strcpy(searchBuf+nPath, ".hs");
+ if (readable(searchBuf)) {
+ *sAvail = TRUE;
+ literate = FALSE;
+ getFileInfo(searchBuf, sTime, sSize);
+ *sExt = ".hs";
+ } else {
+ strcpy(searchBuf+nPath, ".lhs");
+ if (readable(searchBuf)) {
+ *sAvail = TRUE;
+ literate = TRUE;
+ getFileInfo(searchBuf, sTime, sSize);
+ *sExt = ".lhs";
+ }
+ }
+
+ /* Success? */
+ if (*sAvail || *oiAvail) {
+ nPath -= strlen(modName);
+ *path = malloc(nPath+1);
+ if (!(*path))
+ internal("moduleNameToFileNames: malloc failed(1)");
+ strncpy(*path, searchBuf, nPath);
+ (*path)[nPath] = 0;
+ free(augdPath);
+ return TRUE;
+ }
+
+ }
+
+}
+
+
+/* If the primaryObjectName is (eg)
+ /foo/bar/PrelSwamp.o
+ and the extraFileName is (eg)
+ swampy_cbits
+ and DLL_ENDING is set to .o
+ return
+ /foo/bar/swampy_cbits.o
+ and set *extraFileSize to its size, or -1 if not avail
+*/
+String getExtraObjectInfo ( String primaryObjectName,
+ String extraFileName,
+ Int* extraFileSize )
+{
+ Time xTime;
+ Long xSize;
+ String xtra;
+
+ Int i = strlen(primaryObjectName)-1;
+ while (i >= 0 && primaryObjectName[i] != SLASH) i--;
+ if (i == -1) return extraFileName;
+ i++;
+ xtra = malloc ( i+3+strlen(extraFileName)+strlen(DLL_ENDING) );
+ if (!xtra) internal("deriveExtraObjectName: malloc failed");
+ strncpy ( xtra, primaryObjectName, i );
+ xtra[i] = 0;
+ strcat ( xtra, extraFileName );
+ strcat ( xtra, DLL_ENDING );
+
+ *extraFileSize = -1;
+ if (readable(xtra)) {
+ getFileInfo ( xtra, &xTime, &xSize );
+ *extraFileSize = xSize;
+ }
+ return xtra;
+}
+
+
+/* --------------------------------------------------------------------------