Commits

Evan Gates  committed 12a8b8a

add draw.bash, linked_list_append.c, start of sed.c

  • Participants
  • Parent commits 6e683ed

Comments (0)

Files changed (4)

+abs() {
+    local _d=$1
+    printf %d $((_d >= 0 ? _d : -_d))
+}
+
+put_point() {
+    local _canvas _xres _yres
+    local _x _y _i _c
+    _canvas=$1 _x=$2 _y=$3
+    _c=$4
+    ((_xres = $_canvas[0], _yres = $_canvas[1]))
+    ((_x < 0 || _x >= _xres || _y < 0 || _y >= _yres)) && return
+    ((_i = _y * _xres + _x))
+    printf -v "$_canvas[_i + 2]" %d "$_c"
+}
+
+draw_line() {
+    echo draw_line >&2
+    local _canvas _xres _yres _c
+    local _x1 _y1 _x2 _y2 _dx _dy _sx _sy _e1 _e2
+    _canvas=$1
+    ((_xres = $_canvas[0], _yres = $_canvas[1]))
+    _x1=$2 _y1=$3
+    _x2=$4 _y2=$5
+    _c=$6
+
+    ((_dx = $(abs $((_x2 - _x1))),
+      _dy = $(abs $((_y2 - _y1))),
+      _sx = _x1 < _x2 ? 1 : -1   ,
+      _sy = _y1 < _y2 ? 1 : -1   ,
+      _e1 = _dx - _dy            ))
+
+    while :; do
+        put_point "$_canvas" "$_x1" "$_y1" "$_c"
+        ((_x1 == _x2 && _y1 == _y2)) && break
+        ((_e2 = 2 * _e1))
+        ((_e1 > -_dy && (_e1 -= _dy, _x1 += _sx)))
+        ((_e2 <  _dx && (_e1 += _dx, _y1 += _sy)))
+    done
+}
+
+draw_circle() {
+    echo draw_circle >&2
+    local _canvas _xres _yres _c
+    local _x _y _r _x0 _y0 _e
+    _canvas=$1 _x0=$2 _y0=$3 _r=$4 _c=$5
+    ((_x = _r, _y = 0, _e = 1 - _x))
+
+    while ((_x >= _y)); do
+        put_point "$_canvas" $((_x0 + _x)) $((_y0 + _y)) "$_c"
+        put_point "$_canvas" $((_x0 - _x)) $((_y0 + _y)) "$_c"
+        put_point "$_canvas" $((_x0 + _x)) $((_y0 - _y)) "$_c"
+        put_point "$_canvas" $((_x0 - _x)) $((_y0 - _y)) "$_c"
+        put_point "$_canvas" $((_x0 + _y)) $((_y0 + _x)) "$_c"
+        put_point "$_canvas" $((_x0 - _y)) $((_y0 + _x)) "$_c"
+        put_point "$_canvas" $((_x0 + _y)) $((_y0 - _x)) "$_c"
+        put_point "$_canvas" $((_x0 - _y)) $((_y0 - _x)) "$_c"
+        ((_y++))
+        if ((_e < 0)); then
+            ((_e += 2 * _y + 1));
+        else
+            ((--_x, _e += 2 * (_y - _x + 1)))
+        fi
+    done
+}
+
+draw_canvas() {
+    echo draw_canvas >&2
+    local _canvas _xres _yres _i _c
+    _canvas=$1
+    ((_xres = $_canvas[0], _yres = $_canvas[1]))
+
+    printf "P3\n%d %d\n255\n" "$_xres" "$_yres"
+
+    for ((_i = 0; _i < _xres * _yres; _i++)); do
+        ((_c = $_canvas[_i + 2]))
+        printf '%d ' $((_c >> 16 & 0xff)) $((_c >> 8 & 0xff)) $((_c & 0xff))
+    done
+}
+
+make_canvas() {
+    echo make_canvas >&2
+    local _canvas _xres _yres _c
+    _canvas=$1 _xres=$2 _yres=$3 _color=$5
+
+    (($_canvas[0] = _xres, $_canvas[1] = _yres))
+    for ((_i = 0; _i < _xres * _yres; _i++)); do
+        printf -v "$_canvas[_i + 2]" %d "$_c"
+    done
+}
+
+example() {
+    local canvas
+    #                                    rrggbb
+    make_canvas canvas 500 500         0x000000
+    draw_line   canvas   0   0 499 499 0xffffff
+    draw_line   canvas   0 200 499 200 0xff0000
+    draw_line   canvas 450  50 120 400 0x00ff00
+    draw_line   canvas 300 490 300   0 0x0000ff
+    draw_line   canvas  50 450 200  70 0xffff00
+    draw_circle canvas 250 250 150     0xff00ff
+    draw_circle canvas   0   0 250     0x00ffff
+
+    draw_canvas canvas > example.ppm
+    display example.ppm
+    rm example.ppm
+}

