A bit of renaming (term -> terminal)

This commit is contained in:
Julien Palard 2011-09-22 19:43:32 +02:00
parent 6f80a5f5cd
commit 8bb410bb7f
6 changed files with 230 additions and 239 deletions

View File

@ -6,7 +6,7 @@
##
NAME = vt100
SRC = term.c vt100.c test.c vt100_headless.c
SRC = terminal.c vt100.c test.c vt100_headless.c
OBJ = $(SRC:.c=.o)
CC = gcc
INCLUDE = .
@ -30,4 +30,4 @@ clean:
re: clean all
check-syntax:
gcc -o /dev/null -S ${CHK_SOURCES}
gcc -Wall -Wextra -ansi -pedantic -o /dev/null -S ${CHK_SOURCES}

230
term.c
View File

@ -1,230 +0,0 @@
#include <stdlib.h>
#ifndef NDEBUG
# include <stdio.h>
#endif
#include "term.h"
/*
** Term implement a terminal, (vt100 like)
** It expose an API to implement a specific terminal, actually I implement
** vt100.
**
** term.c parses escape sequences like
** \033[4;2H
** It allows control chars to be inside the sequence like :
** \033[4\n;2H
** and accept variations like :
** \033#...
** \033(...
**
** The API is simple, it consists of a structure term_callbacks (see
** term.h) where 4 members points to a ascii_callbacks structure.
** Ascii callbacks is only a struct with some ascii chars where you
** can plug your callbacks functions. see vt100.c as an example.
**
*/
static void term_push(struct terminal *term, char c)
{
if (term->stack_ptr >= TERM_STACK_SIZE)
return ;
term->stack[term->stack_ptr++] = c;
}
static void term_parse_params(struct terminal *term)
{
unsigned int i;
int got_something;
got_something = 0;
term->argc = 0;
term->argv[0] = 0;
for (i = 0; i < term->stack_ptr; ++i)
{
if (term->stack[i] >= '0' && term->stack[i] <= '9')
{
got_something = 1;
term->argv[term->argc] = term->argv[term->argc] * 10
+ term->stack[i] - '0';
}
else if (term->stack[i] == ';')
{
got_something = 0;
term->argc += 1;
term->argv[term->argc] = 0;
}
}
term->argc += got_something;
}
static void term_call_CSI(struct terminal *term, char c)
{
term_parse_params(term);
if (((term_action *)&term->callbacks.csi)[c - '0'] == NULL)
{
if (term->unimplemented != NULL)
term->unimplemented(term, "CSI", c);
goto leave;
}
((term_action *)&term->callbacks.csi)[c - '0'](term);
leave:
term->state = INIT;
term->flag = '\0';
term->stack_ptr = 0;
term->argc = 0;
}
static void term_call_ESC(struct terminal *term, char c)
{
if (((term_action *)&term->callbacks.esc)[c - '0'] == NULL)
{
if (term->unimplemented != NULL)
term->unimplemented(term, "ESC", c);
goto leave;
}
((term_action *)&term->callbacks.esc)[c - '0'](term);
leave:
term->state = INIT;
term->stack_ptr = 0;
term->argc = 0;
}
static void term_call_HASH(struct terminal *term, char c)
{
if (((term_action *)&term->callbacks.hash)[c - '0'] == NULL)
{
if (term->unimplemented != NULL)
term->unimplemented(term, "HASH", c);
goto leave;
}
((term_action *)&term->callbacks.hash)[c - '0'](term);
leave:
term->state = INIT;
term->stack_ptr = 0;
term->argc = 0;
}
static void term_call_GSET(struct terminal *term, char c)
{
if (c < '0' || c > 'B'
|| ((term_action *)&term->callbacks.scs)[c - '0'] == NULL)
{
if (term->unimplemented != NULL)
term->unimplemented(term, "GSET", c);
goto leave;
}
((term_action *)&term->callbacks.scs)[c - '0'](term);
leave:
term->state = INIT;
term->stack_ptr = 0;
term->argc = 0;
}
/*
** INIT
** \_ ESC "\033"
** | \_ CSI "\033["
** | | \_ c == '?' : term->flag = '?'
** | | \_ c == ';' || (c >= '0' && c <= '9') : term_push
** | | \_ else : term_call_CSI()
** | \_ HASH "\033#"
** | | \_ term_call_hash()
** | \_ G0SET "\033("
** | | \_ term_call_GSET()
** | \_ G1SET "\033)"
** | | \_ term_call_GSET()
** \_ term->write()
*/
void term_read(struct terminal *term, char c)
{
if (term->state == INIT)
{
if (c == '\033')
term->state = ESC;
else
term->write(term, c);
}
else if (term->state == ESC)
{
if (c == '[')
term->state = CSI;
else if (c == '#')
term->state = HASH;
else if (c == '(')
term->state = G0SET;
else if (c == ')')
term->state = G1SET;
else if (c >= '0' && c <= 'z')
term_call_ESC(term, c);
else term->write(term, c);
}
else if (term->state == HASH)
{
if (c >= '0' && c <= '9')
term_call_HASH(term, c);
else
term->write(term, c);
}
else if (term->state == G0SET || term->state == G1SET)
{
term_call_GSET(term, c);
}
else if (term->state == CSI)
{
if (c == '?')
term->flag = '?';
else if (c == ';' || (c >= '0' && c <= '9'))
term_push(term, c);
else if (c >= '?' && c <= 'z')
term_call_CSI(term, c);
else
term->write(term, c);
}
}
void term_read_str(struct terminal *term, char *c)
{
while (*c)
term_read(term, *c++);
}
#ifndef NDEBUG
void term_default_unimplemented(struct terminal* term, char *seq, char chr)
{
unsigned int argc;
fprintf(stderr, "WARNING: UNIMPLEMENTED %s (", seq);
for (argc = 0; argc < term->argc; ++argc)
{
fprintf(stderr, "%d", term->argv[argc]);
if (argc != term->argc - 1)
fprintf(stderr, ", ");
}
fprintf(stderr, ")%o\n", chr);
}
#else
void term_default_unimplemented(struct terminal* term, char *seq, char chr)
{
term = term;
seq = seq;
chr = chr;
}
#endif
struct terminal *term_init(unsigned int width, unsigned int height,
void (*vtwrite)(struct terminal *, char))
{
struct terminal *term;
term = calloc(1, sizeof(*term));
term->width = width;
term->height = height;
term->cursor_pos_x = 0;
term->cursor_pos_y = 0;
term->stack_ptr = 0;
term->state = INIT;
term->write = vtwrite;
return term;
}

