trigger_checker.c 12.5 KB
Newer Older
Z
zhong_ning 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "trigger_checker.h"
#include <ctype.h>
S
sun_fan 已提交
18

Z
zhong_ning 已提交
19
#include "init_param.h"
S
sun_fan 已提交
20
#include "trigger_manager.h"
Z
zhong_ning 已提交
21

S
sun_fan 已提交
22
#define MAX_CALC_PARAM 100
Z
zhong_ning 已提交
23
#define LABEL "Trigger"
Z
zhong_ning 已提交
24 25 26
// 申请整块能存作为计算的节点
int CalculatorInit(LogicCalculator *calculator, int dataNumber, int dataUnit, int needCondition)
{
Z
zhong_ning 已提交
27
    PARAM_CHECK(calculator != NULL, return -1, "Invalid param");
Z
zhong_ning 已提交
28 29
    int dataSize = dataUnit * dataNumber;
    if (needCondition) {
S
sun_fan 已提交
30
        dataSize += MAX_DATA_BUFFER_MAX;
Z
zhong_ning 已提交
31 32
    }
    calculator->data = (char *)malloc(dataSize);
Z
zhong_ning 已提交
33
    PARAM_CHECK(calculator->data != NULL, return -1, "Failed to malloc for calculator");
Z
zhong_ning 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47
    calculator->dataNumber = dataNumber;
    calculator->endIndex = 0;
    calculator->dataUnit = dataUnit;

    dataSize = dataUnit * dataNumber;
    calculator->conditionName = calculator->data + dataSize;
    dataSize += SUPPORT_DATA_BUFFER_MAX;
    calculator->conditionContent = calculator->data + dataSize;
    dataSize += SUPPORT_DATA_BUFFER_MAX;
    calculator->inputName = calculator->data + dataSize;
    dataSize += SUPPORT_DATA_BUFFER_MAX;
    calculator->inputContent = calculator->data + dataSize;
    dataSize += SUPPORT_DATA_BUFFER_MAX;
    calculator->readContent = calculator->data + dataSize;
Z
zhong_ning 已提交
48 49
    return memset_s(calculator->triggerContent,
        sizeof(calculator->triggerContent), 0, sizeof(calculator->triggerContent));
Z
zhong_ning 已提交
50 51 52 53
}

void CalculatorFree(LogicCalculator *calculator)
{
Z
zhong_ning 已提交
54
    PARAM_CHECK(calculator != NULL, return, "Invalid param");
Z
zhong_ning 已提交
55 56 57 58 59 60
    free(calculator->data);
    calculator->data = NULL;
}

static void CalculatorClear(LogicCalculator *calculator)
{
Z
zhong_ning 已提交
61
    PARAM_CHECK(calculator != NULL, return, "Invalid param");
Z
zhong_ning 已提交
62 63 64 65 66
    calculator->endIndex = 0;
}

static int CalculatorPushChar(LogicCalculator *calculator, char data)
{
Z
zhong_ning 已提交
67 68 69
    PARAM_CHECK(calculator != NULL, return -1, "Invalid param");
    PARAM_CHECK(calculator->endIndex < calculator->dataNumber, return -1, "More data for calculator support");
    PARAM_CHECK(sizeof(char) == calculator->dataUnit, return -1, "More data for calculator support");
Z
zhong_ning 已提交
70 71 72 73 74 75
    calculator->data[calculator->endIndex++] = data;
    return 0;
}

static int CalculatorPopChar(LogicCalculator *calculator, char *data)
{
Z
zhong_ning 已提交
76 77
    PARAM_CHECK(calculator != NULL, return -1, "Invalid param");
    PARAM_CHECK(calculator->endIndex < calculator->dataNumber, return -1, "More data for calculator support");
Z
zhong_ning 已提交
78 79 80 81 82 83 84
    if (calculator->endIndex == 0) {
        return -1;
    }
    *data = calculator->data[--calculator->endIndex];
    return 0;
}

S
sun_fan 已提交
85
static int CalculatorPush(LogicCalculator *calculator, const void *data)
Z
zhong_ning 已提交
86
{
Z
zhong_ning 已提交
87 88
    PARAM_CHECK(calculator != NULL, return -1, "Invalid param");
    PARAM_CHECK(calculator->endIndex < calculator->dataNumber, return -1, "More data for calculator support");
Z
zhong_ning 已提交
89 90
    char *tmpData = (calculator->data + calculator->dataUnit * calculator->endIndex);
    int ret = memcpy_s(tmpData, calculator->dataUnit, data, calculator->dataUnit);
S
sun_fan 已提交
91
    PARAM_CHECK(ret == EOK, return -1, "Failed to copy logic data");
Z
zhong_ning 已提交
92 93 94 95 96 97
    calculator->endIndex++;
    return 0;
}

