aboutsummaryrefslogtreecommitdiffstats
path: root/src/search.c
diff options
context:
space:
mode:
authorRichard M. Stallman1994-09-23 22:18:59 +0000
committerRichard M. Stallman1994-09-23 22:18:59 +0000
commit080c45fd0b8ce128a681ebf772fcb07048cde4eb (patch)
tree33f5c249a14ae95a489a598b7d61efe9e951f02c /src/search.c
parenta2b38b3c3a102a38dd14df18116a265f320b0b83 (diff)
downloademacs-080c45fd0b8ce128a681ebf772fcb07048cde4eb.tar.gz
emacs-080c45fd0b8ce128a681ebf772fcb07048cde4eb.zip
(Freplace_match): New 4th arg OBJECT can specify string to replace in.
Diffstat (limited to 'src/search.c')
-rw-r--r--src/search.c113
1 files changed, 103 insertions, 10 deletions
diff --git a/src/search.c b/src/search.c
index f3835ff0743..c77f7b7c202 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1186,7 +1186,7 @@ See also the functions `match-beginning', `match-end' and `replace-match'.")
1186 return search_command (regexp, bound, noerror, count, 1, 1); 1186 return search_command (regexp, bound, noerror, count, 1, 1);
1187} 1187}
1188 1188
1189DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 3, 0, 1189DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 4, 0,
1190 "Replace text matched by last search with NEWTEXT.\n\ 1190 "Replace text matched by last search with NEWTEXT.\n\
1191If second arg FIXEDCASE is non-nil, do not alter case of replacement text.\n\ 1191If second arg FIXEDCASE is non-nil, do not alter case of replacement text.\n\
1192Otherwise maybe capitalize the whole text, or maybe just word initials,\n\ 1192Otherwise maybe capitalize the whole text, or maybe just word initials,\n\
@@ -1202,9 +1202,13 @@ Otherwise treat `\\' as special:\n\
1202 If Nth parens didn't match, substitute nothing.\n\ 1202 If Nth parens didn't match, substitute nothing.\n\
1203 `\\\\' means insert one `\\'.\n\ 1203 `\\\\' means insert one `\\'.\n\
1204FIXEDCASE and LITERAL are optional arguments.\n\ 1204FIXEDCASE and LITERAL are optional arguments.\n\
1205Leaves point at end of replacement text.") 1205Leaves point at end of replacement text.\n\
1206 (newtext, fixedcase, literal) 1206\n\
1207 Lisp_Object newtext, fixedcase, literal; 1207The optional fourth argument STRING can be a string to modify.\n\
1208In that case, this function creates and returns a new string\n\
1209which is made by replacing the part of STRING that was matched.")
1210 (newtext, fixedcase, literal, string)
1211 Lisp_Object newtext, fixedcase, literal, string;
1208{ 1212{
1209 enum { nochange, all_caps, cap_initial } case_action; 1213 enum { nochange, all_caps, cap_initial } case_action;
1210 register int pos, last; 1214 register int pos, last;
@@ -1217,17 +1221,31 @@ Leaves point at end of replacement text.")
1217 1221
1218 CHECK_STRING (newtext, 0); 1222 CHECK_STRING (newtext, 0);
1219 1223
1224 if (! NILP (string))
1225 CHECK_STRING (string, 4);
1226
1220 case_action = nochange; /* We tried an initialization */ 1227 case_action = nochange; /* We tried an initialization */
1221 /* but some C compilers blew it */ 1228 /* but some C compilers blew it */
1222 1229
1223 if (search_regs.num_regs <= 0) 1230 if (search_regs.num_regs <= 0)
1224 error ("replace-match called before any match found"); 1231 error ("replace-match called before any match found");
1225 1232
1226 if (search_regs.start[0] < BEGV 1233 if (NILP (string))
1227 || search_regs.start[0] > search_regs.end[0] 1234 {
1228 || search_regs.end[0] > ZV) 1235 if (search_regs.start[0] < BEGV
1229 args_out_of_range (make_number (search_regs.start[0]), 1236 || search_regs.start[0] > search_regs.end[0]
1230 make_number (search_regs.end[0])); 1237 || search_regs.end[0] > ZV)
1238 args_out_of_range (make_number (search_regs.start[0]),
1239 make_number (search_regs.end[0]));
1240 }
1241 else
1242 {
1243 if (search_regs.start[0] < 0
1244 || search_regs.start[0] > search_regs.end[0]
1245 || search_regs.end[0] > XSTRING (string)->size)
1246 args_out_of_range (make_number (search_regs.start[0]),
1247 make_number (search_regs.end[0]));
1248 }
1231 1249
1232 if (NILP (fixedcase)) 1250 if (NILP (fixedcase))
1233 { 1251 {
@@ -1246,7 +1264,11 @@ Leaves point at end of replacement text.")
1246 1264
1247 for (pos = search_regs.start[0]; pos < last; pos++) 1265 for (pos = search_regs.start[0]; pos < last; pos++)
1248 { 1266 {
1249 c = FETCH_CHAR (pos); 1267 if (NILP (string))
1268 c = FETCH_CHAR (pos);
1269 else
1270 c = XSTRING (string)->data[pos];
1271
1250 if (LOWERCASEP (c)) 1272 if (LOWERCASEP (c))
1251 { 1273 {
1252 /* Cannot be all caps if any original char is lower case */ 1274 /* Cannot be all caps if any original char is lower case */
@@ -1291,6 +1313,77 @@ Leaves point at end of replacement text.")
1291 case_action = nochange; 1313 case_action = nochange;
1292 } 1314 }
1293 1315
1316 /* Do replacement in a string. */
1317 if (!NILP (string))
1318 {
1319 Lisp_Object before, after;
1320
1321 before = Fsubstring (string, make_number (0),
1322 make_number (search_regs.start[0]));
1323 after = Fsubstring (string, make_number (search_regs.end[0]), Qnil);
1324
1325 /* Do case substitution into NEWTEXT if desired. */
1326 if (NILP (literal))
1327 {
1328 int lastpos = -1;
1329 /* We build up the substituted string in ACCUM. */
1330 Lisp_Object accum;
1331 Lisp_Object middle;
1332
1333 accum = Qnil;
1334
1335 for (pos = 0; pos < XSTRING (newtext)->size; pos++)
1336 {
1337 int substart = -1;
1338 int subend;
1339
1340 c = XSTRING (newtext)->data[pos];
1341 if (c == '\\')
1342 {
1343 c = XSTRING (newtext)->data[++pos];
1344 if (c == '&')
1345 {
1346 substart = search_regs.start[0];
1347 subend = search_regs.end[0];
1348 }
1349 else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0')
1350 {
1351 if (search_regs.start[c - '0'] >= 1)
1352 {
1353 substart = search_regs.start[c - '0'];
1354 subend = search_regs.end[c - '0'];
1355 }
1356 }
1357 }
1358 if (substart >= 0)
1359 {
1360 if (pos - 1 != lastpos + 1)
1361 middle = Fsubstring (newtext, lastpos + 1, pos - 1);
1362 else
1363 middle = Qnil;
1364 accum = concat3 (accum, middle,
1365 Fsubstring (string, make_number (substart),
1366 make_number (subend)));
1367 lastpos = pos;
1368 }
1369 }
1370
1371 if (pos != lastpos + 1)
1372 middle = Fsubstring (newtext, lastpos + 1, pos);
1373 else
1374 middle = Qnil;
1375
1376 newtext = concat2 (accum, middle);
1377 }
1378
1379 if (case_action == all_caps)
1380 newtext = Fupcase (newtext);
1381 else if (case_action == cap_initial)
1382 newtext = upcase_initials (newtext);
1383
1384 return concat3 (before, newtext, after);
1385 }
1386
1294 /* We insert the replacement text before the old text, and then 1387 /* We insert the replacement text before the old text, and then
1295 delete the original text. This means that markers at the 1388 delete the original text. This means that markers at the
1296 beginning or end of the original will float to the corresponding 1389 beginning or end of the original will float to the corresponding