1 /* $Header: stab.c,v 3.0.1.6 90/03/27 16:22:11 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.6 90/03/27 16:22:11 lwall
10 * patch16: support for machines that can't cast negative floats to unsigned ints
12 * Revision 3.0.1.5 90/03/12 17:00:11 lwall
13 * patch13: undef $/ didn't work as advertised
15 * Revision 3.0.1.4 90/02/28 18:19:14 lwall
16 * patch9: $0 is now always the command name
17 * patch9: you may now undef $/ to have no input record separator
18 * patch9: local($.) didn't work
19 * patch9: sometimes perl thought ordinary data was a symbol table entry
20 * patch9: stab_array() and stab_hash() weren't defined on MICROPORT
22 * Revision 3.0.1.3 89/12/21 20:18:40 lwall
23 * patch7: ANSI strerror() is now supported
24 * patch7: errno may now be a macro with an lvalue
25 * patch7: in stab.c, sighandler() may now return either void or int
27 * Revision 3.0.1.2 89/11/17 15:35:37 lwall
28 * patch5: sighandler() needed to be static
30 * Revision 3.0.1.1 89/11/11 04:55:07 lwall
31 * patch2: sys_errlist[sys_nerr] is illegal
33 * Revision 3.0 89/10/18 15:23:23 lwall
43 static char *sig_name[] = {
48 #define handlertype void
50 #define handlertype int
57 STAB *stab = str->str_u.str_stab;
63 return stab_val(stab);
65 switch (*stab->str_magic->str_ptr) {
66 case '1': case '2': case '3': case '4':
67 case '5': case '6': case '7': case '8': case '9': case '&':
69 paren = atoi(stab_name(stab));
71 if (curspat->spat_regexp &&
72 paren <= curspat->spat_regexp->nparens &&
73 (s = curspat->spat_regexp->startp[paren]) ) {
74 i = curspat->spat_regexp->endp[paren] - s;
76 str_nset(stab_val(stab),s,i);
78 str_sset(stab_val(stab),&str_undef);
81 str_sset(stab_val(stab),&str_undef);
86 paren = curspat->spat_regexp->lastparen;
92 if (curspat->spat_regexp &&
93 (s = curspat->spat_regexp->subbase) ) {
94 i = curspat->spat_regexp->startp[0] - s;
96 str_nset(stab_val(stab),s,i);
98 str_nset(stab_val(stab),"",0);
101 str_nset(stab_val(stab),"",0);
106 if (curspat->spat_regexp &&
107 (s = curspat->spat_regexp->endp[0]) ) {
108 str_set(stab_val(stab),s);
111 str_nset(stab_val(stab),"",0);
117 str_numset(stab_val(stab),(double)stab_io(last_in_stab)->lines);
122 str_numset(stab_val(stab),(double)statusvalue);
125 s = stab_io(curoutstab)->top_name;
126 str_set(stab_val(stab),s);
129 s = stab_io(curoutstab)->fmt_name;
130 str_set(stab_val(stab),s);
134 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page_len);
137 str_numset(stab_val(stab),(double)stab_io(curoutstab)->lines_left);
140 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page);
144 if (record_separator != 12345) {
145 *tokenbuf = record_separator;
147 str_nset(stab_val(stab),tokenbuf,rslen);
151 str_numset(stab_val(stab),(double)arybase);
154 str_numset(stab_val(stab),
155 (double)((stab_io(curoutstab)->flags & IOF_FLUSH) != 0) );
158 str_nset(stab_val(stab),ofs,ofslen);
161 str_nset(stab_val(stab),ors,orslen);
164 str_set(stab_val(stab),ofmt);
167 str_numset(stab_val(stab), (double)errno);
168 str_set(stab_val(stab), strerror(errno));
169 stab_val(stab)->str_nok = 1; /* what a wonderful hack! */
172 str_numset(stab_val(stab),(double)uid);
175 str_numset(stab_val(stab),(double)euid);
179 (void)sprintf(s,"%d",(int)gid);
183 (void)sprintf(s,"%d",(int)egid);
191 GIDTYPE gary[NGROUPS];
193 i = getgroups(NGROUPS,gary);
195 (void)sprintf(s," %ld", (long)gary[i]);
200 str_set(stab_val(stab),buf);
203 return stab_val(stab);
210 STAB *stab = mstr->str_u.str_stab;
213 static handlertype sighandler();
215 switch (mstr->str_rare) {
217 setenv(mstr->str_ptr,str_get(str));
218 /* And you'll never guess what the dog had */
219 break; /* in its mouth... */
222 i = whichsig(mstr->str_ptr); /* ...no, a brick */
223 if (strEQ(s,"IGNORE"))
225 (void)signal(i,SIG_IGN);
229 else if (strEQ(s,"DEFAULT") || !*s)
230 (void)signal(i,SIG_DFL);
232 (void)signal(i,sighandler);
236 hdbmstore(stab_hash(stab),mstr->str_ptr,mstr->str_cur,str);
240 afill(stab_array(stab), (int)str_gnum(str) - arybase);
242 case 'X': /* merely a copy of a * string */
246 if (strNE(s,"StB") || str->str_cur != sizeof(STBP)) {
250 (void)savenostab(stab); /* schedule a free of this stab */
252 Safefree(stab->str_ptr);
253 Newz(601,stbp, 1, STBP);
254 stab->str_ptr = stbp;
255 stab->str_len = stab->str_cur = sizeof(STBP);
257 strcpy(stab_magic(stab),"StB");
258 stab_val(stab) = Str_new(70,0);
259 stab_line(stab) = line;
262 stab = stabent(s,TRUE);
267 struct lstring *lstr = (struct lstring*)str;
270 str->str_magic = Nullstr;
271 str_insert(mstr,lstr->lstr_offset,lstr->lstr_len,
272 str->str_ptr,str->str_cur);
281 switch (*stab->str_magic->str_ptr) {
284 savesptr((STR**)&last_in_stab);
287 Safefree(stab_io(curoutstab)->top_name);
288 stab_io(curoutstab)->top_name = s = savestr(str_get(str));
289 stab_io(curoutstab)->top_stab = stabent(s,TRUE);
292 Safefree(stab_io(curoutstab)->fmt_name);
293 stab_io(curoutstab)->fmt_name = s = savestr(str_get(str));
294 stab_io(curoutstab)->fmt_stab = stabent(s,TRUE);
297 stab_io(curoutstab)->page_len = (long)str_gnum(str);
300 stab_io(curoutstab)->lines_left = (long)str_gnum(str);
301 if (stab_io(curoutstab)->lines_left < 0L)
302 stab_io(curoutstab)->lines_left = 0L;
305 stab_io(curoutstab)->page = (long)str_gnum(str);
308 stab_io(curoutstab)->flags &= ~IOF_FLUSH;
309 if (str_gnum(str) != 0.0) {
310 stab_io(curoutstab)->flags |= IOF_FLUSH;
314 i = (int)str_gnum(str);
315 multiline = (i != 0);
319 record_separator = *str_get(str);
320 rslen = str->str_cur;
323 record_separator = 12345; /* fake a non-existent char */
330 ors = savestr(str_get(str));
331 orslen = str->str_cur;
336 ofs = savestr(str_get(str));
337 ofslen = str->str_cur;
342 ofmt = savestr(str_get(str));
345 arybase = (int)str_gnum(str);
348 statusvalue = U_S(str_gnum(str));
351 errno = (int)str_gnum(str); /* will anyone ever use this? */
354 uid = (int)str_gnum(str);
357 delaymagic |= DM_REUID;
358 break; /* don't do magic till later */
360 #endif /* SETREUID */
362 if (setruid((UIDTYPE)uid) < 0)
366 if (setreuid((UIDTYPE)uid, (UIDTYPE)-1) < 0)
369 fatal("setruid() not implemented");
374 euid = (int)str_gnum(str);
377 delaymagic |= DM_REUID;
378 break; /* don't do magic till later */
380 #endif /* SETREUID */
382 if (seteuid((UIDTYPE)euid) < 0)
383 euid = (int)geteuid();
386 if (setreuid((UIDTYPE)-1, (UIDTYPE)euid) < 0)
387 euid = (int)geteuid();
389 fatal("seteuid() not implemented");
394 gid = (int)str_gnum(str);
397 delaymagic |= DM_REGID;
398 break; /* don't do magic till later */
400 #endif /* SETREGID */
402 (void)setrgid((GIDTYPE)gid);
405 (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
407 fatal("setrgid() not implemented");
412 egid = (int)str_gnum(str);
415 delaymagic |= DM_REGID;
416 break; /* don't do magic till later */
418 #endif /* SETREGID */
420 (void)setegid((GIDTYPE)egid);
423 (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
425 fatal("setegid() not implemented");
430 chopset = str_get(str);
440 register char **sigv;
442 for (sigv = sig_name+1; *sigv; sigv++)
443 if (strEQ(sig,*sigv))
444 return sigv - sig_name;
446 if (strEQ(sig,"CHLD"))
450 if (strEQ(sig,"CLD"))
463 char *oldfile = filename;
464 int oldsave = savestack->ary_fill;
465 ARRAY *oldstack = stack;
469 str_get(hfetch(stab_hash(sigstab),sig_name[sig],strlen(sig_name[sig]),
471 sub = stab_sub(stab);
472 if (!sub && *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
473 if (sig_name[sig][1] == 'H')
474 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CLD",3,TRUE)),
477 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CHLD",4,TRUE)),
479 sub = stab_sub(stab); /* gag */
483 warn("SIG%s handler \"%s\" not defined.\n",
484 sig_name[sig], stab_name(stab) );
487 savearray = stab_xarray(defstab);
488 stab_xarray(defstab) = stack = anew(defstab);
489 stack->ary_flags = 0;
491 str_set(str,sig_name[sig]);
492 (void)apush(stab_xarray(defstab),str);
494 if (sub->depth >= 2) { /* save temporaries on recursion? */
495 if (sub->depth == 100 && dowarn)
496 warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
497 savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
499 filename = sub->filename;
501 (void)cmd_exec(sub->cmd,G_SCALAR,1); /* so do it already */
503 sub->depth--; /* assuming no longjumps out of here */
504 str_free(stack->ary_array[0]); /* free the one real string */
505 afree(stab_xarray(defstab)); /* put back old $_[] */
506 stab_xarray(defstab) = savearray;
509 if (savestack->ary_fill > oldsave)
510 restorelist(oldsave);
517 if (!stab_xarray(stab))
518 stab_xarray(stab) = anew(stab);
526 if (!stab_xhash(stab))
527 stab_xhash(stab) = hnew(COEFFSIZE);
539 register char *namend;
541 char *sawquote = Nullch;
542 char *prevquote = Nullch;
545 if (isascii(*name) && isupper(*name)) {
547 if (*name == 'S' && (
548 strEQ(name, "SIG") ||
549 strEQ(name, "STDIN") ||
550 strEQ(name, "STDOUT") ||
551 strEQ(name, "STDERR") ))
554 else if (*name > 'E') {
555 if (*name == 'I' && strEQ(name, "INC"))
558 else if (*name >= 'A') {
559 if (*name == 'E' && strEQ(name, "ENV"))
562 else if (*name == 'A' && (
563 strEQ(name, "ARGV") ||
564 strEQ(name, "ARGVOUT") ))
567 for (namend = name; *namend; namend++) {
568 if (*namend == '\'' && namend[1])
569 prevquote = sawquote, sawquote = namend;
571 if (sawquote == name && name[1]) {
576 else if (!isalpha(*name) || global)
586 strncpy(tmpbuf,name,s-name+1);
587 d = tmpbuf+(s-name+1);
593 strcpy(tmpbuf+1,name);
595 stab = stabent(tmpbuf,TRUE);
596 if (!(stash = stab_xhash(stab)))
597 stash = stab_xhash(stab) = hnew(0);
602 stab = (STAB*)hfetch(stash,name,len,add);
606 stab->str_pok |= SP_MULTI;
611 Safefree(stab->str_ptr);
612 Newz(602,stbp, 1, STBP);
613 stab->str_ptr = stbp;
614 stab->str_len = stab->str_cur = sizeof(STBP);
616 strcpy(stab_magic(stab),"StB");
617 stab_val(stab) = Str_new(72,0);
618 stab_line(stab) = line;
619 str_magic(stab,stab,'*',name,len);
629 Newz(603,stio,1,STIO);
638 register HENT *entry;
642 for (i = min; i <= max; i++) {
643 for (entry = defstash->tbl_array[i]; entry; entry = entry->hent_next) {
644 stab = (STAB*)entry->hent_val;
645 if (stab->str_pok & SP_MULTI)
647 line = stab_line(stab);
648 warn("Possible typo: \"%s\"", stab_name(stab));
653 static int gensym = 0;
658 (void)sprintf(tokenbuf,"_GEN_%d",gensym++);
659 return stabent(tokenbuf,TRUE);
662 /* hopefully this is only called on local symbol table entries */
671 afree(stab_xarray(stab));
672 (void)hfree(stab_xhash(stab));
673 str_free(stab_val(stab));
674 if (stio = stab_io(stab)) {
675 do_close(stab,FALSE);
676 Safefree(stio->top_name);
677 Safefree(stio->fmt_name);
679 if (sub = stab_sub(stab)) {
683 Safefree(stab->str_ptr);
684 stab->str_ptr = Null(STBP*);
689 #if defined(CRIPPLED_CC) && (defined(iAPX286) || defined(M_I286) || defined(I80286))
693 #ifdef MICROPORT /* Microport 2.4 hack */
694 ARRAY *stab_array(stab)
697 if (((STBP*)(stab->str_ptr))->stbp_array)
698 return ((STBP*)(stab->str_ptr))->stbp_array;
700 return ((STBP*)(aadd(stab)->str_ptr))->stbp_array;
703 HASH *stab_hash(stab)
706 if (((STBP*)(stab->str_ptr))->stbp_hash)
707 return ((STBP*)(stab->str_ptr))->stbp_hash;
709 return ((STBP*)(hadd(stab)->str_ptr))->stbp_hash;
711 #endif /* Microport 2.4 hack */