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; }