static int CalculatorPop(LogicCalculator *calculator, void *data)
{
S
sun_fan 已提交
98
    PARAM_CHECK(calculator != NULL && data != NULL, return -1, "Invalid param");
Z
zhong_ning 已提交
99
    PARAM_CHECK(calculator->endIndex < calculator->dataNumber, return -1, "More data for calculator support");
Z
zhong_ning 已提交
100 101 102 103 104
    if (calculator->endIndex == 0) {
        return -1;
    }
    char *tmpData = calculator->data + calculator->dataUnit * (calculator->endIndex - 1);
    int ret = memcpy_s(data, calculator->dataUnit, tmpData, calculator->dataUnit);
S
sun_fan 已提交
105
    PARAM_CHECK(ret == EOK, return -1, "Failed to copy logic data");
Z
zhong_ning 已提交
106 107 108 109 110 111
    calculator->endIndex--;
    return 0;
}

static int CalculatorLength(const LogicCalculator *calculator)
{
Z
zhong_ning 已提交
112
    PARAM_CHECK(calculator != NULL, return 0, "Invalid param");
Z
zhong_ning 已提交
113 114 115
    return calculator->endIndex;
}

S
sun_fan 已提交
116
static int PrefixAdd(char *prefix, uint32_t *prefixIndex, uint32_t prefixLen, char op)
Z
zhong_ning 已提交
117
{
S
sun_fan 已提交
118
    if ((*prefixIndex + 1 + 1 + 1) >= prefixLen) {
Z
zhong_ning 已提交
119 120 121 122 123 124 125 126
        return -1;
    }
    prefix[(*prefixIndex)++] = ' ';
    prefix[(*prefixIndex)++] = op;
    prefix[(*prefixIndex)++] = ' ';
    return 0;
}

S
sun_fan 已提交
127
static int HandleOperationOr(LogicCalculator *calculator, char *prefix, uint32_t *prefixIndex, uint32_t prefixLen)
Z
zhong_ning 已提交
128 129 130 131
{
    int ret = 0;
    char e;
    prefix[(*prefixIndex)++] = ' ';
S
sun_fan 已提交
132
    if (CalculatorLength(calculator) == 0) {
Z
zhong_ning 已提交
133 134 135 136 137 138 139 140
        CalculatorPushChar(calculator, '|');
    } else {
        do {
            CalculatorPopChar(calculator, &e);
            if (e == '(') {
                CalculatorPushChar(calculator, e);
            } else {
                ret = PrefixAdd(prefix, prefixIndex, prefixLen, e);
Z
zhong_ning 已提交
141
                PARAM_CHECK(ret == 0, return -1, "Invalid prefix");
Z
zhong_ning 已提交
142 143 144 145 146 147 148
            }
        } while (CalculatorLength(calculator) > 0 && e != '(');
        CalculatorPushChar(calculator, '|');
    }
    return 0;
}

S
sun_fan 已提交
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
static int CompareValue(const char *condition, const char *value)
{
    if (strcmp(condition, "*") == 0) {
        return 1;
    }
    if (strcmp(condition, value) == 0) {
        return 1;
    }
    char *tmp = strstr(condition, "*");
    if (tmp != NULL && (strncmp(value, condition, tmp - condition) == 0)) {
        return 1;
    }
    return 0;
}

