Browse code

Reworked plugin API

Dario Rodriguez authored on 09/04/2019 14:28:44
Showing 5 changed files
... ...
@@ -467,13 +467,14 @@ redata_fix_nl(redata_t *redata, int chunkno)
467 467
 }
468 468
 
469 469
 int
470
-redata_load(redata_t *redata, char *filename, int use_unsaved)
470
+redata_load(redata_t *redata, char *filename, int (*callback_question)(/*char *title, char *body, int nopts, char *opts[],void *userptr*/), void *userptr)
471 471
 {
472 472
         int fd,nread,totalread;
473 473
         int chunkno, avail;
474 474
         struct stat statbuf;
475 475
         rechunk_t *chunk;
476 476
         int i;
477
+        int reply;
477 478
         if(redata==NULL || filename==NULL)
478 479
                 return(-1); /* sanity check failed */
479 480
         redata_wipe(redata);
... ...
@@ -520,18 +521,20 @@ redata_load(redata_t *redata, char *filename, int use_unsaved)
520 521
                 redata_fix_nl(redata,chunkno);
521 522
         for(chunkno=0;chunkno<redata->sizechunks;chunkno++)
522 523
                 redata_whatin_refresh(redata,chunkno);
523
-        /* unsaved */
524
+        /* unsaved and other plugins */
524 525
         for(i=0;i<redata->sizeplugins;i++) {
525
-                if(use_unsaved) {
526
-                        /* apply missing changes and append new changes to unsaved */
527
-                        if(redata->plugins[i].postload!=NULL)
528
-                                redata->plugins[i].postload(redata,redata->plugins+i,filename);
529
-                } else {
530
-                        /* nuke existing unsaved (if exists) and prepare new unsaved */
531
-                        /* _trunc() fills itself redata->initialhash */
532
-                        if(redata->plugins[i].truncload!=NULL)
533
-                                redata->plugins[i].truncload(redata,redata->plugins+i,filename);
526
+                if(!redata->plugins[i].active)
527
+                        continue;
528
+                reply=-1;
529
+                if(redata->plugins[i].loadquestion!=NULL && callback_question!=NULL) {
530
+                        char *title, *body;
531
+                        int nopts;
532
+                        char **opts;
533
+                        if(redata->plugins[i].loadquestion(redata,redata->plugins+i,filename,&title,&body,&nopts,&opts)!=-1)
534
+                                reply=callback_question(title,body,nopts,opts,userptr);
534 535
                 }
536
+                if(redata->plugins[i].postload!=NULL)
537
+                        redata->plugins[i].postload(redata,redata->plugins+i,filename,reply);
535 538
         }
536 539
         /* all done */
537 540
         return(0);
... ...
@@ -13,6 +13,8 @@
13 13
 
14 14
 #include <limits.h>
15 15
 
16
+#define MAXPLUGINNAME 32
17
+
16 18
 typedef struct whatin_t {
17 19
         int nlcount;
18 20
 } whatin_t;
... ...
@@ -43,22 +45,19 @@ typedef struct undostack_t {
43 45
         char *buf;
44 46
 } undostack_t;
45 47
 
46
-#define PLUGIN_CHECKUSERCONFIRM 1 /* if check is Ok, confirm with user whether to postload or go inactive */
47
-
48 48
 typedef struct redata_plugin_t {
49 49
         int active;
50
+        char name[MAXPLUGINNAME];
50 51
         int (*unregister)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/);
51
-        /* checkload returns 0:Ok, 1:Not needed, -1: error, go inactive */
52 52
         int (*wipe)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/);
53
-        int (*checkload)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/);
54
-        int (*postload)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/);
55
-        int (*truncload)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/);
53
+        /* loadquestion returns -1 if no question needed */
54
+        int (*loadquestion)(/*redata_t *redata, redata_plugin_t *plugin,char *filename, char **title, char **body, int *nopts, char **opts[] */);
55
+        int (*postload)(/*redata_t *redata, redata_plugin_t *plugin,char *filename,int questionreply */);
56 56
         int (*postsave)(/*redata_t *redata, redata_plugin_t *plugin,char *oldfilename,char *newfilename*/);
57 57
         int (*add)(/*redata_t *redata, redata_plugin_t *plugin,undo_t *undo*/);
58 58
         int (*unadd)(/*redata_t *redata, redata_plugin_t *plugin,undo_t *undo*/);
59 59
         int (*commit)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/);
60 60
         void *userptr;
61
-        int flags;
62 61
 } redata_plugin_t;
63 62
 
