enowars5-service-stldoctor

STL-Analyzing A/D Service for ENOWARS5 in 2021
git clone https://git.sinitax.com/sinitax/enowars5-service-stldoctor
Log | Files | Refs | README | LICENSE | sfeed.txt

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:
Mservice/src/.gitignore | 1+
Mservice/src/Makefile | 3++-
Mservice/src/printdoc.c | 2+-
Mservice/src/stlfile.c | 107++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Aservice/src/test.sh | 9+++++++++
Aservice/src/tests/sample-ascii.stl | 9+++++++++
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