[comp.sources.misc] v16i035: ECU async comm package rev 3.0, Part11/35

wht@n4hgf.uucp (Warren Tucker) (01/06/91)

Submitted-by: wht@n4hgf.uucp (Warren Tucker)
Posting-number: Volume 16, Issue 35
Archive-name: ecu3/part11

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 11 of ecu3
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= expresp.c ==============
echo 'x - extracting expresp.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'expresp.c' &&
X/*+-------------------------------------------------------------------------
X	expresp.c - HDB expect/respond per SCO Devices file
X	wht@n4hgf.Mt-Park.GA.US
X
X Meaning of some of the escape characters:
X \p - pause (approximately 1/4-1/2 second delay)
X \d - delay (2 seconds)
X \D - phone number/token
X \T - phone number with Dialcodes and character translation
X \N - null byte
X \K - insert a BREAK
X \E - turn on echo checking (for slow devices)
X \e - turn off echo checking
X \r - carriage return
X \c - no new-line
X \n - send new-line
X \nnn - send octal number
X \m### - sleep ### (decimal) milliseconds (non-standard)
X Speed - Hayes-specific speed-adaptive connect handler
X
X  Defined functions:
X	pcmd_expresp(param)
X	execute_expresp(expresp_script)
X	expect(str)
X	respond(str)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "ecu.h"
X#include "ecuerror.h"
X#include "esd.h"
X#include "var.h"
X#include "proc.h"
X
X
X#define MAX_FIELDS	50	/* max fields in a chat script */
X#define MAX_EXPRESP	511	/* max length of a chat script */
X#define MAX_EXPECT	63	/* max length of expect string */
X#define DEFAULT_TIMEOUT_MSECS (10*1000L)
X
X#define ERDEBUG(verb,str,arg) if(expresp_verbosity >= verb) \
X	pprintf(str,arg);
X
Xlong atol();
X
Xextern int proctrace;
Xextern int interrupt;
X
Xint expresp_verbosity = 0;
Xulong expect_timeout_msecs = DEFAULT_TIMEOUT_MSECS;
Xint expresp_echo_check = 0;
X
Xchar last_Speed_result[32];
X
X/*+-------------------------------------------------------------------------
X	expect(str) - expect (read) string from remote
Xreturn code on failure, 0 on success
X--------------------------------------------------------------------------*/
Xint
Xexpect(str)
Xchar *str;
X{
X	register char *cptr;
X	char parsebuf[MAX_EXPECT + 1];
X	int remaining = MAX_EXPECT;
X	int erc;
X	int old_ttymode = get_ttymode();
X	register char *parsed = parsebuf;
X	char s4[4];
X	int itmp;
X	long atol();
X
X	if(old_ttymode != 2)
X		ttymode(2);
X
X	if (!strncmp(str, "~t[", 3) || !strncmp(str, "~m[", 3))
X	{
X		expect_timeout_msecs = atol(str + 3);
X		if(*(str + 1) == 't')
X			expect_timeout_msecs *= 1000L;
X		str += 3;
X		ERDEBUG(2,"expect timeout = %lu msec\n",expect_timeout_msecs);
X		if (cptr = strchr(str, ']'))
X		{
X			str = cptr + 1;
X			ERDEBUG(3, "expect: %s\n", str);
X		}
X		else
X		{
X			erc = eExpectRespondFail;
X			goto RESTORE_TTYMODE_AND_RETURN_ERC;
X		}
X	}
X	ERDEBUG(2,"expect: <<%s>>\n",str);
X	if(!strlen(str) || !strcmp(str,"\"\""))
X		goto GOT_EXPECTED;
X
X	if(!strcmp(str,"Speed"))
X	{
X		LRWT lr;
X		long ms_start;
X		long ms_now;
X		struct timeb now_timeb;
X		ftime(&now_timeb);
X		ms_start = (now_timeb.time * 1000) + now_timeb.millitm;
X		do {
X			last_Speed_result[0] = 0;
X			lr.to1 = 90 * 100L;
X			lr.to2 = 120L;
X			/* allow interrupts + cooked read */
X			lr.raw_flag = 0x80;
X			lr.buffer = last_Speed_result;
X			lr.bufsize = sizeof(last_Speed_result);
X			lr.delim = "\n";
X			lr.echo = 0;
X			lgets_timeout(&lr);
X			ftime(&now_timeb);
X			ms_now = (now_timeb.time * 1000) + now_timeb.millitm;
X		} while (!interrupt && !lr.count && ((ms_now - ms_start) < 90*1000L));
X
X		if(interrupt || strncmp(lr.buffer,"CONNECT",7))
X			goto DID_NOT_GET_EXPECTED;
X		else
X			goto GOT_EXPECTED;
X	}
X
X	cptr = str;
X	while(remaining)
X	{
X		if(*cptr == '\\')
X		{
X			if(!*(++cptr))	/* if no character after escape, ... */
X			{
X				ERDEBUG(2," error: str ended with '\\'\n",0);
X				goto DID_NOT_GET_EXPECTED;
X			}
X
X			if(isdigit(*cptr))	/* handle \ooo */
X			{
X				strncpy(s4,cptr,3);
X				s4[3] = 0;
X				sscanf(s4,"%o",&itmp);
X				cptr += strspn(s4,"01234567");
X				*parsed++ = (char)itmp;
X				remaining--;
X				continue;
X			}
X
X			switch(*cptr)
X			{
X			case 'n':
X				*parsed++ = 0x0A;
X				remaining--;
X				break;
X			case 'r':
X				*parsed++ = 0x0D;
X				remaining--;
X				break;
X			default:
X				ERDEBUG(2," meaningless here: \\%c\n",*cptr);
X				break;
X			}
X			cptr++;
X		}
X		else
X		{
X			*parsed++ = *cptr++;
X			remaining--;
X		}
X	}
X	*parsed = 0;
X
X	if(remaining)
X		ERDEBUG(1," expect string too long\n",0);
X
X	if(expresp_verbosity >= 3)
X		hex_dump(parsebuf,strlen(parsebuf),"expecting",1);
X
X	if(llookfor(parsebuf,expect_timeout_msecs,
X		(expresp_verbosity < 3) ? expresp_verbosity : 0))
X	{
XGOT_EXPECTED:
X		ERDEBUG(2,"[EXPECT SUCCEEDED]\n",0);
X		erc = 0;
X		goto RESTORE_TTYMODE_AND_RETURN_ERC;
X		
X	}
X
XDID_NOT_GET_EXPECTED:
X	ERDEBUG(2,"[EXPECT FAILED%s]\n",(interrupt) ? " (interrupted)" : "");
X	if(interrupt)
X	{
X		interrupt = 0;
X		erc = eCONINT;
X	}
X	else
X		erc = eExpectRespondFail;
X	goto RESTORE_TTYMODE_AND_RETURN_ERC;
X
XRESTORE_TTYMODE_AND_RETURN_ERC:
X	if(old_ttymode != 2)
X		ttymode(old_ttymode);
X	return(erc);
X
X}	/* end of expect */
X
X/*+-------------------------------------------------------------------------
X	respond(str) - send to remote
X--------------------------------------------------------------------------*/
Xvoid
Xrespond(str)
Xregister char *str;
X{
Xint itmp;
Xlong ltmp;
Xchar s4[4];
Xint send_no_cr = 0;
X
X	ERDEBUG(2,"respond: <<%s>>\n",str);
X	while(*str)
X	{
X		if(*str == '\\')
X		{
X			/* handle \nnn - send octal number */
X			if(isdigit(*++str))	/* handle \ooo */
X			{
X				strncpy(s4,str,3);
X				s4[3] = 0;
X				sscanf(s4,"%o",&itmp);
X				str += strspn(s4,"01234567") - 1;	/* -1 cause str++ later */
X				lputc((char)itmp);
X			}
X			else switch(*str)
X			{
X				case 'p':  /* pause (approximately 1/4-1/2 second delay) */
X					ldraino(0);	/* wait for output to drain */
X					nap(400L);
X					break;
X				case 'm':  /* nap a while (non-standard) */
X					ltmp = atol(str + 1);
X					str += strspn(str + 1,"0123456789");
X					ldraino(0);	/* wait for output to drain */
X					nap(ltmp);
X					break;
X				case 'd':  /* delay (2 seconds) */
X					ldraino(0);	/* wait for output to drain */
X					nap(2000L);
X					break;
X				case 'D':  /* phone number/token */
X					if(expresp_echo_check)
X						lputs_paced(40,shm->Ltelno);	/* fake it */
X					else
X						lputs(shm->Ltelno);
X					break;
X				case 'T':  /* phnum with Dialcodes and char translation */
X					if(expresp_echo_check)
X						lputs_paced(40,shm->Ltelno);	/* fake it */
X					else
X						lputs(shm->Ltelno);
X					break;
X				case 'N':  /* null byte */
X					lputc(0);
X					break;
X				case 'K':  /* insert a BREAK */
X					lbreak();
X					break;
X				case 'E':  /* turn on echo checking (for slow devices) */
X					expresp_echo_check = 1;
X					break;
X				case 'e':  /* turn off echo checking */
X					expresp_echo_check = 0;
X					break;
X				case 'r':  /* carriage return */
X					lputc(0x0D);
X					break;
X				case 'c':  /* no new-line */
X					send_no_cr = 1;
X					break;
X				case 'n':  /* send new-line */
X					lputc(0x0D);
X					break;
X			}
X
X		}
X		else
X			lputc(*str);
X
X
X		if(expresp_echo_check)
X		{
X			ldraino(1);		/* wait for output to drain, then flush input */
X			nap(40L);		/* fake it */
X		}
X		str++;
X	}
X
X	if(!send_no_cr)
X		lputc(0x0D);
X}	/* end of respond */
X
X/*+-------------------------------------------------------------------------
X	execute_expresp(expresp_script)
X
Xreturn 0 on success, else error code
X--------------------------------------------------------------------------*/
Xint
Xexecute_expresp(expresp_script)
Xchar *expresp_script;
X{
Xchar *fields[MAX_FIELDS + 1];
Xint ifields;
Xint nfields;
Xint erc;
Xchar expresp_copy[MAX_EXPRESP + 1];
Xchar *expect_this;
Xchar *send_on_fail;
X
X#define EXPECT_STATE (!(ifields & 1))	/* even numbered fields are expect */
X	expresp_echo_check = 0;
X	last_Speed_result[0] = 0;
X
X	strncpy(expresp_copy,expresp_script,sizeof(expresp_copy));
X	build_arg_array(expresp_copy,fields,MAX_FIELDS,&nfields);
X	if(!nfields)	/* if no script, assume success */
X	{
X		ERDEBUG(2,"[EMPTY SCRIPT - EXPECT/RESPOND SUCCEEDED]\n",0);
X		return(0);
X	}
X
X	for(ifields = 0; ifields < nfields; ifields++)
X	{
X		if(interrupt)
X			break;
X		if(EXPECT_STATE)
X		{
X			expect_this = fields[ifields];
X			while(1)	/* until break or return(-1) */
X			{
X				if(send_on_fail = strchr(expect_this,'-'))
X					*send_on_fail++ = 0;
X				if(!(erc = expect(expect_this)))
X					break;
X				if((erc != eExpectRespondFail) || !send_on_fail)
X				{
X					ERDEBUG(2,"[EXPECT/RESPOND FAILED]\n",0);
X					return(eExpectRespondFail);
X				}
X				if(expect_this = strchr(send_on_fail,'-'))
X					*expect_this++ = 0;
X				if(interrupt)
X					break;
X				respond(send_on_fail);
X			}
X		}
X		else
X			respond(fields[ifields]);
X	}
X	if(interrupt)
X	{
X		interrupt = 0;
X		ERDEBUG(2,"[CONSOLE INTERRUPT]\n",0);
X		return(eCONINT);
X	}
X	ERDEBUG(2,"[EXPECT/RESPOND SUCCEEDED]\n",0);
X	return(0);
X
X}	/* end of execute_expresp */
X
X/*+-------------------------------------------------------------------------
X	pcmd_expresp(param)
Xexpresp [-v[v...]] <exp-resp-str> [<timeout_msecs>]
X--------------------------------------------------------------------------*/
Xint
Xpcmd_expresp(param)
XESD *param;
X{
Xint erc;
Xint itmp;
Xchar *cptr;
XESD *tesd;
Xchar switches[8];
X
X	if((tesd = make_esd(MAX_EXPRESP + 1)) == (ESD *)0)
X		return(eNoMemory);
X
X	get_switches(param,switches,sizeof(switches));
X
X	if(erc = gstr(param,tesd,0))
X	{
X		free_esd(tesd);
X		return(erc);
X	}
X
X	expect_timeout_msecs = DEFAULT_TIMEOUT_MSECS;
X	expresp_verbosity = (!!strchr(switches,'v')) || proctrace;
X	if(expresp_verbosity)
X	{
X		cptr = switches, itmp = 0;
X		while(*cptr)
X			itmp += (*cptr++ == 'v');
X		if(itmp > 1)
X			expresp_verbosity = itmp;
X	}
X		
X	if(erc = gint(param,&expect_timeout_msecs))
X	{
X		/* if something there non-integer */
X		if(!end_of_cmd(param))
X		{
X			erc = eSyntaxError;
X			goto RETURN;
X		}
X	}
X
X	erc = execute_expresp(tesd->pb);
X
XRETURN:
X	free_esd(tesd);
X	iv[0] = !!erc;
X	if(erc == eExpectRespondFail)
X		erc = 0;
X	return(erc);
X
X}	/* end of pcmd_expresp */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of expresp.c */
SHAR_EOF
$TOUCH -am 1224223790 'expresp.c' &&
chmod 0644 expresp.c ||
echo 'restore of expresp.c failed'
Wc_c="`wc -c < 'expresp.c'`"
test 9617 -eq "$Wc_c" ||
	echo 'expresp.c: original size 9617, current size' "$Wc_c"