File raytrace/raytrace.c

 typedef struct {
     Shape  shape;
     Color  color;
-    int    (*intersect)(Shape, Ray* );
+    int    (*intersect)(Shape, Ray*);
 } Object;
 
 // TODO: use objects as lights

File sanity/linked_list_append.c

+#include <stdio.h>
+#include <stdlib.h>
+
+
+typedef struct node_t Node;
+struct node_t {
+    Node *next;
+    int   val;
+};
+
+void append(Node **head, Node *n)
+{
+    Node **p;
+    for (p = head; *p; p = &(*p)->next)
+        ;
+    *p = n;
+}
+
+void print_all(Node *n)
+{
+    while (n) {
+        printf("%d,",n->val);
+        n = n->next;
+    }
+    printf("\n");
+}
+
+Node *make_node(int val)
+{
+    Node *n = calloc(1, sizeof(Node));
+    n->val = val;
+    return n;
+}
+
+
+int main(void)
+{
+    Node *head = NULL;
+
+    print_all(head);
+
+    append(&head, make_node(1));
+    print_all(head);
+
+    append(&head, make_node(2));
+    print_all(head);
+
+    append(&head, make_node(3));
+    print_all(head);
+
+    return 0;
+}
+#define _POSIX_C_SOURCE 200809L
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <regex.h>
+#include <stdlib.h>
+
+//FIXME: just write own strlcat/strlcpy to stay POSIX compliant
+#include <bsd/string.h>
+
+enum {
+    CONTINUE, // continue execution
+    NEW_LINE, // read new line, continue current cycle
+    APP_LINE, // append new line, continue current cycle
+    NEW_NEXT, // move to new cycle, read new line
+    OLD_NEXT, // move to new cycle, reuse pattern space
+    QUIT    , // do not start a new cycle
+};
+
+enum {
+    EVERY  =  0,
+    LAST   = -1,
+    REGEX  = -2,
+    LASTRE = -3,
+};
+// use regex unless regex is NULL
+// if line is EVERY , every line
+// if line is LAST  , $ line
+// if line is REGEX , regex
+// if line is LASTRE, last used regex
+typedef struct {
+    regex_t regex;
+    int     line;
+} Address;
+
+typedef struct {
+    Address begin;
+    Address end;
+} Range;
+
+typedef struct command_t Command;
+struct command_t {
+    Command      *next;
+    Command      *other; // }, label, ...?
+    Range         range;
+    size_t        line_number;
+    char         *text;
+    int         (*cmd_func)();
+    char          negate;
+};
+
+typedef struct sched_write_t Sched_write;
+struct sched_write_t {
+    Sched_write *next;
+    char        *text;
+    char         is_file;
+};
+
+char *prog_name;
+
+#define SPACE_BYTES 8192
+
+char   space1[SPACE_BYTES],  space2[SPACE_BYTES];
+char  *patt_space = space1, *hold_space = space2;
+
+regex_t *last_regex;
+Sched_write *sched_writes;
+Command *program, *pc, *append;
+size_t line_number;
+
+struct {
+    unsigned char no_print:1;
+    unsigned char did_sub :1;
+} flags;
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define truncating(s,l) fprintf(stderr,                            \
+    "%s: script line, %d: input line, %d: truncating %s to %d bytes\n",\
+    prog_name, pc->line_number, line_number, (s), (l))
+
+char *regex_end(char *str, char delim)
+{
+    char *p, escape;
+    for (p = str, escape = 0; *p; p++)
+        if (escape)
+            escape = 0;
+        else if (*p == '\\')
+            escape = 1;
+        else if (*p == delim)
+            break;
+}
+char *make_address(Address *addr, char *str)
+{
+    if (*str == '/' || *str == '\\') {
+        char delim, *end;
+        if (*str == '\\') {
+            str++;
+            if (*str == '\\' || *str == '\n') {
+                fprintf(stderr, "%s: script line, %d: bad address, %s\n", prog_name, pc->line_number, str);
+                return NULL;
+            }
+        }
+        delim = *str;
+        if (*++str == delim) { // empty regex
+            *addr = (Address){ NULL, LASTRE };
+        } else {
+            if (regcomp(&addr->regex, str, REG_NOSUB)) {
+                fprintf(stderr, "%s: script line, %d: bad address, %s\n", prog_name, pc->line_number, str);
+                return NULL;
+            }
+            str = p + 1;
+        }
+    }
+}
+
+FILE *file_open(char *path, char *mode)
+{
+    FILE* file = fopen(path, mode);
+    if (!file)
+        perror(prog_name);
+    return file;
+}
+
+void file_close(FILE *file)
+{
+    if (fclose(file) == EOF)
+        perror(prog_name);
+}
+
+void print(FILE *file, char *str, int only_first)
+{
+    for (char *end = strchr(str, '\n'); end; str = end + 1, end = strchr(str, '\n')) {
+        int len = end - str + 1;
+        if (len > LINE_MAX)
+            truncating("output line", LINE_MAX);
+        printf("%.*s\n", MIN(len - 1, LINE_MAX), str);
+    }
+    if (*str) {
+        if (strlen(str) > LINE_MAX)
+            truncating("output line", LINE_MAX);
+        printf("%.*s\n", LINE_MAX, str);
+    }
+}
+
+int read_line(char *buf, size_t size, FILE* file)
+{
+    size_t len;
+    if (fgets(buf, size, file) == NULL) {
+        if (ferror(file))
+            perror(prog_name);
+        return EOF;
+    }
+    len = strlen(buf);
+    if (buf[len] == '\n') {
+        buf[len] =  '\0';
+    } else {
+        truncating("intput line", size);
+        do {
+            if (fgets(buf, size, file) == NULL) {
+                if (ferror(file))
+                    perror(prog_name);
+                return EOF;
+            }
+        } while (buf[strlen(buf)] != '\n');
+    }
+    return 0;
+}
+
+int read_char(FILE* file)
+{
+    int c = fgetc(file);
+    if (c == EOF && ferror(file))
+        perror(prog_name);
+    return c;
+}
+
+void schedule_write(char *text, int is_file)
+{
+    Sched_write **p, *new = malloc(sizeof(Sched_write));
+
+    if (!p) {
+        perror(prog_name);
+        return;
+    }
+    *new = (Sched_write){ NULL, text, is_file };
+
+    for (p = &sched_writes; *p; p = &(*p)->next)
+        ;
+    *p = new;
+}
+
+void do_sched_writes(void)
+{
+    for (Sched_write *p = sched_writes; p; p = p->next) {
+        if (p->is_file) {
+            char line[LINE_MAX];
+            FILE *file = file_open(p->text, "r");
+            if (!file)
+                continue;
+            while (read_line(line, LINE_MAX, file) != EOF)
+                print(stdout, line, 0);
+            file_close(file);
+        } else {
+            print(stdout, p->text, 0);
+        }
+    }
+}
+
+int cmd_a(Command *cmd)
+{
+    schedule_write(cmd->text, 0);
+    return CONTINUE;
+}
+
+int cmd_b(Command *cmd)
+{
+    pc = cmd->other;
+    return CONTINUE;
+}
+
+int cmd_c(Command *cmd)
+{
+    *patt_space = '\0';
+    print(stdout, cmd->text, 0);
+}
+
+int cmd_d(Command *cmd)
+{
+    return NEW_NEXT;
+}
+
+int cmd_D(Command *cmd)
+{
+    char *n = strchr(patt_space, '\n');
+    if (!n)
+        return NEW_NEXT;
+    memmove(patt_space, n, strlen(n) + 1);
+    return OLD_NEXT;
+}
+
+int cmd_g(Command *cmd)
+{
+    strcpy(patt_space, hold_space);
+    return CONTINUE;
+}
+
+int cmd_G(Command *cmd)
+{
+    size_t patt_len = strlen(patt_space);
+    size_t hold_len = strlen(hold_space);
+
+    if (patt_len + hold_len + 2 >= SPACE_BYTES)
+        truncating("pattern space", SPACE_BYTES);
+
+    strlcat(patt_space, "\n"      , SPACE_BYTES);
+    strlcat(patt_space, hold_space, SPACE_BYTES);
+
+    return CONTINUE;
+}
+
+int cmd_h(Command *cmd)
+{
+    strcpy(hold_space, patt_space);
+    return CONTINUE;
+}
+
+int cmd_H(Command *cmd)
+{
+    size_t patt_len = strlen(patt_space);
+    size_t hold_len = strlen(hold_space);
+
+    if (patt_len + hold_len + 2 >=  SPACE_BYTES)
+        truncating("hold space", SPACE_BYTES);
+
+    strlcat(hold_space, "\n"      , SPACE_BYTES);
+    strlcat(hold_space, patt_space, SPACE_BYTES);
+
+    return 0;
+}
+
+int cmd_i(Command *cmd)
+{
+    print(stdout, cmd->text, 0);
+    return CONTINUE;
+}
+
+int cmd_l(Command *cmd)
+{
+    return CONTINUE;
+}
+
+int cmd_n(Command *cmd)
+{
+    if (!flags.no_print)
+        print(stdout, patt_space, 0);
+
+    return NEW_LINE;
+}
+
+int cmd_N(Command *cmd)
+{
+    return APP_LINE;
+}
+
+int cmd_p(Command *cmd)
+{
+    print(stdout, patt_space, 0);
+    return CONTINUE;
+}
+
+int cmd_P(Command *cmd)
+{
+    print(stdout, patt_space, 1);
+    return CONTINUE;
+}
+
+int cmd_q(Command *cmd)
+{
+    return QUIT;
+}
+
+int cmd_r(Command *cmd)
+{
+    schedule_write(cmd->text, 1);
+    return CONTINUE;
+}
+
+int cmd_t(Command *cmd)
+{
+    if (flags.did_sub)
+        pc = cmd->other;
+    return CONTINUE;
+}
+
+int cmd_w(Command *cmd)
+{
+    char line[LINE_MAX];
+    FILE *f = file_open(cmd->text, "a");
+
+    if (f) {
+        print(f, patt_space, 0);
+        file_close(f);
+    }
+    return CONTINUE;
+}
+
+int cmd_x(Command *cmd)
+{
+    char *tmp  = hold_space;
+    hold_space = patt_space;
+    patt_space = tmp;
+    return CONTINUE;
+}
+
+int cmd_y(Command *cmd)
+{
+    return CONTINUE;
+}
+
+int cmd_colon(Command *cmd)
+{
+    return CONTINUE;
+}
+
+int cmd_equal(Command *cmd)
+{
+    printf("%d\n", line_number);
+    return CONTINUE;
+}
+
+int cmd_lbrace(Command *cmd)
+{
+    return CONTINUE;
+}
+
+int cmd_rbrace(Command *cmd)
+{
+    return CONTINUE;
+}
+
+int main(int argc, char **argv)
+{
+    return 0;
+}