📄 stab.c
字号:
i = (int)str_gnum(str); multiline = (i != 0); break; case '/': if (str->str_pok) { rs = str_get(str); rslen = str->str_cur; if (rspara = !rslen) { rs = "\n\n"; rslen = 2; } rschar = rs[rslen - 1]; } else { rschar = 0777; /* fake a non-existent char */ rslen = 1; } break; case '\\': if (ors) Safefree(ors); ors = savestr(str_get(str)); orslen = str->str_cur; break; case ',': if (ofs) Safefree(ofs); ofs = savestr(str_get(str)); ofslen = str->str_cur; break; case '#': if (ofmt) Safefree(ofmt); ofmt = savestr(str_get(str)); break; case '[': arybase = (int)str_gnum(str); break; case '?': statusvalue = U_S(str_gnum(str)); break; case '!': errno = (int)str_gnum(str); /* will anyone ever use this? */ break; case '<': uid = (int)str_gnum(str); if (delaymagic) { delaymagic |= DM_RUID; break; /* don't do magic till later */ }#ifdef HAS_SETRUID (void)setruid((UIDTYPE)uid);#else#ifdef HAS_SETREUID (void)setreuid((UIDTYPE)uid, (UIDTYPE)-1);#else if (uid == euid) /* special case $< = $> */ (void)setuid(uid); else fatal("setruid() not implemented");#endif#endif uid = (int)getuid(); break; case '>': euid = (int)str_gnum(str); if (delaymagic) { delaymagic |= DM_EUID; break; /* don't do magic till later */ }#ifdef HAS_SETEUID (void)seteuid((UIDTYPE)euid);#else#ifdef HAS_SETREUID (void)setreuid((UIDTYPE)-1, (UIDTYPE)euid);#else if (euid == uid) /* special case $> = $< */ setuid(euid); else fatal("seteuid() not implemented");#endif#endif euid = (int)geteuid(); break; case '(': gid = (int)str_gnum(str); if (delaymagic) { delaymagic |= DM_RGID; break; /* don't do magic till later */ }#ifdef HAS_SETRGID (void)setrgid((GIDTYPE)gid);#else#ifdef HAS_SETREGID (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);#else if (gid == egid) /* special case $( = $) */ (void)setgid(gid); else fatal("setrgid() not implemented");#endif#endif gid = (int)getgid(); break; case ')': egid = (int)str_gnum(str); if (delaymagic) { delaymagic |= DM_EGID; break; /* don't do magic till later */ }#ifdef HAS_SETEGID (void)setegid((GIDTYPE)egid);#else#ifdef HAS_SETREGID (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);#else if (egid == gid) /* special case $) = $( */ (void)setgid(egid); else fatal("setegid() not implemented");#endif#endif egid = (int)getegid(); break; case ':': chopset = str_get(str); break; case '0': if (!origalen) { s = origargv[0]; s += strlen(s); /* See if all the arguments are contiguous in memory */ for (i = 1; i < origargc; i++) { if (origargv[i] == s + 1) s += strlen(++s); /* this one is ok too */ } if (origenviron[0] == s + 1) { /* can grab env area too? */ my_setenv("NoNeSuCh", Nullch); /* force copy of environment */ for (i = 0; origenviron[i]; i++) if (origenviron[i] == s + 1) s += strlen(++s); } origalen = s - origargv[0]; } s = str_get(str); i = str->str_cur; if (i >= origalen) { i = origalen; str->str_cur = i; str->str_ptr[i] = '\0'; Copy(s, origargv[0], i, char); } else { Copy(s, origargv[0], i, char); s = origargv[0]+i; *s++ = '\0'; while (++i < origalen) *s++ = ' '; } break; default: { struct ufuncs *uf = (struct ufuncs *)str->str_magic->str_ptr; if (uf && uf->uf_set) (*uf->uf_set)(uf->uf_index, str); } break; } break; }}intwhichsig(sig)char *sig;{ register char **sigv; for (sigv = sig_name+1; *sigv; sigv++) if (strEQ(sig,*sigv)) return sigv - sig_name;#ifdef SIGCLD if (strEQ(sig,"CHLD")) return SIGCLD;#endif#ifdef SIGCHLD if (strEQ(sig,"CLD")) return SIGCHLD;#endif return 0;}static handlertypesighandler(sig)int sig;{ STAB *stab; STR *str; int oldsave = savestack->ary_fill; int oldtmps_base = tmps_base; register CSV *csv; SUBR *sub;#ifdef OS2 /* or anybody else who requires SIG_ACK */ signal(sig, SIG_ACK);#endif stab = stabent( str_get(hfetch(stab_hash(sigstab),sig_name[sig],strlen(sig_name[sig]), TRUE)), TRUE); sub = stab_sub(stab); if (!sub && *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) { if (sig_name[sig][1] == 'H') stab = stabent(str_get(hfetch(stab_hash(sigstab),"CLD",3,TRUE)), TRUE); else stab = stabent(str_get(hfetch(stab_hash(sigstab),"CHLD",4,TRUE)), TRUE); sub = stab_sub(stab); /* gag */ } if (!sub) { if (dowarn) warn("SIG%s handler \"%s\" not defined.\n", sig_name[sig], stab_ename(stab) ); return; } /*SUPPRESS 701*/ saveaptr(&stack); str = Str_new(15, sizeof(CSV)); str->str_state = SS_SCSV; (void)apush(savestack,str); csv = (CSV*)str->str_ptr; csv->sub = sub; csv->stab = stab; csv->curcsv = curcsv; csv->curcmd = curcmd; csv->depth = sub->depth; csv->wantarray = G_SCALAR; csv->hasargs = TRUE; csv->savearray = stab_xarray(defstab); csv->argarray = stab_xarray(defstab) = stack = anew(defstab); stack->ary_flags = 0; curcsv = csv; str = str_mortal(&str_undef); str_set(str,sig_name[sig]); (void)apush(stab_xarray(defstab),str); sub->depth++; if (sub->depth >= 2) { /* save temporaries on recursion? */ if (sub->depth == 100 && dowarn) warn("Deep recursion on subroutine \"%s\"",stab_ename(stab)); savelist(sub->tosave->ary_array,sub->tosave->ary_fill); } tmps_base = tmps_max; /* protect our mortal string */ (void)cmd_exec(sub->cmd,G_SCALAR,0); /* so do it already */ tmps_base = oldtmps_base; restorelist(oldsave); /* put everything back */}STAB *aadd(stab)register STAB *stab;{ if (!stab_xarray(stab)) stab_xarray(stab) = anew(stab); return stab;}STAB *hadd(stab)register STAB *stab;{ if (!stab_xhash(stab)) stab_xhash(stab) = hnew(COEFFSIZE); return stab;}STAB *fstab(name)char *name;{ char tmpbuf[1200]; STAB *stab; sprintf(tmpbuf,"'_<%s", name); stab = stabent(tmpbuf, TRUE); str_set(stab_val(stab), name); if (perldb) (void)hadd(aadd(stab)); return stab;}STAB *stabent(name,add)register char *name;int add;{ register STAB *stab; register STBP *stbp; int len; register char *namend; HASH *stash; char *sawquote = Nullch; char *prevquote = Nullch; bool global = FALSE; if (isUPPER(*name)) { if (*name > 'I') { if (*name == 'S' && ( strEQ(name, "SIG") || strEQ(name, "STDIN") || strEQ(name, "STDOUT") || strEQ(name, "STDERR") )) global = TRUE; } else if (*name > 'E') { if (*name == 'I' && strEQ(name, "INC")) global = TRUE; } else if (*name > 'A') { if (*name == 'E' && strEQ(name, "ENV")) global = TRUE; } else if (*name == 'A' && ( strEQ(name, "ARGV") || strEQ(name, "ARGVOUT") )) global = TRUE; } for (namend = name; *namend; namend++) { if (*namend == '\'' && namend[1]) prevquote = sawquote, sawquote = namend; } if (sawquote == name && name[1]) { stash = defstash; sawquote = Nullch; name++; } else if (!isALPHA(*name) || global) stash = defstash; else if ((CMD*)curcmd == &compiling) stash = curstash; else stash = curcmd->c_stash; if (sawquote) { char tmpbuf[256]; char *s, *d; *sawquote = '\0'; /*SUPPRESS 560*/ if (s = prevquote) { strncpy(tmpbuf,name,s-name+1); d = tmpbuf+(s-name+1); *d++ = '_'; strcpy(d,s+1); } else { *tmpbuf = '_'; strcpy(tmpbuf+1,name); } stab = stabent(tmpbuf,TRUE); if (!(stash = stab_xhash(stab))) stash = stab_xhash(stab) = hnew(0); if (!stash->tbl_name) stash->tbl_name = savestr(name); name = sawquote+1; *sawquote = '\''; } len = namend - name; stab = (STAB*)hfetch(stash,name,len,add); if (stab == (STAB*)&str_undef) return Nullstab; if (stab->str_pok) { stab->str_pok |= SP_MULTI; return stab; } else { if (stab->str_len) Safefree(stab->str_ptr); Newz(602,stbp, 1, STBP); stab->str_ptr = stbp; stab->str_len = stab->str_cur = sizeof(STBP); stab->str_pok = 1; strcpy(stab_magic(stab),"StB"); stab_val(stab) = Str_new(72,0); stab_line(stab) = curcmd->c_line; stab_estab(stab) = stab; str_magic((STR*)stab, stab, '*', name, len); stab_stash(stab) = stash; if (isDIGIT(*name) && *name != '0') { stab_flags(stab) = SF_VMAGIC; str_magic(stab_val(stab), stab, 0, Nullch, 0); } if (add & 2) stab->str_pok |= SP_MULTI; return stab; }}voidstab_fullname(str,stab)STR *str;STAB *stab;{ HASH *tb = stab_stash(stab); if (!tb) return; str_set(str,tb->tbl_name); str_ncat(str,"'", 1); str_scat(str,stab->str_magic);}voidstab_efullname(str,stab)STR *str;STAB *stab;{ HASH *tb = stab_estash(stab); if (!tb) return; str_set(str,tb->tbl_name); str_ncat(str,"'", 1); str_scat(str,stab_estab(stab)->str_magic);}STIO *stio_new(){ STIO *stio; Newz(603,stio,1,STIO); stio->page_len = 60; return stio;}voidstab_check(min,max)int min;register int max;{ register HENT *entry; register int i; register STAB *stab; for (i = min; i <= max; i++) { for (entry = defstash->tbl_array[i]; entry; entry = entry->hent_next) { stab = (STAB*)entry->hent_val; if (stab->str_pok & SP_MULTI) continue; curcmd->c_line = stab_line(stab); warn("Possible typo: \"%s\"", stab_name(stab)); } }}static int gensym = 0;STAB *genstab(){ (void)sprintf(tokenbuf,"_GEN_%d",gensym++); return stabent(tokenbuf,TRUE);}/* hopefully this is only called on local symbol table entries */voidstab_clear(stab)register STAB *stab;{ STIO *stio; SUBR *sub; if (!stab || !stab->str_ptr) return; afree(stab_xarray(stab)); stab_xarray(stab) = Null(ARRAY*); (void)hfree(stab_xhash(stab), FALSE); stab_xhash(stab) = Null(HASH*); str_free(stab_val(stab)); stab_val(stab) = Nullstr; /*SUPPRESS 560*/ if (stio = stab_io(stab)) { do_close(stab,FALSE); Safefree(stio->top_name); Safefree(stio->fmt_name); Safefree(stio); } /*SUPPRESS 560*/ if (sub = stab_sub(stab)) { afree(sub->tosave); cmd_free(sub->cmd); } Safefree(stab->str_ptr); stab->str_ptr = Null(STBP*); stab->str_len = 0; stab->str_cur = 0;}#if defined(CRIPPLED_CC) && (defined(iAPX286) || defined(M_I286) || defined(I80286))#define MICROPORT#endif#ifdef MICROPORT /* Microport 2.4 hack */ARRAY *stab_array(stab)register STAB *stab;{ if (((STBP*)(stab->str_ptr))->stbp_array) return ((STBP*)(stab->str_ptr))->stbp_array; else return ((STBP*)(aadd(stab)->str_ptr))->stbp_array;}HASH *stab_hash(stab)register STAB *stab;{ if (((STBP*)(stab->str_ptr))->stbp_hash) return ((STBP*)(stab->str_ptr))->stbp_hash; else return ((STBP*)(hadd(stab)->str_ptr))->stbp_hash;}#endif /* Microport 2.4 hack */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -