Skip to content

Commit dbb62f2

Browse files
committed
promote gsub3 to the default - discard scaffolding
1 parent 6083bb0 commit dbb62f2

File tree

1 file changed

+2
-309
lines changed

1 file changed

+2
-309
lines changed

bi_funct.c

Lines changed: 2 additions & 309 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ the GNU General Public License, version 2, 1991.
1111
********************************************/
1212

1313
/*
14-
* $MawkId: bi_funct.c,v 1.100 2014/09/11 23:18:47 tom Exp $
14+
* $MawkId: bi_funct.c,v 1.101 2014/09/11 23:21:06 tom Exp $
1515
* @Log: bi_funct.c,v @
1616
* Revision 1.9 1996/01/14 17:16:11 mike
1717
* flush_all_output() before system()
@@ -90,8 +90,6 @@ the GNU General Public License, version 2, 1991.
9090
#include <windows.h>
9191
#endif
9292

93-
/* #define EXP_UNROLLED_GSUB 1 */
94-
9593
#if OPT_TRACE > 0
9694
#define return_CELL(func, cell) TRACE(("..." func " ->")); \
9795
TRACE_CELL(cell); \
@@ -1183,115 +1181,8 @@ bi_sub(CELL *sp)
11831181
return_CELL("bi_sub", sp);
11841182
}
11851183

1186-
#if !defined(EXP_UNROLLED_GSUB)
1187-
#define USE_GSUB0
1188-
#endif
1189-
1190-
#if defined(EXP_UNROLLED_GSUB)
1191-
#define USE_GSUB2
1192-
#endif
1193-
11941184
static unsigned repl_cnt; /* number of global replacements */
11951185

