diff options
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 35 |
1 files changed, 11 insertions, 24 deletions
@@ -482,7 +482,6 @@ PP(pp_formline) NV value; bool gotsome = FALSE; /* seen at least one non-blank item on this line */ STRLEN len; /* length of current sv */ - STRLEN linemax; /* estimate of output size in bytes */ bool item_is_utf8 = FALSE; bool targ_is_utf8 = FALSE; const char *fmt; @@ -505,10 +504,11 @@ PP(pp_formline) SvTAINTED_on(PL_formtarget); if (DO_UTF8(PL_formtarget)) targ_is_utf8 = TRUE; - /* this is an initial estimate of how much output buffer space - * to allocate. It may be exceeded later */ - linemax = (SvCUR(formsv) * (IN_BYTES ? 1 : 3) + 1); - t = SvGROW(PL_formtarget, len + linemax + 1); + /* Usually the output data will be the same size as the format, + * so this is a good first guess. Later on, @* or utf8 upgrades + * may trigger further growing. + */ + t = SvGROW(PL_formtarget, len + SvCUR(formsv) + 1); /* XXX from now onwards, SvCUR(PL_formtarget) is invalid */ t += len; f = SvPV_const(formsv, len); @@ -761,14 +761,12 @@ PP(pp_formline) * if trans, translate certain characters during the copy */ { U8 *tmp = NULL; - STRLEN grow = 0; + STRLEN cur = t - SvPVX_const(PL_formtarget); - SvCUR_set(PL_formtarget, - t - SvPVX_const(PL_formtarget)); + SvCUR_set(PL_formtarget, cur); if (targ_is_utf8 && !item_is_utf8) { source = tmp = bytes_to_utf8(source, &to_copy); - grow = to_copy; } else { if (item_is_utf8 && !targ_is_utf8) { U8 *s; @@ -776,14 +774,10 @@ PP(pp_formline) a problem we have a simple solution for. Don't need get magic. */ sv_utf8_upgrade_nomg(PL_formtarget); + cur = SvCUR(PL_formtarget); /* may have changed */ targ_is_utf8 = TRUE; /* re-calculate linemark */ s = (U8*)SvPVX(PL_formtarget); - /* the bytes we initially allocated to append the - * whole line may have been gobbled up during the - * upgrade, so allocate a whole new line's worth - * for safety */ - grow = linemax; while (linemark--) s += UTF8SKIP(s); linemark = s - (U8*)SvPVX(PL_formtarget); @@ -791,17 +785,10 @@ PP(pp_formline) /* Easy. They agree. */ assert (item_is_utf8 == targ_is_utf8); } - if (!trans) - /* @* and ^* are the only things that can exceed - * the linemax, so grow by the output size, plus - * a whole new form's worth in case of any further - * output */ - grow = linemax + to_copy; - if (grow) - SvGROW(PL_formtarget, SvCUR(PL_formtarget) + grow + 1); - t = SvPVX(PL_formtarget) + SvCUR(PL_formtarget); + t = SvGROW(PL_formtarget, cur + to_copy + 1) + cur; Copy(source, t, to_copy, char); + if (trans) { /* blank out ~ or control chars, depending on trans. * works on bytes not chars, so relies on not @@ -817,7 +804,7 @@ PP(pp_formline) } t += to_copy; - SvCUR_set(PL_formtarget, SvCUR(PL_formtarget) + to_copy); + SvCUR_set(PL_formtarget, cur + to_copy); if (tmp) Safefree(tmp); break; |