-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinternal.h
296 lines (258 loc) · 8.27 KB
/
internal.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/****************************************************************************
* pfw/internal.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
#ifndef PFW_INTERNAL_H
#define PFW_INTERNAL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include "pfw.h"
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/queue.h>
/****************************************************************************
* Pre-Processor Definations
****************************************************************************/
#ifdef CONFIG_LIB_PFW_DEBUG
#define PFW_DEBUG(...) printf(__VA_ARGS__)
#else
#define PFW_DEBUG(...)
#endif
/* Rule pridecates. */
#ifndef LIST_FOREACH
#define LIST_FOREACH(var, head, field) \
for ((var) = LIST_FIRST(head); \
(var) != LIST_END(head); \
(var) = LIST_NEXT(var, field))
#endif
#ifndef LIST_FOREACH_SAFE
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = LIST_FIRST(head); \
(var) && ((tvar) = LIST_NEXT(var, field), 1); \
(var) = (tvar))
#endif
#define PFW_MAXLEN_AMMENDS 512
/* Ammend types. */
#define PFW_AMMEND_RAW 1 // Raw string that does not need ammend.
#define PFW_AMMEND_CRITERION 2 // Ammend with criterion.
/* Criterion types. */
#define PFW_CRITERION_EXCLUSIVE 1 // Enum, each value has a literal meaning.
#define PFW_CRITERION_INCLUSIVE 2 // Bitmask, each bit has a literal meaning.
#define PFW_CRITERION_NUMERICAL 3 // Pure 32-bit integer.
/* Rule pridecates. */
#define PFW_PREDICATE_ALL 1 // True if all branches are true.
#define PFW_PREDICATE_ANY 2 // True if any branch is true.
#define PFW_PREDICATE_IS 3 // True if qeual to.
#define PFW_PREDICATE_ISNOT 4 // True if not equal to.
#define PFW_PREDICATE_INCLUDES 5 // True if has this bit.
#define PFW_PREDICATE_EXCLUDES 6 // True if dose not has this bit.
#define PFW_PREDICATE_IN 7 // True if in the interval.
#define PFW_PREDICATE_NOTIN 8 // // True if not in the interval.
/****************************************************************************
* Types
****************************************************************************/
typedef struct pfw_ammend_s pfw_ammend_t;
typedef struct pfw_context_s pfw_context_t;
typedef struct pfw_vector_s pfw_vector_t;
typedef struct pfw_interval_s pfw_interval_t;
typedef struct pfw_listener_s pfw_listener_t;
typedef LIST_HEAD(pfw_listener_list_s, pfw_listener_s)
pfw_listener_list_t;
typedef LIST_ENTRY(pfw_listener_s) pfw_listener_entry_t;
typedef struct pfw_criterion_s pfw_criterion_t;
typedef struct pfw_rule_s pfw_rule_t;
typedef struct pfw_act_s pfw_act_t;
typedef struct pfw_action_s pfw_action_t;
typedef struct pfw_config_s pfw_config_t;
typedef struct pfw_domain_s pfw_domain_t;
typedef struct pfw_plugin_s pfw_plugin_t;
typedef struct pfw_system_s pfw_system_t;
/**
* @brief pfw_ammend_t
*
* A raw string, or ammend with other object.
*
* @see pfw_config_t pfw_act_t
*/
struct pfw_ammend_s {
int type;
union {
const char* raw;
pfw_criterion_t* criterion;
} u;
};
/**
* @brief pfw_interval_t is a open interval, used by NumericalCriterion.
* @see pfw_criterion_t
*/
struct pfw_interval_s {
int32_t left;
int32_t right;
};
/**
* @brief pfw_listener_t is a callback when change occurred.
*/
struct pfw_listener_s {
void* cookie;
pfw_listen_t on_change;
pfw_listener_entry_t entry;
};
/**
* @brief pfw_criterion_t is condition variable.
*
* When criterion is modified, the rules in domains might change;
* so domain might change in next apply.
*
* @see pfw_rule_t pfw_apply() pfw_criterion_*()
*/
struct pfw_criterion_s {
int type; // @see PFW_CRITERION_*
pfw_vector_t* names;
pfw_vector_t* ranges;
int32_t state;
union {
const char* def;
int32_t v;
} init;
pfw_listener_list_t listeners;
};
/**
* @brief pfw_rule_t is tree.
*
* Branch node is a composite of multiple rules; leaf node
* requires a criterion to be a specific state.
*
* @see pfw_criterion_t pfw_config_t
*/
struct pfw_rule_s {
int predicate; // @see PFW_PREDICATE_*
pfw_vector_t* branches;
union {
const char* def;
pfw_criterion_t* p;
} criterion;
union {
int32_t v;
const char* def;
pfw_interval_t* itv;
} state;
};
/**
* @brief pfw_act_t is applying paramter by plugin method.
*
* Apply the parameter to callback in the plugin
* when the act is applied.
*
* @see pfw_action_t pfw_plugin_t
*/
struct pfw_act_s {
union {
const char* def;
pfw_plugin_t* p;
} plugin;
pfw_vector_t* param; // @see pfw_ammend_t
};
/**
* @brief pfw_config_t is a state in state machine.
*
* Once the rules is ok, take acts.
*
* @see pfw_domain_t pfw_rule_t pfw_action_t
*/
struct pfw_config_s {
char* current;
pfw_vector_t* name; // @see pfw_ammend_t
pfw_rule_t* rules;
pfw_vector_t* acts;
};
/**
* @brief pfw_domain_t is a state machine.
*
* when apply changes, state machine might move into a new state.
*
* @see pfw_config_t pfw_apply()
*/
struct pfw_domain_s {
const char* name;
pfw_config_t* current;
pfw_vector_t* configs;
};
/**
* @brief pfw_plugin_t is a sequence of callback
*
* Callbacks used by act in state machine, user can add/remove callback
* to any plugin at runtime.
*/
struct pfw_plugin_s {
char* name;
char* parameter;
void* cookie;
pfw_callback_t cb;
};
/**
* @brief pfw_system_t is a system that includes condition variables and
* state machines.
*
* Create system by parsing two configuration files, regist plugin,
* and initialize the criteria and domains.
*
* @see pfw_criterion_t pfw_domain_t pfw_context_t
* pfw_create() pfw_destroy()
*/
struct pfw_system_s {
pfw_context_t* criteria_ctx;
pfw_context_t* settings_ctx;
pfw_vector_t* criteria;
pfw_vector_t* domains;
pfw_vector_t* plugins;
pfw_load_t on_load; // Load criterion state at initilization.
pfw_save_t on_save; // Save criterion state when it changes.
pthread_mutex_t mutex;
void* cookie;
};
/****************************************************************************
* Functions
****************************************************************************/
/* Utils functions. */
pfw_context_t* pfw_context_create(const char* filename);
char* pfw_context_take_word(pfw_context_t* ctx);
char* pfw_context_take_line(pfw_context_t* ctx);
int pfw_context_get_depth(pfw_context_t* ctx);
void pfw_context_destroy(pfw_context_t* ctx);
int pfw_vector_append(pfw_vector_t** pv, void* obj);
void* pfw_vector_get(pfw_vector_t* vector, int index);
void pfw_vector_free(pfw_vector_t* vector);
/* Parse functions. */
void pfw_free_criteria(pfw_vector_t* criteria);
void pfw_free_settings(pfw_vector_t* settings);
int pfw_parse_criteria(pfw_context_t* ctx, pfw_vector_t** p);
int pfw_parse_settings(pfw_context_t* ctx, pfw_vector_t** p);
bool pfw_sanitize_criteria(pfw_system_t* system);
bool pfw_sanitize_settings(pfw_system_t* system);
void* pfw_plugin_register(pfw_system_t* system, pfw_plugin_def_t* def);
/* Criterion functions */
bool pfw_rule_match(pfw_rule_t* rule);
int pfw_criterion_atoi(pfw_criterion_t* criterion,
const char* value, int32_t* state);
int pfw_criterion_itoa(pfw_criterion_t* criterion,
int32_t state, char* res, int len);
pfw_criterion_t* pfw_criteria_find(pfw_vector_t* criteria,
const char* target);
#endif // PFW_INTERNAL_H