219
terminal.c Normal file
View File

@ -0,0 +1,219 @@
#include <stdlib.h>
#ifndef NDEBUG
# include <stdio.h>
#endif
#include "terminal.h"
/*
** Term implement a terminal, (vt100 like)
** It expose an API to implement a specific terminal.
** Actually I implement vt100 in vt100.c
**
** term.c parses escape sequences like
** \033[4;2H
** It allows control chars to be inside the sequence like :
** \033[4\n;2H
** and accept variations like :
** \033#...
** \033(...
**
** The API is simple, it consists of a structure term_callbacks (see
** term.h) where 4 members points to a ascii_callbacks structure.
** Ascii callbacks is only a struct with some ascii chars where you
** can plug your callbacks functions. see vt100.c as an example.
**
*/
static void terminal_push(struct terminal *this, char c)
{
if (this->stack_ptr >= TERM_STACK_SIZE)
return ;
this->stack[this->stack_ptr++] = c;
}
static void terminal_parse_params(struct terminal *this)
{
unsigned int i;
int got_something;
got_something = 0;
this->argc = 0;
this->argv[0] = 0;
for (i = 0; i < this->stack_ptr; ++i)
{
if (this->stack[i] >= '0' && this->stack[i] <= '9')
{
got_something = 1;
this->argv[this->argc] = this->argv[this->argc] * 10
+ this->stack[i] - '0';
}
else if (this->stack[i] == ';')
{
got_something = 0;
this->argc += 1;
this->argv[this->argc] = 0;
}
}
this->argc += got_something;
}
static void terminal_call_CSI(struct terminal *this, char c)
{
terminal_parse_params(this);
if (((term_action *)&this->callbacks.csi)[c - '0'] == NULL)
{
if (this->unimplemented != NULL)
this->unimplemented(this, "CSI", c);
goto leave;
}
((term_action *)&this->callbacks.csi)[c - '0'](this);
leave:
this->state = INIT;
this->flag = '\0';
this->stack_ptr = 0;
this->argc = 0;
}
static void terminal_call_ESC(struct terminal *this, char c)
{
if (((term_action *)&this->callbacks.esc)[c - '0'] == NULL)
{
if (this->unimplemented != NULL)
this->unimplemented(this, "ESC", c);
goto leave;
}
((term_action *)&this->callbacks.esc)[c - '0'](this);
leave:
this->state = INIT;
this->stack_ptr = 0;
this->argc = 0;
}
static void terminal_call_HASH(struct terminal *this, char c)
{
if (((term_action *)&this->callbacks.hash)[c - '0'] == NULL)
{
if (this->unimplemented != NULL)
this->unimplemented(this, "HASH", c);
goto leave;
}
((term_action *)&this->callbacks.hash)[c - '0'](this);
leave:
this->state = INIT;
this->stack_ptr = 0;
this->argc = 0;
}
static void terminal_call_GSET(struct terminal *this, char c)
{
if (c < '0' || c > 'B'
|| ((term_action *)&this->callbacks.scs)[c - '0'] == NULL)
{
if (this->unimplemented != NULL)
this->unimplemented(this, "GSET", c);
goto leave;
}
((term_action *)&this->callbacks.scs)[c - '0'](this);
leave:
this->state = INIT;
this->stack_ptr = 0;
this->argc = 0;
}
/*
** INIT
** \_ ESC "\033"
** | \_ CSI "\033["
** | | \_ c == '?' : term->flag = '?'
** | | \_ c == ';' || (c >= '0' && c <= '9') : term_push
** | | \_ else : term_call_CSI()
** | \_ HASH "\033#"
** | | \_ term_call_hash()
** | \_ G0SET "\033("
** | | \_ term_call_GSET()
** | \_ G1SET "\033)"
** | | \_ term_call_GSET()
** \_ term->write()
*/
void terminal_read(struct terminal *this, char c)
{
if (this->state == INIT)
{
if (c == '\033')
this->state = ESC;
else
this->write(this, c);
}
else if (this->state == ESC)
{
if (c == '[')
this->state = CSI;
else if (c == '#')
this->state = HASH;
else if (c == '(')
this->state = G0SET;
else if (c == ')')
this->state = G1SET;
else if (c >= '0' && c <= 'z')
terminal_call_ESC(this, c);
else this->write(this, c);
}
else if (this->state == HASH)
{
if (c >= '0' && c <= '9')
terminal_call_HASH(this, c);
else
this->write(this, c);
}
else if (this->state == G0SET || this->state == G1SET)
{
terminal_call_GSET(this, c);
}
else if (this->state == CSI)
{
if (c == '?')
this->flag = '?';
else if (c == ';' || (c >= '0' && c <= '9'))
terminal_push(this, c);
else if (c >= '?' && c <= 'z')
terminal_call_CSI(this, c);
else
this->write(this, c);
}
}
void terminal_read_str(struct terminal *this, char *c)
{
while (*c)
terminal_read(this, *c++);
}
#ifndef NDEBUG
void terminal_default_unimplemented(struct terminal* this, char *seq, char chr)
{
unsigned int argc;
fprintf(stderr, "WARNING: UNIMPLEMENTED %s (", seq);
for (argc = 0; argc < this->argc; ++argc)
{
fprintf(stderr, "%d", this->argv[argc]);
if (argc != this->argc - 1)
fprintf(stderr, ", ");
}
fprintf(stderr, ")%o\n", chr);
}
#else
void terminal_default_unimplemented(struct terminal* this, char *seq, char chr)
{
this = this;
seq = seq;
chr = chr;
}
#endif
struct terminal *terminal_init(void)
{
return calloc(1, sizeof(struct terminal));
}