1196-
#ifdef USE_GSUB0
1197-
/* recursive global subsitution
1198-
dealing with empty matches makes this mildly painful
1199-
1200-
repl is always of type REPL or REPLV, destroyed by caller
1201-
flag is set if, match of empty string at front is OK
1202-
*/
1203-
1204-
static STRING *
1205-
gsub0(PTR re, CELL *repl, char *target, size_t target_len, int flag)
1206-
{
1207-
char *front = 0, *middle;
1208-
STRING *back;
1209-
size_t front_len, middle_len;
1210-
STRING *ret_val;
1211-
CELL xrepl; /* a copy of repl so we can change repl */
1212-
1213-
if (!(middle = REmatch(target, target_len, cast_to_re(re), &middle_len)))
1214-
return new_STRING(target); /* no match */
1215-
1216-
cellcpy(&xrepl, repl);
1217-
1218-
if (!flag && middle_len == 0 && middle == target) {
1219-
/* match at front that's not allowed */
1220-
1221-
if (*target == 0) { /* target is empty string */
1222-
repl_destroy(&xrepl);
1223-
null_str.ref_cnt++;
1224-
return &null_str;
1225-
} else if (1 && isAnchored(re)) {
1226-
repl_destroy(&xrepl);
1227-
return new_STRING1(target, target_len);
1228-
} else {
1229-
char xbuff[2];
1230-
1231-
front_len = 0;
1232-
/* make new repl with target[0] */
1233-
repl_destroy(repl);
1234-
--target_len;
1235-
xbuff[0] = *target++;
1236-
xbuff[1] = 0;
1237-
repl->type = C_REPL;
1238-
repl->ptr = (PTR) new_STRING(xbuff);
1239-
back = gsub0(re, &xrepl, target, target_len, 1);
1240-
}
1241-
} else { /* a match that counts */
1242-
repl_cnt++;
1243-
1244-
front = target;
1245-
front_len = (unsigned) (middle - target);
1246-
1247-
if (front_len == target_len) { /* matched back of target */
1248-
back = &null_str;
1249-
null_str.ref_cnt++;
1250-
} else {
1251-
back = gsub0(re,
1252-
&xrepl,
1253-
middle + middle_len,
1254-
target_len - (front_len + middle_len),
1255-
0);
1256-
}
1257-
1258-
/* patch the &'s if needed */
1259-
if (repl->type == C_REPLV) {
1260-
STRING *sval = new_STRING0(middle_len);
1261-
1262-
memcpy(sval->str, middle, middle_len);
1263-
replv_to_repl(repl, sval);
1264-
free_STRING(sval);
1265-
}
1266-
}
1267-
1268-
/* put the three pieces together */
1269-
ret_val = new_STRING0(front_len + string(repl)->len + back->len);
1270-
{
1271-
char *p = ret_val->str;
1272-
1273-
if (front_len) {
1274-
memcpy(p, front, front_len);
1275-
p += front_len;
1276-
}
1277-
1278-
if (string(repl)->len) {
1279-
memcpy(p, string(repl)->str, string(repl)->len);
1280-
p += string(repl)->len;
1281-
}
1282-
if (back->len)
1283-
memcpy(p, back->str, back->len);
1284-
}
1285-
1286-
/* cleanup, repl is freed by the caller */
1287-
repl_destroy(&xrepl);
1288-
free_STRING(back);
1289-
1290-
return ret_val;
1291-
}
1292-
#endif /* USE_GSUB0 */
1293-
1294-
#if defined(USE_GSUB3)
12951186
static STRING *
12961187
gsub3(PTR re, CELL *repl, CELL *target)
12971188
{
@@ -1437,161 +1328,6 @@ gsub3(PTR re, CELL *repl, CELL *target)
14371328
TRACE(("..done gsub3\n"));
14381329
return output;
14391330
}
1440-
#define my_gsub gsub3
1441-
#elif defined(USE_GSUB2)
1442-
static STRING *
1443-
gsub2(PTR re, CELL *repl, CELL *target)
1444-
{
1445-
int pass;
1446-
int j;
1447-
CELL xrepl;
1448-
STRING *input = string(target);
1449-
STRING *output = 0;
1450-
STRING *sval;
1451-
size_t want = 0;
1452-
size_t have;
1453-
size_t used;
1454-
1455-
TRACE(("called gsub2\n"));
1456-
1457-
/*
1458-
* If the replacement is constant, do it only once.
1459-
*/
1460-
if (repl->type != C_REPLV) {
1461-
cellcpy(&xrepl, repl);
1462-
} else {
1463-
memset(&xrepl, 0, sizeof(xrepl));
1464-
}
1465-
1466-
/*
1467-
* On the first pass, determine the size of the resulting string.
1468-
* On the second pass, actually apply changes - if any.
1469-
*/
1470-
for (pass = 0; pass < 2; ++pass) {
1471-
int skip0 = -1;
1472-
size_t howmuch;
1473-
char *where;
1474-
1475-
TRACE(("start pass %d\n", pass + 1));
1476-
repl_cnt = 0;
1477-
for (j = 0; j <= (int) input->len; ++j) {
1478-
if (isAnchored(re) && (j != 0)) {
1479-
where = 0;
1480-
} else {
1481-
where = REmatch(input->str + j,
1482-
input->len - (size_t) j,
1483-
cast_to_re(re),
1484-
&howmuch);
1485-
}
1486-
/*
1487-
* REmatch returns a non-null pointer if it found a match. But
1488-
* that can be an empty string, e.g., for "*" or "?". The length
1489-
* is in 'howmuch'.
1490-
*/
1491-
if (where != 0) {
1492-
have = (size_t) (where - (input->str + j));
1493-
if (have) {
1494-
skip0 = -1;
1495-
TRACE(("..before match:%d:", (int) have));
1496-
TRACE_STRING2(input->str + j, have);
1497-
TRACE(("\n"));
1498-
if (pass) {
1499-
memcpy(output->str + used, input->str + j, have);
1500-
used += have;
1501-
} else {
1502-
want += have;
1503-
}
1504-
}
1505-
1506-
TRACE(("REmatch %d vs %d len=%d:", (int) j, skip0, (int) howmuch));
1507-
TRACE_STRING2(where, howmuch);
1508-
TRACE(("\n"));
1509-
1510-
if (repl->type == C_REPLV) {
1511-
if (xrepl.ptr == 0 ||
1512-
string(&xrepl)->len != howmuch ||
1513-
(howmuch != 0 &&
1514-
memcmp(string(&xrepl)->str, where, howmuch))) {
1515-
if (xrepl.ptr != 0)
1516-
repl_destroy(&xrepl);
1517-
sval = new_STRING1(where, howmuch);
1518-
cellcpy(&xrepl, repl);
1519-
replv_to_repl(&xrepl, sval);
1520-
free_STRING(sval);
1521-
}
1522-
}
1523-
1524-
have = string(&xrepl)->len;
1525-
TRACE(("..replace:"));
1526-
TRACE_STRING2(string(&xrepl)->str, have);
1527-
TRACE(("\n"));
1528-
1529-
if (howmuch || (j != skip0)) {
1530-
++repl_cnt;
1531-
1532-
if (pass) {
1533-
memcpy(output->str + used, string(&xrepl)->str, have);
1534-
used += have;
1535-
} else {
1536-
want += have;
1537-
}
1538-
}
1539-
1540-
if (howmuch) {
1541-
j = (int) ((size_t) (where - input->str) + howmuch) - 1;
1542-
} else {
1543-
j = (int) (where - input->str);
1544-
if (j < (int) input->len) {
1545-
TRACE(("..emptied:"));
1546-
TRACE_STRING2(input->str + j, 1);
1547-
TRACE(("\n"));
1548-
if (pass) {
1549-
output->str[used++] = input->str[j];
1550-
} else {
1551-
++want;
1552-
}
1553-
}
1554-
}
1555-
skip0 = (howmuch != 0) ? (j + 1) : -1;
1556-
} else {
1557-
if (repl_cnt) {
1558-
have = (input->len - (size_t) j);
1559-
TRACE(("..after match:%d:", (int) have));
1560-
TRACE_STRING2(input->str + j, have);
1561-
TRACE(("\n"));
1562-
if (pass) {
1563-
memcpy(output->str + used, input->str + j, have);
1564-
} else {
1565-
want += have;
1566-
}
1567-
}
1568-
break;
1569-
}
1570-
}
1571-
1572-
if (!repl_cnt)
1573-
break;
1574-
1575-
TRACE(("..done pass %d\n", pass + 1));
1576-
if (!pass) {
1577-
output = new_STRING0(want);
1578-
used = 0;
1579-
TRACE(("..input %d ->output %d\n",
1580-
(int) input->len,
1581-
(int) output->len));
1582-
}
1583-
}
1584-
repl_destroy(&xrepl);
1585-
if (output == 0) {
1586-
output = new_STRING1(input->str, input->len);
1587-
}
1588-
TRACE(("..done gsub2\n"));
1589-
return output;
1590-
}
1591-
#define my_gsub gsub2
1592-
#endif
1593-
1594-
#ifdef EXP_UNROLLED_GSUB
15951331

