static void substitute_one(char **line_p, char **pos_p, const char *listaddr,
const char *listdelim, const char *listdir, text *txt)
{
+ /* It is important for this function to leave the length of the
+ * processed portion unchanged, or increase it by just one ASCII
+ * character (for $$). */
char *line = *line_p;
char *pos = *pos_p;
char *token = pos + 1;
{
char *line;
const char *item;
- char *pos, *subpos;
+ char *pos;
char *tmp;
char *prev = NULL;
- int incision, spc, spcnext;
int len, i;
int directive;
+ int incision, spc;
int peeking = 0; /* for a failed conditional without an else */
int skipwhite; /* skip whitespace after a conditional directive */
int swallow;
pos = line + len;
skipwhite = 1;
}
+ /* We can always line-break where the input had one */
+ spc = len - 1;
prev = NULL;
} else {
len = 0;
pos = line;
+ spc = -1;
skipwhite = 0;
}
if (txt->skip != NULL) {
- incision = pos - line;
- len = incision;
+ incision = len;
} else {
incision = -1;
}
- spc = -1;
- spcnext = 0;
directive = 0;
while (*pos != '\0') {
if (txt->wrapwidth != 0 && len >= txt->wrapwidth &&
- !peeking) {
- if (spcnext < txt->wrapwidth || spc == -1) {
- subpos = line + spcnext;
- while (subpos < pos) {
- if (*subpos == ' ') {
- spc = subpos - line;
- }
- spcnext++;
- if (spcnext >= txt->wrapwidth &&
- spc != -1)
- break;
- subpos++;
- }
- }
- if (spc != -1) break;
- }
+ !peeking && spc != -1) break;
if (*pos == '\r') {
*pos = '\0';
pos++;
} else if (*pos == ' ') {
if (txt->skip == NULL) {
spc = pos - line;
- spcnext = spc + 1;
}
} else if (*pos == '\t') {
/* Avoid breaking due to peeking */
if (peeking) break;
substitute_one(&line, &pos, listaddr,
listdelim, listdir, txt);
- len = pos - line;
+ if (len != pos - line) {
+ len = pos - line;
+ }
skipwhite = 0;
/* The function sets up for the next character
* to process, so continue straight away. */
* later */
incision = pos - line;
}
- len = incision;
} else {
if (incision != -1) {
/* Time to cut */
- if (pos-line != incision) {
+ if (pos - line != incision) {
line[incision] = '\0';
tmp = concatstr(2, line, pos);
pos = tmp + incision;
}
incision = -1;
}
+ }
+ if (len != pos - line) {
len = pos - line;
}
/* handle_directive() sets up for the next
break;
}
if (txt->skip == NULL) {
- if (spcnext == len) spcnext++;
len++;
}
pos++;