Beispiel #1
0
void
Xdol(void)
{
	word *a, *star;
	char *s, *t;
	int n;
	if(count(runq->argv->words)!=1){
		Xerror1("variable name not singleton!");
		return;
	}
	s = runq->argv->words->word;
	deglob(s);
	n = 0;
	for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0';
	a = runq->argv->next->words;
	if(n==0 || *t)
		a = copywords(vlook(s)->val, a);
	else{
		star = vlook("*")->val;
		if(star && 1<=n && n<=count(star)){
			while(--n) star = star->next;
			a = newword(star->word, a);
		}
	}
	poplist();
	runq->argv->words = a;
}
Beispiel #2
0
void
dotrap(void)
{
	Var *trapreq;
	Word *starval;

	while(refdec(&ntrap) >= 0) {
		if(flag['S'])
			exits(truestatus()?"":getstatus());
		starval=vlook("*")->val;
		trapreq=vlook("sysint");
		if(trapreq->fn){
			start(trapreq->fn, trapreq->pc, (Var*)0);
			runq->local=newvar(strdup("*"), runq->local);
			runq->local->val=copywords(starval, (Word*)0);
			runq->local->changed=1;
			runq->redir=runq->startredir=0;
		} else {
			/*
			 * run the stack down until we uncover the
			 * command reading loop.  Xreturn will exit
			 * if there is none (i.e. if this is not
			 * an interactive rc.)
			 */
			while(!runq->iflag)
				Xreturn();
		}
	}
}
Beispiel #3
0
void
Xcount(void)
{
	word *a;
	char *s, *t;
	int n;
	char num[12];
	if(count(runq->argv->words)!=1){
		Xerror1("variable name not singleton!");
		return;
	}
	s = runq->argv->words->word;
	deglob(s);
	n = 0;
	for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0';
	if(n==0 || *t){
		a = vlook(s)->val;
		inttoascii(num, count(a));
	}
	else{
		a = vlook("*")->val;
		inttoascii(num, a && 1<=n && n<=count(a)?1:0);
	}
	poplist();
	pushword(num);
}
Beispiel #4
0
void
dotrap(void)
{
	int i;
	struct var *trapreq;
	struct word *starval;
	starval = vlook("*")->val;
	while(ntrap) for(i = 0;i!=NSIG;i++) while(trap[i]){
		--trap[i];
		--ntrap;
		if(getpid()!=mypid) Exit(getstatus());
		trapreq = vlook(Signame[i]);
		if(trapreq->fn){
			start(trapreq->fn, trapreq->pc, (struct var *)0);
			runq->local = newvar(strdup("*"), runq->local);
			runq->local->val = copywords(starval, (struct word *)0);
			runq->local->changed = 1;
			runq->redir = runq->startredir = 0;
		}
		else if(i==SIGINT || i==SIGQUIT){
			/*
			 * run the stack down until we uncover the
			 * command reading loop.  Xreturn will exit
			 * if there is none (i.e. if this is not
			 * an interactive rc.)
			 */
			while(!runq->iflag) Xreturn();
		}
		else Exit(getstatus());
	}
}
Beispiel #5
0
void
execshift(void)
{
	int n;
	word *a;
	var *star;
	switch(count(runq->argv->words)){
	default:
		pfmt(err, "Usage: shift [n]\n");
		setstatus("shift usage");
		poplist();
		return;
	case 2:
		n = atoi(runq->argv->words->next->word);
		break;
	case 1:
		n = 1;
		break;
	}
	star = vlook("*");
	for(;n && star->val;--n){
		a = star->val->next;
		efree(star->val->word);
		efree((char *)star->val);
		star->val = a;
		star->changed = 1;
	}
	setstatus("");
	poplist();
}
Beispiel #6
0
void
Xqdol(void)
{
	word *a, *p;
	char *s;
	int n;
	if(count(runq->argv->words)!=1){
		Xerror1("variable name not singleton!");
		return;
	}
	s = runq->argv->words->word;
	deglob(s);
	a = vlook(s)->val;
	poplist();
	n = count(a);
	if(n==0){
		pushword("");
		return;
	}
	for(p = a;p;p = p->next) n+=strlen(p->word);
	s = emalloc(n);
	if(a){
		strcpy(s, a->word);
		for(p = a->next;p;p = p->next){
			strcat(s, " ");
			strcat(s, p->word);
		}
	}
	else
		s[0]='\0';
	pushword(s);
	efree(s);
}
Beispiel #7
0
void
vinit(void)
{
	char **env, *name, *val, *p;
	int i;
	Word *w;
	Io *f;
	int n;
	Var *v;

	env = _environ;
	for(i=0; env[i]; free(name), i++) {
		name = strdup(env[i]);
		p = strchr(name, '=');
		if(p == 0 || p == name)
			continue;
		*p = 0;
		val = p+1;
		n = strlen(val);
		if(n == 0)
			continue;

		if(strncmp(name, "fn#", 3)!=0) {
			/* variable */
			w = 0;
			p = val+n-1;
			while(*p) {
				if(*p == IWS)
					*p-- = 0;
				for(; *p && *p != IWS; p--)
					;
				w=newword(p+1, w);
			}
			setvar(name, w);
			vlook(name)->changed=0;
		} else {
			/* function */
			f = opencore(val, n);
			execcmds(f);
		}
	}
	v = vlook("path");
	p = getenv("path");
	if(v->val == 0 && p)
		v->val = newword(p, 0);
}
Beispiel #8
0
void
setvar(char *name, Word *val)
{
	Var *v=vlook(name);
	freewords(v->val);
	v->val=val;
	v->changed=1;
}
Beispiel #9
0
void
execcd(void)
{
	word *a = runq->argv->words;
	word *cdpath;
	char dir[512];
	setstatus("can't cd");
	cdpath = vlook("cdpath")->val;
	switch(count(a)){
	default:
		pfmt(err, "Usage: cd [directory]\n");
		break;
	case 2:
		if(a->next->word[0]=='/' || cdpath==0)
			cdpath=&nullpath;
		for(;cdpath;cdpath = cdpath->next){
			strcpy(dir, cdpath->word);
			if(dir[0])
				strcat(dir, "/");
			strcat(dir, a->next->word);
			if(dochdir(dir)>=0){
				if(strlen(cdpath->word)
				&& strcmp(cdpath->word, ".")!=0)
					pfmt(err, "%s\n", dir);
				setstatus("");
				break;
			}
		}
		if(cdpath==0)
			pfmt(err, "Can't cd %s: %r\n", a->next->word);
		break;
	case 1:
		a = vlook("home")->val;
		if(count(a)>=1){
			if(dochdir(a->word)>=0)
				setstatus("");
			else
				pfmt(err, "Can't cd %s: %r\n", a->word);
		}
		else
			pfmt(err, "Can't cd -- $home empty\n");
		break;
	}
	poplist();
}
Beispiel #10
0
void
_setvar(char *name, word *val, int callfn)
{
	struct var *v = vlook(name);
	freewords(v->val);
	v->val=val;
	v->changed=1;
	if(callfn && v->changefn)
		v->changefn(v);
}
Beispiel #11
0
void
Vinit(void)
{
	int dir, f, len, i, n, nent;
	char *buf, *s;
	char envname[Maxenvname];
	word *val;
	Dir *ent;

	dir = open("/env", OREAD);
	if(dir<0){
		pfmt(err, "rc: can't open /env: %r\n");
		return;
	}
	ent = nil;
	for(;;){
		nent = dirread(dir, &ent);
		if(nent <= 0)
			break;
		for(i = 0; i<nent; i++){
			len = ent[i].length;
			if(len && strncmp(ent[i].name, "fn#", 3)!=0){
				snprint(envname, sizeof envname, "/env/%s", ent[i].name);
				if((f = open(envname, 0))>=0){
					buf = emalloc(len+1);
					n = readn(f, buf, len);
					if (n <= 0)
						buf[0] = '\0';
					else
						buf[n] = '\0';
					val = 0;
					/* Charitably add a 0 at the end if need be */
					if(buf[len-1])
						buf[len++]='\0';
					s = buf+len-1;
					for(;;){
						while(s!=buf && s[-1]!='\0') --s;
						val = newword(s, val);
						if(s==buf)
							break;
						--s;
					}
					setvar(ent[i].name, val);
					vlook(ent[i].name)->changed = 0;
					close(f);
					efree(buf);
				}
			}
		}
		free(ent);
	}
	close(dir);
}
Beispiel #12
0
word*
searchpath(char *w)
{
	word *path;
	if(strncmp(w, "/", 1)==0
/*	|| strncmp(w, "#", 1)==0 */
	|| strncmp(w, "./", 2)==0
	|| strncmp(w, "../", 3)==0
	|| (path = vlook("path")->val)==0)
		path=&nullpath;
	return path;
}
Beispiel #13
0
void
Xrdcmds(void)
{
	struct thread *p = runq;
	word *prompt;
	flush(err);
	nerror = 0;
	if(flag['s'] && !truestatus())
		pfmt(err, "status=%v\n", vlook("status")->val);
	if(runq->iflag){
		prompt = vlook("prompt")->val;
		if(prompt)
			promptstr = prompt->word;
		else
			promptstr="% ";
	}
	Noerror();
	if(yyparse()){
		if(!p->iflag || p->eof && !Eintr()){
			if(p->cmdfile)
				efree(p->cmdfile);
			closeio(p->cmdfd);
			Xreturn();	/* should this be omitted? */
		}
		else{
			if(Eintr()){
				pchr(err, '\n');
				p->eof = 0;
			}
			--p->pc;	/* go back for next command */
		}
	}
	else{
		ntrap = 0;	/* avoid double-interrupts during blocked writes */
		--p->pc;	/* re-execute Xrdcmds after codebuf runs */
		start(codebuf, 1, runq->local);
	}
	freenodes();
}
Beispiel #14
0
void
Xunlocal(void)
{
	var *v = runq->local, *hid;
	if(v==0)
		panic("Xunlocal: no locals!", 0);
	runq->local = v->next;
	hid = vlook(v->name);
	hid->changed = 1;
	efree(v->name);
	freewords(v->val);
	efree((char *)v);
}
Beispiel #15
0
void
Xexit(void)
{
	struct var *trapreq;
	struct word *starval;
	static int beenhere = 0;
	if(getpid()==mypid && !beenhere){
		trapreq = vlook("sigexit");
		if(trapreq->fn){
			beenhere = 1;
			--runq->pc;
			starval = vlook("*")->val;
			start(trapreq->fn, trapreq->pc, (struct var *)0);
			runq->local = newvar(strdup("*"), runq->local);
			runq->local->val = copywords(starval, (struct word *)0);
			runq->local->changed = 1;
			runq->redir = runq->startredir = 0;
			return;
		}
	}
	Exit(getstatus());
}
Beispiel #16
0
/*
 * Initialise awk ARGC, ARGV variables.
 */
