📄 stab.c
字号:
/* $RCSfile: stab.c,v $$Revision: 4.0.1.5 $$Date: 1993/02/05 19:42:47 $ * * Copyright (c) 1991, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * * $Log: stab.c,v $ * Revision 4.0.1.5 1993/02/05 19:42:47 lwall * patch36: length returned wrong value on certain semi-magical variables * * Revision 4.0.1.4 92/06/08 15:32:19 lwall * patch20: fixed confusion between a *var's real name and its effective name * patch20: the debugger now warns you on lines that can't set a breakpoint * patch20: the debugger made perl forget the last pattern used by // * patch20: paragraph mode now skips extra newlines automatically * patch20: ($<,$>) = ... didn't work on some architectures * * Revision 4.0.1.3 91/11/05 18:35:33 lwall * patch11: length($x) was sometimes wrong for numeric $x * patch11: perl now issues warning if $SIG{'ALARM'} is referenced * patch11: *foo = undef coredumped * patch11: solitary subroutine references no longer trigger typo warnings * patch11: local(*FILEHANDLE) had a memory leak * * Revision 4.0.1.2 91/06/07 11:55:53 lwall * patch4: new copyright notice * patch4: added $^P variable to control calling of perldb routines * patch4: added $^F variable to specify maximum system fd, default 2 * patch4: $` was busted inside s/// * patch4: default top-of-form format is now FILEHANDLE_TOP * patch4: length($`), length($&), length($') now optimized to avoid string copy * patch4: $^D |= 1024 now does syntax tree dump at run-time * * Revision 4.0.1.1 91/04/12 09:10:24 lwall * patch1: Configure now differentiates getgroups() type from getgid() type * patch1: you may now use "die" and "caller" in a signal handler * * Revision 4.0 91/03/20 01:39:41 lwall * 4.0 baseline. * */#include "EXTERN.h"#include "perl.h"#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)#include <signal.h>#endifstatic char *sig_name[] = { SIG_NAME,0};#ifdef VOIDSIG#define handlertype void#else#define handlertype int#endifstatic handlertype sighandler();static int origalen = 0;STR *stab_str(str)STR *str;{ STAB *stab = str->str_u.str_stab; register int paren; register char *s; register int i; if (str->str_rare) return stab_val(stab); switch (*stab->str_magic->str_ptr) { case '\004': /* ^D */#ifdef DEBUGGING str_numset(stab_val(stab),(double)(debug & 32767));#endif break; case '\006': /* ^F */ str_numset(stab_val(stab),(double)maxsysfd); break; case '\t': /* ^I */ if (inplace) str_set(stab_val(stab), inplace); else str_sset(stab_val(stab),&str_undef); break; case '\020': /* ^P */ str_numset(stab_val(stab),(double)perldb); break; case '\024': /* ^T */ str_numset(stab_val(stab),(double)basetime); break; case '\027': /* ^W */ str_numset(stab_val(stab),(double)dowarn); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '&': if (curspat) { paren = atoi(stab_ename(stab)); 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_val(stab),s,i); else str_sset(stab_val(stab),&str_undef); } else str_sset(stab_val(stab),&str_undef); } break; case '+': if (curspat) { paren = curspat->spat_regexp->lastparen; goto getparen; } break; case '`': if (curspat) { if (curspat->spat_regexp && (s = curspat->spat_regexp->subbeg) ) { i = curspat->spat_regexp->startp[0] - s; if (i >= 0) str_nset(stab_val(stab),s,i); else str_nset(stab_val(stab),"",0); } else str_nset(stab_val(stab),"",0); } break; case '\'': if (curspat) { if (curspat->spat_regexp && (s = curspat->spat_regexp->endp[0]) ) { str_nset(stab_val(stab),s, curspat->spat_regexp->subend - s); } else str_nset(stab_val(stab),"",0); } break; case '.':#ifndef lint if (last_in_stab && stab_io(last_in_stab)) { str_numset(stab_val(stab),(double)stab_io(last_in_stab)->lines); }#endif break; case '?': str_numset(stab_val(stab),(double)statusvalue); break; case '^': s = stab_io(curoutstab)->top_name; if (s) str_set(stab_val(stab),s); else { str_set(stab_val(stab),stab_ename(curoutstab)); str_cat(stab_val(stab),"_TOP"); } break; case '~': s = stab_io(curoutstab)->fmt_name; if (!s) s = stab_ename(curoutstab); str_set(stab_val(stab),s); break;#ifndef lint case '=': str_numset(stab_val(stab),(double)stab_io(curoutstab)->page_len); break; case '-': str_numset(stab_val(stab),(double)stab_io(curoutstab)->lines_left); break; case '%': str_numset(stab_val(stab),(double)stab_io(curoutstab)->page); break;#endif case ':': break; case '/': break; case '[': str_numset(stab_val(stab),(double)arybase); break; case '|': if (!stab_io(curoutstab)) stab_io(curoutstab) = stio_new(); str_numset(stab_val(stab), (double)((stab_io(curoutstab)->flags & IOF_FLUSH) != 0) ); break; case ',': str_nset(stab_val(stab),ofs,ofslen); break; case '\\': str_nset(stab_val(stab),ors,orslen); break; case '#': str_set(stab_val(stab),ofmt); break; case '!': str_numset(stab_val(stab), (double)errno); str_set(stab_val(stab), errno ? strerror(errno) : ""); stab_val(stab)->str_nok = 1; /* what a wonderful hack! */ break; case '<': str_numset(stab_val(stab),(double)uid); break; case '>': str_numset(stab_val(stab),(double)euid); break; case '(': s = buf; (void)sprintf(s,"%d",(int)gid); goto add_groups; case ')': s = buf; (void)sprintf(s,"%d",(int)egid); add_groups: while (*s) s++;#ifdef HAS_GETGROUPS#ifndef NGROUPS#define NGROUPS 32#endif { GROUPSTYPE gary[NGROUPS]; i = getgroups(NGROUPS,gary); while (--i >= 0) { (void)sprintf(s," %ld", (long)gary[i]); while (*s) s++; } }#endif str_set(stab_val(stab),buf); break; case '*': break; case '0': break; default: { struct ufuncs *uf = (struct ufuncs *)str->str_ptr; if (uf && uf->uf_val) (*uf->uf_val)(uf->uf_index, stab_val(stab)); } break; } return stab_val(stab);}STRLENstab_len(str)STR *str;{ STAB *stab = str->str_u.str_stab; int paren; int i; char *s; if (str->str_rare) return str_len(stab_val(stab)); switch (*stab->str_magic->str_ptr) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '&': if (curspat) { paren = atoi(stab_ename(stab)); 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) return i; else return 0; } else return 0; } break; case '+': if (curspat) { paren = curspat->spat_regexp->lastparen; goto getparen; } break; case '`': if (curspat) { if (curspat->spat_regexp && (s = curspat->spat_regexp->subbeg) ) { i = curspat->spat_regexp->startp[0] - s; if (i >= 0) return i; else return 0; } else return 0; } break; case '\'': if (curspat) { if (curspat->spat_regexp && (s = curspat->spat_regexp->endp[0]) ) { return (STRLEN) (curspat->spat_regexp->subend - s); } else return 0; } break; case ',': return (STRLEN)ofslen; case '\\': return (STRLEN)orslen; } return str_len(stab_str(str));}voidstabset(mstr,str)register STR *mstr;STR *str;{ STAB *stab; register char *s; int i; switch (mstr->str_rare) { case 'E': my_setenv(mstr->str_ptr,str_get(str)); /* And you'll never guess what the dog had */ /* in its mouth... */#ifdef TAINT if (strEQ(mstr->str_ptr,"PATH")) { char *strend = str->str_ptr + str->str_cur; s = str->str_ptr; while (s < strend) { s = cpytill(tokenbuf,s,strend,':',&i); s++; if (*tokenbuf != '/' || (stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) ) str->str_tainted = 2; } }#endif break; case 'S': s = str_get(str); i = whichsig(mstr->str_ptr); /* ...no, a brick */ if (!i && (dowarn || strEQ(mstr->str_ptr,"ALARM"))) warn("No such signal: SIG%s", mstr->str_ptr); if (strEQ(s,"IGNORE"))#ifndef lint (void)signal(i,SIG_IGN);#else ;#endif else if (strEQ(s,"DEFAULT") || !*s) (void)signal(i,SIG_DFL); else { (void)signal(i,sighandler); if (!index(s,'\'')) { sprintf(tokenbuf, "main'%s",s); str_set(str,tokenbuf); } } break;#ifdef SOME_DBM case 'D': stab = mstr->str_u.str_stab; hdbmstore(stab_hash(stab),mstr->str_ptr,mstr->str_cur,str); break;#endif case 'L': { CMD *cmd; stab = mstr->str_u.str_stab; i = str_true(str); str = afetch(stab_xarray(stab),atoi(mstr->str_ptr), FALSE); if (str->str_magic && (cmd = str->str_magic->str_u.str_cmd)) { cmd->c_flags &= ~CF_OPTIMIZE; cmd->c_flags |= i? CFT_D1 : CFT_D0; } else warn("Can't break at that line\n"); } break; case '#': stab = mstr->str_u.str_stab; afill(stab_array(stab), (int)str_gnum(str) - arybase); break; case 'X': /* merely a copy of a * string */ break; case '*': s = str->str_pok ? str_get(str) : ""; if (strNE(s,"StB") || str->str_cur != sizeof(STBP)) { stab = mstr->str_u.str_stab; if (!*s) { STBP *stbp; /*SUPPRESS 701*/ (void)savenostab(stab); /* schedule a free of this stab */ if (stab->str_len) Safefree(stab->str_ptr); Newz(601,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(70,0); stab_line(stab) = curcmd->c_line; stab_estab(stab) = stab; } else { stab = stabent(s,TRUE); if (!stab_xarray(stab)) aadd(stab); if (!stab_xhash(stab)) hadd(stab); if (!stab_io(stab)) stab_io(stab) = stio_new(); } str_sset(str, (STR*) stab); } break; case 's': { struct lstring *lstr = (struct lstring*)str; char *tmps; mstr->str_rare = 0; str->str_magic = Nullstr; tmps = str_get(str); str_insert(mstr,lstr->lstr_offset,lstr->lstr_len, tmps,str->str_cur); } break; case 'v': do_vecset(mstr,str); break; case 0: /*SUPPRESS 560*/ if (!(stab = mstr->str_u.str_stab)) break; switch (*stab->str_magic->str_ptr) { case '\004': /* ^D */#ifdef DEBUGGING debug = (int)(str_gnum(str)) | 32768; if (debug & 1024) dump_all();#endif break; case '\006': /* ^F */ maxsysfd = (int)str_gnum(str); break; case '\t': /* ^I */ if (inplace) Safefree(inplace); if (str->str_pok || str->str_nok) inplace = savestr(str_get(str)); else inplace = Nullch; break; case '\020': /* ^P */ i = (int)str_gnum(str); if (i != perldb) { static SPAT *oldlastspat; if (perldb) oldlastspat = lastspat; else lastspat = oldlastspat; } perldb = i; break; case '\024': /* ^T */ basetime = (time_t)str_gnum(str); break; case '\027': /* ^W */ dowarn = (bool)str_gnum(str); break; case '.': if (localizing) savesptr((STR**)&last_in_stab); break; case '^': Safefree(stab_io(curoutstab)->top_name); stab_io(curoutstab)->top_name = s = savestr(str_get(str)); stab_io(curoutstab)->top_stab = stabent(s,TRUE); break; case '~': Safefree(stab_io(curoutstab)->fmt_name); stab_io(curoutstab)->fmt_name = s = savestr(str_get(str)); stab_io(curoutstab)->fmt_stab = stabent(s,TRUE); break; case '=': stab_io(curoutstab)->page_len = (long)str_gnum(str); break; case '-': stab_io(curoutstab)->lines_left = (long)str_gnum(str); if (stab_io(curoutstab)->lines_left < 0L) stab_io(curoutstab)->lines_left = 0L; break; case '%': stab_io(curoutstab)->page = (long)str_gnum(str); break; case '|': if (!stab_io(curoutstab)) stab_io(curoutstab) = stio_new(); stab_io(curoutstab)->flags &= ~IOF_FLUSH; if (str_gnum(str) != 0.0) { stab_io(curoutstab)->flags |= IOF_FLUSH; } break; case '*':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -