WIP: Crushing and rebuilding from the ground an XML parser

This commit is contained in:
Adrien Bourmault 2021-09-15 18:25:35 +02:00
parent d8f83d86c5
commit b267fc5a09
No known key found for this signature in database
GPG Key ID: 6EB408FE0ACEC664
19 changed files with 28 additions and 248 deletions

View File

@ -29,7 +29,7 @@ DEBDIR=debian
SERVEROBJ= $(BINDIR)/scheduler.o $(BINDIR)/server.o $(BINDIR)/worker.o \
$(BINDIR)/centers.o $(BINDIR)/cmds.o $(BINDIR)/model.o \
$(BINDIR)/main.o $(BINDIR)/arrows.o
$(BINDIR)/main.o $(BINDIR)/arrows.o $(BINDIR)/parsing.o
CLIOBJ= $(BINDIR)/cli.o
SRCS=$(patsubst $(BINDIR)/%.o,$(SRCDIR)/%.c,$(SERVEROBJ)) \

View File

@ -9,7 +9,7 @@
<name>Modèle de test</name>
<author>Adrien Bourmault</author>
<author_id>1</author_id>
<date>1629822515</date> <!-- TODO timestamp ? -->
<date>1629822515</date>
<version>1.0</version>
</identity>
@ -18,7 +18,7 @@
<parameters id="" date="" author="">
<modelization>
<max_thread value="0"/>
<max_cycles value="13"/>
<max_cycle value="13"/>
</modelization>
@ -26,7 +26,7 @@
<dimension value="2"/>
<size x="" y="" z=""/>
<site_multiplicity value="2"/>
<boundaries/> <!-- TODO -->
<!-- <boundaries/>, TODO -->
</space>

View File

@ -19,6 +19,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#pragma once
#ifndef BASE_H
#include "../include/base.h"
#endif

View File

@ -19,6 +19,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#pragma once
#ifndef BASE_H
#include "../include/base.h"
#endif

View File

@ -19,6 +19,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#pragma once
#ifndef BASE_H
#include "../include/base.h"
#endif

View File

@ -19,6 +19,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#pragma once
#ifndef BASE_H
#include "../include/base.h"
#endif

View File

@ -19,6 +19,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#pragma once
#ifndef BASE_H
#include "../include/base.h"
#endif

View File

@ -19,6 +19,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#pragma once
#ifndef BASE_H
#include "../include/base.h"
#endif

View File

@ -19,6 +19,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#pragma once
#ifndef BASE_H
#include "../include/base.h"
#endif

View File

@ -19,6 +19,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#pragma once
#ifndef BASE_H
#include "../include/base.h"
#endif

View File

@ -19,6 +19,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#pragma once
#ifndef BASE_H
#include "../include/base.h"
#endif

View File

@ -19,6 +19,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#pragma once
#ifndef BASE_H
#include "../include/base.h"
#endif
@ -30,181 +31,4 @@
#include <libxml2/libxml/xmlmemory.h>
#include <libxml2/libxml/parser.h>
/* -------------------------------------------------------------------------- */
static xmlDocPtr currentDocument = NULL;
static xmlNodePtr currentDocumentRoot = NULL;
/* -------------------------------------------------------------------------- */
// -------------------------------------------------------------------------- //
// Open and set a document as current document //
// -------------------------------------------------------------------------- //
static inline void XmlSetNewDocument(const char *filename)
{
currentDocument = xmlParseFile(filename);
if (currentDocument == NULL ) {
printLog("%s not parsed successfully.\n", filename);
xmlFreeDoc(currentDocument);
currentDocument = NULL;
return;
}
currentDocumentRoot = xmlDocGetRootElement(currentDocument);
if (currentDocumentRoot == NULL ) {
printLog("%s is invalid (no root)\n", filename);
xmlFreeDoc(currentDocument);
currentDocument = NULL;
currentDocumentRoot = NULL;
return;
}
}
// -------------------------------------------------------------------------- //
// Close and unset current document //
// -------------------------------------------------------------------------- //
static inline void XmlCloseCurrentDocument(void)
{
xmlFreeDoc(currentDocument);
currentDocumentRoot = NULL;
currentDocument = NULL;
}
// -------------------------------------------------------------------------- //
// Reset current working root to document root //
// -------------------------------------------------------------------------- //
static inline void XmlResetWorkingRoot(void)
{
currentDocumentRoot = xmlDocGetRootElement(currentDocument);
}
// -------------------------------------------------------------------------- //
// Parse content of a given XML tag //
// -------------------------------------------------------------------------- //
static inline int XmlParseTag(const char* tagName, char *destination,
char destSize)
{
char *curString;
size_t cursor = 0;
char res = 0;
xmlNodePtr cur = currentDocumentRoot;
//printLog("Asked for %s\n", tagName);
// Enumerate all brothers in tree from current root
while (cur != NULL) {
//printLog("\tGot %s (res = %d)\n", cur->name, res);
// Check if current tag is the asked tag
if ((!xmlStrcmp(cur->name, (const xmlChar *)tagName))) {
//printLog("\tFound %s\n", cur->name);
curString = (char*)xmlNodeListGetString(currentDocument,
cur->xmlChildrenNode, 1);
//printLog("\t\tString : %s\n", curString);
// Check there is text in that tag (and that is asked)
if (destination && curString[0] != '\n') {
cursor =
snprintf(
destination + cursor * sizeof(char),
destSize,
"%s\n",
curString);
res++;
}
free(curString);
}
cur = cur->next;
}
return res;
}
// -------------------------------------------------------------------------- //
// Find a working root for a given tag //
// -------------------------------------------------------------------------- //
static inline xmlNodePtr findWorkingRoot(const char *tagName,
xmlNodePtr curRoot)
{
xmlNodePtr cur = curRoot;
xmlNodePtr recur;
//printLog("Asked for %s\n", tagName);
while (cur != NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *)tagName))){
currentDocumentRoot = cur;
return cur;
}
if (cur->xmlChildrenNode) {
if ((recur =
findWorkingRoot(tagName,
(xmlNodePtr)cur->xmlChildrenNode)) != NULL)
return recur;
}
cur = cur->next;
}
return NULL;
}
// -------------------------------------------------------------------------- //
// Parse and validate an XML tree from given structural tree //
// and current document //
// -------------------------------------------------------------------------- //
static inline int XmlParseTree(ModelField_t *curTree)
{
int currentOrSonCorrectlyParsed = 0;
int curValueLen;
while (curTree) {
if (findWorkingRoot(
curTree->tag,
currentDocumentRoot->parent
) == NULL) {
printLog("Error : can't find a new root\n");
return EBADF;
}
//printLog("Asked for %s\n", curTree->tag);
// Try to parse current tag
if (XmlParseTag(curTree->tag, curTree->destination,
curTree->size) != 0) {
// There are values in that tag
if (curTree->destination[0])
if (!(curTree->destination[0] == '\0')) {
curValueLen = strlen(curTree->destination);
// Delete \n chars
for(int i = 0; i < curValueLen; i++) {
if(curTree->destination[i] == '\n') {
memmove(&curTree->destination[i],
&curTree->destination[i+1],
curValueLen - i);
curValueLen--;
i--;
}
}
printLog("Field %s: %s\n", curTree->tag, curTree->destination);
}
} else {
// There aren't values in that tag
if (curTree->mandatory) {
// But it was mandatory
printLog("Error : can't find %s\n", curTree->tag);
return EBADF;
}
}
if (curTree->son)
currentOrSonCorrectlyParsed |= XmlParseTree(curTree->son);
curTree = curTree->next;
}
return currentOrSonCorrectlyParsed;
}

View File

