[Asterisk-code-review] main/pbx: Move timing routines to pbx timing.c. (asterisk[13])

Corey Farrell asteriskteam at digium.com
Tue Jan 5 11:32:21 CST 2016


Corey Farrell has uploaded a new change for review.

  https://gerrit.asterisk.org/1913

Change subject: main/pbx: Move timing routines to pbx_timing.c.
......................................................................

main/pbx: Move timing routines to pbx_timing.c.

This is the fourth patch in a series meant to reduce the bulk of pbx.c.
This moves pbx timing functions to their own source.

Change-Id: I05c45186cb11edfc901e95f6be4e6a8abf129cd6
---
M main/pbx.c
A main/pbx_timing.c
2 files changed, 294 insertions(+), 254 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/13/1913/1

diff --git a/main/pbx.c b/main/pbx.c
index 88279ef..9cc0cc8 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -7117,260 +7117,6 @@
 	return ret;
 }
 
-/*! \brief Helper for get_range.
- * return the index of the matching entry, starting from 1.
- * If names is not supplied, try numeric values.
- */
-static int lookup_name(const char *s, const char * const names[], int max)
-{
-	int i;
-
-	if (names && *s > '9') {
-		for (i = 0; names[i]; i++) {
-			if (!strcasecmp(s, names[i])) {
-				return i;
-			}
-		}
-	}
-
-	/* Allow months and weekdays to be specified as numbers, as well */
-	if (sscanf(s, "%2d", &i) == 1 && i >= 1 && i <= max) {
-		/* What the array offset would have been: "1" would be at offset 0 */
-		return i - 1;
-	}
-	return -1; /* error return */
-}
-
-/*! \brief helper function to return a range up to max (7, 12, 31 respectively).
- * names, if supplied, is an array of names that should be mapped to numbers.
- */
-static unsigned get_range(char *src, int max, const char * const names[], const char *msg)
-{
-	int start, end; /* start and ending position */
-	unsigned int mask = 0;
-	char *part;
-
-	/* Check for whole range */
-	if (ast_strlen_zero(src) || !strcmp(src, "*")) {
-		return (1 << max) - 1;
-	}
-
-	while ((part = strsep(&src, "&"))) {
-		/* Get start and ending position */
-		char *endpart = strchr(part, '-');
-		if (endpart) {
-			*endpart++ = '\0';
-		}
-		/* Find the start */
-		if ((start = lookup_name(part, names, max)) < 0) {
-			ast_log(LOG_WARNING, "Invalid %s '%s', skipping element\n", msg, part);
-			continue;
-		}
-		if (endpart) { /* find end of range */
-			if ((end = lookup_name(endpart, names, max)) < 0) {
-				ast_log(LOG_WARNING, "Invalid end %s '%s', skipping element\n", msg, endpart);
-				continue;
-			}
-		} else {
-			end = start;
-		}
-		/* Fill the mask. Remember that ranges are cyclic */
-		mask |= (1 << end);   /* initialize with last element */
-		while (start != end) {
-			mask |= (1 << start);
-			if (++start >= max) {
-				start = 0;
-			}
-		}
-	}
-	return mask;
-}
-
-/*! \brief store a bitmask of valid times, one bit each 1 minute */
-static void get_timerange(struct ast_timing *i, char *times)
-{
-	char *endpart, *part;
-	int x;
-	int st_h, st_m;
-	int endh, endm;
-	int minute_start, minute_end;
-
-	/* start disabling all times, fill the fields with 0's, as they may contain garbage */
-	memset(i->minmask, 0, sizeof(i->minmask));
-
-	/* 1-minute per bit */
-	/* Star is all times */
-	if (ast_strlen_zero(times) || !strcmp(times, "*")) {
-		/* 48, because each hour takes 2 integers; 30 bits each */
-		for (x = 0; x < 48; x++) {
-			i->minmask[x] = 0x3fffffff; /* 30 bits */
-		}
-		return;
-	}
-	/* Otherwise expect a range */
-	while ((part = strsep(&times, "&"))) {
-		if (!(endpart = strchr(part, '-'))) {
-			if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
-				ast_log(LOG_WARNING, "%s isn't a valid time.\n", part);
-				continue;
-			}
-			i->minmask[st_h * 2 + (st_m >= 30 ? 1 : 0)] |= (1 << (st_m % 30));
-			continue;
-		}
-		*endpart++ = '\0';
-		/* why skip non digits? Mostly to skip spaces */
-		while (*endpart && !isdigit(*endpart)) {
-			endpart++;
-		}
-		if (!*endpart) {
-			ast_log(LOG_WARNING, "Invalid time range starting with '%s-'.\n", part);
-			continue;
-		}
-		if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
-			ast_log(LOG_WARNING, "'%s' isn't a valid start time.\n", part);
-			continue;
-		}
-		if (sscanf(endpart, "%2d:%2d", &endh, &endm) != 2 || endh < 0 || endh > 23 || endm < 0 || endm > 59) {
-			ast_log(LOG_WARNING, "'%s' isn't a valid end time.\n", endpart);
-			continue;
-		}
-		minute_start = st_h * 60 + st_m;
-		minute_end = endh * 60 + endm;
-		/* Go through the time and enable each appropriate bit */
-		for (x = minute_start; x != minute_end; x = (x + 1) % (24 * 60)) {
-			i->minmask[x / 30] |= (1 << (x % 30));
-		}
-		/* Do the last one */
-		i->minmask[x / 30] |= (1 << (x % 30));
-	}
-	/* All done */
-	return;
-}
-
-static const char * const days[] =
-{
-	"sun",
-	"mon",
-	"tue",
-	"wed",
-	"thu",
-	"fri",
-	"sat",
-	NULL,
-};
-
-static const char * const months[] =
-{
-	"jan",
-	"feb",
-	"mar",
-	"apr",
-	"may",
-	"jun",
-	"jul",
-	"aug",
-	"sep",
-	"oct",
-	"nov",
-	"dec",
-	NULL,
-};
-/*! /brief Build timing
- *
- * /param i info
- * /param info_in
- *
- */
-int ast_build_timing(struct ast_timing *i, const char *info_in)
-{
-	char *info;
-	int j, num_fields, last_sep = -1;
-
-	i->timezone = NULL;
-
-	/* Check for empty just in case */
-	if (ast_strlen_zero(info_in)) {
-		return 0;
-	}
-
-	/* make a copy just in case we were passed a static string */
-	info = ast_strdupa(info_in);
-
-	/* count the number of fields in the timespec */
-	for (j = 0, num_fields = 1; info[j] != '\0'; j++) {
-		if (info[j] == ',') {
-			last_sep = j;
-			num_fields++;
-		}
-	}
-
-	/* save the timezone, if it is specified */
-	if (num_fields == 5) {
-		i->timezone = ast_strdup(info + last_sep + 1);
-	}
-
-	/* Assume everything except time */
-	i->monthmask = 0xfff;	/* 12 bits */
-	i->daymask = 0x7fffffffU; /* 31 bits */
-	i->dowmask = 0x7f; /* 7 bits */
-	/* on each call, use strsep() to move info to the next argument */
-	get_timerange(i, strsep(&info, "|,"));
-	if (info)
-		i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
-	if (info)
-		i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
-	if (info)
-		i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
-	return 1;
-}
-
-int ast_check_timing(const struct ast_timing *i)
-{
-	return ast_check_timing2(i, ast_tvnow());
-}
-
-int ast_check_timing2(const struct ast_timing *i, const struct timeval tv)
-{
-	struct ast_tm tm;
-
-	ast_localtime(&tv, &tm, i->timezone);
-
-	/* If it's not the right month, return */
-	if (!(i->monthmask & (1 << tm.tm_mon)))
-		return 0;
-
-	/* If it's not that time of the month.... */
-	/* Warning, tm_mday has range 1..31! */
-	if (!(i->daymask & (1 << (tm.tm_mday-1))))
-		return 0;
-
-	/* If it's not the right day of the week */
-	if (!(i->dowmask & (1 << tm.tm_wday)))
-		return 0;
-
-	/* Sanity check the hour just to be safe */
-	if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
-		ast_log(LOG_WARNING, "Insane time...\n");
-		return 0;
-	}
-
-	/* Now the tough part, we calculate if it fits
-	   in the right time based on min/hour */
-	if (!(i->minmask[tm.tm_hour * 2 + (tm.tm_min >= 30 ? 1 : 0)] & (1 << (tm.tm_min >= 30 ? tm.tm_min - 30 : tm.tm_min))))
-		return 0;
-
-	/* If we got this far, then we're good */
-	return 1;
-}
-
-int ast_destroy_timing(struct ast_timing *i)
-{
-	if (i->timezone) {
-		ast_free(i->timezone);
-		i->timezone = NULL;
-	}
-	return 0;
-}
 /*
  * errno values
  *  ENOMEM - out of memory
diff --git a/main/pbx_timing.c b/main/pbx_timing.c
new file mode 100644
index 0000000..53529bb
--- /dev/null
+++ b/main/pbx_timing.c
@@ -0,0 +1,294 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2016, CFWare, LLC
+ *
+ * Corey Farrell <git at cfware.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief PBX timing routines.
+ *
+ * \author Corey Farrell <git at cfware.com>
+ */
+
+/*** MODULEINFO
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/localtime.h"
+#include "asterisk/logger.h"
+#include "asterisk/pbx.h"
+#include "asterisk/strings.h"
+#include "asterisk/utils.h"
+
+/*! \brief Helper for get_range.
+ * return the index of the matching entry, starting from 1.
+ * If names is not supplied, try numeric values.
+ */
+static int lookup_name(const char *s, const char * const names[], int max)
+{
+	int i;
+
+	if (names && *s > '9') {
+		for (i = 0; names[i]; i++) {
+			if (!strcasecmp(s, names[i])) {
+				return i;
+			}
+		}
+	}
+
+	/* Allow months and weekdays to be specified as numbers, as well */
+	if (sscanf(s, "%2d", &i) == 1 && i >= 1 && i <= max) {
+		/* What the array offset would have been: "1" would be at offset 0 */
+		return i - 1;
+	}
+	return -1; /* error return */
+}
+
+/*! \brief helper function to return a range up to max (7, 12, 31 respectively).
+ * names, if supplied, is an array of names that should be mapped to numbers.
+ */
+static unsigned get_range(char *src, int max, const char * const names[], const char *msg)
+{
+	int start, end; /* start and ending position */
+	unsigned int mask = 0;
+	char *part;
+
+	/* Check for whole range */
+	if (ast_strlen_zero(src) || !strcmp(src, "*")) {
+		return (1 << max) - 1;
+	}
+
+	while ((part = strsep(&src, "&"))) {
+		/* Get start and ending position */
+		char *endpart = strchr(part, '-');
+		if (endpart) {
+			*endpart++ = '\0';
+		}
+		/* Find the start */
+		if ((start = lookup_name(part, names, max)) < 0) {
+			ast_log(LOG_WARNING, "Invalid %s '%s', skipping element\n", msg, part);
+			continue;
+		}
+		if (endpart) { /* find end of range */
+			if ((end = lookup_name(endpart, names, max)) < 0) {
+				ast_log(LOG_WARNING, "Invalid end %s '%s', skipping element\n", msg, endpart);
+				continue;
+			}
+		} else {
+			end = start;
+		}
+		/* Fill the mask. Remember that ranges are cyclic */
+		mask |= (1 << end);   /* initialize with last element */
+		while (start != end) {
+			mask |= (1 << start);
+			if (++start >= max) {
+				start = 0;
+			}
+		}
+	}
+	return mask;
+}
+
+/*! \brief store a bitmask of valid times, one bit each 1 minute */
+static void get_timerange(struct ast_timing *i, char *times)
+{
+	char *endpart, *part;
+	int x;
+	int st_h, st_m;
+	int endh, endm;
+	int minute_start, minute_end;
+
+	/* start disabling all times, fill the fields with 0's, as they may contain garbage */
+	memset(i->minmask, 0, sizeof(i->minmask));
+
+	/* 1-minute per bit */
+	/* Star is all times */
+	if (ast_strlen_zero(times) || !strcmp(times, "*")) {
+		/* 48, because each hour takes 2 integers; 30 bits each */
+		for (x = 0; x < 48; x++) {
+			i->minmask[x] = 0x3fffffff; /* 30 bits */
+		}
+		return;
+	}
+	/* Otherwise expect a range */
+	while ((part = strsep(&times, "&"))) {
+		if (!(endpart = strchr(part, '-'))) {
+			if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
+				ast_log(LOG_WARNING, "%s isn't a valid time.\n", part);
+				continue;
+			}
+			i->minmask[st_h * 2 + (st_m >= 30 ? 1 : 0)] |= (1 << (st_m % 30));
+			continue;
+		}
+		*endpart++ = '\0';
+		/* why skip non digits? Mostly to skip spaces */
+		while (*endpart && !isdigit(*endpart)) {
+			endpart++;
+		}
+		if (!*endpart) {
+			ast_log(LOG_WARNING, "Invalid time range starting with '%s-'.\n", part);
+			continue;
+		}
+		if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
+			ast_log(LOG_WARNING, "'%s' isn't a valid start time.\n", part);
+			continue;
+		}
+		if (sscanf(endpart, "%2d:%2d", &endh, &endm) != 2 || endh < 0 || endh > 23 || endm < 0 || endm > 59) {
+			ast_log(LOG_WARNING, "'%s' isn't a valid end time.\n", endpart);
+			continue;
+		}
+		minute_start = st_h * 60 + st_m;
+		minute_end = endh * 60 + endm;
+		/* Go through the time and enable each appropriate bit */
+		for (x = minute_start; x != minute_end; x = (x + 1) % (24 * 60)) {
+			i->minmask[x / 30] |= (1 << (x % 30));
+		}
+		/* Do the last one */
+		i->minmask[x / 30] |= (1 << (x % 30));
+	}
+	/* All done */
+	return;
+}
+
+static const char * const days[] =
+{
+	"sun",
+	"mon",
+	"tue",
+	"wed",
+	"thu",
+	"fri",
+	"sat",
+	NULL,
+};
+
+static const char * const months[] =
+{
+	"jan",
+	"feb",
+	"mar",
+	"apr",
+	"may",
+	"jun",
+	"jul",
+	"aug",
+	"sep",
+	"oct",
+	"nov",
+	"dec",
+	NULL,
+};
+
+/*! /brief Build timing
+ *
+ * /param i info
+ * /param info_in
+ *
+ */
+int ast_build_timing(struct ast_timing *i, const char *info_in)
+{
+	char *info;
+	int j, num_fields, last_sep = -1;
+
+	i->timezone = NULL;
+
+	/* Check for empty just in case */
+	if (ast_strlen_zero(info_in)) {
+		return 0;
+	}
+
+	/* make a copy just in case we were passed a static string */
+	info = ast_strdupa(info_in);
+
+	/* count the number of fields in the timespec */
+	for (j = 0, num_fields = 1; info[j] != '\0'; j++) {
+		if (info[j] == ',') {
+			last_sep = j;
+			num_fields++;
+		}
+	}
+
+	/* save the timezone, if it is specified */
+	if (num_fields == 5) {
+		i->timezone = ast_strdup(info + last_sep + 1);
+	}
+
+	/* Assume everything except time */
+	i->monthmask = 0xfff;	/* 12 bits */
+	i->daymask = 0x7fffffffU; /* 31 bits */
+	i->dowmask = 0x7f; /* 7 bits */
+	/* on each call, use strsep() to move info to the next argument */
+	get_timerange(i, strsep(&info, "|,"));
+	if (info)
+		i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
+	if (info)
+		i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
+	if (info)
+		i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
+	return 1;
+}
+
+int ast_check_timing(const struct ast_timing *i)
+{
+	return ast_check_timing2(i, ast_tvnow());
+}
+
+int ast_check_timing2(const struct ast_timing *i, const struct timeval tv)
+{
+	struct ast_tm tm;
+
+	ast_localtime(&tv, &tm, i->timezone);
+
+	/* If it's not the right month, return */
+	if (!(i->monthmask & (1 << tm.tm_mon)))
+		return 0;
+
+	/* If it's not that time of the month.... */
+	/* Warning, tm_mday has range 1..31! */
+	if (!(i->daymask & (1 << (tm.tm_mday-1))))
+		return 0;
+
+	/* If it's not the right day of the week */
+	if (!(i->dowmask & (1 << tm.tm_wday)))
+		return 0;
+
+	/* Sanity check the hour just to be safe */
+	if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
+		ast_log(LOG_WARNING, "Insane time...\n");
+		return 0;
+	}
+
+	/* Now the tough part, we calculate if it fits
+	   in the right time based on min/hour */
+	if (!(i->minmask[tm.tm_hour * 2 + (tm.tm_min >= 30 ? 1 : 0)] & (1 << (tm.tm_min >= 30 ? tm.tm_min - 30 : tm.tm_min))))
+		return 0;
+
+	/* If we got this far, then we're good */
+	return 1;
+}
+
+int ast_destroy_timing(struct ast_timing *i)
+{
+	if (i->timezone) {
+		ast_free(i->timezone);
+		i->timezone = NULL;
+	}
+	return 0;
+}

-- 
To view, visit https://gerrit.asterisk.org/1913
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I05c45186cb11edfc901e95f6be4e6a8abf129cd6
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: Corey Farrell <git at cfware.com>



More information about the asterisk-code-review mailing list