diff options
author | andmarti1424 <andmarti@gmail.com> | 2017-03-14 22:54:21 -0300 |
---|---|---|
committer | andmarti1424 <andmarti@gmail.com> | 2017-03-14 22:54:21 -0300 |
commit | c444f0f587a012e7666e6b9f77110b89dd458dbe (patch) | |
tree | ab9da2914f5af8fdfe56e1bdac829cd42d63fab6 /src/trigger.c | |
parent | 387ca866ee6a411bdf46ed4be1f0b3055dfa65e0 (diff) |
Add files
Diffstat (limited to 'src/trigger.c')
-rw-r--r-- | src/trigger.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/trigger.c b/src/trigger.c new file mode 100644 index 0000000..8600fd2 --- /dev/null +++ b/src/trigger.c @@ -0,0 +1,156 @@ +/* R.Pollak +This is general trigger support, Idea behind triggers, is when ever a value is changed triggers will be called on Write +and when ever a value will be evaluated a READ trigger will be fired +ent structure is extended with trigger structure + +Triggers need mode,type,file,function flags + mode - can be R,W,RW + type - C|LUA (later even SH) + file - File name of the Trigger commands file + function - Which function should be called for both Lua and C +*/ + +#include <sys/types.h> +#include <string.h> +#include <stdlib.h> // for atoi +#include <ncurses.h> +#include <ctype.h> +#include <unistd.h> +#include <stdio.h> +#include <dlfcn.h> + +#include "sc.h" +#include "macros.h" +#include "utils/dictionary.h" +#include "utils/string.h" +#include "range.h" +#include "color.h" +#include "screen.h" +#include "undo.h" +#include "conf.h" +#include "cmds.h" +#include "trigger.h" + +void set_trigger(int r, int c, int rf, int cf, char * str) { + if (any_locked_cells(r, c, rf, cf)) { + sc_error("Locked cells encountered. Nothing changed"); + return; + } + + // parse detail + // Create key-value dictionary for the content of the string + struct dictionary * d = create_dictionary(); + + // Remove quotes + if (str[0]=='"') del_char(str, 0); + if (str[strlen(str)-1]=='"') del_char(str, strlen(str)-1); + + parse_str(d, str); + + if ( + (get(d,"mode") == NULL) || + (get(d,"type") == NULL) || + (get(d,"file") == NULL) || + (get(d,"function") == NULL )) { + sc_error("One of the values specified is wrong. Please check the values of type, fg and bg."); + destroy_dictionary(d); + return; + } + + struct ent * n; + int i, j; + for (i=r; i<=rf; i++) { + for (j=c; j<=cf; j++) { + // action + n = lookat(i, j); + if (n->trigger == NULL) + n->trigger = (struct trigger *) malloc(sizeof(struct trigger)); + else { + free(n->trigger->file); + free(n->trigger->function); + } + n->trigger->file = strdup(get(d,"file")); + n->trigger->function=strdup(get(d,"function")); + int tmp; + if (strcmp(get(d,"mode"), "R") == 0) tmp=TRG_READ; + if (strcmp(get(d,"mode"), "W") == 0) tmp=TRG_WRITE; + if (strcmp(get(d,"mode"), "RW")== 0) tmp=TRG_READ | TRG_WRITE; + if (strcmp(get(d,"type"), "LUA")== 0) tmp|=TRG_LUA; + if (strcmp(get(d,"type"), "C")== 0) { + char * error; + tmp|=TRG_C; + n->trigger->handle=dlopen(n->trigger->file,RTLD_LAZY); + if(!n->trigger->handle) { + fputs (dlerror(), stderr); + exit(1); + } + n->trigger->c_function = dlsym(n->trigger->handle, n->trigger->function); + if ((error = dlerror()) != NULL) { + fputs(error, stderr); + exit(1); + } + } + n->trigger->flag=tmp; + } + } + + destroy_dictionary(d); + return; +} + +void del_trigger(int r, int c, int rf, int cf ) { + if (any_locked_cells(r, c, rf, cf)) { + sc_error("Locked cells encountered. Nothing changed"); + return; + } + + struct ent * n; + int i, j; + for (i=r; i<=rf; i++) { + for (j=c; j<=cf; j++) { + // action + n = lookat(i, j); + if (n->trigger != NULL ) { + if ((n->trigger->flag & TRG_C) == TRG_C) { + dlclose(n->trigger->handle); + } + free(n->trigger->file); + free(n->trigger->function); + free(n->trigger); + n->trigger=NULL; + } + } + } + return; +} + +struct ent ** ATBL(struct ent ***tbl, int row, int col) { + struct ent **ent=(*(tbl+row)+(col)); + struct ent *v= *ent; + + if ((v) && (v->trigger) && ((v->trigger->flag & TRG_READ) == TRG_READ)) + do_trigger(v,TRG_READ); + return ent; +} + +static int in_trigger = 0; + +void do_trigger( struct ent *p , int rw) { + struct trigger *trigger = p->trigger; + if(in_trigger) return; + in_trigger = 1; + if ((trigger->flag & TRG_LUA ) == TRG_LUA) + doLuaTrigger_cell(p,rw); + if ((trigger->flag & TRG_C ) == TRG_C) + do_C_Trigger_cell(p,rw); + in_trigger = 0; + return; +} + +void do_C_Trigger_cell(struct ent * p, int rw) { + int (*function)(struct ent *, int ); + + function=p->trigger->c_function; + printf ("%d\n", (*function)(p,rw )); + return; +} |