File: CronJob.cpp

package info (click to toggle)
bzflag 2.4.30-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 26,488 kB
  • sloc: cpp: 150,376; ansic: 3,463; sh: 2,535; makefile: 2,194; perl: 486; python: 260; objc: 246; php: 206
file content (177 lines) | stat: -rw-r--r-- 5,459 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/* bzflag
 * Copyright (c) 1993-2025 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "bzfsAPI.h"
#include "plugin_utils.h"
#include "CronJob.h"
#include <iostream>


// debug util func
static std::string vector_dump(std::vector<int> &iv)
{
    std::string tmp = "<";
    for (std::vector<int>::iterator itr = iv.begin(); itr != iv.end(); ++itr)
        tmp += format(" %d", *itr);
    tmp += " >";
    return tmp;
}

CronJob::CronJob()
{
    // do nothing
}

CronJob::CronJob(std::string job)
{
    setJob(job);
}

CronJob::~CronJob()
{
    // do nothing
}

void CronJob::setJob(std::string job)
{
    if (job.size() == 0)
        return;
    if (no_whitespace(job).size() == 0)
        return;

    // parse the string we're given into five vectors of n ints and a command
    // note: this is rather expensive
    inputJob = job;

    // first bust it up into tokens based on whitespace.
    // the first five are the timing values and the 'sixth through nth' is the command.
    std::vector<std::string> toks = tokenize(job, " \t", 6, false);

    // hokey dokey.  now we have six strings and we need five arrays of ints and one string out of them.
    minutes = parseTimeList(toks[0], 0, 59);
    hours = parseTimeList(toks[1], 0, 23);
    days = parseTimeList(toks[2], 1, 31);
    months = parseTimeList(toks[3], 1, 12);
    weekdays = parseTimeList(toks[4], 0, 7);
    command = toks[5];

    // sunday is both 7 and 0, make sure we have both or neither
    if (isInVector(weekdays, 0) && !isInVector(weekdays, 7))
        weekdays.push_back(7);
    else if (isInVector(weekdays, 7) && !isInVector(weekdays, 0))
        weekdays.push_back(0);

    // dump the list if we're debuggering
    if (bz_getDebugLevel() >= 4)
    {
        std::cout << "bzfscron: read job: " << inputJob << std::endl;
        std::cout << "bzfscron: job minutes: " << vector_dump(minutes) << std::endl;
        std::cout << "bzfscron: job hours: " << vector_dump(hours) << std::endl;
        std::cout << "bzfscron: job days: " << vector_dump(days) << std::endl;
        std::cout << "bzfscron: job months: " << vector_dump(months) << std::endl;
        std::cout << "bzfscron: job weekdays: " << vector_dump(weekdays) << std::endl;
        std::cout << "bzfscron: job command: " << command << std::endl;
    }
}

std::vector<int> CronJob::parseTimeList(const std::string in, const int min, const int max)
{
    std::vector<int> vi;
    std::string list = in;

    // First things first.  Find out if there's a periodicity and trim it off.
    size_t pos = in.find("/");
    int period = 1;
    if (pos != std::string::npos)
    {
        period = atoi(in.substr(pos + 1).c_str());
        list = in.substr(0, pos);
    }

    // Now tokenize on ","
    std::vector<std::string> stage1 = tokenize(list, ",", 0, false);
    // No tokens?  That's cool too.
    if (stage1.empty())
        stage1.push_back(list);

    // And for each token, blow up any "-" ranges and "*" ranges.
    for (std::vector<std::string>::iterator itr = stage1.begin(); itr != stage1.end(); ++itr)
    {
        if ((*itr).find("*") != std::string::npos)
        {
            bz_debugMessage(4, "bzfscron: exploding * range");
            for (int i = min; i <= max; ++i)
                vi.push_back(i);
        }
        else if ((pos = (int)(*itr).find("-")) != std::string::npos)
        {
            bz_debugMessage(4, "bzfscron: exploding x-y range");
            int rmin = 0, rmax = 0;
            rmin = atoi((*itr).substr(0, pos).c_str());
            rmax = atoi((*itr).substr(pos + 1).c_str());
            if (rmin < min)
                rmin = min;
            if (rmax > max)
                rmax = max;
            for (int i = rmin; i <= rmax; ++i)
                vi.push_back(i);
        }
        else
        {
            bz_debugMessage(4, "bzfscron: using single int");
            vi.push_back(atoi((*itr).c_str()));
        }
    }

    // Remember that periodicity we got rid of earlier?  Now we need it.
    // Eliminate any elements which disagree with the periodicity.
    if (period > 1)
    {
        std::vector<int> vp;
        for (std::vector<int>::iterator itr2 = vi.begin(); itr2 != vi.end(); ++itr2)
        {
            if (((*itr2) == 0) || ((*itr2) % period == 0))
                vp.push_back(*itr2);
        }
        return vp;
    }
    else
        return vi;
}

bool CronJob::matches(int n, int h, int d, int m, int w) const
{
    // if we are supposed to execute now, return true, otherwise return false
    return (isInVector(minutes, n) &&
            isInVector(hours, h) &&
            isInVector(days, d) &&
            isInVector(months, m) &&
            isInVector(weekdays, w));
}

bool CronJob::isInVector(const std::vector<int> &iv, const int x)
{
    for (std::vector<int>::const_iterator itr = iv.begin(); itr != iv.end(); ++itr)
    {
        if (*itr == x)
            return true;
    }
    return false;
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 4 ***
// c-basic-offset: 4 ***
// indent-tabs-mode: nil ***
// End: ***
// ex: shiftwidth=4 tabstop=4