Browse code

Add undobuf structire and corresponding functions

Dario Rodriguez authored on 05/03/2019 21:40:51
Showing 5 changed files
... ...
@@ -1,2 +1,3 @@
1 1
 *.o
2 2
 re
3
+tests
... ...
@@ -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
+