Asterisk - The Open Source Telephony Project GIT-master-0bf3178
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 "asterisk/cli.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_ordinal_str (int num, const char *lang)
 ast_get_ordinal_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/thousands 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 struct ast_strget_ordinal_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_filenames (struct ast_channel *chan, const char *ints, const char *lang, int audiofd, int ctrlfd, struct ast_str *filenames)
 
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_ordinal_full (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 say_ordinal_full 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.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Note
12-16-2004 : Support for Greek added by InAccess Networks (work funded by HOL, www.hol.gr) George Konstantoulakis gkon@.nosp@m.inac.nosp@m.cessn.nosp@m.etwo.nosp@m.rks.c.nosp@m.om
2007-02-08 : Support for Georgian added by Alexander Shaduri ashad.nosp@m.uri@.nosp@m.gmail.nosp@m..com, Next Generation Networks (NGN).
2007-03-20 : Support for Thai added by Dome C. dome@.nosp@m.tel..nosp@m.co.th, IP Crossing Co., Ltd.
2021-07-26 : Refactoring to separate string buildup and playback by Naveen Albert aster.nosp@m.isk@.nosp@m.phrea.nosp@m.knet.nosp@m..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 1596 of file say.c.

Function Documentation

◆ __say_init()

static void __say_init ( void  )
static

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

Definition at line 9791 of file say.c.

9792{
9805}
static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:7994
static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:7228
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:348
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:294
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:4355
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:210
static int say_ordinal_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
say_ordinal_full
Definition: say.c:940
static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:7554
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:460
static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:3957
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:874
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:3229
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:170
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:206
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:204
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
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:125
SAY_EXTERN int(* ast_say_ordinal_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_ordinal_full)
Same as ast_say_number() with audiofd for received audio and returns 1 on ctrlfd being readable.
Definition: say.h:105
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:194
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:208
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:162
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:202
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:199
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:201

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_ordinal_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_ordinal_full(), say_phonetic_str_full(), and say_time().

◆ 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 64 of file say.c.

64 {
65 const char *fn;
66 char fnbuf[10], asciibuf[20] = "letters/ascii";
67 char ltr;
68 int num = 0;
69 int res = 0;
70 int upper = 0;
71 int lower = 0;
72
73 struct ast_str *filenames = ast_str_create(20);
74 if (!filenames) {
75 return NULL;
76 }
77 ast_str_reset(filenames);
78
79 while (str[num] && !res) {
80 fn = NULL;
81 switch (str[num]) {
82 case ('*'):
83 fn = "digits/star";
84 break;
85 case ('#'):
86 fn = "digits/pound";
87 break;
88 case ('!'):
89 fn = "letters/exclaimation-point";
90 break;
91 case ('@'):
92 fn = "letters/at";
93 break;
94 case ('$'):
95 fn = "letters/dollar";
96 break;
97 case ('-'):
98 fn = "letters/dash";
99 break;
100 case ('.'):
101 fn = "letters/dot";
102 break;
103 case ('='):
104 fn = "letters/equals";
105 break;
106 case ('+'):
107 fn = "letters/plus";
108 break;
109 case ('/'):
110 fn = "letters/slash";
111 break;
112 case (' '):
113 fn = "letters/space";
114 break;
115 case ('0'):
116 case ('1'):
117 case ('2'):
118 case ('3'):
119 case ('4'):
120 case ('5'):
121 case ('6'):
122 case ('7'):
123 case ('8'):
124 case ('9'):
125 strcpy(fnbuf, "digits/X");
126 fnbuf[7] = str[num];
127 fn = fnbuf;
128 break;
129 default:
130 ltr = str[num];
131 if ('A' <= ltr && ltr <= 'Z') {
132 ltr += 'a' - 'A'; /* file names are all lower-case */
133 switch (sensitivity) {
135 case AST_SAY_CASE_ALL:
136 upper = !upper;
139 break;
140 }
141 } else if ('a' <= ltr && ltr <= 'z') {
142 switch (sensitivity) {
144 case AST_SAY_CASE_ALL:
145 lower = !lower;
148 break;
149 }
150 }
151
152 if (upper) {
153 strcpy(fnbuf, "uppercase");
154 } else if (lower) {
155 strcpy(fnbuf, "lowercase");
156 } else {
157 strcpy(fnbuf, "letters/X");
158 fnbuf[8] = ltr;
159 }
160 fn = fnbuf;
161 }
162 if ((fn && ast_fileexists(fn, NULL, lang) > 0) ||
163 (snprintf(asciibuf + 13, sizeof(asciibuf) - 13, "%d", str[num]) > 0 && ast_fileexists(asciibuf, NULL, lang) > 0 && (fn = asciibuf))) {
164 ast_str_append(&filenames, 0, "%s%s", ast_str_strlen(filenames) ? "&" : "", fn);
165 }
166 if (upper || lower) {
167 continue;
168 }
169 num++;
170 }
171
172 return filenames;
173}
const char * str
Definition: app_jack.c:147
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1129
#define NULL
Definition: resample.c:96
@ AST_SAY_CASE_LOWER
Definition: say.h:183
@ AST_SAY_CASE_ALL
Definition: say.h:185
@ AST_SAY_CASE_UPPER
Definition: say.h:184
@ AST_SAY_CASE_NONE
Definition: say.h:182
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:1139
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:693
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
Support for dynamic strings.
Definition: strings.h:623

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(), ast_str_strlen(), NULL, and str.

Referenced by say_character_str_full(), and sayfile_exec().

◆ 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 300 of file say.c.

301{
302 const char *fn;
303 char fnbuf[256];
304 int num = 0;
305
306 struct ast_str *filenames = ast_str_create(20);
307 if (!filenames) {
308 return NULL;
309 }
310 ast_str_reset(filenames);
311
312 while (str[num]) {
313 fn = NULL;
314 switch (str[num]) {
315 case ('*'):
316 fn = "digits/star";
317 break;
318 case ('#'):
319 fn = "digits/pound";
320 break;
321 case ('-'):
322 fn = "digits/minus";
323 break;
324 case '0':
325 case '1':
326 case '2':
327 case '3':
328 case '4':
329 case '5':
330 case '6':
331 case '7':
332 case '8':
333 case '9':
334 strcpy(fnbuf, "digits/X");
335 fnbuf[7] = str[num];
336 fn = fnbuf;
337 break;
338 }
339 if (fn && ast_fileexists(fn, NULL, lang) > 0) {
340 ast_str_append(&filenames, 0, "%s%s", ast_str_strlen(filenames) ? "&" : "", fn);
341 }
342 num++;
343 }
344
345 return filenames;
346}

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

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

◆ 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 354 of file say.c.

355{
356 const char *fnr;
357 int amt, dollars = 0, cents = 0;
358 struct ast_str *fnrecurse = NULL;
359 struct ast_str *filenames;
360
361 if (ast_strlen_zero(str)) {
362 return NULL;
363 }
364
365 filenames = ast_str_create(20);
366 if (!filenames) {
367 return NULL;
368 }
369 ast_str_reset(filenames);
370
371 /* Don't use %f because floating point rounding
372 * could distort the cents units. Just parse as string. */
373 if (str && *str == '.') {
374 if (sscanf(str, ".%02u", &cents) < 1) {
375 dollars = cents = 0;
376 } else {
377 /* If we have a space instead of numbers after '.',
378 * then it's not quite valid. */
379 const char *period = strchr(str, '.');
380 if (period && !isdigit(*(period + 1))) {
381 cents = 0;
382 }
383 }
384 } else {
385 int res = sscanf(str, "%d.%02u", &dollars, &cents);
386 if (res < 1) {
387 dollars = cents = 0;
388 } else if (res == 2) {
389 const char *period = strchr(str, '.');
390 if (period && !isdigit(*(period + 1))) {
391 cents = 0;
392 }
393 }
394 }
395 amt = dollars * 100 + cents; /* convert everything to cents */
396
397 ast_debug(1, "Amount is %d (%d dollar%s, %d cent%s)\n", amt, dollars, ESS(dollars), cents, ESS(cents));
398
399 if (amt >= 100) {
400 fnrecurse = ast_get_number_str((amt / 100), lang);
401 if (!fnrecurse) {
402 ast_log(LOG_WARNING, "Couldn't get string for dollars\n");
403 } else {
404 fnr = ast_str_buffer(fnrecurse);
405 ast_str_append(&filenames, 0, "%s", fnr);
406 }
407
408 /* If this is it, end on a down pitch, otherwise up pitch */
409 if (amt < 200) {
410 ast_str_append(&filenames, 0, "&%s", (cents > 0) ? "letters/dollar_" : "letters/dollar");
411 } else {
412 ast_str_append(&filenames, 0, "&%s", "dollars");
413 }
414
415 /* If dollars and cents, add "and" in the middle */
416 if (cents > 0) {
417 ast_str_append(&filenames, 0, "&%s", "and");
418 }
419 }
420
421 if (cents > 0) {
422 fnrecurse = ast_get_number_str(cents, lang);
423 if (!fnrecurse) {
424 ast_log(LOG_ERROR, "Couldn't get string for cents\n");
425 } else {
426 fnr = ast_str_buffer(fnrecurse);
427 ast_str_append(&filenames, 0, (amt < 100 ? "%s" : "&%s"), fnr);
428 }
429 ast_str_append(&filenames, 0, "&%s", (cents == 1) ? "cent" : "cents");
430 } else if (amt == 0) {
431 fnrecurse = ast_get_digit_str("0", lang);
432 if (!fnrecurse) {
433 ast_log(LOG_ERROR, "Couldn't get string for cents\n");
434 } else {
435 fnr = ast_str_buffer(fnrecurse);
436 ast_str_append(&filenames, 0, "%s", fnr);
437 }
438 ast_str_append(&filenames, 0, "&%s", "cents");
439 }
440
441 if (fnrecurse) {
442 ast_free(fnrecurse);
443 }
444
445 return filenames;
446}
#define ast_free(a)
Definition: astmm.h:180
#define ast_log
Definition: astobj2.c:42
#define ESS(x)
Definition: cli.h:59
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_WARNING
struct ast_str * ast_get_number_str(int num, const char *lang)
ast_get_number_str: call language-specific functions
Definition: say.c:566
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:300
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References ast_debug, ast_free, ast_get_digit_str(), ast_get_number_str(), ast_log, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_reset(), ast_strlen_zero(), ESS, LOG_ERROR, LOG_WARNING, NULL, and str.

Referenced by ast_get_money_str().

◆ 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 449 of file say.c.

450{
451 if (!strncasecmp(lang, "en", 2)) { /* English syntax */
452 return ast_get_money_en_dollars_str(str, lang);
453 }
454
455 ast_log(LOG_WARNING, "Language %s not currently supported, defaulting to US Dollars\n", lang);
456 /* Default to english */
457 return ast_get_money_en_dollars_str(str, lang);
458}
static struct ast_str * ast_get_money_en_dollars_str(const char *str, const char *lang)
Definition: say.c:354

References ast_get_money_en_dollars_str(), ast_log, LOG_WARNING, and str.

Referenced by say_money_str_full(), and sayfile_exec().

◆ 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 566 of file say.c.

567{
568 if (!strncasecmp(lang, "en", 2)) { /* English syntax */
569 return get_number_str_en(num, lang);
570 }
571
572 ast_log(LOG_WARNING, "Language %s not currently supported, defaulting to English\n", lang);
573 /* Default to english */
574 return get_number_str_en(num, lang);
575}
static struct ast_str * get_number_str_en(int num, const char *lang)
Definition: say.c:466

References ast_log, get_number_str_en(), and LOG_WARNING.

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

◆ ast_get_ordinal_str()

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

ast_get_ordinal_str: call language-specific functions

Returns an ast_str of files for SayOrdinal playback.

Definition at line 686 of file say.c.

687{
688 if (!strncasecmp(lang, "en", 2)) { /* English syntax */
689 return get_ordinal_str_en(num, lang);
690 }
691
692 ast_log(LOG_WARNING, "Language %s not currently supported, defaulting to English\n", lang);
693 /* Default to english */
694 return get_ordinal_str_en(num, lang);
695}
static struct ast_str * get_ordinal_str_en(int num, const char *lang)
Definition: say.c:577

References ast_log, get_ordinal_str_en(), and LOG_WARNING.

Referenced by say_ordinal_full(), and sayfile_exec().

◆ 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 216 of file say.c.

217{
218 const char *fn;
219 char fnbuf[256];
220 char ltr;
221 int num = 0;
222
223 struct ast_str *filenames = ast_str_create(20);
224 if (!filenames) {
225 return NULL;
226 }
227 ast_str_reset(filenames);
228
229 while (str[num]) {
230 fn = NULL;
231 switch (str[num]) {
232 case ('*'):
233 fn = "digits/star";
234 break;
235 case ('#'):
236 fn = "digits/pound";
237 break;
238 case ('!'):
239 fn = "letters/exclaimation-point";
240 break;
241 case ('@'):
242 fn = "letters/at";
243 break;
244 case ('$'):
245 fn = "letters/dollar";
246 break;
247 case ('-'):
248 fn = "letters/dash";
249 break;
250 case ('.'):
251 fn = "letters/dot";
252 break;
253 case ('='):
254 fn = "letters/equals";
255 break;
256 case ('+'):
257 fn = "letters/plus";
258 break;
259 case ('/'):
260 fn = "letters/slash";
261 break;
262 case (' '):
263 fn = "letters/space";
264 break;
265 case ('0'):
266 case ('1'):
267 case ('2'):
268 case ('3'):
269 case ('4'):
270 case ('5'):
271 case ('6'):
272 case ('7'):
273 case ('8'):
274 strcpy(fnbuf, "digits/X");
275 fnbuf[7] = str[num];
276 fn = fnbuf;
277 break;
278 default: /* '9' falls here... */
279 ltr = str[num];
280 if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
281 strcpy(fnbuf, "phonetic/X_p");
282 fnbuf[9] = ltr;
283 fn = fnbuf;
284 }
285 if (fn && ast_fileexists(fn, NULL, lang) > 0) {
286 ast_str_append(&filenames, 0, "%s%s", ast_str_strlen(filenames) ? "&" : "", fn);
287 }
288 num++;
289 }
290
291 return filenames;
292}

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

Referenced by say_phonetic_str_full(), and sayfile_exec().

◆ ast_say_counted_adjective()

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

Definition at line 9769 of file say.c.

9770{
9771 char *temp;
9772 int temp_len;
9773 const char *ending;
9774 if (!strncasecmp(ast_channel_language(chan), "ru", 2)) { /* Russian */
9775 ending = counted_adjective_ending_ru(num, gender);
9776 } else if (!strncasecmp(ast_channel_language(chan), "ua", 2)) { /* Ukrainian */
9777 ending = counted_adjective_ending_ru(num, gender);
9778 } else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) { /* Polish */
9779 ending = counted_adjective_ending_ru(num, gender);
9780 } else { /* English and default */
9781 ending = "";
9782 }
9783 temp = ast_alloca((temp_len = (strlen(adjective) + strlen(ending) + 1)));
9784 snprintf(temp, temp_len, "%s%s", adjective, ending);
9785 return ast_play_and_wait(chan, temp);
9786}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
const char * ast_channel_language(const struct ast_channel *chan)
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:1616
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:9753

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

◆ ast_say_counted_noun()

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

Definition at line 9727 of file say.c.

9728{
9729 char *temp;
9730 int temp_len;
9731 const char *ending;
9732 if (!strncasecmp(ast_channel_language(chan), "ru", 2)) { /* Russian */
9733 ending = counted_noun_ending_slavic(num);
9734 } else if (!strncasecmp(ast_channel_language(chan), "ua", 2)) { /* Ukrainian */
9735 ending = counted_noun_ending_slavic(num);
9736 } else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) { /* Polish */
9737 ending = counted_noun_ending_slavic(num);
9738 } else { /* English and default */
9739 ending = counted_noun_ending_en(num);
9740 }
9741 temp = ast_alloca((temp_len = (strlen(noun) + strlen(ending) + 1)));
9742 snprintf(temp, temp_len, "%s%s", noun, ending);
9743 return ast_play_and_wait(chan, temp);
9744}
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:9708
static const char * counted_noun_ending_en(int num)
In English, we use the plural for everything but one. For example:
Definition: say.c:9689

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

◆ 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 4021 of file say.c.

4022{
4023 struct timeval when = { t, 0 };
4024 struct ast_tm tm;
4025 char fn[256];
4026 int res = 0;
4027 ast_localtime(&when, &tm, NULL);
4028 if (!res) {
4029 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4030 res = ast_streamfile(chan, fn, lang);
4031 if (!res)
4032 res = ast_waitstream(chan, ints);
4033 }
4034 if (!res)
4035 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
4036 if (!res)
4037 res = ast_waitstream(chan, ints);
4038 if (!res) {
4039 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4040 res = ast_streamfile(chan, fn, lang);
4041 if (!res)
4042 res = ast_waitstream(chan, ints);
4043 }
4044 if (!res) {
4045 /* Year */
4046 int year = tm.tm_year + 1900;
4047 if (year > 1999) { /* year 2000 and later */
4048 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
4049 } else {
4050 if (year < 1100) {
4051 /* I'm not going to handle 1100 and prior */
4052 /* We'll just be silent on the year, instead of bombing out. */
4053 } else {
4054 /* year 1100 to 1999. will anybody need this?!? */
4055 snprintf(fn, sizeof(fn), "digits/%d", (year / 100));
4056 res = wait_file(chan, ints, fn, lang);
4057 if (!res) {
4058 res = wait_file(chan, ints, "digits/hundred", lang);
4059 if (!res && year % 100 != 0) {
4060 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
4061 }
4062 }
4063 }
4064 }
4065 }
4066 return res;
4067}
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
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 wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:860
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:8257
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:8269

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 say_date().

◆ 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 4070 of file say.c.

4071{
4072 struct timeval when = { t, 0 };
4073 struct ast_tm tm;
4074 char fn[256];
4075 int res = 0;
4076 ast_localtime(&when, &tm, NULL);
4077 if (!res) {
4078 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4079 res = ast_streamfile(chan, fn, lang);
4080 if (!res)
4081 res = ast_waitstream(chan, ints);
4082 }
4083 if (!res)
4084 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
4085 if (!res)
4086 res = ast_waitstream(chan, ints);
4087 if (!res) {
4088 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4089 res = ast_streamfile(chan, fn, lang);
4090 if (!res)
4091 res = ast_waitstream(chan, ints);
4092 }
4093 if (!res) {
4094 /* Year */
4095 int year = tm.tm_year + 1900;
4096 if (year > 1999) { /* year 2000 and later */
4097 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
4098 } else {
4099 if (year < 1100) {
4100 /* I'm not going to handle 1100 and prior */
4101 /* We'll just be silent on the year, instead of bombing out. */
4102 } else {
4103 /* year 1100 to 1999. will anybody need this?!? */
4104 /* say 1967 as 'neunzehn hundert sieben und sechzig' */
4105 snprintf(fn, sizeof(fn), "digits/%d", (year / 100) );
4106 res = wait_file(chan, ints, fn, lang);
4107 if (!res) {
4108 res = wait_file(chan, ints, "digits/hundred", lang);
4109 if (!res && year % 100 != 0) {
4110 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
4111 }
4112 }
4113 }
4114 }
4115 }
4116 return res;
4117}

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 say_date().

◆ 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 3992 of file say.c.

3993{
3994 struct ast_tm tm;
3995 struct timeval when = { t, 0 };
3996 char fn[256];
3997 int res = 0;
3998 ast_localtime(&when, &tm, NULL);
3999 if (!res) {
4000 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4001 res = ast_streamfile(chan, fn, lang);
4002 if (!res)
4003 res = ast_waitstream(chan, ints);
4004 }
4005 if (!res) {
4006 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4007 res = ast_streamfile(chan, fn, lang);
4008 if (!res)
4009 res = ast_waitstream(chan, ints);
4010 }
4011 if (!res)
4012 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
4013 if (!res)
4014 res = ast_waitstream(chan, ints);
4015 if (!res)
4016 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4017 return res;
4018}

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 say_date().

