changeset 854:024b2f748a2f

Make sure parts of lines aren't processed twice. This ensures backslash escaping is not done twice, and that the one time it is done it is effective (for break inhibition).
author Ben Schmidt
date Thu, 01 Mar 2012 03:33:53 +1100
parents 90637da7fe2c
children 085c963b45a9
files src/prepstdreply.c
diffstat 1 files changed, 30 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/prepstdreply.c	Thu Mar 01 03:33:50 2012 +1100
+++ b/src/prepstdreply.c	Thu Mar 01 03:33:53 2012 +1100
@@ -72,6 +72,7 @@
 struct source {
 	source *prev;
 	char *upcoming;
+	int processedlen;
 	char *prefix;
 	char *suffix;
 	int fd;
@@ -453,6 +454,7 @@
 	txt->src = mymalloc(sizeof(source));
 	txt->src->prev = NULL;
 	txt->src->upcoming = NULL;
+	txt->src->processedlen = 0;
 	txt->src->prefix = NULL;
 	txt->src->suffix = NULL;
 	txt->src->transparent = 0;
@@ -586,7 +588,10 @@
 	while (*pos != '\0' && *pos != '\r' && *pos != '\n') pos++;
 	if (*pos == '\r') pos++;
 	if (*pos == '\n') pos++;
-	if (*pos != '\0') txt->src->upcoming = mystrdup(pos);
+	if (*pos != '\0') {
+		txt->src->upcoming = mystrdup(pos);
+		txt->src->processedlen = 0;
+	}
 
 	fd = open(filename, O_RDONLY);
 	if (fd < 0) {
@@ -638,7 +643,10 @@
 	while (*pos != '\0' && *pos != '\r' && *pos != '\n') pos++;
 	if (*pos == '\r') pos++;
 	if (*pos == '\n') pos++;
-	if (*pos != '\0') txt->src->upcoming = mystrdup(pos);
+	if (*pos != '\0') {
+		txt->src->upcoming = mystrdup(pos);
+		txt->src->processedlen = 0;
+	}
 
 	(*fmt->rew)(fmt->state);
 
@@ -1013,6 +1021,7 @@
 	char *tmp;
 	char *prev = NULL;
 	int len, i;
+	int processedlen;
 	int incision, linebreak;
 	int directive, inhibitbreak;
 	int peeking = 0; /* for a failed conditional without an else */
@@ -1031,6 +1040,8 @@
 					line = txt->src->upcoming;
 				}
 				txt->src->upcoming = NULL;
+				processedlen = strlen(txt->src->prefix) +
+					    txt->src->processedlen;
 				break;
 			}
 			if (txt->src->limit != 0) {
@@ -1049,9 +1060,11 @@
 					txt->src->upcoming = NULL;
 				} else if (txt->src->transparent) {
 					txt->src->upcoming = tmp;
+					txt->src->processedlen = 0;
 				} else {
 					txt->src->upcoming =
 						unistr_escaped_to_utf8(tmp);
+					txt->src->processedlen = 0;
 					myfree(tmp);
 				}
 			} else {
@@ -1067,7 +1080,8 @@
 		}
 
 		if (prev != NULL) {
-			/* Wrapping */
+			/* Wrapping; join and start processing at the new bit,
+			 * which is always unprocessed. */
 			len = strlen(prev);
 			pos = prev + len - 1;
 			if (txt->wrapmode == WRAP_WORD) {
@@ -1084,6 +1098,7 @@
 				   line for later. */
 				txt->wrapwidth = 0;
 				txt->src->upcoming = line;
+				txt->src->processedlen = 0;
 				line = prev;
 				pos = line + len;
 				skipwhite = 0;
@@ -1114,8 +1129,12 @@
 			linebreak = len;
 			prev = NULL;
 		} else {
-			len = 0;
-			pos = line;
+			/* Not wrapping; start processing where we left off;
+			 * there can't be any break opportunities in the
+			 * processed part, and if it looks like there are, they
+			 * must have been inhibited so aren't really. */
+			pos = line + processedlen;
+			len = processedlen;
 			linebreak = 0;
 			skipwhite = 0;
 		}
@@ -1141,12 +1160,14 @@
 				if (*pos == '\n') pos++;
 				if (*pos == '\0') break;
 				txt->src->upcoming = mystrdup(pos);
+				txt->src->processedlen = 0;
 				break;
 			} else if (*pos == '\n') {
 				*pos = '\0';
 				pos++;
 				if (*pos == '\0') break;
 				txt->src->upcoming = mystrdup(pos);
+				txt->src->processedlen = 0;
 				break;
 			} else if (*pos == ' ') {
 				if (txt->skip == NULL &&
@@ -1282,6 +1303,7 @@
 				if (line[linebreak] == '\0') linebreak = 0;
 			}
 			if (linebreak != 0) {
+				txt->src->processedlen = len - linebreak;
 				len = strlen(line + linebreak);
 				if (txt->src->upcoming == NULL) {
 				    tmp = mymalloc((len + txt->wrapindent + 1) *
@@ -1291,6 +1313,7 @@
 					    strlen(txt->src->upcoming)) *
 					    sizeof(char));
 				}
+				txt->src->processedlen += txt->wrapindent;
 				pos = tmp;
 				for (i = txt->wrapindent; i > 0; i--)
 					*pos++ = ' ';
@@ -1329,11 +1352,13 @@
 				 * line */
 				if (txt->src->upcoming == NULL) {
 					txt->src->upcoming = line;
+					txt->src->processedlen = len;
 				} else {
 					tmp = txt->src->upcoming;
 					txt->src->upcoming = concatstr(3,
 							line, "\n",
 							txt->src->upcoming);
+					txt->src->processedlen = len;
 					myfree(line);
 					myfree(tmp);
 				}