mirror of https://github.com/arendst/Tasmota.git
Merge pull request #14937 from s-hadinger/berry_cron
Berry add cron timers
This commit is contained in:
commit
7f6818f9f6
|
@ -167,6 +167,7 @@ extern void be_load_webclient_lib(bvm *vm);
|
|||
extern void be_load_tcpclient_lib(bvm *vm);
|
||||
extern void be_load_udp_lib(bvm *vm);
|
||||
extern void be_load_crypto_lib(bvm *vm);
|
||||
extern void be_load_ccronexpr_class(bvm *vm);
|
||||
extern void be_load_Leds_ntv_class(bvm *vm);
|
||||
extern void be_load_Leds_class(bvm *vm);
|
||||
extern void be_load_Leds_animator_class(bvm *vm);
|
||||
|
@ -207,6 +208,7 @@ BERRY_API void be_load_custom_libs(bvm *vm)
|
|||
be_load_md5_lib(vm);
|
||||
be_load_serial_lib(vm);
|
||||
be_load_ctypes_lib(vm);
|
||||
be_load_ccronexpr_class(vm);
|
||||
#ifdef USE_LIGHT
|
||||
be_load_light_state_class(vm);
|
||||
#endif
|
||||
|
|
|
@ -199,6 +199,7 @@ extern const bcstring be_const_str__buffer;
|
|||
extern const bcstring be_const_str__ccmd;
|
||||
extern const bcstring be_const_str__class;
|
||||
extern const bcstring be_const_str__cmd;
|
||||
extern const bcstring be_const_str__crons;
|
||||
extern const bcstring be_const_str__debug_present;
|
||||
extern const bcstring be_const_str__def;
|
||||
extern const bcstring be_const_str__dirty;
|
||||
|
@ -228,6 +229,7 @@ extern const bcstring be_const_str_acos;
|
|||
extern const bcstring be_const_str_add;
|
||||
extern const bcstring be_const_str_add_anim;
|
||||
extern const bcstring be_const_str_add_cmd;
|
||||
extern const bcstring be_const_str_add_cron;
|
||||
extern const bcstring be_const_str_add_driver;
|
||||
extern const bcstring be_const_str_add_event_cb;
|
||||
extern const bcstring be_const_str_add_fast_loop;
|
||||
|
@ -283,6 +285,7 @@ extern const bcstring be_const_str_cb;
|
|||
extern const bcstring be_const_str_cb_do_nothing;
|
||||
extern const bcstring be_const_str_cb_event_closure;
|
||||
extern const bcstring be_const_str_cb_obj;
|
||||
extern const bcstring be_const_str_ccronexpr;
|
||||
extern const bcstring be_const_str_ceil;
|
||||
extern const bcstring be_const_str_char;
|
||||
extern const bcstring be_const_str_chars_in_string;
|
||||
|
@ -385,6 +388,7 @@ extern const bcstring be_const_str_event;
|
|||
extern const bcstring be_const_str_event_cb;
|
||||
extern const bcstring be_const_str_event_send;
|
||||
extern const bcstring be_const_str_every_100ms;
|
||||
extern const bcstring be_const_str_every_250ms;
|
||||
extern const bcstring be_const_str_every_50ms;
|
||||
extern const bcstring be_const_str_every_second;
|
||||
extern const bcstring be_const_str_except;
|
||||
|
@ -577,10 +581,13 @@ extern const bcstring be_const_str_month;
|
|||
extern const bcstring be_const_str_montserrat_font;
|
||||
extern const bcstring be_const_str_name;
|
||||
extern const bcstring be_const_str_nan;
|
||||
extern const bcstring be_const_str_next;
|
||||
extern const bcstring be_const_str_next_cron;
|
||||
extern const bcstring be_const_str_nil;
|
||||
extern const bcstring be_const_str_no_X20GPIO_X20specified_X20for_X20neopixelbus;
|
||||
extern const bcstring be_const_str_null_cb;
|
||||
extern const bcstring be_const_str_number;
|
||||
extern const bcstring be_const_str_o;
|
||||
extern const bcstring be_const_str_obj_class_create_obj;
|
||||
extern const bcstring be_const_str_obj_event_base;
|
||||
extern const bcstring be_const_str_offset;
|
||||
|
@ -647,6 +654,7 @@ extern const bcstring be_const_str_remote_ip;
|
|||
extern const bcstring be_const_str_remote_port;
|
||||
extern const bcstring be_const_str_remove;
|
||||
extern const bcstring be_const_str_remove_cmd;
|
||||
extern const bcstring be_const_str_remove_cron;
|
||||
extern const bcstring be_const_str_remove_driver;
|
||||
extern const bcstring be_const_str_remove_light;
|
||||
extern const bcstring be_const_str_remove_rule;
|
||||
|
@ -673,6 +681,7 @@ extern const bcstring be_const_str_rtc;
|
|||
extern const bcstring be_const_str_rule;
|
||||
extern const bcstring be_const_str_run;
|
||||
extern const bcstring be_const_str_run_bat;
|
||||
extern const bcstring be_const_str_run_cron;
|
||||
extern const bcstring be_const_str_run_deferred;
|
||||
extern const bcstring be_const_str_running;
|
||||
extern const bcstring be_const_str_sat;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,20 @@
|
|||
#include "be_constobj.h"
|
||||
|
||||
static be_define_const_map_slots(be_class_ccronexpr_map) {
|
||||
{ be_const_key(deinit, 2), be_const_ctype_func(ccronexpr_init) },
|
||||
{ be_const_key(_X2Ep, -1), be_const_var(0) },
|
||||
{ be_const_key(next, -1), be_const_ctype_func(ccronexpr_next) },
|
||||
{ be_const_key(init, 1), be_const_ctype_func(ccronexpr_init) },
|
||||
};
|
||||
|
||||
static be_define_const_map(
|
||||
be_class_ccronexpr_map,
|
||||
4
|
||||
);
|
||||
|
||||
BE_EXPORT_VARIABLE be_define_const_class(
|
||||
be_class_ccronexpr,
|
||||
1,
|
||||
NULL,
|
||||
ccronexpr
|
||||
);
|
|
@ -1,97 +1,102 @@
|
|||
#include "be_constobj.h"
|
||||
|
||||
static be_define_const_map_slots(be_class_tasmota_map) {
|
||||
{ be_const_key(get_power, -1), be_const_func(l_getpower) },
|
||||
{ be_const_key(gc, -1), be_const_closure(Tasmota_gc_closure) },
|
||||
{ be_const_key(response_append, -1), be_const_func(l_respAppend) },
|
||||
{ be_const_key(resp_cmnd_done, 29), be_const_func(l_respCmndDone) },
|
||||
{ be_const_key(try_rule, -1), be_const_closure(Tasmota_try_rule_closure) },
|
||||
{ be_const_key(get_light, 8), be_const_closure(Tasmota_get_light_closure) },
|
||||
{ be_const_key(_global_def, -1), be_const_comptr(&be_tasmota_global_struct) },
|
||||
{ be_const_key(eth, 76), be_const_func(l_eth) },
|
||||
{ be_const_key(time_dump, -1), be_const_func(l_time_dump) },
|
||||
{ be_const_key(cmd_res, -1), be_const_var(0) },
|
||||
{ be_const_key(_drivers, 18), be_const_var(1) },
|
||||
{ be_const_key(find_key_i, -1), be_const_closure(Tasmota_find_key_i_closure) },
|
||||
{ be_const_key(set_timer, -1), be_const_closure(Tasmota_set_timer_closure) },
|
||||
{ be_const_key(load, 9), be_const_closure(Tasmota_load_closure) },
|
||||
{ be_const_key(set_light, 15), be_const_closure(Tasmota_set_light_closure) },
|
||||
{ be_const_key(fast_loop, -1), be_const_closure(Tasmota_fast_loop_closure) },
|
||||
{ be_const_key(settings, -1), be_const_var(2) },
|
||||
{ be_const_key(web_send_decimal, -1), be_const_func(l_webSendDecimal) },
|
||||
{ be_const_key(strptime, -1), be_const_func(l_strptime) },
|
||||
{ be_const_key(init, 20), be_const_closure(Tasmota_init_closure) },
|
||||
{ be_const_key(get_option, -1), be_const_func(l_getoption) },
|
||||
{ be_const_key(memory, 37), be_const_func(l_memory) },
|
||||
{ be_const_key(find_op, -1), be_const_closure(Tasmota_find_op_closure) },
|
||||
{ be_const_key(yield, -1), be_const_func(l_yield) },
|
||||
{ be_const_key(publish_result, 19), be_const_func(l_publish_result) },
|
||||
{ be_const_key(_timers, 33), be_const_var(3) },
|
||||
{ be_const_key(_ccmd, 75), be_const_var(4) },
|
||||
{ be_const_key(read_sensors, 26), be_const_func(l_read_sensors) },
|
||||
{ be_const_key(rtc, -1), be_const_func(l_rtc) },
|
||||
{ be_const_key(delay, 73), be_const_func(l_delay) },
|
||||
{ be_const_key(event, 35), be_const_closure(Tasmota_event_closure) },
|
||||
{ be_const_key(web_send, 12), be_const_func(l_webSend) },
|
||||
{ be_const_key(i2c_enabled, 78), be_const_func(l_i2cenabled) },
|
||||
{ be_const_key(resp_cmnd_done, -1), be_const_func(l_respCmndDone) },
|
||||
{ be_const_key(web_send, 33), be_const_func(l_webSend) },
|
||||
{ be_const_key(add_driver, 21), be_const_closure(Tasmota_add_driver_closure) },
|
||||
{ be_const_key(wd, 16), be_const_var(0) },
|
||||
{ be_const_key(resp_cmnd_error, 25), be_const_func(l_respCmndError) },
|
||||
{ be_const_key(publish, 71), be_const_func(l_publish) },
|
||||
{ be_const_key(gen_cb, 0), be_const_closure(Tasmota_gen_cb_closure) },
|
||||
{ be_const_key(_settings_ptr, -1), be_const_comptr(&Settings) },
|
||||
{ be_const_key(resp_cmnd_error, -1), be_const_func(l_respCmndError) },
|
||||
{ be_const_key(cmd, -1), be_const_closure(Tasmota_cmd_closure) },
|
||||
{ be_const_key(_cmd, 62), be_const_func(l_cmd) },
|
||||
{ be_const_key(wifi, 71), be_const_func(l_wifi) },
|
||||
{ be_const_key(wire_scan, -1), be_const_closure(Tasmota_wire_scan_closure) },
|
||||
{ be_const_key(resp_cmnd, 17), be_const_func(l_respCmnd) },
|
||||
{ be_const_key(wire2, -1), be_const_var(5) },
|
||||
{ be_const_key(get_switch, 51), be_const_func(l_getswitch) },
|
||||
{ be_const_key(chars_in_string, -1), be_const_closure(Tasmota_chars_in_string_closure) },
|
||||
{ be_const_key(remove_cmd, 7), be_const_closure(Tasmota_remove_cmd_closure) },
|
||||
{ be_const_key(_fl, 1), be_const_var(6) },
|
||||
{ be_const_key(hs2rgb, -1), be_const_closure(Tasmota_hs2rgb_closure) },
|
||||
{ be_const_key(wd, 38), be_const_var(7) },
|
||||
{ be_const_key(get_free_heap, -1), be_const_func(l_getFreeHeap) },
|
||||
{ be_const_key(strftime, -1), be_const_func(l_strftime) },
|
||||
{ be_const_key(_global_addr, 65), be_const_comptr(&TasmotaGlobal) },
|
||||
{ be_const_key(exec_tele, -1), be_const_closure(Tasmota_exec_tele_closure) },
|
||||
{ be_const_key(time_reached, -1), be_const_func(l_timereached) },
|
||||
{ be_const_key(_settings_def, -1), be_const_comptr(&be_tasmota_settings_struct) },
|
||||
{ be_const_key(remove_rule, 67), be_const_closure(Tasmota_remove_rule_closure) },
|
||||
{ be_const_key(gen_cb, -1), be_const_closure(Tasmota_gen_cb_closure) },
|
||||
{ be_const_key(exec_cmd, -1), be_const_closure(Tasmota_exec_cmd_closure) },
|
||||
{ be_const_key(time_str, 14), be_const_closure(Tasmota_time_str_closure) },
|
||||
{ be_const_key(exec_rules, -1), be_const_closure(Tasmota_exec_rules_closure) },
|
||||
{ be_const_key(resp_cmnd_str, -1), be_const_func(l_respCmndStr) },
|
||||
{ be_const_key(global, 4), be_const_var(8) },
|
||||
{ be_const_key(kv, 2), be_const_closure(Tasmota_kv_closure) },
|
||||
{ be_const_key(add_fast_loop, -1), be_const_closure(Tasmota_add_fast_loop_closure) },
|
||||
{ be_const_key(resp_cmnd_failed, -1), be_const_func(l_respCmndFailed) },
|
||||
{ be_const_key(log, -1), be_const_func(l_logInfo) },
|
||||
{ be_const_key(add_cmd, -1), be_const_closure(Tasmota_add_cmd_closure) },
|
||||
{ be_const_key(remove_timer, -1), be_const_closure(Tasmota_remove_timer_closure) },
|
||||
{ be_const_key(millis, 58), be_const_func(l_millis) },
|
||||
{ be_const_key(scale_uint, -1), be_const_func(l_scaleuint) },
|
||||
{ be_const_key(run_deferred, -1), be_const_closure(Tasmota_run_deferred_closure) },
|
||||
{ be_const_key(_debug_present, 30), be_const_var(9) },
|
||||
{ be_const_key(remove_driver, -1), be_const_closure(Tasmota_remove_driver_closure) },
|
||||
{ be_const_key(try_rule, -1), be_const_closure(Tasmota_try_rule_closure) },
|
||||
{ be_const_key(set_timer, -1), be_const_closure(Tasmota_set_timer_closure) },
|
||||
{ be_const_key(time_dump, -1), be_const_func(l_time_dump) },
|
||||
{ be_const_key(cmd_res, -1), be_const_var(1) },
|
||||
{ be_const_key(millis, 35), be_const_func(l_millis) },
|
||||
{ be_const_key(chars_in_string, 82), be_const_closure(Tasmota_chars_in_string_closure) },
|
||||
{ be_const_key(get_power, -1), be_const_func(l_getpower) },
|
||||
{ be_const_key(set_light, 40), be_const_closure(Tasmota_set_light_closure) },
|
||||
{ be_const_key(set_power, -1), be_const_func(l_setpower) },
|
||||
{ be_const_key(check_not_method, -1), be_const_closure(Tasmota_check_not_method_closure) },
|
||||
{ be_const_key(resolvecmnd, 74), be_const_func(l_resolveCmnd) },
|
||||
{ be_const_key(arch, -1), be_const_func(l_arch) },
|
||||
{ be_const_key(fast_loop, -1), be_const_closure(Tasmota_fast_loop_closure) },
|
||||
{ be_const_key(get_option, -1), be_const_func(l_getoption) },
|
||||
{ be_const_key(add_cron, -1), be_const_closure(Tasmota_add_cron_closure) },
|
||||
{ be_const_key(_settings_def, -1), be_const_comptr(&be_tasmota_settings_struct) },
|
||||
{ be_const_key(init, 41), be_const_closure(Tasmota_init_closure) },
|
||||
{ be_const_key(add_rule, 19), be_const_closure(Tasmota_add_rule_closure) },
|
||||
{ be_const_key(resp_cmnd_failed, -1), be_const_func(l_respCmndFailed) },
|
||||
{ be_const_key(exec_tele, -1), be_const_closure(Tasmota_exec_tele_closure) },
|
||||
{ be_const_key(add_fast_loop, -1), be_const_closure(Tasmota_add_fast_loop_closure) },
|
||||
{ be_const_key(_global_def, -1), be_const_comptr(&be_tasmota_global_struct) },
|
||||
{ be_const_key(yield, 73), be_const_func(l_yield) },
|
||||
{ be_const_key(next_cron, -1), be_const_closure(Tasmota_next_cron_closure) },
|
||||
{ be_const_key(web_send_decimal, -1), be_const_func(l_webSendDecimal) },
|
||||
{ be_const_key(time_reached, 11), be_const_func(l_timereached) },
|
||||
{ be_const_key(delay, -1), be_const_func(l_delay) },
|
||||
{ be_const_key(rtc, -1), be_const_func(l_rtc) },
|
||||
{ be_const_key(wire2, -1), be_const_var(2) },
|
||||
{ be_const_key(add_cmd, 75), be_const_closure(Tasmota_add_cmd_closure) },
|
||||
{ be_const_key(exec_rules, 12), be_const_closure(Tasmota_exec_rules_closure) },
|
||||
{ be_const_key(strptime, 74), be_const_func(l_strptime) },
|
||||
{ be_const_key(wire_scan, -1), be_const_closure(Tasmota_wire_scan_closure) },
|
||||
{ be_const_key(run_cron, 10), be_const_closure(Tasmota_run_cron_closure) },
|
||||
{ be_const_key(get_light, 46), be_const_closure(Tasmota_get_light_closure) },
|
||||
{ be_const_key(cmd, -1), be_const_closure(Tasmota_cmd_closure) },
|
||||
{ be_const_key(remove_cmd, -1), be_const_closure(Tasmota_remove_cmd_closure) },
|
||||
{ be_const_key(resp_cmnd_str, -1), be_const_func(l_respCmndStr) },
|
||||
{ be_const_key(_fl, -1), be_const_var(3) },
|
||||
{ be_const_key(i2c_enabled, -1), be_const_func(l_i2cenabled) },
|
||||
{ be_const_key(global, -1), be_const_var(4) },
|
||||
{ be_const_key(_debug_present, 39), be_const_var(5) },
|
||||
{ be_const_key(run_deferred, 18), be_const_closure(Tasmota_run_deferred_closure) },
|
||||
{ be_const_key(load, -1), be_const_closure(Tasmota_load_closure) },
|
||||
{ be_const_key(get_switch, 56), be_const_func(l_getswitch) },
|
||||
{ be_const_key(_ccmd, -1), be_const_var(6) },
|
||||
{ be_const_key(kv, 14), be_const_closure(Tasmota_kv_closure) },
|
||||
{ be_const_key(event, 22), be_const_closure(Tasmota_event_closure) },
|
||||
{ be_const_key(get_free_heap, -1), be_const_func(l_getFreeHeap) },
|
||||
{ be_const_key(_rules, 20), be_const_var(7) },
|
||||
{ be_const_key(_timers, -1), be_const_var(8) },
|
||||
{ be_const_key(remove_timer, 5), be_const_closure(Tasmota_remove_timer_closure) },
|
||||
{ be_const_key(eth, -1), be_const_func(l_eth) },
|
||||
{ be_const_key(arch, 65), be_const_func(l_arch) },
|
||||
{ be_const_key(remove_driver, -1), be_const_closure(Tasmota_remove_driver_closure) },
|
||||
{ be_const_key(response_append, -1), be_const_func(l_respAppend) },
|
||||
{ be_const_key(wifi, -1), be_const_func(l_wifi) },
|
||||
{ be_const_key(log, -1), be_const_func(l_logInfo) },
|
||||
{ be_const_key(find_op, 78), be_const_closure(Tasmota_find_op_closure) },
|
||||
{ be_const_key(hs2rgb, -1), be_const_closure(Tasmota_hs2rgb_closure) },
|
||||
{ be_const_key(find_key_i, -1), be_const_closure(Tasmota_find_key_i_closure) },
|
||||
{ be_const_key(_global_addr, -1), be_const_comptr(&TasmotaGlobal) },
|
||||
{ be_const_key(save, -1), be_const_func(l_save) },
|
||||
{ be_const_key(add_rule, -1), be_const_closure(Tasmota_add_rule_closure) },
|
||||
{ be_const_key(publish, -1), be_const_func(l_publish) },
|
||||
{ be_const_key(wire1, 77), be_const_var(10) },
|
||||
{ be_const_key(_rules, 28), be_const_var(11) },
|
||||
{ be_const_key(add_driver, -1), be_const_closure(Tasmota_add_driver_closure) },
|
||||
{ be_const_key(exec_cmd, 37), be_const_closure(Tasmota_exec_cmd_closure) },
|
||||
{ be_const_key(remove_rule, -1), be_const_closure(Tasmota_remove_rule_closure) },
|
||||
{ be_const_key(publish_result, -1), be_const_func(l_publish_result) },
|
||||
{ be_const_key(settings, -1), be_const_var(9) },
|
||||
{ be_const_key(time_str, -1), be_const_closure(Tasmota_time_str_closure) },
|
||||
{ be_const_key(wire1, -1), be_const_var(10) },
|
||||
{ be_const_key(_drivers, -1), be_const_var(11) },
|
||||
{ be_const_key(scale_uint, 43), be_const_func(l_scaleuint) },
|
||||
{ be_const_key(strftime, 9), be_const_func(l_strftime) },
|
||||
{ be_const_key(_cmd, -1), be_const_func(l_cmd) },
|
||||
{ be_const_key(check_not_method, -1), be_const_closure(Tasmota_check_not_method_closure) },
|
||||
{ be_const_key(remove_cron, -1), be_const_closure(Tasmota_remove_cron_closure) },
|
||||
{ be_const_key(resolvecmnd, 51), be_const_func(l_resolveCmnd) },
|
||||
{ be_const_key(resp_cmnd, -1), be_const_func(l_respCmnd) },
|
||||
{ be_const_key(_crons, 63), be_const_var(12) },
|
||||
{ be_const_key(memory, -1), be_const_func(l_memory) },
|
||||
{ be_const_key(read_sensors, 54), be_const_func(l_read_sensors) },
|
||||
};
|
||||
|
||||
static be_define_const_map(
|
||||
be_class_tasmota_map,
|
||||
81
|
||||
86
|
||||
);
|
||||
|
||||
BE_EXPORT_VARIABLE be_define_const_class(
|
||||
be_class_tasmota,
|
||||
12,
|
||||
13,
|
||||
NULL,
|
||||
Tasmota
|
||||
);
|
||||
|
|
|
@ -157,6 +157,7 @@ int be_find_global_or_module_member(bvm *vm, const char * name) {
|
|||
* '~': send the length of the previous bytes() buffer (or raise an exception if no length known)
|
||||
* 'lv_obj' be_instance of type or subtype
|
||||
* '^lv_event_cb^' callback of a named class - will call `_lvgl.gen_cb(arg_type, closure, self)` and expects a callback address in return
|
||||
* '@': pass a pointer to the Berry VM (virtual parameter added, must be the first argument)
|
||||
*
|
||||
* Ex: ".ii" takes 3 arguments, first one is any type, followed by 2 ints
|
||||
\*********************************************************************************************/
|
||||
|
@ -301,6 +302,13 @@ int be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, i
|
|||
uint32_t p_idx = 0; // index in p[], is incremented with each parameter except '-'
|
||||
int32_t buf_len = -1; // stores the length of a bytes() buffer to be used as '~' attribute
|
||||
|
||||
// special case when first parameter is '@', pass pointer to VM
|
||||
if (NULL != arg_type && arg_type[arg_idx] == '@') {
|
||||
arg_idx++;
|
||||
p[p_idx] = vm;
|
||||
p_idx++;
|
||||
}
|
||||
|
||||
// special case when no parameters are passed but all are optional
|
||||
if (NULL != arg_type && arg_type[arg_idx] == '[') {
|
||||
arg_optional = btrue;
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/********************************************************************
|
||||
* Light_state class - abstract light state
|
||||
*
|
||||
* Handles all states and events for a virtual light.
|
||||
* Can be eventually subclassed to handle a physical light.
|
||||
*
|
||||
*******************************************************************/
|
||||
#ifdef USE_LIGHT
|
||||
|
||||
#include "be_constobj.h"
|
||||
#include "be_mapping.h"
|
||||
|
||||
#include "ccronexpr.h"
|
||||
|
||||
// create
|
||||
static cron_expr* ccronexpr_init(struct bvm* vm, char* expr) {
|
||||
cron_expr* cron = new cron_expr();
|
||||
const char* error = nullptr;
|
||||
cron_parse_expr(expr, cron, &error);
|
||||
|
||||
if (error) {
|
||||
be_raise(vm, "value_error", error); // TODO any way to pass VM?
|
||||
}
|
||||
return cron;
|
||||
}
|
||||
BE_FUNC_CTYPE_DECLARE(ccronexpr_init, "+.p", "@s")
|
||||
|
||||
// deinit
|
||||
static void ccronexpr_deinit(cron_expr* cron) {
|
||||
delete cron;
|
||||
}
|
||||
BE_FUNC_CTYPE_DECLARE(ccronexpr_deinit, "", ".")
|
||||
|
||||
|
||||
// next
|
||||
static uint32_t ccronexpr_next(cron_expr* cron, uint32_t date) {
|
||||
return cron_next(cron, date);
|
||||
}
|
||||
BE_FUNC_CTYPE_DECLARE(ccronexpr_next, "i", ".i")
|
||||
|
||||
// prev
|
||||
static uint32_t ccronexpr_prev(cron_expr* cron, uint32_t date) {
|
||||
return cron_prev(cron, date);
|
||||
}
|
||||
BE_FUNC_CTYPE_DECLARE(ccronexpr_prev, "i", ".i")
|
||||
|
||||
#include "be_fixed_be_class_ccronexpr.h"
|
||||
|
||||
extern "C" void be_load_ccronexpr_class(bvm *vm) {
|
||||
be_pushntvclass(vm, &be_class_ccronexpr);
|
||||
be_setglobal(vm, "ccronexpr");
|
||||
be_pop(vm, 1);
|
||||
}
|
||||
/* @const_object_info_begin
|
||||
|
||||
class be_class_ccronexpr (scope: global, name: ccronexpr) {
|
||||
.p, var // pointer to cron_expr*
|
||||
|
||||
init, ctype_func(ccronexpr_init)
|
||||
deinit, ctype_func(ccronexpr_init)
|
||||
|
||||
next, ctype_func(ccronexpr_next)
|
||||
}
|
||||
@const_object_info_end */
|
||||
|
||||
#endif // USE_LIGHT
|
|
@ -546,7 +546,7 @@ be_local_closure(Tasmota_exec_tele, /* name */
|
|||
********************************************************************/
|
||||
be_local_closure(Tasmota_run_deferred, /* name */
|
||||
be_nested_proto(
|
||||
6, /* nstack */
|
||||
7, /* nstack */
|
||||
1, /* argc */
|
||||
2, /* varg */
|
||||
0, /* has upvals */
|
||||
|
@ -566,34 +566,32 @@ be_local_closure(Tasmota_run_deferred, /* name */
|
|||
}),
|
||||
&be_const_str_run_deferred,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[27]) { /* code */
|
||||
( &(const binstruction[25]) { /* code */
|
||||
0x88040100, // 0000 GETMBR R1 R0 K0
|
||||
0x78060017, // 0001 JMPF R1 #001A
|
||||
0x78060015, // 0001 JMPF R1 #0018
|
||||
0x58040001, // 0002 LDCONST R1 K1
|
||||
0x88080100, // 0003 GETMBR R2 R0 K0
|
||||
0x8C080502, // 0004 GETMET R2 R2 K2
|
||||
0x7C080200, // 0005 CALL R2 1
|
||||
0x14080202, // 0006 LT R2 R1 R2
|
||||
0x780A0011, // 0007 JMPF R2 #001A
|
||||
0x8C080103, // 0008 GETMET R2 R0 K3
|
||||
0x88100100, // 0009 GETMBR R4 R0 K0
|
||||
0x94100801, // 000A GETIDX R4 R4 R1
|
||||
0x88100904, // 000B GETMBR R4 R4 K4
|
||||
0x7C080400, // 000C CALL R2 2
|
||||
0x780A0009, // 000D JMPF R2 #0018
|
||||
0x88080100, // 000E GETMBR R2 R0 K0
|
||||
0x94080401, // 000F GETIDX R2 R2 R1
|
||||
0x88080505, // 0010 GETMBR R2 R2 K5
|
||||
0x880C0100, // 0011 GETMBR R3 R0 K0
|
||||
0x8C0C0706, // 0012 GETMET R3 R3 K6
|
||||
0x5C140200, // 0013 MOVE R5 R1
|
||||
0x7C0C0400, // 0014 CALL R3 2
|
||||
0x5C0C0400, // 0015 MOVE R3 R2
|
||||
0x7C0C0000, // 0016 CALL R3 0
|
||||
0x70020000, // 0017 JMP #0019
|
||||
0x00040307, // 0018 ADD R1 R1 K7
|
||||
0x7001FFE8, // 0019 JMP #0003
|
||||
0x80000000, // 001A RET 0
|
||||
0x780A000F, // 0007 JMPF R2 #0018
|
||||
0x88080100, // 0008 GETMBR R2 R0 K0
|
||||
0x94080401, // 0009 GETIDX R2 R2 R1
|
||||
0x8C0C0103, // 000A GETMET R3 R0 K3
|
||||
0x88140504, // 000B GETMBR R5 R2 K4
|
||||
0x7C0C0400, // 000C CALL R3 2
|
||||
0x780E0007, // 000D JMPF R3 #0016
|
||||
0x880C0505, // 000E GETMBR R3 R2 K5
|
||||
0x88100100, // 000F GETMBR R4 R0 K0
|
||||
0x8C100906, // 0010 GETMET R4 R4 K6
|
||||
0x5C180200, // 0011 MOVE R6 R1
|
||||
0x7C100400, // 0012 CALL R4 2
|
||||
0x5C100600, // 0013 MOVE R4 R3
|
||||
0x7C100000, // 0014 CALL R4 0
|
||||
0x70020000, // 0015 JMP #0017
|
||||
0x00040307, // 0016 ADD R1 R1 K7
|
||||
0x7001FFEA, // 0017 JMP #0003
|
||||
0x80000000, // 0018 RET 0
|
||||
})
|
||||
)
|
||||
);
|
||||
|
@ -749,125 +747,134 @@ be_local_closure(Tasmota_event, /* name */
|
|||
0, /* has sup protos */
|
||||
NULL, /* no sub protos */
|
||||
1, /* has constants */
|
||||
( &(const bvalue[23]) { /* constants */
|
||||
( &(const bvalue[26]) { /* constants */
|
||||
/* K0 */ be_nested_str(introspect),
|
||||
/* K1 */ be_nested_str(string),
|
||||
/* K2 */ be_nested_str(every_50ms),
|
||||
/* K3 */ be_nested_str(run_deferred),
|
||||
/* K4 */ be_nested_str(cmd),
|
||||
/* K5 */ be_nested_str(exec_cmd),
|
||||
/* K6 */ be_nested_str(tele),
|
||||
/* K7 */ be_nested_str(exec_tele),
|
||||
/* K8 */ be_nested_str(rule),
|
||||
/* K9 */ be_nested_str(exec_rules),
|
||||
/* K10 */ be_nested_str(gc),
|
||||
/* K11 */ be_nested_str(_drivers),
|
||||
/* K12 */ be_const_int(0),
|
||||
/* K13 */ be_nested_str(get),
|
||||
/* K14 */ be_nested_str(function),
|
||||
/* K15 */ be_nested_str(format),
|
||||
/* K16 */ be_nested_str(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s),
|
||||
/* K17 */ be_nested_str(debug),
|
||||
/* K18 */ be_nested_str(traceback),
|
||||
/* K19 */ be_const_int(1),
|
||||
/* K20 */ be_nested_str(save_before_restart),
|
||||
/* K21 */ be_nested_str(persist),
|
||||
/* K22 */ be_nested_str(save),
|
||||
/* K4 */ be_nested_str(every_250ms),
|
||||
/* K5 */ be_nested_str(run_cron),
|
||||
/* K6 */ be_nested_str(cmd),
|
||||
/* K7 */ be_nested_str(exec_cmd),
|
||||
/* K8 */ be_nested_str(tele),
|
||||
/* K9 */ be_nested_str(exec_tele),
|
||||
/* K10 */ be_nested_str(rule),
|
||||
/* K11 */ be_nested_str(exec_rules),
|
||||
/* K12 */ be_nested_str(gc),
|
||||
/* K13 */ be_nested_str(_drivers),
|
||||
/* K14 */ be_const_int(0),
|
||||
/* K15 */ be_nested_str(get),
|
||||
/* K16 */ be_nested_str(function),
|
||||
/* K17 */ be_nested_str(format),
|
||||
/* K18 */ be_nested_str(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s),
|
||||
/* K19 */ be_nested_str(_debug_present),
|
||||
/* K20 */ be_nested_str(debug),
|
||||
/* K21 */ be_nested_str(traceback),
|
||||
/* K22 */ be_const_int(1),
|
||||
/* K23 */ be_nested_str(save_before_restart),
|
||||
/* K24 */ be_nested_str(persist),
|
||||
/* K25 */ be_nested_str(save),
|
||||
}),
|
||||
&be_const_str_event,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[91]) { /* code */
|
||||
( &(const binstruction[97]) { /* code */
|
||||
0xA41A0000, // 0000 IMPORT R6 K0
|
||||
0xA41E0200, // 0001 IMPORT R7 K1
|
||||
0x1C200302, // 0002 EQ R8 R1 K2
|
||||
0x78220001, // 0003 JMPF R8 #0006
|
||||
0x8C200103, // 0004 GETMET R8 R0 K3
|
||||
0x7C200200, // 0005 CALL R8 1
|
||||
0x50200000, // 0006 LDBOOL R8 0 0
|
||||
0x1C240304, // 0007 EQ R9 R1 K4
|
||||
0x78260006, // 0008 JMPF R9 #0010
|
||||
0x8C240105, // 0009 GETMET R9 R0 K5
|
||||
0x5C2C0400, // 000A MOVE R11 R2
|
||||
0x5C300600, // 000B MOVE R12 R3
|
||||
0x5C340800, // 000C MOVE R13 R4
|
||||
0x7C240800, // 000D CALL R9 4
|
||||
0x80041200, // 000E RET 1 R9
|
||||
0x70020044, // 000F JMP #0055
|
||||
0x1C240306, // 0010 EQ R9 R1 K6
|
||||
0x78260004, // 0011 JMPF R9 #0017
|
||||
0x8C240107, // 0012 GETMET R9 R0 K7
|
||||
0x5C2C0800, // 0013 MOVE R11 R4
|
||||
0x7C240400, // 0014 CALL R9 2
|
||||
0x80041200, // 0015 RET 1 R9
|
||||
0x7002003D, // 0016 JMP #0055
|
||||
0x1C240308, // 0017 EQ R9 R1 K8
|
||||
0x78260004, // 0018 JMPF R9 #001E
|
||||
0x8C240109, // 0019 GETMET R9 R0 K9
|
||||
0x5C2C0800, // 001A MOVE R11 R4
|
||||
0x7C240400, // 001B CALL R9 2
|
||||
0x80041200, // 001C RET 1 R9
|
||||
0x70020036, // 001D JMP #0055
|
||||
0x1C24030A, // 001E EQ R9 R1 K10
|
||||
0x78260003, // 001F JMPF R9 #0024
|
||||
0x8C24010A, // 0020 GETMET R9 R0 K10
|
||||
0x7C240200, // 0021 CALL R9 1
|
||||
0x80041200, // 0022 RET 1 R9
|
||||
0x70020030, // 0023 JMP #0055
|
||||
0x8824010B, // 0024 GETMBR R9 R0 K11
|
||||
0x7826002E, // 0025 JMPF R9 #0055
|
||||
0x5824000C, // 0026 LDCONST R9 K12
|
||||
0x6028000C, // 0027 GETGBL R10 G12
|
||||
0x882C010B, // 0028 GETMBR R11 R0 K11
|
||||
0x7C280200, // 0029 CALL R10 1
|
||||
0x1428120A, // 002A LT R10 R9 R10
|
||||
0x782A0028, // 002B JMPF R10 #0055
|
||||
0x8828010B, // 002C GETMBR R10 R0 K11
|
||||
0x94281409, // 002D GETIDX R10 R10 R9
|
||||
0x8C2C0D0D, // 002E GETMET R11 R6 K13
|
||||
0x5C341400, // 002F MOVE R13 R10
|
||||
0x5C380200, // 0030 MOVE R14 R1
|
||||
0x7C2C0600, // 0031 CALL R11 3
|
||||
0x60300004, // 0032 GETGBL R12 G4
|
||||
0x5C341600, // 0033 MOVE R13 R11
|
||||
0x7C300200, // 0034 CALL R12 1
|
||||
0x1C30190E, // 0035 EQ R12 R12 K14
|
||||
0x7832001B, // 0036 JMPF R12 #0053
|
||||
0xA802000C, // 0037 EXBLK 0 #0045
|
||||
0x5C301600, // 0038 MOVE R12 R11
|
||||
0x5C341400, // 0039 MOVE R13 R10
|
||||
0x5C380400, // 003A MOVE R14 R2
|
||||
0x5C3C0600, // 003B MOVE R15 R3
|
||||
0x5C400800, // 003C MOVE R16 R4
|
||||
0x5C440A00, // 003D MOVE R17 R5
|
||||
0x7C300A00, // 003E CALL R12 5
|
||||
0x5C201800, // 003F MOVE R8 R12
|
||||
0x78220001, // 0040 JMPF R8 #0043
|
||||
0xA8040001, // 0041 EXBLK 1 1
|
||||
0x70020011, // 0042 JMP #0055
|
||||
0xA8040001, // 0043 EXBLK 1 1
|
||||
0x7002000D, // 0044 JMP #0053
|
||||
0xAC300002, // 0045 CATCH R12 0 2
|
||||
0x7002000A, // 0046 JMP #0052
|
||||
0x60380001, // 0047 GETGBL R14 G1
|
||||
0x8C3C0F0F, // 0048 GETMET R15 R7 K15
|
||||
0x58440010, // 0049 LDCONST R17 K16
|
||||
0x5C481800, // 004A MOVE R18 R12
|
||||
0x5C4C1A00, // 004B MOVE R19 R13
|
||||
0x7C3C0800, // 004C CALL R15 4
|
||||
0x7C380200, // 004D CALL R14 1
|
||||
0xA43A2200, // 004E IMPORT R14 K17
|
||||
0x8C3C1D12, // 004F GETMET R15 R14 K18
|
||||
0x7C3C0200, // 0050 CALL R15 1
|
||||
0x70020000, // 0051 JMP #0053
|
||||
0xB0080000, // 0052 RAISE 2 R0 R0
|
||||
0x00241313, // 0053 ADD R9 R9 K19
|
||||
0x7001FFD1, // 0054 JMP #0027
|
||||
0x1C240314, // 0055 EQ R9 R1 K20
|
||||
0x78260002, // 0056 JMPF R9 #005A
|
||||
0xA4262A00, // 0057 IMPORT R9 K21
|
||||
0x8C281316, // 0058 GETMET R10 R9 K22
|
||||
0x7C280200, // 0059 CALL R10 1
|
||||
0x80041000, // 005A RET 1 R8
|
||||
0x1C200304, // 0006 EQ R8 R1 K4
|
||||
0x78220001, // 0007 JMPF R8 #000A
|
||||
0x8C200105, // 0008 GETMET R8 R0 K5
|
||||
0x7C200200, // 0009 CALL R8 1
|
||||
0x50200000, // 000A LDBOOL R8 0 0
|
||||
0x1C240306, // 000B EQ R9 R1 K6
|
||||
0x78260006, // 000C JMPF R9 #0014
|
||||
0x8C240107, // 000D GETMET R9 R0 K7
|
||||
0x5C2C0400, // 000E MOVE R11 R2
|
||||
0x5C300600, // 000F MOVE R12 R3
|
||||
0x5C340800, // 0010 MOVE R13 R4
|
||||
0x7C240800, // 0011 CALL R9 4
|
||||
0x80041200, // 0012 RET 1 R9
|
||||
0x70020046, // 0013 JMP #005B
|
||||
0x1C240308, // 0014 EQ R9 R1 K8
|
||||
0x78260004, // 0015 JMPF R9 #001B
|
||||
0x8C240109, // 0016 GETMET R9 R0 K9
|
||||
0x5C2C0800, // 0017 MOVE R11 R4
|
||||
0x7C240400, // 0018 CALL R9 2
|
||||
0x80041200, // 0019 RET 1 R9
|
||||
0x7002003F, // 001A JMP #005B
|
||||
0x1C24030A, // 001B EQ R9 R1 K10
|
||||
0x78260004, // 001C JMPF R9 #0022
|
||||
0x8C24010B, // 001D GETMET R9 R0 K11
|
||||
0x5C2C0800, // 001E MOVE R11 R4
|
||||
0x7C240400, // 001F CALL R9 2
|
||||
0x80041200, // 0020 RET 1 R9
|
||||
0x70020038, // 0021 JMP #005B
|
||||
0x1C24030C, // 0022 EQ R9 R1 K12
|
||||
0x78260003, // 0023 JMPF R9 #0028
|
||||
0x8C24010C, // 0024 GETMET R9 R0 K12
|
||||
0x7C240200, // 0025 CALL R9 1
|
||||
0x80041200, // 0026 RET 1 R9
|
||||
0x70020032, // 0027 JMP #005B
|
||||
0x8824010D, // 0028 GETMBR R9 R0 K13
|
||||
0x78260030, // 0029 JMPF R9 #005B
|
||||
0x5824000E, // 002A LDCONST R9 K14
|
||||
0x6028000C, // 002B GETGBL R10 G12
|
||||
0x882C010D, // 002C GETMBR R11 R0 K13
|
||||
0x7C280200, // 002D CALL R10 1
|
||||
0x1428120A, // 002E LT R10 R9 R10
|
||||
0x782A002A, // 002F JMPF R10 #005B
|
||||
0x8828010D, // 0030 GETMBR R10 R0 K13
|
||||
0x94281409, // 0031 GETIDX R10 R10 R9
|
||||
0x8C2C0D0F, // 0032 GETMET R11 R6 K15
|
||||
0x5C341400, // 0033 MOVE R13 R10
|
||||
0x5C380200, // 0034 MOVE R14 R1
|
||||
0x7C2C0600, // 0035 CALL R11 3
|
||||
0x60300004, // 0036 GETGBL R12 G4
|
||||
0x5C341600, // 0037 MOVE R13 R11
|
||||
0x7C300200, // 0038 CALL R12 1
|
||||
0x1C301910, // 0039 EQ R12 R12 K16
|
||||
0x7832001D, // 003A JMPF R12 #0059
|
||||
0xA802000C, // 003B EXBLK 0 #0049
|
||||
0x5C301600, // 003C MOVE R12 R11
|
||||
0x5C341400, // 003D MOVE R13 R10
|
||||
0x5C380400, // 003E MOVE R14 R2
|
||||
0x5C3C0600, // 003F MOVE R15 R3
|
||||
0x5C400800, // 0040 MOVE R16 R4
|
||||
0x5C440A00, // 0041 MOVE R17 R5
|
||||
0x7C300A00, // 0042 CALL R12 5
|
||||
0x5C201800, // 0043 MOVE R8 R12
|
||||
0x78220001, // 0044 JMPF R8 #0047
|
||||
0xA8040001, // 0045 EXBLK 1 1
|
||||
0x70020013, // 0046 JMP #005B
|
||||
0xA8040001, // 0047 EXBLK 1 1
|
||||
0x7002000F, // 0048 JMP #0059
|
||||
0xAC300002, // 0049 CATCH R12 0 2
|
||||
0x7002000C, // 004A JMP #0058
|
||||
0x60380001, // 004B GETGBL R14 G1
|
||||
0x8C3C0F11, // 004C GETMET R15 R7 K17
|
||||
0x58440012, // 004D LDCONST R17 K18
|
||||
0x5C481800, // 004E MOVE R18 R12
|
||||
0x5C4C1A00, // 004F MOVE R19 R13
|
||||
0x7C3C0800, // 0050 CALL R15 4
|
||||
0x7C380200, // 0051 CALL R14 1
|
||||
0x88380113, // 0052 GETMBR R14 R0 K19
|
||||
0x783A0002, // 0053 JMPF R14 #0057
|
||||
0xA43A2800, // 0054 IMPORT R14 K20
|
||||
0x8C3C1D15, // 0055 GETMET R15 R14 K21
|
||||
0x7C3C0200, // 0056 CALL R15 1
|
||||
0x70020000, // 0057 JMP #0059
|
||||
0xB0080000, // 0058 RAISE 2 R0 R0
|
||||
0x00241316, // 0059 ADD R9 R9 K22
|
||||
0x7001FFCF, // 005A JMP #002B
|
||||
0x1C240317, // 005B EQ R9 R1 K23
|
||||
0x78260002, // 005C JMPF R9 #0060
|
||||
0xA4263000, // 005D IMPORT R9 K24
|
||||
0x8C281319, // 005E GETMET R10 R9 K25
|
||||
0x7C280200, // 005F CALL R10 1
|
||||
0x80041000, // 0060 RET 1 R8
|
||||
})
|
||||
)
|
||||
);
|
||||
|
@ -1949,6 +1956,185 @@ be_local_closure(Tasmota_set_timer, /* name */
|
|||
** Solidified function: remove_timer
|
||||
********************************************************************/
|
||||
be_local_closure(Tasmota_remove_timer, /* name */
|
||||
be_nested_proto(
|
||||
7, /* nstack */
|
||||
2, /* argc */
|
||||
2, /* varg */
|
||||
0, /* has upvals */
|
||||
NULL, /* no upvals */
|
||||
0, /* has sup protos */
|
||||
NULL, /* no sub protos */
|
||||
1, /* has constants */
|
||||
( &(const bvalue[ 6]) { /* constants */
|
||||
/* K0 */ be_nested_str(_timers),
|
||||
/* K1 */ be_const_int(0),
|
||||
/* K2 */ be_nested_str(size),
|
||||
/* K3 */ be_nested_str(id),
|
||||
/* K4 */ be_nested_str(remove),
|
||||
/* K5 */ be_const_int(1),
|
||||
}),
|
||||
&be_const_str_remove_timer,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[18]) { /* code */
|
||||
0x88080100, // 0000 GETMBR R2 R0 K0
|
||||
0x780A000E, // 0001 JMPF R2 #0011
|
||||
0x580C0001, // 0002 LDCONST R3 K1
|
||||
0x8C100502, // 0003 GETMET R4 R2 K2
|
||||
0x7C100200, // 0004 CALL R4 1
|
||||
0x14100604, // 0005 LT R4 R3 R4
|
||||
0x78120009, // 0006 JMPF R4 #0011
|
||||
0x94100403, // 0007 GETIDX R4 R2 R3
|
||||
0x88100903, // 0008 GETMBR R4 R4 K3
|
||||
0x1C100801, // 0009 EQ R4 R4 R1
|
||||
0x78120003, // 000A JMPF R4 #000F
|
||||
0x8C100504, // 000B GETMET R4 R2 K4
|
||||
0x5C180600, // 000C MOVE R6 R3
|
||||
0x7C100400, // 000D CALL R4 2
|
||||
0x70020000, // 000E JMP #0010
|
||||
0x000C0705, // 000F ADD R3 R3 K5
|
||||
0x7001FFF1, // 0010 JMP #0003
|
||||
0x80000000, // 0011 RET 0
|
||||
})
|
||||
)
|
||||
);
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
/********************************************************************
|
||||
** Solidified function: add_cron
|
||||
********************************************************************/
|
||||
be_local_closure(Tasmota_add_cron, /* name */
|
||||
be_nested_proto(
|
||||
13, /* nstack */
|
||||
4, /* argc */
|
||||
2, /* varg */
|
||||
0, /* has upvals */
|
||||
NULL, /* no upvals */
|
||||
0, /* has sup protos */
|
||||
NULL, /* no sub protos */
|
||||
1, /* has constants */
|
||||
( &(const bvalue[ 8]) { /* constants */
|
||||
/* K0 */ be_nested_str(check_not_method),
|
||||
/* K1 */ be_nested_str(_crons),
|
||||
/* K2 */ be_nested_str(ccronexpr),
|
||||
/* K3 */ be_nested_str(next),
|
||||
/* K4 */ be_nested_str(rtc),
|
||||
/* K5 */ be_nested_str(local),
|
||||
/* K6 */ be_nested_str(push),
|
||||
/* K7 */ be_nested_str(Trigger),
|
||||
}),
|
||||
&be_const_str_add_cron,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[28]) { /* code */
|
||||
0x8C100100, // 0000 GETMET R4 R0 K0
|
||||
0x5C180400, // 0001 MOVE R6 R2
|
||||
0x7C100400, // 0002 CALL R4 2
|
||||
0x88100101, // 0003 GETMBR R4 R0 K1
|
||||
0x74120002, // 0004 JMPT R4 #0008
|
||||
0x60100012, // 0005 GETGBL R4 G18
|
||||
0x7C100000, // 0006 CALL R4 0
|
||||
0x90020204, // 0007 SETMBR R0 K1 R4
|
||||
0xB8120400, // 0008 GETNGBL R4 K2
|
||||
0x60140008, // 0009 GETGBL R5 G8
|
||||
0x5C180200, // 000A MOVE R6 R1
|
||||
0x7C140200, // 000B CALL R5 1
|
||||
0x7C100200, // 000C CALL R4 1
|
||||
0x8C140903, // 000D GETMET R5 R4 K3
|
||||
0x8C1C0104, // 000E GETMET R7 R0 K4
|
||||
0x7C1C0200, // 000F CALL R7 1
|
||||
0x941C0F05, // 0010 GETIDX R7 R7 K5
|
||||
0x7C140400, // 0011 CALL R5 2
|
||||
0x88180101, // 0012 GETMBR R6 R0 K1
|
||||
0x8C180D06, // 0013 GETMET R6 R6 K6
|
||||
0xB8220E00, // 0014 GETNGBL R8 K7
|
||||
0x5C240A00, // 0015 MOVE R9 R5
|
||||
0x5C280400, // 0016 MOVE R10 R2
|
||||
0x5C2C0600, // 0017 MOVE R11 R3
|
||||
0x5C300800, // 0018 MOVE R12 R4
|
||||
0x7C200800, // 0019 CALL R8 4
|
||||
0x7C180400, // 001A CALL R6 2
|
||||
0x80000000, // 001B RET 0
|
||||
})
|
||||
)
|
||||
);
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
/********************************************************************
|
||||
** Solidified function: run_cron
|
||||
********************************************************************/
|
||||
be_local_closure(Tasmota_run_cron, /* name */
|
||||
be_nested_proto(
|
||||
9, /* nstack */
|
||||
1, /* argc */
|
||||
2, /* varg */
|
||||
0, /* has upvals */
|
||||
NULL, /* no upvals */
|
||||
0, /* has sup protos */
|
||||
NULL, /* no sub protos */
|
||||
1, /* has constants */
|
||||
( &(const bvalue[10]) { /* constants */
|
||||
/* K0 */ be_nested_str(_crons),
|
||||
/* K1 */ be_const_int(0),
|
||||
/* K2 */ be_nested_str(rtc),
|
||||
/* K3 */ be_nested_str(local),
|
||||
/* K4 */ be_nested_str(size),
|
||||
/* K5 */ be_nested_str(trig),
|
||||
/* K6 */ be_nested_str(f),
|
||||
/* K7 */ be_nested_str(next),
|
||||
/* K8 */ be_nested_str(remove),
|
||||
/* K9 */ be_const_int(1),
|
||||
}),
|
||||
&be_const_str_run_cron,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[37]) { /* code */
|
||||
0x88040100, // 0000 GETMBR R1 R0 K0
|
||||
0x78060021, // 0001 JMPF R1 #0024
|
||||
0x58040001, // 0002 LDCONST R1 K1
|
||||
0x8C080102, // 0003 GETMET R2 R0 K2
|
||||
0x7C080200, // 0004 CALL R2 1
|
||||
0x94080503, // 0005 GETIDX R2 R2 K3
|
||||
0x880C0100, // 0006 GETMBR R3 R0 K0
|
||||
0x8C0C0704, // 0007 GETMET R3 R3 K4
|
||||
0x7C0C0200, // 0008 CALL R3 1
|
||||
0x140C0203, // 0009 LT R3 R1 R3
|
||||
0x780E0018, // 000A JMPF R3 #0024
|
||||
0x880C0100, // 000B GETMBR R3 R0 K0
|
||||
0x940C0601, // 000C GETIDX R3 R3 R1
|
||||
0x88100705, // 000D GETMBR R4 R3 K5
|
||||
0x18100802, // 000E LE R4 R4 R2
|
||||
0x78120011, // 000F JMPF R4 #0022
|
||||
0x88100706, // 0010 GETMBR R4 R3 K6
|
||||
0x8C140707, // 0011 GETMET R5 R3 K7
|
||||
0x5C1C0400, // 0012 MOVE R7 R2
|
||||
0x7C140400, // 0013 CALL R5 2
|
||||
0x5C180A00, // 0014 MOVE R6 R5
|
||||
0x741A0004, // 0015 JMPT R6 #001B
|
||||
0x88180100, // 0016 GETMBR R6 R0 K0
|
||||
0x8C180D08, // 0017 GETMET R6 R6 K8
|
||||
0x5C200200, // 0018 MOVE R8 R1
|
||||
0x7C180400, // 0019 CALL R6 2
|
||||
0x70020001, // 001A JMP #001D
|
||||
0x900E0A05, // 001B SETMBR R3 K5 R5
|
||||
0x00040309, // 001C ADD R1 R1 K9
|
||||
0x5C180800, // 001D MOVE R6 R4
|
||||
0x5C1C0400, // 001E MOVE R7 R2
|
||||
0x5C200A00, // 001F MOVE R8 R5
|
||||
0x7C180400, // 0020 CALL R6 2
|
||||
0x70020000, // 0021 JMP #0023
|
||||
0x00040309, // 0022 ADD R1 R1 K9
|
||||
0x7001FFE1, // 0023 JMP #0006
|
||||
0x80000000, // 0024 RET 0
|
||||
})
|
||||
)
|
||||
);
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
/********************************************************************
|
||||
** Solidified function: next_cron
|
||||
********************************************************************/
|
||||
be_local_closure(Tasmota_next_cron, /* name */
|
||||
be_nested_proto(
|
||||
6, /* nstack */
|
||||
2, /* argc */
|
||||
|
@ -1958,41 +2144,80 @@ be_local_closure(Tasmota_remove_timer, /* name */
|
|||
0, /* has sup protos */
|
||||
NULL, /* no sub protos */
|
||||
1, /* has constants */
|
||||
( &(const bvalue[ 7]) { /* constants */
|
||||
/* K0 */ be_nested_str(tasmota),
|
||||
/* K1 */ be_nested_str(_timers),
|
||||
/* K2 */ be_const_int(0),
|
||||
/* K3 */ be_nested_str(size),
|
||||
/* K4 */ be_nested_str(id),
|
||||
/* K5 */ be_nested_str(remove),
|
||||
/* K6 */ be_const_int(1),
|
||||
( &(const bvalue[ 5]) { /* constants */
|
||||
/* K0 */ be_nested_str(_crons),
|
||||
/* K1 */ be_const_int(0),
|
||||
/* K2 */ be_nested_str(size),
|
||||
/* K3 */ be_nested_str(id),
|
||||
/* K4 */ be_nested_str(trig),
|
||||
}),
|
||||
&be_const_str_remove_timer,
|
||||
&be_const_str_next_cron,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[23]) { /* code */
|
||||
0xB80A0000, // 0000 GETNGBL R2 K0
|
||||
0x88080501, // 0001 GETMBR R2 R2 K1
|
||||
0x780A0012, // 0002 JMPF R2 #0016
|
||||
0x58080002, // 0003 LDCONST R2 K2
|
||||
0xB80E0000, // 0004 GETNGBL R3 K0
|
||||
0x880C0701, // 0005 GETMBR R3 R3 K1
|
||||
0x8C0C0703, // 0006 GETMET R3 R3 K3
|
||||
0x7C0C0200, // 0007 CALL R3 1
|
||||
0x140C0403, // 0008 LT R3 R2 R3
|
||||
0x780E000B, // 0009 JMPF R3 #0016
|
||||
0x880C0101, // 000A GETMBR R3 R0 K1
|
||||
0x940C0602, // 000B GETIDX R3 R3 R2
|
||||
0x880C0704, // 000C GETMBR R3 R3 K4
|
||||
0x1C0C0601, // 000D EQ R3 R3 R1
|
||||
0x780E0004, // 000E JMPF R3 #0014
|
||||
0x880C0101, // 000F GETMBR R3 R0 K1
|
||||
0x8C0C0705, // 0010 GETMET R3 R3 K5
|
||||
0x5C140400, // 0011 MOVE R5 R2
|
||||
0x7C0C0400, // 0012 CALL R3 2
|
||||
0x70020000, // 0013 JMP #0015
|
||||
0x00080506, // 0014 ADD R2 R2 K6
|
||||
0x7001FFED, // 0015 JMP #0004
|
||||
0x80000000, // 0016 RET 0
|
||||
( &(const binstruction[16]) { /* code */
|
||||
0x88080100, // 0000 GETMBR R2 R0 K0
|
||||
0x780A000C, // 0001 JMPF R2 #000F
|
||||
0x580C0001, // 0002 LDCONST R3 K1
|
||||
0x8C100502, // 0003 GETMET R4 R2 K2
|
||||
0x7C100200, // 0004 CALL R4 1
|
||||
0x14100604, // 0005 LT R4 R3 R4
|
||||
0x78120007, // 0006 JMPF R4 #000F
|
||||
0x94100403, // 0007 GETIDX R4 R2 R3
|
||||
0x88100903, // 0008 GETMBR R4 R4 K3
|
||||
0x1C100801, // 0009 EQ R4 R4 R1
|
||||
0x78120002, // 000A JMPF R4 #000E
|
||||
0x94100403, // 000B GETIDX R4 R2 R3
|
||||
0x88100904, // 000C GETMBR R4 R4 K4
|
||||
0x80040800, // 000D RET 1 R4
|
||||
0x7001FFF3, // 000E JMP #0003
|
||||
0x80000000, // 000F RET 0
|
||||
})
|
||||
)
|
||||
);
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
/********************************************************************
|
||||
** Solidified function: remove_cron
|
||||
********************************************************************/
|
||||
be_local_closure(Tasmota_remove_cron, /* name */
|
||||
be_nested_proto(
|
||||
7, /* nstack */
|
||||
2, /* argc */
|
||||
2, /* varg */
|
||||
0, /* has upvals */
|
||||
NULL, /* no upvals */
|
||||
0, /* has sup protos */
|
||||
NULL, /* no sub protos */
|
||||
1, /* has constants */
|
||||
( &(const bvalue[ 6]) { /* constants */
|
||||
/* K0 */ be_nested_str(_crons),
|
||||
/* K1 */ be_const_int(0),
|
||||
/* K2 */ be_nested_str(size),
|
||||
/* K3 */ be_nested_str(id),
|
||||
/* K4 */ be_nested_str(remove),
|
||||
/* K5 */ be_const_int(1),
|
||||
}),
|
||||
&be_const_str_remove_cron,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[18]) { /* code */
|
||||
0x88080100, // 0000 GETMBR R2 R0 K0
|
||||
0x780A000E, // 0001 JMPF R2 #0011
|
||||
0x580C0001, // 0002 LDCONST R3 K1
|
||||
0x8C100502, // 0003 GETMET R4 R2 K2
|
||||
0x7C100200, // 0004 CALL R4 1
|
||||
0x14100604, // 0005 LT R4 R3 R4
|
||||
0x78120009, // 0006 JMPF R4 #0011
|
||||
0x94100403, // 0007 GETIDX R4 R2 R3
|
||||
0x88100903, // 0008 GETMBR R4 R4 K3
|
||||
0x1C100801, // 0009 EQ R4 R4 R1
|
||||
0x78120003, // 000A JMPF R4 #000F
|
||||
0x8C100504, // 000B GETMET R4 R2 K4
|
||||
0x5C180600, // 000C MOVE R6 R3
|
||||
0x7C100400, // 000D CALL R4 2
|
||||
0x70020000, // 000E JMP #0010
|
||||
0x000C0705, // 000F ADD R3 R3 K5
|
||||
0x7001FFF1, // 0010 JMP #0003
|
||||
0x80000000, // 0011 RET 0
|
||||
})
|
||||
)
|
||||
);
|
||||
|
@ -2157,6 +2382,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
|
|||
_fl, var
|
||||
_rules, var
|
||||
_timers, var
|
||||
_crons, var
|
||||
_ccmd, var
|
||||
_drivers, var
|
||||
wire1, var
|
||||
|
@ -2240,6 +2466,11 @@ class be_class_tasmota (scope: global, name: Tasmota) {
|
|||
wire_scan, closure(Tasmota_wire_scan_closure)
|
||||
time_str, closure(Tasmota_time_str_closure)
|
||||
|
||||
add_cron, closure(Tasmota_add_cron_closure)
|
||||
run_cron, closure(Tasmota_run_cron_closure)
|
||||
next_cron, closure(Tasmota_next_cron_closure)
|
||||
remove_cron, closure(Tasmota_remove_cron_closure)
|
||||
|
||||
check_not_method, closure(Tasmota_check_not_method_closure)
|
||||
|
||||
hs2rgb, closure(Tasmota_hs2rgb_closure)
|
||||
|
|
|
@ -59,26 +59,62 @@ be_local_closure(Trigger_tostring, /* name */
|
|||
********************************************************************/
|
||||
be_local_closure(Trigger_init, /* name */
|
||||
be_nested_proto(
|
||||
4, /* nstack */
|
||||
4, /* argc */
|
||||
5, /* nstack */
|
||||
5, /* argc */
|
||||
2, /* varg */
|
||||
0, /* has upvals */
|
||||
NULL, /* no upvals */
|
||||
0, /* has sup protos */
|
||||
NULL, /* no sub protos */
|
||||
1, /* has constants */
|
||||
( &(const bvalue[ 3]) { /* constants */
|
||||
( &(const bvalue[ 4]) { /* constants */
|
||||
/* K0 */ be_nested_str(trig),
|
||||
/* K1 */ be_nested_str(f),
|
||||
/* K2 */ be_nested_str(id),
|
||||
/* K3 */ be_nested_str(o),
|
||||
}),
|
||||
&be_const_str_init,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[ 4]) { /* code */
|
||||
( &(const binstruction[ 5]) { /* code */
|
||||
0x90020001, // 0000 SETMBR R0 K0 R1
|
||||
0x90020202, // 0001 SETMBR R0 K1 R2
|
||||
0x90020403, // 0002 SETMBR R0 K2 R3
|
||||
0x80000000, // 0003 RET 0
|
||||
0x90020604, // 0003 SETMBR R0 K3 R4
|
||||
0x80000000, // 0004 RET 0
|
||||
})
|
||||
)
|
||||
);
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
/********************************************************************
|
||||
** Solidified function: next
|
||||
********************************************************************/
|
||||
be_local_closure(Trigger_next, /* name */
|
||||
be_nested_proto(
|
||||
5, /* nstack */
|
||||
2, /* argc */
|
||||
2, /* varg */
|
||||
0, /* has upvals */
|
||||
NULL, /* no upvals */
|
||||
0, /* has sup protos */
|
||||
NULL, /* no sub protos */
|
||||
1, /* has constants */
|
||||
( &(const bvalue[ 2]) { /* constants */
|
||||
/* K0 */ be_nested_str(o),
|
||||
/* K1 */ be_nested_str(next),
|
||||
}),
|
||||
&be_const_str_next,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[ 8]) { /* code */
|
||||
0x88080100, // 0000 GETMBR R2 R0 K0
|
||||
0x780A0004, // 0001 JMPF R2 #0007
|
||||
0x88080100, // 0002 GETMBR R2 R0 K0
|
||||
0x8C080501, // 0003 GETMET R2 R2 K1
|
||||
0x5C100200, // 0004 MOVE R4 R1
|
||||
0x7C080400, // 0005 CALL R2 2
|
||||
0x80040400, // 0006 RET 1 R2
|
||||
0x80000000, // 0007 RET 0
|
||||
})
|
||||
)
|
||||
);
|
||||
|
@ -89,15 +125,17 @@ be_local_closure(Trigger_init, /* name */
|
|||
** Solidified class: Trigger
|
||||
********************************************************************/
|
||||
be_local_class(Trigger,
|
||||
3,
|
||||
4,
|
||||
NULL,
|
||||
be_nested_map(5,
|
||||
be_nested_map(7,
|
||||
( (struct bmapnode*) &(const bmapnode[]) {
|
||||
{ be_const_key(tostring, 3), be_const_closure(Trigger_tostring_closure) },
|
||||
{ be_const_key(id, 2), be_const_var(2) },
|
||||
{ be_const_key(f, -1), be_const_var(1) },
|
||||
{ be_const_key(f, 1), be_const_var(1) },
|
||||
{ be_const_key(o, -1), be_const_var(3) },
|
||||
{ be_const_key(init, -1), be_const_closure(Trigger_init_closure) },
|
||||
{ be_const_key(trig, -1), be_const_var(0) },
|
||||
{ be_const_key(id, 4), be_const_var(2) },
|
||||
{ be_const_key(tostring, -1), be_const_closure(Trigger_tostring_closure) },
|
||||
{ be_const_key(trig, 2), be_const_var(0) },
|
||||
{ be_const_key(next, -1), be_const_closure(Trigger_next_closure) },
|
||||
})),
|
||||
be_str_literal("Trigger")
|
||||
);
|
||||
|
|
|
@ -3,23 +3,32 @@
|
|||
|
||||
class Trigger
|
||||
var trig, f, id
|
||||
def init(trig, f, id)
|
||||
var o # optional object
|
||||
def init(trig, f, id, o)
|
||||
self.trig = trig
|
||||
self.f = f
|
||||
self.id = id
|
||||
self.o = o
|
||||
end
|
||||
def tostring()
|
||||
import string
|
||||
return string.format("<instance: %s(%s, %s, %s)", str(classof(self)),
|
||||
str(self.trig), str(self.f), str(self.id))
|
||||
end
|
||||
# next(now) returns the next trigger, or nil if no more
|
||||
def next(now)
|
||||
if self.o
|
||||
return self.o.next(now)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tasmota = nil
|
||||
class Tasmota
|
||||
var _fl # list of fast_loop registered closures
|
||||
var _rules
|
||||
var _timers
|
||||
var _timers # holds both timers and cron
|
||||
var _crons
|
||||
var _ccmd
|
||||
var _drivers
|
||||
var wire1
|
||||
|
@ -244,11 +253,76 @@ class Tasmota
|
|||
def run_deferred()
|
||||
if self._timers
|
||||
var i=0
|
||||
while i<self._timers.size()
|
||||
if self.time_reached(self._timers[i].trig)
|
||||
var f=self._timers[i].f
|
||||
self._timers.remove(i)
|
||||
while i < self._timers.size()
|
||||
var trigger = self._timers[i]
|
||||
|
||||
if self.time_reached(trigger.trig)
|
||||
var f = trigger.f
|
||||
self._timers.remove(i) # one shot event
|
||||
f()
|
||||
else
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run_cron()
|
||||
if self._crons
|
||||
var i=0
|
||||
var now = self.rtc()['local'] # now in epoch seconds
|
||||
while i < self._crons.size()
|
||||
var trigger = self._crons[i]
|
||||
|
||||
if trigger.trig <= now
|
||||
var f = trigger.f
|
||||
var next_time = trigger.next(now)
|
||||
if !next_time
|
||||
self._crons.remove(i) # one shot event
|
||||
else
|
||||
trigger.trig = next_time # recurring event
|
||||
i += 1
|
||||
end
|
||||
f(now, next_time)
|
||||
else
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def remove_timer(id)
|
||||
var timers = self._timers
|
||||
if timers
|
||||
var i=0
|
||||
while i < timers.size()
|
||||
if timers[i].id == id
|
||||
timers.remove(i)
|
||||
else
|
||||
i=i+1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# crontab style recurring events
|
||||
def add_cron(pattern,f,id)
|
||||
self.check_not_method(f)
|
||||
if !self._crons self._crons=[] end
|
||||
var cron = ccronexpr(str(pattern)) # can fail, throwing an exception
|
||||
var next_time = cron.next(self.rtc()['local'])
|
||||
|
||||
self._crons.push(Trigger(next_time, f, id, cron))
|
||||
end
|
||||
|
||||
# remove cron by id
|
||||
def remove_cron(id)
|
||||
var crons = self._crons
|
||||
if crons
|
||||
var i=0
|
||||
while i < crons.size()
|
||||
if crons[i].id == id
|
||||
crons.remove(i)
|
||||
else
|
||||
i=i+1
|
||||
end
|
||||
|
@ -256,15 +330,14 @@ class Tasmota
|
|||
end
|
||||
end
|
||||
|
||||
# remove timers by id
|
||||
def remove_timer(id)
|
||||
if tasmota._timers
|
||||
# get next timestamp for cron
|
||||
def next_cron(id)
|
||||
var crons = self._crons
|
||||
if crons
|
||||
var i=0
|
||||
while i<tasmota._timers.size()
|
||||
if self._timers[i].id == id
|
||||
self._timers.remove(i)
|
||||
else
|
||||
i=i+1
|
||||
while i < crons.size()
|
||||
if crons[i].id == id
|
||||
return crons[i].trig
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -454,7 +527,13 @@ class Tasmota
|
|||
def event(event_type, cmd, idx, payload, raw)
|
||||
import introspect
|
||||
import string
|
||||
if event_type=='every_50ms' self.run_deferred() end #- first run deferred events -#
|
||||
if event_type=='every_50ms'
|
||||
self.run_deferred()
|
||||
end #- first run deferred events -#
|
||||
|
||||
if event_type=='every_250ms'
|
||||
self.run_cron()
|
||||
end
|
||||
|
||||
var done = false
|
||||
if event_type=='cmd' return self.exec_cmd(cmd, idx, payload)
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2015, staticlibs.net
|
||||
|
||||
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.
|
|
@ -0,0 +1,97 @@
|
|||
Cron expression parsing in ANSI C
|
||||
=================================
|
||||
|
||||
[![travis](https://travis-ci.org/staticlibs/ccronexpr.svg?branch=master)](https://travis-ci.org/staticlibs/ccronexpr)
|
||||
[![appveyor](https://ci.appveyor.com/api/projects/status/github/staticlibs/ccronexpr?svg=true)](https://ci.appveyor.com/project/staticlibs/ccronexpr)
|
||||
|
||||
Given a cron expression and a date, you can get the next date which satisfies the cron expression.
|
||||
|
||||
Supports cron expressions with `seconds` field. Based on implementation of [CronSequenceGenerator](https://github.com/spring-projects/spring-framework/blob/babbf6e8710ab937cd05ece20270f51490299270/spring-context/src/main/java/org/springframework/scheduling/support/CronSequenceGenerator.java) from Spring Framework.
|
||||
|
||||
Compiles and should work on Linux (GCC/Clang), Mac OS (Clang), Windows (MSVC), Android NDK, iOS and possibly on other platforms with `time.h` support.
|
||||
|
||||
Supports compilation in C (89) and in C++ modes.
|
||||
|
||||
Usage example
|
||||
-------------
|
||||
|
||||
#include "ccronexpr.h"
|
||||
|
||||
cron_expr expr;
|
||||
const char* err = NULL;
|
||||
memset(&expr, 0, sizeof(expr));
|
||||
cron_parse_expr("0 */2 1-4 * * *", &expr, &err);
|
||||
if (err) ... /* invalid expression */
|
||||
time_t cur = time(NULL);
|
||||
time_t next = cron_next(&expr, cur);
|
||||
|
||||
|
||||
Compilation and tests run examples
|
||||
----------------------------------
|
||||
|
||||
gcc ccronexpr.c ccronexpr_test.c -I. -Wall -Wextra -std=c89 -DCRON_TEST_MALLOC -o a.out && ./a.out
|
||||
g++ ccronexpr.c ccronexpr_test.c -I. -Wall -Wextra -std=c++11 -DCRON_TEST_MALLOC -o a.out && ./a.out
|
||||
g++ ccronexpr.c ccronexpr_test.c -I. -Wall -Wextra -std=c++11 -DCRON_TEST_MALLOC -DCRON_COMPILE_AS_CXX -o a.out && ./a.out
|
||||
|
||||
clang ccronexpr.c ccronexpr_test.c -I. -Wall -Wextra -std=c89 -DCRON_TEST_MALLOC -o a.out && ./a.out
|
||||
clang++ ccronexpr.c ccronexpr_test.c -I. -Wall -Wextra -std=c++11 -DCRON_TEST_MALLOC -o a.out && ./a.out
|
||||
clang++ ccronexpr.c ccronexpr_test.c -I. -Wall -Wextra -std=c++11 -DCRON_TEST_MALLOC -DCRON_COMPILE_AS_CXX -o a.out && ./a.out
|
||||
|
||||
cl ccronexpr.c ccronexpr_test.c /W4 /D_CRT_SECURE_NO_WARNINGS && ccronexpr.exe
|
||||
|
||||
Examples of supported expressions
|
||||
---------------------------------
|
||||
|
||||
Expression, input date, next date:
|
||||
|
||||
"*/15 * 1-4 * * *", "2012-07-01_09:53:50", "2012-07-02_01:00:00"
|
||||
"0 */2 1-4 * * *", "2012-07-01_09:00:00", "2012-07-02_01:00:00"
|
||||
"0 0 7 ? * MON-FRI", "2009-09-26_00:42:55", "2009-09-28_07:00:00"
|
||||
"0 30 23 30 1/3 ?", "2011-04-30_23:30:00", "2011-07-30_23:30:00"
|
||||
|
||||
See more examples in [tests](https://github.com/staticlibs/ccronexpr/blob/a1343bc5a546b13430bd4ac72f3b047ac08f8192/ccronexpr_test.c#L251).
|
||||
|
||||
Timezones
|
||||
---------
|
||||
|
||||
This implementation does not support explicit timezones handling. By default all dates are
|
||||
processed as UTC (GMT) dates without timezone infomation.
|
||||
|
||||
To use local dates (current system timezone) instead of GMT compile with `-DCRON_USE_LOCAL_TIME`, example:
|
||||
|
||||
gcc -DCRON_USE_LOCAL_TIME ccronexpr.c ccronexpr_test.c -I. -Wall -Wextra -std=c89 -DCRON_TEST_MALLOC -o a.out && TZ="America/Toronto" ./a.out
|
||||
|
||||
License information
|
||||
-------------------
|
||||
|
||||
This project is released under the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).
|
||||
|
||||
Changelog
|
||||
---------
|
||||
|
||||
**2019-03-27**
|
||||
|
||||
* `CRON_USE_LOCAL_TIME` usage fixes
|
||||
|
||||
**2018-05-23**
|
||||
|
||||
* merged [#8](https://github.com/staticlibs/ccronexpr/pull/8)
|
||||
* merged [#9](https://github.com/staticlibs/ccronexpr/pull/9)
|
||||
* minor cleanups
|
||||
|
||||
**2018-01-27**
|
||||
|
||||
* merged [#6](https://github.com/staticlibs/ccronexpr/pull/6)
|
||||
* updated license file (to the one parse-able by github)
|
||||
|
||||
**2017-09-24**
|
||||
|
||||
* merged [#4](https://github.com/staticlibs/ccronexpr/pull/4)
|
||||
|
||||
**2016-06-17**
|
||||
|
||||
* use thread-safe versions of `gmtime` and `localtime`
|
||||
|
||||
**2015-02-28**
|
||||
|
||||
* initial public version
|
|
@ -0,0 +1,29 @@
|
|||
# Copyright 2017, alex at staticlibs.net
|
||||
#
|
||||
# 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.
|
||||
|
||||
image: Visual Studio 2017
|
||||
|
||||
configuration: Release
|
||||
|
||||
build: off
|
||||
|
||||
build_script:
|
||||
- call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat"
|
||||
- cl ccronexpr.c ccronexpr_test.c /W4 /D_CRT_SECURE_NO_WARNINGS /Feccronexpr_32.exe
|
||||
- call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
|
||||
- cl ccronexpr.c ccronexpr_test.c /W4 /D_CRT_SECURE_NO_WARNINGS /Feccronexpr_64.exe
|
||||
|
||||
test_script:
|
||||
- ccronexpr_32.exe
|
||||
- ccronexpr_64.exe
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2015, alex at staticlibs.net
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: ccronexpr.h
|
||||
* Author: alex
|
||||
*
|
||||
* Created on February 24, 2015, 9:35 AM
|
||||
*/
|
||||
|
||||
#ifndef CCRONEXPR_H
|
||||
#define CCRONEXPR_H
|
||||
|
||||
#define CRON_USE_LOCAL_TIME
|
||||
|
||||
#if defined(__cplusplus) && !defined(CRON_COMPILE_AS_CXX)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef ANDROID
|
||||
#include <time.h>
|
||||
#else /* ANDROID */
|
||||
#include <time64.h>
|
||||
#endif /* ANDROID */
|
||||
|
||||
#include <stdint.h> /*added for use if uint*_t data types*/
|
||||
|
||||
/**
|
||||
* Parsed cron expression
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t seconds[8];
|
||||
uint8_t minutes[8];
|
||||
uint8_t hours[3];
|
||||
uint8_t days_of_week[1];
|
||||
uint8_t days_of_month[4];
|
||||
uint8_t months[2];
|
||||
} cron_expr;
|
||||
|
||||
/**
|
||||
* Parses specified cron expression.
|
||||
*
|
||||
* @param expression cron expression as nul-terminated string,
|
||||
* should be no longer that 256 bytes
|
||||
* @param pointer to cron expression structure, it's client code responsibility
|
||||
* to free/destroy it afterwards
|
||||
* @param error output error message, will be set to string literal
|
||||
* error message in case of error. Will be set to NULL on success.
|
||||
* The error message should NOT be freed by client.
|
||||
*/
|
||||
void cron_parse_expr(const char* expression, cron_expr* target, const char** error);
|
||||
|
||||
/**
|
||||
* Uses the specified expression to calculate the next 'fire' date after
|
||||
* the specified date. All dates are processed as UTC (GMT) dates
|
||||
* without timezones information. To use local dates (current system timezone)
|
||||
* instead of GMT compile with '-DCRON_USE_LOCAL_TIME'
|
||||
*
|
||||
* @param expr parsed cron expression to use in next date calculation
|
||||
* @param date start date to start calculation from
|
||||
* @return next 'fire' date in case of success, '((time_t) -1)' in case of error.
|
||||
*/
|
||||
time_t cron_next(cron_expr* expr, time_t date);
|
||||
|
||||
/**
|
||||
* Uses the specified expression to calculate the previous 'fire' date after
|
||||
* the specified date. All dates are processed as UTC (GMT) dates
|
||||
* without timezones information. To use local dates (current system timezone)
|
||||
* instead of GMT compile with '-DCRON_USE_LOCAL_TIME'
|
||||
*
|
||||
* @param expr parsed cron expression to use in previous date calculation
|
||||
* @param date start date to start calculation from
|
||||
* @return previous 'fire' date in case of success, '((time_t) -1)' in case of error.
|
||||
*/
|
||||
time_t cron_prev(cron_expr* expr, time_t date);
|
||||
|
||||
|
||||
#if defined(__cplusplus) && !defined(CRON_COMPILE_AS_CXX)
|
||||
} /* extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /* CCRONEXPR_H */
|
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
* Copyright 2015, alex at staticlibs.net
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: CronExprParser_test.cpp
|
||||
* Author: alex
|
||||
*
|
||||
* Created on February 24, 2015, 9:36 AM
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "ccronexpr.h"
|
||||
|
||||
#define MAX_SECONDS 60
|
||||
#define CRON_MAX_MINUTES 60
|
||||
#define CRON_MAX_HOURS 24
|
||||
#define CRON_MAX_DAYS_OF_WEEK 8
|
||||
#define CRON_MAX_DAYS_OF_MONTH 32
|
||||
#define CRON_MAX_MONTHS 12
|
||||
|
||||
#define INVALID_INSTANT ((time_t) -1)
|
||||
|
||||
#define DATE_FORMAT "%Y-%m-%d_%H:%M:%S"
|
||||
|
||||
#ifndef ARRAY_LEN
|
||||
#define ARRAY_LEN(x) sizeof(x)/sizeof(x[0])
|
||||
#endif
|
||||
|
||||
#ifdef CRON_TEST_MALLOC
|
||||
static int cronAllocations = 0;
|
||||
static int cronTotalAllocations = 0;
|
||||
static int maxAlloc = 0;
|
||||
void* cron_malloc(size_t n) {
|
||||
cronAllocations++;
|
||||
cronTotalAllocations++;
|
||||
if (cronAllocations > maxAlloc) {
|
||||
maxAlloc = cronAllocations;
|
||||
}
|
||||
return malloc(n);
|
||||
}
|
||||
|
||||
void cron_free(void* p) {
|
||||
cronAllocations--;
|
||||
free(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifndef _WIN32
|
||||
time_t timegm(struct tm* __tp);
|
||||
#else /* _WIN32 */
|
||||
static time_t timegm(struct tm* tm) {
|
||||
return _mkgmtime(tm);
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
#else /* ANDROID */
|
||||
static time_t timegm(struct tm * const t) {
|
||||
/* time_t is signed on Android. */
|
||||
static const time_t kTimeMax = ~(1L << (sizeof (time_t) * CHAR_BIT - 1));
|
||||
static const time_t kTimeMin = (1L << (sizeof (time_t) * CHAR_BIT - 1));
|
||||
time64_t result = timegm64(t);
|
||||
if (result < kTimeMin || result > kTimeMax)
|
||||
return -1;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* uint8_t* replace char* for storing hit dates, set_bit and get_bit are used as handlers
|
||||
*/
|
||||
uint8_t cron_get_bit(uint8_t* rbyte, int idx);
|
||||
void cron_set_bit(uint8_t* rbyte, int idx);
|
||||
void cron_del_bit(uint8_t* rbyte, int idx);
|
||||
|
||||
static int crons_equal(cron_expr* cr1, cron_expr* cr2) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < ARRAY_LEN(cr1->seconds); i++) {
|
||||
if (cr1->seconds[i] != cr2->seconds[i]) {
|
||||
printf("seconds not equal @%d %02x != %02x", i, cr1->seconds[i], cr2->seconds[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAY_LEN(cr1->minutes); i++) {
|
||||
if (cr1->minutes[i] != cr2->minutes[i]) {
|
||||
printf("minutes not equal @%d %02x != %02x", i, cr1->minutes[i], cr2->minutes[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAY_LEN(cr1->hours); i++) {
|
||||
if (cr1->hours[i] != cr2->hours[i]) {
|
||||
printf("hours not equal @%d %02x != %02x", i, cr1->hours[i], cr2->hours[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAY_LEN(cr1->days_of_week); i++) {
|
||||
if (cr1->days_of_week[i] != cr2->days_of_week[i]) {
|
||||
printf("days_of_week not equal @%d %02x != %02x", i, cr1->days_of_week[i], cr2->days_of_week[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAY_LEN(cr1->days_of_month); i++) {
|
||||
if (cr1->days_of_month[i] != cr2->days_of_month[i]) {
|
||||
printf("days_of_month not equal @%d %02x != %02x", i, cr1->days_of_month[i], cr2->days_of_month[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAY_LEN(cr1->months); i++) {
|
||||
if (cr1->months[i] != cr2->months[i]) {
|
||||
printf("months not equal @%d %02x != %02x", i, cr1->months[i], cr2->months[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int one_dec_num(const char ch) {
|
||||
switch (ch) {
|
||||
case '0':
|
||||
return 0;
|
||||
case '1':
|
||||
return 1;
|
||||
case '2':
|
||||
return 2;
|
||||
case '3':
|
||||
return 3;
|
||||
case '4':
|
||||
return 4;
|
||||
case '5':
|
||||
return 5;
|
||||
case '6':
|
||||
return 6;
|
||||
case '7':
|
||||
return 7;
|
||||
case '8':
|
||||
return 8;
|
||||
case '9':
|
||||
return 9;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int two_dec_num(const char* first) {
|
||||
return one_dec_num(first[0]) * 10 + one_dec_num(first[1]);
|
||||
}
|
||||
|
||||
int four_dec_num(const char *first) {
|
||||
return ((one_dec_num(first[0]) * 1000)
|
||||
+ (one_dec_num(first[1]) * 100)
|
||||
+ (one_dec_num(first[2]) * 10)
|
||||
+ (one_dec_num(first[3]) * 1));
|
||||
}
|
||||
|
||||
/* strptime is not available in msvc */
|
||||
/* 2012-07-01_09:53:50 */
|
||||
/* 0123456789012345678 */
|
||||
struct tm* poors_mans_strptime(const char* str) {
|
||||
struct tm* cal = (struct tm*) malloc(sizeof(struct tm));
|
||||
assert(cal != NULL);
|
||||
memset(cal, 0, sizeof(struct tm));
|
||||
cal->tm_year = four_dec_num(str) - 1900;
|
||||
cal->tm_mon = two_dec_num(str + 5) - 1;
|
||||
cal->tm_mday = two_dec_num(str + 8);
|
||||
cal->tm_wday = 0;
|
||||
cal->tm_yday = 0;
|
||||
cal->tm_hour = two_dec_num(str + 11);
|
||||
cal->tm_min = two_dec_num(str + 14);
|
||||
cal->tm_sec = two_dec_num(str + 17);
|
||||
return cal;
|
||||
}
|
||||
|
||||
void check_next(const char* pattern, const char* initial, const char* expected) {
|
||||
const char* err = NULL;
|
||||
cron_expr parsed;
|
||||
cron_parse_expr(pattern, &parsed, &err);
|
||||
|
||||
struct tm* calinit = poors_mans_strptime(initial);
|
||||
#ifdef CRON_USE_LOCAL_TIME
|
||||
time_t dateinit = mktime(calinit);
|
||||
#else
|
||||
time_t dateinit = timegm(calinit);
|
||||
#endif
|
||||
assert(-1 != dateinit);
|
||||
time_t datenext = cron_next(&parsed, dateinit);
|
||||
#ifdef CRON_USE_LOCAL_TIME
|
||||
struct tm* calnext = localtime(&datenext);
|
||||
#else
|
||||
struct tm* calnext = gmtime(&datenext);
|
||||
#endif
|
||||
assert(calnext);
|
||||
char* buffer = (char*) malloc(21);
|
||||
memset(buffer, 0, 21);
|
||||
strftime(buffer, 20, DATE_FORMAT, calnext);
|
||||
if (0 != strcmp(expected, buffer)) {
|
||||
printf("Pattern: %s\n", pattern);
|
||||
printf("Initial: %s\n", initial);
|
||||
printf("Expected: %s\n", expected);
|
||||
printf("Actual: %s\n", buffer);
|
||||
assert(0);
|
||||
}
|
||||
free(buffer);
|
||||
free(calinit);
|
||||
}
|
||||
|
||||
void check_same(const char* expr1, const char* expr2) {
|
||||
cron_expr parsed1;
|
||||
cron_parse_expr(expr1, &parsed1, NULL);
|
||||
cron_expr parsed2;
|
||||
cron_parse_expr(expr2, &parsed2, NULL);
|
||||
assert(crons_equal(&parsed1, &parsed2));
|
||||
}
|
||||
|
||||
void check_calc_invalid() {
|
||||
cron_expr parsed;
|
||||
cron_parse_expr("0 0 0 31 6 *", &parsed, NULL);
|
||||
struct tm * calinit = poors_mans_strptime("2012-07-01_09:53:50");
|
||||
time_t dateinit = timegm(calinit);
|
||||
time_t res = cron_next(&parsed, dateinit);
|
||||
assert(INVALID_INSTANT == res);
|
||||
free(calinit);
|
||||
}
|
||||
|
||||
void check_expr_invalid(const char* expr) {
|
||||
const char* err = NULL;
|
||||
cron_expr test;
|
||||
cron_parse_expr(expr, &test, &err);
|
||||
assert(err);
|
||||
}
|
||||
|
||||
void test_expr() {
|
||||
#ifdef CRON_USE_LOCAL_TIME
|
||||
check_next("* 15 11 * * *", "2019-03-09_11:43:00", "2019-03-10_11:15:00");
|
||||
#else
|
||||
check_next("*/15 * 1-4 * * *", "2012-07-01_09:53:50", "2012-07-02_01:00:00");
|
||||
check_next("*/15 * 1-4 * * *", "2012-07-01_09:53:00", "2012-07-02_01:00:00");
|
||||
check_next("0 */2 1-4 * * *", "2012-07-01_09:00:00", "2012-07-02_01:00:00");
|
||||
check_next("0 */2 * * * *", "2012-07-01_09:00:00", "2012-07-01_09:02:00");
|
||||
check_next("0 */2 * * * *", "2013-07-01_09:00:00", "2013-07-01_09:02:00");
|
||||
check_next("0 */2 * * * *", "2018-09-14_14:24:00", "2018-09-14_14:26:00");
|
||||
check_next("0 */2 * * * *", "2018-09-14_14:25:00", "2018-09-14_14:26:00");
|
||||
check_next("0 */20 * * * *", "2018-09-14_14:24:00", "2018-09-14_14:40:00");
|
||||
check_next("* * * * * *", "2012-07-01_09:00:00", "2012-07-01_09:00:01");
|
||||
check_next("* * * * * *", "2012-12-01_09:00:58", "2012-12-01_09:00:59");
|
||||
check_next("10 * * * * *", "2012-12-01_09:42:09", "2012-12-01_09:42:10");
|
||||
check_next("11 * * * * *", "2012-12-01_09:42:10", "2012-12-01_09:42:11");
|
||||
check_next("10 * * * * *", "2012-12-01_09:42:10", "2012-12-01_09:43:10");
|
||||
check_next("10-15 * * * * *", "2012-12-01_09:42:09", "2012-12-01_09:42:10");
|
||||
check_next("10-15 * * * * *", "2012-12-01_21:42:14", "2012-12-01_21:42:15");
|
||||
check_next("0 * * * * *", "2012-12-01_21:10:42", "2012-12-01_21:11:00");
|
||||
check_next("0 * * * * *", "2012-12-01_21:11:00", "2012-12-01_21:12:00");
|
||||
check_next("0 11 * * * *", "2012-12-01_21:10:42", "2012-12-01_21:11:00");
|
||||
check_next("0 10 * * * *", "2012-12-01_21:11:00", "2012-12-01_22:10:00");
|
||||
check_next("0 0 * * * *", "2012-09-30_11:01:00", "2012-09-30_12:00:00");
|
||||
check_next("0 0 * * * *", "2012-09-30_12:00:00", "2012-09-30_13:00:00");
|
||||
check_next("0 0 * * * *", "2012-09-10_23:01:00", "2012-09-11_00:00:00");
|
||||
check_next("0 0 * * * *", "2012-09-11_00:00:00", "2012-09-11_01:00:00");
|
||||
check_next("0 0 0 * * *", "2012-09-01_14:42:43", "2012-09-02_00:00:00");
|
||||
check_next("0 0 0 * * *", "2012-09-02_00:00:00", "2012-09-03_00:00:00");
|
||||
check_next("* * * 10 * *", "2012-10-09_15:12:42", "2012-10-10_00:00:00");
|
||||
check_next("* * * 10 * *", "2012-10-11_15:12:42", "2012-11-10_00:00:00");
|
||||
check_next("0 0 0 * * *", "2012-09-30_15:12:42", "2012-10-01_00:00:00");
|
||||
check_next("0 0 0 * * *", "2012-10-01_00:00:00", "2012-10-02_00:00:00");
|
||||
check_next("0 0 0 * * *", "2012-08-30_15:12:42", "2012-08-31_00:00:00");
|
||||
check_next("0 0 0 * * *", "2012-08-31_00:00:00", "2012-09-01_00:00:00");
|
||||
check_next("0 0 0 * * *", "2012-10-30_15:12:42", "2012-10-31_00:00:00");
|
||||
check_next("0 0 0 * * *", "2012-10-31_00:00:00", "2012-11-01_00:00:00");
|
||||
check_next("0 0 0 1 * *", "2012-10-30_15:12:42", "2012-11-01_00:00:00");
|
||||
check_next("0 0 0 1 * *", "2012-11-01_00:00:00", "2012-12-01_00:00:00");
|
||||
check_next("0 0 0 1 * *", "2010-12-31_15:12:42", "2011-01-01_00:00:00");
|
||||
check_next("0 0 0 1 * *", "2011-01-01_00:00:00", "2011-02-01_00:00:00");
|
||||
check_next("0 0 0 31 * *", "2011-10-30_15:12:42", "2011-10-31_00:00:00");
|
||||
check_next("0 0 0 1 * *", "2011-10-30_15:12:42", "2011-11-01_00:00:00");
|
||||
check_next("* * * * * 2", "2010-10-25_15:12:42", "2010-10-26_00:00:00");
|
||||
check_next("* * * * * 2", "2010-10-20_15:12:42", "2010-10-26_00:00:00");
|
||||
check_next("* * * * * 2", "2010-10-27_15:12:42", "2010-11-02_00:00:00");
|
||||
check_next("55 5 * * * *", "2010-10-27_15:04:54", "2010-10-27_15:05:55");
|
||||
check_next("55 5 * * * *", "2010-10-27_15:05:55", "2010-10-27_16:05:55");
|
||||
check_next("55 * 10 * * *", "2010-10-27_09:04:54", "2010-10-27_10:00:55");
|
||||
check_next("55 * 10 * * *", "2010-10-27_10:00:55", "2010-10-27_10:01:55");
|
||||
check_next("* 5 10 * * *", "2010-10-27_09:04:55", "2010-10-27_10:05:00");
|
||||
check_next("* 5 10 * * *", "2010-10-27_10:05:00", "2010-10-27_10:05:01");
|
||||
check_next("55 * * 3 * *", "2010-10-02_10:05:54", "2010-10-03_00:00:55");
|
||||
check_next("55 * * 3 * *", "2010-10-03_00:00:55", "2010-10-03_00:01:55");
|
||||
check_next("* * * 3 11 *", "2010-10-02_14:42:55", "2010-11-03_00:00:00");
|
||||
check_next("* * * 3 11 *", "2010-11-03_00:00:00", "2010-11-03_00:00:01");
|
||||
check_next("0 0 0 29 2 *", "2007-02-10_14:42:55", "2008-02-29_00:00:00");
|
||||
check_next("0 0 0 29 2 *", "2008-02-29_00:00:00", "2012-02-29_00:00:00");
|
||||
check_next("0 0 7 ? * MON-FRI", "2009-09-26_00:42:55", "2009-09-28_07:00:00");
|
||||
check_next("0 0 7 ? * MON-FRI", "2009-09-28_07:00:00", "2009-09-29_07:00:00");
|
||||
check_next("0 30 23 30 1/3 ?", "2010-12-30_00:00:00", "2011-01-30_23:30:00");
|
||||
check_next("0 30 23 30 1/3 ?", "2011-01-30_23:30:00", "2011-04-30_23:30:00");
|
||||
check_next("0 30 23 30 1/3 ?", "2011-04-30_23:30:00", "2011-07-30_23:30:00");
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_parse() {
|
||||
|
||||
check_same("* * * 2 * *", "* * * 2 * ?");
|
||||
check_same("57,59 * * * * *", "57/2 * * * * *");
|
||||
check_same("1,3,5 * * * * *", "1-6/2 * * * * *");
|
||||
check_same("* * 4,8,12,16,20 * * *", "* * 4/4 * * *");
|
||||
check_same("* * * * * 0-6", "* * * * * TUE,WED,THU,FRI,SAT,SUN,MON");
|
||||
check_same("* * * * * 0", "* * * * * SUN");
|
||||
check_same("* * * * * 0", "* * * * * 7");
|
||||
check_same("* * * * 1-12 *", "* * * * FEB,JAN,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC *");
|
||||
check_same("* * * * 2 *", "* * * * Feb *");
|
||||
check_same("* * * * 1 *", "* * * * 1 *");
|
||||
|
||||
check_expr_invalid("77 * * * * *");
|
||||
check_expr_invalid("44-77 * * * * *");
|
||||
check_expr_invalid("* 77 * * * *");
|
||||
check_expr_invalid("* 44-77 * * * *");
|
||||
check_expr_invalid("* * 27 * * *");
|
||||
check_expr_invalid("* * 23-28 * * *");
|
||||
check_expr_invalid("* * * 45 * *");
|
||||
check_expr_invalid("* * * 28-45 * *");
|
||||
check_expr_invalid("0 0 0 25 13 ?");
|
||||
check_expr_invalid("0 0 0 25 0 ?");
|
||||
check_expr_invalid("0 0 0 32 12 ?");
|
||||
check_expr_invalid("* * * * 11-13 *");
|
||||
check_expr_invalid("-5 * * * * *");
|
||||
check_expr_invalid("3-2 */5 * * * *");
|
||||
check_expr_invalid("/5 * * * * *");
|
||||
check_expr_invalid("*/0 * * * * *");
|
||||
check_expr_invalid("*/-0 * * * * *");
|
||||
check_expr_invalid("* 1 1 0 * *");
|
||||
}
|
||||
|
||||
void test_bits() {
|
||||
|
||||
uint8_t testbyte[8];
|
||||
memset(testbyte, 0, 8);
|
||||
int err = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= 63; i++) {
|
||||
cron_set_bit(testbyte, i);
|
||||
if (!cron_get_bit(testbyte, i)) {
|
||||
printf("Bit set error! Bit: %d!\n", i);
|
||||
err = 1;
|
||||
}
|
||||
cron_del_bit(testbyte, i);
|
||||
if (cron_get_bit(testbyte, i)) {
|
||||
printf("Bit clear error! Bit: %d!\n", i);
|
||||
err = 1;
|
||||
}
|
||||
assert(!err);
|
||||
}
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
cron_set_bit(testbyte, i);
|
||||
}
|
||||
if (testbyte[0] != 0xff) {
|
||||
err = 1;
|
||||
}
|
||||
if (testbyte[1] != 0x0f) {
|
||||
err = 1;
|
||||
}
|
||||
|
||||
assert(!err);
|
||||
}
|
||||
|
||||
/* For this test to work you need to set "-DCRON_TEST_MALLOC=1"*/
|
||||
#ifdef CRON_TEST_MALLOC
|
||||
void test_memory() {
|
||||
cron_expr cron;
|
||||
const char* err;
|
||||
|
||||
cron_parse_expr("* * * * * *", &cron, &err);
|
||||
if (cronAllocations != 0) {
|
||||
printf("Allocations != 0 but %d", cronAllocations);
|
||||
assert(0);
|
||||
}
|
||||
printf("Allocations: total: %d, max: %d", cronTotalAllocations, maxAlloc);
|
||||
}
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
|
||||
test_bits();
|
||||
|
||||
test_expr();
|
||||
test_parse();
|
||||
check_calc_invalid();
|
||||
#ifdef CRON_TEST_MALLOC
|
||||
test_memory(); /* For this test to work you need to set "-DCRON_TEST_MALLOC=1"*/
|
||||
#endif
|
||||
printf("\nAll OK!");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "ccronexpr",
|
||||
"frameworks": "arduino",
|
||||
"keywords": "cron, Time, alarm, schedule, date, hour, minute, second, day, week, month, year",
|
||||
"description": "Crontab parser",
|
||||
"url": "https://github.com/Martin-Laclaustra/CronAlarms",
|
||||
"authors":
|
||||
{
|
||||
"name": "alex@staticlibs.net"
|
||||
},
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/staticlibs/ccronexpr"
|
||||
},
|
||||
"platforms": "espressif32"
|
||||
}
|
|
@ -26,6 +26,7 @@
|
|||
#include "berry_tasmota.h"
|
||||
#include "be_vm.h"
|
||||
#include "ZipReadFS.h"
|
||||
#include "ccronexpr.h"
|
||||
|
||||
extern "C" {
|
||||
extern void be_load_custom_libs(bvm *vm);
|
||||
|
|
Loading…
Reference in New Issue