• c语言-自研定时器计划任务语法


    c语言-自研定时器计划任务语法

    为啥要自研

    市面主流定时器计划任务语法: cron ,但是使用起来非常难受,设计的比较非人性话语法,我想一般人都没几个记住的,都是靠在线生成工具进行使用的,而且只能持续执行不是有限执行,下面举几个cron的案例:

    在这里插入图片描述

    具体想了解的可以自行百度,我试图记住语法,但是因为太混乱了,时间一长就忘了,没法只能到网上工具里生成,而且很多有限的场景没法生成因为cron不支持只执行几次或者有规律的执行,为了解决以上的问题,我自己研究了一套(free time)定时器计划任务语法

    语法格式

    语法: 0,0,7,0,0,0,0,- 长度为8

    对应时间: 秒,分,时,天,星期,月,年,执行计划

    执行计划

    数值: 执行几次

    n: 循环执行

    ^n: 时间乘阶 2*2,4*2,8*2....

    ^数值: 时间乘阶几次 ^2 那么就是2*2,4*2

    符号

    ~: 区间 1~4 那么就会执行1,2,3,4

    /: 间隔 2/5 那么从2开始下次之后就从5开始执行

    []: 分段 [1,5,10,12] 分别在这几个时间点执行

    模式

    模式就是可以: 月底,月初,每周几,星期末,年末,节假日等,(可以支持自定义扩张需要对外提供生成器)

    执行计划: m(循环执行) ,m数值(有限执行)

    begin: 时间底(天底,周末,月底,年底)

    end: 时间初(天初,周初,月初,年初)

    point(?): 指定时间点,指定每月5号,每周3,每2天

    以上是基础模式,其他模式需要自定义(节假日,特殊日期等)

    注意: 在模式的基础上还可以配合时间比如: (每天2点1分10秒执行)

    语法演示

    基本操作

    都是以当前时间为基准进行添加时间

    当前时间+1分钟后执行(执行2次)
    0,1,0,0,0,0,0,2
    (2022-09-24 16:22:59,2022-09-24 16:23:59)

    当前时间+5小时后执行(循环执行)
    0,0,5,0,0,0,0,n
    (2022-09-24 21:23:09,2022-09-25 02:23:09)

    当前时间+1天后执行
    0,0,0,1,0,0,0,n
    (2022-09-25 16:24:07,2022-09-26 16:24:07)

    当前时间+1星期(7天)后执行
    0,0,0,0,1,0,0,n
    (2022-10-01 16:25:19,2022-10-08 16:25:19)

    当前时间加1天1小时1分1秒后执行
    1,1,1,1,0,0,0,2
    (2022-09-25 17:38:57,2022-09-26 18:39:58)

    当前时间分钟递增执行(循环)
    0,1,0,0,0,0,0,^n

    当前时间分钟递增执行(次数)
    0,1,0,0,0,0,0,^2

    符号操作

    符号操作有~和[]以及/ 可以配合有限和循环n,不能使用递增

    区间执行(循环)
    0,2~5,0,0,0,0,0,n(每2分钟3分钟…5分钟各执行一次,然后反复)

    间隔执行
    0,0,3/0,1,0,0,0,n (3小时后,每天执行一次)

    分段执行
    0,0,[2,5,8],0,0,0,0,n (当前时间每2,5,8小时执行一次,然后反复)

    符号操作还可以和基本操作组合,原理就是相加

    0,10,[2,5,8],0,0,0,0,n(当前时间每2,5,8小时加10分钟执行一次,然后反复)

    模式操作

    在[年,月,星期,天,小时,分支,秒]底执行

    年底执行5次
    0,0,0,0,0,0,end,mode5
    (2023-12-31 23:59:59 ,2024-12-31 23:59:59)

    月底执行,一共执行两次
    0,0,0,0,0,end,0,mode2
    (2022-10-31 23:59:59,2022-11-31 23:59:59)

    每个星期日底执行(循环)
    0,0,0,0,end,0,0,mode
    (2022-10-02 23:59:59,2022-10-09 23:59:59)

    每天底执行
    0,0,0,end,0,0,0,mode
    (2022-09-24 23:59:59 , 2022-09-25 23:59:59)

    每小时底执行
    0,0,end,0,0,0,0,mode
    (2022-09-23 15:59:59,2022-09-23 16:59:59)

    每分钟底执行
    0,end,0,0,0,0,0,mode
    (2022-09-23 14:20:59,2022-09-23 14:21:59)

    每秒底执行
    end,0,0,0,0,0,0,mode (可能看不出来,所以当做每秒执行就行)
    (2022-09-23 14:21:26,2022-09-23 14:22:25)

    在[年,月,星期,天,小时,分支,秒]初执行

    每年初执行(2次)
    0,0,0,0,0,0,begin,mode2
    (2023-01-01 00:00:00, 2024-01-01 00:00:00)

    没月初执行
    0,0,0,0,0,begin,0,mode2
    (2022-10-01 00:00:00, 2022-11-01 00:00:00)

    每星期初执行
    0,0,0,0,begin,0,0,mode
    (2022-09-26 00:00:00,2022-10-03 00:00:00)

    每天初执行
    0,0,0,begin,0,0,0,mode
    (2022-09-25 00:00:00,2022-09-26 00:00:00)

    每小时初执行
    0,0,begin,0,0,0,0,mode
    (2022-09-24 16:00:00,2022-09-24 17:00:00)

    每分钟初执行
    0,begin,0,0,0,0,0,mode
    (2022-09-24 15:35:00,2022-09-24 15:36:00)

    每秒钟初执行
    begin,0,0,0,0,0,0,mode (可能看不出来,所以当做每秒执行就行)
    (2022-09-24 15:35:17,2022-09-24 15:35:18)

    指定时间执行

    我们可以使用模式中的point(?) 来完成,而point除了在星期占位特殊可以指定下个星期几执行,在其他占位也是可以指定时间

    每个星期2晚上11点执行
    0,0,point(23),0,point(2),0,0,mode
    (2022-09-27 22:00:00,2022-10-04 22:00:00)

    每天凌晨2点执行
    0,0,point(2),point(1),0,0,0,mode
    (2022-09-25 02:00:00,2022-09-26 02:00:00)

    模式组合

    注意: end ,begin 和point 不能同时出现,但是我们可以和基本模式作进行混合

    -59,1,-2,end,0,0,0,mode (每天晚上10点执行)

    0,0,8,begin,0,0,0,mode (每天早上8点执行)

    0,0,8,point(2),0,0,0,mode (每2天8点执行)

    头文件

    #ifndef STUDY_TIMER_RESOLVER_H
    #define STUDY_TIMER_RESOLVER_H
    #include "time_util.h"
    #include "../util/str_util.h"
    #include "assertmy.h"
    #include 
    #include 
    //秒,分钟,小时,天,星期,月,年,执行计划      -,-,-,-,-,-,-,-      代表0秒,0分,0小时,0天,星期,0月,0年,不执行
    typedef struct timer_resolver {
        char *second;//秒 0-59
        char *minute;//分钟 0-59
        char *hour; //小时0-23
        char *day;  //天 1-31
        char *week;//星期 0-6
        char *month;//月份 1-12
        char *year;//年
        char *plan;//执行计划 -代表不执行,n 循环执行,数字代表执行次数 , ^n 阶级执行(^1 表示一阶执行,^2 表示二阶执行,^3 表示三阶执行...^n表示n阶执行)  mode 代表执行模式 mode2 代表模式执行2次....
        long timestamp;//时间戳 用于计算下次执行时间
        char *help;//协助计算的字段
        CharHashMap *mode;//模式
    
    } TimerResolver;
    
    typedef  int  (*ModeMethod)(char *item,int seat,TimerResolver *timerResolver); //自定义模式方法
    TimerResolver *create_timer_resolver(char *time);
    void print_timer_resolver(TimerResolver *timerResolver);
    long resolver(TimerResolver *timerResolver);
    void switchStructure(TimerResolver *timerResolver);
    void add_timer_mode(TimerResolver *timerResolver, char *key, ModeMethod method);
    void print_format_resolver(TimerResolver *timerResolver, int n);
    #endif //STUDY_TIMER_RESOLVER_H
    
    

    实现文件

    
    #include "timer_resolver.h"
    char *get_return_data(char **data1);
    
    //获取以当前时间后指定年月日时分秒
    long time_point_mode(char *item, int seat, TimerResolver *timerResolver) {
        //解析point(?)模式,取出?的值
        int i = str_find(item, "(");
        item = str_substring(item, i + 1, str_length(item) - 2);
        if (seat == 0) { //加秒数
            return get_next_time_by_timestamp(timerResolver->timestamp, 0, 0, 0, 0, 0, str_to_int(item));
        } else if (seat == 1) { //分钟数
            return get_next_time_by_timestamp(timerResolver->timestamp, 0, 0, 0, 0, str_to_int(item), 0);
        } else if (seat == 2) { //小时数
            return  get_next_time_by_timestamp(timerResolver->timestamp, 0, 0, 0, str_to_int(item), 0, 0);
        } else if (seat == 3) { //天数
            return get_next_time_by_timestamp(timerResolver->timestamp, 0, 0, str_to_int(item), 0, 0, 0);
        } else if (seat == 4) { //周n的日期
            return get_next_week_of_day(timerResolver->timestamp, str_to_int(item));
        } else if (seat == 5) { //月数
            return get_next_time_by_timestamp(timerResolver->timestamp, 0, str_to_int(item), 0, 0, 0, 0);
        } else if (seat == 6) { //年数
            return get_next_time_by_timestamp(timerResolver->timestamp, str_to_int(item), 0, 0, 0, 0, 0);
        }
    }
    
    // 判断指定时间,初的时间
    long time_begin_mode(char *item, int seat, TimerResolver *timerResolver) {
        if (seat == 0) { //秒数
            return get_start_time_of_next_second(timerResolver->timestamp);
        } else if (seat == 1) { //分钟数
            return get_start_time_of_next_minute(timerResolver->timestamp);
        } else if (seat == 2) { //小时数
            return get_start_time_of_next_hour(timerResolver->timestamp);
        } else if (seat == 3) {// 天数
            return get_start_time_of_next_day(timerResolver->timestamp);
        } else if (seat == 4) {// 星期数
            return get_time_next_week_start(timerResolver->timestamp);
        } else if (seat == 5) {// 月数
            return get_start_time_of_next_month(timerResolver->timestamp);
        } else if (seat == 6) {// 年数
            return get_start_time_of_next_year(timerResolver->timestamp);
        }
    }
    
    // 判断指定时间,末的时间
    long time_end_mode(char *item, int seat, TimerResolver *timerResolver) {
        if (seat == 0) { //秒数
            return timerResolver->timestamp+59;
        } else if (seat == 1) { //分钟数(如果当前时间是59秒,则返回下一分钟的59秒)
            return get_end_time_of_next_minute(timerResolver->timestamp) ;
        } else if (seat == 2) { //小时数
            return get_end_time_of_next_hour(timerResolver->timestamp) ;
        } else if (seat == 3) { //天数
            return get_end_time_of_next_day(timerResolver->timestamp) ;
        } else if (seat == 4) { //星期数(周末开始时间)
            return get_end_time_of_next_week(timerResolver->timestamp);
        } else if (seat == 5) { //月数
            return get_end_time_of_next_month(timerResolver->timestamp) ;
        } else if (seat == 6) { //年数
            return get_end_time_of_next_year(timerResolver->timestamp) ;
        }
    }
    
    // 判断是否有此模式
    BOOL mode_exist(char *item, TimerResolver *timerResolver) {
        if(!str_contains(timerResolver->plan,"mode")){
            return FALSE;
        }
        CharHashMapIterator *pIterator = createCharHashMapIterator(timerResolver->mode);
        while (hasNextCharHashMapIterator(pIterator)) {
            CharKvLinkedNode *pNode = nextCharHashMapIterator(pIterator);
            if (str_start_with(item,pNode->key )) {//如果匹配到模式,那么就转换为统一结构化格式
                return TRUE;
            }
        }
        return FALSE;
    }
    
    //模式解析
    long mode_timer(char *item, int seat, TimerResolver *timerResolver) {
        if (str_contains(timerResolver->plan, "mode")) {
            CharHashMapIterator *pIterator = createCharHashMapIterator(timerResolver->mode);
            while (hasNextCharHashMapIterator(pIterator)) {
                CharKvLinkedNode *pNode = nextCharHashMapIterator(pIterator);
                if (str_start_with(item,pNode->key)) {//如果匹配到模式
                    ModeMethod pVoid = (ModeMethod) pNode->value;
                    return pVoid(item, seat, timerResolver);//执行模式方法
                }
            }
        }
        return 0;// 没有匹配到模式
    }
    
    //添加模式方法(如果执行计划为mode,则支持)
    void add_timer_mode(TimerResolver *timerResolver, char *key, ModeMethod method) {
        if (str_contains(timerResolver->plan, "mode")) {
            putCharHashMap(timerResolver->mode, key, method);//添加模式方法
        }
    }
    
    void inside_add_timer_mode(TimerResolver *timerResolver) {
        if (str_contains(timerResolver->plan, "mode")) {
            add_timer_mode(timerResolver, "begin", time_begin_mode);
            add_timer_mode(timerResolver, "end", time_end_mode);
            add_timer_mode(timerResolver, "point", time_point_mode);
        }
    }
    
    //获取下一次执行时间,返回时间戳
    long get_next_time(TimerResolver *timerResolver) {
        if (!timerResolver->plan) {
            return 0;
        }
    
        if (str_contains(timerResolver->plan, "mode")) {
            long mode_timer1 = mode_timer(get_return_data(&timerResolver->second), 0, timerResolver);
            timerResolver->timestamp+=get_time_difference_second(timerResolver->timestamp, mode_timer1);
            long mode_timer2 = mode_timer(get_return_data(&timerResolver->minute), 1, timerResolver);
            timerResolver->timestamp+=get_time_difference_second(timerResolver->timestamp,mode_timer2 );
            long mode_timer3= mode_timer(get_return_data(&timerResolver->hour), 2, timerResolver);
            timerResolver->timestamp+=get_time_difference_second(timerResolver->timestamp,mode_timer3 );
            long  mode_timer4 = mode_timer(get_return_data(&timerResolver->day), 3, timerResolver);
            timerResolver->timestamp+=get_time_difference_second(timerResolver->timestamp, mode_timer4);
            long mode_timer5 = mode_timer(get_return_data(&timerResolver->week), 4, timerResolver);
            timerResolver->timestamp+=get_time_difference_second(timerResolver->timestamp, mode_timer5);
            long mode_timer6 = mode_timer(get_return_data(&timerResolver->month), 5, timerResolver);
            timerResolver->timestamp+=get_time_difference_second(timerResolver->timestamp, mode_timer6);
            long mode_timer7 = mode_timer(get_return_data(&timerResolver->year), 6, timerResolver);
            timerResolver->timestamp+=get_time_difference_second(timerResolver->timestamp, mode_timer7);
        }
        long current = timerResolver->timestamp;
        //获取当前时间
        int second = str_to_int(get_return_data(&timerResolver->second));
        int minute = str_to_int(get_return_data(&timerResolver->minute));
        int hour = str_to_int(get_return_data(&timerResolver->hour));
        int day = str_to_int(get_return_data(&timerResolver->day));
        int week = str_to_int(get_return_data(&timerResolver->week));
        int month = str_to_int(get_return_data(&timerResolver->month));
        int year = str_to_int(get_return_data(&timerResolver->year));
        long newTime = add_time_one(current,
                                    second,
                                    minute,
                                    hour,
                                    day,
                                    month,
                                    year,
                                    week
        );
        timerResolver->timestamp = newTime;
        if(str_contains(timerResolver->plan,"mode")){
            return newTime;
        }else{
            return current;
        }
    }
    
    //解析字符串-,-,-,-,-,-,-,-并创建TimerResolver
    TimerResolver *create_timer_resolver(char *time) {
    
        if (time == NULL && strlen(time) == 0) {
            return NULL;
        }
        //去空
        time = str_trim(time);
        //排除[]内的,号
        int start = 0;
        while ((start = str_find_n(time, "[", start, str_length(time))) != -1) {
            int end = str_find_n(time, "]", start, str_length(time));
            time = str_replace_all_n(time, ",", "@", start, end);
            start++;
        }
    
        TimerResolver *timerResolver = (TimerResolver *) malloc(sizeof(TimerResolver));
        if (timerResolver == NULL) {
            return NULL;
        }
        CharList *pCharlist = str_split(time, ",");
        int str_len = pCharlist->len;
        if (str_len != 8) {
            char message[100];
            sprintf(message, "create_timer_resolver语法错误: %s ", time);
            assertError(message);
        }
        timerResolver->second = pCharlist->str[0];
        timerResolver->minute = pCharlist->str[1];
        timerResolver->hour = pCharlist->str[2];
        timerResolver->day = pCharlist->str[3];
        timerResolver->week = pCharlist->str[4];
        timerResolver->month = pCharlist->str[5];
        timerResolver->year = pCharlist->str[6];
        timerResolver->timestamp = get_current_timestamp();//获取当前时间戳
        //执行计划 -代表不执行,n 循环执行,数字代表执行次数 , ^n 阶级执行(^1 表示一阶执行,^2 表示二阶执行,^3 表示三阶执行...^n表示n阶执行)
        timerResolver->plan = str_compare(pCharlist->str[7], "-") ? "0" : pCharlist->str[7];
        timerResolver->help = "{}";
        timerResolver->mode = createCharHashMap(10);
    
        //添加模式方法
        inside_add_timer_mode(timerResolver);
    
        //转换为结构化格式
        switchStructure(timerResolver);
    
        //计算本次执行时间
        if(!str_contains(timerResolver->plan,"mode")){
            get_next_time(timerResolver);
        }
    
        return timerResolver;
    }
    
    //打印TimerResolver,格式为-,-,-,-,-,-,-,-
    void print_timer_resolver(TimerResolver *timerResolver) {
        printf("%s,%s,%s,%s,%s,%s,%s,%s\n", timerResolver->second, timerResolver->minute, timerResolver->hour,
               timerResolver->day, timerResolver->week, timerResolver->month, timerResolver->year,
               timerResolver->plan);
    }
    //执行n次定时器并且打印效果
    void print_format_resolver(TimerResolver *timerResolver, int n) {
        for (int i = 0; i < n; ++i){
            long i1 = resolver(timerResolver);
            char *string = format_time(i1, "%Y-%m-%d %H:%M:%S");
            printf("%ld---%s\n",i1,string);
        }
    }
    
    
    //解析定时器语法,并且生成下次执行时间,如果返回0,则此语法已经执行结束了,可以删除对应的定时器了
    long resolver(TimerResolver *timerResolver) {
        //判断是否可执行
        if (str_equals(timerResolver->plan,"0") ) {//不执行
            return 0;
        }
    
        if (str_compare(timerResolver->plan, "n")) {//循环执行
            return get_next_time(timerResolver);
        }
        //阶级执行
        if (str_start_with(timerResolver->plan, "^")) {
            CharHashMap *pMapSecond = str_to_json_map(timerResolver->second);
            putCharHashMap(pMapSecond, "return",
                           int_to_str(str_to_int(get_return_data(&timerResolver->second)) * 2));
            timerResolver->second = map_to_json_str(pMapSecond);
    
            CharHashMap *pMapMinute = str_to_json_map(timerResolver->minute);
            putCharHashMap(pMapMinute, "return",
                           int_to_str(str_to_int(get_return_data(&timerResolver->minute)) * 2));
            timerResolver->minute = map_to_json_str(pMapMinute);
    
            CharHashMap *pMapHour = str_to_json_map(timerResolver->hour);
            putCharHashMap(pMapHour, "return",
                           int_to_str(str_to_int(get_return_data(&timerResolver->hour)) * 2));
            timerResolver->hour = map_to_json_str(pMapHour);
    
            CharHashMap *pMapDay = str_to_json_map(timerResolver->day);
            putCharHashMap(pMapDay, "return",
                           int_to_str(str_to_int(get_return_data(&timerResolver->day)) * 2));
            timerResolver->hour = map_to_json_str(pMapDay);
    
            CharHashMap *pMapWeek = str_to_json_map(timerResolver->week);
            putCharHashMap(pMapWeek, "return",
                           int_to_str(str_to_int(get_return_data(&timerResolver->week)) * 2));
            timerResolver->week = map_to_json_str(pMapWeek);
    
            CharHashMap *pMapMonth = str_to_json_map(timerResolver->month);
            putCharHashMap(pMapMonth, "return",
                           int_to_str(str_to_int(get_return_data(&timerResolver->month)) * 2));
            timerResolver->month = map_to_json_str(pMapMonth);
    
            CharHashMap *pMapYear = str_to_json_map(timerResolver->year);
            putCharHashMap(pMapYear, "return",
                           int_to_str(str_to_int(get_return_data(&timerResolver->year)) * 2));
            timerResolver->year = map_to_json_str(pMapYear);
    
            char *string = str_substring(timerResolver->plan, 1, str_length(timerResolver->plan));
            if (str_compare(string, "n")) { //如果是n那么就是循环执行
                return get_next_time(timerResolver);
            }
            if (str_is_number(string)) {//如果是数字,那么就是有限阶级执行
                if (str_compare(string, "0")) {
                    return 0;
                }
                char *one = str_calculate_one(string, "--");
                timerResolver->plan = str_concat(2, "^", one);
                return get_next_time(timerResolver);
            }
        }
        //模式执行
        if (str_start_with(timerResolver->plan, "mode")) {
            timerResolver->timestamp= get_start_time_of_day(timerResolver->timestamp );// 初始化为当天的开始时间 ,然后在后面的计算中,加上指定的时间
            if (str_length(timerResolver->plan) == 4) { //循环执行
                return get_next_time(timerResolver);
            } else {
                char *string = str_substring(timerResolver->plan, 4, str_length(timerResolver->plan));
                if (str_is_number(string)) {//如果是数字,那么就是有限阶级执行
                    if (str_compare(string, "0")) {
                        return 0;
                    }
                    char *one = str_calculate_one(string, "--");
                    timerResolver->plan = str_concat(2, "mode", one);
                    return get_next_time(timerResolver);
                } else {
                    assertError(formatStr("mode解析错误非法字符(必须是mode+数字):%s\n", timerResolver->plan));
                }
            }
        }
        //有限执行
        if (str_is_number(timerResolver->plan)) {
            int plan = str_to_int(timerResolver->plan);
            if (plan > 0) {
                timerResolver->plan = int_to_str(plan - 1);
                return get_next_time(timerResolver);
            }
    
        }
    
    }
    
    
    //分段[]解析
    char *section_analysis(char *item, TimerResolver *timerResolver) {
        //在帮助里存储当前的次数
        CharHashMap *pMap = str_to_json_map(timerResolver->help);
        if (!containsKeyCharHashMap(pMap, "basicsPlan")) {
            putCharHashMap(pMap, "basicsPlan", timerResolver->plan);
            timerResolver->help = map_to_json_str(pMap);
        }
        //将[]里面的@转换为,号
        item = str_replace_all_n(item, "@", ",", 0, str_length(item));
        CharList *pCharlist = str_to_json_array(item);
        //验证是否都是数字
        for (int i = 0; i < pCharlist->len; ++i) {
            if (!str_is_number(pCharlist->str[i])) {
                assertError(formatStr("[]解析错误非法字符(必须是数字):%s\n", pCharlist->str[i]));
            }
        }
        char *string = str_concat(11, "{", "type:[]", ",", "data:", item, ",", "index:0", ",", "return:",
                                  pCharlist->str[0], "}");
        //添加执行的次数
        CharHashMap *pMap1 = str_to_json_map(timerResolver->help);
        char *basicsPlan = getCharHashMap(pMap1, "basicsPlan");
        if(str_equals(basicsPlan,"n")||str_start_with(basicsPlan,"^")){
            timerResolver->plan = timerResolver->plan;
        }else{
            if (str_equals(timerResolver->plan, basicsPlan)) {
                timerResolver->plan = int_to_str(pCharlist->len * str_to_int(basicsPlan));
            } else {
                timerResolver->plan = int_to_str(
                        str_to_int(timerResolver->plan) + (pCharlist->len * str_to_int(basicsPlan)));
            }
        }
        return string;
    }
    
    //区间解析 符号为~ ,位置1表示秒,2表示分支,3表示小时,4表示天,5表示星期,6表示月,7表示年
    char *range_analysis(char *item, TimerResolver *timerResolver) {
        //在帮助里存储当前的次数
        CharHashMap *pMap = str_to_json_map(timerResolver->help);
        if (!containsKeyCharHashMap(pMap, "basicsPlan")) {
            putCharHashMap(pMap, "basicsPlan", timerResolver->plan);
            timerResolver->help = map_to_json_str(pMap);
        }
    
        CharList *pCharlist = str_split(item, "~");
        //验证是否都是数字
        for (int i = 0; i < pCharlist->len; ++i) {
            if (!str_is_number(pCharlist->str[i])) {
                assertError(formatStr("~解析错误非法字符(必须是数字):%s\n", pCharlist->str[i]));
            }
        }
        CharList *range = get_range(pCharlist->str[0], pCharlist->str[1]);
        char *data = array_to_json_str(range);
        char *string = str_concat(11, "{", "type:~", ",", "data:", data, ",", "index:0", ",", "return:", range->str[0],
                                  "}");
        //添加执行的次数
        CharHashMap *pMap1 = str_to_json_map(timerResolver->help);
        char *basicsPlan = getCharHashMap(pMap1, "basicsPlan");
        if(str_equals(basicsPlan,"n")||str_start_with(basicsPlan,"^")){
            timerResolver->plan = timerResolver->plan;
        }else{
            if (str_equals(timerResolver->plan, basicsPlan)) {
                timerResolver->plan = int_to_str(range->len * str_to_int(basicsPlan));
            } else {
                timerResolver->plan = int_to_str(str_to_int(timerResolver->plan) + (range->len * str_to_int(basicsPlan)));
            }
        }
    
        return string;
    }
    
    
    //间隔/ 解析  (5/2)表示从5开始,每隔2个数 执行一次
    char *interval_analysis(char *item, TimerResolver *timerResolver) {
        //在帮助里存储当前的次数
        CharHashMap *pMap = str_to_json_map(timerResolver->help);
        if (!containsKeyCharHashMap(pMap, "basicsPlan")) {
            putCharHashMap(pMap, "basicsPlan", timerResolver->plan);
            timerResolver->help = map_to_json_str(pMap);
        }
    
        CharList *pCharlist = str_split(item, "/");
        //验证是否都是数字
        for (int i = 0; i < pCharlist->len; ++i) {
            if (!str_is_number(pCharlist->str[i])) {
                assertError(formatStr("/解析错误非法字符(必须是数字):%s\n", pCharlist->str[i]));
            }
        }
        char *data = str_concat(5, "[", pCharlist->str[0], ",", pCharlist->str[1], "]");
        char *string = str_concat(11, "{", "type:/", ",", "data:", data, ",", "index:0", ",", "return:", pCharlist->str[0],
                                  "}");
        //添加执行的次数
        CharHashMap *pMap1 = str_to_json_map(timerResolver->help);
        char *basicsPlan = getCharHashMap(pMap1, "basicsPlan");
        if(str_equals(basicsPlan,"n")||str_start_with(basicsPlan,"^")){
            timerResolver->plan = timerResolver->plan;
        }else{
            if (str_equals(timerResolver->plan, basicsPlan)) {
                timerResolver->plan = int_to_str(str_to_int(basicsPlan) + 1);
            }
        }
        return string;
    }
    
    char *mode_analysis(char *item, TimerResolver *timerResolver) {
        CharHashMapIterator *pIterator = createCharHashMapIterator(timerResolver->mode);
        while (hasNextCharHashMapIterator(pIterator)) {
            CharKvLinkedNode *pNode = nextCharHashMapIterator(pIterator);
            if (str_start_with(item,pNode->key)) {//如果匹配到模式,那么就转换为统一结构化格式
                char *string = str_concat(6, "{", "type:mode", ",", "return:", item, "}");
                return string;
            }
        }
        assertError(formatStr("mode模式解析错误没有找到对应的模式-请检查模式是否自定义-并且添加到模式集中:%s\n", item));
    }
    
    
    //普通解析
    char *normal_analysis(char *item) {
        if (str_is_number(item)) {
            char *string = str_concat(6, "{", "type:number", ",", "return:", item, "}");
            return string;
        }
        assertError(formatStr("解析错误,无法解析的表达式:%s\n", item));
    }
    
    
    //获取结构化数据的返回数据
    char *get_return_data(char **data1) {
    
        char *data = *data1;
        //判断是否是字典格式
        if (str_is_map(data)) {
            //解析字典
            CharHashMap *pMap = str_to_json_map(data);
            //获取类型
            char *type = getCharHashMap(pMap, "type");
            //如果类型是[]
            if (str_compare(type,
                            "[]")) { //如果是[]类型 那么就是分段  例如 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]
                //获取data
                char *data = getCharHashMap(pMap, "data");
                //获取index
                char *index = getCharHashMap(pMap, "index");
                //获取返回数据
                char *returnData = getCharHashMap(pMap, "return");
                //获取数组
                //将[]里面的@转换为,号
                CharList *pCharlist = str_to_json_array(data);
                //获取下一个值
                int nextIndex = str_to_int(index) + 1;
                //判断是否超出数组长度,如果超出长度,从头开始
                if (nextIndex >= pCharlist->len) {
                    //超出长度,返回空
                    nextIndex = 0;
                }
                //获取下一个值
                char *nextValue = pCharlist->str[nextIndex];
                //设置返回数据
                putCharHashMap(pMap, "return", nextValue);
                //设置index
                putCharHashMap(pMap, "index", int_to_str(nextIndex));
                //修改原数据
                *data1 = map_to_json_str(pMap);
                //返回数据
                return returnData;
            } else if (str_compare(type, "~")) { //如果类型是~ 那么就是区间 1~5 表示1,2,3,4,5
                //如果类型是~
                //获取data
                char *data = getCharHashMap(pMap, "data");
                //获取index
                char *index = getCharHashMap(pMap, "index");
                //获取返回数据
                char *returnData = getCharHashMap(pMap, "return");
                //获取数组
                CharList *pCharlist = str_to_json_array(data);
                //获取下一个值
                int nextIndex = str_to_int(index) + 1;
                //判断是否超出数组长度,如果超出长度,从头开始
                if (nextIndex >= pCharlist->len) {
                    nextIndex = 0;
                }
                //获取下一个值
                char *nextValue = pCharlist->str[nextIndex];
                //设置返回数据
                putCharHashMap(pMap, "return", nextValue);
                //设置index
                putCharHashMap(pMap, "index", int_to_str(nextIndex));
                //修改原数据
                *data1 = map_to_json_str(pMap);
                //返回数据
                return returnData;
    
            } else if (str_compare(type, "/")) { // 如果类型是/ (5/2)表示从5开始,每隔2个数 执行一次
                //如果类型是/
                //获取data
                char *data = getCharHashMap(pMap, "data");
                //获取index
                char *index = getCharHashMap(pMap, "index");
                //获取返回数据
                char *returnData = getCharHashMap(pMap, "return");
                int nextIndex = str_to_int(index) + 1;
                if (nextIndex == 1) {
                    //获取数组
                    CharList *pCharlist = str_to_json_array(data);
                    //判断index是否是1,如果是1,取第二个值,并且转换为普通结构
                    char *string = str_concat(6, "{", "type:number", ",", "return:", pCharlist->str[nextIndex], "}");
                    *data1 = string;
                }
                return returnData;
            } else if (str_compare(type, "number")) {
                //如果类型是number,那么获取return
                char *returnData = getCharHashMap(pMap, "return");
                return returnData;
            }else if (str_compare(type, "mode")) {
                //如果类型是mode,那么获取return
                char *returnData = getCharHashMap(pMap, "return");
                return returnData;
            }
        }
        assertError(formatStr("解析错误不是结构化数据: %s\n", data));
    
    }
    
    //定时器语法转换为结构化格式
    void switchStructure(TimerResolver *timerResolver) {
        //秒
        if (str_contains(timerResolver->second, "[")) {
            timerResolver->second = section_analysis(timerResolver->second, timerResolver);
        } else if (str_contains(timerResolver->second, "~")) {
            timerResolver->second = range_analysis(timerResolver->second, timerResolver);
        } else if (str_contains(timerResolver->second, "/")) {
            timerResolver->second = interval_analysis(timerResolver->second, timerResolver);
        } else if (mode_exist(timerResolver->second, timerResolver)) {
            timerResolver->second = mode_analysis(timerResolver->second, timerResolver);
        } else {
            timerResolver->second = normal_analysis(timerResolver->second);
        }
        //分
        if (str_contains(timerResolver->minute, "[")) {
            timerResolver->minute = section_analysis(timerResolver->minute, timerResolver);
        } else if (str_contains(timerResolver->minute, "~")) {
            timerResolver->minute = range_analysis(timerResolver->minute, timerResolver);
        } else if (str_contains(timerResolver->minute, "/")) {
            timerResolver->minute = interval_analysis(timerResolver->minute, timerResolver);
        } else if (mode_exist(timerResolver->minute, timerResolver)) {
            timerResolver->minute = mode_analysis(timerResolver->minute, timerResolver);
        } else {
            timerResolver->minute = normal_analysis(timerResolver->minute);
        }
        //时
        if (str_contains(timerResolver->hour, "[")) {
            timerResolver->hour = section_analysis(timerResolver->hour, timerResolver);
        } else if (str_contains(timerResolver->hour, "~")) {
            timerResolver->hour = range_analysis(timerResolver->hour, timerResolver);
        } else if (str_contains(timerResolver->hour, "/")) {
            timerResolver->hour = interval_analysis(timerResolver->hour, timerResolver);
        } else if (mode_exist(timerResolver->hour, timerResolver)) {
            timerResolver->hour = mode_analysis(timerResolver->hour, timerResolver);
        } else {
            timerResolver->hour = normal_analysis(timerResolver->hour);
        }
        //日
        if (str_contains(timerResolver->day, "[")) {
            timerResolver->day = section_analysis(timerResolver->day, timerResolver);
        } else if (str_contains(timerResolver->day, "~")) {
            timerResolver->day = range_analysis(timerResolver->day, timerResolver);
        } else if (str_contains(timerResolver->day, "/")) {
            timerResolver->day = interval_analysis(timerResolver->day, timerResolver);
        } else if (mode_exist(timerResolver->day, timerResolver)) {
            timerResolver->day = mode_analysis(timerResolver->day, timerResolver);
        } else {
            timerResolver->day = normal_analysis(timerResolver->day);
        }
        //周
        if (str_contains(timerResolver->week, "[")) {
            timerResolver->week = section_analysis(timerResolver->week, timerResolver);
        } else if (str_contains(timerResolver->week, "~")) {
            timerResolver->week = range_analysis(timerResolver->week, timerResolver);
        } else if (str_contains(timerResolver->week, "/")) {
            timerResolver->week = interval_analysis(timerResolver->week, timerResolver);
        } else if (mode_exist(timerResolver->week, timerResolver)) {
            timerResolver->week = mode_analysis(timerResolver->week, timerResolver);
        } else {
            timerResolver->week = normal_analysis(timerResolver->week);
        }
        //月
        if (str_contains(timerResolver->month, "[")) {
            timerResolver->month = section_analysis(timerResolver->month, timerResolver);
        } else if (str_contains(timerResolver->month, "~")) {
            timerResolver->month = range_analysis(timerResolver->month, timerResolver);
        } else if (str_contains(timerResolver->month, "/")) {
            timerResolver->month = interval_analysis(timerResolver->month, timerResolver);
        } else if (mode_exist(timerResolver->month, timerResolver)) {
            timerResolver->month = mode_analysis(timerResolver->month, timerResolver);
        } else {
            timerResolver->month = normal_analysis(timerResolver->month);
        }
        //年
        if (str_contains(timerResolver->year, "[")) {
            timerResolver->year = section_analysis(timerResolver->year, timerResolver);
        } else if (str_contains(timerResolver->year, "~")) {
            timerResolver->year = range_analysis(timerResolver->year, timerResolver);
        } else if (str_contains(timerResolver->year, "/")) {
            timerResolver->year = interval_analysis(timerResolver->year, timerResolver);
        } else if (mode_exist(timerResolver->year, timerResolver)) {
            timerResolver->year = mode_analysis(timerResolver->year, timerResolver);
        } else {
            timerResolver->year = normal_analysis(timerResolver->year);
        }
    
    }
    
    //释放TimerResolver
    void free_timer_resolver(TimerResolver *timerResolver) {
        free(timerResolver);
    }
    
    
    

    在这里插入图片描述

    在这里插入图片描述

    点赞 -收藏-关注-便于以后复习和收到最新内容
    有其他问题在评论区讨论-或者私信我-收到会在第一时间回复
    在本博客学习的技术不得以任何方式直接或者间接的从事违反中华人民共和国法律,内容仅供学习、交流与参考
    免责声明:本文部分素材来源于网络,版权归原创者所有,如存在文章/图片/音视频等使用不当的情况,请随时私信联系我、以迅速采取适当措施,避免给双方造成不必要的经济损失。
    感谢,配合,希望我的努力对你有帮助^_^
  • 相关阅读:
    .NET周刊【4月第2期 2024-04-21】
    Docker安装MySQL并使用Navicat连接
    1569. 将子数组重新排序得到同一个二叉查找树的方案数 数学+DFS
    如何缓解压力、拒绝内耗【1】
    KQL和Lucene的区别
    韩顺平-零钱通项目
    native smart contracts, a easy forgotten thing.
    数据结构--B树
    关于宝宝过敏原检测的这几点,专家达成共识啦
    随机分布单向长纤维-复合材料RVE模型-abaqus-python二次开发(上)
  • 原文地址:https://blog.csdn.net/weixin_45203607/article/details/127042202