static void
awkarginit(int ac, char **av)
{
	int i;
	wchar_t *cp;

	ARGVsubi = node(INDEX, vlook(s_ARGV), constant);
	running = 1;
	constant->n_int = ac;
	(void) assign(varARGC, constant);
	for (i = 0; i < ac; ++i) {
		cp = mbstowcsdup(av[i]);
		constant->n_int = i;
		strassign(exprreduce(ARGVsubi), cp,
		    FSTATIC|FSENSE, wcslen(cp));
	}
	running = 0;
}
Beispiel #17
0
void
Xsub(void)
{
	word *a, *v;
	char *s;
	if(count(runq->argv->next->words)!=1){
		Xerror1("variable name not singleton!");
		return;
	}
	s = runq->argv->next->words->word;
	deglob(s);
	a = runq->argv->next->next->words;
	v = vlook(s)->val;
	a = subwords(v, count(v), runq->argv->words, a);
	poplist();
	poplist();
	runq->argv->words = a;
}
Beispiel #18
0
void
Xassign(void)
{
	var *v;
	if(count(runq->argv->words)!=1){
		Xerror1("variable name not singleton!");
		return;
	}
	deglob(runq->argv->words->word);
	v = vlook(runq->argv->words->word);
	poplist();
	globlist();
	freewords(v->val);
	v->val = runq->argv->words;
	v->changed = 1;
	if(v->changefn)
		v->changefn(v);
	runq->argv->words = 0;
	poplist();
}
Beispiel #19
0
/*
 * mainline for awk
 */