15961332
/* set up for call to gsub() */
15971333
CELL *
@@ -1623,7 +1359,7 @@ bi_gsub(CELL *sp)
16231359
TRACE(("arg2: "));
16241360
TRACE_CELL(&sc);
16251361

1626-
result = my_gsub(sp->ptr, sp + 1, &sc);
1362+
result = gsub3(sp->ptr, sp + 1, &sc);
16271363
tc.ptr = (PTR) result;
16281364

16291365
if (repl_cnt) {
@@ -1647,46 +1383,3 @@ bi_gsub(CELL *sp)
16471383

16481384
return_CELL("bi_gsub", sp);
16491385
}
1650-
1651-
#else /* GSUB uses stack... */
1652-
/* set up for call to gsub() */
1653-
CELL *
1654-
bi_gsub(CELL *sp)
1655-
{
1656-
CELL *cp; /* pts at the replacement target */
1657-
CELL sc; /* copy of replacement target */
1658-
CELL tc; /* build the result here */
1659-
1660-
TRACE_FUNC("bi_gsub", sp);
1661-
1662-
sp -= 2;
1663-
if (sp->type != C_RE)
1664-
cast_to_RE(sp);
1665-
if ((sp + 1)->type != C_REPL && (sp + 1)->type != C_REPLV)
1666-
cast_to_REPL(sp + 1);
1667-
1668-
cellcpy(&sc, cp = (CELL *) (sp + 2)->ptr);
1669-
if (sc.type < C_STRING)
1670-
cast1_to_s(&sc);
1671-
1672-
repl_cnt = 0;
1673-
tc.ptr = (PTR) gsub0(sp->ptr, sp + 1,
1674-
string(&sc)->str,
1675-
string(&sc)->len, 1);
1676-
1677-
if (repl_cnt) {
1678-
tc.type = C_STRING;
1679-
slow_cell_assign(cp, &tc);
1680-
}
1681-
1682-
/* cleanup */
1683-
free_STRING(string(&sc));
1684-
free_STRING(string(&tc));
1685-
repl_destroy(sp + 1);
1686-
1687-
sp->type = C_DOUBLE;
1688-
sp->dval = (double) repl_cnt;
1689-
1690-
return_CELL("bi_gsub", sp);
1691-
}
1692-
#endif /* EXP_UNROLLED_GSUB */

0 commit comments

Comments
 (0)