◆ 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 4152 of file say.c.

4153{
4154 struct timeval when = { t, 0 };
4155 struct ast_tm tm;
4156 char fn[256];
4157 int res = 0;
4158 ast_localtime(&when, &tm, NULL);
4159 if (!res) {
4160 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4161 res = ast_streamfile(chan, fn, lang);
4162 if (!res)
4163 res = ast_waitstream(chan, ints);
4164 }
4165 if (!res)
4166 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
4167 if (!res)
4168 res = ast_waitstream(chan, ints);
4169 if (!res) {
4170 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4171 res = ast_streamfile(chan, fn, lang);
4172 if (!res)
4173 res = ast_waitstream(chan, ints);
4174 }
4175 if (!res)
4176 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4177 return res;
4178}

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 say_date().

◆ 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 8372 of file say.c.

8373{
8374 struct ast_tm tm;
8375 struct timeval when = { t, 0 };
8376
8377 char fn[256];
8378 int res = 0;
8379
8380
8381 ast_localtime(&when, &tm, NULL);
8382 /* W E E K - D A Y */
8383 if (!res) {
8384 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8385 res = ast_streamfile(chan, fn, lang);
8386 if (!res)
8387 res = ast_waitstream(chan, ints);
8388 }
8389 /* D A Y */
8390 if (!res) {
8391 gr_say_number_female(tm.tm_mday, chan, ints, lang);
8392 }
8393 /* M O N T H */
8394 if (!res) {
8395 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8396 res = ast_streamfile(chan, fn, lang);
8397 if (!res)
8398 res = ast_waitstream(chan, ints);
8399 }
8400 /* Y E A R */
8401 if (!res)
8402 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
8403 return res;
8404}
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:8183

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 say_date().

◆ 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 4273 of file say.c.

4274{
4275 struct timeval when = { t, 0 };
4276 struct ast_tm tm;
4277 char fn[256];
4278 int res = 0;
4279 ast_localtime(&when, &tm, NULL);
4280 if (!res) {
4281 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4282 res = ast_streamfile(chan, fn, lang);
4283 if (!res) {
4284 res = ast_waitstream(chan, ints);
4285 }
4286 }
4287 if (!res) {
4288 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4289 res = ast_streamfile(chan, fn, lang);
4290 if (!res) {
4291 res = ast_waitstream(chan, ints);
4292 }
4293 }
4294 if (!res) {
4295 res = ast_say_number(chan, tm.tm_mday, ints, lang, "m");
4296 }
4297 if (!res) {
4298 res = ast_waitstream(chan, ints);
4299 }
4300 if (!res) {
4301 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "m");
4302 }
4303 return res;
4304}

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 say_date().

◆ 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 4120 of file say.c.

4121{
4122 struct timeval when = { t, 0 };
4123 struct ast_tm tm;
4124 char fn[256];
4125 int res = 0;
4126 ast_localtime(&when, &tm, NULL);
4127
4128 if (!res)
4129 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4130 if (!res)
4131 res = ast_waitstream(chan, ints);
4132 if (!res) {
4133 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4134 res = ast_streamfile(chan, fn, lang);
4135 if (!res)
4136 res = ast_waitstream(chan, ints);
4137 }
4138 if (!res)
4139 ast_say_number(chan, tm.tm_mday , ints, lang, (char *) NULL);
4140 if (!res)
4141 res = ast_waitstream(chan, ints);
4142 if (!res) {
4143 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4144 res = ast_streamfile(chan, fn, lang);
4145 if (!res)
4146 res = ast_waitstream(chan, ints);
4147 }
4148 return res;
4149}

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 say_date().

◆ 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 4307 of file say.c.

4308{
4309 struct timeval when = { t, 0 };
4310 struct ast_tm tm;
4311 char fn[256];
4312 int res = 0;
4313 ast_localtime(&when, &tm, NULL);
4314 if (!res) {
4315 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4316 res = ast_streamfile(chan, fn, lang);
4317 if (!res)
4318 res = ast_waitstream(chan, ints);
4319 }
4320 if (!res)
4321 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
4322 if (!res)
4323 res = ast_waitstream(chan, ints);
4324 if (!res) {
4325 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4326 res = ast_streamfile(chan, fn, lang);
4327 if (!res)
4328 res = ast_waitstream(chan, ints);
4329 }
4330 if (!res) {
4331 /* Year */
4332 int year = tm.tm_year + 1900;
4333 if (year > 1999) { /* year 2000 and later */
4334 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
4335 } else {
4336 if (year < 1100) {
4337 /* I'm not going to handle 1100 and prior */
4338 /* We'll just be silent on the year, instead of bombing out. */
4339 } else {
4340 /* year 1100 to 1999. will anybody need this?!? */
4341 snprintf(fn, sizeof(fn), "digits/%d", (year / 100));
4342 res = wait_file(chan, ints, fn, lang);
4343 if (!res) {
4344 res = wait_file(chan, ints, "digits/hundred", lang);
4345 if (!res && year % 100 != 0) {
4346 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
4347 }
4348 }
4349 }
4350 }
4351 }
4352 return res;
4353}

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 say_date().

◆ 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 8408 of file say.c.

8409{
8410 struct ast_tm tm;
8411 struct timeval tv = { t, 0 };
8412 char fn[256];
8413 int res = 0;
8414
8415 ast_localtime(&tv, &tm, NULL);
8416
8417 if (!res)
8418 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
8419 if (!res)
8420 res = ast_waitstream(chan, ints);
8421 if (!res)
8422 res = ast_streamfile(chan, "digits/nen", lang);
8423 if (!res) {
8424 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8425 res = ast_streamfile(chan, fn, lang);
8426 if (!res)
8427 res = ast_waitstream(chan, ints);
8428 }
8429 if (!res)
8430 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
8431 if (!res)
8432 res = ast_streamfile(chan, "digits/nichi", lang);
8433 if (!res) {
8434 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8435 res = ast_streamfile(chan, fn, lang);
8436 if (!res)
8437 res = ast_waitstream(chan, ints);
8438 }
8439 return res;
8440}

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 say_date().

◆ 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 9540 of file say.c.

9541{
9542 struct timeval when = { t, 0 };
9543 struct ast_tm tm;
9544 char fn[256];
9545 int res = 0;
9546 ast_localtime(&when, &tm, NULL);
9547
9548 if (!res) {
9549 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
9550 }
9551
9552 if (!res) {
9553 snprintf(fn, sizeof(fn), "digits/tslis %d", tm.tm_wday);
9554 res = ast_streamfile(chan, fn, lang);
9555 if (!res) {
9556 res = ast_waitstream(chan, ints);
9557 }
9558 }
9559
9560 if (!res) {
9561 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
9562/* if (!res)
9563 res = ast_waitstream(chan, ints);
9564*/
9565 }
9566
9567 if (!res) {
9568 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
9569 res = ast_streamfile(chan, fn, lang);
9570 if (!res) {
9571 res = ast_waitstream(chan, ints);
9572 }
9573 }
9574 return res;
9575
9576}

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 say_date().

◆ 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 4181 of file say.c.

4182{
4183 struct timeval when = { t, 0 };
4184 struct ast_tm tm;
4185 char fn[256];
4186 int res = 0;
4187 ast_localtime(&when, &tm, NULL);
4188 if (!res) {
4189 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4190 res = ast_streamfile(chan, fn, lang);
4191 if (!res)
4192 res = ast_waitstream(chan, ints);
4193 }
4194 if (!res)
4195 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
4196 if (!res) {
4197 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4198 res = ast_streamfile(chan, fn, lang);
4199 if (!res)
4200 res = ast_waitstream(chan, ints);
4201 }
4202 if (!res)
4203 res = ast_waitstream(chan, ints);
4204 if (!res)
4205 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4206 return res;
4207}

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 say_date().

◆ 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 4246 of file say.c.

4247{
4248 struct timeval when = { t, 0 };
4249 struct ast_tm tm;
4250 char fn[256];
4251 int res = 0;
4252
4253 ast_localtime(&when, &tm, NULL);
4254 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4255 if (!res)
4256 res = wait_file(chan, ints, fn, lang);
4257 if (!res)
4258 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
4259 if (!res)
4260 res = wait_file(chan, ints, "digits/pt-de", lang);
4261 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4262 if (!res)
4263 res = wait_file(chan, ints, fn, lang);
4264 if (!res)
4265 res = wait_file(chan, ints, "digits/pt-de", lang);
4266 if (!res)
4267 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4268
4269 return res;
4270}

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 say_date().

◆ 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 4210 of file say.c.

4211{
4212 struct timeval when = { t, 0 };
4213 struct ast_tm tm;
4214 char fn[256];
4215 int res = 0;
4216 ast_localtime(&when, &tm, NULL);
4217 if (!res) {
4218 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
4219 res = ast_streamfile(chan, fn, lang);
4220 ast_copy_string(fn, "digits/tee", sizeof(fn));
4221 res = ast_streamfile(chan, fn, lang);
4222 if (!res)
4223 res = ast_waitstream(chan, ints);
4224 }
4225 if (!res)
4226 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
4227 if (!res)
4228 res = ast_waitstream(chan, ints);
4229 if (!res) {
4230 ast_copy_string(fn, "digits/duan", sizeof(fn));
4231 res = ast_streamfile(chan, fn, lang);
4232 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
4233 res = ast_streamfile(chan, fn, lang);
4234 if (!res)
4235 res = ast_waitstream(chan, ints);
4236 }
4237 if (!res){
4238 ast_copy_string(fn, "digits/posor", sizeof(fn));
4239 res = ast_streamfile(chan, fn, lang);
4240 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4241 }
4242 return res;
4243}
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425

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 say_date().

◆ 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 4674 of file say.c.

4675{
4676 struct timeval when = { t, 0 };
4677 struct ast_tm tm;
4678 int res=0, offset, sndoffset;
4679 char sndfile[256], nextmsg[256];
4680
4681 if (!format)
4682 format = "A dBY HMS";
4683
4684 ast_localtime(&when, &tm, tzone);
4685
4686 for (offset=0 ; format[offset] != '\0' ; offset++) {
4687 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
4688 switch (format[offset]) {
4689 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
4690 case '\'':
4691 /* Literal name of a sound file */
4692 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
4693 sndfile[sndoffset] = format[offset];
4694 }
4695 sndfile[sndoffset] = '\0';
4696 res = wait_file(chan, ints, sndfile, lang);
4697 break;
4698 case 'A':
4699 case 'a':
4700 /* Sunday - Saturday */
4701 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
4702 res = wait_file(chan, ints, nextmsg, lang);
4703 break;
4704 case 'B':
4705 case 'b':
4706 case 'h':
4707 /* January - December */
4708 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
4709 res = wait_file(chan, ints, nextmsg, lang);
4710 break;
4711 case 'm':
4712 /* Month enumerated */
4713 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
4714 break;
4715 case 'd':
4716 case 'e':
4717 /* First - Thirtyfirst */
4718 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
4719 break;
4720 case 'Y':
4721 /* Year */
4722 {
4723 int year = tm.tm_year + 1900;
4724 if (year > 1999) { /* year 2000 and later */
4725 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
4726 } else {
4727 if (year < 1100) {
4728 /* I'm not going to handle 1100 and prior */
4729 /* We'll just be silent on the year, instead of bombing out. */
4730 } else {
4731 /* year 1100 to 1999. will anybody need this?!? */
4732 /* say 1967 as 'nineteen hundred seven and sixty' */
4733 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
4734 res = wait_file(chan, ints, nextmsg, lang);
4735 if (!res) {
4736 res = wait_file(chan, ints, "digits/hundred", lang);
4737 if (!res && year % 100 != 0) {
4738 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
4739 }
4740 }
4741 }
4742 }
4743 }
4744 break;
4745 case 'I':
4746 case 'l':
4747 /* 12-Hour */
4748 res = wait_file(chan, ints, "digits/oclock", lang);
4749 if (tm.tm_hour == 0)
4750 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
4751 else if (tm.tm_hour > 12)
4752 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
4753 else
4754 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
4755 if (!res) {
4756 res = wait_file(chan, ints, nextmsg, lang);
4757 }
4758 break;
4759 case 'H':
4760 /* 24-Hour, single digit hours preceded by "oh" (0) */
4761 if (tm.tm_hour < 10 && tm.tm_hour > 0) {
4762 res = wait_file(chan, ints, "digits/0", lang);
4763 }
4764 /* FALLTRHU */
4765 case 'k':
4766 /* 24-Hour */
4767 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
4768 break;
4769 case 'M':
4770 /* Minute */
4771 if (tm.tm_min > 0 || next_item(&format[offset + 1]) == 'S') { /* zero 'digits/0' only if seconds follow */
4772 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
4773 }
4774 if (!res && next_item(&format[offset + 1]) == 'S') { /* minutes only if seconds follow */
4775 if (tm.tm_min == 1) {
4776 res = wait_file(chan, ints, "minute", lang);
4777 } else {
4778 res = wait_file(chan, ints, "minutes", lang);
4779 }
4780 }
4781 break;
4782 case 'P':
4783 case 'p':
4784 /* AM/PM */
4785 if (tm.tm_hour > 11)
4786 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
4787 else
4788 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
4789 res = wait_file(chan, ints, nextmsg, lang);
4790 break;
4791 case 'Q':
4792 /* Shorthand for "Today", "Yesterday", or AdBY */
4793 /* XXX As emphasized elsewhere, this should the native way in your
4794 * language to say the date, with changes in what you say, depending
4795 * upon how recent the date is. XXX */
4796 {
4797 struct timeval now = ast_tvnow();
4798 struct ast_tm tmnow;
4799 time_t beg_today;
4800
4801 ast_localtime(&now, &tmnow, tzone);
4802 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
4803 /* In any case, it saves not having to do ast_mktime() */
4804 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
4805 if (beg_today < t) {
4806 /* Today */
4807 res = wait_file(chan, ints, "digits/today", lang);
4808 } else if (beg_today - 86400 < t) {
4809 /* Yesterday */
4810 res = wait_file(chan, ints, "digits/yesterday", lang);
4811 } else {
4812 res = ast_say_date_with_format_da(chan, t, ints, lang, "AdBY", tzone);
4813 }
4814 }
4815 break;
4816 case 'q':
4817 /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
4818 /* XXX As emphasized elsewhere, this should the native way in your
4819 * language to say the date, with changes in what you say, depending
4820 * upon how recent the date is. XXX */
4821 {
4822 struct timeval now = ast_tvnow();
4823 struct ast_tm tmnow;
4824 time_t beg_today;
4825
4826 ast_localtime(&now, &tmnow, tzone);
4827 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
4828 /* In any case, it saves not having to do ast_mktime() */
4829 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
4830 if (beg_today < t) {
4831 /* Today */
4832 } else if ((beg_today - 86400) < t) {
4833 /* Yesterday */
4834 res = wait_file(chan, ints, "digits/yesterday", lang);
4835 } else if (beg_today - 86400 * 6 < t) {
4836 /* Within the last week */
4837 res = ast_say_date_with_format_da(chan, t, ints, lang, "A", tzone);
4838 } else {
4839 res = ast_say_date_with_format_da(chan, t, ints, lang, "AdBY", tzone);
4840 }
4841 }
4842 break;
4843 case 'R':
4844 res = ast_say_date_with_format_da(chan, t, ints, lang, "HM", tzone);
4845 break;
4846 case 'S':
4847 /* Seconds */
4848 res = wait_file(chan, ints, "digits/and", lang);
4849 if (!res) {
4850 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
4851 if (!res) {
4852 res = wait_file(chan, ints, "seconds", lang);
4853 }
4854 }
4855 break;
4856 case 'T':
4857 res = ast_say_date_with_format_da(chan, t, ints, lang, "HMS", tzone);
4858 break;
4859 case ' ':
4860 case ' ':
4861 /* Just ignore spaces and tabs */
4862 break;
4863 default:
4864 /* Unknown character */
4865 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
4866 }
4867 /* Jump out on DTMF */
4868 if (res) {
4869 break;
4870 }
4871 }
4872 return res;
4873}
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:4674
static char next_item(const char *format)
Definition: say.c:4667
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_da(), 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_say_date_with_format_da(), and say_date_with_format().

◆ 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 4876 of file say.c.

4877{
4878 struct timeval when = { t, 0 };
4879 struct ast_tm tm;
4880 int res=0, offset, sndoffset;
4881 char sndfile[256], nextmsg[256];
4882
4883 if (!format)
4884 format = "A dBY HMS";
4885
4886 ast_localtime(&when, &tm, tzone);
4887
4888 for (offset=0 ; format[offset] != '\0' ; offset++) {
4889 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
4890 switch (format[offset]) {
4891 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
4892 case '\'':
4893 /* Literal name of a sound file */
4894 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
4895 sndfile[sndoffset] = format[offset];
4896 }
4897 sndfile[sndoffset] = '\0';
4898 res = wait_file(chan, ints, sndfile, lang);
4899 break;
4900 case 'A':
4901 case 'a':
4902 /* Sunday - Saturday */
4903 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
4904 res = wait_file(chan, ints, nextmsg, lang);
4905 break;
4906 case 'B':
4907 case 'b':
4908 case 'h':
4909 /* January - December */
4910 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
4911 res = wait_file(chan, ints, nextmsg, lang);
4912 break;
4913 case 'm':
4914 /* Month enumerated */
4915 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
4916 break;
4917 case 'd':
4918 case 'e':
4919 /* First - Thirtyfirst */
4920 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
4921 break;
4922 case 'Y':
4923 /* Year */
4924 {
4925 int year = tm.tm_year + 1900;
4926 if (year > 1999) { /* year 2000 and later */
4927 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
4928 } else {
4929 if (year < 1100) {
4930 /* I'm not going to handle 1100 and prior */
4931 /* We'll just be silent on the year, instead of bombing out. */
4932 } else {
4933 /* year 1100 to 1999. will anybody need this?!? */
4934 /* say 1967 as 'neunzehn hundert sieben und sechzig' */
4935 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
4936 res = wait_file(chan, ints, nextmsg, lang);
4937 if (!res) {
4938 res = wait_file(chan, ints, "digits/hundred", lang);
4939 if (!res && year % 100 != 0) {
4940 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
4941 }
4942 }
4943 }
4944 }
4945 }
4946 break;
4947 case 'I':
4948 case 'l':
4949 /* 12-Hour */
4950 if (tm.tm_hour == 0)
4951 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
4952 else if (tm.tm_hour == 1)
4953 ast_copy_string(nextmsg, "digits/1N", sizeof(nextmsg));
4954 else if (tm.tm_hour > 12)
4955 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
4956 else
4957 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
4958 res = wait_file(chan, ints, nextmsg, lang);
4959 if (!res) {
4960 res = wait_file(chan, ints, "digits/oclock", lang);
4961 }
4962 break;
4963 case 'H':
4964 case 'k':
4965 /* 24-Hour */
4966 if (tm.tm_hour == 1) {
4967 res = wait_file(chan, ints, "digits/1N", lang);
4968 } else {
4969 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
4970 }
4971 if (!res) {
4972 res = wait_file(chan, ints, "digits/oclock", lang);
4973 }
4974 break;
4975 case 'M':
4976 /* Minute */
4977 if (next_item(&format[offset + 1]) == 'S') { /* zero 'digits/0' only if seconds follow */
4978 res = ast_say_number(chan, tm.tm_min, ints, lang, "f"); /* female only if we say minutes */
4979 } else if (tm.tm_min > 0) {
4980 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
4981 }
4982
4983 if (!res && next_item(&format[offset + 1]) == 'S') { /* minutes only if seconds follow */
4984 if (tm.tm_min == 1) {
4985 res = wait_file(chan, ints, "minute", lang);
4986 } else {
4987 res = wait_file(chan, ints, "minutes", lang);
4988 }
4989 }
4990 break;
4991 case 'P':
4992 case 'p':
4993 /* AM/PM */
4994 if (tm.tm_hour > 11)
4995 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
4996 else
4997 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
4998 res = wait_file(chan, ints, nextmsg, lang);
4999 break;
5000 case 'Q':
5001 /* Shorthand for "Today", "Yesterday", or AdBY */
5002 /* XXX As emphasized elsewhere, this should the native way in your
5003 * language to say the date, with changes in what you say, depending
5004 * upon how recent the date is. XXX */
5005 {
5006 struct timeval now = ast_tvnow();
5007 struct ast_tm tmnow;
5008 time_t beg_today;
5009
5010 ast_localtime(&now, &tmnow, tzone);
5011 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5012 /* In any case, it saves not having to do ast_mktime() */
5013 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5014 if (beg_today < t) {
5015 /* Today */
5016 res = wait_file(chan, ints, "digits/today", lang);
5017 } else if (beg_today - 86400 < t) {
5018 /* Yesterday */
5019 res = wait_file(chan, ints, "digits/yesterday", lang);
5020 } else {
5021 res = ast_say_date_with_format_de(chan, t, ints, lang, "AdBY", tzone);
5022 }
5023 }
5024 break;
5025 case 'q':
5026 /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
5027 /* XXX As emphasized elsewhere, this should the native way in your
5028 * language to say the date, with changes in what you say, depending
5029 * upon how recent the date is. XXX */
5030 {
5031 struct timeval now = ast_tvnow();
5032 struct ast_tm tmnow;
5033 time_t beg_today;
5034
5035 ast_localtime(&now, &tmnow, tzone);
5036 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5037 /* In any case, it saves not having to do ast_mktime() */
5038 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5039 if (beg_today < t) {
5040 /* Today */
5041 } else if ((beg_today - 86400) < t) {
5042 /* Yesterday */
5043 res = wait_file(chan, ints, "digits/yesterday", lang);
5044 } else if (beg_today - 86400 * 6 < t) {
5045 /* Within the last week */
5046 res = ast_say_date_with_format_de(chan, t, ints, lang, "A", tzone);
5047 } else {
5048 res = ast_say_date_with_format_de(chan, t, ints, lang, "AdBY", tzone);
5049 }
5050 }
5051 break;
5052 case 'R':
5053 res = ast_say_date_with_format_de(chan, t, ints, lang, "HM", tzone);
5054 break;
5055 case 'S':
5056 /* Seconds */
5057 res = wait_file(chan, ints, "digits/and", lang);
5058 if (!res) {
5059 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
5060 if (!res) {
5061 res = wait_file(chan, ints, tm.tm_sec == 1 ? "second" : "seconds", lang);
5062 }
5063 }
5064 break;
5065 case 'T':
5066 res = ast_say_date_with_format_de(chan, t, ints, lang, "HMS", tzone);
5067 break;
5068 case ' ':
5069 case ' ':
5070 /* Just ignore spaces and tabs */
5071 break;
5072 default:
5073 /* Unknown character */
5074 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
5075 }
5076 /* Jump out on DTMF */
5077 if (res) {
5078 break;
5079 }
5080 }
5081 return res;
5082}
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:4876

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_de(), 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_say_date_with_format_de(), and say_date_with_format().