64 63
 typedef struct redata_t {
... ...
@@ -77,7 +76,6 @@ typedef struct redata_t {
77 76
         redata_plugin_t plugins[1];
78 77
 } redata_t;
79 78
 
80
-#warning TODO: Make redata_xxx call the plugins
81 79
 redata_t *redata_init( int (*pluginregisterfn)(redata_t *redata, redata_plugin_t *slot), ...);
82 80
 void redata_free(redata_t *redata);
83 81
 
... ...
@@ -111,7 +109,7 @@ int redata_undo_inactivatelast(redata_t *redata, undostack_t *stack);
111 109
 int redata_undo_reactivatelast(redata_t *redata, undostack_t *stack);
112 110
 
113 111
 /* high level stuff */
114
-int redata_load(redata_t *redata, char *filename, int use_unsaved);
112
+int redata_load(redata_t *redata, char *filename, int (*callback_question)(/*char *title, char *body, int nopts, char *opts[],void *userptr*/), void *userptr);
115 113
 int redata_save(redata_t *redata, char *filename);
116 114
 
117 115
 int redata_op_add(redata_t *redata, long pos, char *buf, long buflen, undostack_t *fromhere);
... ...
@@ -28,6 +28,8 @@
28 28
 
29 29
 
30 30
 
31
+static int redata_unsaved_loadquestion(redata_t *redata, redata_plugin_t *slot,char *filename, char **title, char **body, int *nopts, char **opts[]);
32
+static int redata_unsaved_postload(redata_t *redata, redata_plugin_t *slot,char *filename,int questionreply);
31 33
 static int redata_unsaved_check_gen(redata_t *redata, redata_plugin_t *slot, char *filename);
32 34
 static char *unsaved_genname(char *filename, char *buf, int bufsize);
33 35
 static char *ptr_getlong(char *ptr,char *endptr,long *data);
... ...
@@ -46,15 +48,16 @@ redata_unsaved_register(redata_t *redata, redata_plugin_t *slot)
46 48
         memset(unsaved,0,sizeof(unsaved_t));
47 49
         unsaved->unsavedfd=-1;
48 50
         unsaved->sizebuf=unsaved->usedbuf=0;
51
+        strncpy(slot->name,"unsaved",sizeof(slot->name));
52
+        slot->name[sizeof(slot->name)-1]='\0';
49 53
         slot->unregister=redata_unsaved_unregister;
50
-        slot->checkload=redata_unsaved_check;
54
+        slot->loadquestion=redata_unsaved_loadquestion;
51 55
         slot->wipe=redata_unsaved_wipe;
52
-        slot->postload=redata_unsaved_loadappend;
53
-        slot->truncload=redata_unsaved_truncload;
56
+        slot->postload=redata_unsaved_postload;
54 57
         slot->postsave=redata_unsaved_trunc;
55 58
         slot->add=redata_unsaved_add;
56 59
         slot->unadd=redata_unsaved_unadd;
57
-        slot->flags=PLUGIN_CHECKUSERCONFIRM;
60
+        slot->commit=redata_unsaved_commit;
58 61
         return(0);
59 62
 }
60 63
 
... ...
@@ -484,6 +487,35 @@ redata_unsaved_commit(redata_t *redata, redata_plugin_t *slot,char *filename)
484 487
         return(0);
485 488
 }
486 489
 
490
+static int
491
+redata_unsaved_loadquestion(redata_t *redata, redata_plugin_t *slot,char *filename, char **title, char **body, int *nopts, char **opts[])
492
+{
493
+        static char mytitle[]={"Unsaved data from a previous session detected"};
494
+        static char mybody[]={"The file you're trying to load has some unsaved data from a previous session. I can recover the data. What do you want to do?"};
495
+        static char *myopts[]={"Recover unsaved data (safest option)","Don't use old unsaved data, delete old unsaved data (if you're sure what you're doing)"};
496
+        if(redata==NULL || slot==NULL || filename==NULL || title==NULL || body==NULL || nopts==NULL || opts==NULL)
497
+                return(-1); /* sanity check failed */
498
+        if(redata_unsaved_check(redata,slot,filename)==-1)
499
+                return(-1); /* no unsaved data on disk */
500
+        *title=mytitle;
501
+        *body=mybody;
502
+        *opts=myopts;
503
+        *nopts=2;
504
+        return(0);
505
+}
506
+
507
+static int
508
+redata_unsaved_postload(redata_t *redata, redata_plugin_t *slot,char *filename,int questionreply)
509
+{
510
+        /* questionreply is from loadquestion, specifically the selected element in the array "opts" */
511
+        if(questionreply==0) /* recover */
512
+                return(redata_unsaved_loadappend(redata, slot, filename));
513
+        else if(questionreply==1 || questionreply==-1) /* delete unsaved data */
514
+                return(redata_unsaved_truncload(redata, slot, filename));
515
+        return(-1);
516
+}
517
+
518
+
487 519
 static char *
488 520
 unsaved_genname(char *filename, char *buf, int bufsize)
489 521
 {
... ...
@@ -154,7 +154,7 @@ fprintf(stderr,"\ntest_newfile(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL)
154 154
         redata_filehash(redata,filename,hash129_pre);
155 155
         free(mem),mem=NULL;
156 156
         /* load file */
157
-        if(redata_load(redata,filename,0)!=0) {
157
+        if(redata_load(redata,filename,NULL,NULL)!=0) {
158 158
                 unlink(filename);
159 159
                 return("couldn't load file");
160 160
         }
... ...
@@ -359,7 +359,7 @@ redata_save(redata,"test.redo");
359 359
                                 return("insuf. mem. for temp. buffer");
360 360
                         if(write_file(filename,mem,filesize)==-1)
361 361
                                 return("couldn't create temporary file");
362
-                        if(redata_load(redata,filename,0)!=0) {
362
+                        if(redata_load(redata,filename,NULL,NULL)!=0) {
363 363
                                 unlink(filename);
364 364
                                 return("couldn't load file");
365 365
                         }
... ...
@@ -43,7 +43,7 @@ main(int argc, char *argv[])
43 43
                 re_free(re),re=NULL;
44 44
                 return(2);
45 45
         }
46
-        if((redata_load(re->redata,re->filename,0))!=0)
46
+        if((redata_load(re->redata,re->filename,NULL,NULL))!=0)
47 47
                 re->flag_newfile=1;
48 48
         else
49 49
                 re->flag_newfile=0;