From: Johan Malm Date: Tue, 23 Jun 2020 06:17:07 +0000 (+0100) Subject: Add src/theme/xbm/parse.c X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=f86394a9979abedc64ddeaf1eddd9ab3f9bd8e25;p=proto%2Flabwc.git Add src/theme/xbm/parse.c --- diff --git a/include/xbm.h b/include/xbm.h index f09264ba..127545da 100644 --- a/include/xbm.h +++ b/include/xbm.h @@ -16,11 +16,24 @@ struct token { enum token_type type; }; +/** + * xbm_create_bitmap - parse xbm tokens and create pixmap + * @tokens: token vector + */ +void xbm_create_bitmap(struct token *tokens); + /** * tokenize - tokenize xbm file * @buffer: buffer containing xbm file - * returns vector of tokens + * return token vector + */ +struct token *xbm_tokenize(char *buffer); + +/** + * xbm_read_file - read file into buffer (as it's easier to tokenize that way) + * @filename: file to be read + * return allocated memory */ -struct token *tokenize(char *buffer); +char *xbm_read_file(const char *filename); #endif /* XBM_H */ diff --git a/src/theme/xbm/parse.c b/src/theme/xbm/parse.c new file mode 100644 index 00000000..6951f256 --- /dev/null +++ b/src/theme/xbm/parse.c @@ -0,0 +1,70 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include + +#include "buf.h" +#include "xbm.h" + +static void process_bytes(int height, int width, struct token *tokens) +{ + struct token *t = tokens; + for (int row = 0; row < height; row++) { + int byte = 1; + for (int col = 0; col < width; col++) { + if (col == byte * 8) { + ++byte; + ++t; + } + if (!t->type) + return; + int value = (int)strtol(t->name, NULL, 0); + int bit = 1 << (col % 8); + if (value & bit) + printf("."); + else + printf(" "); + } + ++t; + printf("\n"); + } +} + +void xbm_create_bitmap(struct token *tokens) +{ + int width = 0, height = 0; + for (struct token *t = tokens; t->type; t++) { + if (width && height) { + if (t->type != TOKEN_INT) + continue; + process_bytes(width, height, t); + return; + } + if (strstr(t->name, "width")) + width = atoi((++t)->name); + else if (strstr(t->name, "height")) + height = atoi((++t)->name); + } +} + +char *xbm_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); +} diff --git a/src/theme/xbm/tokenize.c b/src/theme/xbm/tokenize.c index 301bab69..74650276 100644 --- a/src/theme/xbm/tokenize.c +++ b/src/theme/xbm/tokenize.c @@ -31,8 +31,9 @@ static void get_identifier_token() switch (current_buffer_position[0]) { case '\0': return; - case 'a'...'z': - case 'A'...'Z': + case 'a' ... 'z': + case 'A' ... 'Z': + case '0' ... '9': case '_': case '#': get_identifier_token(); @@ -53,9 +54,9 @@ static void get_number_token() switch (current_buffer_position[0]) { case '\0': return; - case '0'...'9': - case 'a'...'f': - case 'A'...'F': + case '0' ... '9': + case 'a' ... 'f': + case 'A' ... 'F': case 'x': get_number_token(); break; @@ -71,7 +72,7 @@ static void get_special_char_token() current_buffer_position++; } -struct token *tokenize(char *buffer) +struct token *xbm_tokenize(char *buffer) { current_buffer_position = buffer; @@ -79,14 +80,14 @@ struct token *tokenize(char *buffer) switch (current_buffer_position[0]) { case '\0': goto out; - case 'a'...'z': - case 'A'...'Z': + case 'a' ... 'z': + case 'A' ... 'Z': case '_': case '#': add_token(TOKEN_IDENT); get_identifier_token(); continue; - case '0'...'9': + case '0' ... '9': add_token(TOKEN_INT); get_number_token(); continue; diff --git a/tools/xbm/.gitignore b/tools/xbm/.gitignore index 1f1cfd69..22f659d4 100644 --- a/tools/xbm/.gitignore +++ b/tools/xbm/.gitignore @@ -1 +1,2 @@ xbm-tokenize +xbm-parse diff --git a/tools/xbm/Makefile b/tools/xbm/Makefile index 365c6739..af07e3a2 100644 --- a/tools/xbm/Makefile +++ b/tools/xbm/Makefile @@ -3,13 +3,17 @@ CFLAGS += -I../../include LDFLAGS += `pkg-config --cflags --libs cairo` ASAN += -fsanitize=address -PROGS = xbm-tokenize +PROGS = xbm-tokenize xbm-parse DEP_TOKENIZE = ../../src/common/buf.c ../../src/theme/xbm/tokenize.c +DEP_PARSE = $(DEP_TOKENIZE) ../../src/theme/xbm/parse.c all: $(PROGS) xbm-tokenize: xbm-tokenize.c $(DEP_TOKENIZE) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(ASAN) +xbm-parse: xbm-parse.c $(DEP_PARSE) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(ASAN) + clean : $(RM) $(PROGS) diff --git a/tools/xbm/xbm-parse.c b/tools/xbm/xbm-parse.c new file mode 100644 index 00000000..fc9b52d8 --- /dev/null +++ b/tools/xbm/xbm-parse.c @@ -0,0 +1,23 @@ +#include +#include + +#include "xbm.h" + +int main(int argc, char **argv) +{ + struct token *tokens; + + if (argc != 2) { + fprintf(stderr, "usage: %s \n", argv[0]); + return 1; + } + + char *buffer = xbm_read_file(argv[1]); + if (!buffer) + exit(EXIT_FAILURE); + tokens = xbm_tokenize(buffer); + free(buffer); + + xbm_create_bitmap(tokens); + free(tokens); +} diff --git a/tools/xbm/xbm-tokenize.c b/tools/xbm/xbm-tokenize.c index 5eabbe3f..d38827d6 100644 --- a/tools/xbm/xbm-tokenize.c +++ b/tools/xbm/xbm-tokenize.c @@ -41,7 +41,7 @@ int main(int argc, char **argv) char *buffer = read_file(argv[1]); if (!buffer) exit(EXIT_FAILURE); - tokens = tokenize(buffer); + tokens = xbm_tokenize(buffer); free(buffer); for (struct token *t = tokens; t->type; t++) printf("%s\n", t->name);