◆ 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 4396 of file say.c.

4397{
4398 struct timeval when = { t, 0 };
4399 struct ast_tm tm;
4400 int res=0, offset, sndoffset;
4401 char sndfile[256], nextmsg[256];
4402
4403 if (format == NULL)
4404 format = "ABdY 'digits/at' IMp";
4405
4406 ast_localtime(&when, &tm, tzone);
4407
4408 for (offset=0 ; format[offset] != '\0' ; offset++) {
4409 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
4410 switch (format[offset]) {
4411 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
4412 case '\'':
4413 /* Literal name of a sound file */
4414 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
4415 sndfile[sndoffset] = format[offset];
4416 }
4417 sndfile[sndoffset] = '\0';
4418 res = wait_file(chan, ints, sndfile, lang);
4419 break;
4420 case 'A':
4421 case 'a':
4422 /* Sunday - Saturday */
4423 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
4424 res = wait_file(chan, ints, nextmsg, lang);
4425 break;
4426 case 'B':
4427 case 'b':
4428 case 'h':
4429 /* January - December */
4430 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
4431 res = wait_file(chan, ints, nextmsg, lang);
4432 break;
4433 case 'm':
4434 /* Month enumerated */
4435 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
4436 break;
4437 case 'd':
4438 case 'e':
4439 /* First - Thirtyfirst */
4440 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char *) NULL);
4441 break;
4442 case 'Y':
4443 /* Year */
4444 if (tm.tm_year > 99) {
4445 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
4446 } else if (tm.tm_year < 1) {
4447 /* I'm not going to handle 1900 and prior */
4448 /* We'll just be silent on the year, instead of bombing out. */
4449 } else {
4450 res = wait_file(chan, ints, "digits/19", lang);
4451 if (!res) {
4452 if (tm.tm_year <= 9) {
4453 /* 1901 - 1909 */
4454 res = wait_file(chan, ints, "digits/oh", lang);
4455 }
4456
4457 res |= ast_say_number(chan, tm.tm_year, ints, lang, (char *) NULL);
4458 }
4459 }
4460 break;
4461 case 'I':
4462 case 'l':
4463 /* 12-Hour */
4464 if (tm.tm_hour == 0)
4465 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
4466 else if (tm.tm_hour > 12)
4467 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
4468 else
4469 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
4470 res = wait_file(chan, ints, nextmsg, lang);
4471 break;
4472 case 'H':
4473 case 'k':
4474 /* 24-Hour */
4475 if (format[offset] == 'H') {
4476 /* e.g. oh-eight */
4477 if (tm.tm_hour < 10) {
4478 res = wait_file(chan, ints, "digits/oh", lang);
4479 }
4480 } else {
4481 /* e.g. eight */
4482 if (tm.tm_hour == 0) {
4483 res = wait_file(chan, ints, "digits/oh", lang);
4484 }
4485 }
4486 if (!res) {
4487 if (tm.tm_hour != 0) {
4488 int remaining = tm.tm_hour;
4489 if (tm.tm_hour > 20) {
4490 res = wait_file(chan, ints, "digits/20", lang);
4491 remaining -= 20;
4492 }
4493 if (!res) {
4494 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
4495 res = wait_file(chan, ints, nextmsg, lang);
4496 }
4497 }
4498 }
4499 break;
4500 case 'M':
4501 case 'N':
4502 /* Minute */
4503 if (tm.tm_min == 0) {
4504 if (format[offset] == 'M') {
4505 res = wait_file(chan, ints, "digits/oclock", lang);
4506 } else {
4507 res = wait_file(chan, ints, "digits/hundred", lang);
4508 }
4509 } else if (tm.tm_min < 10) {
4510 res = wait_file(chan, ints, "digits/oh", lang);
4511 if (!res) {
4512 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min);
4513 res = wait_file(chan, ints, nextmsg, lang);
4514 }
4515 } else {
4516 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
4517 }
4518 break;
4519 case 'P':
4520 case 'p':
4521 /* AM/PM */
4522 if (tm.tm_hour > 11)
4523 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
4524 else
4525 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
4526 res = wait_file(chan, ints, nextmsg, lang);
4527 break;
4528 case 'Q':
4529 /* Shorthand for "Today", "Yesterday", or ABdY */
4530 /* XXX As emphasized elsewhere, this should the native way in your
4531 * language to say the date, with changes in what you say, depending
4532 * upon how recent the date is. XXX */
4533 {
4534 struct timeval now = ast_tvnow();
4535 struct ast_tm tmnow;
4536 time_t beg_today;
4537
4538 gettimeofday(&now, NULL);
4539 ast_localtime(&now, &tmnow, tzone);
4540 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
4541 /* In any case, it saves not having to do ast_mktime() */
4542 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
4543 if (beg_today + 15768000 < t) {
4544 /* More than 6 months from now - "April nineteenth two thousand three" */
4545 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
4546 } else if (beg_today + 2628000 < t) {
4547 /* Less than 6 months from now - "August seventh" */
4548 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
4549 } else if (beg_today + 86400 * 6 < t) {
4550 /* Less than a month from now - "Sunday, October third" */
4551 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
4552 } else if (beg_today + 172800 < t) {
4553 /* Within the next week */
4554 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
4555 } else if (beg_today + 86400 < t) {
4556 /* Tomorrow */
4557 res = wait_file(chan, ints, "digits/tomorrow", lang);
4558 } else if (beg_today < t) {
4559 /* Today */
4560 res = wait_file(chan, ints, "digits/today", lang);
4561 } else if (beg_today - 86400 < t) {
4562 /* Yesterday */
4563 res = wait_file(chan, ints, "digits/yesterday", lang);
4564 } else if (beg_today - 86400 * 6 < t) {
4565 /* Within the last week */
4566 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
4567 } else if (beg_today - 2628000 < t) {
4568 /* Less than a month ago - "Sunday, October third" */
4569 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
4570 } else if (beg_today - 15768000 < t) {
4571 /* Less than 6 months ago - "August seventh" */
4572 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
4573 } else {
4574 /* More than 6 months ago - "April nineteenth two thousand three" */
4575 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
4576 }
4577 }
4578 break;
4579 case 'q':
4580 /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
4581 /* XXX As emphasized elsewhere, this should the native way in your
4582 * language to say the date, with changes in what you say, depending
4583 * upon how recent the date is. XXX */
4584 {
4585 struct timeval now;
4586 struct ast_tm tmnow;
4587 time_t beg_today;
4588
4589 now = ast_tvnow();
4590 ast_localtime(&now, &tmnow, tzone);
4591 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
4592 /* In any case, it saves not having to do ast_mktime() */
4593 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
4594 if (beg_today + 15768000 < t) {
4595 /* More than 6 months from now - "April nineteenth two thousand three" */
4596 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
4597 } else if (beg_today + 2628000 < t) {
4598 /* Less than 6 months from now - "August seventh" */
4599 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
4600 } else if (beg_today + 86400 * 6 < t) {
4601 /* Less than a month from now - "Sunday, October third" */
4602 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
4603 } else if (beg_today + 172800 < t) {
4604 /* Within the next week */
4605 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
4606 } else if (beg_today + 86400 < t) {
4607 /* Tomorrow */
4608 res = wait_file(chan, ints, "digits/tomorrow", lang);
4609 } else if (beg_today < t) {
4610 /* Today */
4611 res = wait_file(chan, ints, "digits/today", lang);
4612 } else if (beg_today - 86400 < t) {
4613 /* Yesterday */
4614 res = wait_file(chan, ints, "digits/yesterday", lang);
4615 } else if (beg_today - 86400 * 6 < t) {
4616 /* Within the last week */
4617 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
4618 } else if (beg_today - 2628000 < t) {
4619 /* Less than a month ago - "Sunday, October third" */
4620 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
4621 } else if (beg_today - 15768000 < t) {
4622 /* Less than 6 months ago - "August seventh" */
4623 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
4624 } else {
4625 /* More than 6 months ago - "April nineteenth two thousand three" */
4626 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
4627 }
4628 }
4629 break;
4630 case 'R':
4631 res = ast_say_date_with_format_en(chan, t, ints, lang, "HM", tzone);
4632 break;
4633 case 'S':
4634 /* Seconds */
4635 if (tm.tm_sec == 0) {
4636 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
4637 res = wait_file(chan, ints, nextmsg, lang);
4638 } else if (tm.tm_sec < 10) {
4639 res = wait_file(chan, ints, "digits/oh", lang);
4640 if (!res) {
4641 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
4642 res = wait_file(chan, ints, nextmsg, lang);
4643 }
4644 } else {
4645 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
4646 }
4647 break;
4648 case 'T':
4649 res = ast_say_date_with_format_en(chan, t, ints, lang, "HMS", tzone);
4650 break;
4651 case ' ':
4652 case ' ':
4653 /* Just ignore spaces and tabs */
4654 break;
4655 default:
4656 /* Unknown character */
4657 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
4658 }
4659 /* Jump out on DTMF */
4660 if (res) {
4661 break;
4662 }
4663 }
4664 return res;
4665}
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:4396

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_say_date_with_format_en(), ast_say_date_with_format_th(), ast_say_date_with_format_vi(), and say_date_with_format().

◆ 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 5629 of file say.c.

5630{
5631 struct timeval when = { t, 0 };
5632 struct ast_tm tm;
5633 int res=0, offset, sndoffset;
5634 char sndfile[256], nextmsg[256];
5635
5636 if (format == NULL)
5637 format = "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y 'digits/at' IMp";
5638
5639 ast_localtime(&when, &tm, tzone);
5640
5641 for (offset=0 ; format[offset] != '\0' ; offset++) {
5642 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
5643 switch (format[offset]) {
5644 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
5645 case '\'':
5646 /* Literal name of a sound file */
5647 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
5648 sndfile[sndoffset] = format[offset];
5649 }
5650 sndfile[sndoffset] = '\0';
5651 snprintf(nextmsg, sizeof(nextmsg), "%s", sndfile);
5652 res = wait_file(chan, ints, nextmsg, lang);
5653 break;
5654 case 'A':
5655 case 'a':
5656 /* Sunday - Saturday */
5657 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
5658 res = wait_file(chan, ints, nextmsg, lang);
5659 break;
5660 case 'B':
5661 case 'b':
5662 case 'h':
5663 /* January - December */
5664 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
5665 res = wait_file(chan, ints, nextmsg, lang);
5666 break;
5667 case 'm':
5668 /* First - Twelfth */
5669 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
5670 res = wait_file(chan, ints, nextmsg, lang);
5671 break;
5672 case 'd':
5673 case 'e':
5674 /* First - Thirtyfirst */
5675 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
5676 break;
5677 case 'Y':
5678 /* Year */
5679 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
5680 break;
5681 case 'I':
5682 case 'l':
5683 /* 12-Hour */
5684 if (tm.tm_hour == 0)
5685 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
5686 else if (tm.tm_hour == 1 || tm.tm_hour == 13)
5687 snprintf(nextmsg,sizeof(nextmsg), "digits/1F");
5688 else if (tm.tm_hour > 12)
5689 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
5690 else
5691 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
5692 res = wait_file(chan, ints, nextmsg, lang);
5693 break;
5694 case 'H':
5695 case 'k':
5696 /* 24-Hour */
5697 res = ast_say_number(chan, tm.tm_hour, ints, lang, NULL);
5698 break;
5699 case 'M':
5700 /* Minute */
5701 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
5702 break;
5703 case 'P':
5704 case 'p':
5705 /* AM/PM */
5706 if (tm.tm_hour > 18)
5707 res = wait_file(chan, ints, "digits/p-m", lang);
5708 else if (tm.tm_hour > 12)
5709 res = wait_file(chan, ints, "digits/afternoon", lang);
5710 else if (tm.tm_hour)
5711 res = wait_file(chan, ints, "digits/a-m", lang);
5712 break;
5713 case 'Q':
5714 /* Shorthand for "Today", "Yesterday", or ABdY */
5715 /* XXX As emphasized elsewhere, this should the native way in your
5716 * language to say the date, with changes in what you say, depending
5717 * upon how recent the date is. XXX */
5718 {
5719 struct timeval now = ast_tvnow();
5720 struct ast_tm tmnow;
5721 time_t beg_today;
5722
5723 ast_localtime(&now, &tmnow, tzone);
5724 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5725 /* In any case, it saves not having to do ast_mktime() */
5726 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5727 if (beg_today < t) {
5728 /* Today */
5729 res = wait_file(chan, ints, "digits/today", lang);
5730 } else if (beg_today - 86400 < t) {
5731 /* Yesterday */
5732 res = wait_file(chan, ints, "digits/yesterday", lang);
5733 } else {
5734 res = ast_say_date_with_format_es(chan, t, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", tzone);
5735 }
5736 }
5737 break;
5738 case 'q':
5739 /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
5740 /* XXX As emphasized elsewhere, this should the native way in your
5741 * language to say the date, with changes in what you say, depending
5742 * upon how recent the date is. XXX */
5743 {
5744 struct timeval now = ast_tvnow();
5745 struct ast_tm tmnow;
5746 time_t beg_today;
5747
5748 ast_localtime(&now, &tmnow, tzone);
5749 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5750 /* In any case, it saves not having to do ast_mktime() */
5751 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5752 if (beg_today < t) {
5753 /* Today */
5754 res = wait_file(chan, ints, "digits/today", lang);
5755 } else if ((beg_today - 86400) < t) {
5756 /* Yesterday */
5757 res = wait_file(chan, ints, "digits/yesterday", lang);
5758 } else if (beg_today - 86400 * 6 < t) {
5759 /* Within the last week */
5760 res = ast_say_date_with_format_es(chan, t, ints, lang, "A", tzone);
5761 } else {
5762 res = ast_say_date_with_format_es(chan, t, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", tzone);
5763 }
5764 }
5765 break;
5766 case 'R':
5767 res = ast_say_date_with_format_es(chan, t, ints, lang, "H 'digits/y' M", tzone);
5768 break;
5769 case 'S':
5770 /* Seconds */
5771 if (tm.tm_sec == 0) {
5772 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
5773 res = wait_file(chan, ints, nextmsg, lang);
5774 } else if (tm.tm_sec < 10) {
5775 res = wait_file(chan, ints, "digits/oh", lang);
5776 if (!res) {
5777 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
5778 res = wait_file(chan, ints, nextmsg, lang);
5779 }
5780 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
5781 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
5782 res = wait_file(chan, ints, nextmsg, lang);
5783 } else {
5784 int ten, one;
5785 ten = (tm.tm_sec / 10) * 10;
5786 one = (tm.tm_sec % 10);
5787 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
5788 res = wait_file(chan, ints, nextmsg, lang);
5789 if (!res) {
5790 /* Fifty, not fifty-zero */
5791 if (one != 0) {
5792 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
5793 res = wait_file(chan, ints, nextmsg, lang);
5794 }
5795 }
5796 }
5797 break;
5798 case 'T':
5799 res = ast_say_date_with_format_es(chan, t, ints, lang, "HMS", tzone);
5800 break;
5801 case ' ':
5802 case ' ':
5803 /* Just ignore spaces and tabs */
5804 break;
5805 default:
5806 /* Unknown character */
5807 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
5808 }
5809 /* Jump out on DTMF */
5810 if (res) {
5811 break;
5812 }
5813 }
5814 return res;
5815}
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:5629

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_es(), 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_say_date_with_format_es(), and say_date_with_format().

◆ 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 5820 of file say.c.

5821{
5822 struct timeval when = { t, 0 };
5823 struct ast_tm tm;
5824 int res=0, offset, sndoffset;
5825 char sndfile[256], nextmsg[256];
5826
5827 if (format == NULL)
5828 format = "AdBY 'digits/at' IMp";
5829
5830 ast_localtime(&when, &tm, tzone);
5831
5832 for (offset=0 ; format[offset] != '\0' ; offset++) {
5833 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
5834 switch (format[offset]) {
5835 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
5836 case '\'':
5837 /* Literal name of a sound file */
5838 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
5839 sndfile[sndoffset] = format[offset];
5840 }
5841 sndfile[sndoffset] = '\0';
5842 res = wait_file(chan, ints, sndfile, lang);
5843 break;
5844 case 'A':
5845 case 'a':
5846 /* Sunday - Saturday */
5847 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
5848 res = wait_file(chan, ints, nextmsg, lang);
5849 break;
5850 case 'B':
5851 case 'b':
5852 case 'h':
5853 /* January - December */
5854 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
5855 res = wait_file(chan, ints, nextmsg, lang);
5856 break;
5857 case 'm':
5858 /* First - Twelfth */
5859 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
5860 res = wait_file(chan, ints, nextmsg, lang);
5861 break;
5862 case 'd':
5863 case 'e':
5864 /* First */
5865 if (tm.tm_mday == 1) {
5866 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
5867 res = wait_file(chan, ints, nextmsg, lang);
5868 } else {
5869 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
5870 }
5871 break;
5872 case 'Y':
5873 /* Year */
5874 if (tm.tm_year > 99) {
5875 res = wait_file(chan, ints, "digits/2", lang);
5876 if (!res) {
5877 res = wait_file(chan, ints, "digits/thousand", lang);
5878 }
5879 if (tm.tm_year > 100) {
5880 if (!res) {
5881 res = ast_say_number(chan, tm.tm_year - 100, ints, lang, (char * ) NULL);
5882 }
5883 }
5884 } else {
5885 if (tm.tm_year < 1) {
5886 /* I'm not going to handle 1900 and prior */
5887 /* We'll just be silent on the year, instead of bombing out. */
5888 } else {
5889 res = wait_file(chan, ints, "digits/thousand", lang);
5890 if (!res) {
5891 wait_file(chan, ints, "digits/9", lang);
5892 wait_file(chan, ints, "digits/hundred", lang);
5893 res = ast_say_number(chan, tm.tm_year, ints, lang, (char * ) NULL);
5894 }
5895 }
5896 }
5897 break;
5898 case 'I':
5899 case 'l':
5900 /* 12-Hour */
5901 if (tm.tm_hour == 0)
5902 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
5903 else if (tm.tm_hour > 12)
5904 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
5905 else
5906 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
5907 res = wait_file(chan, ints, nextmsg, lang);
5908 if (!res)
5909 res = wait_file(chan, ints, "digits/oclock", lang);
5910 break;
5911 case 'H':
5912 case 'k':
5913 /* 24-Hour */
5914 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char * ) NULL);
5915 if (!res)
5916 res = wait_file(chan, ints, "digits/oclock", lang);
5917 break;
5918 case 'M':
5919 /* Minute */
5920 if (tm.tm_min == 0) {
5921 break;
5922 }
5923 res = ast_say_number(chan, tm.tm_min, ints, lang, (char * ) NULL);
5924 break;
5925 case 'P':
5926 case 'p':
5927 /* AM/PM */
5928 if (tm.tm_hour > 11)
5929 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
5930 else
5931 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
5932 res = wait_file(chan, ints, nextmsg, lang);
5933 break;
5934 case 'Q':
5935 /* Shorthand for "Today", "Yesterday", or AdBY */
5936 /* XXX As emphasized elsewhere, this should the native way in your
5937 * language to say the date, with changes in what you say, depending
5938 * upon how recent the date is. XXX */
5939 {
5940 struct timeval now = ast_tvnow();
5941 struct ast_tm tmnow;
5942 time_t beg_today;
5943
5944 ast_localtime(&now, &tmnow, tzone);
5945 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5946 /* In any case, it saves not having to do ast_mktime() */
5947 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5948 if (beg_today < t) {
5949 /* Today */
5950 res = wait_file(chan, ints, "digits/today", lang);
5951 } else if (beg_today - 86400 < t) {
5952 /* Yesterday */
5953 res = wait_file(chan, ints, "digits/yesterday", lang);
5954 } else {
5955 res = ast_say_date_with_format_fr(chan, t, ints, lang, "AdBY", tzone);
5956 }
5957 }
5958 break;
5959 case 'q':
5960 /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
5961 /* XXX As emphasized elsewhere, this should the native way in your
5962 * language to say the date, with changes in what you say, depending
5963 * upon how recent the date is. XXX */
5964 {
5965 struct timeval now = ast_tvnow();
5966 struct ast_tm tmnow;
5967 time_t beg_today;
5968
5969 ast_localtime(&now, &tmnow, tzone);
5970 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5971 /* In any case, it saves not having to do ast_mktime() */
5972 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5973 if (beg_today < t) {
5974 /* Today */
5975 } else if ((beg_today - 86400) < t) {
5976 /* Yesterday */
5977 res = wait_file(chan, ints, "digits/yesterday", lang);
5978 } else if (beg_today - 86400 * 6 < t) {
5979 /* Within the last week */
5980 res = ast_say_date_with_format_fr(chan, t, ints, lang, "A", tzone);
5981 } else {
5982 res = ast_say_date_with_format_fr(chan, t, ints, lang, "AdBY", tzone);
5983 }
5984 }
5985 break;
5986 case 'R':
5987 res = ast_say_date_with_format_fr(chan, t, ints, lang, "HM", tzone);
5988 break;
5989 case 'S':
5990 /* Seconds */
5991 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char * ) NULL);
5992 if (!res) {
5993 res = wait_file(chan, ints, "second", lang);
5994 }
5995 break;
5996 case 'T':
5997 res = ast_say_date_with_format_fr(chan, t, ints, lang, "HMS", tzone);
5998 break;
5999 case ' ':
6000 case ' ':
6001 /* Just ignore spaces and tabs */
6002 break;
6003 default:
6004 /* Unknown character */
6005 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
6006 }
6007 /* Jump out on DTMF */
6008 if (res) {
6009 break;
6010 }
6011 }
6012 return res;
6013}
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:5820

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_fr(), 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_say_date_with_format_fr(), and say_date_with_format().

