Browse code

unsaved_unadd and unsaved_commit

Dario Rodriguez authored on 20/03/2019 22:56:11
Showing 2 changed files
... ...
@@ -65,7 +65,6 @@ redata_init(void)
65 65
         redata->filename[0]='\0';
66 66
         redata->unsavedfd=-1;
67 67
         redata->unsaved.sizebuf=redata->unsaved.usedbuf=0;
68
-        redata->unsaved.lastsize=0;
69 68
         /* all done */
70 69
         return(redata);
71 70
 }
... ...
@@ -106,7 +105,6 @@ redata_free(redata_t *redata)
106 105
         if(redata->unsaved.buf!=NULL) {
107 106
                 free(redata->unsaved.buf),redata->unsaved.buf=NULL;
108 107
                 redata->unsaved.sizebuf=redata->unsaved.usedbuf=0;
109
-                redata->unsaved.lastsize=0;
110 108
         }
111 109
         /* free main struct */
112 110
         free(redata),redata=NULL;
... ...
@@ -580,7 +578,6 @@ redata_unsaved_loadappend(redata_t *redata)
580 578
                 redata->unsaved.buf=newptr;
581 579
                 redata->unsaved.sizebuf=(statbuf.st_size-headerhashsize);
582 580
         }
583
-        redata->unsaved.lastsize=0;
584 581
         redata->unsaved.usedbuf=0;
585 582
         lim=(statbuf.st_size-headerhashsize);
586 583
         for(nread=0;redata->unsaved.usedbuf<lim;redata->unsaved.usedbuf+=nread,nread=0) {
... ...
@@ -731,21 +728,100 @@ redata_unsaved_add(redata_t *redata, undostack_t *stack, int undono)
731 728
                         buf=redata->unsaved.buf+redata->unsaved.usedbuf;
732 729
                 }
733 730
         }
734
-        return(-1);
731
+        return(0);
735 732
 }
736 733
 
737 734
 int
738 735
 redata_unsaved_unadd(redata_t *redata, undostack_t *stack, int undono)
739 736
 {
740
-#warning TODO
741
-        return(-1);
737
+        /* adds to unsaved the inverse operation to the one specified in the undo */
738
+        char sep;
739
+        undo_t *undo;
740
+        char *sepend,*ptr,*endptr;
741
+        char *buf;
742
+        int k;
743
+        int maxsize,newsize;
744
+        char posbuf[128];
745
+        if(redata==NULL
746
+          || (stack!=&(redata->undostack) && stack!=&(redata->redostack))
747
+          || undono<0 || undono>=stack->usedundo)
748
+                return(-1); /* sanity check failed */
749
+        /* syntax (see loadappend): A<pos><+?><sep><text><sep>[<+?><sep><text><sep>[...]] */
750
+        undo=stack->undo+undono;
751
+        if(undo->type!='A' && undo->type!='D' && undo->type!='M')
752
+                return(-1); /* unrecognized undo type */
753
+        for(k=0,maxsize=0,buf=NULL;k<2;k++,maxsize=0) {
754
+                ptr=stack->buf+undo->off;
755
+                endptr=ptr+undo->len;
756
+                if(k!=0)
757
+                        buf[maxsize]=(undo->type=='A')?'D':(undo->type=='D')?'A':undo->type;
758
+                maxsize++;
759
+                if(undo->type=='A' || undo->type=='D')
760
+                        snprintf(posbuf,sizeof(posbuf),"%li",undo->posorig);
761
+                else
762
+                        snprintf(posbuf,sizeof(posbuf),"%li",(undo->posorig<undo->posdest)?undo->posdest-undo->len:undo->posdest);
763
+                posbuf[sizeof(posbuf)-1]='\0';
764
+                if(k!=0)
765
+                        strcpy(buf+maxsize,posbuf);
766
+                maxsize+=strlen(posbuf);
767
+                if(undo->type=='M') {
768
+                        snprintf(posbuf,sizeof(posbuf),",%li",(undo->posorig<undo->posdest)?undo->posorig:undo->posorig+undo->len);
769
+                        posbuf[sizeof(posbuf)-1]='\0';
770
+                        if(k!=0)
771
+                                strcpy(buf+maxsize,posbuf);
772
+                        maxsize+=strlen(posbuf);
773
+                }
774
+                while(ptr<endptr) {
775
+                        sep=sep_select(ptr,endptr-ptr,&sepend);
776
+                        if(sepend!=endptr) {
777
+                                if(k!=0)
778
+                                        buf[maxsize]='+';
779
+                                maxsize++;
780
+                        }
781
+                        if(k!=0)
782
+                                buf[maxsize]=sep;
783
+                        maxsize++;
784
+                        if(k!=0)
785
+                                memcpy(buf+maxsize,ptr,sepend-ptr);
786
+                        maxsize+=sepend-ptr;
787
+                        if(k!=0)
788
+                                buf[maxsize]=sep;
789
+                        maxsize++;
790
+                        ptr=sepend;
791
+                }
792
+                if(k==0) {
793
+                        /* get mem */
794
+                        if((redata->unsaved.sizebuf-redata->unsaved.sizebuf)<maxsize) {
795
+                                newsize=(redata->unsaved.sizebuf+maxsize+UNDOGROWSIZE-1)/UNDOGROWSIZE;
796
+                                newsize*=UNDOGROWSIZE;
797
+                                if((buf=realloc(redata->unsaved.buf,newsize))==NULL)
798
+                                        return(-1); /* insuf. mem. */
799
+                                redata->unsaved.buf=buf;
800
+                                redata->unsaved.sizebuf=newsize;
801
+                        }
802
+                        buf=redata->unsaved.buf+redata->unsaved.usedbuf;
803
+                }
804
+        }
805
+        return(0);
742 806
 }