Z
zhong_ning 已提交
164 165 166 167 168
static int ComputeSubCondition(LogicCalculator *calculator, LogicData *data, const char *condition)
{
    if (!LOGIC_DATA_TEST_FLAG(data, LOGIC_DATA_FLAGS_ORIGINAL)) {
        return LOGIC_DATA_TEST_FLAG(data, LOGIC_DATA_FLAGS_TRUE);
    }
S
sun_fan 已提交
169 170
    uint32_t triggerContentSize = strlen(calculator->triggerContent);
    // 解析条件, aaaa && bbb=1 && ccc=1的场景
Z
zhong_ning 已提交
171
    char *subStr = strstr(condition + data->startIndex, "=");
S
sun_fan 已提交
172 173
    if (subStr != NULL && ((uint32_t)(subStr - condition) > data->endIndex)) {
        if (strncmp(condition + data->startIndex, calculator->triggerContent, triggerContentSize) == 0) {
Z
zhong_ning 已提交
174 175
            return 1;
        }
S
sun_fan 已提交
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
        return 0;
    }
    int ret = GetValueFromContent(condition + data->startIndex,
        data->endIndex - data->startIndex, 0, calculator->conditionName, SUPPORT_DATA_BUFFER_MAX);
    PARAM_CHECK(ret == 0, return -1, "Failed parse content name");
    ret = GetValueFromContent(condition + data->startIndex, data->endIndex - data->startIndex,
        strlen(calculator->conditionName) + 1, calculator->conditionContent, SUPPORT_DATA_BUFFER_MAX);
    PARAM_CHECK(ret == 0, return -1, "Failed parse content value");
    // check name
    if ((calculator->inputName != NULL) && (strcmp(calculator->conditionName, calculator->inputName) == 0)) {
        return CompareValue(calculator->conditionContent, calculator->inputContent);
    } else if (calculator->conditionName != NULL && strlen(calculator->conditionName) > 0) {
        uint32_t len = SUPPORT_DATA_BUFFER_MAX;
        ret = SystemReadParam(calculator->conditionName, calculator->readContent, &len);
        if (ret != 0) {
            return 0;
Z
zhong_ning 已提交
192
        }
S
sun_fan 已提交
193
        return CompareValue(calculator->conditionContent, calculator->readContent);
Z
zhong_ning 已提交
194
    }
Z
zhong_ning 已提交
195 196 197
    return 0;
}

S
sun_fan 已提交
198
int GetValueFromContent(const char *content, uint32_t contentSize, uint32_t start, char *value, uint32_t valueSize)
Z
zhong_ning 已提交
199
{
S
sun_fan 已提交
200 201
    uint32_t contentIndex = start;
    uint32_t currIndex = 0;
Z
zhong_ning 已提交
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
    while (contentIndex < contentSize && currIndex < valueSize) {
        if (content[contentIndex] == '=') {
            value[currIndex++] = '\0';
            return 0;
        }
        value[currIndex++] = content[contentIndex++];
    }
    if (currIndex < valueSize) {
        value[currIndex] = '\0';
        return 0;
    }
    return -1;
}

int ComputeCondition(LogicCalculator *calculator, const char *condition)
{
S
sun_fan 已提交
218 219
    uint32_t currIndex = 0;
    uint32_t start = 0;
Z
zhong_ning 已提交
220 221 222 223 224 225 226 227
    int noneOper = 1;
    CalculatorClear(calculator);
    LogicData data1 = {};
    LogicData data2 = {};
    while (currIndex < strlen(condition)) {
        if (condition[currIndex] == '|' || condition[currIndex] == '&') {
            noneOper = 0;
            int ret = CalculatorPop(calculator, (void*)&data2);
S
sun_fan 已提交
228 229
            int ret1 = CalculatorPop(calculator, (void*)&data1);
            PARAM_CHECK((ret == 0 && ret1 == 0), return -1, "Failed to pop data");
Z
zhong_ning 已提交
230 231 232 233 234

            ret = ComputeSubCondition(calculator, &data1, condition);
            data1.flags = 0;
            if (condition[currIndex] == '|' && ret == 1) {
                LOGIC_DATA_SET_FLAG(&data1, LOGIC_DATA_FLAGS_TRUE);
X
xionglei6@huawei.com 已提交
235
            } else if ((condition[currIndex] == '|' || ret == 1) &&
S
sun_fan 已提交
236 237
                (ComputeSubCondition(calculator, &data2, condition) == 1)) {
                LOGIC_DATA_SET_FLAG(&data1, LOGIC_DATA_FLAGS_TRUE);
Z
zhong_ning 已提交
238
            }
S
sun_fan 已提交
239
            ret = CalculatorPush(calculator, (void *)&data1);
Z
zhong_ning 已提交
240
            PARAM_CHECK(ret == 0, return -1, "Failed to push data");
Z
zhong_ning 已提交
241 242 243 244 245 246 247 248 249
            start = currIndex + 1; // 跳过符号
        } else if (isspace(condition[currIndex])) {
            if (start == currIndex) {
                start = ++currIndex;
                continue;
            }
            data1.flags = LOGIC_DATA_FLAGS_ORIGINAL;
            data1.startIndex = start;
            data1.endIndex = currIndex;
S
sun_fan 已提交
250
            int ret = CalculatorPush(calculator, (void *)&data1);
Z
zhong_ning 已提交
251
            PARAM_CHECK(ret == 0, return -1, "Failed to push data");
Z
zhong_ning 已提交
252 253 254 255 256 257 258 259 260 261
            start = currIndex + 1;
        }
        currIndex++;
    }
    if (noneOper) {
        data1.flags = LOGIC_DATA_FLAGS_ORIGINAL;
        data1.startIndex = start;
        data1.endIndex = strlen(condition);
    } else {
        int ret = CalculatorPop(calculator, &data1);
Z
zhong_ning 已提交
262
        PARAM_CHECK(ret == 0, return -1, "Invalid calculator");
Z
zhong_ning 已提交
263 264 265 266
    }
    return ComputeSubCondition(calculator, &data1, condition);
}

