LDFLAGS = -L/opt/X11/lib -lX11 -lXft -lfontconfig
CFLAGS = --std=gnu99 -Wall -Wextra -I. -I/opt/X11/include -I/opt/local/include/freetype2 -I/usr/include/freetype2
-OBJS = buf.o screen.o utf8.o keyboard.o mouse.o charset.o
+OBJS = buf.o screen.o utf8.o keyboard.o mouse.o charset.o utils.o
TESTOBJS = tests/tests.o tests/buf.o tests/utf8.o
all: edit test
#define _GNU_SOURCE
#include <string.h>
#include <assert.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <fcntl.h>
#include "edit.h"
-typedef struct {
- uint8_t* buf;
- size_t len;
-} FMap;
-
-static FMap fmap(char* path) {
- int fd;
- FMap file = { .buf = NULL, .len = 0 };
- struct stat sb;
- if (((fd = open(path, O_RDONLY, 0)) < 0) ||
- (fstat(fd, &sb) < 0) ||
- (sb.st_size == 0))
- return file;
- file.buf = (uint8_t*)mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
- file.len = sb.st_size;
- if (file.buf == MAP_FAILED)
- die("memory mapping of file failed");
- return file;
-}
-
-static void funmap(FMap file) {
- if (file.buf)
- munmap(file.buf, file.len);
-}
-
-static void utf8load(Buf* buf, FMap file) {
- for (size_t i = 0; i < file.len;) {
- Rune r = 0;
- size_t len = 0;
- while (!utf8decode(&r, &len, file.buf[i++]));
- buf_ins(buf, buf_end(buf), r);
- }
-}
-
-static void utf8save(Buf* buf, FILE* file) {
- unsigned end = buf_end(buf);
- for (unsigned i = 0; i < end; i++)
- fputrune(buf_get(buf, i), file);
-}
-
-static void binload(Buf* buf, FMap file) {
- for (size_t i = 0; i < file.len; i++)
- buf_ins(buf, buf_end(buf), file.buf[i]);
-}
-
-static void binsave(Buf* buf, FILE* file) {
- unsigned end = buf_end(buf);
- for (unsigned i = 0; i < end; i++)
- fputc((int)buf_get(buf, i), file);
-}
-
void buf_load(Buf* buf, char* path) {
buf->insert_mode = true;
if (!strcmp(path,"-")) {
type = Utf8Valid[(int)buf[i]];
return type;
}
+
+void binload(Buf* buf, FMap file) {
+ for (size_t i = 0; i < file.len; i++)
+ buf_ins(buf, buf_end(buf), file.buf[i]);
+}
+
+void binsave(Buf* buf, FILE* file) {
+ unsigned end = buf_end(buf);
+ for (unsigned i = 0; i < end; i++)
+ fputc((int)buf_get(buf, i), file);
+}
#include <stdarg.h>
#include <string.h>
-/* Charset Handling
+/* Utility Functions
+ *****************************************************************************/
+typedef struct {
+ uint8_t* buf; /* memory mapped byte buffer */
+ size_t len; /* length of the buffer */
+} FMap;
+
+FMap fmap(char* path);
+void funmap(FMap file);
+void die(const char* fmt, ...);
+uint32_t getmillis(void);
+
+/* Unicode Handling
*****************************************************************************/
enum {
UTF_MAX = 6u, /* maximum number of bytes that make up a rune */
/* Represents a unicode code point */
typedef uint32_t Rune;
-enum {
- BINARY = 0,
- UTF_8,
- UTF_16BE,
- UTF_16LE,
- UTF_32BE,
- UTF_32LE,
-};
-
-int charset(const uint8_t* buf, size_t len);
size_t utf8encode(char str[UTF_MAX], Rune rune);
bool utf8decode(Rune* rune, size_t* length, int byte);
Rune fgetrune(FILE* f);
void fputrune(Rune rune, FILE* f);
+/* Buffer management functions
+ *****************************************************************************/
+typedef struct buf {
+ char* path; /* the path to the open file */
+ int charset; /* the character set of the buffer */
+ bool insert_mode; /* tracks current mode */
+ bool modified; /* tracks whether the buffer has been modified */
+ size_t bufsize; /* size of the buffer in runes */
+ Rune* bufstart; /* start of the data buffer */
+ Rune* bufend; /* end of the data buffer */
+ Rune* gapstart; /* start of the gap */
+ Rune* gapend; /* end of the gap */
+} Buf;
+
+void buf_load(Buf* buf, char* path);
+void buf_save(Buf* buf);
+void buf_init(Buf* buf);
+void buf_clr(Buf* buf);
+void buf_del(Buf* buf, unsigned pos);
+void buf_ins(Buf* buf, unsigned pos, Rune);
+Rune buf_get(Buf* buf, unsigned pos);
+unsigned buf_bol(Buf* buf, unsigned pos);
+unsigned buf_eol(Buf* buf, unsigned pos);
+unsigned buf_end(Buf* buf);
+unsigned buf_byrune(Buf* buf, unsigned pos, int count);
+unsigned buf_byline(Buf* buf, unsigned pos, int count);
+unsigned buf_getcol(Buf* buf, unsigned pos);
+unsigned buf_setcol(Buf* buf, unsigned pos, unsigned col);
+
+/* Charset Handling
+ *****************************************************************************/
+enum {
+ BINARY = 0, /* binary encoded file */
+ UTF_8, /* UTF-8 encoded file */
+ UTF_16BE, /* UTF-16 encoding, big-endian */
+ UTF_16LE, /* UTF-16 encoding, little-endian */
+ UTF_32BE, /* UTF-32 encoding, big-endian */
+ UTF_32LE, /* UTF-32 encoding, little-endian */
+};
+
+int charset(const uint8_t* buf, size_t len);
+void utf8load(Buf* buf, FMap file);
+void utf8save(Buf* buf, FILE* file);
+void binload(Buf* buf, FMap file);
+void binsave(Buf* buf, FILE* file);
+
/* Input Handling
*****************************************************************************/
/* key definitions */
void handle_key(Rune key);
void handle_mouse(MouseEvent* mevnt);
-/* Buffer management functions
- *****************************************************************************/
-typedef struct buf {
- char* path; /* the path to the open file */
- int charset; /* the character set of the buffer */
- bool insert_mode; /* tracks current mode */
- bool modified; /* tracks whether the buffer has been modified */
- size_t bufsize; /* size of the buffer in runes */
- Rune* bufstart; /* start of the data buffer */
- Rune* bufend; /* end of the data buffer */
- Rune* gapstart; /* start of the gap */
- Rune* gapend; /* end of the gap */
-} Buf;
-
-void buf_load(Buf* buf, char* path);
-void buf_save(Buf* buf);
-void buf_init(Buf* buf);
-void buf_clr(Buf* buf);
-void buf_del(Buf* buf, unsigned pos);
-void buf_ins(Buf* buf, unsigned pos, Rune);
-Rune buf_get(Buf* buf, unsigned pos);
-unsigned buf_bol(Buf* buf, unsigned pos);
-unsigned buf_eol(Buf* buf, unsigned pos);
-unsigned buf_end(Buf* buf);
-unsigned buf_byrune(Buf* buf, unsigned pos, int count);
-unsigned buf_byline(Buf* buf, unsigned pos, int count);
-unsigned buf_getcol(Buf* buf, unsigned pos);
-unsigned buf_setcol(Buf* buf, unsigned pos, unsigned col);
-
-
/* Screen management functions
*****************************************************************************/
typedef struct {
Rune screen_getcell(unsigned row, unsigned col);
void screen_status(char* fmt, ...);
-/* Miscellaneous Functions
- *****************************************************************************/
-void die(const char* fmt, ...);
-
/* Color Scheme Handling
*****************************************************************************/
/* color indexes for the colorscheme */
}
static void vi_keys(Rune key) {
- static unsigned count = 0;
(void)key;
}
-
#include "edit.h"
-#define _GNU_SOURCE
-#include <time.h>
-#include <sys/time.h>
-
-#ifdef __MACH__
-#define CLOCK_MONOTONIC 0
-// clock_gettime is not implemented on OSX
-int clock_gettime(int id, struct timespec* t) {
- (void)id;
- struct timeval now;
- int rv = gettimeofday(&now, NULL);
- if (rv) return rv;
- t->tv_sec = now.tv_sec;
- t->tv_nsec = now.tv_usec * 1000;
- return 0;
-}
-#endif
-
-uint32_t getmillis(void) {
- struct timespec time;
- clock_gettime(CLOCK_MONOTONIC, &time);
- return ((time.tv_sec * 1000) + (time.tv_nsec / 1000000));
-}
-
-/*****************************************************************************/
-
void unused(MouseEvent* mevnt) {
(void)mevnt;
}
unsigned TargetCol;
enum ColorScheme ColorBase;
-void die(const char* m, ...) {
- (void)m;
-}
-
int main(int argc, char** argv) {
atf_init(argc,argv);
RUN_EXTERN_TEST_SUITE(BufferTests);
void fputrune(Rune rune, FILE* f) {
char utf[UTF_MAX] = {0};
- utf8encode(utf, rune);
- fprintf(f, "%s", utf);
+ size_t n = utf8encode(utf, rune);
+ fwrite(utf, 1, n, f);
}
+
+void utf8load(Buf* buf, FMap file) {
+ for (size_t i = 0; i < file.len;) {
+ Rune r = 0;
+ size_t len = 0;
+ while (!utf8decode(&r, &len, file.buf[i++]));
+ buf_ins(buf, buf_end(buf), r);
+ }
+}
+
+void utf8save(Buf* buf, FILE* file) {
+ unsigned end = buf_end(buf);
+ for (unsigned i = 0; i < end; i++)
+ fputrune(buf_get(buf, i), file);
+}
+
--- /dev/null
+#include "edit.h"
+
+#define _GNU_SOURCE
+#include <time.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifdef __MACH__
+#define CLOCK_MONOTONIC 0
+// clock_gettime is not implemented on OSX
+int clock_gettime(int id, struct timespec* t) {
+ (void)id;
+ struct timeval now;
+ int rv = gettimeofday(&now, NULL);
+ if (rv) return rv;
+ t->tv_sec = now.tv_sec;
+ t->tv_nsec = now.tv_usec * 1000;
+ return 0;
+}
+#endif
+
+uint32_t getmillis(void) {
+ struct timespec time;
+ clock_gettime(CLOCK_MONOTONIC, &time);
+ return ((time.tv_sec * 1000) + (time.tv_nsec / 1000000));
+}
+
+void die(const char* msgfmt, ...) {
+ va_list args;
+ va_start(args, msgfmt);
+ fprintf(stderr, "Error: ");
+ vfprintf(stderr, msgfmt, args);
+ fprintf(stderr, "\n");
+ va_end(args);
+ exit(EXIT_FAILURE);
+}
+
+FMap fmap(char* path) {
+ int fd;
+ FMap file = { .buf = NULL, .len = 0 };
+ struct stat sb;
+ if (((fd = open(path, O_RDONLY, 0)) < 0) ||
+ (fstat(fd, &sb) < 0) ||
+ (sb.st_size == 0))
+ return file;
+ file.buf = (uint8_t*)mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ file.len = sb.st_size;
+ if (file.buf == MAP_FAILED)
+ die("memory mapping of file failed");
+ return file;
+}
+
+void funmap(FMap file) {
+ if (file.buf)
+ munmap(file.buf, file.len);
+}
XIC xic;
XIM xim;
} X;
-
struct {
struct {
int height;
/*****************************************************************************/
-void die(const char* msgfmt, ...) {
- va_list args;
- va_start(args, msgfmt);
- fprintf(stderr, "Error: ");
- vfprintf(stderr, msgfmt, args);
- fprintf(stderr, "\n");
- va_end(args);
- exit(EXIT_FAILURE);
-}
-
static XftColor xftcolor(enum ColorId cid) {
Color c = Palette[cid][ColorBase];
XftColor xc;