comparison src/search.c @ 12807:34d269b30df1

(Freplace_match): New arg SUBEXP.
author Richard M. Stallman <rms@gnu.org>
date Tue, 08 Aug 1995 21:20:07 +0000
parents ac7375e60931
children 1aa239b8d03c
comparison
equal deleted inserted replaced
12806:826ee893ebdf 12807:34d269b30df1
1499 Lisp_Object regexp, bound, noerror, count; 1499 Lisp_Object regexp, bound, noerror, count;
1500 { 1500 {
1501 return search_command (regexp, bound, noerror, count, 1, 1, 1); 1501 return search_command (regexp, bound, noerror, count, 1, 1, 1);
1502 } 1502 }
1503 1503
1504 DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 4, 0, 1504 DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 5, 0,
1505 "Replace text matched by last search with NEWTEXT.\n\ 1505 "Replace text matched by last search with NEWTEXT.\n\
1506 If second arg FIXEDCASE is non-nil, do not alter case of replacement text.\n\ 1506 If second arg FIXEDCASE is non-nil, do not alter case of replacement text.\n\
1507 Otherwise maybe capitalize the whole text, or maybe just word initials,\n\ 1507 Otherwise maybe capitalize the whole text, or maybe just word initials,\n\
1508 based on the replaced text.\n\ 1508 based on the replaced text.\n\
1509 If the replaced text has only capital letters\n\ 1509 If the replaced text has only capital letters\n\
1519 FIXEDCASE and LITERAL are optional arguments.\n\ 1519 FIXEDCASE and LITERAL are optional arguments.\n\
1520 Leaves point at end of replacement text.\n\ 1520 Leaves point at end of replacement text.\n\
1521 \n\ 1521 \n\
1522 The optional fourth argument STRING can be a string to modify.\n\ 1522 The optional fourth argument STRING can be a string to modify.\n\
1523 In that case, this function creates and returns a new string\n\ 1523 In that case, this function creates and returns a new string\n\
1524 which is made by replacing the part of STRING that was matched.") 1524 which is made by replacing the part of STRING that was matched.\n\
1525 (newtext, fixedcase, literal, string) 1525 \n\
1526 Lisp_Object newtext, fixedcase, literal, string; 1526 The optional fifth argument SUBEXP specifies a subexpression of the match.\n\
1527 It says to replace just that subexpression instead of the whole match.\n\
1528 This is useful only after a regular expression search or match\n\
1529 since only regular expressions have distinguished subexpressions.")
1530 (newtext, fixedcase, literal, string, subexp)
1531 Lisp_Object newtext, fixedcase, literal, string, subexp;
1527 { 1532 {
1528 enum { nochange, all_caps, cap_initial } case_action; 1533 enum { nochange, all_caps, cap_initial } case_action;
1529 register int pos, last; 1534 register int pos, last;
1530 int some_multiletter_word; 1535 int some_multiletter_word;
1531 int some_lowercase; 1536 int some_lowercase;
1532 int some_uppercase; 1537 int some_uppercase;
1533 int some_nonuppercase_initial; 1538 int some_nonuppercase_initial;
1534 register int c, prevc; 1539 register int c, prevc;
1535 int inslen; 1540 int inslen;
1541 int sub;
1536 1542
1537 CHECK_STRING (newtext, 0); 1543 CHECK_STRING (newtext, 0);
1538 1544
1539 if (! NILP (string)) 1545 if (! NILP (string))
1540 CHECK_STRING (string, 4); 1546 CHECK_STRING (string, 4);
1543 /* but some C compilers blew it */ 1549 /* but some C compilers blew it */
1544 1550
1545 if (search_regs.num_regs <= 0) 1551 if (search_regs.num_regs <= 0)
1546 error ("replace-match called before any match found"); 1552 error ("replace-match called before any match found");
1547 1553
1554 if (NILP (subexp))
1555 sub = 0;
1556 else
1557 {
1558 CHECK_NUMBER (subexp, 3);
1559 sub = XINT (subexp);
1560 if (sub < 0 || sub >= search_regs.num_regs)
1561 args_out_of_range (subexp, make_number (search_regs.num_regs));
1562 }
1563
1548 if (NILP (string)) 1564 if (NILP (string))
1549 { 1565 {
1550 if (search_regs.start[0] < BEGV 1566 if (search_regs.start[sub] < BEGV
1551 || search_regs.start[0] > search_regs.end[0] 1567 || search_regs.start[sub] > search_regs.end[sub]
1552 || search_regs.end[0] > ZV) 1568 || search_regs.end[sub] > ZV)
1553 args_out_of_range (make_number (search_regs.start[0]), 1569 args_out_of_range (make_number (search_regs.start[sub]),
1554 make_number (search_regs.end[0])); 1570 make_number (search_regs.end[sub]));
1555 } 1571 }
1556 else 1572 else
1557 { 1573 {
1558 if (search_regs.start[0] < 0 1574 if (search_regs.start[sub] < 0
1559 || search_regs.start[0] > search_regs.end[0] 1575 || search_regs.start[sub] > search_regs.end[sub]
1560 || search_regs.end[0] > XSTRING (string)->size) 1576 || search_regs.end[sub] > XSTRING (string)->size)
1561 args_out_of_range (make_number (search_regs.start[0]), 1577 args_out_of_range (make_number (search_regs.start[sub]),
1562 make_number (search_regs.end[0])); 1578 make_number (search_regs.end[sub]));
1563 } 1579 }
1564 1580
1565 if (NILP (fixedcase)) 1581 if (NILP (fixedcase))
1566 { 1582 {
1567 /* Decide how to casify by examining the matched text. */ 1583 /* Decide how to casify by examining the matched text. */
1568 1584
1569 last = search_regs.end[0]; 1585 last = search_regs.end[sub];
1570 prevc = '\n'; 1586 prevc = '\n';
1571 case_action = all_caps; 1587 case_action = all_caps;
1572 1588
1573 /* some_multiletter_word is set nonzero if any original word 1589 /* some_multiletter_word is set nonzero if any original word
1574 is more than one letter long. */ 1590 is more than one letter long. */
1575 some_multiletter_word = 0; 1591 some_multiletter_word = 0;
1576 some_lowercase = 0; 1592 some_lowercase = 0;
1577 some_nonuppercase_initial = 0; 1593 some_nonuppercase_initial = 0;
1578 some_uppercase = 0; 1594 some_uppercase = 0;
1579 1595
1580 for (pos = search_regs.start[0]; pos < last; pos++) 1596 for (pos = search_regs.start[sub]; pos < last; pos++)
1581 { 1597 {
1582 if (NILP (string)) 1598 if (NILP (string))
1583 c = FETCH_CHAR (pos); 1599 c = FETCH_CHAR (pos);
1584 else 1600 else
1585 c = XSTRING (string)->data[pos]; 1601 c = XSTRING (string)->data[pos];
1632 if (!NILP (string)) 1648 if (!NILP (string))
1633 { 1649 {
1634 Lisp_Object before, after; 1650 Lisp_Object before, after;
1635 1651
1636 before = Fsubstring (string, make_number (0), 1652 before = Fsubstring (string, make_number (0),
1637 make_number (search_regs.start[0])); 1653 make_number (search_regs.start[sub]));
1638 after = Fsubstring (string, make_number (search_regs.end[0]), Qnil); 1654 after = Fsubstring (string, make_number (search_regs.end[sub]), Qnil);
1639 1655
1640 /* Do case substitution into NEWTEXT if desired. */ 1656 /* Do case substitution into NEWTEXT if desired. */
1641 if (NILP (literal)) 1657 if (NILP (literal))
1642 { 1658 {
1643 int lastpos = -1; 1659 int lastpos = -1;
1657 if (c == '\\') 1673 if (c == '\\')
1658 { 1674 {
1659 c = XSTRING (newtext)->data[++pos]; 1675 c = XSTRING (newtext)->data[++pos];
1660 if (c == '&') 1676 if (c == '&')
1661 { 1677 {
1662 substart = search_regs.start[0]; 1678 substart = search_regs.start[sub];
1663 subend = search_regs.end[0]; 1679 subend = search_regs.end[sub];
1664 } 1680 }
1665 else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0') 1681 else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0')
1666 { 1682 {
1667 if (search_regs.start[c - '0'] >= 0) 1683 if (search_regs.start[c - '0'] >= 0)
1668 { 1684 {
1714 1730
1715 /* We insert the replacement text before the old text, and then 1731 /* We insert the replacement text before the old text, and then
1716 delete the original text. This means that markers at the 1732 delete the original text. This means that markers at the
1717 beginning or end of the original will float to the corresponding 1733 beginning or end of the original will float to the corresponding
1718 position in the replacement. */ 1734 position in the replacement. */
1719 SET_PT (search_regs.start[0]); 1735 SET_PT (search_regs.start[sub]);
1720 if (!NILP (literal)) 1736 if (!NILP (literal))
1721 Finsert_and_inherit (1, &newtext); 1737 Finsert_and_inherit (1, &newtext);
1722 else 1738 else
1723 { 1739 {
1724 struct gcpro gcpro1; 1740 struct gcpro gcpro1;
1725 GCPRO1 (newtext); 1741 GCPRO1 (newtext);
1726 1742
1727 for (pos = 0; pos < XSTRING (newtext)->size; pos++) 1743 for (pos = 0; pos < XSTRING (newtext)->size; pos++)
1728 { 1744 {
1729 int offset = point - search_regs.start[0]; 1745 int offset = point - search_regs.start[sub];
1730 1746
1731 c = XSTRING (newtext)->data[pos]; 1747 c = XSTRING (newtext)->data[pos];
1732 if (c == '\\') 1748 if (c == '\\')
1733 { 1749 {
1734 c = XSTRING (newtext)->data[++pos]; 1750 c = XSTRING (newtext)->data[++pos];
1735 if (c == '&') 1751 if (c == '&')
1736 Finsert_buffer_substring 1752 Finsert_buffer_substring
1737 (Fcurrent_buffer (), 1753 (Fcurrent_buffer (),
1738 make_number (search_regs.start[0] + offset), 1754 make_number (search_regs.start[sub] + offset),
1739 make_number (search_regs.end[0] + offset)); 1755 make_number (search_regs.end[sub] + offset));
1740 else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0') 1756 else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0')
1741 { 1757 {
1742 if (search_regs.start[c - '0'] >= 1) 1758 if (search_regs.start[c - '0'] >= 1)
1743 Finsert_buffer_substring 1759 Finsert_buffer_substring
1744 (Fcurrent_buffer (), 1760 (Fcurrent_buffer (),
1752 insert_char (c); 1768 insert_char (c);
1753 } 1769 }
1754 UNGCPRO; 1770 UNGCPRO;
1755 } 1771 }
1756 1772
1757 inslen = point - (search_regs.start[0]); 1773 inslen = point - (search_regs.start[sub]);
1758 del_range (search_regs.start[0] + inslen, search_regs.end[0] + inslen); 1774 del_range (search_regs.start[sub] + inslen, search_regs.end[sub] + inslen);
1759 1775
1760 if (case_action == all_caps) 1776 if (case_action == all_caps)
1761 Fupcase_region (make_number (point - inslen), make_number (point)); 1777 Fupcase_region (make_number (point - inslen), make_number (point));
1762 else if (case_action == cap_initial) 1778 else if (case_action == cap_initial)
1763 Fupcase_initials_region (make_number (point - inslen), make_number (point)); 1779 Fupcase_initials_region (make_number (point - inslen), make_number (point));