◆ 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 8647 of file say.c.

8648{
8649 struct timeval when = { t, 0 };
8650 struct ast_tm tm;
8651 int res=0, offset, sndoffset;
8652 char sndfile[256], nextmsg[256];
8653
8654 if (!format)
8655 format = "AdBY 'digits/at' IMp";
8656
8657 ast_localtime(&when, &tm, tzone);
8658
8659 for (offset=0 ; format[offset] != '\0' ; offset++) {
8660 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
8661 switch (format[offset]) {
8662 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
8663 case '\'':
8664 /* Literal name of a sound file */
8665 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
8666 sndfile[sndoffset] = format[offset];
8667 }
8668 sndfile[sndoffset] = '\0';
8669 res = wait_file(chan, ints, sndfile, lang);
8670 break;
8671 case 'A':
8672 case 'a':
8673 /* Sunday - Saturday */
8674 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
8675 res = wait_file(chan, ints, nextmsg, lang);
8676 break;
8677 case 'B':
8678 case 'b':
8679 case 'h':
8680 /* January - December */
8681 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
8682 res = wait_file(chan, ints, nextmsg, lang);
8683 break;
8684 case 'd':
8685 case 'e':
8686 /* first - thirtyfirst */
8687 gr_say_number_female(tm.tm_mday, chan, ints, lang);
8688 break;
8689 case 'Y':
8690 /* Year */
8691
8692 ast_say_number_full_gr(chan, 1900+tm.tm_year, ints, ast_channel_language(chan), -1, -1);
8693 break;
8694 case 'I':
8695 case 'l':
8696 /* 12-Hour */
8697 if (tm.tm_hour == 0)
8698 gr_say_number_female(12, chan, ints, lang);
8699 else if (tm.tm_hour > 12)
8700 gr_say_number_female(tm.tm_hour - 12, chan, ints, lang);
8701 else
8702 gr_say_number_female(tm.tm_hour, chan, ints, lang);
8703 break;
8704 case 'H':
8705 case 'k':
8706 /* 24-Hour */
8707 gr_say_number_female(tm.tm_hour, chan, ints, lang);
8708 break;
8709 case 'M':
8710 /* Minute */
8711 if (tm.tm_min) {
8712 if (!res)
8713 res = ast_streamfile(chan, "digits/kai", lang);
8714 if (!res)
8715 res = ast_waitstream(chan, ints);
8716 if (!res)
8717 res = ast_say_number_full_gr(chan, tm.tm_min, ints, lang, -1, -1);
8718 } else {
8719 if (!res)
8720 res = ast_streamfile(chan, "digits/oclock", lang);
8721 if (!res)
8722 res = ast_waitstream(chan, ints);
8723 }
8724 break;
8725 case 'P':
8726 case 'p':
8727 /* AM/PM */
8728 if (tm.tm_hour > 11)
8729 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
8730 else
8731 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
8732 res = wait_file(chan, ints, nextmsg, lang);
8733 break;
8734 case 'Q':
8735 /* Shorthand for "Today", "Yesterday", or ABdY */
8736 /* XXX As emphasized elsewhere, this should the native way in your
8737 * language to say the date, with changes in what you say, depending
8738 * upon how recent the date is. XXX */
8739 {
8740 struct timeval now = ast_tvnow();
8741 struct ast_tm tmnow;
8742 time_t beg_today;
8743
8744 ast_localtime(&now, &tmnow, tzone);
8745 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
8746 /* In any case, it saves not having to do ast_mktime() */
8747 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
8748 if (beg_today < t) {
8749 /* Today */
8750 res = wait_file(chan, ints, "digits/today", lang);
8751 } else if (beg_today - 86400 < t) {
8752 /* Yesterday */
8753 res = wait_file(chan, ints, "digits/yesterday", lang);
8754 } else {
8755 res = ast_say_date_with_format_gr(chan, t, ints, lang, "AdBY", tzone);
8756 }
8757 }
8758 break;
8759 case 'q':
8760 /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
8761 /* XXX As emphasized elsewhere, this should the native way in your
8762 * language to say the date, with changes in what you say, depending
8763 * upon how recent the date is. XXX */
8764 {
8765 struct timeval now = ast_tvnow();
8766 struct ast_tm tmnow;
8767 time_t beg_today;
8768
8769 ast_localtime(&now, &tmnow, tzone);
8770 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
8771 /* In any case, it saves not having to do ast_mktime() */
8772 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
8773 if (beg_today < t) {
8774 /* Today */
8775 } else if ((beg_today - 86400) < t) {
8776 /* Yesterday */
8777 res = wait_file(chan, ints, "digits/yesterday", lang);
8778 } else if (beg_today - 86400 * 6 < t) {
8779 /* Within the last week */
8780 res = ast_say_date_with_format_gr(chan, t, ints, lang, "A", tzone);
8781 } else {
8782 res = ast_say_date_with_format_gr(chan, t, ints, lang, "AdBY", tzone);
8783 }
8784 }
8785 break;
8786 case 'R':
8787 res = ast_say_date_with_format_gr(chan, t, ints, lang, "HM", tzone);
8788 break;
8789 case 'S':
8790 /* Seconds */
8791 ast_copy_string(nextmsg, "digits/kai", sizeof(nextmsg));
8792 res = wait_file(chan, ints, nextmsg, lang);
8793 if (!res)
8794 res = ast_say_number_full_gr(chan, tm.tm_sec, ints, lang, -1, -1);
8795 if (!res)
8796 ast_copy_string(nextmsg, "seconds", sizeof(nextmsg));
8797 res = wait_file(chan, ints, nextmsg, lang);
8798 break;
8799 case 'T':
8800 res = ast_say_date_with_format_gr(chan, t, ints, lang, "HMS", tzone);
8801 break;
8802 case ' ':
8803 case ' ':
8804 /* Just ignore spaces and tabs */
8805 break;
8806 default:
8807 /* Unknown character */
8808 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
8809 }
8810 /* Jump out on DTMF */
8811 if (res) {
8812 break;
8813 }
8814 }
8815 return res;
8816}
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:8647
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:8228

References ast_channel_language(), ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_gr(), 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_say_date_with_format_gr(), and say_date_with_format().

◆ 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:

Definition at line 5482 of file say.c.

5483{
5484#define IL_DATE_STR "AdBY"
5485#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 */
5486#define IL_DATE_STR_FULL IL_DATE_STR " 'digits/at' " IL_TIME_STR
5487 /* TODO: This whole function is cut&paste from
5488 * ast_say_date_with_format_en . Is that considered acceptable?
5489 **/
5490 struct timeval when = { t, 0 };
5491 struct ast_tm tm;
5492 int res = 0, offset, sndoffset;
5493 char sndfile[256], nextmsg[256];
5494
5495 if (!format) {
5496 format = IL_DATE_STR_FULL;
5497 }
5498
5499 ast_localtime(&when, &tm, tzone);
5500
5501 for (offset = 0; format[offset] != '\0'; offset++) {
5502 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
5503 switch (format[offset]) {
5504 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
5505 case '\'':
5506 /* Literal name of a sound file */
5507 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
5508 sndfile[sndoffset] = format[offset];
5509 }
5510 sndfile[sndoffset] = '\0';
5511 res = wait_file(chan, ints, sndfile, lang);
5512 break;
5513 case 'A':
5514 case 'a':
5515 /* Sunday - Saturday */
5516 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
5517 res = wait_file(chan, ints, nextmsg, lang);
5518 break;
5519 case 'B':
5520 case 'b':
5521 case 'h':
5522 /* January - December */
5523 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
5524 res = wait_file(chan, ints, nextmsg, lang);
5525 break;
5526 case 'd':
5527 case 'e': /* Day of the month */
5528 /* I'm not sure exactly what the parameters
5529 * audiofd and ctrlfd to
5530 * ast_say_number_full_he mean, but it seems
5531 * safe to pass -1 there.
5532 *
5533 * At least in one of the paths :-(
5534 */
5535 res = ast_say_number_full_he(chan, tm.tm_mday, ints, lang, "m", -1, -1);
5536 break;
5537 case 'Y': /* Year */
5538 res = ast_say_number_full_he(chan, tm.tm_year + 1900, ints, lang, "f", -1, -1);
5539 break;
5540 case 'I':
5541 case 'l': /* 12-Hour -> we do not support 12 hour based languages in Hebrew */
5542 case 'H':
5543 case 'k': /* 24-Hour */
5544 res = ast_say_number_full_he(chan, tm.tm_hour, ints, lang, "f", -1, -1);
5545 break;
5546 case 'M': /* Minute */
5547 if (tm.tm_min >= 0 && tm.tm_min <= 9) /* say a leading zero if needed */
5548 res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
5549 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
5550 break;
5551 case 'P':
5552 case 'p':
5553 /* AM/PM - There is no AM/PM in Hebrew... */
5554 break;
5555 case 'Q':
5556 /* Shorthand for "Today", "Yesterday", or "date" */
5557 case 'q':
5558 /* Shorthand for "" (today), "Yesterday", A
5559 * (weekday), or "date" */
5560 /* XXX As emphasized elsewhere, this should the native way in your
5561 * language to say the date, with changes in what you say, depending
5562 * upon how recent the date is. XXX */
5563 {
5564 struct timeval now = ast_tvnow();
5565 struct ast_tm tmnow;
5566 time_t beg_today;
5567 char todo = format[offset]; /* The letter to format*/
5568
5569 ast_localtime(&now, &tmnow, tzone);
5570 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5571 /* In any case, it saves not having to do ast_mktime() */
5572 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5573 if (beg_today < t) {
5574 /* Today */
5575 if (todo == 'Q') {
5576 res = wait_file(chan, ints, "digits/today", lang);
5577 }
5578 } else if (beg_today - 86400 < t) {
5579 /* Yesterday */
5580 res = wait_file(chan, ints, "digits/yesterday", lang);
5581 } else if ((todo != 'Q') && (beg_today - 86400 * 6 < t)) {
5582 /* Within the last week */
5583 res = ast_say_date_with_format_he(chan, t, ints, lang, "A", tzone);
5584 } else {
5585 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
5586 }
5587 }
5588 break;
5589 case 'R':
5590 res = ast_say_date_with_format_he(chan, t, ints, lang, "HM", tzone);
5591 break;
5592 case 'S': /* Seconds */
5593 res = ast_say_number_full_he(chan, tm.tm_sec,
5594 ints, lang, "f", -1, -1
5595 );
5596 break;
5597 case 'T':
5598 res = ast_say_date_with_format_he(chan, t, ints, lang, "HMS", tzone);
5599 break;
5600 /* c, x, and X seem useful for testing. Not sure
5601 * if they're good for the general public */
5602 case 'c':
5603 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR_FULL, tzone);
5604 break;
5605 case 'x':
5606 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
5607 break;
5608 case 'X': /* Currently not locale-dependent...*/
5609 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_TIME_STR, tzone);
5610 break;
5611 case ' ':
5612 case ' ':
5613 /* Just ignore spaces and tabs */
5614 break;
5615 default:
5616 /* Unknown character */
5617 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
5618 }
5619 /* Jump out on DTMF */
5620 if (res) {
5621 break;
5622 }
5623 }
5624 return res;
5625}
#define IL_DATE_STR
#define IL_DATE_STR_FULL
#define IL_TIME_STR
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:1597
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:5482

References ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_he(), 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_say_date_with_format_he(), and say_date_with_format().

◆ 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 5085 of file say.c.

