all: build
config:
- ./rscons configure
+ ./rscons $(RFLAGS) configure
build:
- ./rscons build
+ ./rscons $(RFLAGS) build
clean:
- ./rscons clean
+ ./rscons $(RFLAGS) clean
distclean:
- ./rscons distclean
+ ./rscons $(RFLAGS) distclean
install:
- ./rscons install
+ ./rscons $(RFLAGS) install
uninstall:
- ./rscons uninstall
+ ./rscons $(RFLAGS) uninstall
env["CPPPATH"] += %w[. inc]
env["LIBPATH"] += %w[.]
-# env["CFLAGS"] << "-DNDEBUG"
+# env["CPPFLAGS"] << "-DNDEBUG"
# # Enable Sanitizers
# env["CFLAGS"] += ["-g", "-fsanitize=undefined,address"]
# env["LDFLAGS"] += ["-g", "-fsanitize=undefined,address"]
-
+#
# # Enable Coverage
# env["CFLAGS"] += ["-g", "-O0", "--coverage"]
# env["LDFLAGS"] += ["-g", "-O0", "--coverage"]
declare -a objects
declare -a libpaths
compile=false
+lintonly=false
runtime='
#define _POSIX_C_SOURCE 200809L
#define _XOPEN_SOURCE 700
-L*) # Add libpaths to the search list
libpaths+=("${i#-L}") ;;
- -c|-E) # Mark this as compilation/preprocess only
+ -c|-E) # Mark this as compilation/preprocess only run
compile=true ;;
+ --lint) # Mark this as lint only run
+ lintonly=true ;;
+
esac
done
# scan all identifiers for prohibited symbols
!incomment && /^\s*[^#]/ {
control = 0
+ gsub(/(TEST|PROPERTY|TEST_SUITE)\(.*\)/, "") # ignore test functions
paren = match(\$0, /\(/)
semi = match(\$0, /;\s*$/)
- gsub(/"(\\\\"|[^"])*"/, "") # ignore string literals
- gsub(/'(\\\\'|[^'])'/, "") # ignore char literals
- sub(/\/\/.*$/, "") # ignore line comments
- gsub(/\/\*.*\*\//, "") # ignore block comments on single line
- incomment = sub(/\/\*.*$/, "") # ignore block comment starts
- sub(/^.*\*\//, "") # ignore block comment stops
+ gsub(/"(\\\\"|[^"])*"/, "") # ignore string literals
+ gsub(/'(\\\\'|[^'])'/, "") # ignore char literals
+ sub(/\/\/.*$/, "") # ignore line comments
+ gsub(/\/\*.*\*\//, "") # ignore block comments on single line
+ incomment = sub(/\/\*.*$/, "") # ignore block comment starts
+ sub(/^.*\*\//, "") # ignore block comment stops
+
+# print "'" \$1 "'"
+
opening = gsub(/{/, "")
closing = gsub(/}/, "")
get_syms(\$0, M);
nreturns = 0
if (opening)
{
- warn("function braces should be on their own lines")
+ error("function braces should be on their own lines")
}
}
{
error("reached EOF with open block");
}
-# exit code
+ exit code
}
EOS
)
if ! gawk "$script" "${sources[@]}"; then
exit 1
fi
+ if $lintonly; then
+ exit 0;
+ fi
fi
# if we're compiling, generate the header, compile, and exit
{
FILE* f = (DumpPath ? fopen(DumpPath, "w") : stderr);
fprintf(f, "%s\n\n", msg);
- if (DumpFn) DumpFn(f);
+ if (DumpFn)
+ {
+ DumpFn(f);
+ }
fprintf(f, "\n%s\n", msg);
fclose(f);
_Exit(1);
#include <draw.h>
#include "config.h"
-void draw_rect(XConf* x, int color, int posx, int posy, int width, int height) {
+void draw_rect(XConf* x, int color, int posx, int posy, int width, int height)
+{
x11_draw_rect(x, Palette[color], posx, posy, width, height);
}
-void draw_statbox(XConf* x, int status) {
+void draw_statbox(XConf* x, int status)
+{
draw_rect(x, VerBdr, ScrollWidth, 0, 1, x->height/4);
switch (status) {
case NORMAL: draw_rect(x, TagsBg, 0, 0, ScrollWidth, x->height/4); break;
draw_rect(x, WinBdr, 0, 0, 1, x->height/4);
}
-int draw_hrule(XConf* x, drawcsr* csr) {
+int draw_hrule(XConf* x, drawcsr* csr)
+{
draw_rect(x, HorBdr, 0, csr->y + 1, x->width, 1);
csr->y += 2;
return (csr->y - 2);
}
-void draw_view(XConf* x, View* view, XftFont* font, size_t nrows, drawcsr* csr, int bg, int fg, int sel, bool csrsync) {
+void draw_view(XConf* x, View* view, XftFont* font, size_t nrows, drawcsr* csr, int bg, int fg, int sel, bool csrsync)
+{
int nspecs = 0;
XftGlyphSpec* specs = NULL;
size_t fheight = font->height;
view_resize(view, (csr->w - csr->x), nrows);
view_update(view);
draw_rect(x, bg, csr->x, csr->y, csr->w, ((nrows + 1) * fheight) + 9);
- for (size_t i = 0; i < nrows; i++) {
+ for (size_t i = 0; i < nrows; i++)
+ {
Row* row = view_getrow(view, i + view->index);
size_t posx = (csr->x + 2), y = (csr->y + 2 + (i * fheight));
- for (size_t i = 0; i < row->len; i++) {
+ for (size_t i = 0; i < row->len; i++)
+ {
int rune = row->cols[i].rune;
if (rune == '\r' || rune == '\n' || rune == '\t')
rune = ' ';
draw_rect(x, sel, posx, y, row->cols[i].width, fheight);
if (row->cols[i].off == view->buffer.selection.end)
csr_drawn = draw_csr(x, view, fg, fheight, posx, y, csr_drawn);
- if (csrsync && row->cols[i].off == view->buffer.selection.beg) {
+ if (csrsync && row->cols[i].off == view->buffer.selection.beg)
+ {
XWarpPointer(x->display, None, x->self, 0, 0, x->width, x->height, posx + row->cols[i].width/2, y + fheight*3/4);
csrsync = false;
}
free(specs);
}
-bool draw_csr(XConf* x, View* view, int fg, size_t fheight, int posx, int posy, bool csrdrawn) {
- if (!csrdrawn && !view_selsize(view)) {
+bool draw_csr(XConf* x, View* view, int fg, size_t fheight, int posx, int posy, bool csrdrawn)
+{
+ if (!csrdrawn && !view_selsize(view))
+ {
draw_rect(x, fg, posx-1, posy, 3, 3);
draw_rect(x, fg, posx, posy, 1, fheight);
draw_rect(x, fg, posx-1, posy+fheight-3, 3, 3);
return csrdrawn;
}
-void draw_scroll(XConf* x, drawcsr* csr, View* view, int divider) {
+void draw_scroll(XConf* x, drawcsr* csr, View* view, int divider)
+{
size_t bend = buf_end(&(view->buffer));
if (bend == 0) bend = 1;
if (!view->rows || !view->nrows) return;
static struct pollfd JobFds[MAX_JOBS];
static Job* JobList = NULL;
-static void pipe_read(Job* job) {
+static void pipe_read(Job* job)
+{
struct PipeData* pipedata = job->data;
char buffer[16385];
errno = 0;
long nread = read(job->fd, buffer, sizeof(buffer)-1);
- if (nread <= 0) {
+ if (nread <= 0)
+ {
job->readfn = NULL;
buf_logstop(&pipedata->dest->buffer);
if (view_selsize(pipedata->dest))
view_delete(pipedata->dest, RIGHT, false);
else
view_selprev(pipedata->dest);
- } else if (nread > 0) {
+ }
+ else if (nread > 0)
+ {
buffer[nread] = '\0';
buf_logstart(&pipedata->dest->buffer);
view_putstr(pipedata->dest, buffer);
}
}
-static void pipe_write(Job* job) {
+static void pipe_write(Job* job)
+{
struct PipeData* pipedata = job->data;
char* chunk = pipedata->data + pipedata->nwrite;
errno = 0;
long nwrite = write(job->fd, chunk, pipedata->ndata);
- if (nwrite >= 0) {
+ if (nwrite >= 0)
+ {
pipedata->ndata -= nwrite;
pipedata->nwrite += nwrite;
}
- if ((nwrite < 0 && errno != EWOULDBLOCK) || pipedata->ndata <= 0) {
+ if ((nwrite < 0 && errno != EWOULDBLOCK) || pipedata->ndata <= 0)
+ {
free(pipedata->data);
pipedata->data = NULL;
job->writefn = NULL;
}
}
-static Job* job_remove(Job* list, Job* job) {
- if (list == job) {
- return job->next;
- } else {
+static Job* job_remove(Job* list, Job* job)
+{
+ Job* ret = NULL;
+ if (list == job)
+ {
+ ret = job->next;
+ }
+ else
+ {
list->next = job_remove(list->next, job);
- return list;
+ ret = list;
}
+ return ret;
}
-static void job_finish(Job* job) {
+static void job_finish(Job* job)
+{
JobList = job_remove(JobList, job);
close(job->fd);
free(job->data);
free(job);
}
-static void job_process(int fd, int events) {
+static void job_process(int fd, int events)
+{
Job* job = JobList; // Get job by fd
while (job && job->fd != fd)
job = job->next;
job_finish(job);
}
-static int job_exec(char** cmd, int* p_pid) {
+static int job_exec(char** cmd, int* p_pid)
+{
int pid, fds[2];
/* create the sockets */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0)
return -1;
/* create the process */
- if ((pid = fork()) < 0) {
+ if ((pid = fork()) < 0)
+ {
close(fds[0]), close(fds[1]), fds[0] = -1;
- } else if (0 == pid) {
+ }
+ else if (0 == pid)
+ {
/* redirect child process's io to the pipes */
- if ((dup2(fds[1], 0) < 0) || (dup2(fds[1], 1) < 0) || (dup2(fds[1], 2) < 0)) {
+ if ((dup2(fds[1], 0) < 0) || (dup2(fds[1], 1) < 0) || (dup2(fds[1], 2) < 0))
+ {
perror("failed to pipe");
exit(1);
}
/* execute the process */
close(fds[0]);
exit(execvp(cmd[0], cmd));
- } else {
+ }
+ else
+ {
close(fds[1]);
fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL, 0) | O_NONBLOCK);
}
return fds[0];
}
-Job* job_list(void) {
+Job* job_list(void)
+{
return JobList;
}
-void job_kill(Job* job) {
+void job_kill(Job* job)
+{
job->readfn = NULL;
job->writefn = NULL;
}
-bool job_poll(int ms) {
+bool job_poll(int ms)
+{
int njobs = 0;
/* Add jobs from the job list */
- for (Job *job = JobList; job && njobs < MAX_JOBS; job = job->next) {
+ for (Job *job = JobList; job && njobs < MAX_JOBS; job = job->next)
+ {
JobFds[njobs].fd = job->fd;
JobFds[njobs].events = 0;
JobFds[njobs].revents = 0;
return (ret > 0);
}
-void job_spawn(int fd, jobfn_t readfn, jobfn_t writefn, void* data) {
+void job_spawn(int fd, jobfn_t readfn, jobfn_t writefn, void* data)
+{
Job *job = calloc(1, sizeof(Job));
job->fd = fd;
job->readfn = readfn;
JobList = job;
}
-void job_start(char** cmd, char* data, size_t ndata, View* dest) {
+void job_start(char** cmd, char* data, size_t ndata, View* dest)
+{
int fd = job_exec(cmd, 0);
- if (fd >= 0 && (data || dest)) {
+ if (fd >= 0 && (data || dest))
+ {
struct PipeData* pipedata = NULL;
- if (data) {
+ if (data)
+ {
pipedata = calloc(1, sizeof(struct PipeData));
pipedata->data = data;
pipedata->ndata = ndata;
pipedata->dest = dest;
}
job_spawn(fd, (data ? pipe_read : NULL), (dest ? pipe_write : NULL), pipedata);
- } else {
+ }
+ else
+ {
close(fd);
}
}
-int job_run(char** cmd) {
+int job_run(char** cmd)
+{
int pid = -1, status = 0;
job_exec(cmd, &pid);
- do {
+ do
+ {
waitpid(pid, &status, WUNTRACED|WCONTINUED);
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
return WEXITSTATUS(status);
}
-void job_readfd(int fd, View* view) {
+void job_readfd(int fd, View* view)
+{
struct PipeData* pipedata = calloc(1, sizeof(struct PipeData));
pipedata->dest = view;
job_spawn(fd, pipe_read, NULL, pipedata);
#include <x11.h>
#include <edit.h>
#include <win.h>
+#include <dbc.h>
#include "config.h"
-#define PRESSED(mods, btn) \
- ((mods & (1 << (btn + 7))) == (1 << (btn + 7)))
+static inline int PRESSED(int mods, int btn)
+{
+ return ((mods & (1 << (btn + 7))) == (1 << (btn + 7)));
+}
static int ExecRequest = 0;
-static int mouse_left(bool pressed) {
+static int mouse_left(bool pressed)
+{
static int count = 0;
static Time before = 0;
- if (!pressed) return MouseActNone;
- count = ((X.now - before) <= (uint64_t)ClickTime ? count+1 : 1);
- before = X.now;
- if (PRESSED(X.mods, MouseRight)) {
- return MouseActNone;
- } else if (PRESSED(X.mods, MouseMiddle)) {
- ExecRequest = 0;
- return MouseActExecArg;
- } else if (count == 1) {
- return MouseActSel;
- } else if (count == 2) {
- return MouseActSelCtx;
- } else if (count == 3) {
- return MouseActSelWord;
- } else {
- return MouseActNone;
+ int ret = MouseActNone;
+ if (pressed)
+ {
+ count = ((X.now - before) <= (uint64_t)ClickTime ? count+1 : 1);
+ before = X.now;
+ if (PRESSED(X.mods, MouseRight))
+ {
+ ret = MouseActNone;
+ }
+ else if (PRESSED(X.mods, MouseMiddle))
+ {
+ ExecRequest = 0;
+ ret = MouseActExecArg;
+ }
+ else if (count == 1)
+ {
+ ret = MouseActSel;
+ }
+ else if (count == 2)
+ {
+ ret = MouseActSelCtx;
+ }
+ else if (count == 3)
+ {
+ ret = MouseActSelWord;
+ }
+ else
+ {
+ ret = MouseActNone;
+ }
}
+ return ret;
}
-static int mouse_middle(bool pressed) {
- if (pressed) { ExecRequest = 1; return MouseActNone; }
- if (PRESSED(X.mods, MouseLeft)) {
- return MouseActCut;
- } else if (ExecRequest) {
- return MouseActExec;
- } else {
- return MouseActNone;
+static int mouse_middle(bool pressed)
+{
+ int ret;
+ if (pressed)
+ {
+ ExecRequest = 1;
+ ret = MouseActNone;
+ }
+ else if (PRESSED(X.mods, MouseLeft))
+ {
+ ret = MouseActCut;
+ }
+ else if (ExecRequest)
+ {
+ ret = MouseActExec;
+ }
+ else
+ {
+ ret = MouseActNone;
}
+ return ret;
}
-static int mouse_right(bool pressed) {
- if (pressed) return MouseActNone;
- if (PRESSED(X.mods, MouseLeft)) {
- return MouseActPaste;
- } else {
- return MouseActFetch;
+static int mouse_right(bool pressed)
+{
+ int ret;
+ if (pressed)
+ {
+ ret = MouseActNone;
}
+ else if (PRESSED(X.mods, MouseLeft))
+ {
+ ret = MouseActPaste;
+ }
+ else
+ {
+ ret = MouseActFetch;
+ }
+ return ret;
}
-int process_mouse(int btn, bool pressed) {
- switch(btn) {
- case MouseLeft: return mouse_left(pressed);
- case MouseMiddle: return mouse_middle(pressed);
- case MouseRight: return mouse_right(pressed);
- case MouseWheelUp: return (pressed ? MouseActScrollUp : MouseActNone);
- case MouseWheelDn: return (pressed ? MouseActScrollDn : MouseActNone);
- }
- return MouseActNone;
+int process_mouse(int btn, bool pressed)
+{
+ require(btn <= MouseWheelDn);
+ int ret = MouseActNone;
+ switch(btn)
+ {
+ case MouseLeft: ret = mouse_left(pressed); break;
+ case MouseMiddle: ret = mouse_middle(pressed); break;
+ case MouseRight: ret = mouse_right(pressed); break;
+ case MouseWheelUp: ret = (pressed ? MouseActScrollUp : MouseActNone); break;
+ case MouseWheelDn: ret = (pressed ? MouseActScrollDn : MouseActNone); break;
+ }
+ return ret;
}
static const uint8_t UTF8_SeqMask[] = { 0x00, 0xFF, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00 };
static const uint8_t UTF8_SeqLens[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00 };
-static bool runevalid(Rune val) {
+static bool runevalid(Rune val)
+{
return (val <= RUNE_MAX)
&& ((val & 0xFFFE) != 0xFFFE)
&& ((val < 0xD800) || (val > 0xDFFF))
&& ((val < 0xFDD0) || (val > 0xFDEF));
}
-static size_t runelen(Rune rune) {
+static size_t runelen(Rune rune)
+{
+ size_t ret;
if(!runevalid(rune))
- return 0;
+ {
+ ret = 0;
+ }
else if(rune <= 0x7F)
- return 1;
+ {
+ ret = 1;
+ }
else if(rune <= 0x07FF)
- return 2;
+ {
+ ret = 2;
+ }
else if(rune <= 0xFFFF)
- return 3;
+ {
+ ret = 3;
+ }
else
- return 4;
+ {
+ ret = 4;
+ }
+ return ret;
}
-static uint8_t utfseq(uint8_t byte) {
+static uint8_t utfseq(uint8_t byte)
+{
+ uint8_t ret = 0;
for (int i = 1; i < 8; i++)
+ {
if ((byte & UTF8_SeqBits[i]) == UTF8_SeqBits[i-1])
- return UTF8_SeqLens[i-1];
- return 0;
+ {
+ ret = UTF8_SeqLens[i-1];
+ break;
+ }
+ }
+ return ret;
}
-size_t utf8encode(char str[UTF_MAX], Rune rune) {
+size_t utf8encode(char str[UTF_MAX], Rune rune)
+{
size_t len = runelen(rune);
str[0] = (len == 1 ? 0x00 : UTF8_SeqBits[len])
| (UTF8_SeqMask[len] & (rune >> (6 * (len-1))));
return len;
}
-bool utf8decode(Rune* rune, size_t* length, int byte) {
+bool utf8decode(Rune* rune, size_t* length, int byte)
+{
/* Handle the start of a new rune */
if (*length == 0) {
/* If we were fed in an EOF as a start byte, handle it here */
return ((*length == 0) || (*rune == RUNE_ERR));
}
-int runewidth(unsigned col, Rune r) {
- size_t tabwidth = TabWidth;
- if (r == '\t') return (tabwidth - (col % tabwidth));
- int width = wcwidth(r);
- if (width < 0) width = 1;
+int runewidth(unsigned col, Rune r)
+{
+ int width;
+ if (r == '\t')
+ {
+ width = (TabWidth - (col % TabWidth));
+ }
+ else
+ {
+ width = wcwidth(r);
+ if (width < 0) width = 1;
+ }
return width;
}
-bool risword(Rune r) {
+bool risword(Rune r)
+{
return (r < 127 && (isalnum(r) || r == '_' || r == '+' || r == '-'));
}
-bool rissigil(Rune r) {
+bool rissigil(Rune r)
+{
return (r == ':' || r == '!' || r == '|' || r == '>' || r == '<');
}
-bool risfile(Rune r) {
+bool risfile(Rune r)
+{
return (risword(r) || r == '/' || r == '.' || r == ':' || r == '-' || r == '~');
}
-bool riscmd(Rune r) {
+bool riscmd(Rune r)
+{
return (risword(r) || rissigil(r));
}
-bool risblank(Rune r) {
+bool risblank(Rune r)
+{
return (r == ' ' || r == '\t' || r == '\n' || r == '\r');
}
-bool risbigword(Rune r) {
+bool risbigword(Rune r)
+{
return !risblank(r);
}
exit(1);
}
+static void edit_file(char* file, int line_num)
+{
+ char* path = realpath(file, NULL);
+ if (!path) path = strdup(file); /* if file doesnt exist, use the original name */
+ if (!strcmp("-", path))
+ {
+ job_readfd(STDIN_FILENO, win_view(EDIT));
+ }
+ else
+ {
+ view_init(win_view(EDIT), path);
+ win_setln(line_num);
+ win_title(path);
+ win_prop_set("FILE", "file", path);
+ }
+ free(path);
+}
+
int main(int argc, char** argv)
{
long int line_num = 0;
/* if we still have args left we're going to open it in this instance */
if (*argv)
{
- char* path = realpath(*argv, NULL);
- if (!path) path = strdup(*argv); /* if file doesnt exist, use the original name */
- if (!strcmp("-", path))
- {
- job_readfd(STDIN_FILENO, win_view(EDIT));
- }
- else
- {
- view_init(win_view(EDIT), path);
- win_setln(line_num);
- win_title(path);
- win_prop_set("FILE", "file", path);
- }
- free(path);
+ edit_file(*argv, line_num);
}
/* set host name property */
if (!gethostname(host, sizeof(host)))
win_prop_set("HOST", "host", host);
- /* check if we should embed in a parent */
- char* winid = getenv("TIDE_PARENT");
- if (winid)
- {
- XReparentWindow(X.display, X.self, strtoul(winid, 0, 0), 0, 0);
- XFlush(X.display);
- }
-
/* now create the window and start the event loop */
#ifndef TEST
x11_show(&X);
return (!strcmp(str, Output));
}
-void setup_buffer(void)
+static void setup_buffer(void)
{
free(Output), Output = NULL;
buf_init(&TestBuf);
return 1;
}
-void show_codepoint(QCValue* val)
+static void show_codepoint(QCValue* val)
{
char buf[UTF_MAX+1] = {0};
utf8encode(buf, val->data[0]);
printf("0x%08x (%s)\n", (int)(val->data[0]), buf);
}
-QCValue* GenCodepoint(void)
+static QCValue* GenCodepoint(void)
{
long cp = 0;
do { cp = qcrandr(32,0x10FFFF); }
#include <utf.h>
#include <edit.h>
-TEST_SUITE(Utf8Tests) {
+TEST_SUITE(Utf8Tests)
+{
}