501 lines
10 KiB
C
501 lines
10 KiB
C
/*
|
||
* node_settings.c
|
||
*
|
||
* Created on: 6 июл. 2022 г.
|
||
* Author: alexander
|
||
*/
|
||
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <stdio.h>
|
||
|
||
#include "node_settings.h"
|
||
#include "concat.h"
|
||
#include "db.h"
|
||
|
||
NodeHead settings =
|
||
{ NULL, 0 };
|
||
|
||
static NodeValue* newNodeValue(Value name, char *current, bool set)
|
||
{
|
||
NodeValue *node = (NodeValue*) malloc(sizeof(NodeValue));
|
||
node->name = name;
|
||
node->set = set;
|
||
node->change = false;
|
||
node->next = NULL;
|
||
|
||
node->current = (char*) malloc(sizeof(char) * strlen(current));
|
||
strcpy(node->current, current);
|
||
|
||
return node;
|
||
}
|
||
|
||
static void freeNodeValue(NodeValue *node)
|
||
{
|
||
if (node)
|
||
{
|
||
free(node->current);
|
||
free(node);
|
||
}
|
||
}
|
||
|
||
static void freeAllNodeValue(NodeValue *node)
|
||
{
|
||
NodeValue *next = NULL;
|
||
for (NodeValue *head = node; head; head = next)
|
||
{
|
||
next = head->next;
|
||
freeNodeValue(head);
|
||
}
|
||
}
|
||
|
||
static NodeParameter* newNodeParameter(Parameter name, char *key, bool set, bool singleValue, NodeParameter *dependence, NodeParameter *conflict)
|
||
{
|
||
NodeParameter *node = (NodeParameter*) malloc(sizeof(NodeParameter));
|
||
node->name = name;
|
||
node->set = set;
|
||
node->change = false;
|
||
node->value = NULL;
|
||
node->countValue = 0;
|
||
node->countValueSet = 0;
|
||
node->singleValue = singleValue;
|
||
node->dependence = dependence;
|
||
node->conflict = conflict;
|
||
node->next = NULL;
|
||
|
||
node->key = (char*) malloc(sizeof(char) * strlen(key));
|
||
strcpy(node->key, key);
|
||
|
||
return node;
|
||
}
|
||
|
||
static void freeNodeParameter(NodeParameter *node)
|
||
{
|
||
if (node)
|
||
{
|
||
freeAllNodeValue(node->value);
|
||
free(node->key);
|
||
free(node);
|
||
}
|
||
}
|
||
|
||
static void freeAllNodeParameter(NodeParameter *node)
|
||
{
|
||
NodeParameter *next = NULL;
|
||
for (NodeParameter *head = node; head; head = next)
|
||
{
|
||
next = head->next;
|
||
freeNodeParameter(head);
|
||
}
|
||
}
|
||
|
||
///////////////////////////////
|
||
|
||
static NodeParameter* getLastNodeParameter()
|
||
{
|
||
NodeParameter *head = settings.parameter;
|
||
|
||
if (head)
|
||
{
|
||
while (head->next)
|
||
{
|
||
head = head->next;
|
||
}
|
||
return head;
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
static NodeParameter* getNodeParameter(Parameter name)
|
||
{
|
||
for (NodeParameter *head = settings.parameter; head; head = head->next)
|
||
{
|
||
if (head->name == name)
|
||
{
|
||
return head;
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
NodeValue* getValue(Value name)
|
||
{
|
||
for (NodeParameter *pNode = settings.parameter; pNode; pNode = pNode->next)
|
||
{
|
||
for (NodeValue *vNode = pNode->value; vNode; vNode = vNode->next)
|
||
{
|
||
if (vNode->name == name)
|
||
{
|
||
return vNode;
|
||
}
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
NodeParameter* getParameter(Parameter name)
|
||
{
|
||
for (NodeParameter *head = settings.parameter; head; head = head->next)
|
||
{
|
||
if (head->name == name)
|
||
{
|
||
return head;
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
|
||
void addParameterKey(Parameter name, char *key, bool set, bool singleValue, NodeParameter *dependence, NodeParameter *conflict)
|
||
{
|
||
if (!settings.parameter)
|
||
{
|
||
settings.parameter = newNodeParameter(name, key, set, singleValue, dependence, conflict);
|
||
++settings.countParameter;
|
||
if (set)
|
||
{
|
||
++settings.countParameterSet;
|
||
}
|
||
return;
|
||
}
|
||
|
||
NodeParameter *node = getNodeParameter(name);
|
||
|
||
if (node)
|
||
{
|
||
fprintf(stderr, "%s \"%s\" %s", "Параметр", key, "уже существует!\n");
|
||
}
|
||
else
|
||
{
|
||
node = getLastNodeParameter();
|
||
node->next = newNodeParameter(name, key, set, singleValue, dependence, conflict);
|
||
++settings.countParameter;
|
||
if (set)
|
||
{
|
||
++settings.countParameterSet;
|
||
}
|
||
}
|
||
}
|
||
|
||
static NodeValue* getLastNodeValue(NodeParameter *node)
|
||
{
|
||
NodeValue *head = node->value;
|
||
|
||
if (head)
|
||
{
|
||
while (head->next)
|
||
{
|
||
head = head->next;
|
||
}
|
||
return head;
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
static NodeValue* getNodeValue(NodeParameter *node, Value name)
|
||
{
|
||
for (NodeValue *head = node->value; head; head = head->next)
|
||
{
|
||
if (head->name == name)
|
||
{
|
||
return head;
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
void addParameterValue(Parameter pName, Value vName, char *current, bool set)
|
||
{
|
||
NodeParameter *nodeParameter = getNodeParameter(pName);
|
||
|
||
if (!nodeParameter)
|
||
{
|
||
fprintf(stderr, "%s \"%s\" %s", "Параметр для значения", current, "не существует!\n");
|
||
return;
|
||
}
|
||
|
||
if (!nodeParameter->value)
|
||
{
|
||
nodeParameter->value = newNodeValue(vName, current, set);
|
||
++nodeParameter->countValue;
|
||
if (set)
|
||
{
|
||
++nodeParameter->countValueSet;
|
||
}
|
||
return;
|
||
}
|
||
|
||
NodeValue *nodeValue = getNodeValue(nodeParameter, vName);
|
||
|
||
if (nodeValue)
|
||
{
|
||
fprintf(stderr, "%s \"%s\" %s", "Значение", current, "уже существует!\n");
|
||
}
|
||
else
|
||
{
|
||
nodeValue = getLastNodeValue(nodeParameter);
|
||
nodeValue->next = newNodeValue(vName, current, set);
|
||
++nodeParameter->countValue;
|
||
if (set)
|
||
{
|
||
++nodeParameter->countValueSet;
|
||
}
|
||
}
|
||
}
|
||
|
||
void freeSettings()
|
||
{
|
||
if (settings.parameter)
|
||
{
|
||
freeAllNodeParameter(settings.parameter);
|
||
}
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////
|
||
|
||
NodeValue* getSetNodeValue(NodeParameter *node)
|
||
{
|
||
for (NodeValue *head = node->value; head; head = head->next)
|
||
{
|
||
if (head->set)
|
||
{
|
||
return head;
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////
|
||
|
||
void setParameterValue(Parameter pName, Value vName, char *current)
|
||
{
|
||
NodeParameter *nodeParameter = getNodeParameter(pName);
|
||
|
||
if (!nodeParameter)
|
||
{
|
||
fprintf(stderr, "%s \"%s\" %s", "Параметр для значения", current, "не существует!\n");
|
||
return;
|
||
}
|
||
|
||
size_t length = strlen(current);
|
||
|
||
if (!length)
|
||
{
|
||
if (nodeParameter->set)
|
||
{
|
||
nodeParameter->set = false;
|
||
--settings.countParameterSet;
|
||
}
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
if (!nodeParameter->set)
|
||
{
|
||
nodeParameter->set = true;
|
||
++settings.countParameterSet;
|
||
}
|
||
}
|
||
|
||
if (!nodeParameter->value)
|
||
{
|
||
nodeParameter->value = newNodeValue(vName, current, true);
|
||
++nodeParameter->countValue;
|
||
++nodeParameter->countValueSet;
|
||
return;
|
||
}
|
||
|
||
NodeValue *nodeValue = getNodeValue(nodeParameter, vName);
|
||
|
||
if (nodeValue)
|
||
{
|
||
free(nodeValue->current);
|
||
nodeValue->current = (char*) malloc(sizeof(char) * length);
|
||
strcpy(nodeValue->current, current);
|
||
}
|
||
else
|
||
{
|
||
nodeValue = getLastNodeValue(nodeParameter);
|
||
nodeValue->next = newNodeValue(vName, current, true);
|
||
++nodeParameter->countValue;
|
||
++nodeParameter->countValueSet;
|
||
}
|
||
|
||
changeValue(pName, vName);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////
|
||
|
||
void changeParameter(Parameter name)
|
||
{
|
||
NodeParameter *node = getNodeParameter(name);
|
||
node->change = !node->change;
|
||
|
||
}
|
||
|
||
void setParameter(Parameter name, bool set)
|
||
{
|
||
NodeParameter *node = getNodeParameter(name);
|
||
node->set = set;
|
||
}
|
||
|
||
void changeValue(Parameter pName, Value vName)
|
||
{
|
||
NodeParameter *pNode = getNodeParameter(pName);
|
||
for (NodeValue *head = pNode->value; head; head = head->next)
|
||
{
|
||
if (pNode->singleValue)
|
||
{
|
||
head->change = head->name == vName && !head->set;
|
||
}
|
||
else
|
||
{
|
||
// ДОРАБОТАТЬ НА ИСПОЛЬЗОВАНИЕ МНОГИХ ПАРАМЕТРОВ
|
||
head->change = head->name == vName;
|
||
}
|
||
}
|
||
}
|
||
|
||
static void saveChangeSingleValueSettings(NodeParameter *node)
|
||
{
|
||
NodeValue *nChange = NULL;
|
||
NodeValue *nSet = NULL;
|
||
|
||
for (NodeValue *head = node->value; head; head = head->next)
|
||
{
|
||
if (head->change)
|
||
{
|
||
nChange = head;
|
||
}
|
||
if (head->set)
|
||
{
|
||
nSet = head;
|
||
}
|
||
}
|
||
|
||
if (nChange)
|
||
{
|
||
nChange->change = false;
|
||
nChange->set = true;
|
||
|
||
dbWriteValue(nChange->name, nChange->set);
|
||
|
||
if (nSet)
|
||
{
|
||
nSet->set = false;
|
||
dbWriteValue(nSet->name, nSet->set);
|
||
}
|
||
++node->countValueSet;
|
||
}
|
||
}
|
||
|
||
static void saveChangeValueSettings(NodeParameter *node)
|
||
{
|
||
for (NodeValue *head = node->value; head; head = head->next)
|
||
{
|
||
if (head->change)
|
||
{
|
||
head->change = false;
|
||
head->set = !head->set;
|
||
}
|
||
if (head->set)
|
||
{
|
||
++node->countValueSet;
|
||
}
|
||
}
|
||
}
|
||
|
||
void saveChangeSettings()
|
||
{
|
||
settings.countParameterSet = 0;
|
||
|
||
for (NodeParameter *pHead = settings.parameter; pHead; pHead = pHead->next)
|
||
{
|
||
if (pHead->change)
|
||
{
|
||
pHead->change = false;
|
||
pHead->set = !pHead->set;
|
||
}
|
||
if (pHead->dependence && !pHead->dependence->set)
|
||
{
|
||
pHead->set = false;
|
||
}
|
||
if (pHead->conflict && pHead->conflict->set)
|
||
{
|
||
pHead->set = false;
|
||
}
|
||
if (pHead->set)
|
||
{
|
||
++settings.countParameterSet;
|
||
}
|
||
|
||
dbWriteParameter(pHead->name, pHead->set);
|
||
|
||
pHead->countValueSet = 0;
|
||
|
||
if (pHead->singleValue)
|
||
saveChangeSingleValueSettings(pHead);
|
||
else
|
||
saveChangeValueSettings(pHead);
|
||
}
|
||
}
|
||
|
||
void resetChangeSettings()
|
||
{
|
||
for (NodeParameter *pHead = settings.parameter; pHead; pHead = pHead->next)
|
||
{
|
||
pHead->change = false;
|
||
|
||
for (NodeValue *vHead = pHead->value; vHead; vHead = vHead->next)
|
||
{
|
||
vHead->change = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
bool getSetParameter(Parameter name)
|
||
{
|
||
NodeParameter *node = getNodeParameter(name);
|
||
if (!node)
|
||
{
|
||
return false;
|
||
}
|
||
return node->set;
|
||
}
|
||
|
||
bool getSetValue(Parameter pName, Value vName)
|
||
{
|
||
NodeParameter *pNode = getNodeParameter(pName);
|
||
if (!pNode)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
for (NodeValue *vNode = pNode->value; vNode; vNode = vNode->next)
|
||
{
|
||
if (vNode->name == vName)
|
||
{
|
||
return vNode->set;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
int getCountValue(Parameter name)
|
||
{
|
||
NodeParameter *node = getNodeParameter(name);
|
||
if (!node)
|
||
{
|
||
return -1;
|
||
}
|
||
return node->countValue;
|
||
}
|