@@ -1263,6 +1263,7 @@ static bool ReplacePatterns(EvalContext *ctx, Item *file_start, Item *file_end,
12631263 assert (a != NULL );
12641264 assert (pp != NULL );
12651265 assert (edcontext != NULL );
1266+ bool use_non_convergent = PromiseGetConstraintAsBoolean (ctx , "use_non_convergent" , pp );
12661267
12671268 char line_buff [CF_EXPANDSIZE ];
12681269 char after [CF_BUFSIZE ];
@@ -1330,17 +1331,24 @@ static bool ReplacePatterns(EvalContext *ctx, Item *file_start, Item *file_end,
13301331 break ;
13311332 }
13321333 }
1333-
1334+ char line_buff_cp [ CF_EXPANDSIZE ];
13341335 if (NotAnchored (pp -> promiser ) && BlockTextMatch (ctx , pp -> promiser , line_buff , & start_off , & end_off ))
13351336 {
1336- RecordInterruption (ctx , pp , a ,
1337- "Promised replacement '%s' on line '%s' for pattern '%s'"
1338- " is not convergent while editing '%s'"
1339- " (regular expression matches the replacement string)" ,
1340- line_buff , ip -> name , pp -> promiser , edcontext -> filename );
1341- * result = PromiseResultUpdate (* result , PROMISE_RESULT_INTERRUPTED );
1342- PromiseRef (LOG_LEVEL_ERR , pp );
1343- break ;
1337+ strlcpy (line_buff_cp , line_buff , sizeof (line_buff_cp ));
1338+ strlcpy (after , line_buff_cp + end_off , sizeof (after ));
1339+ snprintf (line_buff_cp + start_off , sizeof (line_buff_cp ) - start_off ,
1340+ "%s%s" , BufferData (replace ), after );
1341+
1342+ if (!use_non_convergent || (strlen (line_buff ) != strlen (line_buff_cp ))) {
1343+ RecordInterruption (ctx , pp , a ,
1344+ "Promised replacement '%s' on line '%s' for pattern '%s'"
1345+ " is not convergent while editing '%s'"
1346+ " (regular expression matches the replacement string)" ,
1347+ line_buff , ip -> name , pp -> promiser , edcontext -> filename );
1348+ * result = PromiseResultUpdate (* result , PROMISE_RESULT_INTERRUPTED );
1349+ PromiseRef (LOG_LEVEL_ERR , pp );
1350+ break ;
1351+ }
13441352 }
13451353
13461354 if (!MakingChanges (ctx , pp , a , result , "replace pattern '%s' in '%s'" , pp -> promiser ,
@@ -1366,8 +1374,14 @@ static bool ReplacePatterns(EvalContext *ctx, Item *file_start, Item *file_end,
13661374 break ;
13671375 }
13681376
1369- if (BlockTextMatch (ctx , pp -> promiser , ip -> name , & start_off , & end_off ))
1377+ if (BlockTextMatch (ctx , pp -> promiser , ip -> name , & start_off , & end_off ) && (!use_non_convergent
1378+ || (strlen (line_buff ) != strlen (line_buff_cp ))))
13701379 {
1380+ strlcpy (line_buff_cp , line_buff , sizeof (line_buff_cp ));
1381+ strlcpy (after , line_buff_cp + end_off , sizeof (after ));
1382+ snprintf (line_buff_cp + start_off , sizeof (line_buff_cp ) - start_off ,
1383+ "%s%s" , BufferData (replace ), after );
1384+
13711385 RecordInterruption (ctx , pp , a ,
13721386 "Promised replacement '%s' for pattern '%s' is not properly convergent while editing '%s'"
13731387 " (pattern still matches the end-state replacement string '%s', consider use"
0 commit comments