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
|