diff options
Diffstat (limited to 'formstuff')
-rw-r--r-- | formstuff | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/formstuff b/formstuff new file mode 100644 index 0000000000..f0e47241c0 --- /dev/null +++ b/formstuff @@ -0,0 +1,223 @@ +FF * +parse_format() +{ + FF froot; + FF *flinebeg; + char *eol; + register FF *fprev = &froot; + register FF *fcmd; + register char *s; + register char *t; + register SV *sv; + bool noblank; + bool repeater; + + Zero(&froot, 1, FF); + s = bufptr; + while (s < bufend || (rsfp && (s = sv_gets(linestr,rsfp, 0)) != Nullch)) { + curcop->cop_line++; + if (in_eval && !rsfp) { + eol = index(s,'\n'); + if (!eol++) + eol = bufend; + } + else + eol = bufend = linestr->sv_ptr + linestr->sv_cur; + if (perldb) { + SV *tmpstr = NEWSV(89,0); + + sv_setpvn(tmpstr, s, eol-s); + av_store(GvAV(curcop->cop_filegv), (int)curcop->cop_line,tmpstr); + } + if (*s == '.') { + /*SUPPRESS 530*/ + for (t = s+1; *t == ' ' || *t == '\t'; t++) ; + if (*t == '\n') { + bufptr = s; + return froot.ff_next; + } + } + if (*s == '#') { + s = eol; + continue; + } + flinebeg = Nullfield; + noblank = FALSE; + repeater = FALSE; + while (s < eol) { + Newz(804,fcmd,1,FF); + fprev->ff_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->ff_pre = nsavestr(s, t-s); + fcmd->ff_presize = t-s; + s = t; + if (s >= eol) { + if (noblank) + fcmd->ff_flags |= FFf_NOBLANK; + if (repeater) + fcmd->ff_flags |= FFf_REPEAT; + break; + } + if (!flinebeg) + flinebeg = fcmd; /* start values here */ + if (*s++ == '^') + fcmd->ff_flags |= FFf_CHOP; /* for doing text filling */ + switch (*s) { + case '*': + fcmd->ff_type = FFt_LINES; + *s = '\0'; + break; + case '<': + fcmd->ff_type = FFt_LEFT; + while (*s == '<') + s++; + break; + case '>': + fcmd->ff_type = FFt_RIGHT; + while (*s == '>') + s++; + break; + case '|': + fcmd->ff_type = FFt_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->ff_type = FFt_DECIMAL; + { + char *p; + + /* Read a run_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->ff_decimals = s-p; + fcmd->ff_flags |= FFf_DP; + } else { + fcmd->ff_decimals = 0; + } + } + break; + default: + default_format: + fcmd->ff_type = FFt_LEFT; + break; + } + if (fcmd->ff_flags & FFf_CHOP && *s == '.') { + fcmd->ff_flags |= FFf_MORE; + while (*s == '.') + s++; + } + fcmd->ff_size = s-t; + } + if (flinebeg) { + again: + if (s >= bufend && + (!rsfp || (s = sv_gets(linestr, rsfp, 0)) == Nullch) ) + goto badform; + curcop->cop_line++; + if (in_eval && !rsfp) { + eol = index(s,'\n'); + if (!eol++) + eol = bufend; + } + else + eol = bufend = linestr->sv_ptr + linestr->sv_cur; + if (perldb) { + SV *tmpstr = NEWSV(90,0); + + sv_setpvn(tmpstr, s, eol-s); + av_store(GvAV(curcop->cop_filegv), + (int)curcop->cop_line,tmpstr); + } + if (strnEQ(s,".\n",2)) { + bufptr = s; + yyerror("Missing values line"); + return froot.ff_next; + } + if (*s == '#') { + s = eol; + goto again; + } + sv = flinebeg->ff_unparsed = NEWSV(91,eol - s); + sv->sv_u.sv_hv = curstash; + sv_setpvn(sv,"(",1); + flinebeg->ff_line = curcop->cop_line; + eol[-1] = '\0'; + if (!flinebeg->ff_next->ff_type || index(s, ',')) { + eol[-1] = '\n'; + sv_catpvn(sv, s, eol - s - 1); + sv_catpvn(sv,",$$);",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 ';': + sv_catpvn(sv, t, s - t); + sv_catpvn(sv, "," ,1); + while (s < eol && (isSPACE(*s) || *s == ';')) + s++; + t = s; + break; + case '$': + sv_catpvn(sv, t, s - t); + t = s; + s = scan_ident(s,eol,tokenbuf,FALSE); + sv_catpvn(sv, t, s - t); + t = s; + if (s < eol && *s && index("$'\"",*s)) + sv_catpvn(sv, ",", 1); + break; + case '"': case '\'': + sv_catpvn(sv, t, s - t); + t = s; + s++; + while (s < eol && (*s != *t || s[-1] == '\\')) + s++; + if (s < eol) + s++; + sv_catpvn(sv, t, s - t); + t = s; + if (s < eol && *s && index("$'\"",*s)) + sv_catpvn(sv, ",", 1); + break; + default: + yyerror("Please use commas to separate fields"); + } + } + sv_catpvn(sv,"$$);",4); + } + } + } + badform: + bufptr = SvPV(linestr); + yyerror("Format not terminated"); + return froot.ff_next; +} + |