@@ -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-
11941184static 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 )
12951186static STRING *
12961187gsub3 (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() */
15971333CELL *
@@ -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