... | ... |
@@ -2,11 +2,13 @@ CC=gcc |
2 | 2 |
CFLAGS=-g -Wall -Ideps -I/usr/include/SDL2 |
3 | 3 |
LDFLAGS=-lSDL2 -lSDL2_image |
4 | 4 |
|
5 |
-all: re |
|
5 |
+all: re tests |
|
6 |
+ |
|
7 |
+recenteditor.o: recenteditor.c recenteditor_data.h |
|
6 | 8 |
|
7 | 9 |
recenteditor_data.o: recenteditor_data.c recenteditor_data.h |
8 | 10 |
|
9 |
-recenteditor.o: recenteditor.c recenteditor_data.h |
|
11 |
+recenteditor_tests.o: recenteditor_tests.c recenteditor_data.h |
|
10 | 12 |
|
11 | 13 |
sha3.o: sha3/sha3.c sha3/sha3.h |
12 | 14 |
$(CC) $(CFLAGS) -Isha3 -c -o sha3.o sha3/sha3.c |
... | ... |
@@ -14,5 +16,8 @@ sha3.o: sha3/sha3.c sha3/sha3.h |
14 | 16 |
re: recenteditor.o recenteditor_data.o sha3.o |
15 | 17 |
$(CC) $(LDFLAGS) -o re recenteditor.o recenteditor_data.o sha3.o |
16 | 18 |
|
19 |
+tests: recenteditor_tests.o recenteditor_data.o sha3.o |
|
20 |
+ $(CC) $(LDFLAGS) -o tests recenteditor_tests.o recenteditor_data.o sha3.o |
|
21 |
+ |
|
17 | 22 |
clean: |
18 | 23 |
rm -f recenteditor.o recenteditor_data.o sha3.o re |
... | ... |
@@ -23,12 +23,19 @@ |
23 | 23 |
#include "sha3/sha3.h" |
24 | 24 |
|
25 | 25 |
#define CHUNKSIZE 32768 |
26 |
+#define UNDOBLOCK 1024 |
|
27 |
+#define UNDOGROWSIZE (256*1024) |
|
26 | 28 |
#define UNSAVEDPREFIX "." |
27 | 29 |
#define UNSAVEDPOSTFIX ".reu" |
28 |
- |
|
30 |
+#define SECURESAVEPREFIX "." |
|
31 |
+#define SECURESAVEPOSTFIX ".saving" |
|
32 |
+#define UNSAVEDHEADER "REUNSAV\n" |
|
33 |
+#define UNSAVEDVERSION "\n000001\0" |
|
29 | 34 |
|
30 | 35 |
static int redata_hash_gen(redata_t *redata, char *filename, char *resbuf129bytes); |
31 | 36 |
static char *unsaved_genname(char *filename, char *buf, int bufsize); |
37 |
+static char *securesave_genname(char *filename, char *buf, int bufsize); |
|
38 |
+static char *genname(char *filename,char *prefix, char *postfix, char *buf, int bufsize); |
|
32 | 39 |
|
33 | 40 |
redata_t * |
34 | 41 |
redata_init(void) |
... | ... |
@@ -49,6 +56,7 @@ redata_init(void) |
49 | 56 |
redata->undo=NULL; |
50 | 57 |
redata->undobuf=NULL; |
51 | 58 |
/* unsaved */ |
59 |
+ redata->filename[0]='\0'; |
|
52 | 60 |
redata->unsavedfd=-1; |
53 | 61 |
redata->flag_unsaveddata=0; |
54 | 62 |
/* all done */ |
... | ... |
@@ -59,6 +67,7 @@ void |
59 | 67 |
redata_free(redata_t *redata) |
60 | 68 |
{ |
61 | 69 |
int i; |
70 |
+ char unsname[PATH_MAX]; |
|
62 | 71 |
if(redata==NULL) |
63 | 72 |
return; /* nothing to do */ |
64 | 73 |
/* data */ |
... | ... |
@@ -75,15 +84,12 @@ redata_free(redata_t *redata) |
75 | 84 |
if(redata->undobuf!=NULL) |
76 | 85 |
free(redata->undobuf),redata->undobuf=NULL; |
77 | 86 |
/* unsaved */ |
78 |
- if(redata->unsavedfd!=-1) |
|
87 |
+ if(redata->unsavedfd!=-1) { |
|
79 | 88 |
close(redata->unsavedfd),redata->unsavedfd=-1; |
80 |
- if(redata->unsavedfilename!=NULL) { |
|
81 |
- if(redata->unsavedfilename[0]!='\0') { |
|
82 |
- /* remove the file, if here, the user has validated exiting without saving */ |
|
83 |
- unlink(redata->unsavedfilename); |
|
84 |
- } |
|
85 |
- free(redata->unsavedfilename),redata->unsavedfilename=NULL; |
|
89 |
+ if(unsaved_genname(redata->filename,unsname,sizeof(unsname))!=NULL) |
|
90 |
+ unlink(unsname); |
|
86 | 91 |
} |
92 |
+ redata->flag_unsaveddata=0; |
|
87 | 93 |
/* free main struct */ |
88 | 94 |
free(redata),redata=NULL; |
89 | 95 |
return; |
... | ... |
@@ -98,25 +104,48 @@ redata_getsize(redata_t *redata) |
98 | 104 |
} |
99 | 105 |
|
100 | 106 |
int |
101 |
-redata_getused(redata_t *redata) |
|
107 |
+redata_getavailable(redata_t *redata) |
|
102 | 108 |
{ |
103 | 109 |
if(redata==NULL) |
104 | 110 |
return(0); /* sanity check failed */ |
105 |
- return(redata_getsize(redata)-redata_getavailable(redata)); |
|
111 |
+ return(redata->available); |
|
106 | 112 |
} |
107 | 113 |
|
108 | 114 |
int |
109 |
-redata_getavailable(redata_t *redata) |
|
115 |
+redata_getused(redata_t *redata) |
|
110 | 116 |
{ |
117 |
+ int used; |
|
111 | 118 |
if(redata==NULL) |
112 | 119 |
return(0); /* sanity check failed */ |
113 |
- return(redata->available); |
|
120 |
+ used=redata->chunkdatasize*redata->sizechunks-redata->available; |
|
121 |
+ return(used); |
|
122 |
+} |
|
123 |
+ |
|
124 |
+int |
|
125 |
+redata_getposptr(redata_t *redata, int pos, int *numchunk, int *offset) |
|
126 |
+{ |
|
127 |
+ int used; |
|
128 |
+ int i; |
|
129 |
+ int ipos; |
|
130 |
+ used=redata_getused(redata); |
|
131 |
+ if(redata==NULL || pos<0 || pos>used || numchunk==NULL || offset==NULL) |
|
132 |
+ return(-1); /* sanity check failed */ |
|
133 |
+ for(ipos=0,i=0;i<redata->sizechunks;ipos+=redata->chunks[i]->useddata,i++) { |
|
134 |
+ if(pos>(ipos+redata->chunks[i]->useddata)) |
|
135 |
+ continue; |
|
136 |
+ /* found */ |
|
137 |
+ *numchunk=i; |
|
138 |
+ *offset=pos-ipos; |
|
139 |
+ return(0); |
|
140 |
+ } |
|
141 |
+ return(-1); |
|
114 | 142 |
} |
115 | 143 |
|
116 | 144 |
int |
117 | 145 |
redata_wipe(redata_t *redata) |
118 | 146 |
{ |
119 | 147 |
int i; |
148 |
+ char unsname[PATH_MAX]; |
|
120 | 149 |
if(redata==NULL) |
121 | 150 |
return(-1); /* sanity check failed */ |
122 | 151 |
/* data */ |
... | ... |
@@ -126,16 +155,13 @@ redata_wipe(redata_t *redata) |
126 | 155 |
} |
127 | 156 |
redata->available=redata_getsize(redata); |
128 | 157 |
/* unsaved */ |
129 |
- if(redata->unsavedfd!=-1) |
|
158 |
+ if(redata->unsavedfd!=-1) { |
|
130 | 159 |
close(redata->unsavedfd),redata->unsavedfd=-1; |
131 |
- if(redata->unsavedfilename!=NULL) { |
|
132 |
- if(redata->unsavedfilename[0]!='\0') { |
|
133 |
- /* remove the file, if here, the user has validated exiting without saving */ |
|
134 |
- unlink(redata->unsavedfilename); |
|
135 |
- } |
|
136 |
- free(redata->unsavedfilename),redata->unsavedfilename=NULL; |
|
160 |
+ if(unsaved_genname(redata->filename,unsname,sizeof(unsname))!=NULL) |
|
161 |
+ unlink(unsname); |
|
137 | 162 |
} |
138 | 163 |
redata->flag_unsaveddata=0; |
164 |
+ redata->filename[0]='\0'; |
|
139 | 165 |
/* all done */ |
140 | 166 |
return(0); |
141 | 167 |
} |
... | ... |
@@ -195,8 +221,10 @@ redata_unsaved_exists(redata_t *redata, char *filename) |
195 | 221 |
{ |
196 | 222 |
char unsname[PATH_MAX+1]; |
197 | 223 |
int fd; |
224 |
+ if(redata==NULL || filename==NULL) |
|
225 |
+ return(-1); /* sanity check failed */ |
|
198 | 226 |
if((unsaved_genname(filename,unsname,sizeof(unsname)))==NULL) |
199 |
- return(-1); |
|
227 |
+ return(-1); /* malformed filename */ |
|
200 | 228 |
if((fd=open(unsname,O_RDONLY))==-1) |
201 | 229 |
return(-1); |
202 | 230 |
close(fd),fd=-1; |
... | ... |
@@ -206,25 +234,84 @@ redata_unsaved_exists(redata_t *redata, char *filename) |
206 | 234 |
int |
207 | 235 |
redata_unsaved_check(redata_t *redata, char *filename) |
208 | 236 |
{ |
237 |
+ char unsname[PATH_MAX+1]; |
|
238 |
+ int fd,nread; |
|
239 |
+ static char header[9]={UNSAVEDHEADER}; |
|
240 |
+ static char version[9]={UNSAVEDVERSION}; |
|
241 |
+ char filehash[129],undohash[129],buf[64]; |
|
242 |
+ if(redata==NULL || filename==NULL) |
|
243 |
+ return(-1); /* sanity check failed */ |
|
244 |
+ if((unsaved_genname(filename,unsname,sizeof(unsname)))==NULL) |
|
245 |
+ return(-1); /* malformed filename */ |
|
246 |
+ if(redata_filehash(redata,filename,filehash)!=0) |
|
247 |
+ return(-1); |
|
248 |
+ if((fd=open(unsname,O_RDONLY))==-1) |
|
249 |
+ return(-1); |
|
250 |
+ if((nread=read(fd,buf,8))==-1 || nread!=8 || memcmp(buf,header,8)!=0) { |
|
251 |
+ close(fd),fd=-1; |
|
252 |
+ return(-1); /* corrupted header */ |
|
253 |
+ } |
|
254 |
+ if((nread=read(fd,undohash,128))==-1 || nread!=128 || memcmp(undohash,filehash,128)!=0) { |
|
255 |
+ close(fd),fd=-1; |
|
256 |
+ return(-1); /* wrong hash */ |
|
257 |
+ } |
|
258 |
+ if((nread=read(fd,buf,8))==-1 || nread!=8 || memcmp(buf,version,8)!=0) { |
|
259 |
+ close(fd),fd=-1; |
|
260 |
+ return(-1); /* wrong version */ |
|
261 |
+ } |
|
262 |
+ close(fd),fd=-1; |
|
263 |
+ return(0); |
|
264 |
+} |
|
209 | 265 |
|
210 |
-#warning TODO |
|
211 |
- return(-1); |
|
266 |
+ |
|
267 |
+int |
|
268 |
+redata_unsaved_unlink(redata_t *redata) |
|
269 |
+{ |
|
270 |
+ char unsname[PATH_MAX+1]; |
|
271 |
+ if(redata==NULL || redata->filename[0]=='\0') |
|
272 |
+ return(-1); /* sanity check failed */ |
|
273 |
+ if(redata_unsaved_exists(redata,redata->filename)==-1) |
|
274 |
+ return(0); /* file not found, nothing to unlink */ |
|
275 |
+ if((unsaved_genname(redata->filename,unsname,sizeof(unsname)))==NULL) |
|
276 |
+ return(-1); /* malformed filename */ |
|
277 |
+ unlink(unsname); |
|
278 |
+ return(0); |
|
212 | 279 |
} |
213 | 280 |
|
281 |
+ |
|
282 |
+ |
|
214 | 283 |
int |
215 |
-redata_unsaved_loadappend(redata_t *redata, char *filename) |
|
284 |
+redata_unsaved_trunc(redata_t *redata) |
|
216 | 285 |
{ |
217 |
-#warning TODO |
|
218 |
- return(-1); |
|
286 |
+ char unsname[PATH_MAX+1]; |
|
287 |
+ static char header[9]={UNSAVEDHEADER}; |
|
288 |
+ static char version[9]={UNSAVEDVERSION}; |
|
289 |
+ int n; |
|
290 |
+ if(redata==NULL || redata->filename[0]=='\0') |
|
291 |
+ return(-1); /* sanity check failed */ |
|
292 |
+ redata_unsaved_unlink(redata); |
|
293 |
+ if((unsaved_genname(redata->filename,unsname,sizeof(unsname)))==NULL) |
|
294 |
+ return(-1); /* malformed filename */ |
|
295 |
+ if((redata->unsavedfd=open(unsname,O_WRONLY|O_TRUNC|O_CREAT,0644))==-1) |
|
296 |
+ return(-1); /* couldn't open file for writing */ |
|
297 |
+ if((n=write(redata->unsavedfd,header,8))==-1 || n!=8 || |
|
298 |
+ (n=write(redata->unsavedfd,redata->initialhash,128))==-1 || n!=128 || |
|
299 |
+ (n=write(redata->unsavedfd,version,8))==-1 || n!=8) { |
|
300 |
+ close(redata->unsavedfd),redata->unsavedfd=-1; |
|
301 |
+ unlink(unsname); |
|
302 |
+ return(-1); /* couldn't write header/hash/version */ |
|
303 |
+ } |
|
304 |
+ return(0); |
|
219 | 305 |
} |
220 | 306 |
|
221 | 307 |
int |
222 |
-redata_unsaved_trunc(redata_t *redata, char *filename) |
|
308 |
+redata_unsaved_loadappend(redata_t *redata) |
|
223 | 309 |
{ |
224 | 310 |
#warning TODO |
225 | 311 |
return(-1); |
226 | 312 |
} |
227 | 313 |
|
314 |
+ |
|
228 | 315 |
int |
229 | 316 |
redata_unsaved_add(redata_t *redata, undo_t *undo) |
230 | 317 |
{ |
... | ... |
@@ -242,12 +329,16 @@ redata_unsaved_unadd(redata_t *redata, undo_t *undo) |
242 | 329 |
int |
243 | 330 |
redata_load(redata_t *redata, char *filename, int use_unsaved) |
244 | 331 |
{ |
245 |
-#warning TODO: use_unsaved (apply unsaved changes after load) |
|
332 |
+#warning TODO: make sure a line of len<chunksize is entirely inside one chunk (to simplify the syntax highlighting code) |
|
246 | 333 |
int fd,nread,totalread; |
247 | 334 |
int chunkno, avail; |
248 | 335 |
struct stat statbuf; |
249 | 336 |
rechunk_t *chunk; |
337 |
+ if(redata==NULL || filename==NULL) |
|
338 |
+ return(-1); /* sanity check failed */ |
|
250 | 339 |
redata_wipe(redata); |
340 |
+ strncpy(redata->filename,filename,sizeof(redata->filename)); |
|
341 |
+ redata->filename[sizeof(redata->filename)-1]='\0'; |
|
251 | 342 |
if((fd=open(filename,O_RDONLY))==-1 || fstat(fd,&statbuf)!=0 || !S_ISREG(statbuf.st_mode)) { |
252 | 343 |
if(fd!=-1) |
253 | 344 |
close(fd),fd=-1; |
... | ... |
@@ -287,12 +378,13 @@ redata_load(redata_t *redata, char *filename, int use_unsaved) |
287 | 378 |
} |
288 | 379 |
close(fd),fd=-1; |
289 | 380 |
/* unsaved */ |
381 |
+ redata_hash(redata,redata->initialhash); |
|
290 | 382 |
if(use_unsaved) { |
291 | 383 |
/* apply missing changes and append new changes to unsaved */ |
292 |
- redata_unsaved_loadappend(redata,filename); |
|
384 |
+ redata_unsaved_loadappend(redata); |
|
293 | 385 |
} else { |
294 | 386 |
/* nuke existing unsaved (if exists) and prepare new unsaved */ |
295 |
- redata_unsaved_trunc(redata,filename); |
|
387 |
+ redata_unsaved_trunc(redata); |
|
296 | 388 |
} |
297 | 389 |
/* all done */ |
298 | 390 |
return(0); |
... | ... |
@@ -301,13 +393,143 @@ redata_load(redata_t *redata, char *filename, int use_unsaved) |
301 | 393 |
int |
302 | 394 |
redata_save(redata_t *redata, char *filename) |
303 | 395 |
{ |
304 |
-#warning TODO |
|
305 |
- return(-1); |
|
396 |
+ int fd; |
|
397 |
+ int i,n; |
|
398 |
+ char tmpfile[PATH_MAX+1]; |
|
399 |
+ if(redata==NULL || filename==NULL) |
|
400 |
+ return(-1); /* sanity check failed */ |
|
401 |
+ if((securesave_genname(redata->filename,tmpfile,sizeof(tmpfile)))==NULL) |
|
402 |
+ return(-1); /* malformed filename */ |
|
403 |
+ if((fd=open(tmpfile,O_WRONLY|O_TRUNC|O_CREAT,0644))==-1) |
|
404 |
+ return(-1); /* couldn't open file for writing */ |
|
405 |
+ for(i=0;i<redata->sizechunks;i++) { |
|
406 |
+ if(redata->chunks[i]->useddata==0) |
|
407 |
+ continue; |
|
408 |
+ if((n=write(fd,redata->chunks[i]->data,redata->chunks[i]->useddata))==-1 || n!=redata->chunks[i]->useddata) { |
|
409 |
+ close(fd),fd=-1; |
|
410 |
+ unlink(tmpfile); |
|
411 |
+ return(-1); /* short write */ |
|
412 |
+ } |
|
413 |
+ } |
|
414 |
+ close(fd),fd=-1; |
|
415 |
+ if(rename(tmpfile,filename)!=0) { |
|
416 |
+ unlink(tmpfile); |
|
417 |
+ return(-1); /* couldn't overwrite old file */ |
|
418 |
+ } |
|
419 |
+ redata_unsaved_unlink(redata); |
|
420 |
+ redata->flag_unsaveddata=0; |
|
421 |
+ redata_hash(redata,redata->initialhash); |
|
422 |
+ return(0); |
|
423 |
+} |
|
424 |
+ |
|
425 |
+int |
|
426 |
+redata_undobuf_reserve(redata_t *redata, int minavail) |
|
427 |
+{ |
|
428 |
+ int unused; |
|
429 |
+ int newsize; |
|
430 |
+ char *newptr; |
|
431 |
+ if(redata==NULL || minavail<0) |
|
432 |
+ return(-1); /* sanity check failed */ |
|
433 |
+ unused=redata->sizeundobuf-redata->usedundobuf; |
|
434 |
+ if(unused<minavail) { |
|
435 |
+ newsize=(redata->sizeundobuf+minavail+UNDOGROWSIZE-1)/UNDOGROWSIZE; |
|
436 |
+ newsize*=UNDOGROWSIZE; |
|
437 |
+ if((newptr=realloc(redata->undobuf,newsize))==NULL) |
|
438 |
+ return(-1); /* insuf. mem. */ |
|
439 |
+ redata->undobuf=newptr; |
|
440 |
+ redata->sizeundobuf=newsize; |
|
441 |
+ } |
|
442 |
+ return(0); |
|
443 |
+} |
|
444 |
+ |
|
445 |
+undo_t * |
|
446 |
+redata_undo_new(redata_t *redata, char *type) |
|
447 |
+{ |
|
448 |
+ int newsize; |
|
449 |
+ undo_t *newptr,*undo; |
|
450 |
+ if(redata==NULL || type==NULL) |
|
451 |
+ return(NULL); /* sanity check failed */ |
|
452 |
+ if(redata->sizeundo==redata->usedundo) { |
|
453 |
+ newsize=(redata->sizeundo+1+UNDOBLOCK-1)/UNDOBLOCK; |
|
454 |
+ newsize*=UNDOBLOCK; |
|
455 |
+ if((newptr=realloc(redata->undo,sizeof(undo_t)*newsize))==NULL) |
|
456 |
+ return(NULL); |
|
457 |
+ redata->undo=newptr; |
|
458 |
+ memset(redata->undo+redata->sizeundo,0,sizeof(undo_t)*(newsize-redata->sizeundo)); |
|
459 |
+ redata->sizeundo=newsize; |
|
460 |
+ } |
|
461 |
+ undo=redata->undo+redata->usedundo; |
|
462 |
+ redata->usedundo++; |
|
463 |
+ strncpy(undo->type,type,sizeof(undo->type)); |
|
464 |
+ undo->type[sizeof(undo->type)-1]='\0'; |
|
465 |
+ undo->off=redata->usedundobuf; |
|
466 |
+ undo->len=0; |
|
467 |
+ return(undo); |
|
468 |
+} |
|
469 |
+ |
|
470 |
+undo_t * |
|
471 |
+redata_undo_newfromchunks(redata_t *redata,char *type, int pos1, int len) |
|
472 |
+{ |
|
473 |
+ int startpos,startoff,endpos,endoff; |
|
474 |
+ undo_t *undo; |
|
475 |
+ int k; |
|
476 |
+ int used; |
|
477 |
+ int copyfrom,copysize; |
|
478 |
+ if(redata==NULL || type==NULL || len<=0) |
|
479 |
+ return(NULL); /* sanity check failed */ |
|
480 |
+ if(redata_getposptr(redata,pos1,&startpos,&startoff)==-1 || |
|
481 |
+ redata_getposptr(redata,pos1+len,&endpos,&endoff)==-1) { |
|
482 |
+ return(NULL); /* chunk data out of bounds */ |
|
483 |
+ } |
|
484 |
+ if(redata_undobuf_reserve(redata,len)!=0) |
|
485 |
+ return(NULL); /* insuf. mem. */ |
|
486 |
+ if((undo=redata_undo_new(redata,type))==NULL) |
|
487 |
+ return(NULL); /* insuf. mem. */ |
|
488 |
+ undo->off=redata->usedundobuf; |
|
489 |
+ /* copy contents */ |
|
490 |
+ for(k=startpos,used=0;k<=endpos;k++) { |
|
491 |
+ if(k==startpos && k==endpos) { |
|
492 |
+ copyfrom=startoff; |
|
493 |
+ copysize=endoff-startoff; |
|
494 |
+ } else if(k==startpos) { |
|
495 |
+ copyfrom=startoff; |
|
496 |
+ copysize=redata->chunks[k]->useddata-startoff; |
|
497 |
+ } else if(k==endpos) { |
|
498 |
+ copyfrom=0; |
|
499 |
+ copysize=endoff; |
|
500 |
+ } else { |
|
501 |
+ copyfrom=0; |
|
502 |
+ copysize=redata->chunks[k]->useddata; |
|
503 |
+ } |
|
504 |
+ memcpy(redata->undobuf+redata->usedundobuf,redata->chunks[k]->data+copyfrom,copysize); |
|
505 |
+ redata->usedundobuf+=copysize; |
|
506 |
+ used+=copysize; |
|
507 |
+ } |
|
508 |
+ undo->len=used; |
|
509 |
+ return(undo); |
|
510 |
+} |
|
511 |
+ |
|
512 |
+undo_t * |
|
513 |
+redata_undobuf_newfrombuf(redata_t *redata, char *type, char *buf, int buflen) |
|
514 |
+{ |
|
515 |
+ undo_t *undo; |
|
516 |
+ if(redata==NULL || type==NULL || buflen<=0) |
|
517 |
+ return(NULL); /* sanity check failed */ |
|
518 |
+ if(redata_undobuf_reserve(redata,buflen)!=0) |
|
519 |
+ return(NULL); /* insuf. mem. */ |
|
520 |
+ if((undo=redata_undo_new(redata,type))==NULL) |
|
521 |
+ return(NULL); /* insuf. mem. */ |
|
522 |
+ undo->off=redata->usedundobuf; |
|
523 |
+ memcpy(redata->undobuf+redata->usedundobuf,buf,buflen); |
|
524 |
+ redata->usedundobuf+=buflen; |
|
525 |
+ undo->len=buflen; |
|
526 |
+ return(undo); |
|
306 | 527 |
} |
307 | 528 |
|
308 | 529 |
int |
309 | 530 |
redata_op_add(redata_t *redata, char *buf, int sizebuf, int pos) |
310 | 531 |
{ |
532 |
+ |
|
311 | 533 |
#warning TODO |
312 | 534 |
return(-1); |
313 | 535 |
} |
... | ... |
@@ -326,6 +548,20 @@ redata_op_move(redata_t *redata, int posorig, int size, int posdest) |
326 | 548 |
return(-1); |
327 | 549 |
} |
328 | 550 |
|
551 |
+int |
|
552 |
+redata_op_undo(redata_t *redata) |
|
553 |
+{ |
|
554 |
+#warning TODO |
|
555 |
+ return(-1); |
|
556 |
+} |
|
557 |
+ |
|
558 |
+int |
|
559 |
+redata_op_redo(redata_t *redata) |
|
560 |
+{ |
|
561 |
+#warning TODO |
|
562 |
+ return(-1); |
|
563 |
+} |
|
564 |
+ |
|
329 | 565 |
int |
330 | 566 |
redata_hash(redata_t *redata, char *resbuf129bytes) |
331 | 567 |
{ |
... | ... |
@@ -395,17 +631,34 @@ redata_hash_gen(redata_t *redata, char *filename, char *resbuf129bytes) |
395 | 631 |
static char * |
396 | 632 |
unsaved_genname(char *filename, char *buf, int bufsize) |
397 | 633 |
{ |
398 |
- char *name,*ptr; |
|
399 |
- int filenamelen; |
|
400 |
- int len,off; |
|
401 | 634 |
static char pre[]={UNSAVEDPREFIX}; |
402 | 635 |
static char post[]={UNSAVEDPOSTFIX}; |
403 |
- if(filename==NULL) |
|
636 |
+ return(genname(filename,pre,post,buf,bufsize)); |
|
637 |
+} |
|
638 |
+ |
|
639 |
+static char * |
|
640 |
+securesave_genname(char *filename, char *buf, int bufsize) |
|
641 |
+{ |
|
642 |
+ static char pre[]={SECURESAVEPREFIX}; |
|
643 |
+ static char post[]={SECURESAVEPOSTFIX}; |
|
644 |
+ return(genname(filename,pre,post,buf,bufsize)); |
|
645 |
+} |
|
646 |
+ |
|
647 |
+ |
|
648 |
+static char * |
|
649 |
+genname(char *filename,char *prefix, char *postfix, char *buf, int bufsize) |
|
650 |
+{ |
|
651 |
+ char *name,*ptr; |
|
652 |
+ int filenamelen; |
|
653 |
+ int prelen,postlen,finallen,off; |
|
654 |
+ if(filename==NULL || prefix==NULL || postfix==NULL) |
|
404 | 655 |
return(NULL); |
405 | 656 |
filenamelen=strlen(filename); |
406 |
- len=filenamelen+sizeof(pre)-1+sizeof(post)-1+1; |
|
657 |
+ prelen=strlen(prefix); |
|
658 |
+ postlen=strlen(postfix); |
|
659 |
+ finallen=filenamelen+prelen+postlen+1; |
|
407 | 660 |
if(buf==NULL) { |
408 |
- if((name=malloc(len))==NULL) |
|
661 |
+ if((name=malloc(finallen))==NULL) |
|
409 | 662 |
return(NULL); |
410 | 663 |
} else { |
411 | 664 |
if(bufsize<filenamelen) |
... | ... |
@@ -417,13 +670,14 @@ unsaved_genname(char *filename, char *buf, int bufsize) |
417 | 670 |
off=0; |
418 | 671 |
memcpy(name+off,filename,ptr-filename); |
419 | 672 |
off+=ptr-filename; |
420 |
- memcpy(name+off,pre,sizeof(pre)-1); |
|
421 |
- off+=sizeof(pre)-1; |
|
673 |
+ memcpy(name+off,prefix,prelen); |
|
674 |
+ off+=prelen; |
|
422 | 675 |
memcpy(name+off,ptr,filenamelen-(ptr-filename)); |
423 | 676 |
off+=filenamelen-(ptr-filename); |
424 |
- memcpy(name+off,post,sizeof(post)-1); |
|
425 |
- off+=sizeof(post)-1; |
|
677 |
+ memcpy(name+off,postfix,postlen); |
|
678 |
+ off+=postlen; |
|
426 | 679 |
name[off]='\0'; |
427 | 680 |
return(name); |
428 | 681 |
} |
429 | 682 |
|
683 |
+ |
... | ... |
@@ -11,6 +11,8 @@ |
11 | 11 |
* This program is licensed under the terms of GNU GPL v2.1+ |
12 | 12 |
*/ |
13 | 13 |
|
14 |
+#include <limits.h> |
|
15 |
+ |
|
14 | 16 |
typedef struct whatin_t { |
15 | 17 |
int nlcount; |
16 | 18 |
} whatin_t; |
... | ... |
@@ -22,7 +24,9 @@ typedef struct rechunk_t { |
22 | 24 |
} rechunk_t; |
23 | 25 |
|
24 | 26 |
typedef struct undo_t { |
25 |
- |
|
27 |
+ char type[5]; |
|
28 |
+ int off; |
|
29 |
+ int len; |
|
26 | 30 |
} undo_t; |
27 | 31 |
|
28 | 32 |
typedef struct redata_t { |
... | ... |
@@ -36,9 +40,12 @@ typedef struct redata_t { |
36 | 40 |
int usedundo; |
37 | 41 |
int curundo; |
38 | 42 |
undo_t *undo; |
43 |
+ int sizeundobuf; |
|
44 |
+ int usedundobuf; |
|
39 | 45 |
char *undobuf; |
40 | 46 |
/* unsaved (for recovery when the program closes unexpectedly) */ |
41 |
- char *unsavedfilename; |
|
47 |
+ char filename[PATH_MAX]; |
|
48 |
+ char initialhash[129]; |
|
42 | 49 |
int unsavedfd; |
43 | 50 |
int flag_unsaveddata; |
44 | 51 |
} redata_t; |
... | ... |
@@ -51,6 +58,10 @@ void redata_free(redata_t *redata); |
51 | 58 |
int redata_getsize(redata_t *redata); |
52 | 59 |
int redata_getused(redata_t *redata); |
53 | 60 |
int redata_getavailable(redata_t *redata); |
61 |
+int redata_getused(redata_t *redata); |
|
62 |
+int redata_getposptr(redata_t *redata, int pos, int *numchunk, int *offset); |
|
63 |
+ |
|
64 |
+ |
|
54 | 65 |
|
55 | 66 |
int redata_wipe(redata_t *redata); |
56 | 67 |
int redata_preallocate(redata_t *redata, int size); |
... | ... |
@@ -58,8 +69,9 @@ int redata_fill_whatin(redata_t *redata, int chunkno); |
58 | 69 |
|
59 | 70 |
int redata_unsaved_exists(redata_t *redata, char *filename); |
60 | 71 |
int redata_unsaved_check(redata_t *redata, char *filename); |
61 |
-int redata_unsaved_loadappend(redata_t *redata, char *filename); |
|
62 |
-int redata_unsaved_trunc(redata_t *redata, char *filename); |
|
72 |
+int redata_unsaved_loadappend(redata_t *redata); |
|
73 |
+int redata_unsaved_unlink(redata_t *redata); |
|
74 |
+int redata_unsaved_trunc(redata_t *redata); |
|
63 | 75 |
int redata_unsaved_add(redata_t *redata, undo_t *undo); |
64 | 76 |
int redata_unsaved_unadd(redata_t *redata, undo_t *undo); |
65 | 77 |
|
... | ... |
@@ -70,7 +82,7 @@ int redata_op_add(redata_t *redata, char *buf, int sizebuf, int pos); |
70 | 82 |
int redata_op_del(redata_t *redata, int pos, int size); |
71 | 83 |
int redata_op_move(redata_t *redata, int posorig, int size, int posdest); |
72 | 84 |
int redata_op_undo(redata_t *redata); |
73 |
-int redata_op_redor(redata_t *redata); |
|
85 |
+int redata_op_redo(redata_t *redata); |
|
74 | 86 |
|
75 | 87 |
int redata_hash(redata_t *redata, char *resbuf129bytes); |
76 | 88 |
int redata_filehash(redata_t *redata, char *filename, char *resbuf129bytes); |
77 | 89 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,32 @@ |
1 |
+/* |
|
2 |
+ * recenteditor_data.c |
|
3 |
+ * |
|
4 |
+ * A programmers editor |
|
5 |
+ * |
|
6 |
+ * Tests (ensure correct functionality of modules) |
|
7 |
+ * |
|
8 |
+ * Author: Dario Rodriguez dario@softhome.net |
|
9 |
+ * This program is licensed under the terms of GNU GPL v2.1+ |
|
10 |
+ */ |
|
11 |
+ |
|
12 |
+#include <stdio.h> |
|
13 |
+#include <stdlib.h> |
|
14 |
+#include <unistd.h> |
|
15 |
+#include <string.h> |
|
16 |
+#include <limits.h> |
|
17 |
+ |
|
18 |
+#include "recenteditor_data.h" |
|
19 |
+ |
|
20 |
+int |
|
21 |
+main(int argc, char *argv[]) |
|
22 |
+{ |
|
23 |
+ redata_t *redata; |
|
24 |
+ if((redata=redata_init())==NULL) { |
|
25 |
+ fprintf(stderr,"ERROR: problem initializong redata module\n"); |
|
26 |
+ return(1); |
|
27 |
+ } |
|
28 |
+#warning TODO |
|
29 |
+ redata_free(redata),redata=NULL; |
|
30 |
+} |
|
31 |
+ |
|
32 |
+ |