DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

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

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T c

⟦be61add93⟧ TextFile

    Length: 7008 (0x1b60)
    Types: TextFile
    Names: »cmds.stack.c«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦e7f64e0c0⟧ »EurOpenD3/mail/vmh.tar.Z« 
        └─⟦dcb95597f⟧ 
            └─⟦this⟧ »cmds.stack.c« 

TextFile

#ifndef lint
static char rcsid[] =
	"$Header: cmds.stack.c,v 1.7 86/10/09 15:59:15 deboor Exp $";

static char notice[] =
	"This program is in the public domain and is available for unlimited \
distribution as long as this notice is enclosed.";
#endif lint

/*
 * Commands for playing with the folder stack.
 *
 * $Source: /c/support/deboor/usr/src/old/vmh/RCS/cmds.stack.c,v $
 * $Revision: 1.7 $
 * $Author: deboor $
 *
 * FUNCTIONS:
 *	cmdList_stack	print out current folder stack
 *	cmdPop		remove folder from folder stack
 *	cmdPush		push a folder onto the folder stack
 *	cmdSwitch	switch to a different folder
 *	init_stack	initialize folder stack
 */

#include "vmh.h"

/*
 * cmdSwitch (count, undo, argc, argv) int count, undo, argc; char **argv;
 *	cmdSwitch simply switches the current folder to be either the first
 *	argument, if any, in the argv vector or to the folder for which it
 *	prompts. Because people don't give counts when switching folders
 *	(unless they're weird), cmdPush calls cmdSwitch with a count of
 *	0 if cmdSwitch should prompt for a folder to which to push, rather
 *	than switch. Knowing this, if you think it's neat to fool a program,
 *	feel free to give a 0 count when switching folders.
 */
/*ARGSUSED*/
cmdSwitch(count, undo, argc, argv)
	int	count,
		undo,
		argc;
	char	**argv;
{
	char    folder[PATHLENGTH];
	int     t;

	if (count)
		prt_action (" Switch folders ");
	if (!argc) {
		if (!count)
			t = getfolderpath("Push to folder ",folder,
				sizeof(folder), 0);
		else
			t = getfolderpath("Switch to folder ", folder,
				sizeof(folder), 0);
	} else {
		(void) strcpy (folder, argv[0]);
		t = getpath (folder, folder, sizeof(folder));
	}

	if (t == 0)                             /* If ok folder . . . */
	{
		wclear(cmdWin); wrefresh(cmdWin);    /* Clear cmd line */
		dofolder(folder);                    /* Do new folder */
		return (0);
	}
	else if (t!=2)
	{
		errormsg("No such folder", 0);
	}
	return (1);
}

/*
 * the folder stack structure. f_name is the folder name. f_prv points to the
 * previous element in the "stack." f_nxt points to the next one. Admittedly,
 * you don't see a doubly linked stack too often, but tough. --ardeb
 */
struct foldstack {
	char			*fs_name;	/* the name */
	struct	foldstack	*fs_prv,	/* the previous element */
				*fs_nxt;	/* the next element */
} *StackHead = NULL;

/*
** initstack()
**	called from initstuff(), this function initializes the top of the
**	stack to be the passed  folder . This way, the stack is never
**	empty, sort of like some bars I've never been to. --ardeb
**
**	Sigh. it's still doubly linked, but it starts out empty.
*/
init_stack ()
{
	StackHead = NULL;	/* mark stack as empty */
}

