span table
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 17 Nov 2019 20:34:23 +0000 (22:34 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 17 Nov 2019 20:34:23 +0000 (22:34 +0200)
libvisor/include/visor.h
libvisor/src/vilibc.c
libvisor/src/vilibc.h
libvisor/src/vimpl.h
libvisor/src/viprintf.c
libvisor/src/visor.c

index 4c8d1f1..2846218 100644 (file)
@@ -20,12 +20,14 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 typedef long vi_addr;
 typedef long vi_motion;
+typedef void vi_file;
 
 struct visor;
 struct vi_buffer;
 
 struct vi_span {
-       vi_addr beg, end;
+       vi_addr beg;
+       unsigned long size;
 };
 
 enum vi_motdir {
@@ -67,14 +69,14 @@ struct vi_alloc {
 };
 
 struct vi_fileops {
-       void *(*open)(const char *path);
-       long (*size)(void *file);
-       void (*close)(void *file);
-       void *(*map)(void *file);
-       void (*unmap)(void *file);
-       long (*read)(void *file, void *buf, long count);
-       long (*write)(void *file, void *buf, long count);
-       long (*seek)(void *file, long offs, int whence);
+       vi_file *(*open)(const char *path);
+       long (*size)(vi_file *file);
+       void (*close)(vi_file *file);
+       void *(*map)(vi_file *file);
+       void (*unmap)(vi_file *file);
+       long (*read)(vi_file *file, void *buf, long count);
+       long (*write)(vi_file *file, void *buf, long count);
+       long (*seek)(vi_file *file, long offs, int whence);
 };
 
 struct vi_ttyops {
@@ -100,6 +102,7 @@ struct visor *vi_create(struct vi_alloc *mm);
 void vi_destroy(struct visor *vi);
 
 void vi_set_fileops(struct visor *vi, struct vi_fileops *fop);
+void vi_set_ttyops(struct visor *vi, struct vi_ttyops *tty);
 
 /* vi_new_buf creates a new buffer and inserts it in the buffer list. If the
  * path pointer is null, the new buffer will be empty, otherwise it's as if it
@@ -110,12 +113,15 @@ int vi_delete_buf(struct visor *vi, struct vi_buffer *vb);
 int vi_num_buf(struct visor *vi);
 
 struct vi_buffer *vi_getcur_buf(struct visor *vi);
-int vi_setcur_buf(struct visor *vi, struct vi_buffer *vb);
+void vi_setcur_buf(struct visor *vi, struct vi_buffer *vb);
 
 struct vi_buffer *vi_next_buf(struct visor *vi);
 struct vi_buffer *vi_prev_buf(struct visor *vi);
 
 
+/* reset a buffer to the newly created state, freeing all resources */
+void vi_buf_reset(struct vi_buffer *vb);
+
 /* Read a file into the buffer.
  * Returns 0 on success, -1 on failure.
  */
index 6c021b0..79081ef 100644 (file)
@@ -3,6 +3,72 @@
 
 #ifndef HAVE_LIBC
 
+int atoi(const char *str)
+{
+       return strtol(str, 0, 10);
+}
+
+long atol(const char *str)
+{
+       return strtol(str, 0, 10);
+}
+
+long strtol(const char *str, char **endp, int base)
+{
+       long acc = 0;
+       int sign = 1;
+       int valid = 0;
+       const char *start = str;
+
+       while(isspace(*str)) str++;
+
+       if(base == 0) {
+               if(str[0] == '0') {
+                       if(str[1] == 'x' || str[1] == 'X') {
+                               base = 16;
+                       } else {
+                               base = 8;
+                       }
+               } else {
+                       base = 10;
+               }
+       }
+
+       if(*str == '+') {
+               str++;
+       } else if(*str == '-') {
+               sign = -1;
+               str++;
+       }
+
+       while(*str) {
+               long val = 0x7fffffff;
+               char c = tolower(*str);
+
+               if(isdigit(c)) {
+                       val = *str - '0';
+               } else if(c >= 'a' && c <= 'f') {
+                       val = 10 + c - 'a';
+               } else {
+                       break;
+               }
+               if(val >= base) {
+                       break;
+               }
+               valid = 1;
+
+               acc = acc * base + val;
+               str++;
+       }
+
+       if(endp) {
+               *endp = (char*)(valid ? str : start);
+       }
+
+       return sign > 0 ? acc : -acc;
+}
+
+
 void *memset(void *s, int c, unsigned long n)
 {
        char *p = s;
@@ -50,6 +116,17 @@ unsigned long strlen(const char *s)
        return len;
 }
 
+char *strchr(const char *s, int c)
+{
+       while(*s) {
+               if(*s == c) {
+                       return (char*)s;
+               }
+               s++;
+       }
+       return 0;
+}
+
 int strcmp(const char *s1, const char *s2)
 {
        while(*s1 && *s1 == *s2) {
@@ -59,6 +136,69 @@ int strcmp(const char *s1, const char *s2)
        return *s1 - *s2;
 }
 
+char *strcpy(char *dest, const char *src)
+{
+       char *dptr = dest;
+       while((*dptr++ = *src++));
+       return dest;
+}
+
+
+int isalnum(int c)
+{
+       return isalpha(c) || isdigit(c);
+}
+
+int isalpha(int c)
+{
+       return isupper(c) || islower(c);
+}
+
+int isblank(int c)
+{
+       return c == ' ' || c == '\t';
+}
+
+int isdigit(int c)
+{
+       return c >= '0' && c <= '9';
+}
+
+int isupper(int c)
+{
+       return c >= 'A' && c <= 'Z';
+}
+
+int islower(int c)
+{
+       return c >= 'a' && c <= 'z';
+}
+
+int isgraph(int c)
+{
+       return c > ' ' && c <= '~';
+}
+
+int isprint(int c)
+{
+       return isgraph(c) || c == ' ';
+}
+
+int isspace(int c)
+{
+       return isblank(c) || c == '\f' || c == '\n' || c == '\r' || c == '\v';
+}
+
+int toupper(int c)
+{
+       return islower(c) ? (c + ('A' - 'a')) : c;
+}
+
+int tolower(int c)
+{
+       return isupper(c) ? (c - ('A' - 'a')) : c;
+}
+
 #endif /* !def HAVE_LIBC */
 
 static char errstr_buf[256];
index 881c6ed..e955585 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
+#include <ctype.h>
+#include <limit.h>
 #else
 
+int atoi(const char *str);
+long atol(const char *str);
+long strtol(const char *str, char **endp, int base);
+
 void *memset(void *s, int c, unsigned long n);
 void *memcpy(void *dest, const void *src, unsigned long n);
 void *memmove(void *dest, const void *src, unsigned long n);
 unsigned long strlen(const char *s);
+char *strchr(const char *s, int c);
 int strcmp(const char *s1, const char *s2);
+char *strcpy(char *dest, const char *src);
 
 #ifdef __GNUC__
 typedef __builtin_va_list va_list;
 #define va_start(v,l)  __builtin_va_start(v,l)
-#define va_end(v)      __builtin_va_end(v)
-#define va_arg(v,l)    __builtin_va_arg(v,l)
+#define va_end(v)              __builtin_va_end(v)
+#define va_arg(v,l)            __builtin_va_arg(v,l)
 #else  /* !def __GNUC__ */
 #error "stdargs implementation for this compiler missing (libvisor/src/vilibc.h)"
 #endif
@@ -33,6 +41,19 @@ int vsprintf(char *buf, const char *fmt, va_list ap);
 int snprintf(char *buf, unsigned long sz, const char *fmt, ...);
 int vsnprintf(char *buf, unsigned long sz, const char *fmt, va_list ap);
 
+int isalnum(int c);
+int isalpha(int c);
+#define isascii(c)     ((c) < 128)
+int isblank(int c);
+int isdigit(int c);
+int isupper(int c);
+int islower(int c);
+int isprint(int c);
+int isspace(int c);
+
+int toupper(int c);
+int tolower(int c);
+
 #endif /* !HAVE_LIBC */
 
 struct visor;
index b2d978f..af9b6c4 100644 (file)
@@ -19,8 +19,11 @@ struct vi_buffer {
        vi_addr cursor, view_start;
        int view_xscroll;
 
+       vi_file *fp;
+       int file_mapped;
+
        char *orig;
-       long orig_size;
+       unsigned long orig_size;
        char *add;
        int add_size, add_max;
 
@@ -28,4 +31,6 @@ struct vi_buffer {
        int num_spans, max_spans;
 };
 
+enum { SPAN_ORIG, SPAN_ADD };
+
 #endif /* VIMPL_H_ */
index 5f2b312..315a7e1 100644 (file)
@@ -6,6 +6,8 @@ enum {
 
 static int intern_printf(int out, char *buf, unsigned long sz, const char *fmt, va_list ap);
 static void bwrite(int out, char *buf, unsigned long buf_sz, char *str, int sz);
+static void utoa(unsigned int val, char *buf, int base);
+static void itoa(int val, char *buf, int base);
 
 int sprintf(char *buf, const char *fmt, ...)
 {
@@ -239,11 +241,66 @@ static int intern_printf(int out, char *buf, unsigned long sz, const char *fmt,
  */
 static void bwrite(int out, char *buf, unsigned long buf_sz, char *str, int sz)
 {
-       int i;
-
        if(out == OUT_BUF) {
                if(buf_sz && buf_sz <= sz) sz = buf_sz;
                buf[sz] = 0;
                memcpy(buf, str, sz);
        }
 }
+
+static void utoa(unsigned int val, char *buf, int base)
+{
+       static char rbuf[16];
+       char *ptr = rbuf;
+
+       if(val == 0) {
+               *ptr++ = '0';
+       }
+
+       while(val) {
+               unsigned int digit = val % base;
+               *ptr++ = digit < 10 ? (digit + '0') : (digit - 10 + 'a');
+               val /= base;
+       }
+
+       ptr--;
+
+       while(ptr >= rbuf) {
+               *buf++ = *ptr--;
+       }
+       *buf = 0;
+}
+
+static void itoa(int val, char *buf, int base)
+{
+       static char rbuf[16];
+       char *ptr = rbuf;
+       int neg = 0;
+
+       if(val < 0) {
+               neg = 1;
+               val = -val;
+       }
+
+       if(val == 0) {
+               *ptr++ = '0';
+       }
+
+       while(val) {
+               int digit = val % base;
+               *ptr++ = digit < 10 ? (digit + '0') : (digit - 10 + 'a');
+               val /= base;
+       }
+
+       if(neg) {
+               *ptr++ = '-';
+       }
+
+       ptr--;
+
+       while(ptr >= rbuf) {
+               *buf++ = *ptr--;
+       }
+       *buf = 0;
+}
+
index af79b4a..fc336d8 100644 (file)
@@ -2,8 +2,18 @@
 #include "visor.h"
 #include "vimpl.h"
 
-#define vi_malloc(s)   vi->mm.malloc(s)
-#define vi_free(p)             vi->mm.free(p)
+#define vi_malloc      vi->mm.malloc
+#define vi_free                vi->mm.free
+#define vi_realloc     vi->mm.realloc
+
+#define vi_open                vi->fop.open
+#define vi_size                vi->fop.size
+#define vi_close       vi->fop.close
+#define vi_map         vi->fop.map
+#define vi_unmap       vi->fop.unmap
+#define vi_read                vi->fop.read
+#define vi_write       vi->fop.write
+#define vi_seek                vi->fop.seek
 
 #ifdef HAVE_LIBC
 static const struct vi_alloc stdalloc = { malloc, free, realloc };
@@ -41,6 +51,11 @@ void vi_set_fileops(struct visor *vi, struct vi_fileops *fop)
        vi->fop = *fop;
 }
 
+void vi_set_ttyops(struct visor *vi, struct vi_ttyops *tty)
+{
+       vi->tty = *tty;
+}
+
 struct vi_buffer *vi_new_buf(struct visor *vi, const char *path)
 {
        struct vi_buffer *nb;
@@ -50,6 +65,7 @@ struct vi_buffer *vi_new_buf(struct visor *vi, const char *path)
                return 0;
        }
        memset(nb, 0, sizeof *nb);
+       nb->vi = vi;
 
        if(path) {
                if(vi_buf_read(nb, path) == -1) {
@@ -70,3 +86,161 @@ struct vi_buffer *vi_new_buf(struct visor *vi, const char *path)
        }
        return nb;
 }
+
+static int remove_buf(struct visor *vi, struct vi_buffer *vb)
+{
+       if(!vi->buflist) {
+               vi_error(vi, "failed to remove a buffer which doesn't exist\n");
+               return -1;
+       }
+
+       if(vb->next == vb) {
+               if(vi->buflist != vb) {
+                       vi_error(vi, "failed to remove buffer, buffer list inconsistency\n");
+                       return -1;
+               }
+               vi->buflist = 0;
+               return 0;
+       }
+
+       if(vi->buflist == vb) {
+               vi->buflist = vb->next;
+       }
+       vb->prev->next = vb->next;
+       vb->next->prev = vb->prev;
+       vb->next = vb->prev = vb;
+       return 0;
+}
+
+int vi_delete_buf(struct visor *vi, struct vi_buffer *vb)
+{
+       if(remove_buf(vi, vb) == -1) {
+               return -1;
+       }
+
+       vi_free(vb->path);
+       vi_free(vb->orig);
+       vi_free(vb->add);
+       vi_free(vb->spans);
+       return 0;
+}
+
+int vi_num_buf(struct visor *vi)
+{
+       int count;
+       struct vi_buffer *vb;
+
+       if(!vi->buflist) return 0;
+
+       count = 1;
+       vb = vi->buflist->next;
+       while(vb != vi->buflist) {
+               count++;
+               vb = vb->next;
+       }
+       return count;
+}
+
+struct vi_buffer *vi_getcur_buf(struct visor *vi)
+{
+       return vi->buflist;
+}
+
+void vi_setcur_buf(struct visor *vi, struct vi_buffer *vb)
+{
+       vi->buflist = vb;
+}
+
+struct vi_buffer *vi_next_buf(struct visor *vi)
+{
+       return vi->buflist ? vi->buflist->next : 0;
+}
+
+struct vi_buffer *vi_prev_buf(struct visor *vi)
+{
+       return vi->buflist ? vi->buflist->prev : 0;
+}
+
+static int add_span(struct vi_buffer *vb, int src, vi_addr start, unsigned long size)
+{
+       struct visor *vi = vb->vi;
+       struct vi_span *sp;
+
+       if(vb->num_spans >= vb->max_spans) {
+               int newmax = vb->max_spans > 0 ? (vb->max_spans << 1) : 16;
+               struct vi_span *tmp = vi_realloc(vb->spans, newmax * sizeof *tmp);
+               if(!tmp) return -1;
+               vb->spans = tmp;
+               vb->max_spans = newmax;
+       }
+
+       sp = vb->spans + vb->num_spans++;
+       sp->beg = start;
+       sp->size = size;
+       return 0;
+}
+
+void vi_buf_reset(struct vi_buffer *vb)
+{
+       struct visor *vi = vb->vi;
+       struct vi_buffer *prev, *next;
+
+       vi_free(vb->path);
+
+       if(vb->fp) {
+               if(vb->file_mapped) vi_unmap(vb->fp);
+               vi_close(vb->fp);
+       }
+       vi_free(vb->orig);
+       vi_free(vb->add);
+       vi_free(vb->spans);
+
+       prev = vb->prev;
+       next = vb->next;
+       memset(vb, 0, sizeof *vb);
+       vb->prev = prev;
+       vb->next = next;
+}
+
+int vi_buf_read(struct vi_buffer *vb, const char *path)
+{
+       struct visor *vi = vb->vi;
+       vi_file *fp;
+       unsigned long fsz;
+       int plen;
+
+       vi_buf_reset(vb);
+
+       if(!(fp = vi_open(path))) {
+               return -1;
+       }
+       plen = strlen(path);
+       if(!(vb->path = vi_malloc(plen + 1))) {
+               vi_error(vi, "failed to allocate path name buffer\n");
+               vi_buf_reset(vb);
+               return -1;
+       }
+       memcpy(vb->path, path, plen + 1);
+
+       vb->num_spans = 0;
+
+       if((fsz = vi_size(fp))) {
+               /* existing file, map it into memory, or failing that read it */
+               if(!vi->fop.map || !(vb->orig = vi_map(fp))) {
+                       if(!(vb->orig = vi_malloc(fsz))) {
+                               vi_buf_reset(vb);
+                               return -1;
+                       }
+               } else {
+                       vb->file_mapped = 1;
+               }
+
+               if(add_span(vb, SPAN_ORIG, 0, fsz) == -1) {
+                       vi_error(vi, "failed to allocate span\n");
+                       vi_buf_reset(vb);
+                       return -1;
+               }
+       }
+       vb->orig_size = fsz;
+       return 0;
+}