📄 toke.c
字号:
term = '"'; while (isALNUM(*s)) *d++ = *s++; } /* assuming tokenbuf won't clobber */ *d++ = '\n'; *d = '\0'; len = d - tokenbuf; d = "\n"; if (rsfp || !(d=ninstr(s,bufend,d,d+1))) herewas = str_make(s,bufend-s); else s--, herewas = str_make(s,d-s); s += herewas->str_cur; if (term == '\'') goto do_single; if (term == '`') goto do_back; goto do_double; } d = tokenbuf; s = cpytill(d,s,bufend,'>',&len); if (s < bufend) s++; else fatal("Unterminated <> operator"); if (*d == '$') d++; while (*d && (isALNUM(*d) || *d == '\'')) d++; if (d - tokenbuf != len) { s = start; term = *s; arg[1].arg_type = A_GLOB; set_csh(); alwaysdollar = TRUE; /* treat $) and $| as variables */ goto snarf_it; } else { d = tokenbuf; if (!len) (void)strcpy(d,"ARGV"); if (*d == '$') { arg[1].arg_type = A_INDREAD; arg[1].arg_ptr.arg_stab = stabent(d+1,TRUE); } else { arg[1].arg_type = A_READ; arg[1].arg_ptr.arg_stab = stabent(d,TRUE); if (!stab_io(arg[1].arg_ptr.arg_stab)) stab_io(arg[1].arg_ptr.arg_stab) = stio_new(); if (strEQ(d,"ARGV")) { (void)aadd(arg[1].arg_ptr.arg_stab); stab_io(arg[1].arg_ptr.arg_stab)->flags |= IOF_ARGV|IOF_START; } } } break; case 'q': s++; if (*s == 'q') { s++; goto do_double; } if (*s == 'x') { s++; goto do_back; } /* FALL THROUGH */ case '\'': do_single: term = *s; arg[1].arg_type = A_SINGLE; leave = Nullch; goto snarf_it; case '"': do_double: term = *s; arg[1].arg_type = A_DOUBLE; makesingle = TRUE; /* maybe disable runtime scanning */ alwaysdollar = TRUE; /* treat $) and $| as variables */ goto snarf_it; case '`': do_back: term = *s; arg[1].arg_type = A_BACKTICK; set_csh(); alwaysdollar = TRUE; /* treat $) and $| as variables */ snarf_it: { STR *tmpstr; STR *tmpstr2 = Nullstr; char *tmps; char *start; bool dorange = FALSE; CLINE; multi_start = curcmd->c_line; if (hereis) multi_open = multi_close = '<'; else { multi_open = term; if (term && (tmps = index("([{< )]}> )]}>",term))) term = tmps[5]; multi_close = term; } tmpstr = Str_new(87,80); if (hereis) { term = *tokenbuf; if (!rsfp) { d = s; while (s < bufend && (*s != term || bcmp(s,tokenbuf,len) != 0) ) { if (*s++ == '\n') curcmd->c_line++; } if (s >= bufend) { curcmd->c_line = multi_start; fatal("EOF in string"); } str_nset(tmpstr,d+1,s-d); s += len - 1; str_ncat(herewas,s,bufend-s); str_replace(linestr,herewas); oldoldbufptr = oldbufptr = bufptr = s = str_get(linestr); bufend = linestr->str_ptr + linestr->str_cur; hereis = FALSE; } else str_nset(tmpstr,"",0); /* avoid "uninitialized" warning */ } else s = str_append_till(tmpstr,s+1,bufend,term,leave); while (s >= bufend) { /* multiple line string? */ if (!rsfp || !(oldoldbufptr = oldbufptr = s = str_gets(linestr, rsfp, 0))) { curcmd->c_line = multi_start; fatal("EOF in string"); } curcmd->c_line++; if (perldb) { STR *str = Str_new(88,0); str_sset(str,linestr); astore(stab_xarray(curcmd->c_filestab), (int)curcmd->c_line,str); } bufend = linestr->str_ptr + linestr->str_cur; if (hereis) { if (*s == term && bcmp(s,tokenbuf,len) == 0) { s = bufend - 1; *s = ' '; str_scat(linestr,herewas); bufend = linestr->str_ptr + linestr->str_cur; } else { s = bufend; str_scat(tmpstr,linestr); } } else s = str_append_till(tmpstr,s,bufend,term,leave); } multi_end = curcmd->c_line; s++; if (tmpstr->str_cur + 5 < tmpstr->str_len) { tmpstr->str_len = tmpstr->str_cur + 1; Renew(tmpstr->str_ptr, tmpstr->str_len, char); } if (arg[1].arg_type == A_SINGLE) { arg[1].arg_ptr.arg_str = tmpstr; break; } tmps = s; s = tmpstr->str_ptr; send = s + tmpstr->str_cur; while (s < send) { /* see if we can make SINGLE */ if (*s == '\\' && s[1] && isDIGIT(s[1]) && !isDIGIT(s[2]) && !alwaysdollar && s[1] != '0') *s = '$'; /* grandfather \digit in subst */ if ((*s == '$' || *s == '@') && s+1 < send && (alwaysdollar || (s[1] != ')' && s[1] != '|'))) { makesingle = FALSE; /* force interpretation */ } else if (*s == '\\' && s+1 < send) { if (index("lLuUE",s[1])) makesingle = FALSE; s++; } s++; } s = d = start = tmpstr->str_ptr; /* assuming shrinkage only */ while (s < send || dorange) { if (in_what & SCAN_TR) { if (dorange) { int i; int max; if (!tmpstr2) { /* oops, have to grow */ tmpstr2 = str_smake(tmpstr); s = tmpstr2->str_ptr + (s - tmpstr->str_ptr); send = tmpstr2->str_ptr + (send - tmpstr->str_ptr); } i = d - tmpstr->str_ptr; STR_GROW(tmpstr, tmpstr->str_len + 256); d = tmpstr->str_ptr + i; d -= 2; max = d[1] & 0377; for (i = (*d & 0377); i <= max; i++) *d++ = i; start = s; dorange = FALSE; continue; } else if (*s == '-' && s+1 < send && s != start) { dorange = TRUE; s++; } } else { if ((*s == '$' && s+1 < send && (alwaysdollar || /*(*/(s[1] != ')' && s[1] != '|')) ) || (*s == '@' && s+1 < send) ) { if (s[1] == '#' && (isALPHA(s[2]) || s[2] == '_')) *d++ = *s++; len = scanident(s,send,tokenbuf) - s; if (*s == '$' || strEQ(tokenbuf,"ARGV") || strEQ(tokenbuf,"ENV") || strEQ(tokenbuf,"SIG") || strEQ(tokenbuf,"INC") ) (void)stabent(tokenbuf,TRUE); /* add symbol */ while (len--) *d++ = *s++; continue; } } if (*s == '\\' && s+1 < send) { s++; switch (*s) { case '-': if (in_what & SCAN_TR) { *d++ = *s++; continue; } /* FALL THROUGH */ default: if (!makesingle && (!leave || (*s && index(leave,*s)))) *d++ = '\\'; *d++ = *s++; continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': *d++ = scanoct(s, 3, &len); s += len; continue; case 'x': *d++ = scanhex(++s, 2, &len); s += len; continue; case 'c': s++; *d = *s++; if (isLOWER(*d)) *d = toupper(*d); *d++ ^= 64; continue; case 'b': *d++ = '\b'; break; case 'n': *d++ = '\n'; break; case 'r': *d++ = '\r'; break; case 'f': *d++ = '\f'; break; case 't': *d++ = '\t'; break; case 'e': *d++ = '\033'; break; case 'a': *d++ = '\007'; break; } s++; continue; } *d++ = *s++; } *d = '\0'; if (arg[1].arg_type == A_DOUBLE && makesingle) arg[1].arg_type = A_SINGLE; /* now we can optimize on it */ tmpstr->str_cur = d - tmpstr->str_ptr; if (arg[1].arg_type == A_GLOB) { arg[1].arg_ptr.arg_stab = stab = genstab(); stab_io(stab) = stio_new(); str_sset(stab_val(stab), tmpstr); } else arg[1].arg_ptr.arg_str = tmpstr; s = tmps; if (tmpstr2) str_free(tmpstr2); break; } } if (hereis) str_free(herewas); return s;}FCMD *load_format(){ FCMD froot; FCMD *flinebeg; char *eol; register FCMD *fprev = &froot; register FCMD *fcmd; register char *s; register char *t; register STR *str; bool noblank; bool repeater; Zero(&froot, 1, FCMD); s = bufptr; while (s < bufend || (rsfp && (s = str_gets(linestr,rsfp, 0)) != Nullch)) { curcmd->c_line++; if (in_eval && !rsfp) { eol = index(s,'\n'); if (!eol++) eol = bufend; } else eol = bufend = linestr->str_ptr + linestr->str_cur; if (perldb) { STR *tmpstr = Str_new(89,0); str_nset(tmpstr, s, eol-s); astore(stab_xarray(curcmd->c_filestab), (int)curcmd->c_line,tmpstr); } if (*s == '.') { /*SUPPRESS 530*/ for (t = s+1; *t == ' ' || *t == '\t'; t++) ; if (*t == '\n') { bufptr = s; return froot.f_next; } } if (*s == '#') { s = eol; continue; } flinebeg = Nullfcmd; noblank = FALSE; repeater = FALSE; while (s < eol) { Newz(804,fcmd,1,FCMD); fprev->f_next = fcmd; fprev = fcmd; for (t=s; t < eol && *t != '@' && *t != '^'; t++) { if (*t == '~') { noblank = TRUE; *t = ' '; if (t[1] == '~') { repeater = TRUE; t[1] = ' '; } } } fcmd->f_pre = nsavestr(s, t-s); fcmd->f_presize = t-s; s = t; if (s >= eol) { if (noblank) fcmd->f_flags |= FC_NOBLANK; if (repeater) fcmd->f_flags |= FC_REPEAT; break; } if (!flinebeg) flinebeg = fcmd; /* start values here */ if (*s++ == '^') fcmd->f_flags |= FC_CHOP; /* for doing text filling */ switch (*s) { case '*': fcmd->f_type = F_LINES; *s = '\0'; break; case '<': fcmd->f_type = F_LEFT; while (*s == '<') s++; break; case '>': fcmd->f_type = F_RIGHT; while (*s == '>') s++; break; case '|': fcmd->f_type = F_CENTER; while (*s == '|') s++; break; case '#': case '.': /* Catch the special case @... and handle it as a string field. */ if (*s == '.' && s[1] == '.') { goto default_format; } fcmd->f_type = F_DECIMAL; { char *p; /* Read a format in the form @####.####, where either group of ### may be empty, or the final .### may be missing. */ while (*s == '#') s++; if (*s == '.') { s++; p = s; while (*s == '#') s++; fcmd->f_decimals = s-p; fcmd->f_flags |= FC_DP; } else { fcmd->f_decimals = 0; } } break; default: default_format: fcmd->f_type = F_LEFT; break; } if (fcmd->f_flags & FC_CHOP && *s == '.') { fcmd->f_flags |= FC_MORE; while (*s == '.') s++; } fcmd->f_size = s-t; } if (flinebeg) { again: if (s >= bufend && (!rsfp || (s = str_gets(linestr, rsfp, 0)) == Nullch) ) goto badform; curcmd->c_line++; if (in_eval && !rsfp) { eol = index(s,'\n'); if (!eol++) eol = bufend; } else eol = bufend = linestr->str_ptr + linestr->str_cur; if (perldb) { STR *tmpstr = Str_new(90,0); str_nset(tmpstr, s, eol-s); astore(stab_xarray(curcmd->c_filestab), (int)curcmd->c_line,tmpstr); } if (strnEQ(s,".\n",2)) { bufptr = s; yyerror("Missing values line"); return froot.f_next; } if (*s == '#') { s = eol; goto again; } str = flinebeg->f_unparsed = Str_new(91,eol - s); str->str_u.str_hash = curstash; str_nset(str,"(",1); flinebeg->f_line = curcmd->c_line; eol[-1] = '\0'; if (!flinebeg->f_next->f_type || index(s, ',')) { eol[-1] = '\n'; str_ncat(str, s, eol - s - 1); str_ncat(str,",$$);",5); s = eol; } else { eol[-1] = '\n'; while (s < eol && isSPACE(*s)) s++; t = s; while (s < eol) { switch (*s) { case ' ': case '\t': case '\n': case ';': str_ncat(str, t, s - t); str_ncat(str, "," ,1); while (s < eol && (isSPACE(*s) || *s == ';')) s++; t = s; break; case '$': str_ncat(str, t, s - t); t = s; s = scanident(s,eol,tokenbuf); str_ncat(str, t, s - t); t = s; if (s < eol && *s && index("$'\"",*s)) str_ncat(str, ",", 1); break; case '"': case '\'': str_ncat(str, t, s - t); t = s; s++; while (s < eol && (*s != *t || s[-1] == '\\')) s++; if (s < eol) s++; str_ncat(str, t, s - t); t = s; if (s < eol && *s && index("$'\"",*s)) str_ncat(str, ",", 1); break; default: yyerror("Please use commas to separate fields"); } } str_ncat(str,"$$);",4); } } } badform: bufptr = str_get(linestr); yyerror("Format not terminated"); return froot.f_next;}static voidset_csh(){#ifdef CSH if (!cshlen) cshlen = strlen(cshname);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -