DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦6da64338b⟧ TextFile

    Length: 7093 (0x1bb5)
    Types: TextFile
    Notes: UNIX file
    Names: »init.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦f4b8d8c84⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »unimenu/src/menu/init.c« 

TextFile

static char *SCCSid = "@(#)init.c	1.1 15:34:44 4/6/85";
/*
#define	DEBUG
*/
/*
 *			Copyright (c) 1984
 *
 *		LANTECH Systems, Incoroporated
 *
 *			All rights reserved
 */

/*
 * Function:	init(file)
 *
 * Purpose:	Initialize the menu data structure.
 *
 * Passed:	The name (char *) of a file.
 *
 * Action:	This function reads in the file, arranges
 *		to find available memory for that file's
 *		information, puts that info there, and
 *		sets up the pointers in the menu data structure.
 *
 * Returns:	A pointer to the created data structure.
 *
 * Called by:	main, execute (for a child to re-initialize.
 *
 * Calls:	List to be compiled.
 *
 * notes:	calloc(1, sizeof(OBJECT)) is often used because
 *		calloc will fill the memory with nulls. - drm
 *
 * History:	Original code June 84, Robert Adams.
 *		Recoded to reflect reality July 84, Robert Adams.
 *		added code for oneline explanations, Top, and Lhcol
 *			mar 85 drm
 *
 */

#include "defs.h"


extern	int	Top;
extern	int	Lhcol;
extern	int	DispCur;

