From d80a7b518f0f146ec148e368d0c7cc878d3de3c8 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 22 Jun 2020 19:03:02 +0100 Subject: [PATCH] Add src/theme/xbm/tokenize.c --- include/xbm.h | 26 ++++++++++ src/theme/xbm/tokenize.c | 105 +++++++++++++++++++++++++++++++++++++++ tools/xbm/.gitignore | 1 + tools/xbm/5x5.xbm | 4 ++ tools/xbm/8x8.xbm | 4 ++ tools/xbm/9x9.xbm | 5 ++ tools/xbm/Makefile | 15 ++++++ tools/xbm/xbm-tokenize.c | 48 ++++++++++++++++++ 8 files changed, 208 insertions(+) create mode 100644 include/xbm.h create mode 100644 src/theme/xbm/tokenize.c create mode 100644 tools/xbm/.gitignore create mode 100644 tools/xbm/5x5.xbm create mode 100644 tools/xbm/8x8.xbm create mode 100644 tools/xbm/9x9.xbm create mode 100644 tools/xbm/Makefile create mode 100644 tools/xbm/xbm-tokenize.c diff --git a/include/xbm.h b/include/xbm.h new file mode 100644 index 00000000..f09264ba --- /dev/null +++ b/include/xbm.h @@ -0,0 +1,26 @@ +#ifndef XBM_H +#define XBM_H + +enum token_type { + TOKEN_NONE = 0, + TOKEN_IDENT, + TOKEN_INT, + TOKEN_SPECIAL, + TOKEN_OTHER, +}; + +#define MAX_TOKEN_SIZE (256) +struct token { + char name[MAX_TOKEN_SIZE]; + size_t pos; + enum token_type type; +}; + +/** + * tokenize - tokenize xbm file + * @buffer: buffer containing xbm file + * returns vector of tokens + */ +struct token *tokenize(char *buffer); + +#endif /* XBM_H */ diff --git a/src/theme/xbm/tokenize.c b/src/theme/xbm/tokenize.c new file mode 100644 index 00000000..301bab69 --- /dev/null +++ b/src/theme/xbm/tokenize.c @@ -0,0 +1,105 @@ +#include +#include +#include + +#include "xbm.h" + +static char *current_buffer_position; +static struct token *tokens; +static int nr_tokens, alloc_tokens; + +static void add_token(enum token_type token_type) +{ + if (nr_tokens == alloc_tokens) { + alloc_tokens = (alloc_tokens + 16) * 2; + tokens = realloc(tokens, alloc_tokens * sizeof(struct token)); + } + struct token *token = tokens + nr_tokens; + memset(token, 0, sizeof(*token)); + nr_tokens++; + token->type = token_type; +} + +static void get_identifier_token() +{ + struct token *token = tokens + nr_tokens - 1; + token->name[token->pos] = current_buffer_position[0]; + token->pos++; + if (token->pos == MAX_TOKEN_SIZE - 1) + return; + current_buffer_position++; + switch (current_buffer_position[0]) { + case '\0': + return; + case 'a'...'z': + case 'A'...'Z': + case '_': + case '#': + get_identifier_token(); + break; + default: + break; + } +} + +static void get_number_token() +{ + struct token *token = tokens + nr_tokens - 1; + token->name[token->pos] = current_buffer_position[0]; + token->pos++; + if (token->pos == MAX_TOKEN_SIZE - 1) + return; + current_buffer_position++; + switch (current_buffer_position[0]) { + case '\0': + return; + case '0'...'9': + case 'a'...'f': + case 'A'...'F': + case 'x': + get_number_token(); + break; + default: + break; + } +} + +static void get_special_char_token() +{ + struct token *token = tokens + nr_tokens - 1; + token->name[0] = current_buffer_position[0]; + current_buffer_position++; +} + +struct token *tokenize(char *buffer) +{ + current_buffer_position = buffer; + + for (;;) { + switch (current_buffer_position[0]) { + case '\0': + goto out; + case 'a'...'z': + case 'A'...'Z': + case '_': + case '#': + add_token(TOKEN_IDENT); + get_identifier_token(); + continue; + case '0'...'9': + add_token(TOKEN_INT); + get_number_token(); + continue; + case '{': + add_token(TOKEN_SPECIAL); + get_special_char_token(); + continue; + default: + break; + } + ++current_buffer_position; + } +out: + add_token(TOKEN_NONE); /* vector end marker */ + return tokens; +} diff --git a/tools/xbm/.gitignore b/tools/xbm/.gitignore new file mode 100644 index 00000000..1f1cfd69 --- /dev/null +++ b/tools/xbm/.gitignore @@ -0,0 +1 @@ +xbm-tokenize diff --git a/tools/xbm/5x5.xbm b/tools/xbm/5x5.xbm new file mode 100644 index 00000000..0d2e0835 --- /dev/null +++ b/tools/xbm/5x5.xbm @@ -0,0 +1,4 @@ +#define max_width 5 +#define max_height 5 +static unsigned char max_bits[] = { + 0x1F, 0x1B, 0x15, 0x1B, 0x1F }; diff --git a/tools/xbm/8x8.xbm b/tools/xbm/8x8.xbm new file mode 100644 index 00000000..efbf07ca --- /dev/null +++ b/tools/xbm/8x8.xbm @@ -0,0 +1,4 @@ +#define close_width 8 +#define close_height 8 +static unsigned char close_bits[] = { + 0xFF, 0xC3, 0xA5, 0x99, 0x99, 0xA5, 0xC3, 0xFF }; diff --git a/tools/xbm/9x9.xbm b/tools/xbm/9x9.xbm new file mode 100644 index 00000000..238df09a --- /dev/null +++ b/tools/xbm/9x9.xbm @@ -0,0 +1,5 @@ +#define x9_width 9 +#define x9_height 9 +static unsigned char x9_bits[] = { + 0xFF, 0x01, 0x83, 0x01, 0x45, 0x01, 0x29, 0x01, 0x11, 0x01, 0x29, 0x01, + 0x45, 0x01, 0x83, 0x01, 0xFF, 0x01 }; diff --git a/tools/xbm/Makefile b/tools/xbm/Makefile new file mode 100644 index 00000000..365c6739 --- /dev/null +++ b/tools/xbm/Makefile @@ -0,0 +1,15 @@ +CFLAGS += -g -Wall -O0 -std=c11 +CFLAGS += -I../../include +LDFLAGS += `pkg-config --cflags --libs cairo` +ASAN += -fsanitize=address + +PROGS = xbm-tokenize +DEP_TOKENIZE = ../../src/common/buf.c ../../src/theme/xbm/tokenize.c + +all: $(PROGS) + +xbm-tokenize: xbm-tokenize.c $(DEP_TOKENIZE) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(ASAN) + +clean : + $(RM) $(PROGS) diff --git a/tools/xbm/xbm-tokenize.c b/tools/xbm/xbm-tokenize.c new file mode 100644 index 00000000..5eabbe3f --- /dev/null +++ b/tools/xbm/xbm-tokenize.c @@ -0,0 +1,48 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include + +#include "buf.h" +#include "xbm.h" + +/* Read file into buffer, because it's easier to tokenize that way */ +char *read_file(const char *filename) +{ + char *line = NULL; + size_t len = 0; + FILE *stream = fopen(filename, "r"); + if (!stream) { + fprintf(stderr, "warn: cannot read '%s'\n", filename); + return NULL; + } + struct buf buffer; + buf_init(&buffer); + while ((getline(&line, &len, stream) != -1)) { + char *p = strrchr(line, '\n'); + if (p) + *p = '\0'; + buf_add(&buffer, line); + } + free(line); + fclose(stream); + return (buffer.buf); +} + +int main(int argc, char **argv) +{ + struct token *tokens; + + if (argc != 2) { + fprintf(stderr, "usage: %s \n", argv[0]); + return 1; + } + + char *buffer = read_file(argv[1]); + if (!buffer) + exit(EXIT_FAILURE); + tokens = tokenize(buffer); + free(buffer); + for (struct token *t = tokens; t->type; t++) + printf("%s\n", t->name); +}