Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions
say.c File Reference

Say numbers and dates (maybe words one day too) More...

#include "asterisk.h"
#include <netinet/in.h>
#include <time.h>
#include <ctype.h>
#include <math.h>
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/say.h"
#include "asterisk/lock.h"
#include "asterisk/localtime.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/test.h"
Include dependency graph for say.c:

Go to the source code of this file.

Data Structures

struct  odmiana
 

Macros

#define IL_DATE_STR   "AdBY"
 
#define IL_DATE_STR_FULL   IL_DATE_STR " 'digits/at' " IL_TIME_STR
 
#define IL_TIME_STR   "HM" /* NOTE: In Hebrew we do not support 12 hours, only 24. No AM or PM exists in the Hebrew language */
 
#define SAY_NUM_BUF_SIZE   256
 

Functions

static void __say_init (void)
 remap the 'say' functions to use those in this file More...
 
struct ast_strast_get_character_str (const char *str, const char *lang, enum ast_say_case_sensitivity sensitivity)
 Returns an ast_str of files for SayAlpha playback. More...
 
struct ast_strast_get_digit_str (const char *str, const char *lang)
 Returns an ast_str of files for SayDigits playback. More...
 
static struct ast_strast_get_money_en_dollars_str (const char *str, const char *lang)
 
struct ast_strast_get_money_str (const char *str, const char *lang)
 ast_get_money_str: call language-specific functions More...
 
struct ast_strast_get_number_str (int num, const char *lang)
 ast_get_number_str: call language-specific functions More...
 
struct ast_strast_get_phonetic_str (const char *str, const char *lang)
 Returns an ast_str of files for SayPhonetic playback. More...
 
int ast_say_counted_adjective (struct ast_channel *chan, int num, const char adjective[], const char gender[])
 
int ast_say_counted_noun (struct ast_channel *chan, int num, const char noun[])
 
