Browse code

implementation of op_del, op_undo, op_redo

Dario Rodriguez authored on 13/03/2019 17:07:30
Showing 3 changed files
... ...
@@ -197,6 +197,25 @@ redata_chunk_insertnew(redata_t *redata, int afterthischunk)
197 197
         return(0);
198 198
 }
199 199
 
200
+int
201
+redata_chunk_deletechunk(redata_t *redata, int chunkno)
202
+{
203
+        rechunk_t *chunk;
204
+        int i;
205
+        if(redata==NULL || chunkno<0 || chunkno>=redata->sizechunks)
206
+                return(-1);
207
+        chunk=redata->chunks[chunkno];
208
+        if(chunk->useddata>0) {
209
+                redata->available+=chunk->useddata;
210
+                chunk->useddata=0;
211
+                chunk->whatin_fresh=0;
212
+        }
213
+        for(i=chunkno;(i+1)<redata->sizechunks;i++)
214
+                redata->chunks[i]=redata->chunks[i+1];
215
+        redata->chunks[redata->sizechunks-1]=chunk;
216
+        return(0);
217
+}
218
+
200 219
 
201 220
 int
202 221
 redata_preallocate(redata_t *redata, long newsize)
... ...
@@ -297,6 +316,7 @@ redata_chunk_insertdata(redata_t *redata, int chunkto, long posto, char *buf, lo
297 316
         memcpy(chunk->data+posto,buf,buflen);
298 317
         chunk->useddata+=buflen;
299 318
         chunk->whatin_fresh=0;
319
+        redata->available-=buflen;
300 320
         return(0);
301 321
 }
302 322
 
... ...
@@ -315,6 +335,7 @@ redata_chunk_deletedata(redata_t *redata, int chunkno, long pos, long n)
315 335
         memmove(chunk->data+pos,chunk->data+pos+n,chunk->useddata-pos-n);
316 336
         chunk->useddata-=n;
317 337
         chunk->whatin_fresh=0;
338
+        redata->available+=n;
318 339
         return(0);
319 340
 }
320 341
 
