[Asterisk-code-review] app_playback.c: Remove experimental 'say' application (asterisk[master])

Sean Bright asteriskteam at digium.com
Wed Oct 20 13:02:44 CDT 2021


Sean Bright has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/16623 )


Change subject: app_playback.c: Remove experimental 'say' application
......................................................................

app_playback.c: Remove experimental 'say' application

ASTERISK-29695 #close

Change-Id: I3200aa184d97679e4a134ec1de82389203d2a0de
---
M apps/app_playback.c
D configs/samples/say.conf.sample
2 files changed, 2 insertions(+), 801 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/23/16623/1

diff --git a/apps/app_playback.c b/apps/app_playback.c
index 0c9281a..e3531a9 100644
--- a/apps/app_playback.c
+++ b/apps/app_playback.c
@@ -35,11 +35,6 @@
 #include "asterisk/pbx.h"
 #include "asterisk/module.h"
 #include "asterisk/app.h"
-/* This file provides config-file based 'say' functions, and implenents
- * some CLI commands.
- */
-#include "asterisk/say.h"	/*!< provides config-file based 'say' functions */
-#include "asterisk/cli.h"
 
 /*** DOCUMENTATION
 	<application name="Playback" language="en_US">
@@ -93,359 +88,12 @@
 
 static char *app = "Playback";
 
-static struct ast_config *say_cfg = NULL;
-
-/*! \brief save the say' api calls.
- * The first entry is NULL if we have the standard source,
- * otherwise we are sourcing from here.
- * 'say load [new|old]' will enable the new or old method, or report status
- */
-static const void *say_api_buf[40];
-static const char * const say_old = "old";
-static const char * const say_new = "new";
-
-static void save_say_mode(const void *arg)
-{
-	int i = 0;
-	say_api_buf[i++] = arg;
-
-	say_api_buf[i++] = ast_say_number_full;
-	say_api_buf[i++] = ast_say_enumeration_full;
-	say_api_buf[i++] = ast_say_digit_str_full;
-	say_api_buf[i++] = ast_say_character_str_full;
-	say_api_buf[i++] = ast_say_phonetic_str_full;
-	say_api_buf[i++] = ast_say_datetime;
-	say_api_buf[i++] = ast_say_time;
-	say_api_buf[i++] = ast_say_date;
-	say_api_buf[i++] = ast_say_datetime_from_now;
-	say_api_buf[i++] = ast_say_date_with_format;
-}
-
-static void restore_say_mode(void *arg)
-{
-	int i = 0;
-	say_api_buf[i++] = arg;
-
-	ast_say_number_full = say_api_buf[i++];
-	ast_say_enumeration_full = say_api_buf[i++];
-	ast_say_digit_str_full = say_api_buf[i++];
-	ast_say_character_str_full = say_api_buf[i++];
-	ast_say_phonetic_str_full = say_api_buf[i++];
-	ast_say_datetime = say_api_buf[i++];
-	ast_say_time = say_api_buf[i++];
-	ast_say_date = say_api_buf[i++];
-	ast_say_datetime_from_now = say_api_buf[i++];
-	ast_say_date_with_format = say_api_buf[i++];
-}
-
-/*! \brief
- * Typical 'say' arguments in addition to the date or number or string
- * to say. We do not include 'options' because they may be different
- * in recursive calls, and so they are better left as an external
- * parameter.
- */
-typedef struct {
-	struct ast_channel *chan;
-	const char *ints;
-	const char *language;
-	int audiofd;
-	int ctrlfd;
-} say_args_t;
-
-static int s_streamwait3(const say_args_t *a, const char *fn)
-{
-	int res = ast_streamfile(a->chan, fn, a->language);
-	if (res) {
-		ast_log(LOG_WARNING, "Unable to play message %s\n", fn);
-		return res;
-	}
-	res = (a->audiofd  > -1 && a->ctrlfd > -1) ?
-	ast_waitstream_full(a->chan, a->ints, a->audiofd, a->ctrlfd) :
-	ast_waitstream(a->chan, a->ints);
-	ast_stopstream(a->chan);
-	return res;
-}
-
-/*! \brief
- * the string is 'prefix:data' or prefix:fmt:data'
- * with ':' being invalid in strings.
- */
-static int do_say(say_args_t *a, const char *s, const char *options, int depth)
-{
-	struct ast_variable *v;
-	char *lang;
-	char *x;
-	char *rule = NULL;
-	char *rule_head = NULL;
-	int ret = 0;
-	struct varshead head = { .first = NULL, .last = NULL };
-	struct ast_var_t *n;
-
-	ast_debug(2, "string <%s> depth <%d>\n", s, depth);
-	if (depth++ > 10) {
-		ast_log(LOG_WARNING, "recursion too deep, exiting\n");
-		return -1;
-	} else if (!say_cfg) {
-		ast_log(LOG_WARNING, "no say.conf, cannot spell '%s'\n", s);
-		return -1;
-	}
-
-	/* scan languages same as in file.c */
-	if (a->language == NULL)
-		a->language = "en";     /* default */
-	ast_debug(2, "try <%s> in <%s>\n", s, a->language);
-	lang = ast_strdupa(a->language);
-	for (;;) {
-		for (v = ast_variable_browse(say_cfg, lang); v ; v = v->next) {
-			if (ast_extension_match(v->name, s)) {
-				rule_head = rule = ast_strdup(v->value);
-				break;
-			}
-		}
-		if (rule)
-			break;
-		if ( (x = strchr(lang, '_')) )
-			*x = '\0';      /* try without suffix */
-		else if (strcmp(lang, "en"))
-			lang = "en";    /* last resort, try 'en' if not done yet */
-		else
-			break;
-	}
-	if (!rule)
-		return 0;
-
-	/* skip up to two prefixes to get the value */
-	if ( (x = strchr(s, ':')) )
-		s = x + 1;
-	if ( (x = strchr(s, ':')) )
-		s = x + 1;
-	ast_debug(2, "value is <%s>\n", s);
-	n = ast_var_assign("SAY", s);
-	if (!n) {
-		ast_log(LOG_ERROR, "Memory allocation error in do_say\n");
-		ast_free(rule_head);
-		return -1;
-	}
-	AST_LIST_INSERT_HEAD(&head, n, entries);
-
-	/* scan the body, one piece at a time */
-	while ( !ret && (x = strsep(&rule, ",")) ) { /* exit on key */
-		char fn[128];
-		const char *p, *fmt, *data; /* format and data pointers */
-
-		/* prepare a decent file name */
-		x = ast_skip_blanks(x);
-		ast_trim_blanks(x);
-
-		/* replace variables */
-		pbx_substitute_variables_varshead(&head, x, fn, sizeof(fn));
-		ast_debug(2, "doing [%s]\n", fn);
-
-		/* locate prefix and data, if any */
-		fmt = strchr(fn, ':');
-		if (!fmt || fmt == fn)	{	/* regular filename */
-			ret = s_streamwait3(a, fn);
-			continue;
-		}
-		fmt++;
-		data = strchr(fmt, ':');	/* colon before data */
-		if (!data || data == fmt) {	/* simple prefix-fmt */
-			ret = do_say(a, fn, options, depth);
-			continue;
-		}
-		/* prefix:fmt:data */
-		for (p = fmt; p < data && ret <= 0; p++) {
-			char fn2[sizeof(fn)];
-			if (*p == ' ' || *p == '\t')	/* skip blanks */
-				continue;
-			if (*p == '\'') {/* file name - we trim them */
-				char *y;
-				strcpy(fn2, ast_skip_blanks(p+1));	/* make a full copy */
-				y = strchr(fn2, '\'');
-				if (!y) {
-					p = data;	/* invalid. prepare to end */
-					break;
-				}
-				*y = '\0';
-				ast_trim_blanks(fn2);
-				p = strchr(p+1, '\'');
-				ret = s_streamwait3(a, fn2);
-			} else {
-				int l = fmt-fn;
-				strcpy(fn2, fn); /* copy everything */
-				/* after prefix, append the format */
-				fn2[l++] = *p;
-				strcpy(fn2 + l, data);
-				ret = do_say(a, fn2, options, depth);
-			}
-
-			if (ret) {
-				break;
-			}
-		}
-	}
-	ast_var_delete(n);
-	ast_free(rule_head);
-	return ret;
-}
-
-static int say_full(struct ast_channel *chan, const char *string,
-	const char *ints, const char *lang, const char *options,
-	int audiofd, int ctrlfd)
-{
-	say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
-	return do_say(&a, string, options, 0);
-}
-
-static int say_number_full(struct ast_channel *chan, int num,
-	const char *ints, const char *lang, const char *options,
-	int audiofd, int ctrlfd)
-{
-	char buf[64];
-	say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
-	snprintf(buf, sizeof(buf), "num:%d", num);
-	return do_say(&a, buf, options, 0);
-}
-
-static int say_enumeration_full(struct ast_channel *chan, int num,
-	const char *ints, const char *lang, const char *options,
-	int audiofd, int ctrlfd)
-{
-	char buf[64];
-	say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
-	snprintf(buf, sizeof(buf), "enum:%d", num);
-	return do_say(&a, buf, options, 0);
-}
-
-static int say_date_generic(struct ast_channel *chan, time_t t,
-	const char *ints, const char *lang, const char *format, const char *timezonename, const char *prefix)
-{
-	char buf[128];
-	struct ast_tm tm;
-	struct timeval when = { t, 0 };
-	say_args_t a = { chan, ints, lang, -1, -1 };
-	if (format == NULL)
-		format = "";
-
-	ast_localtime(&when, &tm, timezonename);
-	snprintf(buf, sizeof(buf), "%s:%s:%04d%02d%02d%02d%02d.%02d-%d-%3d",
-		prefix,
-		format,
-		tm.tm_year+1900,
-		tm.tm_mon+1,
-		tm.tm_mday,
-		tm.tm_hour,
-		tm.tm_min,
-		tm.tm_sec,
-		tm.tm_wday,
-		tm.tm_yday);
-	return do_say(&a, buf, NULL, 0);
-}
-
-static int say_date_with_format(struct ast_channel *chan, time_t t,
-	const char *ints, const char *lang, const char *format, const char *timezonename)
-{
-	return say_date_generic(chan, t, ints, lang, format, timezonename, "datetime");
-}
-
-static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
-	return say_date_generic(chan, t, ints, lang, "", NULL, "date");
-}
-
-static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
-	return say_date_generic(chan, t, ints, lang, "", NULL, "time");
-}
-
-static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
-{
-	return say_date_generic(chan, t, ints, lang, "", NULL, "datetime");
-}
-
-/*! \brief
- * remap the 'say' functions to use those in this file
- */
-static int say_init_mode(const char *mode) {
-	if (!strcmp(mode, say_new)) {
-		if (say_cfg == NULL) {
-			ast_log(LOG_ERROR, "There is no say.conf file to use new mode\n");
-			return -1;
-		}
-		save_say_mode(say_new);
-		ast_say_number_full = say_number_full;
-
-		ast_say_enumeration_full = say_enumeration_full;
-#if 0
-		/*! \todo XXX
-		   These functions doesn't exist.
-		   say.conf.sample indicates this is working...
-		*/
-		ast_say_digits_full = say_digits_full;
-		ast_say_digit_str_full = say_digit_str_full;
-		ast_say_character_str_full = say_character_str_full;
-		ast_say_phonetic_str_full = say_phonetic_str_full;
-		ast_say_datetime_from_now = say_datetime_from_now;
-#endif
-		ast_say_datetime = say_datetime;
-		ast_say_time = say_time;
-		ast_say_date = say_date;
-		ast_say_date_with_format = say_date_with_format;
-	} else if (!strcmp(mode, say_old) && say_api_buf[0] == say_new) {
-		restore_say_mode(NULL);
-	} else if (strcmp(mode, say_old)) {
-		ast_log(LOG_WARNING, "unrecognized mode %s\n", mode);
-		return -1;
-	}
-
-	return 0;
-}
-
-static char *__say_cli_init(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-	const char *old_mode = say_api_buf[0] ? say_new : say_old;
-	const char *mode;
-	switch (cmd) {
-	case CLI_INIT:
-		e->command = "say load [new|old]";
-		e->usage =
-			"Usage: say load [new|old]\n"
-			"       say load\n"
-			"           Report status of current say mode\n"
-			"       say load new\n"
-			"           Set say method, configured in say.conf\n"
-			"       say load old\n"
-			"           Set old say method, coded in asterisk core\n";
-		return NULL;
-	case CLI_GENERATE:
-		return NULL;
-	}
-	if (a->argc == 2) {
-		ast_cli(a->fd, "say mode is [%s]\n", old_mode);
-		return CLI_SUCCESS;
-	} else if (a->argc != e->args)
-		return CLI_SHOWUSAGE;
-	mode = a->argv[2];
-	if (!strcmp(mode, old_mode))
-		ast_cli(a->fd, "say mode is %s already\n", mode);
-	else
-		if (say_init_mode(mode) == 0)
-			ast_cli(a->fd, "setting say mode from %s to %s\n", old_mode, mode);
-
-	return CLI_SUCCESS;
-}
-
-static struct ast_cli_entry cli_playback[] = {
-	AST_CLI_DEFINE(__say_cli_init, "Set or show the say mode"),
-};
-
 static int playback_exec(struct ast_channel *chan, const char *data)
 {
 	int res = 0;
 	int mres = 0;
 	char *tmp;
 	int option_skip=0;
-	int option_say=0;
 	int option_noanswer = 0;
 
 	AST_DECLARE_APP_ARGS(args,
@@ -464,8 +112,6 @@
 	if (args.options) {
 		if (strcasestr(args.options, "skip"))
 			option_skip = 1;
-		if (strcasestr(args.options, "say"))
-			option_say = 1;
 		if (strcasestr(args.options, "noanswer"))
 			option_noanswer = 1;
 	}
@@ -484,10 +130,7 @@
 
 		ast_stopstream(chan);
 		while (!res && (front = strsep(&back, "&"))) {
-			if (option_say)
-				res = say_full(chan, front, "", ast_channel_language(chan), NULL, -1, -1);
-			else
-				res = ast_streamfile(chan, front, ast_channel_language(chan));
+			res = ast_streamfile(chan, front, ast_channel_language(chan));
 			if (!res) {
 				res = ast_waitstream(chan, "");
 				ast_stopstream(chan);
@@ -506,71 +149,13 @@
 	return res;
 }
 
-static int reload(void)
-{
-	struct ast_variable *v;
-	struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED };
-	struct ast_config *newcfg;
-
-	if ((newcfg = ast_config_load("say.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
-		return 0;
-	} else if (newcfg == CONFIG_STATUS_FILEINVALID) {
-		ast_log(LOG_ERROR, "Config file say.conf is in an invalid format.  Aborting.\n");
-		return 0;
-	}
-
-	if (say_cfg) {
-		ast_config_destroy(say_cfg);
-		ast_log(LOG_NOTICE, "Reloading say.conf\n");
-	}
-	say_cfg = newcfg;
-
-	if (say_cfg) {
-		for (v = ast_variable_browse(say_cfg, "general"); v ; v = v->next) {
-    			if (ast_extension_match(v->name, "mode")) {
-				say_init_mode(v->value);
-				break;
-			}
-		}
-	}
-
-	/*! \todo
-	 * XXX here we should sort rules according to the same order
-	 * we have in pbx.c so we have the same matching behaviour.
-	 */
-	return 0;
-}
-
 static int unload_module(void)
 {
-	int res;
-
-	res = ast_unregister_application(app);
-
-	ast_cli_unregister_multiple(cli_playback, ARRAY_LEN(cli_playback));
-
-	if (say_cfg)
-		ast_config_destroy(say_cfg);
-
-	return res;
+	return ast_unregister_application(app);
 }
 
 static int load_module(void)
 {
-	struct ast_variable *v;
-	struct ast_flags config_flags = { 0 };
-
-	say_cfg = ast_config_load("say.conf", config_flags);
-	if (say_cfg && say_cfg != CONFIG_STATUS_FILEINVALID) {
-		for (v = ast_variable_browse(say_cfg, "general"); v ; v = v->next) {
-    			if (ast_extension_match(v->name, "mode")) {
-				say_init_mode(v->value);
-				break;
-			}
-		}
-	}
-
-	ast_cli_register_multiple(cli_playback, ARRAY_LEN(cli_playback));
 	return ast_register_application_xml(app, playback_exec);
 }
 
@@ -578,5 +163,4 @@
 	.support_level = AST_MODULE_SUPPORT_CORE,
 	.load = load_module,
 	.unload = unload_module,
-	.reload = reload,
 );
diff --git a/configs/samples/say.conf.sample b/configs/samples/say.conf.sample
deleted file mode 100644
index de35ee4..0000000
--- a/configs/samples/say.conf.sample
+++ /dev/null
@@ -1,383 +0,0 @@
-;
-; language configuration
-;
-
-[general]
-mode=old	; method for playing numbers and dates
-		; old - using asterisk core function
-		; new - using this configuration file
-
-; The new language routines produce strings of the form
-;	prefix:[format:]data
-; that are matched against the rules in this file to produce
-; an output.
-;
-; The data is generally the string to be spelled (either a number,
-; an ascii string or a date/time in the format specified below).
-; It is available, in the right hand side of a rule, as variable ${SAY}.
-;
-; The format is optional and normally used only for date/time.
-; The prefix is used to select the pronunciation - standard
-; prefixes are
-;	num		used for numbers
-;	enum		used for enumerations
-;	date 		for dates
-;	time 		for times
-;	datetime	for dates and times
-;	char		for character strings
-;	phonetic	for phonetic strings
-;	digit		for digit strings
-;
-; but others can be used at will.
-;
-; Processing occurs as follows:
-; If the format is empty, or there is no format, the entire
-; string is matched against one of the pattern on the left hand side.
-; On the first match, the various comma-separated components on the right
-; hand side are pronounced, as follows:
-; + a component starting with a prefix: (i.e. with a ':' in it)
-;   is re-processed according to these rules;
-; + a component without a ':' in it is considered a filename and
-;   the corresponding file is played.
-;
-; If the format is non-empty, the format is split into its components
-; (individual characters, or filenames in single quotes), and then
-; filenames are played, whereas single characters are used to
-; generate a new string format:pat:data to be processed.
-;
-; DATES/AND TIMES assume that the date info is available in
-; the form	 YYYYMMDDHHmm.ss-dow-doy
-; with 4 digits for the year, 2 for month, day, hour, minutes, seconds,
-; one digit for the day-of-week, and 3 digits for the day-of-year.
-;
-; Example:
-;     datetime::200604172030.00-4-102
-; (typical format for a date) is first matched against the line
-;	datetime::. => date:AdBY 'digits/at' IMp:${SAY}
-; which is normally present with the default format for dates.
-; In turn, the format string "AdBY 'digits/at' IMp" results in
-; the sequence
-;	date:A:200604172030.00-4-102
-;	date:d:200604172030.00-4-102
-;	date:B:200604172030.00-4-102
-;	date:Y:200604172030.00-4-102
-;	digits/at
-;	date:I:200604172030.00-4-102
-;	date:M:200604172030.00-4-102
-;	date:p:200604172030.00-4-102
-;
-;
-; Remember, normally X Z N are special, and the search is
-; case insensitive, so you must use [X] [N] [Z] .. if you
-; want exact match.
-
-; We start with the basic rules that might be more-or-less
-; language-independent
-
-[digit-base](!)		; base rule for digit strings
-			; XXX incomplete yet
-    _digit:[0-9] => digits/${SAY}
-    _digit:[-] => letters/dash
-    _digit:[*] => letters/star
-    _digit:[@] => letters/at
-    _digit:[0-9]. => digit:${SAY:0:1}, digit:${SAY:1}
-
-[date-base](!)		; base rules for dates and times
-    ; the 'SAY' variable contains YYYYMMDDHHmm.ss-dow-doy
-    ; these rule map the strftime attributes.
-    _date:Y:. => num:${SAY:0:4}	; year, 19xx
-    _date:[Bbh]:. => digits/mon-$[${SAY:4:2}-1]			; month name, 0..11
-    _date:[Aa]:. => digits/day-${SAY:16:1}	; day of week
-    _date:[de]:. => num:${SAY:6:2}		; day of month
-    _date:[H]:. => digits/oh, num:${SAY:8:2}			; hour (oh one, oh two, ..., oh nine, ten, eleven, ..., twenty-three)
-    _date:[I]:. => num:$[${SAY:8:2} % 12]	; hour 0-12
-    _date:[M]:. => num:${SAY:10:2}		; minute
-    ; XXX too bad the '?' function does not remove the quotes
-    ; _date:[pP]:. => digits/$[ ${SAY:10:2} > 12 ? "p-m" :: "a-m"]	; am pm
-    _date:[pP]:. => digits/p-m	; am pm
-    _date:[S]:. => num:${SAY:13:2}		; seconds
-    _date:[Ii]:. => num:$[${SAY:8:2} % 12]			; hour 0-12
-    _date:[k]:. => num:${SAY:8:2}				; hour (one, two. three, ...,twenty three
-    _date:[m]:. => num:${SAY:4:2}				; month number
-    _date:[Q]:. => date:dby ;incompleat				; "today", "yesterday" or ABdY
-    _date:[q]:. => date:dby ;incompleat				; "" (for today), "yesterday", weekday, or ABdY
-    _date:[R]:. => date:HM${SAY}				; 24 hour time, including minute
-    _date:[T]:. => date:HMS${SAY}				; 24 hour, minure, seconds
-
-[en-base](!)
-    _[n]um:0. => num:${SAY:1}
-    _[n]um:X => digits/${SAY}
-    _[n]um:1X => digits/${SAY}
-    _[n]um:[2-9]0 =>  digits/${SAY}
-    _[n]um:[2-9][1-9] =>  digits/${SAY:0:1}0, num:${SAY:1}
-    _[n]um:X00 => num:${SAY:0:1}, digits/hundred
-    _[n]um:XXX => num:${SAY:0:1}, digits/hundred, num:${SAY:1}
-
-    _[n]um:X000 => num:${SAY:0:1}, digits/thousand
-    _[n]um:XXXX => num:${SAY:0:1}, digits/thousand, num:${SAY:1}
-    _[n]um:XX000 => num:${SAY:0:2}, digits/thousand
-    _[n]um:XXXXX => num:${SAY:0:2}, digits/thousand, num:${SAY:2}
-    _[n]um:XXX000 => num:${SAY:0:3}, digits/thousand
-    _[n]um:XXXXXX => num:${SAY:0:3}, digits/thousand, num:${SAY:3}
-
-    _[n]um:X000000 => num:${SAY:0:1}, digits/million
-    _[n]um:XXXXXXX => num:${SAY:0:1}, digits/million, num:${SAY:1}
-    _[n]um:XX000000 => num:${SAY:0:2}, digits/million
-    _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/million, num:${SAY:2}
-    _[n]um:XXX000000 => num:${SAY:0:3}, digits/million
-    _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/million, num:${SAY:3}
-
-    _[n]um:X000000000 => num:${SAY:0:1}, digits/billion
-    _[n]um:XXXXXXXXXX => num:${SAY:0:1}, digits/billion, num:${SAY:1}
-    _[n]um:XX000000000 => num:${SAY:0:2}, digits/billion
-    _[n]um:XXXXXXXXXXX => num:${SAY:0:2}, digits/billion, num:${SAY:2}
-    _[n]um:XXX000000000 => num:${SAY:0:3}, digits/billion
-    _[n]um:XXXXXXXXXXXX => num:${SAY:0:3}, digits/billion, num:${SAY:3}
-
-    ; enumeration
-    _e[n]um:X => digits/h-${SAY}
-    _e[n]um:1X => digits/h-${SAY}
-    _e[n]um:[2-9]0 => digits/h-${SAY}
-    _e[n]um:[2-9][1-9] => num:${SAY:0:1}0, digits/h-${SAY:1}
-    _e[n]um:[1-9]00 => num:${SAY:0:1}, digits/h-hundred
-    _e[n]um:[1-9]XX => num:${SAY:0:1}, digits/h-hundred, enum:${SAY:1}
-
-[en_GB](date-base,digit-base,en-base)
-    _[n]um:XXX => num:${SAY:0:1}, digits/hundred, vm-and, num:${SAY:1}
-
-[it](digit-base,date-base)
-    _[n]um:0. => num:${SAY:1}
-    _[n]um:X => digits/${SAY}
-    _[n]um:1X => digits/${SAY}
-    _[n]um:[2-9]0 =>  digits/${SAY}
-    _[n]um:[2-9][1-9] =>  digits/${SAY:0:1}0, num:${SAY:1}
-    _[n]um:100 => digits/hundred
-    _[n]um:1XX => digits/hundred, num:${SAY:1}
-    _[n]um:[2-9]00 => num:${SAY:0:1}, digits/hundred
-    _[n]um:[2-9]XX => num:${SAY:0:1}, digits/hundred, num:${SAY:1}
-
-    _[n]um:1000 => digits/thousand
-    _[n]um:1XXX => digits/thousand, num:${SAY:1}
-    _[n]um:[2-9]000 => num:${SAY:0:1}, digits/thousands
-    _[n]um:[2-9]XXX => num:${SAY:0:1}, digits/thousands, num:${SAY:1}
-    _[n]um:XX000 => num:${SAY:0:2}, digits/thousands
-    _[n]um:XXXXX => num:${SAY:0:2}, digits/thousands, num:${SAY:2}
-    _[n]um:XXX000 => num:${SAY:0:3}, digits/thousands
-    _[n]um:XXXXXX => num:${SAY:0:3}, digits/thousands, num:${SAY:3}
-
-    _[n]um:1000000 => num:${SAY:0:1}, digits/million
-    _[n]um:1XXXXXX => num:${SAY:0:1}, digits/million, num:${SAY:1}
-    _[n]um:[2-9]000000 => num:${SAY:0:1}, digits/millions
-    _[n]um:[2-9]XXXXXX => num:${SAY:0:1}, digits/millions, num:${SAY:1}
-    _[n]um:XX000000 => num:${SAY:0:2}, digits/millions
-    _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/millions, num:${SAY:2}
-    _[n]um:XXX000000 => num:${SAY:0:3}, digits/millions
-    _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/millions, num:${SAY:3}
-
-    _[n]um:X000000000 => num:${SAY:0:1}, digits/billion
-    _[n]um:XXXXXXXXXX => num:${SAY:0:1}, digits/billion, num:${SAY:1}
-    _[n]um:XX000000000 => num:${SAY:0:2}, digits/billion
-    _[n]um:XXXXXXXXXXX => num:${SAY:0:2}, digits/billion, num:${SAY:2}
-    _[n]um:XXX000000000 => num:${SAY:0:3}, digits/billion
-    _[n]um:XXXXXXXXXXXX => num:${SAY:0:3}, digits/billion, num:${SAY:3}
-
-    _datetime::. => date:AdBY 'digits/at' IMp:${SAY}
-    _date::. => date:AdBY:${SAY}
-    _time::. => date:IMp:${SAY}
-
-[en](en-base,date-base,digit-base)
-    _datetime::. => date:AdBY 'digits/at' IMp:${SAY}
-    _date::. => date:AdBY:${SAY}
-    _time::. => date:IMp:${SAY}
-
-[de](date-base,digit-base)
-    _[n]um:0. => num:${SAY:1}
-    _[n]um:X => digits/${SAY}
-    _[n]um:1X => digits/${SAY}
-    _[n]um:[2-9]0 => digits/${SAY}
-    _[n]um:[2-9][1-9] => digits/${SAY:1}-and, digits/${SAY:0:1}0
-    _[n]um:100 => digits/ein, digits/hundred
-    _[n]um:1XX => digits/ein, digits/hundred, num:${SAY:1}
-    _[n]um:[2-9]00 => digits/${SAY:0:1}, digits/hundred
-    _[n]um:[2-9]XX => digits/${SAY:0:1}, digits/hundred, num:${SAY:1}
-
-    _[n]um:1000 => digits/ein, digits/thousand
-    _[n]um:1XXX => digits/ein, digits/thousand, num:${SAY:1}
-    _[n]um:[2-9]000 => digits/${SAY:0:1}, digits/thousand
-    _[n]um:[2-9]XXX => digits/${SAY:0:1}, digits/thousand, num:${SAY:1}
-    _[n]um:XX000 => num:${SAY:0:2}, digits/thousand
-    _[n]um:XXXXX => num:${SAY:0:2}, digits/thousand, num:${SAY:2}
-    _[n]um:XXX000 => num:${SAY:0:3}, digits/thousand
-    _[n]um:XXXXXX => num:${SAY:0:3}, digits/thousand, num:${SAY:1}
-
-    _[n]um:1000000 => digits/eine, digits/million
-    _[n]um:1XXXXXX => digits/eine, digits/million, num:${SAY:1}
-    _[n]um:[2-9]000000 => digits/${SAY:0:1}, digits/millions
-    _[n]um:[2-9]XXXXXX => digits/${SAY:0:1}, digits/millions, num:${SAY:1}
-    _[n]um:XX000000 => num:${SAY:0:2}, digits/millions
-    _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/millions, num:${SAY:2}
-    _[n]um:XXX000000 => num:${SAY:0:3}, digits/millions
-    _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/millions, num:${SAY:3}
-
-    _datetime::. => date:AdBY 'digits/at' IMp:${SAY}
-    _date::. => date:AdBY:${SAY}
-    _time::. => date:IMp:${SAY}
-
-[hu](digit-base,date-base)
-    _[n]um:0. => num:${SAY:1}
-    _[n]um:X => digits/${SAY}
-    _[n]um:1[1-9] => digits/10en, digits/${SAY:1}
-    _[n]um:2[1-9] => digits/20on, digits/${SAY:1}
-    _[n]um:[1-9]0 =>  digits/${SAY}
-    _[n]um:[3-9][1-9] =>  digits/${SAY:0:1}0, num:${SAY:1}
-    _[n]um:XXX => num:${SAY:0:1}, digits/hundred, num:${SAY:1}
-
-    _[n]um:X000 => num:${SAY:0:1}, digits/thousand
-    _[n]um:XXXX => num:${SAY:0:1}, digits/thousand, num:${SAY:1}
-    _[n]um:XX000 => num:${SAY:0:2}, digits/thousand
-    _[n]um:XXXXX => num:${SAY:0:2}, digits/thousand, num:${SAY:2}
-    _[n]um:XXX000 => num:${SAY:0:3}, digits/thousand
-    _[n]um:XXXXXX => num:${SAY:0:3}, digits/thousand, num:${SAY:3}
-
-    _[n]um:X000000 => num:${SAY:0:1}, digits/million
-    _[n]um:XXXXXXX => num:${SAY:0:1}, digits/million, num:${SAY:1}
-    _[n]um:XX000000 => num:${SAY:0:2}, digits/million
-    _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/million, num:${SAY:2}
-    _[n]um:XXX000000 => num:${SAY:0:3}, digits/million
-    _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/million, num:${SAY:3}
-
-    _[n]um:X000000000 => num:${SAY:0:1}, digits/billion
-    _[n]um:XXXXXXXXXX => num:${SAY:0:1}, digits/billion, num:${SAY:1}
-    _[n]um:XX000000000 => num:${SAY:0:2}, digits/billion
-    _[n]um:XXXXXXXXXXX => num:${SAY:0:2}, digits/billion, num:${SAY:2}
-    _[n]um:XXX000000000 => num:${SAY:0:3}, digits/billion
-    _[n]um:XXXXXXXXXXXX => num:${SAY:0:3}, digits/billion, num:${SAY:3}
-
-    _datetime::. => date:YBdA k 'ora' M 'perc':${SAY}
-    _date::. => date:YBdA:${SAY}
-    _time::. => date:k 'ora' M 'perc':${SAY}
-
-[fr](date-base,digit-base)
-    _[n]um:0. => num:${SAY:1}
-    _[n]um:X => digits/${SAY}
-    _[n]um:1X => digits/${SAY}
-    _[n]um:[2-9]0 =>  digits/${SAY}
-    _[n]um:[2-6]1 => digits/${SAY:0:1}0, vm-and, digits/${SAY:1}
-    _[n]um:71 => digits/60, vm-and, num:1${SAY:1}
-    _[n]um:7X => digits/60, num:1${SAY:1}
-    _[n]um:9X => digits/80, num:1${SAY:1}
-    _[n]um:[2-9][1-9] =>  digits/${SAY:0:1}0, num:${SAY:1}
-    _[n]um:100 => digits/hundred
-    _[n]um:1XX => digits/hundred, num:${SAY:1}
-    _[n]um:[2-9]00 => num:${SAY:0:1}, digits/hundred
-    _[n]um:[2-9]XX => num:${SAY:0:1}, digits/hundred, num:${SAY:1}
-
-    _[n]um:1000 => digits/thousand
-    _[n]um:1XXX => digits/thousand, num:${SAY:1}
-    _[n]um:[2-9]000 => num:${SAY:0:1}, digits/thousand
-    _[n]um:[2-9]XXX => num:${SAY:0:1}, digits/thousand, num:${SAY:1}
-    _[n]um:XX000 => num:${SAY:0:2}, digits/thousand
-    _[n]um:XXXXX => num:${SAY:0:2}, digits/thousand, num:${SAY:2}
-    _[n]um:XXX000 => num:${SAY:0:3}, digits/thousand
-    _[n]um:XXXXXX => num:${SAY:0:3}, digits/thousand, num:${SAY:3}
-
-    _[n]um:1000000 => num:${SAY:0:1}, digits/million
-    _[n]um:1XXXXXX => num:${SAY:0:1}, digits/million, num:${SAY:1}
-    _[n]um:[2-9]000000 => num:${SAY:0:1}, digits/million
-    _[n]um:[2-9]XXXXXX => num:${SAY:0:1}, digits/million, num:${SAY:1}
-    _[n]um:XX000000 => num:${SAY:0:2}, digits/million
-    _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/million, num:${SAY:2}
-    _[n]um:XXX000000 => num:${SAY:0:3}, digits/million
-    _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/million, num:${SAY:3}
-
-    _datetime::. => date:AdBY 'digits/at' H 'hours' M 'perc':${SAY}
-    _date::. => date:AdBY:${SAY}
-    _time::. => date:H 'hours' M 'perc':${SAY}
-
-    _pho[n]e:XXXX => num:${SAY:0:2}, num:${SAY:2:2}
-    _pho[n]e:0[1-9]XXXXXXXX => num:${SAY:0:1}, num:${SAY:1:1}, num:${SAY:2:2}, num:${SAY:4:2}, num:${SAY:6:2}, num:${SAY:8:2}
-    _pho[n]e:. => digit:${SAY}
-
-[es](date-base,digit-base)
-    _[n]um:0. => num:${SAY:1}
-    _[n]um:X => digits/${SAY}
-    _[n]um:1X => digits/${SAY}
-    _[n]um:[2-9]0 => digits/${SAY}
-    _[n]um:2[1-9] => digits/20-and, digits/${SAY:1}
-    _[n]um:[3-9][1-9] =>  digits/${SAY:0:1}0, vm-and, digits/${SAY:1}
-    _[n]um:100 => digits/hundred
-    _[n]um:1XX => digits/100-and, num:${SAY:1}
-    _[n]um:[2-9]00 => digits/${SAY}
-    _[n]um:[2-9]XX => digits/${SAY:0:1}00, num:${SAY:1}
-
-    _[n]um:1000 => digits/thousand
-    _[n]um:1XXX => digits/thousand, num:${SAY:1}
-    _[n]um:[2-9]000 => num:${SAY:0:1}, digits/thousand
-    _[n]um:[2-9]XXX => num:${SAY:0:1}, digits/thousand, num:${SAY:1}
-    _[n]um:XX000 => num:${SAY:0:2}, digits/thousand
-    _[n]um:XXXXX => num:${SAY:0:2}, digits/thousand, num:${SAY:2}
-    _[n]um:XXX000 => num:${SAY:0:3}, digits/thousand
-    _[n]um:XXXXXX => num:${SAY:0:3}, digits/thousand, num:${SAY:3}
-
-    _[n]um:1000000 => digits/1M, digits/million
-    _[n]um:1XXXXXX => digits/1M, digits/million, num:${SAY:1}
-    _[n]um:[2-9]000000 => num:${SAY:0:1}, digits/millions
-    _[n]um:[2-9]XXXXXX => num:${SAY:0:1}, digits/millions, num:${SAY:1}
-    _[n]um:XX000000 => num:${SAY:0:2}, digits/millions
-    _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/millions, num:${SAY:2}
-    _[n]um:XXX000000 => num:${SAY:0:3}, digits/millions
-    _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/millions, num:${SAY:3}
-    _[n]um:XXXX000000 => num:${SAY:0:4}, digits/millions
-    _[n]um:XXXXXXXXXX => num:${SAY:0:4}, digits/millions, num:${SAY:4}
-
-    _datetime::. => date:Ad 'letters/d' B 'letters/d' Y 'digits/at' HMp:${SAY}
-    _date::. => date:Ad 'letters/d' B 'letters/d' Y:${SAY}
-    _time::. => date:HMp:${SAY}
-
-[da](date-base,digit-base)
-    _[n]um:0. => num:${SAY:1}
-    _[n]um:X => digits/${SAY}
-    _[n]um:1X => digits/${SAY}
-    _[n]um:[2-9]0 => digits/${SAY}
-    _[n]um:[2-9][1-9] => digits/${SAY:1}-and, digits/${SAY:0:1}0
-    _[n]um:100 => digits/1N, digits/hundred
-    _[n]um:1XX => digits/1N, digits/hundred, num:${SAY:1}
-    _[n]um:[2-9]00 => digits/${SAY:0:1}, digits/hundred
-    _[n]um:[2-9]XX => digits/${SAY:0:1}, digits/hundred, num:${SAY:1}
-
-    _[n]um:1000 => digits/1N, digits/thousand
-    _[n]um:1XXX => digits/1N, digits/thousand, num:${SAY:1}
-    _[n]um:[2-9]000 => digits/${SAY:0:1}, digits/thousand
-    _[n]um:[2-9]XXX => digits/${SAY:0:1}, digits/thousand, num:${SAY:1}
-    _[n]um:XX000 => num:${SAY:0:2}, digits/thousand
-    _[n]um:XXXXX => num:${SAY:0:2}, digits/thousand, num:${SAY:2}
-    _[n]um:XXX000 => num:${SAY:0:3}, digits/thousand
-    _[n]um:XXXXXX => num:${SAY:0:3}, digits/thousand, num:${SAY:3}
-
-    _[n]um:X000000 => digits/${SAY:0:1}, digits/million
-    _[n]um:XXXXXXX => digits/${SAY:0:1}, digits/million, num:${SAY:1}
-    _[n]um:XX000000 => num:${SAY:0:2}, digits/millions
-    _[n]um:XXXXXXXX => num:${SAY:0:2}, digits/millions, num:${SAY:2}
-    _[n]um:XXX000000 => num:${SAY:0:3}, digits/millions
-    _[n]um:XXXXXXXXX => num:${SAY:0:3}, digits/millions, num:${SAY:3}
-
-    _[n]um:X000000000 => num:${SAY:0:1}, digits/billion
-    _[n]um:XXXXXXXXXX => num:${SAY:0:1}, digits/billion, num:${SAY:1}
-    _[n]um:XX000000000 => num:${SAY:0:2}, digits/billion
-    _[n]um:XXXXXXXXXXX => num:${SAY:0:2}, digits/billion, num:${SAY:2}
-    _[n]um:XXX000000000 => num:${SAY:0:3}, digits/billion
-    _[n]um:XXXXXXXXXXXX => num:${SAY:0:3}, digits/billion, num:${SAY:3}
-
-    _datetime::. => date:AdBY 'digits/at' kM:${SAY}
-    _date::. => date:AdBY:${SAY}
-    _time::. => date:HM:${SAY}
-
-    ; enumeration
-    _e[n]um:X => digits/h-${SAY}
-    _e[n]um:1X => digits/h-${SAY}
-    _e[n]um:[2-9]0 => digits/h-${SAY}
-    _e[n]um:[2-9][1-9] => digits/${SAY:1}-and, digits/h-${SAY:0:1}0
-    _e[n]um:100 => digits/1N, digits/h-hundred
-    _e[n]um:1XX => digits/1N, digits/h-hundred, enum:${SAY:1}
-    _e[n]um:[2-9]00 => num:${SAY:0:1}, digits/h-hundred
-    _e[n]um:[2-9]XX => num:${SAY:0:1}, digits/h-hundred, enum:${SAY:1}

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/16623
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: I3200aa184d97679e4a134ec1de82389203d2a0de
Gerrit-Change-Number: 16623
Gerrit-PatchSet: 1
Gerrit-Owner: Sean Bright <sean at seanbright.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20211020/6d1e7853/attachment-0001.html>


More information about the asterisk-code-review mailing list