/*
** cmdPush (levels) int levels;
**	if  levels  is 1, calls cmdSwitch to change folders and then pushes
**	the gotten one on the stack. If  levels  is greater than 1, then the
**	levels'th folder is brought to the top of the stack and the folder
**	changed to it.
*/
/*ARGSUSED*/
cmdPush (levels, undo, argc, argv)
	int	levels,
		undo,
		argc;
	char	**argv;
{
	register struct	foldstack	*tmp;
	register			i;

	if (levels < 0) {
		cmdList_stack();
		return;
	}
	if (levels == 1) {
		prt_action (" Push folder ");
		/* Create a new element for the stack */
		tmp = (struct foldstack *) Malloc (sizeof (struct foldstack));

		/* put in a new copy of the folder name */
		tmp->fs_name = (char *) Malloc (strlen (F->f_name) + 1);
		(void) strcpy (tmp->fs_name, F->f_name);

		/* add the new folder to the top */
		if (StackHead) 
			StackHead->fs_prv = tmp;
		tmp->fs_nxt = StackHead;
		tmp->fs_prv = NULL;
		StackHead = tmp;

		if (cmdSwitch(0,undo,argc,argv)) {	/* unsuccessful change, so... */
			cmdPop (1);	/* pop it off again */
		}

		cmdList_stack();
		return;
	} else {
		char	*tname;
		char	num[20];	/* exorbitant */

		prt_action (" Push the %s folder ", sprintf (num, (levels % 10 == 2 ? "%dnd" : levels % 10 == 3 ? "%drd" : "%dth"),
			levels));
		/* get to the desired level */
		for (tmp = StackHead, i = 2; tmp && i < levels; i++, tmp = tmp->fs_nxt)
			;
		if (tmp == NULL) {
			errormsg ("not that many levels in stack!", 1);
			return;
		}

		tname = tmp->fs_name;
		tmp->fs_name = (char *) Malloc (strlen (F->f_name) + 1);
		(void) strcpy (tmp->fs_name, F->f_name);

		/* change to this folder */
		dofolder (tname);

		/* then free up the string */
		Free ((char *)tname);

		/* and list the stack for the user's sake...as usual */
		cmdList_stack();

	}
}

/*
** cmdPop (levels) int levels;
**	pops the  level'th folder off the stack. i.e. if 1 is given,
**	simply pops the first folder. If 3 is given, travels down the
**	stack to the third level and (void) unlinks that folder.
*/
cmdPop (levels)
	int	levels;
{
	register struct foldstack	*tmp;
	register			i;
	char				num[20];

	if (levels < 0) {
		cmdList_stack();
		return;
	}
	if (levels == 1) {
		prt_action ("Pop the current folder");
		if (StackHead == NULL) {
			errormsg ("not that many levels in stack!", 1);
			return;
		}

		tmp = StackHead;	/* save head */
		StackHead = StackHead->fs_nxt;	/* pop the thing */
		if (StackHead)
			StackHead->fs_prv = NULL;	/* for the hell of it */

		dofolder (tmp->fs_name);	/* switch to the folder */

		Free ((char *)tmp->fs_name);	/* free up the folder name */
		Free ((char *)tmp);		/* then the structure */

		cmdList_stack();	/* list the current stack */
		return;
	}
	prt_action ("Pop the %s folder", sprintf (num, (levels % 10 == 2 ? "%dnd" : levels % 10 == 3 ? "%drd" : "%dth"),
		levels));
	/*
	 * move down the stack  levels  levels or until NULL is hit
	 */
	for (i = 2, tmp = StackHead; tmp && i < levels; i++, tmp = tmp->fs_nxt)
		;
	/* if it's NULL, bitch. */
	if (tmp == NULL) {
		errormsg ("not that many levels in stack!", 1);
		return;
	}

	if (tmp->fs_prv)
		tmp->fs_prv->fs_nxt = tmp->fs_nxt;	/* link prev to next */
	if (tmp->fs_nxt)
		tmp->fs_nxt->fs_prv = tmp->fs_prv;	/* then next to prev */

	if (tmp == StackHead)			/* if that was the top */
		StackHead = StackHead->fs_nxt;	/* advance StackHead */

	Free ((char *)tmp->fs_name);		/* free the foldername! */
	Free ((char *)tmp);			/* then the structure! */
					/* Vive la Revolucion!! */

	cmdList_stack();
}

/*
** cmdList_stack()
**	takes no arguments. Lists the current folder stack in
**	the bottom window. Called by cmdPush and cmdPop if they are
**	given negative levelss.
*/
cmdList_stack ()
{
	register struct foldstack	*tmp;
	static	char			*stackStr = (char *)0;
	register char			*cp,
					*sEnd;

	if (stackStr == (char *) 0)
		stackStr = (char *) Malloc (COLS);
	
	/* first the current folder */
	(void) snprintf (stackStr, COLS, " +%s ", &F->f_name[rootlen+1]);
	cp = stackStr + strlen (&F->f_name[rootlen+1]) + 3;
	sEnd = cp + COLS;


	/* then the stack */
	for (tmp = StackHead; tmp; tmp = tmp->fs_nxt) {
		(void) snprintf (cp, sEnd - cp, "+%s ", &tmp->fs_name[rootlen + 1]);
		cp += strlen (&tmp->fs_name[rootlen + 1]) + 2;
		if (sEnd - cp < 0)
			break;
	}
	
	dotitle (botHdr, stackStr);
}