]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Add src/theme/xbm/tokenize.c
authorJohan Malm <jgm323@gmail.com>
Mon, 22 Jun 2020 18:03:02 +0000 (19:03 +0100)
committerJohan Malm <jgm323@gmail.com>
Mon, 22 Jun 2020 18:03:02 +0000 (19:03 +0100)
include/xbm.h [new file with mode: 0644]
src/theme/xbm/tokenize.c [new file with mode: 0644]
tools/xbm/.gitignore [new file with mode: 0644]
tools/xbm/5x5.xbm [new file with mode: 0644]
tools/xbm/8x8.xbm [new file with mode: 0644]
tools/xbm/9x9.xbm [new file with mode: 0644]
tools/xbm/Makefile [new file with mode: 0644]
tools/xbm/xbm-tokenize.c [new file with mode: 0644]

diff --git a/include/xbm.h b/include/xbm.h
new file mode 100644 (file)
index 0000000..f09264b
--- /dev/null
@@ -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 (file)
index 0000000..301bab6
--- /dev/null
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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 (file)
index 0000000..1f1cfd6
--- /dev/null
@@ -0,0 +1 @@
+xbm-tokenize
diff --git a/tools/xbm/5x5.xbm b/tools/xbm/5x5.xbm
new file mode 100644 (file)
index 0000000..0d2e083
--- /dev/null
@@ -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 (file)
index 0000000..efbf07c
--- /dev/null
@@ -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 (file)
index 0000000..238df09
--- /dev/null
@@ -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 (file)
index 0000000..365c673
--- /dev/null
@@ -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 (file)
index 0000000..5eabbe3
--- /dev/null
@@ -0,0 +1,48 @@
+#define _POSIX_C_SOURCE 200809L
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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 <xbm-file>\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);
+}