From 33d658a37f8c265a85ef59463e6e2e911d9c2c51 Mon Sep 17 00:00:00 2001 From: hasufell Date: Tue, 6 May 2014 23:09:59 +0200 Subject: [PATCH] First try of a parser --- Makefile | 59 ++++++++++++++++++++++++++ err.h | 34 +++++++++++++++ main.c | 6 +++ parser.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ parser.h | 8 ++++ 5 files changed, 231 insertions(+) create mode 100644 Makefile create mode 100644 err.h create mode 100644 main.c create mode 100644 parser.c create mode 100644 parser.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4265f72 --- /dev/null +++ b/Makefile @@ -0,0 +1,59 @@ +# compiler, tools +CC = clang +PKG_CONFIG ?= pkg-config + +# flags +CFLAGS ?= -march=native -O2 -pipe +CFLAGS += -std=c99 -Wall -Wextra -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-unused-function +ifeq ($(shell $(CC) -v 2>&1 | grep 'gcc version' &>/dev/null && echo 1),1) +CFLAGS += -Wno-unused-but-set-variable +endif +LDFLAGS ?= -Wl,-O1 -Wl,--as-needed -Wl,--hash-style=gnu + +ifndef NODEBUG +CFLAGS += -O0 -g3 +endif + +TARGET = drow-engine +HEADERS = err.h parser.h +OBJECTS = main.o parser.o +INCS = -I. + +CFLAGS += $(shell $(PKG_CONFIG) --cflags gl glu glib-2.0) +LIBS = $(shell $(PKG_CONFIG) --libs gl glu glib-2.0) -lglut -lm +CPPFLAGS += -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED -D_GNU_SOURCE + +# install variables +INSTALL = install +INSTALL_BIN = install -m755 +INSTALL_DIR = install -d +PREFIX = /usr/local +LIBDIR = lib64 +INSTALL_BINDIR = $(PREFIX)/bin +INSTALL_LIBDIR = $(PREFIX)/$(LIBDIR) + +%.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) $(INCS) -c $*.c + +all: $(TARGET) + +$(TARGET): $(HEADERS) $(OBJECTS) + $(CC) $(CFLAGS) $(CPPFLAGS) $(INCS) -o $(TARGET) $(OBJECTS) $(LDFLAGS) $(LIBS) + +install: + $(INSTALL_DIR) "$(DESTDIR)$(INSTALL_BINDIR)" + $(INSTALL_BIN) $(TARGET) "$(DESTDIR)$(INSTALL_BINDIR)" + +uninstall: + rm "$(DESTDIR)$(INSTALL_BINDIR)/$(TARGET)" + +clean: + rm -f *.o $(TARGET) + +doc: + doxygen + +doc-pdf: doc + $(MAKE) -C latex pdf + +.PHONY: clean install doc doc-pdf diff --git a/err.h b/err.h new file mode 100644 index 0000000..242a28e --- /dev/null +++ b/err.h @@ -0,0 +1,34 @@ +#ifndef _DROW_ENGINE_ERR_H +#define _DROW_ENGINE_ERR_H + +#include + +/** + * @file err.h + * Holds error handling macros. + * @brief error handling + */ + +/** + * Abort the program with a given error message. + */ +#define ABORT(...) \ +{ \ + fprintf(stderr, __VA_ARGS__); \ + abort(); \ +} + +/** + * Used for checking if a pointer is non-NULL + * after allocation. + */ +#define CHECK_PTR_VAL(ptr) \ +{ \ + if (ptr == NULL) { \ + fprintf(stderr,"NULL Pointer in %s [%d]",__FILE__,__LINE__); \ + abort(); \ + } \ +} + + +#endif /* _DROW_ENGINE_ERR_H */ diff --git a/main.c b/main.c new file mode 100644 index 0000000..a9ec241 --- /dev/null +++ b/main.c @@ -0,0 +1,6 @@ +#include "parser.h" + +int main(void) +{ + parse_obj("testcube_mitSpitze.obj"); +} diff --git a/parser.c b/parser.c new file mode 100644 index 0000000..0d8bb24 --- /dev/null +++ b/parser.c @@ -0,0 +1,124 @@ +#include "err.h" +#include "types.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * static function declarations + */ +static char *read_file(char *filename); + + +/** + * Parse an .obj file and return a NULL terminated + * HE_face array that represents the object. + * + * @param filename .obj file + * @return the HE_face array that represents the object + */ +HE_face *parse_obj(char *filename) +{ + unsigned int vc; + char *string, + *str_ptr_space, + *str_ptr_newline, + *str_tmp_ptr; + const size_t vert_size = sizeof(HE_vert); + HE_vert *vertices = malloc(vert_size); + + /* read the whole file into string */ + if (!filename || !*filename || !(string = read_file(filename))) + return NULL; + + printf("file content\n%s\n\n", string); + + vc = 1; + str_tmp_ptr = strtok_r(string, "\n", &str_ptr_newline); + while (str_tmp_ptr && *str_tmp_ptr) { + + str_tmp_ptr = strtok_r(str_tmp_ptr, " ", &str_ptr_space); + + if (!strcmp(str_tmp_ptr, "v")) { /* parse vertices */ + char *myfloat = NULL; + + /* fill x */ + myfloat = strtok_r(NULL, " ", &str_ptr_space); + CHECK_PTR_VAL(myfloat); + vertices[vc - 1].x = atof(myfloat); + + /* fill y */ + myfloat = strtok_r(NULL, " ", &str_ptr_space); + CHECK_PTR_VAL(myfloat); + vertices[vc - 1].y = atof(myfloat); + + /* fill z */ + myfloat = strtok_r(NULL, " ", &str_ptr_space); + CHECK_PTR_VAL(myfloat); + vertices[vc - 1].z = atof(myfloat); + + vc++; + vertices = realloc(vertices, + vert_size * vc); + CHECK_PTR_VAL(vertices); + } else if (!strcmp(str_tmp_ptr, "f")) { /* parse faces */ + /* TODO */ + } + + str_tmp_ptr = strtok_r(NULL, "\n", &str_ptr_newline); + } + + printf("vertices:\n"); + for (unsigned int i = 0; i < vc - 1; i++) { + printf("x[%d]: %f\n", i, vertices[i].x); + printf("y[%d]: %f\n", i, vertices[i].y); + printf("z[%d]: %f\n", i, vertices[i].z); + printf("\n"); + } + + return NULL; +} + +/** + * Reads a file and returns a newly allocated string. + * + * @param filename file to open + * @return newly allocated string, must be freed by the caller + */ +static char *read_file(char *filename) +{ + char buf[STD_FILE_BUF], + *string = malloc(STD_FILE_BUF); + int objfile = 0; + size_t str_size = 0; + ssize_t n; + uint8_t i = 0; + + objfile = open(filename, O_RDONLY); + + if (objfile) { + /* read and copy chunks */ + while ((n = read(objfile, buf, STD_FILE_BUF)) > 0) { + char *tmp_ptr = string + str_size; + memcpy(tmp_ptr, buf, STD_FILE_BUF); + str_size += n; + string = realloc(string, str_size); + i++; + } + /* add trailing NULL byte */ + string[str_size + 1] = '\0'; + + close(objfile); + + return string; + } else { + return NULL; + } +} diff --git a/parser.h b/parser.h new file mode 100644 index 0000000..1fcce11 --- /dev/null +++ b/parser.h @@ -0,0 +1,8 @@ +#ifndef _DROW_ENGINE_PARSER_H +#define _DROW_ENGINE_PARSER_H + + +void parse_obj(char *filename); + + +#endif /* _DROW_ENGINE_PARSER_H */