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 */
--- /dev/null
+#define _POSIX_C_SOURCE 200809L
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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);
+}
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();
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;
current_buffer_position++;
}
-struct token *tokenize(char *buffer)
+struct token *xbm_tokenize(char *buffer)
{
current_buffer_position = 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;
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)
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "xbm.h"
+
+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 = xbm_read_file(argv[1]);
+ if (!buffer)
+ exit(EXIT_FAILURE);
+ tokens = xbm_tokenize(buffer);
+ free(buffer);
+
+ xbm_create_bitmap(tokens);
+ free(tokens);
+}
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);