head	1.82;
access;
symbols
	fontscreen:1.81
	good:1.81;
locks; strict;
comment	@ * @;


1.82
date	94.12.04.23.36.40;	author jsshephe;	state Exp;
branches;
next	;


desc
@original
@


1.82
log
@included libraries/gadtools.h
@
text
@/* Files for reading and writing the preferences file */
/* $Id: misc.c,v 1.81 1994/12/04 02:09:07 jsshephe Exp jsshephe $
 * $Revision: 1.81 $
 * $Log: misc.c,v $
 * Revision 1.81  1994/12/04  02:09:07	jsshephe
 * Conditionally compiled some debugging text.
 *
 * Revision 1.8  1994/11/27  22:15:40  jsshephe
 * Changed Error() as to not print "Error:" on the first line.
 *
 * Revision 1.7  1994/11/27  21:44:56  jsshephe
 * Since the title is always the same, only passed error message to Error().
 *
 * Revision 1.6  1994/11/27  04:01:16  jsshephe
 * Fixed a bug in SearchSuffix() where it searched past the end of the list.
 *
 * Revision 1.5  1994/08/19  19:38:54  jsshephe
 * changed the filename from loadsave.c to misc.c
 * Added SearchSuffix() and strrstr()
 *
 * Revision 1.4  1994/08/18  23:19:57  jsshephe
 * Put up a error requester when it could not open the prefs file
 *
 * Revision 1.3  1994/08/18  21:24:27  jsshephe
 * changed the prefs structure to use variable length strings
 *
 * Revision 1.2  1994/08/18  20:58:30  jsshephe
 * Added Error()
 * fixed a few things
 *
 * Revision 1.1  1994/08/18  06:10:50  jsshephe
 * Initial revision
 */

#include <exec/types.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <libraries/iffparse.h>
#include <libraries/gadtools.h>
#include <dos/dos.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

/* protos */
#ifdef __OPTIMIZE__
#include <inline/exec.h>
#include <inline/intuition.h>
#include <inline/dos.h>
#else
#include <inline/stubs.h> /* shut up */
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/dos_protos.h>
#endif
#include <inline/iffparse.h>
#include "showprefs.h"

/* Save preference file as 'filename'
 * filename is an absolute path
 */
void SavePrefs(char *filename) {
    struct IFFHandle *iff= NULL;
    struct SuffixList *SufList;

    /* struct SuffixNode *SufNode */

    if (! (iff = AllocIFF())) {
	Error("AllocIFF() failed");
	goto Cleanup;
    }

    if	( !(iff->iff_Stream = Open(filename,MODE_NEWFILE))) {
	Error("Open() failed");
	goto Cleanup;
    }

    InitIFFasDOS(iff);

    if (OpenIFF(iff,IFFF_WRITE)) {
	Error("OpenIFF() failed.");
	goto Cleanup;
    }

    PushChunk(iff,ID_SHOW,ID_FORM,IFFSIZE_UNKNOWN);
    for (SufList = (struct SuffixList *)Suffix_List->lh_Head;
	 SufList->sl_Node.ln_Succ;
	 SufList= (struct SuffixList *)SufList->sl_Node.ln_Succ) {

	UWORD len;

	PushChunk(iff,ID_SHOW,ID_PREF,IFFSIZE_UNKNOWN);

	/* new way - write out the length of the string
	 *	     then the string itself (NULL-terminated)
	 */
	len = strlen(SufList->sl_Node.ln_Name)+1;
	WriteChunkBytes(iff,&len,sizeof(UWORD));
	WriteChunkBytes(iff,SufList->sl_Node.ln_Name,len);

	len = strlen(SufList->command)+1;
	WriteChunkBytes(iff,&len,sizeof(UWORD));
	WriteChunkBytes(iff,SufList->command,len);

	WriteChunkBytes(iff,&SufList->Asynch,sizeof(BOOL));

	PopChunk(iff);
    }
    PopChunk(iff);

Cleanup :
    if (iff) {
	CloseIFF(iff);
	if (iff->iff_Stream)
	    Close(iff->iff_Stream);
	FreeIFF(iff);
    }
}