int
main(int argc, char *argv[])
{
	wchar_t *ap;
	char *cmd;

	cmd = argv[0];
	_cmdname = cmd;

	linebuf = emalloc(NLINE * sizeof (wchar_t));

	/*
	 * At this point only messaging should be internationalized.
	 * numbers are still scanned as in the Posix locale.
	 */
	(void) setlocale(LC_ALL, "");
	(void) setlocale(LC_NUMERIC, "C");
#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN	"SYS_TEST"
#endif
	(void) textdomain(TEXT_DOMAIN);

	awkvarinit();
	/* running = 1; */
	while (argc > 1 && *argv[1] == '-') {
		void *save_ptr = NULL;
		ap = mbstowcsdup(&argv[1][1]);
		if (ap == NULL)
			break;
		if (*ap == '\0') {
			free(ap);
			break;
		}
		save_ptr = (void *) ap;
		++argv;
		--argc;
		if (*ap == '-' && ap[1] == '\0')
			break;
		for (; *ap != '\0'; ++ap) {
			switch (*ap) {
#ifdef DEBUG
			case 'd':
				dflag = 1;
				continue;

#endif
			case 'f':
				if (argc < 2) {
					(void) fprintf(stderr,
				gettext("Missing script file\n"));
					return (1);
				}
				*progfilep++ = argv[1];
				--argc;
				++argv;
				continue;

			case 'F':
				if (ap[1] == '\0') {
					if (argc < 2) {
						(void) fprintf(stderr,
				gettext("Missing field separator\n"));
						return (1);
					}
					ap = mbstowcsdup(argv[1]);
					--argc;
					++argv;
				} else
					++ap;
				strescape(ap);
				strassign(varFS, linebuf, FALLOC,
				    wcslen(linebuf));
				break;

			case 'v': {
				wchar_t *vp;
				wchar_t *arg;

				if (argc < 2) {
					(void) fprintf(stderr,
		gettext("Missing variable assignment\n"));
					return (1);
				}
				arg = mbconvert(argv[1]);
				/*
				 * Ensure the variable expression
				 * is valid (correct form).
				 */
				if (((vp = wcschr(arg, '=')) != NULL) &&
				    isclvar(arg)) {
					*vp = '\0';
					strescape(vp+1);
					strassign(vlook(arg), linebuf,
					    FALLOC|FSENSE,
					    wcslen(linebuf));
					*vp = '=';
				} else {
					(void) fprintf(stderr, gettext(
					    "Invalid form for variable "
					    "assignment: %S\n"), arg);
					return (1);
				}
				--argc;
				++argv;
				continue;
			}

			default:
				(void) fprintf(stderr,
				gettext("Unknown option \"-%S\"\n"), ap);
				return (usage());
			}
			break;
		}
		if (save_ptr)
			free(save_ptr);
	}
	if (progfilep == &progfiles[0]) {
		if (argc < 2)
			return (usage());
		filename = "[command line]";	/* BUG: NEEDS TRANSLATION */
		progptr = mbstowcsdup(argv[1]);
		proglen = wcslen(progptr);
		--argc;
		++argv;
	}

	argv[0] = cmd;

	awkarginit(argc, argv);

	/* running = 0; */
	(void) yyparse();

	lineno = 0;
	/*
	 * Ok, done parsing, so now activate the rest of the nls stuff, set
	 * the radix character.
	 */
	(void) setlocale(LC_ALL, "");
	radixpoint = *localeconv()->decimal_point;
	awk();
	/* NOTREACHED */
	return (0);
}
Beispiel #20
0
/*
 * Read an identifier.
 * Input is first character of identifier.
 * Return VAR.
 */
