1 /* $Header: stab.c,v 3.0.1.4 90/02/28 18:19:14 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 3.0.1.4 90/02/28 18:19:14 lwall
10 * patch9: $0 is now always the command name
11 * patch9: you may now undef $/ to have no input record separator
12 * patch9: local($.) didn't work
13 * patch9: sometimes perl thought ordinary data was a symbol table entry
14 * patch9: stab_array() and stab_hash() weren't defined on MICROPORT
16 * Revision 3.0.1.3 89/12/21 20:18:40 lwall
17 * patch7: ANSI strerror() is now supported
18 * patch7: errno may now be a macro with an lvalue
19 * patch7: in stab.c, sighandler() may now return either void or int
21 * Revision 3.0.1.2 89/11/17 15:35:37 lwall
22 * patch5: sighandler() needed to be static
24 * Revision 3.0.1.1 89/11/11 04:55:07 lwall
25 * patch2: sys_errlist[sys_nerr] is illegal
27 * Revision 3.0 89/10/18 15:23:23 lwall
37 static char *sig_name[] = {
42 #define handlertype void
44 #define handlertype int
51 STAB *stab = str->str_u.str_stab;
57 return stab_val(stab);
59 switch (*stab->str_magic->str_ptr) {
60 case '1': case '2': case '3': case '4':
61 case '5': case '6': case '7': case '8': case '9': case '&':
63 paren = atoi(stab_name(stab));
65 if (curspat->spat_regexp &&
66 paren <= curspat->spat_regexp->nparens &&
67 (s = curspat->spat_regexp->startp[paren]) ) {
68 i = curspat->spat_regexp->endp[paren] - s;
70 str_nset(stab_val(stab),s,i);
72 str_sset(stab_val(stab),&str_undef);
75 str_sset(stab_val(stab),&str_undef);
80 paren = curspat->spat_regexp->lastparen;
86 if (curspat->spat_regexp &&
87 (s = curspat->spat_regexp->subbase) ) {
88 i = curspat->spat_regexp->startp[0] - s;
90 str_nset(stab_val(stab),s,i);
92 str_nset(stab_val(stab),"",0);
95 str_nset(stab_val(stab),"",0);
100 if (curspat->spat_regexp &&
101 (s = curspat->spat_regexp->endp[0]) ) {
102 str_set(stab_val(stab),s);
105 str_nset(stab_val(stab),"",0);
111 str_numset(stab_val(stab),(double)stab_io(last_in_stab)->lines);
116 str_numset(stab_val(stab),(double)statusvalue);
119 s = stab_io(curoutstab)->top_name;
120 str_set(stab_val(stab),s);
123 s = stab_io(curoutstab)->fmt_name;
124 str_set(stab_val(stab),s);
128 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page_len);
131 str_numset(stab_val(stab),(double)stab_io(curoutstab)->lines_left);
134 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page);
138 if (record_separator != 12345) {
139 *tokenbuf = record_separator;
141 str_nset(stab_val(stab),tokenbuf,rslen);
145 str_numset(stab_val(stab),(double)arybase);
148 str_numset(stab_val(stab),
149 (double)((stab_io(curoutstab)->flags & IOF_FLUSH) != 0) );
152 str_nset(stab_val(stab),ofs,ofslen);
155 str_nset(stab_val(stab),ors,orslen);
158 str_set(stab_val(stab),ofmt);
161 str_numset(stab_val(stab), (double)errno);
162 str_set(stab_val(stab), strerror(errno));
163 stab_val(stab)->str_nok = 1; /* what a wonderful hack! */
166 str_numset(stab_val(stab),(double)uid);
169 str_numset(stab_val(stab),(double)euid);
173 (void)sprintf(s,"%d",(int)gid);
177 (void)sprintf(s,"%d",(int)egid);
185 GIDTYPE gary[NGROUPS];
187 i = getgroups(NGROUPS,gary);
189 (void)sprintf(s," %ld", (long)gary[i]);
194 str_set(stab_val(stab),buf);
197 return stab_val(stab);
204 STAB *stab = mstr->str_u.str_stab;
207 static handlertype sighandler();
209 switch (mstr->str_rare) {
211 setenv(mstr->str_ptr,str_get(str));
212 /* And you'll never guess what the dog had */
213 break; /* in its mouth... */
216 i = whichsig(mstr->str_ptr); /* ...no, a brick */
217 if (strEQ(s,"IGNORE"))
219 (void)signal(i,SIG_IGN);
223 else if (strEQ(s,"DEFAULT") || !*s)
224 (void)signal(i,SIG_DFL);
226 (void)signal(i,sighandler);
230 hdbmstore(stab_hash(stab),mstr->str_ptr,mstr->str_cur,str);
234 afill(stab_array(stab), (int)str_gnum(str) - arybase);
236 case 'X': /* merely a copy of a * string */
240 if (strNE(s,"StB") || str->str_cur != sizeof(STBP)) {
244 (void)savenostab(stab); /* schedule a free of this stab */
246 Safefree(stab->str_ptr);
247 Newz(601,stbp, 1, STBP);
248 stab->str_ptr = stbp;
249 stab->str_len = stab->str_cur = sizeof(STBP);
251 strcpy(stab_magic(stab),"StB");
252 stab_val(stab) = Str_new(70,0);
253 stab_line(stab) = line;
256 stab = stabent(s,TRUE);
261 struct lstring *lstr = (struct lstring*)str;
264 str->str_magic = Nullstr;
265 str_insert(mstr,lstr->lstr_offset,lstr->lstr_len,
266 str->str_ptr,str->str_cur);
275 switch (*stab->str_magic->str_ptr) {
278 savesptr((STR**)&last_in_stab);
281 Safefree(stab_io(curoutstab)->top_name);
282 stab_io(curoutstab)->top_name = s = savestr(str_get(str));
283 stab_io(curoutstab)->top_stab = stabent(s,TRUE);
286 Safefree(stab_io(curoutstab)->fmt_name);
287 stab_io(curoutstab)->fmt_name = s = savestr(str_get(str));
288 stab_io(curoutstab)->fmt_stab = stabent(s,TRUE);
291 stab_io(curoutstab)->page_len = (long)str_gnum(str);
294 stab_io(curoutstab)->lines_left = (long)str_gnum(str);
295 if (stab_io(curoutstab)->lines_left < 0L)
296 stab_io(curoutstab)->lines_left = 0L;
299 stab_io(curoutstab)->page = (long)str_gnum(str);
302 stab_io(curoutstab)->flags &= ~IOF_FLUSH;
303 if (str_gnum(str) != 0.0) {
304 stab_io(curoutstab)->flags |= IOF_FLUSH;
308 i = (int)str_gnum(str);
309 multiline = (i != 0);
313 record_separator = *str_get(str);
314 rslen = str->str_cur;
317 record_separator = 12345; /* fake a non-existent char */
324 ors = savestr(str_get(str));
325 orslen = str->str_cur;
330 ofs = savestr(str_get(str));
331 ofslen = str->str_cur;
336 ofmt = savestr(str_get(str));
339 arybase = (int)str_gnum(str);
342 statusvalue = (unsigned short)str_gnum(str);
345 errno = (int)str_gnum(str); /* will anyone ever use this? */
348 uid = (int)str_gnum(str);
351 delaymagic |= DM_REUID;
352 break; /* don't do magic till later */
354 #endif /* SETREUID */
356 if (setruid((UIDTYPE)uid) < 0)
360 if (setreuid((UIDTYPE)uid, (UIDTYPE)-1) < 0)
363 fatal("setruid() not implemented");
368 euid = (int)str_gnum(str);
371 delaymagic |= DM_REUID;
372 break; /* don't do magic till later */
374 #endif /* SETREUID */
376 if (seteuid((UIDTYPE)euid) < 0)
377 euid = (int)geteuid();
380 if (setreuid((UIDTYPE)-1, (UIDTYPE)euid) < 0)
381 euid = (int)geteuid();
383 fatal("seteuid() not implemented");
388 gid = (int)str_gnum(str);
391 delaymagic |= DM_REGID;
392 break; /* don't do magic till later */
394 #endif /* SETREGID */
396 (void)setrgid((GIDTYPE)gid);
399 (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
401 fatal("setrgid() not implemented");
406 egid = (int)str_gnum(str);
409 delaymagic |= DM_REGID;
410 break; /* don't do magic till later */
412 #endif /* SETREGID */
414 (void)setegid((GIDTYPE)egid);
417 (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
419 fatal("setegid() not implemented");
424 chopset = str_get(str);
434 register char **sigv;
436 for (sigv = sig_name+1; *sigv; sigv++)
437 if (strEQ(sig,*sigv))
438 return sigv - sig_name;
440 if (strEQ(sig,"CHLD"))
444 if (strEQ(sig,"CLD"))
457 char *oldfile = filename;
458 int oldsave = savestack->ary_fill;
459 ARRAY *oldstack = stack;
463 str_get(hfetch(stab_hash(sigstab),sig_name[sig],strlen(sig_name[sig]),
465 sub = stab_sub(stab);
466 if (!sub && *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
467 if (sig_name[sig][1] == 'H')
468 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CLD",3,TRUE)),
471 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CHLD",4,TRUE)),
473 sub = stab_sub(stab); /* gag */
477 warn("SIG%s handler \"%s\" not defined.\n",
478 sig_name[sig], stab_name(stab) );
481 savearray = stab_xarray(defstab);
482 stab_xarray(defstab) = stack = anew(defstab);
483 stack->ary_flags = 0;
485 str_set(str,sig_name[sig]);
486 (void)apush(stab_xarray(defstab),str);
488 if (sub->depth >= 2) { /* save temporaries on recursion? */
489 if (sub->depth == 100 && dowarn)
490 warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
491 savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
493 filename = sub->filename;
495 (void)cmd_exec(sub->cmd,G_SCALAR,1); /* so do it already */
497 sub->depth--; /* assuming no longjumps out of here */
498 str_free(stack->ary_array[0]); /* free the one real string */
499 afree(stab_xarray(defstab)); /* put back old $_[] */
500 stab_xarray(defstab) = savearray;
503 if (savestack->ary_fill > oldsave)
504 restorelist(oldsave);
511 if (!stab_xarray(stab))
512 stab_xarray(stab) = anew(stab);
520 if (!stab_xhash(stab))
521 stab_xhash(stab) = hnew(COEFFSIZE);
533 register char *namend;
535 char *sawquote = Nullch;
536 char *prevquote = Nullch;
539 if (isascii(*name) && isupper(*name)) {
541 if (*name == 'S' && (
542 strEQ(name, "SIG") ||
543 strEQ(name, "STDIN") ||
544 strEQ(name, "STDOUT") ||
545 strEQ(name, "STDERR") ))
548 else if (*name > 'E') {
549 if (*name == 'I' && strEQ(name, "INC"))
552 else if (*name >= 'A') {
553 if (*name == 'E' && strEQ(name, "ENV"))
556 else if (*name == 'A' && (
557 strEQ(name, "ARGV") ||
558 strEQ(name, "ARGVOUT") ))
561 for (namend = name; *namend; namend++) {
562 if (*namend == '\'' && namend[1])
563 prevquote = sawquote, sawquote = namend;
565 if (sawquote == name && name[1]) {
570 else if (!isalpha(*name) || global)
580 strncpy(tmpbuf,name,s-name+1);
581 d = tmpbuf+(s-name+1);
587 strcpy(tmpbuf+1,name);
589 stab = stabent(tmpbuf,TRUE);
590 if (!(stash = stab_xhash(stab)))
591 stash = stab_xhash(stab) = hnew(0);
596 stab = (STAB*)hfetch(stash,name,len,add);
600 stab->str_pok |= SP_MULTI;
605 Safefree(stab->str_ptr);
606 Newz(602,stbp, 1, STBP);
607 stab->str_ptr = stbp;
608 stab->str_len = stab->str_cur = sizeof(STBP);
610 strcpy(stab_magic(stab),"StB");
611 stab_val(stab) = Str_new(72,0);
612 stab_line(stab) = line;
613 str_magic(stab,stab,'*',name,len);
623 Newz(603,stio,1,STIO);
632 register HENT *entry;
636 for (i = min; i <= max; i++) {
637 for (entry = defstash->tbl_array[i]; entry; entry = entry->hent_next) {
638 stab = (STAB*)entry->hent_val;
639 if (stab->str_pok & SP_MULTI)
641 line = stab_line(stab);
642 warn("Possible typo: \"%s\"", stab_name(stab));
647 static int gensym = 0;
652 (void)sprintf(tokenbuf,"_GEN_%d",gensym++);
653 return stabent(tokenbuf,TRUE);
656 /* hopefully this is only called on local symbol table entries */
665 afree(stab_xarray(stab));
666 (void)hfree(stab_xhash(stab));
667 str_free(stab_val(stab));
668 if (stio = stab_io(stab)) {
669 do_close(stab,FALSE);
670 Safefree(stio->top_name);
671 Safefree(stio->fmt_name);
673 if (sub = stab_sub(stab)) {
677 Safefree(stab->str_ptr);
678 stab->str_ptr = Null(STBP*);
683 #if defined(CRIPPLED_CC) && (defined(iAPX286) || defined(M_I286) || defined(I80286))
687 #ifdef MICROPORT /* Microport 2.4 hack */
688 ARRAY *stab_array(stab)
691 if (((STBP*)(stab->str_ptr))->stbp_array)
692 return ((STBP*)(stab->str_ptr))->stbp_array;
694 return ((STBP*)(aadd(stab)->str_ptr))->stbp_array;
697 HASH *stab_hash(stab)
700 if (((STBP*)(stab->str_ptr))->stbp_hash)
701 return ((STBP*)(stab->str_ptr))->stbp_hash;
703 return ((STBP*)(hadd(stab)->str_ptr))->stbp_hash;
705 #endif /* Microport 2.4 hack */