struct menu_f  *init (file)			/* make me a menu */
char   *file;					/* from this file */
{
int	fd;				/* for the file to read in */
struct menu_f  *mp;			/* to return */
char   *calloc ();			/* to get the memory */
char   *malloc ();			/* to get the memory */
char   *cp;				/* scratch char pointer */
char   *strcpy ();
char   *getlin ();
struct line_f  *lp;			/* allocated by parslin */
struct line_f *parslin ();		/* returns pointer to alloc'd memory */
struct choice_f *chp;			/* scratch */
struct choice_f *lastchp;		/* to back up linked list */
int     bool;				/* keeps track of end of files */


	Top = 0;
	Lhcol = -1;
	DispCur = 0;

#ifdef DEBUG
	printf("in init: file is %s\n", file);
#endif
	clribuf();				/* these two replace fopen */
	fd = open (file, 0);

	if (fd == -1)
	{
		printf("Cannont open: %s\n", file);
		return (NULL);
	}

	mp = (struct menu_f *) calloc (1, sizeof (struct menu_f));
#ifdef DEBUG
	printf("in init: calloc returned %D\n", (int) mp);
#endif

	if (mp == NULL)
	{
		printf ("Not enough memory for menu pointer.");
		close (fd);
		return (NULL);
	}

	while (cp = getlin (fd))		/* init global info */
	{

		/* continuation lines should not have been returned */
		x (*cp == ' ', "init: cp == SPACE");
		x (*cp == '\t', "init: cp == TAB");

		if (*cp == '#')			/* comment line */
			continue;

		if (*cp == '\n' || *cp == EOS)	/* empty line = end of global */
			break;

		lp = parslin (cp);		/* parse and allocate a line */

		switch (lp -> l_type)
		{
			case LTEXT: 
				mp -> m_global.c_text = lp;
				break;
			case LHELP: 
				mp -> m_global.c_help = lp;
				break;
			case LEXEC: 
				mp -> m_global.c_exec = lp;
				break;
			case LPRMPT: 
				mp->m_prompt = malloc( strlen(lp->l_val) + 1);
				if (mp -> m_prompt)
					strcpy (mp -> m_prompt, lp -> l_val);
				free (lp -> l_key);
				free ((char *) lp);
				break;
			case LCOL:
				mp -> m_col = atoi(lp->l_val);
				free (lp -> l_key);
				free ((char *) lp);
				break;
			case LTOP:
				Top = atoi(lp->l_val);
				free (lp->l_key);
				free ((char *) lp);
				break;
			case LHCOL:
				Lhcol = atoi(lp->l_val);
				free (lp->l_key);
				free ((char *) lp);
				break;
			case LPWD:
				DispCur = atoi(lp->l_val);
				free (lp->l_key);
				free ((char *) lp);
				break;
			case LBAD: 
				mp->m_bad = malloc (strlen (lp->l_val) + 1);
				if (mp -> m_bad)
					strcpy (mp -> m_bad, lp -> l_val);
				free (lp -> l_key);
				free ((char *) lp);
				break;
			case LOTHR: 
				/* insert this puppy in the linked list */
				lp -> l_next = mp -> m_global.c_list;
				mp -> m_global.c_list = lp;
				break;
			case LERROR: 
				printf("Invalid input line: \"%s\"\n",cp);
				CRblk(0);
				free(lp->l_key);
				free(lp);
				continue;
			default: 
				/* as my paternal grandfather used to say:
				   "Holy shit." */
				x (1 == 1, "init: parslin");
				break;
		}
		/* 
		 * we've dealt with continuation lines, 
		 * comments,
		 * empty lines,
		 * and valid lines.
		 * I claim we are through
		 */
	}					/* end while */

	if (cp == NULL)
	{
		printf ("End-of-file MUCH too early in \"%s\"\n", file);
		free (mp);
		close (fd);
		return (NULL);
	}

#ifdef DEBUG
	write(2, "Global init done\n", 17);
#endif
	/* 
	 * I just read the global info, time to read the 
	 * others now.
	 */

	/* 
	 * allocate space 
	 */
	mp->m_list = (struct choice_f *) calloc (1, sizeof(struct choice_f));
	if ( (chp = mp->m_list) == NULL )
		x (1, "init: calloc: chp");

	lastchp = NULL;
	bool = 0;				/* did we read ANYTHING? */

	while (cp = getlin (fd))
	{

		bool = 1;			/* we read something */

		/* continuation lines should not have been returned */
		if ( *cp == ' ' )
			x (1, "init: cp == SPACE II");
		if ( *cp == '\t' )
			x (1, "init: cp == TAB II");

		if (*cp == '#')		 	/* comment line */
			continue;

		/* an empty line represents the end of this choice */
		/* we only need the new space if we used the old space */
		if ((*cp == EOS || *cp == '\n') && chp -> c_text != NULL)
		{
			chp->c_next = (struct choice_f *) calloc(1,
				sizeof(struct choice_f));
			if ( chp->c_next == NULL )
				x (1, "init: calloc: chp II");
			lastchp = chp;
			chp = chp -> c_next;
#ifdef DEBUG
			write(1, "Line added\n", 11);
#endif
			continue;
		}

		if ( (lp = parslin (cp)) == NULL)	/* parse the input */
			x (1, "init: parslin");

		switch (lp->l_type)
		{
			case LTEXT: 
				chp -> c_text = lp;
				break;
			case LEXPL: 
				chp -> c_expl = lp;
				break;
			case LHELP: 
				chp -> c_help = lp;
				break;
			case LEXEC: 
				chp -> c_exec = lp;
				break;
			case LBAD: 
			case LPRMPT: 
			case LOTHR: 
				/* insert this puppy in the linked list */
				lp -> l_next = chp -> c_list;
				chp -> c_list = lp;
				break;
			case LERROR: 
				/* it broke */
				printf("Invalid input line %s\n",cp);
				free(lp -> l_key);
				free(lp);
				continue;
			default: 
				/* as my paternal grandfather used to say:
				   "Holy shit." */
				x (1 == 1, "init: parslin II");
				break;
		}
	}					/* end while */

	if (bool == 0)				/* nothing read in */
	{
		printf ("End-of-file too early in \"%s\"\n", file);
		free (mp -> m_list);
		free (mp);
		close (fd);
		return (NULL);
	}

	/* 
	 * Was the last entry caused by a trailing blank line ?
	 * If so, then de-allocate the space.
	 */
	if (chp -> c_text == NULL)
	{
		choice_free (chp);
		free (chp);
		lastchp -> c_next = NULL;
	}
	/* 
	 * if we got here, then the while exited by getlin
	 * returning NULL.  we have set up the menu pointer.
	 */
	close (fd);

#ifdef DEBUG
	lsm(mp);
#endif
	return (mp);
}

#ifdef DEBUG
/*
 * debugging code to list a menu structure
 */
lsm(mp)
struct	menu_f	*mp;
{
struct	choice_f *ch;
char	c;

	ch = mp->m_list;
	while ( ch )
	{
		if ( ch->c_text )
			printf("text: %s %s\n", ch->c_text->l_key, ch->c_Text);
		if ( ch->c_expl )
			printf("expl: %s %s\n", ch->c_expl->l_key, ch->c_expl->l_val);
		if ( ch->c_help )
			printf("help: %s %s\n", ch->c_help->l_key, ch->c_Help);
		if ( ch->c_exec )
			printf("exec: %s %s\n", ch->c_exec->l_key, ch->c_Exec);
		ch = ch->c_next;
		read(0, &c, 1);
	}
}
#endif