743 807
 
744 808
 int
745 809
 redata_unsaved_commit(redata_t *redata)
746 810
 {
747
-#warning TODO
748
-        return(-1);
811
+        int n,nwritten;
812
+        char unsname[PATH_MAX+1];
813
+        if(redata==NULL || redata->unsavedfd==-1)
814
+                return(-1);
815
+        for(nwritten=0;nwritten<redata->unsaved.usedbuf;nwritten+=n) {
816
+                if((n=write(redata->unsavedfd,redata->unsaved.buf+nwritten,redata->unsaved.usedbuf-nwritten))<0) {
817
+                        close(redata->unsavedfd),redata->unsavedfd=-1;
818
+                        if((unsaved_genname(redata->filename,unsname,sizeof(unsname)))!=NULL)
819
+                                unlink(unsname); /* a corrupted unsaved is of no use, delete it */
820
+                        return(-1); /* error writing */
821
+                }
822
+        }
823
+        redata->unsaved.usedbuf=0;
824
+        return(0);
749 825
 }
750 826
 
751 827
 
... ...
@@ -1120,6 +1196,8 @@ redata_op_add(redata_t *redata, long insertpos, char *buf, long buflen, undostac
1120 1196
                 /* from undo stack */
1121 1197
                 redata_undo_movelast(redata,&(redata->undostack),&(redata->redostack));
1122 1198
         }
1199
+        /* add to unsaved */
1200
+        redata_unsaved_add(redata,&(redata->undostack),redata->undostack.usedundo-1);
1123 1201
         /* compact if needed */
1124 1202
         if(redata_getsize(redata)>(redata->chunkdatasize) && redata_getavailable(redata)>(redata_getsize(redata)/2))
1125 1203
                 redata_compact(redata);
... ...
@@ -1178,6 +1256,8 @@ redata_op_del(redata_t *redata, long delpos, long size, undostack_t *fromhere)
1178 1256
                 /* from undo stack */
1179 1257
                 redata_undo_movelast(redata,&(redata->undostack),&(redata->redostack));
1180 1258
         }
1259
+        /* add to unsaved */
1260
+        redata_unsaved_add(redata,&(redata->undostack),redata->undostack.usedundo-1);
1181 1261
         /* compact if needed */
1182 1262
         if(redata_getsize(redata)>(redata->chunkdatasize) && redata_getavailable(redata)>(redata_getsize(redata)/2))
1183 1263
                 redata_compact(redata);
... ...
@@ -1307,6 +1387,8 @@ redata_op_move(redata_t *redata, long posorig, long size, long posdest, undostac
1307 1387
                 /* from undo stack */
1308 1388
                 redata_undo_movelast(redata,&(redata->undostack),&(redata->redostack));
1309 1389
         }
1390
+        /* add to unsaved */
1391
+        redata_unsaved_add(redata,&(redata->undostack),redata->undostack.usedundo-1);
1310 1392
         /* compact if needed */
1311 1393
         if(redata_getsize(redata)>(redata->chunkdatasize) && redata_getavailable(redata)>(redata_getsize(redata)/2))
1312 1394
                 redata_compact(redata);
... ...
@@ -47,7 +47,6 @@ typedef struct unsaved_t {
47 47
         long sizebuf;
48 48
         long usedbuf;
49 49
         char *buf;
50
-        long lastsize;
51 50
 } unsaved_t;
52 51
 
53 52
 typedef struct redata_t {