1 /* $Header: stab.c,v 4.0 91/03/20 01:39:41 lwall Locked $
3 * Copyright (c) 1989, Larry Wall
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
9 * Revision 4.0 91/03/20 01:39:41 lwall
17 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
21 static char *sig_name[] = {
26 #define handlertype void
28 #define handlertype int
31 static handlertype sighandler();
33 static int origalen = 0;
39 STAB *stab = str->str_u.str_stab;
45 return stab_val(stab);
47 switch (*stab->str_magic->str_ptr) {
50 str_numset(stab_val(stab),(double)(debug & 32767));
55 str_set(stab_val(stab), inplace);
57 str_sset(stab_val(stab),&str_undef);
60 str_numset(stab_val(stab),(double)basetime);
63 str_numset(stab_val(stab),(double)dowarn);
65 case '1': case '2': case '3': case '4':
66 case '5': case '6': case '7': case '8': case '9': case '&':
68 paren = atoi(stab_name(stab));
70 if (curspat->spat_regexp &&
71 paren <= curspat->spat_regexp->nparens &&
72 (s = curspat->spat_regexp->startp[paren]) ) {
73 i = curspat->spat_regexp->endp[paren] - s;
75 str_nset(stab_val(stab),s,i);
77 str_sset(stab_val(stab),&str_undef);
80 str_sset(stab_val(stab),&str_undef);
85 paren = curspat->spat_regexp->lastparen;
91 if (curspat->spat_regexp &&
92 (s = curspat->spat_regexp->subbase) ) {
93 i = curspat->spat_regexp->startp[0] - s;
95 str_nset(stab_val(stab),s,i);
97 str_nset(stab_val(stab),"",0);
100 str_nset(stab_val(stab),"",0);
105 if (curspat->spat_regexp &&
106 (s = curspat->spat_regexp->endp[0]) ) {
107 str_nset(stab_val(stab),s, curspat->spat_regexp->subend - s);
110 str_nset(stab_val(stab),"",0);
116 str_numset(stab_val(stab),(double)stab_io(last_in_stab)->lines);
121 str_numset(stab_val(stab),(double)statusvalue);
124 s = stab_io(curoutstab)->top_name;
125 str_set(stab_val(stab),s);
128 s = stab_io(curoutstab)->fmt_name;
129 str_set(stab_val(stab),s);
133 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page_len);
136 str_numset(stab_val(stab),(double)stab_io(curoutstab)->lines_left);
139 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page);
145 str_numset(stab_val(stab),(double)arybase);
148 if (!stab_io(curoutstab))
149 stab_io(curoutstab) = stio_new();
150 str_numset(stab_val(stab),
151 (double)((stab_io(curoutstab)->flags & IOF_FLUSH) != 0) );
154 str_nset(stab_val(stab),ofs,ofslen);
157 str_nset(stab_val(stab),ors,orslen);
160 str_set(stab_val(stab),ofmt);
163 str_numset(stab_val(stab), (double)errno);
164 str_set(stab_val(stab), errno ? strerror(errno) : "");
165 stab_val(stab)->str_nok = 1; /* what a wonderful hack! */
168 str_numset(stab_val(stab),(double)uid);
171 str_numset(stab_val(stab),(double)euid);
175 (void)sprintf(s,"%d",(int)gid);
179 (void)sprintf(s,"%d",(int)egid);
187 GIDTYPE gary[NGROUPS];
189 i = getgroups(NGROUPS,gary);
191 (void)sprintf(s," %ld", (long)gary[i]);
196 str_set(stab_val(stab),buf);
204 struct ufuncs *uf = (struct ufuncs *)str->str_ptr;
206 if (uf && uf->uf_val)
207 (*uf->uf_val)(uf->uf_index, stab_val(stab));
211 return stab_val(stab);
218 STAB *stab = mstr->str_u.str_stab;
222 switch (mstr->str_rare) {
224 setenv(mstr->str_ptr,str_get(str));
225 /* And you'll never guess what the dog had */
226 /* in its mouth... */
228 if (strEQ(mstr->str_ptr,"PATH")) {
229 char *strend = str->str_ptr + str->str_cur;
233 s = cpytill(tokenbuf,s,strend,':',&i);
236 || (stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
237 str->str_tainted = 2;
244 i = whichsig(mstr->str_ptr); /* ...no, a brick */
245 if (strEQ(s,"IGNORE"))
247 (void)signal(i,SIG_IGN);
251 else if (strEQ(s,"DEFAULT") || !*s)
252 (void)signal(i,SIG_DFL);
254 (void)signal(i,sighandler);
255 if (!index(s,'\'')) {
256 sprintf(tokenbuf, "main'%s",s);
257 str_set(str,tokenbuf);
263 hdbmstore(stab_hash(stab),mstr->str_ptr,mstr->str_cur,str);
271 str = afetch(stab_xarray(stab),atoi(mstr->str_ptr), FALSE);
272 cmd = str->str_magic->str_u.str_cmd;
273 cmd->c_flags &= ~CF_OPTIMIZE;
274 cmd->c_flags |= i? CFT_D1 : CFT_D0;
278 afill(stab_array(stab), (int)str_gnum(str) - arybase);
280 case 'X': /* merely a copy of a * string */
284 if (strNE(s,"StB") || str->str_cur != sizeof(STBP)) {
288 (void)savenostab(stab); /* schedule a free of this stab */
290 Safefree(stab->str_ptr);
291 Newz(601,stbp, 1, STBP);
292 stab->str_ptr = stbp;
293 stab->str_len = stab->str_cur = sizeof(STBP);
295 strcpy(stab_magic(stab),"StB");
296 stab_val(stab) = Str_new(70,0);
297 stab_line(stab) = curcmd->c_line;
298 stab_stash(stab) = curcmd->c_stash;
301 stab = stabent(s,TRUE);
302 if (!stab_xarray(stab))
304 if (!stab_xhash(stab))
307 stab_io(stab) = stio_new();
313 struct lstring *lstr = (struct lstring*)str;
317 str->str_magic = Nullstr;
319 str_insert(mstr,lstr->lstr_offset,lstr->lstr_len,
329 switch (*stab->str_magic->str_ptr) {
330 case '\004': /* ^D */
332 debug = (int)(str_gnum(str)) | 32768;
338 if (str->str_pok || str->str_nok)
339 inplace = savestr(str_get(str));
343 case '\024': /* ^T */
344 basetime = (long)str_gnum(str);
346 case '\027': /* ^W */
347 dowarn = (bool)str_gnum(str);
351 savesptr((STR**)&last_in_stab);
354 Safefree(stab_io(curoutstab)->top_name);
355 stab_io(curoutstab)->top_name = s = savestr(str_get(str));
356 stab_io(curoutstab)->top_stab = stabent(s,TRUE);
359 Safefree(stab_io(curoutstab)->fmt_name);
360 stab_io(curoutstab)->fmt_name = s = savestr(str_get(str));
361 stab_io(curoutstab)->fmt_stab = stabent(s,TRUE);
364 stab_io(curoutstab)->page_len = (long)str_gnum(str);
367 stab_io(curoutstab)->lines_left = (long)str_gnum(str);
368 if (stab_io(curoutstab)->lines_left < 0L)
369 stab_io(curoutstab)->lines_left = 0L;
372 stab_io(curoutstab)->page = (long)str_gnum(str);
375 if (!stab_io(curoutstab))
376 stab_io(curoutstab) = stio_new();
377 stab_io(curoutstab)->flags &= ~IOF_FLUSH;
378 if (str_gnum(str) != 0.0) {
379 stab_io(curoutstab)->flags |= IOF_FLUSH;
383 i = (int)str_gnum(str);
384 multiline = (i != 0);
389 rslen = str->str_cur;
394 rschar = rs[rslen - 1];
397 rschar = 0777; /* fake a non-existent char */
404 ors = savestr(str_get(str));
405 orslen = str->str_cur;
410 ofs = savestr(str_get(str));
411 ofslen = str->str_cur;
416 ofmt = savestr(str_get(str));
419 arybase = (int)str_gnum(str);
422 statusvalue = U_S(str_gnum(str));
425 errno = (int)str_gnum(str); /* will anyone ever use this? */
428 uid = (int)str_gnum(str);
431 delaymagic |= DM_REUID;
432 break; /* don't do magic till later */
434 #endif /* HAS_SETREUID */
436 if (setruid((UIDTYPE)uid) < 0)
440 if (setreuid((UIDTYPE)uid, (UIDTYPE)-1) < 0)
443 if (uid == euid) /* special case $< = $> */
446 fatal("setruid() not implemented");
451 euid = (int)str_gnum(str);
454 delaymagic |= DM_REUID;
455 break; /* don't do magic till later */
457 #endif /* HAS_SETREUID */
459 if (seteuid((UIDTYPE)euid) < 0)
460 euid = (int)geteuid();
463 if (setreuid((UIDTYPE)-1, (UIDTYPE)euid) < 0)
464 euid = (int)geteuid();
466 if (euid == uid) /* special case $> = $< */
469 fatal("seteuid() not implemented");
474 gid = (int)str_gnum(str);
477 delaymagic |= DM_REGID;
478 break; /* don't do magic till later */
480 #endif /* HAS_SETREGID */
482 (void)setrgid((GIDTYPE)gid);
485 (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
487 fatal("setrgid() not implemented");
492 egid = (int)str_gnum(str);
495 delaymagic |= DM_REGID;
496 break; /* don't do magic till later */
498 #endif /* HAS_SETREGID */
500 (void)setegid((GIDTYPE)egid);
503 (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
505 fatal("setegid() not implemented");
510 chopset = str_get(str);
516 /* See if all the arguments are contiguous in memory */
517 for (i = 1; i < origargc; i++) {
518 if (origargv[i] == s + 1)
519 s += strlen(++s); /* this one is ok too */
521 if (origenviron[0] == s + 1) { /* can grab env area too? */
522 setenv("NoNeSuCh", Nullch); /* force copy of environment */
523 for (i = 0; origenviron[i]; i++)
524 if (origenviron[i] == s + 1)
527 origalen = s - origargv[0];
534 str->str_ptr[i] = '\0';
535 bcopy(s, origargv[0], i);
538 bcopy(s, origargv[0], i);
541 while (++i < origalen)
547 struct ufuncs *uf = (struct ufuncs *)str->str_magic->str_ptr;
549 if (uf && uf->uf_set)
550 (*uf->uf_set)(uf->uf_index, str);
561 register char **sigv;
563 for (sigv = sig_name+1; *sigv; sigv++)
564 if (strEQ(sig,*sigv))
565 return sigv - sig_name;
567 if (strEQ(sig,"CHLD"))
571 if (strEQ(sig,"CLD"))
584 CMD *oldcurcmd = curcmd;
585 int oldsave = savestack->ary_fill;
586 ARRAY *oldstack = stack;
587 CSV *oldcurcsv = curcsv;
590 #ifdef OS2 /* or anybody else who requires SIG_ACK */
591 signal(sig, SIG_ACK);
595 str_get(hfetch(stab_hash(sigstab),sig_name[sig],strlen(sig_name[sig]),
597 sub = stab_sub(stab);
598 if (!sub && *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
599 if (sig_name[sig][1] == 'H')
600 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CLD",3,TRUE)),
603 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CHLD",4,TRUE)),
605 sub = stab_sub(stab); /* gag */
609 warn("SIG%s handler \"%s\" not defined.\n",
610 sig_name[sig], stab_name(stab) );
613 savearray = stab_xarray(defstab);
614 stab_xarray(defstab) = stack = anew(defstab);
615 stack->ary_flags = 0;
617 str_set(str,sig_name[sig]);
618 (void)apush(stab_xarray(defstab),str);
620 if (sub->depth >= 2) { /* save temporaries on recursion? */
621 if (sub->depth == 100 && dowarn)
622 warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
623 savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
626 (void)cmd_exec(sub->cmd,G_SCALAR,1); /* so do it already */
628 sub->depth--; /* assuming no longjumps out of here */
629 str_free(stack->ary_array[0]); /* free the one real string */
630 stack->ary_array[0] = Nullstr;
631 afree(stab_xarray(defstab)); /* put back old $_[] */
632 stab_xarray(defstab) = savearray;
634 if (savestack->ary_fill > oldsave)
635 restorelist(oldsave);
644 if (!stab_xarray(stab))
645 stab_xarray(stab) = anew(stab);
653 if (!stab_xhash(stab))
654 stab_xhash(stab) = hnew(COEFFSIZE);
665 sprintf(tmpbuf,"'_<%s", name);
666 stab = stabent(tmpbuf, TRUE);
667 str_set(stab_val(stab), name);
669 (void)hadd(aadd(stab));
681 register char *namend;
683 char *sawquote = Nullch;
684 char *prevquote = Nullch;
687 if (isascii(*name) && isupper(*name)) {
689 if (*name == 'S' && (
690 strEQ(name, "SIG") ||
691 strEQ(name, "STDIN") ||
692 strEQ(name, "STDOUT") ||
693 strEQ(name, "STDERR") ))
696 else if (*name > 'E') {
697 if (*name == 'I' && strEQ(name, "INC"))
700 else if (*name > 'A') {
701 if (*name == 'E' && strEQ(name, "ENV"))
704 else if (*name == 'A' && (
705 strEQ(name, "ARGV") ||
706 strEQ(name, "ARGVOUT") ))
709 for (namend = name; *namend; namend++) {
710 if (*namend == '\'' && namend[1])
711 prevquote = sawquote, sawquote = namend;
713 if (sawquote == name && name[1]) {
718 else if (!isalpha(*name) || global)
720 else if (curcmd == &compiling)
723 stash = curcmd->c_stash;
730 strncpy(tmpbuf,name,s-name+1);
731 d = tmpbuf+(s-name+1);
737 strcpy(tmpbuf+1,name);
739 stab = stabent(tmpbuf,TRUE);
740 if (!(stash = stab_xhash(stab)))
741 stash = stab_xhash(stab) = hnew(0);
742 if (!stash->tbl_name)
743 stash->tbl_name = savestr(name);
748 stab = (STAB*)hfetch(stash,name,len,add);
749 if (stab == (STAB*)&str_undef)
752 stab->str_pok |= SP_MULTI;
757 Safefree(stab->str_ptr);
758 Newz(602,stbp, 1, STBP);
759 stab->str_ptr = stbp;
760 stab->str_len = stab->str_cur = sizeof(STBP);
762 strcpy(stab_magic(stab),"StB");
763 stab_val(stab) = Str_new(72,0);
764 stab_line(stab) = curcmd->c_line;
765 str_magic(stab,stab,'*',name,len);
766 stab_stash(stab) = stash;
767 if (isdigit(*name) && *name != '0') {
768 stab_flags(stab) = SF_VMAGIC;
769 str_magic(stab_val(stab), stab, 0, Nullch, 0);
775 stab_fullname(str,stab)
779 HASH *tb = stab_stash(stab);
783 str_set(str,tb->tbl_name);
784 str_ncat(str,"'", 1);
785 str_scat(str,stab->str_magic);
793 Newz(603,stio,1,STIO);
802 register HENT *entry;
806 for (i = min; i <= max; i++) {
807 for (entry = defstash->tbl_array[i]; entry; entry = entry->hent_next) {
808 stab = (STAB*)entry->hent_val;
809 if (stab->str_pok & SP_MULTI)
811 curcmd->c_line = stab_line(stab);
812 warn("Possible typo: \"%s\"", stab_name(stab));
817 static int gensym = 0;
822 (void)sprintf(tokenbuf,"_GEN_%d",gensym++);
823 return stabent(tokenbuf,TRUE);
826 /* hopefully this is only called on local symbol table entries */
835 afree(stab_xarray(stab));
836 stab_xarray(stab) = Null(ARRAY*);
837 (void)hfree(stab_xhash(stab), FALSE);
838 stab_xhash(stab) = Null(HASH*);
839 str_free(stab_val(stab));
840 stab_val(stab) = Nullstr;
841 if (stio = stab_io(stab)) {
842 do_close(stab,FALSE);
843 Safefree(stio->top_name);
844 Safefree(stio->fmt_name);
846 if (sub = stab_sub(stab)) {
850 Safefree(stab->str_ptr);
851 stab->str_ptr = Null(STBP*);
856 #if defined(CRIPPLED_CC) && (defined(iAPX286) || defined(M_I286) || defined(I80286))
860 #ifdef MICROPORT /* Microport 2.4 hack */
861 ARRAY *stab_array(stab)
864 if (((STBP*)(stab->str_ptr))->stbp_array)
865 return ((STBP*)(stab->str_ptr))->stbp_array;
867 return ((STBP*)(aadd(stab)->str_ptr))->stbp_array;
870 HASH *stab_hash(stab)
873 if (((STBP*)(stab->str_ptr))->stbp_hash)
874 return ((STBP*)(stab->str_ptr))->stbp_hash;
876 return ((STBP*)(hadd(stab)->str_ptr))->stbp_hash;
878 #endif /* Microport 2.4 hack */