diff --git a/include/parsing.h b/include/parsing.h new file mode 100644 index 0000000..3e28962 --- /dev/null +++ b/include/parsing.h @@ -0,0 +1,31 @@ +//=-------------------------------------------------------------------------=// +// XML parsing module // +// // +// Copyright © 2021 The Gem-graph Project // +// // +// This file is part of gem-graph. // +// // +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the GNU Affero General Public License as // +// published by the Free Software Foundation, either version 3 of the // +// License, or (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU Affero General Public License for more details. // +// // +// You should have received a copy of the GNU Affero General Public License // +// along with this program. If not, see . // +//=-------------------------------------------------------------------------=// + +#pragma once +#ifndef BASE_H + #include "../include/base.h" +#endif + +/* -------------------------------------------------------------------------- */ + +int ParseModelXML(Model_t*); + +/* -------------------------------------------------------------------------- */ diff --git a/src/parsing.c b/src/parsing.c new file mode 100644 index 0000000..4a9e4e7 --- /dev/null +++ b/src/parsing.c @@ -0,0 +1,137 @@ +//=-------------------------------------------------------------------------=// +// XML parsing module // +// // +// Copyright © 2021 The Gem-graph Project // +// // +// This file is part of gem-graph. // +// // +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the GNU Affero General Public License as // +// published by the Free Software Foundation, either version 3 of the // +// License, or (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU Affero General Public License for more details. // +// // +// You should have received a copy of the GNU Affero General Public License // +// along with this program. If not, see . // +//=-------------------------------------------------------------------------=// + +#include "../include/base.h" + +#include +#include +#include +#include + +/* -------------------------------------------------------------------------- */ + +static int parseIdentityXML(Model_t*, xmlDocPtr, xmlNodePtr); + static int parseIdentityNameXML(Model_t*, xmlDocPtr, xmlNodePtr); + +// Table of all parsers +struct parserTableXML_t { + const xmlChar *tag; + int (*execute) (Model_t*, xmlDocPtr, xmlNodePtr); +} typedef ParserTableXML_t; + +static ParserTableXML_t toplevelParserTableXML[] = +{ + {(const xmlChar *)"identity", parseIdentityXML}, +}; + +static ParserTableXML_t identityParserTableXML[] = +{ + {(const xmlChar *)"name", parseIdentityChildren}, + {(const xmlChar *)"author", parseIdentityChildren}, + {(const xmlChar *)"author_id", parseIdentityChildren}, + {(const xmlChar *)"date", parseIdentityChildren}, + {(const xmlChar *)"version", parseIdentityChildren}, +}; + +/* -------------------------------------------------------------------------- */ + +static int parseIdentityNameXML (Model_t *model, xmlDocPtr doc, + xmlNodePtr currentNode) +{ + xmlChar *key; + key = xmlNodeListGetString(doc, currentNode->xmlChildrenNode, 1); + printLog("key: %s\n", key); + xmlFree(key); + return 0; +} + +static int parseIdentityXML (Model_t *model, xmlDocPtr doc, + xmlNodePtr currentNode) +{ + xmlChar *key; + currentNode = currentNode->xmlChildrenNode; + while (currentNode != NULL) { + for (int i = 0; i < LEN(identityParserTableXML); i++) { + if ((!xmlStrcmp(currentNode->name, + identityParserTableXML[i].tag))) { + identityParserTableXML[i].execute(model, + doc, + currentNode); + } + } + currentNode = currentNode->next; + } + return 0; +} + +int ParseModelXML(Model_t *model) +{ + printLog("Parsing model %s\n", model->name); + xmlDocPtr xmlDocument; + xmlNodePtr currentNode; + + xmlDocument = xmlParseFile(model->filename); + + if (xmlDocument == NULL) { + printLog("Can't parse model file at '%s'.\n", model->filename); + return -1; + } + + currentNode = xmlDocGetRootElement(xmlDocument); + + if (currentNode == NULL) { + printLog("Invalid model file at '%s', document empty !\n", + model->filename); + xmlFreeDoc(xmlDocument); + return -2; + } + + if (xmlStrcmp(currentNode->name, (const xmlChar *) "gem-graph-model")) { + printLog("Invalid model file at '%s', " + "root node is not !\n", + model->filename); + xmlFreeDoc(xmlDocument); + return -3; + } + + currentNode = currentNode->xmlChildrenNode; + while (currentNode != NULL) { + for (int i = 0; i < LEN(toplevelParserTableXML); i++) { + if ((!xmlStrcmp(currentNode->name, + toplevelParserTableXML[i].tag))) { + toplevelParserTableXML[i].execute(model, + xmlDocument, + currentNode); + } + } + + currentNode = currentNode->next; + } + + xmlFreeDoc(xmlDocument); + + // Interpret what needs to be + //model->date = strtol(date, NULL, 0); + + // validate when we're finished + // model->validated = true; + return 0; +}