commit 14bc8a3883663656cd4254567a978002c062992d
parent 5569ec2abd2c8f31554a02587fda842e4da7eba3
Author: Louis Burda <quent.burda@gmail.com>
Date: Thu, 24 Jun 2021 21:23:02 +0200
refactored code for readability and keeping within 80ch limit, updated service source
Diffstat:
9 files changed, 293 insertions(+), 213 deletions(-)
diff --git a/do.sh b/do.sh
@@ -43,7 +43,7 @@ elif [ "$1" == "cleansrc" ]; then
if [ ! -z $(echo "$path" | grep '.[hc]$') ]; then
sed -i -e 's/^\s*\/\*.*\*\/\s*$//g' "$path" # remove /* */ style comments
sed -i -e 's/\s*\/\*.*\*\/\s*/ /g' "$path" # remove /* */ style comments
- sed -i -e 's/\/\/.*//g' "$path" # remove // style comments
+ sed -i -e 's/\s*\/\/.*//g' "$path" # remove // style comments
sed -i -e ':a;N;$!ba;s/\n\{3,\}/\n\n/g' "$path" # collapse multiple newlines
sed -i -e 's/fprintf(\s*stderr\s*,\s*/printf(/g' "$path" # replace fprintf stderr
elif [ "$(basename "$path")" == "Makefile" ]; then
diff --git a/service/src/main.c b/service/src/main.c
@@ -50,9 +50,10 @@ int echo = 0, loggedin = 0;
int
save_submission(struct parseinfo *info, char *stldata, int stlsize)
{
- DIR *d;
- FILE *f = NULL;
char *dirpath = NULL, *infopath = NULL, *modelpath = NULL;
+ FILE *f = NULL;
+ int status = 0;
+ DIR *d;
if (loggedin)
dirpath = aprintf("%s/.%s-%i", resultdir, info->hash, time(NULL));
@@ -63,33 +64,29 @@ save_submission(struct parseinfo *info, char *stldata, int stlsize)
modelpath = aprintf("%s/%s", dirpath, "model");
if (!(f = fopen(modelpath, "w+"))) goto fail;
if (fwrite(stldata, 1, stlsize, f) != stlsize) goto fail;
- fclose(f);
- f = NULL;
+ NFCLOSE(f);
infopath = aprintf("%s/%s", dirpath, "info");
if (!(f = fopen(infopath, "w+"))) goto fail;
if (save_info(info, f) != OK) goto fail;
- fclose(f);
- f = NULL;
+ NFCLOSE(f);
+
+exit:
+ if (f) fclose(f);
free(dirpath);
free(modelpath);
free(infopath);
- return OK;
+ return status;
fail:
- if (f) fclose(f);
-
if (infopath) remove(infopath);
if (modelpath) remove(modelpath);
if (dirpath) remove(dirpath);
- free(dirpath);
- free(modelpath);
- free(infopath);
-
- return FAIL;
+ status = 1;
+ goto exit;
}
int
@@ -104,50 +101,51 @@ handle_download(const char *scandir)
{
char *infopath, *modelpath;
size_t i, size;
+ int status = 0;
FILE *f;
infopath = aprintf("%s/%s", scandir, "info");
if (!(f = fopen(infopath, "r"))) {
- printf("ERR: Selected result is missing!\n");
- goto cleanup;
+ ERR("Selected result is missing!\n");
+ goto fail;
}
free_info(&cached);
if (load_info(&cached, f) != OK) {
- printf("ERR: Failed to parse info file!\n");
- goto cleanup;
+ ERR("Failed to parse info file!\n");
+ goto fail;
}
- fclose(f);
- f = NULL;
+ NFCLOSE(f);
print_info(&cached);
if (strchr(ask("Download the model? "), 'y')) {
modelpath = aprintf("%s/%s", scandir, "model");
if (!(f = fopen(modelpath, "r"))) {
- printf("ERR: Failed to access file!\n");
- goto cleanup;
+ ERR("Failed to access file!\n");
+ goto fail;
}
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
if (size > MAXFILESIZE) {
- printf("ERR: File is too large!\n");
- goto cleanup;
+ ERR("File is too large!\n");
+ goto fail;
}
printf("Here you go.. (%liB)\n", size);
while ((i = getc(f)) != EOF)
putc(i, stdout);
- fclose(f);
- f = NULL;
+ NFCLOSE(f);
}
- return 0;
-
-cleanup:
+exit:
if (f) fclose(f);
free(infopath);
free(modelpath);
- return 1;
+ return status;
+
+fail:
+ status = 1;
+ goto exit;
}
void
@@ -201,21 +199,21 @@ upload_cmd(const char *arg)
resp = ask("How large is your file? ");
len = strtoul(resp, &end, 10);
if (len <= 0 || len >= MAXFILESIZE || *end) {
- printf("ERR: Invalid file length!\n");
+ ERR("Invalid file length!\n");
return;
}
printf("Ok! Im listening..\n");
contents = checkp(malloc(len + 1));
if (fread(contents, 1, len, stdin) != len) {
- printf("ERR: Not enough data received!\n");
+ ERR("Not enough data received!\n");
goto cleanup;
}
contents[len] = '\0';
if ((cached.valid = parse_file(&cached, contents, len))) {
if (save_submission(&cached, contents, len) != OK)
- printf("ERR: Failed to save your submission!\n");
+ ERR("Failed to save your submission!\n");
else
printf("Your file was saved with ID %s!\n", cached.hash);
}
@@ -235,7 +233,7 @@ search_cmd(const char *arg)
if (arg && !strcmp(arg, "last")) {
if (!cached.valid) {
- printf("ERR: No cached info report available\n");
+ ERR("No cached info report available\n");
return;
}
hash = cached.hash;
@@ -244,7 +242,7 @@ search_cmd(const char *arg)
}
if (!(d = opendir(resultdir))) {
- printf("ERR: Unable to access upload directory!\n");
+ ERR("Unable to access upload directory!\n");
return;
}
@@ -256,14 +254,15 @@ search_cmd(const char *arg)
paths[pathc++] = checkp(strdup(de->d_name));
if (pathc == pathcap) {
pathcap *= 2;
- paths = checkp(realloc(paths, pathcap * sizeof(char*)));
+ paths = realloc(paths, pathcap * sizeof(char*));
+ checkp(paths);
}
}
}
closedir(d);
if (pathc == 0) {
- printf("ERR: Couldn't find a matching scan result!\n");
+ ERR("Couldn't find a matching scan result!\n");
goto cleanup;
}
@@ -272,16 +271,13 @@ search_cmd(const char *arg)
if (strchr(resp, 'q')) break;
which = strtoul(resp, &end, 10);
if (which >= pathc || which < 0 || *end) {
- printf("ERR: Invalid index!\n");
+ ERR("Invalid index!\n");
goto cleanup;
}
scandir = aprintf("%s/%s", resultdir, paths[which]);
-
if (handle_download(scandir)) goto cleanup;
-
- free(scandir);
- scandir = NULL;
+ NFREE(scandir);
}
cleanup:
@@ -301,7 +297,7 @@ list_cmd(const char *arg)
DIR *d;
if (!loggedin) {
- printf("ERR: Not logged in!\n");
+ ERR("Not logged in!\n");
return;
}
@@ -311,13 +307,12 @@ list_cmd(const char *arg)
if (*de->d_name == '.' && !strchr(".", de->d_name[1])) {
printf(">> %s\n", de->d_name);
path = aprintf("%s/%s/info", resultdir, de->d_name);
- if ((f = fopen(path, "r"))) {
- if (load_info(&info, f) == OK)
- print_info(&info);
- else
- printf("ERR: Failed to read saved file info!\n");
- fclose(f);
+ if ((f = fopen(path, "r")) && load_info(&info, f) == OK) {
+ print_info(&info);
+ } else {
+ ERR("Failed to read saved file info!\n");
}
+ if (f) fclose(f);
free(path);
}
}
@@ -331,7 +326,7 @@ auth_cmd(const char *arg)
int ret;
if (loggedin) {
- printf("ERR: Already logged in!\n");
+ ERR("Already logged in!\n");
return;
}
@@ -343,7 +338,7 @@ auth_cmd(const char *arg)
} else if (ret && errno == EEXIST) {
printf("Success!\nWelcome back!\n");
} else {
- printf("ERR: Auth failed!\n");
+ ERR("Auth failed!\n");
return;
}
@@ -364,14 +359,13 @@ cleanexit()
int
main()
{
+ struct command *c;
const char *cmd, *envstr;
char *cp, *arg;
int exit, i, cmdlen;
- if (!(envstr = getenv("RESULTDIR"))) {
- printf("ERR: RESULTDIR not defined\n");
- return 1;
- }
+ if (!(envstr = getenv("RESULTDIR")))
+ die("RESULTDIR not defined\n");
resultdir = checkp(strdup(envstr));
@@ -395,14 +389,16 @@ main()
cmdlen = cp ? cp - cmd : strlen(cmd);
for (i = 0; i < ARRSIZE(commands); i++) {
- if (!strncmp(commands[i].name, cmd, cmdlen)
- && cmdlen == strlen(commands[i].name)) {
- commands[i].func(arg);
+ c = &commands[i];
+ if (!strncmp(c->name, cmd, cmdlen) && !c->name[cmdlen]) {
+ c->func(arg);
break;
}
}
if (i == ARRSIZE(commands) && strlen(cmd) != 0)
- printf("No such command!\n");
+ ERR("No such command!\n");
}
+
+ return EXIT_SUCCESS;
}
diff --git a/service/src/stlfile.c b/service/src/stlfile.c
@@ -27,7 +27,8 @@ stack_push(struct stack *stack, int v)
{
if (stack->count == stack->cap) {
stack->cap *= 2;
- stack->data = checkp(realloc(stack->data, sizeof(int) * stack->cap));
+ stack->data = realloc(stack->data, sizeof(int) * stack->cap);
+ checkp(stack->data);
}
stack->data[stack->count] = v;
@@ -98,7 +99,6 @@ consume_keyword(char **start)
for (i = 0; i < ARRSIZE(kwmap); i++) {
len = strlen(kwmap[i].str);
if (!strncmp(kwmap[i].str, bp, len) && (!bp[len] || isws(bp[len]))) {
-
*start = bp + len + (bp[len] ? 1 : 0);
return kwmap[i].code;
}
@@ -107,9 +107,6 @@ consume_keyword(char **start)
return KW_UNKNOWN;
}
-#define PARSE_FAIL(...) \
- do { printf("FORMAT ERR: " __VA_ARGS__); goto fail; } while (0)
-
int
parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
{
@@ -135,81 +132,113 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
switch (kw) {
case KW_SOLID_BEGIN:
stack_push(&states, STATE_SOLID);
- if (stack_ind(&states, KW_SOLID_BEGIN) != -1)
- PARSE_FAIL("Multiple nested solids!\n");
+ if (stack_ind(&states, KW_SOLID_BEGIN) != -1) {
+ FMT_ERR("Multiple nested solids!\n");
+ goto format_error;
+ }
tmp = bp;
- if (!consume_keyword(&bp) && (arg = consume_arg(&bp, &end))) {
+ if (!consume_keyword(&bp)
+ && (arg = consume_arg(&bp, &end))) {
info->solidname = strndup(arg, end - arg);
} else {
bp = tmp;
}
break;
case KW_SOLID_END:
- if ((kw = stack_pop(&states)) != STATE_SOLID)
- PARSE_FAIL("Improper nesting, parent: %s\n", kwmap[kw].str);
+ if ((kw = stack_pop(&states)) != STATE_SOLID) {
+ FMT_ERR("Improper nesting, parent: %s\n",
+ kwmap[kw].str);
+ goto format_error;
+ }
tmp = bp;
if (info->solidname && !consume_keyword(&bp)
&& (arg = consume_arg(&bp, &end))) {
- if (strncmp(info->solidname, arg, end - arg))
- PARSE_FAIL("Solid end/begin names do not match!\n");
+ if (strncmp(info->solidname, arg, end - arg)) {
+ FMT_ERR("Solid names do not match!\n");
+ goto format_error;
+ }
} else {
bp = tmp;
}
break;
case KW_LOOP_BEGIN:
stack_push(&states, STATE_LOOP);
- if (stack_ind(&states, KW_LOOP_BEGIN) != -1)
- PARSE_FAIL("Multiple nested loops!\n");
+ if (stack_ind(&states, KW_LOOP_BEGIN) != -1) {
+ FMT_ERR("Multiple nested loops!\n");
+ goto format_error;
+ }
break;
case KW_LOOP_END:
- if ((kw = stack_pop(&states)) != STATE_LOOP)
- PARSE_FAIL("Improper nesting, parent: %s\n", kwmap[kw].str);
+ if ((kw = stack_pop(&states)) != STATE_LOOP) {
+ FMT_ERR("Improper nesting, parent: %s\n",
+ kwmap[kw].str);
+ goto format_error;
+ }
info->loopcount++;
break;
case KW_FACET_BEGIN:
stack_push(&states, STATE_FACET);
- if (stack_ind(&states, KW_LOOP_BEGIN) != -1)
- PARSE_FAIL("Multiple nested facets!\n");
+ if (stack_ind(&states, KW_LOOP_BEGIN) != -1) {
+ FMT_ERR("Multiple nested facets!\n");
+ goto format_error;
+ }
for (i = 0; i < 3; i++) {
- if (!(arg = consume_arg(&bp, &end)))
- PARSE_FAIL("Facet with less than 3 args!\n");
+ if (!(arg = consume_arg(&bp, &end))) {
+ FMT_ERR("Facet with < 3 args!\n");
+ goto format_error;
+ }
farg = strtof(arg, &tmp);
- if (!isws(*tmp))
- PARSE_FAIL("Facet with invalid arg '%s'!\n", arg);
+ if (!isws(*tmp)) {
+ FMT_ERR("Facet arg '%s'\n", arg);
+ goto format_error;
+ }
}
break;
case KW_FACET_END:
- if ((kw = stack_pop(&states)) != STATE_FACET)
- PARSE_FAIL("Improper nesting, parent: %s\n", kwmap[kw].str);
+ if ((kw = stack_pop(&states)) != STATE_FACET) {
+ FMT_ERR("Improper nesting, parent: %s\n",
+ kwmap[kw].str);
+ goto format_error;
+ }
break;
case KW_VERTEX:
for (i = 0; i < 3; i++) {
- if (!(arg = consume_arg(&bp, &end)))
- PARSE_FAIL("Vertex with less than 3 args!\n");
+ if (!(arg = consume_arg(&bp, &end))) {
+ FMT_ERR("Vertex with < 3 args\n");
+ goto format_error;
+ }
farg = strtof(arg, &tmp);
- if (!isws(*tmp))
- PARSE_FAIL("Vertex with invalid arg '%s'!\n", arg);
+ if (!isws(*tmp)) {
+ FMT_ERR("Vertex arg '%s'\n", arg);
+ goto format_error;
+ }
info->bbmin[i] = MIN(info->bbmin[i], farg);
info->bbmax[i] = MAX(info->bbmax[i], farg);
}
break;
case KW_UNKNOWN:
prev = skipws(prev);
- PARSE_FAIL("Expected keyword, got:\n%.*s...\n", 30, prev);
+ FMT_ERR("Expected keyword, got:\n%.*s...\n", 30, prev);
+ goto format_error;
}
prev = bp;
}
- if (states.count)
- PARSE_FAIL("Expected keyword, got:\n%.*s...\n", 30, bp);
+ if (states.count) {
+ FMT_ERR("Expected keyword, got:\n%.*s...\n", 30, bp);
+ goto format_error;
+ }
bp = skipws(bp);
- if (*bp) PARSE_FAIL("Extraneous data at end of file\n");
+ if (*bp) {
+ FMT_ERR("Extraneous data at end of file\n");
+ goto format_error;
+ }
stack_free(&states);
return OK;
-fail:
+format_error:
stack_free(&states);
return FAIL;
}
@@ -223,8 +252,10 @@ parse_file_bin(struct parseinfo *info, char *buf, size_t len)
info->type = TYPE_BIN;
- if (len < 84)
- PARSE_FAIL("Truncated data! (header missing)\n");
+ if (len < 84) {
+ FMT_ERR("Truncated data! (header missing)\n");
+ goto fail;
+ }
memcpy(info->header, buf, 80);
@@ -248,12 +279,16 @@ parse_file_bin(struct parseinfo *info, char *buf, size_t len)
}
for (i = 0; i < info->loopcount; i++) {
- if (bp + 50 > end)
- PARSE_FAIL("Truncated data! (loops missing)\n");
+ if (bp + 50 > end) {
+ FMT_ERR("Truncated data! (loops missing)\n");
+ goto fail;
+ }
for (k = 0; k < 12; k++, bp += 4) {
v = fle32toh(*(float*)bp);
- if (v == INFINITY || v == NAN)
- PARSE_FAIL("Encountered invalid float\n");
+ if (v == INFINITY || v == NAN) {
+ FMT_ERR("Encountered invalid float\n");
+ goto fail;
+ }
if (k >= 3) {
info->bbmin[k % 3] = MIN(info->bbmin[k % 3], v);
info->bbmax[k % 3] = MAX(info->bbmax[k % 3], v);
@@ -262,11 +297,15 @@ parse_file_bin(struct parseinfo *info, char *buf, size_t len)
bp += 2;
}
- if (bp != end) PARSE_FAIL("Extraneous data at end of file\n");
+ if (bp != end) {
+ FMT_ERR("Extraneous data at end of file\n");
+ goto fail;
+ }
return OK;
fail:
+ NFREE(info->solidname);
return FAIL;
}
@@ -277,10 +316,10 @@ parse_file(struct parseinfo *info, char *buf, size_t len)
const char *resp;
char *bp;
- if (info->valid) free_info(info);
+ free_info(info);
if (len < 10) {
- printf("ERR: File too small!\n");
+ ERR("File too small!\n");
return FAIL;
}
@@ -297,7 +336,7 @@ parse_file(struct parseinfo *info, char *buf, size_t len)
if (!info->modelname) {
resp = ask("Please enter your model name: ");
if (strlen(resp) < 4) {
- printf("ERR: Model name is too short!\n");
+ ERR("Model name is too short!\n");
return FAIL;
}
info->modelname = checkp(strdup(resp));
@@ -403,9 +442,9 @@ print_info(struct parseinfo *info)
void
free_info(struct parseinfo *info)
{
- NULLFREE(info->hash);
- NULLFREE(info->modelname);
- NULLFREE(info->solidname);
+ NFREE(info->hash);
+ NFREE(info->modelname);
+ NFREE(info->solidname);
info->valid = 0;
}
diff --git a/service/src/stlfile.h b/service/src/stlfile.h
@@ -9,6 +9,8 @@
#include "util.h"
+#define FMT_ERR(...) ERR("FORMAT " __VA_ARGS__)
+
enum {
KW_INVALID = -1,
KW_UNKNOWN,
diff --git a/service/src/util.h b/service/src/util.h
@@ -11,7 +11,10 @@
#define MIN(x,y) ((x) > (y) ? (y) : (x))
#define MAX(x,y) ((x) < (y) ? (y) : (x))
-#define NULLFREE(p) do { free(p); p = NULL; } while (0)
+#define ERR(...) printf("ERR: " __VA_ARGS__)
+
+#define NFREE(p) do { free(p); p = NULL; } while (0)
+#define NFCLOSE(f) do { fclose(f); f = NULL; } while (0)
#define MHASHLEN 40
diff --git a/src/main.c b/src/main.c
@@ -50,9 +50,10 @@ int echo = 0, loggedin = 0;
int
save_submission(struct parseinfo *info, char *stldata, int stlsize)
{
- DIR *d;
- FILE *f = NULL;
char *dirpath = NULL, *infopath = NULL, *modelpath = NULL;
+ FILE *f = NULL;
+ int status = 0;
+ DIR *d;
if (loggedin)
dirpath = aprintf("%s/.%s-%i", resultdir, info->hash, time(NULL));
@@ -63,33 +64,29 @@ save_submission(struct parseinfo *info, char *stldata, int stlsize)
modelpath = aprintf("%s/%s", dirpath, "model");
if (!(f = fopen(modelpath, "w+"))) goto fail;
if (fwrite(stldata, 1, stlsize, f) != stlsize) goto fail;
- fclose(f);
- f = NULL;
+ NFCLOSE(f);
infopath = aprintf("%s/%s", dirpath, "info");
if (!(f = fopen(infopath, "w+"))) goto fail;
if (save_info(info, f) != OK) goto fail;
- fclose(f);
- f = NULL;
+ NFCLOSE(f);
+
+exit:
+ if (f) fclose(f);
free(dirpath);
free(modelpath);
free(infopath);
- return OK;
+ return status;
fail:
- if (f) fclose(f);
-
if (infopath) remove(infopath);
if (modelpath) remove(modelpath);
if (dirpath) remove(dirpath);
- free(dirpath);
- free(modelpath);
- free(infopath);
-
- return FAIL;
+ status = 1;
+ goto exit;
}
int
@@ -104,50 +101,51 @@ handle_download(const char *scandir)
{
char *infopath, *modelpath;
size_t i, size;
+ int status = 0;
FILE *f;
infopath = aprintf("%s/%s", scandir, "info");
if (!(f = fopen(infopath, "r"))) {
- fprintf(stderr, "ERR: Selected result is missing!\n");
- goto cleanup;
+ ERR("Selected result is missing!\n");
+ goto fail;
}
free_info(&cached);
if (load_info(&cached, f) != OK) {
- fprintf(stderr, "ERR: Failed to parse info file!\n");
- goto cleanup;
+ ERR("Failed to parse info file!\n");
+ goto fail;
}
- fclose(f);
- f = NULL;
+ NFCLOSE(f);
print_info(&cached);
if (strchr(ask("Download the model? "), 'y')) {
modelpath = aprintf("%s/%s", scandir, "model");
if (!(f = fopen(modelpath, "r"))) {
- fprintf(stderr, "ERR: Failed to access file!\n");
- goto cleanup;
+ ERR("Failed to access file!\n");
+ goto fail;
}
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
if (size > MAXFILESIZE) {
- fprintf(stderr, "ERR: File is too large!\n");
- goto cleanup;
+ ERR("File is too large!\n");
+ goto fail;
}
printf("Here you go.. (%liB)\n", size);
while ((i = getc(f)) != EOF)
putc(i, stdout);
- fclose(f);
- f = NULL;
+ NFCLOSE(f);
}
- return 0;
-
-cleanup:
+exit:
if (f) fclose(f);
free(infopath);
free(modelpath);
- return 1;
+ return status;
+
+fail:
+ status = 1;
+ goto exit;
}
void
@@ -201,21 +199,21 @@ upload_cmd(const char *arg)
resp = ask("How large is your file? ");
len = strtoul(resp, &end, 10);
if (len <= 0 || len >= MAXFILESIZE || *end) {
- fprintf(stderr, "ERR: Invalid file length!\n");
+ ERR("Invalid file length!\n");
return;
}
printf("Ok! Im listening..\n");
contents = checkp(malloc(len + 1));
if (fread(contents, 1, len, stdin) != len) {
- fprintf(stderr, "ERR: Not enough data received!\n");
+ ERR("Not enough data received!\n");
goto cleanup;
}
contents[len] = '\0';
if ((cached.valid = parse_file(&cached, contents, len))) {
if (save_submission(&cached, contents, len) != OK)
- fprintf(stderr, "ERR: Failed to save your submission!\n");
+ ERR("Failed to save your submission!\n");
else
printf("Your file was saved with ID %s!\n", cached.hash);
}
@@ -235,7 +233,7 @@ search_cmd(const char *arg)
if (arg && !strcmp(arg, "last")) {
if (!cached.valid) {
- fprintf(stderr, "ERR: No cached info report available\n");
+ ERR("No cached info report available\n");
return;
}
hash = cached.hash;
@@ -244,7 +242,7 @@ search_cmd(const char *arg)
}
if (!(d = opendir(resultdir))) {
- fprintf(stderr, "ERR: Unable to access upload directory!\n");
+ ERR("Unable to access upload directory!\n");
return;
}
@@ -256,14 +254,15 @@ search_cmd(const char *arg)
paths[pathc++] = checkp(strdup(de->d_name));
if (pathc == pathcap) {
pathcap *= 2;
- paths = checkp(realloc(paths, pathcap * sizeof(char*)));
+ paths = realloc(paths, pathcap * sizeof(char*));
+ checkp(paths);
}
}
}
closedir(d);
if (pathc == 0) {
- fprintf(stderr, "ERR: Couldn't find a matching scan result!\n");
+ ERR("Couldn't find a matching scan result!\n");
goto cleanup;
}
@@ -272,16 +271,13 @@ search_cmd(const char *arg)
if (strchr(resp, 'q')) break;
which = strtoul(resp, &end, 10);
if (which >= pathc || which < 0 || *end) {
- fprintf(stderr, "ERR: Invalid index!\n");
+ ERR("Invalid index!\n");
goto cleanup;
}
scandir = aprintf("%s/%s", resultdir, paths[which]);
-
if (handle_download(scandir)) goto cleanup;
-
- free(scandir);
- scandir = NULL;
+ NFREE(scandir);
}
cleanup:
@@ -301,7 +297,7 @@ list_cmd(const char *arg)
DIR *d;
if (!loggedin) {
- fprintf(stderr, "ERR: Not logged in!\n");
+ ERR("Not logged in!\n");
return;
}
@@ -311,13 +307,12 @@ list_cmd(const char *arg)
if (*de->d_name == '.' && !strchr(".", de->d_name[1])) {
printf(">> %s\n", de->d_name);
path = aprintf("%s/%s/info", resultdir, de->d_name);
- if ((f = fopen(path, "r"))) {
- if (load_info(&info, f) == OK)
- print_info(&info);
- else
- fprintf(stderr, "ERR: Failed to read saved file info!\n");
- fclose(f);
+ if ((f = fopen(path, "r")) && load_info(&info, f) == OK) {
+ print_info(&info);
+ } else {
+ ERR("Failed to read saved file info!\n");
}
+ if (f) fclose(f);
free(path);
}
}
@@ -331,7 +326,7 @@ auth_cmd(const char *arg)
int ret;
if (loggedin) {
- fprintf(stderr, "ERR: Already logged in!\n");
+ ERR("Already logged in!\n");
return;
}
@@ -343,7 +338,7 @@ auth_cmd(const char *arg)
} else if (ret && errno == EEXIST) {
printf("Success!\nWelcome back!\n");
} else {
- fprintf(stderr, "ERR: Auth failed!\n");
+ ERR("Auth failed!\n");
return;
}
@@ -364,14 +359,13 @@ cleanexit()
int
main()
{
+ struct command *c;
const char *cmd, *envstr;
char *cp, *arg;
int exit, i, cmdlen;
- if (!(envstr = getenv("RESULTDIR"))) {
- fprintf(stderr, "ERR: RESULTDIR not defined\n");
- return 1;
- }
+ if (!(envstr = getenv("RESULTDIR")))
+ die("RESULTDIR not defined\n");
resultdir = checkp(strdup(envstr));
@@ -395,14 +389,16 @@ main()
cmdlen = cp ? cp - cmd : strlen(cmd);
for (i = 0; i < ARRSIZE(commands); i++) {
- if (!strncmp(commands[i].name, cmd, cmdlen)
- && cmdlen == strlen(commands[i].name)) {
- commands[i].func(arg);
+ c = &commands[i];
+ if (!strncmp(c->name, cmd, cmdlen) && !c->name[cmdlen]) {
+ c->func(arg);
break;
}
}
if (i == ARRSIZE(commands) && strlen(cmd) != 0)
- fprintf(stderr, "No such command!\n");
+ ERR("No such command!\n");
}
+
+ return EXIT_SUCCESS;
}
diff --git a/src/stlfile.c b/src/stlfile.c
@@ -27,7 +27,8 @@ stack_push(struct stack *stack, int v)
{
if (stack->count == stack->cap) {
stack->cap *= 2;
- stack->data = checkp(realloc(stack->data, sizeof(int) * stack->cap));
+ stack->data = realloc(stack->data, sizeof(int) * stack->cap);
+ checkp(stack->data);
}
stack->data[stack->count] = v;
@@ -98,7 +99,6 @@ consume_keyword(char **start)
for (i = 0; i < ARRSIZE(kwmap); i++) {
len = strlen(kwmap[i].str);
if (!strncmp(kwmap[i].str, bp, len) && (!bp[len] || isws(bp[len]))) {
- // printf("GOT: %s\n", kwmap[i].str);
*start = bp + len + (bp[len] ? 1 : 0);
return kwmap[i].code;
}
@@ -107,9 +107,6 @@ consume_keyword(char **start)
return KW_UNKNOWN;
}
-#define PARSE_FAIL(...) \
- do { fprintf(stderr, "FORMAT ERR: " __VA_ARGS__); goto fail; } while (0)
-
int
parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
{
@@ -135,81 +132,113 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len)
switch (kw) {
case KW_SOLID_BEGIN:
stack_push(&states, STATE_SOLID);
- if (stack_ind(&states, KW_SOLID_BEGIN) != -1)
- PARSE_FAIL("Multiple nested solids!\n");
+ if (stack_ind(&states, KW_SOLID_BEGIN) != -1) {
+ FMT_ERR("Multiple nested solids!\n");
+ goto format_error;
+ }
tmp = bp;
- if (!consume_keyword(&bp) && (arg = consume_arg(&bp, &end))) {
+ if (!consume_keyword(&bp)
+ && (arg = consume_arg(&bp, &end))) {
info->solidname = strndup(arg, end - arg);
} else {
bp = tmp;
}
break;
case KW_SOLID_END:
- if ((kw = stack_pop(&states)) != STATE_SOLID)
- PARSE_FAIL("Improper nesting, parent: %s\n", kwmap[kw].str);
+ if ((kw = stack_pop(&states)) != STATE_SOLID) {
+ FMT_ERR("Improper nesting, parent: %s\n",
+ kwmap[kw].str);
+ goto format_error;
+ }
tmp = bp;
if (info->solidname && !consume_keyword(&bp)
&& (arg = consume_arg(&bp, &end))) {
- if (strncmp(info->solidname, arg, end - arg))
- PARSE_FAIL("Solid end/begin names do not match!\n");
+ if (strncmp(info->solidname, arg, end - arg)) {
+ FMT_ERR("Solid names do not match!\n");
+ goto format_error;
+ }
} else {
bp = tmp;
}
break;
case KW_LOOP_BEGIN:
stack_push(&states, STATE_LOOP);
- if (stack_ind(&states, KW_LOOP_BEGIN) != -1)
- PARSE_FAIL("Multiple nested loops!\n");
+ if (stack_ind(&states, KW_LOOP_BEGIN) != -1) {
+ FMT_ERR("Multiple nested loops!\n");
+ goto format_error;
+ }
break;
case KW_LOOP_END:
- if ((kw = stack_pop(&states)) != STATE_LOOP)
- PARSE_FAIL("Improper nesting, parent: %s\n", kwmap[kw].str);
+ if ((kw = stack_pop(&states)) != STATE_LOOP) {
+ FMT_ERR("Improper nesting, parent: %s\n",
+ kwmap[kw].str);
+ goto format_error;
+ }
info->loopcount++;
break;
case KW_FACET_BEGIN:
stack_push(&states, STATE_FACET);
- if (stack_ind(&states, KW_LOOP_BEGIN) != -1)
- PARSE_FAIL("Multiple nested facets!\n");
+ if (stack_ind(&states, KW_LOOP_BEGIN) != -1) {
+ FMT_ERR("Multiple nested facets!\n");
+ goto format_error;
+ }
for (i = 0; i < 3; i++) {
- if (!(arg = consume_arg(&bp, &end)))
- PARSE_FAIL("Facet with less than 3 args!\n");
+ if (!(arg = consume_arg(&bp, &end))) {
+ FMT_ERR("Facet with < 3 args!\n");
+ goto format_error;
+ }
farg = strtof(arg, &tmp);
- if (!isws(*tmp))
- PARSE_FAIL("Facet with invalid arg '%s'!\n", arg);
+ if (!isws(*tmp)) {
+ FMT_ERR("Facet arg '%s'\n", arg);
+ goto format_error;
+ }
}
break;
case KW_FACET_END:
- if ((kw = stack_pop(&states)) != STATE_FACET)
- PARSE_FAIL("Improper nesting, parent: %s\n", kwmap[kw].str);
+ if ((kw = stack_pop(&states)) != STATE_FACET) {
+ FMT_ERR("Improper nesting, parent: %s\n",
+ kwmap[kw].str);
+ goto format_error;
+ }
break;
case KW_VERTEX:
for (i = 0; i < 3; i++) {
- if (!(arg = consume_arg(&bp, &end)))
- PARSE_FAIL("Vertex with less than 3 args!\n");
+ if (!(arg = consume_arg(&bp, &end))) {
+ FMT_ERR("Vertex with < 3 args\n");
+ goto format_error;
+ }
farg = strtof(arg, &tmp);
- if (!isws(*tmp))
- PARSE_FAIL("Vertex with invalid arg '%s'!\n", arg);
+ if (!isws(*tmp)) {
+ FMT_ERR("Vertex arg '%s'\n", arg);
+ goto format_error;
+ }
info->bbmin[i] = MIN(info->bbmin[i], farg);
info->bbmax[i] = MAX(info->bbmax[i], farg);
}
break;
case KW_UNKNOWN:
prev = skipws(prev);
- PARSE_FAIL("Expected keyword, got:\n%.*s...\n", 30, prev);
+ FMT_ERR("Expected keyword, got:\n%.*s...\n", 30, prev);
+ goto format_error;
}
prev = bp;
}
- if (states.count)
- PARSE_FAIL("Expected keyword, got:\n%.*s...\n", 30, bp);
+ if (states.count) {
+ FMT_ERR("Expected keyword, got:\n%.*s...\n", 30, bp);
+ goto format_error;
+ }
bp = skipws(bp);
- if (*bp) PARSE_FAIL("Extraneous data at end of file\n");
+ if (*bp) {
+ FMT_ERR("Extraneous data at end of file\n");
+ goto format_error;
+ }
stack_free(&states);
return OK;
-fail:
+format_error:
stack_free(&states);
return FAIL;
}
@@ -223,8 +252,10 @@ parse_file_bin(struct parseinfo *info, char *buf, size_t len)
info->type = TYPE_BIN;
- if (len < 84)
- PARSE_FAIL("Truncated data! (header missing)\n");
+ if (len < 84) {
+ FMT_ERR("Truncated data! (header missing)\n");
+ goto fail;
+ }
memcpy(info->header, buf, 80);
@@ -248,12 +279,16 @@ parse_file_bin(struct parseinfo *info, char *buf, size_t len)
}
for (i = 0; i < info->loopcount; i++) {
- if (bp + 50 > end)
- PARSE_FAIL("Truncated data! (loops missing)\n");
+ if (bp + 50 > end) {
+ FMT_ERR("Truncated data! (loops missing)\n");
+ goto fail;
+ }
for (k = 0; k < 12; k++, bp += 4) {
v = fle32toh(*(float*)bp);
- if (v == INFINITY || v == NAN)
- PARSE_FAIL("Encountered invalid float\n");
+ if (v == INFINITY || v == NAN) {
+ FMT_ERR("Encountered invalid float\n");
+ goto fail;
+ }
if (k >= 3) {
info->bbmin[k % 3] = MIN(info->bbmin[k % 3], v);
info->bbmax[k % 3] = MAX(info->bbmax[k % 3], v);
@@ -262,11 +297,15 @@ parse_file_bin(struct parseinfo *info, char *buf, size_t len)
bp += 2;
}
- if (bp != end) PARSE_FAIL("Extraneous data at end of file\n");
+ if (bp != end) {
+ FMT_ERR("Extraneous data at end of file\n");
+ goto fail;
+ }
return OK;
fail:
+ NFREE(info->solidname);
return FAIL;
}
@@ -277,10 +316,10 @@ parse_file(struct parseinfo *info, char *buf, size_t len)
const char *resp;
char *bp;
- if (info->valid) free_info(info);
+ free_info(info);
if (len < 10) {
- fprintf(stderr, "ERR: File too small!\n");
+ ERR("File too small!\n");
return FAIL;
}
@@ -298,7 +337,7 @@ parse_file(struct parseinfo *info, char *buf, size_t len)
if (!info->modelname) {
resp = ask("Please enter your model name: ");
if (strlen(resp) < 4) {
- fprintf(stderr, "ERR: Model name is too short!\n");
+ ERR("Model name is too short!\n");
return FAIL;
}
info->modelname = checkp(strdup(resp));
@@ -404,9 +443,9 @@ print_info(struct parseinfo *info)
void
free_info(struct parseinfo *info)
{
- NULLFREE(info->hash);
- NULLFREE(info->modelname);
- NULLFREE(info->solidname);
+ NFREE(info->hash);
+ NFREE(info->modelname);
+ NFREE(info->solidname);
info->valid = 0;
}
diff --git a/src/stlfile.h b/src/stlfile.h
@@ -9,6 +9,8 @@
#include "util.h"
+#define FMT_ERR(...) ERR("FORMAT " __VA_ARGS__)
+
enum {
KW_INVALID = -1,
KW_UNKNOWN,
diff --git a/src/util.h b/src/util.h
@@ -11,7 +11,10 @@
#define MIN(x,y) ((x) > (y) ? (y) : (x))
#define MAX(x,y) ((x) < (y) ? (y) : (x))
-#define NULLFREE(p) do { free(p); p = NULL; } while (0)
+#define ERR(...) fprintf(stderr, "ERR: " __VA_ARGS__)
+
+#define NFREE(p) do { free(p); p = NULL; } while (0)
+#define NFCLOSE(f) do { fclose(f); f = NULL; } while (0)
#define MHASHLEN 40