#include <stdarg.h>
#include <string.h>
-/* Type Definitions
- *****************************************************************************/
-typedef unsigned short ushort;
-typedef unsigned char uchar;
-typedef unsigned long ulong;
-typedef unsigned int uint;
-typedef signed char schar;
-typedef long long vlong;
-typedef unsigned long long uvlong;
-
-typedef uint8_t uint8;
-typedef uint16_t uint16;
-typedef uint32_t uint32;
-typedef uint64_t uint64;
-
-typedef int8_t int8;
-typedef int16_t int16;
-typedef int32_t int32;
-typedef int64_t int64;
-
-typedef uintptr_t uintptr;
-typedef intptr_t intptr;
+static char* strmcat(char* first, ...) {
+ va_list args;
+ /* calculate the length of the final string */
+ size_t len = strlen(first);
+ va_start(args, first);
+ for (char* s = NULL; (s = va_arg(args, char*));)
+ len += strlen(s);
+ va_end(args);
+ /* allocate the final string and copy the args into it */
+ char *str = malloc(len+1), *curr = str;
+ while (first && *first) *(curr++) = *(first++);
+ va_start(args, first);
+ for (char* s = NULL; (s = va_arg(args, char*));)
+ while (s && *s) *(curr++) = *(s++);
+ va_end(args);
+ /* null terminate and return */
+ *curr = '\0';
+ return str;
+}
/* Option Parsing
*
return log;
}
+static void log_add(size_t beg, size_t end, char* data, Log** logstk) {
+ Log* prev = *logstk;
+ /* decide if this is an insert or delete */
+ if (!data) {
+ if (prev && !prev->data && prev->end == beg)
+ prev->end++;
+ else
+ *logstk = mklog(beg, end, data, prev);
+ } else {
+ if (prev && prev->data && prev->beg == beg) {
+ char* newdata = strmcat(prev->data, data, 0);
+ free(data);
+ free(prev->data);
+ prev->data = newdata;
+ } else if (prev && prev->data && prev->beg == beg+1) {
+ char* newdata = strmcat(data, prev->data, 0);
+ free(data);
+ free(prev->data);
+ prev->data = newdata;
+ prev->end = --prev->beg;
+ } else {
+ *logstk = mklog(beg, end, data, prev);
+ }
+ }
+}
+
static void log_clear(Log** list) {
while (*list) {
Log* deadite = *list;
size_t beg = buf_getsel(buf).beg;
if (s && *s) {
while (*s) putb(buf, *(s++), &(buf->selection));
- buf->undo = mklog(beg, buf_getsel(buf).end, NULL, buf->undo);
+ log_add(beg, buf_getsel(buf).end, NULL, &(buf->undo));
}
}
buf->gapend += nbytes;
sel.end = sel.beg;
buf->selection = sel;
- buf->undo = mklog(sel.beg, sel.end, str, buf->undo);
+ log_add(sel.beg, sel.end, str, &(buf->undo));
}
}
job_start(execcmd, input, len, (op != '<' ? curr : edit));
}
-static char* strmcat(char* first, ...) {
- va_list args;
- /* calculate the length of the final string */
- size_t len = strlen(first);
- va_start(args, first);
- for (char* s = NULL; (s = va_arg(args, char*));)
- len += strlen(s);
- va_end(args);
- /* allocate the final string and copy the args into it */
- char *str = malloc(len+1), *curr = str;
- while (first && *first) *(curr++) = *(first++);
- va_start(args, first);
- for (char* s = NULL; (s = va_arg(args, char*));)
- while (s && *s) *(curr++) = *(s++);
- va_end(args);
- /* null terminate and return */
- *curr = '\0';
- return str;
-}
-
static void cmd_execwitharg(char* cmd, char* arg) {
cmd = (arg ? strmcat(cmd, " '", arg, "'", 0) : strmcat(cmd));
cmd_exec(cmd);