[comp.sources.amiga] v91i088: CShell 5.10 - alternative command interface, Part01/06

amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (04/17/91)

Submitted-by: umueller@iiic.ethz.ch
Posting-number: Volume 91, Issue 088
Archive-name: shells/cshell-5.10/part01

[ executable to appear in comp.binaries.amiga  ...tad ]
[ file `csh.doc' was split to facilitate posting  ...tad ]

Announcing: CShell 5.10

CShell  5.10  offers  a much more powerful parser, some new command options
and bug fixes.

Main features include: (see changes.doc for complete list)
- totally rewritten parser, therefore:
-  local variables, in aliases as well as in batch files
-  blocks can be formed, redirected, aborted: {e yo;e ho}
-  $(foo) will insert output of program foo at that point, similar: `foo`
-  parsing also done with command itself, e.g. '*' is a legal command line
-  aliases/foreach/forline/fornum/source can be redirected as a whole
-  direct recursion in aliases prevented, 'alias ls "ls -s"' works
-  additional speedup; twice as fast as 4.xx, four times as fast as c:Execute
- 'assign' now can handle all types of assings correctly under 2.0
- 'class' can pattern-match now, e.g. 'class sound name="mod.*"'
- 'copy' has a larger buffer, copy -m' moves files
- 'dir -z formatstring' is a very powerful formatting feature, some more opts
- 'forline i STDIN' reads args from stdin
- 'man' can handle multiple .doc files, so you can document your own aliases
- 'source' can handle multiple line blocks of arbitrary length
- 'rback'/'run' now set the variable '$_newproc' to the # of the new process
- $_abbrev can be used to disable abbreviation if internal commands
- $_ioerr contains the secondary return code after an error
- $_pipe now holds the directory for the temporary pipe files
- $_verbose need to be set to special values, now can trace alias calls
- @console tells whether stdin or stdout are interactive
- @ioerr converts a secondary error number to a string (like 'Why')
- @mounted indicates whether a device has been mounted yet or not
- @sortnum sorts its arguments numerically
- shift-arrow-up and shift-arrow-down now behave like under AmigaDOS
- concatted lines in source files can be arbitrary long
- . now stands for current directory, .. for parent

Most important bug fixes:
- INTERNAL residents can now be used with V37 Kickstarts
- c:Execute can be started
- 'Wait 5&' as an alias for 'rback Wait 5' now works

Miscellaneous info:
- Some more documentation, tips & tricks
- Executable size: 89K


#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 6)."
# Contents:  README Syms.c class.sh globals.c lmakefile main.c makefile
#   menu.sh proto.h run.c sample.sh set.c shell.h technotes.doc
#   tips.doc
# Wrapped by tadguy@ab20 on Tue Apr 16 15:34:34 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2637 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XAnnouncing: CShell 5.10
X
XCShell  5.10  offers  a much more powerful parser, some new command options
Xand bug fixes.
X
XMain features include: (see changes.doc for complete list)
X- totally rewritten parser, therefore:
X-  local variables, in aliases as well as in batch files
X-  blocks can be formed, redirected, aborted: {e yo;e ho}
X-  $(foo) will insert output of program foo at that point, similar: `foo`
X-  parsing also done with command itself, e.g. '*' is a legal command line
X-  aliases/foreach/forline/fornum/source can be redirected as a whole
X-  direct recursion in aliases prevented, 'alias ls "ls -s"' works
X-  additional speedup; twice as fast as 4.xx, four times as fast as c:Execute
X- 'assign' now can handle all types of assings correctly under 2.0
X- 'class' can pattern-match now, e.g. 'class sound name="mod.*"'
X- 'copy' has a larger buffer, copy -m' moves files
X- 'dir -z formatstring' is a very powerful formatting feature, some more opts
X- 'forline i STDIN' reads args from stdin
X- 'man' can handle multiple .doc files, so you can document your own aliases
X- 'source' can handle multiple line blocks of arbitrary length
X- 'rback'/'run' now set the variable '$_newproc' to the # of the new process
X- $_abbrev can be used to disable abbreviation if internal commands
X- $_ioerr contains the secondary return code after an error
X- $_pipe now holds the directory for the temporary pipe files
X- $_verbose need to be set to special values, now can trace alias calls
X- @console tells whether stdin or stdout are interactive
X- @ioerr converts a secondary error number to a string (like 'Why')
X- @mounted indicates whether a device has been mounted yet or not
X- @sortnum sorts its arguments numerically
X- shift-arrow-up and shift-arrow-down now behave like under AmigaDOS
X- concatted lines in source files can be arbitrary long
X- . now stands for current directory, .. for parent
X
XMost important bug fixes:
X- INTERNAL residents can now be used with V37 Kickstarts
X- c:Execute can be started
X- 'Wait 5&' as an alias for 'rback Wait 5' now works
X
XMiscellaneous info:
X- Some more documentation, tips & tricks
X- Executable size: 89K
X
XAvailable now from ab20.larc.nasa.gov, will be distributed over
Xcomp.binaries.amiga.
X
Xcsh510.lzh      # executable, docs, sample scripts
Xcsh510s.lzh     # source (lattice & manx)
X                                          __
X |          Urban Mueller         |      / / |    Urban Mueller    |
X | USENET:  umueller@iiic.ethz.ch | __  / /  |    Schulhausstr. 83 |
X | FIDONET: 2:302/906 (AUGL)      | \ \/ /   | CH-6312 Steinhausen |
X | "Don't tell my employer"       |  \__/    |    SWITZERLAND      |
END_OF_FILE
if test 2637 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Syms.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Syms.c'\"
else
echo shar: Extracting \"'Syms.c'\" \(19 characters\)
sed "s/^X//" >'Syms.c' <<'END_OF_FILE'
X#include "shell.h"
END_OF_FILE
if test 19 -ne `wc -c <'Syms.c'`; then
    echo shar: \"'Syms.c'\" unpacked with wrong size!
fi
# end of 'Syms.c'
fi
if test -f 'class.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'class.sh'\"
else
echo shar: Extracting \"'class.sh'\" \(1730 characters\)
sed "s/^X//" >'class.sh' <<'END_OF_FILE'
Xclass -n
Xclass dms      offs=0,444D5321
Xclass warp     offs=0,57617270
Xclass zoom     offs=0,5A4F4F4D
Xclass lharc    offs=2,2D6C68..2D
Xclass zoo      offs=0,5A4F4F20
Xclass arc      offs=0,1a08
Xclass compr    offs=0,1f9d
Xclass anim     offs=0,464f524d........414e494d
Xclass icon     offs=0,e3100001 offs=0,f34c0012
Xclass gif      offs=0,474946
Xclass zip      offs=0,504b0304
Xclass ppacked  offs=0,50503230
X
Xclass dms      suff=.dms act exec="Dms write" extr="Dms write" view="Dms view"
Xclass warp     suff=.wrp act exec="Warp write 0 79" extr="Warp write 0 79"
Xclass zoom     suff=.zom act exec="Zoom" extr="Zoom"
Xclass lharc    suff=.lzh act exec="lharc e" extr="lharc e" view="lharc v" add="lharc a" edit=lharca
Xclass zoo      suff=.zoo act exec="zoo e" extr="zoo e//" view="zoo v" add="zoo a"
Xclass arc      suff=.arc act exec="arc e" extr="arc e" view="arc -v"
Xclass zip      suff=.zip act exec="unzip" extr="unzip" view="unzip l"
Xclass ppacked  suff=.pp  act exec="ppmore" view=ppmore
Xclass lhwarp   suff=.lhw act exec="lhwarp write 0"
Xclass anim     suff=.anim act exec=showanim view=showanim
Xclass gif      suff=.gif  act exec=virtgif  view=virtgif extr="shamsharp"
Xclass ilbm     offs=0,464F524D........494C424D act exec=M view=M edit=dpaint
Xclass text     offs=0,464F524D........46545854 act edit=excellence
Xclass prog     offs=0,000003f300000000 act view=htype edit=newzap
Xclass object   suff=.o
Xclass include  suff=.h
Xclass c_source suff=.c act exec=ced
Xclass script   suff=.sh
Xclass ascii    suff=.doc suff=.txt name=readme chars act view=more exec=more edit=ced
Xclass ""       default act view=htype edit=ced
X
Xalias v    "%n action -a view $n;more $n"
Xalias ed   "%n action -a edit $n;ced $n"
Xalias xt   "action extr"
END_OF_FILE
if test 1730 -ne `wc -c <'class.sh'`; then
    echo shar: \"'class.sh'\" unpacked with wrong size!
fi
# end of 'class.sh'
fi
if test -f 'globals.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'globals.c'\"
else
echo shar: Extracting \"'globals.c'\" \(4788 characters\)
sed "s/^X//" >'globals.c' <<'END_OF_FILE'
X
X/*
X * GLOBALS.C
X *
X * (c)1986 Matthew Dillon     9 October 1986
X *
X *    Most global variables.
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X * Version 5.00L by Urban Mueller 17-Feb-91
X *
X */
X
X#include "shell.h"
X
Xchar v_titlebar	[]="_titlebar";	/* Window title						*/
Xchar v_prompt	[]="_prompt";	/* your prompt (ascii command)		*/
Xchar v_hist		[]="_history";	/* set history depth (value)		*/
Xchar v_histnum	[]="_histnum";	/* set history numbering var		*/
Xchar v_debug	[]="_debug";	/* set debug mode					*/
Xchar v_verbose	[]="_verbose";	/* set verbose for source files		*/
Xchar v_stat		[]="_maxerr";	/* worst return value to date		*/
Xchar v_lasterr	[]="_lasterr";	/* return value from last comm.		*/
Xchar v_cwd		[]="_cwd";		/* current directory				*/
Xchar v_except	[]="_except";	/* "nnn;command"					*/
Xchar v_every	[]="_every";	/* executed before prompt			*/
Xchar v_passed	[]="_passed";	/* passed arguments to source file	*/
Xchar v_path		[]="_path";		/* search path for external commands*/
Xchar v_gotofwd	[]="_gtf";		/* set name for fwd goto name		*/
Xchar v_linenum	[]="_linenum";	/* name for forline line #			*/
Xchar v_lcd		[]="_lcd";		/* last current directory			*/
Xchar v_rxpath	[]="_rxpath";	/* path for .rexx commands			*/
Xchar v_hilite	[]="_hilite";	/* hilighting escape sequence		*/
Xchar v_scroll	[]="_scroll";	/* scroll jump in fast mode			*/
Xchar v_minrows	[]="_minrows";	/* minimum # of rows for fast scroll*/
Xchar v_result	[]="_result";	/* result from rxsend				*/
Xchar v_qcd		[]="_qcd";		/* file name for csh-qcd			*/
Xchar v_noreq	[]="_noreq";	/* turn off system requesters		*/
Xchar v_value	[]="_value";	/* return value of a function		*/
Xchar v_nobreak	[]="_nobreak";	/* disabling of ^C					*/
Xchar v_bground	[]="_bground";	/* started in background			*/
Xchar v_pipe		[]="_pipe";		/* path for pipes					*/
Xchar v_datefmt	[]="_datefmt";	/* format of dates					*/
Xchar v_ioerr	[]="_ioerr";	/* last secondary result			*/
Xchar v_abbrev	[]="_abbrev";	/* disable command abbreviations	*/
X
Xstruct HIST *H_head, *H_tail;	/* HISTORY lists */
X
Xstruct PERROR Perror[]= {	/* error code->string */
X	103,	"Insufficient free storage",
X	105,	"Task table full",
X	120,	"Argument line invalid or too long",
X	121,	"File is not an object module",
X	122,	"Invalid resident library during load",
X	201,	"No default directory",
X	202,	"Object in use",
X	203,	"Object already exists",
X	204,	"Directory not found",
X	205,	"Object not found",
X	206,	"Bad stream name",
X	207,	"Object too large",
X	209,	"Action not known",
X	210,	"Invalid stream component name",
X	211,	"Invalid object lock",
X	212,	"Object not of required type",
X	213,	"Disk not validated",
X	214,	"Disk write protected",
X	215,	"Rename across devices",
X	216,	"Directory not empty",
X	217,	"Too many levels",
X	218,	"Device not mounted",
X	219,	"Seek error",
X	220,	"Comment too long",
X	221,	"Disk full",
X	222,	"File delete protected",
X	223,	"File write protected",
X	224,	"File read protected",
X	225,	"Not a DOS disk",
X	226,	"No disk in drive",
X
X /* custom error messages */
X
X	500,	"Bad arguments",
X	501,	"Label not found",
X	502,	"Must be within source file",
X	503,	"Syntax Error",
X	504,	"Redirection error",
X	505,	"Pipe error",
X	506,	"Too many arguments",
X	507,	"Destination not a directory",
X	508,	"Cannot mv a filesystem",
X	509,	"Error in command name",
X	510,	"Bad drive name",
X	511,	"Illegal number",
X	512,	"Out of memory",
X	513,	"User interrupt",
X	0,	NULL
X};
X
Xchar **av;					/* Internal argument list				*/
XFILE *Src_base[MAXSRC];		/* file pointers for source files		*/
Xlong  Src_pos[MAXSRC];		/* seek position storage for same		*/
Xshort Src_if[MAXSRC];		/* the if level at batch file start		*/
Xshort Src_abort[MAXSRC];	/* abort this batch file				*/
Xchar If_base[MAXIF];		/* If/Else stack for conditionals		*/
Xint H_len, H_tail_base;		/* History associated stuff				*/
Xint H_stack;				/* AddHistory disable stack				*/
Xint E_stack;				/* Exception disable stack				*/
Xint Src_stack, If_stack;	/* Stack Indexes						*/
Xint forward_goto;			/* Flag for searching for foward lables	*/
Xint ac;						/* Internal argc						*/
Xint max_ac=256;				/* Maximum # of args (increasable)		*/
Xint debug;					/* Debug mode							*/
Xint disable;				/* Disable com. execution (conditionals)*/
Xint Verbose;				/* Verbose mode for source files		*/
Xint Lastresult;				/* Last return code						*/
Xint Exec_abortline;			/* flag to abort rest of line			*/
Xint Quit;					/* Quit flag							*/
Xchar stdin_redir;			/* stdin is redirected					*/
Xchar stdout_redir;			/* stdout is redirected					*/
Xchar *MyMem;
Xstruct Process *Myprocess;
Xstruct CommandLineInterface *Mycli;
Xint S_histlen = 20;			/* Max # history entries				*/
X
Xunsigned int options;
Xchar Buf[280], confirmed;
XCLASS *CRoot, *LastCRoot;
X
Xlong IoError;
END_OF_FILE
if test 4788 -ne `wc -c <'globals.c'`; then
    echo shar: \"'globals.c'\" unpacked with wrong size!
fi
# end of 'globals.c'
fi
if test -f 'lmakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lmakefile'\"
else
echo shar: Extracting \"'lmakefile'\" \(817 characters\)
sed "s/^X//" >'lmakefile' <<'END_OF_FILE'
X######################################################################
X# Makefile to build Shell 5.10L under Lattice C 5.10
X# NOTE: char's are UNSIGNED by default, and the executable's calld 'zsh'
X
XFLAGS  = -ms -v -d3 -cu -cs -rr -O
XOBJ=run.o main.o comm1.o comm2.o comm3.o execom.o set.o sub.o globals.o rawcon.o
X
X# -ms = short code optimize     -v  = no stack overflow check
X# -d0 = no debug info           -cu = unsigned chars by default
X# -cs = one copy per string     -m3 = code for 68030
X# -H  = read precompiled header -ph = write precompiled header
X# -rr = register arguments       ND = strip debug information
X
Xzsh: $(OBJ)
X	BLINK lib:cres.o $(OBJ) LIB lib:lcr.lib lib:amiga.lib TO zsh NOICONS ND
X
Xshell.syms: shell.h proto.h
X	lc -cu -ph -oshell.syms syms.c
X
X$(OBJ): shell.syms
X	lc $(FLAGS) -HShell.syms $*.c
END_OF_FILE
if test 817 -ne `wc -c <'lmakefile'`; then
    echo shar: \"'lmakefile'\" unpacked with wrong size!
fi
# end of 'lmakefile'
fi
if test -f 'main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'main.c'\"
else
echo shar: Extracting \"'main.c'\" \(8629 characters\)
sed "s/^X//" >'main.c' <<'END_OF_FILE'
X/*
X * MAIN.C
X *
X * Matthew Dillon, 24 Feb 1986
X * (c)1986 Matthew Dillon     9 October 1986
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X * Version 5.00L by Urban Mueller 17-Feb-91
X *
X */
X
X#include "shell.h"
X
Xvoid breakreset(void);
Xstruct Window *getwindow (void);
Xstruct RootNode2x *RootNode;
X
Xchar shellname[]   ="CShell V5.10L";
Xchar shellversion[]="510";
Xchar shellvers[]   ="5.10";
Xchar shellv   []   ="\0$VER: csh 5.1";
Xchar shellctr []   ="CshCounter";
Xchar shellres []   ="CshResident";
X
Xstatic void add_residents(void);
X
Xchar *oldtitle;
Xchar trueprompt[100];
Xchar Inline[260];
Xstruct IntuitionBase *IntuitionBase;
Xstruct Window *Win;
Xstruct ArpBase *ArpBase;
Xint    oldtaskpri=-999;
X
Xextern struct DosLibrary *DOSBase;
X
Xstatic char *defset[]={
X	v_histnum,  "0",
X	v_titlebar, shellname,
X	v_hist,     "50",
X	v_lasterr,  "0",
X	v_stat,     "0",
X	v_path,     "RAM:,RAM:c,df0:c,df1:c,sys:system,csh:,s:",
X	v_rxpath,   "REXX:",
X	v_scroll,   "3",
X	v_minrows,  "34",
X	v_hilite,   "c7",
X	v_lcd,      "",
X	v_qcd,      "csh:csh-qcd",
X	"_terminal","",
X	"_man",     "csh:csh.doc",
X	"_insert",  "1",
X	"_version", shellversion,
X	NULL,       NULL
X};
X
Xstatic char *defalias[]={
X	"cls",  "echo -n ^l",
X	"dswap","cd $_lcd",
X	"exit", "endcli;quit",
X	"cdir", "%q cd $q; cls; dir",
X	"q",    "quit",
X	"manlist", "sea -nl $_man \"    \"",
X	NULL,   NULL
X};
X
Xextern struct Library *DosBase;
X
X
Xmain(argc, argv)
Xchar *argv[];
X{
X	static ROOT locals;
X	int i;
X	char buf[10];
X	struct Window *getwindow();
X	char nologin=0;
X#ifdef AZTEC_C
X	extern int Enable_Abort;
X	Enable_Abort = 0;
X#endif
X
X	MyMem=salloc(4);
X
X	if( argc==0 ) {              /* Prevent starting from workbench */
X		Delay(120);
X		exit(0);
X	}
X
X	RootNode=(void *)DOSBase->dl_Root;
X	push_locals( &locals );
X
X	initmap();
X	init_mbase();
X
X	if(!(ArpBase=(struct ArpBase *)OpenLibrary("arp.library",34L)))
X		{ printf("No arp library\n"); exit(0); }
X
X	IntuitionBase=(struct IntuitionBase *)ArpBase->IntuiBase;
X
X	if( ArpBase->DosBase->lib_Version >= 36 )
X		o_kick20=1;
X	set_var( LEVEL_SET, "_kick2x", (o_kick20) ? "1" : "0" );
X
X	if( !IsInteractive(Input()))
X		o_bground=1;
X	set_var( LEVEL_SET, v_bground, (o_bground) ? "1" : "0" );
X
X
X	Forbid();
X	i=0;
X	if (Getenv(shellctr,buf,10L)) i=atoi(buf);
X	if (Getenv(shellres,buf,10L)) o_resident=1;
X	sprintf(buf, "%d", i+1);
X	Setenv(shellctr, buf);
X	Permit();
X
X#ifdef isalphanum
X	for( i='a'; i<='z'; i++ )
X		isalph[i]=1;
X	for( i='A'; i<='Z'; i++ )
X		isalph[i]=1;
X	for( i='0'; i<='9'; i++ )
X		isalph[i]=1;
X	isalph['_']=1;
X#endif
X
X#ifdef AZTEC_C
X	stdin->_flags	|= _IONBF;	/* make sure we're set as an unbuffered tty */
X	stdout->_flags	|= _IONBF;	/* in case of redirection in .login */
X	Close( (BPTR)_devtab[2].fd);
X	_devtab[2].mode |= O_STDIO;
X	_devtab[2].fd = _devtab[1].fd;	/* set stderr to Output() otherwise */
X					/* don't work with aux driver */
X#else
X	/* if( setvbuf( stdout,NULL,_IOLBF,BUFSIZ )) exit(20); */
X	/* setnbf( stdout ); */
X	/* Close( _ufbs[2] ); */
X	/*_ufbs[2]=_ufbs[1]; */
X	/* setnbf( stderr ); */
X#endif
X
X	Myprocess = (struct Process *)FindTask(0L);
X	Mycli=(struct CommandLineInterface *)((long)Myprocess->pr_CLI << 2);
X
X	if( !o_nowindow && (Win=getwindow()) && IsInteractive(Input())) {
X		oldtitle=(char *)(Win->Title);
X		set_menu();
X	}
X
X	sprintf(buf,"%ld",Myprocess->pr_TaskNum);
X	set_var(LEVEL_SET, "_clinumber", buf);
X
X	seterr(0);
X	if (Myprocess->pr_CurrentDir == NULL)
X		do_cd("x :");
X	else
X		do_pwd(NULL);
X
X	o_nowindow= 1;
X
X	set_var(LEVEL_SET,v_prompt, (IsInteractive(Input())) ? "%c%p> ":"");
X	for( i=0; defset[i]; i+=2 )
X		set_var( LEVEL_SET, defset[i], defset[i+1] );
X	for( i=0; defalias[i]; i+=2 )
X		set_var( LEVEL_ALIAS, defalias[i], defalias[i+1] );
X
X	o_nowindow= 0;
X	o_internal= 1;
X
X	for (i = 1; i < argc; ++i) {
X		if (*argv[i]=='-') {
X			char *str=argv[i]+1;
X			for( ; *str; str++ ) {
X				switch( *str) {
X				case 'k': set_var(LEVEL_SET,v_nobreak,"1"); break;
X				case 'i': if( str[1]=='0' ) str++, o_internal=0; break;
X				case 'r': add_residents(); break;
X				case 'v': Verbose=1; set_var(LEVEL_SET,v_verbose,"hs"); break;
X				case 'n': nologin=TRUE;    break;
X				case 'b': oldtaskpri=Myprocess->pr_Task.tc_Node.ln_Pri;
X				          SetTaskPri( &Myprocess->pr_Task, -1 ); break;
X				case 'f': oldtaskpri=Myprocess->pr_Task.tc_Node.ln_Pri;
X				          SetTaskPri( &Myprocess->pr_Task,  1 ); break;
X				case 'c': Inline[0] = ' '; Inline[1] = '\0';
X				          while (++i < argc)
X				              { strcat(Inline,argv[i]); strcat(Inline," "); }
X				          execute(Inline);
X				          main_exit(Lastresult); break;
X				case 'a': o_nowindow= o_noraw= 1; 
X				          set_var( LEVEL_SET, v_hilite, "" ); break;
X				case 't': o_nowindow= o_vt100= o_nofastscr= 1;
X				          set_var( LEVEL_SET, v_hilite, "r" );
X				          set_var( LEVEL_SET, v_noreq, "1" );
X				          set_var( LEVEL_SET, "_terminal", "1" );
X				          set_var( LEVEL_ALIAS, "cls", "e -n ^[[0\\;0H^[[J" );
X				          break;
X				case 's': if( o_kick20 ) {
X				              struct RootNode2x *root=(void *)DOSBase->dl_Root;
X				              root->rn_Flags|=1<<24;
X				          } break;
X				}
X			}
X		} else {
X			sprintf (Inline, "source %s",argv[i]);
X			execute (Inline);
X		}
X	}
X
X	if (!nologin && exists("S:.login")) execute("source S:.login");
X
X	for (;;) {
X		if (breakcheck())
X#ifdef AZTEC_C
X		while (WaitForChar(Input(), 100L) || stdin->_bp < stdin->_bend)
X#else
X		while (WaitForChar(Input(), 100L) || stdin->_rcnt != stdin->_wcnt )
X#endif
X			gets(Inline);
X		clearerr(stdin);  /* prevent acidental quit */
X		exec_every();
X		update_sys_var(v_titlebar);
X		update_sys_var(v_prompt);
X		breakreset();
X#if RAW_CONSOLE
X		if (Quit || !rawgets(Inline, disable ? "_ " : trueprompt)) main_exit(0);
X#else
X		printf("%s", disable ? "_ " : trueprompt);
X		fflush(stdout);
X		if (Quit || !gets(Inline)) main_exit(0);
X#endif
X		breakreset();
X		if (*Inline) exec_command(Inline);
X	}
X}
X
Xvoid
Xmain_exit(n)
X{
X	int i;
X	char buf[10];
X
X	Getenv(shellctr,buf,10L);
X	i=atoi(buf);
X	sprintf(buf,"%d",i-1);
X	Setenv(shellctr, buf);
X	if( oldtitle )
X		SetWindowTitles(Win,oldtitle,(char *)-1);
X	if( oldtaskpri != -999 )
X		SetTaskPri(&Myprocess->pr_Task,oldtaskpri);
X	for (i=1; i<MAXMYFILES; i++) myclose(i);
X	remove_menu();
X	CloseLibrary((struct Library *)ArpBase);
X	exit(n);
X}
X
Xint
Xbreakcheck()
X{
X	return !o_nobreak && SetSignal(0L,0L) & SIGBREAKF_CTRL_C;
X}
X
Xvoid
Xbreakreset()
X{
X	SetSignal(0L, SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D);
X}
X
Xdobreak()
X{
X	if (breakcheck()) { printf("^C\n"); return(1); }
X	return(0);
X}
X
X/* this routine causes manx to use this Chk_Abort() rather than it's own */
X/* otherwise it resets our ^C when doing any I/O (even when Enable_Abort */
X/* is zero).  Since we want to check for our own ^C's			 */
X
Xlong
XChk_Abort()
X{
X	return(0);
X}
X
Xvoid
X_wb_parse()
X{
X}
X
Xdo_howmany()
X{
X	char buf[10];
X
X	Getenv(shellctr, buf, 10L);
X	printf("Shell(s) running: %s\n",buf);
X	return 0;
X}
X
Xstatic struct Window *
Xgetwindow()
X{
X	struct InfoData *infodata;
X	struct Window *win;
X	long args[8];
X
X	if( o_nowindow )
X		return NULL;
X	infodata=(void *)SAllocMem((long)sizeof(struct InfoData),MEMF_CLEAR|MEMF_PUBLIC);
X	args[0]=(long)infodata >> 2;
X	Write(Output(),"",1);     /*    make window appear */ 
X	SendPacket(ACTION_DISK_INFO,args,(void *)Myprocess->pr_ConsoleTask);
X	win=(struct Window *)infodata->id_VolumeNode;
X	FreeMem(infodata,(long)sizeof(struct InfoData));
X	if( win==NULL )
X		o_nowindow=1;
X	newwidth();
X	return win;
X}
X
X
Xextern struct DosLibrary *DOSBase;
X
Xstruct ResidentList {
X	BPTR rl_Next;
X	LONG rl_UseCount;
X	BPTR rl_SegList;
X	char rl_SegName[1];
X};
X
X
Xstatic void
Xadd_residents()
X{
X	char buf[80], *g, *p, c;
X	struct RootNode *Node;
X	struct DosInfo  *Info;
X	struct ResidentList *res;
X	struct ResidentProgramNode *rpn;
X
X	if( o_kick20 || ArpBase->ResidentPrgList )
X		return;
X
X	Forbid(); 
X	Node=(struct RootNode *)DOSBase->dl_Root;
X	Info=(struct DosInfo  *)(Node->rn_Info*4);
X	res=(struct ResidentList *)((long)Info->di_NetHand*4);
X
X	for( ; res; res=(struct ResidentList *)((long)res->rl_Next*4) ) {
X		g=res->rl_SegName, p=buf;
X		for( c=*g++; c>0; --c ) *p++=*g++;
X		*p=0;
X		if( res->rl_UseCount>=0 )
X			res->rl_UseCount++;
X		else
X			continue;
X		AddResidentPrg( res->rl_SegList, buf);
X		for(rpn=ArpBase->ResidentPrgList; rpn; rpn=rpn->rpn_Next)
X			if( rpn->rpn_Segment==res->rl_SegList )
X				rpn->rpn_Usage++;
X	}
X	Permit();
X}
X
X#ifndef AZTEC_C
X
Xchar *
Xrindex(char *s, int c)
X{
X	char *r;
X
X	for( r=NULL; *s; s++ )
X		if( *s==c )
X			r=s;
X	return r;
X}
X
Xint
Xsetenv( char *var, char *val )
X{
X	char buf[300];
X	sprintf(buf, "%s=%s", var, val );
X	return putenv( buf );
X}
X
Xint
Xchkabort(void)
X{
X	return 0;
X}
X
X#endif
END_OF_FILE
if test 8629 -ne `wc -c <'main.c'`; then
    echo shar: \"'main.c'\" unpacked with wrong size!
fi
# end of 'main.c'
fi
if test -f 'makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile'\"
else
echo shar: Extracting \"'makefile'\" \(610 characters\)
sed "s/^X//" >'makefile' <<'END_OF_FILE'
X######################################################################
X# Makefile to build Shell 5.10  under Aztec C 5.0d
X# make sure you use 5.0d or above, as setenv() has changed
X# NOTE: Our chars are UNSIGNED by default, and the executable's called zsh
X
XOBJ=run.o main.o comm1.o comm2.o comm3.o execom.o set.o sub.o globals.o rawcon.o
XINC=shell.syms
X
XFLAGS	= -pp -wurp -ssr
XDEBUG	= -bs
XPRECOM	= -hiShell.syms
X
Xzsh:  makefile shell.syms $(OBJ)
X	ln -t +q -m -g -o zsh $(OBJ) -larpl -lc
X
Xshell.syms : shell.h proto.h
X	cc -pp -hoShell.syms shell.h -DAZTEC_C
X
X$(OBJ): $(INC)
X	cc $(DEBUG) $(FLAGS) $(PRECOM) $*.c
END_OF_FILE
if test 610 -ne `wc -c <'makefile'`; then
    echo shar: \"'makefile'\" unpacked with wrong size!
fi
# end of 'makefile'
fi
if test -f 'menu.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'menu.sh'\"
else
echo shar: Extracting \"'menu.sh'\" \(980 characters\)
sed "s/^X//" >'menu.sh' <<'END_OF_FILE'
X# This installs an intuition menu with all editing keys
X
Xmenu -n Move \
X "Left         CursL",\
X "Right        CursR",\
X "WordLeft   S-CursL",\
X "WordRight  S-CursR",\
X "BegOfLine       ^A",^a\
X "EndOfLine       ^E",^e
X
Xmenu  Delete \
X "Left         BkSpc",^h\
X "Right          Del",\177\
X "WordLeft        ^W",^[^h\
X "WordRight  ESC-Del",^[\177\
X "To BOL          ^B",^[x^h\
X "To EOL          ^K",^[x\177\
X "Line            ^X",^[d
X
Xmenu History \
X "Back         CursU",\
X "Forward      CursD",\
X "Start      S-CursU",\
X "End        S-CursD",\
X "Complete     ESC-!",^[!\
X "Get tail        ^T",^T
X
Xmenu Complete \
X "One            TAB",^I\
X "Partial      S-TAB",\
X "All        ESC-TAB",^[^I\
X "QuickCD      ESC-c",^[c\
X "LastCD       ESC-~",^[~
X
Xmenu Execute \
X "Now         RETURN",^M\
X "+Hist   ESC-RETURN",^[^M\
X "Not             ^N",^N\
X "Exit            ^\",
X
Xmenu Misc \
X "Undo            ^U",^U\
X "Repeat          ^R",\
X "Retype          ^L",^L\
X "Ins/Ovr      ESC-i",^[i
X
END_OF_FILE
if test 980 -ne `wc -c <'menu.sh'`; then
    echo shar: \"'menu.sh'\" unpacked with wrong size!
fi
# end of 'menu.sh'
fi
if test -f 'proto.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'proto.h'\"
else
echo shar: Extracting \"'proto.h'\" \(5741 characters\)
sed "s/^X//" >'proto.h' <<'END_OF_FILE'
X/* main.c */
Xint main(int argc, char **argv);
Xvoid main_exit(int n);
Xint breakcheck(void);
Xint dobreak(void);
Xlong Chk_Abort(void);
Xvoid _wb_parse(void);
Xint do_howmany(void);
Xvoid breakreset(void);
X
X/* comm1.c */
Xint do_sleep(void);
Xint do_protect(void);
Xint do_filenote(void);
Xint do_cat(void);
Xvoid get_drives(char *buf);
Xchar *drive_name(char *name);
Xchar *oneinfo( char *name, int function );
Xint do_info(void);
Xint do_dir(void);
Xint do_quit(void);
Xint do_echo(void);
Xint do_source(char *str );
Xint do_pwd(char *str );
Xint do_cd(char *str );
Xchar *quick_cd( char *buf, char *name, int repeat );
Xint do_mkdir(void);
Xint do_mv(void);
Xint all_args(int (*action)(char *str), int dirsflag);
Xint do_search(void);
Xint do_rm(void);
Xint do_history(void);
Xint do_mem(void);
Xint do_forline(void);
Xint do_fornum(void);
Xint do_foreach(void);
Xint do_forever(char *str);
Xint do_window(void);
Xchar *dates(struct DateStamp *dss, int flags);
Xint do_date(void);
X
X/* comm2.c */
Xint do_abortline(void);
Xint do_return(void);
Xint do_strhead(void);
Xint do_strtail(void);
Xint do_if(char *garbage, int com);
Xint do_label(void);
Xint do_goto(void);
Xint do_inc(char *garbage, int com);
Xint do_input(void);
Xint do_ver(void);
Xint do_ps(void);
Xint do_copy(void);
Xint do_touch(void);
Xint do_addbuffers(void);
Xint do_relabel(void);
Xint do_diskchange(void);
Xint dofunc(int id, char **av, int ac);
Xint do_error( void );
X
X/* comm3.c */
Xint do_tee(void);
Xint do_head(char *garbage, int com);
Xvoid man(struct __stdio *f, char *s);
Xint do_man(void);
Xint do_assign(void);
Xchar **expand_devs(void);
Xint do_join(void);
Xint do_strings(void);
Xint do_open(void);
Xint do_close(void);
Xvoid myclose(int n);
Xint do_fileslist(void);
Xlong extOpen(char *name, long mode);
Xvoid extClose(long fh);
Xint do_basename(void);
Xint do_tackon(void);
Xint do_resident(void);
Xint loadres(char *s);
Xint do_truerun(char *avline, int backflag);
Xint exists(char *name);
Xint do_aset(void);
Xint do_htype(void);
Xint do_stack(void);
Xint do_fault(void);
Xint eval_rpn(char **av, int ac, int flag);
Xint do_rpn(char *garbage, int ifflag);
Xint do_path(void);
Xint do_pri(void);
Xint do_strleft(void);
Xint do_strright(void);
Xint do_strmid(void);
Xint do_strlen(void);
Xint myatoi(char *s, int mmin, int mmax);
Xint unlatoi(char *s);
Xint posatoi(char *s);
Xint do_fltlower(void);
Xint do_fltupper(void);
Xint do_linecnt(void);
Xint do_uniq(void);
Xint do_rxsend(char *avline);
Xint do_rxrec(void);
Xint do_rxreturn(void);
Xint do_waitport(void);
Xint do_ascii(void);
Xvoid appendslash(char *path);
Xint do_whereis(void);
Xint do_usage(void);
Xint do_menu(void);
Xvoid remove_menu(void);
Xvoid set_menu(void);
Xint do_getenv(void);
Xint do_setenv(void);
Xchar **read_file(struct __stdio *file, int *ac);
Xvoid free_file(char **ptr);
Xint do_qsort(void);
Xint do_truncate(void);
Xint do_split(void);
Xint do_action( char *argline );
Xint do_class( char *avline );
Xint do_readfile( void );
X
X/* execom.c */
Xvoid *mymalloc(int len);
Xint exec_command(char *base);
X#ifndef isalphanum
Xint isalphanum(char c);
X#endif
Xchar *exec_function(char *str, char **fav, int fac);
Xint do_help(void);
Xvoid exec_every(void);
Xvoid show_usage(char *str);
Xint do_exec(char *str);
Xint interactive(void);
Xchar *a0tospace(char *str);
Xint execute( char *str );
Xchar *find_internal(char *str);
X
X/* sub.c */
Xchar *getclass(char *file);
Xvoid seterr(int err);
Xchar *next_word(char *str);
Xchar *compile_av(char **av, int start, int end, char delim, int quote);
Xvoid Free(void *ptr);
Xvoid add_history(char *str);
Xchar *get_history(char *ptr, int echo);
Xvoid replace_head(char *str);
Xvoid pError(char *str);
Xint ierror(char *str, int err);
Xchar *ioerror(int num);
Xstruct DPTR *dopen(char *name, int *stat);
Xint dclose(struct DPTR *dp);
Xint isdir(char *file);
Xvoid free_expand(char **av);
Xchar **expand(char *base, int *pac);
Xchar *strupr(char *s);
Xchar *strlwr(char *s);
Xint compare_ok(char *wild, char *name, int casedep);
Xvoid expand_all(char *name, struct __stdio *file);
Xint cmp(struct file_info *s1, struct file_info *s2);
Xint sizecmp(struct file_info *s1, struct file_info *s2);
Xint datecmp(struct file_info *s1, struct file_info *s2);
Xint classcmp(struct file_info *s1, struct file_info *s2);
Xint numcmp( struct file_info *s1, struct file_info *s2 );
Xvoid QuickSort(char **av, int n);
Xvoid DirQuickSort(char **av,int n,int (*func)(struct file_info *,struct file_info *), int rev, int fac);
Xint filesize(char *name);
Xchar **and(char **av1, int ac1, char **av2, int ac2, int *ac, int base);
Xchar **without(char **av1, int ac1, char **av2, int ac2, int *ac, int base);
Xchar **or(char **av1, int ac1, char **av2, int ac2, int *ac, int base);
Xvoid clear_archive_bit(char *name);
Xchar *itoa( int i );
Xchar *itok( int i );
Xchar *getaction( char *class, char *action );
Xint doaction( char *file, char *action, char *args );
Xvoid *salloc( int len );
Xvoid *SAllocMem( long size, long req );
Xvoid setioerror( int err );
X
X/* set.c */
Xvoid init_mbase(void);
Xvoid set_var(int level, char *name, char *str);
Xvoid update_sys_var( char *name );
Xvoid set_var_n(int level, char *name, char *str, int n);
Xchar *get_var(int level, char *name);
Xvoid unset_level(int level);
Xvoid unset_var(int level, char *name);
Xint do_unset_var(char *str, int level);
Xint do_set_var(char *command, int level);
Xvoid push_locals( struct VRoot *newroot );
Xvoid pop_locals( void );
Xint do_local(void);
X
X/* rawconsole.c */
Xint newwidth(void);
Xvoid initmap(void);
Xchar *rawgets(char line[], char prompt[]);
Xvoid prepscroll(int fromtee);
Xvoid quickscroll(void);
Xvoid setrawcon( long flag, int ievent );
Xint do_keymap( void );
X
X/* run.c */
Xint do_run(char *str);
Xchar *dofind(char *cmd, char *ext, char *buf, char *path);
X
Xchar *index(char *_s, int _c);
Xchar *rindex(char *_s, int _c);
Xint setenv(char *var, char *val);
END_OF_FILE
if test 5741 -ne `wc -c <'proto.h'`; then
    echo shar: \"'proto.h'\" unpacked with wrong size!
fi
# end of 'proto.h'
fi
if test -f 'run.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'run.c'\"
else
echo shar: Extracting \"'run.c'\" \(4740 characters\)
sed "s/^X//" >'run.c' <<'END_OF_FILE'
X
X/*
X * RUN.C
X *
X * (c)1986 Matthew Dillon     9 October 1986
X *
X *    RUN   handles running of external commands.
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X * Version 5.00L by Urban Mueller 17-Feb-91
X *
X */
X
X#include "shell.h"
X
Xint MySyncRun( char *com, char *args, BPTR in, BPTR out );
Xint echofunc(void);
X
Xint
Xdo_run( char *str )
X{
X	int retcode;
X	char buf[200]; /* enough space for 100 char cmd name + path stuff */
X	char *path, *argline, *copy, *ext, *end;
X
X	if( !*av[0] )
X		return 0;
X
X	if( (retcode=echofunc())>=0 )
X		return retcode;
X
X	a0tospace( av[0] );                                 /* allow "com mand" */
X
X	argline=compile_av(av, 1, ac, ' ', 1);
X	strcat(argline,"\n");
X
X	if (strlen(av[0]) > 100) { ierror(NULL,509); return -1; }
X
X	if( !strcmp(av[0],".bra") || !strcmp(av[0],".ket") ) return 0;
X
X	if( ac==1 && isdir(av[0])) {
X		sprintf(buf,"cd %s",av[0]);
X		return execute( buf );
X	}
X
X	sprintf(buf,"res_%s",BaseName(av[0]));              /* delayed residents */
X	if (o_resident && Getenv(buf, buf+100, 90L) && loadres(av[0]))
X		Setenv(buf,NULL);
X
X	if( (retcode=MySyncRun(av[0],argline,0L,0L))>=0 )   /* AmigaDOS path */
X		goto done2;
X
X	IoError=IoErr();
X	if( (IoError==218 || IoError==225 || IoError==226) && index(av[0],':')) {
X		ierror( av[0], IoError );
X		return 20;
X	}
X
X	strcpy(buf,"Execute ");
X	if (path = dofind(av[0],"",buf+8,v_path)) {             /* shell path    */
X		if((retcode = MySyncRun(path,argline,0L,0L))>=0)
X			goto done2;
X		else {
X			struct DPTR *dp;
X			int stat;
X			if(dp=dopen(path,&stat)) {
X				stat= !stat && dp->fib->fib_Protection & FIBF_SCRIPT;
X				dclose(dp);
X				if( stat ) {
X					execute(buf);
X					return 0;
X				}
X			}
X		}
X	}
X
X	if(!(end=rindex(av[0],'.'))) end="";               /* automatic sourcing */
X	ext=strcmp(end,".sh") ? ".sh" : "";
X	if (path = dofind(av[0],ext,buf,v_path)) {
X		av[1] = buf;
X		copy = salloc(strlen(str)+3);
X		sprintf(copy,"x %s",str);
X		retcode = do_source(copy);
X		goto done;
X	}
X
X	copy=salloc(strlen(av[0])+strlen(argline)+5);
X	sprintf(copy,"%s %s",av[0],argline);
X
X	ext=strcmp(end,".rexx") ? ".rexx" : "";           /* automatic rx-ing   */
X	if( path = dofind(av[0], ext, buf, v_rxpath )) {
X		if( (retcode=MySyncRun("rx",copy,0L,0L)) >=0 ) goto done;
X		if (path = dofind("rx","",buf,v_path)) {
X			retcode = MySyncRun(path,copy,0L,0L);
X			goto done;
X		}
X	}
X
X	if( !doaction(av[0],"exec",argline)) {
X		retcode=0;
X		goto done;
X	}
X
X	retcode=-1;
X	fprintf(stderr,"Command not found %s\n",av[0]);
X
Xdone:
X	free( copy );
Xdone2:
X	setioerror( IoErr() );
X	free( argline );
X	return retcode;
X}
X
Xstruct Segment {
X	BPTR NextEntry;
X	LONG UseCount;
X	BPTR SegPtr;
X	BSTR SegName;
X};
X
Xint
XMySyncRun( char *com, char *args, BPTR in, BPTR out )
X{
X	struct Segment *seg;
X	int ret;
X	char buf2[200], *buf=buf2;
X	long oldname;
X
X#ifdef KICK20
X	if( o_kick20 ) {
X		oldname = (long)Mycli->cli_CommandName;
X
X		while( (long)buf & 3 ) buf++;
X		buf[0] = strlen( com );
X		strncpy(buf+1,com,80);
X
X		Forbid();
X		seg=FindSegment( (UBYTE *)com, NULL, 0 );
X		Permit();
X		if( seg ) {
X			Mycli->cli_CommandName = (long)buf/4;
X			seg->UseCount++;
X
X			ret=RunCommand(seg->SegPtr, Mycli->cli_DefaultStack,
X			                           (UBYTE *)args, strlen(args));
X			seg->UseCount--;
X			Mycli->cli_CommandName = (long)oldname;
X			return ret;
X		}
X
X		if( o_internal ) {
X			Forbid();
X			seg=FindSegment( (UBYTE *)com, NULL, 1 );
X			Permit();
X			if( seg ) {
X				Mycli->cli_CommandName = (long)buf/4;
X
X				ret=RunCommand(seg->SegPtr, Mycli->cli_DefaultStack,
X				                           (UBYTE *)args, strlen(args));
X				Mycli->cli_CommandName = (long)oldname;
X				return ret;
X			}
X		}
X
X	}
X#endif
X
X	if( !Strcmp(BaseName(com), "Execute")) {
X		sprintf(buf2,"%s %s",com,args);
X		Execute(buf2,0,0);
X		return 0;
X	}
X
X	if( (ret= SyncRun( com, args, in, out ))>=0 )
X		return ret;
X
X	return ret;
X}
X
X#if 0
Xint
Xdo_which( char *str )
X{
X	char *got, *com=av[1];
X
X	if( get_var(LEVEL_ALIAS,com) ) {
X		printf("Shell Alias '%s'\n",com);
X		return 0;
X	}
X
X	if( *(got=find_internal( com ))>1 ) {
X		printf("Shell Internal '%s'\n",got);
X		return 0;
X	}
X
X
X
X	printf( "Not found\n" );
X	return 20;
X}
X#endif
X
X
Xchar *
Xdofind( char *cmd, char *ext, char *buf, char *path)
X{
X	char *ptr, *s=path, *ret=NULL;
X
X	Myprocess->pr_WindowPtr = (APTR)(-1);
X	sprintf(buf,"%s%s",cmd,ext);
X	if (exists(buf)) {
X		ret=buf;
X		goto exit;
X	}
X	if (BaseName(buf)==buf) {
X		if( *path=='_' )
X			s = get_var(LEVEL_SET, path);
X		while (*s) {
X			for (ptr=buf; *s && *s!=','; ) *ptr++ = *s++;
X			if( ptr[-1]!=':' && ptr[-1]!='/')
X				*ptr++='/';
X			sprintf(ptr, "%s%s", cmd, ext);
X			if (exists(buf)) {
X				ret=buf;
X				goto exit;
X			}
X			if (*s) s++;
X		}
X	}
Xexit:
X	Myprocess->pr_WindowPtr = (APTR)o_noreq;
X	return ret;
X}
END_OF_FILE
if test 4740 -ne `wc -c <'run.c'`; then
    echo shar: \"'run.c'\" unpacked with wrong size!
fi
# end of 'run.c'
fi
if test -f 'sample.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sample.sh'\"
else
echo shar: Extracting \"'sample.sh'\" \(1100 characters\)
sed "s/^X//" >'sample.sh' <<'END_OF_FILE'
X# first a few useful aliases
Xal d   "dir -hq"  # hides .info and block lengths
Xal lst "ls -t"    # sorts by access time
Xal lsl "ls -l"    # sorts by length
X
X# sc searches *.c, even 'sc -c main()' works
Xal sc "%a search @pickopts( $a ) *.c @pickargs( $a )
X
X# edf edits a function in CygnusEd if the name starts in the first column:
Xal edf "%func set b \"\";search -afl *.c $func | inp b;\
X if $b;split b file line;ed $file;waitforport rexx_ced;\
X  inc line 1;rxs rexx_ced \"jump to file \"$file \"jumpto \"$line\" 0\";\
X else;\
X  echo Not found;\
X endif
X
X# this aliases suppress wild card expansion for certain commands
Xal zoo     "*a Zoo $a
Xal lharc   "*a Lharc $a
Xal lz      "*a Lz $a
Xal newlist "*a Newlist $a
X
X# pushd pushes the current directory on a stack
X# popd  retrieves it from there
Xset stk ""
Xal pushd   "set stk $_cwd @subwords( $stk 1 10 )
Xal popd    "\\cd @first( $stk );set stk @subwords( $stk 2 10 )
X
X# this one will show all pictures, the newest first
Xal newpix  "ls -nt | forline i STDIN \"ShowIFF $i
X
X# shift-arrow-up will retrieve an abbreviated line from history
Xkeymap 0 768=24
END_OF_FILE
if test 1100 -ne `wc -c <'sample.sh'`; then
    echo shar: \"'sample.sh'\" unpacked with wrong size!
fi
# end of 'sample.sh'
fi
if test -f 'set.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'set.c'\"
else
echo shar: Extracting \"'set.c'\" \(7922 characters\)
sed "s/^X//" >'set.c' <<'END_OF_FILE'
X
X/*
X * SET.C
X *
X * (c)1986 Matthew Dillon     9 October 1986
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X * Version 5.00L by Urban Mueller 17-Feb-91
X *
X */
X
X#include "shell.h"
X
Xstatic char *sys_expand( char *str, char *t );
Xstatic void set_sys_var( char *name );
X
X#define MAXLEVELS (4+MAXSRC)
X
XROOT _Mbase[MAXLEVELS], *Mbase[ MAXLEVELS ];
X
Xvoid
Xinit_mbase(void)
X{
X	int i;
X	for( i=0; i<MAXLEVELS; i++ )
X		Mbase[i]=&_Mbase[i];
X}
X
Xvoid
Xset_var( int level, char *name, char *str )
X{
X	NODE **first, *node;
X	char *t, c;
X	int  truelevel=level;
X
X	if( !str ) str="";
X
X	for( t=name; isalphanum(*t); t++ ) ;
X	c=*t; *t=0;
X
X	if( level==LEVEL_SET ) level=LEVEL_LOCAL;
X
X	for( ;; ) {
X		first=&Mbase[level]->first[*name & MAXHASH-1];
X		for( node=*first; node; node=node->next )
X			if( !strcmp( node->name, name) ) {
X				free( node->text );
X				goto copy;
X			}
X		if( truelevel!=LEVEL_SET )
X			break;
X		level=LEVEL_SET, truelevel=-1;
X	}
X
X	if(!(node=malloc(sizeof(NODE) + strlen(name)))) {
X		ierror(NULL,512);
X		return;
X	}
X	node->next=*first;
X	*first=node;
X	strcpy( node->name, name );
X
Xcopy:
X	if(!(node->text=malloc(strlen(str)+1))) {
X		ierror(NULL,512);
X		return;
X	}
X	strcpy( node->text, str );
X	*t=c;
X	if( *name=='_' )
X		set_sys_var( name );
X}
X
X
Xchar *
Xget_var( int level, char *name )
X{
X	NODE *node;
X	char *t, c;
X	int  truelevel=level;
X
X	if( level==LEVEL_SET ) level=LEVEL_LOCAL;
X
X	for ( t= name; (signed char)*t>0; t++ ) ;
X	c=*t; *t=0;
X
X	for( ;; ) {
X		node=Mbase[level]->first[*name & MAXHASH-1];
X
X		for( ; node; node=node->next )
X			if( !strcmp(node->name,name) )
X				{ *t=c; return node->text; }
X		if( truelevel!=LEVEL_SET )
X			break;
X		level=LEVEL_SET, truelevel=-1;
X	}
X
X	*t=c;
X
X	return NULL;
X}
X
Xvoid
Xunset_level( int level )
X{
X	NODE *node;
X	int i;
X
X	for( i=0; i<MAXHASH; i++ ) {
X		for( node=Mbase[level]->first[i]; node; node=node->next ) {
X			Free ( node->text );
X			Free ( node );
X		}
X		Mbase[level]->first[i] = NULL;
X	}
X}
X
Xvoid
Xunset_var( int level, char *name )
X{
X	NODE **first=&Mbase[level]->first[*name & MAXHASH-1], *node, *prev;
X	char *t, c;
X
X	for( t=name; isalphanum(*t); t++ ) ;
X	c=*t; *t=0;
X
X	for( node=*first, prev=NULL; node; prev=node, node=node->next )
X		if( !strcmp( node->name, name) ) {
X			if( prev ) prev->next=node->next; else *first=node->next;
X			Free( node->text );
X			Free( node );
X			if( *name=='_' )
X				set_sys_var( name );
X			break;
X		}
X	*t=c;
X}
X
X
Xvoid
Xset_var_n( int level, char *name, char *str, int n )
X{
X	char c, len=strlen(str);
X
X	if( n>len )
X		n=len;
X
X	if( n>=0 ) {
X		c=str[n]; str[n]=0;
X		set_var( level, name, str );
X		str[n]=c;
X	} else 
X		set_var( level, name, "" );
X}
X
Xint
Xdo_unset_var( char *str, int level )
X{
X	int i;
X
X	for (i = 1; i < ac; ++i)
X		unset_var (level, av[i]);
X	return 0;
X}
X
Xint
Xdo_set_var( char *command, int level )
X{
X	ROOT *root = Mbase[level];
X	NODE *node;
X	int i;
X	char *str;
X
X	switch (ac) {
X	case 1:
X		for( i=0; i<MAXHASH && !breakcheck(); i++ )
X			for( node=root->first[i]; node && !dobreak(); node=node->next )
X				printf ("%s%-10s %s\n", o_lolite, node->name, node->text);
X		break;
X	case 2:
X		if (str=get_var(level,av[1])) printf ("%-10s %s\n", av[1], str);
X		break;
X	default:
X		set_var (level, av[1], next_word (next_word (command)));
X		break;
X	}
X	return 0;
X}
X
X
Xextern char shellvers[];
X
Xstatic char *
Xsys_expand( char *str, char *t )
X{
X	struct DateStamp dss;
X	char *u;
X	DateStamp(&dss);
X
X	if( !str ) {
X		*t=0;
X		return t;
X	}
X
X	while (*str)
X		if (*str=='%') {
X			str+=2;
X			switch( str[-1] ) {
X			case 'p': t+=sprintf(t,"%s", get_var(LEVEL_SET, "_cwd"));  break;
X			case 'm': t+=sprintf(t,"%d", AvailMem( 0 )/1024);          break;
X			case 't': t+=sprintf(t,"%s", next_word(dates(&dss,0)));    break;
X			case 'c': t+=sprintf(t,"%s", o_hilite);                    break;
X			case 'v': t+=sprintf(t,"%s", shellvers );                  break;
X			case 'n': t+=sprintf(t,"%s", get_var(LEVEL_SET,"_clinumber"));break;
X			case 'h': t+=sprintf(t,"%s", get_var(LEVEL_SET, v_histnum));  break;
X			case 'd':    sprintf(t,"%s", dates(&dss,0));if(u=index(t,' '))t=u;break;
X			case 'f': t+=sprintf(t,"%s", oneinfo(get_var(LEVEL_SET,v_cwd),4));break;
X			case 'r': t+=sprintf(t,"%d", (SBYTE)Myprocess->pr_Task.tc_Node.ln_Pri);break;
X			default : *t++=str[-2]; *t++=str[-1]; break;
X			}
X		}
X		else *t++=*str++;
X	*t=0;
X	return t;
X}
X
Xvoid
Xpush_locals( ROOT *newroot )
X{
X	int i;
X	NODE **nodeptr;
X
X	newroot->prev=Mbase[ LEVEL_LOCAL ];
X	Mbase[ LEVEL_LOCAL ]=newroot;
X
X	nodeptr=newroot->first;
X	for( i=MAXHASH; i>0; --i )
X		*nodeptr++=NULL;
X
X}
X
Xvoid
Xpop_locals( void )
X{
X	ROOT *prev=Mbase[ LEVEL_LOCAL ]->prev;
X	unset_level( LEVEL_LOCAL );
X	Mbase[ LEVEL_LOCAL ]=prev;
X}
X
Xint
Xdo_local(void)
X{
X	int i;
X
X	if( ac==1 )
X		do_set_var( "", LEVEL_LOCAL);
X	else 
X		for( i=1; i<ac; i++ )
X			set_var(LEVEL_LOCAL,av[i],"");
X	return 0;
X}
X
X
Xchar truetitle[200];
X
Xchar o_hilite[24], o_lolite[8], *o_csh_qcd, o_kick20, o_nobreak;
Xchar o_minrows, o_scroll, o_nowindow, o_noraw, o_vt100, o_nofastscr;
Xchar o_bground, o_resident, o_internal, o_pipe[16]="T:", o_datefmt;
Xchar o_abbrev=1;
Xlong o_noreq;
X
Xextern char trueprompt[100];
X
Xstatic void
Xset_sys_var( char *name )
X{
X	char *get, *str, c=name[1], col;
X
X	if( c==v_debug  [1] ) debug  =  get_var(LEVEL_SET,v_debug  )!=NULL;
X	if( c==v_nobreak[1] ) o_nobreak=get_var(LEVEL_SET,v_nobreak)!=NULL;
X	if( c==v_abbrev [1] && (str=get_var(LEVEL_SET,v_abbrev)))o_abbrev=*str!='n';
X
X	if( c==v_verbose[1] ) {
X		Verbose=0;
X		if( str=get_var(LEVEL_SET,v_verbose)) {
X			if( index(str,'s' )) Verbose|= VERBOSE_SOURCE;
X			if( index(str,'a' )) Verbose|= VERBOSE_ALIAS;
X			if( index(str,'h' )) Verbose|= VERBOSE_HILITE;
X		}
X	}
X	if( c==v_pipe   [1] ) {
X		strcpy(o_pipe,"t:");
X		if( str=get_var(LEVEL_SET,v_pipe) )
X			strcpy(o_pipe,str);
X		appendslash(o_pipe);
X	}
X	if( c==v_hilite [1] && !strcmp( name, v_hilite)) {
X		o_hilite[0]=o_lolite[0]=0;
X		get= get_var(LEVEL_SET,v_hilite);
X		str= o_hilite;
X		while( get && *get ) {
X			switch( *get++ ) {
X			case 'b': str+=sprintf( str, "\033[1m" ); break;
X			case 'i': str+=sprintf( str, "\033[3m" ); break;
X			case 'u': str+=sprintf( str, "\033[4m" ); break;
X			case 'r': str+=sprintf( str, "\033[7m" ); break;
X			case 'c': str+=strlen(str);
X			          if( *get>='0' && *get<='9' ) {
X			             col=*get++;
X			             if( *get==',' && get[1]>='0' && get[1]<='9' ) {
X			                 str+=sprintf( str,"\033[3%cm\033[4%cm",col,get[1]);
X			                 get+=2;
X			             } else 
X			                 str+=sprintf( str,"\033[3%cm",col );
X			          }
X			          break;
X			}
X		}
X		*str=0;
X		if( *o_hilite )
X			strcpy(o_lolite,"\033[m");
X		strcpy(sys_expand(str,trueprompt),o_lolite);
X	}
X	if( c==v_scroll[1] ) {
X		o_scroll=0;
X		if( (str= get_var(LEVEL_SET,v_scroll))) {
X			o_scroll=atoi( str );
X			if( o_scroll<2 ) o_scroll=0;
X			if( o_scroll>8 ) o_scroll=8;
X		}
X	}
X	if( c==v_datefmt[1] ) {
X		o_datefmt=(str=get_var(LEVEL_SET,v_datefmt)) && !strcmp(str,"subst");
X	}
X	if( c==v_minrows[1] ) {
X		o_minrows=34;
X		if( (str= get_var(LEVEL_SET,v_minrows))) {
X			o_minrows=atoi( str );
X			if( o_minrows<8 )   o_minrows=8;
X			if( o_minrows>100 ) o_minrows=100, o_scroll=0;
X		}
X	}
X	if( c==v_qcd[1] ) {
X		o_csh_qcd="s:csh-qcd";
X		if( str=get_var(LEVEL_SET,v_qcd) )
X			o_csh_qcd=str;
X	}
X	if( c==v_noreq[1] ) {
X		o_noreq= get_var(LEVEL_SET,v_noreq ) ? -1 : 0;
X		Myprocess->pr_WindowPtr = (APTR)o_noreq;
X	}
X	if( c==v_hist[1] )
X		S_histlen=(str= get_var(LEVEL_SET, v_hist)) ? atoi(str) : 0;
X	if( c==v_titlebar[1] )
X		update_sys_var( v_titlebar );
X}
X
Xvoid
Xupdate_sys_var( char *name )
X{
X	char c=name[1], *str, buf[250];
X
X	if( c==v_prompt[1] ) {
X		if( (str=get_var(LEVEL_SET,v_prompt) ) ==NULL) str="$ ";
X		strcpy(sys_expand(str,trueprompt),o_lolite);
X	}
X	if( c==v_titlebar[1] && !o_nowindow && Win ) {
X		sys_expand( get_var(LEVEL_SET, v_titlebar), buf);
X		if (strcmp((char*)Win->Title, buf)) {
X			strcpy(truetitle,buf);
X			SetWindowTitles(Win, truetitle, (char *)-1);
X		}
X	}
X}
END_OF_FILE
if test 7922 -ne `wc -c <'set.c'`; then
    echo shar: \"'set.c'\" unpacked with wrong size!
fi
# end of 'set.c'
fi
if test -f 'shell.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'shell.h'\"
else
echo shar: Extracting \"'shell.h'\" \(6349 characters\)
sed "s/^X//" >'shell.h' <<'END_OF_FILE'
X
X/*
X * SHELL.H
X *
X * (c)1986 Matthew Dillon     9 October 1986
X *
X *
X * SHELL include file.. contains shell parameters and extern's
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X * Version 5.00L by Urban Mueller 16-Mar-91
X *
X */
X
X#define RAW_CONSOLE 1   /* Set to 0 to compile out Cmd Line Editing */
X#define KICK20
X
X#ifdef DICE
X
X#define	C_Args
X#define char unsigned char
X
X#endif
X
X#define strlen strlen
X
X#include <exec/types.h>
X#include <exec/exec.h>
X#include <libraries/arpbase.h>
X#include <intuition/intuitionbase.h>
X#include <libraries/dosextens.h>
X#include <time.h>
X#include <ctype.h>
X#include <fcntl.h>
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include "proto.h"
X
XLONG AssignLock( UBYTE *name, BPTR lock );
XBOOL AssignLate( UBYTE *name, UBYTE *path );
XBOOL AssignPath( UBYTE *name, UBYTE *path );
XBOOL AssignAdd( UBYTE *name, BPTR lock );
X
Xtypedef struct FileInfoBlock FIB;
X
X#ifdef AZTEC_C
X
X#include <functions.h>
X#define DEVTAB(x) (BPTR)(_devtab[x->_unit].fd)
X#define CHARSWAIT(x) (x->_bp < x->_bend)
X#define COMPILER "Aztec C 5.0d"
X#pragma amicall(DOSBase, 0x264, AssignLock(d1,d2))
X#pragma amicall(DOSBase, 0x26a, AssignLate(d1,d2))
X#pragma amicall(DOSBase, 0x270, AssignPath(d1,d2))
X#pragma amicall(DOSBase, 0x276, AssignAdd(d1,d2))
X
X#else
X
X#include <proto/all.h>
X#include <ios1.h>
X#define DEVTAB(x) _ufbs[(x)->_file].ufbfh
X#define CHARSWAIT(x) (x->_rcnt != x->_wcnt)
X
X  extern struct UFB _ufbs[];
X#ifndef memmove
X#define memmove(t,f,l) movmem((f),(t),(l))
X#endif
X#define COMPILER "Lattice C 5.10"
X#define index strchr
X#define swapmem(x,y,z) swmem(x,y,z)
X#pragma libcall DOSBase AssignLock 264 2102
X#pragma libcall DOSBase AssignLate 26a 2102
X#pragma libcall DOSBase AssignPath 270 2102
X#pragma libcall DOSBase AssignAdd 276 2102
X
X#endif
X
X#ifndef MAX
X#define MAX(x,y) ((x)>(y) ? (x) : (y))
X#endif
X
X#define MAXSRC		5		/* Max. # of source file levels	*/
X#define MAXIF		10		/* Max. # of if levels			*/
X#define MAXALIAS	20		/* Max. # of alias levels		*/
X#define MAXMYFILES	9		/* Max. # of internal files		*/
X#define MAXHASH		32		/* Max. # of hash chains		*/
X
X#define LEVEL_SET		0		/* which variable list to use   */
X#define LEVEL_ALIAS		1
X#define LEVEL_LABEL		2
X#define LEVEL_LOCAL		3
X#define LEVEL_SOURCE	3
X
X#define SBYTE signed char
X#define MAXITEMS 16
X#define MAXMENUS 6
X
X#define VERBOSE_SOURCE 1
X#define VERBOSE_ALIAS  2
X#define VERBOSE_HILITE 4
X
X#ifndef NULL
X#define NULL 0L
X#endif
X
X#define CHECKBREAK() dobreak()
X
X#ifndef AZTEC_C
Xstruct _dev {
X	long  fd;
X	short mode;
X	};
X#endif
X
Xstruct HIST {
X	struct HIST *next, *prev;	/* doubly linked list */
X	char *line;					/* line in history    */
X};
X
Xstruct PERROR {
X	int errnum;					/* Format of global error lookup */
X	char *errstr;
X};
X
Xstruct DPTR {					/* Format of directory fetch pointer */
X	BPTR lock;					/* lock on directory   */
X	FIB *fib;					/* mod'd fib for entry */
X	};
X
Xextern struct HIST *H_head, *H_tail;
Xextern struct PERROR Perror[];
Xextern char **av;
Xextern char *Current;
Xextern int  H_len, H_tail_base, H_stack;
Xextern int  E_stack;
Xextern int  Src_stack, If_stack, forward_goto;
Xextern int  ac;
Xextern int  max_ac;
Xextern int  debug, Rval, Verbose, disable, Quit;
Xextern int  Lastresult, atoierr;
Xextern int  Exec_abortline;
Xextern int  S_histlen;
Xextern unsigned int options;
X
Xextern FILE *Src_base[MAXSRC];
Xextern long  Src_pos[MAXSRC];
Xextern short Src_if[MAXSRC], Src_abort[MAXSRC];
Xextern char  If_base[MAXIF];
Xextern struct Process *Myprocess;
Xextern struct CommandLineInterface *Mycli;
X
Xextern struct ArpBase *ArpBase;
X
Xextern char v_titlebar[], v_prompt[], v_hist[], v_histnum[], v_debug[],
X	v_verbose[], v_stat[], v_lasterr[], v_cwd[], v_except[], v_passed[],
X	v_path[], v_gotofwd[], v_linenum[], v_every[], v_lcd[], v_rxpath[],
X	v_hilite[], v_scroll[], v_minrows[], v_result[], v_qcd[], v_noreq[],
X	v_value[], v_nobreak[], v_bground[], v_pipe[], v_datefmt[], v_ioerr[],
X	v_abbrev[];
X
Xextern char o_hilite[], o_lolite[], *o_csh_qcd, o_internal;
Xextern char o_aux, o_minrows, o_scroll, o_nowindow, o_noraw, o_vt100;
Xextern char o_nofastscr, o_kick20, o_nobreak, o_bground, o_resident;
Xextern char o_pipe[], o_datefmt, o_abbrev;
Xextern long o_noreq;
Xextern char Buf[], isalph[], confirmed, *classfile;
X
Xextern char *MyMem;
X
X/* #define isalphanum(x) isalph[x] */
X
Xtypedef struct file_info {
X	LONG flags;
X	LONG size;
X	LONG blocks;
X	char class[12];
X	struct DateStamp date;
X} FILEINFO;
X
Xtypedef struct Class {
X	struct Class *next;
X	char name[1];
X} CLASS;
X
Xextern CLASS *CRoot, *LastCRoot;
Xextern struct Window *Win;
X
Xextern long IoError;
X
Xtypedef struct VNode {
X	struct VNode *next;
X	long len;
X	char *text;
X	char name[1];
X} NODE;
X
Xtypedef struct VRoot {
X	NODE         *first[MAXHASH];
X	struct VRoot *prev;
X} ROOT;
X
X
X#if 1
XLONG RunCommand( BPTR seg, long stack, UBYTE *paramptr, long paramlen );
Xstruct Segment *FindSegment( UBYTE *name, struct Segment *seg, long system );
XBOOL AssignAdd( UBYTE *name, BPTR lock );
X
X#ifdef AZTEC_C
X# pragma amicall(DOSBase, 0x1f8, RunCommand(d1,d2,d3,d4))
X# pragma amicall(DOSBase, 0x30c, FindSegment(d1,d2,d3))
X# pragma amicall(DOSBase, 0x276, AssignAdd(d1,d2))
X#else
X# pragma libcall DOSBase RunCommand 1f8 432104
X# pragma libcall DOSBase FindSegment 30c 32103
X# pragma libcall DOSBase AssignAdd 276 2102
X#endif
X
Xstruct RootNode2x {
X	BPTR    rn_TaskArray;
X	BPTR    rn_ConsoleSegment;
X	struct  DateStamp rn_Time;
X	LONG    rn_RestartSeg;
X	BPTR    rn_Info;
X	BPTR    rn_FileHandlerSegment;
X	struct MinList rn_CliList;
X	struct MsgPort *rn_BootProc;
X	BPTR    rn_ShellSegment;
X	LONG    rn_Flags;
X};
X
X
Xstruct DosList2x {
X	BPTR			dol_Next;
X	LONG			dol_Type;
X	struct MsgPort *dol_Task;
X	BPTR			dol_Lock;
X
X	union {
X		struct {
X			BSTR	dol_Handler;
X			LONG	dol_StackSize;
X			LONG	dol_Priority;
X			ULONG	dol_Startup;
X			BPTR	dol_SegList;
X			BPTR	dol_GlobVec;
X		} dol_handler;
X
X		struct {
X			struct DateStamp	dol_VolumeDate;
X			BPTR				dol_LockList;
X			LONG				dol_DiskType;
X		} dol_volume;
X
X		struct {
X			UBYTE 	*dol_AssignName;
X			struct AssignList *dol_List;
X		} dol_assign;
X
X	} dol_misc;
X
X	BSTR	dol_Name;
X};
X
Xstruct AssignList2x {
X	struct AssignList *al_Next;
X	BPTR		   al_Lock;
X};
X
X#define DLST_DEVICE     0
X#define DLST_DIRECTORY  1
X#define DLST_VOLUME     2
X#define DLST_LATE       3
X#define DLST_NONBINDING 4
X#define DLST_PRIVATE   -1
X
X#define ST_USERDIR      2
X#endif
END_OF_FILE
if test 6349 -ne `wc -c <'shell.h'`; then
    echo shar: \"'shell.h'\" unpacked with wrong size!
fi
# end of 'shell.h'
fi
if test -f 'technotes.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'technotes.doc'\"
else
echo shar: Extracting \"'technotes.doc'\" \(4227 characters\)
sed "s/^X//" >'technotes.doc' <<'END_OF_FILE'
X		TECHINCAL NOTES FOR CSHELL
X		==========================
X
X
XTHE PARSER
X----------
X
XThe  heart  of  CShell  is the parser.  It was, I suppose, originally taken
Xfrom a UNIX csh. It does its job in two steps:
X
XFirst  comes  the  preformatting,  which is done while copying the original
Xline  to  a temporary buffer.  It is important to make a difference between
Xquoted  and  and  unquoted characters.  Earlier shell versions of the shell
Xset  the  most  significant  bit  of quoted chars, but this made the use of
Xinternational  character  sets  impossible.   Now  it's  done the other way
Xround:   Every _unquoted_ char with special meaning (e.g.  the asterisk) is
Xreplaced  by  a number between 128 and 159.  Ascii code 160 is used as word
Xseparator in strings (so words may contain blanks).
X
XAfter  the preformatting is done, the parser's main task is building up the
Xargument  array  av[i]  for  the internal and external commands.  Memory is
Xallocated  for  every argument and the argument is put together from one or
Xmore  tokens  (e.g.   $a$b).  After av[0] has been completed, certain flags
Xare  set  in  order  to  do  things  like preventing wild card expinsion of
Xarguments to 'dir'.
X
XThen,  with the argument line is complete, the aliases list is searched for
Xa  name that matches av[0].  If it exists, the parser is called recursively
Xwith  the  alias's  command line.  Recursive calls of the parser (using the
Xfunction  execute()) have no more side effects at all since version 5.1 and
Xcan therefore used to do things like automatic cd and class features.
X
XIn  order to speed up this process with many allocations and deallocations,
XI  have  written  a  custom  storage  allocator.   It  allocates  groups of
X1000-byte-blocks  (called  frames)  using malloc() and then distibutes them
Xuntil  they're  used  up.  Of course, deallocation of single allocations is
Xnot  possible,  only  the  frame as a whole can be deallocated.  But that's
Xokay, since all temporaries are deallocated when the parser is left.
X
X
XTHE BUILTINS
X------------
X
XThe other side of the shell are the built in commands.  They look much like
XCLI commands in C, but they have lots of support functions for their needs.
X
XTo  write a builtin command for CShell, you use the global variables av and
Xac  instead of argv and argc, and use printf() for output.  That's it.  Any
Xother changes, if necessary, will be done by me.
X
XEvery  builtin  command  has its equivalent as a C function with the prefix
Xdo_ (example:  do_addbuffers).  The are no hard coded jumps to any of those
Xfunctions,  instead there is a table with the descriptions of all functions
X(like  name, usage, minimum arguments and, last but not least, a pointer to
Xthat function).
X
X
XWHY BUILT IN COMMANDS?
X----------------------
X
XThe reasons why C-Shell still relies heavily on internal commands:
X- They can take advantage from each other (e.g. class recognition in the
X  'dir' command, use of 'search' command in quick cd)
X- They have a fast calling sequence
X- They need no hard disk seeks, so the startup can be accelerated
X  significantly
X- They are shorter than external commands
X- And finally, if you don't like them, don't use them. The wasted resources
X  become more and more negligible nowadays... CShell uses 2% of my memory.
X
X
XSOURCES
X-------
X
XThe  source  for CShell is available, if you don't have it, request it from
Xme.   It consists of 10 modules, together 200K.  It is compilable under SAS
X(Lattice)  &  Manx  C,  although  the  executables produced by Manx are not
Xresidentable.   If you want to modify it, ask me for an up-to-date version
Xfirst.   You  may  not  release  modified  versions  (imagine  the chaos if
Xeverbody  releases his private csh), but if you send them to me, you have a
Xgood  chance  that I'll build it in.  You'll be, of course, be mentioned in
Xthe docs.
X
XEven  if  you  don't  intend to modify it, I still encourage you to get the
Xsource,  because  there  are  so many things you can look up there once you
Xneed them (did *you* know how to set the system date?).  I apologize for my
Xpoor to nonexistent comments, I'll go through again when I've got the time.
XAh,  yes,  that  famous  Dillon-formatting  is gone, now it's traditionally
Xformatted.
END_OF_FILE
if test 4227 -ne `wc -c <'technotes.doc'`; then
    echo shar: \"'technotes.doc'\" unpacked with wrong size!
fi
# end of 'technotes.doc'
fi
if test -f 'tips.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tips.doc'\"
else
echo shar: Extracting \"'tips.doc'\" \(3454 characters\)
sed "s/^X//" >'tips.doc' <<'END_OF_FILE'
XSome good ideas:
X
X
X    EDITING
X
X
XThe very common situation:
X$ mkdir documents
X$ cd documents
Xcan be abbreviated to:
X$ mk documents
X$ [CTRL-T]              (inserts all but first word of previous line)
X
X
XAlso very common:
X$ mv document document1
X$ mv document[CTRL-P]1
XThe CTRL-P function duplicates the previous word on the command line
X
X
XYou  might  have  wondered  what  CTRL-N  (leave current line) is good for.
XAssume, for example, you just typed
X$ rm dh1:graphics/lo-res/gorilla
Xwhen  it comes to your mind that would prefer to keep a copy of that pic on
Xdiskette.  Many would now delete this command line.  Being a smart guy, you
Xdo the following:
X$ [CTRL-N]              (leaves this command line alone)
X$ co[CTRL-T] df0:
X$ [Up-Arrow][Up-Arrow]  (gets back the command line you left)
X
X
XIn case you don't know what history completion is:
X$ search *.c *.h makefile foobar
X$ ram:
X$ dir
X$ rm tmpfile
XNow if want to repeat the search command, enter
X$ se[Shift-Up-Arrow]
Xwhich brings up the the last command that started with 'se'.
X
X
XIf you want to delete the file
X$ dh2:comm/uucp/mail/junk/409
Xand you're far away from that directory, enter
X$ ju[ESC-c]409          (enters the result of cd ju)
X
X
XThe  same function is also usable for 'cd'.  Assume you have several 'junk'
Xdirectories:
X$ ju[ESC-c][CTRL-R][CTRL-R][CTRL-R]
XLike  this  you'll cycke through the junk directories.  When you've got the
Xright one, press enter.
X
X
XAssume  there  are the files comm1.c, comm2.c, and comm3.c as well as their
Xcorresponding .o files.  You want comm3.c:
X$ co[Shift-Tab]1[Tab]
XOf course this is more useful with longer file names.
X
X
XYou can tab file name expand any patterns, not only abbreviations.  Assume
Xyou want to delete all .c files in the current directory but the last:
X$ rm *.c[ESC-Tab][CTRL-W]
XIn addition, you get to see all the files once again before deleting them.
X
X
XNext one: You have entered:
X$ dir
X$ foreach i ( *.c ) "e >>ram:temp $i
X$ more ram:temp
Xand you would like to execute the same three statements again, enter:
X$ [Up-Arrow][Up-Arrow][Up-Arrow][ESC-Return][CTRL-R][CTRL-R]
X
X
XI  know  that  the editing is not very user friendly.  This is because it's
Xquite  hard  and troublesome to get raw keycodes from the console, and it's
Ximpossible  to  get  them  from a VT200 terminal.  Therefore I had to stick
Xwith CTRL and ESC combinations. Once you have learnt them (some of them are
Xsimilar to EMACS), you can save lots of typing.
X
X
X    COMMANDS
X
X
XMy  advice  here  is clear:  Use aliases, aliases, aliases.  In order to be
Xable  to  create  them as quickly as possible, create an alias (e.g.  'le')
Xthat edits your login file, plus another one (e.g.  'lx'), that re-executes
Xit.   My  login  contains  almost  only aliases, everthing else I've put in
X'firstlogin.sh'.
X
X
XIf you don't like the default options of one command, you can add more of
Xthem using an alias:
X$ alias dir "dir -q
XFrom now on, blocks will no longer be displayed in 'dir'.
X
X
XIf your aliases have arguments, e.g.
X$ alias sc "search *.c
Xproblems arise when you try to specify options. e.g. case sensitivity:
X$ sc -c "hello world
Xthis will obviously not work. That's what @pickopts is good for:
X$ alias sc "%a search @pickopts( $a ) *.c @pickargs( $a )
X
X
XOnce you have more aliases, it is useful to keep them sorted.  You might
Xalso document them: Create a file 'aliases.doc', and perform
X$ set _man aliases.doc csh.doc
XThat way, you can document them in a separate file.
X
X
END_OF_FILE
if test 3454 -ne `wc -c <'tips.doc'`; then
    echo shar: \"'tips.doc'\" unpacked with wrong size!
fi
# end of 'tips.doc'
fi
echo shar: End of archive 1 \(of 6\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.misc.