5086{
5087 struct timeval when = { t, 0 };
5088 struct ast_tm tm;
5089 int res=0, offset, sndoffset;
5090 char sndfile[256], nextmsg[256];
5091
5092 if (!format)
5093 format = "A dBY HMS";
5094
5095 ast_localtime(&when, &tm, tzone);
5096
5097 for (offset=0 ; format[offset] != '\0' ; offset++) {
5098 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
5099 switch (format[offset]) {
5100 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
5101 case '\'':
5102 /* Literal name of a sound file */
5103 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
5104 sndfile[sndoffset] = format[offset];
5105 }
5106 sndfile[sndoffset] = '\0';
5107 res = wait_file(chan, ints, sndfile, lang);
5108 break;
5109 case 'A':
5110 case 'a':
5111 /* Sunday - Saturday */
5112 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
5113 res = wait_file(chan, ints, nextmsg, lang);
5114 break;
5115 case 'B':
5116 case 'b':
5117 case 'h':
5118 /* January - December */
5119 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
5120 res = wait_file(chan, ints, nextmsg, lang);
5121 break;
5122 case 'm':
5123 /* Month enumerated */
5124 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
5125 break;
5126 case 'd':
5127 case 'e':
5128 /* First - Thirtyfirst */
5129 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
5130 break;
5131 case 'Y':
5132 /* Year */
5133 {
5134 int year = tm.tm_year + 1900;
5135 if (year > 1999) { /* year 2000 and later */
5136 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
5137 } else {
5138 if (year < 1100) {
5139 /* I'm not going to handle 1100 and prior */
5140 /* We'll just be silent on the year, instead of bombing out. */
5141 } else {
5142 /* year 1100 to 1999. will anybody need this?!? */
5143 /* say 1967 as 'nineteen hundred seven and sixty' */
5144 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
5145 res = wait_file(chan, ints, nextmsg, lang);
5146 if (!res) {
5147 res = wait_file(chan, ints, "digits/hundred", lang);
5148 if (!res && year % 100 != 0) {
5149 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
5150 }
5151 }
5152 }
5153 }
5154 }
5155 break;
5156 case 'I':
5157 case 'l':
5158 /* 12-Hour */
5159 res = wait_file(chan, ints, "digits/oclock", lang);
5160 if (tm.tm_hour == 0)
5161 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
5162 else if (tm.tm_hour > 12)
5163 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
5164 else
5165 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
5166 if (!res) {
5167 res = wait_file(chan, ints, nextmsg, lang);
5168 }
5169 break;
5170 case 'H':
5171 /* 24-Hour, single digit hours preceeded by "oh" (0) */
5172 if (tm.tm_hour < 10 && tm.tm_hour > 0) {
5173 res = wait_file(chan, ints, "digits/0", lang);
5174 }
5175 /* FALLTRHU */
5176 case 'k':
5177 /* 24-Hour */
5178 res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
5179 break;
5180 case 'M':
5181 /* Minute */
5182 if (tm.tm_min > 0 || next_item(&format[offset + 1]) == 'S') { /* zero 'digits/0' only if seconds follow */
5183 if (tm.tm_min < 10)
5184 res = wait_file(chan, ints, "digits/0", lang);
5185 /* Gender depends on whether or not seconds follow */
5186 if (next_item(&format[offset + 1]) == 'S')
5187 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
5188 else
5189 res = ast_say_number(chan, tm.tm_min, ints, lang, "n");
5190 }
5191 if (!res && next_item(&format[offset + 1]) == 'S') { /* minutes only if seconds follow */
5192 /* Say minute/minutes depending on whether minutes end in 1 */
5193 if ((tm.tm_min % 10 == 1) && (tm.tm_min != 11)) {
5194 res = wait_file(chan, ints, "minute", lang);
5195 } else {
5196 res = wait_file(chan, ints, "minutes", lang);
5197 }
5198 }
5199 break;
5200 case 'P':
5201 case 'p':
5202 /* AM/PM */
5203 if (tm.tm_hour > 11)
5204 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
5205 else
5206 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
5207 res = wait_file(chan, ints, nextmsg, lang);
5208 break;
5209 case 'Q':
5210 /* Shorthand for "Today", "Yesterday", or AdBY */
5211 /* XXX As emphasized elsewhere, this should the native way in your
5212 * language to say the date, with changes in what you say, depending
5213 * upon how recent the date is. XXX */
5214 {
5215 struct timeval now = ast_tvnow();
5216 struct ast_tm tmnow;
5217 time_t beg_today;
5218
5219 ast_localtime(&now, &tmnow, tzone);
5220 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5221 /* In any case, it saves not having to do ast_mktime() */
5222 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5223 if (beg_today < t) {
5224 /* Today */
5225 res = wait_file(chan, ints, "digits/today", lang);
5226 } else if (beg_today - 86400 < t) {
5227 /* Yesterday */
5228 res = wait_file(chan, ints, "digits/yesterday", lang);
5229 } else {
5230 res = ast_say_date_with_format_is(chan, t, ints, lang, "AdBY", tzone);
5231 }
5232 }
5233 break;
5234 case 'q':
5235 /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
5236 /* XXX As emphasized elsewhere, this should the native way in your
5237 * language to say the date, with changes in what you say, depending
5238 * upon how recent the date is. XXX */
5239 {
5240 struct timeval now = ast_tvnow();
5241 struct ast_tm tmnow;
5242 time_t beg_today;
5243
5244 ast_localtime(&now, &tmnow, tzone);
5245 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5246 /* In any case, it saves not having to do ast_mktime() */
5247 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5248 if (beg_today < t) {
5249 /* Today */
5250 } else if ((beg_today - 86400) < t) {
5251 /* Yesterday */
5252 res = wait_file(chan, ints, "digits/yesterday", lang);
5253 } else if (beg_today - 86400 * 6 < t) {
5254 /* Within the last week */
5255 res = ast_say_date_with_format_is(chan, t, ints, lang, "A", tzone);
5256 } else {
5257 res = ast_say_date_with_format_is(chan, t, ints, lang, "AdBY", tzone);
5258 }
5259 }
5260 break;
5261 case 'R':
5262 res = ast_say_date_with_format_is(chan, t, ints, lang, "HM", tzone);
5263 break;
5264 case 'S':
5265 /* Seconds */
5266 res = wait_file(chan, ints, "digits/and", lang);
5267 if (!res) {
5268 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
5269 /* Say minute/minutes depending on whether seconds end in 1 */
5270 if (!res && (tm.tm_sec % 10 == 1) && (tm.tm_sec != 11)) {
5271 res = wait_file(chan, ints, "second", lang);
5272 } else {
5273 res = wait_file(chan, ints, "seconds", lang);
5274 }
5275 }
5276 break;
5277 case 'T':
5278 res = ast_say_date_with_format_is(chan, t, ints, lang, "HMS", tzone);
5279 break;
5280 case ' ':
5281 case ' ':
5282 /* Just ignore spaces and tabs */
5283 break;
5284 default:
5285 /* Unknown character */
5286 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
5287 }
5288 /* Jump out on DTMF */
5289 if (res) {
5290 break;
5291 }
5292 }
5293 return res;
5294}
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:5085

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_is(), 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_say_date_with_format_is(), and say_date_with_format().

◆ 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 6016 of file say.c.

6017{
6018 struct timeval when = { t, 0 };
6019 struct ast_tm tm;
6020 int res=0, offset, sndoffset;
6021 char sndfile[256], nextmsg[256];
6022
6023 if (format == NULL)
6024 format = "AdB 'digits/at' IMp";
6025
6026 ast_localtime(&when, &tm, tzone);
6027
6028 for (offset=0 ; format[offset] != '\0' ; offset++) {
6029 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
6030 switch (format[offset]) {
6031 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
6032 case '\'':
6033 /* Literal name of a sound file */
6034 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
6035 sndfile[sndoffset] = format[offset];
6036 }
6037 sndfile[sndoffset] = '\0';
6038 res = wait_file(chan, ints, sndfile, lang);
6039 break;
6040 case 'A':
6041 case 'a':
6042 /* Sunday - Saturday */
6043 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
6044 res = wait_file(chan, ints, nextmsg, lang);
6045 break;
6046 case 'B':
6047 case 'b':
6048 case 'h':
6049 /* January - December */
6050 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
6051 res = wait_file(chan, ints, nextmsg, lang);
6052 break;
6053 case 'm':
6054 /* First - Twelfth */
6055 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
6056 res = wait_file(chan, ints, nextmsg, lang);
6057 break;
6058 case 'd':
6059 case 'e':
6060 /* First day of the month is spelled as ordinal */
6061 if (tm.tm_mday == 1) {
6062 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
6063 res = wait_file(chan, ints, nextmsg, lang);
6064 } else {
6065 if (!res) {
6066 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
6067 }
6068 }
6069 break;
6070 case 'Y':
6071 /* Year */
6072 if (tm.tm_year > 99) {
6073 res = wait_file(chan, ints, "digits/ore-2000", lang);
6074 if (tm.tm_year > 100) {
6075 if (!res) {
6076 /* This works until the end of 2021 */
6077 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
6078 res = wait_file(chan, ints, nextmsg, lang);
6079 }
6080 }
6081 } else {
6082 if (tm.tm_year < 1) {
6083 /* I'm not going to handle 1900 and prior */
6084 /* We'll just be silent on the year, instead of bombing out. */
6085 } else {
6086 res = wait_file(chan, ints, "digits/ore-1900", lang);
6087 if ((!res) && (tm.tm_year != 0)) {
6088 if (tm.tm_year <= 21) {
6089 /* 1910 - 1921 */
6090 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
6091 res = wait_file(chan, ints, nextmsg, lang);
6092 } else {
6093 /* 1922 - 1999, but sounds badly in 1928, 1931, 1938, etc... */
6094 int ten, one;
6095 ten = tm.tm_year / 10;
6096 one = tm.tm_year % 10;
6097 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten * 10);
6098 res = wait_file(chan, ints, nextmsg, lang);
6099 if (!res) {
6100 if (one != 0) {
6101 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
6102 res = wait_file(chan, ints, nextmsg, lang);
6103 }
6104 }
6105 }
6106 }
6107 }
6108 }
6109 break;
6110 case 'I':
6111 case 'l':
6112 /* 12-Hour */
6113 if (tm.tm_hour == 0) {
6114 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
6115 } else if (tm.tm_hour > 12) {
6116 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
6117 } else {
6118 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
6119 }
6120 res = wait_file(chan, ints, nextmsg, lang);
6121 break;
6122 case 'H':
6123 case 'k':
6124 /* 24-Hour */
6125 if (tm.tm_hour == 0) {
6126 res = wait_file(chan, ints, "digits/ore-mezzanotte", lang);
6127 } else if (tm.tm_hour == 1) {
6128 res = wait_file(chan, ints, "digits/ore-una", lang);
6129 } else {
6130 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
6131 }
6132 break;
6133 case 'M':
6134 /* Minute */
6135 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
6136 break;
6137 case 'P':
6138 case 'p':
6139 /* AM/PM */
6140 if (tm.tm_hour > 11) {
6141 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
6142 } else {
6143 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
6144 }
6145 res = wait_file(chan, ints, nextmsg, lang);
6146 break;
6147 case 'Q':
6148 /* Shorthand for "Today", "Yesterday", or ABdY */
6149 /* XXX As emphasized elsewhere, this should the native way in your
6150 * language to say the date, with changes in what you say, depending
6151 * upon how recent the date is. XXX */
6152 {
6153 struct timeval now = ast_tvnow();
6154 struct ast_tm tmnow;
6155 time_t beg_today;
6156
6157 ast_localtime(&now, &tmnow, tzone);
6158 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6159 /* In any case, it saves not having to do ast_mktime() */
6160 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6161 if (beg_today < t) {
6162 /* Today */
6163 res = wait_file(chan, ints, "digits/today", lang);
6164 } else if (beg_today - 86400 < t) {
6165 /* Yesterday */
6166 res = wait_file(chan, ints, "digits/yesterday", lang);
6167 } else {
6168 res = ast_say_date_with_format_it(chan, t, ints, lang, "AdB", tzone);
6169 }
6170 }
6171 break;
6172 case 'q':
6173 /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
6174 {
6175 struct timeval now = ast_tvnow();
6176 struct ast_tm tmnow;
6177 time_t beg_today;
6178
6179 ast_localtime(&now, &tmnow, tzone);
6180 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6181 /* In any case, it saves not having to do ast_mktime() */
6182 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6183 if (beg_today < t) {
6184 /* Today */
6185 } else if ((beg_today - 86400) < t) {
6186 /* Yesterday */
6187 res = wait_file(chan, ints, "digits/yesterday", lang);
6188 } else if (beg_today - 86400 * 6 < t) {
6189 /* Within the last week */
6190 res = ast_say_date_with_format_it(chan, t, ints, lang, "A", tzone);
6191 } else {
6192 res = ast_say_date_with_format_it(chan, t, ints, lang, "AdB", tzone);
6193 }
6194 }
6195 break;
6196 case 'R':
6197 res = ast_say_date_with_format_it(chan, t, ints, lang, "HM", tzone);
6198 break;
6199 case 'S':
6200 /* Seconds */
6201 if (tm.tm_sec == 0) {
6202 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6203 res = wait_file(chan, ints, nextmsg, lang);
6204 } else if (tm.tm_sec < 10) {
6205 res = wait_file(chan, ints, "digits/oh", lang);
6206 if (!res) {
6207 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6208 res = wait_file(chan, ints, nextmsg, lang);
6209 }
6210 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
6211 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6212 res = wait_file(chan, ints, nextmsg, lang);
6213 } else {
6214 int ten, one;
6215 ten = (tm.tm_sec / 10) * 10;
6216 one = (tm.tm_sec % 10);
6217 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
6218 res = wait_file(chan, ints, nextmsg, lang);
6219 if (!res) {
6220 /* Fifty, not fifty-zero */
6221 if (one != 0) {
6222 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
6223 res = wait_file(chan, ints, nextmsg, lang);
6224 }
6225 }
6226 }
6227 break;
6228 case 'T':
6229 res = ast_say_date_with_format_it(chan, t, ints, lang, "HMS", tzone);
6230 break;
6231 case ' ':
6232 case ' ':
6233 /* Just ignore spaces and tabs */
6234 break;
6235 default:
6236 /* Unknown character */
6237 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
6238 }
6239 /* Jump out on DTMF */
6240 if (res) {
6241 break;
6242 }
6243 }
6244 return res;
6245}
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:6016

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_it(), 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_say_date_with_format_it(), and say_date_with_format().

◆ 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 8819 of file say.c.

8820{
8821 struct timeval tv = { time, 0 };
8822 struct ast_tm tm;
8823 int res = 0, offset, sndoffset;
8824 char sndfile[256], nextmsg[256];
8825
8826 if (!format)
8827 format = "YbdAPIMS";
8828
8829 ast_localtime(&tv, &tm, timezone);
8830
8831 for (offset = 0; format[offset] != '\0'; offset++) {
8832 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
8833 switch (format[offset]) {
8834 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
8835 case '\'':
8836 /* Literal name of a sound file */
8837 for (sndoffset = 0; (format[++offset] != '\'') && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
8838 sndfile[sndoffset] = format[offset];
8839 }
8840 sndfile[sndoffset] = '\0';
8841 res = wait_file(chan,ints,sndfile,lang);
8842 break;
8843 case 'A':
8844 case 'a':
8845 /* Sunday - Saturday */
8846 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
8847 res = wait_file(chan,ints,nextmsg,lang);
8848 break;
8849 case 'B':
8850 case 'b':
8851 case 'h':
8852 /* January - December */
8853 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
8854 res = wait_file(chan,ints,nextmsg,lang);
8855 break;
8856 case 'd':
8857 case 'e':
8858 /* First - Thirtyfirst */
8859 if (tm.tm_mday < 21) {
8860 snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d_2", tm.tm_mday);
8861 res = wait_file(chan,ints,nextmsg,lang);
8862 } else if (tm.tm_mday < 30) {
8863 /* Between 21 and 29 - two sounds */
8864 res = wait_file(chan,ints, "digits/20",lang);
8865 if (!res) {
8866 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_mday - 20);
8867 res = wait_file(chan,ints,nextmsg,lang);
8868 }
8869 res = wait_file(chan,ints, "digits/nichi",lang);
8870 } else if (tm.tm_mday == 30) {
8871 /* 30 */
8872 res = wait_file(chan,ints, "digits/h-30_2",lang);
8873 } else {
8874 /* 31 */
8875 res = wait_file(chan,ints, "digits/30",lang);
8876 res = wait_file(chan,ints, "digits/1",lang);
8877 res = wait_file(chan,ints, "digits/nichi",lang);
8878 }
8879 break;
8880 case 'Y':
8881 /* Year */
8882 if (tm.tm_year > 99) {
8883 res = wait_file(chan,ints, "digits/2",lang);
8884 if (!res) {
8885 res = wait_file(chan,ints, "digits/thousand",lang);
8886 }
8887 if (tm.tm_year > 100) {
8888 if (!res) {
8889 /* This works until the end of 2020 */
8890 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
8891 res = wait_file(chan,ints,nextmsg,lang);
8892 }
8893 }
8894 } else {
8895 if (tm.tm_year < 1) {
8896 /* I'm not going to handle 1900 and prior */
8897 /* We'll just be silent on the year, instead of bombing out. */
8898 } else {
8899 res = wait_file(chan,ints, "digits/19",lang);
8900 if (!res) {
8901 if (tm.tm_year <= 9) {
8902 /* 1901 - 1909 */
8903 res = wait_file(chan,ints, "digits/oh",lang);
8904 if (!res) {
8905 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
8906 res = wait_file(chan,ints,nextmsg,lang);
8907 }
8908 } else if (tm.tm_year <= 20) {
8909 /* 1910 - 1920 */
8910 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
8911 res = wait_file(chan,ints,nextmsg,lang);
8912 } else {
8913 /* 1921 - 1999 */
8914 int ten, one;
8915 ten = tm.tm_year / 10;
8916 one = tm.tm_year % 10;
8917 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten * 10);
8918 res = wait_file(chan,ints,nextmsg,lang);
8919 if (!res) {
8920 if (one != 0) {
8921 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
8922 res = wait_file(chan,ints,nextmsg,lang);
8923 }
8924 }
8925 }
8926 }
8927 }
8928 }
8929 res = wait_file(chan,ints, "digits/nen",lang);
8930 break;
8931 case 'P':
8932 case 'p':
8933 /* AM/PM */
8934 if (tm.tm_hour > 11)
8935 snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
8936 else
8937 snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
8938 res = wait_file(chan,ints,nextmsg,lang);
8939 break;
8940 case 'I':
8941 case 'l':
8942 /* 12-Hour */
8943 if (tm.tm_hour == 0)
8944 snprintf(nextmsg,sizeof(nextmsg), "digits/12");
8945 else if (tm.tm_hour == 9 || tm.tm_hour == 21)
8946 snprintf(nextmsg,sizeof(nextmsg), "digits/9_2");
8947 else if (tm.tm_hour > 12)
8948 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
8949 else
8950 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
8951 res = wait_file(chan,ints,nextmsg,lang);
8952 if(!res) res = wait_file(chan,ints, "digits/ji",lang);
8953 break;
8954 case 'H':
8955 case 'k':
8956 if (!res) {
8957 if (tm.tm_hour != 0) {
8958 int remainder = tm.tm_hour;
8959 if (tm.tm_hour > 20) {
8960 res = wait_file(chan,ints, "digits/20",lang);
8961 remainder -= 20;
8962 }
8963 if (!res) {
8964 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", remainder);
8965 res = wait_file(chan,ints,nextmsg,lang);
8966 }
8967 }
8968 }
8969 res = wait_file(chan,ints, "digits/ji",lang);
8970 break;
8971 case 'M':
8972 /* Minute */
8973 if ((tm.tm_min < 21) || (tm.tm_min % 10 == 0)) {
8974 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min);
8975 res = wait_file(chan,ints,nextmsg,lang);
8976 } else {
8977 int ten, one;
8978 ten = (tm.tm_min / 10) * 10;
8979 one = (tm.tm_min % 10);
8980 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
8981 res = wait_file(chan,ints,nextmsg,lang);
8982 if (!res) {
8983 /* Fifty, not fifty-zero */
8984 if (one != 0) {
8985 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
8986 res = wait_file(chan,ints,nextmsg,lang);
8987 }
8988 }
8989 }
8990 res = wait_file(chan,ints, "digits/fun",lang);
8991 break;
8992 case 'Q':
8993 /* Shorthand for "Today", "Yesterday", or ABdY */
8994 {
8995 struct timeval now;
8996 struct ast_tm tmnow;
8997 time_t beg_today;
8998
8999 gettimeofday(&now,NULL);
9000 ast_localtime(&now,&tmnow,timezone);
9001 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
9002 /* In any case, it saves not having to do ast_mktime() */
9003 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
9004 if (beg_today < time) {
9005 /* Today */
9006 res = wait_file(chan,ints, "digits/today",lang);
9007 } else if (beg_today - 86400 < time) {
9008 /* Yesterday */
9009 res = wait_file(chan,ints, "digits/yesterday",lang);
9010 } else {
9011 res = ast_say_date_with_format(chan, time, ints, lang, "ABdY", timezone);
9012 }
9013 }
9014 break;
9015 case 'q':
9016 /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
9017 {
9018 struct timeval now;
9019 struct ast_tm tmnow;
9020 time_t beg_today;
9021
9022 gettimeofday(&now,NULL);
9023 ast_localtime(&now,&tmnow,timezone);
9024 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
9025 /* In any case, it saves not having to do ast_mktime() */
9026 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
9027 if (beg_today < time) {
9028 /* Today */
9029 } else if ((beg_today - 86400) < time) {
9030 /* Yesterday */
9031 res = wait_file(chan,ints, "digits/yesterday",lang);
9032 } else if (beg_today - 86400 * 6 < time) {
9033 /* Within the last week */
9034 res = ast_say_date_with_format(chan, time, ints, lang, "A", timezone);
9035 } else {
9036 res = ast_say_date_with_format(chan, time, ints, lang, "ABdY", timezone);
9037 }
9038 }
9039 break;
9040 case 'R':
9041 res = ast_say_date_with_format(chan, time, ints, lang, "HM", timezone);
9042 break;
9043 case 'S':
9044 /* Seconds */
9045 if (tm.tm_sec == 0) {
9046 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
9047 res = wait_file(chan,ints,nextmsg,lang);
9048 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
9049 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
9050 res = wait_file(chan,ints,nextmsg,lang);
9051 } else {
9052 int ten, one;
9053 ten = (tm.tm_sec / 10) * 10;
9054 one = (tm.tm_sec % 10);
9055 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
9056 res = wait_file(chan,ints,nextmsg,lang);
9057 if (!res) {
9058 /* Fifty, not fifty-zero */
9059 if (one != 0) {
9060 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
9061 res = wait_file(chan,ints,nextmsg,lang);
9062 }
9063 }
9064 }
9065 res = wait_file(chan,ints, "digits/byou",lang);
9066 break;
9067 case 'T':
9068 res = ast_say_date_with_format(chan, time, ints, lang, "HMS", timezone);
9069 break;
9070 case ' ':
9071 case ' ':
9072 /* Just ignore spaces and tabs */
9073 break;
9074 default:
9075 /* Unknown character */
9076 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
9077 }
9078 /* Jump out on DTMF */
9079 if (res) {
9080 break;
9081 }
9082 }
9083 return res;
9084}
#define LOG_DEBUG

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 say_date_with_format().