/* Load Preference file 'filename' */
/* Dup - TRUE means save the settings in the duplicate Array */
/*     - used for restore */
/* Duplicate is only used if Dup is TRUE */
void Load(char *filename, BOOL Dup,struct List *Duplicate) {
    struct IFFHandle *iff= NULL;
    struct SuffixNode SufNode;
    struct ContextNode *cn;
    int error;

    if (! (iff = AllocIFF())) {
	Error("AllocIFF() failed");
	goto LoadCleanup;
    }

    if	( !(iff->iff_Stream = Open(filename,MODE_OLDFILE))) {
	Error("Cannot open env:show.prefs");
	goto LoadCleanup;
    }

    InitIFFasDOS(iff);

    if (error=OpenIFF(iff,IFFF_READ)) {
	char errormsg[MAX_LENGTH];
	sprintf(errormsg,"OpenIFF() failed. Error: %d",error);
	Error(errormsg);
	goto LoadCleanup;
    }

    /* stop at PREFS hunks */
    StopChunk(iff,ID_SHOW,ID_PREF);

    for(;;) {
	error=ParseIFF(iff,IFFPARSE_SCAN);

	if (error == IFFERR_EOC) continue;
	else if (error) break;

	cn = CurrentChunk(iff);

	if ( cn && (cn->cn_Type == ID_SHOW) && (cn->cn_ID == ID_PREF)) {
	    struct SuffixList *NewNode;
	    UWORD len;

	    /* new way - uses variable length strings */
	    ReadChunkBytes(iff,&len,sizeof(UWORD));
	    ReadChunkBytes(iff,SufNode.suffix,len);

	    ReadChunkBytes(iff,&len,sizeof(UWORD));
	    ReadChunkBytes(iff,SufNode.command,len);

	    ReadChunkBytes(iff,&SufNode.Asynch,sizeof(BOOL));

	    if (NewNode =MakeNode(SufNode.suffix,SufNode.command,SufNode.Asynch)) {
		AddTail(Suffix_List,(struct Node *)NewNode);
	    }
	    else {
		error = IFFERR_NOMEM;
		break;
	    }

	    /* Duplicate the list if we need to */
	    if (Dup) {
		struct SuffixList *DupNode;
		if (DupNode =MakeNode(SufNode.suffix,SufNode.command,SufNode.Asynch))
		    AddTail(Duplicate,(struct Node *)DupNode);
		else {
		    error = IFFERR_NOMEM;
		    break;
		}
	    }

	}
    }

    if (error && (error != IFFERR_EOF)) {
	char errormsg[MAX_LENGTH];
	sprintf(errormsg,"IFF read failed. Error %d",error);
	Error(errormsg);
    }

LoadCleanup :
    if (iff) {
	CloseIFF(iff);
	if (iff->iff_Stream)
	    Close(iff->iff_Stream);
	FreeIFF(iff);
    }
}


/* Make a new SuffixList Node with the specified parameters */
/* returns NULL is something did not succeed */
/* else returns the new node */
struct SuffixList *MakeNode(char *suffix, char *command, BOOL Asynch) {
    struct SuffixList *NewNode = AllocMem(sizeof(struct SuffixList),MEMF_PUBLIC|MEMF_CLEAR);
    if (NewNode) {
	NewNode->sl_Node.ln_Name = AllocMem(MAX_LENGTH*sizeof(char),MEMF_CLEAR|MEMF_PUBLIC);
	if (NewNode->sl_Node.ln_Name) {
	    strcpy(NewNode->sl_Node.ln_Name,suffix);
	    NewNode->sl_Node.ln_Pri = 0;
	    NewNode->sl_Node.ln_Type = NT_USER;
	    strcpy(NewNode->command,command);
	    NewNode->Asynch = Asynch;
	}
	else {
	    FreeMem(NewNode,sizeof(struct SuffixList));
	    NewNode = NULL;
	}
   }
   return NewNode;
}

/* free up nodes in list */
/* does not free list */
void Destroy_List(struct List *LList) {
    struct SuffixList *oldNode;
    while (oldNode=(struct SuffixList *)RemHead(LList)) {
	if (oldNode->sl_Node.ln_Name)
	    FreeMem(oldNode->sl_Node.ln_Name,MAX_LENGTH*sizeof(char));
	FreeMem(oldNode, sizeof(struct SuffixList));
    }
}

/* display error requester with the respective title and error message */
void Error(char *error) {
    static char title[] = "Fatal Error";

    struct EasyStruct es = {
	sizeof(struct EasyStruct),
	NULL,
	title,
	error,
	"OK"
    };
    EasyRequest(NULL,&es,NULL,NULL);
}


/* returns the Node with the suffix defined in filename */
struct Node *SearchSuffix(struct List *SufList, char *filename) {
    struct Node *retval;

    #ifdef debug
	printf("SearchSuffix filename to be searched: %s\n",filename);
    #endif

    /* make sure the list is not empty */
    if (SufList->lh_TailPred != (struct Node *)SufList) {
	for(retval = SufList->lh_Head;retval->ln_Succ &&
	  !strrstr(filename,retval->ln_Name); retval =retval->ln_Succ) {
	    #ifdef debug
		printf("Name %s\n",retval->ln_Name);
	    #endif
	} /* for */

	if (retval && retval->ln_Succ && strrstr(filename,retval->ln_Name)) {
	    #ifdef debug
		puts("Found");
	    #endif
	    return retval;
	}
	else {
	    #ifdef debug
		puts("Not Found");
	    #endif
	    return NULL;
	}
    }
    else
	return NULL;
}

/* finds last occurrence of substr in string */
char *strrstr(char *string, const char *substr) {
    char *tempstring = string;
    char *found = NULL;
    char *temp;

    if (string) {
	while (temp = strstr(tempstring,substr)) {
	    tempstring = temp;
	    tempstring++;
	    found = temp;
	}
    }
    return found;
}
@
