From 9cf645d6c720fb0a21f85da22b4cc404a3b5e546 Mon Sep 17 00:00:00 2001 From: Diego Hernan Borghetti Date: Wed, 5 May 2010 19:16:13 -0300 Subject: [PATCH] Basic syntax system, right now only C and hardcode in eco! This need a lot more of work, but it's a start, still two important thing to do: 1) Read the syntax file from a external config file, like put all the definition in ~/.eco/syntax/cmode and the same with the rest. 2) Set the syntax for every buffer and fix the screen to take the syntax from there. --- Makefile | 1 + main.c | 73 +++++++++++++++++++++- screen.c | 22 +++++++ screen.h | 4 ++ syntax.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ syntax.h | 64 ++++++++++++++++++++ update.c | 4 ++ 7 files changed, 375 insertions(+), 1 deletion(-) create mode 100644 syntax.c create mode 100644 syntax.h diff --git a/Makefile b/Makefile index 1bd2804..7baaa85 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ OBJS += list.o OBJS += fd.o OBJS += time.o OBJS += timer.o +OBJS += syntax.o TARGET = eco diff --git a/main.c b/main.c index 9fddf61..7447d50 100644 --- a/main.c +++ b/main.c @@ -10,6 +10,7 @@ #include #include "debug.h" +#include "list.h" #include "fd.h" #include "timer.h" #include "time.h" @@ -26,12 +27,79 @@ #include "cmd.h" #include "config.h" #include "kill.h" +#include "syntax.h" /* only global in this file!! */ E_Eco *E; -int e_check_unsave(E_Eco *ec) +/* make a C dictionary! */ +static int e_cmode_check(char *ext) +{ + if (!strcmp(ext, ".c")) + return(0); + else if (!strcmp(ext, ".C")) + return(0); + return(1); +} + +static void e_cmode_init(void) +{ + E_Syntax *sy; + + sy= e_syntax_new(); + sy->name= strdup("C Mode"); + sy->check_type= e_cmode_check; + sy->dirs.first= NULL; + sy->dirs.last= NULL; + + e_syntax_word_add(sy, "void", E_TR_RED, E_TR_BLACK); + e_syntax_word_add(sy, "int", E_TR_RED, E_TR_BLACK); + e_syntax_word_add(sy, "char", E_TR_RED, E_TR_BLACK); + e_syntax_word_add(sy, "float", E_TR_RED, E_TR_BLACK); + e_syntax_word_add(sy, "double", E_TR_RED, E_TR_BLACK); + e_syntax_word_add(sy, "long", E_TR_RED, E_TR_BLACK); + e_syntax_word_add(sy, "struct", E_TR_RED, E_TR_BLACK); + e_syntax_word_add(sy, "typedef", E_TR_RED, E_TR_BLACK); + e_syntax_word_add(sy, "static", E_TR_RED, E_TR_BLACK); + e_syntax_word_add(sy, "inline", E_TR_RED, E_TR_BLACK); + + e_syntax_word_add(sy, "if", E_TR_CYAN, E_TR_BLACK); + e_syntax_word_add(sy, "else", E_TR_CYAN, E_TR_BLACK); + e_syntax_word_add(sy, "else if", E_TR_CYAN, E_TR_BLACK); + e_syntax_word_add(sy, "while", E_TR_CYAN, E_TR_BLACK); + e_syntax_word_add(sy, "for", E_TR_CYAN, E_TR_BLACK); + e_syntax_word_add(sy, "do", E_TR_CYAN, E_TR_BLACK); + e_syntax_word_add(sy, "return", E_TR_BLUE, E_TR_BLACK); + e_syntax_word_add(sy, "return;", E_TR_BLUE, E_TR_BLACK); + e_syntax_word_add(sy, "#ifndef", E_TR_CYAN, E_TR_BLACK); + e_syntax_word_add(sy, "#define", E_TR_CYAN, E_TR_BLACK); + e_syntax_word_add(sy, "#endif", E_TR_CYAN, E_TR_BLACK); + e_syntax_word_add(sy, "#include", E_TR_GREEN, E_TR_BLACK); + e_syntax_word_add(sy, "malloc", E_TR_RED, E_TR_BLACK); + e_syntax_word_add(sy, "free", E_TR_RED, E_TR_BLACK); + e_syntax_word_add(sy, "realloc", E_TR_RED, E_TR_BLACK); + + e_syntax_char_add(sy, '{', E_TR_YELLOW, E_TR_BLACK); + e_syntax_char_add(sy, '}', E_TR_YELLOW, E_TR_BLACK); + + e_syntax_char_add(sy, '(', E_TR_YELLOW, E_TR_BLACK); + e_syntax_char_add(sy, ')', E_TR_YELLOW, E_TR_BLACK); + e_syntax_char_add(sy, '[', E_TR_YELLOW, E_TR_BLACK); + e_syntax_char_add(sy, ']', E_TR_YELLOW, E_TR_BLACK); + + e_syntax_char_add(sy, '=', E_TR_GREEN, E_TR_BLACK); + e_syntax_char_add(sy, ',', E_TR_GREEN, E_TR_BLACK); + e_syntax_char_add(sy, '.', E_TR_GREEN, E_TR_BLACK); + e_syntax_char_add(sy, ';', E_TR_GREEN, E_TR_BLACK); + e_syntax_char_add(sy, '*', E_TR_YELLOW, E_TR_BLACK); + e_syntax_char_add(sy, '/', E_TR_YELLOW, E_TR_BLACK); + e_syntax_char_add(sy, '"', E_TR_GREEN, E_TR_BLACK); + + e_syntax_add(sy); +} + +static int e_check_unsave(E_Eco *ec) { E_Buffer *p; char *s, *buf; @@ -402,6 +470,9 @@ int main(int argc, char **argv) /* set the poll function. */ e_fd_add(fileno(stdin), e_fd_read, NULL); + /* register the cmode in the system. */ + e_cmode_init(); + /* and start the loop. */ E->loop= 1; diff --git a/screen.c b/screen.c index c6aefb2..2003e62 100644 --- a/screen.c +++ b/screen.c @@ -9,6 +9,8 @@ #include "term.h" #include "screen.h" +#include "list.h" +#include "syntax.h" E_Screen *e_screen_init(E_Term *tr) @@ -46,6 +48,7 @@ E_Screen *e_screen_init(E_Term *tr) } ln->fcol= (char *)malloc(tr->ncol); ln->bcol= (char *)malloc(tr->ncol); + ln->crow= 0; for (e= 0; e < tr->ncol; e++) { ln->fcol[e]= E_TR_WHITE; ln->bcol[e]= E_TR_BLACK; @@ -58,6 +61,7 @@ E_Screen *e_screen_init(E_Term *tr) perror("malloc"); exit(-1); } + ln->crow= 0; ln->fcol= (char *)malloc(tr->ncol); ln->bcol= (char *)malloc(tr->ncol); for (e= 0; e < tr->ncol; e++) { @@ -109,6 +113,16 @@ void e_screen_move(E_Screen *sc, int row, int col) sc->col= col; } +void e_screen_crow(E_Screen *sc, int row, char crow) +{ + E_ScreenLine *ln; + + if (row >= 0 && row < sc->nrow) { + ln= sc->vscr[row]; + ln->crow= crow; + } +} + void e_screen_eeol(E_Screen *sc) { E_ScreenLine *ln; @@ -144,8 +158,12 @@ void e_screen_eeop(E_Screen *sc) void e_screen_swap(E_Term *tr, E_Screen *sc, int user_force) { E_ScreenLine *vln, *pln; + E_Syntax *sy; int e, i, force; + /* FIXME! */ + sy= e_syntax_search(".c"); + /* default color, white and black. */ e_term_fgcol(tr, E_TR_WHITE); e_term_bgcol(tr, E_TR_BLACK); @@ -155,6 +173,10 @@ void e_screen_swap(E_Term *tr, E_Screen *sc, int user_force) pln= sc->pscr[e]; force= user_force; + /* Apply the color but skip current row. */ + if (sy && vln->crow == 0) + e_syntax_apply(sy, vln, sc->ncol); + for (i= 0; i < sc->ncol; i++) { /* Check for color changes. */ if (vln->fcol[i] != pln->fcol[i] || diff --git a/screen.h b/screen.h index 2c31956..98adcc3 100644 --- a/screen.h +++ b/screen.h @@ -10,6 +10,9 @@ typedef struct _E_ScreenLine { char *fcol; char *bcol; + /* is this the current row ? */ + char crow; + char text[]; } E_ScreenLine; @@ -33,6 +36,7 @@ void e_screen_putc(E_Screen *sc, int c, char fcol, char bcol); void e_screen_move(E_Screen *sc, int row, int col); void e_screen_eeol(E_Screen *sc); void e_screen_eeop(E_Screen *sc); +void e_screen_crow(E_Screen *sc, int row, char crow); void e_screen_swap(E_Term *tr, E_Screen *sc, int user_force); #endif /* _ECO_SCREEN_H */ diff --git a/syntax.c b/syntax.c new file mode 100644 index 0000000..b676883 --- /dev/null +++ b/syntax.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2010 Diego Hernan Borghetti. + * Eco + */ + +#include +#include +#include + +#include "debug.h" +#include "list.h" +#include "term.h" +#include "screen.h" +#include "syntax.h" + + +/* our syntax data base. */ +static E_List syntaxs= { NULL, NULL }; + +static E_Syntax_Word *e_syntax_word_search(E_Syntax *sy, char *word, int nch) +{ + E_Syntax_Word *p; + + p= (E_Syntax_Word *)sy->dirs.first; + while (p) { + if (p->nch == nch) { + if (!strncmp(p->word, word, nch)) + return(p); + } + p= p->next; + } + + return(NULL); +} + +static E_Syntax_Char *e_syntax_char_search(E_Syntax *sy, char ch) +{ + E_Syntax_Char *p; + + p= (E_Syntax_Char *)sy->chars.first; + while (p) { + if (p->ch == ch) + return(p); + p= p->next; + } + return(NULL); +} + +E_Syntax *e_syntax_search(char *ext) +{ + E_Syntax *p; + + p= (E_Syntax *)syntaxs.first; + while (p) { + if ((*p->check_type)(ext) == 0) + return(p); + p= p->next; + } + return(NULL); +} + +void e_syntax_add(E_Syntax *sy) +{ + if (sy) { + E_LIST_ADD(&syntaxs, sy); + } +} + +void e_syntax_rem(E_Syntax *sy) +{ + if (sy) { + E_LIST_REM(&syntaxs, sy); + } +} + +E_Syntax *e_syntax_new(void) +{ + E_Syntax *sy; + + sy= (E_Syntax *)malloc(sizeof(E_Syntax)); + sy->next= NULL; + sy->prev= NULL; + sy->name= NULL; + sy->check_type= NULL; + sy->dirs.first= NULL; + sy->dirs.last= NULL; + sy->chars.first= NULL; + sy->chars.last= NULL; + return(sy); +} + +void e_syntax_free(E_Syntax *sy) +{ + E_Syntax_Word *p; + + while (sy->dirs.first) { + p= (E_Syntax_Word *)sy->dirs.first; + sy->dirs.first= sy->dirs.first->next; + free((void *)p->word); + free((void *)p); + } + + if (sy->name) + free((void *)sy->name); + + free((void *)sy); +} + +void e_syntax_word_add(E_Syntax *sy, char *word, char fg, char bg) +{ + E_Syntax_Word *wr; + + wr= e_syntax_word_search(sy, word, strlen(word)); + if (wr) + return; + + wr= (E_Syntax_Word *)malloc(sizeof(E_Syntax_Word)); + wr->next= NULL; + wr->prev= NULL; + wr->word= strdup(word); + wr->nch= strlen(wr->word); + wr->fgcol= fg; + wr->bgcol= bg; + E_LIST_ADD(&sy->dirs, wr); +} + +void e_syntax_char_add(E_Syntax *sy, char ch, char fg, char bg) +{ + E_Syntax_Char *cha; + + cha= e_syntax_char_search(sy, ch); + if (cha) + return; + + cha= (E_Syntax_Char *)malloc(sizeof(E_Syntax_Char)); + cha->next= NULL; + cha->prev= NULL; + cha->ch= ch; + cha->fgcol= fg; + cha->bgcol= bg; + E_LIST_ADD(&sy->chars, cha); +} + +static int e_syntax_word(char *line, int *idx, int nch) +{ + int i, e, first; + + first= 0; + e= 0; + for (i= *idx; i < nch; i++) { + if (line[i] != ' ' && line[i] != '\t' && !first) { + *idx= i; + first= 1; + } + + if (first && (line[i] == ' ' || line[i] == '\t')) + return(e); + if (first) + e++; + } + return(-1); +} + +static void e_syntax_color(E_Syntax_Word *wr, E_ScreenLine *ln, int i, int nch) +{ + int e; + + for (e= i; e < (i+nch); e++) { + ln->fcol[e]= wr->fgcol; + ln->bcol[e]= wr->bgcol; + } +} + +void e_syntax_apply(E_Syntax *sy, E_ScreenLine *ln, int ncol) +{ + E_Syntax_Word *wr; + E_Syntax_Char *ch; + int i, nch; + + i= 0; + + /* First round, check for words. */ +do_word: + nch= e_syntax_word(ln->text, &i, ncol); + if (nch == -1) { + goto do_char; + return; + } + + wr= e_syntax_word_search(sy, &(ln->text[i]), nch); + if (wr) + e_syntax_color(wr, ln, i, nch); + + if (i+nch < ncol) { + i += nch; + goto do_word; + } + + /* Second round, check for characters. */ +do_char: + for (i= 0; i < ncol; i++) { + ch= e_syntax_char_search(sy, ln->text[i]); + if (ch) { + ln->fcol[i]= ch->fgcol; + ln->bcol[i]= ch->bgcol; + } + } +} diff --git a/syntax.h b/syntax.h new file mode 100644 index 0000000..ba7f1f5 --- /dev/null +++ b/syntax.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010 Diego Hernan Borghetti. + */ + +#ifndef _ECO_SYNTAX_H +#define _ECO_SYNTAX_H + +typedef struct _E_Syntax_Word { + struct _E_Syntax_Word *next; + struct _E_Syntax_Word *prev; + + /* the character's for this word (or only one). */ + char *word; + + /* number of characters. */ + int nch; + + /* color to apply, foreground and background. */ + char fgcol; + char bgcol; +} E_Syntax_Word; + +typedef struct _E_Syntax_Char { + struct _E_Syntax_Char *next; + struct _E_Syntax_Char *prev; + + /* the character. */ + char ch; + + /* color to apply, foreground and background. */ + char fgcol; + char bgcol; +} E_Syntax_Char; + +typedef struct _E_Syntax { + struct _E_Syntax *next; + struct _E_Syntax *prev; + + /* language name. */ + char *name; + + /* Function to check the file type. + * The argument is the file extension or NULL! + * return zero on success or different that zero otherwise. + */ + int (*check_type)(char *); + + /* the dictionary of word's. */ + E_List dirs; + + /* and only character, for second round. */ + E_List chars; +} E_Syntax; + +E_Syntax *e_syntax_search(char *ext); +void e_syntax_add(E_Syntax *sy); +void e_syntax_rem(E_Syntax *sy); +E_Syntax *e_syntax_new(void); +void e_syntax_free(E_Syntax *sy); +void e_syntax_word_add(E_Syntax *sy, char *word, char fg, char bg); +void e_syntax_char_add(E_Syntax *sy, char ch, char fg, char bg); +void e_syntax_apply(E_Syntax *sy, E_ScreenLine *ln, int ncol); + +#endif /* _ECO_SYNTAX_H */ diff --git a/update.c b/update.c index b9c08d1..8bea188 100644 --- a/update.c +++ b/update.c @@ -30,10 +30,14 @@ int e_update_line(E_Eco *ec, E_Line *ln, int row) char fgcol, bgcol; if (ec->view->b->line == ln) { + /* Mark the current line in the screen. */ + e_screen_crow(ec->sc, row, 1); invert= 1; i= ec->view->b->dot_pad; } else { + /* clear the flag if this is not the current line. */ + e_screen_crow(ec->sc, row, 0); invert= 0; i= 0; } -- 2.11.4.GIT