Lose intermediate handling (unused). Change argument parsing to work properly over multiple buffers by saving a copy of the argument (we can't just save off/len since the buffer may vanish at any point).

pull/1/head
Nicholas Marriott 2007-09-29 14:25:49 +00:00
parent 653ee721df
commit 1e316cfc7c
5 changed files with 84 additions and 68 deletions

111
input.c
View File

@ -1,4 +1,4 @@
/* $Id: input.c,v 1.10 2007-09-29 10:57:39 nicm Exp $ */ /* $Id: input.c,v 1.11 2007-09-29 14:25:49 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -45,6 +45,8 @@ struct {
enum input_class input_lookup_class(u_char); enum input_class input_lookup_class(u_char);
int input_get_argument(struct input_ctx *, u_int, uint16_t *, uint16_t); int input_get_argument(struct input_ctx *, u_int, uint16_t *, uint16_t);
int input_new_argument(struct input_ctx *);
int input_add_argument(struct input_ctx *, u_char ch);
void *input_state_first(u_char, enum input_class, struct input_ctx *); void *input_state_first(u_char, enum input_class, struct input_ctx *);
void *input_state_escape(u_char, enum input_class, struct input_ctx *); void *input_state_escape(u_char, enum input_class, struct input_ctx *);
@ -101,11 +103,39 @@ input_lookup_class(u_char ch)
return (iclass); return (iclass);
} }
int
input_new_argument(struct input_ctx *ictx)
{
struct input_arg *arg;
ARRAY_EXPAND(&ictx->args, 1);
arg = &ARRAY_LAST(&ictx->args);
arg->used = 0;
return (0);
}
int
input_add_argument(struct input_ctx *ictx, u_char ch)
{
struct input_arg *arg;
if (ARRAY_LENGTH(&ictx->args) == 0)
return (0);
arg = &ARRAY_LAST(&ictx->args);
if (arg->used > (sizeof arg->data) - 1)
return (-1);
arg->data[arg->used++] = ch;
return (0);
}
int int
input_get_argument(struct input_ctx *ictx, u_int i, uint16_t *n, uint16_t d) input_get_argument(struct input_ctx *ictx, u_int i, uint16_t *n, uint16_t d)
{ {
struct input_arg *arg; struct input_arg *arg;
char tmp[64];
const char *errstr; const char *errstr;
*n = d; *n = d;
@ -113,15 +143,10 @@ input_get_argument(struct input_ctx *ictx, u_int i, uint16_t *n, uint16_t d)
return (0); return (0);
arg = &ARRAY_ITEM(&ictx->args, i); arg = &ARRAY_ITEM(&ictx->args, i);
if (arg->len == 0) if (*arg->data == '\0')
return (0); return (0);
if (arg->len > sizeof tmp - 1) *n = strtonum(arg->data, 0, UINT16_MAX, &errstr);
return (-1);
memcpy(tmp, ictx->buf + arg->off, arg->len);
tmp[arg->len] = '\0';
*n = strtonum(tmp, 0, UINT16_MAX, &errstr);
if (errstr != NULL) if (errstr != NULL)
return (-1); return (-1);
return (0); return (0);
@ -132,9 +157,6 @@ input_init(struct input_ctx *ictx, struct screen *s)
{ {
ictx->s = s; ictx->s = s;
ictx->intoff = 0;
ictx->intlen = 0;
ARRAY_INIT(&ictx->args); ARRAY_INIT(&ictx->args);
ictx->state = input_state_first; ictx->state = input_state_first;
@ -225,8 +247,6 @@ input_state_escape(u_char ch, enum input_class iclass, struct input_ctx *ictx)
return (input_state_escape); return (input_state_escape);
case INPUT_SPACE: case INPUT_SPACE:
case INPUT_INTERMEDIATE: case INPUT_INTERMEDIATE:
ictx->intoff = ictx->off;
ictx->intlen = 1;
return (input_state_intermediate); return (input_state_intermediate);
case INPUT_PARAMETER: case INPUT_PARAMETER:
input_handle_private_two(ch, ictx); input_handle_private_two(ch, ictx);
@ -255,7 +275,6 @@ input_state_intermediate(
switch (iclass) { switch (iclass) {
case INPUT_SPACE: case INPUT_SPACE:
case INPUT_INTERMEDIATE: case INPUT_INTERMEDIATE:
ictx->intlen++;
return (input_state_intermediate); return (input_state_intermediate);
case INPUT_PARAMETER: case INPUT_PARAMETER:
input_handle_private_two(ch, ictx); input_handle_private_two(ch, ictx);
@ -279,31 +298,30 @@ input_state_sequence_first(
u_char ch, enum input_class iclass, struct input_ctx *ictx) u_char ch, enum input_class iclass, struct input_ctx *ictx)
{ {
ictx->private = '\0'; ictx->private = '\0';
ARRAY_CLEAR(&ictx->args);
switch (iclass) { switch (iclass) {
case INPUT_PARAMETER: case INPUT_PARAMETER:
if (ch >= 0x3c && ch <= 0x3f) { if (ch >= 0x3c && ch <= 0x3f) {
/* Private control sequence. */ /* Private control sequence. */
ictx->private = ch; ictx->private = ch;
ictx->saved = ictx->off;
return (input_state_sequence_next); return (input_state_sequence_next);
} }
input_new_argument(ictx);
break; break;
case INPUT_C0CONTROL:
case INPUT_C1CONTROL:
case INPUT_SPACE: case INPUT_SPACE:
case INPUT_INTERMEDIATE: case INPUT_INTERMEDIATE:
case INPUT_UPPERCASE: case INPUT_UPPERCASE:
case INPUT_LOWERCASE: case INPUT_LOWERCASE:
case INPUT_C0CONTROL:
case INPUT_C1CONTROL:
case INPUT_DELETE: case INPUT_DELETE:
case INPUT_G1DISPLAYABLE: case INPUT_G1DISPLAYABLE:
case INPUT_SPECIAL: case INPUT_SPECIAL:
break; break;
} }
/* Pass this character to next state directly. */ /* Pass character on directly. */
ictx->saved = ictx->off - 1;
return (input_state_sequence_next(ch, iclass, ictx)); return (input_state_sequence_next(ch, iclass, ictx));
} }
@ -311,39 +329,26 @@ void *
input_state_sequence_next( input_state_sequence_next(
u_char ch, enum input_class iclass, struct input_ctx *ictx) u_char ch, enum input_class iclass, struct input_ctx *ictx)
{ {
struct input_arg *iarg;
switch (iclass) { switch (iclass) {
case INPUT_SPACE: case INPUT_SPACE:
case INPUT_INTERMEDIATE: case INPUT_INTERMEDIATE:
if (ictx->saved != ictx->off) { if (input_add_argument(ictx, '\0') != 0)
ARRAY_EXPAND(&ictx->args, 1); break;
iarg = &ARRAY_LAST(&ictx->args);
iarg->off = ictx->saved;
iarg->len = ictx->off - ictx->saved - 1;
}
ictx->intoff = ictx->off;
ictx->intlen = 1;
return (input_state_sequence_intermediate); return (input_state_sequence_intermediate);
case INPUT_PARAMETER: case INPUT_PARAMETER:
if (ch == ';') { if (ch == ';') {
ARRAY_EXPAND(&ictx->args, 1); if (input_add_argument(ictx, '\0') != 0)
iarg = &ARRAY_LAST(&ictx->args); break;
iarg->off = ictx->saved; input_new_argument(ictx);
iarg->len = ictx->off - ictx->saved - 1;
ictx->saved = ictx->off;
return (input_state_sequence_next); return (input_state_sequence_next);
} }
if (input_add_argument(ictx, ch) != 0)
break;
return (input_state_sequence_next); return (input_state_sequence_next);
case INPUT_UPPERCASE: case INPUT_UPPERCASE:
case INPUT_LOWERCASE: case INPUT_LOWERCASE:
if (ictx->saved != ictx->off) { if (input_add_argument(ictx, '\0') != 0)
ARRAY_EXPAND(&ictx->args, 1); break;
iarg = &ARRAY_LAST(&ictx->args);
iarg->off = ictx->saved;
iarg->len = ictx->off - ictx->saved - 1;
}
input_handle_sequence(ch, ictx); input_handle_sequence(ch, ictx);
break; break;
case INPUT_C0CONTROL: case INPUT_C0CONTROL:
@ -363,7 +368,6 @@ input_state_sequence_intermediate(
switch (iclass) { switch (iclass) {
case INPUT_SPACE: case INPUT_SPACE:
case INPUT_INTERMEDIATE: case INPUT_INTERMEDIATE:
ictx->intlen++;
return (input_state_sequence_intermediate); return (input_state_sequence_intermediate);
case INPUT_UPPERCASE: case INPUT_UPPERCASE:
case INPUT_LOWERCASE: case INPUT_LOWERCASE:
@ -437,8 +441,7 @@ input_handle_c1_control(u_char ch, struct input_ctx *ictx)
void void
input_handle_private_two(u_char ch, struct input_ctx *ictx) input_handle_private_two(u_char ch, struct input_ctx *ictx)
{ {
log_debug2("-- p2 %zu: %hhu (%c) (%zu, %zu)", log_debug2("-- p2 %zu: %hhu (%c)", ictx->off, ch, ch);
ictx->off, ch, ch, ictx->intoff, ictx->intlen);
switch (ch) { switch (ch) {
case '=': /* DECKPAM */ case '=': /* DECKPAM */
@ -456,8 +459,7 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx)
void void
input_handle_standard_two(u_char ch, struct input_ctx *ictx) input_handle_standard_two(u_char ch, struct input_ctx *ictx)
{ {
log_debug2("-- s2 %zu: %hhu (%c) (%zu,%zu)", log_debug2("-- s2 %zu: %hhu (%c)", ictx->off, ch, ch);
ictx->off, ch, ch, ictx->intoff, ictx->intlen);
log_debug("unknown s2: %hhu", ch); log_debug("unknown s2: %hhu", ch);
} }
@ -491,26 +493,21 @@ input_handle_sequence(u_char ch, struct input_ctx *ictx)
u_int i; u_int i;
struct input_arg *iarg; struct input_arg *iarg;
log_debug2("-- sq %zu: %hhu (%c) (%zu,%zu): %u", log_debug2("-- sq "
ictx->off, ch, ch, ictx->intoff, ictx->intlen, "%zu: %hhu (%c): %u", ictx->off, ch, ch, ARRAY_LENGTH(&ictx->args));
ARRAY_LENGTH(&ictx->args));
for (i = 0; i < ARRAY_LENGTH(&ictx->args); i++) { for (i = 0; i < ARRAY_LENGTH(&ictx->args); i++) {
iarg = &ARRAY_ITEM(&ictx->args, i); iarg = &ARRAY_ITEM(&ictx->args, i);
if (iarg->len > 0) { if (*iarg->data != '\0')
log_debug2(" ++ %u: (%zu) %.*s", i, log_debug2(" ++ %u: %s", i, iarg->data);
iarg->len, (int) iarg->len, ictx->buf + iarg->off);
}
} }
/* XXX bsearch? */ /* XXX bsearch? */
for (i = 0; i < (sizeof table / sizeof table[0]); i++) { for (i = 0; i < (sizeof table / sizeof table[0]); i++) {
if (table[i].ch == ch) { if (table[i].ch == ch) {
table[i].fn(ictx); table[i].fn(ictx);
ARRAY_CLEAR(&ictx->args);
return; return;
} }
} }
ARRAY_CLEAR(&ictx->args);
log_debug("unknown sq: %c (%hhu %hhu)", ch, ch, ictx->private); log_debug("unknown sq: %c (%hhu %hhu)", ch, ch, ictx->private);
} }

View File

@ -1,4 +1,4 @@
/* $Id: local.c,v 1.10 2007-09-29 10:57:39 nicm Exp $ */ /* $Id: local.c,v 1.11 2007-09-29 14:25:49 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -310,11 +310,13 @@ local_putc(int c)
if (c < 0 || c > (int) UCHAR_MAX) if (c < 0 || c > (int) UCHAR_MAX)
fatalx("invalid character"); fatalx("invalid character");
/* XXX
if (debug_level > 2) { if (debug_level > 2) {
f = fopen("tmux-out.log", "a+"); f = fopen("tmux-out.log", "a+");
fprintf(f, "%c", ch); fprintf(f, "%c", ch);
fclose(f); fclose(f);
} }
*/
buffer_write(local_out, &ch, 1); buffer_write(local_out, &ch, 1);
return (c); return (c);

13
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.25 2007-09-29 13:22:15 nicm Exp $ */ /* $Id: tmux.h,v 1.26 2007-09-29 14:25:49 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -396,11 +396,11 @@ struct screen {
#define SCREEN_DEFDATA ' ' #define SCREEN_DEFDATA ' '
#define SCREEN_DEFATTR 0 #define SCREEN_DEFATTR 0
#define SCREEN_DEFCOLR 0x88 #define SCREEN_DEFCOLR 0x88
/* Input parser sequence argument. */ /* Input parser sequence argument. */
struct input_arg { struct input_arg {
size_t off; u_char data[64];
size_t len; size_t used;
}; };
/* Input character classes. */ /* Input character classes. */
@ -431,10 +431,6 @@ struct input_ctx {
void *(*state)(u_char, enum input_class, struct input_ctx *); void *(*state)(u_char, enum input_class, struct input_ctx *);
size_t intoff;
size_t intlen;
size_t saved;
u_char private; u_char private;
ARRAY_DECL(, struct input_arg) args; ARRAY_DECL(, struct input_arg) args;
}; };
@ -663,6 +659,7 @@ __dead void log_fatalx(const char *, ...);
/* xmalloc.c */ /* xmalloc.c */
void *ensure_size(void *, size_t *, size_t, size_t); void *ensure_size(void *, size_t *, size_t, size_t);
void *ensure_for(void *, size_t *, size_t, size_t); void *ensure_for(void *, size_t *, size_t, size_t);
char *xmemstrdup(const char *, size_t);
char *xstrdup(const char *); char *xstrdup(const char *);
void *xcalloc(size_t, size_t); void *xcalloc(size_t, size_t);
void *xmalloc(size_t); void *xmalloc(size_t);

View File

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.13 2007-09-29 09:15:49 nicm Exp $ */ /* $Id: window.c,v 1.14 2007-09-29 14:25:49 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -314,9 +314,17 @@ window_input(struct window *w, struct buffer *b, size_t size)
void void
window_output(struct window *w, struct buffer *b) window_output(struct window *w, struct buffer *b)
{ {
FILE *f;
if (BUFFER_USED(w->in) == 0) if (BUFFER_USED(w->in) == 0)
return; return;
if (debug_level > 2) {
f = fopen("tmux-in.log", "a+");
fwrite(BUFFER_OUT(w->in), BUFFER_USED(w->in), 1, f);
fclose(f);
}
input_parse(&w->ictx, BUFFER_OUT(w->in), BUFFER_USED(w->in), b); input_parse(&w->ictx, BUFFER_OUT(w->in), BUFFER_USED(w->in), b);
buffer_remove(w->in, BUFFER_USED(w->in)); buffer_remove(w->in, BUFFER_USED(w->in));

View File

@ -1,4 +1,4 @@
/* $Id: xmalloc.c,v 1.2 2007-07-25 23:13:18 nicm Exp $ */ /* $Id: xmalloc.c,v 1.3 2007-09-29 14:25:49 nicm Exp $ */
/* /*
* Copyright (c) 2004 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2004 Nicholas Marriott <nicm@users.sourceforge.net>
@ -69,6 +69,18 @@ ensure_size(void *buf, size_t *len, size_t nmemb, size_t size)
return (buf); return (buf);
} }
char *
xmemstrdup(const char *buf, size_t len)
{
char *s;
s = xmalloc(len + 1);
memcpy(s, buf, len);
s[len] = '\0';
return (s);
}
char * char *
xstrdup(const char *s) xstrdup(const char *s)
{ {