From: nishi Date: Wed, 5 Jun 2024 01:02:22 +0000 (+0000) Subject: works X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=d1ff7fee9829ad82539a525d8c33bd3e0b41204a;p=dataworks.git works git-svn-id: file:///raid/svn-main/nishi-dataworks/trunk@149 d4a5a174-5a4a-5b4b-b672-37683c10d7d5 --- diff --git a/Client/Makefile b/Client/Makefile index d8cdf17..208403f 100644 --- a/Client/Makefile +++ b/Client/Makefile @@ -3,7 +3,7 @@ .PHONY: all clean .SUFFIXES: .c .o -OBJS = main.o +OBJS = client.o all: dataworks$(EXEC_SUFFIX) diff --git a/Client/main.c b/Client/client.c similarity index 100% rename from Client/main.c rename to Client/client.c diff --git a/Document/Doxyfile b/Document/Doxyfile index 993997f..862e7f3 100644 --- a/Document/Doxyfile +++ b/Document/Doxyfile @@ -31,3 +31,7 @@ OUTPUT_LANGUAGE = English GENERATE_LATEX = NO HTML_EXTRA_STYLESHEET = doxygen-theme/doxygen-awesome.css HTML_COLORSTYLE = LIGHT + +EXAMPLE_PATH = ../Client +EXAMPLE_RECURSIVE = YES +EXAMPLE_PATTERNS = *.c diff --git a/Document/index.md b/Document/index.md index a6793e6..a5e62d7 100644 --- a/Document/index.md +++ b/Document/index.md @@ -7,3 +7,5 @@ **DataWorks** is free software, and sources are published under 3-clause BSD License by Crabware. Crabware is a software-development division of Hinode Gakuen PC-Club. Contact: Nishi <nishi@nishi.boats> + +@example client.c diff --git a/Grammar/dw.y b/Grammar/dw.y index 1222225..3509483 100644 --- a/Grammar/dw.y +++ b/Grammar/dw.y @@ -38,6 +38,7 @@ struct Node { char* string; char* ident; + int errnum; struct Node** nodes; } node; } diff --git a/Library/dw_parser.h b/Library/dw_parser.h index 7bdd7a7..2476fae 100644 --- a/Library/dw_parser.h +++ b/Library/dw_parser.h @@ -45,6 +45,10 @@ extern "C" { #include "../Grammar/dw.tab.h" struct Node* __dw_parser_parse(const char* str, bool top); +struct Node* __dw_duplicate_node(struct Node* node); +void __dw_free_node(struct Node* node); +void __dw_free_node2(struct Node* node, bool top); +void __dw_print_node(struct Node* node, bool top); #ifdef __cplusplus } diff --git a/Library/exec.c b/Library/exec.c index bd6b84e..58099ad 100644 --- a/Library/exec.c +++ b/Library/exec.c @@ -28,6 +28,7 @@ #include "dw_database.h" +#include "dataworks.h" #include "dw_parser.h" #include "dw_util.h" @@ -35,26 +36,145 @@ #include #include -void print_node(struct Node* node, bool top) { - printf("%s(", node->ident); - if(node->nodes != NULL) { +struct Node* parser_process(struct dataworks_db* db, struct Node* node, bool dolog) { + if(node->ident != NULL) { + if(dolog) __dw_print_node(node, true); int i; - for(i = 0; node->nodes[i] != NULL; i++) { - if(i > 0) printf(", "); - if(node->nodes[i]->ident != NULL) { - print_node(node->nodes[i], false); + struct Node* newnode = malloc(sizeof(*newnode)); + newnode->ident = NULL; + newnode->string = NULL; + newnode->nodes = NULL; + newnode->errnum = DW_ERR_SUCCESS; + char** fields = malloc(sizeof(*fields)); + fields[0] = NULL; + char* fieldtypes = malloc(1); + fieldtypes[0] = 0; + char* name = NULL; + if(__dw_strcaseequ(node->ident, "version")) { + newnode->string = __dw_strdup(dataworks_get_version()); + } + if(node->nodes != NULL) { + for(i = 0; node->nodes[i] != NULL; i++) { + struct Node* r = parser_process(db, node->nodes[i], false); + if(r->errnum != DW_ERR_SUCCESS) { + newnode->errnum = r->errnum; + __dw_free_node(r); + int j; + for(j = 0; fields[j] != NULL; j++) free(fields[j]); + free(fields); + free(fieldtypes); + if(name != NULL) free(name); + return newnode; + } + if(__dw_strcaseequ(node->ident, "print")) { + if(r->string != NULL) { + printf("%s", r->string); + } + fflush(stdout); + } else if(__dw_strcaseequ(node->ident, "concat")) { + if(r->string != NULL) { + if(newnode->string == NULL) { + newnode->string = malloc(1); + newnode->string[0] = 0; + } + char* tmp = newnode->string; + newnode->string = __dw_strcat(tmp, r->string); + free(tmp); + } + } else if(__dw_strcaseequ(node->ident, "use")) { + if(name != NULL) { + newnode->errnum = DW_ERR_EXEC_TOO_MANY_ARGUMENTS; + __dw_free_node(r); + int j; + for(j = 0; fields[j] != NULL; j++) free(fields[j]); + free(fields); + free(fieldtypes); + if(name != NULL) free(name); + return newnode; + } + if(name == NULL) { + name = __dw_strdup(r->string); + } + } else if(__dw_strcaseequ(node->ident, "create_table")) { + if(name == NULL) { + name = __dw_strdup(r->string); + } else { + char* val = __dw_strdup(r->string); + int j; + char cbuf[2]; + cbuf[1] = 0; + for(j = 0; val[j] != 0; j++) { + if(val[j] == ':') { + val[j] = 0; + cbuf[0] = 0; + if(__dw_strcaseequ(val, "string")) { + cbuf[0] = DW_RECORD_STRING; + } else if(__dw_strcaseequ(val, "integer")) { + cbuf[0] = DW_RECORD_INTEGER; + } else if(__dw_strcaseequ(val, "floating")) { + cbuf[0] = DW_RECORD_FLOATING; + } else if(__dw_strcaseequ(val, "logical")) { + cbuf[0] = DW_RECORD_LOGICAL; + } else if(__dw_strcaseequ(val, "help")) { + cbuf[0] = DW_RECORD_HELP; + } + char* tmp = fieldtypes; + fieldtypes = __dw_strcat(tmp, cbuf); + free(tmp); + + char** oldfields = fields; + int k; + for(k = 0; oldfields[k] != NULL; k++) + ; + fields = malloc(sizeof(*fields) * (k + 2)); + for(k = 0; oldfields[k] != NULL; k++) { + fields[k] = oldfields[k]; + } + fields[k] = __dw_strdup(val + j + 1); + fields[k + 1] = NULL; + break; + } + } + free(val); + } + } else { + int j; + for(i = 0; fields[i] != NULL; i++) free(fields[i]); + free(fields); + free(fieldtypes); + if(name != NULL) free(name); + newnode->errnum = DW_ERR_EXEC_UNKNOWN_METHOD; + __dw_free_node(r); + return newnode; + } + __dw_free_node(r); + } + } + if(__dw_strcaseequ(node->ident, "create_table")) { + if(name != NULL) { + newnode->errnum = dataworks_database_create_table(db, name, fields, fieldtypes); + } else { + newnode->errnum = DW_ERR_EXEC_INSUFFICIENT_ARGUMENTS; + } + } else if(__dw_strcaseequ(node->ident, "print")) { + printf("\n"); + } else if(__dw_strcaseequ(node->ident, "use")) { + if(name != NULL) { + newnode->errnum = dataworks_database_use_table(db, name); + if(dolog) printf("Using table `%s`.\n", name); } else { - printf("\"%s\"", node->nodes[i]->string); + newnode->errnum = DW_ERR_EXEC_INSUFFICIENT_ARGUMENTS; } } - } - printf(")"); - if(top) printf("\n"); -} - -void parser_process(struct Node* node, bool dolog) { - if(node->ident != NULL) { - if(dolog) print_node(node, true); + if(name != NULL) free(name); + for(i = 0; fields[i] != NULL; i++) free(fields[i]); + free(fields); + free(fieldtypes); + return newnode; + } else { + struct Node* n = __dw_duplicate_node(node); + n->errnum = DW_ERR_SUCCESS; + return n; } } @@ -67,8 +187,16 @@ struct dataworks_db_result* dataworks_database_execute_code(struct dataworks_db* if((node = __dw_parser_parse(code, dolog)) == NULL) { r->error = true; r->errnum = DW_ERR_PARSER_FAIL; - }else{ - parser_process(node, dolog); + } else { + struct Node* ret = parser_process(db, node, dolog); + if(ret->errnum == DW_ERR_SUCCESS) { + __dw_print_node(ret, true); + } else { + r->error = true; + r->errnum = ret->errnum; + } + __dw_free_node(ret); + __dw_free_node(node); } return r; diff --git a/Library/parser.c b/Library/parser.c index a251f33..7004025 100644 --- a/Library/parser.c +++ b/Library/parser.c @@ -49,12 +49,73 @@ struct Node* __dw_parser_parse(const char* str, bool top) { yydebug = 1; #endif + struct Node* rnode; void* buf = yy_scan_string(str); if(yyparse() != 0) { yy_delete_buffer(buf); return NULL; } + rnode = __dw_duplicate_node(&yyval.node); + __dw_free_node2(&yyval.node, true); yy_delete_buffer(buf); - return &yyval.node; + return rnode; +} + +struct Node* __dw_duplicate_node(struct Node* node) { + struct Node* r = malloc(sizeof(*r)); + r->ident = NULL; + r->string = NULL; + r->nodes = NULL; + if(node->ident != NULL) r->ident = __dw_strdup(node->ident); + if(node->string != NULL) r->string = __dw_strdup(node->string); + if(node->nodes != NULL) { + int i; + for(i = 0; node->nodes[i] != NULL; i++) + ; + r->nodes = malloc(sizeof(*r->nodes) * (i + 1)); + for(i = 0; node->nodes[i] != NULL; i++) { + r->nodes[i] = __dw_duplicate_node(node->nodes[i]); + } + r->nodes[i] = NULL; + } + return r; +} + +void __dw_free_node(struct Node* node) { __dw_free_node2(node, false); } + +void __dw_free_node2(struct Node* node, bool top) { + if(node->ident != NULL) free(node->ident); + if(node->string != NULL) free(node->string); + if(node->nodes != NULL) { + int i; + for(i = 0; node->nodes[i] != NULL; i++) { + __dw_free_node2(node->nodes[i], false); + } + } + if(!top) free(node); +} + +void __dw_print_node(struct Node* node, bool top) { + if(node->string != NULL) { + printf("\"%s\"", node->string); + fflush(stdout); + if(top) printf("\n"); + } else if(node->ident != NULL) { + printf("%s(", node->ident); + fflush(stdout); + if(node->nodes != NULL) { + int i; + for(i = 0; node->nodes[i] != NULL; i++) { + if(i > 0) { + printf(", "); + fflush(stdout); + } + __dw_print_node(node->nodes[i], false); + } + } + printf(")"); + fflush(stdout); + if(top) printf("\n"); + } }