#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include <sys/time.h>
#include <signal.h>
#include <limits.h>
#include <unistd.h>
#include <math.h>
#include "schedule.h"
#include "timeRoutines.h"
#include "schedule.tab.h"
Defines | |
#define | SUCCESS 0 |
#define | ERROR 1 |
#define | MAX_CMD_LEN 300 |
#define | SCHED_WILDCARD -1 |
#define | TIME_IN_PAST -1 |
#define | ERR_FILE stdout |
Enumerations | |
enum | CalIndex { CI_YEAR, CI_MOY, CI_DOM, CI_DOW, CI_HOUR, CI_MIN } |
Functions | |
size_t | strnlen (const char *s, size_t n) |
void | usage () |
void | getFileLoc (const char *fileLoc) |
int | processArgs (int argc, char **argv) |
int | processScheduleFile (const char *fileName) |
void | runNotifications () |
void | displayCalValue (FILE *out, valueStruct *value) |
int | rollYear (scheduleEntry *entry, struct tm *scheduled) |
int | rollMonth (scheduleEntry *entry, struct tm *scheduled) |
int | rollDayOfMonth (scheduleEntry *entry, struct tm *scheduled) |
int | rollHour (scheduleEntry *entry, struct tm *scheduled) |
int | rollMinute (scheduleEntry *entry, struct tm *scheduled) |
int | daysInMonth (int year, int month) |
void | initValues (scheduleEntry *entry, struct tm *scheduled, enum CalIndex level) |
int | returnFirstValue (valueStruct values) |
void | execActionCommand (scheduleEntry *entry) |
scheduleEntry * | parseSchedule (const char *buffer) |
void | addEntryToList (scheduleEntry *entry) |
time_t | setDebugTime (time_t time) |
time_t | getCurrentTime () |
valueStruct * | copyValueStruct (valueStruct *dest, valueStruct *source) |
void | normalizeValueStruct (valueStruct *value) |
int | compareCurrentToSchedule (int current, valueStruct *values) |
int | compareEventTime (const void *event1, const void *event2) |
eventEntry ** | getScheduledEvents (time_t startTime, time_t stopTime, int *numEvents) |
int | setTaskAlarm (time_t timeToSleep) |
scheduleNode * | createScheduleNode () |
void | freeScheduleNodeList (scheduleNode *current) |
void | freeEventSchedule (eventEntry **schedule, int numEvents) |
int | addScheduleEntryAdv (valueStruct *year, valueStruct *month, valueStruct *dayOfMonth, valueStruct *dayOfWeek, valueStruct *hour, valueStruct *minute, int duration, const char *task, const char *reminder) |
int | addScheduleEntryNormalize (valueStruct *year, valueStruct *month, valueStruct *dayOfMonth, valueStruct *dayOfWeek, valueStruct *hour, valueStruct *minute, int duration, const char *task, const char *reminder, actionNode *actionSet) |
scheduleEntry * | createScheduleEntry (int year, int month, int dayOfMonth, int dayOfWeek, int hour, int minute, int duration, const char *task, const char *reminder) |
scheduleEntry * | createScheduleEntryAdv (valueStruct *year, valueStruct *month, valueStruct *dayOfMonth, valueStruct *dayOfWeek, valueStruct *hour, valueStruct *minute, int duration, const char *task, const char *reminder) |
void | freeScheduleEntry (scheduleEntry *entry) |
void | displaySchedule (FILE *out) |
void | displayTodaysSchedulex (FILE *out) |
void | displayTodaysSchedule (FILE *out) |
actionNode * | createActionSet (actionDef *action) |
actionDef * | createActionCommand (char *commandName, char *commandStr, enum ActionType type) |
actionDef * | findActionCommand (char *commandName) |
void | addActionToActionSet (actionNode *node, actionDef *action) |
void | addActionCommand (char *commandName, char *commandStr, enum ActionType type) |
void | freeEventEntry (eventEntry *entry) |
scheduledExec * | calcNextTaskAlarm () |
void | executeScheduledEntry (scheduledExec *task) |
time_t | calcNextTimeForTask (scheduleEntry *entry) |
void | setTestTime (time_t time) |
valueStruct * | createSingleValue (int value) |
valueStruct * | createRangeValue (int begin, int end, int step) |
valueStruct * | createWildcardValue () |
valueStruct * | createListValue (valueStruct *value) |
void | addListValue (valueStruct *list, valueStruct *value) |
void | freeValueStruct (valueStruct *value) |
void | freeValueStructList (valueStruct *value) |
Variables | |
int | scheduleCount = 0 |
const int | monthDaysNorm [] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} |
const int | monthDaysLeap [] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} |
const int | INIT_MON_VAL = 0 |
const int | INIT_DOM_VAL = 1 |
const int | INIT_HOUR_VAL = 0 |
const int | INIT_MIN_VAL = 0 |
#define ERR_FILE stdout |
#define ERROR 1 |
#define MAX_CMD_LEN 300 |
#define SCHED_WILDCARD -1 |
#define SUCCESS 0 |
#define TIME_IN_PAST -1 |
enum CalIndex |
void addActionCommand | ( | char * | commandName, | |
char * | commandStr, | |||
enum ActionType | type | |||
) |
Add a command string to the current list of reminder commands.
void addActionToActionSet | ( | actionNode * | node, | |
actionDef * | action | |||
) |
Add an action to a provided set of actions.
void addEntryToList | ( | scheduleEntry * | entry | ) |
void addListValue | ( | valueStruct * | list, | |
valueStruct * | value | |||
) |
Add a value to an the list provided.
int addScheduleEntryAdv | ( | valueStruct * | year, | |
valueStruct * | month, | |||
valueStruct * | dayOfMonth, | |||
valueStruct * | dayOfWeek, | |||
valueStruct * | hour, | |||
valueStruct * | minute, | |||
int | duration, | |||
const char * | task, | |||
const char * | reminder | |||
) |
Add a schedule entry to the list of entries using the values provided. Args: year 4 digit year month Valid values: 0 - 11 dayOfMonth Valid values: 1 - 31 dayOfWeek Valid values: 0 - 6 0 is equal to Sunday hour Valid values: 0 - 23 minute Valid values: 0 - 59 duration Duration of task in minutes task Null terminated string containing task description reminder Null terminated string containing reminder message Returns: SUCCESS if entry created. ERROR if error occurred during add. Entry was not created.
int addScheduleEntryNormalize | ( | valueStruct * | year, | |
valueStruct * | month, | |||
valueStruct * | dayOfMonth, | |||
valueStruct * | dayOfWeek, | |||
valueStruct * | hour, | |||
valueStruct * | minute, | |||
int | duration, | |||
const char * | task, | |||
const char * | reminder, | |||
actionNode * | actionSet | |||
) |
Add a schedule entry to the list of entries using the values provided. Args: year 4 digit year month Valid values: 1 - 12 dayOfMonth Valid values: 1 - 31 dayOfWeek Valid values: 1 - 7 1 is equal to Sunday hour Valid values: 0 - 23 minute Valid values: 0 - 59 duration Duration of task in minutes task Null terminated string containing task description reminder Null terminated string containing reminder message actionSet Root node of action set. May be NULL Returns: SUCCESS if entry created. ERROR if error occurred during add. Entry was not created.
scheduledExec* calcNextTaskAlarm | ( | ) |
Return next scheduled task and the time to execute that task. If no future tasks are scheduled, then a null value will be returned.
Returned value must be freed by caller.
time_t calcNextTimeForTask | ( | scheduleEntry * | entry | ) |
Returns the next time that the provided entry should be activated. If in the past, TIME_IN_PAST, a negative value wil be returned.
int compareCurrentToSchedule | ( | int | current, | |
valueStruct * | values | |||
) |
Compare current calendar value to all values in provided ValueStruct to determine if next applicable schedule value is in past, present, or future. Return offset from current value. For example: Current month = 9; Values: 1,2,5-8; Return -8 (1-9) Current month = 3; Values: 1,2,5-8; Return 2 (5-3) Current month = 5; Values: 1,2,5-8; Return 0 (5-5)
int compareEventTime | ( | const void * | event1, | |
const void * | event2 | |||
) |
Compare two eventEntry elements and return - int, 0, or + int for event1 < event2, event1 = event2, or event1 > event2 respectively.
valueStruct * copyValueStruct | ( | valueStruct * | dest, | |
valueStruct * | source | |||
) |
Perform deep copy of valueStruct items needed for LIST type Args: dest Allocated structure or null if to be allocated. If null, then newly allocted and populated structure will be returned source Source to copy Return Populated structure. If dest arg was not null, then it will be the same pointer. Otherwise, it will be a newly allocated pointer.
actionDef* createActionCommand | ( | char * | commandName, | |
char * | commandStr, | |||
enum ActionType | type | |||
) |
Create a command
actionNode* createActionSet | ( | actionDef * | action | ) |
Create a new action set and populate with the provided action.
valueStruct* createListValue | ( | valueStruct * | value | ) |
Creates a list value valueStruct instance. Should be freed using freeValueStructList
valueStruct* createRangeValue | ( | int | begin, | |
int | end, | |||
int | step | |||
) |
Creates a range value valueStruct instance. Should be freed using freeValueStruct
scheduleEntry* createScheduleEntry | ( | int | year, | |
int | month, | |||
int | dayOfMonth, | |||
int | dayOfWeek, | |||
int | hour, | |||
int | minute, | |||
int | duration, | |||
const char * | task, | |||
const char * | reminder | |||
) |
Create a schedule entry using the values provided. Must be freed using freeScheduleEntry(entry *) Args: year 4 digit year or -1 for wildcard month Valid values: 0 - 11 or -1 for wildcard dayOfMonth Valid values: 1 - 31 or -1 for wildcard dayOfWeek Valid values: 0 - 6 or -1 for wildcard 0 is equal to Sunday hour Valid values: 0 - 23 or -1 for wildcard minute Valid values: 0 - 59 duration Duration of task in minutes task Null terminated string containing task description reminder Null terminated string containing reminder message Returns: Newly allocated and popluated schedule entry NULL if error occurred during creation
scheduleEntry* createScheduleEntryAdv | ( | valueStruct * | year, | |
valueStruct * | month, | |||
valueStruct * | dayOfMonth, | |||
valueStruct * | dayOfWeek, | |||
valueStruct * | hour, | |||
valueStruct * | minute, | |||
int | duration, | |||
const char * | task, | |||
const char * | reminder | |||
) |
Create a schedule entry using the values contained within valueStruct elements. This allows for more advanced scheduling by providing additional methods for specifying values. In addition to wildcard and single values, the following types may be used:
NOTE: Must be freed using freeScheduleEntry(entry *)
Args: year - minute are valueStructs with the values constrained as shown below: year 4 digit year month Valid values: 0 - 11 dayOfMonth Valid values: 1 - 31 dayOfWeek Valid values: 0 - 6 0 is equal to Sunday hour Valid values: 0 - 23 minute Valid values: 0 - 59 duration Duration of task in minutes: 0 - max int. task Null terminated string containing task description reminder Null terminated string containing reminder message Returns: Newly allocated and popluated schedule entry NULL if error occurred during creation
scheduleNode * createScheduleNode | ( | ) |
Allocate and initialize a scheduleNode
valueStruct* createSingleValue | ( | int | value | ) |
Creates a single value valueStruct instance. Should be freed using freeValueStruct
valueStruct* createWildcardValue | ( | ) |
Creates a wildcard value valueStruct instance. Should be freed using freeValueStruct
int daysInMonth | ( | int | year, | |
int | month | |||
) |
Return the number of days in the month for the given year.
void displayCalValue | ( | FILE * | out, | |
valueStruct * | value | |||
) |
void displaySchedule | ( | FILE * | out | ) |
void displayTodaysSchedule | ( | FILE * | out | ) |
void displayTodaysSchedulex | ( | FILE * | out | ) |
void execActionCommand | ( | scheduleEntry * | entry | ) |
Execute all action commands for the current entry. If the entry has specific commands, then these will be executed in order. If not, them all default commands will be executed in order. After all commands are executed, all commands with the ALWAYS action type will be executed in order.
void executeScheduledEntry | ( | scheduledExec * | task | ) |
Execute all actions associated with the scheduled task.
actionDef* findActionCommand | ( | char * | commandName | ) |
Find an existing action command for the provided name.
void freeEventEntry | ( | eventEntry * | entry | ) |
void freeEventSchedule | ( | eventEntry ** | schedule, | |
int | numEvents | |||
) |
void freeScheduleEntry | ( | scheduleEntry * | entry | ) |
Free the schedule entry and all associated allocations.
void freeScheduleNodeList | ( | scheduleNode * | current | ) |
Free the node list, but not the schedule entries contained within the nodes NOTE: Just testing idea of using recursion to free linked list. Not sure if it is any better than assiging next to a temp.
void freeValueStruct | ( | valueStruct * | value | ) |
This will free the valueStruct and if it is a list, then it will recursively free all list members. If the top level List is allocated on the stack, then use freeValueStructList instead as it will not attempt to free the top level node.
void freeValueStructList | ( | valueStruct * | value | ) |
This will recursively free the members of the list, but not the top level item.
NOTE: If the top level List is allocated on the heap, then use freeValueStruct instead.
time_t getCurrentTime | ( | ) |
Return "current" time. During testing, current time will be overridden to provide fixed value for deterministic results.
void getFileLoc | ( | const char * | fileLoc | ) |
eventEntry ** getScheduledEvents | ( | time_t | startTime, | |
time_t | stopTime, | |||
int * | numEvents | |||
) |
Returns sorted array of scheduled events based on start and stop times. For repeating events, will return only the next scheduled time from now within the range. The size of the array will be returned in the out parameter numEvents Returned array should be freed using freeEventSchedule.
void initValues | ( | scheduleEntry * | entry, | |
struct tm * | scheduled, | |||
enum CalIndex | level | |||
) |
Initialize scheduled values from the provided level on down using values contained within the entry. For example: If the level is DOM, then year and month will remain intact and all finer grained time values will be initialized to the lowest value if wild or the value from the entry.
void normalizeValueStruct | ( | valueStruct * | value | ) |
scheduleEntry* parseSchedule | ( | const char * | buffer | ) |
int processArgs | ( | int | argc, | |
char ** | argv | |||
) |
int processScheduleFile | ( | const char * | fileName | ) |
int returnFirstValue | ( | valueStruct | values | ) |
Return the first value based on type of entry.
int rollDayOfMonth | ( | scheduleEntry * | entry, | |
struct tm * | scheduled | |||
) |
Increment the day of month, if mutable, by the number of days provided. This may be constrained by the Day of Week setting. If not, then attempt incrementing coarser grained calendar variables. If date could not be incremented, return ERROR.
Assumptions: both scheduled tm_wday and tm_mday are set
int rollHour | ( | scheduleEntry * | entry, | |
struct tm * | scheduled | |||
) |
Increment the hour if mutable. If not, then attempt incrementing coarser grained calendar variables. If date could not be incremented, return ERROR.
int rollMinute | ( | scheduleEntry * | entry, | |
struct tm * | scheduled | |||
) |
Increment the minute if mutable. If not, attempt incrementing coarser grained calendar variables. If date could not be incremented, return ERROR.
int rollMonth | ( | scheduleEntry * | entry, | |
struct tm * | scheduled | |||
) |
Increment the month if mutable. If not, the attempt incrementing coarser grained calendar variables. If date could not be incremented, return ERROR.
int rollYear | ( | scheduleEntry * | entry, | |
struct tm * | scheduled | |||
) |
Increment the year if mutable. If not, return ERROR
void runNotifications | ( | ) |
time_t setDebugTime | ( | time_t | time | ) |
int setTaskAlarm | ( | time_t | timeToSleep | ) |
void setTestTime | ( | time_t | time | ) |
Set fixed test time. Should be used for testing only.
size_t strnlen | ( | const char * | s, | |
size_t | n | |||
) |
void usage | ( | ) |
const int INIT_DOM_VAL = 1 |
const int INIT_HOUR_VAL = 0 |
const int INIT_MIN_VAL = 0 |
const int INIT_MON_VAL = 0 |
const int monthDaysLeap[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} |
const int monthDaysNorm[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} |
int scheduleCount = 0 |