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);