◆ 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 6248 of file say.c.

6249{
6250 struct timeval when = { t, 0 };
6251 struct ast_tm tm;
6252 int res=0, offset, sndoffset;
6253 char sndfile[256], nextmsg[256];
6254
6255 if (format == NULL)
6256 format = "AdBY 'digits/at' IMp";
6257
6258 ast_localtime(&when, &tm, tzone);
6259
6260 for (offset=0 ; format[offset] != '\0' ; offset++) {
6261 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
6262 switch (format[offset]) {
6263 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
6264 case '\'':
6265 /* Literal name of a sound file */
6266 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
6267 sndfile[sndoffset] = format[offset];
6268 }
6269 sndfile[sndoffset] = '\0';
6270 res = wait_file(chan, ints, sndfile, lang);
6271 break;
6272 case 'A':
6273 case 'a':
6274 /* Sunday - Saturday */
6275 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
6276 res = wait_file(chan, ints, nextmsg, lang);
6277 break;
6278 case 'B':
6279 case 'b':
6280 case 'h':
6281 /* January - December */
6282 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
6283 res = wait_file(chan, ints, nextmsg, lang);
6284 break;
6285 case 'm':
6286 /* First - Twelfth */
6287 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
6288 res = wait_file(chan, ints, nextmsg, lang);
6289 break;
6290 case 'd':
6291 case 'e':
6292 /* First - Thirtyfirst */
6293 res = ast_say_number(chan, tm.tm_mday, ints, lang, NULL);
6294 break;
6295 case 'Y':
6296 /* Year */
6297 if (tm.tm_year > 99) {
6298 res = wait_file(chan, ints, "digits/2", lang);
6299 if (!res) {
6300 res = wait_file(chan, ints, "digits/thousand", lang);
6301 }
6302 if (tm.tm_year > 100) {
6303 if (!res) {
6304 res = ast_say_number(chan, tm.tm_year - 100, ints, lang, (char *) NULL);
6305 }
6306 }
6307 } else {
6308 if (tm.tm_year < 1) {
6309 /* I'm not going to handle 1900 and prior */
6310 /* We'll just be silent on the year, instead of bombing out. */
6311 } else {
6312 res = wait_file(chan, ints, "digits/19", lang);
6313 if (!res) {
6314 if (tm.tm_year <= 9) {
6315 /* 1901 - 1909 */
6316 res = wait_file(chan, ints, "digits/oh", lang);
6317 if (!res) {
6318 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
6319 res = wait_file(chan, ints, nextmsg, lang);
6320 }
6321 } else if (tm.tm_year <= 20) {
6322 /* 1910 - 1920 */
6323 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
6324 res = wait_file(chan, ints, nextmsg, lang);
6325 } else {
6326 /* 1921 - 1999 */
6327 int ten, one;
6328 ten = tm.tm_year / 10;
6329 one = tm.tm_year % 10;
6330 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten * 10);
6331 res = wait_file(chan, ints, nextmsg, lang);
6332 if (!res) {
6333 if (one != 0) {
6334 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
6335 res = wait_file(chan, ints, nextmsg, lang);
6336 }
6337 }
6338 }
6339 }
6340 }
6341 }
6342 break;
6343 case 'I':
6344 case 'l':
6345 /* 12-Hour */
6346 if (tm.tm_hour == 0)
6347 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
6348 else if (tm.tm_hour > 12)
6349 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
6350 else
6351 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
6352 res = wait_file(chan, ints, nextmsg, lang);
6353 break;
6354 case 'H':
6355 case 'k':
6356 /* 24-Hour */
6357 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
6358 if (!res) {
6359 res = wait_file(chan, ints, "digits/nl-uur", lang);
6360 }
6361 break;
6362 case 'M':
6363 /* Minute */
6364 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
6365 break;
6366 case 'P':
6367 case 'p':
6368 /* AM/PM */
6369 if (tm.tm_hour > 11)
6370 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
6371 else
6372 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
6373 res = wait_file(chan, ints, nextmsg, lang);
6374 break;
6375 case 'Q':
6376 /* Shorthand for "Today", "Yesterday", or AdBY */
6377 /* XXX As emphasized elsewhere, this should the native way in your
6378 * language to say the date, with changes in what you say, depending
6379 * upon how recent the date is. XXX */
6380 {
6381 struct timeval now = ast_tvnow();
6382 struct ast_tm tmnow;
6383 time_t beg_today;
6384
6385 ast_localtime(&now, &tmnow, tzone);
6386 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6387 /* In any case, it saves not having to do ast_mktime() */
6388 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6389 if (beg_today < t) {
6390 /* Today */
6391 res = wait_file(chan, ints, "digits/today", lang);
6392 } else if (beg_today - 86400 < t) {
6393 /* Yesterday */
6394 res = wait_file(chan, ints, "digits/yesterday", lang);
6395 } else {
6396 res = ast_say_date_with_format_nl(chan, t, ints, lang, "AdBY", tzone);
6397 }
6398 }
6399 break;
6400 case 'q':
6401 /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
6402 {
6403 struct timeval now = ast_tvnow();
6404 struct ast_tm tmnow;
6405 time_t beg_today;
6406
6407 ast_localtime(&now, &tmnow, tzone);
6408 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6409 /* In any case, it saves not having to do ast_mktime() */
6410 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6411 if (beg_today < t) {
6412 /* Today */
6413 } else if ((beg_today - 86400) < t) {
6414 /* Yesterday */
6415 res = wait_file(chan, ints, "digits/yesterday", lang);
6416 } else if (beg_today - 86400 * 6 < t) {
6417 /* Within the last week */
6418 res = ast_say_date_with_format_nl(chan, t, ints, lang, "A", tzone);
6419 } else {
6420 res = ast_say_date_with_format_nl(chan, t, ints, lang, "AdBY", tzone);
6421 }
6422 }
6423 break;
6424 case 'R':
6425 res = ast_say_date_with_format_nl(chan, t, ints, lang, "HM", tzone);
6426 break;
6427 case 'S':
6428 /* Seconds */
6429 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
6430 break;
6431 case 'T':
6432 res = ast_say_date_with_format_nl(chan, t, ints, lang, "HMS", tzone);
6433 break;
6434 case ' ':
6435 case ' ':
6436 /* Just ignore spaces and tabs */
6437 break;
6438 default:
6439 /* Unknown character */
6440 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
6441 }
6442 /* Jump out on DTMF */
6443 if (res) {
6444 break;
6445 }
6446 }
6447 return res;
6448}
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:6248

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_nl(), 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_say_date_with_format_nl(), and say_date_with_format().

◆ 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 6451 of file say.c.

6452{
6453 struct timeval when = { thetime, 0 };
6454 struct ast_tm tm;
6455 int res=0, offset, sndoffset;
6456 char sndfile[256], nextmsg[256];
6457
6458 ast_localtime(&when, &tm, tzone);
6459
6460 for (offset = 0 ; format[offset] != '\0' ; offset++) {
6461 int remaining;
6462 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
6463 switch (format[offset]) {
6464 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
6465 case '\'':
6466 /* Literal name of a sound file */
6467 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
6468 sndfile[sndoffset] = format[offset];
6469 }
6470 sndfile[sndoffset] = '\0';
6471 res = wait_file(chan, ints, sndfile, lang);
6472 break;
6473 case 'A':
6474 case 'a':
6475 /* Sunday - Saturday */
6476 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
6477 res = wait_file(chan, ints, nextmsg, lang);
6478 break;
6479 case 'B':
6480 case 'b':
6481 case 'h':
6482 /* January - December */
6483 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
6484 res = wait_file(chan, ints, nextmsg, lang);
6485 break;
6486 case 'm':
6487 /* Month enumerated */
6488 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, NULL);
6489 break;
6490 case 'd':
6491 case 'e':
6492 /* First - Thirtyfirst */
6493 remaining = tm.tm_mday;
6494 if (tm.tm_mday > 30) {
6495 res = wait_file(chan, ints, "digits/h-30", lang);
6496 remaining -= 30;
6497 }
6498 if (tm.tm_mday > 20 && tm.tm_mday < 30) {
6499 res = wait_file(chan, ints, "digits/h-20", lang);
6500 remaining -= 20;
6501 }
6502 if (!res) {
6503 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", remaining);
6504 res = wait_file(chan, ints, nextmsg, lang);
6505 }
6506 break;
6507 case 'Y':
6508 /* Year */
6509 if (tm.tm_year > 100) {
6510 res = wait_file(chan, ints, "digits/2", lang);
6511 if (!res)
6512 res = wait_file(chan, ints, "digits/1000.2", lang);
6513 if (tm.tm_year > 100) {
6514 if (!res)
6515 res = ast_say_enumeration(chan, tm.tm_year - 100, ints, lang, NULL);
6516 }
6517 } else if (tm.tm_year == 100) {
6518 res = wait_file(chan, ints, "digits/h-2000", lang);
6519 } else {
6520 if (tm.tm_year < 1) {
6521 /* I'm not going to handle 1900 and prior */
6522 /* We'll just be silent on the year, instead of bombing out. */
6523 break;
6524 } else {
6525 res = wait_file(chan, ints, "digits/1000", lang);
6526 if (!res) {
6527 wait_file(chan, ints, "digits/900", lang);
6528 res = ast_say_enumeration(chan, tm.tm_year, ints, lang, NULL);
6529 }
6530 }
6531 }
6532 if (!res)
6533 wait_file(chan, ints, "digits/year", lang);
6534 break;
6535 case 'I':
6536 case 'l':
6537 /* 12-Hour */
6538 if (tm.tm_hour == 0)
6539 ast_copy_string(nextmsg, "digits/t-12", sizeof(nextmsg));
6540 else if (tm.tm_hour > 12)
6541 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour - 12);
6542 else
6543 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
6544
6545 res = wait_file(chan, ints, nextmsg, lang);
6546 break;
6547 case 'H':
6548 case 'k':
6549 /* 24-Hour */
6550 if (tm.tm_hour != 0) {
6551 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
6552 res = wait_file(chan, ints, nextmsg, lang);
6553 } else
6554 res = wait_file(chan, ints, "digits/t-24", lang);
6555 break;
6556 case 'M':
6557 case 'N':
6558 /* Minute */
6559 if (tm.tm_min == 0) {
6560 if (format[offset] == 'M') {
6561 res = wait_file(chan, ints, "digits/oclock", lang);
6562 } else {
6563 res = wait_file(chan, ints, "digits/100", lang);
6564 }
6565 } else
6566 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
6567 break;
6568 case 'P':
6569 case 'p':
6570 /* AM/PM */
6571 if (tm.tm_hour > 11)
6572 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
6573 else
6574 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
6575 res = wait_file(chan, ints, nextmsg, lang);
6576 break;
6577 case 'Q':
6578 /* Shorthand for "Today", "Yesterday", or AdBY */
6579 {
6580 struct timeval now = ast_tvnow();
6581 struct ast_tm tmnow;
6582 time_t beg_today;
6583
6584 ast_localtime(&now, &tmnow, tzone);
6585 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6586 /* In any case, it saves not having to do ast_mktime() */
6587 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6588 if (beg_today < thetime) {
6589 /* Today */
6590 res = wait_file(chan, ints, "digits/today", lang);
6591 } else if (beg_today - 86400 < thetime) {
6592 /* Yesterday */
6593 res = wait_file(chan, ints, "digits/yesterday", lang);
6594 } else {
6595 res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", tzone);
6596 }
6597 }
6598 break;
6599 case 'q':
6600 /* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY */
6601 {
6602 struct timeval now = ast_tvnow();
6603 struct ast_tm tmnow;
6604 time_t beg_today;
6605
6606 ast_localtime(&now, &tmnow, tzone);
6607 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6608 /* In any case, it saves not having to do ast_mktime() */
6609 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6610 if (beg_today < thetime) {
6611 /* Today */
6612 } else if ((beg_today - 86400) < thetime) {
6613 /* Yesterday */
6614 res = wait_file(chan, ints, "digits/yesterday", lang);
6615 } else if (beg_today - 86400 * 6 < thetime) {
6616 /* Within the last week */
6617 res = ast_say_date_with_format(chan, thetime, ints, lang, "A", tzone);
6618 } else {
6619 res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", tzone);
6620 }
6621 }
6622 break;
6623 case 'R':
6624 res = ast_say_date_with_format(chan, thetime, ints, lang, "HM", tzone);
6625 break;
6626 case 'S':
6627 /* Seconds */
6628 res = wait_file(chan, ints, "digits/and", lang);
6629 if (!res) {
6630 if (tm.tm_sec == 1) {
6631 res = wait_file(chan, ints, "digits/1z", lang);
6632 if (!res)
6633 res = wait_file(chan, ints, "digits/second-a", lang);
6634 } else {
6635 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
6636 if (!res) {
6637 int ten, one;
6638 ten = tm.tm_sec / 10;
6639 one = tm.tm_sec % 10;
6640
6641 if (one > 1 && one < 5 && ten != 1)
6642 res = wait_file(chan, ints, "seconds", lang);
6643 else
6644 res = wait_file(chan, ints, "second", lang);
6645 }
6646 }
6647 }
6648 break;
6649 case 'T':
6650 res = ast_say_date_with_format(chan, thetime, ints, lang, "HMS", tzone);
6651 break;
6652 case ' ':
6653 case ' ':
6654 /* Just ignore spaces and tabs */
6655 break;
6656 default:
6657 /* Unknown character */
6658 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
6659 }
6660 /* Jump out on DTMF */
6661 if (res)
6662 break;
6663 }
6664 return res;
6665}

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 say_date_with_format().

◆ 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 6668 of file say.c.