View File

@ -128,10 +128,9 @@ struct terminal
int fd;
};
struct terminal *term_init(unsigned int width, unsigned int height,
void (*write)(struct terminal *, char));
void term_default_unimplemented(struct terminal* term, char *seq, char chr);
void term_read(struct terminal *term, char c);
void term_read_str(struct terminal *term, char *c);
struct terminal *terminal_init(void);
void terminal_default_unimplemented(struct terminal* term, char *seq, char chr);
void terminal_read(struct terminal *term, char c);
void terminal_read_str(struct terminal *term, char *c);
#endif

View File

@ -919,7 +919,10 @@ struct terminal *vt100_init(void (*unimplemented)(struct terminal* term_emul, ch
vt100->y = 0;
vt100->modes = MASK_DECANM;
vt100->top_line = 0;
term = term_init(80, 24, vt100_write);
term = terminal_init();
term->width = 80;
term->height = 24;
term->write = vt100_write;
term->callbacks.csi.f = HVP;
term->callbacks.csi.K = EL;
term->callbacks.csi.c = DA;

View File

@ -1,7 +1,7 @@
#ifndef __VT100_H__
#define __VT100_H__
#include "term.h"
#include "terminal.h"
/*
* Source : http://vt100.net/docs/vt100-ug/chapter3.html