Hugs has a Bug by My WindowsME
Sigbjorn Finne
sof@galconn.com
Wed, 31 Oct 2001 11:38:20 -0800
This is a multi-part message in MIME format.
------=_NextPart_000_1029_01C16200.8A852C30
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Hi,
my guess is that you've accidentally corrupted your Hugs98
settings, causing the fatal errors below.
Attached is some code for a utility that will restore your settings
back to the default ones; I posted this utility to this mailing list
a couple of months back, see
http://haskell.cs.yale.edu/pipermail/hugs-users/2001-August/000122.html
for more info.
hth
--sigbjorn
----- Original Message -----
From: <belal@web.de>
To: <hugs-users@haskell.org>
Sent: Tuesday, October 30, 2001 04:44
Subject: Hugs has a Bug by My WindowsME
> I've installed Hugs-Interpreter at my WIndowsME. And then it did not
functioned. I have becomed a messege:
> "FATAL ERROR:unable to load Prelude"..
> And another messege, which was in the hugs windows:
> "ERROR c:\Programme\hugs98\lib\Prelude.hs
> Garbage Collection fails to reclaim sufficient space"..
> I hope you can help me...
> PS: the file Prelude.hs is in the correct directory.
------=_NextPart_000_1029_01C16200.8A852C30
Content-Type: application/octet-stream;
name="restore.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="restore.c"
/*
* Hugs98 Registry reset app - get rid off the
* user-specific Hugs98 options settings from the Registry.
*
* The reason why this util is needed is that Hugs doesn't=20
* perform any validity checks when persisting the :set'able
* options to the Registry. As a result, the user might end
* up inadvertently zapping the search path, causing Hugs=20
* to be unable to locate the Prelude the next time it starts
* up. Which is undesirable, since it'll then exit before
* the useris able to get to get to the interpreter prompt
* & repair the damage done via another :set !!
*
* The only way to exit from this unhappy state of affairs
* is to either be Registry-savy and do the mods 'regedit',
* or reinstall. So, clearly some room for improvement in
* usability here.
*
* This util is a stop-gap measure which lets the user rid
* him/herself of the *user-specific* option settings that
* Hugs will have saved in the Registry. By deleting the
* user-specific settings, the next time Hugs starts up,
* it'll default back to using the machine-wide default
* options. i.e., the user may end up having to go in=20
* and tweak these settings again, but at least Hugs has
* been brought back into a useable state.
*
* To compile this utility, you'll need a Win32 C compiler;
* here are the options to use with the three compilers I've
* tested it with:
*
* MSVC: cl /o restorer restore.c advapi32.lib
* gcc: gcc -mno-cygwin -o restorer restore.c
* lcc-win32: lc restore.c -o main.exe
*=20
* 7/01 -- sof
*/
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
#define MAX(x,y) ( x > y ? x : y)
#define HUGS_HCU_ROOT "Software\\Haskell\\Hugs"
/* This util inspects the Registry looking for
existing Hugs installations in the current
user hive.
Store each one of the installs found in a table,
so that we can later on go in and selectively
reset each one of them.
*/
typedef struct {
TCHAR* keyName;
HKEY hKey;
} HugsInstall;
typedef struct {
unsigned int size;
unsigned int idx;
HugsInstall* tab;
} InstallTable;
/*
* Function: initInstallTable ( unsigned int sz )
*
* Purpose: Allocate a table (of 'sz' elements) that will
* hold information about available Hugs installation.
*
* Returns: empty Hugs InstallTable of size 'sz' elements.
*/
InstallTable*
initInstallTable(unsigned int size)
{
HugsInstall* tab;
InstallTable* table;
=20
table =3D (InstallTable*)malloc(sizeof(InstallTable));
=20
if (table =3D=3D NULL) {
return table;
}
tab =3D (HugsInstall*)malloc(size * sizeof(HugsInstall));
=20
if (tab =3D=3D NULL) {
free(table);
return NULL;
}
=20
table->size =3D size;
table->idx =3D 0;
table->tab =3D tab;
=20
return table;
}
void
DestroyTable(InstallTable* table)
{
int i;
if (!table)=20
return;
for ( i=3D0; i < (int)table->idx ; i++ ) {
free(table->tab[i].keyName);
RegCloseKey(table->tab[i].hKey);
}
=20
free(table->tab);
free(table);
} =20
/*
* Function: expandTable(InstallTable*)
*
* Purpose: expand the installation table by 50%.
* Helper routine used by addInstall().
*
* Returns: boolean indicating whether the expansion
* was successful or not.
*/
BOOL
expandTable(InstallTable* table)
{
HugsInstall* tab;
unsigned int newSz;
if (!table) {
return FALSE;
}
=20
newSz =3D table->size + MAX(1, (table -> size / 2));
tab =3D (HugsInstall*)realloc(table->tab, sizeof(HugsInstall) * =
newSz);
if (tab =3D=3D NULL) {
return FALSE;
}
table->size =3D newSz;
table->tab =3D tab;
return TRUE;
}
BOOL
addHugsInstall(InstallTable* table, char* dirName, HKEY hKey)
{
char* tmp;
if (!table)
return FALSE;
/* idx points to the next available slot */
if ( table->idx =3D=3D table->size ) {
if ( !expandTable(table) ) {
return FALSE;
}
}
=20
tmp =3D (char*)malloc(sizeof(char) * (strlen(dirName) + 1));
=20
if (!tmp)=20
return FALSE;
=20
strcpy(tmp, dirName);
table->tab[table->idx].keyName =3D tmp;
table->tab[table->idx].hKey =3D hKey;
=20
table->idx +=3D 1;
=20
return TRUE;
}
#define HandleRegError(msg, rc) printf("Error calling %s - return code =
=3D 0x%x\n", msg, rc)
void
ResetOption(InstallTable* table, int idx)
{
LONG lRes;
=20
lRes =3D RegDeleteValue(table->tab[idx].hKey, "Options");
printf("Finished resetting %s\n\n", table->tab[idx].keyName);
}
void
HandleDeletion(InstallTable* table)
{
int i, idx;
int ch;
int val;
char line[10];
BOOL* delVector;
int* idxVector;
=20
printf("Hugs98 Repair Tool\n\n");
printf("By selecting one of the installations below, you'll reset\n");
printf("your user-specific options that Hugs98 has saved away\n");
printf("in the Windows Registry (Resetting just gets you back\n");
printf("to using the default Hugs options).\n\n");
=20
if (!table || table->idx =3D=3D 0) {
printf("\n\n No local Hugs installations found. Exiting\n");
return;
}
=20
idxVector=3D(int*)malloc(sizeof(int) * (table->idx));
delVector=3D(int*)malloc(sizeof(BOOL) * (table->idx));
for (i=3D0;i < (int)table->idx; i++) {
delVector[i]=3DFALSE;
idxVector[i]=3D-1;
}
do {
idx =3D 0;
printf("Local Hugs98 installations: \n");
for (i=3D0; i < (int)table->idx ; i++ ) {
if (delVector[i]) {
continue;
}
idxVector[idx] =3D i;
printf(" %i - %s\n", idx+1, table->tab[i].keyName);
idx++;
}
=20
printf("\nInstallation to reset (0 =3D=3D reset all; ENTER to exit) =
? ");
fflush(stdout);
if (fgets(line,10,stdin) !=3D NULL) {
if (line[0] =3D=3D '\n') {
free(delVector);
free(idxVector);
return;
}
val =3D atoi(line);
if (val !=3D 0) {
if ( val > idx ) {
printf("Selection, %u, out of range\n", val);
continue;
}
ResetOption(table, idxVector[val-1]);
delVector[idxVector[val-1]]=3DTRUE;
} else {
for (i=3D0; i < table->idx ; i++) {
if (!delVector[i]) {
ResetOption(table, i);
}
}
free(delVector);
free(idxVector);
break;
}
}
} while (1);
}
int
main()
{
HKEY hHugsKey;
HKEY hSubKey;
LONG lRes;
TCHAR nameBuf [ 511 ];
TCHAR nameBuf2 [ 2048 ];
DWORD dwSize, dwIndex;
InstallTable* table;
FILETIME ft;
lRes =3D=20
RegOpenKeyEx ( HKEY_CURRENT_USER,
HUGS_HCU_ROOT,
0,
KEY_ALL_ACCESS,
&hHugsKey);
=20
if ( lRes !=3D ERROR_SUCCESS ) {
HandleRegError("RegOpenKey", lRes);
return 1;
}
=20
dwIndex =3D -1;
=20
table =3D initInstallTable(2);
do {
dwSize =3D sizeof ( nameBuf );
dwIndex++;
lRes =3D=20
RegEnumKeyEx ( hHugsKey,
dwIndex,
nameBuf,
&dwSize,
NULL,
NULL,
NULL,
&ft);
if ( lRes =3D=3D ERROR_SUCCESS ||
lRes =3D=3D ERROR_MORE_DATA ||=20
lRes =3D=3D ERROR_NO_MORE_ITEMS ) {
strcpy(nameBuf2, HUGS_HCU_ROOT);
strcat(nameBuf2, "\\");
strcat(nameBuf2, nameBuf);
RegOpenKeyEx ( HKEY_CURRENT_USER,
nameBuf2,
0,
KEY_ALL_ACCESS,
&hSubKey);
if ( !addHugsInstall(table, nameBuf, hSubKey) ) {
break;
}
}
} while ( lRes =3D=3D ERROR_SUCCESS ||=20
lRes =3D=3D ERROR_MORE_DATA );=20
=20
if ( lRes !=3D ERROR_MORE_DATA && lRes !=3D ERROR_NO_MORE_ITEMS ) {
HandleRegError("RegEnumKeyEx", lRes);
return 0;
}
=20
HandleDeletion(table);
=20
DestroyTable(table);
RegCloseKey(hHugsKey);
=20
return 0;
}
------=_NextPart_000_1029_01C16200.8A852C30--