6669{
6670 struct timeval when = { t, 0 };
6671 struct ast_tm tm;
6672 int res=0, offset, sndoffset;
6673 char sndfile[256], nextmsg[256];
6674
6675 if (format == NULL)
6676 format = "Ad 'digits/pt-de' B 'digits/pt-de' Y I 'digits/pt-e' Mp";
6677
6678 ast_localtime(&when, &tm, tzone);
6679
6680 for (offset=0 ; format[offset] != '\0' ; offset++) {
6681 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
6682 switch (format[offset]) {
6683 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
6684 case '\'':
6685 /* Literal name of a sound file */
6686 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
6687 sndfile[sndoffset] = format[offset];
6688 }
6689 sndfile[sndoffset] = '\0';
6690 snprintf(nextmsg, sizeof(nextmsg), "%s", sndfile);
6691 res = wait_file(chan, ints, nextmsg, lang);
6692 break;
6693 case 'A':
6694 case 'a':
6695 /* Sunday - Saturday */
6696 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
6697 res = wait_file(chan, ints, nextmsg, lang);
6698 break;
6699 case 'B':
6700 case 'b':
6701 case 'h':
6702 /* January - December */
6703 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
6704 res = wait_file(chan, ints, nextmsg, lang);
6705 break;
6706 case 'm':
6707 /* First - Twelfth */
6708 if (!strcasecmp(lang, "pt_BR")) {
6709 res = ast_say_number(chan, tm.tm_mon+1, ints, lang, (char *) NULL);
6710 } else {
6711 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
6712 res = wait_file(chan, ints, nextmsg, lang);
6713 }
6714 break;
6715 case 'd':
6716 case 'e':
6717 /* First - Thirtyfirst */
6718 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
6719 break;
6720 case 'Y':
6721 /* Year */
6722 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
6723 break;
6724 case 'I':
6725 case 'l':
6726 /* 12-Hour */
6727 if (!strcasecmp(lang, "pt_BR")) {
6728 if (tm.tm_hour == 0) {
6729 if (format[offset] == 'I')
6730 res = wait_file(chan, ints, "digits/pt-a", lang);
6731 if (!res)
6732 res = wait_file(chan, ints, "digits/pt-meianoite", lang);
6733 } else if (tm.tm_hour == 12) {
6734 if (format[offset] == 'I')
6735 res = wait_file(chan, ints, "digits/pt-ao", lang);
6736 if (!res)
6737 res = wait_file(chan, ints, "digits/pt-meiodia", lang);
6738 } else {
6739 if (format[offset] == 'I') {
6740 if ((tm.tm_hour % 12) != 1)
6741 res = wait_file(chan, ints, "digits/pt-as", lang);
6742 else
6743 res = wait_file(chan, ints, "digits/pt-a", lang);
6744 }
6745 if (!res)
6746 res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
6747 }
6748 } else {
6749 if (tm.tm_hour == 0) {
6750 if (format[offset] == 'I')
6751 res = wait_file(chan, ints, "digits/pt-ah", lang);
6752 if (!res)
6753 res = wait_file(chan, ints, "digits/pt-meianoite", lang);
6754 }
6755 else if (tm.tm_hour == 12) {
6756 if (format[offset] == 'I')
6757 res = wait_file(chan, ints, "digits/pt-ao", lang);
6758 if (!res)
6759 res = wait_file(chan, ints, "digits/pt-meiodia", lang);
6760 }
6761 else {
6762 if (format[offset] == 'I') {
6763 res = wait_file(chan, ints, "digits/pt-ah", lang);
6764 if ((tm.tm_hour % 12) != 1)
6765 if (!res)
6766 res = wait_file(chan, ints, "digits/pt-sss", lang);
6767 }
6768 if (!res)
6769 res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
6770 }
6771 }
6772 break;
6773 case 'H':
6774 case 'k':
6775 /* 24-Hour */
6776 if (!strcasecmp(lang, "pt_BR")) {
6777 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
6778 if ((!res) && (format[offset] == 'H')) {
6779 if (tm.tm_hour > 1) {
6780 res = wait_file(chan, ints, "digits/hours", lang);
6781 } else {
6782 res = wait_file(chan, ints, "digits/hour", lang);
6783 }
6784 }
6785 } else {
6786 res = ast_say_number(chan, -tm.tm_hour, ints, lang, NULL);
6787 if (!res) {
6788 if (tm.tm_hour != 0) {
6789 int remaining = tm.tm_hour;
6790 if (tm.tm_hour > 20) {
6791 res = wait_file(chan, ints, "digits/20", lang);
6792 remaining -= 20;
6793 }
6794 if (!res) {
6795 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
6796 res = wait_file(chan, ints, nextmsg, lang);
6797 }
6798 }
6799 }
6800 }
6801 break;
6802 case 'M':
6803 /* Minute */
6804 if (!strcasecmp(lang, "pt_BR")) {
6805 res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
6806 if (!res) {
6807 if (tm.tm_min > 1) {
6808 res = wait_file(chan, ints, "minutes", lang);
6809 } else {
6810 res = wait_file(chan, ints, "minute", lang);
6811 }
6812 }
6813 } else {
6814 if (tm.tm_min == 0) {
6815 res = wait_file(chan, ints, "digits/pt-hora", lang);
6816 if (tm.tm_hour != 1)
6817 if (!res)
6818 res = wait_file(chan, ints, "digits/pt-sss", lang);
6819 } else {
6820 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
6821 }
6822 }
6823 break;
6824 case 'P':
6825 case 'p':
6826 /* AM/PM */
6827 if (!strcasecmp(lang, "pt_BR")) {
6828 if ((tm.tm_hour != 0) && (tm.tm_hour != 12)) {
6829 res = wait_file(chan, ints, "digits/pt-da", lang);
6830 if (!res) {
6831 if ((tm.tm_hour >= 0) && (tm.tm_hour < 12))
6832 res = wait_file(chan, ints, "digits/morning", lang);
6833 else if ((tm.tm_hour >= 12) && (tm.tm_hour < 18))
6834 res = wait_file(chan, ints, "digits/afternoon", lang);
6835 else res = wait_file(chan, ints, "digits/night", lang);
6836 }
6837 }
6838 } else {
6839 if (tm.tm_hour > 12)
6840 res = wait_file(chan, ints, "digits/p-m", lang);
6841 else if (tm.tm_hour && tm.tm_hour < 12)
6842 res = wait_file(chan, ints, "digits/a-m", lang);
6843 }
6844 break;
6845 case 'Q':
6846 /* Shorthand for "Today", "Yesterday", or ABdY */
6847 /* XXX As emphasized elsewhere, this should the native way in your
6848 * language to say the date, with changes in what you say, depending
6849 * upon how recent the date is. XXX */
6850 {
6851 struct timeval now = ast_tvnow();
6852 struct ast_tm tmnow;
6853 time_t beg_today;
6854
6855 ast_localtime(&now, &tmnow, tzone);
6856 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6857 /* In any case, it saves not having to do ast_mktime() */
6858 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6859 if (beg_today < t) {
6860 /* Today */
6861 res = wait_file(chan, ints, "digits/today", lang);
6862 } else if (beg_today - 86400 < t) {
6863 /* Yesterday */
6864 res = wait_file(chan, ints, "digits/yesterday", lang);
6865 } else {
6866 res = ast_say_date_with_format_pt(chan, t, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", tzone);
6867 }
6868 }
6869 break;
6870 case 'q':
6871 /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
6872 /* XXX As emphasized elsewhere, this should the native way in your
6873 * language to say the date, with changes in what you say, depending
6874 * upon how recent the date is. XXX */
6875 {
6876 struct timeval now = ast_tvnow();
6877 struct ast_tm tmnow;
6878 time_t beg_today;
6879
6880 ast_localtime(&now, &tmnow, tzone);
6881 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6882 /* In any case, it saves not having to do ast_mktime() */
6883 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6884 if (beg_today < t) {
6885 /* Today */
6886 } else if ((beg_today - 86400) < t) {
6887 /* Yesterday */
6888 res = wait_file(chan, ints, "digits/yesterday", lang);
6889 } else if (beg_today - 86400 * 6 < t) {
6890 /* Within the last week */
6891 res = ast_say_date_with_format_pt(chan, t, ints, lang, "A", tzone);
6892 } else {
6893 res = ast_say_date_with_format_pt(chan, t, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", tzone);
6894 }
6895 }
6896 break;
6897 case 'R':
6898 res = ast_say_date_with_format_pt(chan, t, ints, lang, "H 'digits/pt-e' M", tzone);
6899 break;
6900 case 'S':
6901 /* Seconds */
6902 if (!strcasecmp(lang, "pt_BR")) {
6903 res = ast_say_number(chan, tm.tm_sec, ints, lang, NULL);
6904 if (!res) {
6905 if (tm.tm_sec > 1) {
6906 res = wait_file(chan, ints, "seconds", lang);
6907 } else {
6908 res = wait_file(chan, ints, "second", lang);
6909 }
6910 }
6911 } else {
6912 if (tm.tm_sec == 0) {
6913 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6914 res = wait_file(chan, ints, nextmsg, lang);
6915 } else if (tm.tm_sec < 10) {
6916 res = wait_file(chan, ints, "digits/oh", lang);
6917 if (!res) {
6918 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6919 res = wait_file(chan, ints, nextmsg, lang);
6920 }
6921 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
6922 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
6923 res = wait_file(chan, ints, nextmsg, lang);
6924 } else {
6925 int ten, one;
6926 ten = (tm.tm_sec / 10) * 10;
6927 one = (tm.tm_sec % 10);
6928 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
6929 res = wait_file(chan, ints, nextmsg, lang);
6930 if (!res) {
6931 /* Fifty, not fifty-zero */
6932 if (one != 0) {
6933 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
6934 res = wait_file(chan, ints, nextmsg, lang);
6935 }
6936 }
6937 }
6938 }
6939 break;
6940 case 'T':
6941 res = ast_say_date_with_format_pt(chan, t, ints, lang, "HMS", tzone);
6942 break;
6943 case ' ':
6944 case ' ':
6945 /* Just ignore spaces and tabs */
6946 break;
6947 default:
6948 /* Unknown character */
6949 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
6950 }
6951 /* Jump out on DTMF */
6952 if (res) {
6953 break;
6954 }
6955 }
6956 return res;
6957}
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:6668

References ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_pt(), 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_say_date_with_format_pt(), and say_date_with_format().

◆ 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 5297 of file say.c.

5298{
5299 struct timeval when = { t, 0 };
5300 struct ast_tm tm;
5301 int res=0, offset, sndoffset;
5302 char sndfile[256], nextmsg[256];
5303
5304 if (format == NULL)
5305 format = "a 'digits/tee' e 'digits/duan' hY I 'digits/naliga' M 'digits/natee'";
5306
5307 ast_localtime(&when, &tm, tzone);
5308
5309 for (offset=0 ; format[offset] != '\0' ; offset++) {
5310 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
5311 switch (format[offset]) {
5312 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
5313 case '\'':
5314 /* Literal name of a sound file */
5315 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
5316 sndfile[sndoffset] = format[offset];
5317 }
5318 sndfile[sndoffset] = '\0';
5319 res = wait_file(chan, ints, sndfile, lang);
5320 break;
5321 case 'A':
5322 case 'a':
5323 /* Sunday - Saturday */
5324 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
5325 res = wait_file(chan, ints, nextmsg, lang);
5326 break;
5327 case 'B':
5328 case 'b':
5329 case 'h':
5330 /* January - December */
5331 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
5332 res = wait_file(chan, ints, nextmsg, lang);
5333 break;
5334 case 'm':
5335 /* Month enumerated */
5336 res = ast_say_number(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
5337 break;
5338 case 'd':
5339 case 'e':
5340 /* First - Thirtyfirst */
5341 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
5342 break;
5343 case 'Y':
5344 /* Year */
5345 res = ast_say_number(chan, tm.tm_year + 1900 + 543, ints, lang, (char *) NULL);
5346 break;
5347 case 'I':
5348 case 'l':
5349 /* 12-Hour */
5350 if (tm.tm_hour == 0)
5351 ast_copy_string(nextmsg, "digits/24", sizeof(nextmsg));
5352 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
5353 res = wait_file(chan, ints, nextmsg, lang);
5354 break;
5355 case 'H':
5356 case 'k':
5357 /* 24-Hour */
5358 if (tm.tm_hour == 0)
5359 ast_copy_string(nextmsg, "digits/24", sizeof(nextmsg));
5360 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
5361 res = wait_file(chan, ints, nextmsg, lang);
5362 break;
5363 case 'M':
5364 case 'N':
5365 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
5366 break;
5367 case 'P':
5368 case 'p':
5369 break;
5370 case 'Q':
5371 /* Shorthand for "Today", "Yesterday", or ABdY */
5372 /* XXX As emphasized elsewhere, this should the native way in your
5373 * language to say the date, with changes in what you say, depending
5374 * upon how recent the date is. XXX */
5375 {
5376 struct timeval now = ast_tvnow();
5377 struct ast_tm tmnow;
5378 time_t beg_today;
5379
5380 ast_localtime(&now, &tmnow, tzone);
5381 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5382 /* In any case, it saves not having to do ast_mktime() */
5383 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5384 if (beg_today < t) {
5385 /* Today */
5386 res = wait_file(chan, ints, "digits/today", lang);
5387 } else if (beg_today - 86400 < t) {
5388 /* Yesterday */
5389 res = wait_file(chan, ints, "digits/yesterday", lang);
5390 } else if (beg_today - 86400 * 6 < t) {
5391 /* Within the last week */
5392 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
5393 } else if (beg_today - 2628000 < t) {
5394 /* Less than a month ago - "Sunday, October third" */
5395 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
5396 } else if (beg_today - 15768000 < t) {
5397 /* Less than 6 months ago - "August seventh" */
5398 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
5399 } else {
5400 /* More than 6 months ago - "April nineteenth two thousand three" */
5401 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
5402 }
5403 }
5404 break;
5405 case 'q':
5406 /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
5407 /* XXX As emphasized elsewhere, this should the native way in your
5408 * language to say the date, with changes in what you say, depending
5409 * upon how recent the date is. XXX */
5410 {
5411 struct timeval now = ast_tvnow();
5412 struct ast_tm tmnow;
5413 time_t beg_today;
5414
5415 ast_localtime(&now, &tmnow, tzone);
5416 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
5417 /* In any case, it saves not having to do ast_mktime() */
5418 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
5419 if (beg_today < t) {
5420 /* Today */
5421 } else if ((beg_today - 86400) < t) {
5422 /* Yesterday */
5423 res = wait_file(chan, ints, "digits/yesterday", lang);
5424 } else if (beg_today - 86400 * 6 < t) {
5425 /* Within the last week */
5426 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
5427 } else if (beg_today - 2628000 < t) {
5428 /* Less than a month ago - "Sunday, October third" */
5429 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
5430 } else if (beg_today - 15768000 < t) {
5431 /* Less than 6 months ago - "August seventh" */
5432 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
5433 } else {
5434 /* More than 6 months ago - "April nineteenth two thousand three" */
5435 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
5436 }
5437 }
5438 break;
5439 case 'R':
5440 res = ast_say_date_with_format_en(chan, t, ints, lang, "HM", tzone);
5441 break;
5442 case 'S':
5443 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
5444 break;
5445 case 'T':
5446 res = ast_say_date_with_format_en(chan, t, ints, lang, "HMS", tzone);
5447 break;
5448 case ' ':
5449 case ' ':
5450 /* Just ignore spaces and tabs */
5451 break;
5452 default:
5453 /* Unknown character */
5454 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
5455 }
5456 /* Jump out on DTMF */
5457 if (res) {
5458 break;
5459 }
5460 }
5461 return res;
5462}

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 say_date_with_format().

◆ 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 9087 of file say.c.

9088{
9089 struct timeval when = { t, 0 };
9090 struct ast_tm tm;
9091 int res = 0, offset, sndoffset;
9092 char sndfile[256], nextmsg[256];
9093
9094 if (format == NULL)
9095 format = "A 'digits/day' eB 'digits/year' Y 'digits/at' k 'hours' M 'minutes' p";
9096
9097 ast_localtime(&when, &tm, tzone);
9098
9099 for (offset=0 ; format[offset] != '\0' ; offset++) {
9100 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
9101 switch (format[offset]) {
9102 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
9103 case '\'':
9104 /* Literal name of a sound file */
9105 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
9106 sndfile[sndoffset] = format[offset];
9107 }
9108 sndfile[sndoffset] = '\0';
9109 res = wait_file(chan, ints, sndfile, lang);
9110 break;
9111 case 'A':
9112 case 'a':
9113 /* Sunday - Saturday */
9114 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
9115 res = wait_file(chan, ints, nextmsg, lang);
9116 break;
9117 case 'B':
9118 case 'b':
9119 case 'h':
9120 /* January - December */
9121 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
9122 res = wait_file(chan, ints, nextmsg, lang);
9123 break;
9124 case 'm':
9125 /* Month enumerated */
9126 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
9127 break;
9128 case 'd':
9129 case 'e':
9130 /* 1 - 31 */
9131 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
9132 break;
9133 case 'Y':
9134 /* Year */
9135 if (tm.tm_year > 99) {
9136 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
9137 } else if (tm.tm_year < 1) {
9138 /* I'm not going to handle 1900 and prior */
9139 /* We'll just be silent on the year, instead of bombing out. */
9140 } else {
9141 res = wait_file(chan, ints, "digits/19", lang);
9142 if (!res) {
9143 if (tm.tm_year <= 9) {
9144 /* 1901 - 1909 */
9145 res = wait_file(chan, ints, "digits/odd", lang);
9146 }
9147
9148 res |= ast_say_number(chan, tm.tm_year, ints, lang, (char *) NULL);
9149 }
9150 }
9151 break;
9152 case 'I':
9153 case 'l':
9154 /* 12-Hour */
9155 if (tm.tm_hour == 0)
9156 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
9157 else if (tm.tm_hour > 12)
9158 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
9159 else
9160 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
9161 res = wait_file(chan, ints, nextmsg, lang);
9162 break;
9163 case 'H':
9164 case 'k':
9165 /* 24-Hour */
9166 if (format[offset] == 'H') {
9167 /* e.g. oh-eight */
9168 if (tm.tm_hour < 10) {
9169 res = wait_file(chan, ints, "digits/0", lang);
9170 }
9171 } else {
9172 /* e.g. eight */
9173 if (tm.tm_hour == 0) {
9174 res = wait_file(chan, ints, "digits/0", lang);
9175 }
9176 }
9177 if (!res) {
9178 if (tm.tm_hour != 0) {
9179 int remaining = tm.tm_hour;
9180 if (tm.tm_hour > 20) {
9181 res = wait_file(chan, ints, "digits/20", lang);
9182 remaining -= 20;
9183 }
9184 if (!res) {
9185 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
9186 res = wait_file(chan, ints, nextmsg, lang);
9187 }
9188 }
9189 }
9190 break;
9191 case 'M':
9192 case 'N':
9193 /* Minute */
9194 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
9195 break;
9196 case 'P':
9197 case 'p':
9198 /* AM/PM */
9199 if (tm.tm_hour > 11)
9200 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
9201 else
9202 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
9203 res = wait_file(chan, ints, nextmsg, lang);
9204 break;
9205 case 'Q':
9206 /* Shorthand for "Today", "Yesterday", or ABdY */
9207 /* XXX As emphasized elsewhere, this should the native way in your
9208 * language to say the date, with changes in what you say, depending
9209 * upon how recent the date is. XXX */
9210 {
9211 struct timeval now = ast_tvnow();
9212 struct ast_tm tmnow;
9213 time_t beg_today;
9214
9215 gettimeofday(&now, NULL);
9216 ast_localtime(&now, &tmnow, tzone);
9217 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
9218 /* In any case, it saves not having to do ast_mktime() */
9219 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
9220 if (beg_today < t) {
9221 /* Today */
9222 res = wait_file(chan, ints, "digits/today", lang);
9223 } else if (beg_today - 86400 < t) {
9224 /* Yesterday */
9225 res = wait_file(chan, ints, "digits/yesterday", lang);
9226 } else if (beg_today - 86400 * 6 < t) {
9227 /* Within the last week */
9228 res = ast_say_date_with_format_vi(chan, t, ints, lang, "A", tzone);
9229 } else if (beg_today - 2628000 < t) {
9230 /* Less than a month ago - "Chu nhat ngay 13 thang 2" */
9231 res = ast_say_date_with_format_vi(chan, t, ints, lang, "A 'digits/day' dB", tzone);
9232 } else if (beg_today - 15768000 < t) {
9233 /* Less than 6 months ago - "August seventh" */
9234 res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB", tzone);
9235 } else {
9236 /* More than 6 months ago - "April nineteenth two thousand three" */
9237 res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB 'digits/year' Y", tzone);
9238 }
9239 }
9240 break;
9241 case 'q':
9242 /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
9243 /* XXX As emphasized elsewhere, this should the native way in your
9244 * language to say the date, with changes in what you say, depending
9245 * upon how recent the date is. XXX */
9246 {
9247 struct timeval now;
9248 struct ast_tm tmnow;
9249 time_t beg_today;
9250
9251 now = ast_tvnow();
9252 ast_localtime(&now, &tmnow, tzone);
9253 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
9254 /* In any case, it saves not having to do ast_mktime() */
9255 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
9256 if (beg_today < t) {
9257 /* Today */
9258 } else if ((beg_today - 86400) < t) {
9259 /* Yesterday */
9260 res = wait_file(chan, ints, "digits/yesterday", lang);
9261 } else if (beg_today - 86400 * 6 < t) {
9262 /* Within the last week */
9263 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
9264 } else if (beg_today - 2628000 < t) {
9265 /* Less than a month ago - "Chu nhat ngay 13 thang 2" */
9266 res = ast_say_date_with_format_vi(chan, t, ints, lang, "A 'digits/day' dB", tzone);
9267 } else if (beg_today - 15768000 < t) {
9268 /* Less than 6 months ago - "August seventh" */
9269 res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB", tzone);
9270 } else {
9271 /* More than 6 months ago - "April nineteenth two thousand three" */
9272 res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB 'digits/year' Y", tzone);
9273 }
9274 }
9275 break;
9276 case 'R':
9277 res = ast_say_date_with_format_vi(chan, t, ints, lang, "HM", tzone);
9278 break;
9279 case 'S':
9280 /* Seconds */
9281 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
9282 break;
9283 case 'T':
9284 res = ast_say_date_with_format_vi(chan, t, ints, lang, "H 'hours' M 'minutes' S 'seconds'", tzone);
9285 break;
9286 case ' ':
9287 case ' ':
9288 /* Just ignore spaces and tabs */
9289 break;
9290 default:
9291 /* Unknown character */
9292 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
9293 }
9294 /* Jump out on DTMF */
9295 if (res) {
9296 break;
9297 }
9298 }
9299 return res;
9300}
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:9087

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_en(), ast_say_date_with_format_vi(), 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_say_date_with_format_vi(), and say_date_with_format().

◆ 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 6960 of file say.c.