# ============= feval.c ==============
echo 'x - extracting feval.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'feval.c' &&
X/*+-------------------------------------------------------------------------
X    feval.c - integer and string function evaluation
X	wht@n4hgf.Mt-Park.GA.US
X
X    feval_int(param,&int_returned) where 'int' here means long ECU $i int
X    feval_str(param,&esd_to_be_plugged)
X
X  These routines are called with param.index as follows:
X
X         !nnnnn       nnn is name of function
X          ^
X          |
X
X  Defined functions:
X	feval_int(param,value)
X	feval_str(param,result_esd)
X	strfunc_left(param,scratch_esd,result_esd)
X	strfunc_right(param,scratch_esd,result_esd)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:12-24-1990-04:31-wht@n4hgf-experimental esio driver functions */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "ecu.h"
X#include "ecuerror.h"
X#include "esd.h"
X#include "proc.h"
X#include "var.h"
X
X#if defined(ESIO_IN_USE)
Xchar *msr_text();
X#endif
X
X#define FIargc           1
X#define FIbaud           2
X#define FIcolors         3
X#define FIconn           4
X#define FIcsec           5
X#define FIctoi           6
X#define FIcurx           7
X#define FIcury           8
X#define FIfatime         9
X#define FIfmode         10
X#define FIfmtime        11
X#define FIfsize         12
X#define FIftell         13
X#define FIinstr         14
X#define FIisalnum       15
X#define FIisalpha       16
X#define FIisascii       17
X#define FIischr         18
X#define FIiscntrl       19
X#define FIisdigit       20
X#define FIisdir         21
X#define FIisgraph       22
X#define FIislower       23
X#define FIisprint       24
X#define FIispunct       25
X#define FIisreg         26
X#define FIisspace       27
X#define FIisupper       28
X#define FIisxdigit      29
X#define FIlen           30
X#define FIlgetc         31
X#define FImatch         32
X#define FImhack         33
X#define FIpid           34
X#define FIrchr          35
X#define FIrchrc         36
X#define FIshmid         37
X#define FIstoi          38
X#define FIxchr          39
X#define FIxchrc         40
X#define FIesecs         41
X#define FIlines         42
X#define FIcols          43
X#define FIrinstr        44
X#define FIesio          45
X#if defined(ESIO_IN_USE)
X#define FImsr           46
X#define FIlnerr         47
X#define FIridet         49
X#define FIbrdet         50
X#endif
X
XKEYTAB feval_int_tbl[] =
X{
X	{"argc",FIargc},
X	{"baud",FIbaud},
X#if defined(ESIO_IN_USE)
X	{"brdet",FIbrdet},
X#endif
X	{"colors",FIcolors},
X	{"cols",FIcols},
X	{"conn",FIconn},
X	{"csec",FIcsec},
X	{"ctoi",FIctoi},
X	{"curx",FIcurx},
X	{"cury",FIcury},
X	{"esecs",FIesecs},
X	{"esio",FIesio},
X	{"fatime",FIfatime},
X	{"fmode",FIfmode},
X	{"fmtime",FIfmtime},
X	{"fsize",FIfsize},
X	{"ftell",FIftell},
X	{"instr",FIinstr},
X	{"isalnum",FIisalnum},
X	{"isalpha",FIisalpha},
X	{"isalpha",FIisalpha},
X	{"isascii",FIisascii},
X	{"ischr",FIischr},
X	{"iscntrl",FIiscntrl},
X	{"isdigit",FIisdigit},
X	{"isdir",FIisdir},
X	{"isgraph",FIisgraph},
X	{"islower",FIislower},
X	{"isprint",FIisprint},
X	{"ispunct",FIispunct},
X	{"isreg",FIisreg},
X	{"isspace",FIisspace},
X	{"isupper",FIisupper},
X	{"isxdigit",FIisxdigit},
X	{"len",FIlen},
X#if defined(ESIO_IN_USE)
X	{"lnerr",FIlnerr},
X#endif
X	{"lgetc",FIlgetc},
X	{"lines",FIlines},
X	{"match",FImatch},
X	{"mhack",FImhack},
X#if defined(ESIO_IN_USE)
X	{"msr",FImsr},
X#endif
X	{"pid",FIpid},
X	{"rchr",FIrchr},
X	{"rchrc",FIrchrc},
X#if defined(ESIO_IN_USE)
X	{"ridet",FIridet},
X#endif
X	{"rinstr",FIrinstr},
X	{"shmid",FIshmid},
X	{"stoi",FIstoi},
X	{"xchr",FIxchr},
X	{"xchrc",FIxchrc},
X	{(char *)0,0}
X};
X
X#define FSargv           1
X#define FScgetc          2
X#define FScgets          3
X#define FSchr            4
X#define FSdate           5
X#define FSdatez          6
X#define FSday            7
X#define FSdayz           8
X#define FSdir            9
X#define FSedate         10
X#define FSenvvar        11
X#define FSerrstr        12
X#define FSetime         13
X#define FSfmodestr      14
X#define FSitos          15
X#define FSleft          16
X#define FSline          17
X#define FSlogname       18
X#define FSmid           19
X#define FSmonth         20
X#define FSmonthz        21
X#define FSrdesc         22
X#define FSright         23
X#define FSrname         24
X#define FSrtel          25
X#define FSscreen        26
X#define FStime          27
X#define FStimes         28
X#define FStimez         29
X#define FStimezs        30
X#define FStty           31
X#define FSbasename      32
X#define FSdirpart       33
X#define FSfilepart      34
X#if defined(ESIO_IN_USE)
X#define FSmsrtext       35
X#endif
X
XKEYTAB feval_str_tbl[] =
X{
X	{"argv",FSargv},
X	{"basename",FSbasename},
X	{"cgetc",FScgetc},
X	{"cgets",FScgets},
X	{"chr",FSchr},
X	{"date",FSdate},
X	{"datez",FSdatez},
X	{"day",FSday},
X	{"dir",FSdir},
X	{"dirpart",FSdirpart},
X	{"edate",FSedate},
X	{"envvar",FSenvvar},
X	{"errstr",FSerrstr},
X	{"etime",FSetime},
X	{"filepart",FSfilepart},
X	{"fmodestr",FSfmodestr},
X	{"itos",FSitos},
X	{"left",FSleft},
X	{"line",FSline},
X	{"logname",FSlogname},
X	{"mid",FSmid},
X	{"month",FSmonth},
X#if defined(ESIO_IN_USE)
X	{"msrtext",FSmsrtext},
X#endif
X	{"rdesc",FSrdesc},
X	{"right",FSright},
X	{"rname",FSrname},
X	{"rtelno",FSrtel},
X	{"screen",FSscreen},
X	{"time",FStime},
X	{"times",FStimes},
X	{"timez",FStimez},
X	{"timezs",FStimezs},
X	{"tty",FStty},
X	{(char *)0,0}
X};
X
Xextern char curr_dir[];
Xextern int proctrace;
Xextern PCB *pcb_stack[];
Xextern int proc_level;
Xextern char *sys_errlist[];
Xextern int sys_nerr;
Xextern struct timeb starting_timeb;
Xextern uint tcap_LINES;
Xextern uint tcap_COLS;
X
Xextern int shm_shmid;
X
Xchar *day_of_week_list = "SunMonTueWedThuFriSat";
Xchar *month_name_list = "JanFebMarAprMayJunJulAugSepOctNovDec";
X
X/*+-------------------------------------------------------------------------
X    erc = feval_int(param,&int_returned);
XFunctions (parameter types are expressed by the usage of variables)
X--------------------------------------------------------------------------*/
Xfeval_int(param,value)
XESD *param;
Xlong *value;
X{
Xregister erc;
Xregister keyword_token;
Xint index_save;
XESD *tesd1 = (ESD *)0;
XESD *tesd2 = (ESD *)0;
Xulong int1;
Xchar s32[32];
Xstruct timeb now_timeb;
X
X	index_save = param->index;
X
X	if(erc = get_alphanum_zstr(param,s32,sizeof(s32)))
X	{
X		erc = eInvalidFunction;
X		goto RETURN;
X	}
X
X	keyword_token = keyword_lookup(feval_int_tbl,s32);
X	switch(keyword_token)
X	{
X/* LEN($S0)         length of $S0 */
X	case FIlen:
X		if(!(tesd1 = make_esd(256)))
X		{
X			erc = eNoMemory;
X			goto RETURN;
X		}
X		if(erc = skip_paren(param,1))
X			goto RETURN;
X		if(erc = gstr(param,tesd1,1))
X			goto RETURN;
X		if(erc = skip_paren(param,0))
X			goto RETURN;
X		*value = (long)tesd1->cb;
X		break;
X
X/* INSTR($I0,$I1)   index of first occurrence of $I1 in $I0, -1 if none */
X	case FIinstr:
X		if(!(tesd1 = make_esd(256)))
X		{
X			erc = eNoMemory;
X			goto RETURN;
X		}
X		if(!(tesd2 = make_esd(256)))
X		{
X			erc = eNoMemory;
X			goto RETURN;
X		}
X		if(erc = skip_paren(param,1))
X			goto RETURN;
X		if(erc = gstr(param,tesd1,1))
X			goto RETURN;
X		if(erc = skip_comma(param))
X			goto RETURN;
X		if(erc = gstr(param,tesd2,1))
X			goto RETURN;
X		if(erc = skip_paren(param,0))
X			goto RETURN;
X
X		*value = (long)ulindex(tesd1->pb,tesd2->pb);
X		break;
X
X/* RINSTR($I0,$I1)   index of last occurrence of $I1 in $I0, -1 if none */
X	case FIrinstr:
X		if(!(tesd1 = make_esd(256)))
X		{
X			erc = eNoMemory;
X			goto RETURN;
X		}
X		if(!(tesd2 = make_esd(256)))
X		{
X			erc = eNoMemory;
X			goto RETURN;
X		}
X		if(erc = skip_paren(param,1))
X			goto RETURN;
X		if(erc = gstr(param,tesd1,1))
X			goto RETURN;
X		if(erc = skip_comma(param))
X			goto RETURN;
X		if(erc = gstr(param,tesd2,1))
X			goto RETURN;
X		if(erc = skip_paren(param,0))
X			goto RETURN;
X
X		*value = (long)ulrindex(tesd1->pb,tesd2->pb);
X		break;
X
X	case FImatch:
X		if(!(tesd1 = make_esd(256)))
X		{
X			erc = eNoMemory;
X			goto RETURN;
X		}
X		if(!(tesd2 = make_esd(256)))
X		{
X			erc = eNoMemory;
X			goto RETURN;
X		}
X		if(erc = skip_paren(param,1))
X			goto RETURN;
X		if(erc = gstr(param,tesd1,1))
X			goto RETURN;
X		if(erc = skip_comma(param))
X			goto RETURN;
X		if(erc = gstr(param,tesd2,1))
X			goto RETURN;
X		if(erc = skip_paren(param,0))
X			goto RETURN;
X
X		erc = regexp_operation(tesd1->pb,tesd2->pb,value);
X		break;
X
X	case FImhack:
X		ftime(&now_timeb);
X		*value = ((now_timeb.time - starting_timeb.time) * 1000) +
X				(now_timeb.millitm - starting_timeb.millitm);
X		erc = 0;
X		break;
X
X	case FIesecs:
X		ftime(&now_timeb);
X		*value = now_timeb.time;
X		erc = 0;
X		break;
X
X	case FIargc:
X		if(!proc_level)
X		{
X			pputs("not executing procedure\n");
X			erc = eFATAL_ALREADY;
X			break;
X		}
X		*value = (long)pcb_stack[proc_level - 1]->argc;
X		break;
X
X	case FIcolors:
X		if(erc = ifunc_colors(value))
X			goto RETURN;
X		break;
X
X	case FIftell:
X		if(erc = ifunc_ftell(param,value))
X			goto RETURN;
X		break;
X
X	case FIfmode:
X		if(erc = ifunc_fmode(param,value))
X			goto RETURN;
X		break;
X
X	case FIfsize:
X		if(erc = ifunc_fsize(param,value))
X			goto RETURN;
X		break;
X
X	case FIfmtime:
X		if(erc = ifunc_fmtime(param,value))
X			goto RETURN;
X		break;
X
X	case FIfatime:
X		if(erc = ifunc_fatime(param,value))
X			goto RETURN;
X		break;
X
X	case FIischr:
X		if(erc = ifunc_ischr(param,value))
X			goto RETURN;
X		break;
X
X	case FIisdir:
X		if(erc = ifunc_isdir(param,value))
X			goto RETURN;
X		break;
X
X	case FIisreg:
X		if(erc = ifunc_isreg(param,value))
X			goto RETURN;
X		break;
X
X	case FIbaud:
X		*value = (long)shm->Lbaud;
X		erc = 0;
X		break;
X
X	case FIpid:
X		*value = (long)getpid();
X		erc = 0;
X		break;
X
X	case FIcsec:
X		*value = (shm->Lmodem_off_hook) ? shm->Loff_hook_time : -1;
X		erc = 0;
X		break;
X
X	case FIconn:
X		*value = (long)(shm->Lmodem_off_hook) ? (long)shm->Liofd : 0;
X		erc = 0;
X		break;
X
X	case FIxchr:
X		*value = shm->xmit_chars;
X		erc = 0;
X		break;
X
X	case FIxchrc:
X		*value = shm->xmit_chars_this_connect;
X		erc = 0;
X		break;
X
X	case FIrchr:
X		shmx_rc_report(value,&int1);
X		break;
X
X	case FIrchrc:
X		shmx_rc_report(&int1,value);
X		erc = 0;
X		break;
X
X/* LGETC($I0) get char from line, waiting for $I0 msec
Xreturns  character read or -1 if none read in time */
X	case FIlgetc:
X		if(erc = skip_paren(param,1))
X			goto RETURN;
X		if(erc = gint(param,&int1))
X			goto RETURN;
X		if(erc = skip_paren(param,0))
X			goto RETURN;
X		*value = (long)lgetc_timeout(int1);
X		break;
X
X	case FIctoi:
X		if(!(tesd1 = make_esd(256)))
X		{
X			erc = eNoMemory;
X			goto RETURN;
X		}
X		if(erc = skip_paren(param,1))
X			goto RETURN;
X		if(erc = gstr(param,tesd1,1))
X			goto RETURN;
X		if(erc = skip_paren(param,0))
X			goto RETURN;
X		if(tesd1->cb == 0)
X			*value = -1;
X		else
X			*value = (long)((unsigned)0xFF & (unsigned)tesd1->pb[0]);
X		break;
X
X	case FIstoi:
X		if(!(tesd1 = make_esd(256)))
X		{
X			erc = eNoMemory;
X			goto RETURN;
X		}
X		if(erc = skip_paren(param,1))
X			goto RETURN;
X		if(erc = gstr(param,tesd1,1))
X			goto RETURN;
X		if(erc = skip_paren(param,0))
X			goto RETURN;
X
X		tesd1->index = 0;
X		skip_cmd_break(tesd1);
X		*value = 0;
X		gint_constant(tesd1,value);
X		break;
X
X	case FIcurx:
X		*value = (long)shm->cursor_x;
X		break;
X
X	case FIcury:
X		*value = (long)shm->cursor_y;
X		break;
X
X	case FIshmid:
X		*value = (long)shm_shmid;
X		break;
X
X	case FIisalpha:
X	case FIisupper:
X	case FIislower:
X	case FIisdigit:
X	case FIisxdigit:
X	case FIisspace:
X	case FIispunct:
X	case FIisalnum:
X	case FIisprint:
X	case FIisgraph:
X	case FIiscntrl:
X	case FIisascii:
X		if(!(tesd1 = make_esd(256)))
X		{
X			erc = eNoMemory;
X			goto RETURN;
X		}
X		if(erc = skip_paren(param,1))
X			goto RETURN;
X		if(erc = gstr(param,tesd1,1))
X			goto RETURN;
X		if(erc = skip_paren(param,0))
X			goto RETURN;
X		if(!tesd1->cb)
X		{
X			*value = 0;
X			goto RETURN;
X		}
X		switch(keyword_token)
X		{
X			case FIisalpha:
X				*value = !!isalpha(*tesd1->pb);
X				break;
X			case FIisupper:
X				*value = !!isupper(*tesd1->pb);
X				break;
X			case FIislower:
X				*value = !!islower(*tesd1->pb);
X				break;
X			case FIisdigit:
X				*value = !!isdigit(*tesd1->pb);
X				break;
X			case FIisxdigit:
X				*value = !!isxdigit(*tesd1->pb);
X				break;
X			case FIisspace:
X				*value = !!isspace(*tesd1->pb);
X				break;
X			case FIispunct:
X				*value = !!ispunct(*tesd1->pb);
X				break;
X			case FIisalnum:
X				*value = !!isalnum(*tesd1->pb);
X				break;
X			case FIisprint:
X				*value = !!isprint(*tesd1->pb);
X				break;
X			case FIisgraph:
X				*value = !!isgraph(*tesd1->pb);
X				break;
X			case FIiscntrl:
X				*value = !!iscntrl(*tesd1->pb);
X				break;
X			case FIisascii:
X				*value = !!isascii(*tesd1->pb);
X				break;
X		}
X		break;
X
X	case FIlines:
X		*value = (long)tcap_LINES;
X		break;
X
X	case FIcols:
X		*value = (long)tcap_COLS;
X		break;
X
X#if defined(ESIO_IN_USE)
X	case FIesio:
X		*value = 1;
X		break;
X	case FImsr:
X		*value = (long)esio_msr();
X		break;
X	case FIlnerr:
X		*value = (long)esio_line_errors();
X		break;
X	case FIridet:
X		*value = (long)esio_rings_detected();
X		break;
X	case FIbrdet:
X		*value = (long)esio_breaks_detected();
X		break;
X#else
X	case FIesio:
X		*value = 0;
X		break;
X#endif
X
X	default:
X		erc = eInvalidFunction;
X	}   /* end of keyword lookup erc switch statement */
X
XRETURN:
X	if(tesd1)
X		free_esd(tesd1);
X	if(tesd2)
X		free_esd(tesd2);
X	return(erc);
X
X}   /* end of feval_int() */
X
X/*+------------------------------------------------------------------
X    strfunc_left(param,&scratch_esd,&result_esd)
X-------------------------------------------------------------------*/
Xint
Xstrfunc_left(param,scratch_esd,result_esd)
XESD *param;
XESD *scratch_esd;
XESD *result_esd;
X{
Xregister erc;
Xint itmp;
Xlong ltmp;
X
X	if(erc = skip_paren(param,1))
X		return(erc);
X	if(erc = gstr(param,scratch_esd,1))
X		return(erc);
X	if(erc = skip_comma(param))
X		return(erc);
X	if(erc = gint(param,&ltmp))
X		return(erc);
X	itmp = (int)ltmp;
X	if(itmp < 0)
X		return(eBadParameter);
X	if(erc = skip_paren(param,0))
X		return(erc);
X	/* take min of param and .cb */
X	itmp = (itmp < scratch_esd->cb) ? itmp : scratch_esd->cb;
X	if(itmp > (result_esd->maxcb - result_esd->cb) )
X		return(eBufferTooSmall);
X	memcpy(&result_esd->pb[result_esd->cb],
X	    scratch_esd->pb,itmp);
X	result_esd->cb += itmp;
X	return(erc);
X}   /* end of strfunc_left() */
X
X/*+-------------------------------------------------------------------------
X    erc = strfunc_right(param,&scratch_esd,&result_esd)
X--------------------------------------------------------------------------*/
Xint
Xstrfunc_right(param,scratch_esd,result_esd)
XESD *param;
XESD *scratch_esd;
XESD *result_esd;
X{
Xregister erc;
Xint itmp;
Xlong ltmp;
X
X	if(erc = skip_paren(param,1))
X		return(erc);
X	if(erc = gstr(param,scratch_esd,1))
X		return(erc);
X	if(erc = skip_comma(param))
X		return(erc);
X	if(erc = gint(param,&ltmp))
X		return(erc);
X	itmp = (int)ltmp;
X	if(itmp < 0)
X		return(eBadParameter);
X	if(erc = skip_paren(param,0))
X		return(erc);
X
X/* take min of param and .cb */
X	itmp = (itmp < scratch_esd->cb) ? itmp : scratch_esd->cb;
X	if(itmp > (result_esd->maxcb - result_esd->cb) )
X		return(eBufferTooSmall);
X	memcpy(&result_esd->pb[result_esd->cb],
X	    &scratch_esd->pb[scratch_esd->cb - itmp],itmp);
X	result_esd->cb += itmp;
X	return(0);
X
X}   /* end of strfunc_right() */
X
X/*+-------------------------------------------------------------------------
X    erc = feval_str(param,&esd_to_be_plugged);
X    results are APPENDED to 'result_esd'
X--------------------------------------------------------------------------*/
Xfeval_str(param,result_esd)
XESD *param;
XESD *result_esd;
X{
Xregister erc;
Xregister itmp;
Xint int1,int2;
Xchar s32[32];
Xchar *cptr;
Xlong ltmp;
Xlong ltmp2;
Xlong ltmp3;
XESD *tesd1;
XESD *tesd2 = (ESD *)0;
Xchar *get_ttyname();
Xchar *getenv();
Xchar *getlogin();
Xchar *get_elapsed_time();
Xchar *mode_map();
X
X	if(!(tesd1 = make_esd(128)))
X		return(eNoMemory);
X
X	if(erc = get_alphanum_zstr(param,s32,sizeof(s32)-1))
X	{
X		free_esd(tesd1);
X		return(eInvalidFunction);
X	}
X
X	erc = 0;
X	itmp=keyword_lookup(feval_str_tbl,s32);
X	switch(itmp)
X	{
X/* LEFT($S0,$I0)   return leftmost $I0 characters of $S0 */
X	case FSleft:
X		erc = strfunc_left(param,tesd1,result_esd);
X		break;
X
X/* RIGHT($S0,$I0)   return rightmost $I0 characters of $S0 */
X	case FSright:
X		erc = strfunc_right(param,tesd1,result_esd);
X		break;
X
X/* MID($S0,$I0,$I1)   return middle $I1 chars of $S0 starting at $I0 */
X	case FSmid:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gstr(param,tesd1,1))
X			break;
X		if(erc = skip_comma(param))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		int1 = (int)ltmp;
X		if(int1 < 0)
X		{
X			erc = eBadParameter;
X			break;
X		}
X		if(erc = skip_cmd_break(param))
X			break;
X		if(param->pb[param->index] == ')') /* if we find a ')' instead of ... */
X		{                                  /* 2nd int param, default to max */
X			++param->index;
X			int2 = 256;
X		}
X		else
X		{
X			if(erc = skip_comma(param))
X				break;
X			if(erc = gint(param,&ltmp))
X				break;
X			int2 = (int)ltmp;
X			if(int2 < 0)
X			{
X				erc = eBadParameter;
X				break;
X			}
X			if(erc = skip_paren(param,0))
X				break;
X		}
X
X		if(int1 >= tesd1->cb) /* if initial index past end of string */
X			break;
X		itmp = tesd1->cb - int1;
X		itmp = (int2 < itmp) ? int2 : itmp;
X		cptr = tesd1->pb + int1;
X		goto CPTR_ITMP_COMMON;
X
X/* ARGV($I0) */
X	case FSargv:
X		if(!proc_level)
X		{
X			pputs("not executing procedure\n");
X			erc = eFATAL_ALREADY;
X			break;
X		}
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		itmp = (long)pcb_stack[proc_level - 1]->argc; /* arg count */
X		if((int)ltmp > itmp - 1)
X		{
X			if(proctrace)
X			{
X				pprintf("WARNING: %%argc=%d, %%argv(%ld) null\n",
X					itmp,ltmp);
X			}
X			break;
X		}
X		cptr = (pcb_stack[proc_level - 1])->argv[(int)ltmp];
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSdir:
X		cptr = curr_dir;
X		itmp = strlen(curr_dir);
X		goto CPTR_ITMP_COMMON;
X
X	case FSetime:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		cptr = get_elapsed_time(ltmp);
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSerrstr:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		if((int)ltmp >= sys_nerr)
X		{
X			sprintf(s32,"error %d",(int)ltmp);
X			cptr = s32;
X		}
X		else
X			cptr = sys_errlist[(int)ltmp];
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSenvvar:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gstr(param,tesd1,1))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		if(!(cptr = getenv(tesd1->pb)))
X			break;
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSlogname:
X		if(!(cptr = getlogin()))
X			break;
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSfmodestr:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		cptr = mode_map((int)ltmp,(char *)0);
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FStty:
X		cptr = get_ttyname();
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSrname:
X		if(!shm->Lmodem_off_hook)
X			break;
X		cptr = shm->Lrname;
X		itmp = strlen(shm->Lrname);
X		goto CPTR_ITMP_COMMON;
X
X	case FSrdesc:
X		if(!shm->Lmodem_off_hook)
X			break;
X		cptr = shm->Ldescr;
X		itmp = strlen(shm->Ldescr);
X		goto CPTR_ITMP_COMMON;
X
X	case FSrtel:
X		if(!shm->Lmodem_off_hook)
X			break;
X		cptr = shm->Ltelno;
X		itmp = strlen(shm->Ltelno);
X		goto CPTR_ITMP_COMMON;
X
X	case FSline:
X		if(shm->Liofd < 0)
X			break;
X		cptr = shm->Lline;
X		itmp = strlen(shm->Lline);
X		goto CPTR_ITMP_COMMON;
X
X	case FSmonth:
X	case FSmonthz:
X	    cptr = &month_name_list[(get_month(itmp == FSmonthz) - 1) * 3];
X		itmp = 3;
X		goto CPTR_ITMP_COMMON;
X
X	case FSday:
X	case FSdayz:
X		cptr = &day_of_week_list[get_day(itmp == FSdayz) * 3];
X		itmp = 3;
X		goto CPTR_ITMP_COMMON;
X
X	case FSscreen:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))		/* y */
X			break;
X		if(ltmp > 42)
X		{
X			erc = eBadParameter;
X			break;
X		}
X		if(erc = skip_comma(param))
X			break;
X		if(erc = gint(param,&ltmp2))	/* x */
X			break;
X		if(ltmp2 > 79)
X		{
X			erc = eBadParameter;
X			break;
X		}
X		if(erc = skip_comma(param))
X			break;
X		if(erc = gint(param,&ltmp3))	/* len */
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X
X		int1 = ((int)ltmp * 80) + (int)ltmp2;	/* screen position */
X		itmp = (int)ltmp3;						/* length */
X		int2 = sizeof(shm->screen) - int1;		/* size from y,x to end */
X		if(itmp > int2)
X			itmp = int2;
X		cptr = ((char *)shm->screen) + int1;
X		goto CPTR_ITMP_COMMON;
X
X	case FSbasename:
X		if(!(tesd2 = make_esd(32)))
X			return(eNoMemory);
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gstr(param,tesd1,1))
X			break;
X		if(erc = skip_comma(param))
X			break;
X		if(erc = gstr(param,tesd2,1))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		cptr = tesd1->pb;
X		itmp = tesd1->cb;
X		if((tesd1->cb >= tesd2->cb) &&
X			!strcmp(cptr + tesd1->cb - tesd2->cb,tesd2->pb))
X		{
X			itmp -= tesd2->cb;
X		}
X		goto CPTR_ITMP_COMMON;
X
X	case FSdirpart:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gstr(param,tesd1,1))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		if(cptr = strrchr(tesd1->pb,'/'))
X			itmp = cptr - tesd1->pb;
X		else
X			itmp = tesd1->cb;
X		cptr = tesd1->pb;
X		goto CPTR_ITMP_COMMON;
X
X	case FSfilepart:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gstr(param,tesd1,1))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		if(cptr = strrchr(tesd1->pb,'/'))
X			itmp = strlen(++cptr);
X		else
X		{
X			cptr = tesd1->pb;
X			itmp = tesd1->cb;
X		}
X		goto CPTR_ITMP_COMMON;
X
X#if defined(ESIO_IN_USE)
X	case FSmsrtext:
X		cptr = msr_text(esio_msr());
X		itmp = strlen(cptr);
X		goto CPTR_ITMP_COMMON;
X#endif
X
XCPTR_ITMP_COMMON:
X		if( itmp > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		memcpy(&result_esd->pb[result_esd->cb],cptr,itmp);
X		result_esd->cb += itmp;
X		break;
X
X	case FSedate:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(erc = skip_paren(param,0))
X			break;
X		if(19 > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		epoch_secs_to_str(ltmp,3,&result_esd->pb[result_esd->cb]);
X		result_esd->cb += 19;
X		break;
X
X	case FStime:
X		if(5 > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		get_tod(0,&result_esd->pb[result_esd->cb]);
X		result_esd->cb += 5;
X		break;
X
X	case FStimes:
X		if(8 > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		get_tod(1,&result_esd->pb[result_esd->cb]);
X		result_esd->cb += 8;
X		break;
X
X	case FStimez:
X		if(5 > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		get_tod(6,&result_esd->pb[result_esd->cb]);
X		result_esd->cb += 5;
X		break;
X
X	case FStimezs:
X		if(8 > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		get_tod(7,&result_esd->pb[result_esd->cb]);
X		result_esd->cb += 8;
X		break;
X
X	case FSdate:
X		if(10 > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		get_tod(5,&result_esd->pb[result_esd->cb]);
X		result_esd->cb += 10;
X		break;
X
X	case FSdatez:
X		if(10 > (result_esd->maxcb - result_esd->cb))
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		get_tod(8,&result_esd->pb[result_esd->cb]);
X		result_esd->cb += 10;
X		break;
X
X	case FScgets:
X		erc = ttygets_esd(result_esd,1,1);
X		break;
X
X	case FScgetc:
X		if(result_esd->cb == result_esd->maxcb)
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		result_esd->pb[result_esd->cb] = ttygetc(0);
X		result_esd->cb++;
X		break;
X
X	case FSchr:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		if(!ltmp)
X		{
X			pputs("cannot use %chr(0)\n");
X			return(eFATAL_ALREADY);
X		}
X		if(erc = skip_paren(param,0))
X			break;
X		if(result_esd->cb == result_esd->maxcb )
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		result_esd->pb[result_esd->cb] = (char)ltmp;
X		result_esd->cb++;
X		break;
X
X	case FSitos:
X		if(erc = skip_paren(param,1))
X			break;
X		if(erc = gint(param,&ltmp))
X			break;
X		s32[0] = 0;
X		if(!skip_comma(param))
X		{
X			if(erc = get_numeric_zstr(param,s32 + 1,sizeof(s32) - 4))
X				strcpy(s32 + 1,"1");
X			if(((itmp = atoi(s32 + 1)) < 0) ||
X				(itmp > (result_esd->maxcb - result_esd->cb)))
X			{
X				erc = eBufferTooSmall;
X				break;
X			}
X			s32[0] = '%';
X			if(ulindex(param->pb + param->index,"x") == 0)
X			{
X				param->index++;
X				strcat(s32,"lx");
X			}
X			else if(ulindex(param->pb + param->index,"o") == 0)
X			{
X				param->index++;
X				strcat(s32,"lo");
X			}
X			else if(ulindex(param->pb + param->index,"d") == 0)
X			{
X				param->index++;
X				strcat(s32,"ld");
X			}
X			else if(erc)
X				break;
X			else
X				strcat(s32,"ld");
X		}
X		if(erc = skip_paren(param,0))
X			break;
X		sprintf(tesd1->pb,s32[0] ? s32 : "%ld",ltmp);
X		tesd1->cb = strlen(tesd1->pb);
X		if(result_esd->maxcb - result_esd->cb < tesd1->cb)
X		{
X			erc = eBufferTooSmall;
X			break;
X		}
X		strcpy(&result_esd->pb[result_esd->cb],tesd1->pb);
X		result_esd->cb += tesd1->cb;
X		break;
X
X
X	default:
X		erc = eInvalidFunction;
X		break;
X	}   /* end of keyword lookup erc switch statement */
X
X	null_terminate_esd(result_esd);
X	free_esd(tesd1);
X	if(tesd2)
X		free_esd(tesd1);
X	return(erc);
X
X}   /* end of feval_str() */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of feval.c */
SHAR_EOF
$TOUCH -am 1226023290 'feval.c' &&
chmod 0644 feval.c ||
echo 'restore of feval.c failed'
Wc_c="`wc -c < 'feval.c'`"
test 24950 -eq "$Wc_c" ||
	echo 'feval.c: original size 24950, current size' "$Wc_c"
# ============= gint.c ==============
echo 'x - extracting gint.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'gint.c' &&
X/*+-------------------------------------------------------------------------
X    gint.c - ecu get integer parameter functions
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	gcol_range(param,col1,col2)
X	gint(param,int_returned)
X	gint_base(param,value)
X	gint_constant(param,value)
X	gintop(param,intop)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "ecu.h"
X#include "ecuerror.h"
X#include "esd.h"
X#include "var.h"
X
X#define OP_ADD      1
X#define OP_SUB      2
X#define OP_MUL      3
X#define OP_DIV      4
X#define OP_XOR      5
X#define OP_MOD      6
X#define OP_OR       7
X#define OP_AND      8
X
X#define BASE_DEC	1
X#define BASE_OCT	2
X#define BASE_HEX  	3
X
X
X/*+-------------------------------------------------------------------------
X    gint_constant(param,int_returned) - evaluate integer constant
X--------------------------------------------------------------------------*/
Xint
Xgint_constant(param,value)
XESD *param;
Xlong *value;
X{
Xregister itmp;
Xint base = BASE_DEC;
Xint erc;
Xlong new_value;
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X	null_terminate_esd(param);
X
X/* get integer from string */
X	if((!strncmp(param->pb + param->index,"0x",2)) ||
X		(!strncmp(param->pb + param->index,"0X",2)))
X	{
X		base = BASE_HEX;
X		param->index += 2;
X	}
X#ifdef WANT_OCT
X	else if(*(param->pb + param->index) == '0')
X		base = BASE_OCT;
X#endif
X
X	param->old_index = param->index;
X	switch(base)
X	{
X	case BASE_HEX:
X		sscanf(param->pb + param->index,"%lx",&new_value);
X		itmp = param->index + strspn(param->pb + param->index,
X			"0123456789ABCDEFabcdef");
X		erc = eInvalidHexNumber;
X		break;
X	case BASE_DEC:
X		sscanf(param->pb + param->index,"%ld",&new_value);
X		itmp = param->index + strspn(param->pb + param->index,"0123456789");
X		erc = eInvalidDecNumber;
X		break;
X#ifdef WANT_OCT
X	case BASE_OCT:
X		sscanf(param->pb + param->index,"%lo",&new_value);
X		itmp = param->index + strspn(param->pb + param->index,"01234567");
X		erc = eInvalidOctNumber;
X		break;
X#endif
X	}
X
X	param->index = itmp;
X	if(isalnum(*(param->pb + itmp)))
X		param->old_index = itmp;
X
X	if(param->old_index != param->index)
X	{
X		*value = new_value;
X		return(0);
X	}
X	return(erc);
X
X}   /* end of gint_constant */
X
X/*+-------------------------------------------------------------------------
X    gint_base(param,value) - evaluate integer constant, variable or function
X--------------------------------------------------------------------------*/
Xint
Xgint_base(param,value)
XESD *param;
Xlong *value;
X{
Xregister erc;
Xlong *varptr;
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X
X	switch(param->pb[param->index])		/* look at first character */
X	{
X	case '$':		/* '$i...' variable reference? */
X		if(param->index >= param->cb-2)
X			return(eSyntaxError);
X		param->old_index = ++param->index;
X		if(to_lower(param->pb[param->index++]) != 'i')
X			return(eIllegalVarType);
X		if(erc = get_ivptr(param,&varptr,0))
X			return(erc);
X		*value = *varptr;	
X		return(0);
X
X	case '%':		/* '%...' function reference? */
X		param->index++;
X		if(erc = feval_int(param,value))
X			return(erc);
X		return(0);
X
X	default:
X		break;
X	}   /* end of switch statement */
X
X/* we did not catch any special cases with the switch statement must
Xbe numeric integer */
X
X	return(gint_constant(param,value));
X
X}   /* end of gint_base() */
X
X/*+-------------------------------------------------------------------------
X    gintop(param,intop) - evaluate integer operator
X--------------------------------------------------------------------------*/
Xint
Xgintop(param,intop)
XESD *param;
Xint *intop;
X{
X	register erc;
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X	switch(param->pb[param->index])
X	{
X	case '+':
X		param->index++;
X		*intop = OP_ADD;
X		break;
X
X	case '-':
X		param->index++;
X		*intop = OP_SUB;
X		break;
X
X	case '*':
X		param->index++;
X		*intop = OP_MUL;
X		break;
X
X	case '/':
X		param->index++;
X		*intop = OP_DIV;
X		break;
X
X	case '|':
X		if(*(param->pb + param->index + 1) == '|')
X			return(eInvalidIntOp);
X		param->index++;
X		*intop = OP_OR;
X		break;
X
X	case '@':
X		param->index++;
X		*intop = OP_MOD;
X		break;
X
X	case '^':
X		param->index++;
X		*intop = OP_XOR;
X		break;
X
X	case '&':
X		if(*(param->pb + param->index + 1) == '&')
X			return(eInvalidIntOp);
X		param->index++;
X		*intop = OP_AND;
X		break;
X
X	default:
X		return(eInvalidIntOp);
X		break;
X	}   /* end of switch statement */
X
X	return(0);
X
X}   /* end of gintop() */
X
X/*+-------------------------------------------------------------------------
X    gint(param,int_returned) - evaluate integer expression
X--------------------------------------------------------------------------*/
Xint
Xgint(param,int_returned)
XESD *param;
Xlong *int_returned;
X{
Xregister erc;
Xlong int1;
Xlong int_accum = 0;
Xint intop;
Xint unary_minus = 0;
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X	if(param->pb[param->index] == '-')
X		unary_minus++,param->index++;
X
X	if(erc = gint_base(param,&int1))
X		return(erc);
X	int_accum = (unary_minus) ? -int1 : int1;
X
X	while((erc = gintop(param,&intop)) == 0)
X	{
X		if(erc = gint_base(param,&int1))
X			return(erc);
X		switch(intop)
X		{
X		case OP_ADD:
X			int_accum += int1;
X			break;
X		case OP_SUB:
X			int_accum -= int1;
X			break;
X		case OP_MUL:
X			int_accum *= int1;
X			break;
X		case OP_DIV:
X			int_accum /= int1;
X			break;
X		case OP_MOD:
X			int_accum %= int1;
X			break;
X		case OP_XOR:
X			(unsigned)int_accum ^= (unsigned)int1;
X			break;
X		case OP_AND:
X			(unsigned)int_accum &= (unsigned)int1;
X			break;
X		case OP_OR:
X			(unsigned)int_accum |= (unsigned)int1;
X			break;
X		default:
X			return(eInvalidIntOp);
X		}
X	}
X	param->index = param->old_index;
X
X	*int_returned = int_accum;
X	return(0);
X}   /* end of gint() */
X
X/*+-------------------------------------------------------------------------
X    col_range(param,col1,col2) - get a column range
X:$i0[-$i1]
Xargument may be integer constant, function or variable, but not expression
X--------------------------------------------------------------------------*/
Xint
Xgcol_range(param,col1,col2)
XESD *param;
Xulong *col1;
Xulong *col2;
X{
X	register erc;
X
X	if(skip_cmd_char(param,':') == 0)
X	{
X		if(erc = gint_base(param,col1))
X			return(erc);
X
X		if(skip_cmd_char(param,'-') == 0)     /* if hyphen found, range */
X		{
X			if(erc = gint_base(param,col2))
X				return(erc);
X		}
X		else
X			*col2 = *col1;		/* otherwise, first and last columns same */
X
X		if(*col1 > *col2)
X		{
X			pputs("Invalid column range: column 1 greater than column 2\n");
X			return(eFATAL_ALREADY);
X		}
X	}
X	else
X		erc = eBadParameter;
X
X	return(erc);
X}   /* end of gcol_range() */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of gint.c */
SHAR_EOF
$TOUCH -am 1224223890 'gint.c' &&
chmod 0644 gint.c ||
echo 'restore of gint.c failed'
Wc_c="`wc -c < 'gint.c'`"
test 6629 -eq "$Wc_c" ||
	echo 'gint.c: original size 6629, current size' "$Wc_c"
# ============= gstr.c ==============
echo 'x - extracting gstr.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'gstr.c' &&
X/*+-------------------------------------------------------------------------
X    gstr.c - ecu get string parameter functions
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	gstr(param,result,realloc_ok)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "ecu.h"
X#include "ecuerror.h"
X#include "esd.h"
X#include "var.h"
X
Xextern int proctrace;
X
X/*+-------------------------------------------------------------------------
X    gstr(param,result,realloc_ok) - get a string 
X
XExamples:
X
X set $s0='test ... '+%date+' '+%time+%chr(0x0D)+%chr(0x0A)
X hexdump $s0
X0000  74 65 73 74 20 2E 2E 2E 20 30 36 2D 30 39 2D 31 | test ... 06-09-1 |
X0010  39 38 39 20 31 37 3A 31 35 0D 0A                | 989 17:15..      |
X
X set $s0='12345678':1-6+'abc'
X set s0
X$S00 = '234567abc'
X
Xif realloc_ok and string too small, realloc result string as necessary
X
X--------------------------------------------------------------------------*/
Xint
Xgstr(param,result,realloc_ok)
XESD *param;
XESD *result;
Xint realloc_ok;
X{
Xregister char param_char;
Xregister char *pb;
XESD *tesd;
XESD *svptr;
Xint cb = 0;
Xint segment_index;
Xint next_is_literal = 0;	/* last char was not a backslash */
Xulong itmp1;
Xulong itmp2;
Xulong itmp3;
Xulong itmp4;
Xint erc;
Xint param_index_save;
Xint result_remaining;
Xint in_quoted_string = 0;   /* not currently in quoted string */
Xint end_of_parameter = 0;
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X
X	segment_index = 0;			
X	result_remaining = result->maxcb;	/* number we can put into result */
X	param_index_save = param->index;
X
X	if((tesd = make_esd(5120)) == (ESD *)0)
X		return(eNoMemory);
X	pb = tesd->pb;
X
XCONCATENATE:
X	while((param->index < param->cb) && !end_of_parameter)
X	{
X		param_char = param->pb[param->index];
X		if(in_quoted_string)
X		{
X			++param->index;
X			if(next_is_literal)
X			{
X				next_is_literal = 0;
X				switch(param_char)
X				{
X					case 'b' : param_char = 0x08; break;
X					case 'n' : param_char = 0x0A; break;
X					case 'r' : param_char = 0x0D; break;
X					case 't' : param_char = 0x09; break;
X					case '\'': param_char = '\''; break;
X				}
X				if((result_remaining-- == 0) && (!realloc_ok && (cb == 5120)))
X				{
X					erc = eBufferTooSmall;
X					goto RETURN;
X				}
X				*(pb + cb++) = param_char;
X			}
X			else if(param_char == '\\')
X				next_is_literal = 1;
X			else if(param_char == '\'')
X				in_quoted_string = 0;
X			else
X			{
X				if((result_remaining-- == 0) && (!realloc_ok && (cb == 5120)))
X				{
X					erc = eBufferTooSmall;
X					goto RETURN;
X				}
X				*(pb + cb++) = param_char;
X			}
X		}
X		else /* not in quoted string */
X		{
X			param->old_index = param->index;
X			switch(param_char)
X			{
X			case '\'':      /* apostrophe denotes literal text */
X				++param->index;
X				in_quoted_string = 1;
X				break;
X
X			case '%':
X				++param->index;
X				tesd->cb = cb;
X				if(erc = feval_str(param,tesd))
X					goto RETURN;
X				cb = tesd->cb;
X				result_remaining = (result->maxcb - cb);
X				break;
X
X			case '$':           /* '$Snn' variable reference? */
X				/* must be at least two more character */
X				if(param->index >= param->cb-2)
X				{
X					erc = eSyntaxError;
X					goto RETURN;
X				}
X				param->old_index = ++param->index;
X				if(to_lower(param->pb[param->index++]) != 's' )
X				{
X					erc = eIllegalVarType;
X					goto RETURN;
X				}
X				if(erc = get_svptr(param,&svptr,0))
X					goto RETURN;
X				if((!realloc_ok && (svptr->cb > (result->maxcb - cb))) ||
X					(svptr->cb > (5120 - cb)))
X				{
X					erc = eBufferTooSmall;
X					goto RETURN;
X				}
X				else if(svptr->cb)
X				{
X					memcpy(&pb[cb],svptr->pb,svptr->cb);
X					cb += svptr->cb;
X					result_remaining -= svptr->cb;
X				}
X				break;
X
X			case ':':
X/*
Xitmp1 holds col 1 (0-n) of substring operation
Xitmp2 holds col 2 (0-n) of operation adjusted to reflect end of string segment
Xitmp3 holds length of string segment
Xitmp4 holds length of substring segment output by substring operation
X*/
X				if(erc = gcol_range(param,&itmp1,&itmp2))
X					goto RETURN;
X				if((itmp3 = cb - segment_index)
X				    &&
X					(itmp4 = ((itmp2<itmp3)?itmp2:itmp3) - itmp1 + 1))
X				{
X					if(itmp1)
X						memcpy(&pb[segment_index],
X							&pb[segment_index+(int)itmp1],(int)itmp4);
X					cb -= ((int)itmp3 - (int)itmp4);
X				}
X				break;
X
X			case '+':
X				segment_index = cb;
X				++param->index;
X				goto CONCATENATE;
X
X			case ';':
X			case '#':
X				end_of_parameter = 1;
X				break;
X
X			default:
X				null_terminate_esd(result);
X				erc = 0;
X				if((param->index < param->cb) &&
X					isalnum(*(param->pb + param->index)))
X					erc = eSyntaxError;
X				else if(param_index_save == param->index)
X					erc = eBadParameter;
X				end_of_parameter = 1;
X				break;
X			}   /* end of switch (param_char) */
X		}       /* end of else not in quoted string */
X	}           /* end of while(index<cb) */
X
X
XRETURN:
X	if(result_remaining < 0)
X	{
X		if(realloc_ok)
X			erc = realloc_esd(result,((cb * 64) * 31) / 64);
X		else
X			erc = eBufferTooSmall;
X		if(erc)
X			return(erc);
X	}
X	if(cb)
X		memcpy(result->pb,pb,cb);
X	result->cb = cb;
X	null_terminate_esd(result);
X	free_esd(tesd);
X	return(erc);
X}   /* end of gqstr */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of qstr.c */
SHAR_EOF
$TOUCH -am 1224223890 'gstr.c' &&
chmod 0644 gstr.c ||
echo 'restore of gstr.c failed'
Wc_c="`wc -c < 'gstr.c'`"
test 5212 -eq "$Wc_c" ||
	echo 'gstr.c: original size 5212, current size' "$Wc_c"
true || echo 'restore of hdbintf.c failed'
echo End of part 11, continue with part 12
exit 0
--------------------------------------------------------------------
Warren Tucker, TuckerWare emory!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US
Hacker Extraordinaire  d' async PADs,  pods,  proteins and protocols

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.