shithub: neatroff

Download patch

ref: c380cf15117112369d834b462b6ed4355c902a33
parent: aa79ff4da0a2b1ff7e0330fe8bab3d6f14515391
author: Ali Gholami Rudi <ali@rudi.ir>
date: Thu Jul 17 07:14:25 EDT 2014

char: break escape sequence reading functions

--- a/char.c
+++ b/char.c
@@ -55,6 +55,47 @@
 	return l;
 }
 
+/* read quoted arguments of escape sequences (ESC_Q) */
+void quotednext(char *d, int (*next)(void), void (*back)(int))
+{
+	char delim[GNLEN], cs[GNLEN];
+	charnext(delim, next, back);
+	while (charnext_delim(cs, next, back, delim) >= 0) {
+		charnext_str(d, cs);
+		d = strchr(d, '\0');
+	}
+}
+
+/* read unquoted arguments of escape sequences (ESC_P) */
+void unquotednext(char *d, int cmd, int (*next)(void), void (*back)(int))
+{
+	int c = next();
+	if (cmd == 's' && (c == '-' || c == '+')) {
+		*d++ = c;
+		c = next();
+	}
+	if (c == '(') {
+		*d++ = next();
+		*d++ = next();
+	} else if (!n_cp && c == '[') {
+		c = next();
+		while (c > 0 && c != '\n' && c != ']') {
+			*d++ = c;
+			c = next();
+		}
+	} else {
+		*d++ = c;
+		if (cmd == 's' && c >= '1' && c <= '3') {
+			c = next();
+			if (isdigit(c))
+				*d++ = c;
+			else
+				back(c);
+		}
+	}
+	*d = '\0';
+}
+
 /*
  * read the next character or escape sequence (x, \x, \(xy, \[xyz], \C'xyz')
  *
@@ -91,7 +132,7 @@
 			c[l] = '\0';
 			return '[';
 		} else if (c[1] == 'C') {
-			argnext(c, 'C', next, back);
+			quotednext(c, next, back);
 			return 'C';
 		}
 		return '\\';
@@ -140,81 +181,36 @@
 	return ret;
 }
 
-/* read the argument of a troff escape sequence */
-void argnext(char *d, int cmd, int (*next)(void), void (*back)(int))
+/* read quoted arguments; this is called only for internal neatroff strings */
+static void quotedread(char **sp, char *d)
 {
-	char delim[GNLEN], cs[GNLEN];
-	int c;
-	if (strchr(ESC_P, cmd)) {
-		c = next();
-		if (cmd == 's' && (c == '-' || c == '+')) {
-			*d++ = c;
-			c = next();
-		}
-		if (c == '(') {
-			*d++ = next();
-			*d++ = next();
-		} else if (!n_cp && c == '[') {
-			c = next();
-			while (c > 0 && c != '\n' && c != ']') {
-				*d++ = c;
-				c = next();
-			}
-		} else {
-			*d++ = c;
-			if (cmd == 's' && c >= '1' && c <= '3') {
-				c = next();
-				if (isdigit(c))
-					*d++ = c;
-				else
-					back(c);
-			}
-		}
-	}
-	if (strchr(ESC_Q, cmd)) {
-		charnext(delim, next, back);
-		while (charnext_delim(cs, next, back, delim) >= 0) {
-			charnext_str(d, cs);
-			d = strchr(d, '\0');
-		}
-	}
+	char *s = *sp;
+	int q = *s++;
+	while (*s && *s != q)
+		*d++ = *s++;
+	if (*s == q)
+		s++;
 	*d = '\0';
+	*sp = s;
 }
 
