]> Nishi Git Mirror - dataworks.git/commitdiff
works
authornishi <nishi@d4a5a174-5a4a-5b4b-b672-37683c10d7d5>
Wed, 5 Jun 2024 01:02:22 +0000 (01:02 +0000)
committernishi <nishi@d4a5a174-5a4a-5b4b-b672-37683c10d7d5>
Wed, 5 Jun 2024 01:02:22 +0000 (01:02 +0000)
git-svn-id: file:///raid/svn-main/nishi-dataworks/trunk@149 d4a5a174-5a4a-5b4b-b672-37683c10d7d5

Client/Makefile
Client/client.c [moved from Client/main.c with 100% similarity]
Document/Doxyfile
Document/index.md
Grammar/dw.y
Library/dw_parser.h
Library/exec.c
Library/parser.c

index d8cdf174e73f14588b215a94dcdc87df13d3292c..208403f0ab4acf23feda25dbf03a1a62fc9c280e 100644 (file)
@@ -3,7 +3,7 @@
 .PHONY: all clean
 .SUFFIXES: .c .o
 
-OBJS = main.o
+OBJS = client.o
 
 all: dataworks$(EXEC_SUFFIX)
 
similarity index 100%
rename from Client/main.c
rename to Client/client.c
index 993997fddf3b06995cbde897c1fd84b2392792e8..862e7f3e77cc269fd5839886d90f7e8ad74a4b4a 100644 (file)
@@ -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
index a6793e62fe6242646fea66363565742f1cd585af..a5e62d7d9adaf89b4ef667a05ef5232c83a4ab6c 100644 (file)
@@ -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 &lt;nishi@nishi.boats&gt;
+
+@example client.c
index 1222225e874b072d1806c850b0f5d52d15db1784..3509483fc9e287d11c9e1ef033b15230d1efab48 100644 (file)
@@ -38,6 +38,7 @@
        struct Node {
                char* string;
                char* ident;
+               int errnum;
                struct Node** nodes;
        } node;
 }
index 7bdd7a75529be8ace3a3f7c02acfbf9b303861a9..2476faef7702a95b155500bc86dd801776183899 100644 (file)
@@ -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
 }
index bd6b84e831ccf8e79022b51507437642e4f7116d..58099ad7c8da967df92e163ce9112e56f86634f3 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "dw_database.h"
 
+#include "dataworks.h"
 #include "dw_parser.h"
 #include "dw_util.h"
 
 #include <stdlib.h>
 #include <string.h>
 
-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;
index a251f332556fd4b26f22dd97dfc85e3bee32a155..70040253b8e343c5c34aae3f27984b0f626d97fb 100644 (file)
@@ -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");
+       }
 }