static int ast_say_date_da (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Danish syntax. More...
 
static int ast_say_date_de (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 German syntax. More...
 
static int ast_say_date_en (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 English syntax. More...
 
static int ast_say_date_fr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 French syntax. More...
 
static int ast_say_date_gr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Greek support. More...
 
static int ast_say_date_he (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hebrew syntax. More...
 
static int ast_say_date_hu (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hungarian syntax. More...
 
static int ast_say_date_is (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int ast_say_date_ja (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int ast_say_date_ka (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Georgian syntax. e.g. "oriatas xuti tslis 5 noemberi". More...
 
static int ast_say_date_nl (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Dutch syntax. More...
 
static int ast_say_date_pt (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Portuguese syntax. More...
 
static int ast_say_date_th (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Thai syntax. More...
 
static int ast_say_date_with_format_da (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Danish syntax. More...
 
static int ast_say_date_with_format_de (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 German syntax. More...
 
static int ast_say_date_with_format_en (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 English syntax. More...
 
static int ast_say_date_with_format_es (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Spanish syntax. More...
 
static int ast_say_date_with_format_fr (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 French syntax oclock = heure. More...
 
static int ast_say_date_with_format_gr (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Greek support. More...
 
static int ast_say_date_with_format_he (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 ast_say_date_with_format_he Say formatted date in Hebrew More...
 
static int ast_say_date_with_format_is (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 
static int ast_say_date_with_format_it (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Italian syntax. More...
 
static int ast_say_date_with_format_ja (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 
static int ast_say_date_with_format_nl (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Dutch syntax. More...
 
static int ast_say_date_with_format_pl (struct ast_channel *chan, time_t thetime, const char *ints, const char *lang, const char *format, const char *tzone)
 Polish syntax. More...
 
static int ast_say_date_with_format_pt (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Portuguese syntax. More...
 
static int ast_say_date_with_format_th (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Thai syntax. More...
 
static int ast_say_date_with_format_vi (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Vietnamese syntax. More...
 
static int ast_say_date_with_format_zh (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 Taiwanese / Chinese syntax. More...
 
static int ast_say_datetime_de (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 German syntax. More...
 
static int ast_say_datetime_en (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 English syntax. More...
 
static int ast_say_datetime_fr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 French syntax. More...
 
static int ast_say_datetime_from_now_en (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 English syntax. More...
 
static int ast_say_datetime_from_now_fr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 French syntax. More...
 
static int ast_say_datetime_from_now_he (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hebrew syntax. More...
 
static int ast_say_datetime_from_now_ka (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Georgian syntax. More...
 
static int ast_say_datetime_from_now_pt (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Portuguese syntax. More...
 
static int ast_say_datetime_gr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Greek support. More...
 
static int ast_say_datetime_he (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hebrew syntax. More...
 
static int ast_say_datetime_hu (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hungarian syntax. More...
 
static int ast_say_datetime_ja (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int ast_say_datetime_ka (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Georgian syntax. Say date, then say time. More...
 
static int ast_say_datetime_nl (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Dutch syntax. More...
 
static int ast_say_datetime_pt (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Portuguese syntax. More...
 
static int ast_say_datetime_pt_BR (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Brazilian Portuguese syntax. More...
 
static int ast_say_datetime_th (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Thai syntax. More...
 
static int ast_say_datetime_zh (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Taiwanese / Chinese syntax. More...
 
static int ast_say_enumeration_full_da (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_enumeration_full_da: Danish syntax More...
 
static int ast_say_enumeration_full_de (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_enumeration_full_de: German syntax More...
 
static int ast_say_enumeration_full_en (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_enumeration_full_en: English syntax More...
 
static int ast_say_enumeration_full_he (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 
static int ast_say_enumeration_full_is (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_enumeration_full_is: Icelandic syntax More...
 
static int ast_say_enumeration_full_vi (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 
static int ast_say_number_full_cs (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_cs: Czech syntax More...
 
static int ast_say_number_full_da (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_da: Danish syntax New files: More...
 
static int ast_say_number_full_de (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_de: German syntax More...
 
static int ast_say_number_full_en (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_en: English syntax More...
 
static int ast_say_number_full_en_GB (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_en_GB: British syntax New files: More...
 
static int ast_say_number_full_es (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_es: Spanish syntax More...
 
static int ast_say_number_full_fr (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_fr: French syntax Extra sounds needed: 1F: feminin 'une' et: 'and' More...
 
static int ast_say_number_full_gr (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 Greek support A list of the files that you need to create -> digits/xilia = "xilia" -> digits/myrio = "ekatomyrio" -> digits/thousands = "xiliades" -> digits/millions = "ektatomyria" -> digits/[1..12] :: A pronunciation of th digits form 1 to 12 e.g. "tria" -> digits/[10..100] :: A pronunciation of the tens from 10 to 90 e.g. 80 = "ogdonta" Here we must note that we use digits/tens/100 to utter "ekato" and digits/hundred-100 to utter "ekaton" -> digits/hundred-[100...1000] :: A pronunciation of hundreds from 100 to 1000 e.g 400 = "terakosia". Here again we use hundreds/1000 for "xilia" and digits/thousnds for "xiliades". More...
 
static int ast_say_number_full_he (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 
static int ast_say_number_full_hu (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_hu: Hungarian syntax More...
 
static int ast_say_number_full_is (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_is: Icelandic syntax More...
 
static int ast_say_number_full_it (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_it: Italian More...
 
static int ast_say_number_full_ja (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 
static int ast_say_number_full_ka (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_ka: Georgian syntax More...
 
static int ast_say_number_full_nl (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_nl: dutch syntax New files: digits/nl-en More...
 
static int ast_say_number_full_no (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_no: Norwegian syntax New files: In addition to American English, the following sounds are required: "and", "1N" More...
 
static int ast_say_number_full_pl (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 
static int ast_say_number_full_pt (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 
static int ast_say_number_full_ru (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_ru: Russian syntax More...
 
static int ast_say_number_full_se (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full_se: Swedish syntax More...
 
static int ast_say_number_full_th (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 Thai syntax. More...
 
static int ast_say_number_full_ur (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 
static int ast_say_number_full_vi (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_vi: Vietnamese syntax More...
 
static int ast_say_number_full_zh (struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
 ast_say_number_full_zh: Taiwanese / Chinese syntax More...
 
static int ast_say_time_de (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 German syntax. More...
 
static int ast_say_time_en (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 English syntax. More...
 
static int ast_say_time_fr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 French syntax. More...
 
static int ast_say_time_gr (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Greek support. More...
 
static int ast_say_time_he (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hebrew syntax. More...
 
static int ast_say_time_hu (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Hungarian syntax. More...
 
static int ast_say_time_ja (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int ast_say_time_ka (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Georgian syntax. e.g. "otxi saati da eqvsi tsuti". More...
 
static int ast_say_time_nl (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Dutch syntax. More...
 
static int ast_say_time_pt (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Portuguese syntax. More...
 
static int ast_say_time_pt_BR (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Brazilian Portuguese syntax. More...
 
static int ast_say_time_th (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Thai syntax. More...
 
static int ast_say_time_zh (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 Taiwanese / Chinese syntax. More...
 
static char * ast_translate_number_ka (int num, char *res, int res_len)
 Georgian support. More...
 
static const char * counted_adjective_ending_ru (int num, const char gender[])
 In slavic languages such as Russian and Ukrainian the rules for declining adjectives are simpler than those for nouns. When counting we use only the singular (to which we give no suffix) and the genative plural (which we represent by adding an "x"). Oh, an in the singular gender matters so we append the supplied gender suffix ("m", "f", "n"). More...
 
static const char * counted_noun_ending_en (int num)
 In English, we use the plural for everything but one. For example: More...
 
static const char * counted_noun_ending_slavic (int num)
 Counting of objects in slavic languages such as Russian and Ukrainian the rules are more complicated. There are two plural forms used in counting. They are the genative singular which we represent with the suffix "x1" and the genative plural which we represent with the suffix "x2". The base names of the soundfiles remain in English. For example: More...
 
static int exp10_int (int power)
 
static int get_lastdigits_ru (int num)
 determine last digits for thousands/millions (ru) More...
 
static struct ast_strget_number_str_en (int num, const char *lang)
 
static int gr_say_number_female (int num, struct ast_channel *chan, const char *ints, const char *lang)
 Greek digits/female-[1..4] : "Mia, dyo , treis, tessereis". More...
 
static char next_item (const char *format)
 
static char * pl_append (char *buffer, char *str)
 
static void pl_odtworz_plik (struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, char *fn)
 
static char * pl_rzad_na_tekst (odmiana *odm, int i, int rzad)
 
static void powiedz (struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, odmiana *odm, int rzad, int i)
 
static int say_character_str_full (struct ast_channel *chan, const char *str, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd)
 
static int say_date (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int say_date_with_format (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
 
static int say_datetime (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int say_datetime_from_now (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int say_digit_str_full (struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
 
static int say_enumeration_full (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_enumeration_full: call language-specific functions More...
 
static int say_money_str_full (struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
 
static int say_number_full (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 ast_say_number_full: call language-specific functions More...
 
static int say_phonetic_str_full (struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
 
static int say_time (struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 
static int wait_file (struct ast_channel *chan, const char *ints, const char *file, const char *lang)
 

Detailed Description

Say numbers and dates (maybe words one day too)

Author
Mark Spencer marks[email protected][email protected][email protected]digiu[email protected]m.co[email protected]m
Note
12-16-2004 : Support for Greek added by InAccess Networks (work funded by HOL, www.hol.gr) George Konstantoulakis [email protected][email protected]inac[email protected]cessn[email protected]etwo[email protected]rks.c[email protected]om
2007-02-08 : Support for Georgian added by Alexander Shaduri ashad[email protected][email protected][email protected]gmail[email protected].com, Next Generation Networks (NGN).
2007-03-20 : Support for Thai added by Dome C. [email protected][email protected]tel.[email protected]co.th, IP Crossing Co., Ltd.
2021-07-26 : Refactoring to separate string buildup and playback by Naveen Albert aster[email protected][email protected][email protected]phrea[email protected]knet[email protected].org

Definition in file say.c.

Macro Definition Documentation

◆ IL_DATE_STR

#define IL_DATE_STR   "AdBY"

◆ IL_DATE_STR_FULL

#define IL_DATE_STR_FULL   IL_DATE_STR " 'digits/at' " IL_TIME_STR

◆ IL_TIME_STR

#define IL_TIME_STR   "HM" /* NOTE: In Hebrew we do not support 12 hours, only 24. No AM or PM exists in the Hebrew language */

◆ SAY_NUM_BUF_SIZE

#define SAY_NUM_BUF_SIZE   256

Definition at line 1446 of file say.c.

Referenced by ast_say_number_full_he().

Function Documentation

◆ __say_init()

static void __say_init ( void  )
static

remap the 'say' functions to use those in this file

Definition at line 9601 of file say.c.

References ast_say_character_str_full, ast_say_date, ast_say_date_with_format, ast_say_datetime, ast_say_datetime_from_now, ast_say_digit_str_full, ast_say_enumeration_full, ast_say_money_str_full, ast_say_number_full, ast_say_phonetic_str_full, ast_say_time, say_character_str_full(), say_date(), say_date_with_format(), say_datetime(), say_datetime_from_now(), say_digit_str_full(), say_enumeration_full(), say_money_str_full(), say_number_full(), say_phonetic_str_full(), and say_time().

9602 {
9614 }
static int say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd)
Definition: say.c:171
SAY_EXTERN int(* ast_say_number_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_number_full)
Same as ast_say_number() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: say.h:86
static int say_number_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_number_full: call language-specific functions
Definition: say.c:713
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:183
SAY_EXTERN int(* ast_say_enumeration_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_enumeration_full)
Same as ast_say_enumeration() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: say.h:106
SAY_EXTERN int(* ast_say_datetime_from_now)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_datetime_from_now)
Definition: say.h:187
static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:7802
static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:7362
SAY_EXTERN int(* ast_say_money_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_money_str_full)
Definition: say.h:151
SAY_EXTERN int(* ast_say_digit_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_digit_str_full)
Same as ast_say_digit_str() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: say.h:143
static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:3807
static int say_money_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
Definition: say.c:430
static int say_enumeration_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
ast_say_enumeration_full: call language-specific functions
Definition: say.c:3079
SAY_EXTERN int(* ast_say_date)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_date)
Definition: say.h:185
SAY_EXTERN int(* ast_say_date_with_format)(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezone) SAY_INIT(ast_say_date_with_format)
Definition: say.h:189
static int say_date_with_format(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Definition: say.c:4205
SAY_EXTERN int(* ast_say_datetime)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_datetime)
Definition: say.h:182
static int say_digit_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
Definition: say.c:339
static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:7041
static int say_phonetic_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
Definition: say.c:270
SAY_EXTERN int(* ast_say_character_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd) SAY_INIT(ast_say_character_str_full)
Definition: say.h:175
SAY_EXTERN int(* ast_say_phonetic_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_phonetic_str_full)
Definition: say.h:180

◆ ast_get_character_str()

struct ast_str* ast_get_character_str ( const char *  str,
const char *  lang,
enum ast_say_case_sensitivity  sensitivity 
)

Returns an ast_str of files for SayAlpha playback.

Parameters
strText to be translated to the corresponding audio files.
langChannel language
sensitivityCase sensitivity

Computes the list of files to be played by SayAlpha.

Return values
ampersand-separatedstring of Asterisk sound files that can be played back.

Definition at line 63 of file say.c.

References ast_fileexists(), AST_SAY_CASE_ALL, AST_SAY_CASE_LOWER, AST_SAY_CASE_NONE, AST_SAY_CASE_UPPER, ast_str_append(), ast_str_create, ast_str_reset(), and NULL.

Referenced by say_character_str_full(), and sayfile_exec().

63  {
64  const char *fn;
65  char fnbuf[10], asciibuf[20] = "letters/ascii";
66  char ltr;
67  int num = 0;
68  int res = 0;
69  int upper = 0;
70  int lower = 0;
71 
72  struct ast_str *filenames = ast_str_create(20);
73  ast_str_reset(filenames);
74 
75  while (str[num] && !res) {
76  fn = NULL;
77  switch (str[num]) {
78  case ('*'):
79  fn = "digits/star";
80  break;
81  case ('#'):
82  fn = "digits/pound";
83  break;
84  case ('!'):
85  fn = "letters/exclaimation-point";
86  break;
87  case ('@'):
88  fn = "letters/at";
89  break;
90  case ('$'):
91  fn = "letters/dollar";
92  break;
93  case ('-'):
94  fn = "letters/dash";
95  break;
96  case ('.'):
97  fn = "letters/dot";
98  break;
99  case ('='):
100  fn = "letters/equals";
101  break;
102  case ('+'):
103  fn = "letters/plus";
104  break;
105  case ('/'):
106  fn = "letters/slash";
107  break;
108  case (' '):
109  fn = "letters/space";
110  break;
111  case ('0'):
112  case ('1'):
113  case ('2'):
114  case ('3'):
115  case ('4'):
116  case ('5'):
117  case ('6'):
118  case ('7'):
119  case ('8'):
120  case ('9'):
121  strcpy(fnbuf, "digits/X");
122  fnbuf[7] = str[num];
123  fn = fnbuf;
124  break;
125  default:
126  ltr = str[num];
127  if ('A' <= ltr && ltr <= 'Z') {
128  ltr += 'a' - 'A'; /* file names are all lower-case */
129  switch (sensitivity) {
130  case AST_SAY_CASE_UPPER:
131  case AST_SAY_CASE_ALL:
132  upper = !upper;
133  case AST_SAY_CASE_LOWER:
134  case AST_SAY_CASE_NONE:
135  break;
136  }
137  } else if ('a' <= ltr && ltr <= 'z') {
138  switch (sensitivity) {
139  case AST_SAY_CASE_LOWER:
140  case AST_SAY_CASE_ALL:
141  lower = !lower;
142  case AST_SAY_CASE_UPPER:
143  case AST_SAY_CASE_NONE:
144  break;
145  }
146  }
147 
148  if (upper) {
149  strcpy(fnbuf, "uppercase");
150  } else if (lower) {
151  strcpy(fnbuf, "lowercase");
152  } else {
153  strcpy(fnbuf, "letters/X");
154  fnbuf[8] = ltr;
155  }
156  fn = fnbuf;
157  }
158  if ((fn && ast_fileexists(fn, NULL, lang) > 0) ||
159  (snprintf(asciibuf + 13, sizeof(asciibuf) - 13, "%d", str[num]) > 0 && ast_fileexists(asciibuf, NULL, lang) > 0 && (fn = asciibuf))) {
160  ast_str_append(&filenames, 0, (num == 0 ? "%s" : "&%s"), fn);
161  }
162  if (upper || lower) {
163  continue;
164  }
165  num++;
166  }
167 
168  return filenames;
169 }
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ ast_get_digit_str()

struct ast_str* ast_get_digit_str ( const char *  str,
const char *  lang 
)

Returns an ast_str of files for SayDigits playback.

Parameters
strText to be translated to the corresponding audio files.
langChannel language

Computes the list of files to be played by SayDigits.

Return values
ampersand-separatedstring of Asterisk sound files that can be played back.

Definition at line 294 of file say.c.

References ast_fileexists(), ast_str_append(), ast_str_create, ast_str_reset(), and NULL.

Referenced by ast_get_money_en_dollars_str(), get_number_str_en(), say_digit_str_full(), and sayfile_exec().

295 {
296  const char *fn;
297  char fnbuf[256];
298  int num = 0;
299 
300  struct ast_str *filenames = ast_str_create(20);
301  ast_str_reset(filenames);
302 
303  while (str[num]) {
304  fn = NULL;
305  switch (str[num]) {
306  case ('*'):
307  fn = "digits/star";
308  break;
309  case ('#'):
310  fn = "digits/pound";
311  break;
312  case ('-'):
313  fn = "digits/minus";
314  break;
315  case '0':
316  case '1':
317  case '2':
318  case '3':
319  case '4':
320  case '5':
321  case '6':
322  case '7':
323  case '8':
324  case '9':
325  strcpy(fnbuf, "digits/X");
326  fnbuf[7] = str[num];
327  fn = fnbuf;
328  break;
329  }
330  if (fn && ast_fileexists(fn, NULL, lang) > 0) {
331  ast_str_append(&filenames, 0, (num == 0 ? "%s" : "&%s"), fn);
332  }
333  num++;
334  }
335 
336  return filenames;
337 }
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ ast_get_money_en_dollars_str()

static struct ast_str* ast_get_money_en_dollars_str ( const char *  str,
const char *  lang 
)
static

Definition at line 363 of file say.c.

References ast_debug, ast_get_digit_str(), ast_get_number_str(), ast_str_append(), ast_str_buffer(), ast_str_create, and ast_str_reset().

Referenced by ast_get_money_str().

364 {
365  const char *fnr;
366 
367  double dollars = 0;
368  int amt, cents;
369  struct ast_str *fnrecurse;
370 
371  struct ast_str *filenames = ast_str_create(20);
372  ast_str_reset(filenames);
373 
374  if (sscanf(str, "%30lf", &dollars) != 1) {
375  amt = 0;
376  } else { /* convert everything to cents */
377  amt = dollars * 100;
378  }
379 
380  /* Just the cents after the dollar decimal point */
381  cents = amt - (((int) dollars) * 100);
382  ast_debug(1, "Cents is %d, amount is %d\n", cents, amt);
383 
384  if (amt >= 100) {
385  fnrecurse = ast_get_number_str((amt / 100), lang);
386  fnr = ast_str_buffer(fnrecurse);
387  ast_str_append(&filenames, 0, "%s", fnr);
388 
389  /* If this is it, end on a down pitch, otherwise up pitch */
390  if (amt < 200) {
391  ast_str_append(&filenames, 0, "&%s", (cents > 0) ? "letters/dollar_" : "letters/dollar");
392  } else {
393  ast_str_append(&filenames, 0, "&%s", "dollars");
394  }
395 
396  /* If dollars and cents, add "and" in the middle */
397  if (cents > 0) {
398  ast_str_append(&filenames, 0, "&%s", "and");
399  }
400  }
401 
402  if (cents > 0) {
403  ast_debug(1, "Entered cents block\n");
404  fnrecurse = ast_get_number_str(cents, lang);
405  fnr = ast_str_buffer(fnrecurse);
406  ast_str_append(&filenames, 0, (amt < 100 ? "%s" : "&%s"), fnr);
407  ast_str_append(&filenames, 0, "&%s", (cents == 1) ? "cent" : "cents");
408  } else if (amt == 0) {
409  fnrecurse = ast_get_digit_str("0", lang);
410  fnr = ast_str_buffer(fnrecurse);
411  ast_str_append(&filenames, 0, "%s", fnr);
412  ast_str_append(&filenames, 0, "&%s", "cents");
413  }
414 
415  return filenames;
416 }
struct ast_str * ast_get_number_str(int num, const char *lang)
ast_get_number_str: call language-specific functions
Definition: say.c:525
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * str
Definition: app_jack.c:147
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_str * ast_get_digit_str(const char *str, const char *lang)
Returns an ast_str of files for SayDigits playback.
Definition: say.c:294
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ ast_get_money_str()

struct ast_str* ast_get_money_str ( const char *  str,
const char *  lang 
)

ast_get_money_str: call language-specific functions

Returns an ast_str of files for SayMoney playback.

Definition at line 419 of file say.c.

References ast_get_money_en_dollars_str(), ast_log, and LOG_WARNING.

Referenced by say_money_str_full(), and sayfile_exec().

420 {
421  if (!strncasecmp(lang, "en", 2)) { /* English syntax */
422  return ast_get_money_en_dollars_str(str, lang);
423  }
424 
425  ast_log(LOG_WARNING, "Language %s not currently supported, defaulting to US Dollars\n", lang);
426  /* Default to english */
427  return ast_get_money_en_dollars_str(str, lang);
428 }
#define LOG_WARNING
Definition: logger.h:274
const char * str
Definition: app_jack.c:147
#define ast_log
Definition: astobj2.c:42
static struct ast_str * ast_get_money_en_dollars_str(const char *str, const char *lang)
Definition: say.c:363

◆ ast_get_number_str()

struct ast_str* ast_get_number_str ( int  num,
const char *  lang 
)

ast_get_number_str: call language-specific functions

Returns an ast_str of files for SayNumber playback.

Definition at line 525 of file say.c.

References ast_log, ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_is(), ast_say_date_ja(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_pt(), ast_say_date_th(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_es(), ast_say_date_with_format_fr(), ast_say_date_with_format_gr(), ast_say_date_with_format_he(), ast_say_date_with_format_is(), ast_say_date_with_format_it(), ast_say_date_with_format_ja(), ast_say_date_with_format_nl(), ast_say_date_with_format_pl(), ast_say_date_with_format_pt(), ast_say_date_with_format_th(), ast_say_date_with_format_vi(), ast_say_date_with_format_zh(), ast_say_datetime_de(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_from_now_pt(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_hu(), ast_say_datetime_ja(), ast_say_datetime_ka(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_pt_BR(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_is(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_is(), ast_say_number_full_it(), ast_say_number_full_ja(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pl(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_hu(), ast_say_time_ja(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_pt(), ast_say_time_pt_BR(), ast_say_time_th(), ast_say_time_zh(), format, get_number_str_en(), language, LOG_WARNING, and options.

Referenced by ast_get_money_en_dollars_str(), ast_say_number_full_en(), get_number_str_en(), and sayfile_exec().

526 {
527  if (!strncasecmp(lang, "en", 2)) { /* English syntax */
528  return get_number_str_en(num, lang);
529  }
530 
531  ast_log(LOG_WARNING, "Language %s not currently supported, defaulting to English\n", lang);
532  /* Default to english */
533  return get_number_str_en(num, lang);
534 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
static struct ast_str * get_number_str_en(int num, const char *lang)
Definition: say.c:454

◆ ast_get_phonetic_str()

struct ast_str* ast_get_phonetic_str ( const char *  str,
const char *  lang 
)

Returns an ast_str of files for SayPhonetic playback.

Parameters
strText to be translated to the corresponding audio files.
langChannel language

Computes the list of files to be played by SayPhonetic.

Return values
ampersand-separatedstring of Asterisk sound files that can be played back.

Definition at line 195 of file say.c.

References ast_fileexists(), ast_str_append(), ast_str_create, ast_str_reset(), and NULL.

Referenced by say_phonetic_str_full(), and sayfile_exec().

196 {
197  const char *fn;
198  char fnbuf[256];
199  char ltr;
200  int num = 0;
201 
202  struct ast_str *filenames = ast_str_create(20);
203  ast_str_reset(filenames);
204 
205  while (str[num]) {
206  fn = NULL;
207  switch (str[num]) {
208  case ('*'):
209  fn = "digits/star";
210  break;
211  case ('#'):
212  fn = "digits/pound";
213  break;
214  case ('!'):
215  fn = "letters/exclaimation-point";
216  break;
217  case ('@'):
218  fn = "letters/at";
219  break;
220  case ('$'):
221  fn = "letters/dollar";
222  break;
223  case ('-'):
224  fn = "letters/dash";
225  break;
226  case ('.'):
227  fn = "letters/dot";
228  break;
229  case ('='):
230  fn = "letters/equals";
231  break;
232  case ('+'):
233  fn = "letters/plus";
234  break;
235  case ('/'):
236  fn = "letters/slash";
237  break;
238  case (' '):
239  fn = "letters/space";
240  break;
241  case ('0'):
242  case ('1'):
243  case ('2'):
244  case ('3'):
245  case ('4'):
246  case ('5'):
247  case ('6'):
248  case ('7'):
249  case ('8'):
250  strcpy(fnbuf, "digits/X");
251  fnbuf[7] = str[num];
252  fn = fnbuf;
253  break;
254  default: /* '9' falls here... */
255  ltr = str[num];
256  if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
257  strcpy(fnbuf, "phonetic/X_p");
258  fnbuf[9] = ltr;
259  fn = fnbuf;
260  }
261  if (fn && ast_fileexists(fn, NULL, lang) > 0) {
262  ast_str_append(&filenames, 0, (num == 0 ? "%s" : "&%s"), fn);
263  }
264  num++;
265  }
266 
267  return filenames;
268 }
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ ast_say_counted_adjective()

int ast_say_counted_adjective ( struct ast_channel chan,
int  num,
const char  adjective[],
const char  gender[] 
)

Definition at line 9577 of file say.c.

References ast_alloca, ast_channel_language(), ast_play_and_wait(), and counted_adjective_ending_ru().

9578 {
9579  char *temp;
9580  int temp_len;
9581  const char *ending;
9582  if (!strncasecmp(ast_channel_language(chan), "ru", 2)) { /* Russian */
9583  ending = counted_adjective_ending_ru(num, gender);
9584  } else if (!strncasecmp(ast_channel_language(chan), "ua", 2)) { /* Ukrainian */
9585  ending = counted_adjective_ending_ru(num, gender);
9586  } else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) { /* Polish */
9587  ending = counted_adjective_ending_ru(num, gender);
9588  } else { /* English and default */
9589  ending = "";
9590  }
9591  temp = ast_alloca((temp_len = (strlen(adjective) + strlen(ending) + 1)));
9592  snprintf(temp, temp_len, "%s%s", adjective, ending);
9593  return ast_play_and_wait(chan, temp);
9594 }
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: main/app.c:1470
static const char * counted_adjective_ending_ru(int num, const char gender[])
In slavic languages such as Russian and Ukrainian the rules for declining adjectives are simpler than...
Definition: say.c:9561
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
const char * ast_channel_language(const struct ast_channel *chan)

◆ ast_say_counted_noun()

int ast_say_counted_noun ( struct ast_channel chan,
int  num,
const char  noun[] 
)

Definition at line 9535 of file say.c.

References ast_alloca, ast_channel_language(), ast_play_and_wait(), counted_noun_ending_en(), and counted_noun_ending_slavic().

9536 {
9537  char *temp;
9538  int temp_len;
9539  const char *ending;
9540  if (!strncasecmp(ast_channel_language(chan), "ru", 2)) { /* Russian */
9541  ending = counted_noun_ending_slavic(num);
9542  } else if (!strncasecmp(ast_channel_language(chan), "ua", 2)) { /* Ukrainian */
9543  ending = counted_noun_ending_slavic(num);
9544  } else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) { /* Polish */
9545  ending = counted_noun_ending_slavic(num);
9546  } else { /* English and default */
9547  ending = counted_noun_ending_en(num);
9548  }
9549  temp = ast_alloca((temp_len = (strlen(noun) + strlen(ending) + 1)));
9550  snprintf(temp, temp_len, "%s%s", noun, ending);
9551  return ast_play_and_wait(chan, temp);
9552 }
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: main/app.c:1470
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
static const char * counted_noun_ending_slavic(int num)
Counting of objects in slavic languages such as Russian and Ukrainian the rules are more complicated...
Definition: say.c:9516
const char * ast_channel_language(const struct ast_channel *chan)
static const char * counted_noun_ending_en(int num)
In English, we use the plural for everything but one. For example:
Definition: say.c:9497

◆ ast_say_date_da()

int ast_say_date_da ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Danish syntax.

Definition at line 3871 of file say.c.

References ast_localtime(), ast_say_enumeration(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date().

3872 {
3873  struct timeval when = { t, 0 };
3874  struct ast_tm tm;
3875  char fn[256];
3876  int res = 0;
3877  ast_localtime(&when, &tm, NULL);
3878  if (!res) {
3879  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
3880  res = ast_streamfile(chan, fn, lang);
3881  if (!res)
3882  res = ast_waitstream(chan, ints);
3883  }
3884  if (!res)
3885  res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
3886  if (!res)
3887  res = ast_waitstream(chan, ints);
3888  if (!res) {
3889  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
3890  res = ast_streamfile(chan, fn, lang);
3891  if (!res)
3892  res = ast_waitstream(chan, ints);
3893  }
3894  if (!res) {
3895  /* Year */
3896  int year = tm.tm_year + 1900;
3897  if (year > 1999) { /* year 2000 and later */
3898  res = ast_say_number(chan, year, ints, lang, (char *) NULL);
3899  } else {
3900  if (year < 1100) {
3901  /* I'm not going to handle 1100 and prior */
3902  /* We'll just be silent on the year, instead of bombing out. */
3903  } else {
3904  /* year 1100 to 1999. will anybody need this?!? */
3905  snprintf(fn, sizeof(fn), "digits/%d", (year / 100));
3906  res = wait_file(chan, ints, fn, lang);
3907  if (!res) {
3908  res = wait_file(chan, ints, "digits/hundred", lang);
3909  if (!res && year % 100 != 0) {
3910  res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
3911  }
3912  }
3913  }
3914  }
3915  }
3916  return res;
3917 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says an enumeration
Definition: channel.c:8343

◆ ast_say_date_de()

int ast_say_date_de ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

German syntax.

Definition at line 3920 of file say.c.

References ast_localtime(), ast_say_enumeration(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date().

3921 {
3922  struct timeval when = { t, 0 };
3923  struct ast_tm tm;
3924  char fn[256];
3925  int res = 0;
3926  ast_localtime(&when, &tm, NULL);
3927  if (!res) {
3928  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
3929  res = ast_streamfile(chan, fn, lang);
3930  if (!res)
3931  res = ast_waitstream(chan, ints);
3932  }
3933  if (!res)
3934  res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
3935  if (!res)
3936  res = ast_waitstream(chan, ints);
3937  if (!res) {
3938  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
3939  res = ast_streamfile(chan, fn, lang);
3940  if (!res)
3941  res = ast_waitstream(chan, ints);
3942  }
3943  if (!res) {
3944  /* Year */
3945  int year = tm.tm_year + 1900;
3946  if (year > 1999) { /* year 2000 and later */
3947  res = ast_say_number(chan, year, ints, lang, (char *) NULL);
3948  } else {
3949  if (year < 1100) {
3950  /* I'm not going to handle 1100 and prior */
3951  /* We'll just be silent on the year, instead of bombing out. */
3952  } else {
3953  /* year 1100 to 1999. will anybody need this?!? */
3954  /* say 1967 as 'neunzehn hundert sieben und sechzig' */
3955  snprintf(fn, sizeof(fn), "digits/%d", (year / 100) );
3956  res = wait_file(chan, ints, fn, lang);
3957  if (!res) {
3958  res = wait_file(chan, ints, "digits/hundred", lang);
3959  if (!res && year % 100 != 0) {
3960  res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
3961  }
3962  }
3963  }
3964  }
3965  }
3966  return res;
3967 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says an enumeration
Definition: channel.c:8343

◆ ast_say_date_en()

int ast_say_date_en ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

English syntax.

Definition at line 3842 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, and ast_tm::tm_year.

Referenced by ast_get_number_str(), and say_date().

3843 {
3844  struct ast_tm tm;
3845  struct timeval when = { t, 0 };
3846  char fn[256];
3847  int res = 0;
3848  ast_localtime(&when, &tm, NULL);
3849  if (!res) {
3850  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
3851  res = ast_streamfile(chan, fn, lang);
3852  if (!res)
3853  res = ast_waitstream(chan, ints);
3854  }
3855  if (!res) {
3856  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
3857  res = ast_streamfile(chan, fn, lang);
3858  if (!res)
3859  res = ast_waitstream(chan, ints);
3860  }
3861  if (!res)
3862  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
3863  if (!res)
3864  res = ast_waitstream(chan, ints);
3865  if (!res)
3866  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
3867  return res;
3868 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_date_fr()

int ast_say_date_fr ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

French syntax.

Definition at line 4002 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, and ast_tm::tm_year.

Referenced by ast_get_number_str(), and say_date().

4003 {
4004  struct timeval when = { t, 0 };
4005  struct ast_tm tm;
4006  char fn[256];
4007  int res = 0;
4008  ast_localtime(&when, &tm, NULL);
4009  if (!res) {
4010  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4011  res = ast_streamfile(chan, fn, lang);
4012  if (!res)
4013  res = ast_waitstream(chan, ints);
4014  }
4015  if (!res)
4016  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
4017  if (!res)
4018  res = ast_waitstream(chan, ints);
4019  if (!res) {
4020  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4021  res = ast_streamfile(chan, fn, lang);
4022  if (!res)
4023  res = ast_waitstream(chan, ints);
4024  }
4025  if (!res)
4026  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4027  return res;
4028 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_date_gr()

static int ast_say_date_gr ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Greek support.

The format is weekday - day - month -year

A list of the files that you need to create digits/day-[1..7] : "Deytera .. Paraskeyh" digits/months/1..12 : "Ianouariou .. Dekembriou" Attention the months are in "gekinh klhsh"

Definition at line 8180 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), gr_say_number_female(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, and ast_tm::tm_year.

Referenced by ast_get_number_str(), and say_date().

8181 {
8182  struct ast_tm tm;
8183  struct timeval when = { t, 0 };
8184 
8185  char fn[256];
8186  int res = 0;
8187 
8188 
8189  ast_localtime(&when, &tm, NULL);
8190  /* W E E K - D A Y */
8191  if (!res) {
8192  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8193  res = ast_streamfile(chan, fn, lang);
8194  if (!res)
8195  res = ast_waitstream(chan, ints);
8196  }
8197  /* D A Y */
8198  if (!res) {
8199  gr_say_number_female(tm.tm_mday, chan, ints, lang);
8200  }
8201  /* M O N T H */
8202  if (!res) {
8203  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8204  res = ast_streamfile(chan, fn, lang);
8205  if (!res)
8206  res = ast_waitstream(chan, ints);
8207  }
8208  /* Y E A R */
8209  if (!res)
8210  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
8211  return res;
8212 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang)
Greek digits/female-[1..4] : "Mia, dyo , treis, tessereis".
Definition: say.c:7991

◆ ast_say_date_he()

int ast_say_date_he ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Hebrew syntax.

Definition at line 4123 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, and ast_tm::tm_year.

Referenced by ast_get_number_str(), and say_date().

4124 {
4125  struct timeval when = { t, 0 };
4126  struct ast_tm tm;
4127  char fn[256];
4128  int res = 0;
4129  ast_localtime(&when, &tm, NULL);
4130  if (!res) {
4131  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4132  res = ast_streamfile(chan, fn, lang);
4133  if (!res) {
4134  res = ast_waitstream(chan, ints);
4135  }
4136  }
4137  if (!res) {
4138  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4139  res = ast_streamfile(chan, fn, lang);
4140  if (!res) {
4141  res = ast_waitstream(chan, ints);
4142  }
4143  }
4144  if (!res) {
4145  res = ast_say_number(chan, tm.tm_mday, ints, lang, "m");
4146  }
4147  if (!res) {
4148  res = ast_waitstream(chan, ints);
4149  }
4150  if (!res) {
4151  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "m");
4152  }
4153  return res;
4154 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_date_hu()

int ast_say_date_hu ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Hungarian syntax.

Definition at line 3970 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, and ast_tm::tm_year.

Referenced by ast_get_number_str(), and say_date().

3971 {
3972  struct timeval when = { t, 0 };
3973  struct ast_tm tm;
3974  char fn[256];
3975  int res = 0;
3976  ast_localtime(&when, &tm, NULL);
3977 
3978  if (!res)
3979  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
3980  if (!res)
3981  res = ast_waitstream(chan, ints);
3982  if (!res) {
3983  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
3984  res = ast_streamfile(chan, fn, lang);
3985  if (!res)
3986  res = ast_waitstream(chan, ints);
3987  }
3988  if (!res)
3989  ast_say_number(chan, tm.tm_mday , ints, lang, (char *) NULL);
3990  if (!res)
3991  res = ast_waitstream(chan, ints);
3992  if (!res) {
3993  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
3994  res = ast_streamfile(chan, fn, lang);
3995  if (!res)
3996  res = ast_waitstream(chan, ints);
3997  }
3998  return res;
3999 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_date_is()

int ast_say_date_is ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Definition at line 4157 of file say.c.

References ast_localtime(), ast_say_enumeration(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date().

4158 {
4159  struct timeval when = { t, 0 };
4160  struct ast_tm tm;
4161  char fn[256];
4162  int res = 0;
4163  ast_localtime(&when, &tm, NULL);
4164  if (!res) {
4165  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4166  res = ast_streamfile(chan, fn, lang);
4167  if (!res)
4168  res = ast_waitstream(chan, ints);
4169  }
4170  if (!res)
4171  res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
4172  if (!res)
4173  res = ast_waitstream(chan, ints);
4174  if (!res) {
4175  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4176  res = ast_streamfile(chan, fn, lang);
4177  if (!res)
4178  res = ast_waitstream(chan, ints);
4179  }
4180  if (!res) {
4181  /* Year */
4182  int year = tm.tm_year + 1900;
4183  if (year > 1999) { /* year 2000 and later */
4184  res = ast_say_number(chan, year, ints, lang, (char *) NULL);
4185  } else {
4186  if (year < 1100) {
4187  /* I'm not going to handle 1100 and prior */
4188  /* We'll just be silent on the year, instead of bombing out. */
4189  } else {
4190  /* year 1100 to 1999. will anybody need this?!? */
4191  snprintf(fn, sizeof(fn), "digits/%d", (year / 100));
4192  res = wait_file(chan, ints, fn, lang);
4193  if (!res) {
4194  res = wait_file(chan, ints, "digits/hundred", lang);
4195  if (!res && year % 100 != 0) {
4196  res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
4197  }
4198  }
4199  }
4200  }
4201  }
4202  return res;
4203 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says an enumeration
Definition: channel.c:8343

◆ ast_say_date_ja()

int ast_say_date_ja ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Definition at line 8216 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, and ast_tm::tm_year.

Referenced by ast_get_number_str(), and say_date().

8217 {
8218  struct ast_tm tm;
8219  struct timeval tv = { t, 0 };
8220  char fn[256];
8221  int res = 0;
8222 
8223  ast_localtime(&tv, &tm, NULL);
8224 
8225  if (!res)
8226  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
8227  if (!res)
8228  res = ast_waitstream(chan, ints);
8229  if (!res)
8230  res = ast_streamfile(chan, "digits/nen", lang);
8231  if (!res) {
8232  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8233  res = ast_streamfile(chan, fn, lang);
8234  if (!res)
8235  res = ast_waitstream(chan, ints);
8236  }
8237  if (!res)
8238  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
8239  if (!res)
8240  res = ast_streamfile(chan, "digits/nichi", lang);
8241  if (!res) {
8242  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8243  res = ast_streamfile(chan, fn, lang);
8244  if (!res)
8245  res = ast_waitstream(chan, ints);
8246  }
8247  return res;
8248 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_date_ka()

static int ast_say_date_ka ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Georgian syntax. e.g. "oriatas xuti tslis 5 noemberi".

Georgian support for date/time requires the following files (*.gsm):

  • mon-1, mon-2, ... (ianvari, tebervali, ...)
  • day-1, day-2, ... (orshabati, samshabati, ...)
  • saati_da
  • tsuti
  • tslis

Definition at line 9348 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, and ast_tm::tm_year.

Referenced by ast_get_number_str(), and say_date().

9349 {
9350  struct timeval when = { t, 0 };
9351  struct ast_tm tm;
9352  char fn[256];
9353  int res = 0;
9354  ast_localtime(&when, &tm, NULL);
9355 
9356  if (!res) {
9357  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
9358  }
9359 
9360  if (!res) {
9361  snprintf(fn, sizeof(fn), "digits/tslis %d", tm.tm_wday);
9362  res = ast_streamfile(chan, fn, lang);
9363  if (!res) {
9364  res = ast_waitstream(chan, ints);
9365  }
9366  }
9367 
9368  if (!res) {
9369  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
9370 /* if (!res)
9371  res = ast_waitstream(chan, ints);
9372 */
9373  }
9374 
9375  if (!res) {
9376  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
9377  res = ast_streamfile(chan, fn, lang);
9378  if (!res) {
9379  res = ast_waitstream(chan, ints);
9380  }
9381  }
9382  return res;
9383 
9384 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_date_nl()

int ast_say_date_nl ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Dutch syntax.

Definition at line 4031 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, and ast_tm::tm_year.

Referenced by ast_get_number_str(), and say_date().

4032 {
4033  struct timeval when = { t, 0 };
4034  struct ast_tm tm;
4035  char fn[256];
4036  int res = 0;
4037  ast_localtime(&when, &tm, NULL);
4038  if (!res) {
4039  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4040  res = ast_streamfile(chan, fn, lang);
4041  if (!res)
4042  res = ast_waitstream(chan, ints);
4043  }
4044  if (!res)
4045  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
4046  if (!res) {
4047  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4048  res = ast_streamfile(chan, fn, lang);
4049  if (!res)
4050  res = ast_waitstream(chan, ints);
4051  }
4052  if (!res)
4053  res = ast_waitstream(chan, ints);
4054  if (!res)
4055  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4056  return res;
4057 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_date_pt()

int ast_say_date_pt ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Portuguese syntax.

Definition at line 4096 of file say.c.

References ast_localtime(), ast_say_number(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date().

4097 {
4098  struct timeval when = { t, 0 };
4099  struct ast_tm tm;
4100  char fn[256];
4101  int res = 0;
4102 
4103  ast_localtime(&when, &tm, NULL);
4104  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4105  if (!res)
4106  res = wait_file(chan, ints, fn, lang);
4107  if (!res)
4108  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
4109  if (!res)
4110  res = wait_file(chan, ints, "digits/pt-de", lang);
4111  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4112  if (!res)
4113  res = wait_file(chan, ints, fn, lang);
4114  if (!res)
4115  res = wait_file(chan, ints, "digits/pt-de", lang);
4116  if (!res)
4117  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4118 
4119  return res;
4120 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337

◆ ast_say_date_th()

int ast_say_date_th ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Thai syntax.

Definition at line 4060 of file say.c.

References ast_copy_string(), ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, and ast_tm::tm_year.

Referenced by ast_get_number_str(), and say_date().

4061 {
4062  struct timeval when = { t, 0 };
4063  struct ast_tm tm;
4064  char fn[256];
4065  int res = 0;
4066  ast_localtime(&when, &tm, NULL);
4067  if (!res) {
4068  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4069  res = ast_streamfile(chan, fn, lang);
4070  ast_copy_string(fn, "digits/tee", sizeof(fn));
4071  res = ast_streamfile(chan, fn, lang);
4072  if (!res)
4073  res = ast_waitstream(chan, ints);
4074  }
4075  if (!res)
4076  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
4077  if (!res)
4078  res = ast_waitstream(chan, ints);
4079  if (!res) {
4080  ast_copy_string(fn, "digits/duan", sizeof(fn));
4081  res = ast_streamfile(chan, fn, lang);
4082  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4083  res = ast_streamfile(chan, fn, lang);
4084  if (!res)
4085  res = ast_waitstream(chan, ints);
4086  }
4087  if (!res){
4088  ast_copy_string(fn, "digits/posor", sizeof(fn));
4089  res = ast_streamfile(chan, fn, lang);
4090  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4091  }
4092  return res;
4093 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_date_with_format_da()

int ast_say_date_with_format_da ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Danish syntax.

Definition at line 4493 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_enumeration(), ast_say_number(), ast_tvnow(), LOG_WARNING, next_item(), NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

4494 {
4495  struct timeval when = { t, 0 };
4496  struct ast_tm tm;
4497  int res=0, offset, sndoffset;
4498  char sndfile[256], nextmsg[256];
4499 
4500  if (!format)
4501  format = "A dBY HMS";
4502 
4503  ast_localtime(&when, &tm, tzone);
4504 
4505  for (offset=0 ; format[offset] != '\0' ; offset++) {
4506  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
4507  switch (format[offset]) {
4508  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
4509  case '\'':
4510  /* Literal name of a sound file */
4511  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
4512  sndfile[sndoffset] = format[offset];
4513  }
4514  sndfile[sndoffset] = '\0';
4515  res = wait_file(chan, ints, sndfile, lang);
4516  break;
4517  case 'A':
4518  case 'a':
4519  /* Sunday - Saturday */
4520  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
4521  res = wait_file(chan, ints, nextmsg, lang);
4522  break;
4523  case 'B':
4524  case 'b':
4525  case 'h':
4526  /* January - December */
4527  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
4528  res = wait_file(chan, ints, nextmsg, lang);
4529  break;
4530  case 'm':
4531  /* Month enumerated */
4532  res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
4533  break;
4534  case 'd':
4535  case 'e':
4536  /* First - Thirtyfirst */
4537  res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
4538  break;
4539  case 'Y':
4540  /* Year */
4541  {
4542  int year = tm.tm_year + 1900;
4543  if (year > 1999) { /* year 2000 and later */
4544  res = ast_say_number(chan, year, ints, lang, (char *) NULL);
4545  } else {
4546  if (year < 1100) {
4547  /* I'm not going to handle 1100 and prior */
4548  /* We'll just be silent on the year, instead of bombing out. */
4549  } else {
4550  /* year 1100 to 1999. will anybody need this?!? */
4551  /* say 1967 as 'nineteen hundred seven and sixty' */
4552  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
4553  res = wait_file(chan, ints, nextmsg, lang);
4554  if (!res) {
4555  res = wait_file(chan, ints, "digits/hundred", lang);
4556  if (!res && year % 100 != 0) {
4557  res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
4558  }
4559  }
4560  }
4561  }
4562  }
4563  break;
4564  case 'I':
4565  case 'l':
4566  /* 12-Hour */
4567  res = wait_file(chan, ints, "digits/oclock", lang);
4568  if (tm.tm_hour == 0)
4569  ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
4570  else if (tm.tm_hour > 12)
4571  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
4572  else
4573  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
4574  if (!res) {
4575  res = wait_file(chan, ints, nextmsg, lang);
4576  }
4577  break;
4578  case 'H':
4579  /* 24-Hour, single digit hours preceded by "oh" (0) */
4580  if (tm.tm_hour < 10 && tm.tm_hour > 0) {
4581  res = wait_file(chan, ints, "digits/0", lang);
4582  }
4583  /* FALLTRHU */
4584  case 'k':
4585  /* 24-Hour */
4586  res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
4587  break;
4588  case 'M':
4589  /* Minute */
4590  if (tm.tm_min > 0 || next_item(&format[offset + 1]) == 'S') { /* zero 'digits/0' only if seconds follow */
4591  res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
4592  }
4593  if (!res && next_item(&format[offset + 1]) == 'S') { /* minutes only if seconds follow */
4594  if (tm.tm_min == 1) {
4595  res = wait_file(chan, ints, "minute", lang);
4596  } else {
4597  res = wait_file(chan, ints, "minutes", lang);
4598  }
4599  }
4600  break;
4601  case 'P':
4602  case 'p':
4603  /* AM/PM */
4604  if (tm.tm_hour > 11)
4605  ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
4606  else
4607  ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
4608  res = wait_file(chan, ints, nextmsg, lang);
4609  break;
4610  case 'Q':
4611  /* Shorthand for "Today", "Yesterday", or AdBY */
4612  /* XXX As emphasized elsewhere, this should the native way in your
4613  * language to say the date, with changes in what you say, depending
4614  * upon how recent the date is. XXX */
4615  {
4616  struct timeval now = ast_tvnow();
4617  struct ast_tm tmnow;
4618  time_t beg_today;
4619 
4620  ast_localtime(&now, &tmnow, tzone);
4621  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
4622  /* In any case, it saves not having to do ast_mktime() */
4623  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
4624  if (beg_today < t) {
4625  /* Today */
4626  res = wait_file(chan, ints, "digits/today", lang);
4627  } else if (beg_today - 86400 < t) {
4628  /* Yesterday */
4629  res = wait_file(chan, ints, "digits/yesterday", lang);
4630  } else {
4631  res = ast_say_date_with_format_da(chan, t, ints, lang, "AdBY", tzone);
4632  }
4633  }
4634  break;
4635  case 'q':
4636  /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
4637  /* XXX As emphasized elsewhere, this should the native way in your
4638  * language to say the date, with changes in what you say, depending
4639  * upon how recent the date is. XXX */
4640  {
4641  struct timeval now = ast_tvnow();
4642  struct ast_tm tmnow;
4643  time_t beg_today;
4644 
4645  ast_localtime(&now, &tmnow, tzone);
4646  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
4647  /* In any case, it saves not having to do ast_mktime() */
4648  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
4649  if (beg_today < t) {
4650  /* Today */
4651  } else if ((beg_today - 86400) < t) {
4652  /* Yesterday */
4653  res = wait_file(chan, ints, "digits/yesterday", lang);
4654  } else if (beg_today - 86400 * 6 < t) {
4655  /* Within the last week */
4656  res = ast_say_date_with_format_da(chan, t, ints, lang, "A", tzone);
4657  } else {
4658  res = ast_say_date_with_format_da(chan, t, ints, lang, "AdBY", tzone);
4659  }
4660  }
4661  break;
4662  case 'R':
4663  res = ast_say_date_with_format_da(chan, t, ints, lang, "HM", tzone);
4664  break;
4665  case 'S':
4666  /* Seconds */
4667  res = wait_file(chan, ints, "digits/and", lang);
4668  if (!res) {
4669  res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
4670  if (!res) {
4671  res = wait_file(chan, ints, "seconds", lang);
4672  }
4673  }
4674  break;
4675  case 'T':
4676  res = ast_say_date_with_format_da(chan, t, ints, lang, "HMS", tzone);
4677  break;
4678  case ' ':
4679  case ' ':
4680  /* Just ignore spaces and tabs */
4681  break;
4682  default:
4683  /* Unknown character */
4684  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
4685  }
4686  /* Jump out on DTMF */
4687  if (res) {
4688  break;
4689  }
4690  }
4691  return res;
4692 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static char next_item(const char *format)
Definition: say.c:4486
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says an enumeration
Definition: channel.c:8343
static snd_pcm_format_t format
Definition: chan_alsa.c:102
static int ast_say_date_with_format_da(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Danish syntax.
Definition: say.c:4493

◆ ast_say_date_with_format_de()

int ast_say_date_with_format_de ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

German syntax.

Definition at line 4695 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_enumeration(), ast_say_number(), ast_tvnow(), LOG_WARNING, next_item(), NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

4696 {
4697  struct timeval when = { t, 0 };
4698  struct ast_tm tm;
4699  int res=0, offset, sndoffset;
4700  char sndfile[256], nextmsg[256];
4701 
4702  if (!format)
4703  format = "A dBY HMS";
4704 
4705  ast_localtime(&when, &tm, tzone);
4706 
4707  for (offset=0 ; format[offset] != '\0' ; offset++) {
4708  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
4709  switch (format[offset]) {
4710  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
4711  case '\'':
4712  /* Literal name of a sound file */
4713  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
4714  sndfile[sndoffset] = format[offset];
4715  }
4716  sndfile[sndoffset] = '\0';
4717  res = wait_file(chan, ints, sndfile, lang);
4718  break;
4719  case 'A':
4720  case 'a':
4721  /* Sunday - Saturday */
4722  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
4723  res = wait_file(chan, ints, nextmsg, lang);
4724  break;
4725  case 'B':
4726  case 'b':
4727  case 'h':
4728  /* January - December */
4729  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
4730  res = wait_file(chan, ints, nextmsg, lang);
4731  break;
4732  case 'm':
4733  /* Month enumerated */
4734  res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
4735  break;
4736  case 'd':
4737  case 'e':
4738  /* First - Thirtyfirst */
4739  res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
4740  break;
4741  case 'Y':
4742  /* Year */
4743  {
4744  int year = tm.tm_year + 1900;
4745  if (year > 1999) { /* year 2000 and later */
4746  res = ast_say_number(chan, year, ints, lang, (char *) NULL);
4747  } else {
4748  if (year < 1100) {
4749  /* I'm not going to handle 1100 and prior */
4750  /* We'll just be silent on the year, instead of bombing out. */
4751  } else {
4752  /* year 1100 to 1999. will anybody need this?!? */
4753  /* say 1967 as 'neunzehn hundert sieben und sechzig' */
4754  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
4755  res = wait_file(chan, ints, nextmsg, lang);
4756  if (!res) {
4757  res = wait_file(chan, ints, "digits/hundred", lang);
4758  if (!res && year % 100 != 0) {
4759  res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
4760  }
4761  }
4762  }
4763  }
4764  }
4765  break;
4766  case 'I':
4767  case 'l':
4768  /* 12-Hour */
4769  if (tm.tm_hour == 0)
4770  ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
4771  else if (tm.tm_hour > 12)
4772  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
4773  else
4774  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
4775  res = wait_file(chan, ints, nextmsg, lang);
4776  if (!res) {
4777  res = wait_file(chan, ints, "digits/oclock", lang);
4778  }
4779  break;
4780  case 'H':
4781  case 'k':
4782  /* 24-Hour */
4783  res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
4784  if (!res) {
4785  res = wait_file(chan, ints, "digits/oclock", lang);
4786  }
4787  break;
4788  case 'M':
4789  /* Minute */
4790  if (next_item(&format[offset + 1]) == 'S') { /* zero 'digits/0' only if seconds follow */
4791  res = ast_say_number(chan, tm.tm_min, ints, lang, "f"); /* female only if we say minutes */
4792  } else if (tm.tm_min > 0) {
4793  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
4794  }
4795 
4796  if (!res && next_item(&format[offset + 1]) == 'S') { /* minutes only if seconds follow */
4797  if (tm.tm_min == 1) {
4798  res = wait_file(chan, ints, "minute", lang);
4799  } else {
4800  res = wait_file(chan, ints, "minutes", lang);
4801  }
4802  }
4803  break;
4804  case 'P':
4805  case 'p':
4806  /* AM/PM */
4807  if (tm.tm_hour > 11)
4808  ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
4809  else
4810  ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
4811  res = wait_file(chan, ints, nextmsg, lang);
4812  break;
4813  case 'Q':
4814  /* Shorthand for "Today", "Yesterday", or AdBY */
4815  /* XXX As emphasized elsewhere, this should the native way in your
4816  * language to say the date, with changes in what you say, depending
4817  * upon how recent the date is. XXX */
4818  {
4819  struct timeval now = ast_tvnow();
4820  struct ast_tm tmnow;
4821  time_t beg_today;
4822 
4823  ast_localtime(&now, &tmnow, tzone);
4824  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
4825  /* In any case, it saves not having to do ast_mktime() */
4826  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
4827  if (beg_today < t) {
4828  /* Today */
4829  res = wait_file(chan, ints, "digits/today", lang);
4830  } else if (beg_today - 86400 < t) {
4831  /* Yesterday */
4832  res = wait_file(chan, ints, "digits/yesterday", lang);
4833  } else {
4834  res = ast_say_date_with_format_de(chan, t, ints, lang, "AdBY", tzone);
4835  }
4836  }
4837  break;
4838  case 'q':
4839  /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
4840  /* XXX As emphasized elsewhere, this should the native way in your
4841  * language to say the date, with changes in what you say, depending
4842  * upon how recent the date is. XXX */
4843  {
4844  struct timeval now = ast_tvnow();
4845  struct ast_tm tmnow;
4846  time_t beg_today;
4847 
4848  ast_localtime(&now, &tmnow, tzone);
4849  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
4850  /* In any case, it saves not having to do ast_mktime() */
4851  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
4852  if (beg_today < t) {
4853  /* Today */
4854  } else if ((beg_today - 86400) < t) {
4855  /* Yesterday */
4856  res = wait_file(chan, ints, "digits/yesterday", lang);
4857  } else if (beg_today - 86400 * 6 < t) {
4858  /* Within the last week */
4859  res = ast_say_date_with_format_de(chan, t, ints, lang, "A", tzone);
4860  } else {
4861  res = ast_say_date_with_format_de(chan, t, ints, lang, "AdBY", tzone);
4862  }
4863  }
4864  break;
4865  case 'R':
4866  res = ast_say_date_with_format_de(chan, t, ints, lang, "HM", tzone);
4867  break;
4868  case 'S':
4869  /* Seconds */
4870  res = wait_file(chan, ints, "digits/and", lang);
4871  if (!res) {
4872  res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
4873  if (!res) {
4874  res = wait_file(chan, ints, tm.tm_sec == 1 ? "second" : "seconds", lang);
4875  }
4876  }
4877  break;
4878  case 'T':
4879  res = ast_say_date_with_format_de(chan, t, ints, lang, "HMS", tzone);
4880  break;
4881  case ' ':
4882  case ' ':
4883  /* Just ignore spaces and tabs */
4884  break;
4885  default:
4886  /* Unknown character */
4887  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
4888  }
4889  /* Jump out on DTMF */
4890  if (res) {
4891  break;
4892  }
4893  }
4894  return res;
4895 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static char next_item(const char *format)
Definition: say.c:4486
static int ast_say_date_with_format_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
German syntax.
Definition: say.c:4695
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says an enumeration
Definition: channel.c:8343
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_en()

int ast_say_date_with_format_en ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

English syntax.

Definition at line 4246 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_enumeration(), ast_say_number(), ast_tvnow(), LOG_WARNING, NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), ast_say_date_with_format_th(), ast_say_date_with_format_vi(), and say_date_with_format().

4247 {
4248  struct timeval when = { t, 0 };
4249  struct ast_tm tm;
4250  int res=0, offset, sndoffset;
4251  char sndfile[256], nextmsg[256];
4252 
4253  if (format == NULL)
4254  format = "ABdY 'digits/at' IMp";
4255 
4256  ast_localtime(&when, &tm, tzone);
4257 
4258  for (offset=0 ; format[offset] != '\0' ; offset++) {
4259  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
4260  switch (format[offset]) {
4261  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
4262  case '\'':
4263  /* Literal name of a sound file */
4264  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
4265  sndfile[sndoffset] = format[offset];
4266  }
4267  sndfile[sndoffset] = '\0';
4268  res = wait_file(chan, ints, sndfile, lang);
4269  break;
4270  case 'A':
4271  case 'a':
4272  /* Sunday - Saturday */
4273  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
4274  res = wait_file(chan, ints, nextmsg, lang);
4275  break;
4276  case 'B':
4277  case 'b':
4278  case 'h':
4279  /* January - December */
4280  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
4281  res = wait_file(chan, ints, nextmsg, lang);
4282  break;
4283  case 'm':
4284  /* Month enumerated */
4285  res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
4286  break;
4287  case 'd':
4288  case 'e':
4289  /* First - Thirtyfirst */
4290  res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char *) NULL);
4291  break;
4292  case 'Y':
4293  /* Year */
4294  if (tm.tm_year > 99) {
4295  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4296  } else if (tm.tm_year < 1) {
4297  /* I'm not going to handle 1900 and prior */
4298  /* We'll just be silent on the year, instead of bombing out. */
4299  } else {
4300  res = wait_file(chan, ints, "digits/19", lang);
4301  if (!res) {
4302  if (tm.tm_year <= 9) {
4303  /* 1901 - 1909 */
4304  res = wait_file(chan, ints, "digits/oh", lang);
4305  }
4306 
4307  res |= ast_say_number(chan, tm.tm_year, ints, lang, (char *) NULL);
4308  }
4309  }
4310  break;
4311  case 'I':
4312  case 'l':
4313  /* 12-Hour */
4314  if (tm.tm_hour == 0)
4315  ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
4316  else if (tm.tm_hour > 12)
4317  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
4318  else
4319  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
4320  res = wait_file(chan, ints, nextmsg, lang);
4321  break;
4322  case 'H':
4323  case 'k':
4324  /* 24-Hour */
4325  if (format[offset] == 'H') {
4326  /* e.g. oh-eight */
4327  if (tm.tm_hour < 10) {
4328  res = wait_file(chan, ints, "digits/oh", lang);
4329  }
4330  } else {
4331  /* e.g. eight */
4332  if (tm.tm_hour == 0) {
4333  res = wait_file(chan, ints, "digits/oh", lang);
4334  }
4335  }
4336  if (!res) {
4337  if (tm.tm_hour != 0) {
4338  int remaining = tm.tm_hour;
4339  if (tm.tm_hour > 20) {
4340  res = wait_file(chan, ints, "digits/20", lang);
4341  remaining -= 20;
4342  }
4343  if (!res) {
4344  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
4345  res = wait_file(chan, ints, nextmsg, lang);
4346  }
4347  }
4348  }
4349  break;
4350  case 'M':
4351  case 'N':
4352  /* Minute */
4353  if (tm.tm_min == 0) {
4354  if (format[offset] == 'M') {
4355  res = wait_file(chan, ints, "digits/oclock", lang);
4356  } else {
4357  res = wait_file(chan, ints, "digits/hundred", lang);
4358  }
4359  } else if (tm.tm_min < 10) {
4360  res = wait_file(chan, ints, "digits/oh", lang);
4361  if (!res) {
4362  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min);
4363  res = wait_file(chan, ints, nextmsg, lang);
4364  }
4365  } else {
4366  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
4367  }
4368  break;
4369  case 'P':
4370  case 'p':
4371  /* AM/PM */
4372  if (tm.tm_hour > 11)
4373  ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
4374  else
4375  ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
4376  res = wait_file(chan, ints, nextmsg, lang);
4377  break;
4378  case 'Q':
4379  /* Shorthand for "Today", "Yesterday", or ABdY */
4380  /* XXX As emphasized elsewhere, this should the native way in your
4381  * language to say the date, with changes in what you say, depending
4382  * upon how recent the date is. XXX */
4383  {
4384  struct timeval now = ast_tvnow();
4385  struct ast_tm tmnow;
4386  time_t beg_today;
4387 
4388  gettimeofday(&now, NULL);
4389  ast_localtime(&now, &tmnow, tzone);
4390  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
4391  /* In any case, it saves not having to do ast_mktime() */
4392  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
4393  if (beg_today < t) {
4394  /* Today */
4395  res = wait_file(chan, ints, "digits/today", lang);
4396  } else if (beg_today - 86400 < t) {
4397  /* Yesterday */
4398  res = wait_file(chan, ints, "digits/yesterday", lang);
4399  } else if (beg_today - 86400 * 6 < t) {
4400  /* Within the last week */
4401  res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
4402  } else if (beg_today - 2628000 < t) {
4403  /* Less than a month ago - "Sunday, October third" */
4404  res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
4405  } else if (beg_today - 15768000 < t) {
4406  /* Less than 6 months ago - "August seventh" */
4407  res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
4408  } else {
4409  /* More than 6 months ago - "April nineteenth two thousand three" */
4410  res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
4411  }
4412  }
4413  break;
4414  case 'q':
4415  /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
4416  /* XXX As emphasized elsewhere, this should the native way in your
4417  * language to say the date, with changes in what you say, depending
4418  * upon how recent the date is. XXX */
4419  {
4420  struct timeval now;
4421  struct ast_tm tmnow;
4422  time_t beg_today;
4423 
4424  now = ast_tvnow();
4425  ast_localtime(&now, &tmnow, tzone);
4426  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
4427  /* In any case, it saves not having to do ast_mktime() */
4428  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
4429  if (beg_today < t) {
4430  /* Today */
4431  } else if ((beg_today - 86400) < t) {
4432  /* Yesterday */
4433  res = wait_file(chan, ints, "digits/yesterday", lang);
4434  } else if (beg_today - 86400 * 6 < t) {
4435  /* Within the last week */
4436  res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
4437  } else if (beg_today - 2628000 < t) {
4438  /* Less than a month ago - "Sunday, October third" */
4439  res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
4440  } else if (beg_today - 15768000 < t) {
4441  /* Less than 6 months ago - "August seventh" */
4442  res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
4443  } else {
4444  /* More than 6 months ago - "April nineteenth two thousand three" */
4445  res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
4446  }
4447  }
4448  break;
4449  case 'R':
4450  res = ast_say_date_with_format_en(chan, t, ints, lang, "HM", tzone);
4451  break;
4452  case 'S':
4453  /* Seconds */
4454  if (tm.tm_sec == 0) {
4455  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
4456  res = wait_file(chan, ints, nextmsg, lang);
4457  } else if (tm.tm_sec < 10) {
4458  res = wait_file(chan, ints, "digits/oh", lang);
4459  if (!res) {
4460  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
4461  res = wait_file(chan, ints, nextmsg, lang);
4462  }
4463  } else {
4464  res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
4465  }
4466  break;
4467  case 'T':
4468  res = ast_say_date_with_format_en(chan, t, ints, lang, "HMS", tzone);
4469  break;
4470  case ' ':
4471  case ' ':
4472  /* Just ignore spaces and tabs */
4473  break;
4474  default:
4475  /* Unknown character */
4476  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
4477  }
4478  /* Jump out on DTMF */
4479  if (res) {
4480  break;
4481  }
4482  }
4483  return res;
4484 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
static int ast_say_date_with_format_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
English syntax.
Definition: say.c:4246
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says an enumeration
Definition: channel.c:8343
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_es()

int ast_say_date_with_format_es ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Spanish syntax.

Definition at line 5442 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_number(), ast_tvnow(), LOG_WARNING, NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

5443 {
5444  struct timeval when = { t, 0 };
5445  struct ast_tm tm;
5446  int res=0, offset, sndoffset;
5447  char sndfile[256], nextmsg[256];
5448 
5449  if (format == NULL)
5450  format = "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y 'digits/at' IMp";
5451 
5452  ast_localtime(&when, &tm, tzone);
5453 
5454  for (offset=0 ; format[offset] != '\0' ; offset++) {
5455  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
5456  switch (format[offset]) {
5457  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
5458  case '\'':
5459  /* Literal name of a sound file */
5460  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
5461  sndfile[sndoffset] = format[offset];
5462  }
5463  sndfile[sndoffset] = '\0';
5464  snprintf(nextmsg, sizeof(nextmsg), "%s", sndfile);
5465  res = wait_file(chan, ints, nextmsg, lang);
5466  break;
5467  case 'A':
5468  case 'a':
5469  /* Sunday - Saturday */
5470  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
5471  res = wait_file(chan, ints, nextmsg, lang);
5472  break;
5473  case 'B':
5474  case 'b':
5475  case 'h':
5476  /* January - December */
5477  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
5478  res = wait_file(chan, ints, nextmsg, lang);
5479  break;
5480  case 'm':
5481  /* First - Twelfth */
5482  snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
5483  res = wait_file(chan, ints, nextmsg, lang);
5484  break;
5485  case 'd':
5486  case 'e':
5487  /* First - Thirtyfirst */
5488  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
5489  break;
5490  case 'Y':
5491  /* Year */
5492  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
5493  break;
5494  case 'I':
5495  case 'l':
5496  /* 12-Hour */
5497  if (tm.tm_hour == 0)
5498  ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
5499  else if (tm.tm_hour == 1 || tm.tm_hour == 13)
5500  snprintf(nextmsg,sizeof(nextmsg), "digits/1F");
5501  else if (tm.tm_hour > 12)
5502  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
5503  else
5504  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
5505  res = wait_file(chan, ints, nextmsg, lang);
5506  break;
5507  case 'H':
5508  case 'k':
5509  /* 24-Hour */
5510  res = ast_say_number(chan, tm.tm_hour, ints, lang, NULL);
5511  break;
5512  case 'M':
5513  /* Minute */
5514  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
5515  break;
5516  case 'P':
5517  case 'p':
5518  /* AM/PM */
5519  if (tm.tm_hour > 18)
5520  res = wait_file(chan, ints, "digits/p-m", lang);
5521  else if (tm.tm_hour > 12)
5522  res = wait_file(chan, ints, "digits/afternoon", lang);
5523  else if (tm.tm_hour)
5524  res = wait_file(chan, ints, "digits/a-m", lang);
5525  break;
5526  case 'Q':
5527  /* Shorthand for "Today", "Yesterday", or ABdY */
5528  /* XXX As emphasized elsewhere, this should the native way in your
5529  * language to say the date, with changes in what you say, depending
5530  * upon how recent the date is. XXX */
5531  {
5532  struct timeval now = ast_tvnow();
5533  struct ast_tm tmnow;
5534  time_t beg_today;
5535 
5536  ast_localtime(&now, &tmnow, tzone);
5537  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5538  /* In any case, it saves not having to do ast_mktime() */
5539  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5540  if (beg_today < t) {
5541  /* Today */
5542  res = wait_file(chan, ints, "digits/today", lang);
5543  } else if (beg_today - 86400 < t) {
5544  /* Yesterday */
5545  res = wait_file(chan, ints, "digits/yesterday", lang);
5546  } else {
5547  res = ast_say_date_with_format_es(chan, t, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", tzone);
5548  }
5549  }
5550  break;
5551  case 'q':
5552  /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
5553  /* XXX As emphasized elsewhere, this should the native way in your
5554  * language to say the date, with changes in what you say, depending
5555  * upon how recent the date is. XXX */
5556  {
5557  struct timeval now = ast_tvnow();
5558  struct ast_tm tmnow;
5559  time_t beg_today;
5560 
5561  ast_localtime(&now, &tmnow, tzone);
5562  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5563  /* In any case, it saves not having to do ast_mktime() */
5564  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5565  if (beg_today < t) {
5566  /* Today */
5567  res = wait_file(chan, ints, "digits/today", lang);
5568  } else if ((beg_today - 86400) < t) {
5569  /* Yesterday */
5570  res = wait_file(chan, ints, "digits/yesterday", lang);
5571  } else if (beg_today - 86400 * 6 < t) {
5572  /* Within the last week */
5573  res = ast_say_date_with_format_es(chan, t, ints, lang, "A", tzone);
5574  } else {
5575  res = ast_say_date_with_format_es(chan, t, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", tzone);
5576  }
5577  }
5578  break;
5579  case 'R':
5580  res = ast_say_date_with_format_es(chan, t, ints, lang, "H 'digits/y' M", tzone);
5581  break;
5582  case 'S':
5583  /* Seconds */
5584  if (tm.tm_sec == 0) {
5585  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
5586  res = wait_file(chan, ints, nextmsg, lang);
5587  } else if (tm.tm_sec < 10) {
5588  res = wait_file(chan, ints, "digits/oh", lang);
5589  if (!res) {
5590  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
5591  res = wait_file(chan, ints, nextmsg, lang);
5592  }
5593  } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
5594  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
5595  res = wait_file(chan, ints, nextmsg, lang);
5596  } else {
5597  int ten, one;
5598  ten = (tm.tm_sec / 10) * 10;
5599  one = (tm.tm_sec % 10);
5600  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
5601  res = wait_file(chan, ints, nextmsg, lang);
5602  if (!res) {
5603  /* Fifty, not fifty-zero */
5604  if (one != 0) {
5605  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
5606  res = wait_file(chan, ints, nextmsg, lang);
5607  }
5608  }
5609  }
5610  break;
5611  case 'T':
5612  res = ast_say_date_with_format_es(chan, t, ints, lang, "HMS", tzone);
5613  break;
5614  case ' ':
5615  case ' ':
5616  /* Just ignore spaces and tabs */
5617  break;
5618  default:
5619  /* Unknown character */
5620  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
5621  }
5622  /* Jump out on DTMF */
5623  if (res) {
5624  break;
5625  }
5626  }
5627  return res;
5628 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
static int ast_say_date_with_format_es(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Spanish syntax.
Definition: say.c:5442
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_fr()

int ast_say_date_with_format_fr ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

French syntax oclock = heure.

Definition at line 5633 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_number(), ast_tvnow(), LOG_WARNING, NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

5634 {
5635  struct timeval when = { t, 0 };
5636  struct ast_tm tm;
5637  int res=0, offset, sndoffset;
5638  char sndfile[256], nextmsg[256];
5639 
5640  if (format == NULL)
5641  format = "AdBY 'digits/at' IMp";
5642 
5643  ast_localtime(&when, &tm, tzone);
5644 
5645  for (offset=0 ; format[offset] != '\0' ; offset++) {
5646  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
5647  switch (format[offset]) {
5648  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
5649  case '\'':
5650  /* Literal name of a sound file */
5651  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
5652  sndfile[sndoffset] = format[offset];
5653  }
5654  sndfile[sndoffset] = '\0';
5655  res = wait_file(chan, ints, sndfile, lang);
5656  break;
5657  case 'A':
5658  case 'a':
5659  /* Sunday - Saturday */
5660  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
5661  res = wait_file(chan, ints, nextmsg, lang);
5662  break;
5663  case 'B':
5664  case 'b':
5665  case 'h':
5666  /* January - December */
5667  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
5668  res = wait_file(chan, ints, nextmsg, lang);
5669  break;
5670  case 'm':
5671  /* First - Twelfth */
5672  snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
5673  res = wait_file(chan, ints, nextmsg, lang);
5674  break;
5675  case 'd':
5676  case 'e':
5677  /* First */
5678  if (tm.tm_mday == 1) {
5679  snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
5680  res = wait_file(chan, ints, nextmsg, lang);
5681  } else {
5682  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
5683  }
5684  break;
5685  case 'Y':
5686  /* Year */
5687  if (tm.tm_year > 99) {
5688  res = wait_file(chan, ints, "digits/2", lang);
5689  if (!res) {
5690  res = wait_file(chan, ints, "digits/thousand", lang);
5691  }
5692  if (tm.tm_year > 100) {
5693  if (!res) {
5694  res = ast_say_number(chan, tm.tm_year - 100, ints, lang, (char * ) NULL);
5695  }
5696  }
5697  } else {
5698  if (tm.tm_year < 1) {
5699  /* I'm not going to handle 1900 and prior */
5700  /* We'll just be silent on the year, instead of bombing out. */
5701  } else {
5702  res = wait_file(chan, ints, "digits/thousand", lang);
5703  if (!res) {
5704  wait_file(chan, ints, "digits/9", lang);
5705  wait_file(chan, ints, "digits/hundred", lang);
5706  res = ast_say_number(chan, tm.tm_year, ints, lang, (char * ) NULL);
5707  }
5708  }
5709  }
5710  break;
5711  case 'I':
5712  case 'l':
5713  /* 12-Hour */
5714  if (tm.tm_hour == 0)
5715  ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
5716  else if (tm.tm_hour > 12)
5717  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
5718  else
5719  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
5720  res = wait_file(chan, ints, nextmsg, lang);
5721  if (!res)
5722  res = wait_file(chan, ints, "digits/oclock", lang);
5723  break;
5724  case 'H':
5725  case 'k':
5726  /* 24-Hour */
5727  res = ast_say_number(chan, tm.tm_hour, ints, lang, (char * ) NULL);
5728  if (!res)
5729  res = wait_file(chan, ints, "digits/oclock", lang);
5730  break;
5731  case 'M':
5732  /* Minute */
5733  if (tm.tm_min == 0) {
5734  break;
5735  }
5736  res = ast_say_number(chan, tm.tm_min, ints, lang, (char * ) NULL);
5737  break;
5738  case 'P':
5739  case 'p':
5740  /* AM/PM */
5741  if (tm.tm_hour > 11)
5742  ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
5743  else
5744  ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
5745  res = wait_file(chan, ints, nextmsg, lang);
5746  break;
5747  case 'Q':
5748  /* Shorthand for "Today", "Yesterday", or AdBY */
5749  /* XXX As emphasized elsewhere, this should the native way in your
5750  * language to say the date, with changes in what you say, depending
5751  * upon how recent the date is. XXX */
5752  {
5753  struct timeval now = ast_tvnow();
5754  struct ast_tm tmnow;
5755  time_t beg_today;
5756 
5757  ast_localtime(&now, &tmnow, tzone);
5758  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5759  /* In any case, it saves not having to do ast_mktime() */
5760  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5761  if (beg_today < t) {
5762  /* Today */
5763  res = wait_file(chan, ints, "digits/today", lang);
5764  } else if (beg_today - 86400 < t) {
5765  /* Yesterday */
5766  res = wait_file(chan, ints, "digits/yesterday", lang);
5767  } else {
5768  res = ast_say_date_with_format_fr(chan, t, ints, lang, "AdBY", tzone);
5769  }
5770  }
5771  break;
5772  case 'q':
5773  /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
5774  /* XXX As emphasized elsewhere, this should the native way in your
5775  * language to say the date, with changes in what you say, depending
5776  * upon how recent the date is. XXX */
5777  {
5778  struct timeval now = ast_tvnow();
5779  struct ast_tm tmnow;
5780  time_t beg_today;
5781 
5782  ast_localtime(&now, &tmnow, tzone);
5783  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5784  /* In any case, it saves not having to do ast_mktime() */
5785  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5786  if (beg_today < t) {
5787  /* Today */
5788  } else if ((beg_today - 86400) < t) {
5789  /* Yesterday */
5790  res = wait_file(chan, ints, "digits/yesterday", lang);
5791  } else if (beg_today - 86400 * 6 < t) {
5792  /* Within the last week */
5793  res = ast_say_date_with_format_fr(chan, t, ints, lang, "A", tzone);
5794  } else {
5795  res = ast_say_date_with_format_fr(chan, t, ints, lang, "AdBY", tzone);
5796  }
5797  }
5798  break;
5799  case 'R':
5800  res = ast_say_date_with_format_fr(chan, t, ints, lang, "HM", tzone);
5801  break;
5802  case 'S':
5803  /* Seconds */
5804  res = ast_say_number(chan, tm.tm_sec, ints, lang, (char * ) NULL);
5805  if (!res) {
5806  res = wait_file(chan, ints, "second", lang);
5807  }
5808  break;
5809  case 'T':
5810  res = ast_say_date_with_format_fr(chan, t, ints, lang, "HMS", tzone);
5811  break;
5812  case ' ':
5813  case ' ':
5814  /* Just ignore spaces and tabs */
5815  break;
5816  default:
5817  /* Unknown character */
5818  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
5819  }
5820  /* Jump out on DTMF */
5821  if (res) {
5822  break;
5823  }
5824  }
5825  return res;
5826 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static snd_pcm_format_t format
Definition: chan_alsa.c:102
static int ast_say_date_with_format_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
French syntax oclock = heure.
Definition: say.c:5633

◆ ast_say_date_with_format_gr()

static int ast_say_date_with_format_gr ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Greek support.

Definition at line 8455 of file say.c.

References ast_channel_language(), ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_number_full_gr(), ast_streamfile(), ast_tvnow(), ast_waitstream(), gr_say_number_female(), LOG_WARNING, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

8456 {
8457  struct timeval when = { t, 0 };
8458  struct ast_tm tm;
8459  int res=0, offset, sndoffset;
8460  char sndfile[256], nextmsg[256];
8461 
8462  if (!format)
8463  format = "AdBY 'digits/at' IMp";
8464 
8465  ast_localtime(&when, &tm, tzone);
8466 
8467  for (offset=0 ; format[offset] != '\0' ; offset++) {
8468  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
8469  switch (format[offset]) {
8470  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
8471  case '\'':
8472  /* Literal name of a sound file */
8473  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
8474  sndfile[sndoffset] = format[offset];
8475  }
8476  sndfile[sndoffset] = '\0';
8477  res = wait_file(chan, ints, sndfile, lang);
8478  break;
8479  case 'A':
8480  case 'a':
8481  /* Sunday - Saturday */
8482  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
8483  res = wait_file(chan, ints, nextmsg, lang);
8484  break;
8485  case 'B':
8486  case 'b':
8487  case 'h':
8488  /* January - December */
8489  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
8490  res = wait_file(chan, ints, nextmsg, lang);
8491  break;
8492  case 'd':
8493  case 'e':
8494  /* first - thirtyfirst */
8495  gr_say_number_female(tm.tm_mday, chan, ints, lang);
8496  break;
8497  case 'Y':
8498  /* Year */
8499 
8500  ast_say_number_full_gr(chan, 1900+tm.tm_year, ints, ast_channel_language(chan), -1, -1);
8501  break;
8502  case 'I':
8503  case 'l':
8504  /* 12-Hour */
8505  if (tm.tm_hour == 0)
8506  gr_say_number_female(12, chan, ints, lang);
8507  else if (tm.tm_hour > 12)
8508  gr_say_number_female(tm.tm_hour - 12, chan, ints, lang);
8509  else
8510  gr_say_number_female(tm.tm_hour, chan, ints, lang);
8511  break;
8512  case 'H':
8513  case 'k':
8514  /* 24-Hour */
8515  gr_say_number_female(tm.tm_hour, chan, ints, lang);
8516  break;
8517  case 'M':
8518  /* Minute */
8519  if (tm.tm_min) {
8520  if (!res)
8521  res = ast_streamfile(chan, "digits/kai", lang);
8522  if (!res)
8523  res = ast_waitstream(chan, ints);
8524  if (!res)
8525  res = ast_say_number_full_gr(chan, tm.tm_min, ints, lang, -1, -1);
8526  } else {
8527  if (!res)
8528  res = ast_streamfile(chan, "digits/oclock", lang);
8529  if (!res)
8530  res = ast_waitstream(chan, ints);
8531  }
8532  break;
8533  case 'P':
8534  case 'p':
8535  /* AM/PM */
8536  if (tm.tm_hour > 11)
8537  ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
8538  else
8539  ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
8540  res = wait_file(chan, ints, nextmsg, lang);
8541  break;
8542  case 'Q':
8543  /* Shorthand for "Today", "Yesterday", or ABdY */
8544  /* XXX As emphasized elsewhere, this should the native way in your
8545  * language to say the date, with changes in what you say, depending
8546  * upon how recent the date is. XXX */
8547  {
8548  struct timeval now = ast_tvnow();
8549  struct ast_tm tmnow;
8550  time_t beg_today;
8551 
8552  ast_localtime(&now, &tmnow, tzone);
8553  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
8554  /* In any case, it saves not having to do ast_mktime() */
8555  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
8556  if (beg_today < t) {
8557  /* Today */
8558  res = wait_file(chan, ints, "digits/today", lang);
8559  } else if (beg_today - 86400 < t) {
8560  /* Yesterday */
8561  res = wait_file(chan, ints, "digits/yesterday", lang);
8562  } else {
8563  res = ast_say_date_with_format_gr(chan, t, ints, lang, "AdBY", tzone);
8564  }
8565  }
8566  break;
8567  case 'q':
8568  /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
8569  /* XXX As emphasized elsewhere, this should the native way in your
8570  * language to say the date, with changes in what you say, depending
8571  * upon how recent the date is. XXX */
8572  {
8573  struct timeval now = ast_tvnow();
8574  struct ast_tm tmnow;
8575  time_t beg_today;
8576 
8577  ast_localtime(&now, &tmnow, tzone);
8578  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
8579  /* In any case, it saves not having to do ast_mktime() */
8580  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
8581  if (beg_today < t) {
8582  /* Today */
8583  } else if ((beg_today - 86400) < t) {
8584  /* Yesterday */
8585  res = wait_file(chan, ints, "digits/yesterday", lang);
8586  } else if (beg_today - 86400 * 6 < t) {
8587  /* Within the last week */
8588  res = ast_say_date_with_format_gr(chan, t, ints, lang, "A", tzone);
8589  } else {
8590  res = ast_say_date_with_format_gr(chan, t, ints, lang, "AdBY", tzone);
8591  }
8592  }
8593  break;
8594  case 'R':
8595  res = ast_say_date_with_format_gr(chan, t, ints, lang, "HM", tzone);
8596  break;
8597  case 'S':
8598  /* Seconds */
8599  ast_copy_string(nextmsg, "digits/kai", sizeof(nextmsg));
8600  res = wait_file(chan, ints, nextmsg, lang);
8601  if (!res)
8602  res = ast_say_number_full_gr(chan, tm.tm_sec, ints, lang, -1, -1);
8603  if (!res)
8604  ast_copy_string(nextmsg, "seconds", sizeof(nextmsg));
8605  res = wait_file(chan, ints, nextmsg, lang);
8606  break;
8607  case 'T':
8608  res = ast_say_date_with_format_gr(chan, t, ints, lang, "HMS", tzone);
8609  break;
8610  case ' ':
8611  case ' ':
8612  /* Just ignore spaces and tabs */
8613  break;
8614  default:
8615  /* Unknown character */
8616  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
8617  }
8618  /* Jump out on DTMF */
8619  if (res) {
8620  break;
8621  }
8622  }
8623  return res;
8624 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
Greek support A list of the files that you need to create -> digits/xilia = "xilia" -> digits/myrio =...
Definition: say.c:8036
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
static int ast_say_date_with_format_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Greek support.
Definition: say.c:8455
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
const char * ast_channel_language(const struct ast_channel *chan)
static snd_pcm_format_t format
Definition: chan_alsa.c:102
static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang)
Greek digits/female-[1..4] : "Mia, dyo , treis, tessereis".
Definition: say.c:7991

◆ ast_say_date_with_format_he()

int ast_say_date_with_format_he ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

ast_say_date_with_format_he Say formatted date in Hebrew

ast_say_date_with_format_en for the details of the options

Changes from the English version:

  • don't replicate in here the logic of ast_say_number_full_he
  • year is always 4-digit (because it's simpler)
  • added c, x, and X. Mainly for my tests
  • The standard "long" format used in Hebrew is AdBY, rather than ABdY
Todo:
  • A "ha" is missing in the standard date format, before the 'd'.
  • The numbers of 3000–19000 are not handled well

Definition at line 5295 of file say.c.

References ast_debug, ast_localtime(), ast_log, ast_say_number_full_he(), ast_tvnow(), IL_DATE_STR, IL_DATE_STR_FULL, IL_TIME_STR, LOG_WARNING, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

5296 {
5297 #define IL_DATE_STR "AdBY"
5298 #define IL_TIME_STR "HM" /* NOTE: In Hebrew we do not support 12 hours, only 24. No AM or PM exists in the Hebrew language */
5299 #define IL_DATE_STR_FULL IL_DATE_STR " 'digits/at' " IL_TIME_STR
5300  /* TODO: This whole function is cut&paste from
5301  * ast_say_date_with_format_en . Is that considered acceptable?
5302  **/
5303  struct timeval when = { t, 0 };
5304  struct ast_tm tm;
5305  int res = 0, offset, sndoffset;
5306  char sndfile[256], nextmsg[256];
5307 
5308  if (!format) {
5310  }
5311 
5312  ast_localtime(&when, &tm, tzone);
5313 
5314  for (offset = 0; format[offset] != '\0'; offset++) {
5315  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
5316  switch (format[offset]) {
5317  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
5318  case '\'':
5319  /* Literal name of a sound file */
5320  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
5321  sndfile[sndoffset] = format[offset];
5322  }
5323  sndfile[sndoffset] = '\0';
5324  res = wait_file(chan, ints, sndfile, lang);
5325  break;
5326  case 'A':
5327  case 'a':
5328  /* Sunday - Saturday */
5329  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
5330  res = wait_file(chan, ints, nextmsg, lang);
5331  break;
5332  case 'B':
5333  case 'b':
5334  case 'h':
5335  /* January - December */
5336  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
5337  res = wait_file(chan, ints, nextmsg, lang);
5338  break;
5339  case 'd':
5340  case 'e': /* Day of the month */
5341  /* I'm not sure exactly what the parameters
5342  * audiofd and ctrlfd to
5343  * ast_say_number_full_he mean, but it seems
5344  * safe to pass -1 there.
5345  *
5346  * At least in one of the pathes :-(
5347  */
5348  res = ast_say_number_full_he(chan, tm.tm_mday, ints, lang, "m", -1, -1);
5349  break;
5350  case 'Y': /* Year */
5351  res = ast_say_number_full_he(chan, tm.tm_year + 1900, ints, lang, "f", -1, -1);
5352  break;
5353  case 'I':
5354  case 'l': /* 12-Hour -> we do not support 12 hour based langauges in Hebrew */
5355  case 'H':
5356  case 'k': /* 24-Hour */
5357  res = ast_say_number_full_he(chan, tm.tm_hour, ints, lang, "f", -1, -1);
5358  break;
5359  case 'M': /* Minute */
5360  if (tm.tm_min >= 0 && tm.tm_min <= 9) /* say a leading zero if needed */
5361  res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
5362  res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
5363  break;
5364  case 'P':
5365  case 'p':
5366  /* AM/PM - There is no AM/PM in Hebrew... */
5367  break;
5368  case 'Q':
5369  /* Shorthand for "Today", "Yesterday", or "date" */
5370  case 'q':
5371  /* Shorthand for "" (today), "Yesterday", A
5372  * (weekday), or "date" */
5373  /* XXX As emphasized elsewhere, this should the native way in your
5374  * language to say the date, with changes in what you say, depending
5375  * upon how recent the date is. XXX */
5376  {
5377  struct timeval now = ast_tvnow();
5378  struct ast_tm tmnow;
5379  time_t beg_today;
5380  char todo = format[offset]; /* The letter to format*/
5381 
5382  ast_localtime(&now, &tmnow, tzone);
5383  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5384  /* In any case, it saves not having to do ast_mktime() */
5385  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5386  if (beg_today < t) {
5387  /* Today */
5388  if (todo == 'Q') {
5389  res = wait_file(chan, ints, "digits/today", lang);
5390  }
5391  } else if (beg_today - 86400 < t) {
5392  /* Yesterday */
5393  res = wait_file(chan, ints, "digits/yesterday", lang);
5394  } else if ((todo != 'Q') && (beg_today - 86400 * 6 < t)) {
5395  /* Within the last week */
5396  res = ast_say_date_with_format_he(chan, t, ints, lang, "A", tzone);
5397  } else {
5398  res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
5399  }
5400  }
5401  break;
5402  case 'R':
5403  res = ast_say_date_with_format_he(chan, t, ints, lang, "HM", tzone);
5404  break;
5405  case 'S': /* Seconds */
5406  res = ast_say_number_full_he(chan, tm.tm_sec,
5407  ints, lang, "f", -1, -1
5408  );
5409  break;
5410  case 'T':
5411  res = ast_say_date_with_format_he(chan, t, ints, lang, "HMS", tzone);
5412  break;
5413  /* c, x, and X seem useful for testing. Not sure
5414  * if they're good for the general public */
5415  case 'c':
5416  res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR_FULL, tzone);
5417  break;
5418  case 'x':
5419  res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
5420  break;
5421  case 'X': /* Currently not locale-dependent...*/
5422  res = ast_say_date_with_format_he(chan, t, ints, lang, IL_TIME_STR, tzone);
5423  break;
5424  case ' ':
5425  case ' ':
5426  /* Just ignore spaces and tabs */
5427  break;
5428  default:
5429  /* Unknown character */
5430  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
5431  }
5432  /* Jump out on DTMF */
5433  if (res) {
5434  break;
5435  }
5436  }
5437  return res;
5438 }
#define IL_DATE_STR_FULL
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
static int ast_say_number_full_he(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
Definition: say.c:1447
#define IL_DATE_STR
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int ast_say_date_with_format_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
ast_say_date_with_format_he Say formatted date in Hebrew
Definition: say.c:5295
#define IL_TIME_STR
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_is()

int ast_say_date_with_format_is ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Definition at line 4898 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_enumeration(), ast_say_number(), ast_tvnow(), LOG_WARNING, next_item(), NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

4899 {
4900  struct timeval when = { t, 0 };
4901  struct ast_tm tm;
4902  int res=0, offset, sndoffset;
4903  char sndfile[256], nextmsg[256];
4904 
4905  if (!format)
4906  format = "A dBY HMS";
4907 
4908  ast_localtime(&when, &tm, tzone);
4909 
4910  for (offset=0 ; format[offset] != '\0' ; offset++) {
4911  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
4912  switch (format[offset]) {
4913  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
4914  case '\'':
4915  /* Literal name of a sound file */
4916  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
4917  sndfile[sndoffset] = format[offset];
4918  }
4919  sndfile[sndoffset] = '\0';
4920  res = wait_file(chan, ints, sndfile, lang);
4921  break;
4922  case 'A':
4923  case 'a':
4924  /* Sunday - Saturday */
4925  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
4926  res = wait_file(chan, ints, nextmsg, lang);
4927  break;
4928  case 'B':
4929  case 'b':
4930  case 'h':
4931  /* January - December */
4932  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
4933  res = wait_file(chan, ints, nextmsg, lang);
4934  break;
4935  case 'm':
4936  /* Month enumerated */
4937  res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
4938  break;
4939  case 'd':
4940  case 'e':
4941  /* First - Thirtyfirst */
4942  res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
4943  break;
4944  case 'Y':
4945  /* Year */
4946  {
4947  int year = tm.tm_year + 1900;
4948  if (year > 1999) { /* year 2000 and later */
4949  res = ast_say_number(chan, year, ints, lang, (char *) NULL);
4950  } else {
4951  if (year < 1100) {
4952  /* I'm not going to handle 1100 and prior */
4953  /* We'll just be silent on the year, instead of bombing out. */
4954  } else {
4955  /* year 1100 to 1999. will anybody need this?!? */
4956  /* say 1967 as 'nineteen hundred seven and sixty' */
4957  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
4958  res = wait_file(chan, ints, nextmsg, lang);
4959  if (!res) {
4960  res = wait_file(chan, ints, "digits/hundred", lang);
4961  if (!res && year % 100 != 0) {
4962  res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
4963  }
4964  }
4965  }
4966  }
4967  }
4968  break;
4969  case 'I':
4970  case 'l':
4971  /* 12-Hour */
4972  res = wait_file(chan, ints, "digits/oclock", lang);
4973  if (tm.tm_hour == 0)
4974  ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
4975  else if (tm.tm_hour > 12)
4976  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
4977  else
4978  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
4979  if (!res) {
4980  res = wait_file(chan, ints, nextmsg, lang);
4981  }
4982  break;
4983  case 'H':
4984  /* 24-Hour, single digit hours preceeded by "oh" (0) */
4985  if (tm.tm_hour < 10 && tm.tm_hour > 0) {
4986  res = wait_file(chan, ints, "digits/0", lang);
4987  }
4988  /* FALLTRHU */
4989  case 'k':
4990  /* 24-Hour */
4991  res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
4992  break;
4993  case 'M':
4994  /* Minute */
4995  if (tm.tm_min > 0 || next_item(&format[offset + 1]) == 'S') { /* zero 'digits/0' only if seconds follow */
4996  if (tm.tm_min < 10)
4997  res = wait_file(chan, ints, "digits/0", lang);
4998  /* Gender depends on whether or not seconds follow */
4999  if (next_item(&format[offset + 1]) == 'S')
5000  res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
5001  else
5002  res = ast_say_number(chan, tm.tm_min, ints, lang, "n");
5003  }
5004  if (!res && next_item(&format[offset + 1]) == 'S') { /* minutes only if seconds follow */
5005  /* Say minute/minutes depending on whether minutes end in 1 */
5006  if ((tm.tm_min % 10 == 1) && (tm.tm_min != 11)) {
5007  res = wait_file(chan, ints, "minute", lang);
5008  } else {
5009  res = wait_file(chan, ints, "minutes", lang);
5010  }
5011  }
5012  break;
5013  case 'P':
5014  case 'p':
5015  /* AM/PM */
5016  if (tm.tm_hour > 11)
5017  ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
5018  else
5019  ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
5020  res = wait_file(chan, ints, nextmsg, lang);
5021  break;
5022  case 'Q':
5023  /* Shorthand for "Today", "Yesterday", or AdBY */
5024  /* XXX As emphasized elsewhere, this should the native way in your
5025  * language to say the date, with changes in what you say, depending
5026  * upon how recent the date is. XXX */
5027  {
5028  struct timeval now = ast_tvnow();
5029  struct ast_tm tmnow;
5030  time_t beg_today;
5031 
5032  ast_localtime(&now, &tmnow, tzone);
5033  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5034  /* In any case, it saves not having to do ast_mktime() */
5035  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5036  if (beg_today < t) {
5037  /* Today */
5038  res = wait_file(chan, ints, "digits/today", lang);
5039  } else if (beg_today - 86400 < t) {
5040  /* Yesterday */
5041  res = wait_file(chan, ints, "digits/yesterday", lang);
5042  } else {
5043  res = ast_say_date_with_format_is(chan, t, ints, lang, "AdBY", tzone);
5044  }
5045  }
5046  break;
5047  case 'q':
5048  /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
5049  /* XXX As emphasized elsewhere, this should the native way in your
5050  * language to say the date, with changes in what you say, depending
5051  * upon how recent the date is. XXX */
5052  {
5053  struct timeval now = ast_tvnow();
5054  struct ast_tm tmnow;
5055  time_t beg_today;
5056 
5057  ast_localtime(&now, &tmnow, tzone);
5058  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5059  /* In any case, it saves not having to do ast_mktime() */
5060  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5061  if (beg_today < t) {
5062  /* Today */
5063  } else if ((beg_today - 86400) < t) {
5064  /* Yesterday */
5065  res = wait_file(chan, ints, "digits/yesterday", lang);
5066  } else if (beg_today - 86400 * 6 < t) {
5067  /* Within the last week */
5068  res = ast_say_date_with_format_is(chan, t, ints, lang, "A", tzone);
5069  } else {
5070  res = ast_say_date_with_format_is(chan, t, ints, lang, "AdBY", tzone);
5071  }
5072  }
5073  break;
5074  case 'R':
5075  res = ast_say_date_with_format_is(chan, t, ints, lang, "HM", tzone);
5076  break;
5077  case 'S':
5078  /* Seconds */
5079  res = wait_file(chan, ints, "digits/and", lang);
5080  if (!res) {
5081  res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
5082  /* Say minute/minutes depending on whether seconds end in 1 */
5083  if (!res && (tm.tm_sec % 10 == 1) && (tm.tm_sec != 11)) {
5084  res = wait_file(chan, ints, "second", lang);
5085  } else {
5086  res = wait_file(chan, ints, "seconds", lang);
5087  }
5088  }
5089  break;
5090  case 'T':
5091  res = ast_say_date_with_format_is(chan, t, ints, lang, "HMS", tzone);
5092  break;
5093  case ' ':
5094  case ' ':
5095  /* Just ignore spaces and tabs */
5096  break;
5097  default:
5098  /* Unknown character */
5099  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
5100  }
5101  /* Jump out on DTMF */
5102  if (res) {
5103  break;
5104  }
5105  }
5106  return res;
5107 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static char next_item(const char *format)
Definition: say.c:4486
static int ast_say_date_with_format_is(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Definition: say.c:4898
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says an enumeration
Definition: channel.c:8343
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_it()

int ast_say_date_with_format_it ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Italian syntax.

Definition at line 5829 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_number(), ast_tvnow(), LOG_WARNING, NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

5830 {
5831  struct timeval when = { t, 0 };
5832  struct ast_tm tm;
5833  int res=0, offset, sndoffset;
5834  char sndfile[256], nextmsg[256];
5835 
5836  if (format == NULL)
5837  format = "AdB 'digits/at' IMp";
5838 
5839  ast_localtime(&when, &tm, tzone);
5840 
5841  for (offset=0 ; format[offset] != '\0' ; offset++) {
5842  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
5843  switch (format[offset]) {
5844  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
5845  case '\'':
5846  /* Literal name of a sound file */
5847  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
5848  sndfile[sndoffset] = format[offset];
5849  }
5850  sndfile[sndoffset] = '\0';
5851  res = wait_file(chan, ints, sndfile, lang);
5852  break;
5853  case 'A':
5854  case 'a':
5855  /* Sunday - Saturday */
5856  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
5857  res = wait_file(chan, ints, nextmsg, lang);
5858  break;
5859  case 'B':
5860  case 'b':
5861  case 'h':
5862  /* January - December */
5863  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
5864  res = wait_file(chan, ints, nextmsg, lang);
5865  break;
5866  case 'm':
5867  /* First - Twelfth */
5868  snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
5869  res = wait_file(chan, ints, nextmsg, lang);
5870  break;
5871  case 'd':
5872  case 'e':
5873  /* First day of the month is spelled as ordinal */
5874  if (tm.tm_mday == 1) {
5875  snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
5876  res = wait_file(chan, ints, nextmsg, lang);
5877  } else {
5878  if (!res) {
5879  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
5880  }
5881  }
5882  break;
5883  case 'Y':
5884  /* Year */
5885  if (tm.tm_year > 99) {
5886  res = wait_file(chan, ints, "digits/ore-2000", lang);
5887  if (tm.tm_year > 100) {
5888  if (!res) {
5889  /* This works until the end of 2021 */
5890  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
5891  res = wait_file(chan, ints, nextmsg, lang);
5892  }
5893  }
5894  } else {
5895  if (tm.tm_year < 1) {
5896  /* I'm not going to handle 1900 and prior */
5897  /* We'll just be silent on the year, instead of bombing out. */
5898  } else {
5899  res = wait_file(chan, ints, "digits/ore-1900", lang);
5900  if ((!res) && (tm.tm_year != 0)) {
5901  if (tm.tm_year <= 21) {
5902  /* 1910 - 1921 */
5903  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
5904  res = wait_file(chan, ints, nextmsg, lang);
5905  } else {
5906  /* 1922 - 1999, but sounds badly in 1928, 1931, 1938, etc... */
5907  int ten, one;
5908  ten = tm.tm_year / 10;
5909  one = tm.tm_year % 10;
5910  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten * 10);
5911  res = wait_file(chan, ints, nextmsg, lang);
5912  if (!res) {
5913  if (one != 0) {
5914  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
5915  res = wait_file(chan, ints, nextmsg, lang);
5916  }
5917  }
5918  }
5919  }
5920  }
5921  }
5922  break;
5923  case 'I':
5924  case 'l':
5925  /* 12-Hour */
5926  if (tm.tm_hour == 0) {
5927  ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
5928  } else if (tm.tm_hour > 12) {
5929  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
5930  } else {
5931  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
5932  }
5933  res = wait_file(chan, ints, nextmsg, lang);
5934  break;
5935  case 'H':
5936  case 'k':
5937  /* 24-Hour */
5938  if (tm.tm_hour == 0) {
5939  res = wait_file(chan, ints, "digits/ore-mezzanotte", lang);
5940  } else if (tm.tm_hour == 1) {
5941  res = wait_file(chan, ints, "digits/ore-una", lang);
5942  } else {
5943  res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
5944  }
5945  break;
5946  case 'M':
5947  /* Minute */
5948  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
5949  break;
5950  case 'P':
5951  case 'p':
5952  /* AM/PM */
5953  if (tm.tm_hour > 11) {
5954  ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
5955  } else {
5956  ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
5957  }
5958  res = wait_file(chan, ints, nextmsg, lang);
5959  break;
5960  case 'Q':
5961  /* Shorthand for "Today", "Yesterday", or ABdY */
5962  /* XXX As emphasized elsewhere, this should the native way in your
5963  * language to say the date, with changes in what you say, depending
5964  * upon how recent the date is. XXX */
5965  {
5966  struct timeval now = ast_tvnow();
5967  struct ast_tm tmnow;
5968  time_t beg_today;
5969 
5970  ast_localtime(&now, &tmnow, tzone);
5971  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5972  /* In any case, it saves not having to do ast_mktime() */
5973  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5974  if (beg_today < t) {
5975  /* Today */
5976  res = wait_file(chan, ints, "digits/today", lang);
5977  } else if (beg_today - 86400 < t) {
5978  /* Yesterday */
5979  res = wait_file(chan, ints, "digits/yesterday", lang);
5980  } else {
5981  res = ast_say_date_with_format_it(chan, t, ints, lang, "AdB", tzone);
5982  }
5983  }
5984  break;
5985  case 'q':
5986  /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
5987  {
5988  struct timeval now = ast_tvnow();
5989  struct ast_tm tmnow;
5990  time_t beg_today;
5991 
5992  ast_localtime(&now, &tmnow, tzone);
5993  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5994  /* In any case, it saves not having to do ast_mktime() */
5995  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5996  if (beg_today < t) {
5997  /* Today */
5998  } else if ((beg_today - 86400) < t) {
5999  /* Yesterday */
6000  res = wait_file(chan, ints, "digits/yesterday", lang);
6001  } else if (beg_today - 86400 * 6 < t) {
6002  /* Within the last week */
6003  res = ast_say_date_with_format_it(chan, t, ints, lang, "A", tzone);
6004  } else {
6005  res = ast_say_date_with_format_it(chan, t, ints, lang, "AdB", tzone);
6006  }
6007  }
6008  break;
6009  case 'R':
6010  res = ast_say_date_with_format_it(chan, t, ints, lang, "HM", tzone);
6011  break;
6012  case 'S':
6013  /* Seconds */
6014  if (tm.tm_sec == 0) {
6015  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6016  res = wait_file(chan, ints, nextmsg, lang);
6017  } else if (tm.tm_sec < 10) {
6018  res = wait_file(chan, ints, "digits/oh", lang);
6019  if (!res) {
6020  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6021  res = wait_file(chan, ints, nextmsg, lang);
6022  }
6023  } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
6024  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6025  res = wait_file(chan, ints, nextmsg, lang);
6026  } else {
6027  int ten, one;
6028  ten = (tm.tm_sec / 10) * 10;
6029  one = (tm.tm_sec % 10);
6030  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
6031  res = wait_file(chan, ints, nextmsg, lang);
6032  if (!res) {
6033  /* Fifty, not fifty-zero */
6034  if (one != 0) {
6035  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
6036  res = wait_file(chan, ints, nextmsg, lang);
6037  }
6038  }
6039  }
6040  break;
6041  case 'T':
6042  res = ast_say_date_with_format_it(chan, t, ints, lang, "HMS", tzone);
6043  break;
6044  case ' ':
6045  case ' ':
6046  /* Just ignore spaces and tabs */
6047  break;
6048  default:
6049  /* Unknown character */
6050  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
6051  }
6052  /* Jump out on DTMF */
6053  if (res) {
6054  break;
6055  }
6056  }
6057  return res;
6058 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int ast_say_date_with_format_it(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Italian syntax.
Definition: say.c:5829
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_ja()

int ast_say_date_with_format_ja ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Definition at line 8627 of file say.c.

References ast_localtime(), ast_log, ast_say_date_with_format, LOG_DEBUG, LOG_WARNING, NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

8628 {
8629  struct timeval tv = { time, 0 };
8630  struct ast_tm tm;
8631  int res = 0, offset, sndoffset;
8632  char sndfile[256], nextmsg[256];
8633 
8634  if (!format)
8635  format = "YbdAPIMS";
8636 
8637  ast_localtime(&tv, &tm, timezone);
8638 
8639  for (offset = 0; format[offset] != '\0'; offset++) {
8640  ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
8641  switch (format[offset]) {
8642  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
8643  case '\'':
8644  /* Literal name of a sound file */
8645  for (sndoffset = 0; (format[++offset] != '\'') && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
8646  sndfile[sndoffset] = format[offset];
8647  }
8648  sndfile[sndoffset] = '\0';
8649  res = wait_file(chan,ints,sndfile,lang);
8650  break;
8651  case 'A':
8652  case 'a':
8653  /* Sunday - Saturday */
8654  snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
8655  res = wait_file(chan,ints,nextmsg,lang);
8656  break;
8657  case 'B':
8658  case 'b':
8659  case 'h':
8660  /* January - December */
8661  snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
8662  res = wait_file(chan,ints,nextmsg,lang);
8663  break;
8664  case 'd':
8665  case 'e':
8666  /* First - Thirtyfirst */
8667  if (tm.tm_mday < 21) {
8668  snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d_2", tm.tm_mday);
8669  res = wait_file(chan,ints,nextmsg,lang);
8670  } else if (tm.tm_mday < 30) {
8671  /* Between 21 and 29 - two sounds */
8672  res = wait_file(chan,ints, "digits/20",lang);
8673  if (!res) {
8674  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_mday - 20);
8675  res = wait_file(chan,ints,nextmsg,lang);
8676  }
8677  res = wait_file(chan,ints, "digits/nichi",lang);
8678  } else if (tm.tm_mday == 30) {
8679  /* 30 */
8680  res = wait_file(chan,ints, "digits/h-30_2",lang);
8681  } else {
8682  /* 31 */
8683  res = wait_file(chan,ints, "digits/30",lang);
8684  res = wait_file(chan,ints, "digits/1",lang);
8685  res = wait_file(chan,ints, "digits/nichi",lang);
8686  }
8687  break;
8688  case 'Y':
8689  /* Year */
8690  if (tm.tm_year > 99) {
8691  res = wait_file(chan,ints, "digits/2",lang);
8692  if (!res) {
8693  res = wait_file(chan,ints, "digits/thousand",lang);
8694  }
8695  if (tm.tm_year > 100) {
8696  if (!res) {
8697  /* This works until the end of 2020 */
8698  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
8699  res = wait_file(chan,ints,nextmsg,lang);
8700  }
8701  }
8702  } else {
8703  if (tm.tm_year < 1) {
8704  /* I'm not going to handle 1900 and prior */
8705  /* We'll just be silent on the year, instead of bombing out. */
8706  } else {
8707  res = wait_file(chan,ints, "digits/19",lang);
8708  if (!res) {
8709  if (tm.tm_year <= 9) {
8710  /* 1901 - 1909 */
8711  res = wait_file(chan,ints, "digits/oh",lang);
8712  if (!res) {
8713  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
8714  res = wait_file(chan,ints,nextmsg,lang);
8715  }
8716  } else if (tm.tm_year <= 20) {
8717  /* 1910 - 1920 */
8718  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
8719  res = wait_file(chan,ints,nextmsg,lang);
8720  } else {
8721  /* 1921 - 1999 */
8722  int ten, one;
8723  ten = tm.tm_year / 10;
8724  one = tm.tm_year % 10;
8725  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten * 10);
8726  res = wait_file(chan,ints,nextmsg,lang);
8727  if (!res) {
8728  if (one != 0) {
8729  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
8730  res = wait_file(chan,ints,nextmsg,lang);
8731  }
8732  }
8733  }
8734  }
8735  }
8736  }
8737  res = wait_file(chan,ints, "digits/nen",lang);
8738  break;
8739  case 'P':
8740  case 'p':
8741  /* AM/PM */
8742  if (tm.tm_hour > 11)
8743  snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
8744  else
8745  snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
8746  res = wait_file(chan,ints,nextmsg,lang);
8747  break;
8748  case 'I':
8749  case 'l':
8750  /* 12-Hour */
8751  if (tm.tm_hour == 0)
8752  snprintf(nextmsg,sizeof(nextmsg), "digits/12");
8753  else if (tm.tm_hour == 9 || tm.tm_hour == 21)
8754  snprintf(nextmsg,sizeof(nextmsg), "digits/9_2");
8755  else if (tm.tm_hour > 12)
8756  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
8757  else
8758  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
8759  res = wait_file(chan,ints,nextmsg,lang);
8760  if(!res) res = wait_file(chan,ints, "digits/ji",lang);
8761  break;
8762  case 'H':
8763  case 'k':
8764  if (!res) {
8765  if (tm.tm_hour != 0) {
8766  int remainder = tm.tm_hour;
8767  if (tm.tm_hour > 20) {
8768  res = wait_file(chan,ints, "digits/20",lang);
8769  remainder -= 20;
8770  }
8771  if (!res) {
8772  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", remainder);
8773  res = wait_file(chan,ints,nextmsg,lang);
8774  }
8775  }
8776  }
8777  res = wait_file(chan,ints, "digits/ji",lang);
8778  break;
8779  case 'M':
8780  /* Minute */
8781  if ((tm.tm_min < 21) || (tm.tm_min % 10 == 0)) {
8782  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min);
8783  res = wait_file(chan,ints,nextmsg,lang);
8784  } else {
8785  int ten, one;
8786  ten = (tm.tm_min / 10) * 10;
8787  one = (tm.tm_min % 10);
8788  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
8789  res = wait_file(chan,ints,nextmsg,lang);
8790  if (!res) {
8791  /* Fifty, not fifty-zero */
8792  if (one != 0) {
8793  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
8794  res = wait_file(chan,ints,nextmsg,lang);
8795  }
8796  }
8797  }
8798  res = wait_file(chan,ints, "digits/fun",lang);
8799  break;
8800  case 'Q':
8801  /* Shorthand for "Today", "Yesterday", or ABdY */
8802  {
8803  struct timeval now;
8804  struct ast_tm tmnow;
8805  time_t beg_today;
8806 
8807  gettimeofday(&now,NULL);
8808  ast_localtime(&now,&tmnow,timezone);
8809  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
8810  /* In any case, it saves not having to do ast_mktime() */
8811  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
8812  if (beg_today < time) {
8813  /* Today */
8814  res = wait_file(chan,ints, "digits/today",lang);
8815  } else if (beg_today - 86400 < time) {
8816  /* Yesterday */
8817  res = wait_file(chan,ints, "digits/yesterday",lang);
8818  } else {
8819  res = ast_say_date_with_format(chan, time, ints, lang, "ABdY", timezone);
8820  }
8821  }
8822  break;
8823  case 'q':
8824  /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
8825  {
8826  struct timeval now;
8827  struct ast_tm tmnow;
8828  time_t beg_today;
8829 
8830  gettimeofday(&now,NULL);
8831  ast_localtime(&now,&tmnow,timezone);
8832  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
8833  /* In any case, it saves not having to do ast_mktime() */
8834  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
8835  if (beg_today < time) {
8836  /* Today */
8837  } else if ((beg_today - 86400) < time) {
8838  /* Yesterday */
8839  res = wait_file(chan,ints, "digits/yesterday",lang);
8840  } else if (beg_today - 86400 * 6 < time) {
8841  /* Within the last week */
8842  res = ast_say_date_with_format(chan, time, ints, lang, "A", timezone);
8843  } else {
8844  res = ast_say_date_with_format(chan, time, ints, lang, "ABdY", timezone);
8845  }
8846  }
8847  break;
8848  case 'R':
8849  res = ast_say_date_with_format(chan, time, ints, lang, "HM", timezone);
8850  break;
8851  case 'S':
8852  /* Seconds */
8853  if (tm.tm_sec == 0) {
8854  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
8855  res = wait_file(chan,ints,nextmsg,lang);
8856  } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
8857  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
8858  res = wait_file(chan,ints,nextmsg,lang);
8859  } else {
8860  int ten, one;
8861  ten = (tm.tm_sec / 10) * 10;
8862  one = (tm.tm_sec % 10);
8863  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
8864  res = wait_file(chan,ints,nextmsg,lang);
8865  if (!res) {
8866  /* Fifty, not fifty-zero */
8867  if (one != 0) {
8868  snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
8869  res = wait_file(chan,ints,nextmsg,lang);
8870  }
8871  }
8872  }
8873  res = wait_file(chan,ints, "digits/byou",lang);
8874  break;
8875  case 'T':
8876  res = ast_say_date_with_format(chan, time, ints, lang, "HMS", timezone);
8877  break;
8878  case ' ':
8879  case ' ':
8880  /* Just ignore spaces and tabs */
8881  break;
8882  default:
8883  /* Unknown character */
8884  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
8885  }
8886  /* Jump out on DTMF */
8887  if (res) {
8888  break;
8889  }
8890  }
8891  return res;
8892 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
#define LOG_DEBUG
Definition: logger.h:241
#define ast_log
Definition: astobj2.c:42
SAY_EXTERN int(* ast_say_date_with_format)(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezone) SAY_INIT(ast_say_date_with_format)
Definition: say.h:189
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_nl()

int ast_say_date_with_format_nl ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Dutch syntax.

Definition at line 6061 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_number(), ast_tvnow(), LOG_WARNING, NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

6062 {
6063  struct timeval when = { t, 0 };
6064  struct ast_tm tm;
6065  int res=0, offset, sndoffset;
6066  char sndfile[256], nextmsg[256];
6067 
6068  if (format == NULL)
6069  format = "AdBY 'digits/at' IMp";
6070 
6071  ast_localtime(&when, &tm, tzone);
6072 
6073  for (offset=0 ; format[offset] != '\0' ; offset++) {
6074  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
6075  switch (format[offset]) {
6076  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
6077  case '\'':
6078  /* Literal name of a sound file */
6079  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
6080  sndfile[sndoffset] = format[offset];
6081  }
6082  sndfile[sndoffset] = '\0';
6083  res = wait_file(chan, ints, sndfile, lang);
6084  break;
6085  case 'A':
6086  case 'a':
6087  /* Sunday - Saturday */
6088  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
6089  res = wait_file(chan, ints, nextmsg, lang);
6090  break;
6091  case 'B':
6092  case 'b':
6093  case 'h':
6094  /* January - December */
6095  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
6096  res = wait_file(chan, ints, nextmsg, lang);
6097  break;
6098  case 'm':
6099  /* First - Twelfth */
6100  snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
6101  res = wait_file(chan, ints, nextmsg, lang);
6102  break;
6103  case 'd':
6104  case 'e':
6105  /* First - Thirtyfirst */
6106  res = ast_say_number(chan, tm.tm_mday, ints, lang, NULL);
6107  break;
6108  case 'Y':
6109  /* Year */
6110  if (tm.tm_year > 99) {
6111  res = wait_file(chan, ints, "digits/2", lang);
6112  if (!res) {
6113  res = wait_file(chan, ints, "digits/thousand", lang);
6114  }
6115  if (tm.tm_year > 100) {
6116  if (!res) {
6117  res = ast_say_number(chan, tm.tm_year - 100, ints, lang, (char *) NULL);
6118  }
6119  }
6120  } else {
6121  if (tm.tm_year < 1) {
6122  /* I'm not going to handle 1900 and prior */
6123  /* We'll just be silent on the year, instead of bombing out. */
6124  } else {
6125  res = wait_file(chan, ints, "digits/19", lang);
6126  if (!res) {
6127  if (tm.tm_year <= 9) {
6128  /* 1901 - 1909 */
6129  res = wait_file(chan, ints, "digits/oh", lang);
6130  if (!res) {
6131  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
6132  res = wait_file(chan, ints, nextmsg, lang);
6133  }
6134  } else if (tm.tm_year <= 20) {
6135  /* 1910 - 1920 */
6136  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
6137  res = wait_file(chan, ints, nextmsg, lang);
6138  } else {
6139  /* 1921 - 1999 */
6140  int ten, one;
6141  ten = tm.tm_year / 10;
6142  one = tm.tm_year % 10;
6143  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten * 10);
6144  res = wait_file(chan, ints, nextmsg, lang);
6145  if (!res) {
6146  if (one != 0) {
6147  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
6148  res = wait_file(chan, ints, nextmsg, lang);
6149  }
6150  }
6151  }
6152  }
6153  }
6154  }
6155  break;
6156  case 'I':
6157  case 'l':
6158  /* 12-Hour */
6159  if (tm.tm_hour == 0)
6160  ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
6161  else if (tm.tm_hour > 12)
6162  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
6163  else
6164  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
6165  res = wait_file(chan, ints, nextmsg, lang);
6166  break;
6167  case 'H':
6168  case 'k':
6169  /* 24-Hour */
6170  res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
6171  if (!res) {
6172  res = wait_file(chan, ints, "digits/nl-uur", lang);
6173  }
6174  break;
6175  case 'M':
6176  /* Minute */
6177  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
6178  break;
6179  case 'P':
6180  case 'p':
6181  /* AM/PM */
6182  if (tm.tm_hour > 11)
6183  ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
6184  else
6185  ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
6186  res = wait_file(chan, ints, nextmsg, lang);
6187  break;
6188  case 'Q':
6189  /* Shorthand for "Today", "Yesterday", or AdBY */
6190  /* XXX As emphasized elsewhere, this should the native way in your
6191  * language to say the date, with changes in what you say, depending
6192  * upon how recent the date is. XXX */
6193  {
6194  struct timeval now = ast_tvnow();
6195  struct ast_tm tmnow;
6196  time_t beg_today;
6197 
6198  ast_localtime(&now, &tmnow, tzone);
6199  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6200  /* In any case, it saves not having to do ast_mktime() */
6201  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6202  if (beg_today < t) {
6203  /* Today */
6204  res = wait_file(chan, ints, "digits/today", lang);
6205  } else if (beg_today - 86400 < t) {
6206  /* Yesterday */
6207  res = wait_file(chan, ints, "digits/yesterday", lang);
6208  } else {
6209  res = ast_say_date_with_format_nl(chan, t, ints, lang, "AdBY", tzone);
6210  }
6211  }
6212  break;
6213  case 'q':
6214  /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
6215  {
6216  struct timeval now = ast_tvnow();
6217  struct ast_tm tmnow;
6218  time_t beg_today;
6219 
6220  ast_localtime(&now, &tmnow, tzone);
6221  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6222  /* In any case, it saves not having to do ast_mktime() */
6223  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6224  if (beg_today < t) {
6225  /* Today */
6226  } else if ((beg_today - 86400) < t) {
6227  /* Yesterday */
6228  res = wait_file(chan, ints, "digits/yesterday", lang);
6229  } else if (beg_today - 86400 * 6 < t) {
6230  /* Within the last week */
6231  res = ast_say_date_with_format_nl(chan, t, ints, lang, "A", tzone);
6232  } else {
6233  res = ast_say_date_with_format_nl(chan, t, ints, lang, "AdBY", tzone);
6234  }
6235  }
6236  break;
6237  case 'R':
6238  res = ast_say_date_with_format_nl(chan, t, ints, lang, "HM", tzone);
6239  break;
6240  case 'S':
6241  /* Seconds */
6242  res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
6243  break;
6244  case 'T':
6245  res = ast_say_date_with_format_nl(chan, t, ints, lang, "HMS", tzone);
6246  break;
6247  case ' ':
6248  case ' ':
6249  /* Just ignore spaces and tabs */
6250  break;
6251  default:
6252  /* Unknown character */
6253  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
6254  }
6255  /* Jump out on DTMF */
6256  if (res) {
6257  break;
6258  }
6259  }
6260  return res;
6261 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
static int ast_say_date_with_format_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Dutch syntax.
Definition: say.c:6061
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_pl()

int ast_say_date_with_format_pl ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Polish syntax.

Definition at line 6264 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format, ast_say_enumeration(), ast_say_number(), ast_tvnow(), LOG_WARNING, NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

6265 {
6266  struct timeval when = { thetime, 0 };
6267  struct ast_tm tm;
6268  int res=0, offset, sndoffset;
6269  char sndfile[256], nextmsg[256];
6270 
6271  ast_localtime(&when, &tm, tzone);
6272 
6273  for (offset = 0 ; format[offset] != '\0' ; offset++) {
6274  int remaining;
6275  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
6276  switch (format[offset]) {
6277  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
6278  case '\'':
6279  /* Literal name of a sound file */
6280  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
6281  sndfile[sndoffset] = format[offset];
6282  }
6283  sndfile[sndoffset] = '\0';
6284  res = wait_file(chan, ints, sndfile, lang);
6285  break;
6286  case 'A':
6287  case 'a':
6288  /* Sunday - Saturday */
6289  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
6290  res = wait_file(chan, ints, nextmsg, lang);
6291  break;
6292  case 'B':
6293  case 'b':
6294  case 'h':
6295  /* January - December */
6296  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
6297  res = wait_file(chan, ints, nextmsg, lang);
6298  break;
6299  case 'm':
6300  /* Month enumerated */
6301  res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, NULL);
6302  break;
6303  case 'd':
6304  case 'e':
6305  /* First - Thirtyfirst */
6306  remaining = tm.tm_mday;
6307  if (tm.tm_mday > 30) {
6308  res = wait_file(chan, ints, "digits/h-30", lang);
6309  remaining -= 30;
6310  }
6311  if (tm.tm_mday > 20 && tm.tm_mday < 30) {
6312  res = wait_file(chan, ints, "digits/h-20", lang);
6313  remaining -= 20;
6314  }
6315  if (!res) {
6316  snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", remaining);
6317  res = wait_file(chan, ints, nextmsg, lang);
6318  }
6319  break;
6320  case 'Y':
6321  /* Year */
6322  if (tm.tm_year > 100) {
6323  res = wait_file(chan, ints, "digits/2", lang);
6324  if (!res)
6325  res = wait_file(chan, ints, "digits/1000.2", lang);
6326  if (tm.tm_year > 100) {
6327  if (!res)
6328  res = ast_say_enumeration(chan, tm.tm_year - 100, ints, lang, NULL);
6329  }
6330  } else if (tm.tm_year == 100) {
6331  res = wait_file(chan, ints, "digits/h-2000", lang);
6332  } else {
6333  if (tm.tm_year < 1) {
6334  /* I'm not going to handle 1900 and prior */
6335  /* We'll just be silent on the year, instead of bombing out. */
6336  break;
6337  } else {
6338  res = wait_file(chan, ints, "digits/1000", lang);
6339  if (!res) {
6340  wait_file(chan, ints, "digits/900", lang);
6341  res = ast_say_enumeration(chan, tm.tm_year, ints, lang, NULL);
6342  }
6343  }
6344  }
6345  if (!res)
6346  wait_file(chan, ints, "digits/year", lang);
6347  break;
6348  case 'I':
6349  case 'l':
6350  /* 12-Hour */
6351  if (tm.tm_hour == 0)
6352  ast_copy_string(nextmsg, "digits/t-12", sizeof(nextmsg));
6353  else if (tm.tm_hour > 12)
6354  snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour - 12);
6355  else
6356  snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
6357 
6358  res = wait_file(chan, ints, nextmsg, lang);
6359  break;
6360  case 'H':
6361  case 'k':
6362  /* 24-Hour */
6363  if (tm.tm_hour != 0) {
6364  snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
6365  res = wait_file(chan, ints, nextmsg, lang);
6366  } else
6367  res = wait_file(chan, ints, "digits/t-24", lang);
6368  break;
6369  case 'M':
6370  case 'N':
6371  /* Minute */
6372  if (tm.tm_min == 0) {
6373  if (format[offset] == 'M') {
6374  res = wait_file(chan, ints, "digits/oclock", lang);
6375  } else {
6376  res = wait_file(chan, ints, "digits/100", lang);
6377  }
6378  } else
6379  res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
6380  break;
6381  case 'P':
6382  case 'p':
6383  /* AM/PM */
6384  if (tm.tm_hour > 11)
6385  ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
6386  else
6387  ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
6388  res = wait_file(chan, ints, nextmsg, lang);
6389  break;
6390  case 'Q':
6391  /* Shorthand for "Today", "Yesterday", or AdBY */
6392  {
6393  struct timeval now = ast_tvnow();
6394  struct ast_tm tmnow;
6395  time_t beg_today;
6396 
6397  ast_localtime(&now, &tmnow, tzone);
6398  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6399  /* In any case, it saves not having to do ast_mktime() */
6400  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6401  if (beg_today < thetime) {
6402  /* Today */
6403  res = wait_file(chan, ints, "digits/today", lang);
6404  } else if (beg_today - 86400 < thetime) {
6405  /* Yesterday */
6406  res = wait_file(chan, ints, "digits/yesterday", lang);
6407  } else {
6408  res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", tzone);
6409  }
6410  }
6411  break;
6412  case 'q':
6413  /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
6414  {
6415  struct timeval now = ast_tvnow();
6416  struct ast_tm tmnow;
6417  time_t beg_today;
6418 
6419  ast_localtime(&now, &tmnow, tzone);
6420  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6421  /* In any case, it saves not having to do ast_mktime() */
6422  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6423  if (beg_today < thetime) {
6424  /* Today */
6425  } else if ((beg_today - 86400) < thetime) {
6426  /* Yesterday */
6427  res = wait_file(chan, ints, "digits/yesterday", lang);
6428  } else if (beg_today - 86400 * 6 < thetime) {
6429  /* Within the last week */
6430  res = ast_say_date_with_format(chan, thetime, ints, lang, "A", tzone);
6431  } else {
6432  res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", tzone);
6433  }
6434  }
6435  break;
6436  case 'R':
6437  res = ast_say_date_with_format(chan, thetime, ints, lang, "HM", tzone);
6438  break;
6439  case 'S':
6440  /* Seconds */
6441  res = wait_file(chan, ints, "digits/and", lang);
6442  if (!res) {
6443  if (tm.tm_sec == 1) {
6444  res = wait_file(chan, ints, "digits/1z", lang);
6445  if (!res)
6446  res = wait_file(chan, ints, "digits/second-a", lang);
6447  } else {
6448  res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
6449  if (!res) {
6450  int ten, one;
6451  ten = tm.tm_sec / 10;
6452  one = tm.tm_sec % 10;
6453 
6454  if (one > 1 && one < 5 && ten != 1)
6455  res = wait_file(chan, ints, "seconds", lang);
6456  else
6457  res = wait_file(chan, ints, "second", lang);
6458  }
6459  }
6460  }
6461  break;
6462  case 'T':
6463  res = ast_say_date_with_format(chan, thetime, ints, lang, "HMS", tzone);
6464  break;
6465  case ' ':
6466  case ' ':
6467  /* Just ignore spaces and tabs */
6468  break;
6469  default:
6470  /* Unknown character */
6471  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
6472  }
6473  /* Jump out on DTMF */
6474  if (res)
6475  break;
6476  }
6477  return res;
6478 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
SAY_EXTERN int(* ast_say_date_with_format)(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezone) SAY_INIT(ast_say_date_with_format)
Definition: say.h:189
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says an enumeration
Definition: channel.c:8343
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_pt()

int ast_say_date_with_format_pt ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Portuguese syntax.

Definition at line 6481 of file say.c.

References ast_debug, ast_localtime(), ast_log, ast_say_number(), ast_tvnow(), LOG_WARNING, NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

6482 {
6483  struct timeval when = { t, 0 };
6484  struct ast_tm tm;
6485  int res=0, offset, sndoffset;
6486  char sndfile[256], nextmsg[256];
6487 
6488  if (format == NULL)
6489  format = "Ad 'digits/pt-de' B 'digits/pt-de' Y I 'digits/pt-e' Mp";
6490 
6491  ast_localtime(&when, &tm, tzone);
6492 
6493  for (offset=0 ; format[offset] != '\0' ; offset++) {
6494  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
6495  switch (format[offset]) {
6496  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
6497  case '\'':
6498  /* Literal name of a sound file */
6499  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
6500  sndfile[sndoffset] = format[offset];
6501  }
6502  sndfile[sndoffset] = '\0';
6503  snprintf(nextmsg, sizeof(nextmsg), "%s", sndfile);
6504  res = wait_file(chan, ints, nextmsg, lang);
6505  break;
6506  case 'A':
6507  case 'a':
6508  /* Sunday - Saturday */
6509  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
6510  res = wait_file(chan, ints, nextmsg, lang);
6511  break;
6512  case 'B':
6513  case 'b':
6514  case 'h':
6515  /* January - December */
6516  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
6517  res = wait_file(chan, ints, nextmsg, lang);
6518  break;
6519  case 'm':
6520  /* First - Twelfth */
6521  if (!strcasecmp(lang, "pt_BR")) {
6522  res = ast_say_number(chan, tm.tm_mon+1, ints, lang, (char *) NULL);
6523  } else {
6524  snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
6525  res = wait_file(chan, ints, nextmsg, lang);
6526  }
6527  break;
6528  case 'd':
6529  case 'e':
6530  /* First - Thirtyfirst */
6531  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
6532  break;
6533  case 'Y':
6534  /* Year */
6535  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
6536  break;
6537  case 'I':
6538  case 'l':
6539  /* 12-Hour */
6540  if (!strcasecmp(lang, "pt_BR")) {
6541  if (tm.tm_hour == 0) {
6542  if (format[offset] == 'I')
6543  res = wait_file(chan, ints, "digits/pt-a", lang);
6544  if (!res)
6545  res = wait_file(chan, ints, "digits/pt-meianoite", lang);
6546  } else if (tm.tm_hour == 12) {
6547  if (format[offset] == 'I')
6548  res = wait_file(chan, ints, "digits/pt-ao", lang);
6549  if (!res)
6550  res = wait_file(chan, ints, "digits/pt-meiodia", lang);
6551  } else {
6552  if (format[offset] == 'I') {
6553  if ((tm.tm_hour % 12) != 1)
6554  res = wait_file(chan, ints, "digits/pt-as", lang);
6555  else
6556  res = wait_file(chan, ints, "digits/pt-a", lang);
6557  }
6558  if (!res)
6559  res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
6560  }
6561  } else {
6562  if (tm.tm_hour == 0) {
6563  if (format[offset] == 'I')
6564  res = wait_file(chan, ints, "digits/pt-ah", lang);
6565  if (!res)
6566  res = wait_file(chan, ints, "digits/pt-meianoite", lang);
6567  }
6568  else if (tm.tm_hour == 12) {
6569  if (format[offset] == 'I')
6570  res = wait_file(chan, ints, "digits/pt-ao", lang);
6571  if (!res)
6572  res = wait_file(chan, ints, "digits/pt-meiodia", lang);
6573  }
6574  else {
6575  if (format[offset] == 'I') {
6576  res = wait_file(chan, ints, "digits/pt-ah", lang);
6577  if ((tm.tm_hour % 12) != 1)
6578  if (!res)
6579  res = wait_file(chan, ints, "digits/pt-sss", lang);
6580  }
6581  if (!res)
6582  res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
6583  }
6584  }
6585  break;
6586  case 'H':
6587  case 'k':
6588  /* 24-Hour */
6589  if (!strcasecmp(lang, "pt_BR")) {
6590  res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
6591  if ((!res) && (format[offset] == 'H')) {
6592  if (tm.tm_hour > 1) {
6593  res = wait_file(chan, ints, "digits/hours", lang);
6594  } else {
6595  res = wait_file(chan, ints, "digits/hour", lang);
6596  }
6597  }
6598  } else {
6599  res = ast_say_number(chan, -tm.tm_hour, ints, lang, NULL);
6600  if (!res) {
6601  if (tm.tm_hour != 0) {
6602  int remaining = tm.tm_hour;
6603  if (tm.tm_hour > 20) {
6604  res = wait_file(chan, ints, "digits/20", lang);
6605  remaining -= 20;
6606  }
6607  if (!res) {
6608  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
6609  res = wait_file(chan, ints, nextmsg, lang);
6610  }
6611  }
6612  }
6613  }
6614  break;
6615  case 'M':
6616  /* Minute */
6617  if (!strcasecmp(lang, "pt_BR")) {
6618  res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
6619  if (!res) {
6620  if (tm.tm_min > 1) {
6621  res = wait_file(chan, ints, "minutes", lang);
6622  } else {
6623  res = wait_file(chan, ints, "minute", lang);
6624  }
6625  }
6626  } else {
6627  if (tm.tm_min == 0) {
6628  res = wait_file(chan, ints, "digits/pt-hora", lang);
6629  if (tm.tm_hour != 1)
6630  if (!res)
6631  res = wait_file(chan, ints, "digits/pt-sss", lang);
6632  } else {
6633  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
6634  }
6635  }
6636  break;
6637  case 'P':
6638  case 'p':
6639  /* AM/PM */
6640  if (!strcasecmp(lang, "pt_BR")) {
6641  if ((tm.tm_hour != 0) && (tm.tm_hour != 12)) {
6642  res = wait_file(chan, ints, "digits/pt-da", lang);
6643  if (!res) {
6644  if ((tm.tm_hour >= 0) && (tm.tm_hour < 12))
6645  res = wait_file(chan, ints, "digits/morning", lang);
6646  else if ((tm.tm_hour >= 12) && (tm.tm_hour < 18))
6647  res = wait_file(chan, ints, "digits/afternoon", lang);
6648  else res = wait_file(chan, ints, "digits/night", lang);
6649  }
6650  }
6651  } else {
6652  if (tm.tm_hour > 12)
6653  res = wait_file(chan, ints, "digits/p-m", lang);
6654  else if (tm.tm_hour && tm.tm_hour < 12)
6655  res = wait_file(chan, ints, "digits/a-m", lang);
6656  }
6657  break;
6658  case 'Q':
6659  /* Shorthand for "Today", "Yesterday", or ABdY */
6660  /* XXX As emphasized elsewhere, this should the native way in your
6661  * language to say the date, with changes in what you say, depending
6662  * upon how recent the date is. XXX */
6663  {
6664  struct timeval now = ast_tvnow();
6665  struct ast_tm tmnow;
6666  time_t beg_today;
6667 
6668  ast_localtime(&now, &tmnow, tzone);
6669  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6670  /* In any case, it saves not having to do ast_mktime() */
6671  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6672  if (beg_today < t) {
6673  /* Today */
6674  res = wait_file(chan, ints, "digits/today", lang);
6675  } else if (beg_today - 86400 < t) {
6676  /* Yesterday */
6677  res = wait_file(chan, ints, "digits/yesterday", lang);
6678  } else {
6679  res = ast_say_date_with_format_pt(chan, t, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", tzone);
6680  }
6681  }
6682  break;
6683  case 'q':
6684  /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
6685  /* XXX As emphasized elsewhere, this should the native way in your
6686  * language to say the date, with changes in what you say, depending
6687  * upon how recent the date is. XXX */
6688  {
6689  struct timeval now = ast_tvnow();
6690  struct ast_tm tmnow;
6691  time_t beg_today;
6692 
6693  ast_localtime(&now, &tmnow, tzone);
6694  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6695  /* In any case, it saves not having to do ast_mktime() */
6696  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6697  if (beg_today < t) {
6698  /* Today */
6699  } else if ((beg_today - 86400) < t) {
6700  /* Yesterday */
6701  res = wait_file(chan, ints, "digits/yesterday", lang);
6702  } else if (beg_today - 86400 * 6 < t) {
6703  /* Within the last week */
6704  res = ast_say_date_with_format_pt(chan, t, ints, lang, "A", tzone);
6705  } else {
6706  res = ast_say_date_with_format_pt(chan, t, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", tzone);
6707  }
6708  }
6709  break;
6710  case 'R':
6711  res = ast_say_date_with_format_pt(chan, t, ints, lang, "H 'digits/pt-e' M", tzone);
6712  break;
6713  case 'S':
6714  /* Seconds */
6715  if (!strcasecmp(lang, "pt_BR")) {
6716  res = ast_say_number(chan, tm.tm_sec, ints, lang, NULL);
6717  if (!res) {
6718  if (tm.tm_sec > 1) {
6719  res = wait_file(chan, ints, "seconds", lang);
6720  } else {
6721  res = wait_file(chan, ints, "second", lang);
6722  }
6723  }
6724  } else {
6725  if (tm.tm_sec == 0) {
6726  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6727  res = wait_file(chan, ints, nextmsg, lang);
6728  } else if (tm.tm_sec < 10) {
6729  res = wait_file(chan, ints, "digits/oh", lang);
6730  if (!res) {
6731  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6732  res = wait_file(chan, ints, nextmsg, lang);
6733  }
6734  } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
6735  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6736  res = wait_file(chan, ints, nextmsg, lang);
6737  } else {
6738  int ten, one;
6739  ten = (tm.tm_sec / 10) * 10;
6740  one = (tm.tm_sec % 10);
6741  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
6742  res = wait_file(chan, ints, nextmsg, lang);
6743  if (!res) {
6744  /* Fifty, not fifty-zero */
6745  if (one != 0) {
6746  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
6747  res = wait_file(chan, ints, nextmsg, lang);
6748  }
6749  }
6750  }
6751  }
6752  break;
6753  case 'T':
6754  res = ast_say_date_with_format_pt(chan, t, ints, lang, "HMS", tzone);
6755  break;
6756  case ' ':
6757  case ' ':
6758  /* Just ignore spaces and tabs */
6759  break;
6760  default:
6761  /* Unknown character */
6762  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
6763  }
6764  /* Jump out on DTMF */
6765  if (res) {
6766  break;
6767  }
6768  }
6769  return res;
6770 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int ast_say_date_with_format_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Portuguese syntax.
Definition: say.c:6481
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_th()

int ast_say_date_with_format_th ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Thai syntax.

Definition at line 5110 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_en(), ast_say_number(), ast_tvnow(), LOG_WARNING, NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

5111 {
5112  struct timeval when = { t, 0 };
5113  struct ast_tm tm;
5114  int res=0, offset, sndoffset;
5115  char sndfile[256], nextmsg[256];
5116 
5117  if (format == NULL)
5118  format = "a 'digits/tee' e 'digits/duan' hY I 'digits/naliga' M 'digits/natee'";
5119 
5120  ast_localtime(&when, &tm, tzone);
5121 
5122  for (offset=0 ; format[offset] != '\0' ; offset++) {
5123  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
5124  switch (format[offset]) {
5125  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
5126  case '\'':
5127  /* Literal name of a sound file */
5128  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
5129  sndfile[sndoffset] = format[offset];
5130  }
5131  sndfile[sndoffset] = '\0';
5132  res = wait_file(chan, ints, sndfile, lang);
5133  break;
5134  case 'A':
5135  case 'a':
5136  /* Sunday - Saturday */
5137  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
5138  res = wait_file(chan, ints, nextmsg, lang);
5139  break;
5140  case 'B':
5141  case 'b':
5142  case 'h':
5143  /* January - December */
5144  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
5145  res = wait_file(chan, ints, nextmsg, lang);
5146  break;
5147  case 'm':
5148  /* Month enumerated */
5149  res = ast_say_number(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
5150  break;
5151  case 'd':
5152  case 'e':
5153  /* First - Thirtyfirst */
5154  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
5155  break;
5156  case 'Y':
5157  /* Year */
5158  res = ast_say_number(chan, tm.tm_year + 1900 + 543, ints, lang, (char *) NULL);
5159  break;
5160  case 'I':
5161  case 'l':
5162  /* 12-Hour */
5163  if (tm.tm_hour == 0)
5164  ast_copy_string(nextmsg, "digits/24", sizeof(nextmsg));
5165  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
5166  res = wait_file(chan, ints, nextmsg, lang);
5167  break;
5168  case 'H':
5169  case 'k':
5170  /* 24-Hour */
5171  if (tm.tm_hour == 0)
5172  ast_copy_string(nextmsg, "digits/24", sizeof(nextmsg));
5173  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
5174  res = wait_file(chan, ints, nextmsg, lang);
5175  break;
5176  case 'M':
5177  case 'N':
5178  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
5179  break;
5180  case 'P':
5181  case 'p':
5182  break;
5183  case 'Q':
5184  /* Shorthand for "Today", "Yesterday", or ABdY */
5185  /* XXX As emphasized elsewhere, this should the native way in your
5186  * language to say the date, with changes in what you say, depending
5187  * upon how recent the date is. XXX */
5188  {
5189  struct timeval now = ast_tvnow();
5190  struct ast_tm tmnow;
5191  time_t beg_today;
5192 
5193  ast_localtime(&now, &tmnow, tzone);
5194  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5195  /* In any case, it saves not having to do ast_mktime() */
5196  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5197  if (beg_today < t) {
5198  /* Today */
5199  res = wait_file(chan, ints, "digits/today", lang);
5200  } else if (beg_today - 86400 < t) {
5201  /* Yesterday */
5202  res = wait_file(chan, ints, "digits/yesterday", lang);
5203  } else if (beg_today - 86400 * 6 < t) {
5204  /* Within the last week */
5205  res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
5206  } else if (beg_today - 2628000 < t) {
5207  /* Less than a month ago - "Sunday, October third" */
5208  res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
5209  } else if (beg_today - 15768000 < t) {
5210  /* Less than 6 months ago - "August seventh" */
5211  res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
5212  } else {
5213  /* More than 6 months ago - "April nineteenth two thousand three" */
5214  res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
5215  }
5216  }
5217  break;
5218  case 'q':
5219  /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
5220  /* XXX As emphasized elsewhere, this should the native way in your
5221  * language to say the date, with changes in what you say, depending
5222  * upon how recent the date is. XXX */
5223  {
5224  struct timeval now = ast_tvnow();
5225  struct ast_tm tmnow;
5226  time_t beg_today;
5227 
5228  ast_localtime(&now, &tmnow, tzone);
5229  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5230  /* In any case, it saves not having to do ast_mktime() */
5231  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5232  if (beg_today < t) {
5233  /* Today */
5234  } else if ((beg_today - 86400) < t) {
5235  /* Yesterday */
5236  res = wait_file(chan, ints, "digits/yesterday", lang);
5237  } else if (beg_today - 86400 * 6 < t) {
5238  /* Within the last week */
5239  res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
5240  } else if (beg_today - 2628000 < t) {
5241  /* Less than a month ago - "Sunday, October third" */
5242  res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
5243  } else if (beg_today - 15768000 < t) {
5244  /* Less than 6 months ago - "August seventh" */
5245  res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
5246  } else {
5247  /* More than 6 months ago - "April nineteenth two thousand three" */
5248  res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
5249  }
5250  }
5251  break;
5252  case 'R':
5253  res = ast_say_date_with_format_en(chan, t, ints, lang, "HM", tzone);
5254  break;
5255  case 'S':
5256  res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
5257  break;
5258  case 'T':
5259  res = ast_say_date_with_format_en(chan, t, ints, lang, "HMS", tzone);
5260  break;
5261  case ' ':
5262  case ' ':
5263  /* Just ignore spaces and tabs */
5264  break;
5265  default:
5266  /* Unknown character */
5267  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
5268  }
5269  /* Jump out on DTMF */
5270  if (res) {
5271  break;
5272  }
5273  }
5274  return res;
5275 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
static int ast_say_date_with_format_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
English syntax.
Definition: say.c:4246
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_vi()

int ast_say_date_with_format_vi ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Vietnamese syntax.

Definition at line 8895 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_en(), ast_say_enumeration(), ast_say_number(), ast_tvnow(), LOG_WARNING, NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

8896 {
8897  struct timeval when = { t, 0 };
8898  struct ast_tm tm;
8899  int res = 0, offset, sndoffset;
8900  char sndfile[256], nextmsg[256];
8901 
8902  if (format == NULL)
8903  format = "A 'digits/day' eB 'digits/year' Y 'digits/at' k 'hours' M 'minutes' p";
8904 
8905  ast_localtime(&when, &tm, tzone);
8906 
8907  for (offset=0 ; format[offset] != '\0' ; offset++) {
8908  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
8909  switch (format[offset]) {
8910  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
8911  case '\'':
8912  /* Literal name of a sound file */
8913  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
8914  sndfile[sndoffset] = format[offset];
8915  }
8916  sndfile[sndoffset] = '\0';
8917  res = wait_file(chan, ints, sndfile, lang);
8918  break;
8919  case 'A':
8920  case 'a':
8921  /* Sunday - Saturday */
8922  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
8923  res = wait_file(chan, ints, nextmsg, lang);
8924  break;
8925  case 'B':
8926  case 'b':
8927  case 'h':
8928  /* January - December */
8929  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
8930  res = wait_file(chan, ints, nextmsg, lang);
8931  break;
8932  case 'm':
8933  /* Month enumerated */
8934  res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
8935  break;
8936  case 'd':
8937  case 'e':
8938  /* 1 - 31 */
8939  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
8940  break;
8941  case 'Y':
8942  /* Year */
8943  if (tm.tm_year > 99) {
8944  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
8945  } else if (tm.tm_year < 1) {
8946  /* I'm not going to handle 1900 and prior */
8947  /* We'll just be silent on the year, instead of bombing out. */
8948  } else {
8949  res = wait_file(chan, ints, "digits/19", lang);
8950  if (!res) {
8951  if (tm.tm_year <= 9) {
8952  /* 1901 - 1909 */
8953  res = wait_file(chan, ints, "digits/odd", lang);
8954  }
8955 
8956  res |= ast_say_number(chan, tm.tm_year, ints, lang, (char *) NULL);
8957  }
8958  }
8959  break;
8960  case 'I':
8961  case 'l':
8962  /* 12-Hour */
8963  if (tm.tm_hour == 0)
8964  ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
8965  else if (tm.tm_hour > 12)
8966  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
8967  else
8968  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
8969  res = wait_file(chan, ints, nextmsg, lang);
8970  break;
8971  case 'H':
8972  case 'k':
8973  /* 24-Hour */
8974  if (format[offset] == 'H') {
8975  /* e.g. oh-eight */
8976  if (tm.tm_hour < 10) {
8977  res = wait_file(chan, ints, "digits/0", lang);
8978  }
8979  } else {
8980  /* e.g. eight */
8981  if (tm.tm_hour == 0) {
8982  res = wait_file(chan, ints, "digits/0", lang);
8983  }
8984  }
8985  if (!res) {
8986  if (tm.tm_hour != 0) {
8987  int remaining = tm.tm_hour;
8988  if (tm.tm_hour > 20) {
8989  res = wait_file(chan, ints, "digits/20", lang);
8990  remaining -= 20;
8991  }
8992  if (!res) {
8993  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
8994  res = wait_file(chan, ints, nextmsg, lang);
8995  }
8996  }
8997  }
8998  break;
8999  case 'M':
9000  case 'N':
9001  /* Minute */
9002  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
9003  break;
9004  case 'P':
9005  case 'p':
9006  /* AM/PM */
9007  if (tm.tm_hour > 11)
9008  ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
9009  else
9010  ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
9011  res = wait_file(chan, ints, nextmsg, lang);
9012  break;
9013  case 'Q':
9014  /* Shorthand for "Today", "Yesterday", or ABdY */
9015  /* XXX As emphasized elsewhere, this should the native way in your
9016  * language to say the date, with changes in what you say, depending
9017  * upon how recent the date is. XXX */
9018  {
9019  struct timeval now = ast_tvnow();
9020  struct ast_tm tmnow;
9021  time_t beg_today;
9022 
9023  gettimeofday(&now, NULL);
9024  ast_localtime(&now, &tmnow, tzone);
9025  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
9026  /* In any case, it saves not having to do ast_mktime() */
9027  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
9028  if (beg_today < t) {
9029  /* Today */
9030  res = wait_file(chan, ints, "digits/today", lang);
9031  } else if (beg_today - 86400 < t) {
9032  /* Yesterday */
9033  res = wait_file(chan, ints, "digits/yesterday", lang);
9034  } else if (beg_today - 86400 * 6 < t) {
9035  /* Within the last week */
9036  res = ast_say_date_with_format_vi(chan, t, ints, lang, "A", tzone);
9037  } else if (beg_today - 2628000 < t) {
9038  /* Less than a month ago - "Chu nhat ngay 13 thang 2" */
9039  res = ast_say_date_with_format_vi(chan, t, ints, lang, "A 'digits/day' dB", tzone);
9040  } else if (beg_today - 15768000 < t) {
9041  /* Less than 6 months ago - "August seventh" */
9042  res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB", tzone);
9043  } else {
9044  /* More than 6 months ago - "April nineteenth two thousand three" */
9045  res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB 'digits/year' Y", tzone);
9046  }
9047  }
9048  break;
9049  case 'q':
9050  /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
9051  /* XXX As emphasized elsewhere, this should the native way in your
9052  * language to say the date, with changes in what you say, depending
9053  * upon how recent the date is. XXX */
9054  {
9055  struct timeval now;
9056  struct ast_tm tmnow;
9057  time_t beg_today;
9058 
9059  now = ast_tvnow();
9060  ast_localtime(&now, &tmnow, tzone);
9061  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
9062  /* In any case, it saves not having to do ast_mktime() */
9063  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
9064  if (beg_today < t) {
9065  /* Today */
9066  } else if ((beg_today - 86400) < t) {
9067  /* Yesterday */
9068  res = wait_file(chan, ints, "digits/yesterday", lang);
9069  } else if (beg_today - 86400 * 6 < t) {
9070  /* Within the last week */
9071  res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
9072  } else if (beg_today - 2628000 < t) {
9073  /* Less than a month ago - "Chu nhat ngay 13 thang 2" */
9074  res = ast_say_date_with_format_vi(chan, t, ints, lang, "A 'digits/day' dB", tzone);
9075  } else if (beg_today - 15768000 < t) {
9076  /* Less than 6 months ago - "August seventh" */
9077  res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB", tzone);
9078  } else {
9079  /* More than 6 months ago - "April nineteenth two thousand three" */
9080  res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB 'digits/year' Y", tzone);
9081  }
9082  }
9083  break;
9084  case 'R':
9085  res = ast_say_date_with_format_vi(chan, t, ints, lang, "HM", tzone);
9086  break;
9087  case 'S':
9088  /* Seconds */
9089  res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
9090  break;
9091  case 'T':
9092  res = ast_say_date_with_format_vi(chan, t, ints, lang, "H 'hours' M 'minutes' S 'seconds'", tzone);
9093  break;
9094  case ' ':
9095  case ' ':
9096  /* Just ignore spaces and tabs */
9097  break;
9098  default:
9099  /* Unknown character */
9100  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
9101  }
9102  /* Jump out on DTMF */
9103  if (res) {
9104  break;
9105  }
9106  }
9107  return res;
9108 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
#define LOG_WARNING
Definition: logger.h:274
static int ast_say_date_with_format_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
English syntax.
Definition: say.c:4246
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
static int ast_say_date_with_format_vi(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Vietnamese syntax.
Definition: say.c:8895
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says an enumeration
Definition: channel.c:8343
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_say_date_with_format_zh()

int ast_say_date_with_format_zh ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang,
const char *  format,
const char *  tzone 
)
static

Taiwanese / Chinese syntax.

Definition at line 6773 of file say.c.

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_tvnow(), LOG_WARNING, NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_year, and wait_file().

Referenced by ast_get_number_str(), and say_date_with_format().

6774 {
6775  struct timeval when = { t, 0 };
6776  struct ast_tm tm;
6777  int res=0, offset, sndoffset;
6778  char sndfile[256], nextmsg[256];
6779 
6780  if (format == NULL)
6781  format = "YBdAkM";
6782 
6783  ast_localtime(&when, &tm, tzone);
6784 
<