-/* this is called only for internal neatroff strings */
-void argread(char **sp, char *d, int cmd)
+/* read unquoted arguments; this is called only for internal neatroff strings */
+static void unquotedread(char **sp, char *d)
 {
 	char *s = *sp;
-	int q;
-	if (strchr(ESC_P, cmd)) {
-		if (cmd == 's' && (*s == '-' || *s == '+'))
+	if (*s == '(') {
+		s++;
+		*d++ = *s++;
+		*d++ = *s++;
+	} else if (!n_cp && *s == '[') {
+		s++;
+		while (*s && *s != ']')
 			*d++ = *s++;
-		if (*s == '(') {
+		if (*s == ']')
 			s++;
-			*d++ = *s++;
-			*d++ = *s++;
-		} else if (!n_cp && *s == '[') {
-			s++;
-			while (*s && *s != ']')
-				*d++ = *s++;
-			if (*s == ']')
-				s++;
-		} else {
-			*d++ = *s++;
-			if (cmd == 's' && s[-1] >= '1' && s[-1] <= '3')
-				if (isdigit(*s))
-					*d++ = *s++;
-		}
-	}
-	if (strchr(ESC_Q, cmd)) {
-		q = *s++;
-		while (*s && *s != q)
-			*d++ = *s++;
-		if (*s == q)
-			s++;
-	}
-	if (cmd == 'z')
+	} else {
 		*d++ = *s++;
+	}
 	*d = '\0';
 	*sp = s;
 }
@@ -246,7 +242,11 @@
 				(*s)++;
 		} else if (strchr("CDfhmsvXx", d[1])) {
 			int c = d[1];
-			argread(s, d, d[1]);
+			d[0] = '\0';
+			if (strchr(ESC_P, c))
+				unquotedread(s, d);
+			if (strchr(ESC_Q, c))
+				quotedread(s, d);
 			return c == 'C' ? 0 : c;
 		}
 	}
--- a/cp.c
+++ b/cp.c
@@ -103,7 +103,7 @@
 {
 	char arg[ILNLEN];
 	char *s;
-	argnext(arg, 'R', cp_next, cp_back);
+	quotednext(arg, cp_next, cp_back);
 	s = arg;
 	while (*s && *s != ' ')
 		s++;
@@ -121,7 +121,7 @@
 	char *r, *s = arg;
 	char *s1, *s2;
 	int n;
-	argnext(arg, '?', cp_next, cp_back);
+	quotednext(arg, cp_next, cp_back);
 	n = eval_up(&s, '\0');
 	if (charread(&s, delim) < 0)
 		return;
--- a/ren.c
+++ b/ren.c
@@ -734,7 +734,11 @@
 			return;
 		}
 		if (strchr(" bCcDdefHhkLlmNoprSsuvXxZz0^|{}&/,", c[1])) {
-			argnext(arg, c[1], next, back);
+			arg[0] = '\0';
+			if (strchr(ESC_P, c[1]))
+				unquotednext(arg, c[1], next, back);
+			if (strchr(ESC_Q, c[1]))
+				quotednext(arg, next, back);
 			if (c[1] == 'e') {
 				snprintf(c, GNLEN, "%c%c", c_ec, c_ec);
 			} else if (c[1] == 'N') {
@@ -766,7 +770,7 @@
 	return 0;
 }
 
-/* like ren_char(); return 1 if d1 was read and d2 if d2 was read */
+/* like ren_char(); return 1 if d1 was read and 2 if d2 was read */
 static int ren_chardel(struct wb *wb, int (*next)(void), void (*back)(int),
 			char *d1, char *d2)
 {
--- a/roff.h
+++ b/roff.h
@@ -423,8 +423,8 @@
 int charnext_delim(char *c, int (*next)(void), void (*back)(int), char *delim);
 int charread_delim(char **s, char *c, char *delim);
 void charnext_str(char *d, char *c);
-void argnext(char *d, int cmd, int (*next)(void), void (*back)(int));
-void argread(char **sp, char *d, int cmd);
+void quotednext(char *d, int (*next)(void), void (*back)(int));
+void unquotednext(char *d, int cmd, int (*next)(void), void (*back)(int));
 int escread(char **s, char *d);
 /* string streams; nested next()/back() interface for string buffers */
 void sstr_push(char *s);