Я пытаюсь создать текстовый синтаксический анализатор с использованием структуры. Кажется, что это работает отлично для более мелкой структуры, которую я использовал для ее проверки, но большая стойка, требуемая для моего последнего приложения (управление модемом), кажется, не представляется так, как хотелось бы в памяти.Инициализация структуры с массивом вложенных структур
Я думаю, что проблема заключается в инициализации эту структуру:
struct state
{
size_t const id;
size_t(* const callback)(void*);
void* const callback_arg;
char const* const out_pattern;
size_t const out_pattern_length;
unsigned long int timeout;
size_t const timeout_state;
size_t const next_states_length;
struct next_state const* next_states;
};
С помощью этого макроса:
#define sm_state(id, callback, callback_arg, out_str, out_str_length, timeout, \
timeout_state, next_states_length, ...) \
{id, callback, callback_arg, out_str, out_str_length, timeout, \
timeout_state, next_states_length, \
(struct next_state const[next_states_length]){__VA_ARGS__}}
где next_state является:
#define sm_next_state(next_state_id, in_pattern_length, in_pattern) \
{next_state_id, in_pattern_length, in_pattern}
struct next_state
{
size_t const next_state;
size_t const in_pattern_length;
char const* in_pattern;
};
Тестовый пример, который работает так:
enum states_enum
{
fruit = 1,
vegitable,
error,
};
struct state const states[] = {
// id callback callback argument pattern to be sent on entry patlen timeout t/o state next states count next_states
sm_state( fruit, NULL, NULL, "hello, pick a fruit\n", 20, 100000UL, 1, 3, sm_next_state(fruit, 4, "pear"), sm_next_state(vegitable, 5, "apple"), sm_next_state(error, 6, "turnip")),
sm_state( vegitable, NULL, NULL, "now pick a vegetable\n", 21, 100000UL, 3, 3, sm_next_state(fruit, 7, "cabbage"), sm_next_state(vegitable, 6, "potato"), sm_next_state(error, 6, "turnip")),
sm_state( error, NULL, NULL, "error, you entered turnip...\n", 29, 100000UL, 1, 3, sm_next_state(fruit, 3, "one"), sm_next_state(vegitable, 3, "two"), sm_next_state(error, 6, "turnip"))
};
int i = 0;
while (i < 3)
{
printf("id: %d\n", states[i].id);
++i;
}
выход:
id: 1
id: 2
id: 3
И чем больше структура, которая не работает:
enum bluetooth_states_enum
{
bt_off = 1,
bt_on,
bt_set_echo_off,
bt_set_auto_answer,
bt_set_ignore_dsr,
bt_set_spp,
bt_set_io_cap,
bt_set_mitm_protection,
bt_write,
bt_reset,
bt_set_firendly_name,
bt_set_connectable,
bt_set_key,
bt_listening,
bt_answer,
bt_in_call,
bt_hup,
bt_error,
};
struct state const states[] = {
sm_state( bt_off, NULL, NULL, "", 0, -1, bt_off, 0,),
sm_state( bt_on, NULL, NULL, "AT\r", 3, 100000UL, bt_error, 2, sm_next_state(bt_set_echo_off, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_echo_off, NULL, NULL, "ATE0\r", 5, 100000UL, bt_error, 2, sm_next_state(bt_set_auto_answer, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_auto_answer, NULL, NULL, "ATS0=2\r", 7, 100000UL, bt_error, 2, sm_next_state(bt_set_ignore_dsr, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_ignore_dsr, NULL, NULL, "ATS102=1\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_set_spp, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_spp, NULL, NULL, "ATS102=1\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_set_io_cap, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_io_cap, NULL, NULL, "ATS321=0\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_set_mitm_protection, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_mitm_protection, NULL, NULL, "ATS322=1\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_write, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_write, NULL, NULL, "AT&W\r", 5, 100000UL, bt_error, 2, sm_next_state(bt_reset, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_reset, NULL, NULL, "ATZ\r", 4, 100000UL, bt_error, 2, sm_next_state(bt_set_firendly_name, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_firendly_name, NULL, NULL, "AT+BTF=\"Friendly Name\"\r", 18, 100000UL, bt_error, 2, sm_next_state(bt_set_connectable, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_connectable, NULL, NULL, "AT+BTP\r", 7, 100000UL, bt_error, 2, sm_next_state(bt_set_key, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_key, NULL, NULL, "AT+BTK=\"8475\"\r", 14, 100000UL, bt_error, 2, sm_next_state(bt_listening, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_listening, NULL, NULL, "", 0, -1, 0, 1, sm_next_state(bt_answer, 4, "RING")),
sm_state( bt_answer, NULL, NULL, "ATA\r", 4, 100000UL, bt_error, 2, sm_next_state(bt_in_call, 7, "CONNECT"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_in_call, NULL, NULL, "", 0, 100000UL, bt_error, 2, sm_next_state(bt_set_connectable, 10, "NO CONNECT"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_error, NULL, NULL, "", 0, -1, bt_off, 1, sm_next_state(bt_off, 0, ""))
};
выход:
id: 1820602156
id: 7
id: -1
id: 1973037073
id: 0
id: 0
id: 123336558
id: 0
id: 0
id: 0
id: 736
id: 760826203
id: 3108
id: -1322777276
id: 1
id: 7916
id: 152
Казалось бы, что больше примеров не существует в памяти , Если кто-нибудь может указать, что я делаю неправильно, это было бы потрясающе.
Хммм. Работает для меня, за исключением того, что мне нужно изменить '% d' на'% zu' в формате печати, потому что 'id' является' size_t'. –