6961{
6962 struct timeval when = { t, 0 };
6963 struct ast_tm tm;
6964 int res=0, offset, sndoffset;
6965 char sndfile[256], nextmsg[256];
6966
6967 if (format == NULL)
6968 format = "YBdAkM";
6969
6970 ast_localtime(&when, &tm, tzone);
6971
6972 for (offset=0 ; format[offset] != '\0' ; offset++) {
6973 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
6974 switch (format[offset]) {
6975 /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
6976 case '\'':
6977 /* Literal name of a sound file */
6978 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
6979 sndfile[sndoffset] = format[offset];
6980 }
6981 sndfile[sndoffset] = '\0';
6982 res = wait_file(chan, ints, sndfile, lang);
6983 break;
6984 case 'A':
6985 case 'a':
6986 /* Sunday - Saturday */
6987 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
6988 res = wait_file(chan, ints, nextmsg, lang);
6989 break;
6990 case 'B':
6991 case 'b':
6992 case 'h':
6993 case 'm':
6994 /* January - December */
6995 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
6996 res = wait_file(chan, ints, nextmsg, lang);
6997 break;
6998 case 'd':
6999 case 'e':
7000 /* First - Thirtyfirst */
7001 if (!(tm.tm_mday % 10) || (tm.tm_mday < 10)) {
7002 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday);
7003 res = wait_file(chan, ints, nextmsg, lang);
7004 } else {
7005 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday - (tm.tm_mday % 10));
7006 res = wait_file(chan, ints, nextmsg, lang);
7007 if (!res) {
7008 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday % 10);
7009 res = wait_file(chan, ints, nextmsg, lang);
7010 }
7011 }
7012 if (!res) res = wait_file(chan, ints, "digits/day", lang);
7013 break;
7014 case 'Y':
7015 /* Year */
7016 if (tm.tm_year > 99) {
7017 res = wait_file(chan, ints, "digits/2", lang);
7018 if (!res) {
7019 res = wait_file(chan, ints, "digits/thousand", lang);
7020 }
7021 if (tm.tm_year > 100) {
7022 if (!res) {
7023 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) / 10);
7024 res = wait_file(chan, ints, nextmsg, lang);
7025 if (!res) {
7026 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) % 10);
7027 res = wait_file(chan, ints, nextmsg, lang);
7028 }
7029 }
7030 }
7031 if (!res) {
7032 res = wait_file(chan, ints, "digits/year", lang);
7033 }
7034 } else {
7035 if (tm.tm_year < 1) {
7036 /* I'm not going to handle 1900 and prior */
7037 /* We'll just be silent on the year, instead of bombing out. */
7038 } else {
7039 res = wait_file(chan, ints, "digits/1", lang);
7040 if (!res) {
7041 res = wait_file(chan, ints, "digits/9", lang);
7042 }
7043 if (!res) {
7044 if (tm.tm_year <= 9) {
7045 /* 1901 - 1909 */
7046 res = wait_file(chan, ints, "digits/0", lang);
7047 if (!res) {
7048 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
7049 res = wait_file(chan, ints, nextmsg, lang);
7050 }
7051 } else {
7052 /* 1910 - 1999 */
7053 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year / 10);
7054 res = wait_file(chan, ints, nextmsg, lang);
7055 if (!res) {
7056 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year % 10);
7057 res = wait_file(chan, ints, nextmsg, lang);
7058 }
7059 }
7060 }
7061 }
7062 if (!res) {
7063 res = wait_file(chan, ints, "digits/year", lang);
7064 }
7065 }
7066 break;
7067 case 'I':
7068 case 'l':
7069 /* 12-Hour */
7070 if (tm.tm_hour == 0)
7071 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
7072 else if (tm.tm_hour > 12)
7073 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
7074 else
7075 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
7076 res = wait_file(chan, ints, nextmsg, lang);
7077 if (!res) {
7078 res = wait_file(chan, ints, "digits/oclock", lang);
7079 }
7080 break;
7081 case 'H':
7082 if (tm.tm_hour < 10) {
7083 res = wait_file(chan, ints, "digits/0", lang);
7084 }
7085 /* XXX Static analysis warns of no break here. No idea if this is
7086 * correct or not
7087 */
7088 case 'k':
7089 /* 24-Hour */
7090 if (!(tm.tm_hour % 10) || tm.tm_hour < 10) {
7091 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
7092 res = wait_file(chan, ints, nextmsg, lang);
7093 } else {
7094 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - (tm.tm_hour % 10));
7095 res = wait_file(chan, ints, nextmsg, lang);
7096 if (!res) {
7097 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour % 10);
7098 res = wait_file(chan, ints, nextmsg, lang);
7099 }
7100 }
7101 if (!res) {
7102 res = wait_file(chan, ints, "digits/oclock", lang);
7103 }
7104 break;
7105 case 'M':
7106 /* Minute */
7107 if (!(tm.tm_min % 10) || tm.tm_min < 10) {
7108 if (tm.tm_min < 10) {
7109 res = wait_file(chan, ints, "digits/0", lang);
7110 }
7111 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min);
7112 res = wait_file(chan, ints, nextmsg, lang);
7113 } else {
7114 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min - (tm.tm_min % 10));
7115 res = wait_file(chan, ints, nextmsg, lang);
7116 if (!res) {
7117 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min % 10);
7118 res = wait_file(chan, ints, nextmsg, lang);
7119 }
7120 }
7121 if (!res) {
7122 res = wait_file(chan, ints, "minute", lang);
7123 }
7124 break;
7125 case 'P':
7126 case 'p':
7127 /* AM/PM */
7128 if (tm.tm_hour > 11)
7129 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
7130 else
7131 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
7132 res = wait_file(chan, ints, nextmsg, lang);
7133 break;
7134 case 'Q':
7135 /* Shorthand for "Today", "Yesterday", or ABdY */
7136 /* XXX As emphasized elsewhere, this should the native way in your
7137 * language to say the date, with changes in what you say, depending
7138 * upon how recent the date is. XXX */
7139 {
7140 struct timeval now = ast_tvnow();
7141 struct ast_tm tmnow;
7142 time_t beg_today;
7143
7144 ast_localtime(&now, &tmnow, tzone);
7145 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
7146 /* In any case, it saves not having to do ast_mktime() */
7147 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
7148 if (beg_today < t) {
7149 /* Today */
7150 res = wait_file(chan, ints, "digits/today", lang);
7151 } else if (beg_today - 86400 < t) {
7152 /* Yesterday */
7153 res = wait_file(chan, ints, "digits/yesterday", lang);
7154 } else {
7155 res = ast_say_date_with_format_zh(chan, t, ints, lang, "YBdA", tzone);
7156 }
7157 }
7158 break;
7159 case 'q':
7160 /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
7161 /* XXX As emphasized elsewhere, this should the native way in your
7162 * language to say the date, with changes in what you say, depending
7163 * upon how recent the date is. XXX */
7164 {
7165 struct timeval now = ast_tvnow();
7166 struct ast_tm tmnow;
7167 time_t beg_today;
7168
7169 ast_localtime(&now, &tmnow, tzone);
7170 /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
7171 /* In any case, it saves not having to do ast_mktime() */
7172 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
7173 if (beg_today < t) {
7174 /* Today */
7175 } else if ((beg_today - 86400) < t) {
7176 /* Yesterday */
7177 res = wait_file(chan, ints, "digits/yesterday", lang);
7178 } else if (beg_today - 86400 * 6 < t) {
7179 /* Within the last week */
7180 res = ast_say_date_with_format_zh(chan, t, ints, lang, "A", tzone);
7181 } else {
7182 res = ast_say_date_with_format_zh(chan, t, ints, lang, "YBdA", tzone);
7183 }
7184 }
7185 break;
7186 case 'R':
7187 res = ast_say_date_with_format_zh(chan, t, ints, lang, "kM", tzone);
7188 break;
7189 case 'S':
7190 /* Seconds */
7191 if (!(tm.tm_sec % 10) || tm.tm_sec < 10) {
7192 if (tm.tm_sec < 10) {
7193 res = wait_file(chan, ints, "digits/0", lang);
7194 }
7195 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
7196 res = wait_file(chan, ints, nextmsg, lang);
7197 } else {
7198 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec - (tm.tm_sec % 10));
7199 res = wait_file(chan, ints, nextmsg, lang);
7200 if (!res) {
7201 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec % 10);
7202 res = wait_file(chan, ints, nextmsg, lang);
7203 }
7204 }
7205 if (!res) {
7206 res = wait_file(chan, ints, "second", lang);
7207 }
7208 break;
7209 case 'T':
7210 res = ast_say_date_with_format_zh(chan, t, ints, lang, "HMS", tzone);
7211 break;
7212 case ' ':
7213 case ' ':
7214 /* Just ignore spaces and tabs */
7215 break;
7216 default:
7217 /* Unknown character */
7218 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
7219 }
7220 /* Jump out on DTMF */
7221 if (res) {
7222 break;
7223 }
7224 }
7225 return res;
7226}
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.
Definition: say.c:6960

References ast_copy_string(), ast_debug, ast_localtime(), ast_log, ast_say_date_with_format_zh(), 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_say_date_with_format_zh(), and say_date_with_format().

◆ ast_say_datetime_de()

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

German syntax.

Definition at line 7656 of file say.c.

7657{
7658 struct timeval when = { t, 0 };
7659 struct ast_tm tm;
7660 int res = 0;
7661
7662 ast_localtime(&when, &tm, NULL);
7663 res = ast_say_date(chan, t, ints, lang);
7664 if (!res)
7665 ast_say_time(chan, t, ints, lang);
7666 return res;
7667
7668}

References ast_localtime(), ast_say_date, ast_say_time, and NULL.

Referenced by say_datetime().

◆ ast_say_datetime_en()

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

English syntax.

Definition at line 7589 of file say.c.

7590{
7591 struct timeval when = { t, 0 };
7592 struct ast_tm tm;
7593 char fn[256];
7594 int res = 0;
7595 int hour, pm=0;
7596
7597 ast_localtime(&when, &tm, NULL);
7598 if (!res) {
7599 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7600 res = ast_streamfile(chan, fn, lang);
7601 if (!res)
7602 res = ast_waitstream(chan, ints);
7603 }
7604 if (!res) {
7605 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7606 res = ast_streamfile(chan, fn, lang);
7607 if (!res)
7608 res = ast_waitstream(chan, ints);
7609 }
7610 if (!res)
7611 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
7612
7613 hour = tm.tm_hour;
7614 if (!hour)
7615 hour = 12;
7616 else if (hour == 12)
7617 pm = 1;
7618 else if (hour > 12) {
7619 hour -= 12;
7620 pm = 1;
7621 }
7622 if (!res)
7623 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
7624
7625 if (tm.tm_min > 9) {
7626 if (!res)
7627 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7628 } else if (tm.tm_min) {
7629 if (!res)
7630 res = ast_streamfile(chan, "digits/oh", lang);
7631 if (!res)
7632 res = ast_waitstream(chan, ints);
7633 if (!res)
7634 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7635 } else {
7636 if (!res)
7637 res = ast_streamfile(chan, "digits/oclock", lang);
7638 if (!res)
7639 res = ast_waitstream(chan, ints);
7640 }
7641 if (pm) {
7642 if (!res)
7643 res = ast_streamfile(chan, "digits/p-m", lang);
7644 } else {
7645 if (!res)
7646 res = ast_streamfile(chan, "digits/a-m", lang);
7647 }
7648 if (!res)
7649 res = ast_waitstream(chan, ints);
7650 if (!res)
7651 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
7652 return res;
7653}

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

Referenced by say_datetime().

◆ ast_say_datetime_fr()

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

French syntax.

Definition at line 7685 of file say.c.

7686{
7687 struct timeval when = { t, 0 };
7688 struct ast_tm tm;
7689 char fn[256];
7690 int res = 0;
7691
7692 ast_localtime(&when, &tm, NULL);
7693
7694 if (!res)
7695 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
7696
7697 if (!res) {
7698 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7699 res = ast_streamfile(chan, fn, lang);
7700 if (!res)
7701 res = ast_waitstream(chan, ints);
7702 }
7703 if (!res) {
7704 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7705 res = ast_streamfile(chan, fn, lang);
7706 if (!res)
7707 res = ast_waitstream(chan, ints);
7708 }
7709
7710 if (!res)
7711 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
7712 if (!res)
7713 res = ast_streamfile(chan, "digits/oclock", lang);
7714 if (tm.tm_min > 0) {
7715 if (!res)
7716 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7717 }
7718 if (!res)
7719 res = ast_waitstream(chan, ints);
7720 if (!res)
7721 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
7722 return res;
7723}

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

Referenced by say_datetime().

◆ ast_say_datetime_from_now_en()

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

English syntax.

Definition at line 8013 of file say.c.

8014{
8015 int res=0;
8016 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
8017 int daydiff;
8018 struct ast_tm tm;
8019 struct ast_tm now;
8020 char fn[256];
8021
8022 ast_localtime(&when, &tm, NULL);
8023 ast_localtime(&nowtv, &now, NULL);
8024 daydiff = now.tm_yday - tm.tm_yday;
8025 if ((daydiff < 0) || (daydiff > 6)) {
8026 /* Day of month and month */
8027 if (!res) {
8028 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8029 res = ast_streamfile(chan, fn, lang);
8030 if (!res)
8031 res = ast_waitstream(chan, ints);
8032 }
8033 if (!res)
8034 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
8035
8036 } else if (daydiff) {
8037 /* Just what day of the week */
8038 if (!res) {
8039 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8040 res = ast_streamfile(chan, fn, lang);
8041 if (!res)
8042 res = ast_waitstream(chan, ints);
8043 }
8044 } /* Otherwise, it was today */
8045 if (!res)
8046 res = ast_say_time(chan, t, ints, lang);
8047 return res;
8048}

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

Referenced by say_datetime_from_now().

◆ ast_say_datetime_from_now_fr()

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

French syntax.

Definition at line 8051 of file say.c.

8052{
8053 int res=0;
8054 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
8055 int daydiff;
8056 struct ast_tm tm;
8057 struct ast_tm now;
8058 char fn[256];
8059
8060 ast_localtime(&when, &tm, NULL);
8061 ast_localtime(&nowtv, &now, NULL);
8062 daydiff = now.tm_yday - tm.tm_yday;
8063 if ((daydiff < 0) || (daydiff > 6)) {
8064 /* Day of month and month */
8065 if (!res) {
8066 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8067 res = ast_streamfile(chan, fn, lang);
8068 if (!res)
8069 res = ast_waitstream(chan, ints);
8070 }
8071 if (!res)
8072 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
8073
8074 } else if (daydiff) {
8075 /* Just what day of the week */
8076 if (!res) {
8077 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8078 res = ast_streamfile(chan, fn, lang);
8079 if (!res)
8080 res = ast_waitstream(chan, ints);
8081 }
8082 } /* Otherwise, it was today */
8083 if (!res)
8084 res = ast_say_time(chan, t, ints, lang);
8085 return res;
8086}

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

Referenced by say_datetime_from_now().

◆ ast_say_datetime_from_now_he()

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

Hebrew syntax.

Definition at line 8139 of file say.c.

8140{
8141 int res = 0;
8142 struct timeval nowt = ast_tvnow(), when = { t, 0 };
8143 int daydiff;
8144 struct ast_tm tm;
8145 struct ast_tm now;
8146 char fn[256];
8147
8148 ast_localtime(&when, &tm, NULL);
8149 ast_localtime(&nowt, &now, NULL);
8150 daydiff = now.tm_yday - tm.tm_yday;
8151 if ((daydiff < 0) || (daydiff > 6)) {
8152 /* Day of month and month */
8153 if (!res) {
8154 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8155 res = ast_streamfile(chan, fn, lang);
8156 if (!res)
8157 res = ast_waitstream(chan, ints);
8158 }
8159 if (!res) {
8160 res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
8161 }
8162 } else if (daydiff) {
8163 /* Just what day of the week */
8164 if (!res) {
8165 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8166 res = ast_streamfile(chan, fn, lang);
8167 if (!res) {
8168 res = ast_waitstream(chan, ints);
8169 }
8170 }
8171 } /* Otherwise, it was today */
8172 if (!res) {
8173 res = ast_say_time(chan, t, ints, lang);
8174 }
8175 return res;
8176}

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

Referenced by say_datetime_from_now().

◆ ast_say_datetime_from_now_ka()

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

Georgian syntax.

Definition at line 9636 of file say.c.

9637{
9638 int res=0;
9639 int daydiff;
9640 struct ast_tm tm;
9641 struct ast_tm now;
9642 struct timeval when = { t, 0 }, nowt = ast_tvnow();
9643 char fn[256];
9644
9645 ast_localtime(&when, &tm, NULL);
9646 ast_localtime(&nowt, &now, NULL);
9647 daydiff = now.tm_yday - tm.tm_yday;
9648 if ((daydiff < 0) || (daydiff > 6)) {
9649 /* Day of month and month */
9650 if (!res) {
9651 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
9652 }
9653 if (!res) {
9654 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
9655 res = ast_streamfile(chan, fn, lang);
9656 if (!res) {
9657 res = ast_waitstream(chan, ints);
9658 }
9659 }
9660
9661 } else if (daydiff) {
9662 /* Just what day of the week */
9663 if (!res) {
9664 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
9665 res = ast_streamfile(chan, fn, lang);
9666 if (!res) {
9667 res = ast_waitstream(chan, ints);
9668 }
9669 }
9670 } /* Otherwise, it was today */
9671 if (!res) {
9672 res = ast_say_time(chan, t, ints, lang);
9673 }
9674
9675 return res;
9676}

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

Referenced by say_datetime_from_now().

◆ ast_say_datetime_from_now_pt()

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

Portuguese syntax.

Definition at line 8089 of file say.c.

8090{
8091 int res=0;
8092 int daydiff;
8093 struct ast_tm tm;
8094 struct ast_tm now;
8095 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
8096 char fn[256];
8097
8098 ast_localtime(&when, &tm, NULL);
8099 ast_localtime(&nowtv, &now, NULL);
8100 daydiff = now.tm_yday - tm.tm_yday;
8101 if ((daydiff < 0) || (daydiff > 6)) {
8102 /* Day of month and month */
8103 if (!res)
8104 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
8105 if (!res)
8106 res = wait_file(chan, ints, "digits/pt-de", lang);
8107 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8108 if (!res)
8109 res = wait_file(chan, ints, fn, lang);
8110
8111 } else if (daydiff) {
8112 /* Just what day of the week */
8113 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8114 if (!res)
8115 res = wait_file(chan, ints, fn, lang);
8116 } /* Otherwise, it was today */
8117 if (!strcasecmp(lang, "pt_BR")) {
8118 if (tm.tm_hour > 1) {
8119 ast_copy_string(fn, "digits/pt-as", sizeof(fn));
8120 } else {
8121 ast_copy_string(fn, "digits/pt-a", sizeof(fn));
8122 }
8123 if (!res)
8124 res = wait_file(chan, ints, fn, lang);
8125 } else {
8126 ast_copy_string(fn, "digits/pt-ah", sizeof(fn));
8127 if (!res)
8128 res = wait_file(chan, ints, fn, lang);
8129 if (tm.tm_hour != 1)
8130 if (!res)
8131 res = wait_file(chan, ints, "digits/pt-sss", lang);
8132 if (!res)
8133 res = ast_say_time(chan, t, ints, lang);
8134 }
8135 return res;
8136}

References ast_copy_string(), ast_localtime(), ast_say_number(), ast_say_time, ast_tvnow(), NULL, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_mon, ast_tm::tm_wday, ast_tm::tm_yday, and wait_file().

Referenced by say_datetime_from_now().

◆ ast_say_datetime_gr()

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

Greek support.

Definition at line 8547 of file say.c.

8548{
8549 struct timeval when = { t, 0 };
8550 struct ast_tm tm;
8551 char fn[256];
8552 int res = 0;
8553
8554 ast_localtime(&when, &tm, NULL);
8555
8556 /* W E E K - D A Y */
8557 if (!res) {
8558 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8559 res = ast_streamfile(chan, fn, lang);
8560 if (!res)
8561 res = ast_waitstream(chan, ints);
8562 }
8563 /* D A Y */
8564 if (!res) {
8565 gr_say_number_female(tm.tm_mday, chan, ints, lang);
8566 }
8567 /* M O N T H */
8568 if (!res) {
8569 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8570 res = ast_streamfile(chan, fn, lang);
8571 if (!res)
8572 res = ast_waitstream(chan, ints);
8573 }
8574
8575 res = ast_say_time_gr(chan, t, ints, lang);
8576 return res;
8577}
static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Greek support.
Definition: say.c:8452

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

Referenced by say_datetime().

◆ ast_say_datetime_he()

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

Hebrew syntax.

Definition at line 7929 of file say.c.

7930{
7931 struct timeval when = { t, 0 };
7932 struct ast_tm tm;
7933 char fn[256];
7934 int res = 0;
7935 int hour;
7936
7937 ast_localtime(&when, &tm, NULL);
7938 if (!res) {
7939 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7940 res = ast_streamfile(chan, fn, lang);
7941 if (!res) {
7942 res = ast_waitstream(chan, ints);
7943 }
7944 }
7945 if (!res) {
7946 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7947 res = ast_streamfile(chan, fn, lang);
7948 if (!res) {
7949 res = ast_waitstream(chan, ints);
7950 }
7951 }
7952 if (!res) {
7953 res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
7954 }
7955
7956 hour = tm.tm_hour;
7957 if (!hour) {
7958 hour = 12;
7959 }
7960
7961 if (!res) {
7962 res = ast_say_number(chan, hour, ints, lang, "f");
7963 }
7964
7965 if (tm.tm_min > 9) {
7966 if (!res) {
7967 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
7968 }
7969 } else if (tm.tm_min) {
7970 if (!res) {
7971 /* say a leading zero if needed */
7972 res = ast_say_number(chan, 0, ints, lang, "f");
7973 }
7974 if (!res) {
7975 res = ast_waitstream(chan, ints);
7976 }
7977 if (!res) {
7978 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
7979 }
7980 } else {
7981 if (!res) {
7982 res = ast_waitstream(chan, ints);
7983 }
7984 }
7985 if (!res) {
7986 res = ast_waitstream(chan, ints);
7987 }
7988 if (!res) {
7989 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "f");
7990 }
7991 return res;
7992}

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

Referenced by say_datetime().

◆ ast_say_datetime_hu()

int ast_say_datetime_hu ( struct ast_channel chan,
time_t  t,