ref: 69e9e62bae8ef3eb372d06d143349a5d2b429cee
parent: a579ab3890031df70e0c05a9f301f6798991969e
author: Ali Gholami Rudi <ali@rudi.ir>
date: Fri Nov 23 13:23:12 EST 2012
tr: improve argument parsing for register names
--- a/tr.c
+++ b/tr.c
@@ -134,21 +134,56 @@
n_ad = 0;
}
-static void tr_readcmd(char *s)
+static char *arg_regname(char *s, int len)
{
- int i = 0;
+ char *e = s + 2;
int c;
while ((c = cp_next()) == ' ')
;
- while (i < 2 && c > 0 && isprint(c)) {
- s[i++] = c;
+ while (s < e && c >= 0 && c != ' ' && c != '\n') {
+ *s++ = c;
c = cp_next();
}
- s[i] = '\0';
- if (!isprint(c))
+ if (c >= 0)
cp_back(c);
+ *s++ = '\0';
+ return s;
}
+static char *arg_normal(char *s, int len)
+{
+ char *e = s + len - 1;
+ int c;
+ while ((c = cp_next()) == ' ')
+ ;
+ while (s < e && c > 0 && c != ' ' && c != '\n') {
+ *s++ = c;
+ c = cp_next();
+ }
+ if (c >= 0)
+ cp_back(c);
+ *s++ = '\0';
+ return s;
+}
+
+static char *arg_string(char *s, int len)
+{
+ char *e = s + len - 1;
+ int c;
+ while ((c = cp_next()) == ' ')
+ ;
+ if (c == '"')
+ c = cp_next();
+ while (s < e && c > 0 && c != '\n') {
+ *s++ = c;
+ c = cp_next();
+ }
+ *s++ = '\0';
+ if (c >= 0)
+ cp_back(c);
+ return s;
+}
+
/* skip everything until the end of line */
static void jmp_eol(void)
{
@@ -159,58 +194,50 @@
}
/* read macro arguments */
-static int tr_args(char **args, int maxargs, char *buf, int len)
+static int mkargs(char **args, int maxargs, char *buf, int len)
{
char *s = buf;
char *e = buf + len - 1;
int c;
int n = 0;
- while ((c = cp_next()) == ' ')
- ;
- while (n < maxargs && s < e && c > 0 && c != '\n') {
+ while (n < maxargs) {
+ c = cp_next();
+ if (c < 0 || c == '\n')
+ return n;
+ cp_back(c);
args[n++] = s;
- while (s < e && c > 0 && c != ' ' && c != '\n') {
- *s++ = c;
- c = cp_next();
- }
- *s++ = '\0';
- while (c == ' ')
- c = cp_next();
+ s = arg_normal(s, e - s);
}
- if (c >= 0 && c != '\n')
- jmp_eol();
+ jmp_eol();
return n;
}
/* read arguments for .ds */
-static int tr_args_ds(char **args, int maxargs, char *buf, int len)
+static int mkargs_ds(char **args, int maxargs, char *buf, int len)
{
char *s = buf;
char *e = buf + len - 1;
int c;
- while ((c = cp_next()) == ' ')
- ;
- if (c == '\n' || c < 0)
- return 0;
args[0] = s;
- *s++ = c;
- c = cp_next();
- if (c >= 0 && c != '\n' && c != ' ')
- *s++ = c;
- *s++ = '\0';
- while ((c = cp_next()) == ' ')
- ;
- if (c == '"')
- c = cp_next();
+ s = arg_regname(s, e - s);
args[1] = s;
- while (s < e && c > 0 && c != '\n') {
- *s++ = c;
- c = cp_next();
- }
- *s = '\0';
+ s = arg_string(s, e - s);
+ c = cp_next();
+ if (c >= 0 && c != '\n')
+ jmp_eol();
return 2;
}
+/* read arguments for commands .nr that expect a register name */
+static int mkargs_reg1(char **args, int maxargs, char *buf, int len)
+{
+ char *s = buf;
+ char *e = buf + len - 1;
+ args[0] = s;
+ s = arg_regname(s, e - s);
+ return mkargs(args + 1, maxargs - 1, s, e - s) + 1;
+}
+
static struct cmd {
char *id;
void (*f)(int argc, char **args);
@@ -217,14 +244,14 @@
int (*args)(char **args, int maxargs, char *buf, int len);
} cmds[] = {
{"br", tr_br},
- {"de", tr_de},
- {"ds", tr_ds, tr_args_ds},
+ {"de", tr_de, mkargs_reg1},
+ {"ds", tr_ds, mkargs_ds},
{"fp", tr_fp},
{"ft", tr_ft},
{"in", tr_in},
{"ll", tr_ll},
{"na", tr_na},
- {"nr", tr_nr},
+ {"nr", tr_nr, mkargs_reg1},
{"ps", tr_ps},
{"sp", tr_sp},
{"vs", tr_vs},
@@ -244,7 +271,7 @@
nl = 1;
args[0] = cmd;
cmd[0] = c;
- tr_readcmd(cmd + 1);
+ arg_regname(cmd + 1, LINEL - 2);
for (i = 0; i < LEN(cmds); i++)
if (!strcmp(cmd + 1, cmds[i].id))
req = &cmds[i];
@@ -252,7 +279,7 @@
if (req->args)
argc = req->args(args + 1, NARGS - 1, buf, LINEL);
else
- argc = tr_args(args + 1, NARGS - 1, buf, LINEL);
+ argc = mkargs(args + 1, NARGS - 1, buf, LINEL);
req->f(argc + 1, args);
} else {
jmp_eol();