static int
lexid(wint_t c)
{
	wchar_t *cp;
	size_t i;
	NODE *np;

	cp = linebuf;
	do {
		*cp++ = c;
		c = lexgetc();
	} while (iswalpha(c) || iswdigit(c) || c == '_');
	*cp = '\0';
	lexungetc(c);
	yylval.node = np = vlook(linebuf);

	switch (np->n_type) {
	case KEYWORD:
		switch (np->n_keywtype) {
		case PRINT:
		case PRINTF:
			++inprint;
			/* FALLTHROUGH */
		default:
			return ((int)np->n_keywtype);
		}
		/* NOTREACHED */

	case ARRAY:
	case VAR:
		/*
		 * If reading the argument list, create a dummy node
		 * for the duration of that function. These variables
		 * can be removed from the symbol table at function end
		 * but they must still exist because the execution tree
		 * knows about them.
		 */
		if (funparm) {
do_funparm:
			np = emptynode(PARM, i = (cp-linebuf));
			np->n_flags = FSTRING;
			np->n_string = _null;
			np->n_strlen = 0;
			(void) memcpy(np->n_name, linebuf,
			    (i+1) * sizeof (wchar_t));
			addsymtab(np);
			yylval.node = np;
		} else if (np == varNF || (np == varFS &&
		    (!doing_begin || begin_getline))) {
			/*
			 * If the user program references NF or sets
			 * FS either outside of a begin block or
			 * in a begin block after a getline then the
			 * input line will be split immediately upon read
			 * rather than when a field is first referenced.
			 */
			needsplit = 1;
		} else if (np == varENVIRON)
			needenviron = 1;
	/* FALLTHROUGH */
	case PARM:
		return (VAR);

	case UFUNC:
		/*
		 * It is ok to redefine functions as parameters
		 */
		if (funparm) goto do_funparm;
	/* FALLTHROUGH */
	case FUNC:
	case GETLINE:
		/*
		 * When a getline is encountered, clear the 'doing_begin' flag.
		 * This will force the 'needsplit' flag to be set, even inside
		 * a begin block, if FS is altered. (See VAR case above)
		 */
		if (doing_begin)
			begin_getline = 1;
		return (np->n_type);
	}
	/* NOTREACHED */
	return (0);
}
Beispiel #21
0
/*
 * Do initial setup of buffers, etc.
 * This must be called before most processing
 * and especially before lexical analysis.
 * Variables initialised here will be overruled by command
 * line parameter initialisation.
 */
