... | ... |
@@ -94,6 +94,7 @@ redata_init(int (*pluginregisterfn)(redata_t *redata, redata_plugin_t *slot), .. |
94 | 94 |
redata->undostack.undo=NULL; |
95 | 95 |
redata->undostack.buf=NULL; |
96 | 96 |
/* plugins */ |
97 |
+ va_start(args,pluginregisterfn); |
|
97 | 98 |
for(nargs=0,fn=pluginregisterfn;fn!=NULL;fn=va_arg(args,int (*)(redata_t *redata,redata_plugin_t *slot))) { |
98 | 99 |
res=fn(redata,redata->plugins+nargs); |
99 | 100 |
redata->plugins[nargs].active=(res==0)?1:0; |
... | ... |
@@ -146,6 +147,20 @@ redata_free(redata_t *redata) |
146 | 147 |
return; |
147 | 148 |
} |
148 | 149 |
|
150 |
+void |
|
151 |
+redata_idleproc(redata_t *redata, char *filename) |
|
152 |
+{ |
|
153 |
+ int i; |
|
154 |
+ if(redata==NULL) |
|
155 |
+ return; |
|
156 |
+ for(i=0;i<redata->sizeplugins;i++) { |
|
157 |
+ if(redata->plugins[i].commit!=NULL) |
|
158 |
+ redata->plugins[i].commit(redata,redata->plugins+i,filename); |
|
159 |
+ } |
|
160 |
+ return; |
|
161 |
+} |
|
162 |
+ |
|
163 |
+ |
|
149 | 164 |
int |
150 | 165 |
redata_config_chunkdatasize(redata_t *redata, int chunkdatasize) |
151 | 166 |
{ |
... | ... |
@@ -524,27 +539,94 @@ redata_fix_nl(redata_t *redata, int chunkno) |
524 | 539 |
} |
525 | 540 |
|
526 | 541 |
int |
527 |
-redata_load(redata_t *redata, char *filename, int (*callback_question)(/*char *title, char *body, int nopts, char *opts[],void *userptr*/), void *userptr) |
|
542 |
+redata_loadquestions_setup(redata_t *redata, char *filename) |
|
543 |
+{ |
|
544 |
+ int i; |
|
545 |
+ if(redata==NULL || filename==NULL) |
|
546 |
+ return(-1); /* sanity check failed */ |
|
547 |
+ redata_loadquestions_wipe(redata); |
|
548 |
+ /* unsaved and other plugins: loadquestion (pre-to-load) */ |
|
549 |
+ for(i=0;i<redata->sizeplugins;i++) { |
|
550 |
+ if(!redata->plugins[i].active) |
|
551 |
+ continue; |
|
552 |
+ if(redata->plugins[i].loadquestion!=NULL) |
|
553 |
+ redata->plugins[i].loadquestion(redata,redata->plugins+i,filename); |
|
554 |
+ } |
|
555 |
+ return(0); |
|
556 |
+ |
|
557 |
+} |
|
558 |
+ |
|
559 |
+question_t * |
|
560 |
+redata_loadquestions_getnext(redata_t *redata) |
|
561 |
+{ |
|
562 |
+ int i; |
|
563 |
+ if(redata==NULL) |
|
564 |
+ return(NULL); /* sanity check failed */ |
|
565 |
+ for(i=0;i<redata->sizeplugins;i++) { |
|
566 |
+ if(!redata->plugins[i].active || redata->plugins[i].question.active==0) |
|
567 |
+ continue; |
|
568 |
+ if(redata->plugins[i].question.selectedoption==-1) |
|
569 |
+ return(&(redata->plugins[i].question)); |
|
570 |
+ } |
|
571 |
+ return(NULL); /* no more questions */ |
|
572 |
+} |
|
573 |
+ |
|
574 |
+int |
|
575 |
+redata_loadquestions_reply(redata_t *redata, question_t *question, int selectedoption) |
|
576 |
+{ |
|
577 |
+ if(redata==NULL || question==NULL || selectedoption<-1 || selectedoption>=question->nopts) |
|
578 |
+ return(-1); |
|
579 |
+ question->selectedoption=(selectedoption==-1)?question->defaultoption:selectedoption; |
|
580 |
+ return(0); |
|
581 |
+} |
|
582 |
+ |
|
583 |
+int |
|
584 |
+redata_loadquestions_wipe(redata_t *redata) |
|
528 | 585 |
{ |
586 |
+ int i; |
|
587 |
+ if(redata==NULL) |
|
588 |
+ return(-1); |
|
589 |
+ for(i=0;i<redata->sizeplugins;i++) { |
|
590 |
+ if(!redata->plugins[i].active) |
|
591 |
+ continue; |
|
592 |
+ memset(redata->plugins[i].questionfilename,0,sizeof(redata->plugins[i].questionfilename)); |
|
593 |
+ memset(&(redata->plugins[i].question),0,sizeof(redata->plugins[i].question)); |
|
594 |
+ redata->plugins[i].question.active=0; |
|
595 |
+ redata->plugins[i].question.selectedoption=-1; |
|
596 |
+ } |
|
597 |
+ return(0); |
|
598 |
+} |
|
599 |
+ |
|
600 |
+int |
|
601 |
+redata_load(redata_t *redata, char *filename, char **errordesc) |
|
602 |
+{ |
|
603 |
+#warning TODO: what to do when there plugins with questions AFTER loading instead of before loading... |
|
529 | 604 |
int fd,nread,totalread; |
530 | 605 |
int chunkno, avail; |
531 | 606 |
struct stat statbuf; |
532 | 607 |
rechunk_t *chunk; |
533 | 608 |
int i; |
534 | 609 |
int reply; |
535 |
- if(redata==NULL || filename==NULL) |
|
610 |
+ if(redata==NULL || filename==NULL) { |
|
611 |
+ if(errordesc!=NULL) |
|
612 |
+ *errordesc="Internal error"; |
|
536 | 613 |
return(-1); /* sanity check failed */ |
614 |
+ } |
|
537 | 615 |
redata_wipe(redata); |
538 | 616 |
strncpy(redata->filename,filename,sizeof(redata->filename)); |
539 | 617 |
redata->filename[sizeof(redata->filename)-1]='\0'; |
540 | 618 |
if((fd=open(filename,O_RDONLY))==-1 || fstat(fd,&statbuf)!=0 || !S_ISREG(statbuf.st_mode)) { |
541 | 619 |
if(fd!=-1) |
542 | 620 |
close(fd),fd=-1; |
543 |
- return(-1); /* file not found, couldn't query size or not regular file */ |
|
621 |
+ if(errordesc!=NULL) |
|
622 |
+ *errordesc="File not found, couldn't query size or not a regular file"; |
|
623 |
+ return(-1); /* file not found, couldn't query size or not a regular file */ |
|
544 | 624 |
} |
545 | 625 |
/* preallocate 10% more than needed */ |
546 | 626 |
if(redata_preallocate(redata,statbuf.st_size+(statbuf.st_size/10)+1 )) { |
547 | 627 |
close(fd),fd=-1; |
628 |
+ if(errordesc!=NULL) |
|
629 |
+ *errordesc="Insufficient memory"; |
|
548 | 630 |
return(-1); /* insuf. mem. */ |
549 | 631 |
} |
550 | 632 |
for(totalread=0,chunkno=0,nread=0;totalread<statbuf.st_size;totalread+=nread,nread=0) { |
... | ... |
@@ -568,6 +650,8 @@ redata_load(redata_t *redata, char *filename, int (*callback_question)(/*char *t |
568 | 650 |
} |
569 | 651 |
if((nread=read(fd,chunk->data+chunk->useddata,avail))<=0) { |
570 | 652 |
close(fd),fd=-1; |
653 |
+ if(errordesc!=NULL) |
|
654 |
+ *errordesc="Short read loading file"; |
|
571 | 655 |
return(-1); /* short read */ |
572 | 656 |
} |
573 | 657 |
chunk->useddata+=nread; |
... | ... |
@@ -578,49 +662,56 @@ redata_load(redata_t *redata, char *filename, int (*callback_question)(/*char *t |
578 | 662 |
redata_fix_nl(redata,chunkno); |
579 | 663 |
for(chunkno=0;chunkno<redata->sizechunks;chunkno++) |
580 | 664 |
redata_whatin_refresh(redata,chunkno); |
581 |
- /* unsaved and other plugins */ |
|
665 |
+ /* unsaved and other plugins: postload */ |
|
582 | 666 |
for(i=0;i<redata->sizeplugins;i++) { |
583 | 667 |
if(!redata->plugins[i].active) |
584 | 668 |
continue; |
585 |
- reply=-1; |
|
586 |
- if(redata->plugins[i].loadquestion!=NULL && callback_question!=NULL) { |
|
587 |
- char *title, *body; |
|
588 |
- int nopts; |
|
589 |
- char **opts; |
|
590 |
- if(redata->plugins[i].loadquestion(redata,redata->plugins+i,filename,&title,&body,&nopts,&opts)!=-1) |
|
591 |
- reply=callback_question(title,body,nopts,opts,userptr); |
|
592 |
- } |
|
593 | 669 |
if(redata->plugins[i].postload!=NULL) |
594 |
- redata->plugins[i].postload(redata,redata->plugins+i,filename,reply); |
|
670 |
+ redata->plugins[i].postload(redata,redata->plugins+i,filename); |
|
595 | 671 |
} |
672 |
+ redata_loadquestions_wipe(redata); |
|
673 |
+#warning TODO: IMPLEMENT POSTLOADQUESTIONS (call now loadquestion_postload). |
|
596 | 674 |
/* all done */ |
597 | 675 |
return(0); |
598 | 676 |
} |
599 | 677 |
|
600 | 678 |
int |
601 |
-redata_save(redata_t *redata, char *filename) |
|
679 |
+redata_save(redata_t *redata, char *filename, char **errordesc) |
|
602 | 680 |
{ |
603 | 681 |
int fd; |
604 | 682 |
int i,n; |
605 | 683 |
char tmpfile[PATH_MAX+1]; |
606 |
- if(redata==NULL || filename==NULL) |
|
684 |
+ if(redata==NULL || filename==NULL) { |
|
685 |
+ if(errordesc!=NULL) |
|
686 |
+ *errordesc="Internal error"; |
|
607 | 687 |
return(-1); /* sanity check failed */ |
608 |
- if((securesave_genname(redata->filename,tmpfile,sizeof(tmpfile)))==NULL) |
|
688 |
+ } |
|
689 |
+ if((securesave_genname(redata->filename,tmpfile,sizeof(tmpfile)))==NULL) { |
|
690 |
+ if(errordesc!=NULL) |
|
691 |
+ *errordesc="Malformed filename"; |
|
609 | 692 |
return(-1); /* malformed filename */ |
610 |
- if((fd=open(tmpfile,O_WRONLY|O_TRUNC|O_CREAT,0644))==-1) |
|
693 |
+ } |
|
694 |
+ if((fd=open(tmpfile,O_WRONLY|O_TRUNC|O_CREAT,0644))==-1) { |
|
695 |
+ if(errordesc!=NULL) |
|
696 |
+ *errordesc="Couldn't open file for writing"; |
|
611 | 697 |
return(-1); /* couldn't open file for writing */ |
698 |
+ } |
|
612 | 699 |
for(i=0;i<redata->sizechunks;i++) { |
613 | 700 |
if(redata->chunks[i]->useddata==0) |
614 | 701 |
continue; |
615 | 702 |
if((n=write(fd,redata->chunks[i]->data,redata->chunks[i]->useddata))==-1 || n!=redata->chunks[i]->useddata) { |
616 | 703 |
close(fd),fd=-1; |
617 | 704 |
unlink(tmpfile); |
705 |
+ if(errordesc!=NULL) |
|
706 |
+ *errordesc="Short write saving file"; |
|
618 | 707 |
return(-1); /* short write */ |
619 | 708 |
} |
620 | 709 |
} |
621 | 710 |
close(fd),fd=-1; |
622 | 711 |
if(rename(tmpfile,filename)!=0) { |
623 | 712 |
unlink(tmpfile); |
713 |
+ if(errordesc!=NULL) |
|
714 |
+ *errordesc="Couldn't overwrite old file"; |
|
624 | 715 |
return(-1); /* couldn't overwrite old file */ |
625 | 716 |
} |
626 | 717 |
for(i=0;i<redata->sizeplugins;i++) { |
... | ... |
@@ -13,8 +13,22 @@ |
13 | 13 |
|
14 | 14 |
#include <limits.h> |
15 | 15 |
|
16 |
+#ifndef RE_DATA_H |
|
17 |
+#define RE_DATA_H |
|
16 | 18 |
#define MAXPLUGINNAME 32 |
17 | 19 |
|
20 |
+typedef struct question_t { |
|
21 |
+ int active; |
|
22 |
+ int is_postload; |
|
23 |
+ char *id; |
|
24 |
+ char *title,*titleshort; |
|
25 |
+ char *body,*bodyshort; |
|
26 |
+ int nopts; |
|
27 |
+ char **opts,**optsshort; |
|
28 |
+ int defaultoption; |
|
29 |
+ int selectedoption; |
|
30 |
+} question_t; |
|
31 |
+ |
|
18 | 32 |
typedef struct whatin_t { |
19 | 33 |
int nlcount; |
20 | 34 |
int iscontinuation; |
... | ... |
@@ -51,11 +65,12 @@ typedef struct undostack_t { |
51 | 65 |
typedef struct redata_plugin_t { |
52 | 66 |
int active; |
53 | 67 |
char name[MAXPLUGINNAME]; |
68 |
+ char *questionfilename[PATH_MAX]; |
|
69 |
+ question_t question; |
|
54 | 70 |
int (*unregister)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/); |
55 | 71 |
int (*wipe)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/); |
56 |
- /* loadquestion returns -1 if no question needed */ |
|
57 |
- int (*loadquestion)(/*redata_t *redata, redata_plugin_t *plugin,char *filename, char **title, char **body, int *nopts, char **opts[] */); |
|
58 |
- int (*postload)(/*redata_t *redata, redata_plugin_t *plugin,char *filename,int questionreply */); |
|
72 |
+ int (*loadquestion)(/*redata_t *redata, redata_plugin_t *plugin,char *filename */); |
|
73 |
+ int (*postload)(/*redata_t *redata, redata_plugin_t *plugin,char *filename */); |
|
59 | 74 |
int (*postsave)(/*redata_t *redata, redata_plugin_t *plugin,char *oldfilename,char *newfilename*/); |
60 | 75 |
int (*add)(/*redata_t *redata, redata_plugin_t *plugin,undo_t *undo*/); |
61 | 76 |
int (*unadd)(/*redata_t *redata, redata_plugin_t *plugin,undo_t *undo*/); |
... | ... |
@@ -84,6 +99,8 @@ typedef struct redata_t { |
84 | 99 |
redata_t *redata_init( int (*pluginregisterfn)(redata_t *redata, redata_plugin_t *slot), ...); |
85 | 100 |
void redata_free(redata_t *redata); |
86 | 101 |
|
102 |
+void redata_idleproc(redata_t *redata, char *filename); |
|
103 |
+ |
|
87 | 104 |
int redata_config_chunkdatasize(redata_t *redata, int chunkdatasize); |
88 | 105 |
|
89 | 106 |
long redata_getsize(redata_t *redata); |
... | ... |
@@ -119,8 +136,13 @@ int redata_undo_groupinit(redata_t *redata, undostack_t *stack); |
119 | 136 |
int redata_undo_groupcommit(redata_t *redata, undostack_t *stack); |
120 | 137 |
|
121 | 138 |
/* high level stuff */ |
122 |
-int redata_load(redata_t *redata, char *filename, int (*callback_question)(/*char *title, char *body, int nopts, char *opts[],void *userptr*/), void *userptr); |
|
123 |
-int redata_save(redata_t *redata, char *filename); |
|
139 |
+int redata_loadquestions_setup(redata_t *redata, char *filename); |
|
140 |
+question_t *redata_loadquestions_getnext(redata_t *redata); |
|
141 |
+int redata_loadquestions_reply(redata_t *redata, question_t *question, int selectedoption); |
|
142 |
+int redata_loadquestions_wipe(redata_t *redata); |
|
143 |
+ |
|
144 |
+int redata_load(redata_t *redata, char *filename, char **errordesc); |
|
145 |
+int redata_save(redata_t *redata, char *filename, char **errordesc); |
|
124 | 146 |
|
125 | 147 |
int redata_op_add(redata_t *redata, long pos, char *buf, long buflen, undostack_t *fromhere); |
126 | 148 |
int redata_op_addn(redata_t *redata, long pos, char character, long n, undostack_t *fromhere); |
... | ... |
@@ -170,3 +192,4 @@ int redata_pos2linecol(redata_t *redata, long pos, int *line, int *col); |
170 | 192 |
/* get the pos of that line/col (calculated using the utf8 convenience functions) */ |
171 | 193 |
int redata_linecol2pos(redata_t *redata, int line, int colrequest, long *pos, int *coldone); |
172 | 194 |
|
195 |
+#endif |
... | ... |
@@ -28,8 +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 |
+static int redata_unsaved_loadquestion(redata_t *redata, redata_plugin_t *slot,char *filename); |
|
32 |
+static int redata_unsaved_postload(redata_t *redata, redata_plugin_t *slot,char *filename); |
|
33 | 33 |
static int redata_unsaved_check_gen(redata_t *redata, redata_plugin_t *slot, char *filename); |
34 | 34 |
static char *unsaved_genname(char *filename, char *buf, int bufsize); |
35 | 35 |
static char *ptr_getlong(char *ptr,char *endptr,long *data); |
... | ... |
@@ -58,6 +58,7 @@ redata_unsaved_register(redata_t *redata, redata_plugin_t *slot) |
58 | 58 |
slot->add=redata_unsaved_add; |
59 | 59 |
slot->unadd=redata_unsaved_unadd; |
60 | 60 |
slot->commit=redata_unsaved_commit; |
61 |
+ slot->userptr=unsaved; |
|
61 | 62 |
return(0); |
62 | 63 |
} |
63 | 64 |
|
... | ... |
@@ -205,6 +206,9 @@ redata_unsaved_trunc(redata_t *redata, redata_plugin_t *slot, char *oldfilename, |
205 | 206 |
int |
206 | 207 |
redata_unsaved_truncload(redata_t *redata, redata_plugin_t *slot, char *filename) |
207 | 208 |
{ |
209 |
+#if 1 |
|
210 |
+fprintf(stderr,"UNSAVED: TRUNCLOAD (ignore)\n"); |
|
211 |
+#endif |
|
208 | 212 |
return(redata_unsaved_trunc(redata, slot, NULL, filename)); |
209 | 213 |
} |
210 | 214 |
|
... | ... |
@@ -224,16 +228,28 @@ redata_unsaved_loadappend(redata_t *redata, redata_plugin_t *slot, char *filenam |
224 | 228 |
char endcode; |
225 | 229 |
int flag_multipart; |
226 | 230 |
unsaved_t *unsaved=(unsaved_t *) ((slot!=NULL)?(slot->userptr):NULL); |
231 |
+#if 1 |
|
232 |
+fprintf(stderr,"UNSAVED: LOADAPPEND (recover)\n"); |
|
233 |
+#endif |
|
227 | 234 |
if(redata==NULL || slot==NULL || unsaved==NULL || filename==NULL) |
228 | 235 |
return(-1); |
236 |
+#if 1 |
|
237 |
+fprintf(stderr,"UNSAVED: LOADAPPEND pre-check\n"); |
|
238 |
+#endif |
|
229 | 239 |
if((fd=redata_unsaved_check_gen(redata,slot,filename))==-1) |
230 | 240 |
return(-1); /* check failed */ |
241 |
+#if 1 |
|
242 |
+fprintf(stderr,"UNSAVED: LOADAPPEND post-check\n"); |
|
243 |
+#endif |
|
231 | 244 |
if(fstat(fd,&statbuf)!=0 || !S_ISREG(statbuf.st_mode)) { |
232 | 245 |
close(fd),fd=-1; |
233 | 246 |
return(-1); /* couldn't query size or not regular file */ |
234 | 247 |
} |
235 | 248 |
redata_hash(redata,unsaved->initialhash); |
236 |
- headerhashsize=(sizeof(header)-1)+1+128+1; |
|
249 |
+ headerhashsize=(sizeof(header)-1)+128+1; |
|
250 |
+#if 1 |
|
251 |
+fprintf(stderr,"UNSAVED: LOADAPPEND headerhashsize: %li\n",headerhashsize); |
|
252 |
+#endif |
|
237 | 253 |
/* load unsaved to memory */ |
238 | 254 |
if(unsaved->sizebuf<(statbuf.st_size-headerhashsize)) { |
239 | 255 |
if((newptr=realloc(unsaved->buf,(statbuf.st_size-headerhashsize)))==NULL) { |
... | ... |
@@ -254,8 +270,21 @@ redata_unsaved_loadappend(redata_t *redata, redata_plugin_t *slot, char *filenam |
254 | 270 |
} |
255 | 271 |
close(fd),fd=-1; |
256 | 272 |
/* process unsaved data */ |
273 |
+ slot->active=0; |
|
257 | 274 |
endptr=unsaved->buf+unsaved->usedbuf; |
258 | 275 |
for(ptr=unsaved->buf;ptr<endptr;) { |
276 |
+#ifdef DEBUG_PLUGIN_UNSAVED |
|
277 |
+{ |
|
278 |
+int m; |
|
279 |
+fprintf(stderr,"%05X: ",ptr-unsaved->buf); |
|
280 |
+for(m=0;m<16 && (ptr+m)<endptr;m++) |
|
281 |
+ fprintf(stderr,"%02X%s ",((unsigned char *)ptr)[m],(m==7)?" ":""); |
|
282 |
+fprintf(stderr," | "); |
|
283 |
+for(m=0;m<16 && (ptr+m)<endptr;m++) |
|
284 |
+ fprintf(stderr,"%c%s",((((unsigned char *)ptr)[m])<20)?'.':((((unsigned char *)ptr)[m])>126)?'.':((unsigned char *)ptr)[m],(m==7)?" ":""); |
|
285 |
+fprintf(stderr,"\n"); |
|
286 |
+} |
|
287 |
+#endif |
|
259 | 288 |
if((ptr=ptr_getchar(ptr,endptr,&actioncode))==NULL) |
260 | 289 |
return(-1); /* no space for action char */ |
261 | 290 |
/* multipart example: A10+$aj$%$% >> insert "aj$" into pos 10 */ |
... | ... |
@@ -322,7 +351,8 @@ redata_unsaved_loadappend(redata_t *redata, redata_plugin_t *slot, char *filenam |
322 | 351 |
return(-1); /* corrupted undobuf */ |
323 | 352 |
} |
324 | 353 |
} |
325 |
- return(-1); |
|
354 |
+ slot->active=1; |
|
355 |
+ return(0); |
|
326 | 356 |
} |
327 | 357 |
|
328 | 358 |
int |
... | ... |
@@ -337,7 +367,7 @@ redata_unsaved_add(redata_t *redata, redata_plugin_t *slot, undo_t *undo) |
337 | 367 |
undostack_t *stack; |
338 | 368 |
unsaved_t *unsaved=(unsaved_t *) ((slot!=NULL)?(slot->userptr):NULL); |
339 | 369 |
stack=redata_getstack(redata,undo); |
340 |
- if(redata==NULL || slot==NULL || unsaved==NULL || undo==NULL || stack==NULL) |
|
370 |
+ if(redata==NULL || slot==NULL || unsaved==NULL || undo==NULL || stack==NULL || slot->active==0) |
|
341 | 371 |
return(-1); /* sanity check failed */ |
342 | 372 |
/* syntax (see loadappend): A<pos><+?><sep><text><sep>[<+?><sep><text><sep>[...]] */ |
343 | 373 |
if(undo->type!='A' && undo->type!='D' && undo->type!='M') |
... | ... |
@@ -389,7 +419,8 @@ redata_unsaved_add(redata_t *redata, redata_plugin_t *slot, undo_t *undo) |
389 | 419 |
unsaved->sizebuf=newsize; |
390 | 420 |
} |
391 | 421 |
buf=unsaved->buf+unsaved->usedbuf; |
392 |
- } |
|
422 |
+ } else |
|
423 |
+ unsaved->usedbuf+=maxsize; |
|
393 | 424 |
} |
394 | 425 |
return(0); |
395 | 426 |
} |
... | ... |
@@ -407,7 +438,7 @@ redata_unsaved_unadd(redata_t *redata, redata_plugin_t *slot, undo_t *undo) |
407 | 438 |
undostack_t *stack; |
408 | 439 |
unsaved_t *unsaved=(unsaved_t *) ((slot!=NULL)?(slot->userptr):NULL); |
409 | 440 |
stack=redata_getstack(redata,undo); |
410 |
- if(redata==NULL || slot==NULL || unsaved==NULL || undo==NULL || stack==NULL) |
|
441 |
+ if(redata==NULL || slot==NULL || unsaved==NULL || undo==NULL || stack==NULL || slot->active==0) |
|
411 | 442 |
return(-1); /* sanity check failed */ |
412 | 443 |
/* syntax (see loadappend): A<pos><+?><sep><text><sep>[<+?><sep><text><sep>[...]] */ |
413 | 444 |
if(undo->type!='A' && undo->type!='D' && undo->type!='M') |
... | ... |
@@ -475,6 +506,9 @@ redata_unsaved_commit(redata_t *redata, redata_plugin_t *slot,char *filename) |
475 | 506 |
unsaved_t *unsaved=(unsaved_t *) ((slot!=NULL)?(slot->userptr):NULL); |
476 | 507 |
if(redata==NULL || slot==NULL || unsaved==NULL || unsaved->unsavedfd==-1) |
477 | 508 |
return(-1); |
509 |
+#if 1 |
|
510 |
+fprintf(stderr,"UNSAVED_COMMITTED\n"); |
|
511 |
+#endif |
|
478 | 512 |
for(nwritten=0;nwritten<unsaved->usedbuf;nwritten+=n) { |
479 | 513 |
if((n=write(unsaved->unsavedfd,unsaved->buf+nwritten,unsaved->usedbuf-nwritten))<0) { |
480 | 514 |
close(unsaved->unsavedfd),unsaved->unsavedfd=-1; |
... | ... |
@@ -488,30 +522,47 @@ redata_unsaved_commit(redata_t *redata, redata_plugin_t *slot,char *filename) |
488 | 522 |
} |
489 | 523 |
|
490 | 524 |
static int |
491 |
-redata_unsaved_loadquestion(redata_t *redata, redata_plugin_t *slot,char *filename, char **title, char **body, int *nopts, char **opts[]) |
|
525 |
+redata_unsaved_loadquestion(redata_t *redata, redata_plugin_t *slot,char *filename) |
|
492 | 526 |
{ |
493 | 527 |
static char mytitle[]={"Unsaved data from a previous session detected"}; |
494 | 528 |
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 | 529 |
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) |
|
530 |
+ static char mytitleshort[]={"Unsaved data found"}; |
|
531 |
+ static char mybodyshort[]={"Should try to recover the data?"}; |
|
532 |
+ static char *myoptsshort[]={"Recover","Ignore it"}; |
|
533 |
+ question_t *q; |
|
534 |
+ if(redata==NULL || slot==NULL || filename==NULL) |
|
497 | 535 |
return(-1); /* sanity check failed */ |
536 |
+ q=&(slot->question); |
|
537 |
+ q->active=0; |
|
498 | 538 |
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; |
|
539 |
+ return(0); /* no unsaved data on disk */ |
|
540 |
+ q->active=1; |
|
541 |
+ q->title=mytitle; |
|
542 |
+ q->titleshort=mytitleshort; |
|
543 |
+ q->body=mybody; |
|
544 |
+ q->bodyshort=mybodyshort; |
|
545 |
+ q->opts=myopts; |
|
546 |
+ q->optsshort=myoptsshort; |
|
547 |
+ q->nopts=2; |
|
548 |
+ q->defaultoption=1; |
|
549 |
+ q->selectedoption=-1; |
|
504 | 550 |
return(0); |
505 | 551 |
} |
506 | 552 |
|
507 | 553 |
static int |
508 |
-redata_unsaved_postload(redata_t *redata, redata_plugin_t *slot,char *filename,int questionreply) |
|
554 |
+redata_unsaved_postload(redata_t *redata, redata_plugin_t *slot,char *filename) |
|
509 | 555 |
{ |
556 |
+#warning XXX TODO: add errordesc parameter, so that the user can see what happened. |
|
557 |
+ int selectedoption; |
|
558 |
+ if(redata==NULL || slot==NULL || filename==NULL) |
|
559 |
+ return(-1); /* sanity check failed */ |
|
510 | 560 |
/* 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 */ |
|
561 |
+ selectedoption=slot->question.selectedoption; |
|
562 |
+ if(slot->question.active==0 || selectedoption==1 || selectedoption==-1) /* delete unsaved data */ |
|
514 | 563 |
return(redata_unsaved_truncload(redata, slot, filename)); |
564 |
+ else if(selectedoption==0) /* recover */ |
|
565 |
+ return(redata_unsaved_loadappend(redata, slot, filename)); |
|
515 | 566 |
return(-1); |
516 | 567 |
} |
517 | 568 |
|
... | ... |
@@ -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,NULL,NULL)!=0) { |
|
157 |
+ if(redata_load(redata,filename,NULL)!=0) { |
|
158 | 158 |
unlink(filename); |
159 | 159 |
return("couldn't load file"); |
160 | 160 |
} |
... | ... |
@@ -163,7 +163,7 @@ fprintf(stderr,"\ntest_newfile(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL) |
163 | 163 |
if(strcmp(hash129_pre,hash129_post)!=0) |
164 | 164 |
return("loaded file is corrupted"); |
165 | 165 |
/* save file */ |
166 |
- redata_save(redata,filename); |
|
166 |
+ redata_save(redata,filename,NULL); |
|
167 | 167 |
hash129_post[0]='\0'; |
168 | 168 |
redata_filehash(redata,filename,hash129_post); |
169 | 169 |
if(strcmp(hash129_pre,hash129_post)!=0) |
... | ... |
@@ -201,7 +201,7 @@ fprintf(stderr,"\ntest_edit(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL)?"\ |
201 | 201 |
progress[l+1]='\0'; |
202 | 202 |
} |
203 | 203 |
if(k!=0) unlink("test.pre"),unlink("test.post"),unlink("test.undo"),unlink("test.redo"); |
204 |
-if(k!=0) redata_save(redata,"test.pre"); |
|
204 |
+if(k!=0) redata_save(redata,"test.pre",NULL); |
|
205 | 205 |
if(*ptr=='A') { |
206 | 206 |
/* A<insertpos><endchar><text><endchar> */ |
207 | 207 |
ptr++; |
... | ... |
@@ -318,7 +318,7 @@ if(k!=0) redata_save(redata,"test.pre"); |
318 | 318 |
if(cursize>maxsize) |
319 | 319 |
maxsize=cursize; |
320 | 320 |
if(k!=0) { |
321 |
-if(k!=0) redata_save(redata,"test.post"); |
|
321 |
+if(k!=0) redata_save(redata,"test.post",NULL); |
|
322 | 322 |
redata_hash(redata,hash129_redata); |
323 | 323 |
redata_memhash(redata,mem,cursize,hash129_mem); |
324 | 324 |
if(strcmp(hash129_redata,hash129_mem)!=0) { |
... | ... |
@@ -330,7 +330,7 @@ if(k!=0) redata_save(redata,"test.post"); |
330 | 330 |
return(errorbuf); |
331 | 331 |
} |
332 | 332 |
redata_op_undo(redata,NULL); |
333 |
-redata_save(redata,"test.undo"); |
|
333 |
+redata_save(redata,"test.undo",NULL); |
|
334 | 334 |
redata_hash(redata,hash129_redata); |
335 | 335 |
if(strcmp(hash129_redata,hash129_memold)!=0) { |
336 | 336 |
if(mem!=NULL) |
... | ... |
@@ -341,7 +341,7 @@ redata_save(redata,"test.undo"); |
341 | 341 |
return(errorbuf); |
342 | 342 |
} |
343 | 343 |
redata_op_redo(redata,NULL); |
344 |
-redata_save(redata,"test.redo"); |
|
344 |
+redata_save(redata,"test.redo",NULL); |
|
345 | 345 |
redata_hash(redata,hash129_redata); |
346 | 346 |
if(strcmp(hash129_redata,hash129_mem)!=0) { |
347 | 347 |
if(mem!=NULL) |
... | ... |
@@ -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,NULL,NULL)!=0) { |
|
362 |
+ if(redata_load(redata,filename,NULL)!=0) { |
|
363 | 363 |
unlink(filename); |
364 | 364 |
return("couldn't load file"); |
365 | 365 |
} |
... | ... |
@@ -13,18 +13,24 @@ |
13 | 13 |
#include <string.h> |
14 | 14 |
#include <limits.h> |
15 | 15 |
#include <signal.h> |
16 |
+#include <time.h> |
|
16 | 17 |
|
17 | 18 |
#include "re_data.h" |
19 |
+#include "re_plugin_unsaved.h" |
|
18 | 20 |
#include "re_ui.h" |
19 | 21 |
#include "ext/socklib.h" |
20 | 22 |
|
21 | 23 |
#define LINEFORCESCROLL 1 |
22 | 24 |
#define COLFORCESCROLL 5 |
23 | 25 |
|
26 |
+#define IDLETIMEOUTSECONDS 10 |
|
27 |
+ |
|
24 | 28 |
#define COMMANDBUFSIZE 1024 |
25 | 29 |
|
26 | 30 |
#define COMMAND_WARNING "(!)" |
27 | 31 |
#define COMMAND_GOTOLINE "Go to line: " |
32 |
+#define COMMAND_QUESTION "(?)" |
|
33 |
+#define COMMAND_EXIT "Exit" |
|
28 | 34 |
|
29 | 35 |
#define COLOR_STATUSBG "\x00\x00\xff\xff" |
30 | 36 |
#define COLOR_STATUSFG "\xff\xff\x00\xff" |
... | ... |
@@ -48,8 +54,10 @@ typedef struct re_t { |
48 | 54 |
int maxrow,maxcol; |
49 | 55 |
int headerdirty; |
50 | 56 |
int contentsdirty; |
57 |
+ int command_first_key; |
|
51 | 58 |
char *command; |
52 | 59 |
char commandbuf[COMMANDBUFSIZE]; |
60 |
+ question_t *question; |
|
53 | 61 |
int ignorenkeys; |
54 | 62 |
} re_t; |
55 | 63 |
|
... | ... |
@@ -86,6 +94,8 @@ main(int argc, char *argv[]) |
86 | 94 |
SDL_Event event; |
87 | 95 |
sselect *ssel; |
88 | 96 |
int flag_had_events; |
97 |
+ time_t lastidle,now; |
|
98 |
+ int load_pending; |
|
89 | 99 |
if(argc!=2 || strcmp(argv[argc-1],"--help")==0) { |
90 | 100 |
fprintf(stderr,"Syntax: %s filename\n",argv[0]); |
91 | 101 |
return(1); |
... | ... |
@@ -104,18 +114,6 @@ main(int argc, char *argv[]) |
104 | 114 |
re_free(re),re=NULL; |
105 | 115 |
return(2); |
106 | 116 |
} |
107 |
- if((redata_load(re->data,re->filename,NULL,NULL))!=0) |
|
108 |
- re->flag_newfile=1; |
|
109 |
- else |
|
110 |
- re->flag_newfile=0; |
|
111 |
-#if 0 |
|
112 |
-#warning TESTS |
|
113 |
- { |
|
114 |
- char buf[129]; |
|
115 |
- redata_hash(re->data,buf); |
|
116 |
- fprintf(stderr,"%s %s\n",buf,re->filename); |
|
117 |
- } |
|
118 |
-#endif |
|
119 | 117 |
reui_title(re->ui,re->filename); |
120 | 118 |
flag_sigint=flag_sigpipe=0; |
121 | 119 |
setsignal(SIGINT,sighandler_sigint); |
... | ... |
@@ -134,13 +132,43 @@ main(int argc, char *argv[]) |
134 | 132 |
re->contentsdirty=1; |
135 | 133 |
flag_had_events=0; |
136 | 134 |
SDL_StartTextInput(); |
135 |
+ lastidle=0; |
|
136 |
+ load_pending=1; |
|
137 |
+ redata_loadquestions_setup(re->data, re->filename); |
|
137 | 138 |
while(do_exit==0 && flag_sigint==0) { |
139 |
+ /* load file (or ask pre-load questions), if pending */ |
|
140 |
+ if(load_pending && re->command==NULL) { |
|
141 |
+ question_t *question; |
|
142 |
+ if((question=redata_loadquestions_getnext(re->data))!=NULL) { |
|
143 |
+ re->command=COMMAND_QUESTION; |
|
144 |
+ re->question=question; |
|
145 |
+#if 0 |
|
146 |
+fprintf(stderr,"QUESTION INIT: %s: %s\n",re->question->title,re->question->body); |
|
147 |
+#endif |
|
148 |
+ } else { |
|
149 |
+ if(redata_load(re->data,re->filename,NULL)==-1) |
|
150 |
+ re->flag_newfile=1; |
|
151 |
+ else |
|
152 |
+ re->flag_newfile=0; |
|
153 |
+#warning XXX TODO: NO PARECE FUNCIONAR EL PLUGIN_UNSAVED (pregunta pero no carga los cambios) |
|
154 |
+ re->originline=re->origincol=0; |
|
155 |
+ re->curline=re->curcol=0; |
|
156 |
+ re->cursorpos=0; |
|
157 |
+ load_pending=0; |
|
158 |
+ re->headerdirty=1; |
|
159 |
+ re->contentsdirty=1; |
|
160 |
+ } |
|
161 |
+ } |
|
138 | 162 |
if(re->headerdirty) { |
139 | 163 |
if(re->command==NULL) { |
164 |
+#if 0 |
|
140 | 165 |
fprintf(stderr,"REDRAW Header (editing)\n"); |
166 |
+#endif |
|
141 | 167 |
re_drawheader_editing(re); |
142 | 168 |
} else { |
169 |
+#if 0 |
|
143 | 170 |
fprintf(stderr,"REDRAW Header (command)\n"); |
171 |
+#endif |
|
144 | 172 |
re_drawheader_command(re); |
145 | 173 |
if(strcmp(re->command,COMMAND_WARNING)==0) { |
146 | 174 |
/* the warnings only get shown once, remove it */ |
... | ... |
@@ -182,6 +210,15 @@ fprintf(stderr,"REDRAW Header (command)\n"); |
182 | 210 |
break; |
183 | 211 |
} |
184 | 212 |
} |
213 |
+ /* additional processing of global commands */ |
|
214 |
+ if(re->command!=NULL && strcmp(re->command,COMMAND_EXIT)==0) |
|
215 |
+ do_exit=1; |
|
216 |
+ /* timeouts */ |
|
217 |
+ now=time(NULL); |
|
218 |
+ if((lastidle+IDLETIMEOUTSECONDS)<now || (lastidle-IDLETIMEOUTSECONDS)>now) { |
|
219 |
+ lastidle=now; |
|
220 |
+ redata_idleproc(re->data,re->filename); |
|
221 |
+ } |
|
185 | 222 |
} |
186 | 223 |
SDL_StopTextInput(); |
187 | 224 |
sselect_free(ssel),ssel=NULL; |
... | ... |
@@ -219,7 +256,7 @@ re_init(void) |
219 | 256 |
if((re=malloc(sizeof(re_t)))==NULL) |
220 | 257 |
return(NULL); /* insuf. mem. */ |
221 | 258 |
memset(re,0,sizeof(re_t)); |
222 |
- if((re->data=redata_init(NULL))==NULL) { |
|
259 |
+ if((re->data=redata_init(redata_unsaved_register,NULL))==NULL) { |
|
223 | 260 |
re_free(re),re=NULL; |
224 | 261 |
return(NULL); /* insuf. mem. */ |
225 | 262 |
} |
... | ... |
@@ -326,7 +363,7 @@ fprintf(stderr,"SDL_TEXTEDITING: composition:\"%s\" start:%i len:%i\n",event->ed |
326 | 363 |
/* default case: keydown event */ |
327 | 364 |
if(event->type!=SDL_KEYDOWN) |
328 | 365 |
return(0); /* Ignore other possible events */ |
329 |
-#if 1 |
|
366 |
+#if 0 |
|
330 | 367 |
fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym); |
331 | 368 |
#endif |
332 | 369 |
if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) { |
... | ... |
@@ -411,10 +448,15 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym); |
411 | 448 |
} else if(event->key.keysym.sym==SDLK_q && (SDL_GetModState()&KMOD_CTRL)!=0) { |
412 | 449 |
fprintf(stderr,"re_processkey(): received Control+q\n"); |
413 | 450 |
re->command=""; |
451 |
+ re->command_first_key='q'; |
|
452 |
+ re->headerdirty=1; |
|
453 |
+ } else if(event->key.keysym.sym==SDLK_k && (SDL_GetModState()&KMOD_CTRL)!=0) { |
|
454 |
+fprintf(stderr,"re_processkey(): received Control+k\n"); |
|
455 |
+ re->command=""; |
|
456 |
+ re->command_first_key='k'; |
|
414 | 457 |
re->headerdirty=1; |
415 | 458 |
} else if(event->key.keysym.sym==SDLK_z && (SDL_GetModState()&KMOD_CTRL)!=0) { |
416 | 459 |
long newpos; |
417 |
- int oldline; |
|
418 | 460 |
fprintf(stderr,"re_processkey(): received Control+z\n"); |
419 | 461 |
if(redata_op_undo(re->data,&newpos)) |
420 | 462 |
return(-1); |
... | ... |
@@ -439,10 +481,14 @@ re_processkey_commandwait(re_t *re, SDL_Event *event) |
439 | 481 |
/* default case: keydown event */ |
440 | 482 |
if(event->type!=SDL_KEYDOWN) |
441 | 483 |
return(0); /* Ignore other possible events */ |
442 |
- if(event->key.keysym.sym==SDLK_l) { |
|
484 |
+ if(re->command_first_key=='q' && event->key.keysym.sym==SDLK_l) { |
|
443 | 485 |
re->command=COMMAND_GOTOLINE; |
444 | 486 |
re->commandbuf[0]='\0'; |
445 | 487 |
re->headerdirty=1; |
488 |
+ } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_q) { |
|
489 |
+ re->command=COMMAND_EXIT; |
|
490 |
+ re->commandbuf[0]='\0'; |
|
491 |
+ re->headerdirty=1; |
|
446 | 492 |
} else { |
447 | 493 |
re->command=NULL; |
448 | 494 |
re->headerdirty=1; |
... | ... |
@@ -478,6 +524,7 @@ re_processkey_commanddata(re_t *re, SDL_Event *event) |
478 | 524 |
re->command=NULL; |
479 | 525 |
re->commandbuf[0]='\0'; |
480 | 526 |
re->headerdirty=1; |
527 |
+#warning XXX: TODO: re->question: Make cursor change option, make numbers change option |
|
481 | 528 |
} else if(event->key.keysym.sym==SDLK_BACKSPACE && re->commandbuf[0]!='\0') { |
482 | 529 |
int nchar; |
483 | 530 |
char *ptr; |
... | ... |
@@ -517,6 +564,17 @@ re_processcommand(re_t *re) |
517 | 564 |
re->originline=line-(re->maxrow/2); |
518 | 565 |
re->headerdirty=1; |
519 | 566 |
re->contentsdirty=1; |
567 |
+ } else if(strcmp(re->command,COMMAND_QUESTION)==0) { |
|
568 |
+ /* validate reply */ |
|
569 |
+ if(!(atoi(re->commandbuf)>0 && atoi(re->commandbuf)<=re->question->nopts)) { |
|
570 |
+ /* invalid reply: reset buf */ |
|
571 |
+ re->commandbuf[0]=0; |
|
572 |
+ re->headerdirty=1; |
|
573 |
+ return(-1); |
|
574 |
+ } |
|
575 |
+ /* send reply */ |
|
576 |
+ redata_loadquestions_reply(re->data,re->question,atoi(re->commandbuf)-1); |
|
577 |
+ re->headerdirty=1; |
|
520 | 578 |
} |
521 | 579 |
re->command=NULL; |
522 | 580 |
re->commandbuf[0]='\0'; |
... | ... |
@@ -536,7 +594,9 @@ re_moveupdown(re_t *re, int totalinc) |
536 | 594 |
inc=(totalinc<0)?-1:1; |
537 | 595 |
newpos=re->cursorpos; /* get rid of compiler warning (will be overwitten in the loop as totalinc never is 0) */ |
538 | 596 |
for(doneinc=0;doneinc!=totalinc;doneinc+=inc) { |
597 |
+#if 0 |
|
539 | 598 |
fprintf(stderr,"MOVING from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol); |
599 |
+#endif |
|
540 | 600 |
if((inc==-1 && redata_line_prevrealstart(re->data,re->cursorpos,&realstart)==-1) |
541 | 601 |
|| (inc==1 && redata_line_nextrealstart(re->data,re->cursorpos,&realstart)==-1)) { |
542 | 602 |
break; /* couldn't get current line data, we are at start/end */ |
... | ... |
@@ -549,17 +609,25 @@ fprintf(stderr,"MOVING from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->cu |
549 | 609 |
} |
550 | 610 |
if(re->curline>(re->originline+re->maxrow-LINEFORCESCROLL)) |
551 | 611 |
re->originline+=LINEFORCESCROLL; |
612 |
+#if 0 |
|
552 | 613 |
fprintf(stderr,"MOVING to cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol); |
614 |
+#endif |
|
553 | 615 |
} |
554 | 616 |
if(redata_line_inccol(re->data,re->cursorpos,re->curcol,&newpos2,NULL)==-1) { |
555 | 617 |
/* error advancing cursor, "emergency" repositioning */ |
618 |
+#if 0 |
|
556 | 619 |
fprintf(stderr,"COLUMN ERROR\n"); |
620 |
+#endif |
|
557 | 621 |
re->curcol=0; |
558 | 622 |
newpos2=newpos; |
559 | 623 |
} |
624 |
+#if 0 |
|
560 | 625 |
fprintf(stderr,"COLUMN from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol); |
626 |
+#endif |
|
561 | 627 |
re->cursorpos=newpos2; |
628 |
+#if 0 |
|
562 | 629 |
fprintf(stderr,"COLUMN to cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol); |
630 |
+#endif |
|
563 | 631 |
re->contentsdirty=1; |
564 | 632 |
re->headerdirty=1; |
565 | 633 |
return(0); |
... | ... |
@@ -701,6 +769,21 @@ re_drawheader_command(re_t *re) |
701 | 769 |
} else if(strcmp(re->command,COMMAND_WARNING)==0) { |
702 | 770 |
reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_WARNINGBG); |
703 | 771 |
reui_printf(re->ui,0,0,COLOR_WARNINGFG,"%s %s",re->command,re->commandbuf); |
772 |
+ } else if(strcmp(re->command,COMMAND_QUESTION)==0) { |
|
773 |
+ question_t *q; |
|
774 |
+ reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG); |
|
775 |
+#warning XXX TODO: suppont arbitrary number of options, highlight current option |
|
776 |
+ q=re->question; |
|
777 |
+ re->commandbuf[sizeof(re->commandbuf)-1]='\0'; |
|
778 |
+ reui_printf(re->ui,0,0,COLOR_QUERYFG,"%s %s: %s %s%s%s%s%s%s%s%s: %s" |
|
779 |
+ ,re->command |
|
780 |
+ ,(q->titleshort!=NULL)?q->titleshort:q->title |
|
781 |
+ ,(q->bodyshort!=NULL)?q->bodyshort:q->body |
|
782 |
+ ,(q->nopts>0)?"1.":"",(q->nopts>0)?(q->optsshort!=NULL)?q->optsshort[0]:q->opts[0]:"" |
|
783 |
+ ,(q->nopts>1)?" 2.":"",(q->nopts>1)?(q->optsshort!=NULL)?q->optsshort[1]:q->opts[1]:"" |
|
784 |
+ ,(q->nopts>2)?" 3.":"",(q->nopts>2)?(q->optsshort!=NULL)?q->optsshort[2]:q->opts[2]:"" |
|
785 |
+ ,(q->nopts>3)?" 4.":"",(q->nopts>4)?(q->optsshort!=NULL)?q->optsshort[3]:q->opts[3]:"" |
|
786 |
+ ,re->commandbuf); |
|
704 | 787 |
} else { |
705 | 788 |
reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG); |
706 | 789 |
re->commandbuf[sizeof(re->commandbuf)-1]='\0'; |