From f93071483f2d477a9470fb19290adacccedfea6e Mon Sep 17 00:00:00 2001 From: Jason Parker Date: Wed, 30 Dec 2009 22:30:21 +0000 Subject: [PATCH] Add app_voicemail and say.c support for Vietnamese. Also add an XXX comment that I'm baffled nobody has ever complained about. We say "first message", and then we go into language-specific stuff where we proceed to say..."first message". (closes issue #15053) Reported by: dinhtrung Patches: vietnamese.ods uploaded by dinhtrung (license 776) app_voicemail.c.diff uploaded by dinhtrung (license 776) (closes issue #15626) Reported by: dinhtrung Patches: say.c.diff uploaded by dinhtrung (license 776) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@237050 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_voicemail.c | 81 +++++++++- doc/lang/vietnamese.ods | Bin 0 -> 20503 bytes main/say.c | 336 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 414 insertions(+), 3 deletions(-) create mode 100644 doc/lang/vietnamese.ods diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index c29da2f2c9..ee66a6ef9b 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -6966,6 +6966,8 @@ static int play_message_datetime(struct ast_channel *chan, struct ast_vm_user *v res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); + } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ + res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' A 'digits/day' dB 'digits/year' Y 'digits/at' k 'hours' M 'minutes'", NULL); } else { res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); } @@ -7122,6 +7124,7 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struc } if (!res) { + /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ /* POLISH syntax */ if (!strncasecmp(chan->language, "pl", 2)) { if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { @@ -7159,6 +7162,19 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struc res = wait_file2(chan, vms, "vm-number"); res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); } + /* VIETNAMESE syntax */ + } else if (!strncasecmp(chan->language, "vi", 2)) { + if (!vms->curmsg) { + res = wait_file2(chan, vms, "vm-message"); + res = wait_file2(chan, vms, "vm-first"); + } else if (vms->curmsg == vms->lastmsg) { + res = wait_file2(chan, vms, "vm-message"); + res = wait_file2(chan, vms, "vm-last"); + } else { + res = wait_file2(chan, vms, "vm-message"); + res = wait_file2(chan, vms, "vm-number"); + res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); + } } else { if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ @@ -7492,6 +7508,8 @@ static int vm_play_folder_name(struct ast_channel *chan, char *box) return vm_play_folder_name_pl(chan, box); } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ return vm_play_folder_name_ua(chan, box); + } else if (!strncasecmp(chan->language, "vi", 2)) { + return ast_play_and_wait(chan, box); } else { /* Default English */ cmd = ast_play_and_wait(chan, box); return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ @@ -8365,6 +8383,37 @@ static int vm_intro_zh(struct ast_channel *chan, struct vm_state *vms) return res; } +/* Vietnamese syntax */ +static int vm_intro_vi(struct ast_channel *chan, struct vm_state *vms) +{ + int res; + + /* Introduce messages they have */ + res = ast_play_and_wait(chan, "vm-youhave"); + if (!res) { + if (vms->newmessages) { + res = say_and_wait(chan, vms->newmessages, chan->language); + if (!res) + res = ast_play_and_wait(chan, "vm-INBOX"); + if (vms->oldmessages && !res) + res = ast_play_and_wait(chan, "vm-and"); + } + if (!res && vms->oldmessages) { + res = say_and_wait(chan, vms->oldmessages, chan->language); + if (!res) + res = ast_play_and_wait(chan, "vm-Old"); + } + if (!res) { + if (!vms->oldmessages && !vms->newmessages) { + res = ast_play_and_wait(chan, "vm-no"); + if (!res) + res = ast_play_and_wait(chan, "vm-message"); + } + } + } + return res; +} + static int vm_intro(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) { char prefile[256]; @@ -8417,6 +8466,8 @@ static int vm_intro(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm return vm_intro_se(chan, vms); } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ return vm_intro_multilang(chan, vms, "n"); + } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ + return vm_intro_vi(chan, vms); } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ return vm_intro_zh(chan, vms); } else { /* Default to ENGLISH */ @@ -9012,6 +9063,30 @@ static int vm_browse_messages_zh(struct ast_channel *chan, struct vm_state *vms, return cmd; } +/*! + * \brief Vietnamese syntax for 'You have N messages' greeting. + * \param chan + * \param vms + * \param vmu + * + * \return zero on success, -1 on error. + */ +static int vm_browse_messages_vi(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) +{ + int cmd = 0; + + if (vms->lastmsg > -1) { + cmd = play_message(chan, vmu, vms); + } else { + cmd = ast_play_and_wait(chan, "vm-no"); + if (!cmd) { + snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); + cmd = ast_play_and_wait(chan, vms->fn); + } + } + return cmd; +} + /*! * \brief Top level method to invoke the language variant vm_browse_messages_XX function. * \param chan The channel for the current user. We read the language property from this. @@ -9035,8 +9110,10 @@ static int vm_browse_messages(struct ast_channel *chan, struct vm_state *vms, st return vm_browse_messages_it(chan, vms, vmu); } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ return vm_browse_messages_pt(chan, vms, vmu); - } else if (!strncasecmp(chan->language, "zh", 2)){ - return vm_browse_messages_zh(chan, vms, vmu); /* CHINESE (Taiwan) */ + } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ + return vm_browse_messages_vi(chan, vms, vmu); + } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ + return vm_browse_messages_zh(chan, vms, vmu); } else { /* Default to English syntax */ return vm_browse_messages_en(chan, vms, vmu); } diff --git a/doc/lang/vietnamese.ods b/doc/lang/vietnamese.ods new file mode 100644 index 0000000000000000000000000000000000000000..8094c42f0805de727b91ddf93b7b344ba035de51 GIT binary patch literal 20503 zc-oA*1yE$mvIUCk;O;)SyW0Q*4DPOt)4034yZc~+5AN>n?(XjJ=bUrz{rA22KjQ6< z?5Mr=%9U9aySlR?QeGMy0v+V9E3r14H^_=RoZ-*-FN67G*5=j#M>ku5fvv5TxsidR zxebuf8EDL4W8h%!z+htw024qP}SeIOxhxAb=`?Htzp(AqBb=H5OXow|< zN%G5~LBJcKK%f~_t3xd7)4>OGV)aU9iXpQ@x#cc?796IWmBKIgt2WXN(21SwL@=Bg z#=U2iDII$2J`V%&-B!8AVG0)27StxITvMTb$sJw2jMxA_=Q?X|64X8~FgUPdLG(`R zh+~-dy}PJFHVM~c>MT!YPiftxs+bew&Tz$;Cn~SEaHW~(FI!BaJHF-=RT_Ju6TCWe zFSTXt>UghZ^e?Tnm$iczoVbyKbkOO3bES|Rqt-JWr%(Ff}Ys9)6g6|B(ZDjA?~!yQ(5*GG_0=cCio($mqS9UMq4 z*zL%{w(LM1-zAidK|t6!LRLvYH)Vq8s8mlK%ou7bZs=$T8PwHT?S*85CXtG1pV-@a zQCvPF@+q}?822#h>xH~)uYLIHN#)b_Jm9EPbZwVIF|d#erx=g_YFRdY@E%!nqSB9G zQ8&7{&gJvblm4=a-R`h=m6d3liQ5}M76MHLN7JXlhs1{6*a1c6*+!r2Ssw<0yzGz1 zu`o9{zxAur_M~ycb5|942U`X@0SoB?cAP6;$ruVkV&A{CqvR*#hK#Kg1dcpJYA9px z3wSD6uHi7d5ttZ`S6%o1qM9zfMhmGygQ^ZTh~*m7ah?`^poI&Ud?? zIG=>?9FIVfbb8O<%m>&pU3( zL7T)~WfY@)xPxhSl#%=5T6Y8h{6R+d(t0ruVLb`%ko{rFtx>l!8B(8x4w0^f@{r@j zWJ3si76roDq#N1W{G2Y10cy%>0MwZ#W53zxrGdUMQ=Y3McL8CC=*y0;y59O4pHJG5 zOr1&Fqyl53og!mnO^e<0n|oc#Dql@XYm@uO$w0q}jmvi5k-NeD&HgCf_{PPKWc&K_ zJS{?=G?sN(;`vw`jyAKNv==!;aOxLPhU^aS{T>R}m+7iZ(Fs;gudSte&_be0}YMT;8ylYCGSdj&$s^t$5IMH<)lk8&+X=hBFlGQrOEd zk~)hKJPZ!v=A<8U+kTyZmG+qkG!&fR!#gN16i44*IxK(?H^CngKo1DQ&1!?wMD)T_ z<=wCPbu4`~IQDJR#)7*%hO|asBC(#HRpWkx^fx|Qug+X5ZE7SDNfjseQo&(c#c;O^ zK9B(s%|0okXajbQsW-itFt~$L1=+h)>H&M`6ri|&qw$~BQgra6K*bagC?b| z#83kaPR%y*qrua#mAXUK#X&+qh-W<+NS@W{-u7ZEbi;rbuDjooS>>$%PF5(SBA`J6 zDZl|>%K`ejf(QFi53L+Zxf?SSk(Rt`EG3_u1>xTWob3HGRT(=6d1HhN%{k*(1#YE)m*RI&iO|vY(v}^3^ zt_!~aw`)&(tPEmDoF#!XC}s7V!Ekv16@x(WHg~huRs(|9s;WAl*uFKf%$t~1Y}M9R z`2az3f31y}@(hl98I%N%D8w8elE>`_<2Rgm9!K^&k!Q{L=^lv<3NHYRO+ArEf51{i z-}|eDQV(l+2IC@dfzjnY^!3oImv*0=g!VzUb-~tfbV{%D_cVR~E@OX$dx>Wbx^AIX z#e*6xrZ=$ZhsNn`=U1`dW16(Ofx_f{F3_38B30Q6sjogpEFY+Dpj#gT7+Rl}Vu4;H zLs6GJh@T9Dzhho2CO^)=r>qd`SRC$oC)|Tm;Q=W-CHK#!=UiI3n!%>)EVih3zMGh` z{u=gUXdFB%ZN40^=9^dCyQRx_iPQ~UJ{&Pw^TAdv(1Jgec8Bb zji}FWJikgq9fC*-y{-?FyASJ!VDa~aux%k{Q7S(NN1~6oPIl)o8#_V23*K;1wSRZZS2V9LL&;6B{@JIm`q0gY zwCYLDyq6toGSqo#JLomyEDPlhp~iE@{$MvzQR59;%Q9&h(YC6t6ucW4qnY#O#DcR~ zF_tcT?U75ZPsZ@w-V%5qph>I zL#@uh0gmM}MKLRe{UKCNvr3|1-0!3-`J_0oM-uKQRl@5ibH{t-Lwx0eybYdABdGR@ zScz|oXwqXYBUVn?Ok15FAi-_cC4S^Ae;WlG>;aXkoCC2Y4vfxrsTg#9at!4*hAF97t`wEcrY4Lu}pdpb4KS`Y@oYEc^BUwBI7J<2}BQ~ARLbH4H z*!x+UA6Md8Hg2;f!|Q34FKTx%RBfg_=1vZ}^ma8a|3Nopq@RGePaGZt_S+uas2x~e zJTv%>ny=c;U^gS6I>xhWw4Zcq11~ASH%%th89W)adLC>2Z0bzuusYP}wmtg)B~zY! z)o!u1dWIt%R7G*U80$@d>CH(;J%|@{vfV7WFK~Q_L`Z+R94OOXU$6S>VXni#8n zDNDS;%S+e}GQ~j_L{+QIf3)-~NIAV&_x=|&-}&V1Eqg=QE(>XCTkaeP{rV!(rc80L z>XjKJ?Fm9qbv=O%eb8TsAvhqv7%yS%J1w!}Y1Y~B($_b{;@5(x z6sxFdwfN4K3BflL!^=ClSF9*jYft=usc6>ET+p;OSCgexYjC73R-x5OPnr!+qHiAo z)YBBd&xzdIX7dmPq9jm}Vy+DIbS7NugcvayirhZ*LdbdztCYvGSdeVpJ5%k{@`vzO zfT`gTT7{MOiqnRbw?m%3gx5D1>mVW_53N+|N$V4Ez`VRF;2Y&sMRY(3{@F-h(?HjzLHlE)BiJndpnp0+6{A}k6+i2b~Z@HZ0$dH3~kt6 zSIReJ9F}z!tYh!t%a^?=c!|qF)eaG!7J-uC6vs#_G1fc?<%-$V>t%c%dCy%nsew35YYT+0fICT;~0Q&zfa!3knC7-r+-lJ1PN z?Z`2h;H=3;u+elud2`v~8;EY=xw?AtexD_1IH^x;t*aBXb>l}WaZaS*m$q%=Hvwuj zzL54Ql9)xRTfe-T-$+DSpnBooi52 z4Te^b$nAL)ukm}c%%SX959N1sqMZ3$Cq^>)wC#SYVECw+>==CLqvjX)Z^wMtTdGU z>pVv6n5bjThY_sBB&nV)_JT?C>Ubekh(Ud7$Z@UO?@i?bi(tC3i}#67&J@sOVRB3o zRbiUWSBXYppq>y+&v3UW7T#@AZiAphy_t^c$W<1;*tx08-B)Nm9{P!$bz%{6@t%`& z%1E|IDqaC;+jSS_>Orh@nRe}Jj@8!jOdw*fg+hzdGR8DrPzA~_2Gha!4Z>gJKXn<@ z=`~GtI7Y=E^sPDW?YmdJ;Y;CEQ|^}^EQ8gmTYe$_-XzZTpYPXIr1&)sm&zvHWRJ5z zWwZH!`eT5I$J(RW$fkxP!@XI*{)oetd%MqYS~BIfFkQlwBY-1*qK`f0U0Y-3w?)65 z$)y}3;Xy4#`zR)T1cJ79^qtj0W0OW?ac^~l-gK3J{qo!>q~&Y7Jgs`hUuj>g1pEt9 zxuI3pv5L^{d4cw*{u66hzyEyD_9O49Pi&j!E8Ag{7e5DV1UT095BFAYHHrsE6jJl_ zCeO_0a!h5pQ=L1Nq9c*(eB1j(*L)f$2@)}qY|?ZDI>*8mh2$-)*c_m( zN+ao92RxtTa04SxgZ|m+0!D>k!NOgmg)WJvVo84`E~W~`vJ)Bnv_8#<0k|6rGE3=- zPUt~U{W-aZwsK?d0q!^(E<=Vv;;eb?A`oTLNY{tOn-QiTk3TT$@ht)}D}wVr@ak>Q z*o2UwQzp{9@&!2bRi@TUh^FIa><8A}k9@FptDzquBn(>gkKz0W@8>a}^ew2N205ia zZ<*KN`F06j8U?-iSl7jjc$#h`S#Is&s>{~e&9H9X;F-&<0J$52bOI@3u%%e>O@aMt zb_B?akJA37W_7bK;JW3SXPN7=5)ZK{2+OR$t%aL970&uMZu!fib!wahvsaq{@G#x% zujv5MuXwxx{32)56;{%abC&O*jq(>5NQT4olWzWMG)It>o`UlHqq{o}xY?lD6kQ_1 zugRGFjAul-0cP$?FK8R-&J%HlzZCf#rN39Wl{}O)od6}m$N_eSAzyIsnwCO(wbAa_nzHZ9h_mpBy2GO=c{2JkP8$660W9m z7WIGjEF%!TX{>Q~U}gHv?#M>pJ~#on%M_voJo%+f}@k+m|HNgppe>gnIYD5~Y?z4L`~CnET$bFk{ofkyP)y2%N)+!v~(` z1hNrWqI$jZJ0~#)gKoGWZos^qaM`z(cZ(vBiVbiByG=7XtL)vZ?*AyNGLRhlL4M?#Wn)3`!Q>w=2Iy<~K91La;dzkSqk!(p0W zry0L5kFTFanIxnAwkMxAE~Pru_U!$;BgDI1&NNY8AVBcIKC*?Xm{0Re&wq(Lq#vKx z)kFY*Bik4TS>9jac2VUfAl1#3SZ(z3k@RjzgKpjZ?Q(z#d6-Pd4K<$?8QUnxeu4B3 z;)sS%5h|RzB^10KGerT?G0i(mNfz3!N!6;=X|2JC=)Q5=xE_B@ZJ>KNm)&X1e~o;{ zh_tzwDwJ9E!}$tp2;o9r3Ku0 zw;MHEFMv@|v_~C~cQmY}9uWYq(7Bd3LEk{jn%6PIj0v)8c*=ryRz4B1K8SK~PCLYo za#M>*;u29@!iL^^C|4q@bMhU8+)Pi){Xw|K2isw>`zw{9+iP|r-u)T{xz5)WQA6^n zvGnK_%-RVw4Gdy2L>IPC@D( zbYv92UfQk;o4@8as`@M(E=?d*ddhl(>`LLaUR6RRTvIkLO0Xq1>r}$irHgoHN@SA9 zvCBBMt8Voury?p*(+NaHv7qHeK3*P?9~n32ONkX#7slBp`+O_Ja`xmD{8m1q*AtZD zjC)IbOK~{9#f9UOj%r2LCs9=T5dLY0zbQPj^0=5Cg-g9)S6?DGADPV3-7;H^xSJCg zX_!995AUY{PsL=UW19&lI`Go2@X9h{-No_X4tByC3vGb0gDe5NL4irbL)A?o`XhqD z#P{7*&p02SJX`%>6QU@wx7YOYWXY2xxt2BVr(qJGVC(Y=u94dt$2T)zr`7G-9XyQj^uMbTwhV5objs0sS1*1b1_$g_r>-cU6((sQ%sPQh3o zOwqDP=DlKT3DFZxwg^f`!G1%D(K#j6sBarZvm&GAKZ<*^vH^)8oXCro~_7NaUu^fPI~DIJfY=u8LfE4vP<<^e*{^Y^DN zA$>PtG+)`z3<;8o2qb&>YlluucRzbIsKZDOh+L|((s+EbnDBU9%>@Ox03e3KEMMe^ zozU{*gnW_oXrFYW?PhW0!SR&1^~RzQB$l0l2iu+UrJAG=bw1DJ8rw^9ZVJgI!5w_= zphj>oChnBeG9)W4JOi+Nl~{+EVb5)+kg8~rb4xeE8wLH%e& zweGI+2>ewc;qxMG!>qIw>_H?Hs`T(qmptVUMx!5BbkzpY|8u{+JeWw(8aCo`?x!cRvt@e4W`_*J$?z+?tY&Eq|{GEDR=80 ztClIo{Z#R?TrWVpFF3+Ru0u&F(lXC*EFl#+glSvtKdcY#i3!u#yrpxltN&5AB(5`6 z_W7)Kha8t04Sn1YQH1WdIF4HCe*KvE78q*rT+bvWjhSzk#pHH|CJ2F0bH99uNmiNk zTLs5!=O%HKTW{|c3sbWZ;?o6cg<4%KNx_ON$6Iy{2+am^u4R|tVn!sg3OuQ2Ax(o_ zA}!OPg~>y;`R4a*?yHGWqRU9$cBHz_VFPSFzad;+(N32%fzstNv}dSWY_if|cgVmA zzsoTmi05Fub5GB9qLd&@OTWi5h;@^2_C-eWTuU?de05qv+JBr}5M8KsF4#E-MdtLq z9v<^5nk50Rha&)1&K#>ajjS3xB|$4Bm>A`m%UTUDC&{}7(nQ;rOoR;4e1w98WYCP> zYfTb$8?jZT_DX2$q4YrKTNG$Tzc0dNs}d?Z7Tm?!9zI`(k?S=@+lALXAo2IR^O!YS zhoLb>^V?>76k=@v|F1WWYp9>k-DD65!6Q&8aO zpI=X5qYu}>`Es&#(isCoGIRwAG?!*sim}`WSWupB%$MtV&Jl(@UG=jVlP0b9j-Ow& z%ZHbhlG=64>sG%H7F5$6+i=g!MYb#gSHu;HC(x+7hcsgi*OQo|sxC?K5oZlDwzAM} zV(A&k`DfK&H~k{sUQp|alw(g2MuVF5#fxW#jU=k5E!TsG zu|yQ>k^VPSWow%;SaQkXbY2uR-HF!lO`7{#l1sCxv#CHL*kPMHshL6fg^-SVizd_~ z4enS<9FM(~QAT!V3k-f}gk;(l0x!VF;#qmG3D&|$qh1aNdCWa^b_{4B>PiZ4*di;G z{PUbQa3eLc^BaI`b{jXm(r7~A1Uj^b-uZEyt%)h{b`P)A&~d4l$>nu_3KPWVn{x4P zA~IpEK{&GnC?%%iw+;0zxLMc`{sPbS-!;H%>}XgVw_{JckZ^&*yyp8Nqpo^<)kX^( zuj0cdPF_uw-z!`ihEC)fKjP5`$28p%$v6Xt_p~X$g_h=2uf@0CEVu8Nw|mKka8d=P z1^qOi4Si=}Y}fOIA8bUfG+8Zfu1vjEcT5_gD;%ealPs(ZePKr0zU&v4;QVG0@oc9J zU~hwFi%&8y6Nk}+QX*lVAR?j@QkWC%PF~;jG&<2iujdls(7M}>9WN*Qf*gEs?y}Ce z#-*-gtZURWFwF9O|5Mro&~%ks^xm# za?SLp+8R?XZMvzQeB?hs)nE8BDdj>H!s!DYEpO&nx}qvWW)@a!XakU$S9(P3YsJFg z*=wl9giux2E}zgwMUoqc@Y#!*Lu*S$8%Q0OD%`pR`X%Q&9GnhpIpAKLe2tQF^)uEd zgC_|2z}8(^y#4Wug=Am3dfL29vj;wJBFgGro}}OCoAG&;u(~_MmJ#oRJdK3$c$M81 zH4n5oKi&pp=NeI#&$+sINnl0rl0tL5Y?T|uF&Y+~V1A+P>Zz}EP!h*_0<^FlwHwhR z)qzFw6^h~hJIABDmb%n7$7D}YEZ8J)hJaf}kNv1F=H`~Y0&l%Jtd7Ps*l+h z_V>j}Z;#`h{&8vAmr7rSXqfRgfE<`%hnnztVN=1N;t%@&L2F}qACo#ZwJ>oxyREV1#|V;?WfJ?2cjjwju# z*ZEIqd1+`ECs7T@NfHnc4Qeou|NlM^xIgCL=w=0Q_^SsZfD6+*N6*j9e2$(T zl3YlIB`J{&H|oIPC;LfrTWc4|22|u1Wtv+qLDNUQaYl_*ZLn?Bkl0w`@}i4qFHcW~ zO>TjuzWcYE3y&E*a+IEKkp&_)4S&BV0`w;M=a@|&^>=U z8-8p_M_c6a*@>XcSp8_>zS_4e4e5Qm+cBkYdB`~Vzl z0G%sFP8wQ@1TTcuH)vK(i`kni3`~MILbnk(T8;-%>mxk7no(1rn2SEW=#I5+TI7R3 zL0U3rTl~e}3wa0?Qc3oN%%(NA6OtslW3@mU4^Y~ZK26K;g;-b_(DPinKKlvsiSY5G za8n4mUREa`C6!|(m#R!Ykg9T2VV%t9n6i!O4`exQSaX@m7Rd7Tww*0xB&1?zS_+FTCl0hLyy zeAFel0N8w~S{ijz5l)y*_N{w6y!^z(e@vyr59qeaN51ZguD{Mc2BEMf@7Kw=&*<(^~xs*=HMI<^!Y6A z=UdO7cK7(ns>`clf!vN&_A)9E=+JB_TNB{zQ#t>7n4~4<=S>Rt(^Opeb8c0yC=aZy z^DLmr**)Jf>eZowS;RLc5^VPyI$xG%=7XHAPX8?I%aKS)ha-nzLM@swASOK?TJAPb zW#G;&GMzXS>4*~Q4wxxe#D%55Phe6MQNx4mKK4>HwW=Z0=Q10n|B}R@r=JC0uB_MH zg`YRalhEVeJ&Zy4Rj4?j1}t&cEfr*69*0<{8Ttjf#3^f)qy5?}%L&lN0}xXi*k+Zf zXuzjxsF*ff#bs!y@H1THp=dyu_A1|qxO55vpMPA7xSXf<9NY0=-(#2e! z%g<=@BCL)OE`6JdupDvcFk1P!gH?mZno^rH6*1}ko%{&EB6#x{k2TRGGM8}&^I*0; zoM#5MD<2AY-L2u)4c^OuRqhs{OF}m90R(HR1b*FSu#wF9O*cOS)EL_2uFUi<&+$%k z70as-lC82%4dudU@e6Ay?MEBWlx~fA)yg)wfT@B$@bXZ&niv*3JN zv-gjI|FMuq+g4=KE7X1&65TtBFkY_wn!wGNro1V_^Lu#9rbWhIe!892h@IZs)eccm zqUkL_jE_|>B`~Oa8>zQzt>ZIaO^#HDZ)APE)I0N@vq)7fuig|nIvLnm`B zLw_wHntSptOT=AFs2}SaW&Baanu30&Uc%10XpIDkX=kg{gVLVKz1_);q`p;w-knB5 z30}gxQom1~?%bSje+;n63C0z3o=+oYt=5h7HGLFGgOmk;7n4lar-aN!o_kmfW;`Zp zUiSns&$fjGdrrjcS`T`isLVR6#^OM|5T(mQoe%CjBIXyIj5%ISOW3)DG|tLyQ3pJb zJ>^|HtH|B{xQ+N)VenfJDO8sCob%rNwele=z|4Jacbp<&0b|#i=Eg*LF$m9OF=aYh zVr@eQ<3#0G4*vy-fe8**ag;^+t*;HKW5^IFZ{sG*l@CH^0bzE?c(6<8+%fWZ_Cbjg zx5cw;lji7eZsX;@xgp+y*U*~Do(Sp<>@mV_(&H?g$k+)qUHXuY2|WAjeeNUB<{!HC z^ym0FPGLc*D{WQFZk=6|^@LNcrSq{}hbErwcF1jsujN4;(qTM?%t@AsLv+mH5=26Fm3C^B~lzBYnnh@bMdGRc%-b8DYV$l#T?T}X< zp}(}2&r7j6r7dL*DSP)1BJz?DOTD!?45!mHde~O{u3-APv3iR&nt3_~z0zxJB9QOv zF$mpPyDWZ+Qie%Z=w#-||e(pb!;O zXIV#G^oPv$s_)!=`Z-hI{K8w3(-Sd``nOj1FisX(9Y`5&niF%zB=6_3g(SDscf1Oc zA7LqsjEs{f-bM?k7t8vSpJPeSFHxkL!az$}eT#I%2fZ|!W$3R?n#1(>o*jx>GJ%;Y z{Rdg3CG4z(wP#q^hBM|%lH=8G6kD|vQNs>}6-6=BI+2D|KjOVVl#M&6ti{Sy*{kIC$9E{^k8Yd3?r3Jpb0Qa{*Xc z@iG1v^4HV;wXhc7cCM^wZjiDkrM=86U1VF@A+ebI$ma`RvUN%y9Uj6g*gK~Y352}HqW+|ZgH zD?AoQ1=E%-C&xB6Kk6^<`Mv0q9o7zoh>;_r8-9Xb=|O@q`%d`!l{%*ufo?CxY;@Jsmklz}0D5)vrR02X`nuL(gWWl9d#GeF(OwM=XuLJ7fd8PH_|aLi zj1IZK(2mt>E>GjRohbF==G(!1N1rq!QHhE~s`BRS?`JN(#q$DX9OzT;swceStJZR( zLn^PpT%jVz$Zsylg?dMQa9QxOl`pbNob2pQ>meGyyjv{k>^IU(%+SIJ{7S1(jFO)} zmXvw%Z?!rXD(+t2FD&+(rjbzWgUW#l=L1qgCfjz7O^v|tNcRBv zvjOUQhWIORT3QCDIQ!j?8G(pp$#->*{k59hf`EJsAbv|QcMt0MYR#ERGzb1YH@-Ux zGV<2kO)#ftM?zQsXgMdRU}sxhbG=hLKFLn2xJaonv<6e1?sUT!o~yODmk{L(0PW|- zTQH@@NZ;>V(VX$0qpHoujp;qiW6jw;BQ+;UDXMsFW~Y<$D2Up1dAl4o6G9v1Li{Ta?Lm0D9y9v2+( z)O9E^u~HIFdSP>ld%Tq5e}NH2zl{0h)~|%A0h7Y#_V0dnKDFv?&hXBs^y()TAA4(+ zso;+)?nOLTwrx*sy@8MOC2g{ymI>LN*KG+W`K_ZmcVZ+r#QVrkAv>%%w%fIPPoC%X z5=bD8F$CSTt#u@{@*N%7K0->F&ki{{wHf0mob`;~5+tQHO@R=W2`=nndg()>Kmx$q?|5^A?n!&rgAANcxWzL~7dg}XA{@Fk4d3npTCJ?w^-)|o~^wXe&r3j$P_)}ho zo^#Cy9aGHX@>)qpYB_&8QPw?3>xCrpA{|sIhtiC&8IHXurnBfCo&Fk;aHWrnrTivatFz?-dvxtdZ&zeWztH@b8|f*w_eR=>}Vm8I?naRL_v? z5)XC-OK}E^M)c;5v%kaKOiW2&Z#F%;v>@puFbiLNnG5AsTZq=s?1R|37yRAKPSKeP zTo>hLMstip3)5pVIb4^3S0^(t@ci^=40$a<0MCRWw#_Rs83);_opz_cN1)^;BQrW! z+-od)CnzhJ{J2f0cK*5BB4{B;Bs-7qHC^GDumllvphg`p7UQ*|i6>KGb6|QCU?@it z{#X$2$zkHiXBz6W!D6FLP=0G!TVwKy1=-U;UWc72Cf)ckP2{MJSITl1@+(ki0zM<) zlTJY z24Pzojqp`E<~o&SKep6V)W5D|(?VJ0YS|U`7i@Q}{AasoO_SHz$R6UcMH7#--_@|{ z%8c4@($n>0sDzf_;Zjpt^m5RZdQ&mV%6Dr8v0K!zu)E)#H(GYOu5dU)7-Os2}KI# zz8C&Dt|LuHrhITWqlYJO^%*c<$7BYhYg7S`Eg*i`YWJ1iynDe7xx)!Dr zG$9KG@-3OI&que;W~OlVbIe6`6+4)`sd^5&K$;4n7acY1w<{Ajw|U=sgfdlPIqwoF zrx&diA3}dP76pPJO0SeEqcNPM*HPsA%j2fcY`$ZkNZ6wh+)StX#rlMJy0;qqqcn_P zA|Jwer?J2?<&PXJ)E;8+kii=_BalS*y{JGY=0^m$AQ<-f`ci+QWKa+KK(2nQ`+>6E zgHMC)Vy|59c0)=#MzWi;1Lds_`M^ z{8=bTrBZ=&t9Amcy8MepP(D&8aXfX26^)0s9WnZgRgW%?j)_NkCB4rGI__?S?lXb{ z5hJ5pY}00UOv7zG0J{-#j{66L+Gm&7s3IlqI)+w0@LDl}N)}k>`SJ0!pB39MIGK~I z@mIX`x1rEl55tY94%tS8lG5rrWmFRp?MKIfg)LVjV*M|UiG~F{_D)KKKbJB9U%k`B zhelQw&84LL9H4aIawt7fe@39KBhvBiiuj4j@>0)&Ydx?HSdMtm7O~pYKRI6EX23os z(0Sc@nzw6?8a96vZ>=0l+n)d4zgPoV=Tnl-(E{)7r=8w4_iH6p(dwP3@K43f81ZKp2r>Z&Re*S- z*#{lff{O8?7{(YDuj8(XSwvxf_~E<)Yh9idIG zuC;0lgY`jKjqT0EO1^*`kzm?3>+vT_q4-)I7#EyS!=tQlqqA~12|POGT9Upi+1%?7 z@{gy$Jzl~0~D(#ZdFn0RG;P7K?m{@AiU2YL=4@Lp5crlaSL=TTkQNK8}>$_lYp3@b_DgyM-sFv z-lTY=8k|wxAc}p>Y_#oz;B88_T4$`47(O%)8o`%j-~CVqinp6{CmI}+dab*&#)WBn zM>|_oqHAYV^HEPj$cdC7pH6W6jN}5JfO5g{QyK^oA*Fu08s_s^@t}5EP^Rz7-`>j4KLu;4K2@(DMu!6(~L z`SHf+R(!R0-ZIXTMYP-s8He+VLbEq&{DXOT$_%pTqKXdqEpAjUbNVHdI?i8?Ow4k4 z<6Vg35Wg@eFulFwW# zc!m4OPr@X7uojL(u9()Jkw;25jzJ42{X-HG4@Oe<%#`S6L<{8tPm@q7+4s2Ej=N|u z&*iC)Y>}_@{C9Yd)*ZnL6ZgS zi1vwekhUKlrz!*s#81TnQFE<5GI>ch1Bn)AZZk0v5TX`_ZSuf*=blS6!rP#XLyuEA z(PNaRl}8*$yR=PDK#(mX>AjH8aJ9;|BBH)-_4m^~vlYgGR{6J1L1$m{2wq0UGrIT+ z-IXA`9Q3@|(ukO!FMBRR7Z1ijvOEwfkJV&*q7iZ450Bu%Brp+Yo=841gMPVfZkG~x zT>}?Mf$z~S7ncTu0Q$*H(PZNL)@r!+FLo1BLecZN#Dh;&{s@d-SA|oYVI;kU{dgrT z2K)H3*E%bt?9TaCXMJ|he6hRL;~!WOei$h+Ht4b<%m8D^B^-L4I(L@}j^740#Gq~+ z#edu&JaT{e9+MRVsa}WSFg$JRcLN`K@+Dy0?y03eb56aPIZ|IpIRi|eMQ*;x#?rk1 z{OswAv$sD8*U!U^_8g9BH>;7=DUjoAaF|Vnz0*ZgKw%NWpn}haF%)qI%iW+?A_Jer zkEgFSi3TcnQ!ltzg#?@yG@ZF-)VC#c2Iw{n_Crpf1eH&TkjN0O3ogL!;pK07oZQl)%og-Th86l$NEK zzOki(2-Z=OKj#=7POgE;`IDpPsSnI1hJXIFXc~PW^?!6=>Vm+vT%KYyPd^j%y@BMF zqs(X7FP($r^XO_Z)dR0`rFzohkp(W3LvEkdaF&wQam|5HP7~YR%<~(8L&BU z>fd2@;^2dKjPmqx_3C27O?7suUi_)KX~kfwyBA;v@1*}MNnM3Eq>UqXIk;}Ej&HW&;;s=bFIm;o zEQ|hpJ{o4d<`yP_yfv$+pK>VVmyp5o2ZAME6*h<1B@#K3t$uQ|tpOvC)=HjVkXu|m ztOZ*jtOGZ;*=c5TAYC8ohH6hQZpw@g$Y3!I0;Rv8@V7KjC{P)v`mhq>mFV`1abHc6 z^`uX~I~3HF?BsWk4@vNAq8F71&GNJA~x?<7>&!U%6M6 z0ychPWG%i7;(Z5Ag<9%*?is4<|4$`X9u4LG#*HOQx*B6F$r?9XW~`wzmNXNi>`Phh zBzO3kgTa`>n6iaIWF{&6EVr?hK}n=*B9Y-rwq$aRNKw{8Xw9l`+eT`IiK@@Xhr)y|jW5-Dl1^0RFUcpRT2z-=uS^ zB(n~5EB?1%5KkXZdga8j$t5oF<}uADD)LHC<$012219cNfk!=32)%38Ja-$i3xOE2 zfq7c1WIB{>Mu_|))aHJYt!myjBB{Xa;?R_BG;D7SSvwKQ2ZOUR$TF$DViqrZXEid!ciF0Sz`Dp? zr%?GPp^Wxwi44n+pwSfS716V7T1Xk$EZD=G;pxhv0{ zf5pA$>eD>usG~dVm=Yt|qIUQ9$J8}kM@q#}U{S`rgAH1De7rloM0n4b)GipL^wCfs zA)GS>U&3zi3W$eiR)S}XDw4gQZ%b^DufN}yj4MtT;_c&u4)`}s4e`N;hJNWZ!pFm* z<$!p!21ATolCF9p5>IXWa0%CU!@Uu%u41zonfWnWy^b^;;pCX=O8;YJs6~{MSR<)c6P$Urs&|n?J*61cvs^{^z zM`df`Z?)$P{&LZKG27?Xp?qsB%tX!)`%(3A%T4>!CGY1cPRGp;D0=6FD#$l=ZI7!9 z&nFu&n;+CCx9>!)7{iLhnZo5UGEw=(+p>Fc$XnLKjteVfhPb&gI4W2|m^3P>>ar@t zF70;7qkN)eM3G`mmE7Ww9z^t;O;`@IZ6pXr#zOFh;tAtvJ-+@3tJ+0uwAq4$m&HK^ z5M52j?)3ifVr*xOW^-CcYcA(iHS3=&bzfb69(WbHmd+>2Sk7 zpss|mz9lX`H)yu**;=(*Gu`k+rj2sVYlp^%(kR~f#c?W7$y%{HqZqK7$(B?n7RE75 zE-O($Z6!nQ@kfk=ON@SXv^aD1jnQ%SWn|Ed%6V()xV{fw?q_nIIm4Fk?}|dPRkByY z;OMedgQk>BRzKd6J(tnW$R^mtj(36;t+QEgE5msZ~mda3553aMd<;IYrI!;j>G%6o~y_rL%kr`$&p;x(=bNmv0T8rzHIu za3e4qpjq#OmE5!EUb#Q9+J}`PgbX*WaAhswj@eiAKAlN>cjZH61*_JR&|5M1C><&! zUc zS2P^4Uy=3Ob02nMM<2?HeM39#LN&YT+R2ihoanVt0@Z7&=+vA7Cnnn?VoSRDczE8( zZ58UlpYNk^XN!H-wg^a|caXm?8uw3NugUDhG($zBXNk!pgwenfV78>;Q&5;#fe8{b zr*O%WS&MRfk{<{wSE4f%&*oR{i@0NY%xOx8yi@_~>ZhnZR%c-b_K)J;Ina|AF*k0F zge5*$G*(L>rfGK|s1q15YT2n185q|Zu?hD|GW_9U7duj)CfNcW@{b$8Af4Xgl0Zu! zrvqdGO479GM3eF1ntq1M-x?Ysz``Oqsoo(z(J2CwaEjqf^kS2FA7l$w-xz;=zM$eS)kst$>pw z`r{5C^WI$?dYbFflUa{vSEfb?>gkGo8b#|v#`Ccuivk=kFcJ-!mH-|e2SJV(0K5`B zn>PjH9$#C8eMNos-ugn&?OX_F?j~Rxf$QrDM7V&S%Im8}H%@b7wZXSxtM#q+V57D5 zN<*3pwU`r literal 0 Hc-jL100001 diff --git a/main/say.c b/main/say.c index c3ca18565f..89ff4f6bf7 100644 --- a/main/say.c +++ b/main/say.c @@ -350,12 +350,14 @@ static int ast_say_number_full_ka(struct ast_channel *chan, int num, const char static int ast_say_number_full_hu(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd); static int ast_say_number_full_th(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd); 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); /* Forward declarations of language specific variants of ast_say_enumeration_full */ static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd); 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 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 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_vi(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd); /* Forward declarations of ast_say_date, ast_say_datetime and ast_say_time functions */ static int ast_say_date_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang); @@ -383,6 +385,7 @@ static int ast_say_date_with_format_pt(struct ast_channel *chan, time_t t, const 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); 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 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 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 int ast_say_time_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang); static int ast_say_time_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang); @@ -496,6 +499,8 @@ static int say_number_full(struct ast_channel *chan, int num, const char *ints, return ast_say_number_full_zh(chan, num, ints, language, audiofd, ctrlfd); } else if (!strncasecmp(language, "ur", 2)) { /* Urdu syntax */ return ast_say_number_full_ur(chan, num, ints, language, options, audiofd, ctrlfd); + } else if (!strncasecmp(language, "vi", 2)) { /* Vietnamese syntax */ + return ast_say_number_full_vi(chan, num, ints, language, audiofd, ctrlfd); } /* Default to english */ @@ -2612,6 +2617,101 @@ static int ast_say_number_full_th(struct ast_channel *chan, int num, const char return res; } +/*! \brief ast_say_number_full_vi: Vietnamese syntax */ +static int ast_say_number_full_vi(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd) +{ + int res = 0; + int playh = 0; + int playoh = 0; + int playohz = 0; + int playz = 0; + int playl = 0; + char fn[256] = ""; + if (!num) + return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd); + while (!res && (num || playh)) { + if (num < 0) { + ast_copy_string(fn, "digits/minus", sizeof(fn)); + if ( num > INT_MIN ) { + num = -num; + } else { + num = 0; + } + } else if (playl) { + snprintf(fn, sizeof(fn), "digits/%da", num); + playl = 0; + num = 0; + } else if (playh) { + ast_copy_string(fn, "digits/hundred", sizeof(fn)); + playh = 0; + } else if (playz) { + ast_copy_string(fn, "digits/odd", sizeof(fn)); + playz = 0; + } else if (playoh) { + ast_copy_string(fn, "digits/0-hundred", sizeof(fn)); + playoh = 0; + } else if (playohz) { + ast_copy_string(fn, "digits/0-hundred-odd", sizeof(fn)); + playohz = 0; + } else if (num < 20) { + snprintf(fn, sizeof(fn), "digits/%d", num); + num = 0; + } else if (num < 100) { + snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10); + num %= 10; + if ((num == 5) || (num == 4) || (num == 1)) playl++; + } else { + if (num < 1000) { + snprintf(fn, sizeof(fn), "digits/%d", (num/100)); + num %= 100; + if (num && (num < 10)) { + playz++; + playh++; + } else { + playh++; + } + } else { + if (num < 1000000) { /* 1,000,000 */ + res = ast_say_number_full_vi(chan, num / 1000, ints, language, audiofd, ctrlfd); + if (res) + return res; + num %= 1000; + snprintf(fn, sizeof(fn), "digits/thousand"); + if (num && (num < 10)) { + playohz++; + } else if (num && (num < 100)){ + playoh++; + } else { + playh = 0; + playohz = 0; + playoh = 0; + } + } else { + if (num < 1000000000) { /* 1,000,000,000 */ + res = ast_say_number_full_vi(chan, num / 1000000, ints, language, audiofd, ctrlfd); + if (res) + return res; + num %= 1000000; + ast_copy_string(fn, "digits/million", sizeof(fn)); + } else { + res = -1; + } + } + } + } + if (!res) { + if (!ast_streamfile(chan, fn, language)) { + if ((audiofd > -1) && (ctrlfd > -1)) + res = ast_waitstream_full(chan, ints, audiofd, ctrlfd); + else + res = ast_waitstream(chan, ints); + } + ast_stopstream(chan); + } + } + return res; +} + /*! \brief ast_say_enumeration_full: call language-specific functions */ /* Called from AGI */ static int say_enumeration_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd) @@ -2624,6 +2724,8 @@ static int say_enumeration_full(struct ast_channel *chan, int num, const char *i return ast_say_enumeration_full_de(chan, num, ints, language, options, audiofd, ctrlfd); } else if (!strncasecmp(language, "he", 2)) { /* Hebrew syntax */ return ast_say_enumeration_full_he(chan, num, ints, language, options, audiofd, ctrlfd); + } else if (!strncasecmp(language, "vi", 2)) { /* Vietnamese syntax */ + return ast_say_enumeration_full_vi(chan, num, ints, language, audiofd, ctrlfd); } /* Default to english */ @@ -2729,6 +2831,25 @@ static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const return res; } +static int ast_say_enumeration_full_vi(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd) +{ + int res = 0; + char fn[256] = ""; + ast_copy_string(fn, "digits/h", sizeof(fn)); + if (!res) { + if (!ast_streamfile(chan, fn, language)) { + if ((audiofd > -1) && (ctrlfd > -1)) { + res = ast_waitstream_full(chan, ints, audiofd, ctrlfd); + } else { + res = ast_waitstream(chan, ints); + } + } + ast_stopstream(chan); + } + + return ast_say_number_full_vi(chan, num, ints, language, audiofd, ctrlfd); +} + /*! \brief ast_say_enumeration_full_da: Danish syntax */ 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) { @@ -3534,6 +3655,8 @@ static int say_date_with_format(struct ast_channel *chan, time_t t, const char * return ast_say_date_with_format_zh(chan, t, ints, lang, format, tzone); } else if (!strncasecmp(lang, "zh", 2)) { /* Taiwanese / Chinese syntax */ return ast_say_date_with_format_zh(chan, t, ints, lang, format, tzone); + } else if (!strncasecmp(lang, "vi", 2)) { /* Vietnamese syntax */ + return ast_say_date_with_format_vi(chan, t, ints, lang, format, tzone); } /* Default to English */ @@ -7515,12 +7638,223 @@ static int ast_say_date_with_format_gr(struct ast_channel *chan, time_t t, const return res; } +/* Vietnamese syntax */ +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) +{ + struct timeval when = { t, 0 }; + struct ast_tm tm; + int res = 0, offset, sndoffset; + char sndfile[256], nextmsg[256]; + if (format == NULL) + format = "A 'digits/day' eB 'digits/year' Y 'digits/at' k 'hours' M 'minutes' p"; + ast_localtime(&when, &tm, tzone); -/*********************************** Georgian Support ***************************************/ + for (offset=0 ; format[offset] != '\0' ; offset++) { + ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format); + switch (format[offset]) { + /* NOTE: if you add more options here, please try to be consistent with strftime(3) */ + case '\'': + /* Literal name of a sound file */ + sndoffset = 0; + for (sndoffset = 0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++) + sndfile[sndoffset] = format[offset]; + sndfile[sndoffset] = '\0'; + res = wait_file(chan, ints, sndfile, lang); + break; + case 'A': + case 'a': + /* Sunday - Saturday */ + snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday); + res = wait_file(chan, ints, nextmsg, lang); + break; + case 'B': + case 'b': + case 'h': + /* January - December */ + snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon); + res = wait_file(chan, ints, nextmsg, lang); + break; + case 'm': + /* Month enumerated */ + res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL); + break; + case 'd': + case 'e': + /* 1 - 31 */ + res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL); + break; + case 'Y': + /* Year */ + if (tm.tm_year > 99) { + res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL); + } else if (tm.tm_year < 1) { + /* I'm not going to handle 1900 and prior */ + /* We'll just be silent on the year, instead of bombing out. */ + } else { + res = wait_file(chan, ints, "digits/19", lang); + if (!res) { + if (tm.tm_year <= 9) { + /* 1901 - 1909 */ + res = wait_file(chan, ints, "digits/odd", lang); + } + + res |= ast_say_number(chan, tm.tm_year, ints, lang, (char *) NULL); + } + } + break; + case 'I': + case 'l': + /* 12-Hour */ + if (tm.tm_hour == 0) + ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg)); + else if (tm.tm_hour > 12) + snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12); + else + snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour); + res = wait_file(chan, ints, nextmsg, lang); + break; + case 'H': + case 'k': + /* 24-Hour */ + if (format[offset] == 'H') { + /* e.g. oh-eight */ + if (tm.tm_hour < 10) { + res = wait_file(chan, ints, "digits/0", lang); + } + } else { + /* e.g. eight */ + if (tm.tm_hour == 0) { + res = wait_file(chan, ints, "digits/0", lang); + } + } + if (!res) { + if (tm.tm_hour != 0) { + int remaining = tm.tm_hour; + if (tm.tm_hour > 20) { + res = wait_file(chan, ints, "digits/20", lang); + remaining -= 20; + } + if (!res) { + snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining); + res = wait_file(chan, ints, nextmsg, lang); + } + } + } + break; + case 'M': + case 'N': + /* Minute */ + res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL); + break; + case 'P': + case 'p': + /* AM/PM */ + if (tm.tm_hour > 11) + ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg)); + else + ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg)); + res = wait_file(chan, ints, nextmsg, lang); + break; + case 'Q': + /* Shorthand for "Today", "Yesterday", or ABdY */ + /* XXX As emphasized elsewhere, this should the native way in your + * language to say the date, with changes in what you say, depending + * upon how recent the date is. XXX */ + { + struct timeval now = ast_tvnow(); + struct ast_tm tmnow; + time_t beg_today; + + gettimeofday(&now, NULL); + ast_localtime(&now, &tmnow, tzone); + /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */ + /* In any case, it saves not having to do ast_mktime() */ + beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec); + if (beg_today < t) { + /* Today */ + res = wait_file(chan, ints, "digits/today", lang); + } else if (beg_today - 86400 < t) { + /* Yesterday */ + res = wait_file(chan, ints, "digits/yesterday", lang); + } else if (beg_today - 86400 * 6 < t) { + /* Within the last week */ + res = ast_say_date_with_format_vi(chan, t, ints, lang, "A", tzone); + } else if (beg_today - 2628000 < t) { + /* Less than a month ago - "Chu nhat ngay 13 thang 2" */ + res = ast_say_date_with_format_vi(chan, t, ints, lang, "A 'digits/day' dB", tzone); + } else if (beg_today - 15768000 < t) { + /* Less than 6 months ago - "August seventh" */ + res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB", tzone); + } else { + /* More than 6 months ago - "April nineteenth two thousand three" */ + res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB 'digits/year' Y", tzone); + } + } + break; + case 'q': + /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */ + /* XXX As emphasized elsewhere, this should the native way in your + * language to say the date, with changes in what you say, depending + * upon how recent the date is. XXX */ + { + struct timeval now; + struct ast_tm tmnow; + time_t beg_today; + now = ast_tvnow(); + ast_localtime(&now, &tmnow, tzone); + /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */ + /* In any case, it saves not having to do ast_mktime() */ + beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec); + if (beg_today < t) { + /* Today */ + } else if ((beg_today - 86400) < t) { + /* Yesterday */ + res = wait_file(chan, ints, "digits/yesterday", lang); + } else if (beg_today - 86400 * 6 < t) { + /* Within the last week */ + res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone); + } else if (beg_today - 2628000 < t) { + /* Less than a month ago - "Chu nhat ngay 13 thang 2" */ + res = ast_say_date_with_format_vi(chan, t, ints, lang, "A 'digits/day' dB", tzone); + } else if (beg_today - 15768000 < t) { + /* Less than 6 months ago - "August seventh" */ + res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB", tzone); + } else { + /* More than 6 months ago - "April nineteenth two thousand three" */ + res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB 'digits/year' Y", tzone); + } + } + break; + case 'R': + res = ast_say_date_with_format_vi(chan, t, ints, lang, "HM", tzone); + break; + case 'S': + /* Seconds */ + res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL); + break; + case 'T': + res = ast_say_date_with_format_vi(chan, t, ints, lang, "H 'hours' M 'minutes' S 'seconds'", tzone); + break; + case ' ': + case ' ': + /* Just ignore spaces and tabs */ + break; + default: + /* Unknown character */ + ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset); + } + /* Jump out on DTMF */ + if (res) { + break; + } + } + return res; +} +/*********************************** Georgian Support ***************************************/ /* Convert a number into a semi-localized string. Only for Georgian. res must be of at least 256 bytes, preallocated. -- 2.47.3