commit 93107ebd417e75efed4e2173feeea1030ce6cd02
parent 80b190c66dab551b75db790df86efaffe0f86671
Author: Louis Burda <quent.burda@gmail.com>
Date: Mon, 3 May 2021 23:44:36 +0200
improved parsing for ascii stl and added sample file for testing
Diffstat:
6 files changed, 95 insertions(+), 36 deletions(-)
diff --git a/service/src/.gitignore b/service/src/.gitignore
@@ -1,2 +1,3 @@
printdoc
*.o
+vgcore.*
diff --git a/service/src/Makefile b/service/src/Makefile
@@ -1,3 +1,4 @@
+CFLAGS = -g -I .
.PHONY: all clean
@@ -7,7 +8,7 @@ clean:
rm -f printdoc *.o
%.o: %.c %.h
- $(CC) -c -o $@ $< -I .
+ $(CC) -c -o $@ $< $(CFLAGS) $(LDLIBS)
printdoc: printdoc.c stlfile.o util.o
$(CC) -o $@ $^ $(CFLAGS) $(LDLIBS)
diff --git a/service/src/printdoc.c b/service/src/printdoc.c
@@ -138,7 +138,7 @@ submit_cmd(char *arg)
lastrun.valid = parse_file(&lastrun, contents, len);
- if (lastrun.valid) dump(lastrun.infopath);
+ // if (lastrun.valid) dump(lastrun.infopath);
free(contents);
}
diff --git a/service/src/stlfile.c b/service/src/stlfile.c
@@ -1,6 +1,8 @@
#include "stlfile.h"
#include "util.h"
+static const char wsset[] = " \r\n\t";
+
void
stack_init(struct stack *stack)
{
@@ -37,29 +39,55 @@ stack_free(struct stack *stack)
free(stack->data);
}
+long
+skip_set(char *start, const char *set)
+{
+ char *p;
+ for (p = start; *p && strchr(set, *p); p++);
+ return p - start;
+}
+
+char*
+consume_arg(char **start)
+{
+ char *p, *tmp;
+
+ p = *start + skip_set(*start, wsset);
+ for (; !strchr(wsset, *p); p++);
+ *p = '\0';
+ tmp = *start;
+ *start = p + 1;
+ return tmp;
+}
+
int
-consume_keyword(char **start, char *end)
+consume_keyword(char **start)
{
static const struct {
int code;
const char *str;
} mapping[] = {
- { KW_SOLID_BEGIN, "solid" },
- { KW_SOLID_END, "endsolid" },
- { KW_LOOP_BEGIN, "outer loop" },
- { KW_LOOP_END, "endloop" },
+ { KW_SOLID_BEGIN, "solid" },
+ { KW_SOLID_END, "endsolid" },
+ { KW_LOOP_BEGIN, "outer loop" },
+ { KW_LOOP_END, "endloop" },
{ KW_FACET_BEGIN, "facet normal" },
- { KW_FACET_END, "endfacet" },
- { KW_VERTEX, "vertex" },
+ { KW_FACET_END, "endfacet" },
+ { KW_VERTEX, "vertex" },
};
- char *bp;
- int i;
+ char *bp, *nsep;
+ int i, len;
- for (bp = *start; strchr(" \r\n\t", *bp); bp++);
+ bp = *start + skip_set(*start, wsset);
- for (i = 0; i < ARRSIZE(mapping); i++)
- if (!strcmp(mapping[i].str, bp))
+ for (i = 0; i < ARRSIZE(mapping); i++) {
+ len = strlen(mapping[i].str);
+ if (!strncmp(mapping[i].str, bp, len) && strchr(wsset, *(bp + len))) {
+ printf("GOT: %s\n", mapping[i].str);
+ *start = bp + len + (bp[len] ? 1 : 0);
return mapping[i].code;
+ }
+ }
return KW_UNKNOWN;
}
@@ -67,50 +95,61 @@ consume_keyword(char **start, char *end)
int
parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
{
- char *bp, *pbp, *end = buf + len;
+ char *bp, *nsep, *prev;
struct stack states;
- int type, kw;
+ int i, kw;
stack_init(&states);
-#define PARSER_ASSERT_NESTING(x, y) \
- do { if ((x) != (y)) { \
- fprintf(stderr, "STL Format error: invalid nesting!"); \
- return FAIL; \
- } } while (0)
-
- info = checkp(malloc(sizeof(struct parseinfo)));
info->type = TYPE_ASCII;
- while ((kw = consume_keyword(&bp, end))) {
+ bp = prev = buf;
+ while ((kw = consume_keyword(&bp))) {
switch (kw) {
case KW_SOLID_BEGIN:
+ /* TODO: save solid name */
stack_push(&states, STATE_SOLID);
+ consume_arg(&bp);
break;
case KW_SOLID_END:
- if (stack_pop(&states) == STATE_SOLID)
- break;
- goto unknown;
+ /* TODO: check that name matches */
+ if (stack_pop(&states) != STATE_SOLID)
+ goto unknown;
+ consume_arg(&bp);
+ break;
case KW_LOOP_BEGIN:
+ /* TODO: ensure only one loop */
stack_push(&states, STATE_LOOP);
break;
case KW_LOOP_END:
- if (stack_pop(&states) == STATE_LOOP)
- break;
- goto unknown;
+ if (stack_pop(&states) != STATE_LOOP)
+ goto unknown;
+ break;
case KW_FACET_BEGIN:
+ /* TODO: check if args are integers */
stack_push(&states, STATE_FACET);
+ for (i = 0; i < 3 && consume_arg(&bp); i++);
break;
case KW_FACET_END:
- if (stack_pop(&states) == STATE_FACET)
- break;
- goto unknown;
-
+ if (stack_pop(&states) != STATE_FACET)
+ goto unknown;
+ break;
+ case KW_VERTEX:
+ /* TODO: check if args are integers */
+ for (i = 0; i < 3 && consume_arg(&bp); i++);
+ break;
unknown:
case KW_UNKNOWN:
- fprintf(stderr, "Encountered unexpected keyword: '%.*s..'", 30, bp);
+ prev += skip_set(prev, wsset);
+ fprintf(stderr, "Expected keyword, got:\n%.*s...\n", 30, prev);
return FAIL;
}
+ prev = bp;
+ }
+
+ if (states.count) {
+ fprintf(stderr, "Expected keyword, got:\n%.*s...\n", 30, bp);
+ return FAIL;
}
stack_free(&states);
@@ -162,7 +201,7 @@ parse_file(struct parseinfo *info, char *buf, size_t len)
}
/* check bin vs ascii */
- for (bp = buf; strchr(" \n\r\t", *bp); bp++);
+ for (bp = buf; strchr(wsset, *bp); bp++);
return !strncmp("solid ", bp, 6)
? parse_file_ascii(info, buf, len)
diff --git a/service/src/test.sh b/service/src/test.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+(
+ echo "help"
+ echo "submit"
+ cat tests/sample-ascii.stl | wc -c
+ cat tests/sample-ascii.stl
+) | valgrind --leak-check=full ./printdoc
+
diff --git a/service/src/tests/sample-ascii.stl b/service/src/tests/sample-ascii.stl
@@ -0,0 +1,9 @@
+solid test
+ facet normal 0 0 1
+ outer loop
+ vertex 1 0 0
+ vertex 1 1 0
+ vertex 0 1 0
+ endloop
+ endfacet
+endsolid test