S
sun_fan 已提交
267
int ConvertInfixToPrefix(const char *condition, char *prefix, uint32_t prefixLen)
Z
zhong_ning 已提交
268
{
S
sun_fan 已提交
269
    char e = 0;
Z
zhong_ning 已提交
270
    int ret = 0;
S
sun_fan 已提交
271 272
    uint32_t curr = 0;
    uint32_t prefixIndex = 0;
Z
zhong_ning 已提交
273
    LogicCalculator calculator;
S
sun_fan 已提交
274
    CalculatorInit(&calculator, MAX_CALC_PARAM, 1, 0);
Z
zhong_ning 已提交
275 276 277 278 279 280

    while (curr < strlen(condition)) {
        if (condition[curr] == ')') {
            CalculatorPopChar(&calculator, &e);
            while (e != '(') {
                ret = PrefixAdd(prefix, &prefixIndex, prefixLen, e);
S
sun_fan 已提交
281 282 283
                PARAM_CHECK(ret == 0,
                    CalculatorFree(&calculator); return -1, "Invalid prefix");
                CalculatorPopChar(&calculator, &e);
Z
zhong_ning 已提交
284 285
            }
        } else if (condition[curr] == '|') {
S
sun_fan 已提交
286 287
            PARAM_CHECK(condition[curr + 1] == '|',
                CalculatorFree(&calculator); return -1, "Invalid condition");
Z
zhong_ning 已提交
288
            ret = HandleOperationOr(&calculator, prefix, &prefixIndex, prefixLen);
S
sun_fan 已提交
289 290
            PARAM_CHECK(ret == 0,
                CalculatorFree(&calculator); return -1, "Invalid prefix");
Z
zhong_ning 已提交
291 292
            curr++;
        } else if (condition[curr] == '&') {
S
sun_fan 已提交
293 294
            PARAM_CHECK(condition[curr + 1] == '&',
                CalculatorFree(&calculator); return -1, "Invalid condition");
Z
zhong_ning 已提交
295 296 297 298 299 300 301 302 303
            prefix[prefixIndex++] = ' ';
            CalculatorPushChar(&calculator, condition[curr]);
            curr++;
        } else if (condition[curr] == '(') {
            CalculatorPushChar(&calculator, condition[curr]);
        } else {
            prefix[prefixIndex++] = condition[curr];
        }
        curr++;
S
sun_fan 已提交
304 305
        PARAM_CHECK(prefixIndex < prefixLen,
            CalculatorFree(&calculator); return -1, "Invalid prefixIndex");
Z
zhong_ning 已提交
306 307 308 309 310
    }

    while (CalculatorLength(&calculator) > 0) {
        CalculatorPopChar(&calculator, &e);
        ret = PrefixAdd(prefix, &prefixIndex, prefixLen, e);
S
sun_fan 已提交
311 312
        PARAM_CHECK(ret == 0,
            CalculatorFree(&calculator);
Z
zhong_ning 已提交
313 314 315 316 317
            return -1, "Invalid prefix %u %u", prefixIndex, prefixLen);
    }
    prefix[prefixIndex] = '\0';
    CalculatorFree(&calculator);
    return 0;
Z
zhong_ning 已提交
318 319
}

S
sun_fan 已提交
320
int CheckMatchSubCondition(const char *condition, const char *input, int length)
Z
zhong_ning 已提交
321
{
S
sun_fan 已提交
322 323 324
    char *tmp = strstr(condition, input);
    if ((tmp != NULL) && (strlen(tmp) > length) && (tmp[length] == '=')) {
        return 1;
Z
zhong_ning 已提交
325
    }
S
sun_fan 已提交
326
    return 0;
S
sun_fan 已提交
327
}