Initial version of mod_say_pl
This commit is contained in:
parent
88a13a7580
commit
b056fd06a3
|
@ -0,0 +1,2 @@
|
|||
BASE=../../../freeswitch
|
||||
include $(BASE)/build/modmake.rules
|
|
@ -0,0 +1,7 @@
|
|||
mod_say_pl - support for Polish language in FreeSWITCH
|
||||
=======================================================
|
||||
|
||||
Moduł bazuje na mod_say_en. Aktualnie nie jest jeszcze kompletny,
|
||||
tym nie mniej pozwala na czytanie liczb czy dat/czasu. Liczę na
|
||||
Wasze wsparcie w zakresie testowania modułu, sugestii, łat, etc.
|
||||
na http://jira.freeswitch.org/.
|
|
@ -0,0 +1,94 @@
|
|||
<include>
|
||||
|
||||
<extension name="test_say_pl">
|
||||
<condition field="destination_number" expression="^^44(\d{2})$">
|
||||
<action application="answer"/>
|
||||
<action application="set" data="sound_prefix=$${sounds_dir}/pl/espeak"/>
|
||||
<action application="set" data="default_language=pl"/>
|
||||
<action application="sleep" data="1000"/>
|
||||
<action application="transfer" data="test_say_pl_$1"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="test_say_pl_01">
|
||||
<condition field="destination_number" expression="^test_say_pl_01$">
|
||||
<action application="set" data="num=${expr(randomize(&x);ceil(random(0,1000000,&x)))}"/>
|
||||
<action application="log" data="INFO Test: say pl: ${num}"/>
|
||||
<action application="say" data="pl number pronounced ${num}"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
<action application="transfer" data="test_say_pl_01"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="test_say_pl_02">
|
||||
<condition field="destination_number" expression="^test_say_pl_02$">
|
||||
<action application="set" data="num=${expr(randomize(&x);ceil(random(0,1000000,&x)))}"/>
|
||||
<action application="log" data="INFO Test: say pl: ${num}"/>
|
||||
<action application="say" data="pl number iterated ${num}"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
<action application="transfer" data="test_say_pl_02"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="test_say_pl_03">
|
||||
<condition field="destination_number" expression="^test_say_pl_03$">
|
||||
<action application="set" data="hh=${expr(randomize(&x);ceil(random(0,24,&x)))}"/>
|
||||
<action application="set" data="mm=${expr(randomize(&x);ceil(random(0,60,&x)))}"/>
|
||||
<action application="set" data="ss=${expr(randomize(&x);ceil(random(0,60,&x)))}"/>
|
||||
<action application="log" data="INFO Test: say pl: ${hh}:${mm}:${ss}"/>
|
||||
<action application="say" data="pl TIME_MEASUREMENT pronounced ${hh}:${mm}:${ss}"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
<action application="transfer" data="test_say_pl_03"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="test_say_pl_04">
|
||||
<condition field="destination_number" expression="^test_say_pl_04$">
|
||||
<action application="log" data="INFO Test: say pl: ${strftime()}"/>
|
||||
<action application="say" data="pl TIME_MEASUREMENT pronounced ${strftime()}"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
<action application="transfer" data="test_say_pl_04"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="test_say_pl_05">
|
||||
<condition field="destination_number" expression="^test_say_pl_05$">
|
||||
<action application="log" data="INFO Test: say pl: ${strftime()}"/>
|
||||
<action application="say" data="pl current_date_time pronounced ${strepoch()}"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
<action application="transfer" data="test_say_pl_05"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="test_say_pl_06">
|
||||
<condition field="destination_number" expression="^test_say_pl_06$">
|
||||
<action application="log" data="INFO Test: say pl: ${strftime()}"/>
|
||||
<action application="say" data="pl current_date pronounced ${strepoch()}"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
<action application="transfer" data="test_say_pl_06"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="test_say_pl_07">
|
||||
<condition field="destination_number" expression="^test_say_pl_07$">
|
||||
<action application="log" data="INFO Test: say pl: ${strftime()}"/>
|
||||
<action application="say" data="pl short_date_time pronounced ${strepoch()}"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
<action application="transfer" data="test_say_pl_07"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="test_say_pl_11">
|
||||
<condition field="destination_number" expression="^test_say_pl_11$">
|
||||
<action application="set" data="i1=${expr(randomize(&x);ceil(random(0,255,&x)))}"/>
|
||||
<action application="set" data="i2=${expr(randomize(&x);ceil(random(0,255,&x)))}"/>
|
||||
<action application="set" data="i3=${expr(randomize(&x);ceil(random(0,255,&x)))}"/>
|
||||
<action application="set" data="i4=${expr(randomize(&x);ceil(random(0,255,&x)))}"/>
|
||||
<action application="log" data="INFO Test: say pl: ${i1}.${i2}.${i3}.${i4}"/>
|
||||
<action application="say" data="pl IP_ADDRESS pronounced ${i1}.${i2}.${i3}.${i4}"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
<action application="transfer" data="test_pl_11"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
</include>
|
|
@ -0,0 +1,19 @@
|
|||
<include>
|
||||
<language name="pl" say-module="PL" sound-prefix="$${sounds_dir}/pl/espeak">
|
||||
<phrases>
|
||||
<macros>
|
||||
</macros>
|
||||
</phrases>
|
||||
</language>
|
||||
</include>
|
||||
<!--
|
||||
For Emacs:
|
||||
Local Variables:
|
||||
mode:xml
|
||||
indent-tabs-mode:nil
|
||||
tab-width:2
|
||||
c-basic-offset:2
|
||||
End:
|
||||
For VIM:
|
||||
vim:set softtabstop=2 shiftwidth=2 tabstop=2 expandtab:
|
||||
-->
|
|
@ -0,0 +1,358 @@
|
|||
#!/bin/bash
|
||||
|
||||
TTS=espeak
|
||||
TTS_OPTS="-a90 -b1 -s130 -p77"
|
||||
|
||||
######################
|
||||
# directories for voice files
|
||||
######################
|
||||
|
||||
rm -rf pl/epeak
|
||||
mkdir -p pl/espeak/digits/HD
|
||||
mkdir -p pl/espeak/time/HD
|
||||
mkdir -p pl/espeak/digits/16000
|
||||
mkdir -p pl/espeak/time/16000
|
||||
mkdir -p pl/espeak/digits/8000
|
||||
mkdir -p pl/espeak/time/8000
|
||||
|
||||
######################
|
||||
# create sound files
|
||||
######################
|
||||
|
||||
function mksound {
|
||||
local TYPE=$1; shift
|
||||
local FILE=$1; shift
|
||||
local TEXT=$*
|
||||
|
||||
${TTS} ${TTS_OPTS} -v pl -w pl/espeak/${TYPE}/HD/${FILE}.wav "${TEXT}"
|
||||
sox pl/espeak/${TYPE}/HD/${FILE}.wav -r 16000 pl/espeak/${TYPE}/16000/${FILE}.wav
|
||||
sox pl/espeak/${TYPE}/HD/${FILE}.wav -r 8000 pl/espeak/${TYPE}/8000/${FILE}.wav
|
||||
|
||||
echo "${TYPE} ${FILE}... done."
|
||||
}
|
||||
|
||||
######################
|
||||
# IVR messages
|
||||
######################
|
||||
|
||||
TYPE=digits
|
||||
|
||||
while read FILE TEXT
|
||||
do
|
||||
if [ "${FILE}" != "#" ]
|
||||
then
|
||||
mksound ${TYPE} ${FILE} ${TEXT}
|
||||
else
|
||||
echo "Comment: ${TEXT}"
|
||||
fi
|
||||
done <<'EOT'
|
||||
# l. główne, r.męski, mianownik
|
||||
0 zero
|
||||
1 jeden
|
||||
2 dwa
|
||||
3 trzy
|
||||
4 cztery
|
||||
5 pięć
|
||||
6 sześć
|
||||
7 siedem
|
||||
8 osiem
|
||||
9 dziewięć
|
||||
10 dziesięć
|
||||
11 jedenaście
|
||||
12 dwanaście
|
||||
13 trzynaście
|
||||
14 czternaście
|
||||
15 pietnaście
|
||||
16 szesnaście
|
||||
17 siedemnaście
|
||||
18 osiemnaście
|
||||
19 dziewiętnaście
|
||||
20 dwadzieścia
|
||||
30 trzydzieści
|
||||
40 czterdzieści
|
||||
50 pięćdziesiąt
|
||||
60 sześćdziesiąt
|
||||
70 siedemdziesiąt
|
||||
80 osiemdziesiąc
|
||||
90 dziewięćdziesiąt
|
||||
100 sto
|
||||
200 dwieście
|
||||
300 trzysta
|
||||
400 czterysta
|
||||
500 pięćset
|
||||
600 sześćset
|
||||
700 siedemset
|
||||
800 osiemset
|
||||
900 dziewięćset
|
||||
1000 tysiąc
|
||||
1000a tysiące
|
||||
1000s tysięcy
|
||||
1000000 milion
|
||||
1000000a miliony
|
||||
1000000s milionów
|
||||
# l. główne, r.żeński, mianownik
|
||||
1_f jedna
|
||||
2_f dwie
|
||||
# l. główne, r.nijaki, mianownik
|
||||
1_n jedno
|
||||
2_n dwie
|
||||
# l. porządowe, r.męski, mianownik
|
||||
0_pm zerowy
|
||||
1_pm pierwszy
|
||||
2_pm drugi
|
||||
3_pm trzeci
|
||||
4_pm czwarty
|
||||
5_pm piąty
|
||||
6_pm szósty
|
||||
7_pm siódmy
|
||||
8_pm ósmy
|
||||
9_pm dziewiąty
|
||||
10_pm dziesiąty
|
||||
11_pm jedenasty
|
||||
12_pm dwunasty
|
||||
13_pm trzynasty
|
||||
14_pm czternasty
|
||||
15_pm piętnasty
|
||||
16_pm szesnasty
|
||||
17_pm siedemnasty
|
||||
18_pm osiemnasty
|
||||
19_pm dziewiętnasty
|
||||
20_pm dwudziesty
|
||||
30_pm trzydziesty
|
||||
40_pm czterdziesty
|
||||
50_pm pięćdziesiąty
|
||||
60_pm sześćdziesiąty
|
||||
70_pm siedemdziesiąty
|
||||
80_pm osiemdziesiąty
|
||||
90_pm dziewięćdziesiąty
|
||||
100_pm setny
|
||||
200_pm dwusetny
|
||||
300_pm trzysetny
|
||||
400_pm czterysetny
|
||||
500_pm pięćsetny
|
||||
600_pm sześćsetny
|
||||
700_pm siedemsetny
|
||||
800_pm osiemsetny
|
||||
900_pm dziewięćsetny
|
||||
1000_pm tysięczny
|
||||
# l. porządowe specjane - numery dni, r.męski, mianownik
|
||||
01_pm pierwszy
|
||||
02_pm drugi
|
||||
03_pm trzeci
|
||||
04_pm czwarty
|
||||
05_pm piąty
|
||||
06_pm szósty
|
||||
07_pm siódmy
|
||||
08_pm ósmy
|
||||
09_pm dziewiąty
|
||||
21_pm dwudziesty pierwszy
|
||||
22_pm dwudziesty drugi
|
||||
23_pm dwudziesty trzeci
|
||||
24_pm dwudziesty czwarty
|
||||
25_pm dwudziesty piąty
|
||||
26_pm dwudziesty szósty
|
||||
27_pm dwudziesty siódmy
|
||||
28_pm dwudziesty ósmy
|
||||
29_pm dwudziesty dziewiąty
|
||||
31_pm trzydziesty pierwszy
|
||||
|
||||
# l. porządowe, r.żeski, mianownik
|
||||
0_pf zerowa
|
||||
1_pf pierwsza
|
||||
2_pf druga
|
||||
3_pf trzecia
|
||||
4_pf czwarta
|
||||
5_pf piąta
|
||||
6_pf szósta
|
||||
7_pf siódma
|
||||
8_pf ósma
|
||||
9_pf dziewiąta
|
||||
10_pf dziesiąta
|
||||
11_pf jedenasta
|
||||
12_pf dwunasta
|
||||
13_pf trzynasta
|
||||
14_pf czternasta
|
||||
15_pf piętnasta
|
||||
16_pf szesnasta
|
||||
17_pf siedemnasta
|
||||
18_pf osiemnasta
|
||||
19_pf dziewiętnasta
|
||||
20_pf dwudziesta
|
||||
30_pf trzydziesta
|
||||
40_pf czterdziesta
|
||||
50_pf pięćdziesiąta
|
||||
60_pf sześćdziesiąta
|
||||
70_pf siedemdziesiąta
|
||||
80_pf osiemdziesiąta
|
||||
90_pf dziewięćdziesiąta
|
||||
100_pf setna
|
||||
200_pf dwusetna
|
||||
300_pf trzysetna
|
||||
400_pf czterysetna
|
||||
500_pf pięćsetna
|
||||
600_pf sześćsetna
|
||||
700_pf siedemsetna
|
||||
800_pf osiemsetna
|
||||
900_pf dziewięćsetna
|
||||
1000_pf tysięczna
|
||||
# l. porządowe, r.męski, dopełniacz
|
||||
0_pmD zerowego
|
||||
1_pmD pierwszego
|
||||
2_pmD drugiego
|
||||
3_pmD trzeciego
|
||||
4_pmD czwartego
|
||||
5_pmD piątego
|
||||
6_pmD szóstego
|
||||
7_pmD siódmego
|
||||
8_pmD ósmego
|
||||
9_pmD dziewiątego
|
||||
10_pmD dziesiątego
|
||||
11_pmD jedenastego
|
||||
12_pmD dwunastego
|
||||
13_pmD trzynastego
|
||||
14_pmD czternastego
|
||||
15_pmD piętnastego
|
||||
16_pmD szesnastego
|
||||
17_pmD siedemnastego
|
||||
18_pmD osiemnastego
|
||||
19_pmD dziewiętnastego
|
||||
20_pmD dwudziestego
|
||||
30_pmD trzydziestego
|
||||
40_pmD czterdziestego
|
||||
50_pmD pięćdziesiątego
|
||||
60_pmD sześćdziesiątego
|
||||
70_pmD siedemdziesiątego
|
||||
80_pmD osiemdziesiątego
|
||||
90_pmD dziewięćdziesiątego
|
||||
100_pmD setnego
|
||||
200_pmD dwusetnego
|
||||
300_pmD trzysetnego
|
||||
400_pmD czterysetnego
|
||||
500_pmD pięćsetnego
|
||||
600_pmD sześćsetnego
|
||||
700_pmD siedemsetnego
|
||||
800_pmD osiemsetnego
|
||||
900_pmD dziewięćsetnego
|
||||
1000_pmD tysięcznego
|
||||
# l. porządowe, r.żeski, dopełniacz
|
||||
0_pfD zerowej
|
||||
1_pfD pierwszej
|
||||
2_pfD drugiej
|
||||
3_pfD trzeciej
|
||||
4_pfD czwartej
|
||||
5_pfD piątej
|
||||
6_pfD szóstej
|
||||
7_pfD siódmej
|
||||
8_pfD ósmej
|
||||
9_pfD dziewiątej
|
||||
10_pfD dziesiątej
|
||||
11_pfD jedenastej
|
||||
12_pfD dwunastej
|
||||
13_pfD trzynastej
|
||||
14_pfD czternastej
|
||||
15_pfD piętnastej
|
||||
16_pfD szesnastej
|
||||
17_pfD siedemnastej
|
||||
18_pfD osiemnastej
|
||||
19_pfD dziewiętnastej
|
||||
20_pfD dwudziestej
|
||||
30_pfD trzydziestej
|
||||
40_pfD czterdziestej
|
||||
50_pfD pięćdziesiątej
|
||||
60_pfD sześćdziesiątej
|
||||
70_pfD siedemdziesiątej
|
||||
80_pfD osiemdziesiątej
|
||||
90_pfD dziewięćdziesiątej
|
||||
100_pfD setnej
|
||||
200_pfD dwusetnej
|
||||
300_pfD trzysetnej
|
||||
400_pfD czterysetnej
|
||||
500_pfD pięćsetnej
|
||||
600_pfD sześćsetnej
|
||||
700_pfD siedemsetnej
|
||||
800_pfD osiemsetnej
|
||||
900_pfD dziewięćsetnej
|
||||
1000_pfD tysięcznej
|
||||
# dodatkowe
|
||||
star gwiazdka
|
||||
star_C gwiazdkę
|
||||
pound krzyżyk
|
||||
dot kropka
|
||||
dot_C kropkę
|
||||
coma przecinek
|
||||
EOT
|
||||
|
||||
TYPE=time
|
||||
|
||||
while read FILE TEXT
|
||||
do
|
||||
if [ "${FILE}" != "#" ]
|
||||
then
|
||||
mksound ${TYPE} ${FILE} ${TEXT}
|
||||
else
|
||||
echo "Comment: ${TEXT}"
|
||||
fi
|
||||
done <<'EOT'
|
||||
# l. jednostki czasu
|
||||
t_sekunda sekunda
|
||||
t_sekundy sekundy
|
||||
t_sekund sekund
|
||||
t_minuta minuta
|
||||
t_minuty minuty
|
||||
t_minut minut
|
||||
t_godzina godzina
|
||||
t_godziny godziny
|
||||
t_godzin godzin
|
||||
t_dzien dzień
|
||||
t_dni dni
|
||||
t_tydzien tydzień
|
||||
t_tygodnie tygodnie
|
||||
t_tygodni tygodni
|
||||
t_miesiac miesiąc
|
||||
t_miesiace miesiące
|
||||
t_miesiecy miesięcy
|
||||
t_rok rok
|
||||
t_roku roku
|
||||
t_lata lata
|
||||
t_lat lat
|
||||
# dni tygodnia, mianownik
|
||||
day-0 niedziela
|
||||
day-1 poniedziałek
|
||||
day-2 wtorek
|
||||
day-3 środa
|
||||
day-4 czwartek
|
||||
day-5 piątek
|
||||
day-6 sobota
|
||||
# miesiące, mianownik
|
||||
mon-0 styczeń
|
||||
mon-1 luty
|
||||
mon-2 marzec
|
||||
mon-3 kwiecień
|
||||
mon-4 maj
|
||||
mon-5 czerwiec
|
||||
mon-6 lipiec
|
||||
mon-7 sierpień
|
||||
mon-8 wrzesień
|
||||
mon-9 październik
|
||||
mon-10 listopad
|
||||
mon-11 grudzień
|
||||
# miesiące, dopełniacz
|
||||
mon-0_D stycznia
|
||||
mon-1_D lutego
|
||||
mon-2_D marca
|
||||
mon-3_D kwietnia
|
||||
mon-4_D maja
|
||||
mon-5_D czerwieca
|
||||
mon-6_D lipieca
|
||||
mon-7_D sierpnia
|
||||
mon-8_D września
|
||||
mon-9_D października
|
||||
mon-10_D listopada
|
||||
mon-11_D grudnia
|
||||
# dodatkowe
|
||||
t_wczoraj wczoraj
|
||||
t_dzisiaj dzisiaj
|
||||
t_jutro jutro
|
||||
EOT
|
||||
|
||||
echo "ALL DONE."
|
|
@ -0,0 +1,673 @@
|
|||
/*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Michael B. Murdock <mike@mmurdock.org>
|
||||
* Mariusz Czułada <manieq.net@gmail.com>
|
||||
*
|
||||
* mod_say_pl.c -- Say for Polish
|
||||
*
|
||||
*/
|
||||
|
||||
#include <switch.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_say_pl_load);
|
||||
SWITCH_MODULE_DEFINITION(mod_say_pl, mod_say_pl_load, NULL, NULL);
|
||||
|
||||
|
||||
#define say_num(_sh, num, meth, gen) { \
|
||||
char tmp[80]; \
|
||||
switch_status_t tstatus; \
|
||||
switch_say_method_t smeth = say_args->method; \
|
||||
switch_say_type_t stype = say_args->type; \
|
||||
switch_say_gender_t sgen = say_args->gender; \
|
||||
say_args->type = SST_ITEMS; say_args->method = meth; \
|
||||
say_args->gender = gen; \
|
||||
switch_snprintf(tmp, sizeof(tmp), "%u", (unsigned)num); \
|
||||
if ((tstatus = \
|
||||
pl_say_general_count(_sh, tmp, say_args)) \
|
||||
!= SWITCH_STATUS_SUCCESS) { \
|
||||
return tstatus; \
|
||||
} \
|
||||
say_args->method = smeth; say_args->type = stype; \
|
||||
say_args->gender = sgen; \
|
||||
} \
|
||||
|
||||
static switch_status_t play_group(switch_say_method_t method, switch_say_gender_t gender, int a, int b, int c, char *what, switch_say_file_handle_t *sh)
|
||||
{
|
||||
char tmp[80];
|
||||
|
||||
if (a) {
|
||||
switch_say_file(sh, "digits/%d00", a);
|
||||
}
|
||||
|
||||
if (b) {
|
||||
if (b > 1) {
|
||||
if ((method == SSM_COUNTED)) {
|
||||
if (gender == SSG_MASCULINE)
|
||||
switch_say_file(sh, "digits/%d0_pm", b);
|
||||
else if (gender == SSG_FEMININE)
|
||||
switch_say_file(sh, "digits/%d0_pf", b);
|
||||
else if (gender == SSG_NEUTER)
|
||||
switch_say_file(sh, "digits/%d0_pn", b);
|
||||
} else {
|
||||
switch_say_file(sh, "digits/%d0", b);
|
||||
}
|
||||
} else {
|
||||
if ((method == SSM_COUNTED)) {
|
||||
if (gender == SSG_MASCULINE)
|
||||
switch_say_file(sh, "digits/%d%d_pm", b, c);
|
||||
else if (gender == SSG_FEMININE)
|
||||
switch_say_file(sh, "digits/%d%d_pf", b, c);
|
||||
else if (gender == SSG_NEUTER)
|
||||
switch_say_file(sh, "digits/%d%d_pn", b, c);
|
||||
} else {
|
||||
switch_say_file(sh, "digits/%d%d", b, c);
|
||||
}
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (c) {
|
||||
if (method == SSM_COUNTED) {
|
||||
if (gender == SSG_MASCULINE && b != 1 && (c == 1 || c == 2)) {
|
||||
switch_say_file(sh, "digits/%d_pm", c);
|
||||
} else if (gender == SSG_FEMININE && b != 1 && (c == 1 || c == 2)) {
|
||||
switch_say_file(sh, "digits/%d_pf", c);
|
||||
} else {
|
||||
switch_say_file(sh, "digits/%d_pn", c);
|
||||
}
|
||||
} else {
|
||||
if (gender == SSG_FEMININE && b != 1 && (c == 1 || c == 2)) {
|
||||
switch_say_file(sh, "digits/%d_f", c);
|
||||
} else {
|
||||
switch_say_file(sh, "digits/%d", c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (what && (a || b || c)) {
|
||||
if (!a && !b && c == 1) {
|
||||
switch_snprintf(tmp, sizeof(tmp), "%s", what);
|
||||
} else if (b != 1 && (c == 2 || c == 3 || c == 4)) {
|
||||
switch_snprintf(tmp, sizeof(tmp), "%sa", what);
|
||||
} else if (a*100+b*10+c > 4) {
|
||||
switch_snprintf(tmp, sizeof(tmp), "%ss", what);
|
||||
}
|
||||
switch_say_file(sh, tmp);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t pl_say_general_count(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args)
|
||||
{
|
||||
int in;
|
||||
int x = 0;
|
||||
int places[9] = { 0 };
|
||||
char sbuf[128] = "";
|
||||
switch_status_t status;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "SAY: %s\n", tosay);
|
||||
|
||||
if (say_args->method == SSM_ITERATED) {
|
||||
if ((tosay = switch_strip_commas(tosay, sbuf, sizeof(sbuf)-1))) {
|
||||
char *p;
|
||||
for (p = tosay; p && *p; p++) {
|
||||
switch_say_file(sh, "digits/%c", *p);
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!(tosay = switch_strip_commas(tosay, sbuf, sizeof(sbuf)-1)) || strlen(tosay) > 9) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
in = atoi(tosay);
|
||||
|
||||
if (in != 0) {
|
||||
for (x = 8; x >= 0; x--) {
|
||||
int num = (int) pow(10, x);
|
||||
if ((places[(uint32_t) x] = in / num)) {
|
||||
in -= places[(uint32_t) x] * num;
|
||||
}
|
||||
}
|
||||
|
||||
switch (say_args->method) {
|
||||
case SSM_COUNTED:
|
||||
case SSM_PRONOUNCED:
|
||||
if ((status = play_group(SSM_PRONOUNCED, say_args->gender, places[8], places[7], places[6], "digits/1000000", sh)) != SWITCH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
if ((status = play_group(SSM_PRONOUNCED, say_args->gender, places[5], places[4], places[3], "digits/1000", sh)) != SWITCH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
if ((status = play_group(say_args->method, say_args->gender, places[2], places[1], places[0], NULL, sh)) != SWITCH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch_say_file(sh, "digits/0");
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t pl_say_time(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args)
|
||||
{
|
||||
int32_t t;
|
||||
switch_time_t target = 0, target_now = 0;
|
||||
switch_time_exp_t tm, tm_now;
|
||||
uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0;
|
||||
const char *tz = NULL;
|
||||
|
||||
tz = switch_say_file_handle_get_variable(sh, "timezone");
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "SAY: %s\n", tosay);
|
||||
|
||||
if (say_args->type == SST_TIME_MEASUREMENT) {
|
||||
int64_t hours = 0;
|
||||
int64_t minutes = 0;
|
||||
int64_t seconds = 0;
|
||||
int64_t r = 0;
|
||||
|
||||
if (strchr(tosay, ':')) {
|
||||
char *tme = strdup(tosay);
|
||||
char *p;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse time string!\n");
|
||||
if ((p = strrchr(tme, ':'))) {
|
||||
*p++ = '\0';
|
||||
seconds = atoi(p);
|
||||
if ((p = strchr(tme, ':'))) {
|
||||
*p++ = '\0';
|
||||
minutes = atoi(p);
|
||||
if (tme) {
|
||||
hours = atoi(tme);
|
||||
}
|
||||
} else {
|
||||
minutes = atoi(tme);
|
||||
}
|
||||
}
|
||||
free(tme);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse time in seconds!\n");
|
||||
if ((seconds = atol(tosay)) <= 0) {
|
||||
seconds = (int64_t) switch_epoch_time_now(NULL);
|
||||
}
|
||||
|
||||
if (seconds >= 60) {
|
||||
minutes = seconds / 60;
|
||||
r = seconds % 60;
|
||||
seconds = r;
|
||||
}
|
||||
|
||||
if (minutes >= 60) {
|
||||
hours = minutes / 60;
|
||||
r = minutes % 60;
|
||||
minutes = r;
|
||||
}
|
||||
}
|
||||
|
||||
if (hours) {
|
||||
int hd = 0, hj = 0;
|
||||
say_num(sh, hours, SSM_PRONOUNCED, SSG_FEMININE);
|
||||
hj = hours % 10;
|
||||
hd = (hours/10) % 10;
|
||||
if (hours == 1) {
|
||||
switch_say_file(sh, "time/t_godzina");
|
||||
}else if (hd != 1 && ( hj == 2 || hj == 3 || hj == 4)) {
|
||||
switch_say_file(sh, "time/t_godziny");
|
||||
} else {
|
||||
switch_say_file(sh, "time/t_godzin");
|
||||
}
|
||||
} else {
|
||||
switch_say_file(sh, "digits/0");
|
||||
switch_say_file(sh, "time/t_godzin");
|
||||
}
|
||||
|
||||
if (minutes) {
|
||||
int md = 0, mj = 0;
|
||||
say_num(sh, minutes, SSM_PRONOUNCED, SSG_FEMININE);
|
||||
mj = minutes % 10;
|
||||
md = (minutes/10) % 10;
|
||||
if (minutes == 1) {
|
||||
switch_say_file(sh, "time/minuta");
|
||||
}else if (md != 1 && ( mj == 2 || mj == 3 || mj == 4)) {
|
||||
switch_say_file(sh, "time/t_minuty");
|
||||
} else {
|
||||
switch_say_file(sh, "time/t_minut");
|
||||
}
|
||||
} else {
|
||||
switch_say_file(sh, "digits/0");
|
||||
switch_say_file(sh, "time/t_minut");
|
||||
}
|
||||
|
||||
if (seconds) {
|
||||
int sd = 0, sj = 0;
|
||||
say_num(sh, seconds, SSM_PRONOUNCED, SSG_FEMININE);
|
||||
sj = seconds % 10;
|
||||
sd = (seconds/10) % 10;
|
||||
if (seconds == 1) {
|
||||
switch_say_file(sh, "time/t_sekunda");
|
||||
}else if (sd != 1 && ( sj == 2 || sj == 3 || sj == 4)) {
|
||||
switch_say_file(sh, "time/t_sekundy");
|
||||
} else {
|
||||
switch_say_file(sh, "time/t_sekund");
|
||||
}
|
||||
} else {
|
||||
switch_say_file(sh, "digits/0");
|
||||
switch_say_file(sh, "time/t_sekund");
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if ((t = atol(tosay)) > 0) {
|
||||
target = switch_time_make(t, 0);
|
||||
target_now = switch_micro_time_now();
|
||||
} else {
|
||||
target = switch_micro_time_now();
|
||||
target_now = switch_micro_time_now();
|
||||
}
|
||||
|
||||
if (tz) {
|
||||
int check = atoi(tz);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz);
|
||||
if (check) {
|
||||
switch_time_exp_tz(&tm, target, check);
|
||||
switch_time_exp_tz(&tm_now, target_now, check);
|
||||
} else {
|
||||
switch_time_exp_tz_name(tz, &tm, target);
|
||||
switch_time_exp_tz_name(tz, &tm_now, target_now);
|
||||
}
|
||||
} else {
|
||||
switch_time_exp_lt(&tm, target);
|
||||
switch_time_exp_lt(&tm_now, target_now);
|
||||
}
|
||||
|
||||
switch (say_args->type) {
|
||||
case SST_CURRENT_DATE_TIME:
|
||||
say_date = say_time = 1;
|
||||
break;
|
||||
case SST_CURRENT_DATE:
|
||||
say_date = 1;
|
||||
break;
|
||||
case SST_CURRENT_TIME:
|
||||
say_time = 1;
|
||||
break;
|
||||
case SST_SHORT_DATE_TIME:
|
||||
say_time = 1;
|
||||
if (tm.tm_year != tm_now.tm_year) {
|
||||
say_date = 1;
|
||||
break;
|
||||
}
|
||||
if (tm.tm_yday == tm_now.tm_yday) {
|
||||
say_today = 1;
|
||||
break;
|
||||
}
|
||||
if (tm.tm_yday == tm_now.tm_yday - 1) {
|
||||
say_yesterday = 1;
|
||||
break;
|
||||
}
|
||||
if (tm.tm_yday >= tm_now.tm_yday - 5) {
|
||||
say_dow = 1;
|
||||
break;
|
||||
}
|
||||
if (tm.tm_mon != tm_now.tm_mon) {
|
||||
say_month = say_day = say_dow = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
say_month = say_day = say_dow = 1;
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (say_today) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: today\n");
|
||||
switch_say_file(sh, "time/t_dzisiaj");
|
||||
}
|
||||
if (say_yesterday) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: yesterday\n");
|
||||
switch_say_file(sh, "time/t_wczoraj");
|
||||
}
|
||||
if (say_dow) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: dow\n");
|
||||
switch_say_file(sh, "time/day-%d", tm.tm_wday);
|
||||
}
|
||||
|
||||
if (say_date) {
|
||||
say_year = say_month = say_day = say_dow = 1;
|
||||
say_today = say_yesterday = 0;
|
||||
}
|
||||
|
||||
if (say_day) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: day\n");
|
||||
//say_num(sh, tm.tm_mday, SSM_COUNTED, SSG_MASCULINE);
|
||||
switch_say_file(sh, "digits/%02d_pm", tm.tm_mday);
|
||||
}
|
||||
if (say_month) {
|
||||
switch_say_file(sh, "time/mon-%d_D", tm.tm_mon);
|
||||
}
|
||||
if (say_year) {
|
||||
say_num(sh, tm.tm_year + 1900, SSM_COUNTED, SSG_MASCULINE);
|
||||
//switch_say_file(sh, "time/t_roku");
|
||||
}
|
||||
|
||||
if (say_time) {
|
||||
switch_say_file(sh, "time/t_godzina");
|
||||
say_num(sh, tm.tm_hour, SSM_COUNTED, SSG_FEMININE);
|
||||
//switch_say_file(sh, "digits/%da", tm.tm_hour);
|
||||
|
||||
say_num(sh, tm.tm_min, SSM_PRONOUNCED, SSG_FEMININE);
|
||||
/* switch_say_file(sh, "digits/t_minut");*/
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static switch_status_t pl_say_money(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args)
|
||||
{
|
||||
char sbuf[16] = ""; /* enough for 999,999,999,999.99 (w/o the commas or leading $) */
|
||||
char *dollars = NULL;
|
||||
char *cents = NULL;
|
||||
|
||||
if (strlen(tosay) > 15 || !(tosay = switch_strip_nonnumerics(tosay, sbuf, sizeof(sbuf)-1))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
dollars = sbuf;
|
||||
|
||||
if ((cents = strchr(sbuf, '.'))) {
|
||||
*cents++ = '\0';
|
||||
if (strlen(cents) > 2) {
|
||||
cents[2] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* If positive sign - skip over" */
|
||||
if (sbuf[0] == '+') {
|
||||
dollars++;
|
||||
}
|
||||
|
||||
/* If negative say "negative" */
|
||||
if (sbuf[0] == '-') {
|
||||
switch_say_file(sh, "currency/negative");
|
||||
dollars++;
|
||||
}
|
||||
|
||||
/* Say dollar amount */
|
||||
pl_say_general_count(sh, dollars, say_args);
|
||||
if (atoi(dollars) == 1) {
|
||||
switch_say_file(sh, "currency/dollar");
|
||||
} else {
|
||||
switch_say_file(sh, "currency/dollars");
|
||||
}
|
||||
|
||||
/* Say cents */
|
||||
if (cents) {
|
||||
/* Say "and" */
|
||||
switch_say_file(sh, "currency/and");
|
||||
|
||||
pl_say_general_count(sh, cents, say_args);
|
||||
if (atoi(cents) == 1) {
|
||||
switch_say_file(sh, "currency/cent");
|
||||
} else {
|
||||
switch_say_file(sh, "currency/cents");
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static switch_status_t pl_say_ip(switch_say_file_handle_t *sh,
|
||||
char *tosay,
|
||||
switch_say_args_t *say_args)
|
||||
|
||||
{
|
||||
char *a, *b, *c, *d;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
if (!(a = strdup(tosay))) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (!(b = strchr(a, '.'))) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
*b++ = '\0';
|
||||
|
||||
if (!(c = strchr(b, '.'))) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
*c++ = '\0';
|
||||
|
||||
if (!(d = strchr(c, '.'))) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
*d++ = '\0';
|
||||
|
||||
say_num(sh, atoi(a), say_args->method, SSG_MASCULINE);
|
||||
switch_say_file(sh, "digits/dot");
|
||||
say_num(sh, atoi(b), say_args->method, SSG_MASCULINE);
|
||||
switch_say_file(sh, "digits/dot");
|
||||
say_num(sh, atoi(c), say_args->method, SSG_MASCULINE);
|
||||
switch_say_file(sh, "digits/dot");
|
||||
say_num(sh, atoi(d), say_args->method, SSG_MASCULINE);
|
||||
|
||||
end:
|
||||
|
||||
free(a);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static switch_status_t pl_say_spell(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args)
|
||||
{
|
||||
char *p;
|
||||
|
||||
for (p = tosay; p && *p; p++) {
|
||||
int a = tolower((int) *p);
|
||||
if (a >= '0' && a <= '9') {
|
||||
switch_say_file(sh, "digits/%c", a);
|
||||
} else {
|
||||
if (say_args->type == SST_NAME_SPELLED) {
|
||||
switch_say_file(sh, "ascii/%d", a);
|
||||
} else if (say_args->type == SST_NAME_PHONETIC) {
|
||||
switch_say_file(sh, "phonetic-ascii/%d", a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* pl */
|
||||
static switch_new_say_callback_t choose_callback(switch_say_args_t *say_args)
|
||||
{
|
||||
switch_new_say_callback_t say_cb = NULL;
|
||||
|
||||
switch (say_args->type) {
|
||||
case SST_NUMBER:
|
||||
case SST_ITEMS:
|
||||
case SST_PERSONS:
|
||||
case SST_MESSAGES:
|
||||
say_cb = pl_say_general_count;
|
||||
break;
|
||||
case SST_TIME_MEASUREMENT:
|
||||
case SST_CURRENT_DATE:
|
||||
case SST_CURRENT_TIME:
|
||||
case SST_CURRENT_DATE_TIME:
|
||||
case SST_SHORT_DATE_TIME:
|
||||
say_cb = pl_say_time;
|
||||
break;
|
||||
case SST_IP_ADDRESS:
|
||||
say_cb = pl_say_ip;
|
||||
break;
|
||||
case SST_NAME_SPELLED:
|
||||
case SST_NAME_PHONETIC:
|
||||
say_cb = pl_say_spell;
|
||||
break;
|
||||
case SST_CURRENCY:
|
||||
say_cb = pl_say_money;
|
||||
break;
|
||||
default:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown Say type=[%d]\n", say_args->type);
|
||||
break;
|
||||
}
|
||||
|
||||
return say_cb;
|
||||
}
|
||||
|
||||
|
||||
static switch_status_t run_callback(switch_new_say_callback_t say_cb, char *tosay, switch_say_args_t *say_args, switch_core_session_t *session, char **rstr)
|
||||
{
|
||||
switch_say_file_handle_t *sh;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
switch_event_t *var_event = NULL;
|
||||
|
||||
if (session) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_channel_get_variables(channel, &var_event);
|
||||
}
|
||||
|
||||
switch_say_file_handle_create(&sh, say_args->ext, &var_event);
|
||||
|
||||
status = say_cb(sh, tosay, say_args);
|
||||
|
||||
if ((*rstr = switch_say_file_handle_detach_path(sh))) {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_say_file_handle_destroy(&sh);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* PL */
|
||||
static switch_status_t pl_say(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
|
||||
{
|
||||
|
||||
switch_new_say_callback_t say_cb = NULL;
|
||||
char *string = NULL;
|
||||
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
say_cb = choose_callback(say_args);
|
||||
|
||||
if (say_cb) {
|
||||
status = run_callback(say_cb, tosay, say_args, session, &string);
|
||||
if (session && string) {
|
||||
status = switch_ivr_play_file(session, NULL, string, args);
|
||||
}
|
||||
|
||||
switch_safe_free(string);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* PL */
|
||||
static switch_status_t pl_say_string(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, char **rstr)
|
||||
{
|
||||
|
||||
switch_new_say_callback_t say_cb = NULL;
|
||||
char *string = NULL;
|
||||
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
say_cb = choose_callback(say_args);
|
||||
|
||||
if (say_cb) {
|
||||
status = run_callback(say_cb, tosay, say_args, session, &string);
|
||||
if (string) {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
*rstr = string;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_say_pl_load)
|
||||
{
|
||||
switch_say_interface_t *say_interface;
|
||||
/* connect my internal structure to the blank pointer passed to me */
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
say_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SAY_INTERFACE);
|
||||
say_interface->interface_name = "pl";
|
||||
say_interface->say_function = pl_say;
|
||||
say_interface->say_string_function = pl_say_string;
|
||||
|
||||
/* indicate that the module should continue to be loaded */
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
Loading…
Reference in New Issue