diff options
| author | Louis Burda <quent.burda@gmail.com> | 2021-05-03 23:44:36 +0200 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2021-05-03 23:44:36 +0200 |
| commit | 93107ebd417e75efed4e2173feeea1030ce6cd02 (patch) | |
| tree | 5385d62e06f751674878d532144e0add67a45ad9 /service/src/stlfile.c | |
| parent | 80b190c66dab551b75db790df86efaffe0f86671 (diff) | |
| download | enowars5-service-stldoctor-93107ebd417e75efed4e2173feeea1030ce6cd02.tar.gz enowars5-service-stldoctor-93107ebd417e75efed4e2173feeea1030ce6cd02.zip | |
improved parsing for ascii stl and added sample file for testing
Diffstat (limited to 'service/src/stlfile.c')
| -rw-r--r-- | service/src/stlfile.c | 107 |
1 files changed, 73 insertions, 34 deletions
diff --git a/service/src/stlfile.c b/service/src/stlfile.c index d57964b..d5a64a6 100644 --- 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) |
