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

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

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

Go to the source code of this file.

Data Structures

struct  odmiana
 

Macros

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

Functions

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

Detailed Description

Say numbers and dates (maybe words one day too)

Author
Mark Spencer marks.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 1446 of file say.c.

Referenced by ast_say_number_full_he().

Function Documentation

◆ __say_init()

static void __say_init ( void  )
static

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

Definition at line 9601 of file say.c.

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

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

◆ ast_get_character_str()

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

Returns an ast_str of files for SayAlpha playback.

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

Computes the list of files to be played by SayAlpha.

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

Definition at line 63 of file say.c.

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

Referenced by say_character_str_full(), and sayfile_exec().

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

◆ ast_get_digit_str()

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

Returns an ast_str of files for SayDigits playback.

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

Computes the list of files to be played by SayDigits.

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

Definition at line 294 of file say.c.

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

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

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

◆ ast_get_money_en_dollars_str()

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

Definition at line 363 of file say.c.

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

Referenced by ast_get_money_str().

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

◆ ast_get_money_str()

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

ast_get_money_str: call language-specific functions

Returns an ast_str of files for SayMoney playback.

Definition at line 419 of file say.c.

References ast_get_money_en_dollars_str(), ast_log, and LOG_WARNING.

Referenced by say_money_str_full(), and sayfile_exec().

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

◆ ast_get_number_str()

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

ast_get_number_str: call language-specific functions

Returns an ast_str of files for SayNumber playback.

Definition at line 525 of file say.c.

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

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

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

◆ ast_get_phonetic_str()

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

Returns an ast_str of files for SayPhonetic playback.

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

Computes the list of files to be played by SayPhonetic.

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

Definition at line 195 of file say.c.

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

Referenced by say_phonetic_str_full(), and sayfile_exec().

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

◆ ast_say_counted_adjective()

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

Definition at line 9577 of file say.c.

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

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

◆ ast_say_counted_noun()

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

Definition at line 9535 of file say.c.

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

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

◆ ast_say_date_da()

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

Danish syntax.

Definition at line 3871 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_de()

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

German syntax.

Definition at line 3920 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_en()

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

English syntax.

Definition at line 3842 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_fr()

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

French syntax.

Definition at line 4002 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_gr()

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

Greek support.

The format is weekday - day - month -year

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

Definition at line 8180 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_he()

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

Hebrew syntax.

Definition at line 4123 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_hu()

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

Hungarian syntax.

Definition at line 3970 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_is()

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

Definition at line 4157 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_ja()

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

Definition at line 8216 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_ka()

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

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

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

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

Definition at line 9348 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_nl()

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

Dutch syntax.

Definition at line 4031 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_pt()

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

Portuguese syntax.

Definition at line 4096 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_th()

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

Thai syntax.

Definition at line 4060 of file say.c.

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

Referenced by ast_get_number_str(), and say_date().

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

◆ ast_say_date_with_format_da()

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

Danish syntax.

Definition at line 4493 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_de()

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

German syntax.

Definition at line 4695 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_en()

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

English syntax.

Definition at line 4246 of file say.c.

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

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

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

◆ ast_say_date_with_format_es()

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

Spanish syntax.

Definition at line 5442 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_fr()

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

French syntax oclock = heure.

Definition at line 5633 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_gr()

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

Greek support.

Definition at line 8455 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_he()

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

ast_say_date_with_format_he Say formatted date in Hebrew

ast_say_date_with_format_en for the details of the options

Changes from the English version:

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

Definition at line 5295 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_is()

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

Definition at line 4898 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_it()

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

Italian syntax.

Definition at line 5829 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_ja()

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

Definition at line 8627 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_nl()

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

Dutch syntax.

Definition at line 6061 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_pl()

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

Polish syntax.

Definition at line 6264 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_pt()

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

Portuguese syntax.

Definition at line 6481 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_th()

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

Thai syntax.

Definition at line 5110 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_vi()

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

Vietnamese syntax.

Definition at line 8895 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

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

◆ ast_say_date_with_format_zh()

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

Taiwanese / Chinese syntax.

Definition at line 6773 of file say.c.

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

Referenced by ast_get_number_str(), and say_date_with_format().

6774 {
6775  struct timeval when = { t, 0 };
6776  struct ast_tm tm;
6777  int res=0, offset, sndoffset;
6778  char sndfile[256], nextmsg[256];
6779 
6780  if (format == NULL)
6781  format = "YBdAkM";
6782 
6783  ast_localtime(&when, &tm, tzone);
6784 
6785  for (offset=0 ; format[offset] != '\0' ; offset++) {
6786  ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
6787  switch (format[offset]) {
6788  /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
6789  case '\'':
6790  /* Literal name of a sound file */
6791  for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
6792  sndfile[sndoffset] = format[offset];
6793  }
6794  sndfile[sndoffset] = '\0';
6795  res = wait_file(chan, ints, sndfile, lang);
6796  break;
6797  case 'A':
6798  case 'a':
6799  /* Sunday - Saturday */
6800  snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
6801  res = wait_file(chan, ints, nextmsg, lang);
6802  break;
6803  case 'B':
6804  case 'b':
6805  case 'h':
6806  case 'm':
6807  /* January - December */
6808  snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
6809  res = wait_file(chan, ints, nextmsg, lang);
6810  break;
6811  case 'd':
6812  case 'e':
6813  /* First - Thirtyfirst */
6814  if (!(tm.tm_mday % 10) || (tm.tm_mday < 10)) {
6815  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday);
6816  res = wait_file(chan, ints, nextmsg, lang);
6817  } else {
6818  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday - (tm.tm_mday % 10));
6819  res = wait_file(chan, ints, nextmsg, lang);
6820  if (!res) {
6821  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday % 10);
6822  res = wait_file(chan, ints, nextmsg, lang);
6823  }
6824  }
6825  if (!res) res = wait_file(chan, ints, "digits/day", lang);
6826  break;
6827  case 'Y':
6828  /* Year */
6829  if (tm.tm_year > 99) {
6830  res = wait_file(chan, ints, "digits/2", lang);
6831  if (!res) {
6832  res = wait_file(chan, ints, "digits/thousand", lang);
6833  }
6834  if (tm.tm_year > 100) {
6835  if (!res) {
6836  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) / 10);
6837  res = wait_file(chan, ints, nextmsg, lang);
6838  if (!res) {
6839  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) % 10);
6840  res = wait_file(chan, ints, nextmsg, lang);
6841  }
6842  }
6843  }
6844  if (!res) {
6845  res = wait_file(chan, ints, "digits/year", lang);
6846  }
6847  } else {
6848  if (tm.tm_year < 1) {
6849  /* I'm not going to handle 1900 and prior */
6850  /* We'll just be silent on the year, instead of bombing out. */
6851  } else {
6852  res = wait_file(chan, ints, "digits/1", lang);
6853  if (!res) {
6854  res = wait_file(chan, ints, "digits/9", lang);
6855  }
6856  if (!res) {
6857  if (tm.tm_year <= 9) {
6858  /* 1901 - 1909 */
6859  res = wait_file(chan, ints, "digits/0", lang);
6860  if (!res) {
6861  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
6862  res = wait_file(chan, ints, nextmsg, lang);
6863  }
6864  } else {
6865  /* 1910 - 1999 */
6866  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year / 10);
6867  res = wait_file(chan, ints, nextmsg, lang);
6868  if (!res) {
6869  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year % 10);
6870  res = wait_file(chan, ints, nextmsg, lang);
6871  }
6872  }
6873  }
6874  }
6875  if (!res) {
6876  res = wait_file(chan, ints, "digits/year", lang);
6877  }
6878  }
6879  break;
6880  case 'I':
6881  case 'l':
6882  /* 12-Hour */
6883  if (tm.tm_hour == 0)
6884  ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
6885  else if (tm.tm_hour > 12)
6886  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
6887  else
6888  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
6889  res = wait_file(chan, ints, nextmsg, lang);
6890  if (!res) {
6891  res = wait_file(chan, ints, "digits/oclock", lang);
6892  }
6893  break;
6894  case 'H':
6895  if (tm.tm_hour < 10) {
6896  res = wait_file(chan, ints, "digits/0", lang);
6897  }
6898  /* XXX Static analysis warns of no break here. No idea if this is
6899  * correct or not
6900  */
6901  case 'k':
6902  /* 24-Hour */
6903  if (!(tm.tm_hour % 10) || tm.tm_hour < 10) {
6904  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
6905  res = wait_file(chan, ints, nextmsg, lang);
6906  } else {
6907  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - (tm.tm_hour % 10));
6908  res = wait_file(chan, ints, nextmsg, lang);
6909  if (!res) {
6910  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour % 10);
6911  res = wait_file(chan, ints, nextmsg, lang);
6912  }
6913  }
6914  if (!res) {
6915  res = wait_file(chan, ints, "digits/oclock", lang);
6916  }
6917  break;
6918  case 'M':
6919  /* Minute */
6920  if (!(tm.tm_min % 10) || tm.tm_min < 10) {
6921  if (tm.tm_min < 10) {
6922  res = wait_file(chan, ints, "digits/0", lang);
6923  }
6924  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min);
6925  res = wait_file(chan, ints, nextmsg, lang);
6926  } else {
6927  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min - (tm.tm_min % 10));
6928  res = wait_file(chan, ints, nextmsg, lang);
6929  if (!res) {
6930  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min % 10);
6931  res = wait_file(chan, ints, nextmsg, lang);
6932  }
6933  }
6934  if (!res) {
6935  res = wait_file(chan, ints, "minute", lang);
6936  }
6937  break;
6938  case 'P':
6939  case 'p':
6940  /* AM/PM */
6941  if (tm.tm_hour > 11)
6942  ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
6943  else
6944  ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
6945  res = wait_file(chan, ints, nextmsg, lang);
6946  break;
6947  case 'Q':
6948  /* Shorthand for "Today", "Yesterday", or ABdY */
6949  /* XXX As emphasized elsewhere, this should the native way in your
6950  * language to say the date, with changes in what you say, depending
6951  * upon how recent the date is. XXX */
6952  {
6953  struct timeval now = ast_tvnow();
6954  struct ast_tm tmnow;
6955  time_t beg_today;
6956 
6957  ast_localtime(&now, &tmnow, tzone);
6958  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6959  /* In any case, it saves not having to do ast_mktime() */
6960  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6961  if (beg_today < t) {
6962  /* Today */
6963  res = wait_file(chan, ints, "digits/today", lang);
6964  } else if (beg_today - 86400 < t) {
6965  /* Yesterday */
6966  res = wait_file(chan, ints, "digits/yesterday", lang);
6967  } else {
6968  res = ast_say_date_with_format_zh(chan, t, ints, lang, "YBdA", tzone);
6969  }
6970  }
6971  break;
6972  case 'q':
6973  /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
6974  /* XXX As emphasized elsewhere, this should the native way in your
6975  * language to say the date, with changes in what you say, depending
6976  * upon how recent the date is. XXX */
6977  {
6978  struct timeval now = ast_tvnow();
6979  struct ast_tm tmnow;
6980  time_t beg_today;
6981 
6982  ast_localtime(&now, &tmnow, tzone);
6983  /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
6984  /* In any case, it saves not having to do ast_mktime() */
6985  beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
6986  if (beg_today < t) {
6987  /* Today */
6988  } else if ((beg_today - 86400) < t) {
6989  /* Yesterday */
6990  res = wait_file(chan, ints, "digits/yesterday", lang);
6991  } else if (beg_today - 86400 * 6 < t) {
6992  /* Within the last week */
6993  res = ast_say_date_with_format_zh(chan, t, ints, lang, "A", tzone);
6994  } else {
6995  res = ast_say_date_with_format_zh(chan, t, ints, lang, "YBdA", tzone);
6996  }
6997  }
6998  break;
6999  case 'R':
7000  res = ast_say_date_with_format_zh(chan, t, ints, lang, "kM", tzone);
7001  break;
7002  case 'S':
7003  /* Seconds */
7004  if (!(tm.tm_sec % 10) || tm.tm_sec < 10) {
7005  if (tm.tm_sec < 10) {
7006  res = wait_file(chan, ints, "digits/0", lang);
7007  }
7008  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
7009  res = wait_file(chan, ints, nextmsg, lang);
7010  } else {
7011  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec - (tm.tm_sec % 10));
7012  res = wait_file(chan, ints, nextmsg, lang);
7013  if (!res) {
7014  snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec % 10);
7015  res = wait_file(chan, ints, nextmsg, lang);
7016  }
7017  }
7018  if (!res) {
7019  res = wait_file(chan, ints, "second", lang);
7020  }
7021  break;
7022  case 'T':
7023  res = ast_say_date_with_format_zh(chan, t, ints, lang, "HMS", tzone);
7024  break;
7025  case ' ':
7026  case ' ':
7027  /* Just ignore spaces and tabs */
7028  break;
7029  default:
7030  /* Unknown character */
7031  ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
7032  }
7033  /* Jump out on DTMF */
7034  if (res) {
7035  break;
7036  }
7037  }
7038  return res;
7039 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
static int ast_say_date_with_format_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:6773
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static snd_pcm_format_t format
Definition: chan_alsa.c:102

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

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

Referenced by ast_get_number_str(), and say_datetime().

7465 {
7466  struct timeval when = { t, 0 };
7467  struct ast_tm tm;
7468  int res = 0;
7469 
7470  ast_localtime(&when, &tm, NULL);
7471  res = ast_say_date(chan, t, ints, lang);
7472  if (!res)
7473  ast_say_time(chan, t, ints, lang);
7474  return res;
7475 
7476 }
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:183
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
SAY_EXTERN int(* ast_say_date)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_date)
Definition: say.h:185

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

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 ast_get_number_str(), and say_datetime().