... ...
@@ -713,7 +734,7 @@ redata_undo_movelast(redata_t *redata, undostack_t *from, undostack_t *to)
713 734
 {
714 735
         undo_t *undofrom;
715 736
         undo_t *undoto;
716
-        if(redata==NULL || from!=to
737
+        if(redata==NULL || from==to
717 738
           || (from!=&(redata->undostack) && from!=&(redata->redostack))
718 739
           || (to!=&(redata->undostack) && to!=&(redata->redostack))
719 740
           || from->usedundo<1)
... ...
@@ -758,7 +779,7 @@ redata_undo_wipe(redata_t *redata, undostack_t *stack)
758 779
 }
759 780
 
760 781
 int
761
-redata_op_add(redata_t *redata, int insertpos, char *buf, int buflen, undostack_t *fromhere)
782
+redata_op_add(redata_t *redata, long insertpos, char *buf, long buflen, undostack_t *fromhere)
762 783
 {
763 784
         int chunkno;
764 785
         long pos;
... ...
@@ -804,6 +825,7 @@ redata_op_add(redata_t *redata, int insertpos, char *buf, int buflen, undostack_
804 825
                 needed+=(chunk->useddata-pos);
805 826
                 if(redata_preallocate(redata,redata_getsize(redata)+needed)!=0) {
806 827
                         if(undo!=NULL) {
828
+                                redata->undostack.usedundo--;
807 829
                                 redata->undostack.usedbuf-=buflen;
808 830
                                 memset(undo,0,sizeof(undo_t));
809 831
                         }
... ...
@@ -834,7 +856,6 @@ redata_op_add(redata_t *redata, int insertpos, char *buf, int buflen, undostack_
834 856
                 /* new or from redo stack */
835 857
                 undo->posorig=undo->posdest=insertpos;
836 858
                 redata_hash(redata,undo->posthash);
837
-                redata->undostack.usedundo++;
838 859
                 if(fromhere==&(redata->redostack))
839 860
                         redata_undo_removelast(redata,&(redata->redostack));
840 861
                 else
... ...
@@ -847,14 +868,62 @@ redata_op_add(redata_t *redata, int insertpos, char *buf, int buflen, undostack_
847 868
 }
848 869
 
849 870
 int
850
-redata_op_del(redata_t *redata, int pos, int size, undostack_t *fromhere)
871
+redata_op_del(redata_t *redata, long delpos, long size, undostack_t *fromhere)
851 872
 {
852
-#warning TODO
853
-        return(-1);
873
+        int chunkno,curchunk;
874
+        long pos;
875
+        undo_t *undo;
876
+        rechunk_t *chunk;
877
+        long ndel;
878
+        long curpos,curdel;
879
+        if(redata==NULL || size<0
880
+          || delpos>redata_getused(redata)
881
+          || (delpos+size)>redata_getused(redata)
882
+          || (fromhere!=NULL && (fromhere!=&(redata->undostack) && fromhere!=&(redata->redostack))))
883
+                return(-1); /* sanity check failed */
884
+        if(redata_getposptr(redata,delpos,&chunkno,&pos)==-1)
885
+                return(-1); /* invalid pos */
886
+        if(fromhere!=&(redata->undostack)) {
887
+                if((undo=redata_undo_newfromchunks(redata,&(redata->undostack),"DEL",delpos,size))==NULL)
888
+                        return(-1); /* couldn't create undo struct */
889
+                redata_hash(redata,undo->prehash);
890
+        } else {
891
+                undo=NULL;
892
+        }
893
+        for(curchunk=chunkno,ndel=0;ndel<size;curchunk++) {
894
+                curpos=(curchunk==chunkno)?pos:0;
895
+                curdel=redata->chunks[curchunk]->useddata-curpos;
896
+                curdel=(curdel>(size-ndel))?(size-ndel):curdel;
897
+                redata_chunk_deletedata(redata,chunkno,curpos,curdel);
898
+                ndel+=curdel;
899
+        }
900
+        /* fix nl and delete unused chunks */
901
+        for(curchunk--;curchunk>=chunkno;curchunk--) {
902
+                chunk=redata->chunks[curchunk];
903
+                if(chunk->useddata==0) {
904
+                        /* move this chunk to the end */
905
+                        redata_chunk_deletechunk(redata,curchunk);
906
+                } else
907
+                        redata_fix_nl(redata,curchunk);
908
+        }
909
+        /* activate undo */
910
+        if(undo!=NULL) {
911
+                /* new or from redo stack */
912
+                undo->posorig=undo->posdest=delpos;
913
+                redata_hash(redata,undo->posthash);
914
+                if(fromhere==&(redata->redostack))
915
+                        redata_undo_removelast(redata,&(redata->redostack));
916
+                else
917
+                        redata_undo_wipe(redata,&(redata->redostack));
918
+        } else {
919
+                /* from undo stack */
920
+                redata_undo_movelast(redata,&(redata->undostack),&(redata->redostack));
921
+        }
922
+        return(0);
854 923
 }
855 924
 
856 925
 int
857
-redata_op_move(redata_t *redata, int posorig, int size, int posdest, undostack_t *fromhere)
926
+redata_op_move(redata_t *redata, long posorig, long size, long posdest, undostack_t *fromhere)
858 927
 {
859 928
 #warning TODO
860 929
         return(-1);
... ...
@@ -13,7 +13,6 @@
13 13
 
14 14
 #include <limits.h>
15 15
 
16
-#warning TODO: change "pos" (offset in data) to long
17 16
 typedef struct whatin_t {
18 17
         int nlcount;
19 18
 } whatin_t;
... ...
@@ -62,8 +61,6 @@ typedef struct redata_t {
62 61
         int flag_unsaveddata;
63 62
 } redata_t;
64 63
 
65
-#warning TODO: undo operations log/buffer, add/remove/move text funtions
66
-
67 64
 redata_t *redata_init(void);
68 65
 void redata_free(redata_t *redata);
69 66
 
... ...
@@ -78,6 +75,7 @@ int redata_getposptr(redata_t *redata, long pos, int *numchunk, long *offset);
78 75
 int redata_wipe(redata_t *redata);
79 76
 int redata_preallocate(redata_t *redata, long size);
80 77
 int redata_chunk_insertnew(redata_t *redata, int afterthischunk);
78
+int redata_chunk_deletechunk(redata_t *redata, int chunkno);
81 79
 int redata_chunk_movedata(redata_t *redata, int chunkfrom, long posfrom, int chunkto, long posto, long size);
82 80
 int redata_chunk_insertdata(redata_t *redata, int chunkto, long posto, char *buf, long buflen);
83 81
 int redata_chunk_deletedata(redata_t *redata, int chunkno, long pos, long n);
... ...
@@ -104,9 +102,9 @@ int redata_unsaved_commit(redata_t *redata);
104 102
 int redata_load(redata_t *redata, char *filename, int use_unsaved);
105 103
 int redata_save(redata_t *redata, char *filename);
106 104
 
107
-int redata_op_add(redata_t *redata, int pos, char *buf, int buflen, undostack_t *fromhere);
108
-int redata_op_del(redata_t *redata, int pos, int size, undostack_t *fromhere);
109
-int redata_op_move(redata_t *redata, int posorig, int size, int posdest, undostack_t *fromhere);
105
+int redata_op_add(redata_t *redata, long pos, char *buf, long buflen, undostack_t *fromhere);
106
+int redata_op_del(redata_t *redata, long pos, long size, undostack_t *fromhere);
107
+int redata_op_move(redata_t *redata, long posorig, long size, long posdest, undostack_t *fromhere);
110 108
 int redata_op_undo(redata_t *redata);
111 109
 int redata_op_redo(redata_t *redata);
112 110
 
... ...
@@ -171,6 +171,7 @@ fprintf(stderr,"\ntest_edit(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL)?"\
171 171
                                 progress[l]=(l<(sizeof(progress)-2))?*ptr:'+';
172 172
                                 progress[l+1]='\0';
173 173
                         }
174
+if(k!=0) redata_save(redata,"test.pre");
174 175
                         if(*ptr=='A') {
175 176
                                 /* A,<insertpos>,<endchar>,<text><endchar> */
176 177
                                 ptr++;
... ...
@@ -185,6 +186,7 @@ fprintf(stderr,"\ntest_edit(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL)?"\
185 186
                                 ptr+=(*ptr==',')?1:0;
186 187
                                 endcode=*ptr;
187 188
                                 ptr+=(*ptr!='\0')?1:0;
189
+                                ptr+=(*ptr==',')?1:0;
188 190
                                 ptrend=strchr(ptr,endcode);
189 191
                                 ptrend=(ptrend==NULL)?ptr+strlen(ptr):ptrend;
190 192
                                 size=ptrend-ptr;
... ...
@@ -206,6 +208,7 @@ fprintf(stderr,"\ntest_edit(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL)?"\
206 208
                                 return(errorbuf);
207 209
                         }
208 210
                         if(k!=0) {
211
+if(k!=0) redata_save(redata,"test.post");
209 212
                                 redata_hash(redata,hash129_redata);
210 213
                                 redata_memhash(redata,mem,cursize,hash129_mem);
211 214
                                 if(strcmp(hash129_redata,hash129_mem)!=0) {
... ...
@@ -217,6 +220,7 @@ fprintf(stderr,"\ntest_edit(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL)?"\
217 220
                                         return(errorbuf);
218 221
                                 }
219 222
                                 redata_op_undo(redata);
223
+redata_save(redata,"test.undo");
220 224
                                 redata_hash(redata,hash129_redata);
221 225
                                 if(strcmp(hash129_redata,hash129_memold)!=0) {
222 226
                                         if(mem!=NULL)
... ...
@@ -227,6 +231,7 @@ fprintf(stderr,"\ntest_edit(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL)?"\
227 231
                                         return(errorbuf);
228 232
                                 }
229 233
                                 redata_op_redo(redata);
234
+redata_save(redata,"test.redo");
230 235
                                 redata_hash(redata,hash129_redata);
231 236
                                 if(strcmp(hash129_redata,hash129_mem)!=0) {
232 237
                                         if(mem!=NULL)