static void
awkvarinit()
{
	NODE *np;

	(void) setvbuf(stderr, NULL, _IONBF, 0);

	if ((NIOSTREAM = sysconf(_SC_OPEN_MAX) - 4) <= 0) {
		(void) fprintf(stderr,
	gettext("not enough available file descriptors"));
		exit(1);
	}
	ofiles = (OFILE *)emalloc(sizeof (OFILE)*NIOSTREAM);
#ifdef A_ZERO_POINTERS
	(void) memset((wchar_t *)ofiles, 0, sizeof (OFILE) * NIOSTREAM);
#else
	{
		/* initialize file descriptor table */
		OFILE *fp;
		for (fp = ofiles; fp < &ofiles[NIOSTREAM]; fp += 1) {
			fp->f_fp = FNULL;
					fp->f_mode = 0;
					fp->f_name = (char *)0;
		}
	}
#endif
	constant = intnode((INT)0);

	const0 = intnode((INT)0);
	const1 = intnode((INT)1);
	constundef = emptynode(CONSTANT, 0);
	constundef->n_flags = FSTRING|FVINT;
	constundef->n_string = _null;
	constundef->n_strlen = 0;
	inc_oper = emptynode(ADD, 0);
	inc_oper->n_right = const1;
	asn_oper = emptynode(ADD, 0);
	field0 = node(FIELD, const0, NNULL);

	{
		RESFUNC near*rp;

		for (rp = &resfuncs[0]; rp->rf_name != (LOCCHARP)NULL; ++rp) {
			np = finstall(rp->rf_name, rp->rf_func, rp->rf_type);
		}
	}
	{
		RESERVED near*rp;

		for (rp = &reserved[0]; rp->r_name != (LOCCHARP)NULL; ++rp) {
			switch (rp->r_type) {
			case SVAR:
			case VAR:
				running = 1;
				np = vlook(rp->r_name);
				if (rp->r_type == SVAR)
					np->n_flags |= FSPECIAL;
				if (rp->r_svalue != NULL)
					strassign(np, rp->r_svalue, FSTATIC,
					    (size_t)rp->r_ivalue);
				else {
					constant->n_int = rp->r_ivalue;
					(void) assign(np, constant);
				}
				running = 0;
				break;

			case KEYWORD:
				kinstall(rp->r_name, (int)rp->r_ivalue);
				break;
			}
		}
	}

	varNR = vlook(s_NR);
	varFNR = vlook(s_FNR);
	varNF = vlook(s_NF);
	varOFMT = vlook(s_OFMT);
	varCONVFMT = vlook(s_CONVFMT);
	varOFS = vlook(s_OFS);
	varORS = vlook(s_ORS);
	varRS = vlook(s_RS);
	varFS = vlook(s_FS);
	varARGC = vlook(s_ARGC);
	varSUBSEP = vlook(s_SUBSEP);
	varENVIRON = vlook(s_ENVIRON);
	varFILENAME = vlook(s_FILENAME);
	varSYMTAB = vlook(s_SYMTAB);
	incNR = node(ASG, varNR, node(ADD, varNR, const1));
	incFNR = node(ASG, varFNR, node(ADD, varFNR, const1));
	clrFNR = node(ASG, varFNR, const0);
}
Beispiel #22
0
char*
getstatus(void)
{
	var *status = vlook("status");
	return status->val?status->val->word:"";
}
Beispiel #23
0
void
execwhatis(void){	/* mildly wrong -- should fork before writing */
	word *a, *b, *path;
	var *v;
	struct builtin *bp;
	char file[512];
	struct io out[1];
	int found, sep;
	a = runq->argv->words->next;
	if(a==0){
		Xerror1("Usage: whatis name ...");
		return;
	}
	setstatus("");
	out->fd = mapfd(1);
	out->bufp = out->buf;
	out->ebuf = &out->buf[NBUF];
	out->strp = 0;
	for(;a;a = a->next){
		v = vlook(a->word);
		if(v->val){
			pfmt(out, "%s=", a->word);
			if(v->val->next==0)
				pfmt(out, "%q\n", v->val->word);
			else{
				sep='(';
				for(b = v->val;b && b->word;b = b->next){
					pfmt(out, "%c%q", sep, b->word);
					sep=' ';
				}
				pfmt(out, ")\n");
			}
			found = 1;
		}
		else
			found = 0;
		v = gvlook(a->word);
		if(v->fn)
			pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
		else{
			for(bp = Builtin;bp->name;bp++)
				if(strcmp(a->word, bp->name)==0){
					pfmt(out, "builtin %s\n", a->word);
					break;
				}
			if(!bp->name){
				for(path = searchpath(a->word);path;path = path->next){
					strcpy(file, path->word);
					if(file[0])
						strcat(file, "/");
					strcat(file, a->word);
					if(Executable(file)){
						pfmt(out, "%s\n", file);
						break;
					}
				}
				if(!path && !found){
					pfmt(err, "%s: not found\n", a->word);
					setstatus("not found");
				}
			}
		}
	}
	poplist();
	flush(err);
}