7398 {
7399  struct timeval when = { t, 0 };
7400  struct ast_tm tm;
7401  char fn[256];
7402  int res = 0;
7403  int hour, pm=0;
7404 
7405  ast_localtime(&when, &tm, NULL);
7406  if (!res) {
7407  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7408  res = ast_streamfile(chan, fn, lang);
7409  if (!res)
7410  res = ast_waitstream(chan, ints);
7411  }
7412  if (!res) {
7413  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7414  res = ast_streamfile(chan, fn, lang);
7415  if (!res)
7416  res = ast_waitstream(chan, ints);
7417  }
7418  if (!res)
7419  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
7420 
7421  hour = tm.tm_hour;
7422  if (!hour)
7423  hour = 12;
7424  else if (hour == 12)
7425  pm = 1;
7426  else if (hour > 12) {
7427  hour -= 12;
7428  pm = 1;
7429  }
7430  if (!res)
7431  res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
7432 
7433  if (tm.tm_min > 9) {
7434  if (!res)
7435  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7436  } else if (tm.tm_min) {
7437  if (!res)
7438  res = ast_streamfile(chan, "digits/oh", lang);
7439  if (!res)
7440  res = ast_waitstream(chan, ints);
7441  if (!res)
7442  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7443  } else {
7444  if (!res)
7445  res = ast_streamfile(chan, "digits/oclock", lang);
7446  if (!res)
7447  res = ast_waitstream(chan, ints);
7448  }
7449  if (pm) {
7450  if (!res)
7451  res = ast_streamfile(chan, "digits/p-m", lang);
7452  } else {
7453  if (!res)
7454  res = ast_streamfile(chan, "digits/a-m", lang);
7455  }
7456  if (!res)
7457  res = ast_waitstream(chan, ints);
7458  if (!res)
7459  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
7460  return res;
7461 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

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

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 ast_get_number_str(), and say_datetime().

7494 {
7495  struct timeval when = { t, 0 };
7496  struct ast_tm tm;
7497  char fn[256];
7498  int res = 0;
7499 
7500  ast_localtime(&when, &tm, NULL);
7501 
7502  if (!res)
7503  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
7504 
7505  if (!res) {
7506  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7507  res = ast_streamfile(chan, fn, lang);
7508  if (!res)
7509  res = ast_waitstream(chan, ints);
7510  }
7511  if (!res) {
7512  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7513  res = ast_streamfile(chan, fn, lang);
7514  if (!res)
7515  res = ast_waitstream(chan, ints);
7516  }
7517 
7518  if (!res)
7519  res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
7520  if (!res)
7521  res = ast_streamfile(chan, "digits/oclock", lang);
7522  if (tm.tm_min > 0) {
7523  if (!res)
7524  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7525  }
7526  if (!res)
7527  res = ast_waitstream(chan, ints);
7528  if (!res)
7529  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
7530  return res;
7531 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

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

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 ast_get_number_str(), and say_datetime_from_now().

7822 {
7823  int res=0;
7824  struct timeval nowtv = ast_tvnow(), when = { t, 0 };
7825  int daydiff;
7826  struct ast_tm tm;
7827  struct ast_tm now;
7828  char fn[256];
7829 
7830  ast_localtime(&when, &tm, NULL);
7831  ast_localtime(&nowtv, &now, NULL);
7832  daydiff = now.tm_yday - tm.tm_yday;
7833  if ((daydiff < 0) || (daydiff > 6)) {
7834  /* Day of month and month */
7835  if (!res) {
7836  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7837  res = ast_streamfile(chan, fn, lang);
7838  if (!res)
7839  res = ast_waitstream(chan, ints);
7840  }
7841  if (!res)
7842  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
7843 
7844  } else if (daydiff) {
7845  /* Just what day of the week */
7846  if (!res) {
7847  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7848  res = ast_streamfile(chan, fn, lang);
7849  if (!res)
7850  res = ast_waitstream(chan, ints);
7851  }
7852  } /* Otherwise, it was today */
7853  if (!res)
7854  res = ast_say_time(chan, t, ints, lang);
7855  return res;
7856 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:183
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

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

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 ast_get_number_str(), and say_datetime_from_now().

7860 {
7861  int res=0;
7862  struct timeval nowtv = ast_tvnow(), when = { t, 0 };
7863  int daydiff;
7864  struct ast_tm tm;
7865  struct ast_tm now;
7866  char fn[256];
7867 
7868  ast_localtime(&when, &tm, NULL);
7869  ast_localtime(&nowtv, &now, NULL);
7870  daydiff = now.tm_yday - tm.tm_yday;
7871  if ((daydiff < 0) || (daydiff > 6)) {
7872  /* Day of month and month */
7873  if (!res) {
7874  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7875  res = ast_streamfile(chan, fn, lang);
7876  if (!res)
7877  res = ast_waitstream(chan, ints);
7878  }
7879  if (!res)
7880  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
7881 
7882  } else if (daydiff) {
7883  /* Just what day of the week */
7884  if (!res) {
7885  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7886  res = ast_streamfile(chan, fn, lang);
7887  if (!res)
7888  res = ast_waitstream(chan, ints);
7889  }
7890  } /* Otherwise, it was today */
7891  if (!res)
7892  res = ast_say_time(chan, t, ints, lang);
7893  return res;
7894 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:183
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

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

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 ast_get_number_str(), and say_datetime_from_now().

7948 {
7949  int res = 0;
7950  struct timeval nowt = ast_tvnow(), when = { t, 0 };
7951  int daydiff;
7952  struct ast_tm tm;
7953  struct ast_tm now;
7954  char fn[256];
7955 
7956  ast_localtime(&when, &tm, NULL);
7957  ast_localtime(&nowt, &now, NULL);
7958  daydiff = now.tm_yday - tm.tm_yday;
7959  if ((daydiff < 0) || (daydiff > 6)) {
7960  /* Day of month and month */
7961  if (!res) {
7962  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7963  res = ast_streamfile(chan, fn, lang);
7964  if (!res)
7965  res = ast_waitstream(chan, ints);
7966  }
7967  if (!res) {
7968  res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
7969  }
7970  } else if (daydiff) {
7971  /* Just what day of the week */
7972  if (!res) {
7973  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7974  res = ast_streamfile(chan, fn, lang);
7975  if (!res) {
7976  res = ast_waitstream(chan, ints);
7977  }
7978  }
7979  } /* Otherwise, it was today */
7980  if (!res) {
7981  res = ast_say_time(chan, t, ints, lang);
7982  }
7983  return res;
7984 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:183
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

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

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 ast_get_number_str(), and say_datetime_from_now().

9445 {
9446  int res=0;
9447  int daydiff;
9448  struct ast_tm tm;
9449  struct ast_tm now;
9450  struct timeval when = { t, 0 }, nowt = ast_tvnow();
9451  char fn[256];
9452 
9453  ast_localtime(&when, &tm, NULL);
9454  ast_localtime(&nowt, &now, NULL);
9455  daydiff = now.tm_yday - tm.tm_yday;
9456  if ((daydiff < 0) || (daydiff > 6)) {
9457  /* Day of month and month */
9458  if (!res) {
9459  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
9460  }
9461  if (!res) {
9462  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
9463  res = ast_streamfile(chan, fn, lang);
9464  if (!res) {
9465  res = ast_waitstream(chan, ints);
9466  }
9467  }
9468 
9469  } else if (daydiff) {
9470  /* Just what day of the week */
9471  if (!res) {
9472  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
9473  res = ast_streamfile(chan, fn, lang);
9474  if (!res) {
9475  res = ast_waitstream(chan, ints);
9476  }
9477  }
9478  } /* Otherwise, it was today */
9479  if (!res) {
9480  res = ast_say_time(chan, t, ints, lang);
9481  }
9482 
9483  return res;
9484 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:183
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

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

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 ast_get_number_str(), and say_datetime_from_now().

7898 {
7899  int res=0;
7900  int daydiff;
7901  struct ast_tm tm;
7902  struct ast_tm now;
7903  struct timeval nowtv = ast_tvnow(), when = { t, 0 };
7904  char fn[256];
7905 
7906  ast_localtime(&when, &tm, NULL);
7907  ast_localtime(&nowtv, &now, NULL);
7908  daydiff = now.tm_yday - tm.tm_yday;
7909  if ((daydiff < 0) || (daydiff > 6)) {
7910  /* Day of month and month */
7911  if (!res)
7912  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
7913  if (!res)
7914  res = wait_file(chan, ints, "digits/pt-de", lang);
7915  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7916  if (!res)
7917  res = wait_file(chan, ints, fn, lang);
7918 
7919  } else if (daydiff) {
7920  /* Just what day of the week */
7921  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7922  if (!res)
7923  res = wait_file(chan, ints, fn, lang);
7924  } /* Otherwise, it was today */
7925  if (!strcasecmp(lang, "pt_BR")) {
7926  if (tm.tm_hour > 1) {
7927  ast_copy_string(fn, "digits/pt-as", sizeof(fn));
7928  } else {
7929  ast_copy_string(fn, "digits/pt-a", sizeof(fn));
7930  }
7931  if (!res)
7932  res = wait_file(chan, ints, fn, lang);
7933  } else {
7934  ast_copy_string(fn, "digits/pt-ah", sizeof(fn));
7935  if (!res)
7936  res = wait_file(chan, ints, fn, lang);
7937  if (tm.tm_hour != 1)
7938  if (!res)
7939  res = wait_file(chan, ints, "digits/pt-sss", lang);
7940  if (!res)
7941  res = ast_say_time(chan, t, ints, lang);
7942  }
7943  return res;
7944 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:183
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

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

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 ast_get_number_str(), and say_datetime().

8356 {
8357  struct timeval when = { t, 0 };
8358  struct ast_tm tm;
8359  char fn[256];
8360  int res = 0;
8361 
8362  ast_localtime(&when, &tm, NULL);
8363 
8364  /* W E E K - D A Y */
8365  if (!res) {
8366  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8367  res = ast_streamfile(chan, fn, lang);
8368  if (!res)
8369  res = ast_waitstream(chan, ints);
8370  }
8371  /* D A Y */
8372  if (!res) {
8373  gr_say_number_female(tm.tm_mday, chan, ints, lang);
8374  }
8375  /* M O N T H */
8376  if (!res) {
8377  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8378  res = ast_streamfile(chan, fn, lang);
8379  if (!res)
8380  res = ast_waitstream(chan, ints);
8381  }
8382 
8383  res = ast_say_time_gr(chan, t, ints, lang);
8384  return res;
8385 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Greek support.
Definition: say.c:8260
static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang)
Greek digits/female-[1..4] : "Mia, dyo , treis, tessereis".
Definition: say.c:7991

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

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 ast_get_number_str(), and say_datetime().

7738 {
7739  struct timeval when = { t, 0 };
7740  struct ast_tm tm;
7741  char fn[256];
7742  int res = 0;
7743  int hour;
7744 
7745  ast_localtime(&when, &tm, NULL);
7746  if (!res) {
7747  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7748  res = ast_streamfile(chan, fn, lang);
7749  if (!res) {
7750  res = ast_waitstream(chan, ints);
7751  }
7752  }
7753  if (!res) {
7754  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7755  res = ast_streamfile(chan, fn, lang);
7756  if (!res) {
7757  res = ast_waitstream(chan, ints);
7758  }
7759  }
7760  if (!res) {
7761  res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
7762  }
7763 
7764  hour = tm.tm_hour;
7765  if (!hour) {
7766  hour = 12;
7767  }
7768 
7769  if (!res) {
7770  res = ast_say_number(chan, hour, ints, lang, "f");
7771  }
7772 
7773  if (tm.tm_min > 9) {
7774  if (!res) {
7775  res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
7776  }
7777  } else if (tm.tm_min) {
7778  if (!res) {
7779  /* say a leading zero if needed */
7780  res = ast_say_number(chan, 0, ints, lang, "f");
7781  }
7782  if (!res) {
7783  res = ast_waitstream(chan, ints);
7784  }
7785  if (!res) {
7786  res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
7787  }
7788  } else {
7789  if (!res) {
7790  res = ast_waitstream(chan, ints);
7791  }
7792  }
7793  if (!res) {
7794  res = ast_waitstream(chan, ints);
7795  }
7796  if (!res) {
7797  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "f");
7798  }
7799  return res;
7800 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_datetime_hu()

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

Hungarian syntax.

Definition at line 7479 of file say.c.

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

Referenced by ast_get_number_str(), and say_datetime().

7480 {
7481  struct timeval when = { t, 0 };
7482  struct ast_tm tm;
7483  int res = 0;
7484 
7485  ast_localtime(&when, &tm, NULL);
7486  res = ast_say_date(chan, t, ints, lang);
7487  if (!res)
7488  ast_say_time(chan, t, ints, lang);
7489  return res;
7490 }
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:183
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
SAY_EXTERN int(* ast_say_date)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_date)
Definition: say.h:185

◆ ast_say_datetime_ja()

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

Definition at line 8388 of file say.c.

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 ast_get_number_str(), and say_datetime().

8389 {
8390  struct timeval tv = { t, 0 };
8391  struct ast_tm tm;
8392  char fn[256];
8393  int res = 0;
8394  int hour, pm = 0;
8395 
8396  ast_localtime(&tv, &tm, NULL);
8397 
8398  if (!res)
8399  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
8400  if (!res)
8401  res = ast_streamfile(chan, "digits/nen", lang);
8402  if (!res) {
8403  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
8404  res = ast_streamfile(chan, fn, lang);
8405  if (!res)
8406  res = ast_waitstream(chan, ints);
8407  }
8408  if (!res)
8409  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
8410  if (!res)
8411  res = ast_streamfile(chan, "digits/nichi", lang);
8412  if (!res) {
8413  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
8414  res = ast_streamfile(chan, fn, lang);
8415  if (!res)
8416  res = ast_waitstream(chan, ints);
8417  }
8418 
8419  hour = tm.tm_hour;
8420  if (!hour)
8421  hour = 12;
8422  else if (hour == 12)
8423  pm = 1;
8424  else if (hour > 12) {
8425  hour -= 12;
8426  pm = 1;
8427  }
8428  if (pm) {
8429  if (!res)
8430  res = ast_streamfile(chan, "digits/p-m", lang);
8431  } else {
8432  if (!res)
8433  res = ast_streamfile(chan, "digits/a-m", lang);
8434  }
8435  if (hour == 9 || hour == 21) {
8436  if (!res)
8437  res = ast_streamfile(chan, "digits/9_2", lang);
8438  } else {
8439  if (!res)
8440  res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
8441  }
8442  if (!res)
8443  res = ast_streamfile(chan, "digits/ji", lang);
8444  if (!res)
8445  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
8446  if (!res)
8447  res = ast_streamfile(chan, "digits/fun", lang);
8448  if (!res)
8449  res = ast_waitstream(chan, ints);
8450  return res;
8451 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_datetime_ka()

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

Georgian syntax. Say date, then say time.

Definition at line 9425 of file say.c.

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

Referenced by ast_get_number_str(), and say_datetime().

9426 {
9427  struct timeval when = { t, 0 };
9428  struct ast_tm tm;
9429  int res = 0;
9430 
9431  ast_localtime(&when, &tm, NULL);
9432  res = ast_say_date(chan, t, ints, lang);
9433  if (!res) {
9434  ast_say_time(chan, t, ints, lang);
9435  }
9436  return res;
9437 
9438 }
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:183
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
SAY_EXTERN int(* ast_say_date)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_date)
Definition: say.h:185

◆ ast_say_datetime_nl()

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

Dutch syntax.

Definition at line 7534 of file say.c.

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

Referenced by ast_get_number_str(), and say_datetime().

7535 {
7536  struct timeval when = { t, 0 };
7537  struct ast_tm tm;
7538  int res = 0;
7539 
7540  ast_localtime(&when, &tm, NULL);
7541  res = ast_say_date(chan, t, ints, lang);
7542  if (!res) {
7543  res = ast_streamfile(chan, "digits/nl-om", lang);
7544  if (!res)
7545  res = ast_waitstream(chan, ints);
7546  }
7547  if (!res)
7548  ast_say_time(chan, t, ints, lang);
7549  return res;
7550 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:183
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
SAY_EXTERN int(* ast_say_date)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_date)
Definition: say.h:185
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_datetime_pt()

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

Portuguese syntax.

Definition at line 7553 of file say.c.

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 ast_get_number_str(), and say_datetime().

7554 {
7555  struct timeval when = { t, 0 };
7556  struct ast_tm tm;
7557  char fn[256];
7558  int res = 0;
7559  int hour, pm=0;
7560 
7561  ast_localtime(&when, &tm, NULL);
7562  if (!res) {
7563  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7564  res = ast_streamfile(chan, fn, lang);
7565  if (!res)
7566  res = ast_waitstream(chan, ints);
7567  }
7568  if (!res) {
7569  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7570  res = ast_streamfile(chan, fn, lang);
7571  if (!res)
7572  res = ast_waitstream(chan, ints);
7573  }
7574  if (!res)
7575  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
7576 
7577  hour = tm.tm_hour;
7578  if (!hour)
7579  hour = 12;
7580  else if (hour == 12)
7581  pm = 1;
7582  else if (hour > 12) {
7583  hour -= 12;
7584  pm = 1;
7585  }
7586  if (!res)
7587  res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
7588 
7589  if (tm.tm_min > 9) {
7590  if (!res)
7591  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7592  } else if (tm.tm_min) {
7593  if (!res)
7594  res = ast_streamfile(chan, "digits/oh", lang);
7595  if (!res)
7596  res = ast_waitstream(chan, ints);
7597  if (!res)
7598  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7599  } else {
7600  if (!res)
7601  res = ast_streamfile(chan, "digits/oclock", lang);
7602  if (!res)
7603  res = ast_waitstream(chan, ints);
7604  }
7605  if (pm) {
7606  if (!res)
7607  res = ast_streamfile(chan, "digits/p-m", lang);
7608  } else {
7609  if (!res)
7610  res = ast_streamfile(chan, "digits/a-m", lang);
7611  }
7612  if (!res)
7613  res = ast_waitstream(chan, ints);
7614  if (!res)
7615  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
7616  return res;
7617 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_datetime_pt_BR()

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

Brazilian Portuguese syntax.

Definition at line 7620 of file say.c.

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

Referenced by ast_get_number_str(), and say_datetime().

7621 {
7622  struct timeval when = { t, 0 };
7623  struct ast_tm tm;
7624  int res = 0;
7625 
7626  ast_localtime(&when, &tm, NULL);
7627  res = ast_say_date(chan, t, ints, lang);
7628  if (!res)
7629  res = ast_say_time(chan, t, ints, lang);
7630  return res;
7631 }
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:183
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
SAY_EXTERN int(* ast_say_date)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_date)
Definition: say.h:185

◆ ast_say_datetime_th()

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

Thai syntax.

Definition at line 7634 of file say.c.

References ast_copy_string(), 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 ast_get_number_str(), and say_datetime().

7635 {
7636  struct timeval when = { t, 0 };
7637  struct ast_tm tm;
7638  char fn[256];
7639  int res = 0;
7640  int hour;
7641  ast_localtime(&when, &tm, NULL);
7642  if (!res) {
7643  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7644  res = ast_streamfile(chan, fn, lang);
7645  if (!res)
7646  res = ast_waitstream(chan, ints);
7647  }
7648  if (!res) {
7649  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7650  res = ast_streamfile(chan, fn, lang);
7651  if (!res)
7652  res = ast_waitstream(chan, ints);
7653  }
7654  if (!res){
7655  ast_copy_string(fn, "digits/posor", sizeof(fn));
7656  res = ast_streamfile(chan, fn, lang);
7657  res = ast_say_number(chan, tm.tm_year + 1900 + 543, ints, lang, (char *) NULL);
7658  }
7659  if (!res)
7660  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
7661 
7662  hour = tm.tm_hour;
7663  if (!hour)
7664  hour = 24;
7665  if (!res){
7666  ast_copy_string(fn, "digits/wela", sizeof(fn));
7667  res = ast_streamfile(chan, fn, lang);
7668  }
7669  if (!res)
7670  res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
7671  if (!res)
7672  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7673  return res;
7674 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_datetime_zh()

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

Taiwanese / Chinese syntax.

Definition at line 7677 of file say.c.

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 ast_get_number_str(), and say_datetime().

7678 {
7679  struct timeval when = { t, 0 };
7680  struct ast_tm tm;
7681  char fn[256];
7682  int res = 0;
7683  int hour, pm=0;
7684 
7685  ast_localtime(&when, &tm, NULL);
7686  if (!res)
7687  res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
7688  if (!res) {
7689  snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
7690  res = ast_streamfile(chan, fn, lang);
7691  if (!res)
7692  res = ast_waitstream(chan, ints);
7693  }
7694  if (!res)
7695  res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
7696  if (!res) {
7697  snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
7698  res = ast_streamfile(chan, fn, lang);
7699  if (!res)
7700  res = ast_waitstream(chan, ints);
7701  }
7702 
7703  hour = tm.tm_hour;
7704  if (!hour)
7705  hour = 12;
7706  else if (hour == 12)
7707  pm = 1;
7708  else if (hour > 12) {
7709  hour -= 12;
7710  pm = 1;
7711  }
7712  if (pm) {
7713  if (!res)
7714  res = ast_streamfile(chan, "digits/p-m", lang);
7715  } else {
7716  if (!res)
7717  res = ast_streamfile(chan, "digits/a-m", lang);
7718  }
7719  if (!res)
7720  res = ast_waitstream(chan, ints);
7721  if (!res)
7722  res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
7723  if (!res)
7724  res = ast_streamfile(chan, "digits/oclock", lang);
7725  if (!res)
7726  res = ast_waitstream(chan, ints);
7727  if (!res)
7728  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7729  if (!res)
7730  res = ast_streamfile(chan, "minute", lang);
7731  if (!res)
7732  res = ast_waitstream(chan, ints);
7733  return res;
7734 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_enumeration_full_da()

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 
)
static

ast_say_enumeration_full_da: Danish syntax

Definition at line 3218 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_say_number_full_de(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_enumeration_full().

3219 {
3220  /* options can be: '' or 'm' male gender; 'f' female gender; 'n' neuter gender */
3221  int res = 0, t = 0;
3222  char fn[256] = "", fna[256] = "";
3223  char *gender;
3224 
3225  if (options && !strncasecmp(options, "f", 1)) {
3226  gender = "F";
3227  } else if (options && !strncasecmp(options, "n", 1)) {
3228  gender = "N";
3229  } else {
3230  gender = "";
3231  }
3232 
3233  if (!num)
3234  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
3235 
3236  while (!res && num) {
3237  if (num < 0) {
3238  ast_copy_string(fn, "digits/minus", sizeof(fn)); /* kind of senseless for enumerations, but our best effort for error checking */
3239  if ( num > INT_MIN ) {
3240  num = -num;
3241  } else {
3242  num = 0;
3243  }
3244  } else if (num < 100 && t) {
3245  ast_copy_string(fn, "digits/and", sizeof(fn));
3246  t = 0;
3247  } else if (num < 20) {
3248  snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
3249  num = 0;
3250  } else if (num < 100) {
3251  int ones = num % 10;
3252  if (ones) {
3253  snprintf(fn, sizeof(fn), "digits/%d-and", ones);
3254  num -= ones;
3255  } else {
3256  snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
3257  num = 0;
3258  }
3259  } else if (num == 100 && t == 0) {
3260  snprintf(fn, sizeof(fn), "digits/h-hundred%s", gender);
3261  num = 0;
3262  } else if (num < 1000) {
3263  int hundreds = num / 100;
3264  num = num % 100;
3265  if (hundreds == 1) {
3266  ast_copy_string(fn, "digits/1N", sizeof(fn));
3267  } else {
3268  snprintf(fn, sizeof(fn), "digits/%d", hundreds);
3269  }
3270  if (num) {
3271  ast_copy_string(fna, "digits/hundred", sizeof(fna));
3272  } else {
3273  snprintf(fna, sizeof(fna), "digits/h-hundred%s", gender);
3274  }
3275  t = 1;
3276  } else if (num < 1000000) {
3277  int thousands = num / 1000;
3278  num = num % 1000;
3279  if (thousands == 1) {
3280  if (num) {
3281  ast_copy_string(fn, "digits/1N", sizeof(fn));
3282  ast_copy_string(fna, "digits/thousand", sizeof(fna));
3283  } else {
3284  if (t) {
3285  ast_copy_string(fn, "digits/1N", sizeof(fn));
3286  snprintf(fna, sizeof(fna), "digits/h-thousand%s", gender);
3287  } else {
3288  snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
3289  }
3290  }
3291  } else {
3292  res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
3293  if (res) {
3294  return res;
3295  }
3296  if (num) {
3297  ast_copy_string(fn, "digits/thousand", sizeof(fn));
3298  } else {
3299  snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
3300  }
3301  }
3302  t = 1;
3303  } else if (num < 1000000000) {
3304  int millions = num / 1000000;
3305  num = num % 1000000;
3306  if (millions == 1) {
3307  if (num) {
3308  ast_copy_string(fn, "digits/1F", sizeof(fn));
3309  ast_copy_string(fna, "digits/million", sizeof(fna));
3310  } else {
3311  ast_copy_string(fn, "digits/1N", sizeof(fn));
3312  snprintf(fna, sizeof(fna), "digits/h-million%s", gender);
3313  }
3314  } else {
3315  res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
3316  if (res) {
3317  return res;
3318  }
3319  if (num) {
3320  ast_copy_string(fn, "digits/millions", sizeof(fn));
3321  } else {
3322  snprintf(fn, sizeof(fn), "digits/h-million%s", gender);
3323  }
3324  }
3325  t = 1;
3326  } else if (num < INT_MAX) {
3327  int billions = num / 1000000000;
3328  num = num % 1000000000;
3329  if (billions == 1) {
3330  if (num) {
3331  ast_copy_string(fn, "digits/1F", sizeof(fn));
3332  ast_copy_string(fna, "digits/milliard", sizeof(fna));
3333  } else {
3334  ast_copy_string(fn, "digits/1N", sizeof(fn));
3335  snprintf(fna, sizeof(fna), "digits/h-milliard%s", gender);
3336  }
3337  } else {
3338  res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
3339  if (res)
3340  return res;
3341  if (num) {
3342  ast_copy_string(fn, "digits/milliards", sizeof(fna));
3343  } else {
3344  snprintf(fn, sizeof(fna), "digits/h-milliard%s", gender);
3345  }
3346  }
3347  t = 1;
3348  } else if (num == INT_MAX) {
3349  snprintf(fn, sizeof(fn), "digits/h-last%s", gender);
3350  num = 0;
3351  } else {
3352  ast_debug(1, "Number '%d' is too big for me\n", num);
3353  res = -1;
3354  }
3355 
3356  if (!res) {
3357  if (!ast_streamfile(chan, fn, language)) {
3358  if ((audiofd > -1) && (ctrlfd > -1))
3359  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3360  else
3361  res = ast_waitstream(chan, ints);
3362  }
3363  ast_stopstream(chan);
3364  if (!res) {
3365  if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
3366  if ((audiofd > -1) && (ctrlfd > -1)) {
3367  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3368  } else {
3369  res = ast_waitstream(chan, ints);
3370  }
3371  }
3372  ast_stopstream(chan);
3373  strcpy(fna, "");
3374  }
3375  }
3376  }
3377  return res;
3378 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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
Definition: say.c:1038
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_enumeration_full_de()

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 
)
static

ast_say_enumeration_full_de: German syntax

Definition at line 3381 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_say_number_full_de(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_enumeration_full().

3382 {
3383  /* options can be: '' or 'm' male gender; 'f' female gender; 'n' neuter gender */
3384  int res = 0, t = 0;
3385  char fn[256] = "", fna[256] = "";
3386  char *gender;
3387 
3388  if (options && !strncasecmp(options, "f", 1)) {
3389  gender = "F";
3390  } else if (options && !strncasecmp(options, "n", 1)) {
3391  gender = "N";
3392  } else {
3393  gender = "";
3394  }
3395 
3396  if (!num)
3397  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
3398 
3399  while (!res && num) {
3400  if (num < 0) {
3401  ast_copy_string(fn, "digits/minus", sizeof(fn)); /* kind of senseless for enumerations, but our best effort for error checking */
3402  if ( num > INT_MIN ) {
3403  num = -num;
3404  } else {
3405  num = 0;
3406  }
3407  } else if (num < 100 && t) {
3408  ast_copy_string(fn, "digits/and", sizeof(fn));
3409  t = 0;
3410  } else if (num < 20) {
3411  snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
3412  num = 0;
3413  } else if (num < 100) {
3414  int ones = num % 10;
3415  if (ones) {
3416  snprintf(fn, sizeof(fn), "digits/%d-and", ones);
3417  num -= ones;
3418  } else {
3419  snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
3420  num = 0;
3421  }
3422  } else if (num == 100 && t == 0) {
3423  snprintf(fn, sizeof(fn), "digits/h-hundred%s", gender);
3424  num = 0;
3425  } else if (num < 1000) {
3426  int hundreds = num / 100;
3427  num = num % 100;
3428  if (hundreds == 1) {
3429  ast_copy_string(fn, "digits/1N", sizeof(fn));
3430  } else {
3431  snprintf(fn, sizeof(fn), "digits/%d", hundreds);
3432  }
3433  if (num) {
3434  ast_copy_string(fna, "digits/hundred", sizeof(fna));
3435  } else {
3436  snprintf(fna, sizeof(fna), "digits/h-hundred%s", gender);
3437  }
3438  t = 1;
3439  } else if (num < 1000000) {
3440  int thousands = num / 1000;
3441  num = num % 1000;
3442  if (thousands == 1) {
3443  if (num) {
3444  ast_copy_string(fn, "digits/1N", sizeof(fn));
3445  ast_copy_string(fna, "digits/thousand", sizeof(fna));
3446  } else {
3447  if (t) {
3448  ast_copy_string(fn, "digits/1N", sizeof(fn));
3449  snprintf(fna, sizeof(fna), "digits/h-thousand%s", gender);
3450  } else {
3451  snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
3452  }
3453  }
3454  } else {
3455  res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
3456  if (res) {
3457  return res;
3458  }
3459  if (num) {
3460  ast_copy_string(fn, "digits/thousand", sizeof(fn));
3461  } else {
3462  snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
3463  }
3464  }
3465  t = 1;
3466  } else if (num < 1000000000) {
3467  int millions = num / 1000000;
3468  num = num % 1000000;
3469  if (millions == 1) {
3470  if (num) {
3471  ast_copy_string(fn, "digits/1F", sizeof(fn));
3472  ast_copy_string(fna, "digits/million", sizeof(fna));
3473  } else {
3474  ast_copy_string(fn, "digits/1N", sizeof(fn));
3475  snprintf(fna, sizeof(fna), "digits/h-million%s", gender);
3476  }
3477  } else {
3478  res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
3479  if (res) {
3480  return res;
3481  }
3482  if (num) {
3483  ast_copy_string(fn, "digits/millions", sizeof(fn));
3484  } else {
3485  snprintf(fn, sizeof(fn), "digits/h-million%s", gender);
3486  }
3487  }
3488  t = 1;
3489  } else if (num < INT_MAX) {
3490  int billions = num / 1000000000;
3491  num = num % 1000000000;
3492  if (billions == 1) {
3493  if (num) {
3494  ast_copy_string(fn, "digits/1F", sizeof(fn));
3495  ast_copy_string(fna, "digits/milliard", sizeof(fna));
3496  } else {
3497  ast_copy_string(fn, "digits/1N", sizeof(fn));
3498  snprintf(fna, sizeof(fna), "digits/h-milliard%s", gender);
3499  }
3500  } else {
3501  res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
3502  if (res)
3503  return res;
3504  if (num) {
3505  ast_copy_string(fn, "digits/milliards", sizeof(fna));
3506  } else {
3507  snprintf(fn, sizeof(fna), "digits/h-milliard%s", gender);
3508  }
3509  }
3510  t = 1;
3511  } else if (num == INT_MAX) {
3512  snprintf(fn, sizeof(fn), "digits/h-last%s", gender);
3513  num = 0;
3514  } else {
3515  ast_debug(1, "Number '%d' is too big for me\n", num);
3516  res = -1;
3517  }
3518 
3519  if (!res) {
3520  if (!ast_streamfile(chan, fn, language)) {
3521  if ((audiofd > -1) && (ctrlfd > -1))
3522  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3523  else
3524  res = ast_waitstream(chan, ints);
3525  }
3526  ast_stopstream(chan);
3527  if (!res) {
3528  if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
3529  if ((audiofd > -1) && (ctrlfd > -1)) {
3530  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3531  } else {
3532  res = ast_waitstream(chan, ints);
3533  }
3534  }
3535  ast_stopstream(chan);
3536  strcpy(fna, "");
3537  }
3538  }
3539  }
3540  return res;
3541 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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
Definition: say.c:1038
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_enumeration_full_en()

static int ast_say_enumeration_full_en ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_enumeration_full_en: English syntax

Note
This is the default syntax, if no other syntax defined in this file is used

Definition at line 3101 of file say.c.

References ast_copy_string(), ast_debug, ast_say_number_full_en(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_enumeration_full().

3102 {
3103  int res = 0, t = 0;
3104  char fn[256] = "";
3105 
3106  while (!res && num) {
3107  if (num < 0) {
3108  ast_copy_string(fn, "digits/minus", sizeof(fn)); /* kind of senseless for enumerations, but our best effort for error checking */
3109  if ( num > INT_MIN ) {
3110  num = -num;
3111  } else {
3112  num = 0;
3113  }
3114  } else if (num < 20) {
3115  snprintf(fn, sizeof(fn), "digits/h-%d", num);
3116  num = 0;
3117  } else if (num < 100) {
3118  int tens = num / 10;
3119  num = num % 10;
3120  if (num == 0) {
3121  snprintf(fn, sizeof(fn), "digits/h-%d", (tens * 10));
3122  } else {
3123  snprintf(fn, sizeof(fn), "digits/%d", (tens * 10));
3124  }
3125  } else if (num < 1000) {
3126  int hundreds = num / 100;
3127  num = num % 100;
3128  if (hundreds > 1 || t == 1) {
3129  res = ast_say_number_full_en(chan, hundreds, ints, language, audiofd, ctrlfd);
3130  }
3131  if (res)
3132  return res;
3133  if (num) {
3134  ast_copy_string(fn, "digits/hundred", sizeof(fn));
3135  } else {
3136  ast_copy_string(fn, "digits/h-hundred", sizeof(fn));
3137  }
3138  } else if (num < 1000000) {
3139  int thousands = num / 1000;
3140  num = num % 1000;
3141  if (thousands > 1 || t == 1) {
3142  res = ast_say_number_full_en(chan, thousands, ints, language, audiofd, ctrlfd);
3143  }
3144  if (res)
3145  return res;
3146  if (num) {
3147  ast_copy_string(fn, "digits/thousand", sizeof(fn));
3148  } else {
3149  ast_copy_string(fn, "digits/h-thousand", sizeof(fn));
3150  }
3151  t = 1;
3152  } else if (num < 1000000000) {
3153  int millions = num / 1000000;
3154  num = num % 1000000;
3155  t = 1;
3156  res = ast_say_number_full_en(chan, millions, ints, language, audiofd, ctrlfd);
3157  if (res)
3158  return res;
3159  if (num) {
3160  ast_copy_string(fn, "digits/million", sizeof(fn));
3161  } else {
3162  ast_copy_string(fn, "digits/h-million", sizeof(fn));
3163  }
3164  } else if (num < INT_MAX) {
3165  int billions = num / 1000000000;
3166  num = num % 1000000000;
3167  t = 1;
3168  res = ast_say_number_full_en(chan, billions, ints, language, audiofd, ctrlfd);
3169  if (res)
3170  return res;
3171  if (num) {
3172  ast_copy_string(fn, "digits/billion", sizeof(fn));
3173  } else {
3174  ast_copy_string(fn, "digits/h-billion", sizeof(fn));
3175  }
3176  } else if (num == INT_MAX) {
3177  ast_copy_string(fn, "digits/h-last", sizeof(fn));
3178  num = 0;
3179  } else {
3180  ast_debug(1, "Number '%d' is too big for me\n", num);
3181  res = -1;
3182  }
3183 
3184  if (!res) {
3185  if (!ast_streamfile(chan, fn, language)) {
3186  if ((audiofd > -1) && (ctrlfd > -1)) {
3187  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3188  } else {
3189  res = ast_waitstream(chan, ints);
3190  }
3191  }
3192  ast_stopstream(chan);
3193  }
3194  }
3195  return res;
3196 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
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
Definition: say.c:772
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_enumeration_full_he()

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

Definition at line 3543 of file say.c.

References ast_debug, ast_say_number_full_he(), ast_stopstream(), ast_streamfile(), ast_verb, ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_enumeration_full().

3544 {
3545  int res = 0;
3546  char fn[256] = "";
3547  int mf = -1; /* +1 = Masculin; -1 = Feminin */
3548  ast_verb(3, "ast_say_digits_full: started. num: %d, options=\"%s\"\n", num, options);
3549 
3550  if (options && !strncasecmp(options, "m", 1)) {
3551  mf = -1;
3552  }
3553 
3554  ast_verb(3, "ast_say_digits_full: num: %d, options=\"%s\", mf=%d\n", num, options, mf);
3555 
3556  while (!res && num) {
3557  if (num < 0) {
3558  snprintf(fn, sizeof(fn), "digits/minus"); /* kind of senseless for enumerations, but our best effort for error checking */
3559  if (num > INT_MIN) {
3560  num = -num;
3561  } else {
3562  num = 0;
3563  }
3564  } else if (num < 21) {
3565  if (mf < 0) {
3566  if (num < 10) {
3567  snprintf(fn, sizeof(fn), "digits/f-0%d", num);
3568  } else {
3569  snprintf(fn, sizeof(fn), "digits/f-%d", num);
3570  }
3571  } else {
3572  if (num < 10) {
3573  snprintf(fn, sizeof(fn), "digits/m-0%d", num);
3574  } else {
3575  snprintf(fn, sizeof(fn), "digits/m-%d", num);
3576  }
3577  }
3578  num = 0;
3579  } else if ((num < 100) && num >= 20) {
3580  snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
3581  num = num % 10;
3582  } else if ((num >= 100) && (num < 1000)) {
3583  int tmpnum = num / 100;
3584  snprintf(fn, sizeof(fn), "digits/%d00", tmpnum);
3585  num = num - (tmpnum * 100);
3586  } else if ((num >= 1000) && (num < 10000)) {
3587  int tmpnum = num / 1000;
3588  snprintf(fn, sizeof(fn), "digits/%dk", tmpnum);
3589  num = num - (tmpnum * 1000);
3590  } else if (num < 20000) {
3591  snprintf(fn, sizeof(fn), "digits/m-%d", (num / 1000));
3592  num = num % 1000;
3593  } else if (num < 1000000) {
3594  res = ast_say_number_full_he(chan, num / 1000, ints, language, "m", audiofd, ctrlfd);
3595  if (res) {
3596  return res;
3597  }
3598  snprintf(fn, sizeof(fn), "digits/1k");
3599  num = num % 1000;
3600  } else if (num < 2000000) {
3601  snprintf(fn, sizeof(fn), "digits/1m");
3602  num = num % 1000000;
3603  } else if (num < 3000000) {
3604  snprintf(fn, sizeof(fn), "digits/2m");
3605  num = num - 2000000;
3606  } else if (num < 1000000000) {
3607  res = ast_say_number_full_he(chan, num / 1000000, ints, language, "m", audiofd, ctrlfd);
3608  if (res) {
3609  return res;
3610  }
3611  snprintf(fn, sizeof(fn), "digits/1m");
3612  num = num % 1000000;
3613  } else {
3614  ast_debug(1, "Number '%d' is too big for me\n", num);
3615  res = -1;
3616  }
3617  if (!res) {
3618  if (!ast_streamfile(chan, fn, language)) {
3619  if ((audiofd > -1) && (ctrlfd > -1)) {
3620  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3621  } else {
3622  res = ast_waitstream(chan, ints);
3623  }
3624  }
3625  ast_stopstream(chan);
3626  }
3627  }
3628  return res;
3629 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static int ast_say_number_full_he(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
Definition: say.c:1447
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_enumeration_full_is()

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 
)
static

ast_say_enumeration_full_is: Icelandic syntax

Definition at line 3632 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_say_number_full_is(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_enumeration_full().

3633 {
3634  /* options can be: '' or 'm' male gender; 'f' female gender; 'n' neuter gender */
3635  int res = 0, t = 0;
3636  char fn[256] = "", fna[256] = "";
3637  char *gender;
3638 
3639  if (options && !strncasecmp(options, "f", 1)) {
3640  gender = "F";
3641  } else if (options && !strncasecmp(options, "n", 1)) {
3642  gender = "N";
3643  } else {
3644  gender = "";
3645  }
3646 
3647  if (!num)
3648  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
3649 
3650  while (!res && num) {
3651  if (num < 0) {
3652  ast_copy_string(fn, "digits/minus", sizeof(fn)); /* kind of senseless for enumerations, but our best effort for error checking */
3653  if ( num > INT_MIN ) {
3654  num = -num;
3655  } else {
3656  num = 0;
3657  }
3658  } else if (num < 100 && t) {
3659  ast_copy_string(fn, "digits/and", sizeof(fn));
3660  t = 0;
3661  } else if (num < 20) {
3662  snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
3663  num = 0;
3664  } else if (num < 100) {
3665  int ones = num % 10;
3666  if (ones) {
3667  int tens = num - ones;
3668  snprintf(fn, sizeof(fn), "digits/h-%d%s", tens, gender);
3669  num = ones;
3670  t++;
3671  }
3672  else if (t) {
3673  snprintf(fn, sizeof(fn), "digits/and");
3674  t = 0;
3675  }
3676  else {
3677  snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
3678  num = 0;
3679  }
3680 
3681  } else if (num == 100 && t == 0) {
3682  snprintf(fn, sizeof(fn), "digits/h-hundred%s", gender);
3683  num = 0;
3684  } else if (num < 1000) {
3685  int hundreds = num / 100;
3686  num = num % 100;
3687  if (hundreds == 1) {
3688  ast_copy_string(fn, "digits/1hk", sizeof(fn));
3689  } else {
3690  snprintf(fn, sizeof(fn), "digits/%d", hundreds);
3691  }
3692  if (num) {
3693  ast_copy_string(fna, "digits/hundred", sizeof(fna));
3694  } else {
3695  snprintf(fna, sizeof(fna), "digits/h-hundred%s", gender);
3696  }
3697  t = 1;
3698  } else if (num < 1000000) {
3699  int thousands = num / 1000;
3700  num = num % 1000;
3701  if (thousands == 1) {
3702  if (num) {
3703  /* Thousand is a neutral word, so use the neutral recording */
3704  ast_copy_string(fn, "digits/1hk", sizeof(fn));
3705  ast_copy_string(fna, "digits/thousand", sizeof(fna));
3706  } else {
3707  if (t) {
3708  ast_copy_string(fn, "digits/1hk", sizeof(fn));
3709  snprintf(fna, sizeof(fna), "digits/h-thousand%s", gender);
3710  } else {
3711  snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
3712  }
3713  }
3714  } else {
3715  res = ast_say_number_full_is(chan, thousands, ints, language, options, audiofd, ctrlfd);
3716  if (res) {
3717  return res;
3718  }
3719  if (num) {
3720  ast_copy_string(fn, "digits/thousand", sizeof(fn));
3721  } else {
3722  snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
3723  }
3724  }
3725  if (num)
3726  t = 1;
3727  } else if (num < 1000000000) {
3728  int millions = num / 1000000;
3729  num = num % 1000000;
3730  if (millions == 1) {
3731  if (num) {
3732  /* Million is a feminine word, so use the female form */
3733  ast_copy_string(fn, "digits/1kvk", sizeof(fn));
3734  ast_copy_string(fna, "digits/million", sizeof(fna));
3735  } else {
3736  ast_copy_string(fn, "digits/1hk", sizeof(fn));
3737  snprintf(fna, sizeof(fna), "digits/h-million%s", gender);
3738  }
3739  } else {
3740  res = ast_say_number_full_is(chan, millions, ints, language, options, audiofd, ctrlfd);
3741  if (res) {
3742  return res;
3743  }
3744  if (num) {
3745  ast_copy_string(fn, "digits/millions", sizeof(fn));
3746  } else {
3747  snprintf(fn, sizeof(fn), "digits/h-million%s", gender);
3748  }
3749  }
3750  if (num)
3751  t = 1;
3752  } else if (num < INT_MAX) {
3753  int billions = num / 1000000000;
3754  num = num % 1000000000;
3755  if (billions == 1) {
3756  if (num) {
3757  ast_copy_string(fn, "digits/1", sizeof(fn));
3758  ast_copy_string(fna, "digits/milliard", sizeof(fna));
3759  } else {
3760  ast_copy_string(fn, "digits/1hk", sizeof(fn));
3761  snprintf(fna, sizeof(fna), "digits/h-milliard%s", gender);
3762  }
3763  } else {
3764  res = ast_say_number_full_is(chan, billions, ints, language, options, audiofd, ctrlfd);
3765  if (res)
3766  return res;
3767  if (num) {
3768  ast_copy_string(fn, "digits/milliards", sizeof(fna));
3769  } else {
3770  snprintf(fn, sizeof(fna), "digits/h-milliard%s", gender);
3771  }
3772  }
3773  if (num)
3774  t = 1;
3775  } else if (num == INT_MAX) {
3776  snprintf(fn, sizeof(fn), "digits/h-last%s", gender);
3777  num = 0;
3778  } else {
3779  ast_debug(1, "Number '%d' is too big for me\n", num);
3780  res = -1;
3781  }
3782 
3783  if (!res) {
3784  if (!ast_streamfile(chan, fn, language)) {
3785  if ((audiofd > -1) && (ctrlfd > -1))
3786  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3787  else
3788  res = ast_waitstream(chan, ints);
3789  }
3790  ast_stopstream(chan);
3791  if (!res) {
3792  if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
3793  if ((audiofd > -1) && (ctrlfd > -1)) {
3794  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3795  } else {
3796  res = ast_waitstream(chan, ints);
3797  }
3798  }
3799  ast_stopstream(chan);
3800  strcpy(fna, "");
3801  }
3802  }
3803  }
3804  return res;
3805 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
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
Definition: say.c:1699
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_enumeration_full_vi()

static int ast_say_enumeration_full_vi ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

Definition at line 3198 of file say.c.

References ast_copy_string(), ast_say_number_full_vi(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_enumeration_full().

3199 {
3200  int res = 0;
3201  char fn[256] = "";
3202  ast_copy_string(fn, "digits/h", sizeof(fn));
3203  if (!res) {
3204  if (!ast_streamfile(chan, fn, language)) {
3205  if ((audiofd > -1) && (ctrlfd > -1)) {
3206  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3207  } else {
3208  res = ast_waitstream(chan, ints);
3209  }
3210  }
3211  ast_stopstream(chan);
3212  }
3213 
3214  return ast_say_number_full_vi(chan, num, ints, language, audiofd, ctrlfd);
3215 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
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
Definition: say.c:2983
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_cs()

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 
)
static

ast_say_number_full_cs: Czech syntax

files needed:

  • 1m,2m - gender male
  • 1w,2w - gender female
  • 3,4,...,20
  • 30,40,...,90
  • hundereds - 100 - sto, 200 - 2ste, 300,400 3,4sta, 500,600,...,900 5,6,...9set

for each number 10^(3n + 3) exist 3 files represented as: 1 tousand = jeden tisic = 1_E3 2,3,4 tousands = dva,tri,ctyri tisice = 2-3_E3 5,6,... tousands = pet,sest,... tisic = 5_E3

million = _E6 miliard = _E9 etc...

tousand, milion are gender male, so 1 and 2 is 1m 2m miliard is gender female, so 1 and 2 is 1w 2w

Definition at line 826 of file say.c.

References ast_copy_string(), ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), and exp10_int().

Referenced by ast_get_number_str(), and say_number_full().

827 {
828  int res = 0;
829  int playh = 0;
830  char fn[256] = "";
831 
832  int hundered = 0;
833  int left = 0;
834  int length = 0;
835 
836  /* options - w = woman, m = man, n = neutral. Defaultl is woman */
837  if (!options)
838  options = "w";
839 
840  if (!num)
841  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
842 
843  while (!res && (num || playh)) {
844  if (num < 0) {
845  ast_copy_string(fn, "digits/minus", sizeof(fn));
846  if ( num > INT_MIN ) {
847  num = -num;
848  } else {
849  num = 0;
850  }
851  } else if (num < 3 ) {
852  snprintf(fn, sizeof(fn), "digits/%d%c", num, options[0]);
853  playh = 0;
854  num = 0;
855  } else if (num < 20) {
856  snprintf(fn, sizeof(fn), "digits/%d", num);
857  playh = 0;
858  num = 0;
859  } else if (num < 100) {
860  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
861  num %= 10;
862  } else if (num < 1000) {
863  hundered = num / 100;
864  if ( hundered == 1 ) {
865  ast_copy_string(fn, "digits/1sto", sizeof(fn));
866  } else if ( hundered == 2 ) {
867  ast_copy_string(fn, "digits/2ste", sizeof(fn));
868  } else {
869  res = ast_say_number_full_cs(chan, hundered, ints, language, options, audiofd, ctrlfd);
870  if (res)
871  return res;
872  if (hundered == 3 || hundered == 4) {
873  ast_copy_string(fn, "digits/sta", sizeof(fn));
874  } else if ( hundered > 4 ) {
875  ast_copy_string(fn, "digits/set", sizeof(fn));
876  }
877  }
878  num -= (hundered * 100);
879  } else { /* num > 1000 */
880  length = (int)log10(num)+1;
881  while ( (length % 3 ) != 1 ) {
882  length--;
883  }
884  left = num / (exp10_int(length-1));
885  if ( left == 2 ) {
886  switch (length-1) {
887  case 9: options = "w"; /* 1,000,000,000 gender female */
888  break;
889  default : options = "m"; /* others are male */
890  }
891  }
892  if ( left > 1 ) { /* we don't say "one thousand" but only thousand */
893  res = ast_say_number_full_cs(chan, left, ints, language, options, audiofd, ctrlfd);
894  if (res)
895  return res;
896  }
897  if ( left >= 5 ) { /* >= 5 have the same declesion */
898  snprintf(fn, sizeof(fn), "digits/5_E%d", length - 1);
899  } else if ( left >= 2 && left <= 4 ) {
900  snprintf(fn, sizeof(fn), "digits/2-4_E%d", length - 1);
901  } else { /* left == 1 */
902  snprintf(fn, sizeof(fn), "digits/1_E%d", length - 1);
903  }
904  num -= left * (exp10_int(length-1));
905  }
906  if (!res) {
907  if (!ast_streamfile(chan, fn, language)) {
908  if ((audiofd > -1) && (ctrlfd > -1)) {
909  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
910  } else {
911  res = ast_waitstream(chan, ints);
912  }
913  }
914  ast_stopstream(chan);
915  }
916  }
917  return res;
918 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
static int exp10_int(int power)
Definition: say.c:796
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
Definition: say.c:826
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_da()

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 
)
static

ast_say_number_full_da: Danish syntax New files:

  • In addition to English, the following sounds are required: "1N", "millions", "and" and "1-and" through "9-and"

Definition at line 924 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

925 {
926  int res = 0;
927  int playh = 0;
928  int playa = 0;
929  int cn = 1; /* +1 = commune; -1 = neuter */
930  char fn[256] = "";
931  if (!num)
932  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
933 
934  if (options && !strncasecmp(options, "n", 1)) cn = -1;
935 
936  while (!res && (num || playh || playa )) {
937  /* The grammar for Danish numbers is the same as for English except
938  * for the following:
939  * - 1 exists in both commune ("en", file "1N") and neuter ("et", file "1")
940  * - numbers 20 through 99 are said in reverse order, i.e. 21 is
941  * "one-and twenty" and 68 is "eight-and sixty".
942  * - "million" is different in singular and plural form
943  * - numbers > 1000 with zero as the third digit from last have an
944  * "and" before the last two digits, i.e. 2034 is "two thousand and
945  * four-and thirty" and 1000012 is "one million and twelve".
946  */
947  if (num < 0) {
948  ast_copy_string(fn, "digits/minus", sizeof(fn));
949  if ( num > INT_MIN ) {
950  num = -num;
951  } else {
952  num = 0;
953  }
954  } else if (playh) {
955  ast_copy_string(fn, "digits/hundred", sizeof(fn));
956  playh = 0;
957  } else if (playa) {
958  ast_copy_string(fn, "digits/and", sizeof(fn));
959  playa = 0;
960  } else if (num == 1 && cn == -1) {
961  ast_copy_string(fn, "digits/1N", sizeof(fn));
962  num = 0;
963  } else if (num < 20) {
964  snprintf(fn, sizeof(fn), "digits/%d", num);
965  num = 0;
966  } else if (num < 100) {
967  int ones = num % 10;
968  if (ones) {
969  snprintf(fn, sizeof(fn), "digits/%d-and", ones);
970  num -= ones;
971  } else {
972  snprintf(fn, sizeof(fn), "digits/%d", num);
973  num = 0;
974  }
975  } else {
976  if (num < 1000) {
977  int hundreds = num / 100;
978  if (hundreds == 1)
979  ast_copy_string(fn, "digits/1N", sizeof(fn));
980  else
981  snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
982 
983  playh++;
984  num -= 100 * hundreds;
985  if (num)
986  playa++;
987 
988  } else {
989  if (num < 1000000) {
990  res = ast_say_number_full_da(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
991  if (res)
992  return res;
993  num = num % 1000;
994  ast_copy_string(fn, "digits/thousand", sizeof(fn));
995  } else {
996  if (num < 1000000000) {
997  int millions = num / 1000000;
998  res = ast_say_number_full_da(chan, millions, ints, language, "c", audiofd, ctrlfd);
999  if (res)
1000  return res;
1001  if (millions == 1)
1002  ast_copy_string(fn, "digits/million", sizeof(fn));
1003  else
1004  ast_copy_string(fn, "digits/millions", sizeof(fn));
1005  num = num % 1000000;
1006  } else {
1007  ast_debug(1, "Number '%d' is too big for me\n", num);
1008  res = -1;
1009  }
1010  }
1011  if (num && num < 100)
1012  playa++;
1013  }
1014  }
1015  if (!res) {
1016  if (!ast_streamfile(chan, fn, language)) {
1017  if ((audiofd > -1) && (ctrlfd > -1))
1018  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1019  else
1020  res = ast_waitstream(chan, ints);
1021  }
1022  ast_stopstream(chan);
1023  }
1024  }
1025  return res;
1026 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
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:
Definition: say.c:924
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_de()

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 
)
static

ast_say_number_full_de: German syntax

New files: In addition to English, the following sounds are required:

  • "millions"
  • "1-and" through "9-and"
  • "1F" (eine)
  • "1N" (ein)
  • NB "1" is recorded as 'eins'

Definition at line 1038 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), and say_number_full().

1039 {
1040  int res = 0, t = 0;
1041  int mf = 1; /* +1 = male and neuter; -1 = female */
1042  char fn[256] = "";
1043  char fna[256] = "";
1044  if (!num)
1045  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1046 
1047  if (options && (!strncasecmp(options, "f", 1)))
1048  mf = -1;
1049 
1050  while (!res && num) {
1051  /* The grammar for German numbers is the same as for English except
1052  * for the following:
1053  * - numbers 20 through 99 are said in reverse order, i.e. 21 is
1054  * "one-and twenty" and 68 is "eight-and sixty".
1055  * - "one" varies according to gender
1056  * - 100 is 'hundert', however all other instances are 'ein hundert'
1057  * - 1000 is 'tausend', however all other instances are 'ein tausend'
1058  * - 1000000 is always 'eine million'
1059  * - "million" is different in singular and plural form
1060  * - 'and' should not go between a hundreds place value and any
1061  * tens/ones place values that follows it. i.e 136 is ein hundert
1062  * sechs und dreizig, not ein hundert und sechs und dreizig.
1063  */
1064  if (num < 0) {
1065  ast_copy_string(fn, "digits/minus", sizeof(fn));
1066  if ( num > INT_MIN ) {
1067  num = -num;
1068  } else {
1069  num = 0;
1070  }
1071  } else if (num == 1 && mf == -1) {
1072  snprintf(fn, sizeof(fn), "digits/%dF", num);
1073  num = 0;
1074  } else if (num < 20) {
1075  snprintf(fn, sizeof(fn), "digits/%d", num);
1076  num = 0;
1077  } else if (num < 100) {
1078  int ones = num % 10;
1079  if (ones) {
1080  snprintf(fn, sizeof(fn), "digits/%d-and", ones);
1081  num -= ones;
1082  } else {
1083  snprintf(fn, sizeof(fn), "digits/%d", num);
1084  num = 0;
1085  }
1086  } else if (num == 100 && t == 0) {
1087  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1088  num = 0;
1089  } else if (num < 1000) {
1090  int hundreds = num / 100;
1091  num = num % 100;
1092  if (hundreds == 1) {
1093  ast_copy_string(fn, "digits/1N", sizeof(fn));
1094  } else {
1095  snprintf(fn, sizeof(fn), "digits/%d", hundreds);
1096  }
1097  ast_copy_string(fna, "digits/hundred", sizeof(fna));
1098  } else if (num == 1000 && t == 0) {
1099  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1100  num = 0;
1101  } else if (num < 1000000) {
1102  int thousands = num / 1000;
1103  num = num % 1000;
1104  t = 1;
1105  if (thousands == 1) {
1106  ast_copy_string(fn, "digits/1N", sizeof(fn));
1107  ast_copy_string(fna, "digits/thousand", sizeof(fna));
1108  } else {
1109  res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
1110  if (res)
1111  return res;
1112  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1113  }
1114  } else if (num < 1000000000) {
1115  int millions = num / 1000000;
1116  num = num % 1000000;
1117  t = 1;
1118  if (millions == 1) {
1119  ast_copy_string(fn, "digits/1F", sizeof(fn));
1120  ast_copy_string(fna, "digits/million", sizeof(fna));
1121  } else {
1122  res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
1123  if (res)
1124  return res;
1125  ast_copy_string(fn, "digits/millions", sizeof(fn));
1126  }
1127  } else if (num <= INT_MAX) {
1128  int billions = num / 1000000000;
1129  num = num % 1000000000;
1130  t = 1;
1131  if (billions == 1) {
1132  ast_copy_string(fn, "digits/1F", sizeof(fn));
1133  ast_copy_string(fna, "digits/milliard", sizeof(fna));
1134  } else {
1135  res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
1136  if (res) {
1137  return res;
1138  }
1139  ast_copy_string(fn, "digits/milliards", sizeof(fn));
1140  }
1141  } else {
1142  ast_debug(1, "Number '%d' is too big for me\n", num);
1143  res = -1;
1144  }
1145  if (!res) {
1146  if (!ast_streamfile(chan, fn, language)) {
1147  if ((audiofd > -1) && (ctrlfd > -1))
1148  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1149  else
1150  res = ast_waitstream(chan, ints);
1151  }
1152  ast_stopstream(chan);
1153  if (!res) {
1154  if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
1155  if ((audiofd > -1) && (ctrlfd > -1))
1156  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1157  else
1158  res = ast_waitstream(chan, ints);
1159  }
1160  ast_stopstream(chan);
1161  strcpy(fna, "");
1162  }
1163  }
1164  }
1165  return res;
1166 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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
Definition: say.c:1038
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_en()

static int ast_say_number_full_en ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_en: English syntax

Note
This is the default syntax, if no other syntax defined in this file is used

Definition at line 772 of file say.c.

References ast_free, ast_get_number_str(), ast_stopstream(), ast_str_buffer(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), and strsep().

Referenced by ast_get_number_str(), ast_say_enumeration_full_en(), ast_say_number_full_ja(), and say_number_full().

773 {
774  const char *fn;
775  int res = 0;
776 
777  struct ast_str *filenames = ast_get_number_str(num, language);
778  char *files = ast_str_buffer(filenames);
779 
780  while ((fn = strsep(&files, "&"))) {
781  res = ast_streamfile(chan, fn, language);
782  if (!res) {
783  if ((audiofd > -1) && (ctrlfd > -1))
784  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
785  else
786  res = ast_waitstream(chan, ints);
787  }
788  ast_stopstream(chan);
789  }
790 
791  ast_free(filenames);
792 
793  return res;
794 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_str * ast_get_number_str(int num, const char *lang)
ast_get_number_str: call language-specific functions
Definition: say.c:525
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
char * strsep(char **str, const char *delims)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_en_GB()

static int ast_say_number_full_en_GB ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_en_GB: British syntax New files:

  • In addition to American English, the following sounds are required: "vm-and"

Definition at line 1172 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

1173 {
1174  int res = 0;
1175  int playh = 0;
1176  int playa = 0;
1177  char fn[256] = "";
1178  if (!num)
1179  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1180 
1181  while (!res && (num || playh || playa )) {
1182  if (num < 0) {
1183  ast_copy_string(fn, "digits/minus", sizeof(fn));
1184  if ( num > INT_MIN ) {
1185  num = -num;
1186  } else {
1187  num = 0;
1188  }
1189  } else if (playh) {
1190  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1191  playh = 0;
1192  } else if (playa) {
1193  ast_copy_string(fn, "vm-and", sizeof(fn));
1194  playa = 0;
1195  } else if (num < 20) {
1196  snprintf(fn, sizeof(fn), "digits/%d", num);
1197  num = 0;
1198  } else if (num < 100) {
1199  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
1200  num %= 10;
1201  } else if (num < 1000) {
1202  int hundreds = num / 100;
1203  snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
1204 
1205  playh++;
1206  num -= 100 * hundreds;
1207  if (num)
1208  playa++;
1209  } else if (num < 1000000) {
1210  res = ast_say_number_full_en_GB(chan, num / 1000, ints, language, audiofd, ctrlfd);
1211  if (res)
1212  return res;
1213  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1214  num %= 1000;
1215  if (num && num < 100)
1216  playa++;
1217  } else if (num < 1000000000) {
1218  int millions = num / 1000000;
1219  res = ast_say_number_full_en_GB(chan, millions, ints, language, audiofd, ctrlfd);
1220  if (res)
1221  return res;
1222  ast_copy_string(fn, "digits/million", sizeof(fn));
1223  num %= 1000000;
1224  if (num && num < 100)
1225  playa++;
1226  } else {
1227  ast_debug(1, "Number '%d' is too big for me\n", num);
1228  res = -1;
1229  }
1230 
1231  if (!res) {
1232  if (!ast_streamfile(chan, fn, language)) {
1233  if ((audiofd > -1) && (ctrlfd > -1))
1234  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1235  else
1236  res = ast_waitstream(chan, ints);
1237  }
1238  ast_stopstream(chan);
1239  }
1240  }
1241  return res;
1242 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
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:
Definition: say.c:1172
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_es()

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 
)
static

ast_say_number_full_es: Spanish syntax

New files: Requires a few new audios: 1F.gsm: feminine 'una' 21.gsm thru 29.gsm, cien.gsm, mil.gsm, millon.gsm, millones.gsm, 100.gsm, 200.gsm, 300.gsm, 400.gsm, 500.gsm, 600.gsm, 700.gsm, 800.gsm, 900.gsm, y.gsm

Definition at line 1251 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

1252 {
1253  int res = 0;
1254  int playa = 0;
1255  int mf = 0; /* +1 = male; -1 = female */
1256  char fn[256] = "";
1257  if (!num)
1258  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1259 
1260  if (options) {
1261  if (!strncasecmp(options, "f", 1))
1262  mf = -1;
1263  else if (!strncasecmp(options, "m", 1))
1264  mf = 1;
1265  }
1266 
1267  while (!res && num) {
1268  if (num < 0) {
1269  ast_copy_string(fn, "digits/minus", sizeof(fn));
1270  if ( num > INT_MIN ) {
1271  num = -num;
1272  } else {
1273  num = 0;
1274  }
1275  } else if (playa) {
1276  ast_copy_string(fn, "digits/and", sizeof(fn));
1277  playa = 0;
1278  } else if (num == 1) {
1279  if (mf < 0)
1280  snprintf(fn, sizeof(fn), "digits/%dF", num);
1281  else if (mf > 0)
1282  snprintf(fn, sizeof(fn), "digits/%dM", num);
1283  else
1284  snprintf(fn, sizeof(fn), "digits/%d", num);
1285  num = 0;
1286  } else if (num < 31) {
1287  snprintf(fn, sizeof(fn), "digits/%d", num);
1288  num = 0;
1289  } else if (num < 100) {
1290  snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
1291  num %= 10;
1292  if (num)
1293  playa++;
1294  } else if (num == 100) {
1295  ast_copy_string(fn, "digits/100", sizeof(fn));
1296  num = 0;
1297  } else if (num < 200) {
1298  ast_copy_string(fn, "digits/100-and", sizeof(fn));
1299  num -= 100;
1300  } else {
1301  if (num < 1000) {
1302  snprintf(fn, sizeof(fn), "digits/%d", (num/100)*100);
1303  num %= 100;
1304  } else if (num < 2000) {
1305  num %= 1000;
1306  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1307  } else {
1308  if (num < 1000000) {
1309  res = ast_say_number_full_es(chan, num / 1000, ints, language, options, audiofd, ctrlfd);
1310  if (res)
1311  return res;
1312  num %= 1000;
1313  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1314  } else {
1315  if (num < 2147483640) {
1316  if ((num/1000000) == 1) {
1317  res = ast_say_number_full_es(chan, num / 1000000, ints, language, "M", audiofd, ctrlfd);
1318  if (res)
1319  return res;
1320  ast_copy_string(fn, "digits/million", sizeof(fn));
1321  } else {
1322  res = ast_say_number_full_es(chan, num / 1000000, ints, language, options, audiofd, ctrlfd);
1323  if (res)
1324  return res;
1325  ast_copy_string(fn, "digits/millions", sizeof(fn));
1326  }
1327  num %= 1000000;
1328  } else {
1329  ast_debug(1, "Number '%d' is too big for me\n", num);
1330  res = -1;
1331  }
1332  }
1333  }
1334  }
1335 
1336  if (!res) {
1337  if (!ast_streamfile(chan, fn, language)) {
1338  if ((audiofd > -1) && (ctrlfd > -1))
1339  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1340  else
1341  res = ast_waitstream(chan, ints);
1342  }
1343  ast_stopstream(chan);
1344 
1345  }
1346 
1347  }
1348  return res;
1349 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
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
Definition: say.c:1251
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_fr()

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 
)
static

ast_say_number_full_fr: French syntax Extra sounds needed: 1F: feminin 'une' et: 'and'

Definition at line 1355 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

1356 {
1357  int res = 0;
1358  int playh = 0;
1359  int playa = 0;
1360  int mf = 1; /* +1 = male; -1 = female */
1361  char fn[256] = "";
1362  if (!num)
1363  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1364 
1365  if (options && !strncasecmp(options, "f", 1))
1366  mf = -1;
1367 
1368  while (!res && (num || playh || playa)) {
1369  if (num < 0) {
1370  ast_copy_string(fn, "digits/minus", sizeof(fn));
1371  if ( num > INT_MIN ) {
1372  num = -num;
1373  } else {
1374  num = 0;
1375  }
1376  } else if (playh) {
1377  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1378  playh = 0;
1379  } else if (playa) {
1380  ast_copy_string(fn, "digits/et", sizeof(fn));
1381  playa = 0;
1382  } else if (num == 1) {
1383  if (mf < 0)
1384  snprintf(fn, sizeof(fn), "digits/%dF", num);
1385  else
1386  snprintf(fn, sizeof(fn), "digits/%d", num);
1387  num = 0;
1388  } else if (num < 21) {
1389  snprintf(fn, sizeof(fn), "digits/%d", num);
1390  num = 0;
1391  } else if (num < 70) {
1392  snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
1393  if ((num % 10) == 1) playa++;
1394  num = num % 10;
1395  } else if (num < 80) {
1396  ast_copy_string(fn, "digits/60", sizeof(fn));
1397  if ((num % 10) == 1) playa++;
1398  num -= 60;
1399  } else if (num < 100) {
1400  ast_copy_string(fn, "digits/80", sizeof(fn));
1401  num = num - 80;
1402  } else if (num < 200) {
1403  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1404  num = num - 100;
1405  } else if (num < 1000) {
1406  snprintf(fn, sizeof(fn), "digits/%d", (num/100));
1407  playh++;
1408  num = num % 100;
1409  } else if (num < 2000) {
1410  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1411  num = num - 1000;
1412  } else if (num < 1000000) {
1413  res = ast_say_number_full_fr(chan, num / 1000, ints, language, options, audiofd, ctrlfd);
1414  if (res)
1415  return res;
1416  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1417  num = num % 1000;
1418  } else if (num < 1000000000) {
1419  res = ast_say_number_full_fr(chan, num / 1000000, ints, language, options, audiofd, ctrlfd);
1420  if (res)
1421  return res;
1422  ast_copy_string(fn, "digits/million", sizeof(fn));
1423  num = num % 1000000;
1424  } else {
1425  ast_debug(1, "Number '%d' is too big for me\n", num);
1426  res = -1;
1427  }
1428  if (!res) {
1429  if (!ast_streamfile(chan, fn, language)) {
1430  if ((audiofd > -1) && (ctrlfd > -1))
1431  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1432  else
1433  res = ast_waitstream(chan, ints);
1434  }
1435  ast_stopstream(chan);
1436  }
1437  }
1438  return res;
1439 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
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 &#39;une&#39; et: &#39;and&#39; ...
Definition: say.c:1355
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_gr()

static int ast_say_number_full_gr ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

Greek support A list of the files that you need to create -> digits/xilia = "xilia" -> digits/myrio = "ekatomyrio" -> digits/thousands = "xiliades" -> digits/millions = "ektatomyria" -> digits/[1..12] :: A pronunciation of th digits form 1 to 12 e.g. "tria" -> digits/[10..100] :: A pronunciation of the tens from 10 to 90 e.g. 80 = "ogdonta" Here we must note that we use digits/tens/100 to utter "ekato" and digits/hundred-100 to utter "ekaton" -> digits/hundred-[100...1000] :: A pronunciation of hundreds from 100 to 1000 e.g 400 = "terakosia". Here again we use hundreds/1000 for "xilia" and digits/thousnds for "xiliades".

Definition at line 8036 of file say.c.

References ast_channel_language(), ast_copy_string(), ast_debug, ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), ast_say_date_with_format_gr(), and say_number_full().

8037 {
8038  int res = 0;
8039  char fn[256] = "";
8040  int i=0;
8041 
8042 
8043  if (!num) {
8044  ast_copy_string(fn, "digits/0", sizeof(fn));
8045  res = ast_streamfile(chan, fn, ast_channel_language(chan));
8046  if (!res)
8047  return ast_waitstream(chan, ints);
8048  }
8049 
8050  while (!res && num ) {
8051  i++;
8052  if (num < 13) {
8053  snprintf(fn, sizeof(fn), "digits/%d", num);
8054  num = 0;
8055  } else if (num <= 100) {
8056  /* 13 < num <= 100 */
8057  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
8058  num %= 10;
8059  } else if (num < 200) {
8060  /* 100 < num < 200 */
8061  snprintf(fn, sizeof(fn), "digits/hundred-100");
8062  num %= 100;
8063  } else if (num < 1000) {
8064  /* 200 < num < 1000 */
8065  snprintf(fn, sizeof(fn), "digits/hundred-%d", (num/100)*100);
8066  num %= 100;
8067  } else if (num < 2000){
8068  snprintf(fn, sizeof(fn), "digits/xilia");
8069  num %= 1000;
8070  } else {
8071  /* num > 1000 */
8072  if (num < 1000000) {
8073  res = ast_say_number_full_gr(chan, (num / 1000), ints, ast_channel_language(chan), audiofd, ctrlfd);
8074  if (res)
8075  return res;
8076  num %= 1000;
8077  snprintf(fn, sizeof(fn), "digits/thousands");
8078  } else {
8079  if (num < 1000000000) { /* 1,000,000,000 */
8080  res = ast_say_number_full_gr(chan, (num / 1000000), ints, ast_channel_language(chan), audiofd, ctrlfd);
8081  if (res)
8082  return res;
8083  num %= 1000000;
8084  snprintf(fn, sizeof(fn), "digits/millions");
8085  } else {
8086  ast_debug(1, "Number '%d' is too big for me\n", num);
8087  res = -1;
8088  }
8089  }
8090  }
8091  if (!res) {
8092  if (!ast_streamfile(chan, fn, language)) {
8093  if ((audiofd > -1) && (ctrlfd > -1))
8094  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
8095  else
8096  res = ast_waitstream(chan, ints);
8097  }
8098  ast_stopstream(chan);
8099  }
8100  }
8101  return res;
8102 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
Greek support A list of the files that you need to create -> digits/xilia = "xilia" -> digits/myrio =...
Definition: say.c:8036
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
const char * ast_channel_language(const struct ast_channel *chan)
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_he()

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

Definition at line 1447 of file say.c.

References ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_verb, ast_waitstream(), ast_waitstream_full(), and SAY_NUM_BUF_SIZE.

Referenced by ast_get_number_str(), ast_say_date_with_format_he(), ast_say_enumeration_full_he(), ast_say_time_he(), and say_number_full().

1448 {
1449  int res = 0;
1450  int state = 0; /* no need to save anything */
1451  int mf = -1; /* +1 = Masculin; -1 = Feminin */
1452  int tmpnum = 0;
1453 
1454  char fn[SAY_NUM_BUF_SIZE] = "";
1455 
1456  ast_verb(3, "ast_say_digits_full: started. num: %d, options=\"%s\"\n", num, options);
1457 
1458  if (!num) {
1459  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1460  }
1461  if (options && !strncasecmp(options, "m", 1)) {
1462  mf = 1;
1463  }
1464  ast_verb(3, "ast_say_digits_full: num: %d, state=%d, options=\"%s\", mf=%d\n", num, state, options, mf);
1465 
1466  /* Do we have work to do? */
1467  while (!res && (num || (state > 0))) {
1468  /* first type of work: play a second sound. In this loop
1469  * we can only play one sound file at a time. Thus playing
1470  * a second one requires repeating the loop just for the
1471  * second file. The variable 'state' remembers where we were.
1472  * state==0 is the normal mode and it means that we continue
1473  * to check if the number num has yet anything left.
1474  */
1475  ast_verb(3, "ast_say_digits_full: num: %d, state=%d, options=\"%s\", mf=%d, tmpnum=%d\n", num, state, options, mf, tmpnum);
1476 
1477  if (state == 1) {
1478  state = 0;
1479  } else if (state == 2) {
1480  if ((num >= 11) && (num < 21)) {
1481  if (mf < 0) {
1482  snprintf(fn, sizeof(fn), "digits/ve");
1483  } else {
1484  snprintf(fn, sizeof(fn), "digits/uu");
1485  }
1486  } else {
1487  switch (num) {
1488  case 1:
1489  snprintf(fn, sizeof(fn), "digits/ve");
1490  break;
1491  case 2:
1492  snprintf(fn, sizeof(fn), "digits/uu");
1493  break;
1494  case 3:
1495  if (mf < 0) {
1496  snprintf(fn, sizeof(fn), "digits/ve");
1497  } else {
1498  snprintf(fn, sizeof(fn), "digits/uu");
1499  }
1500  break;
1501  case 4:
1502  snprintf(fn, sizeof(fn), "digits/ve");
1503  break;
1504  case 5:
1505  snprintf(fn, sizeof(fn), "digits/ve");
1506  break;
1507  case 6:
1508  snprintf(fn, sizeof(fn), "digits/ve");
1509  break;
1510  case 7:
1511  snprintf(fn, sizeof(fn), "digits/ve");
1512  break;
1513  case 8:
1514  snprintf(fn, sizeof(fn), "digits/uu");
1515  break;
1516  case 9:
1517  snprintf(fn, sizeof(fn), "digits/ve");
1518  break;
1519  case 10:
1520  snprintf(fn, sizeof(fn), "digits/ve");
1521  break;
1522  }
1523  }
1524  state = 0;
1525  } else if (state == 3) {
1526  snprintf(fn, sizeof(fn), "digits/1k");
1527  state = 0;
1528  } else if (num < 0) {
1529  snprintf(fn, sizeof(fn), "digits/minus");
1530  num = (-1) * num;
1531  } else if (num < 20) {
1532  if (mf < 0) {
1533  snprintf(fn, sizeof(fn), "digits/%d", num);
1534  } else {
1535  snprintf(fn, sizeof(fn), "digits/%dm", num);
1536  }
1537  num = 0;
1538  } else if ((num < 100) && (num >= 20)) {
1539  snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
1540  num = num % 10;
1541  if (num > 0) {
1542  state = 2;
1543  }
1544  } else if ((num >= 100) && (num < 1000)) {
1545  tmpnum = num / 100;
1546  snprintf(fn, sizeof(fn), "digits/%d00", tmpnum);
1547  num = num - (tmpnum * 100);
1548  if ((num > 0) && (num < 11)) {
1549  state = 2;
1550  }
1551  } else if ((num >= 1000) && (num < 10000)) {
1552  tmpnum = num / 1000;
1553  snprintf(fn, sizeof(fn), "digits/%dk", tmpnum);
1554  num = num - (tmpnum * 1000);
1555  if ((num > 0) && (num < 11)) {
1556  state = 2;
1557  }
1558  } else if (num < 20000) {
1559  snprintf(fn, sizeof(fn), "digits/%dm", (num / 1000));
1560  num = num % 1000;
1561  state = 3;
1562  } else if (num < 1000000) {
1563  res = ast_say_number_full_he(chan, num / 1000, ints, language, "m", audiofd, ctrlfd);
1564  if (res) {
1565  return res;
1566  }
1567  snprintf(fn, sizeof(fn), "digits/1k");
1568  num = num % 1000;
1569  if ((num > 0) && (num < 11)) {
1570  state = 2;
1571  }
1572  } else if (num < 2000000) {
1573  snprintf(fn, sizeof(fn), "digits/million");
1574  num = num % 1000000;
1575  if ((num > 0) && (num < 11)) {
1576  state = 2;
1577  }
1578  } else if (num < 3000000) {
1579  snprintf(fn, sizeof(fn), "digits/twomillion");
1580  num = num - 2000000;
1581  if ((num > 0) && (num < 11)) {
1582  state = 2;
1583  }
1584  } else if (num < 1000000000) {
1585  res = ast_say_number_full_he(chan, num / 1000000, ints, language, "m", audiofd, ctrlfd);
1586  if (res) {
1587  return res;
1588  }
1589  snprintf(fn, sizeof(fn), "digits/million");
1590  num = num % 1000000;
1591  if ((num > 0) && (num < 11)) {
1592  state = 2;
1593  }
1594  } else {
1595  ast_debug(1, "Number '%d' is too big for me\n", num);
1596  res = -1;
1597  }
1598  tmpnum = 0;
1599  if (!res) {
1600  if (!ast_streamfile(chan, fn, language)) {
1601  if ((audiofd > -1) && (ctrlfd > -1)) {
1602  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1603  } else {
1604  res = ast_waitstream(chan, ints);
1605  }
1606  }
1607  ast_stopstream(chan);
1608  }
1609  }
1610  return res;
1611 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define SAY_NUM_BUF_SIZE
Definition: say.c:1446
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
static int ast_say_number_full_he(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
Definition: say.c:1447
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_hu()

static int ast_say_number_full_hu ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_hu: Hungarian syntax

Extra sounds needed: 10en: "tizen" 20on: "huszon"

Definition at line 1619 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

1620 {
1621  int res = 0;
1622  int playh = 0;
1623  char fn[256] = "";
1624  if (!num)
1625  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1626 
1627  /*
1628  Hungarian support
1629  like english, except numbers up to 29 are from 2 words.
1630  10 and first word of 1[1-9] and 20 and first word of 2[1-9] are different.
1631  */
1632 
1633  while(!res && (num || playh)) {
1634  if (num < 0) {
1635  ast_copy_string(fn, "digits/minus", sizeof(fn));
1636  if ( num > INT_MIN ) {
1637  num = -num;
1638  } else {
1639  num = 0;
1640  }
1641  } else if (playh) {
1642  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1643  playh = 0;
1644  } else if (num < 11 || num == 20) {
1645  snprintf(fn, sizeof(fn), "digits/%d", num);
1646  num = 0;
1647  } else if (num < 20) {
1648  ast_copy_string(fn, "digits/10en", sizeof(fn));
1649  num -= 10;
1650  } else if (num < 30) {
1651  ast_copy_string(fn, "digits/20on", sizeof(fn));
1652  num -= 20;
1653  } else if (num < 100) {
1654  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
1655  num %= 10;
1656  } else {
1657  if (num < 1000){
1658  snprintf(fn, sizeof(fn), "digits/%d", (num/100));
1659  playh++;
1660  num %= 100;
1661  } else {
1662  if (num < 1000000) { /* 1,000,000 */
1663  res = ast_say_number_full_hu(chan, num / 1000, ints, language, audiofd, ctrlfd);
1664  if (res)
1665  return res;
1666  num %= 1000;
1667  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1668  } else {
1669  if (num < 1000000000) { /* 1,000,000,000 */
1670  res = ast_say_number_full_hu(chan, num / 1000000, ints, language, audiofd, ctrlfd);
1671  if (res)
1672  return res;
1673  num %= 1000000;
1674  ast_copy_string(fn, "digits/million", sizeof(fn));
1675  } else {
1676  ast_debug(1, "Number '%d' is too big for me\n", num);
1677  res = -1;
1678  }
1679  }
1680  }
1681  }
1682  if (!res) {
1683  if(!ast_streamfile(chan, fn, language)) {
1684  if ((audiofd > -1) && (ctrlfd > -1))
1685  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1686  else
1687  res = ast_waitstream(chan, ints);
1688  }
1689  ast_stopstream(chan);
1690  }
1691  }
1692  return res;
1693 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
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
Definition: say.c:1619
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_is()

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 
)
static

ast_say_number_full_is: Icelandic syntax

Definition at line 1699 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), ast_say_enumeration_full_is(), and say_number_full().

1700 {
1701  int res = 0;
1702  int playh = 0;
1703  int playa = 0;
1704  int cn = 1; /* 1 = masc; 2 = fem; 3 = neut */
1705  char fn[256] = "";
1706 
1707  if (!num)
1708  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1709 
1710  if (options && !strncasecmp(options, "f", 1)) cn = 2;
1711  if (options && !strncasecmp(options, "c", 1)) cn = 3;
1712  /* It seems that sometimes people are using c and sometimes n. */
1713  if (options && !strncasecmp(options, "n", 1)) cn = 3;
1714 
1715  while (!res && (num || playh || playa )) {
1716  if (num < 0) {
1717  ast_copy_string(fn, "digits/minus", sizeof(fn));
1718  if ( num > INT_MIN ) {
1719  num = -num;
1720  } else {
1721  num = 0;
1722  }
1723  } else if (playh) {
1724  if (playh > 1)
1725  ast_copy_string(fn, "digits/hundreds", sizeof(fn));
1726  else
1727  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1728  playh = 0;
1729  } else if (playa) {
1730  ast_copy_string(fn, "digits/and", sizeof(fn));
1731  playa = 0;
1732  } else if (num < 5 && cn == 2) {
1733  snprintf(fn, sizeof(fn), "digits/%dkvk", num);
1734  num = 0;
1735  } else if (num < 5 && cn == 3) {
1736  snprintf(fn, sizeof(fn), "digits/%dhk", num);
1737  num = 0;
1738  } else if (num < 20) {
1739  snprintf(fn, sizeof(fn), "digits/%d", num);
1740  num = 0;
1741  } else if (num < 100) {
1742  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
1743  num %= 10;
1744  if (num)
1745  playa++;
1746  } else if (num < 1000) {
1747  int hundreds = num / 100;
1748  /* The number prepending hundreds are in neutral */
1749  if (hundreds < 5)
1750  snprintf(fn, sizeof(fn), "digits/%dhk", hundreds);
1751  else
1752  snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
1753 
1754  playh = hundreds;
1755  num -= 100 * hundreds;
1756  if (num && num < 20)
1757  playa++;
1758  /* The 'and' moves forward on even tens. */
1759  if (num && (num % 10) == 0)
1760  playa++;
1761  } else if (num < 1000000) {
1762  res = ast_say_number_full_is(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
1763  /* Play 'and' if it's an even hundred. */
1764  if ((num % 100) == 0 && (num % 1000 != 0)) {
1765  playa++;
1766  }
1767  if (res)
1768  return res;
1769  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1770  num %= 1000;
1771  if (num && (num < 20 || (num % 10 == 0)))
1772  playa++;
1773  } else if (num < 1000000000) {
1774  int millions = num / 1000000;
1775  /* The number of millions is feminine */
1776  res = ast_say_number_full_is(chan, millions, ints, language, "f", audiofd, ctrlfd);
1777  if (res)
1778  return res;
1779  if (millions > 1)
1780  ast_copy_string(fn, "digits/millions", sizeof(fn));
1781  else
1782  ast_copy_string(fn, "digits/million", sizeof(fn));
1783  num %= 1000000;
1784  if (num && num < 100)
1785  playa++;
1786  } else if (num < INT_MAX) {
1787  int milliards = num / 1000000000;
1788  /* The number of milliards is masculine */
1789  res = ast_say_number_full_is(chan, milliards, ints, language, "m", audiofd, ctrlfd);
1790  if (res)
1791  return res;
1792  if (milliards > 1)
1793  ast_copy_string(fn, "digits/milliards", sizeof(fn));
1794  else
1795  ast_copy_string(fn, "digits/milliard", sizeof(fn));
1796  num %= 1000000000;
1797  if (num && num < 100)
1798  playa++;
1799  } else {
1800  ast_debug(1, "Number '%d' is too big for me\n", num);
1801  res = -1;
1802  }
1803 
1804  if (!res) {
1805  if (!ast_streamfile(chan, fn, language)) {
1806  if ((audiofd > -1) && (ctrlfd > -1))
1807  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1808  else
1809  res = ast_waitstream(chan, ints);
1810  }
1811  ast_stopstream(chan);
1812  }
1813  }
1814  return res;
1815 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
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
Definition: say.c:1699
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_it()

static int ast_say_number_full_it ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_it: Italian

Definition at line 1819 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

1820 {
1821  int res = 0;
1822  int playh = 0;
1823  int tempnum = 0;
1824  char fn[256] = "";
1825 
1826  if (!num)
1827  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1828 
1829  /*
1830  Italian support
1831 
1832  Like english, numbers up to 20 are a single 'word', and others
1833  compound, but with exceptions.
1834  For example 21 is not twenty-one, but there is a single word in 'it'.
1835  Idem for 28 (ie when a the 2nd part of a compund number
1836  starts with a vowel)
1837 
1838  There are exceptions also for hundred, thousand and million.
1839  In english 100 = one hundred, 200 is two hundred.
1840  In italian 100 = cento , like to say hundred (without one),
1841  200 and more are like english.
1842 
1843  Same applies for thousand:
1844  1000 is one thousand in en, 2000 is two thousand.
1845  In it we have 1000 = mille , 2000 = 2 mila
1846 
1847  For million(s) we use the plural, if more than one
1848  Also, one million is abbreviated in it, like on-million,
1849  or 'un milione', not 'uno milione'.
1850  So the right file is provided.
1851  */
1852 
1853  while (!res && (num || playh)) {
1854  if (num < 0) {
1855  ast_copy_string(fn, "digits/minus", sizeof(fn));
1856  if ( num > INT_MIN ) {
1857  num = -num;
1858  } else {
1859  num = 0;
1860  }
1861  } else if (playh) {
1862  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1863  playh = 0;
1864  } else if (num < 20) {
1865  snprintf(fn, sizeof(fn), "digits/%d", num);
1866  num = 0;
1867  } else if (num == 21) {
1868  snprintf(fn, sizeof(fn), "digits/%d", num);
1869  num = 0;
1870  } else if (num == 28) {
1871  snprintf(fn, sizeof(fn), "digits/%d", num);
1872  num = 0;
1873  } else if (num == 31) {
1874  snprintf(fn, sizeof(fn), "digits/%d", num);
1875  num = 0;
1876  } else if (num == 38) {
1877  snprintf(fn, sizeof(fn), "digits/%d", num);
1878  num = 0;
1879  } else if (num == 41) {
1880  snprintf(fn, sizeof(fn), "digits/%d", num);
1881  num = 0;
1882  } else if (num == 48) {
1883  snprintf(fn, sizeof(fn), "digits/%d", num);
1884  num = 0;
1885  } else if (num == 51) {
1886  snprintf(fn, sizeof(fn), "digits/%d", num);
1887  num = 0;
1888  } else if (num == 58) {
1889  snprintf(fn, sizeof(fn), "digits/%d", num);
1890  num = 0;
1891  } else if (num == 61) {
1892  snprintf(fn, sizeof(fn), "digits/%d", num);
1893  num = 0;
1894  } else if (num == 68) {
1895  snprintf(fn, sizeof(fn), "digits/%d", num);
1896  num = 0;
1897  } else if (num == 71) {
1898  snprintf(fn, sizeof(fn), "digits/%d", num);
1899  num = 0;
1900  } else if (num == 78) {
1901  snprintf(fn, sizeof(fn), "digits/%d", num);
1902  num = 0;
1903  } else if (num == 81) {
1904  snprintf(fn, sizeof(fn), "digits/%d", num);
1905  num = 0;
1906  } else if (num == 88) {
1907  snprintf(fn, sizeof(fn), "digits/%d", num);
1908  num = 0;
1909  } else if (num == 91) {
1910  snprintf(fn, sizeof(fn), "digits/%d", num);
1911  num = 0;
1912  } else if (num == 98) {
1913  snprintf(fn, sizeof(fn), "digits/%d", num);
1914  num = 0;
1915  } else if (num < 100) {
1916  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
1917  num %= 10;
1918  } else {
1919  if (num < 1000) {
1920  if ((num / 100) > 1) {
1921  snprintf(fn, sizeof(fn), "digits/%d", (num/100));
1922  playh++;
1923  } else {
1924  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1925  }
1926  num %= 100;
1927  } else {
1928  if (num < 1000000) { /* 1,000,000 */
1929  if ((num/1000) > 1)
1930  res = ast_say_number_full_it(chan, num / 1000, ints, language, audiofd, ctrlfd);
1931  if (res)
1932  return res;
1933  tempnum = num;
1934  num %= 1000;
1935  if ((tempnum / 1000) < 2)
1936  ast_copy_string(fn, "digits/thousand", sizeof(fn));
1937  else /* for 1000 it says mille, for >1000 (eg 2000) says mila */
1938  ast_copy_string(fn, "digits/thousands", sizeof(fn));
1939  } else {
1940  if (num < 1000000000) { /* 1,000,000,000 */
1941  if ((num / 1000000) > 1)
1942  res = ast_say_number_full_it(chan, num / 1000000, ints, language, audiofd, ctrlfd);
1943  if (res)
1944  return res;
1945  tempnum = num;
1946  num %= 1000000;
1947  if ((tempnum / 1000000) < 2)
1948  ast_copy_string(fn, "digits/million", sizeof(fn));
1949  else
1950  ast_copy_string(fn, "digits/millions", sizeof(fn));
1951  } else {
1952  ast_debug(1, "Number '%d' is too big for me\n", num);
1953  res = -1;
1954  }
1955  }
1956  }
1957  }
1958  if (!res) {
1959  if (!ast_streamfile(chan, fn, language)) {
1960  if ((audiofd > -1) && (ctrlfd > -1))
1961  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
1962  else
1963  res = ast_waitstream(chan, ints);
1964  }
1965  ast_stopstream(chan);
1966  }
1967  }
1968  return res;
1969 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
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
Definition: say.c:1819
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_ja()

static int ast_say_number_full_ja ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

Definition at line 8105 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_say_number_full_en(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

8106 {
8107  int res = 0;
8108  int playh = 0;
8109  char fn[256] = "";
8110 
8111  if (!num)
8112  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
8113 
8114  while (!res && (num || playh)) {
8115  if (num < 0) {
8116  ast_copy_string(fn, "digits/minus", sizeof(fn));
8117  if ( num > INT_MIN ) {
8118  num = -num;
8119  } else {
8120  num = 0;
8121  }
8122  } else if (playh) {
8123  ast_copy_string(fn, "digits/hundred", sizeof(fn));
8124  playh = 0;
8125  } else if (num < 20) {
8126  snprintf(fn, sizeof(fn), "digits/%d", num);
8127  num = 0;
8128  } else if (num < 100) {
8129  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
8130  num %= 10;
8131  } else {
8132  if (num < 1000){
8133  snprintf(fn, sizeof(fn), "digits/%d", (num/100));
8134  playh++;
8135  num %= 100;
8136  } else {
8137  if (num < 1000000) { /* 1,000,000 */
8138  res = ast_say_number_full_en(chan, num / 1000, ints, language, audiofd, ctrlfd);
8139  if (res)
8140  return res;
8141  num %= 1000;
8142  snprintf(fn, sizeof(fn), "digits/thousand");
8143  } else {
8144  if (num < 1000000000) { /* 1,000,000,000 */
8145  res = ast_say_number_full_en(chan, num / 1000000, ints, language, audiofd, ctrlfd);
8146  if (res)
8147  return res;
8148  num %= 1000000;
8149  ast_copy_string(fn, "digits/million", sizeof(fn));
8150  } else {
8151  ast_debug(1, "Number '%d' is too big for me\n", num);
8152  res = -1;
8153  }
8154  }
8155  }
8156  }
8157  if (!res) {
8158  if (!ast_streamfile(chan, fn, language)) {
8159  if ((audiofd > -1) && (ctrlfd > -1))
8160  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
8161  else
8162  res = ast_waitstream(chan, ints);
8163  }
8164  ast_stopstream(chan);
8165  }
8166  }
8167  return res;
8168 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
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
Definition: say.c:772
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_ka()

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 
)
static

ast_say_number_full_ka: Georgian syntax

Definition at line 9270 of file say.c.

References ast_free, ast_malloc, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_translate_number_ka(), ast_waitstream(), ast_waitstream_full(), and len().

Referenced by ast_get_number_str(), and say_number_full().

9271 {
9272  int res = 0;
9273  char fn[512] = "";
9274  char* s = 0;
9275  const char* remaining = fn;
9276 
9277  if (!num) {
9278  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
9279  }
9280 
9281 
9282  ast_translate_number_ka(num, fn, 512);
9283 
9284 
9285 
9286  while (res == 0 && (s = strstr(remaining, " "))) {
9287  size_t len = s - remaining;
9288  char* new_string = ast_malloc(len + 1 + strlen("digits/"));
9289 
9290  sprintf(new_string, "digits/");
9291  strncat(new_string, remaining, len); /* we can't sprintf() it, it's not null-terminated. */
9292 /* new_string[len + strlen("digits/")] = '\0'; */
9293 
9294  if (!ast_streamfile(chan, new_string, language)) {
9295  if ((audiofd > -1) && (ctrlfd > -1)) {
9296  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
9297  } else {
9298  res = ast_waitstream(chan, ints);
9299  }
9300  }
9301  ast_stopstream(chan);
9302 
9303  ast_free(new_string);
9304 
9305  remaining = s + 1; /* position just after the found space char. */
9306  while (*remaining == ' ') { /* skip multiple spaces */
9307  remaining++;
9308  }
9309  }
9310 
9311 
9312  /* the last chunk. */
9313  if (res == 0 && *remaining) {
9314 
9315  char* new_string = ast_malloc(strlen(remaining) + 1 + strlen("digits/"));
9316  sprintf(new_string, "digits/%s", remaining);
9317 
9318  if (!ast_streamfile(chan, new_string, language)) {
9319  if ((audiofd > -1) && (ctrlfd > -1)) {
9320  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
9321  } else {
9322  res = ast_waitstream(chan, ints);
9323  }
9324  }
9325  ast_stopstream(chan);
9326 
9327  ast_free(new_string);
9328 
9329  }
9330 
9331 
9332  return res;
9333 
9334 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static char * ast_translate_number_ka(int num, char *res, int res_len)
Georgian support.
Definition: say.c:9131
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_nl()

static int ast_say_number_full_nl ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_nl: dutch syntax New files: digits/nl-en

Definition at line 1974 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

1975 {
1976  int res = 0;
1977  int playh = 0;
1978  int units = 0;
1979  char fn[256] = "";
1980  if (!num)
1981  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
1982  while (!res && (num || playh )) {
1983  if (num < 0) {
1984  ast_copy_string(fn, "digits/minus", sizeof(fn));
1985  if ( num > INT_MIN ) {
1986  num = -num;
1987  } else {
1988  num = 0;
1989  }
1990  } else if (playh) {
1991  ast_copy_string(fn, "digits/hundred", sizeof(fn));
1992  playh = 0;
1993  } else if (num < 20) {
1994  snprintf(fn, sizeof(fn), "digits/%d", num);
1995  num = 0;
1996  } else if (num < 100) {
1997  units = num % 10;
1998  if (units > 0) {
1999  res = ast_say_number_full_nl(chan, units, ints, language, audiofd, ctrlfd);
2000  if (res)
2001  return res;
2002  num = num - units;
2003  ast_copy_string(fn, "digits/nl-en", sizeof(fn));
2004  } else {
2005  snprintf(fn, sizeof(fn), "digits/%d", num - units);
2006  num = 0;
2007  }
2008  } else if (num < 200) {
2009  /* hundred, not one-hundred */
2010  ast_copy_string(fn, "digits/hundred", sizeof(fn));
2011  num %= 100;
2012  } else if (num < 1000) {
2013  snprintf(fn, sizeof(fn), "digits/%d", num / 100);
2014  playh++;
2015  num %= 100;
2016  } else {
2017  if (num < 1100) {
2018  /* thousand, not one-thousand */
2019  num %= 1000;
2020  ast_copy_string(fn, "digits/thousand", sizeof(fn));
2021  } else if (num < 10000) { /* 1,100 to 9,9999 */
2022  res = ast_say_number_full_nl(chan, num / 100, ints, language, audiofd, ctrlfd);
2023  if (res)
2024  return res;
2025  num %= 100;
2026  ast_copy_string(fn, "digits/hundred", sizeof(fn));
2027  } else {
2028  if (num < 1000000) { /* 1,000,000 */
2029  res = ast_say_number_full_nl(chan, num / 1000, ints, language, audiofd, ctrlfd);
2030  if (res)
2031  return res;
2032  num %= 1000;
2033  ast_copy_string(fn, "digits/thousand", sizeof(fn));
2034  } else {
2035  if (num < 1000000000) { /* 1,000,000,000 */
2036  res = ast_say_number_full_nl(chan, num / 1000000, ints, language, audiofd, ctrlfd);
2037  if (res)
2038  return res;
2039  num %= 1000000;
2040  ast_copy_string(fn, "digits/million", sizeof(fn));
2041  } else {
2042  ast_debug(1, "Number '%d' is too big for me\n", num);
2043  res = -1;
2044  }
2045  }
2046  }
2047  }
2048 
2049  if (!res) {
2050  if (!ast_streamfile(chan, fn, language)) {
2051  if ((audiofd > -1) && (ctrlfd > -1))
2052  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
2053  else
2054  res = ast_waitstream(chan, ints);
2055  }
2056  ast_stopstream(chan);
2057  }
2058  }
2059  return res;
2060 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
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
Definition: say.c:1974
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_no()

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 
)
static

ast_say_number_full_no: Norwegian syntax New files: In addition to American English, the following sounds are required: "and", "1N"

The grammar for Norwegian numbers is the same as for English except for the following:

  • 1 exists in both commune ("en", file "1") and neuter ("ett", file "1N") "and" before the last two digits, i.e. 2034 is "two thousand and thirty-four" and 1000012 is "one million and twelve".

Definition at line 2072 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

2073 {
2074  int res = 0;
2075  int playh = 0;
2076  int playa = 0;
2077  int cn = 1; /* +1 = commune; -1 = neuter */
2078  char fn[256] = "";
2079 
2080  if (!num)
2081  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
2082 
2083  if (options && !strncasecmp(options, "n", 1)) cn = -1;
2084 
2085  while (!res && (num || playh || playa )) {
2086  if (num < 0) {
2087  ast_copy_string(fn, "digits/minus", sizeof(fn));
2088  if ( num > INT_MIN ) {
2089  num = -num;
2090  } else {
2091  num = 0;
2092  }
2093  } else if (playh) {
2094  ast_copy_string(fn, "digits/hundred", sizeof(fn));
2095  playh = 0;
2096  } else if (playa) {
2097  ast_copy_string(fn, "digits/and", sizeof(fn));
2098  playa = 0;
2099  } else if (num == 1 && cn == -1) {
2100  ast_copy_string(fn, "digits/1N", sizeof(fn));
2101  num = 0;
2102  } else if (num < 20) {
2103  snprintf(fn, sizeof(fn), "digits/%d", num);
2104  num = 0;
2105  } else if (num < 100) {
2106  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
2107  num %= 10;
2108  } else if (num < 1000) {
2109  int hundreds = num / 100;
2110  if (hundreds == 1)
2111  ast_copy_string(fn, "digits/1N", sizeof(fn));
2112  else
2113  snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
2114 
2115  playh++;
2116  num -= 100 * hundreds;
2117  if (num)
2118  playa++;
2119  } else if (num < 1000000) {
2120  res = ast_say_number_full_no(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
2121  if (res)
2122  return res;
2123  ast_copy_string(fn, "digits/thousand", sizeof(fn));
2124  num %= 1000;
2125  if (num && num < 100)
2126  playa++;
2127  } else if (num < 1000000000) {
2128  int millions = num / 1000000;
2129  res = ast_say_number_full_no(chan, millions, ints, language, "c", audiofd, ctrlfd);
2130  if (res)
2131  return res;
2132  ast_copy_string(fn, "digits/million", sizeof(fn));
2133  num %= 1000000;
2134  if (num && num < 100)
2135  playa++;
2136  } else {
2137  ast_debug(1, "Number '%d' is too big for me\n", num);
2138  res = -1;
2139  }
2140 
2141  if (!res) {
2142  if (!ast_streamfile(chan, fn, language)) {
2143  if ((audiofd > -1) && (ctrlfd > -1))
2144  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
2145  else
2146  res = ast_waitstream(chan, ints);
2147  }
2148  ast_stopstream(chan);
2149  }
2150  }
2151  return res;
2152 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
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"
Definition: say.c:2072
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_pl()

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

Definition at line 2359 of file say.c.

References ast_malloc, odmiana::cyfry, odmiana::cyfry2, odmiana::dziesiatki, odmiana::nastki, NULL, powiedz(), odmiana::rzedy, odmiana::separator_dziesiatek, and odmiana::setki.

Referenced by ast_get_number_str(), and say_number_full().

2360 {
2361  char *zenski_cyfry[] = {"0", "1z", "2z", "3", "4", "5", "6", "7", "8", "9"};
2362 
2363  char *zenski_cyfry2[] = {"0", "1", "2z", "3", "4", "5", "6", "7", "8", "9"};
2364 
2365  char *meski_cyfry[] = {"0", "1", "2-1m", "3-1m", "4-1m", "5m", /*"2-1mdwaj"*/ "6m", "7m", "8m", "9m"};
2366 
2367  char *meski_cyfry2[] = {"0", "1", "2-2m", "3-2m", "4-2m", "5m", "6m", "7m", "8m", "9m"};
2368 
2369  char *meski_setki[] = {"", "100m", "200m", "300m", "400m", "500m", "600m", "700m", "800m", "900m"};
2370 
2371  char *meski_dziesiatki[] = {"", "10m", "20m", "30m", "40m", "50m", "60m", "70m", "80m", "90m"};
2372 
2373  char *meski_nastki[] = {"", "11m", "12m", "13m", "14m", "15m", "16m", "17m", "18m", "19m"};
2374 
2375  char *nijaki_cyfry[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
2376 
2377  char *nijaki_cyfry2[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
2378 
2379  char *nijaki_setki[] = {"", "100", "200", "300", "400", "500", "600", "700", "800", "900"};
2380 
2381  char *nijaki_dziesiatki[] = {"", "10", "20", "30", "40", "50", "60", "70", "80", "90"};
2382 
2383  char *nijaki_nastki[] = {"", "11", "12", "13", "14", "15", "16", "17", "18", "19"};
2384 
2385  char *rzedy[][3] = { {"1000", "1000.2", "1000.5"}, {"1000000", "1000000.2", "1000000.5"}, {"1000000000", "1000000000.2", "1000000000.5"}};
2386 
2387  /* Initialise variables to allow compilation on Debian-stable, etc */
2388  odmiana *o;
2389 
2390  static odmiana *odmiana_nieosobowa = NULL;
2391  static odmiana *odmiana_meska = NULL;
2392  static odmiana *odmiana_zenska = NULL;
2393 
2394  if (odmiana_nieosobowa == NULL) {
2395  odmiana_nieosobowa = ast_malloc(sizeof(*odmiana_nieosobowa));
2396 
2397  odmiana_nieosobowa->separator_dziesiatek = " ";
2398 
2399  memcpy(odmiana_nieosobowa->cyfry, nijaki_cyfry, sizeof(odmiana_nieosobowa->cyfry));
2400  memcpy(odmiana_nieosobowa->cyfry2, nijaki_cyfry2, sizeof(odmiana_nieosobowa->cyfry));
2401  memcpy(odmiana_nieosobowa->setki, nijaki_setki, sizeof(odmiana_nieosobowa->setki));
2402  memcpy(odmiana_nieosobowa->dziesiatki, nijaki_dziesiatki, sizeof(odmiana_nieosobowa->dziesiatki));
2403  memcpy(odmiana_nieosobowa->nastki, nijaki_nastki, sizeof(odmiana_nieosobowa->nastki));
2404  memcpy(odmiana_nieosobowa->rzedy, rzedy, sizeof(odmiana_nieosobowa->rzedy));
2405  }
2406 
2407  if (odmiana_zenska == NULL) {
2408  odmiana_zenska = ast_malloc(sizeof(*odmiana_zenska));
2409 
2410  odmiana_zenska->separator_dziesiatek = " ";
2411 
2412  memcpy(odmiana_zenska->cyfry, zenski_cyfry, sizeof(odmiana_zenska->cyfry));
2413  memcpy(odmiana_zenska->cyfry2, zenski_cyfry2, sizeof(odmiana_zenska->cyfry));
2414  memcpy(odmiana_zenska->setki, nijaki_setki, sizeof(odmiana_zenska->setki));
2415  memcpy(odmiana_zenska->dziesiatki, nijaki_dziesiatki, sizeof(odmiana_zenska->dziesiatki));
2416  memcpy(odmiana_zenska->nastki, nijaki_nastki, sizeof(odmiana_zenska->nastki));
2417  memcpy(odmiana_zenska->rzedy, rzedy, sizeof(odmiana_zenska->rzedy));
2418  }
2419 
2420  if (odmiana_meska == NULL) {
2421  odmiana_meska = ast_malloc(sizeof(*odmiana_meska));
2422 
2423  odmiana_meska->separator_dziesiatek = " ";
2424 
2425  memcpy(odmiana_meska->cyfry, meski_cyfry, sizeof(odmiana_meska->cyfry));
2426  memcpy(odmiana_meska->cyfry2, meski_cyfry2, sizeof(odmiana_meska->cyfry));
2427  memcpy(odmiana_meska->setki, meski_setki, sizeof(odmiana_meska->setki));
2428  memcpy(odmiana_meska->dziesiatki, meski_dziesiatki, sizeof(odmiana_meska->dziesiatki));
2429  memcpy(odmiana_meska->nastki, meski_nastki, sizeof(odmiana_meska->nastki));
2430  memcpy(odmiana_meska->rzedy, rzedy, sizeof(odmiana_meska->rzedy));
2431  }
2432 
2433  if (options) {
2434  if (strncasecmp(options, "f", 1) == 0)
2435  o = odmiana_zenska;
2436  else if (strncasecmp(options, "m", 1) == 0)
2437  o = odmiana_meska;
2438  else
2439  o = odmiana_nieosobowa;
2440  } else
2441  o = odmiana_nieosobowa;
2442 
2443  powiedz(chan, language, audiofd, ctrlfd, ints, o, 0, num);
2444  return 0;
2445 }
char * setki[10]
Definition: say.c:2158
char * nastki[10]
Definition: say.c:2160
char * cyfry2[10]
Definition: say.c:2157
#define NULL
Definition: resample.c:96
char * cyfry[10]
Definition: say.c:2156
char * rzedy[3][3]
Definition: say.c:2161
char * separator_dziesiatek
Definition: say.c:2155
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
static void powiedz(struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, odmiana *odm, int rzad, int i)
Definition: say.c:2198
Definition: say.c:2154
char * dziesiatki[10]
Definition: say.c:2159
static struct test_options options

◆ ast_say_number_full_pt()

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

Definition at line 2455 of file say.c.

References ast_copy_string(), ast_log, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), LOG_WARNING, and wait_file().

Referenced by ast_get_number_str(), and say_number_full().

2456 {
2457  int res = 0;
2458  int playh = 0;
2459  int mf = 1; /* +1 = male; -1 = female */
2460  char fn[256] = "";
2461 
2462  if (!num)
2463  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
2464 
2465  if (options && !strncasecmp(options, "f", 1))
2466  mf = -1;
2467 
2468  while (!res && num ) {
2469  if (num < 0) {
2470  ast_copy_string(fn, "digits/minus", sizeof(fn));
2471  if ( num > INT_MIN ) {
2472  num = -num;
2473  } else {
2474  num = 0;
2475  }
2476  } else if (num < 20) {
2477  if ((num == 1 || num == 2) && (mf < 0))
2478  snprintf(fn, sizeof(fn), "digits/%dF", num);
2479  else
2480  snprintf(fn, sizeof(fn), "digits/%d", num);
2481  num = 0;
2482  } else if (num < 100) {
2483  snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
2484  if (num % 10)
2485  playh = 1;
2486  num = num % 10;
2487  } else if (num < 1000) {
2488  if (num == 100)
2489  ast_copy_string(fn, "digits/100", sizeof(fn));
2490  else if (num < 200)
2491  ast_copy_string(fn, "digits/100E", sizeof(fn));
2492  else {
2493  if (mf < 0 && num > 199)
2494  snprintf(fn, sizeof(fn), "digits/%dF", (num / 100) * 100);
2495  else
2496  snprintf(fn, sizeof(fn), "digits/%d", (num / 100) * 100);
2497  if (num % 100)
2498  playh = 1;
2499  }
2500  num = num % 100;
2501  } else if (num < 1000000) {
2502  if (num > 1999) {
2503  res = ast_say_number_full_pt(chan, (num / 1000) * mf, ints, language, options, audiofd, ctrlfd);
2504  if (res)
2505  return res;
2506  }
2507  ast_copy_string(fn, "digits/1000", sizeof(fn));
2508  if ((num % 1000) && ((num % 1000) < 100 || !(num % 100)))
2509  playh = 1;
2510  num = num % 1000;
2511  } else if (num < 1000000000) {
2512  res = ast_say_number_full_pt(chan, (num / 1000000), ints, language, options, audiofd, ctrlfd );
2513  if (res)
2514  return res;
2515  if (num < 2000000)
2516  ast_copy_string(fn, "digits/1000000", sizeof(fn));
2517  else
2518  ast_copy_string(fn, "digits/1000000S", sizeof(fn));
2519 
2520  if ((num % 1000000) &&
2521  /* no thousands */
2522  ((!((num / 1000) % 1000) && ((num % 1000) < 100 || !(num % 100))) ||
2523  /* no hundreds and below */
2524  (!(num % 1000) && (((num / 1000) % 1000) < 100 || !((num / 1000) % 100))) ) )
2525  playh = 1;
2526  num = num % 1000000;
2527  } else {
2528  /* number is too big */
2529  ast_log(LOG_WARNING, "Number '%d' is too big to say.", num);
2530  res = -1;
2531  }
2532  if (!res) {
2533  if (!ast_streamfile(chan, fn, language)) {
2534  if ((audiofd > -1) && (ctrlfd > -1))
2535  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
2536  else
2537  res = ast_waitstream(chan, ints);
2538  }
2539  ast_stopstream(chan);
2540  }
2541  if (!res && playh) {
2542  res = wait_file(chan, ints, "digits/pt-e", language);
2543  ast_stopstream(chan);
2544  playh = 0;
2545  }
2546  }
2547  return res;
2548 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define LOG_WARNING
Definition: logger.h:274
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_log
Definition: astobj2.c:42
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)
Definition: say.c:2455
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_ru()

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 
)
static

ast_say_number_full_ru: Russian syntax

additional files: n00.gsm (one hundred, two hundred, ...) thousand.gsm million.gsm thousands-i.gsm (tisyachi) million-a.gsm (milliona) thousands.gsm millions.gsm 1f.gsm (odna) 2f.gsm (dve)

where 'n' from 1 to 9

Definition at line 2834 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), get_lastdigits_ru(), and NULL.

Referenced by ast_get_number_str(), and say_number_full().

2835 {
2836  int res = 0;
2837  int lastdigits = 0;
2838  char fn[256] = "";
2839  if (!num)
2840  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
2841 
2842  while (!res && (num)) {
2843  if (num < 0) {
2844  ast_copy_string(fn, "digits/minus", sizeof(fn));
2845  if ( num > INT_MIN ) {
2846  num = -num;
2847  } else {
2848  num = 0;
2849  }
2850  } else if (num < 20) {
2851  if (options && strlen(options) == 1 && num < 3) {
2852  snprintf(fn, sizeof(fn), "digits/%d%s", num, options);
2853  } else {
2854  snprintf(fn, sizeof(fn), "digits/%d", num);
2855  }
2856  num = 0;
2857  } else if (num < 100) {
2858  snprintf(fn, sizeof(fn), "digits/%d", num - (num % 10));
2859  num %= 10;
2860  } else if (num < 1000){
2861  snprintf(fn, sizeof(fn), "digits/%d", num - (num % 100));
2862  num %= 100;
2863  } else if (num < 1000000) { /* 1,000,000 */
2864  lastdigits = get_lastdigits_ru(num / 1000);
2865  /* say thousands */
2866  if (lastdigits < 3) {
2867  res = ast_say_number_full_ru(chan, num / 1000, ints, language, "f", audiofd, ctrlfd);
2868  } else {
2869  res = ast_say_number_full_ru(chan, num / 1000, ints, language, NULL, audiofd, ctrlfd);
2870  }
2871  if (res)
2872  return res;
2873  if (lastdigits == 1) {
2874  ast_copy_string(fn, "digits/thousand", sizeof(fn));
2875  } else if (lastdigits > 1 && lastdigits < 5) {
2876  ast_copy_string(fn, "digits/thousands-i", sizeof(fn));
2877  } else {
2878  ast_copy_string(fn, "digits/thousands", sizeof(fn));
2879  }
2880  num %= 1000;
2881  } else if (num < 1000000000) { /* 1,000,000,000 */
2882  lastdigits = get_lastdigits_ru(num / 1000000);
2883  /* say millions */
2884  res = ast_say_number_full_ru(chan, num / 1000000, ints, language, NULL, audiofd, ctrlfd);
2885  if (res)
2886  return res;
2887  if (lastdigits == 1) {
2888  ast_copy_string(fn, "digits/million", sizeof(fn));
2889  } else if (lastdigits > 1 && lastdigits < 5) {
2890  ast_copy_string(fn, "digits/million-a", sizeof(fn));
2891  } else {
2892  ast_copy_string(fn, "digits/millions", sizeof(fn));
2893  }
2894  num %= 1000000;
2895  } else {
2896  ast_debug(1, "Number '%d' is too big for me\n", num);
2897  res = -1;
2898  }
2899  if (!res) {
2900  if (!ast_streamfile(chan, fn, language)) {
2901  if ((audiofd > -1) && (ctrlfd > -1))
2902  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
2903  else
2904  res = ast_waitstream(chan, ints);
2905  }
2906  ast_stopstream(chan);
2907  }
2908  }
2909  return res;
2910 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
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
Definition: say.c:2834
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
static int get_lastdigits_ru(int num)
determine last digits for thousands/millions (ru)
Definition: say.c:2807
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_se()

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 
)
static

ast_say_number_full_se: Swedish syntax

Sound files needed

  • 1N

Definition at line 2555 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

2556 {
2557  int playh = 0;
2558  int start = 1;
2559  char fn[256] = "";
2560  int cn = 1; /* +1 = commune; -1 = neuter */
2561  int res = 0;
2562 
2563  if (!num) {
2564  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
2565  }
2566  if (options && !strncasecmp(options, "n", 1)) cn = -1;
2567 
2568  while (num || playh) {
2569  if (num < 0) {
2570  ast_copy_string(fn, "digits/minus", sizeof(fn));
2571  if ( num > INT_MIN ) {
2572  num = -num;
2573  } else {
2574  num = 0;
2575  }
2576  } else if (playh) {
2577  ast_copy_string(fn, "digits/hundred", sizeof(fn));
2578  playh = 0;
2579  } else if (start && num < 200 && num > 99 && cn == -1) {
2580  /* Don't say "en hundra" just say "hundra". */
2581  snprintf(fn, sizeof(fn), "digits/hundred");
2582  num -= 100;
2583  } else if (num == 1 && cn == -1) { /* En eller ett? */
2584  ast_copy_string(fn, "digits/1N", sizeof(fn));
2585  num = 0;
2586  } else if (num < 20) {
2587  snprintf(fn, sizeof(fn), "digits/%d", num);
2588  num = 0;
2589  } else if (num < 100) { /* Below hundreds - teens and tens */
2590  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
2591  num %= 10;
2592  } else if (num < 1000) {
2593  /* Hundreds */
2594  snprintf(fn, sizeof(fn), "digits/%d", (num/100));
2595  playh++;
2596  num %= 100;
2597  } else if (num < 1000000) { /* 1,000,000 */
2598  /* Always say "ett hundra tusen", not "en hundra tusen" */
2599  res = ast_say_number_full_se(chan, num / 1000, ints, language, "c", audiofd, ctrlfd);
2600  if (res) {
2601  return res;
2602  }
2603  num %= 1000;
2604  ast_copy_string(fn, "digits/thousand", sizeof(fn));
2605  } else if (num < 1000000000) { /* 1,000,000,000 */
2606  /* Always say "en miljon", not "ett miljon" */
2607  res = ast_say_number_full_se(chan, num / 1000000, ints, language, "n", audiofd, ctrlfd);
2608  if (res) {
2609  return res;
2610  }
2611  num %= 1000000;
2612  ast_copy_string(fn, "digits/million", sizeof(fn));
2613  } else { /* Miljarder - Billions */
2614  ast_debug(1, "Number '%d' is too big for me\n", num);
2615  return -1;
2616  }
2617 
2618  if (!ast_streamfile(chan, fn, language)) {
2619  if ((audiofd > -1) && (ctrlfd > -1)) {
2620  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
2621  } else {
2622  res = ast_waitstream(chan, ints);
2623  }
2624  ast_stopstream(chan);
2625  if (res) {
2626  return res;
2627  }
2628  }
2629  start = 0;
2630  }
2631  return 0;
2632 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
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
Definition: say.c:2555
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_th()

static int ast_say_number_full_th ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

Thai syntax.

Definition at line 2913 of file say.c.

References ast_copy_string(), ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

2914 {
2915  int res = 0;
2916  int playh = 0;
2917  char fn[256] = "";
2918  if (!num)
2919  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
2920 
2921  while(!res && (num || playh)) {
2922  if (num < 0) {
2923  ast_copy_string(fn, "digits/lop", sizeof(fn));
2924  if ( num > INT_MIN ) {
2925  num = -num;
2926  } else {
2927  num = 0;
2928  }
2929  } else if (playh) {
2930  ast_copy_string(fn, "digits/roi", sizeof(fn));
2931  playh = 0;
2932  } else if (num < 100) {
2933  if ((num <= 20) || ((num % 10) == 1)) {
2934  snprintf(fn, sizeof(fn), "digits/%d", num);
2935  num = 0;
2936  } else {
2937  snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
2938  num %= 10;
2939  }
2940  } else if (num < 1000) {
2941  snprintf(fn, sizeof(fn), "digits/%d", (num/100));
2942  playh++;
2943  num %= 100;
2944  } else if (num < 10000) { /* 10,000 */
2945  res = ast_say_number_full_th(chan, num / 1000, ints, language, audiofd, ctrlfd);
2946  if (res)
2947  return res;
2948  num %= 1000;
2949  ast_copy_string(fn, "digits/pan", sizeof(fn));
2950  } else if (num < 100000) { /* 100,000 */
2951  res = ast_say_number_full_th(chan, num / 10000, ints, language, audiofd, ctrlfd);
2952  if (res)
2953  return res;
2954  num %= 10000;
2955  ast_copy_string(fn, "digits/muan", sizeof(fn));
2956  } else if (num < 1000000) { /* 1,000,000 */
2957  res = ast_say_number_full_th(chan, num / 100000, ints, language, audiofd, ctrlfd);
2958  if (res)
2959  return res;
2960  num %= 100000;
2961  ast_copy_string(fn, "digits/san", sizeof(fn));
2962  } else {
2963  res = ast_say_number_full_th(chan, num / 1000000, ints, language, audiofd, ctrlfd);
2964  if (res)
2965  return res;
2966  num %= 1000000;
2967  ast_copy_string(fn, "digits/larn", sizeof(fn));
2968  }
2969  if (!res) {
2970  if(!ast_streamfile(chan, fn, language)) {
2971  if ((audiofd > -1) && (ctrlfd > -1))
2972  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
2973  else
2974  res = ast_waitstream(chan, ints);
2975  }
2976  ast_stopstream(chan);
2977  }
2978  }
2979  return res;
2980 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
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.
Definition: say.c:2913
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_ur()

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

Definition at line 2748 of file say.c.

References ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), and say_number_full().

2749 {
2750  int res = 0;
2751  int playh = 0;
2752  char fn[256] = "";
2753 
2754  if (!num) {
2755  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
2756  }
2757 
2758  while (!res && (num || playh)) {
2759  if (playh) {
2760  snprintf(fn, sizeof(fn), "digits/hundred");
2761  playh = 0;
2762  } else if (num < 100) {
2763  snprintf(fn, sizeof(fn), "digits/%d", num);
2764  num = 0;
2765  } else if (num < 1000) {
2766  snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
2767  playh++;
2768  num -= ((num / 100) * 100);
2769  } else if (num < 100000) { /* 1,00,000 */
2770  if ((res = ast_say_number_full_ur(chan, num / 1000, ints, language, options, audiofd, ctrlfd))) {
2771  return res;
2772  }
2773  num = num % 1000;
2774  snprintf(fn, sizeof(fn), "digits/thousand");
2775  } else if (num < 10000000) { /* 1,00,00,000 */
2776  if ((res = ast_say_number_full_ur(chan, num / 100000, ints, language, options, audiofd, ctrlfd))) {
2777  return res;
2778  }
2779  num = num % 100000;
2780  snprintf(fn, sizeof(fn), "digits/lac");
2781  } else if (num < 1000000000) { /* 1,00,00,00,000 */
2782  if ((res = ast_say_number_full_ur(chan, num / 10000000, ints, language, options, audiofd, ctrlfd))) {
2783  return res;
2784  }
2785  num = num % 10000000;
2786  snprintf(fn, sizeof(fn), "digits/crore");
2787  } else {
2788  ast_debug(1, "Number '%d' is too big for me\n", num);
2789  res = -1;
2790  }
2791 
2792  if (!res) {
2793  if (!ast_streamfile(chan, fn, language)) {
2794  if ((audiofd > -1) && (ctrlfd > -1)) {
2795  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
2796  } else {
2797  res = ast_waitstream(chan, ints);
2798  }
2799  }
2800  ast_stopstream(chan);
2801  }
2802  }
2803  return res;
2804 }
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)
Definition: say.c:2748
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static struct test_options options
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_vi()

static int ast_say_number_full_vi ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_vi: Vietnamese syntax

Definition at line 2983 of file say.c.

References ast_copy_string(), ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by ast_get_number_str(), ast_say_enumeration_full_vi(), and say_number_full().

2984 {
2985  int res = 0;
2986  int playh = 0;
2987  int playoh = 0;
2988  int playohz = 0;
2989  int playz = 0;
2990  int playl = 0;
2991  char fn[256] = "";
2992  if (!num)
2993  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
2994  while (!res && (num || playh)) {
2995  if (num < 0) {
2996  ast_copy_string(fn, "digits/minus", sizeof(fn));
2997  if ( num > INT_MIN ) {
2998  num = -num;
2999  } else {
3000  num = 0;
3001  }
3002  } else if (playl) {
3003  snprintf(fn, sizeof(fn), "digits/%da", num);
3004  playl = 0;
3005  num = 0;
3006  } else if (playh) {
3007  ast_copy_string(fn, "digits/hundred", sizeof(fn));
3008  playh = 0;
3009  } else if (playz) {
3010  ast_copy_string(fn, "digits/odd", sizeof(fn));
3011  playz = 0;
3012  } else if (playoh) {
3013  ast_copy_string(fn, "digits/0-hundred", sizeof(fn));
3014  playoh = 0;
3015  } else if (playohz) {
3016  ast_copy_string(fn, "digits/0-hundred-odd", sizeof(fn));
3017  playohz = 0;
3018  } else if (num < 20) {
3019  snprintf(fn, sizeof(fn), "digits/%d", num);
3020  num = 0;
3021  } else if (num < 100) {
3022  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
3023  num %= 10;
3024  if ((num == 5) || (num == 4) || (num == 1)) playl++;
3025  } else {
3026  if (num < 1000) {
3027  snprintf(fn, sizeof(fn), "digits/%d", (num/100));
3028  num %= 100;
3029  if (num && (num < 10)) {
3030  playz++;
3031  playh++;
3032  } else {
3033  playh++;
3034  }
3035  } else {
3036  if (num < 1000000) { /* 1,000,000 */
3037  res = ast_say_number_full_vi(chan, num / 1000, ints, language, audiofd, ctrlfd);
3038  if (res)
3039  return res;
3040  num %= 1000;
3041  snprintf(fn, sizeof(fn), "digits/thousand");
3042  if (num && (num < 10)) {
3043  playohz++;
3044  } else if (num && (num < 100)){
3045  playoh++;
3046  } else {
3047  playh = 0;
3048  playohz = 0;
3049  playoh = 0;
3050  }
3051  } else {
3052  if (num < 1000000000) { /* 1,000,000,000 */
3053  res = ast_say_number_full_vi(chan, num / 1000000, ints, language, audiofd, ctrlfd);
3054  if (res)
3055  return res;
3056  num %= 1000000;
3057  ast_copy_string(fn, "digits/million", sizeof(fn));
3058  } else {
3059  res = -1;
3060  }
3061  }
3062  }
3063  }
3064  if (!res) {
3065  if (!ast_streamfile(chan, fn, language)) {
3066  if ((audiofd > -1) && (ctrlfd > -1))
3067  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
3068  else
3069  res = ast_waitstream(chan, ints);
3070  }
3071  ast_stopstream(chan);
3072  }
3073  }
3074  return res;
3075 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
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
Definition: say.c:2983
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_number_full_zh()

static int ast_say_number_full_zh ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full_zh: Taiwanese / Chinese syntax

Definition at line 2635 of file say.c.

References ast_copy_string(), ast_debug, ast_say_digits_full(), ast_stopstream(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), and buf.

Referenced by ast_get_number_str(), and say_number_full().

2636 {
2637  int res = 0;
2638  int playh = 0;
2639  int playt = 0;
2640  int playz = 0;
2641  int last_length = 0;
2642  char buf[20] = "";
2643  char fn[256] = "";
2644  if (!num)
2645  return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
2646 
2647  while (!res && (num || playh || playt || playz)) {
2648  if (num < 0) {
2649  ast_copy_string(fn, "digits/minus", sizeof(fn));
2650  if ( num > INT_MIN ) {
2651  num = -num;
2652  } else {
2653  num = 0;
2654  }
2655  } else if (playz) {
2656  snprintf(fn, sizeof(fn), "digits/0");
2657  last_length = 0;
2658  playz = 0;
2659  } else if (playh) {
2660  ast_copy_string(fn, "digits/hundred", sizeof(fn));
2661  playh = 0;
2662  } else if (playt) {
2663  snprintf(fn, sizeof(fn), "digits/thousand");
2664  playt = 0;
2665  } else if (num < 10) {
2666  snprintf(buf, 12, "%d", num);
2667  if (last_length - strlen(buf) > 1 && last_length != 0) {
2668  last_length = strlen(buf);
2669  playz++;
2670  continue;
2671  }
2672  snprintf(fn, sizeof(fn), "digits/%d", num);
2673  num = 0;
2674  } else if (num < 100) {
2675  snprintf(buf, 10, "%d", num);
2676  if (last_length - strlen(buf) > 1 && last_length != 0) {
2677  last_length = strlen(buf);
2678  playz++;
2679  continue;
2680  }
2681  last_length = strlen(buf);
2682  snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
2683  num %= 10;
2684  } else {
2685  if (num < 1000){
2686  snprintf(buf, 10, "%d", num);
2687  if (last_length - strlen(buf) > 1 && last_length != 0) {
2688  last_length = strlen(buf);
2689  playz++;
2690  continue;
2691  }
2692  snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
2693  playh++;
2694  snprintf(buf, 10, "%d", num);
2695  ast_debug(1, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
2696  last_length = strlen(buf);
2697  num -= ((num / 100) * 100);
2698  } else if (num < 10000){
2699  snprintf(buf, 10, "%d", num);
2700  snprintf(fn, sizeof(fn), "digits/%d", (num / 1000));
2701  playt++;
2702  snprintf(buf, 10, "%d", num);
2703  ast_debug(1, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
2704  last_length = strlen(buf);
2705  num -= ((num / 1000) * 1000);
2706  } else if (num < 100000000) { /* 100,000,000 */
2707  res = ast_say_number_full_zh(chan, num / 10000, ints, language, audiofd, ctrlfd);
2708  if (res)
2709  return res;
2710  snprintf(buf, 10, "%d", num);
2711  ast_debug(1, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
2712  num -= ((num / 10000) * 10000);
2713  last_length = strlen(buf);
2714  snprintf(fn, sizeof(fn), "digits/wan");
2715  } else {
2716  if (num < 1000000000) { /* 1,000,000,000 */
2717  res = ast_say_number_full_zh(chan, num / 100000000, ints, language, audiofd, ctrlfd);
2718  if (res)
2719  return res;
2720  snprintf(buf, 10, "%d", num);
2721  ast_debug(1, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
2722  last_length = strlen(buf);
2723  num -= ((num / 100000000) * 100000000);
2724  snprintf(fn, sizeof(fn), "digits/yi");
2725  } else {
2726  ast_debug(1, "Number '%d' is too big for me\n", num);
2727  res = -1;
2728  }
2729  }
2730  }
2731  if (!res) {
2732  if (!ast_streamfile(chan, fn, language)) {
2733  if ((audiofd > -1) && (ctrlfd > -1))
2734  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
2735  else
2736  res = ast_waitstream(chan, ints);
2737  }
2738  ast_stopstream(chan);
2739  }
2740  }
2741  return res;
2742 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable...
Definition: channel.c:8379
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
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
Definition: say.c:2635
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_say_time_de()

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

German syntax.

Definition at line 7125 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_get_number_str(), and say_time().

7126 {
7127  struct timeval when = { t, 0 };
7128  struct ast_tm tm;
7129  int res = 0;
7130 
7131  ast_localtime(&when, &tm, NULL);
7132  if (!res)
7133  res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
7134  if (!res)
7135  res = ast_streamfile(chan, "digits/oclock", lang);
7136  if (!res)
7137  res = ast_waitstream(chan, ints);
7138  if (!res)
7139  if (tm.tm_min > 0)
7140  res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
7141  return res;
7142 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_time_en()

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

English syntax.

Definition at line 7076 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_get_number_str(), and say_time().

7077 {
7078  struct timeval when = { t, 0 };
7079  struct ast_tm tm;
7080  int res = 0;
7081  int hour, pm=0;
7082 
7083  ast_localtime(&when, &tm, NULL);
7084  hour = tm.tm_hour;
7085  if (!hour)
7086  hour = 12;
7087  else if (hour == 12)
7088  pm = 1;
7089  else if (hour > 12) {
7090  hour -= 12;
7091  pm = 1;
7092  }
7093  if (!res)
7094  res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
7095 
7096  if (tm.tm_min > 9) {
7097  if (!res)
7098  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7099  } else if (tm.tm_min) {
7100  if (!res)
7101  res = ast_streamfile(chan, "digits/oh", lang);
7102  if (!res)
7103  res = ast_waitstream(chan, ints);
7104  if (!res)
7105  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7106  } else {
7107  if (!res)
7108  res = ast_streamfile(chan, "digits/oclock", lang);
7109  if (!res)
7110  res = ast_waitstream(chan, ints);
7111  }
7112  if (pm) {
7113  if (!res)
7114  res = ast_streamfile(chan, "digits/p-m", lang);
7115  } else {
7116  if (!res)
7117  res = ast_streamfile(chan, "digits/a-m", lang);
7118  }
7119  if (!res)
7120  res = ast_waitstream(chan, ints);
7121  return res;
7122 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_time_fr()

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

French syntax.

Definition at line 7168 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), NULL, ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_get_number_str(), and say_time().

7169 {
7170  struct timeval when = { t, 0 };
7171  struct ast_tm tm;
7172  int res = 0;
7173 
7174  ast_localtime(&when, &tm, NULL);
7175 
7176  res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
7177  if (!res)
7178  res = ast_streamfile(chan, "digits/oclock", lang);
7179  if (tm.tm_min) {
7180  if (!res)
7181  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7182  }
7183  return res;
7184 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337

◆ ast_say_time_gr()

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

Greek support.

A list of the files that you need to create

  • digits/female/1..4 : "Mia, dyo , treis, tesseris "
  • digits/kai : "KAI"
  • didgits : "h wra"
  • digits/p-m : "meta meshmbrias"
  • digits/a-m : "pro meshmbrias"

Definition at line 8260 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), gr_say_number_female(), NULL, ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_get_number_str(), ast_say_datetime_gr(), and say_time().

8261 {
8262 
8263  struct timeval when = { t, 0 };
8264  struct ast_tm tm;
8265  int res = 0;
8266  int hour, pm=0;
8267 
8268  ast_localtime(&when, &tm, NULL);
8269  hour = tm.tm_hour;
8270 
8271  if (!hour)
8272  hour = 12;
8273  else if (hour == 12)
8274  pm = 1;
8275  else if (hour > 12) {
8276  hour -= 12;
8277  pm = 1;
8278  }
8279 
8280  res = gr_say_number_female(hour, chan, ints, lang);
8281  if (tm.tm_min) {
8282  if (!res)
8283  res = ast_streamfile(chan, "digits/kai", lang);
8284  if (!res)
8285  res = ast_waitstream(chan, ints);
8286  if (!res)
8287  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
8288  } else {
8289  if (!res)
8290  res = ast_streamfile(chan, "digits/hwra", lang);
8291  if (!res)
8292  res = ast_waitstream(chan, ints);
8293  }
8294  if (pm) {
8295  if (!res)
8296  res = ast_streamfile(chan, "digits/p-m", lang);
8297  } else {
8298  if (!res)
8299  res = ast_streamfile(chan, "digits/a-m", lang);
8300  }
8301  if (!res)
8302  res = ast_waitstream(chan, ints);
8303  return res;
8304 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang)
Greek digits/female-[1..4] : "Mia, dyo , treis, tessereis".
Definition: say.c:7991

◆ ast_say_time_he()

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

Hebrew syntax.

Definition at line 7326 of file say.c.

References ast_localtime(), ast_say_number_full_he(), ast_waitstream(), NULL, ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_get_number_str(), and say_time().

7327 {
7328  struct timeval when = { t, 0 };
7329  struct ast_tm tm;
7330  int res = 0;
7331  int hour;
7332 
7333  ast_localtime(&when, &tm, NULL);
7334  hour = tm.tm_hour;
7335  if (!hour)
7336  hour = 12;
7337 
7338  if (!res)
7339  res = ast_say_number_full_he(chan, hour, ints, lang, "f", -1, -1);
7340 
7341  if (tm.tm_min > 9) {
7342  if (!res)
7343  res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
7344  } else if (tm.tm_min) {
7345  if (!res) { /* say a leading zero if needed */
7346  res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
7347  }
7348  if (!res)
7349  res = ast_waitstream(chan, ints);
7350  if (!res)
7351  res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
7352  } else {
7353  if (!res)
7354  res = ast_waitstream(chan, ints);
7355  }
7356  if (!res)
7357  res = ast_waitstream(chan, ints);
7358  return res;
7359 }
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
static int ast_say_number_full_he(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
Definition: say.c:1447
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_time_hu()

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

Hungarian syntax.

Definition at line 7145 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_get_number_str(), and say_time().

7146 {
7147  struct timeval when = { t, 0 };
7148  struct ast_tm tm;
7149  int res = 0;
7150 
7151  ast_localtime(&when, &tm, NULL);
7152  if (!res)
7153  res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
7154  if (!res)
7155  res = ast_streamfile(chan, "digits/oclock", lang);
7156  if (!res)
7157  res = ast_waitstream(chan, ints);
7158  if (!res)
7159  if (tm.tm_min > 0) {
7160  res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
7161  if (!res)
7162  res = ast_streamfile(chan, "minute", lang);
7163  }
7164  return res;
7165 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_time_ja()

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

Definition at line 8308 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_get_number_str(), and say_time().

8309 {
8310  struct timeval tv = { t, 0 };
8311  struct ast_tm tm;
8312  int res = 0;
8313  int hour, pm=0;
8314 
8315  ast_localtime(&tv, &tm, NULL);
8316  hour = tm.tm_hour;
8317 
8318  if (!hour)
8319  hour = 12;
8320  else if (hour == 12)
8321  pm = 1;
8322  else if (hour > 12) {
8323  hour -= 12;
8324  pm = 1;
8325  }
8326 
8327  if (pm) {
8328  if (!res)
8329  res = ast_streamfile(chan, "digits/p-m", lang);
8330  } else {
8331  if (!res)
8332  res = ast_streamfile(chan, "digits/a-m", lang);
8333  }
8334  if (hour == 9 || hour == 21) {
8335  if (!res)
8336  res = ast_streamfile(chan, "digits/9_2", lang);
8337  } else {
8338  if (!res)
8339  res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
8340  }
8341  if (!res)
8342  res = ast_streamfile(chan, "digits/ji", lang);
8343  if (!res)
8344  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
8345  if (!res)
8346  res = ast_streamfile(chan, "digits/fun", lang);
8347  if (!res)
8348  res = ast_waitstream(chan, ints);
8349  return res;
8350 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_time_ka()

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

Georgian syntax. e.g. "otxi saati da eqvsi tsuti".

Definition at line 9391 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_get_number_str(), and say_time().

9392 {
9393  struct timeval when = { t, 0 };
9394  struct ast_tm tm;
9395  int res = 0;
9396 
9397  ast_localtime(&when, &tm, NULL);
9398 
9399  res = ast_say_number(chan, tm.tm_hour, ints, lang, (char*)NULL);
9400  if (!res) {
9401  res = ast_streamfile(chan, "digits/saati_da", lang);
9402  if (!res) {
9403  res = ast_waitstream(chan, ints);
9404  }
9405  }
9406 
9407  if (tm.tm_min) {
9408  if (!res) {
9409  res = ast_say_number(chan, tm.tm_min, ints, lang, (char*)NULL);
9410 
9411  if (!res) {
9412  res = ast_streamfile(chan, "digits/tsuti", lang);
9413  if (!res) {
9414  res = ast_waitstream(chan, ints);
9415  }
9416  }
9417  }
9418  }
9419  return res;
9420 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_time_nl()

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

Dutch syntax.

Definition at line 7187 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_get_number_str(), and say_time().

7188 {
7189  struct timeval when = { t, 0 };
7190  struct ast_tm tm;
7191  int res = 0;
7192 
7193  ast_localtime(&when, &tm, NULL);
7194  if (!res)
7195  res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
7196  if (!res)
7197  res = ast_streamfile(chan, "digits/nl-uur", lang);
7198  if (!res)
7199  res = ast_waitstream(chan, ints);
7200  if (!res)
7201  if (tm.tm_min > 0)
7202  res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
7203  return res;
7204 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_say_time_pt()

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

Portuguese syntax.

Definition at line 7207 of file say.c.

References ast_localtime(), ast_say_number(), NULL, ast_tm::tm_hour, ast_tm::tm_min, and wait_file().

Referenced by ast_get_number_str(), and say_time().

7208 {
7209  struct timeval when = { t, 0 };
7210  struct ast_tm tm;
7211  int res = 0;
7212  int hour;
7213 
7214  ast_localtime(&when, &tm, NULL);
7215  hour = tm.tm_hour;
7216  if (!res)
7217  res = ast_say_number(chan, hour, ints, lang, "f");
7218  if (tm.tm_min) {
7219  if (!res)
7220  res = wait_file(chan, ints, "digits/pt-e", lang);
7221  if (!res)
7222  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7223  } else {
7224  if (!res)
7225  res = wait_file(chan, ints, "digits/pt-hora", lang);
7226  if (tm.tm_hour != 1)
7227  if (!res)
7228  res = wait_file(chan, ints, "digits/pt-sss", lang);
7229  }
7230  if (!res)
7231  res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
7232  return res;
7233 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337

◆ ast_say_time_pt_BR()

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

Brazilian Portuguese syntax.

Definition at line 7236 of file say.c.

References ast_localtime(), ast_say_number(), NULL, ast_tm::tm_hour, ast_tm::tm_min, and wait_file().

Referenced by ast_get_number_str(), and say_time().

7237 {
7238  struct timeval when = { t, 0 };
7239  struct ast_tm tm;
7240  int res = 0;
7241 
7242  ast_localtime(&when, &tm, NULL);
7243 
7244  res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
7245  if (!res) {
7246  if (tm.tm_hour > 1)
7247  res = wait_file(chan, ints, "digits/hours", lang);
7248  else
7249  res = wait_file(chan, ints, "digits/hour", lang);
7250  }
7251  if ((!res) && (tm.tm_min)) {
7252  res = wait_file(chan, ints, "digits/pt-e", lang);
7253  if (!res)
7254  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7255  if (!res) {
7256  if (tm.tm_min > 1)
7257  res = wait_file(chan, ints, "minutes", lang);
7258  else
7259  res = wait_file(chan, ints, "minute", lang);
7260  }
7261  }
7262  return res;
7263 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337

◆ ast_say_time_th()

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

Thai syntax.

Definition at line 7266 of file say.c.

References ast_localtime(), ast_say_number(), NULL, ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_get_number_str(), and say_time().

7267 {
7268  struct timeval when = { t, 0 };
7269  struct ast_tm tm;
7270  int res = 0;
7271  int hour;
7272  ast_localtime(&when, &tm, NULL);
7273  hour = tm.tm_hour;
7274  if (!hour)
7275  hour = 24;
7276  if (!res)
7277  res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
7278  if (!res)
7279  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7280  return res;
7281 }
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337

◆ ast_say_time_zh()

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

Taiwanese / Chinese syntax.

Definition at line 7284 of file say.c.

References ast_localtime(), ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, ast_tm::tm_hour, and ast_tm::tm_min.

Referenced by ast_get_number_str(), and say_time().

7285 {
7286  struct timeval when = { t, 0 };
7287  struct ast_tm tm;
7288  int res = 0;
7289  int hour, pm=0;
7290 
7291  ast_localtime(&when, &tm, NULL);
7292  hour = tm.tm_hour;
7293  if (!hour)
7294  hour = 12;
7295  else if (hour == 12)
7296  pm = 1;
7297  else if (hour > 12) {
7298  hour -= 12;
7299  pm = 1;
7300  }
7301  if (pm) {
7302  if (!res)
7303  res = ast_streamfile(chan, "digits/p-m", lang);
7304  } else {
7305  if (!res)
7306  res = ast_streamfile(chan, "digits/a-m", lang);
7307  }
7308  if (!res)
7309  res = ast_waitstream(chan, ints);
7310  if (!res)
7311  res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
7312  if (!res)
7313  res = ast_streamfile(chan, "digits/oclock", lang);
7314  if (!res)
7315  res = ast_waitstream(chan, ints);
7316  if (!res)
7317  res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
7318  if (!res)
7319  res = ast_streamfile(chan, "minute", lang);
7320  if (!res)
7321  res = ast_waitstream(chan, ints);
7322  return res;
7323 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776

◆ ast_translate_number_ka()

static char* ast_translate_number_ka ( int  num,
char *  res,
int  res_len 
)
static

Georgian support.

Convert a number into a semi-localized string. Only for Georgian. res must be of at least 256 bytes, preallocated. The output corresponds to Georgian spoken numbers, so it may be either converted to real words by applying a direct conversion table, or played just by substituting the entities with played files.

Output may consist of the following tokens (separated by spaces): 0, minus. 1-9, 1_-9_. (erti, ori, sami, otxi, ... . erti, or, sam, otx, ...). 10-19. 20, 40, 60, 80, 20_, 40_, 60_, 80_. (oci, ormoci, ..., ocda, ormocda, ...). 100, 100_, 200, 200_, ..., 900, 900_. (asi, as, orasi, oras, ...). 1000, 1000_. (atasi, atas). 1000000, 1000000_. (milioni, milion). 1000000000, 1000000000_. (miliardi, miliard).

To be able to play the sounds, each of the above tokens needs a corresponding sound file. (e.g. 200_.gsm).

Definition at line 9131 of file say.c.

References buf, and digit.

Referenced by ast_say_number_full_ka().

9132 {
9133  char buf[256];
9134  int digit = 0;
9135  int remaining = 0;
9136 
9137 
9138  if (num < 0) {
9139  strncat(res, "minus ", res_len - strlen(res) - 1);
9140  if ( num > INT_MIN ) {
9141  num = -num;
9142  } else {
9143  num = 0;
9144  }
9145  }
9146 
9147 
9148  /* directly read the numbers */
9149  if (num <= 20 || num == 40 || num == 60 || num == 80 || num == 100) {
9150  snprintf(buf, sizeof(buf), "%d", num);
9151  strncat(res, buf, res_len - strlen(res) - 1);
9152  return res;
9153  }
9154 
9155 
9156  if (num < 40) { /* ocda... */
9157  strncat(res, "20_ ", res_len - strlen(res) - 1);
9158  return ast_translate_number_ka(num - 20, res, res_len);
9159  }
9160 
9161  if (num < 60) { /* ormocda... */
9162  strncat(res, "40_ ", res_len - strlen(res) - 1);
9163  return ast_translate_number_ka(num - 40, res, res_len);
9164  }
9165 
9166  if (num < 80) { /* samocda... */
9167  strncat(res, "60_ ", res_len - strlen(res) - 1);
9168  return ast_translate_number_ka(num - 60, res, res_len);
9169  }
9170 
9171  if (num < 100) { /* otxmocda... */
9172  strncat(res, "80_ ", res_len - strlen(res) - 1);
9173  return ast_translate_number_ka(num - 80, res, res_len);
9174  }
9175 
9176 
9177  if (num < 1000) { /* as, oras, samas, ..., cxraas. asi, orasi, ..., cxraasi. */
9178  remaining = num % 100;
9179  digit = (num - remaining) / 100;
9180 
9181  if (remaining == 0) {
9182  snprintf(buf, sizeof(buf), "%d", num);
9183  strncat(res, buf, res_len - strlen(res) - 1);
9184  return res;
9185  } else {
9186  snprintf(buf, sizeof(buf), "%d_ ", digit*100);
9187  strncat(res, buf, res_len - strlen(res) - 1);
9188  return ast_translate_number_ka(remaining, res, res_len);
9189  }
9190  }
9191 
9192 
9193  if (num == 1000) {
9194  strncat(res, "1000", res_len - strlen(res) - 1);
9195  return res;
9196  }
9197 
9198 
9199  if (num < 1000000) {
9200  remaining = num % 1000;
9201  digit = (num - remaining) / 1000;
9202 
9203  if (remaining == 0) {
9204  ast_translate_number_ka(digit, res, res_len);
9205  strncat(res, " 1000", res_len - strlen(res) - 1);
9206  return res;
9207  }
9208 
9209  if (digit == 1) {
9210  strncat(res, "1000_ ", res_len - strlen(res) - 1);
9211  return ast_translate_number_ka(remaining, res, res_len);
9212  }
9213 
9214  ast_translate_number_ka(digit, res, res_len);
9215  strncat(res, " 1000_ ", res_len - strlen(res) - 1);
9216  return ast_translate_number_ka(remaining, res, res_len);
9217  }
9218 
9219 
9220  if (num == 1000000) {
9221  strncat(res, "1 1000000", res_len - strlen(res) - 1);
9222  return res;
9223  }
9224 
9225 
9226  if (num < 1000000000) {
9227  remaining = num % 1000000;
9228  digit = (num - remaining) / 1000000;
9229 
9230  if (remaining == 0) {
9231  ast_translate_number_ka(digit, res, res_len);
9232  strncat(res, " 1000000", res_len - strlen(res) - 1);
9233  return res;
9234  }
9235 
9236  ast_translate_number_ka(digit, res, res_len);
9237  strncat(res, " 1000000_ ", res_len - strlen(res) - 1);
9238  return ast_translate_number_ka(remaining, res, res_len);
9239  }
9240 
9241 
9242  if (num == 1000000000) {
9243  strncat(res, "1 1000000000", res_len - strlen(res) - 1);
9244  return res;
9245  }
9246 
9247 
9248  if (num > 1000000000) {
9249  remaining = num % 1000000000;
9250  digit = (num - remaining) / 1000000000;
9251 
9252  if (remaining == 0) {
9253  ast_translate_number_ka(digit, res, res_len);
9254  strncat(res, " 1000000000", res_len - strlen(res) - 1);
9255  return res;
9256  }
9257 
9258  ast_translate_number_ka(digit, res, res_len);
9259  strncat(res, " 1000000000_ ", res_len - strlen(res) - 1);
9260  return ast_translate_number_ka(remaining, res, res_len);
9261  }
9262 
9263  return res;
9264 
9265 }
char digit
static char * ast_translate_number_ka(int num, char *res, int res_len)
Georgian support.
Definition: say.c:9131
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

◆ counted_adjective_ending_ru()

static const char* counted_adjective_ending_ru ( int  num,
const char  gender[] 
)
static

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").

Definition at line 9561 of file say.c.

Referenced by ast_say_counted_adjective().

9562 {
9563  if (num < 0) {
9564  num *= -1;
9565  }
9566  num %= 100; /* never pay attention to more than two digits */
9567  if (num >= 20) { /* at 20 and beyond only the last digit matters */
9568  num %= 10;
9569  }
9570  if (num == 1) {
9571  return gender ? gender : "";
9572  } else { /* all other numbers get the genative plural */
9573  return "x";
9574  }
9575 }

◆ counted_noun_ending_en()

static const char* counted_noun_ending_en ( int  num)
static

In English, we use the plural for everything but one. For example:

  • 1 degree
  • 2 degrees
  • 5 degrees The filename for the plural form is generated by appending "s". Note that purpose is to generate a unique filename, not to implement irregular declensions. Thus:
  • 1 man
  • 2 mans (the "mans" soundfile will of course say "men")

Definition at line 9497 of file say.c.

Referenced by ast_say_counted_noun().

9498 {
9499  if (num == 1 || num == -1) {
9500  return "";
9501  } else {
9502  return "s";
9503  }
9504 }

◆ counted_noun_ending_slavic()

static const char* counted_noun_ending_slavic ( int  num)
static

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:

  • 1 degree (soudfile says "gradus")
  • 2 degreex1 (soundfile says "gradusa")
  • 5 degreex2 (soundfile says "gradusov")

Definition at line 9516 of file say.c.

Referenced by ast_say_counted_noun().

9517 {
9518  if (num < 0) {
9519  num *= -1;
9520  }
9521  num %= 100; /* never pay attention to more than two digits */
9522  if (num >= 20) { /* for numbers 20 and above, pay attention to only last digit */
9523  num %= 10;
9524  }
9525  if (num == 1) { /* singular */
9526  return "";
9527  }
9528  if (num > 0 && num < 5) { /* 2--4 get genative singular */
9529  return "x1";
9530  } else { /* 5--19 get genative plural */
9531  return "x2";
9532  }
9533 }

◆ exp10_int()

static int exp10_int ( int  power)
static

Definition at line 796 of file say.c.

Referenced by ast_say_number_full_cs().

797 {
798  int x, res= 1;
799  for (x=0;x<power;x++)
800  res *= 10;
801  return res;
802 }

◆ get_lastdigits_ru()

static int get_lastdigits_ru ( int  num)
static

determine last digits for thousands/millions (ru)

Definition at line 2807 of file say.c.

Referenced by ast_say_number_full_ru().

2807  {
2808  if (num < 20) {
2809  return num;
2810  } else if (num < 100) {
2811  return get_lastdigits_ru(num % 10);
2812  } else if (num < 1000) {
2813  return get_lastdigits_ru(num % 100);
2814  }
2815  return 0; /* number too big */
2816 }
static int get_lastdigits_ru(int num)
determine last digits for thousands/millions (ru)
Definition: say.c:2807

◆ get_number_str_en()

static struct ast_str* get_number_str_en ( int  num,
const char *  lang 
)
static

Definition at line 454 of file say.c.

References ast_copy_string(), ast_get_digit_str(), ast_get_number_str(), ast_log, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_reset(), and LOG_WARNING.

Referenced by ast_get_number_str().

455 {
456  const char *fnr;
457  int loops = 0;
458 
459  int res = 0;
460  int playh = 0;
461  char fn[256] = "";
462 
463  struct ast_str *filenames;
464 
465  if (!num)
466  return ast_get_digit_str("0", lang);
467 
468  filenames = ast_str_create(20);
469  ast_str_reset(filenames);
470 
471  while (!res && (num || playh)) {
472  if (num < 0) {
473  ast_copy_string(fn, "digits/minus", sizeof(fn));
474  if ( num > INT_MIN ) {
475  num = -num;
476  } else {
477  num = 0;
478  }
479  } else if (playh) {
480  ast_copy_string(fn, "digits/hundred", sizeof(fn));
481  playh = 0;
482  } else if (num < 20) {
483  snprintf(fn, sizeof(fn), "digits/%d", num);
484  num = 0;
485  } else if (num < 100) {
486  snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
487  num %= 10;
488  } else {
489  if (num < 1000){
490  snprintf(fn, sizeof(fn), "digits/%d", (num/100));
491  playh++;
492  num %= 100;
493  } else {
494  struct ast_str *fnrecurse;
495  if (num < 1000000) { /* 1,000,000 */
496  fnrecurse = ast_get_number_str((num / 1000), lang);
497  fnr = ast_str_buffer(fnrecurse);
498  ast_str_append(&filenames, 0, (loops == 0 ? "%s" : "&%s"), fnr);
499  num %= 1000;
500  snprintf(fn, sizeof(fn), "&digits/thousand");
501  } else {
502  if (num < 1000000000) { /* 1,000,000,000 */
503  fnrecurse = ast_get_number_str((num / 1000000), lang);
504  fnr = ast_str_buffer(fnrecurse);
505  ast_str_append(&filenames, 0, (loops == 0 ? "%s" : "&%s"), fnr);
506  num %= 1000000;
507  ast_copy_string(fn, "&digits/million", sizeof(fn));
508  } else {
509  ast_log(LOG_WARNING, "Number '%d' is too big for me\n", num);
510  res = -1;
511  }
512  }
513  }
514  }
515  if (!res) {
516  ast_str_append(&filenames, 0, (loops == 0 ? "%s" : "&%s"), fn);
517  loops++;
518  }
519  }
520 
521  return filenames;
522 }
struct ast_str * ast_get_number_str(int num, const char *lang)
ast_get_number_str: call language-specific functions
Definition: say.c:525
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_log
Definition: astobj2.c:42
struct ast_str * ast_get_digit_str(const char *str, const char *lang)
Returns an ast_str of files for SayDigits playback.
Definition: say.c:294
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ gr_say_number_female()

static int gr_say_number_female ( int  num,
struct ast_channel chan,
const char *  ints,
const char *  lang 
)
static

Greek digits/female-[1..4] : "Mia, dyo , treis, tessereis".

Definition at line 7991 of file say.c.

References ast_say_number(), ast_streamfile(), ast_waitstream(), NULL, tmp(), and wait_file().

Referenced by ast_say_date_gr(), ast_say_date_with_format_gr(), ast_say_datetime_gr(), and ast_say_time_gr().

7991  {
7992  int tmp;
7993  int left;
7994  int res;
7995  char fn[256] = "";
7996 
7997  /* ast_debug(1, "\n\n Saying number female %s %d \n\n", lang, num); */
7998  if (num < 5) {
7999  snprintf(fn, sizeof(fn), "digits/female-%d", num);
8000  res = wait_file(chan, ints, fn, lang);
8001  } else if (num < 13) {
8002  res = ast_say_number(chan, num, ints, lang, (char *) NULL);
8003  } else if (num <100 ) {
8004  tmp = (num/10) * 10;
8005  left = num - tmp;
8006  snprintf(fn, sizeof(fn), "digits/%d", tmp);
8007  res = ast_streamfile(chan, fn, lang);
8008  if (!res)
8009  res = ast_waitstream(chan, ints);
8010  if (left)
8011  gr_say_number_female(left, chan, ints, lang);
8012 
8013  } else {
8014  return -1;
8015  }
8016  return res;
8017 }
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
Definition: say.c:699
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static int tmp()
Definition: bt_open.c:389
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang)
Greek digits/female-[1..4] : "Mia, dyo , treis, tessereis".
Definition: say.c:7991

◆ next_item()

static char next_item ( const char *  format)
static

Definition at line 4486 of file say.c.

References ast_skip_blanks().

Referenced by ast_say_date_with_format_da(), ast_say_date_with_format_de(), and ast_say_date_with_format_is().

4487 {
4488  const char *next = ast_skip_blanks(format);
4489  return *next;
4490 }
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ pl_append()

static char* pl_append ( char *  buffer,
char *  str 
)
static

Definition at line 2177 of file say.c.

Referenced by powiedz().

2178 {
2179  strcpy(buffer, str);
2180  buffer += strlen(str);
2181  return buffer;
2182 }
const char * str
Definition: app_jack.c:147

◆ pl_odtworz_plik()

static void pl_odtworz_plik ( struct ast_channel chan,
const char *  language,
int  audiofd,
int  ctrlfd,
const char *  ints,
char *  fn 
)
static

Definition at line 2184 of file say.c.

References ast_debug, ast_stopstream(), ast_streamfile(), ast_waitstream(), and ast_waitstream_full().

Referenced by powiedz().

2185 {
2186  char file_name[255] = "digits/";
2187  strcat(file_name, fn);
2188  ast_debug(1, "Trying to play: %s\n", file_name);
2189  if (!ast_streamfile(chan, file_name, language)) {
2190  if ((audiofd > -1) && (ctrlfd > -1))
2191  ast_waitstream_full(chan, ints, audiofd, ctrlfd);
2192  else
2193  ast_waitstream(chan, ints);
2194  }
2195  ast_stopstream(chan);
2196 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ pl_rzad_na_tekst()

static char* pl_rzad_na_tekst ( odmiana odm,
int  i,
int  rzad 
)
static

Definition at line 2164 of file say.c.

References odmiana::rzedy.

Referenced by powiedz().

2165 {
2166  if (rzad==0)
2167  return "";
2168 
2169  if (i==1)
2170  return odm->rzedy[rzad - 1][0];
2171  if ((i > 21 || i < 11) && i%10 > 1 && i%10 < 5)
2172  return odm->rzedy[rzad - 1][1];
2173  else
2174  return odm->rzedy[rzad - 1][2];
2175 }
char * rzedy[3][3]
Definition: say.c:2161

◆ powiedz()

static void powiedz ( struct ast_channel chan,
const char *  language,
int  audiofd,
int  ctrlfd,
const char *  ints,
odmiana odm,
int  rzad,
int  i 
)
static

Definition at line 2198 of file say.c.

References b, buf, odmiana::cyfry, odmiana::cyfry2, odmiana::dziesiatki, odmiana::nastki, pl_append(), pl_odtworz_plik(), pl_rzad_na_tekst(), odmiana::separator_dziesiatek, and odmiana::setki.

Referenced by ast_say_number_full_pl().

2199 {
2200  /* Initialise variables to allow compilation on Debian-stable, etc */
2201  int m1000E6 = 0;
2202  int i1000E6 = 0;
2203  int m1000E3 = 0;
2204  int i1000E3 = 0;
2205  int m1000 = 0;
2206  int i1000 = 0;
2207  int m100 = 0;
2208  int i100 = 0;
2209 
2210  if (i == 0 && rzad > 0) {
2211  return;
2212  }
2213  if (i == 0) {
2214  pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry[0]);
2215  return;
2216  }
2217 
2218  m1000E6 = i % 1000000000;
2219  i1000E6 = i / 1000000000;
2220 
2221  powiedz(chan, language, audiofd, ctrlfd, ints, odm, rzad+3, i1000E6);
2222 
2223  m1000E3 = m1000E6 % 1000000;
2224  i1000E3 = m1000E6 / 1000000;
2225 
2226  powiedz(chan, language, audiofd, ctrlfd, ints, odm, rzad+2, i1000E3);
2227 
2228  m1000 = m1000E3 % 1000;
2229  i1000 = m1000E3 / 1000;
2230 
2231  powiedz(chan, language, audiofd, ctrlfd, ints, odm, rzad+1, i1000);
2232 
2233  m100 = m1000 % 100;
2234  i100 = m1000 / 100;
2235 
2236  if (i100>0)
2237  pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->setki[i100]);
2238 
2239  if (m100 > 0 && m100 <= 9) {
2240  if (m1000 > 0)
2241  pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100]);
2242  else
2243  pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry[m100]);
2244  } else if (m100 % 10 == 0 && m100 != 0) {
2245  pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
2246  } else if (m100 > 10 && m100 <= 19) {
2247  pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->nastki[m100 % 10]);
2248  } else if (m100 > 20) {
2249  if (odm->separator_dziesiatek[0] == ' ') {
2250  pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
2251  pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100 % 10]);
2252  } else {
2253  char buf[10];
2254  char *b = buf;
2255  b = pl_append(b, odm->dziesiatki[m100 / 10]);
2256  b = pl_append(b, odm->separator_dziesiatek);
2257  pl_append(b, odm->cyfry2[m100 % 10]);
2258  pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, buf);
2259  }
2260  }
2261 
2262  if (rzad > 0) {
2263  pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, pl_rzad_na_tekst(odm, i, rzad));
2264  }
2265 }
char * setki[10]
Definition: say.c:2158
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
char * nastki[10]
Definition: say.c:2160
char * cyfry2[10]
Definition: say.c:2157
char * cyfry[10]
Definition: say.c:2156
static char * pl_append(char *buffer, char *str)
Definition: say.c:2177
char * separator_dziesiatek
Definition: say.c:2155
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
static char * pl_rzad_na_tekst(odmiana *odm, int i, int rzad)
Definition: say.c:2164
static void powiedz(struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, odmiana *odm, int rzad, int i)
Definition: say.c:2198
char * dziesiatki[10]
Definition: say.c:2159
static struct test_val b
static void pl_odtworz_plik(struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, char *fn)
Definition: say.c:2184

◆ say_character_str_full()

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

Definition at line 171 of file say.c.

References ast_free, ast_get_character_str(), ast_stopstream(), ast_str_buffer(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), and strsep().

Referenced by __say_init(), and say_init_mode().

172 {
173  const char *fn;
174  int res = 0;
175 
176  struct ast_str *filenames = ast_get_character_str(str, lang, sensitivity);
177  char *files = ast_str_buffer(filenames);
178 
179  while ((fn = strsep(&files, "&"))) {
180  res = ast_streamfile(chan, fn, lang);
181  if (!res) {
182  if ((audiofd > -1) && (ctrlfd > -1))
183  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
184  else
185  res = ast_waitstream(chan, ints);
186  }
187  ast_stopstream(chan);
188  }
189 
190  ast_free(filenames);
191 
192  return res;
193 }
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.
Definition: say.c:63
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
const char * str
Definition: app_jack.c:147
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
char * strsep(char **str, const char *delims)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ say_date()

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

Definition at line 3807 of file say.c.

References ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_is(), ast_say_date_ja(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_pt(), and ast_say_date_th().

Referenced by __say_init().

3808 {
3809  if (!strncasecmp(lang, "en", 2)) { /* English syntax */
3810  return ast_say_date_en(chan, t, ints, lang);
3811  } else if (!strncasecmp(lang, "da", 2)) { /* Danish syntax */
3812  return ast_say_date_da(chan, t, ints, lang);
3813  } else if (!strncasecmp(lang, "de", 2)) { /* German syntax */
3814  return ast_say_date_de(chan, t, ints, lang);
3815  } else if (!strncasecmp(lang, "fr", 2)) { /* French syntax */
3816  return ast_say_date_fr(chan, t, ints, lang);
3817  } else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
3818  return ast_say_date_gr(chan, t, ints, lang);
3819  } else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
3820  return ast_say_date_ja(chan, t, ints, lang);
3821  } else if (!strncasecmp(lang, "he", 2)) { /* Hebrew syntax */
3822  return ast_say_date_he(chan, t, ints, lang);
3823  } else if (!strncasecmp(lang, "hu", 2)) { /* Hungarian syntax */
3824  return ast_say_date_hu(chan, t, ints, lang);
3825  } else if (!strncasecmp(lang, "is", 2)) { /* Icelandic syntax */
3826  return ast_say_date_is(chan, t, ints, lang);
3827  } else if (!strncasecmp(lang, "ka", 2)) { /* Georgian syntax */
3828  return ast_say_date_ka(chan, t, ints, lang);
3829  } else if (!strncasecmp(lang, "nl", 2)) { /* Dutch syntax */
3830  return ast_say_date_nl(chan, t, ints, lang);
3831  } else if (!strncasecmp(lang, "pt", 2)) { /* Portuguese syntax */
3832  return ast_say_date_pt(chan, t, ints, lang);
3833  } else if (!strncasecmp(lang, "th", 2)) { /* Thai syntax */
3834  return ast_say_date_th(chan, t, ints, lang);
3835  }
3836 
3837  /* Default to English */
3838  return ast_say_date_en(chan, t, ints, lang);
3839 }
static int ast_say_date_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
French syntax.
Definition: say.c:4002
static int ast_say_date_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Thai syntax.
Definition: say.c:4060
static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Greek support.
Definition: say.c:8180
static int ast_say_date_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
English syntax.
Definition: say.c:3842
static int ast_say_date_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Dutch syntax.
Definition: say.c:4031
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".
Definition: say.c:9348
static int ast_say_date_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Hungarian syntax.
Definition: say.c:3970
static int ast_say_date_is(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:4157
static int ast_say_date_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Hebrew syntax.
Definition: say.c:4123
static int ast_say_date_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
German syntax.
Definition: say.c:3920
static int ast_say_date_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Portuguese syntax.
Definition: say.c:4096
static int ast_say_date_da(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Danish syntax.
Definition: say.c:3871
static int ast_say_date_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:8216

◆ say_date_with_format()

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

Definition at line 4205 of file say.c.

References ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_es(), ast_say_date_with_format_fr(), ast_say_date_with_format_gr(), ast_say_date_with_format_he(), ast_say_date_with_format_is(), ast_say_date_with_format_it(), ast_say_date_with_format_ja(), ast_say_date_with_format_nl(), ast_say_date_with_format_pl(), ast_say_date_with_format_pt(), ast_say_date_with_format_th(), ast_say_date_with_format_vi(), and ast_say_date_with_format_zh().

Referenced by __say_init().

4206 {
4207  if (!strncasecmp(lang, "en", 2)) { /* English syntax */
4208  return ast_say_date_with_format_en(chan, t, ints, lang, format, tzone);
4209  } else if (!strncasecmp(lang, "da", 2)) { /* Danish syntax */
4210  return ast_say_date_with_format_da(chan, t, ints, lang, format, tzone);
4211  } else if (!strncasecmp(lang, "de", 2)) { /* German syntax */
4212  return ast_say_date_with_format_de(chan, t, ints, lang, format, tzone);
4213  } else if (!strncasecmp(lang, "es", 2)) { /* Spanish syntax */
4214  return ast_say_date_with_format_es(chan, t, ints, lang, format, tzone);
4215  } else if (!strncasecmp(lang, "he", 2)) { /* Hebrew syntax */
4216  return ast_say_date_with_format_he(chan, t, ints, lang, format, tzone);
4217  } else if (!strncasecmp(lang, "fr", 2)) { /* French syntax */
4218  return ast_say_date_with_format_fr(chan, t, ints, lang, format, tzone);
4219  } else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
4220  return ast_say_date_with_format_gr(chan, t, ints, lang, format, tzone);
4221  } else if (!strncasecmp(lang, "is", 2)) { /* Icelandic syntax */
4222  return ast_say_date_with_format_is(chan, t, ints, lang, format, tzone);
4223  } else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
4224  return ast_say_date_with_format_ja(chan, t, ints, lang, format, tzone);
4225  } else if (!strncasecmp(lang, "it", 2)) { /* Italian syntax */
4226  return ast_say_date_with_format_it(chan, t, ints, lang, format, tzone);
4227  } else if (!strncasecmp(lang, "nl", 2)) { /* Dutch syntax */
4228  return ast_say_date_with_format_nl(chan, t, ints, lang, format, tzone);
4229  } else if (!strncasecmp(lang, "pl", 2)) { /* Polish syntax */
4230  return ast_say_date_with_format_pl(chan, t, ints, lang, format, tzone);
4231  } else if (!strncasecmp(lang, "pt", 2)) { /* Portuguese syntax */
4232  return ast_say_date_with_format_pt(chan, t, ints, lang, format, tzone);
4233  } else if (!strncasecmp(lang, "th", 2)) { /* Thai syntax */
4234  return ast_say_date_with_format_th(chan, t, ints, lang, format, tzone);
4235  } else if (!strncasecmp(lang, "zh", 2)) { /* Taiwanese / Chinese syntax */
4236  return ast_say_date_with_format_zh(chan, t, ints, lang, format, tzone);
4237  } else if (!strncasecmp(lang, "vi", 2)) { /* Vietnamese syntax */
4238  return ast_say_date_with_format_vi(chan, t, ints, lang, format, tzone);
4239  }
4240 
4241  /* Default to English */
4242  return ast_say_date_with_format_en(chan, t, ints, lang, format, tzone);
4243 }
static int ast_say_date_with_format_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Dutch syntax.
Definition: say.c:6061
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:6773
static int ast_say_date_with_format_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
English syntax.
Definition: say.c:4246
static int ast_say_date_with_format_es(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Spanish syntax.
Definition: say.c:5442
static int ast_say_date_with_format_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Greek support.
Definition: say.c:8455
static int ast_say_date_with_format_vi(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Vietnamese syntax.
Definition: say.c:8895
static int ast_say_date_with_format_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
ast_say_date_with_format_he Say formatted date in Hebrew
Definition: say.c:5295
static int ast_say_date_with_format_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
German syntax.
Definition: say.c:4695
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)
Definition: say.c:8627
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.
Definition: say.c:5110
static int ast_say_date_with_format_is(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Definition: say.c:4898
static int ast_say_date_with_format_it(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Italian syntax.
Definition: say.c:5829
static 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)
Polish syntax.
Definition: say.c:6264
static int ast_say_date_with_format_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Portuguese syntax.
Definition: say.c:6481
static snd_pcm_format_t format
Definition: chan_alsa.c:102
static int ast_say_date_with_format_da(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
Danish syntax.
Definition: say.c:4493
static int ast_say_date_with_format_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
French syntax oclock = heure.
Definition: say.c:5633

◆ say_datetime()

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

Definition at line 7362 of file say.c.

References ast_say_datetime_de(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_hu(), ast_say_datetime_ja(), ast_say_datetime_ka(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_pt_BR(), ast_say_datetime_th(), and ast_say_datetime_zh().

Referenced by __say_init().

7363 {
7364  if (!strncasecmp(lang, "en", 2)) { /* English syntax */
7365  return ast_say_datetime_en(chan, t, ints, lang);
7366  } else if (!strncasecmp(lang, "de", 2)) { /* German syntax */
7367  return ast_say_datetime_de(chan, t, ints, lang);
7368  } else if (!strncasecmp(lang, "fr", 2)) { /* French syntax */
7369  return ast_say_datetime_fr(chan, t, ints, lang);
7370  } else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
7371  return ast_say_datetime_gr(chan, t, ints, lang);
7372  } else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
7373  return ast_say_datetime_ja(chan, t, ints, lang);
7374  } else if (!strncasecmp(lang, "he", 2)) { /* Hebrew syntax */
7375  return ast_say_datetime_he(chan, t, ints, lang);
7376  } else if (!strncasecmp(lang, "hu", 2)) { /* Hungarian syntax */
7377  return ast_say_datetime_hu(chan, t, ints, lang);
7378  } else if (!strncasecmp(lang, "ka", 2)) { /* Georgian syntax */
7379  return ast_say_datetime_ka(chan, t, ints, lang);
7380  } else if (!strncasecmp(lang, "nl", 2)) { /* Dutch syntax */
7381  return ast_say_datetime_nl(chan, t, ints, lang);
7382  } else if (!strncasecmp(lang, "pt_BR", 5)) { /* Brazilian Portuguese syntax */
7383  return ast_say_datetime_pt_BR(chan, t, ints, lang);
7384  } else if (!strncasecmp(lang, "pt", 2)) { /* Portuguese syntax */
7385  return ast_say_datetime_pt(chan, t, ints, lang);
7386  } else if (!strncasecmp(lang, "th", 2)) { /* Thai syntax */
7387  return ast_say_datetime_th(chan, t, ints, lang);
7388  } else if (!strncasecmp(lang, "zh", 2)) { /* Taiwanese / Chinese syntax */
7389  return ast_say_datetime_zh(chan, t, ints, lang);
7390  }
7391 
7392  /* Default to English */
7393  return ast_say_datetime_en(chan, t, ints, lang);
7394 }
static int ast_say_datetime_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Brazilian Portuguese syntax.
Definition: say.c:7620
static int ast_say_datetime_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Thai syntax.
Definition: say.c:7634
static int ast_say_datetime_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Dutch syntax.
Definition: say.c:7534
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.
Definition: say.c:9425
static int ast_say_datetime_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
French syntax.
Definition: say.c:7493
static int ast_say_datetime_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
English syntax.
Definition: say.c:7397
static int ast_say_datetime_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Portuguese syntax.
Definition: say.c:7553
static int ast_say_datetime_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:8388
static int ast_say_datetime_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Taiwanese / Chinese syntax.
Definition: say.c:7677
static int ast_say_datetime_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
German syntax.
Definition: say.c:7464
static int ast_say_datetime_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Hungarian syntax.
Definition: say.c:7479
static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Greek support.
Definition: say.c:8355
static int ast_say_datetime_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Hebrew syntax.
Definition: say.c:7737

◆ say_datetime_from_now()

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

Definition at line 7802 of file say.c.

References ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), and ast_say_datetime_from_now_pt().

Referenced by __say_init(), and say_init_mode().

7803 {
7804  if (!strncasecmp(lang, "en", 2)) { /* English syntax */
7805  return ast_say_datetime_from_now_en(chan, t, ints, lang);
7806  } else if (!strncasecmp(lang, "fr", 2)) { /* French syntax */
7807  return ast_say_datetime_from_now_fr(chan, t, ints, lang);
7808  } else if (!strncasecmp(lang, "he", 2)) { /* Hebrew syntax */
7809  return ast_say_datetime_from_now_he(chan, t, ints, lang);
7810  } else if (!strncasecmp(lang, "ka", 2)) { /* Georgian syntax */
7811  return ast_say_datetime_from_now_ka(chan, t, ints, lang);
7812  } else if (!strncasecmp(lang, "pt", 2)) { /* Portuguese syntax */
7813  return ast_say_datetime_from_now_pt(chan, t, ints, lang);
7814  }
7815 
7816  /* Default to English */
7817  return ast_say_datetime_from_now_en(chan, t, ints, lang);
7818 }
static int ast_say_datetime_from_now_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Hebrew syntax.
Definition: say.c:7947
static int ast_say_datetime_from_now_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
French syntax.
Definition: say.c:7859
static int ast_say_datetime_from_now_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Portuguese syntax.
Definition: say.c:7897
static int ast_say_datetime_from_now_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
English syntax.
Definition: say.c:7821
static int ast_say_datetime_from_now_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Georgian syntax.
Definition: say.c:9444

◆ say_digit_str_full()

static int say_digit_str_full ( struct ast_channel chan,
const char *  str,
const char *  ints,
const char *  lang,
int  audiofd,
int  ctrlfd 
)
static

Definition at line 339 of file say.c.

References ast_free, ast_get_digit_str(), ast_stopstream(), ast_str_buffer(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), and strsep().

Referenced by __say_init(), and say_init_mode().

340 {
341  const char *fn;
342  int res = 0;
343 
344  struct ast_str *filenames = ast_get_digit_str(str, lang);
345  char *files = ast_str_buffer(filenames);
346 
347  while ((fn = strsep(&files, "&"))) {
348  res = ast_streamfile(chan, fn, lang);
349  if (!res) {
350  if ((audiofd > -1) && (ctrlfd > -1))
351  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
352  else
353  res = ast_waitstream(chan, ints);
354  }
355  ast_stopstream(chan);
356  }
357 
358  ast_free(filenames);
359 
360  return res;
361 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
const char * str
Definition: app_jack.c:147
struct ast_str * ast_get_digit_str(const char *str, const char *lang)
Returns an ast_str of files for SayDigits playback.
Definition: say.c:294
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
char * strsep(char **str, const char *delims)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ say_enumeration_full()

static int say_enumeration_full ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options,
int  audiofd,
int  ctrlfd 
)
static

ast_say_enumeration_full: call language-specific functions

Note
Called from AGI

Definition at line 3079 of file say.c.

References ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_is(), and ast_say_enumeration_full_vi().

Referenced by __say_init().

3080 {
3081  if (!strncasecmp(language, "en", 2)) { /* English syntax */
3082  return ast_say_enumeration_full_en(chan, num, ints, language, audiofd, ctrlfd);
3083  } else if (!strncasecmp(language, "da", 2)) { /* Danish syntax */
3084  return ast_say_enumeration_full_da(chan, num, ints, language, options, audiofd, ctrlfd);
3085  } else if (!strncasecmp(language, "de", 2)) { /* German syntax */
3086  return ast_say_enumeration_full_de(chan, num, ints, language, options, audiofd, ctrlfd);
3087  } else if (!strncasecmp(language, "he", 2)) { /* Hebrew syntax */
3088  return ast_say_enumeration_full_he(chan, num, ints, language, options, audiofd, ctrlfd);
3089  } else if (!strncasecmp(language, "is", 2)) { /* Icelandic syntax */
3090  return ast_say_enumeration_full_is(chan, num, ints, language, options, audiofd, ctrlfd);
3091  } else if (!strncasecmp(language, "vi", 2)) { /* Vietnamese syntax */
3092  return ast_say_enumeration_full_vi(chan, num, ints, language, audiofd, ctrlfd);
3093  }
3094 
3095  /* Default to english */
3096  return ast_say_enumeration_full_en(chan, num, ints, language, audiofd, ctrlfd);
3097 }
static int ast_say_enumeration_full_vi(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
Definition: say.c:3198
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)
Definition: say.c:3543
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
Definition: say.c:3632
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
Definition: say.c:3101
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
Definition: say.c:3218
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
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
Definition: say.c:3381
static struct test_options options

◆ say_money_str_full()

static int say_money_str_full ( struct ast_channel chan,
const char *  str,
const char *  ints,
const char *  lang,
int  audiofd,
int  ctrlfd 
)
static

Definition at line 430 of file say.c.

References ast_free, ast_get_money_str(), ast_stopstream(), ast_str_buffer(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), and strsep().

Referenced by __say_init().

431 {
432  const char *fn;
433  int res = 0;
434 
435  struct ast_str *filenames = ast_get_money_str(str, lang);
436  char *files = ast_str_buffer(filenames);
437 
438  while ((fn = strsep(&files, "&"))) {
439  res = ast_streamfile(chan, fn, lang);
440  if (!res) {
441  if ((audiofd > -1) && (ctrlfd > -1))
442  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
443  else
444  res = ast_waitstream(chan, ints);
445  }
446  ast_stopstream(chan);
447  }
448 
449  ast_free(filenames);
450 
451  return res;
452 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
const char * str
Definition: app_jack.c:147
struct ast_str * ast_get_money_str(const char *str, const char *lang)
ast_get_money_str: call language-specific functions
Definition: say.c:419
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
char * strsep(char **str, const char *delims)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ say_number_full()

static int say_number_full ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options,
int  audiofd,
int  ctrlfd 
)
static

ast_say_number_full: call language-specific functions

Note
Called from AGI

Definition at line 713 of file say.c.

References ast_channel_name(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_is(), ast_say_number_full_it(), ast_say_number_full_ja(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pl(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), and ast_test_suite_event_notify.

Referenced by __say_init().

714 {
715  ast_test_suite_event_notify("SAYNUM", "Message: saying number %d\r\nNumber: %d\r\nChannel: %s", num, num, ast_channel_name(chan));
716  if (!strncasecmp(language, "en_GB", 5)) { /* British syntax */
717  return ast_say_number_full_en_GB(chan, num, ints, language, audiofd, ctrlfd);
718  } else if (!strncasecmp(language, "en", 2)) { /* English syntax */
719  return ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd);
720  } else if (!strncasecmp(language, "cs", 2)) { /* Czech syntax */
721  return ast_say_number_full_cs(chan, num, ints, language, options, audiofd, ctrlfd);
722  } else if (!strncasecmp(language, "da", 2)) { /* Danish syntax */
723  return ast_say_number_full_da(chan, num, ints, language, options, audiofd, ctrlfd);
724  } else if (!strncasecmp(language, "de", 2)) { /* German syntax */
725  return ast_say_number_full_de(chan, num, ints, language, options, audiofd, ctrlfd);
726  } else if (!strncasecmp(language, "es", 2)) { /* Spanish syntax */
727  return ast_say_number_full_es(chan, num, ints, language, options, audiofd, ctrlfd);
728  } else if (!strncasecmp(language, "fr", 2)) { /* French syntax */
729  return ast_say_number_full_fr(chan, num, ints, language, options, audiofd, ctrlfd);
730  } else if (!strncasecmp(language, "gr", 2)) { /* Greek syntax */
731  return ast_say_number_full_gr(chan, num, ints, language, audiofd, ctrlfd);
732  } else if (!strncasecmp(language, "ja", 2)) { /* Japanese syntax */
733  return ast_say_number_full_ja(chan, num, ints, language, audiofd, ctrlfd);
734  } else if (!strncasecmp(language, "he", 2)) { /* Hebrew syntax */
735  return ast_say_number_full_he(chan, num, ints, language, options, audiofd, ctrlfd);
736  } else if (!strncasecmp(language, "hu", 2)) { /* Hungarian syntax */
737  return ast_say_number_full_hu(chan, num, ints, language, audiofd, ctrlfd);
738  } else if (!strncasecmp(language, "is", 2)) { /* Icelandic syntax */
739  return ast_say_number_full_is(chan, num, ints, language, options, audiofd, ctrlfd);
740  } else if (!strncasecmp(language, "it", 2)) { /* Italian syntax */
741  return ast_say_number_full_it(chan, num, ints, language, audiofd, ctrlfd);
742  } else if (!strncasecmp(language, "ka", 2)) { /* Georgian syntax */
743  return ast_say_number_full_ka(chan, num, ints, language, options, audiofd, ctrlfd);
744  } else if (!strncasecmp(language, "nl", 2)) { /* Dutch syntax */
745  return ast_say_number_full_nl(chan, num, ints, language, audiofd, ctrlfd);
746  } else if (!strncasecmp(language, "no", 2)) { /* Norwegian syntax */
747  return ast_say_number_full_no(chan, num, ints, language, options, audiofd, ctrlfd);
748  } else if (!strncasecmp(language, "pl", 2)) { /* Polish syntax */
749  return ast_say_number_full_pl(chan, num, ints, language, options, audiofd, ctrlfd);
750  } else if (!strncasecmp(language, "pt", 2)) { /* Portuguese syntax */
751  return ast_say_number_full_pt(chan, num, ints, language, options, audiofd, ctrlfd);
752  } else if (!strncasecmp(language, "ru", 2)) { /* Russian syntax */
753  return ast_say_number_full_ru(chan, num, ints, language, options, audiofd, ctrlfd);
754  } else if (!strncasecmp(language, "se", 2)) { /* Swedish syntax */
755  return ast_say_number_full_se(chan, num, ints, language, options, audiofd, ctrlfd);
756  } else if (!strncasecmp(language, "th", 2)) { /* Thai syntax */
757  return ast_say_number_full_th(chan, num, ints, language, audiofd, ctrlfd);
758  } else if (!strncasecmp(language, "zh", 2)) { /* Taiwanese / Chinese syntax */
759  return ast_say_number_full_zh(chan, num, ints, language, audiofd, ctrlfd);
760  } else if (!strncasecmp(language, "ur", 2)) { /* Urdu syntax */
761  return ast_say_number_full_ur(chan, num, ints, language, options, audiofd, ctrlfd);
762  } else if (!strncasecmp(language, "vi", 2)) { /* Vietnamese syntax */
763  return ast_say_number_full_vi(chan, num, ints, language, audiofd, ctrlfd);
764  }
765 
766  /* Default to english */
767  return ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd);
768 }
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)
Definition: say.c:2748
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
Definition: say.c:2555
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
Definition: say.c:1619
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
Definition: say.c:2834
static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
Greek support A list of the files that you need to create -> digits/xilia = "xilia" -> digits/myrio =...
Definition: say.c:8036
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
Definition: say.c:1974
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
Definition: say.c:1819
static int ast_say_number_full_he(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
Definition: say.c:1447
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
Definition: say.c:1699
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 &#39;une&#39; et: &#39;and&#39; ...
Definition: say.c:1355
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"
Definition: say.c:2072
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
Definition: say.c:826
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
Definition: say.c:1038
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)
Definition: say.c:2455
static int ast_say_number_full_ja(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
Definition: say.c:8105
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:117
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:
Definition: say.c:1172
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
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
Definition: say.c:1251
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:
Definition: say.c:924
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
Definition: say.c:2983
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.
Definition: say.c:2913
const char * ast_channel_name(const struct ast_channel *chan)
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
Definition: say.c:2635
static struct test_options options
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
Definition: say.c:772
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
Definition: say.c:9270
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)
Definition: say.c:2359

◆ say_phonetic_str_full()

static int say_phonetic_str_full ( struct ast_channel chan,
const char *  str,
const char *  ints,
const char *  lang,
int  audiofd,
int  ctrlfd 
)
static

Definition at line 270 of file say.c.

References ast_free, ast_get_phonetic_str(), ast_stopstream(), ast_str_buffer(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), and strsep().

Referenced by __say_init(), and say_init_mode().

271 {
272  const char *fn;
273  int res = 0;
274 
275  struct ast_str *filenames = ast_get_phonetic_str(str, lang);
276  char *files = ast_str_buffer(filenames);
277 
278  while ((fn = strsep(&files, "&"))) {
279  res = ast_streamfile(chan, fn, lang);
280  if (!res) {
281  if ((audiofd > -1) && (ctrlfd > -1))
282  res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
283  else
284  res = ast_waitstream(chan, ints);
285  }
286  ast_stopstream(chan);
287  }
288 
289  ast_free(filenames);
290 
291  return res;
292 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
const char * str
Definition: app_jack.c:147
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1785
char * strsep(char **str, const char *delims)
struct ast_str * ast_get_phonetic_str(const char *str, const char *lang)
Returns an ast_str of files for SayPhonetic playback.
Definition: say.c:195
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ say_time()

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

Definition at line 7041 of file say.c.

References ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_hu(), ast_say_time_ja(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_pt(), ast_say_time_pt_BR(), ast_say_time_th(), and ast_say_time_zh().

Referenced by __say_init().

7042 {
7043  if (!strncasecmp(lang, "en", 2)) { /* English syntax */
7044  return ast_say_time_en(chan, t, ints, lang);
7045  } else if (!strncasecmp(lang, "de", 2)) { /* German syntax */
7046  return ast_say_time_de(chan, t, ints, lang);
7047  } else if (!strncasecmp(lang, "fr", 2)) { /* French syntax */
7048  return ast_say_time_fr(chan, t, ints, lang);
7049  } else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
7050  return ast_say_time_gr(chan, t, ints, lang);
7051  } else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
7052  return ast_say_time_ja(chan, t, ints, lang);
7053  } else if (!strncasecmp(lang, "he", 2)) { /* Hebrew syntax */
7054  return ast_say_time_he(chan, t, ints, lang);
7055  } else if (!strncasecmp(lang, "hu", 2)) { /* Hungarian syntax */
7056  return(ast_say_time_hu(chan, t, ints, lang));
7057  } else if (!strncasecmp(lang, "ka", 2)) { /* Georgian syntax */
7058  return ast_say_time_ka(chan, t, ints, lang);
7059  } else if (!strncasecmp(lang, "nl", 2)) { /* Dutch syntax */
7060  return ast_say_time_nl(chan, t, ints, lang);
7061  } else if (!strncasecmp(lang, "pt_BR", 5)) { /* Brazilian Portuguese syntax */
7062  return ast_say_time_pt_BR(chan, t, ints, lang);
7063  } else if (!strncasecmp(lang, "pt", 2)) { /* Portuguese syntax */
7064  return ast_say_time_pt(chan, t, ints, lang);
7065  } else if (!strncasecmp(lang, "th", 2)) { /* Thai syntax */
7066  return(ast_say_time_th(chan, t, ints, lang));
7067  } else if (!strncasecmp(lang, "zh", 2)) { /* Taiwanese / Chinese syntax */
7068  return ast_say_time_zh(chan, t, ints, lang);
7069  }
7070 
7071  /* Default to English */
7072  return ast_say_time_en(chan, t, ints, lang);
7073 }
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".
Definition: say.c:9391
static int ast_say_time_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Hebrew syntax.
Definition: say.c:7326
static int ast_say_time_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
English syntax.
Definition: say.c:7076
static int ast_say_time_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Thai syntax.
Definition: say.c:7266
static int ast_say_time_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
German syntax.
Definition: say.c:7125
static int ast_say_time_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Dutch syntax.
Definition: say.c:7187
static int ast_say_time_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:8308
static int ast_say_time_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Portuguese syntax.
Definition: say.c:7207
static int ast_say_time_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
French syntax.
Definition: say.c:7168
static int ast_say_time_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Brazilian Portuguese syntax.
Definition: say.c:7236
static int ast_say_time_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Hungarian syntax.
Definition: say.c:7145
static int ast_say_time_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Taiwanese / Chinese syntax.
Definition: say.c:7284
static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Greek support.
Definition: say.c:8260

◆ wait_file()

static int wait_file ( struct ast_channel chan,
const char *  ints,
const char *  file,
const char *  lang 
)
static

Definition at line 699 of file say.c.

References ast_log, ast_streamfile(), ast_waitstream(), and LOG_WARNING.

Referenced by ast_say_date_da(), ast_say_date_de(), ast_say_date_is(), ast_say_date_pt(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_es(), ast_say_date_with_format_fr(), ast_say_date_with_format_gr(), ast_say_date_with_format_he(), ast_say_date_with_format_is(), ast_say_date_with_format_it(), ast_say_date_with_format_ja(), ast_say_date_with_format_nl(), ast_say_date_with_format_pl(), ast_say_date_with_format_pt(), ast_say_date_with_format_th(), ast_say_date_with_format_vi(), ast_say_date_with_format_zh(), ast_say_datetime_from_now_pt(), ast_say_number_full_pt(), ast_say_time_pt(), ast_say_time_pt_BR(), and gr_say_number_female().

700 {
701  int res;
702  if ((res = ast_streamfile(chan, file, lang))) {
703  ast_log(LOG_WARNING, "Unable to play message %s\n", file);
704  }
705  if (!res) {
706  res = ast_waitstream(chan, ints);
707  }
708  return res;
709 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776