@ -44,6 +44,8 @@
#define KEY_BACKSPACE 127
#define KEY_DELETE 126 // accessible after sequence KEY_ESCAPE_1, 2, 3
/* -------------------------------------------------------------------------- */
//
// Print monitor screen
//

View File

@ -23,6 +23,8 @@
#include "../include/server.h"
#include "../include/model.h"
/* -------------------------------------------------------------------------- */
static Server_t *server;
static void SigIntTermHandler(int signum)

View File

@ -20,7 +20,7 @@
//=-------------------------------------------------------------------------=//
#include "../include/base.h"
#include "../include/xml.h"
#include "../include/parsing.h"
#include "../include/arrows.h"
#include "../include/scheduler.h"
@ -50,8 +50,6 @@ static int knownModelSize; // begins to 1
Model_t *lastModel;
Model_t **lastModelAddr;
static inline int ModelParseFile(Model_t *model);
void ModelSystemDestroy(void);
/* -------------------------------------------------------------------------- */
@ -293,7 +291,7 @@ void ModelSystemInit(Parameters_t *parameters)
extensionPosition - modelDirEntry->d_name);
// Ask to parse the new model
if (ModelParseFile(newModel) != 0) {
if (ParseModelXML(newModel) != 0) {
ModelDelete(newModel->id);
continue;
};
@ -338,66 +336,3 @@ static inline void CreateField(ModelField_t *modelField,
modelField->son = son;
modelField->next = next;
}
static inline int ModelParseFile(Model_t *model)
{
char date[25];
ModelField_t identityField;
ModelField_t identityNameField;
ModelField_t identityAuthorField;
ModelField_t identityDateField;
ModelField_t identityVersionField;
ModelField_t parametersField;
ModelField_t parametersModelizationField;
ModelField_t parametersSpaceField;
CreateField(&identityField,
"identity", false, NULL, 0, &identityNameField, NULL);
CreateField(&identityNameField,
"name", true, model->name, MAX_MODEL_NAME_SIZE,
NULL, &identityAuthorField);
CreateField(&identityAuthorField,
"author", true, model->author, MAX_AUTHOR_NAME_SIZE,
NULL, &identityDateField);
CreateField(&identityDateField,
"date", true, date, 25,
NULL, &identityVersionField);
CreateField(&identityVersionField,
"version", true, model->version, MAX_VERSION_SIZE, NULL, NULL);
CreateField(&parametersField,
"parameters", false, NULL, 0, NULL, NULL);
CreateField(&parametersModelizationField,
"modelization", false, NULL, 0, NULL, NULL);
CreateField(&parametersSpaceField,
"space", false, NULL, 0, NULL, NULL);
// TODO modify model according to things in file
printLog("Parsing model %s\n", model->name);
XmlSetNewDocument(model->filename);
XmlResetWorkingRoot();
XmlCloseCurrentDocument();
if (XmlParseTree(&identityField) != 0) {
printLog("Invalid document, parsing can't succeed!\n");
return EBADF;
}
// Interpret what needs to be
model->date = strtol(date, NULL, 0);
// validate when we're finished
model->validated = true;
return 0;
}

View File

@ -26,6 +26,8 @@
#include <sys/sysinfo.h>
/* -------------------------------------------------------------------------- */
static void *schedulerMain(void *scheduler);
/* -------------------------------------------------------------------------- */

View File

@ -29,6 +29,8 @@
#include <fcntl.h>
#include <errno.h>
/* -------------------------------------------------------------------------- */
static void *serverMain(void *server);
/* -------------------------------------------------------------------------- */

View File

@ -21,6 +21,8 @@
#include "../include/base.h"
/* -------------------------------------------------------------------------- */
static void *supervisorMain(void *supervisor);
/* -------------------------------------------------------------------------- */

View File

@ -21,6 +21,8 @@
#include "../include/base.h"
/* -------------------------------------------------------------------------- */
static void *WorkerMain(void *worker);
/* -------------------------------------------------------------------------- */