summaryrefslogtreecommitdiff
path: root/stab.c
diff options
context:
space:
mode:
Diffstat (limited to 'stab.c')
-rw-r--r--stab.c239
1 files changed, 190 insertions, 49 deletions
diff --git a/stab.c b/stab.c
index 845cec3b42..73d6f39107 100644
--- a/stab.c
+++ b/stab.c
@@ -1,24 +1,16 @@
-/* $Header: stab.c,v 1.0.1.2 88/02/02 11:25:53 root Exp $
+/* $Header: stab.c,v 2.0 88/06/05 00:11:01 root Exp $
*
* $Log: stab.c,v $
- * Revision 1.0.1.2 88/02/02 11:25:53 root
- * patch13: moved extern int out of function for a poor Xenix machine.
- *
- * Revision 1.0.1.1 88/01/28 10:35:17 root
- * patch8: changed some stabents to support eval operator.
- *
- * Revision 1.0 87/12/18 13:06:14 root
- * Initial revision
+ * Revision 2.0 88/06/05 00:11:01 root
+ * Baseline version 2.0.
*
*/
-#include <signal.h>
-#include "handy.h"
#include "EXTERN.h"
-#include "search.h"
-#include "util.h"
#include "perl.h"
+#include <signal.h>
+
static char *sig_name[] = {
"",
"HUP",
@@ -68,6 +60,8 @@ static char *sig_name[] = {
};
extern int errno;
+extern int sys_nerr;
+extern char *sys_errlist[];
STR *
stab_str(stab)
@@ -75,27 +69,31 @@ STAB *stab;
{
register int paren;
register char *s;
+ register int i;
switch (*stab->stab_name) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '&':
if (curspat) {
paren = atoi(stab->stab_name);
- if (curspat->spat_compex.subend[paren] &&
- (s = getparen(&curspat->spat_compex,paren))) {
- curspat->spat_compex.subend[paren] = Nullch;
- str_set(stab->stab_val,s);
+ getparen:
+ if (curspat->spat_regexp &&
+ paren <= curspat->spat_regexp->nparens &&
+ (s = curspat->spat_regexp->startp[paren]) ) {
+ i = curspat->spat_regexp->endp[paren] - s;
+ if (i >= 0)
+ str_nset(stab->stab_val,s,i);
+ else
+ str_nset(stab->stab_val,"",0);
}
+ else
+ str_nset(stab->stab_val,"",0);
}
break;
case '+':
if (curspat) {
- paren = curspat->spat_compex.lastparen;
- if (curspat->spat_compex.subend[paren] &&
- (s = getparen(&curspat->spat_compex,paren))) {
- curspat->spat_compex.subend[paren] = Nullch;
- str_set(stab->stab_val,s);
- }
+ paren = curspat->spat_regexp->lastparen;
+ goto getparen;
}
break;
case '.':
@@ -115,7 +113,7 @@ STAB *stab;
str_set(stab->stab_val,s);
break;
case '=':
- str_numset(stab->stab_val,(double)curoutstab->stab_io->lines);
+ str_numset(stab->stab_val,(double)curoutstab->stab_io->page_len);
break;
case '-':
str_numset(stab->stab_val,(double)curoutstab->stab_io->lines_left);
@@ -123,18 +121,6 @@ STAB *stab;
case '%':
str_numset(stab->stab_val,(double)curoutstab->stab_io->page);
break;
- case '(':
- if (curspat) {
- str_numset(stab->stab_val,(double)(curspat->spat_compex.subbeg[0] -
- curspat->spat_compex.subbase));
- }
- break;
- case ')':
- if (curspat) {
- str_numset(stab->stab_val,(double)(curspat->spat_compex.subend[0] -
- curspat->spat_compex.subbeg[0]));
- }
- break;
case '/':
*tokenbuf = record_separator;
tokenbuf[1] = '\0';
@@ -157,7 +143,41 @@ STAB *stab;
str_set(stab->stab_val,ofmt);
break;
case '!':
- str_numset(stab->stab_val,(double)errno);
+ str_numset(stab->stab_val, (double)errno);
+ str_set(stab->stab_val,
+ errno < 0 || errno > sys_nerr ? "(unknown)" : sys_errlist[errno]);
+ stab->stab_val->str_nok = 1; /* what a wonderful hack! */
+ break;
+ case '<':
+ str_numset(stab->stab_val,(double)uid);
+ break;
+ case '>':
+ str_numset(stab->stab_val,(double)euid);
+ break;
+ case '(':
+ s = tokenbuf;
+ sprintf(s,"%d",(int)getgid());
+ goto add_groups;
+ case ')':
+ s = tokenbuf;
+ sprintf(s,"%d",(int)getegid());
+ add_groups:
+ while (*s) s++;
+#ifdef GETGROUPS
+#ifndef NGROUPS
+#define NGROUPS 32
+#endif
+ {
+ GIDTYPE gary[NGROUPS];
+
+ i = getgroups(NGROUPS,gary);
+ while (--i >= 0) {
+ sprintf(s," %ld", (long)gary[i]);
+ while (*s) s++;
+ }
+ }
+#endif
+ str_set(stab->stab_val,tokenbuf);
break;
}
return stab->stab_val;
@@ -175,13 +195,13 @@ STR *str;
switch (stab->stab_name[0]) {
case '^':
safefree(curoutstab->stab_io->top_name);
- curoutstab->stab_io->top_name = str_get(str);
- curoutstab->stab_io->top_stab = stabent(str_get(str),TRUE);
+ curoutstab->stab_io->top_name = s = savestr(str_get(str));
+ curoutstab->stab_io->top_stab = stabent(s,TRUE);
break;
case '~':
safefree(curoutstab->stab_io->fmt_name);
- curoutstab->stab_io->fmt_name = str_get(str);
- curoutstab->stab_io->fmt_stab = stabent(str_get(str),TRUE);
+ curoutstab->stab_io->fmt_name = s = savestr(str_get(str));
+ curoutstab->stab_io->fmt_stab = stabent(s,TRUE);
break;
case '=':
curoutstab->stab_io->page_len = (long)str_gnum(str);
@@ -222,9 +242,44 @@ STR *str;
case '[':
arybase = (int)str_gnum(str);
break;
+ case '?':
+ statusvalue = (unsigned short)str_gnum(str);
+ break;
case '!':
errno = (int)str_gnum(str); /* will anyone ever use this? */
break;
+ case '<':
+#ifdef SETRUID
+ uid = (int)str_gnum(str);
+ if (setruid(uid) < 0)
+ uid = (int)getuid();
+#else
+ fatal("setruid() not implemented");
+#endif
+ break;
+ case '>':
+#ifdef SETEUID
+ euid = (int)str_gnum(str);
+ if (seteuid(euid) < 0)
+ euid = (int)geteuid();
+#else
+ fatal("seteuid() not implemented");
+#endif
+ break;
+ case '(':
+#ifdef SETRGID
+ setrgid((int)str_gnum(str));
+#else
+ fatal("setrgid() not implemented");
+#endif
+ break;
+ case ')':
+#ifdef SETEGID
+ setegid((int)str_gnum(str));
+#else
+ fatal("setegid() not implemented");
+#endif
+ break;
case '.':
case '+':
case '&':
@@ -238,8 +293,6 @@ STR *str;
case '7':
case '8':
case '9':
- case '(':
- case ')':
break; /* "read-only" registers */
}
}
@@ -261,15 +314,18 @@ STR *str;
safefree(signame);
signame = Nullch;
}
+ else if (stab->stab_array) {
+ afill(stab->stab_array, (int)str_gnum(str) - arybase);
+ }
}
-whichsig(signame)
-char *signame;
+whichsig(sig)
+char *sig;
{
register char **sigv;
for (sigv = sig_name+1; *sigv; sigv++)
- if (strEQ(signame,*sigv))
+ if (strEQ(sig,*sigv))
return sigv - sig_name;
return 0;
}
@@ -280,16 +336,39 @@ int sig;
STAB *stab;
ARRAY *savearray;
STR *str;
+ char *oldfile = filename;
+ int oldsave = savestack->ary_fill;
+ SUBR *sub;
stab = stabent(str_get(hfetch(sigstab->stab_hash,sig_name[sig])),TRUE);
+ sub = stab->stab_sub;
+ if (!sub) {
+ if (dowarn)
+ warn("SIG%s handler \"%s\" not defined.\n",
+ sig_name[sig], stab->stab_name );
+ return;
+ }
savearray = defstab->stab_array;
- defstab->stab_array = anew();
+ defstab->stab_array = anew(defstab);
str = str_new(0);
str_set(str,sig_name[sig]);
apush(defstab->stab_array,str);
- str = cmd_exec(stab->stab_sub);
+ sub->depth++;
+ if (sub->depth >= 2) { /* save temporaries on recursion? */
+ if (sub->depth == 100 && dowarn)
+ warn("Deep recursion on subroutine \"%s\"",stab->stab_name);
+ savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
+ }
+ filename = sub->filename;
+
+ str = cmd_exec(sub->cmd); /* so do it already */
+
+ sub->depth--; /* assuming no longjumps out of here */
afree(defstab->stab_array); /* put back old $_[] */
defstab->stab_array = savearray;
+ filename = oldfile;
+ if (savestack->ary_fill > oldsave)
+ restorelist(oldsave);
}
char *
@@ -313,7 +392,7 @@ aadd(stab)
register STAB *stab;
{
if (!stab->stab_array)
- stab->stab_array = anew();
+ stab->stab_array = anew(stab);
return stab;
}
@@ -325,3 +404,65 @@ register STAB *stab;
stab->stab_hash = hnew();
return stab;
}
+
+STAB *
+stabent(name,add)
+register char *name;
+int add;
+{
+ register STAB *stab;
+
+ for (stab = stab_index[*name]; stab; stab = stab->stab_next) {
+ if (strEQ(name,stab->stab_name)) {
+ stab->stab_flags |= SF_MULTI; /* is okay, probably */
+ return stab;
+ }
+ }
+
+ /* no entry--should we add one? */
+
+ if (add) {
+ stab = (STAB *) safemalloc(sizeof(STAB));
+ bzero((char*)stab, sizeof(STAB));
+ stab->stab_name = savestr(name);
+ stab->stab_val = str_new(0);
+ stab->stab_next = stab_index[*name];
+ stab_index[*name] = stab;
+ return stab;
+ }
+ return Nullstab;
+}
+
+STIO *
+stio_new()
+{
+ STIO *stio = (STIO *) safemalloc(sizeof(STIO));
+
+ bzero((char*)stio, sizeof(STIO));
+ stio->page_len = 60;
+ return stio;
+}
+
+stab_check(min,max)
+int min;
+register int max;
+{
+ register int i;
+ register STAB *stab;
+
+ for (i = min; i <= max; i++) {
+ for (stab = stab_index[i]; stab; stab = stab->stab_next) {
+ if (stab->stab_flags & SF_MULTI)
+ continue;
+ if (i == 'A' && strEQ(stab->stab_name, "ARGV"))
+ continue;
+ if (i == 'E' && strEQ(stab->stab_name, "ENV"))
+ continue;
+ if (i == 'S' && strEQ(stab->stab_name, "SIG"))
+ continue;
+ if (i == 'I' && strEQ(stab->stab_name, "INC"))
+ continue;
+ warn("Possible typo: %s,", stab->stab_name);
+ }
+ }
+}