00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "asterisk.h"
00039
00040 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 411244 $")
00041
00042 #include <netinet/in.h>
00043 #include <time.h>
00044 #include <ctype.h>
00045 #include <math.h>
00046
00047 #ifdef SOLARIS
00048 #include <iso/limits_iso.h>
00049 #endif
00050
00051 #include "asterisk/file.h"
00052 #include "asterisk/channel.h"
00053 #include "asterisk/say.h"
00054 #include "asterisk/lock.h"
00055 #include "asterisk/localtime.h"
00056 #include "asterisk/utils.h"
00057 #include "asterisk/app.h"
00058 #include "asterisk/test.h"
00059
00060
00061 static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang);
00062
00063
00064 static int say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
00065 {
00066 const char *fn;
00067 char fnbuf[10], asciibuf[20] = "letters/ascii";
00068 char ltr;
00069 int num = 0;
00070 int res = 0;
00071
00072 while (str[num] && !res) {
00073 fn = NULL;
00074 switch (str[num]) {
00075 case ('*'):
00076 fn = "digits/star";
00077 break;
00078 case ('#'):
00079 fn = "digits/pound";
00080 break;
00081 case ('!'):
00082 fn = "letters/exclaimation-point";
00083 break;
00084 case ('@'):
00085 fn = "letters/at";
00086 break;
00087 case ('$'):
00088 fn = "letters/dollar";
00089 break;
00090 case ('-'):
00091 fn = "letters/dash";
00092 break;
00093 case ('.'):
00094 fn = "letters/dot";
00095 break;
00096 case ('='):
00097 fn = "letters/equals";
00098 break;
00099 case ('+'):
00100 fn = "letters/plus";
00101 break;
00102 case ('/'):
00103 fn = "letters/slash";
00104 break;
00105 case (' '):
00106 fn = "letters/space";
00107 break;
00108 case ('0'):
00109 case ('1'):
00110 case ('2'):
00111 case ('3'):
00112 case ('4'):
00113 case ('5'):
00114 case ('6'):
00115 case ('7'):
00116 case ('8'):
00117 case ('9'):
00118 strcpy(fnbuf, "digits/X");
00119 fnbuf[7] = str[num];
00120 fn = fnbuf;
00121 break;
00122 default:
00123 ltr = str[num];
00124 if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A';
00125 strcpy(fnbuf, "letters/X");
00126 fnbuf[8] = ltr;
00127 fn = fnbuf;
00128 }
00129 if ((fn && ast_fileexists(fn, NULL, lang) > 0) ||
00130 (snprintf(asciibuf + 13, sizeof(asciibuf) - 13, "%d", str[num]) > 0 && ast_fileexists(asciibuf, NULL, lang) > 0 && (fn = asciibuf))) {
00131 res = ast_streamfile(chan, fn, lang);
00132 if (!res) {
00133 if ((audiofd > -1) && (ctrlfd > -1))
00134 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
00135 else
00136 res = ast_waitstream(chan, ints);
00137 }
00138 ast_stopstream(chan);
00139 }
00140 num++;
00141 }
00142
00143 return res;
00144 }
00145
00146 static int say_phonetic_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
00147 {
00148 const char *fn;
00149 char fnbuf[256];
00150 char ltr;
00151 int num = 0;
00152 int res = 0;
00153
00154 while (str[num] && !res) {
00155 fn = NULL;
00156 switch (str[num]) {
00157 case ('*'):
00158 fn = "digits/star";
00159 break;
00160 case ('#'):
00161 fn = "digits/pound";
00162 break;
00163 case ('!'):
00164 fn = "letters/exclaimation-point";
00165 break;
00166 case ('@'):
00167 fn = "letters/at";
00168 break;
00169 case ('$'):
00170 fn = "letters/dollar";
00171 break;
00172 case ('-'):
00173 fn = "letters/dash";
00174 break;
00175 case ('.'):
00176 fn = "letters/dot";
00177 break;
00178 case ('='):
00179 fn = "letters/equals";
00180 break;
00181 case ('+'):
00182 fn = "letters/plus";
00183 break;
00184 case ('/'):
00185 fn = "letters/slash";
00186 break;
00187 case (' '):
00188 fn = "letters/space";
00189 break;
00190 case ('0'):
00191 case ('1'):
00192 case ('2'):
00193 case ('3'):
00194 case ('4'):
00195 case ('5'):
00196 case ('6'):
00197 case ('7'):
00198 case ('8'):
00199 strcpy(fnbuf, "digits/X");
00200 fnbuf[7] = str[num];
00201 fn = fnbuf;
00202 break;
00203 default:
00204 ltr = str[num];
00205 if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A';
00206 strcpy(fnbuf, "phonetic/X_p");
00207 fnbuf[9] = ltr;
00208 fn = fnbuf;
00209 }
00210 if (fn && ast_fileexists(fn, NULL, lang) > 0) {
00211 res = ast_streamfile(chan, fn, lang);
00212 if (!res) {
00213 if ((audiofd > -1) && (ctrlfd > -1))
00214 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
00215 else
00216 res = ast_waitstream(chan, ints);
00217 }
00218 ast_stopstream(chan);
00219 }
00220 num++;
00221 }
00222
00223 return res;
00224 }
00225
00226 static int say_digit_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
00227 {
00228 const char *fn;
00229 char fnbuf[256];
00230 int num = 0;
00231 int res = 0;
00232
00233 while (str[num] && !res) {
00234 fn = NULL;
00235 switch (str[num]) {
00236 case ('*'):
00237 fn = "digits/star";
00238 break;
00239 case ('#'):
00240 fn = "digits/pound";
00241 break;
00242 case ('-'):
00243 fn = "digits/minus";
00244 break;
00245 case '0':
00246 case '1':
00247 case '2':
00248 case '3':
00249 case '4':
00250 case '5':
00251 case '6':
00252 case '7':
00253 case '8':
00254 case '9':
00255 strcpy(fnbuf, "digits/X");
00256 fnbuf[7] = str[num];
00257 fn = fnbuf;
00258 break;
00259 }
00260 if (fn && ast_fileexists(fn, NULL, lang) > 0) {
00261 res = ast_streamfile(chan, fn, lang);
00262 if (!res) {
00263 if ((audiofd > -1) && (ctrlfd > -1))
00264 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
00265 else
00266 res = ast_waitstream(chan, ints);
00267 }
00268 ast_stopstream(chan);
00269 }
00270 num++;
00271 }
00272
00273 return res;
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 static int ast_say_number_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
00338 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);
00339 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);
00340 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);
00341 static int ast_say_number_full_en_GB(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
00342 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);
00343 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);
00344 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);
00345 static int ast_say_number_full_it(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
00346 static int ast_say_number_full_nl(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
00347 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);
00348 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);
00349 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);
00350 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);
00351 static int ast_say_number_full_zh(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
00352 static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
00353 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);
00354 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);
00355 static int ast_say_number_full_hu(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
00356 static int ast_say_number_full_th(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
00357 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);
00358 static int ast_say_number_full_vi(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
00359
00360
00361 static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
00362 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);
00363 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);
00364 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);
00365 static int ast_say_enumeration_full_vi(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
00366
00367
00368 static int ast_say_date_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00369 static int ast_say_date_da(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00370 static int ast_say_date_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00371 static int ast_say_date_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00372 static int ast_say_date_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00373 static int ast_say_date_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00374 static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00375 static int ast_say_date_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00376 static int ast_say_date_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00377 static int ast_say_date_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00378 static int ast_say_date_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00379
00380 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);
00381 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);
00382 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);
00383 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);
00384 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);
00385 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);
00386 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);
00387 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);
00388 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);
00389 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);
00390 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);
00391 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);
00392 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);
00393 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);
00394
00395 static int ast_say_time_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00396 static int ast_say_time_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00397 static int ast_say_time_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00398 static int ast_say_time_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00399 static int ast_say_time_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00400 static int ast_say_time_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00401 static int ast_say_time_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00402 static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00403 static int ast_say_time_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00404 static int ast_say_time_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00405 static int ast_say_time_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00406 static int ast_say_time_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00407
00408 static int ast_say_datetime_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00409 static int ast_say_datetime_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00410 static int ast_say_datetime_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00411 static int ast_say_datetime_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00412 static int ast_say_datetime_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00413 static int ast_say_datetime_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00414 static int ast_say_datetime_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00415 static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00416 static int ast_say_datetime_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00417 static int ast_say_datetime_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00418 static int ast_say_datetime_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00419 static int ast_say_datetime_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00420
00421 static int ast_say_datetime_from_now_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00422 static int ast_say_datetime_from_now_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00423 static int ast_say_datetime_from_now_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00424 static int ast_say_datetime_from_now_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00425 static int ast_say_datetime_from_now_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
00426
00427 static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
00428 {
00429 int res;
00430 if ((res = ast_streamfile(chan, file, lang))) {
00431 ast_log(LOG_WARNING, "Unable to play message %s\n", file);
00432 }
00433 if (!res) {
00434 res = ast_waitstream(chan, ints);
00435 }
00436 return res;
00437 }
00438
00439
00440
00441 static int say_number_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
00442 {
00443 ast_test_suite_event_notify("SAYNUM", "Message: saying number %d\r\nNumber: %d\r\nChannel: %s", num, num, ast_channel_name(chan));
00444 if (!strncasecmp(language, "en_GB", 5)) {
00445 return ast_say_number_full_en_GB(chan, num, ints, language, audiofd, ctrlfd);
00446 } else if (!strncasecmp(language, "en", 2)) {
00447 return ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd);
00448 } else if (!strncasecmp(language, "cs", 2)) {
00449 return ast_say_number_full_cs(chan, num, ints, language, options, audiofd, ctrlfd);
00450 } else if (!strncasecmp(language, "cz", 2)) {
00451 static int deprecation_warning = 0;
00452 if (deprecation_warning++ % 10 == 0) {
00453 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n");
00454 }
00455 return ast_say_number_full_cs(chan, num, ints, language, options, audiofd, ctrlfd);
00456 } else if (!strncasecmp(language, "da", 2)) {
00457 return ast_say_number_full_da(chan, num, ints, language, options, audiofd, ctrlfd);
00458 } else if (!strncasecmp(language, "de", 2)) {
00459 return ast_say_number_full_de(chan, num, ints, language, options, audiofd, ctrlfd);
00460 } else if (!strncasecmp(language, "es", 2)) {
00461 return ast_say_number_full_es(chan, num, ints, language, options, audiofd, ctrlfd);
00462 } else if (!strncasecmp(language, "fr", 2)) {
00463 return ast_say_number_full_fr(chan, num, ints, language, options, audiofd, ctrlfd);
00464 } else if (!strncasecmp(language, "ge", 2)) {
00465 static int deprecation_warning = 0;
00466 if (deprecation_warning++ % 10 == 0) {
00467 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
00468 }
00469 return ast_say_number_full_ka(chan, num, ints, language, options, audiofd, ctrlfd);
00470 } else if (!strncasecmp(language, "gr", 2)) {
00471 return ast_say_number_full_gr(chan, num, ints, language, audiofd, ctrlfd);
00472 } else if (!strncasecmp(language, "he", 2)) {
00473 return ast_say_number_full_he(chan, num, ints, language, options, audiofd, ctrlfd);
00474 } else if (!strncasecmp(language, "hu", 2)) {
00475 return ast_say_number_full_hu(chan, num, ints, language, audiofd, ctrlfd);
00476 } else if (!strncasecmp(language, "it", 2)) {
00477 return ast_say_number_full_it(chan, num, ints, language, audiofd, ctrlfd);
00478 } else if (!strncasecmp(language, "ka", 2)) {
00479 return ast_say_number_full_ka(chan, num, ints, language, options, audiofd, ctrlfd);
00480 } else if (!strncasecmp(language, "mx", 2)) {
00481 static int deprecation_warning = 0;
00482 if (deprecation_warning++ % 10 == 0) {
00483 ast_log(LOG_WARNING, "mx is not a standard language code. Please switch to using es_MX instead.\n");
00484 }
00485 return ast_say_number_full_es(chan, num, ints, language, options, audiofd, ctrlfd);
00486 } else if (!strncasecmp(language, "nl", 2)) {
00487 return ast_say_number_full_nl(chan, num, ints, language, audiofd, ctrlfd);
00488 } else if (!strncasecmp(language, "no", 2)) {
00489 return ast_say_number_full_no(chan, num, ints, language, options, audiofd, ctrlfd);
00490 } else if (!strncasecmp(language, "pl", 2)) {
00491 return ast_say_number_full_pl(chan, num, ints, language, options, audiofd, ctrlfd);
00492 } else if (!strncasecmp(language, "pt", 2)) {
00493 return ast_say_number_full_pt(chan, num, ints, language, options, audiofd, ctrlfd);
00494 } else if (!strncasecmp(language, "ru", 2)) {
00495 return ast_say_number_full_ru(chan, num, ints, language, options, audiofd, ctrlfd);
00496 } else if (!strncasecmp(language, "se", 2)) {
00497 return ast_say_number_full_se(chan, num, ints, language, options, audiofd, ctrlfd);
00498 } else if (!strncasecmp(language, "th", 2)) {
00499 return ast_say_number_full_th(chan, num, ints, language, audiofd, ctrlfd);
00500 } else if (!strncasecmp(language, "tw", 2)) {
00501 static int deprecation_warning = 0;
00502 if (deprecation_warning++ % 10 == 0) {
00503 ast_log(LOG_WARNING, "tw is a standard language code for Twi, not Taiwanese. Please switch to using zh_TW instead.\n");
00504 }
00505 return ast_say_number_full_zh(chan, num, ints, language, audiofd, ctrlfd);
00506 } else if (!strncasecmp(language, "zh", 2)) {
00507 return ast_say_number_full_zh(chan, num, ints, language, audiofd, ctrlfd);
00508 } else if (!strncasecmp(language, "ur", 2)) {
00509 return ast_say_number_full_ur(chan, num, ints, language, options, audiofd, ctrlfd);
00510 } else if (!strncasecmp(language, "vi", 2)) {
00511 return ast_say_number_full_vi(chan, num, ints, language, audiofd, ctrlfd);
00512 }
00513
00514
00515 return ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd);
00516 }
00517
00518
00519
00520 static int ast_say_number_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
00521 {
00522 int res = 0;
00523 int playh = 0;
00524 char fn[256] = "";
00525 if (!num)
00526 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
00527
00528 while (!res && (num || playh)) {
00529 if (num < 0) {
00530 ast_copy_string(fn, "digits/minus", sizeof(fn));
00531 if ( num > INT_MIN ) {
00532 num = -num;
00533 } else {
00534 num = 0;
00535 }
00536 } else if (playh) {
00537 ast_copy_string(fn, "digits/hundred", sizeof(fn));
00538 playh = 0;
00539 } else if (num < 20) {
00540 snprintf(fn, sizeof(fn), "digits/%d", num);
00541 num = 0;
00542 } else if (num < 100) {
00543 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
00544 num %= 10;
00545 } else {
00546 if (num < 1000){
00547 snprintf(fn, sizeof(fn), "digits/%d", (num/100));
00548 playh++;
00549 num %= 100;
00550 } else {
00551 if (num < 1000000) {
00552 res = ast_say_number_full_en(chan, num / 1000, ints, language, audiofd, ctrlfd);
00553 if (res)
00554 return res;
00555 num %= 1000;
00556 snprintf(fn, sizeof(fn), "digits/thousand");
00557 } else {
00558 if (num < 1000000000) {
00559 res = ast_say_number_full_en(chan, num / 1000000, ints, language, audiofd, ctrlfd);
00560 if (res)
00561 return res;
00562 num %= 1000000;
00563 ast_copy_string(fn, "digits/million", sizeof(fn));
00564 } else {
00565 ast_debug(1, "Number '%d' is too big for me\n", num);
00566 res = -1;
00567 }
00568 }
00569 }
00570 }
00571 if (!res) {
00572 if (!ast_streamfile(chan, fn, language)) {
00573 if ((audiofd > -1) && (ctrlfd > -1))
00574 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
00575 else
00576 res = ast_waitstream(chan, ints);
00577 }
00578 ast_stopstream(chan);
00579 }
00580 }
00581 return res;
00582 }
00583
00584 static int exp10_int(int power)
00585 {
00586 int x, res= 1;
00587 for (x=0;x<power;x++)
00588 res *= 10;
00589 return res;
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 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)
00615 {
00616 int res = 0;
00617 int playh = 0;
00618 char fn[256] = "";
00619
00620 int hundered = 0;
00621 int left = 0;
00622 int length = 0;
00623
00624
00625 if (!options)
00626 options = "w";
00627
00628 if (!num)
00629 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
00630
00631 while (!res && (num || playh)) {
00632 if (num < 0) {
00633 ast_copy_string(fn, "digits/minus", sizeof(fn));
00634 if ( num > INT_MIN ) {
00635 num = -num;
00636 } else {
00637 num = 0;
00638 }
00639 } else if (num < 3 ) {
00640 snprintf(fn, sizeof(fn), "digits/%d%c", num, options[0]);
00641 playh = 0;
00642 num = 0;
00643 } else if (num < 20) {
00644 snprintf(fn, sizeof(fn), "digits/%d", num);
00645 playh = 0;
00646 num = 0;
00647 } else if (num < 100) {
00648 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
00649 num %= 10;
00650 } else if (num < 1000) {
00651 hundered = num / 100;
00652 if ( hundered == 1 ) {
00653 ast_copy_string(fn, "digits/1sto", sizeof(fn));
00654 } else if ( hundered == 2 ) {
00655 ast_copy_string(fn, "digits/2ste", sizeof(fn));
00656 } else {
00657 res = ast_say_number_full_cs(chan, hundered, ints, language, options, audiofd, ctrlfd);
00658 if (res)
00659 return res;
00660 if (hundered == 3 || hundered == 4) {
00661 ast_copy_string(fn, "digits/sta", sizeof(fn));
00662 } else if ( hundered > 4 ) {
00663 ast_copy_string(fn, "digits/set", sizeof(fn));
00664 }
00665 }
00666 num -= (hundered * 100);
00667 } else {
00668 length = (int)log10(num)+1;
00669 while ( (length % 3 ) != 1 ) {
00670 length--;
00671 }
00672 left = num / (exp10_int(length-1));
00673 if ( left == 2 ) {
00674 switch (length-1) {
00675 case 9: options = "w";
00676 break;
00677 default : options = "m";
00678 }
00679 }
00680 if ( left > 1 ) {
00681 res = ast_say_number_full_cs(chan, left, ints, language, options, audiofd, ctrlfd);
00682 if (res)
00683 return res;
00684 }
00685 if ( left >= 5 ) {
00686 snprintf(fn, sizeof(fn), "digits/5_E%d", length - 1);
00687 } else if ( left >= 2 && left <= 4 ) {
00688 snprintf(fn, sizeof(fn), "digits/2-4_E%d", length - 1);
00689 } else {
00690 snprintf(fn, sizeof(fn), "digits/1_E%d", length - 1);
00691 }
00692 num -= left * (exp10_int(length-1));
00693 }
00694 if (!res) {
00695 if (!ast_streamfile(chan, fn, language)) {
00696 if ((audiofd > -1) && (ctrlfd > -1)) {
00697 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
00698 } else {
00699 res = ast_waitstream(chan, ints);
00700 }
00701 }
00702 ast_stopstream(chan);
00703 }
00704 }
00705 return res;
00706 }
00707
00708
00709
00710
00711
00712 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)
00713 {
00714 int res = 0;
00715 int playh = 0;
00716 int playa = 0;
00717 int cn = 1;
00718 char fn[256] = "";
00719 if (!num)
00720 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
00721
00722 if (options && !strncasecmp(options, "n", 1)) cn = -1;
00723
00724 while (!res && (num || playh || playa )) {
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 if (num < 0) {
00736 ast_copy_string(fn, "digits/minus", sizeof(fn));
00737 if ( num > INT_MIN ) {
00738 num = -num;
00739 } else {
00740 num = 0;
00741 }
00742 } else if (playh) {
00743 ast_copy_string(fn, "digits/hundred", sizeof(fn));
00744 playh = 0;
00745 } else if (playa) {
00746 ast_copy_string(fn, "digits/and", sizeof(fn));
00747 playa = 0;
00748 } else if (num == 1 && cn == -1) {
00749 ast_copy_string(fn, "digits/1N", sizeof(fn));
00750 num = 0;
00751 } else if (num < 20) {
00752 snprintf(fn, sizeof(fn), "digits/%d", num);
00753 num = 0;
00754 } else if (num < 100) {
00755 int ones = num % 10;
00756 if (ones) {
00757 snprintf(fn, sizeof(fn), "digits/%d-and", ones);
00758 num -= ones;
00759 } else {
00760 snprintf(fn, sizeof(fn), "digits/%d", num);
00761 num = 0;
00762 }
00763 } else {
00764 if (num < 1000) {
00765 int hundreds = num / 100;
00766 if (hundreds == 1)
00767 ast_copy_string(fn, "digits/1N", sizeof(fn));
00768 else
00769 snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
00770
00771 playh++;
00772 num -= 100 * hundreds;
00773 if (num)
00774 playa++;
00775
00776 } else {
00777 if (num < 1000000) {
00778 res = ast_say_number_full_da(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
00779 if (res)
00780 return res;
00781 num = num % 1000;
00782 ast_copy_string(fn, "digits/thousand", sizeof(fn));
00783 } else {
00784 if (num < 1000000000) {
00785 int millions = num / 1000000;
00786 res = ast_say_number_full_da(chan, millions, ints, language, "c", audiofd, ctrlfd);
00787 if (res)
00788 return res;
00789 if (millions == 1)
00790 ast_copy_string(fn, "digits/million", sizeof(fn));
00791 else
00792 ast_copy_string(fn, "digits/millions", sizeof(fn));
00793 num = num % 1000000;
00794 } else {
00795 ast_debug(1, "Number '%d' is too big for me\n", num);
00796 res = -1;
00797 }
00798 }
00799 if (num && num < 100)
00800 playa++;
00801 }
00802 }
00803 if (!res) {
00804 if (!ast_streamfile(chan, fn, language)) {
00805 if ((audiofd > -1) && (ctrlfd > -1))
00806 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
00807 else
00808 res = ast_waitstream(chan, ints);
00809 }
00810 ast_stopstream(chan);
00811 }
00812 }
00813 return res;
00814 }
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826 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)
00827 {
00828 int res = 0, t = 0;
00829 int mf = 1;
00830 char fn[256] = "";
00831 char fna[256] = "";
00832 if (!num)
00833 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
00834
00835 if (options && (!strncasecmp(options, "f", 1)))
00836 mf = -1;
00837
00838 while (!res && num) {
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 if (num < 0) {
00853 ast_copy_string(fn, "digits/minus", sizeof(fn));
00854 if ( num > INT_MIN ) {
00855 num = -num;
00856 } else {
00857 num = 0;
00858 }
00859 } else if (num == 1 && mf == -1) {
00860 snprintf(fn, sizeof(fn), "digits/%dF", num);
00861 num = 0;
00862 } else if (num < 20) {
00863 snprintf(fn, sizeof(fn), "digits/%d", num);
00864 num = 0;
00865 } else if (num < 100) {
00866 int ones = num % 10;
00867 if (ones) {
00868 snprintf(fn, sizeof(fn), "digits/%d-and", ones);
00869 num -= ones;
00870 } else {
00871 snprintf(fn, sizeof(fn), "digits/%d", num);
00872 num = 0;
00873 }
00874 } else if (num == 100 && t == 0) {
00875 ast_copy_string(fn, "digits/hundred", sizeof(fn));
00876 num = 0;
00877 } else if (num < 1000) {
00878 int hundreds = num / 100;
00879 num = num % 100;
00880 if (hundreds == 1) {
00881 ast_copy_string(fn, "digits/1N", sizeof(fn));
00882 } else {
00883 snprintf(fn, sizeof(fn), "digits/%d", hundreds);
00884 }
00885 ast_copy_string(fna, "digits/hundred", sizeof(fna));
00886 } else if (num == 1000 && t == 0) {
00887 ast_copy_string(fn, "digits/thousand", sizeof(fn));
00888 num = 0;
00889 } else if (num < 1000000) {
00890 int thousands = num / 1000;
00891 num = num % 1000;
00892 t = 1;
00893 if (thousands == 1) {
00894 ast_copy_string(fn, "digits/1N", sizeof(fn));
00895 ast_copy_string(fna, "digits/thousand", sizeof(fna));
00896 } else {
00897 res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
00898 if (res)
00899 return res;
00900 ast_copy_string(fn, "digits/thousand", sizeof(fn));
00901 }
00902 } else if (num < 1000000000) {
00903 int millions = num / 1000000;
00904 num = num % 1000000;
00905 t = 1;
00906 if (millions == 1) {
00907 ast_copy_string(fn, "digits/1F", sizeof(fn));
00908 ast_copy_string(fna, "digits/million", sizeof(fna));
00909 } else {
00910 res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
00911 if (res)
00912 return res;
00913 ast_copy_string(fn, "digits/millions", sizeof(fn));
00914 }
00915 } else if (num <= INT_MAX) {
00916 int billions = num / 1000000000;
00917 num = num % 1000000000;
00918 t = 1;
00919 if (billions == 1) {
00920 ast_copy_string(fn, "digits/1F", sizeof(fn));
00921 ast_copy_string(fna, "digits/milliard", sizeof(fna));
00922 } else {
00923 res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
00924 if (res) {
00925 return res;
00926 }
00927 ast_copy_string(fn, "digits/milliards", sizeof(fn));
00928 }
00929 } else {
00930 ast_debug(1, "Number '%d' is too big for me\n", num);
00931 res = -1;
00932 }
00933 if (!res) {
00934 if (!ast_streamfile(chan, fn, language)) {
00935 if ((audiofd > -1) && (ctrlfd > -1))
00936 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
00937 else
00938 res = ast_waitstream(chan, ints);
00939 }
00940 ast_stopstream(chan);
00941 if (!res) {
00942 if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
00943 if ((audiofd > -1) && (ctrlfd > -1))
00944 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
00945 else
00946 res = ast_waitstream(chan, ints);
00947 }
00948 ast_stopstream(chan);
00949 strcpy(fna, "");
00950 }
00951 }
00952 }
00953 return res;
00954 }
00955
00956
00957
00958
00959
00960 static int ast_say_number_full_en_GB(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
00961 {
00962 int res = 0;
00963 int playh = 0;
00964 int playa = 0;
00965 char fn[256] = "";
00966 if (!num)
00967 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
00968
00969 while (!res && (num || playh || playa )) {
00970 if (num < 0) {
00971 ast_copy_string(fn, "digits/minus", sizeof(fn));
00972 if ( num > INT_MIN ) {
00973 num = -num;
00974 } else {
00975 num = 0;
00976 }
00977 } else if (playh) {
00978 ast_copy_string(fn, "digits/hundred", sizeof(fn));
00979 playh = 0;
00980 } else if (playa) {
00981 ast_copy_string(fn, "digits/and", sizeof(fn));
00982 playa = 0;
00983 } else if (num < 20) {
00984 snprintf(fn, sizeof(fn), "digits/%d", num);
00985 num = 0;
00986 } else if (num < 100) {
00987 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
00988 num %= 10;
00989 } else if (num < 1000) {
00990 int hundreds = num / 100;
00991 snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
00992
00993 playh++;
00994 num -= 100 * hundreds;
00995 if (num)
00996 playa++;
00997 } else if (num < 1000000) {
00998 res = ast_say_number_full_en_GB(chan, num / 1000, ints, language, audiofd, ctrlfd);
00999 if (res)
01000 return res;
01001 ast_copy_string(fn, "digits/thousand", sizeof(fn));
01002 num %= 1000;
01003 if (num && num < 100)
01004 playa++;
01005 } else if (num < 1000000000) {
01006 int millions = num / 1000000;
01007 res = ast_say_number_full_en_GB(chan, millions, ints, language, audiofd, ctrlfd);
01008 if (res)
01009 return res;
01010 ast_copy_string(fn, "digits/million", sizeof(fn));
01011 num %= 1000000;
01012 if (num && num < 100)
01013 playa++;
01014 } else {
01015 ast_debug(1, "Number '%d' is too big for me\n", num);
01016 res = -1;
01017 }
01018
01019 if (!res) {
01020 if (!ast_streamfile(chan, fn, language)) {
01021 if ((audiofd > -1) && (ctrlfd > -1))
01022 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
01023 else
01024 res = ast_waitstream(chan, ints);
01025 }
01026 ast_stopstream(chan);
01027 }
01028 }
01029 return res;
01030 }
01031
01032
01033
01034
01035
01036
01037
01038
01039 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)
01040 {
01041 int res = 0;
01042 int playa = 0;
01043 int mf = 0;
01044 char fn[256] = "";
01045 if (!num)
01046 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
01047
01048 if (options) {
01049 if (!strncasecmp(options, "f", 1))
01050 mf = -1;
01051 else if (!strncasecmp(options, "m", 1))
01052 mf = 1;
01053 }
01054
01055 while (!res && num) {
01056 if (num < 0) {
01057 ast_copy_string(fn, "digits/minus", sizeof(fn));
01058 if ( num > INT_MIN ) {
01059 num = -num;
01060 } else {
01061 num = 0;
01062 }
01063 } else if (playa) {
01064 ast_copy_string(fn, "digits/and", sizeof(fn));
01065 playa = 0;
01066 } else if (num == 1) {
01067 if (mf < 0)
01068 snprintf(fn, sizeof(fn), "digits/%dF", num);
01069 else if (mf > 0)
01070 snprintf(fn, sizeof(fn), "digits/%dM", num);
01071 else
01072 snprintf(fn, sizeof(fn), "digits/%d", num);
01073 num = 0;
01074 } else if (num < 31) {
01075 snprintf(fn, sizeof(fn), "digits/%d", num);
01076 num = 0;
01077 } else if (num < 100) {
01078 snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
01079 num %= 10;
01080 if (num)
01081 playa++;
01082 } else if (num == 100) {
01083 ast_copy_string(fn, "digits/100", sizeof(fn));
01084 num = 0;
01085 } else if (num < 200) {
01086 ast_copy_string(fn, "digits/100-and", sizeof(fn));
01087 num -= 100;
01088 } else {
01089 if (num < 1000) {
01090 snprintf(fn, sizeof(fn), "digits/%d", (num/100)*100);
01091 num %= 100;
01092 } else if (num < 2000) {
01093 num %= 1000;
01094 ast_copy_string(fn, "digits/thousand", sizeof(fn));
01095 } else {
01096 if (num < 1000000) {
01097 res = ast_say_number_full_es(chan, num / 1000, ints, language, options, audiofd, ctrlfd);
01098 if (res)
01099 return res;
01100 num %= 1000;
01101 ast_copy_string(fn, "digits/thousand", sizeof(fn));
01102 } else {
01103 if (num < 2147483640) {
01104 if ((num/1000000) == 1) {
01105 res = ast_say_number_full_es(chan, num / 1000000, ints, language, "M", audiofd, ctrlfd);
01106 if (res)
01107 return res;
01108 ast_copy_string(fn, "digits/million", sizeof(fn));
01109 } else {
01110 res = ast_say_number_full_es(chan, num / 1000000, ints, language, options, audiofd, ctrlfd);
01111 if (res)
01112 return res;
01113 ast_copy_string(fn, "digits/millions", sizeof(fn));
01114 }
01115 num %= 1000000;
01116 } else {
01117 ast_debug(1, "Number '%d' is too big for me\n", num);
01118 res = -1;
01119 }
01120 }
01121 }
01122 }
01123
01124 if (!res) {
01125 if (!ast_streamfile(chan, fn, language)) {
01126 if ((audiofd > -1) && (ctrlfd > -1))
01127 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
01128 else
01129 res = ast_waitstream(chan, ints);
01130 }
01131 ast_stopstream(chan);
01132
01133 }
01134
01135 }
01136 return res;
01137 }
01138
01139
01140
01141
01142
01143 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)
01144 {
01145 int res = 0;
01146 int playh = 0;
01147 int playa = 0;
01148 int mf = 1;
01149 char fn[256] = "";
01150 if (!num)
01151 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
01152
01153 if (options && !strncasecmp(options, "f", 1))
01154 mf = -1;
01155
01156 while (!res && (num || playh || playa)) {
01157 if (num < 0) {
01158 ast_copy_string(fn, "digits/minus", sizeof(fn));
01159 if ( num > INT_MIN ) {
01160 num = -num;
01161 } else {
01162 num = 0;
01163 }
01164 } else if (playh) {
01165 ast_copy_string(fn, "digits/hundred", sizeof(fn));
01166 playh = 0;
01167 } else if (playa) {
01168 ast_copy_string(fn, "digits/et", sizeof(fn));
01169 playa = 0;
01170 } else if (num == 1) {
01171 if (mf < 0)
01172 snprintf(fn, sizeof(fn), "digits/%dF", num);
01173 else
01174 snprintf(fn, sizeof(fn), "digits/%d", num);
01175 num = 0;
01176 } else if (num < 21) {
01177 snprintf(fn, sizeof(fn), "digits/%d", num);
01178 num = 0;
01179 } else if (num < 70) {
01180 snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
01181 if ((num % 10) == 1) playa++;
01182 num = num % 10;
01183 } else if (num < 80) {
01184 ast_copy_string(fn, "digits/60", sizeof(fn));
01185 if ((num % 10) == 1) playa++;
01186 num -= 60;
01187 } else if (num < 100) {
01188 ast_copy_string(fn, "digits/80", sizeof(fn));
01189 num = num - 80;
01190 } else if (num < 200) {
01191 ast_copy_string(fn, "digits/hundred", sizeof(fn));
01192 num = num - 100;
01193 } else if (num < 1000) {
01194 snprintf(fn, sizeof(fn), "digits/%d", (num/100));
01195 playh++;
01196 num = num % 100;
01197 } else if (num < 2000) {
01198 ast_copy_string(fn, "digits/thousand", sizeof(fn));
01199 num = num - 1000;
01200 } else if (num < 1000000) {
01201 res = ast_say_number_full_fr(chan, num / 1000, ints, language, options, audiofd, ctrlfd);
01202 if (res)
01203 return res;
01204 ast_copy_string(fn, "digits/thousand", sizeof(fn));
01205 num = num % 1000;
01206 } else if (num < 1000000000) {
01207 res = ast_say_number_full_fr(chan, num / 1000000, ints, language, options, audiofd, ctrlfd);
01208 if (res)
01209 return res;
01210 ast_copy_string(fn, "digits/million", sizeof(fn));
01211 num = num % 1000000;
01212 } else {
01213 ast_debug(1, "Number '%d' is too big for me\n", num);
01214 res = -1;
01215 }
01216 if (!res) {
01217 if (!ast_streamfile(chan, fn, language)) {
01218 if ((audiofd > -1) && (ctrlfd > -1))
01219 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
01220 else
01221 res = ast_waitstream(chan, ints);
01222 }
01223 ast_stopstream(chan);
01224 }
01225 }
01226 return res;
01227 }
01228
01229
01230
01231
01232
01233
01234 #define SAY_NUM_BUF_SIZE 256
01235 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)
01236 {
01237 int res = 0;
01238 int state = 0;
01239 int mf = -1;
01240 int tmpnum = 0;
01241
01242 char fn[SAY_NUM_BUF_SIZE] = "";
01243
01244 ast_verb(3, "ast_say_digits_full: started. num: %d, options=\"%s\"\n", num, options);
01245
01246 if (!num) {
01247 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
01248 }
01249 if (options && !strncasecmp(options, "m", 1)) {
01250 mf = 1;
01251 }
01252 ast_verb(3, "ast_say_digits_full: num: %d, state=%d, options=\"%s\", mf=%d\n", num, state, options, mf);
01253
01254
01255 while (!res && (num || (state > 0))) {
01256
01257
01258
01259
01260
01261
01262
01263 ast_verb(3, "ast_say_digits_full: num: %d, state=%d, options=\"%s\", mf=%d, tmpnum=%d\n", num, state, options, mf, tmpnum);
01264
01265 if (state == 1) {
01266 state = 0;
01267 } else if (state == 2) {
01268 if ((num >= 11) && (num < 21)) {
01269 if (mf < 0) {
01270 snprintf(fn, sizeof(fn), "digits/ve");
01271 } else {
01272 snprintf(fn, sizeof(fn), "digits/uu");
01273 }
01274 } else {
01275 switch (num) {
01276 case 1:
01277 snprintf(fn, sizeof(fn), "digits/ve");
01278 break;
01279 case 2:
01280 snprintf(fn, sizeof(fn), "digits/uu");
01281 break;
01282 case 3:
01283 if (mf < 0) {
01284 snprintf(fn, sizeof(fn), "digits/ve");
01285 } else {
01286 snprintf(fn, sizeof(fn), "digits/uu");
01287 }
01288 break;
01289 case 4:
01290 snprintf(fn, sizeof(fn), "digits/ve");
01291 break;
01292 case 5:
01293 snprintf(fn, sizeof(fn), "digits/ve");
01294 break;
01295 case 6:
01296 snprintf(fn, sizeof(fn), "digits/ve");
01297 break;
01298 case 7:
01299 snprintf(fn, sizeof(fn), "digits/ve");
01300 break;
01301 case 8:
01302 snprintf(fn, sizeof(fn), "digits/uu");
01303 break;
01304 case 9:
01305 snprintf(fn, sizeof(fn), "digits/ve");
01306 break;
01307 case 10:
01308 snprintf(fn, sizeof(fn), "digits/ve");
01309 break;
01310 }
01311 }
01312 state = 0;
01313 } else if (state == 3) {
01314 snprintf(fn, sizeof(fn), "digits/1k");
01315 state = 0;
01316 } else if (num < 0) {
01317 snprintf(fn, sizeof(fn), "digits/minus");
01318 num = (-1) * num;
01319 } else if (num < 20) {
01320 if (mf < 0) {
01321 snprintf(fn, sizeof(fn), "digits/%d", num);
01322 } else {
01323 snprintf(fn, sizeof(fn), "digits/%dm", num);
01324 }
01325 num = 0;
01326 } else if ((num < 100) && (num >= 20)) {
01327 snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
01328 num = num % 10;
01329 if (num > 0) {
01330 state = 2;
01331 }
01332 } else if ((num >= 100) && (num < 1000)) {
01333 tmpnum = num / 100;
01334 snprintf(fn, sizeof(fn), "digits/%d00", tmpnum);
01335 num = num - (tmpnum * 100);
01336 if ((num > 0) && (num < 11)) {
01337 state = 2;
01338 }
01339 } else if ((num >= 1000) && (num < 10000)) {
01340 tmpnum = num / 1000;
01341 snprintf(fn, sizeof(fn), "digits/%dk", tmpnum);
01342 num = num - (tmpnum * 1000);
01343 if ((num > 0) && (num < 11)) {
01344 state = 2;
01345 }
01346 } else if (num < 20000) {
01347 snprintf(fn, sizeof(fn), "digits/%dm", (num / 1000));
01348 num = num % 1000;
01349 state = 3;
01350 } else if (num < 1000000) {
01351 res = ast_say_number_full_he(chan, num / 1000, ints, language, "m", audiofd, ctrlfd);
01352 if (res) {
01353 return res;
01354 }
01355 snprintf(fn, sizeof(fn), "digits/1k");
01356 num = num % 1000;
01357 if ((num > 0) && (num < 11)) {
01358 state = 2;
01359 }
01360 } else if (num < 2000000) {
01361 snprintf(fn, sizeof(fn), "digits/million");
01362 num = num % 1000000;
01363 if ((num > 0) && (num < 11)) {
01364 state = 2;
01365 }
01366 } else if (num < 3000000) {
01367 snprintf(fn, sizeof(fn), "digits/twomillion");
01368 num = num - 2000000;
01369 if ((num > 0) && (num < 11)) {
01370 state = 2;
01371 }
01372 } else if (num < 1000000000) {
01373 res = ast_say_number_full_he(chan, num / 1000000, ints, language, "m", audiofd, ctrlfd);
01374 if (res) {
01375 return res;
01376 }
01377 snprintf(fn, sizeof(fn), "digits/million");
01378 num = num % 1000000;
01379 if ((num > 0) && (num < 11)) {
01380 state = 2;
01381 }
01382 } else {
01383 ast_debug(1, "Number '%d' is too big for me\n", num);
01384 res = -1;
01385 }
01386 tmpnum = 0;
01387 if (!res) {
01388 if (!ast_streamfile(chan, fn, language)) {
01389 if ((audiofd > -1) && (ctrlfd > -1)) {
01390 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
01391 } else {
01392 res = ast_waitstream(chan, ints);
01393 }
01394 }
01395 ast_stopstream(chan);
01396 }
01397 }
01398 return res;
01399 }
01400
01401
01402
01403
01404
01405
01406
01407 static int ast_say_number_full_hu(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
01408 {
01409 int res = 0;
01410 int playh = 0;
01411 char fn[256] = "";
01412 if (!num)
01413 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
01414
01415
01416
01417
01418
01419
01420
01421 while(!res && (num || playh)) {
01422 if (num < 0) {
01423 ast_copy_string(fn, "digits/minus", sizeof(fn));
01424 if ( num > INT_MIN ) {
01425 num = -num;
01426 } else {
01427 num = 0;
01428 }
01429 } else if (playh) {
01430 ast_copy_string(fn, "digits/hundred", sizeof(fn));
01431 playh = 0;
01432 } else if (num < 11 || num == 20) {
01433 snprintf(fn, sizeof(fn), "digits/%d", num);
01434 num = 0;
01435 } else if (num < 20) {
01436 ast_copy_string(fn, "digits/10en", sizeof(fn));
01437 num -= 10;
01438 } else if (num < 30) {
01439 ast_copy_string(fn, "digits/20on", sizeof(fn));
01440 num -= 20;
01441 } else if (num < 100) {
01442 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
01443 num %= 10;
01444 } else {
01445 if (num < 1000){
01446 snprintf(fn, sizeof(fn), "digits/%d", (num/100));
01447 playh++;
01448 num %= 100;
01449 } else {
01450 if (num < 1000000) {
01451 res = ast_say_number_full_hu(chan, num / 1000, ints, language, audiofd, ctrlfd);
01452 if (res)
01453 return res;
01454 num %= 1000;
01455 ast_copy_string(fn, "digits/thousand", sizeof(fn));
01456 } else {
01457 if (num < 1000000000) {
01458 res = ast_say_number_full_hu(chan, num / 1000000, ints, language, audiofd, ctrlfd);
01459 if (res)
01460 return res;
01461 num %= 1000000;
01462 ast_copy_string(fn, "digits/million", sizeof(fn));
01463 } else {
01464 ast_debug(1, "Number '%d' is too big for me\n", num);
01465 res = -1;
01466 }
01467 }
01468 }
01469 }
01470 if (!res) {
01471 if(!ast_streamfile(chan, fn, language)) {
01472 if ((audiofd > -1) && (ctrlfd > -1))
01473 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
01474 else
01475 res = ast_waitstream(chan, ints);
01476 }
01477 ast_stopstream(chan);
01478 }
01479 }
01480 return res;
01481 }
01482
01483
01484 static int ast_say_number_full_it(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
01485 {
01486 int res = 0;
01487 int playh = 0;
01488 int tempnum = 0;
01489 char fn[256] = "";
01490
01491 if (!num)
01492 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518 while (!res && (num || playh)) {
01519 if (num < 0) {
01520 ast_copy_string(fn, "digits/minus", sizeof(fn));
01521 if ( num > INT_MIN ) {
01522 num = -num;
01523 } else {
01524 num = 0;
01525 }
01526 } else if (playh) {
01527 ast_copy_string(fn, "digits/hundred", sizeof(fn));
01528 playh = 0;
01529 } else if (num < 20) {
01530 snprintf(fn, sizeof(fn), "digits/%d", num);
01531 num = 0;
01532 } else if (num == 21) {
01533 snprintf(fn, sizeof(fn), "digits/%d", num);
01534 num = 0;
01535 } else if (num == 28) {
01536 snprintf(fn, sizeof(fn), "digits/%d", num);
01537 num = 0;
01538 } else if (num == 31) {
01539 snprintf(fn, sizeof(fn), "digits/%d", num);
01540 num = 0;
01541 } else if (num == 38) {
01542 snprintf(fn, sizeof(fn), "digits/%d", num);
01543 num = 0;
01544 } else if (num == 41) {
01545 snprintf(fn, sizeof(fn), "digits/%d", num);
01546 num = 0;
01547 } else if (num == 48) {
01548 snprintf(fn, sizeof(fn), "digits/%d", num);
01549 num = 0;
01550 } else if (num == 51) {
01551 snprintf(fn, sizeof(fn), "digits/%d", num);
01552 num = 0;
01553 } else if (num == 58) {
01554 snprintf(fn, sizeof(fn), "digits/%d", num);
01555 num = 0;
01556 } else if (num == 61) {
01557 snprintf(fn, sizeof(fn), "digits/%d", num);
01558 num = 0;
01559 } else if (num == 68) {
01560 snprintf(fn, sizeof(fn), "digits/%d", num);
01561 num = 0;
01562 } else if (num == 71) {
01563 snprintf(fn, sizeof(fn), "digits/%d", num);
01564 num = 0;
01565 } else if (num == 78) {
01566 snprintf(fn, sizeof(fn), "digits/%d", num);
01567 num = 0;
01568 } else if (num == 81) {
01569 snprintf(fn, sizeof(fn), "digits/%d", num);
01570 num = 0;
01571 } else if (num == 88) {
01572 snprintf(fn, sizeof(fn), "digits/%d", num);
01573 num = 0;
01574 } else if (num == 91) {
01575 snprintf(fn, sizeof(fn), "digits/%d", num);
01576 num = 0;
01577 } else if (num == 98) {
01578 snprintf(fn, sizeof(fn), "digits/%d", num);
01579 num = 0;
01580 } else if (num < 100) {
01581 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
01582 num %= 10;
01583 } else {
01584 if (num < 1000) {
01585 if ((num / 100) > 1) {
01586 snprintf(fn, sizeof(fn), "digits/%d", (num/100));
01587 playh++;
01588 } else {
01589 ast_copy_string(fn, "digits/hundred", sizeof(fn));
01590 }
01591 num %= 100;
01592 } else {
01593 if (num < 1000000) {
01594 if ((num/1000) > 1)
01595 res = ast_say_number_full_it(chan, num / 1000, ints, language, audiofd, ctrlfd);
01596 if (res)
01597 return res;
01598 tempnum = num;
01599 num %= 1000;
01600 if ((tempnum / 1000) < 2)
01601 ast_copy_string(fn, "digits/thousand", sizeof(fn));
01602 else
01603 ast_copy_string(fn, "digits/thousands", sizeof(fn));
01604 } else {
01605 if (num < 1000000000) {
01606 if ((num / 1000000) > 1)
01607 res = ast_say_number_full_it(chan, num / 1000000, ints, language, audiofd, ctrlfd);
01608 if (res)
01609 return res;
01610 tempnum = num;
01611 num %= 1000000;
01612 if ((tempnum / 1000000) < 2)
01613 ast_copy_string(fn, "digits/million", sizeof(fn));
01614 else
01615 ast_copy_string(fn, "digits/millions", sizeof(fn));
01616 } else {
01617 ast_debug(1, "Number '%d' is too big for me\n", num);
01618 res = -1;
01619 }
01620 }
01621 }
01622 }
01623 if (!res) {
01624 if (!ast_streamfile(chan, fn, language)) {
01625 if ((audiofd > -1) && (ctrlfd > -1))
01626 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
01627 else
01628 res = ast_waitstream(chan, ints);
01629 }
01630 ast_stopstream(chan);
01631 }
01632 }
01633 return res;
01634 }
01635
01636
01637
01638
01639 static int ast_say_number_full_nl(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
01640 {
01641 int res = 0;
01642 int playh = 0;
01643 int units = 0;
01644 char fn[256] = "";
01645 if (!num)
01646 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
01647 while (!res && (num || playh )) {
01648 if (num < 0) {
01649 ast_copy_string(fn, "digits/minus", sizeof(fn));
01650 if ( num > INT_MIN ) {
01651 num = -num;
01652 } else {
01653 num = 0;
01654 }
01655 } else if (playh) {
01656 ast_copy_string(fn, "digits/hundred", sizeof(fn));
01657 playh = 0;
01658 } else if (num < 20) {
01659 snprintf(fn, sizeof(fn), "digits/%d", num);
01660 num = 0;
01661 } else if (num < 100) {
01662 units = num % 10;
01663 if (units > 0) {
01664 res = ast_say_number_full_nl(chan, units, ints, language, audiofd, ctrlfd);
01665 if (res)
01666 return res;
01667 num = num - units;
01668 ast_copy_string(fn, "digits/nl-en", sizeof(fn));
01669 } else {
01670 snprintf(fn, sizeof(fn), "digits/%d", num - units);
01671 num = 0;
01672 }
01673 } else if (num < 200) {
01674
01675 ast_copy_string(fn, "digits/hundred", sizeof(fn));
01676 num %= 100;
01677 } else if (num < 1000) {
01678 snprintf(fn, sizeof(fn), "digits/%d", num / 100);
01679 playh++;
01680 num %= 100;
01681 } else {
01682 if (num < 1100) {
01683
01684 num %= 1000;
01685 ast_copy_string(fn, "digits/thousand", sizeof(fn));
01686 } else if (num < 10000) {
01687 res = ast_say_number_full_nl(chan, num / 100, ints, language, audiofd, ctrlfd);
01688 if (res)
01689 return res;
01690 num %= 100;
01691 ast_copy_string(fn, "digits/hundred", sizeof(fn));
01692 } else {
01693 if (num < 1000000) {
01694 res = ast_say_number_full_nl(chan, num / 1000, ints, language, audiofd, ctrlfd);
01695 if (res)
01696 return res;
01697 num %= 1000;
01698 ast_copy_string(fn, "digits/thousand", sizeof(fn));
01699 } else {
01700 if (num < 1000000000) {
01701 res = ast_say_number_full_nl(chan, num / 1000000, ints, language, audiofd, ctrlfd);
01702 if (res)
01703 return res;
01704 num %= 1000000;
01705 ast_copy_string(fn, "digits/million", sizeof(fn));
01706 } else {
01707 ast_debug(1, "Number '%d' is too big for me\n", num);
01708 res = -1;
01709 }
01710 }
01711 }
01712 }
01713
01714 if (!res) {
01715 if (!ast_streamfile(chan, fn, language)) {
01716 if ((audiofd > -1) && (ctrlfd > -1))
01717 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
01718 else
01719 res = ast_waitstream(chan, ints);
01720 }
01721 ast_stopstream(chan);
01722 }
01723 }
01724 return res;
01725 }
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737 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)
01738 {
01739 int res = 0;
01740 int playh = 0;
01741 int playa = 0;
01742 int cn = 1;
01743 char fn[256] = "";
01744
01745 if (!num)
01746 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
01747
01748 if (options && !strncasecmp(options, "n", 1)) cn = -1;
01749
01750 while (!res && (num || playh || playa )) {
01751 if (num < 0) {
01752 ast_copy_string(fn, "digits/minus", sizeof(fn));
01753 if ( num > INT_MIN ) {
01754 num = -num;
01755 } else {
01756 num = 0;
01757 }
01758 } else if (playh) {
01759 ast_copy_string(fn, "digits/hundred", sizeof(fn));
01760 playh = 0;
01761 } else if (playa) {
01762 ast_copy_string(fn, "digits/and", sizeof(fn));
01763 playa = 0;
01764 } else if (num == 1 && cn == -1) {
01765 ast_copy_string(fn, "digits/1N", sizeof(fn));
01766 num = 0;
01767 } else if (num < 20) {
01768 snprintf(fn, sizeof(fn), "digits/%d", num);
01769 num = 0;
01770 } else if (num < 100) {
01771 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
01772 num %= 10;
01773 } else if (num < 1000) {
01774 int hundreds = num / 100;
01775 if (hundreds == 1)
01776 ast_copy_string(fn, "digits/1N", sizeof(fn));
01777 else
01778 snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
01779
01780 playh++;
01781 num -= 100 * hundreds;
01782 if (num)
01783 playa++;
01784 } else if (num < 1000000) {
01785 res = ast_say_number_full_no(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
01786 if (res)
01787 return res;
01788 ast_copy_string(fn, "digits/thousand", sizeof(fn));
01789 num %= 1000;
01790 if (num && num < 100)
01791 playa++;
01792 } else if (num < 1000000000) {
01793 int millions = num / 1000000;
01794 res = ast_say_number_full_no(chan, millions, ints, language, "c", audiofd, ctrlfd);
01795 if (res)
01796 return res;
01797 ast_copy_string(fn, "digits/million", sizeof(fn));
01798 num %= 1000000;
01799 if (num && num < 100)
01800 playa++;
01801 } else {
01802 ast_debug(1, "Number '%d' is too big for me\n", num);
01803 res = -1;
01804 }
01805
01806 if (!res) {
01807 if (!ast_streamfile(chan, fn, language)) {
01808 if ((audiofd > -1) && (ctrlfd > -1))
01809 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
01810 else
01811 res = ast_waitstream(chan, ints);
01812 }
01813 ast_stopstream(chan);
01814 }
01815 }
01816 return res;
01817 }
01818
01819 typedef struct {
01820 char *separator_dziesiatek;
01821 char *cyfry[10];
01822 char *cyfry2[10];
01823 char *setki[10];
01824 char *dziesiatki[10];
01825 char *nastki[10];
01826 char *rzedy[3][3];
01827 } odmiana;
01828
01829 static char *pl_rzad_na_tekst(odmiana *odm, int i, int rzad)
01830 {
01831 if (rzad==0)
01832 return "";
01833
01834 if (i==1)
01835 return odm->rzedy[rzad - 1][0];
01836 if ((i > 21 || i < 11) && i%10 > 1 && i%10 < 5)
01837 return odm->rzedy[rzad - 1][1];
01838 else
01839 return odm->rzedy[rzad - 1][2];
01840 }
01841
01842 static char* pl_append(char* buffer, char* str)
01843 {
01844 strcpy(buffer, str);
01845 buffer += strlen(str);
01846 return buffer;
01847 }
01848
01849 static void pl_odtworz_plik(struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, char *fn)
01850 {
01851 char file_name[255] = "digits/";
01852 strcat(file_name, fn);
01853 ast_debug(1, "Trying to play: %s\n", file_name);
01854 if (!ast_streamfile(chan, file_name, language)) {
01855 if ((audiofd > -1) && (ctrlfd > -1))
01856 ast_waitstream_full(chan, ints, audiofd, ctrlfd);
01857 else
01858 ast_waitstream(chan, ints);
01859 }
01860 ast_stopstream(chan);
01861 }
01862
01863 static void powiedz(struct ast_channel *chan, const char *language, int audiofd, int ctrlfd, const char *ints, odmiana *odm, int rzad, int i)
01864 {
01865
01866 int m1000E6 = 0;
01867 int i1000E6 = 0;
01868 int m1000E3 = 0;
01869 int i1000E3 = 0;
01870 int m1000 = 0;
01871 int i1000 = 0;
01872 int m100 = 0;
01873 int i100 = 0;
01874
01875 if (i == 0 && rzad > 0) {
01876 return;
01877 }
01878 if (i == 0) {
01879 pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry[0]);
01880 return;
01881 }
01882
01883 m1000E6 = i % 1000000000;
01884 i1000E6 = i / 1000000000;
01885
01886 powiedz(chan, language, audiofd, ctrlfd, ints, odm, rzad+3, i1000E6);
01887
01888 m1000E3 = m1000E6 % 1000000;
01889 i1000E3 = m1000E6 / 1000000;
01890
01891 powiedz(chan, language, audiofd, ctrlfd, ints, odm, rzad+2, i1000E3);
01892
01893 m1000 = m1000E3 % 1000;
01894 i1000 = m1000E3 / 1000;
01895
01896 powiedz(chan, language, audiofd, ctrlfd, ints, odm, rzad+1, i1000);
01897
01898 m100 = m1000 % 100;
01899 i100 = m1000 / 100;
01900
01901 if (i100>0)
01902 pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->setki[i100]);
01903
01904 if (m100 > 0 && m100 <= 9) {
01905 if (m1000 > 0)
01906 pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100]);
01907 else
01908 pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry[m100]);
01909 } else if (m100 % 10 == 0 && m100 != 0) {
01910 pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
01911 } else if (m100 > 10 && m100 <= 19) {
01912 pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->nastki[m100 % 10]);
01913 } else if (m100 > 20) {
01914 if (odm->separator_dziesiatek[0] == ' ') {
01915 pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
01916 pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100 % 10]);
01917 } else {
01918 char buf[10];
01919 char *b = buf;
01920 b = pl_append(b, odm->dziesiatki[m100 / 10]);
01921 b = pl_append(b, odm->separator_dziesiatek);
01922 pl_append(b, odm->cyfry2[m100 % 10]);
01923 pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, buf);
01924 }
01925 }
01926
01927 if (rzad > 0) {
01928 pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, pl_rzad_na_tekst(odm, i, rzad));
01929 }
01930 }
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024 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)
02025 {
02026 char *zenski_cyfry[] = {"0", "1z", "2z", "3", "4", "5", "6", "7", "8", "9"};
02027
02028 char *zenski_cyfry2[] = {"0", "1", "2z", "3", "4", "5", "6", "7", "8", "9"};
02029
02030 char *meski_cyfry[] = {"0", "1", "2-1m", "3-1m", "4-1m", "5m", "6m", "7m", "8m", "9m"};
02031
02032 char *meski_cyfry2[] = {"0", "1", "2-2m", "3-2m", "4-2m", "5m", "6m", "7m", "8m", "9m"};
02033
02034 char *meski_setki[] = {"", "100m", "200m", "300m", "400m", "500m", "600m", "700m", "800m", "900m"};
02035
02036 char *meski_dziesiatki[] = {"", "10m", "20m", "30m", "40m", "50m", "60m", "70m", "80m", "90m"};
02037
02038 char *meski_nastki[] = {"", "11m", "12m", "13m", "14m", "15m", "16m", "17m", "18m", "19m"};
02039
02040 char *nijaki_cyfry[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
02041
02042 char *nijaki_cyfry2[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
02043
02044 char *nijaki_setki[] = {"", "100", "200", "300", "400", "500", "600", "700", "800", "900"};
02045
02046 char *nijaki_dziesiatki[] = {"", "10", "20", "30", "40", "50", "60", "70", "80", "90"};
02047
02048 char *nijaki_nastki[] = {"", "11", "12", "13", "14", "15", "16", "17", "18", "19"};
02049
02050 char *rzedy[][3] = { {"1000", "1000.2", "1000.5"}, {"1000000", "1000000.2", "1000000.5"}, {"1000000000", "1000000000.2", "1000000000.5"}};
02051
02052
02053 odmiana *o;
02054
02055 static odmiana *odmiana_nieosobowa = NULL;
02056 static odmiana *odmiana_meska = NULL;
02057 static odmiana *odmiana_zenska = NULL;
02058
02059 if (odmiana_nieosobowa == NULL) {
02060 odmiana_nieosobowa = ast_malloc(sizeof(*odmiana_nieosobowa));
02061
02062 odmiana_nieosobowa->separator_dziesiatek = " ";
02063
02064 memcpy(odmiana_nieosobowa->cyfry, nijaki_cyfry, sizeof(odmiana_nieosobowa->cyfry));
02065 memcpy(odmiana_nieosobowa->cyfry2, nijaki_cyfry2, sizeof(odmiana_nieosobowa->cyfry));
02066 memcpy(odmiana_nieosobowa->setki, nijaki_setki, sizeof(odmiana_nieosobowa->setki));
02067 memcpy(odmiana_nieosobowa->dziesiatki, nijaki_dziesiatki, sizeof(odmiana_nieosobowa->dziesiatki));
02068 memcpy(odmiana_nieosobowa->nastki, nijaki_nastki, sizeof(odmiana_nieosobowa->nastki));
02069 memcpy(odmiana_nieosobowa->rzedy, rzedy, sizeof(odmiana_nieosobowa->rzedy));
02070 }
02071
02072 if (odmiana_zenska == NULL) {
02073 odmiana_zenska = ast_malloc(sizeof(*odmiana_zenska));
02074
02075 odmiana_zenska->separator_dziesiatek = " ";
02076
02077 memcpy(odmiana_zenska->cyfry, zenski_cyfry, sizeof(odmiana_zenska->cyfry));
02078 memcpy(odmiana_zenska->cyfry2, zenski_cyfry2, sizeof(odmiana_zenska->cyfry));
02079 memcpy(odmiana_zenska->setki, nijaki_setki, sizeof(odmiana_zenska->setki));
02080 memcpy(odmiana_zenska->dziesiatki, nijaki_dziesiatki, sizeof(odmiana_zenska->dziesiatki));
02081 memcpy(odmiana_zenska->nastki, nijaki_nastki, sizeof(odmiana_zenska->nastki));
02082 memcpy(odmiana_zenska->rzedy, rzedy, sizeof(odmiana_zenska->rzedy));
02083 }
02084
02085 if (odmiana_meska == NULL) {
02086 odmiana_meska = ast_malloc(sizeof(*odmiana_meska));
02087
02088 odmiana_meska->separator_dziesiatek = " ";
02089
02090 memcpy(odmiana_meska->cyfry, meski_cyfry, sizeof(odmiana_meska->cyfry));
02091 memcpy(odmiana_meska->cyfry2, meski_cyfry2, sizeof(odmiana_meska->cyfry));
02092 memcpy(odmiana_meska->setki, meski_setki, sizeof(odmiana_meska->setki));
02093 memcpy(odmiana_meska->dziesiatki, meski_dziesiatki, sizeof(odmiana_meska->dziesiatki));
02094 memcpy(odmiana_meska->nastki, meski_nastki, sizeof(odmiana_meska->nastki));
02095 memcpy(odmiana_meska->rzedy, rzedy, sizeof(odmiana_meska->rzedy));
02096 }
02097
02098 if (options) {
02099 if (strncasecmp(options, "f", 1) == 0)
02100 o = odmiana_zenska;
02101 else if (strncasecmp(options, "m", 1) == 0)
02102 o = odmiana_meska;
02103 else
02104 o = odmiana_nieosobowa;
02105 } else
02106 o = odmiana_nieosobowa;
02107
02108 powiedz(chan, language, audiofd, ctrlfd, ints, o, 0, num);
02109 return 0;
02110 }
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120 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)
02121 {
02122 int res = 0;
02123 int playh = 0;
02124 int mf = 1;
02125 char fn[256] = "";
02126
02127 if (!num)
02128 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02129
02130 if (options && !strncasecmp(options, "f", 1))
02131 mf = -1;
02132
02133 while (!res && num ) {
02134 if (num < 0) {
02135 ast_copy_string(fn, "digits/minus", sizeof(fn));
02136 if ( num > INT_MIN ) {
02137 num = -num;
02138 } else {
02139 num = 0;
02140 }
02141 } else if (num < 20) {
02142 if ((num == 1 || num == 2) && (mf < 0))
02143 snprintf(fn, sizeof(fn), "digits/%dF", num);
02144 else
02145 snprintf(fn, sizeof(fn), "digits/%d", num);
02146 num = 0;
02147 } else if (num < 100) {
02148 snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
02149 if (num % 10)
02150 playh = 1;
02151 num = num % 10;
02152 } else if (num < 1000) {
02153 if (num == 100)
02154 ast_copy_string(fn, "digits/100", sizeof(fn));
02155 else if (num < 200)
02156 ast_copy_string(fn, "digits/100E", sizeof(fn));
02157 else {
02158 if (mf < 0 && num > 199)
02159 snprintf(fn, sizeof(fn), "digits/%dF", (num / 100) * 100);
02160 else
02161 snprintf(fn, sizeof(fn), "digits/%d", (num / 100) * 100);
02162 if (num % 100)
02163 playh = 1;
02164 }
02165 num = num % 100;
02166 } else if (num < 1000000) {
02167 if (num > 1999) {
02168 res = ast_say_number_full_pt(chan, (num / 1000) * mf, ints, language, options, audiofd, ctrlfd);
02169 if (res)
02170 return res;
02171 }
02172 ast_copy_string(fn, "digits/1000", sizeof(fn));
02173 if ((num % 1000) && ((num % 1000) < 100 || !(num % 100)))
02174 playh = 1;
02175 num = num % 1000;
02176 } else if (num < 1000000000) {
02177 res = ast_say_number_full_pt(chan, (num / 1000000), ints, language, options, audiofd, ctrlfd );
02178 if (res)
02179 return res;
02180 if (num < 2000000)
02181 ast_copy_string(fn, "digits/1000000", sizeof(fn));
02182 else
02183 ast_copy_string(fn, "digits/1000000S", sizeof(fn));
02184
02185 if ((num % 1000000) &&
02186
02187 ((!((num / 1000) % 1000) && ((num % 1000) < 100 || !(num % 100))) ||
02188
02189 (!(num % 1000) && (((num / 1000) % 1000) < 100 || !((num / 1000) % 100))) ) )
02190 playh = 1;
02191 num = num % 1000000;
02192 } else {
02193
02194 ast_log(LOG_WARNING, "Number '%d' is too big to say.", num);
02195 res = -1;
02196 }
02197 if (!res) {
02198 if (!ast_streamfile(chan, fn, language)) {
02199 if ((audiofd > -1) && (ctrlfd > -1))
02200 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02201 else
02202 res = ast_waitstream(chan, ints);
02203 }
02204 ast_stopstream(chan);
02205 }
02206 if (!res && playh) {
02207 res = wait_file(chan, ints, "digits/pt-e", language);
02208 ast_stopstream(chan);
02209 playh = 0;
02210 }
02211 }
02212 return res;
02213 }
02214
02215
02216
02217
02218
02219
02220 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)
02221 {
02222 int playh = 0;
02223 int start = 1;
02224 char fn[256] = "";
02225 int cn = 1;
02226 int res = 0;
02227
02228 if (!num) {
02229 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02230 }
02231 if (options && !strncasecmp(options, "n", 1)) cn = -1;
02232
02233 while (num || playh) {
02234 if (num < 0) {
02235 ast_copy_string(fn, "digits/minus", sizeof(fn));
02236 if ( num > INT_MIN ) {
02237 num = -num;
02238 } else {
02239 num = 0;
02240 }
02241 } else if (playh) {
02242 ast_copy_string(fn, "digits/hundred", sizeof(fn));
02243 playh = 0;
02244 } else if (start && num < 200 && num > 99 && cn == -1) {
02245
02246 snprintf(fn, sizeof(fn), "digits/hundred");
02247 num -= 100;
02248 } else if (num == 1 && cn == -1) {
02249 ast_copy_string(fn, "digits/1N", sizeof(fn));
02250 num = 0;
02251 } else if (num < 20) {
02252 snprintf(fn, sizeof(fn), "digits/%d", num);
02253 num = 0;
02254 } else if (num < 100) {
02255 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
02256 num %= 10;
02257 } else if (num < 1000) {
02258
02259 snprintf(fn, sizeof(fn), "digits/%d", (num/100));
02260 playh++;
02261 num %= 100;
02262 } else if (num < 1000000) {
02263
02264 res = ast_say_number_full_se(chan, num / 1000, ints, language, "c", audiofd, ctrlfd);
02265 if (res) {
02266 return res;
02267 }
02268 num %= 1000;
02269 ast_copy_string(fn, "digits/thousand", sizeof(fn));
02270 } else if (num < 1000000000) {
02271
02272 res = ast_say_number_full_se(chan, num / 1000000, ints, language, "n", audiofd, ctrlfd);
02273 if (res) {
02274 return res;
02275 }
02276 num %= 1000000;
02277 ast_copy_string(fn, "digits/million", sizeof(fn));
02278 } else {
02279 ast_debug(1, "Number '%d' is too big for me\n", num);
02280 return -1;
02281 }
02282
02283 if (!ast_streamfile(chan, fn, language)) {
02284 if ((audiofd > -1) && (ctrlfd > -1)) {
02285 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02286 } else {
02287 res = ast_waitstream(chan, ints);
02288 }
02289 ast_stopstream(chan);
02290 if (res) {
02291 return res;
02292 }
02293 }
02294 start = 0;
02295 }
02296 return 0;
02297 }
02298
02299
02300 static int ast_say_number_full_zh(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
02301 {
02302 int res = 0;
02303 int playh = 0;
02304 int playt = 0;
02305 int playz = 0;
02306 int last_length = 0;
02307 char buf[20] = "";
02308 char fn[256] = "";
02309 if (!num)
02310 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02311
02312 while (!res && (num || playh || playt || playz)) {
02313 if (num < 0) {
02314 ast_copy_string(fn, "digits/minus", sizeof(fn));
02315 if ( num > INT_MIN ) {
02316 num = -num;
02317 } else {
02318 num = 0;
02319 }
02320 } else if (playz) {
02321 snprintf(fn, sizeof(fn), "digits/0");
02322 last_length = 0;
02323 playz = 0;
02324 } else if (playh) {
02325 ast_copy_string(fn, "digits/hundred", sizeof(fn));
02326 playh = 0;
02327 } else if (playt) {
02328 snprintf(fn, sizeof(fn), "digits/thousand");
02329 playt = 0;
02330 } else if (num < 10) {
02331 snprintf(buf, 10, "%d", num);
02332 if (last_length - strlen(buf) > 1 && last_length != 0) {
02333 last_length = strlen(buf);
02334 playz++;
02335 continue;
02336 }
02337 snprintf(fn, sizeof(fn), "digits/%d", num);
02338 num = 0;
02339 } else if (num < 100) {
02340 snprintf(buf, 10, "%d", num);
02341 if (last_length - strlen(buf) > 1 && last_length != 0) {
02342 last_length = strlen(buf);
02343 playz++;
02344 continue;
02345 }
02346 last_length = strlen(buf);
02347 snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
02348 num %= 10;
02349 } else {
02350 if (num < 1000){
02351 snprintf(buf, 10, "%d", num);
02352 if (last_length - strlen(buf) > 1 && last_length != 0) {
02353 last_length = strlen(buf);
02354 playz++;
02355 continue;
02356 }
02357 snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
02358 playh++;
02359 snprintf(buf, 10, "%d", num);
02360 ast_debug(1, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
02361 last_length = strlen(buf);
02362 num -= ((num / 100) * 100);
02363 } else if (num < 10000){
02364 snprintf(buf, 10, "%d", num);
02365 snprintf(fn, sizeof(fn), "digits/%d", (num / 1000));
02366 playt++;
02367 snprintf(buf, 10, "%d", num);
02368 ast_debug(1, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
02369 last_length = strlen(buf);
02370 num -= ((num / 1000) * 1000);
02371 } else if (num < 100000000) {
02372 res = ast_say_number_full_zh(chan, num / 10000, ints, language, audiofd, ctrlfd);
02373 if (res)
02374 return res;
02375 snprintf(buf, 10, "%d", num);
02376 ast_debug(1, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
02377 num -= ((num / 10000) * 10000);
02378 last_length = strlen(buf);
02379 snprintf(fn, sizeof(fn), "digits/wan");
02380 } else {
02381 if (num < 1000000000) {
02382 res = ast_say_number_full_zh(chan, num / 100000000, ints, language, audiofd, ctrlfd);
02383 if (res)
02384 return res;
02385 snprintf(buf, 10, "%d", num);
02386 ast_debug(1, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
02387 last_length = strlen(buf);
02388 num -= ((num / 100000000) * 100000000);
02389 snprintf(fn, sizeof(fn), "digits/yi");
02390 } else {
02391 ast_debug(1, "Number '%d' is too big for me\n", num);
02392 res = -1;
02393 }
02394 }
02395 }
02396 if (!res) {
02397 if (!ast_streamfile(chan, fn, language)) {
02398 if ((audiofd > -1) && (ctrlfd > -1))
02399 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02400 else
02401 res = ast_waitstream(chan, ints);
02402 }
02403 ast_stopstream(chan);
02404 }
02405 }
02406 return res;
02407 }
02408
02409
02410
02411
02412
02413 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)
02414 {
02415 int res = 0;
02416 int playh = 0;
02417 char fn[256] = "";
02418
02419 if (!num) {
02420 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02421 }
02422
02423 while (!res && (num || playh)) {
02424 if (playh) {
02425 snprintf(fn, sizeof(fn), "digits/hundred");
02426 playh = 0;
02427 } else if (num < 100) {
02428 snprintf(fn, sizeof(fn), "digits/%d", num);
02429 num = 0;
02430 } else if (num < 1000) {
02431 snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
02432 playh++;
02433 num -= ((num / 100) * 100);
02434 } else if (num < 100000) {
02435 if ((res = ast_say_number_full_ur(chan, num / 1000, ints, language, options, audiofd, ctrlfd))) {
02436 return res;
02437 }
02438 num = num % 1000;
02439 snprintf(fn, sizeof(fn), "digits/thousand");
02440 } else if (num < 10000000) {
02441 if ((res = ast_say_number_full_ur(chan, num / 100000, ints, language, options, audiofd, ctrlfd))) {
02442 return res;
02443 }
02444 num = num % 100000;
02445 snprintf(fn, sizeof(fn), "digits/lac");
02446 } else if (num < 1000000000) {
02447 if ((res = ast_say_number_full_ur(chan, num / 10000000, ints, language, options, audiofd, ctrlfd))) {
02448 return res;
02449 }
02450 num = num % 10000000;
02451 snprintf(fn, sizeof(fn), "digits/crore");
02452 } else {
02453 ast_debug(1, "Number '%d' is too big for me\n", num);
02454 res = -1;
02455 }
02456
02457 if (!res) {
02458 if (!ast_streamfile(chan, fn, language)) {
02459 if ((audiofd > -1) && (ctrlfd > -1)) {
02460 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02461 } else {
02462 res = ast_waitstream(chan, ints);
02463 }
02464 }
02465 ast_stopstream(chan);
02466 }
02467 }
02468 return res;
02469 }
02470
02471
02472 static int get_lastdigits_ru(int num) {
02473 if (num < 20) {
02474 return num;
02475 } else if (num < 100) {
02476 return get_lastdigits_ru(num % 10);
02477 } else if (num < 1000) {
02478 return get_lastdigits_ru(num % 100);
02479 }
02480 return 0;
02481 }
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499 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)
02500 {
02501 int res = 0;
02502 int lastdigits = 0;
02503 char fn[256] = "";
02504 if (!num)
02505 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02506
02507 while (!res && (num)) {
02508 if (num < 0) {
02509 ast_copy_string(fn, "digits/minus", sizeof(fn));
02510 if ( num > INT_MIN ) {
02511 num = -num;
02512 } else {
02513 num = 0;
02514 }
02515 } else if (num < 20) {
02516 if (options && strlen(options) == 1 && num < 3) {
02517 snprintf(fn, sizeof(fn), "digits/%d%s", num, options);
02518 } else {
02519 snprintf(fn, sizeof(fn), "digits/%d", num);
02520 }
02521 num = 0;
02522 } else if (num < 100) {
02523 snprintf(fn, sizeof(fn), "digits/%d", num - (num % 10));
02524 num %= 10;
02525 } else if (num < 1000){
02526 snprintf(fn, sizeof(fn), "digits/%d", num - (num % 100));
02527 num %= 100;
02528 } else if (num < 1000000) {
02529 lastdigits = get_lastdigits_ru(num / 1000);
02530
02531 if (lastdigits < 3) {
02532 res = ast_say_number_full_ru(chan, num / 1000, ints, language, "f", audiofd, ctrlfd);
02533 } else {
02534 res = ast_say_number_full_ru(chan, num / 1000, ints, language, NULL, audiofd, ctrlfd);
02535 }
02536 if (res)
02537 return res;
02538 if (lastdigits == 1) {
02539 ast_copy_string(fn, "digits/thousand", sizeof(fn));
02540 } else if (lastdigits > 1 && lastdigits < 5) {
02541 ast_copy_string(fn, "digits/thousands-i", sizeof(fn));
02542 } else {
02543 ast_copy_string(fn, "digits/thousands", sizeof(fn));
02544 }
02545 num %= 1000;
02546 } else if (num < 1000000000) {
02547 lastdigits = get_lastdigits_ru(num / 1000000);
02548
02549 res = ast_say_number_full_ru(chan, num / 1000000, ints, language, NULL, audiofd, ctrlfd);
02550 if (res)
02551 return res;
02552 if (lastdigits == 1) {
02553 ast_copy_string(fn, "digits/million", sizeof(fn));
02554 } else if (lastdigits > 1 && lastdigits < 5) {
02555 ast_copy_string(fn, "digits/million-a", sizeof(fn));
02556 } else {
02557 ast_copy_string(fn, "digits/millions", sizeof(fn));
02558 }
02559 num %= 1000000;
02560 } else {
02561 ast_debug(1, "Number '%d' is too big for me\n", num);
02562 res = -1;
02563 }
02564 if (!res) {
02565 if (!ast_streamfile(chan, fn, language)) {
02566 if ((audiofd > -1) && (ctrlfd > -1))
02567 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02568 else
02569 res = ast_waitstream(chan, ints);
02570 }
02571 ast_stopstream(chan);
02572 }
02573 }
02574 return res;
02575 }
02576
02577
02578 static int ast_say_number_full_th(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
02579 {
02580 int res = 0;
02581 int playh = 0;
02582 char fn[256] = "";
02583 if (!num)
02584 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02585
02586 while(!res && (num || playh)) {
02587 if (num < 0) {
02588 ast_copy_string(fn, "digits/lop", sizeof(fn));
02589 if ( num > INT_MIN ) {
02590 num = -num;
02591 } else {
02592 num = 0;
02593 }
02594 } else if (playh) {
02595 ast_copy_string(fn, "digits/roi", sizeof(fn));
02596 playh = 0;
02597 } else if (num < 100) {
02598 if ((num <= 20) || ((num % 10) == 1)) {
02599 snprintf(fn, sizeof(fn), "digits/%d", num);
02600 num = 0;
02601 } else {
02602 snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
02603 num %= 10;
02604 }
02605 } else if (num < 1000) {
02606 snprintf(fn, sizeof(fn), "digits/%d", (num/100));
02607 playh++;
02608 num %= 100;
02609 } else if (num < 10000) {
02610 res = ast_say_number_full_th(chan, num / 1000, ints, language, audiofd, ctrlfd);
02611 if (res)
02612 return res;
02613 num %= 1000;
02614 ast_copy_string(fn, "digits/pan", sizeof(fn));
02615 } else if (num < 100000) {
02616 res = ast_say_number_full_th(chan, num / 10000, ints, language, audiofd, ctrlfd);
02617 if (res)
02618 return res;
02619 num %= 10000;
02620 ast_copy_string(fn, "digits/muan", sizeof(fn));
02621 } else if (num < 1000000) {
02622 res = ast_say_number_full_th(chan, num / 100000, ints, language, audiofd, ctrlfd);
02623 if (res)
02624 return res;
02625 num %= 100000;
02626 ast_copy_string(fn, "digits/san", sizeof(fn));
02627 } else {
02628 res = ast_say_number_full_th(chan, num / 1000000, ints, language, audiofd, ctrlfd);
02629 if (res)
02630 return res;
02631 num %= 1000000;
02632 ast_copy_string(fn, "digits/larn", sizeof(fn));
02633 }
02634 if (!res) {
02635 if(!ast_streamfile(chan, fn, language)) {
02636 if ((audiofd > -1) && (ctrlfd > -1))
02637 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02638 else
02639 res = ast_waitstream(chan, ints);
02640 }
02641 ast_stopstream(chan);
02642 }
02643 }
02644 return res;
02645 }
02646
02647
02648 static int ast_say_number_full_vi(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
02649 {
02650 int res = 0;
02651 int playh = 0;
02652 int playoh = 0;
02653 int playohz = 0;
02654 int playz = 0;
02655 int playl = 0;
02656 char fn[256] = "";
02657 if (!num)
02658 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02659 while (!res && (num || playh)) {
02660 if (num < 0) {
02661 ast_copy_string(fn, "digits/minus", sizeof(fn));
02662 if ( num > INT_MIN ) {
02663 num = -num;
02664 } else {
02665 num = 0;
02666 }
02667 } else if (playl) {
02668 snprintf(fn, sizeof(fn), "digits/%da", num);
02669 playl = 0;
02670 num = 0;
02671 } else if (playh) {
02672 ast_copy_string(fn, "digits/hundred", sizeof(fn));
02673 playh = 0;
02674 } else if (playz) {
02675 ast_copy_string(fn, "digits/odd", sizeof(fn));
02676 playz = 0;
02677 } else if (playoh) {
02678 ast_copy_string(fn, "digits/0-hundred", sizeof(fn));
02679 playoh = 0;
02680 } else if (playohz) {
02681 ast_copy_string(fn, "digits/0-hundred-odd", sizeof(fn));
02682 playohz = 0;
02683 } else if (num < 20) {
02684 snprintf(fn, sizeof(fn), "digits/%d", num);
02685 num = 0;
02686 } else if (num < 100) {
02687 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
02688 num %= 10;
02689 if ((num == 5) || (num == 4) || (num == 1)) playl++;
02690 } else {
02691 if (num < 1000) {
02692 snprintf(fn, sizeof(fn), "digits/%d", (num/100));
02693 num %= 100;
02694 if (num && (num < 10)) {
02695 playz++;
02696 playh++;
02697 } else {
02698 playh++;
02699 }
02700 } else {
02701 if (num < 1000000) {
02702 res = ast_say_number_full_vi(chan, num / 1000, ints, language, audiofd, ctrlfd);
02703 if (res)
02704 return res;
02705 num %= 1000;
02706 snprintf(fn, sizeof(fn), "digits/thousand");
02707 if (num && (num < 10)) {
02708 playohz++;
02709 } else if (num && (num < 100)){
02710 playoh++;
02711 } else {
02712 playh = 0;
02713 playohz = 0;
02714 playoh = 0;
02715 }
02716 } else {
02717 if (num < 1000000000) {
02718 res = ast_say_number_full_vi(chan, num / 1000000, ints, language, audiofd, ctrlfd);
02719 if (res)
02720 return res;
02721 num %= 1000000;
02722 ast_copy_string(fn, "digits/million", sizeof(fn));
02723 } else {
02724 res = -1;
02725 }
02726 }
02727 }
02728 }
02729 if (!res) {
02730 if (!ast_streamfile(chan, fn, language)) {
02731 if ((audiofd > -1) && (ctrlfd > -1))
02732 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02733 else
02734 res = ast_waitstream(chan, ints);
02735 }
02736 ast_stopstream(chan);
02737 }
02738 }
02739 return res;
02740 }
02741
02742
02743
02744 static int say_enumeration_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
02745 {
02746 if (!strncasecmp(language, "en", 2)) {
02747 return ast_say_enumeration_full_en(chan, num, ints, language, audiofd, ctrlfd);
02748 } else if (!strncasecmp(language, "da", 2)) {
02749 return ast_say_enumeration_full_da(chan, num, ints, language, options, audiofd, ctrlfd);
02750 } else if (!strncasecmp(language, "de", 2)) {
02751 return ast_say_enumeration_full_de(chan, num, ints, language, options, audiofd, ctrlfd);
02752 } else if (!strncasecmp(language, "he", 2)) {
02753 return ast_say_enumeration_full_he(chan, num, ints, language, options, audiofd, ctrlfd);
02754 } else if (!strncasecmp(language, "vi", 2)) {
02755 return ast_say_enumeration_full_vi(chan, num, ints, language, audiofd, ctrlfd);
02756 }
02757
02758
02759 return ast_say_enumeration_full_en(chan, num, ints, language, audiofd, ctrlfd);
02760 }
02761
02762
02763
02764 static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
02765 {
02766 int res = 0, t = 0;
02767 char fn[256] = "";
02768
02769 while (!res && num) {
02770 if (num < 0) {
02771 ast_copy_string(fn, "digits/minus", sizeof(fn));
02772 if ( num > INT_MIN ) {
02773 num = -num;
02774 } else {
02775 num = 0;
02776 }
02777 } else if (num < 20) {
02778 snprintf(fn, sizeof(fn), "digits/h-%d", num);
02779 num = 0;
02780 } else if (num < 100) {
02781 int tens = num / 10;
02782 num = num % 10;
02783 if (num == 0) {
02784 snprintf(fn, sizeof(fn), "digits/h-%d", (tens * 10));
02785 } else {
02786 snprintf(fn, sizeof(fn), "digits/%d", (tens * 10));
02787 }
02788 } else if (num < 1000) {
02789 int hundreds = num / 100;
02790 num = num % 100;
02791 if (hundreds > 1 || t == 1) {
02792 res = ast_say_number_full_en(chan, hundreds, ints, language, audiofd, ctrlfd);
02793 }
02794 if (res)
02795 return res;
02796 if (num) {
02797 ast_copy_string(fn, "digits/hundred", sizeof(fn));
02798 } else {
02799 ast_copy_string(fn, "digits/h-hundred", sizeof(fn));
02800 }
02801 } else if (num < 1000000) {
02802 int thousands = num / 1000;
02803 num = num % 1000;
02804 if (thousands > 1 || t == 1) {
02805 res = ast_say_number_full_en(chan, thousands, ints, language, audiofd, ctrlfd);
02806 }
02807 if (res)
02808 return res;
02809 if (num) {
02810 ast_copy_string(fn, "digits/thousand", sizeof(fn));
02811 } else {
02812 ast_copy_string(fn, "digits/h-thousand", sizeof(fn));
02813 }
02814 t = 1;
02815 } else if (num < 1000000000) {
02816 int millions = num / 1000000;
02817 num = num % 1000000;
02818 t = 1;
02819 res = ast_say_number_full_en(chan, millions, ints, language, audiofd, ctrlfd);
02820 if (res)
02821 return res;
02822 if (num) {
02823 ast_copy_string(fn, "digits/million", sizeof(fn));
02824 } else {
02825 ast_copy_string(fn, "digits/h-million", sizeof(fn));
02826 }
02827 } else if (num < INT_MAX) {
02828 int billions = num / 1000000000;
02829 num = num % 1000000000;
02830 t = 1;
02831 res = ast_say_number_full_en(chan, billions, ints, language, audiofd, ctrlfd);
02832 if (res)
02833 return res;
02834 if (num) {
02835 ast_copy_string(fn, "digits/billion", sizeof(fn));
02836 } else {
02837 ast_copy_string(fn, "digits/h-billion", sizeof(fn));
02838 }
02839 } else if (num == INT_MAX) {
02840 ast_copy_string(fn, "digits/h-last", sizeof(fn));
02841 num = 0;
02842 } else {
02843 ast_debug(1, "Number '%d' is too big for me\n", num);
02844 res = -1;
02845 }
02846
02847 if (!res) {
02848 if (!ast_streamfile(chan, fn, language)) {
02849 if ((audiofd > -1) && (ctrlfd > -1)) {
02850 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02851 } else {
02852 res = ast_waitstream(chan, ints);
02853 }
02854 }
02855 ast_stopstream(chan);
02856 }
02857 }
02858 return res;
02859 }
02860
02861 static int ast_say_enumeration_full_vi(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
02862 {
02863 int res = 0;
02864 char fn[256] = "";
02865 ast_copy_string(fn, "digits/h", sizeof(fn));
02866 if (!res) {
02867 if (!ast_streamfile(chan, fn, language)) {
02868 if ((audiofd > -1) && (ctrlfd > -1)) {
02869 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02870 } else {
02871 res = ast_waitstream(chan, ints);
02872 }
02873 }
02874 ast_stopstream(chan);
02875 }
02876
02877 return ast_say_number_full_vi(chan, num, ints, language, audiofd, ctrlfd);
02878 }
02879
02880
02881 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)
02882 {
02883
02884 int res = 0, t = 0;
02885 char fn[256] = "", fna[256] = "";
02886 char *gender;
02887
02888 if (options && !strncasecmp(options, "f", 1)) {
02889 gender = "F";
02890 } else if (options && !strncasecmp(options, "n", 1)) {
02891 gender = "N";
02892 } else {
02893 gender = "";
02894 }
02895
02896 if (!num)
02897 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02898
02899 while (!res && num) {
02900 if (num < 0) {
02901 ast_copy_string(fn, "digits/minus", sizeof(fn));
02902 if ( num > INT_MIN ) {
02903 num = -num;
02904 } else {
02905 num = 0;
02906 }
02907 } else if (num < 100 && t) {
02908 ast_copy_string(fn, "digits/and", sizeof(fn));
02909 t = 0;
02910 } else if (num < 20) {
02911 snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
02912 num = 0;
02913 } else if (num < 100) {
02914 int ones = num % 10;
02915 if (ones) {
02916 snprintf(fn, sizeof(fn), "digits/%d-and", ones);
02917 num -= ones;
02918 } else {
02919 snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
02920 num = 0;
02921 }
02922 } else if (num == 100 && t == 0) {
02923 snprintf(fn, sizeof(fn), "digits/h-hundred%s", gender);
02924 num = 0;
02925 } else if (num < 1000) {
02926 int hundreds = num / 100;
02927 num = num % 100;
02928 if (hundreds == 1) {
02929 ast_copy_string(fn, "digits/1N", sizeof(fn));
02930 } else {
02931 snprintf(fn, sizeof(fn), "digits/%d", hundreds);
02932 }
02933 if (num) {
02934 ast_copy_string(fna, "digits/hundred", sizeof(fna));
02935 } else {
02936 snprintf(fna, sizeof(fna), "digits/h-hundred%s", gender);
02937 }
02938 t = 1;
02939 } else if (num < 1000000) {
02940 int thousands = num / 1000;
02941 num = num % 1000;
02942 if (thousands == 1) {
02943 if (num) {
02944 ast_copy_string(fn, "digits/1N", sizeof(fn));
02945 ast_copy_string(fna, "digits/thousand", sizeof(fna));
02946 } else {
02947 if (t) {
02948 ast_copy_string(fn, "digits/1N", sizeof(fn));
02949 snprintf(fna, sizeof(fna), "digits/h-thousand%s", gender);
02950 } else {
02951 snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
02952 }
02953 }
02954 } else {
02955 res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
02956 if (res) {
02957 return res;
02958 }
02959 if (num) {
02960 ast_copy_string(fn, "digits/thousand", sizeof(fn));
02961 } else {
02962 snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
02963 }
02964 }
02965 t = 1;
02966 } else if (num < 1000000000) {
02967 int millions = num / 1000000;
02968 num = num % 1000000;
02969 if (millions == 1) {
02970 if (num) {
02971 ast_copy_string(fn, "digits/1F", sizeof(fn));
02972 ast_copy_string(fna, "digits/million", sizeof(fna));
02973 } else {
02974 ast_copy_string(fn, "digits/1N", sizeof(fn));
02975 snprintf(fna, sizeof(fna), "digits/h-million%s", gender);
02976 }
02977 } else {
02978 res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
02979 if (res) {
02980 return res;
02981 }
02982 if (num) {
02983 ast_copy_string(fn, "digits/millions", sizeof(fn));
02984 } else {
02985 snprintf(fn, sizeof(fn), "digits/h-million%s", gender);
02986 }
02987 }
02988 t = 1;
02989 } else if (num < INT_MAX) {
02990 int billions = num / 1000000000;
02991 num = num % 1000000000;
02992 if (billions == 1) {
02993 if (num) {
02994 ast_copy_string(fn, "digits/1F", sizeof(fn));
02995 ast_copy_string(fna, "digits/milliard", sizeof(fna));
02996 } else {
02997 ast_copy_string(fn, "digits/1N", sizeof(fn));
02998 snprintf(fna, sizeof(fna), "digits/h-milliard%s", gender);
02999 }
03000 } else {
03001 res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
03002 if (res)
03003 return res;
03004 if (num) {
03005 ast_copy_string(fn, "digits/milliards", sizeof(fna));
03006 } else {
03007 snprintf(fn, sizeof(fna), "digits/h-milliard%s", gender);
03008 }
03009 }
03010 t = 1;
03011 } else if (num == INT_MAX) {
03012 snprintf(fn, sizeof(fn), "digits/h-last%s", gender);
03013 num = 0;
03014 } else {
03015 ast_debug(1, "Number '%d' is too big for me\n", num);
03016 res = -1;
03017 }
03018
03019 if (!res) {
03020 if (!ast_streamfile(chan, fn, language)) {
03021 if ((audiofd > -1) && (ctrlfd > -1))
03022 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
03023 else
03024 res = ast_waitstream(chan, ints);
03025 }
03026 ast_stopstream(chan);
03027 if (!res) {
03028 if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
03029 if ((audiofd > -1) && (ctrlfd > -1)) {
03030 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
03031 } else {
03032 res = ast_waitstream(chan, ints);
03033 }
03034 }
03035 ast_stopstream(chan);
03036 strcpy(fna, "");
03037 }
03038 }
03039 }
03040 return res;
03041 }
03042
03043
03044 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)
03045 {
03046
03047 int res = 0, t = 0;
03048 char fn[256] = "", fna[256] = "";
03049 char *gender;
03050
03051 if (options && !strncasecmp(options, "f", 1)) {
03052 gender = "F";
03053 } else if (options && !strncasecmp(options, "n", 1)) {
03054 gender = "N";
03055 } else {
03056 gender = "";
03057 }
03058
03059 if (!num)
03060 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
03061
03062 while (!res && num) {
03063 if (num < 0) {
03064 ast_copy_string(fn, "digits/minus", sizeof(fn));
03065 if ( num > INT_MIN ) {
03066 num = -num;
03067 } else {
03068 num = 0;
03069 }
03070 } else if (num < 100 && t) {
03071 ast_copy_string(fn, "digits/and", sizeof(fn));
03072 t = 0;
03073 } else if (num < 20) {
03074 snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
03075 num = 0;
03076 } else if (num < 100) {
03077 int ones = num % 10;
03078 if (ones) {
03079 snprintf(fn, sizeof(fn), "digits/%d-and", ones);
03080 num -= ones;
03081 } else {
03082 snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
03083 num = 0;
03084 }
03085 } else if (num == 100 && t == 0) {
03086 snprintf(fn, sizeof(fn), "digits/h-hundred%s", gender);
03087 num = 0;
03088 } else if (num < 1000) {
03089 int hundreds = num / 100;
03090 num = num % 100;
03091 if (hundreds == 1) {
03092 ast_copy_string(fn, "digits/1N", sizeof(fn));
03093 } else {
03094 snprintf(fn, sizeof(fn), "digits/%d", hundreds);
03095 }
03096 if (num) {
03097 ast_copy_string(fna, "digits/hundred", sizeof(fna));
03098 } else {
03099 snprintf(fna, sizeof(fna), "digits/h-hundred%s", gender);
03100 }
03101 t = 1;
03102 } else if (num < 1000000) {
03103 int thousands = num / 1000;
03104 num = num % 1000;
03105 if (thousands == 1) {
03106 if (num) {
03107 ast_copy_string(fn, "digits/1N", sizeof(fn));
03108 ast_copy_string(fna, "digits/thousand", sizeof(fna));
03109 } else {
03110 if (t) {
03111 ast_copy_string(fn, "digits/1N", sizeof(fn));
03112 snprintf(fna, sizeof(fna), "digits/h-thousand%s", gender);
03113 } else {
03114 snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
03115 }
03116 }
03117 } else {
03118 res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
03119 if (res) {
03120 return res;
03121 }
03122 if (num) {
03123 ast_copy_string(fn, "digits/thousand", sizeof(fn));
03124 } else {
03125 snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
03126 }
03127 }
03128 t = 1;
03129 } else if (num < 1000000000) {
03130 int millions = num / 1000000;
03131 num = num % 1000000;
03132 if (millions == 1) {
03133 if (num) {
03134 ast_copy_string(fn, "digits/1F", sizeof(fn));
03135 ast_copy_string(fna, "digits/million", sizeof(fna));
03136 } else {
03137 ast_copy_string(fn, "digits/1N", sizeof(fn));
03138 snprintf(fna, sizeof(fna), "digits/h-million%s", gender);
03139 }
03140 } else {
03141 res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
03142 if (res) {
03143 return res;
03144 }
03145 if (num) {
03146 ast_copy_string(fn, "digits/millions", sizeof(fn));
03147 } else {
03148 snprintf(fn, sizeof(fn), "digits/h-million%s", gender);
03149 }
03150 }
03151 t = 1;
03152 } else if (num < INT_MAX) {
03153 int billions = num / 1000000000;
03154 num = num % 1000000000;
03155 if (billions == 1) {
03156 if (num) {
03157 ast_copy_string(fn, "digits/1F", sizeof(fn));
03158 ast_copy_string(fna, "digits/milliard", sizeof(fna));
03159 } else {
03160 ast_copy_string(fn, "digits/1N", sizeof(fn));
03161 snprintf(fna, sizeof(fna), "digits/h-milliard%s", gender);
03162 }
03163 } else {
03164 res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
03165 if (res)
03166 return res;
03167 if (num) {
03168 ast_copy_string(fn, "digits/milliards", sizeof(fna));
03169 } else {
03170 snprintf(fn, sizeof(fna), "digits/h-milliard%s", gender);
03171 }
03172 }
03173 t = 1;
03174 } else if (num == INT_MAX) {
03175 snprintf(fn, sizeof(fn), "digits/h-last%s", gender);
03176 num = 0;
03177 } else {
03178 ast_debug(1, "Number '%d' is too big for me\n", num);
03179 res = -1;
03180 }
03181
03182 if (!res) {
03183 if (!ast_streamfile(chan, fn, language)) {
03184 if ((audiofd > -1) && (ctrlfd > -1))
03185 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
03186 else
03187 res = ast_waitstream(chan, ints);
03188 }
03189 ast_stopstream(chan);
03190 if (!res) {
03191 if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
03192 if ((audiofd > -1) && (ctrlfd > -1)) {
03193 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
03194 } else {
03195 res = ast_waitstream(chan, ints);
03196 }
03197 }
03198 ast_stopstream(chan);
03199 strcpy(fna, "");
03200 }
03201 }
03202 }
03203 return res;
03204 }
03205
03206 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)
03207 {
03208 int res = 0;
03209 char fn[256] = "";
03210 int mf = -1;
03211 ast_verb(3, "ast_say_digits_full: started. num: %d, options=\"%s\"\n", num, options);
03212
03213 if (options && !strncasecmp(options, "m", 1)) {
03214 mf = -1;
03215 }
03216
03217 ast_verb(3, "ast_say_digits_full: num: %d, options=\"%s\", mf=%d\n", num, options, mf);
03218
03219 while (!res && num) {
03220 if (num < 0) {
03221 snprintf(fn, sizeof(fn), "digits/minus");
03222 if (num > INT_MIN) {
03223 num = -num;
03224 } else {
03225 num = 0;
03226 }
03227 } else if (num < 21) {
03228 if (mf < 0) {
03229 if (num < 10) {
03230 snprintf(fn, sizeof(fn), "digits/f-0%d", num);
03231 } else {
03232 snprintf(fn, sizeof(fn), "digits/f-%d", num);
03233 }
03234 } else {
03235 if (num < 10) {
03236 snprintf(fn, sizeof(fn), "digits/m-0%d", num);
03237 } else {
03238 snprintf(fn, sizeof(fn), "digits/m-%d", num);
03239 }
03240 }
03241 num = 0;
03242 } else if ((num < 100) && num >= 20) {
03243 snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
03244 num = num % 10;
03245 } else if ((num >= 100) && (num < 1000)) {
03246 int tmpnum = num / 100;
03247 snprintf(fn, sizeof(fn), "digits/%d00", tmpnum);
03248 num = num - (tmpnum * 100);
03249 } else if ((num >= 1000) && (num < 10000)) {
03250 int tmpnum = num / 1000;
03251 snprintf(fn, sizeof(fn), "digits/%dk", tmpnum);
03252 num = num - (tmpnum * 1000);
03253 } else if (num < 20000) {
03254 snprintf(fn, sizeof(fn), "digits/m-%d", (num / 1000));
03255 num = num % 1000;
03256 } else if (num < 1000000) {
03257 res = ast_say_number_full_he(chan, num / 1000, ints, language, "m", audiofd, ctrlfd);
03258 if (res) {
03259 return res;
03260 }
03261 snprintf(fn, sizeof(fn), "digits/1k");
03262 num = num % 1000;
03263 } else if (num < 2000000) {
03264 snprintf(fn, sizeof(fn), "digits/1m");
03265 num = num % 1000000;
03266 } else if (num < 3000000) {
03267 snprintf(fn, sizeof(fn), "digits/2m");
03268 num = num - 2000000;
03269 } else if (num < 1000000000) {
03270 res = ast_say_number_full_he(chan, num / 1000000, ints, language, "m", audiofd, ctrlfd);
03271 if (res) {
03272 return res;
03273 }
03274 snprintf(fn, sizeof(fn), "digits/1m");
03275 num = num % 1000000;
03276 } else {
03277 ast_debug(1, "Number '%d' is too big for me\n", num);
03278 res = -1;
03279 }
03280 if (!res) {
03281 if (!ast_streamfile(chan, fn, language)) {
03282 if ((audiofd > -1) && (ctrlfd > -1)) {
03283 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
03284 } else {
03285 res = ast_waitstream(chan, ints);
03286 }
03287 }
03288 ast_stopstream(chan);
03289 }
03290 }
03291 return res;
03292 }
03293
03294 static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03295 {
03296 if (!strncasecmp(lang, "en", 2)) {
03297 return ast_say_date_en(chan, t, ints, lang);
03298 } else if (!strncasecmp(lang, "da", 2)) {
03299 return ast_say_date_da(chan, t, ints, lang);
03300 } else if (!strncasecmp(lang, "de", 2)) {
03301 return ast_say_date_de(chan, t, ints, lang);
03302 } else if (!strncasecmp(lang, "fr", 2)) {
03303 return ast_say_date_fr(chan, t, ints, lang);
03304 } else if (!strncasecmp(lang, "ge", 2)) {
03305 static int deprecation_warning = 0;
03306 if (deprecation_warning++ % 10 == 0) {
03307 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
03308 }
03309 return ast_say_date_ka(chan, t, ints, lang);
03310 } else if (!strncasecmp(lang, "gr", 2)) {
03311 return ast_say_date_gr(chan, t, ints, lang);
03312 } else if (!strncasecmp(lang, "he", 2)) {
03313 return ast_say_date_he(chan, t, ints, lang);
03314 } else if (!strncasecmp(lang, "hu", 2)) {
03315 return ast_say_date_hu(chan, t, ints, lang);
03316 } else if (!strncasecmp(lang, "ka", 2)) {
03317 return ast_say_date_ka(chan, t, ints, lang);
03318 } else if (!strncasecmp(lang, "nl", 2)) {
03319 return ast_say_date_nl(chan, t, ints, lang);
03320 } else if (!strncasecmp(lang, "pt", 2)) {
03321 return ast_say_date_pt(chan, t, ints, lang);
03322 } else if (!strncasecmp(lang, "th", 2)) {
03323 return ast_say_date_th(chan, t, ints, lang);
03324 }
03325
03326
03327 return ast_say_date_en(chan, t, ints, lang);
03328 }
03329
03330
03331 int ast_say_date_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03332 {
03333 struct ast_tm tm;
03334 struct timeval when = { t, 0 };
03335 char fn[256];
03336 int res = 0;
03337 ast_localtime(&when, &tm, NULL);
03338 if (!res) {
03339 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03340 res = ast_streamfile(chan, fn, lang);
03341 if (!res)
03342 res = ast_waitstream(chan, ints);
03343 }
03344 if (!res) {
03345 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03346 res = ast_streamfile(chan, fn, lang);
03347 if (!res)
03348 res = ast_waitstream(chan, ints);
03349 }
03350 if (!res)
03351 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03352 if (!res)
03353 res = ast_waitstream(chan, ints);
03354 if (!res)
03355 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03356 return res;
03357 }
03358
03359
03360 int ast_say_date_da(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03361 {
03362 struct timeval when = { t, 0 };
03363 struct ast_tm tm;
03364 char fn[256];
03365 int res = 0;
03366 ast_localtime(&when, &tm, NULL);
03367 if (!res) {
03368 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03369 res = ast_streamfile(chan, fn, lang);
03370 if (!res)
03371 res = ast_waitstream(chan, ints);
03372 }
03373 if (!res)
03374 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03375 if (!res)
03376 res = ast_waitstream(chan, ints);
03377 if (!res) {
03378 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03379 res = ast_streamfile(chan, fn, lang);
03380 if (!res)
03381 res = ast_waitstream(chan, ints);
03382 }
03383 if (!res) {
03384
03385 int year = tm.tm_year + 1900;
03386 if (year > 1999) {
03387 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
03388 } else {
03389 if (year < 1100) {
03390
03391
03392 } else {
03393
03394 snprintf(fn, sizeof(fn), "digits/%d", (year / 100));
03395 res = wait_file(chan, ints, fn, lang);
03396 if (!res) {
03397 res = wait_file(chan, ints, "digits/hundred", lang);
03398 if (!res && year % 100 != 0) {
03399 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
03400 }
03401 }
03402 }
03403 }
03404 }
03405 return res;
03406 }
03407
03408
03409 int ast_say_date_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03410 {
03411 struct timeval when = { t, 0 };
03412 struct ast_tm tm;
03413 char fn[256];
03414 int res = 0;
03415 ast_localtime(&when, &tm, NULL);
03416 if (!res) {
03417 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03418 res = ast_streamfile(chan, fn, lang);
03419 if (!res)
03420 res = ast_waitstream(chan, ints);
03421 }
03422 if (!res)
03423 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03424 if (!res)
03425 res = ast_waitstream(chan, ints);
03426 if (!res) {
03427 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03428 res = ast_streamfile(chan, fn, lang);
03429 if (!res)
03430 res = ast_waitstream(chan, ints);
03431 }
03432 if (!res) {
03433
03434 int year = tm.tm_year + 1900;
03435 if (year > 1999) {
03436 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
03437 } else {
03438 if (year < 1100) {
03439
03440
03441 } else {
03442
03443
03444 snprintf(fn, sizeof(fn), "digits/%d", (year / 100) );
03445 res = wait_file(chan, ints, fn, lang);
03446 if (!res) {
03447 res = wait_file(chan, ints, "digits/hundred", lang);
03448 if (!res && year % 100 != 0) {
03449 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
03450 }
03451 }
03452 }
03453 }
03454 }
03455 return res;
03456 }
03457
03458
03459 int ast_say_date_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03460 {
03461 struct timeval when = { t, 0 };
03462 struct ast_tm tm;
03463 char fn[256];
03464 int res = 0;
03465 ast_localtime(&when, &tm, NULL);
03466
03467 if (!res)
03468 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03469 if (!res)
03470 res = ast_waitstream(chan, ints);
03471 if (!res) {
03472 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03473 res = ast_streamfile(chan, fn, lang);
03474 if (!res)
03475 res = ast_waitstream(chan, ints);
03476 }
03477 if (!res)
03478 ast_say_number(chan, tm.tm_mday , ints, lang, (char *) NULL);
03479 if (!res)
03480 res = ast_waitstream(chan, ints);
03481 if (!res) {
03482 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03483 res = ast_streamfile(chan, fn, lang);
03484 if (!res)
03485 res = ast_waitstream(chan, ints);
03486 }
03487 return res;
03488 }
03489
03490
03491 int ast_say_date_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03492 {
03493 struct timeval when = { t, 0 };
03494 struct ast_tm tm;
03495 char fn[256];
03496 int res = 0;
03497 ast_localtime(&when, &tm, NULL);
03498 if (!res) {
03499 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03500 res = ast_streamfile(chan, fn, lang);
03501 if (!res)
03502 res = ast_waitstream(chan, ints);
03503 }
03504 if (!res)
03505 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03506 if (!res)
03507 res = ast_waitstream(chan, ints);
03508 if (!res) {
03509 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03510 res = ast_streamfile(chan, fn, lang);
03511 if (!res)
03512 res = ast_waitstream(chan, ints);
03513 }
03514 if (!res)
03515 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03516 return res;
03517 }
03518
03519
03520 int ast_say_date_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03521 {
03522 struct timeval when = { t, 0 };
03523 struct ast_tm tm;
03524 char fn[256];
03525 int res = 0;
03526 ast_localtime(&when, &tm, NULL);
03527 if (!res) {
03528 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03529 res = ast_streamfile(chan, fn, lang);
03530 if (!res)
03531 res = ast_waitstream(chan, ints);
03532 }
03533 if (!res)
03534 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03535 if (!res) {
03536 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03537 res = ast_streamfile(chan, fn, lang);
03538 if (!res)
03539 res = ast_waitstream(chan, ints);
03540 }
03541 if (!res)
03542 res = ast_waitstream(chan, ints);
03543 if (!res)
03544 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03545 return res;
03546 }
03547
03548
03549 int ast_say_date_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03550 {
03551 struct timeval when = { t, 0 };
03552 struct ast_tm tm;
03553 char fn[256];
03554 int res = 0;
03555 ast_localtime(&when, &tm, NULL);
03556 if (!res) {
03557 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03558 res = ast_streamfile(chan, fn, lang);
03559 ast_copy_string(fn, "digits/tee", sizeof(fn));
03560 res = ast_streamfile(chan, fn, lang);
03561 if (!res)
03562 res = ast_waitstream(chan, ints);
03563 }
03564 if (!res)
03565 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03566 if (!res)
03567 res = ast_waitstream(chan, ints);
03568 if (!res) {
03569 ast_copy_string(fn, "digits/duan", sizeof(fn));
03570 res = ast_streamfile(chan, fn, lang);
03571 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03572 res = ast_streamfile(chan, fn, lang);
03573 if (!res)
03574 res = ast_waitstream(chan, ints);
03575 }
03576 if (!res){
03577 ast_copy_string(fn, "digits/posor", sizeof(fn));
03578 res = ast_streamfile(chan, fn, lang);
03579 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03580 }
03581 return res;
03582 }
03583
03584
03585 int ast_say_date_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03586 {
03587 struct timeval when = { t, 0 };
03588 struct ast_tm tm;
03589 char fn[256];
03590 int res = 0;
03591
03592 ast_localtime(&when, &tm, NULL);
03593 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03594 if (!res)
03595 res = wait_file(chan, ints, fn, lang);
03596 if (!res)
03597 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
03598 if (!res)
03599 res = wait_file(chan, ints, "digits/pt-de", lang);
03600 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03601 if (!res)
03602 res = wait_file(chan, ints, fn, lang);
03603 if (!res)
03604 res = wait_file(chan, ints, "digits/pt-de", lang);
03605 if (!res)
03606 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03607
03608 return res;
03609 }
03610
03611
03612 int ast_say_date_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03613 {
03614 struct timeval when = { t, 0 };
03615 struct ast_tm tm;
03616 char fn[256];
03617 int res = 0;
03618 ast_localtime(&when, &tm, NULL);
03619 if (!res) {
03620 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03621 res = ast_streamfile(chan, fn, lang);
03622 if (!res) {
03623 res = ast_waitstream(chan, ints);
03624 }
03625 }
03626 if (!res) {
03627 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03628 res = ast_streamfile(chan, fn, lang);
03629 if (!res) {
03630 res = ast_waitstream(chan, ints);
03631 }
03632 }
03633 if (!res) {
03634 res = ast_say_number(chan, tm.tm_mday, ints, lang, "m");
03635 }
03636 if (!res) {
03637 res = ast_waitstream(chan, ints);
03638 }
03639 if (!res) {
03640 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "m");
03641 }
03642 return res;
03643 }
03644
03645 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)
03646 {
03647 if (!strncasecmp(lang, "en", 2)) {
03648 return ast_say_date_with_format_en(chan, t, ints, lang, format, tzone);
03649 } else if (!strncasecmp(lang, "da", 2)) {
03650 return ast_say_date_with_format_da(chan, t, ints, lang, format, tzone);
03651 } else if (!strncasecmp(lang, "de", 2)) {
03652 return ast_say_date_with_format_de(chan, t, ints, lang, format, tzone);
03653 } else if (!strncasecmp(lang, "es", 2)) {
03654 return ast_say_date_with_format_es(chan, t, ints, lang, format, tzone);
03655 } else if (!strncasecmp(lang, "he", 2)) {
03656 return ast_say_date_with_format_he(chan, t, ints, lang, format, tzone);
03657 } else if (!strncasecmp(lang, "fr", 2)) {
03658 return ast_say_date_with_format_fr(chan, t, ints, lang, format, tzone);
03659 } else if (!strncasecmp(lang, "gr", 2)) {
03660 return ast_say_date_with_format_gr(chan, t, ints, lang, format, tzone);
03661 } else if (!strncasecmp(lang, "it", 2)) {
03662 return ast_say_date_with_format_it(chan, t, ints, lang, format, tzone);
03663 } else if (!strncasecmp(lang, "mx", 2)) {
03664 static int deprecation_warning = 0;
03665 if (deprecation_warning++ % 10 == 0) {
03666 ast_log(LOG_WARNING, "mx is not a standard language code. Please switch to using es_MX instead.\n");
03667 }
03668 return ast_say_date_with_format_es(chan, t, ints, lang, format, tzone);
03669 } else if (!strncasecmp(lang, "nl", 2)) {
03670 return ast_say_date_with_format_nl(chan, t, ints, lang, format, tzone);
03671 } else if (!strncasecmp(lang, "pl", 2)) {
03672 return ast_say_date_with_format_pl(chan, t, ints, lang, format, tzone);
03673 } else if (!strncasecmp(lang, "pt", 2)) {
03674 return ast_say_date_with_format_pt(chan, t, ints, lang, format, tzone);
03675 } else if (!strncasecmp(lang, "th", 2)) {
03676 return ast_say_date_with_format_th(chan, t, ints, lang, format, tzone);
03677 } else if (!strncasecmp(lang, "tw", 2)) {
03678 static int deprecation_warning = 0;
03679 if (deprecation_warning++ % 10 == 0) {
03680 ast_log(LOG_WARNING, "tw is a standard language code for Twi, not Taiwanese. Please switch to using zh_TW instead.\n");
03681 }
03682 return ast_say_date_with_format_zh(chan, t, ints, lang, format, tzone);
03683 } else if (!strncasecmp(lang, "zh", 2)) {
03684 return ast_say_date_with_format_zh(chan, t, ints, lang, format, tzone);
03685 } else if (!strncasecmp(lang, "vi", 2)) {
03686 return ast_say_date_with_format_vi(chan, t, ints, lang, format, tzone);
03687 }
03688
03689
03690 return ast_say_date_with_format_en(chan, t, ints, lang, format, tzone);
03691 }
03692
03693
03694 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)
03695 {
03696 struct timeval when = { t, 0 };
03697 struct ast_tm tm;
03698 int res=0, offset, sndoffset;
03699 char sndfile[256], nextmsg[256];
03700
03701 if (format == NULL)
03702 format = "ABdY 'digits/at' IMp";
03703
03704 ast_localtime(&when, &tm, tzone);
03705
03706 for (offset=0 ; format[offset] != '\0' ; offset++) {
03707 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
03708 switch (format[offset]) {
03709
03710 case '\'':
03711
03712 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
03713 sndfile[sndoffset] = format[offset];
03714 }
03715 sndfile[sndoffset] = '\0';
03716 res = wait_file(chan, ints, sndfile, lang);
03717 break;
03718 case 'A':
03719 case 'a':
03720
03721 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
03722 res = wait_file(chan, ints, nextmsg, lang);
03723 break;
03724 case 'B':
03725 case 'b':
03726 case 'h':
03727
03728 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
03729 res = wait_file(chan, ints, nextmsg, lang);
03730 break;
03731 case 'm':
03732
03733 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
03734 break;
03735 case 'd':
03736 case 'e':
03737
03738 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char *) NULL);
03739 break;
03740 case 'Y':
03741
03742 if (tm.tm_year > 99) {
03743 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03744 } else if (tm.tm_year < 1) {
03745
03746
03747 } else {
03748 res = wait_file(chan, ints, "digits/19", lang);
03749 if (!res) {
03750 if (tm.tm_year <= 9) {
03751
03752 res = wait_file(chan, ints, "digits/oh", lang);
03753 }
03754
03755 res |= ast_say_number(chan, tm.tm_year, ints, lang, (char *) NULL);
03756 }
03757 }
03758 break;
03759 case 'I':
03760 case 'l':
03761
03762 if (tm.tm_hour == 0)
03763 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
03764 else if (tm.tm_hour > 12)
03765 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
03766 else
03767 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
03768 res = wait_file(chan, ints, nextmsg, lang);
03769 break;
03770 case 'H':
03771 case 'k':
03772
03773 if (format[offset] == 'H') {
03774
03775 if (tm.tm_hour < 10) {
03776 res = wait_file(chan, ints, "digits/oh", lang);
03777 }
03778 } else {
03779
03780 if (tm.tm_hour == 0) {
03781 res = wait_file(chan, ints, "digits/oh", lang);
03782 }
03783 }
03784 if (!res) {
03785 if (tm.tm_hour != 0) {
03786 int remaining = tm.tm_hour;
03787 if (tm.tm_hour > 20) {
03788 res = wait_file(chan, ints, "digits/20", lang);
03789 remaining -= 20;
03790 }
03791 if (!res) {
03792 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
03793 res = wait_file(chan, ints, nextmsg, lang);
03794 }
03795 }
03796 }
03797 break;
03798 case 'M':
03799 case 'N':
03800
03801 if (tm.tm_min == 0) {
03802 if (format[offset] == 'M') {
03803 res = wait_file(chan, ints, "digits/oclock", lang);
03804 } else {
03805 res = wait_file(chan, ints, "digits/hundred", lang);
03806 }
03807 } else if (tm.tm_min < 10) {
03808 res = wait_file(chan, ints, "digits/oh", lang);
03809 if (!res) {
03810 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min);
03811 res = wait_file(chan, ints, nextmsg, lang);
03812 }
03813 } else {
03814 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
03815 }
03816 break;
03817 case 'P':
03818 case 'p':
03819
03820 if (tm.tm_hour > 11)
03821 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
03822 else
03823 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
03824 res = wait_file(chan, ints, nextmsg, lang);
03825 break;
03826 case 'Q':
03827
03828
03829
03830
03831 {
03832 struct timeval now = ast_tvnow();
03833 struct ast_tm tmnow;
03834 time_t beg_today;
03835
03836 gettimeofday(&now, NULL);
03837 ast_localtime(&now, &tmnow, tzone);
03838
03839
03840 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03841 if (beg_today < t) {
03842
03843 res = wait_file(chan, ints, "digits/today", lang);
03844 } else if (beg_today - 86400 < t) {
03845
03846 res = wait_file(chan, ints, "digits/yesterday", lang);
03847 } else if (beg_today - 86400 * 6 < t) {
03848
03849 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
03850 } else if (beg_today - 2628000 < t) {
03851
03852 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
03853 } else if (beg_today - 15768000 < t) {
03854
03855 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
03856 } else {
03857
03858 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
03859 }
03860 }
03861 break;
03862 case 'q':
03863
03864
03865
03866
03867 {
03868 struct timeval now;
03869 struct ast_tm tmnow;
03870 time_t beg_today;
03871
03872 now = ast_tvnow();
03873 ast_localtime(&now, &tmnow, tzone);
03874
03875
03876 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03877 if (beg_today < t) {
03878
03879 } else if ((beg_today - 86400) < t) {
03880
03881 res = wait_file(chan, ints, "digits/yesterday", lang);
03882 } else if (beg_today - 86400 * 6 < t) {
03883
03884 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
03885 } else if (beg_today - 2628000 < t) {
03886
03887 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
03888 } else if (beg_today - 15768000 < t) {
03889
03890 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
03891 } else {
03892
03893 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
03894 }
03895 }
03896 break;
03897 case 'R':
03898 res = ast_say_date_with_format_en(chan, t, ints, lang, "HM", tzone);
03899 break;
03900 case 'S':
03901
03902 if (tm.tm_sec == 0) {
03903 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
03904 res = wait_file(chan, ints, nextmsg, lang);
03905 } else if (tm.tm_sec < 10) {
03906 res = wait_file(chan, ints, "digits/oh", lang);
03907 if (!res) {
03908 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
03909 res = wait_file(chan, ints, nextmsg, lang);
03910 }
03911 } else {
03912 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
03913 }
03914 break;
03915 case 'T':
03916 res = ast_say_date_with_format_en(chan, t, ints, lang, "HMS", tzone);
03917 break;
03918 case ' ':
03919 case ' ':
03920
03921 break;
03922 default:
03923
03924 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
03925 }
03926
03927 if (res) {
03928 break;
03929 }
03930 }
03931 return res;
03932 }
03933
03934 static char next_item(const char *format)
03935 {
03936 const char *next = ast_skip_blanks(format);
03937 return *next;
03938 }
03939
03940
03941 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)
03942 {
03943 struct timeval when = { t, 0 };
03944 struct ast_tm tm;
03945 int res=0, offset, sndoffset;
03946 char sndfile[256], nextmsg[256];
03947
03948 if (!format)
03949 format = "A dBY HMS";
03950
03951 ast_localtime(&when, &tm, tzone);
03952
03953 for (offset=0 ; format[offset] != '\0' ; offset++) {
03954 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
03955 switch (format[offset]) {
03956
03957 case '\'':
03958
03959 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
03960 sndfile[sndoffset] = format[offset];
03961 }
03962 sndfile[sndoffset] = '\0';
03963 res = wait_file(chan, ints, sndfile, lang);
03964 break;
03965 case 'A':
03966 case 'a':
03967
03968 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
03969 res = wait_file(chan, ints, nextmsg, lang);
03970 break;
03971 case 'B':
03972 case 'b':
03973 case 'h':
03974
03975 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
03976 res = wait_file(chan, ints, nextmsg, lang);
03977 break;
03978 case 'm':
03979
03980 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
03981 break;
03982 case 'd':
03983 case 'e':
03984
03985 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
03986 break;
03987 case 'Y':
03988
03989 {
03990 int year = tm.tm_year + 1900;
03991 if (year > 1999) {
03992 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
03993 } else {
03994 if (year < 1100) {
03995
03996
03997 } else {
03998
03999
04000 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
04001 res = wait_file(chan, ints, nextmsg, lang);
04002 if (!res) {
04003 res = wait_file(chan, ints, "digits/hundred", lang);
04004 if (!res && year % 100 != 0) {
04005 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
04006 }
04007 }
04008 }
04009 }
04010 }
04011 break;
04012 case 'I':
04013 case 'l':
04014
04015 res = wait_file(chan, ints, "digits/oclock", lang);
04016 if (tm.tm_hour == 0)
04017 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
04018 else if (tm.tm_hour > 12)
04019 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04020 else
04021 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04022 if (!res) {
04023 res = wait_file(chan, ints, nextmsg, lang);
04024 }
04025 break;
04026 case 'H':
04027
04028 if (tm.tm_hour < 10 && tm.tm_hour > 0) {
04029 res = wait_file(chan, ints, "digits/0", lang);
04030 }
04031
04032 case 'k':
04033
04034 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
04035 break;
04036 case 'M':
04037
04038 if (tm.tm_min > 0 || next_item(&format[offset + 1]) == 'S') {
04039 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
04040 }
04041 if (!res && next_item(&format[offset + 1]) == 'S') {
04042 if (tm.tm_min == 1) {
04043 res = wait_file(chan, ints, "digits/minute", lang);
04044 } else {
04045 res = wait_file(chan, ints, "digits/minutes", lang);
04046 }
04047 }
04048 break;
04049 case 'P':
04050 case 'p':
04051
04052 if (tm.tm_hour > 11)
04053 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
04054 else
04055 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
04056 res = wait_file(chan, ints, nextmsg, lang);
04057 break;
04058 case 'Q':
04059
04060
04061
04062
04063 {
04064 struct timeval now = ast_tvnow();
04065 struct ast_tm tmnow;
04066 time_t beg_today;
04067
04068 ast_localtime(&now, &tmnow, tzone);
04069
04070
04071 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04072 if (beg_today < t) {
04073
04074 res = wait_file(chan, ints, "digits/today", lang);
04075 } else if (beg_today - 86400 < t) {
04076
04077 res = wait_file(chan, ints, "digits/yesterday", lang);
04078 } else {
04079 res = ast_say_date_with_format_da(chan, t, ints, lang, "AdBY", tzone);
04080 }
04081 }
04082 break;
04083 case 'q':
04084
04085
04086
04087
04088 {
04089 struct timeval now = ast_tvnow();
04090 struct ast_tm tmnow;
04091 time_t beg_today;
04092
04093 ast_localtime(&now, &tmnow, tzone);
04094
04095
04096 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04097 if (beg_today < t) {
04098
04099 } else if ((beg_today - 86400) < t) {
04100
04101 res = wait_file(chan, ints, "digits/yesterday", lang);
04102 } else if (beg_today - 86400 * 6 < t) {
04103
04104 res = ast_say_date_with_format_da(chan, t, ints, lang, "A", tzone);
04105 } else {
04106 res = ast_say_date_with_format_da(chan, t, ints, lang, "AdBY", tzone);
04107 }
04108 }
04109 break;
04110 case 'R':
04111 res = ast_say_date_with_format_da(chan, t, ints, lang, "HM", tzone);
04112 break;
04113 case 'S':
04114
04115 res = wait_file(chan, ints, "digits/and", lang);
04116 if (!res) {
04117 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
04118 if (!res) {
04119 res = wait_file(chan, ints, "digits/seconds", lang);
04120 }
04121 }
04122 break;
04123 case 'T':
04124 res = ast_say_date_with_format_da(chan, t, ints, lang, "HMS", tzone);
04125 break;
04126 case ' ':
04127 case ' ':
04128
04129 break;
04130 default:
04131
04132 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04133 }
04134
04135 if (res) {
04136 break;
04137 }
04138 }
04139 return res;
04140 }
04141
04142
04143 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)
04144 {
04145 struct timeval when = { t, 0 };
04146 struct ast_tm tm;
04147 int res=0, offset, sndoffset;
04148 char sndfile[256], nextmsg[256];
04149
04150 if (!format)
04151 format = "A dBY HMS";
04152
04153 ast_localtime(&when, &tm, tzone);
04154
04155 for (offset=0 ; format[offset] != '\0' ; offset++) {
04156 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04157 switch (format[offset]) {
04158
04159 case '\'':
04160
04161 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
04162 sndfile[sndoffset] = format[offset];
04163 }
04164 sndfile[sndoffset] = '\0';
04165 res = wait_file(chan, ints, sndfile, lang);
04166 break;
04167 case 'A':
04168 case 'a':
04169
04170 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04171 res = wait_file(chan, ints, nextmsg, lang);
04172 break;
04173 case 'B':
04174 case 'b':
04175 case 'h':
04176
04177 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04178 res = wait_file(chan, ints, nextmsg, lang);
04179 break;
04180 case 'm':
04181
04182 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
04183 break;
04184 case 'd':
04185 case 'e':
04186
04187 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
04188 break;
04189 case 'Y':
04190
04191 {
04192 int year = tm.tm_year + 1900;
04193 if (year > 1999) {
04194 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
04195 } else {
04196 if (year < 1100) {
04197
04198
04199 } else {
04200
04201
04202 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
04203 res = wait_file(chan, ints, nextmsg, lang);
04204 if (!res) {
04205 res = wait_file(chan, ints, "digits/hundred", lang);
04206 if (!res && year % 100 != 0) {
04207 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
04208 }
04209 }
04210 }
04211 }
04212 }
04213 break;
04214 case 'I':
04215 case 'l':
04216
04217 if (tm.tm_hour == 0)
04218 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
04219 else if (tm.tm_hour > 12)
04220 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04221 else
04222 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04223 res = wait_file(chan, ints, nextmsg, lang);
04224 if (!res) {
04225 res = wait_file(chan, ints, "digits/oclock", lang);
04226 }
04227 break;
04228 case 'H':
04229 case 'k':
04230
04231 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
04232 if (!res) {
04233 res = wait_file(chan, ints, "digits/oclock", lang);
04234 }
04235 break;
04236 case 'M':
04237
04238 if (next_item(&format[offset + 1]) == 'S') {
04239 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
04240 } else if (tm.tm_min > 0) {
04241 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04242 }
04243
04244 if (!res && next_item(&format[offset + 1]) == 'S') {
04245 if (tm.tm_min == 1) {
04246 res = wait_file(chan, ints, "digits/minute", lang);
04247 } else {
04248 res = wait_file(chan, ints, "digits/minutes", lang);
04249 }
04250 }
04251 break;
04252 case 'P':
04253 case 'p':
04254
04255 if (tm.tm_hour > 11)
04256 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
04257 else
04258 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
04259 res = wait_file(chan, ints, nextmsg, lang);
04260 break;
04261 case 'Q':
04262
04263
04264
04265
04266 {
04267 struct timeval now = ast_tvnow();
04268 struct ast_tm tmnow;
04269 time_t beg_today;
04270
04271 ast_localtime(&now, &tmnow, tzone);
04272
04273
04274 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04275 if (beg_today < t) {
04276
04277 res = wait_file(chan, ints, "digits/today", lang);
04278 } else if (beg_today - 86400 < t) {
04279
04280 res = wait_file(chan, ints, "digits/yesterday", lang);
04281 } else {
04282 res = ast_say_date_with_format_de(chan, t, ints, lang, "AdBY", tzone);
04283 }
04284 }
04285 break;
04286 case 'q':
04287
04288
04289
04290
04291 {
04292 struct timeval now = ast_tvnow();
04293 struct ast_tm tmnow;
04294 time_t beg_today;
04295
04296 ast_localtime(&now, &tmnow, tzone);
04297
04298
04299 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04300 if (beg_today < t) {
04301
04302 } else if ((beg_today - 86400) < t) {
04303
04304 res = wait_file(chan, ints, "digits/yesterday", lang);
04305 } else if (beg_today - 86400 * 6 < t) {
04306
04307 res = ast_say_date_with_format_de(chan, t, ints, lang, "A", tzone);
04308 } else {
04309 res = ast_say_date_with_format_de(chan, t, ints, lang, "AdBY", tzone);
04310 }
04311 }
04312 break;
04313 case 'R':
04314 res = ast_say_date_with_format_de(chan, t, ints, lang, "HM", tzone);
04315 break;
04316 case 'S':
04317
04318 res = wait_file(chan, ints, "digits/and", lang);
04319 if (!res) {
04320 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
04321 if (!res) {
04322 res = wait_file(chan, ints, tm.tm_sec == 1 ? "digits/second" : "digits/seconds", lang);
04323 }
04324 }
04325 break;
04326 case 'T':
04327 res = ast_say_date_with_format_de(chan, t, ints, lang, "HMS", tzone);
04328 break;
04329 case ' ':
04330 case ' ':
04331
04332 break;
04333 default:
04334
04335 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04336 }
04337
04338 if (res) {
04339 break;
04340 }
04341 }
04342 return res;
04343 }
04344
04345
04346 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)
04347 {
04348 struct timeval when = { t, 0 };
04349 struct ast_tm tm;
04350 int res=0, offset, sndoffset;
04351 char sndfile[256], nextmsg[256];
04352
04353 if (format == NULL)
04354 format = "a 'digits/tee' e 'digits/duan' hY I 'digits/naliga' M 'digits/natee'";
04355
04356 ast_localtime(&when, &tm, tzone);
04357
04358 for (offset=0 ; format[offset] != '\0' ; offset++) {
04359 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04360 switch (format[offset]) {
04361
04362 case '\'':
04363
04364 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
04365 sndfile[sndoffset] = format[offset];
04366 }
04367 sndfile[sndoffset] = '\0';
04368 res = wait_file(chan, ints, sndfile, lang);
04369 break;
04370 case 'A':
04371 case 'a':
04372
04373 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04374 res = wait_file(chan, ints, nextmsg, lang);
04375 break;
04376 case 'B':
04377 case 'b':
04378 case 'h':
04379
04380 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04381 res = wait_file(chan, ints, nextmsg, lang);
04382 break;
04383 case 'm':
04384
04385 res = ast_say_number(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
04386 break;
04387 case 'd':
04388 case 'e':
04389
04390 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
04391 break;
04392 case 'Y':
04393
04394 res = ast_say_number(chan, tm.tm_year + 1900 + 543, ints, lang, (char *) NULL);
04395 break;
04396 case 'I':
04397 case 'l':
04398
04399 if (tm.tm_hour == 0)
04400 ast_copy_string(nextmsg, "digits/24", sizeof(nextmsg));
04401 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04402 res = wait_file(chan, ints, nextmsg, lang);
04403 break;
04404 case 'H':
04405 case 'k':
04406
04407 if (tm.tm_hour == 0)
04408 ast_copy_string(nextmsg, "digits/24", sizeof(nextmsg));
04409 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04410 res = wait_file(chan, ints, nextmsg, lang);
04411 break;
04412 case 'M':
04413 case 'N':
04414 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04415 break;
04416 case 'P':
04417 case 'p':
04418 break;
04419 case 'Q':
04420
04421
04422
04423
04424 {
04425 struct timeval now = ast_tvnow();
04426 struct ast_tm tmnow;
04427 time_t beg_today;
04428
04429 ast_localtime(&now, &tmnow, tzone);
04430
04431
04432 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04433 if (beg_today < t) {
04434
04435 res = wait_file(chan, ints, "digits/today", lang);
04436 } else if (beg_today - 86400 < t) {
04437
04438 res = wait_file(chan, ints, "digits/yesterday", lang);
04439 } else if (beg_today - 86400 * 6 < t) {
04440
04441 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
04442 } else if (beg_today - 2628000 < t) {
04443
04444 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
04445 } else if (beg_today - 15768000 < t) {
04446
04447 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
04448 } else {
04449
04450 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
04451 }
04452 }
04453 break;
04454 case 'q':
04455
04456
04457
04458
04459 {
04460 struct timeval now = ast_tvnow();
04461 struct ast_tm tmnow;
04462 time_t beg_today;
04463
04464 ast_localtime(&now, &tmnow, tzone);
04465
04466
04467 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04468 if (beg_today < t) {
04469
04470 } else if ((beg_today - 86400) < t) {
04471
04472 res = wait_file(chan, ints, "digits/yesterday", lang);
04473 } else if (beg_today - 86400 * 6 < t) {
04474
04475 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
04476 } else if (beg_today - 2628000 < t) {
04477
04478 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
04479 } else if (beg_today - 15768000 < t) {
04480
04481 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
04482 } else {
04483
04484 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
04485 }
04486 }
04487 break;
04488 case 'R':
04489 res = ast_say_date_with_format_en(chan, t, ints, lang, "HM", tzone);
04490 break;
04491 case 'S':
04492 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
04493 break;
04494 case 'T':
04495 res = ast_say_date_with_format_en(chan, t, ints, lang, "HMS", tzone);
04496 break;
04497 case ' ':
04498 case ' ':
04499
04500 break;
04501 default:
04502
04503 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04504 }
04505
04506 if (res) {
04507 break;
04508 }
04509 }
04510 return res;
04511 }
04512
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528
04529
04530
04531 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)
04532 {
04533 #define IL_DATE_STR "AdBY"
04534 #define IL_TIME_STR "HM"
04535 #define IL_DATE_STR_FULL IL_DATE_STR " 'digits/at' " IL_TIME_STR
04536
04537
04538
04539 struct timeval when = { t, 0 };
04540 struct ast_tm tm;
04541 int res = 0, offset, sndoffset;
04542 char sndfile[256], nextmsg[256];
04543
04544 if (!format) {
04545 format = IL_DATE_STR_FULL;
04546 }
04547
04548 ast_localtime(&when, &tm, tzone);
04549
04550 for (offset = 0; format[offset] != '\0'; offset++) {
04551 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04552 switch (format[offset]) {
04553
04554 case '\'':
04555
04556 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
04557 sndfile[sndoffset] = format[offset];
04558 }
04559 sndfile[sndoffset] = '\0';
04560 res = wait_file(chan, ints, sndfile, lang);
04561 break;
04562 case 'A':
04563 case 'a':
04564
04565 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04566 res = wait_file(chan, ints, nextmsg, lang);
04567 break;
04568 case 'B':
04569 case 'b':
04570 case 'h':
04571
04572 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04573 res = wait_file(chan, ints, nextmsg, lang);
04574 break;
04575 case 'd':
04576 case 'e':
04577
04578
04579
04580
04581
04582
04583
04584 res = ast_say_number_full_he(chan, tm.tm_mday, ints, lang, "m", -1, -1);
04585 break;
04586 case 'Y':
04587 res = ast_say_number_full_he(chan, tm.tm_year + 1900, ints, lang, "f", -1, -1);
04588 break;
04589 case 'I':
04590 case 'l':
04591 case 'H':
04592 case 'k':
04593 res = ast_say_number_full_he(chan, tm.tm_hour, ints, lang, "f", -1, -1);
04594 break;
04595 case 'M':
04596 if (tm.tm_min >= 0 && tm.tm_min <= 9)
04597 res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
04598 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
04599 break;
04600 case 'P':
04601 case 'p':
04602
04603 break;
04604 case 'Q':
04605
04606 case 'q':
04607
04608
04609
04610
04611
04612 {
04613 struct timeval now = ast_tvnow();
04614 struct ast_tm tmnow;
04615 time_t beg_today;
04616 char todo = format[offset];
04617
04618 ast_localtime(&now, &tmnow, tzone);
04619
04620
04621 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04622 if (beg_today < t) {
04623
04624 if (todo == 'Q') {
04625 res = wait_file(chan, ints, "digits/today", lang);
04626 }
04627 } else if (beg_today - 86400 < t) {
04628
04629 res = wait_file(chan, ints, "digits/yesterday", lang);
04630 } else if ((todo != 'Q') && (beg_today - 86400 * 6 < t)) {
04631
04632 res = ast_say_date_with_format_he(chan, t, ints, lang, "A", tzone);
04633 } else {
04634 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
04635 }
04636 }
04637 break;
04638 case 'R':
04639 res = ast_say_date_with_format_he(chan, t, ints, lang, "HM", tzone);
04640 break;
04641 case 'S':
04642 res = ast_say_number_full_he(chan, tm.tm_sec,
04643 ints, lang, "f", -1, -1
04644 );
04645 break;
04646 case 'T':
04647 res = ast_say_date_with_format_he(chan, t, ints, lang, "HMS", tzone);
04648 break;
04649
04650
04651 case 'c':
04652 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR_FULL, tzone);
04653 break;
04654 case 'x':
04655 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
04656 break;
04657 case 'X':
04658 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_TIME_STR, tzone);
04659 break;
04660 case ' ':
04661 case ' ':
04662
04663 break;
04664 default:
04665
04666 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04667 }
04668
04669 if (res) {
04670 break;
04671 }
04672 }
04673 return res;
04674 }
04675
04676
04677
04678 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)
04679 {
04680 struct timeval when = { t, 0 };
04681 struct ast_tm tm;
04682 int res=0, offset, sndoffset;
04683 char sndfile[256], nextmsg[256];
04684
04685 if (format == NULL)
04686 format = "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y 'digits/at' IMp";
04687
04688 ast_localtime(&when, &tm, tzone);
04689
04690 for (offset=0 ; format[offset] != '\0' ; offset++) {
04691 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04692 switch (format[offset]) {
04693
04694 case '\'':
04695
04696 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
04697 sndfile[sndoffset] = format[offset];
04698 }
04699 sndfile[sndoffset] = '\0';
04700 snprintf(nextmsg, sizeof(nextmsg), "%s", sndfile);
04701 res = wait_file(chan, ints, nextmsg, lang);
04702 break;
04703 case 'A':
04704 case 'a':
04705
04706 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04707 res = wait_file(chan, ints, nextmsg, lang);
04708 break;
04709 case 'B':
04710 case 'b':
04711 case 'h':
04712
04713 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04714 res = wait_file(chan, ints, nextmsg, lang);
04715 break;
04716 case 'm':
04717
04718 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04719 res = wait_file(chan, ints, nextmsg, lang);
04720 break;
04721 case 'd':
04722 case 'e':
04723
04724 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
04725 break;
04726 case 'Y':
04727
04728 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
04729 break;
04730 case 'I':
04731 case 'l':
04732
04733 if (tm.tm_hour == 0)
04734 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
04735 else if (tm.tm_hour == 1 || tm.tm_hour == 13)
04736 snprintf(nextmsg,sizeof(nextmsg), "digits/1F");
04737 else if (tm.tm_hour > 12)
04738 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04739 else
04740 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04741 res = wait_file(chan, ints, nextmsg, lang);
04742 break;
04743 case 'H':
04744 case 'k':
04745
04746 res = ast_say_number(chan, tm.tm_hour, ints, lang, NULL);
04747 break;
04748 case 'M':
04749
04750 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04751 break;
04752 case 'P':
04753 case 'p':
04754
04755 if (tm.tm_hour > 18)
04756 res = wait_file(chan, ints, "digits/p-m", lang);
04757 else if (tm.tm_hour > 12)
04758 res = wait_file(chan, ints, "digits/afternoon", lang);
04759 else if (tm.tm_hour)
04760 res = wait_file(chan, ints, "digits/a-m", lang);
04761 break;
04762 case 'Q':
04763
04764
04765
04766
04767 {
04768 struct timeval now = ast_tvnow();
04769 struct ast_tm tmnow;
04770 time_t beg_today;
04771
04772 ast_localtime(&now, &tmnow, tzone);
04773
04774
04775 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04776 if (beg_today < t) {
04777
04778 res = wait_file(chan, ints, "digits/today", lang);
04779 } else if (beg_today - 86400 < t) {
04780
04781 res = wait_file(chan, ints, "digits/yesterday", lang);
04782 } else {
04783 res = ast_say_date_with_format_es(chan, t, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", tzone);
04784 }
04785 }
04786 break;
04787 case 'q':
04788
04789
04790
04791
04792 {
04793 struct timeval now = ast_tvnow();
04794 struct ast_tm tmnow;
04795 time_t beg_today;
04796
04797 ast_localtime(&now, &tmnow, tzone);
04798
04799
04800 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04801 if (beg_today < t) {
04802
04803 res = wait_file(chan, ints, "digits/today", lang);
04804 } else if ((beg_today - 86400) < t) {
04805
04806 res = wait_file(chan, ints, "digits/yesterday", lang);
04807 } else if (beg_today - 86400 * 6 < t) {
04808
04809 res = ast_say_date_with_format_es(chan, t, ints, lang, "A", tzone);
04810 } else {
04811 res = ast_say_date_with_format_es(chan, t, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", tzone);
04812 }
04813 }
04814 break;
04815 case 'R':
04816 res = ast_say_date_with_format_es(chan, t, ints, lang, "H 'digits/y' M", tzone);
04817 break;
04818 case 'S':
04819
04820 if (tm.tm_sec == 0) {
04821 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
04822 res = wait_file(chan, ints, nextmsg, lang);
04823 } else if (tm.tm_sec < 10) {
04824 res = wait_file(chan, ints, "digits/oh", lang);
04825 if (!res) {
04826 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
04827 res = wait_file(chan, ints, nextmsg, lang);
04828 }
04829 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
04830 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
04831 res = wait_file(chan, ints, nextmsg, lang);
04832 } else {
04833 int ten, one;
04834 ten = (tm.tm_sec / 10) * 10;
04835 one = (tm.tm_sec % 10);
04836 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
04837 res = wait_file(chan, ints, nextmsg, lang);
04838 if (!res) {
04839
04840 if (one != 0) {
04841 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
04842 res = wait_file(chan, ints, nextmsg, lang);
04843 }
04844 }
04845 }
04846 break;
04847 case 'T':
04848 res = ast_say_date_with_format_es(chan, t, ints, lang, "HMS", tzone);
04849 break;
04850 case ' ':
04851 case ' ':
04852
04853 break;
04854 default:
04855
04856 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04857 }
04858
04859 if (res) {
04860 break;
04861 }
04862 }
04863 return res;
04864 }
04865
04866
04867
04868
04869 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)
04870 {
04871 struct timeval when = { t, 0 };
04872 struct ast_tm tm;
04873 int res=0, offset, sndoffset;
04874 char sndfile[256], nextmsg[256];
04875
04876 if (format == NULL)
04877 format = "AdBY 'digits/at' IMp";
04878
04879 ast_localtime(&when, &tm, tzone);
04880
04881 for (offset=0 ; format[offset] != '\0' ; offset++) {
04882 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04883 switch (format[offset]) {
04884
04885 case '\'':
04886
04887 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
04888 sndfile[sndoffset] = format[offset];
04889 }
04890 sndfile[sndoffset] = '\0';
04891 res = wait_file(chan, ints, sndfile, lang);
04892 break;
04893 case 'A':
04894 case 'a':
04895
04896 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04897 res = wait_file(chan, ints, nextmsg, lang);
04898 break;
04899 case 'B':
04900 case 'b':
04901 case 'h':
04902
04903 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04904 res = wait_file(chan, ints, nextmsg, lang);
04905 break;
04906 case 'm':
04907
04908 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04909 res = wait_file(chan, ints, nextmsg, lang);
04910 break;
04911 case 'd':
04912 case 'e':
04913
04914 if (tm.tm_mday == 1) {
04915 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
04916 res = wait_file(chan, ints, nextmsg, lang);
04917 } else {
04918 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
04919 }
04920 break;
04921 case 'Y':
04922
04923 if (tm.tm_year > 99) {
04924 res = wait_file(chan, ints, "digits/2", lang);
04925 if (!res) {
04926 res = wait_file(chan, ints, "digits/thousand", lang);
04927 }
04928 if (tm.tm_year > 100) {
04929 if (!res) {
04930 res = ast_say_number(chan, tm.tm_year - 100, ints, lang, (char * ) NULL);
04931 }
04932 }
04933 } else {
04934 if (tm.tm_year < 1) {
04935
04936
04937 } else {
04938 res = wait_file(chan, ints, "digits/thousand", lang);
04939 if (!res) {
04940 wait_file(chan, ints, "digits/9", lang);
04941 wait_file(chan, ints, "digits/hundred", lang);
04942 res = ast_say_number(chan, tm.tm_year, ints, lang, (char * ) NULL);
04943 }
04944 }
04945 }
04946 break;
04947 case 'I':
04948 case 'l':
04949
04950 if (tm.tm_hour == 0)
04951 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
04952 else if (tm.tm_hour > 12)
04953 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04954 else
04955 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04956 res = wait_file(chan, ints, nextmsg, lang);
04957 if (!res)
04958 res = wait_file(chan, ints, "digits/oclock", lang);
04959 break;
04960 case 'H':
04961 case 'k':
04962
04963 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char * ) NULL);
04964 if (!res)
04965 res = wait_file(chan, ints, "digits/oclock", lang);
04966 break;
04967 case 'M':
04968
04969 if (tm.tm_min == 0) {
04970 break;
04971 }
04972 res = ast_say_number(chan, tm.tm_min, ints, lang, (char * ) NULL);
04973 break;
04974 case 'P':
04975 case 'p':
04976
04977 if (tm.tm_hour > 11)
04978 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
04979 else
04980 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
04981 res = wait_file(chan, ints, nextmsg, lang);
04982 break;
04983 case 'Q':
04984
04985
04986
04987
04988 {
04989 struct timeval now = ast_tvnow();
04990 struct ast_tm tmnow;
04991 time_t beg_today;
04992
04993 ast_localtime(&now, &tmnow, tzone);
04994
04995
04996 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04997 if (beg_today < t) {
04998
04999 res = wait_file(chan, ints, "digits/today", lang);
05000 } else if (beg_today - 86400 < t) {
05001
05002 res = wait_file(chan, ints, "digits/yesterday", lang);
05003 } else {
05004 res = ast_say_date_with_format_fr(chan, t, ints, lang, "AdBY", tzone);
05005 }
05006 }
05007 break;
05008 case 'q':
05009
05010
05011
05012
05013 {
05014 struct timeval now = ast_tvnow();
05015 struct ast_tm tmnow;
05016 time_t beg_today;
05017
05018 ast_localtime(&now, &tmnow, tzone);
05019
05020
05021 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05022 if (beg_today < t) {
05023
05024 } else if ((beg_today - 86400) < t) {
05025
05026 res = wait_file(chan, ints, "digits/yesterday", lang);
05027 } else if (beg_today - 86400 * 6 < t) {
05028
05029 res = ast_say_date_with_format_fr(chan, t, ints, lang, "A", tzone);
05030 } else {
05031 res = ast_say_date_with_format_fr(chan, t, ints, lang, "AdBY", tzone);
05032 }
05033 }
05034 break;
05035 case 'R':
05036 res = ast_say_date_with_format_fr(chan, t, ints, lang, "HM", tzone);
05037 break;
05038 case 'S':
05039
05040 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char * ) NULL);
05041 if (!res) {
05042 res = wait_file(chan, ints, "digits/second", lang);
05043 }
05044 break;
05045 case 'T':
05046 res = ast_say_date_with_format_fr(chan, t, ints, lang, "HMS", tzone);
05047 break;
05048 case ' ':
05049 case ' ':
05050
05051 break;
05052 default:
05053
05054 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05055 }
05056
05057 if (res) {
05058 break;
05059 }
05060 }
05061 return res;
05062 }
05063
05064
05065 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)
05066 {
05067 struct timeval when = { t, 0 };
05068 struct ast_tm tm;
05069 int res=0, offset, sndoffset;
05070 char sndfile[256], nextmsg[256];
05071
05072 if (format == NULL)
05073 format = "AdB 'digits/at' IMp";
05074
05075 ast_localtime(&when, &tm, tzone);
05076
05077 for (offset=0 ; format[offset] != '\0' ; offset++) {
05078 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05079 switch (format[offset]) {
05080
05081 case '\'':
05082
05083 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
05084 sndfile[sndoffset] = format[offset];
05085 }
05086 sndfile[sndoffset] = '\0';
05087 res = wait_file(chan, ints, sndfile, lang);
05088 break;
05089 case 'A':
05090 case 'a':
05091
05092 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05093 res = wait_file(chan, ints, nextmsg, lang);
05094 break;
05095 case 'B':
05096 case 'b':
05097 case 'h':
05098
05099 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05100 res = wait_file(chan, ints, nextmsg, lang);
05101 break;
05102 case 'm':
05103
05104 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
05105 res = wait_file(chan, ints, nextmsg, lang);
05106 break;
05107 case 'd':
05108 case 'e':
05109
05110 if (tm.tm_mday == 1) {
05111 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
05112 res = wait_file(chan, ints, nextmsg, lang);
05113 } else {
05114 if (!res) {
05115 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
05116 }
05117 }
05118 break;
05119 case 'Y':
05120
05121 if (tm.tm_year > 99) {
05122 res = wait_file(chan, ints, "digits/ore-2000", lang);
05123 if (tm.tm_year > 100) {
05124 if (!res) {
05125
05126 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
05127 res = wait_file(chan, ints, nextmsg, lang);
05128 }
05129 }
05130 } else {
05131 if (tm.tm_year < 1) {
05132
05133
05134 } else {
05135 res = wait_file(chan, ints, "digits/ore-1900", lang);
05136 if ((!res) && (tm.tm_year != 0)) {
05137 if (tm.tm_year <= 21) {
05138
05139 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
05140 res = wait_file(chan, ints, nextmsg, lang);
05141 } else {
05142
05143 int ten, one;
05144 ten = tm.tm_year / 10;
05145 one = tm.tm_year % 10;
05146 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten * 10);
05147 res = wait_file(chan, ints, nextmsg, lang);
05148 if (!res) {
05149 if (one != 0) {
05150 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
05151 res = wait_file(chan, ints, nextmsg, lang);
05152 }
05153 }
05154 }
05155 }
05156 }
05157 }
05158 break;
05159 case 'I':
05160 case 'l':
05161
05162 if (tm.tm_hour == 0)
05163 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
05164 else if (tm.tm_hour > 12)
05165 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
05166 else
05167 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
05168 res = wait_file(chan, ints, nextmsg, lang);
05169 break;
05170 case 'H':
05171 case 'k':
05172
05173 if (tm.tm_hour == 0) {
05174 res = wait_file(chan, ints, "digits/ore-mezzanotte", lang);
05175 } else if (tm.tm_hour == 1) {
05176 res = wait_file(chan, ints, "digits/ore-una", lang);
05177 } else {
05178 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
05179 }
05180 break;
05181 case 'M':
05182
05183 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05184 break;
05185 case 'P':
05186 case 'p':
05187
05188 if (tm.tm_hour > 11)
05189 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
05190 else
05191 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
05192 res = wait_file(chan, ints, nextmsg, lang);
05193 break;
05194 case 'Q':
05195
05196
05197
05198
05199 {
05200 struct timeval now = ast_tvnow();
05201 struct ast_tm tmnow;
05202 time_t beg_today;
05203
05204 ast_localtime(&now, &tmnow, tzone);
05205
05206
05207 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05208 if (beg_today < t) {
05209
05210 res = wait_file(chan, ints, "digits/today", lang);
05211 } else if (beg_today - 86400 < t) {
05212
05213 res = wait_file(chan, ints, "digits/yesterday", lang);
05214 } else {
05215 res = ast_say_date_with_format_it(chan, t, ints, lang, "AdB", tzone);
05216 }
05217 }
05218 break;
05219 case 'q':
05220
05221 {
05222 struct timeval now = ast_tvnow();
05223 struct ast_tm tmnow;
05224 time_t beg_today;
05225
05226 ast_localtime(&now, &tmnow, tzone);
05227
05228
05229 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05230 if (beg_today < t) {
05231
05232 } else if ((beg_today - 86400) < t) {
05233
05234 res = wait_file(chan, ints, "digits/yesterday", lang);
05235 } else if (beg_today - 86400 * 6 < t) {
05236
05237 res = ast_say_date_with_format_it(chan, t, ints, lang, "A", tzone);
05238 } else {
05239 res = ast_say_date_with_format_it(chan, t, ints, lang, "AdB", tzone);
05240 }
05241 }
05242 break;
05243 case 'R':
05244 res = ast_say_date_with_format_it(chan, t, ints, lang, "HM", tzone);
05245 break;
05246 case 'S':
05247
05248 if (tm.tm_sec == 0) {
05249 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05250 res = wait_file(chan, ints, nextmsg, lang);
05251 } else if (tm.tm_sec < 10) {
05252 res = wait_file(chan, ints, "digits/oh", lang);
05253 if (!res) {
05254 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05255 res = wait_file(chan, ints, nextmsg, lang);
05256 }
05257 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
05258 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05259 res = wait_file(chan, ints, nextmsg, lang);
05260 } else {
05261 int ten, one;
05262 ten = (tm.tm_sec / 10) * 10;
05263 one = (tm.tm_sec % 10);
05264 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
05265 res = wait_file(chan, ints, nextmsg, lang);
05266 if (!res) {
05267
05268 if (one != 0) {
05269 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
05270 res = wait_file(chan, ints, nextmsg, lang);
05271 }
05272 }
05273 }
05274 break;
05275 case 'T':
05276 res = ast_say_date_with_format_it(chan, t, ints, lang, "HMS", tzone);
05277 break;
05278 case ' ':
05279 case ' ':
05280
05281 break;
05282 default:
05283
05284 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05285 }
05286
05287 if (res) {
05288 break;
05289 }
05290 }
05291 return res;
05292 }
05293
05294
05295 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)
05296 {
05297 struct timeval when = { t, 0 };
05298 struct ast_tm tm;
05299 int res=0, offset, sndoffset;
05300 char sndfile[256], nextmsg[256];
05301
05302 if (format == NULL)
05303 format = "AdBY 'digits/at' IMp";
05304
05305 ast_localtime(&when, &tm, tzone);
05306
05307 for (offset=0 ; format[offset] != '\0' ; offset++) {
05308 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05309 switch (format[offset]) {
05310
05311 case '\'':
05312
05313 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
05314 sndfile[sndoffset] = format[offset];
05315 }
05316 sndfile[sndoffset] = '\0';
05317 res = wait_file(chan, ints, sndfile, lang);
05318 break;
05319 case 'A':
05320 case 'a':
05321
05322 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05323 res = wait_file(chan, ints, nextmsg, lang);
05324 break;
05325 case 'B':
05326 case 'b':
05327 case 'h':
05328
05329 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05330 res = wait_file(chan, ints, nextmsg, lang);
05331 break;
05332 case 'm':
05333
05334 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
05335 res = wait_file(chan, ints, nextmsg, lang);
05336 break;
05337 case 'd':
05338 case 'e':
05339
05340 res = ast_say_number(chan, tm.tm_mday, ints, lang, NULL);
05341 break;
05342 case 'Y':
05343
05344 if (tm.tm_year > 99) {
05345 res = wait_file(chan, ints, "digits/2", lang);
05346 if (!res) {
05347 res = wait_file(chan, ints, "digits/thousand", lang);
05348 }
05349 if (tm.tm_year > 100) {
05350 if (!res) {
05351
05352 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
05353 res = wait_file(chan, ints, nextmsg, lang);
05354 }
05355 }
05356 } else {
05357 if (tm.tm_year < 1) {
05358
05359
05360 } else {
05361 res = wait_file(chan, ints, "digits/19", lang);
05362 if (!res) {
05363 if (tm.tm_year <= 9) {
05364
05365 res = wait_file(chan, ints, "digits/oh", lang);
05366 if (!res) {
05367 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
05368 res = wait_file(chan, ints, nextmsg, lang);
05369 }
05370 } else if (tm.tm_year <= 20) {
05371
05372 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
05373 res = wait_file(chan, ints, nextmsg, lang);
05374 } else {
05375
05376 int ten, one;
05377 ten = tm.tm_year / 10;
05378 one = tm.tm_year % 10;
05379 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten * 10);
05380 res = wait_file(chan, ints, nextmsg, lang);
05381 if (!res) {
05382 if (one != 0) {
05383 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
05384 res = wait_file(chan, ints, nextmsg, lang);
05385 }
05386 }
05387 }
05388 }
05389 }
05390 }
05391 break;
05392 case 'I':
05393 case 'l':
05394
05395 if (tm.tm_hour == 0)
05396 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
05397 else if (tm.tm_hour > 12)
05398 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
05399 else
05400 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
05401 res = wait_file(chan, ints, nextmsg, lang);
05402 break;
05403 case 'H':
05404 case 'k':
05405
05406 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
05407 if (!res) {
05408 res = wait_file(chan, ints, "digits/nl-uur", lang);
05409 }
05410 break;
05411 case 'M':
05412
05413 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05414 break;
05415 case 'P':
05416 case 'p':
05417
05418 if (tm.tm_hour > 11)
05419 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
05420 else
05421 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
05422 res = wait_file(chan, ints, nextmsg, lang);
05423 break;
05424 case 'Q':
05425
05426
05427
05428
05429 {
05430 struct timeval now = ast_tvnow();
05431 struct ast_tm tmnow;
05432 time_t beg_today;
05433
05434 ast_localtime(&now, &tmnow, tzone);
05435
05436
05437 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05438 if (beg_today < t) {
05439
05440 res = wait_file(chan, ints, "digits/today", lang);
05441 } else if (beg_today - 86400 < t) {
05442
05443 res = wait_file(chan, ints, "digits/yesterday", lang);
05444 } else {
05445 res = ast_say_date_with_format_nl(chan, t, ints, lang, "AdBY", tzone);
05446 }
05447 }
05448 break;
05449 case 'q':
05450
05451 {
05452 struct timeval now = ast_tvnow();
05453 struct ast_tm tmnow;
05454 time_t beg_today;
05455
05456 ast_localtime(&now, &tmnow, tzone);
05457
05458
05459 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05460 if (beg_today < t) {
05461
05462 } else if ((beg_today - 86400) < t) {
05463
05464 res = wait_file(chan, ints, "digits/yesterday", lang);
05465 } else if (beg_today - 86400 * 6 < t) {
05466
05467 res = ast_say_date_with_format_nl(chan, t, ints, lang, "A", tzone);
05468 } else {
05469 res = ast_say_date_with_format_nl(chan, t, ints, lang, "AdBY", tzone);
05470 }
05471 }
05472 break;
05473 case 'R':
05474 res = ast_say_date_with_format_nl(chan, t, ints, lang, "HM", tzone);
05475 break;
05476 case 'S':
05477
05478 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
05479 break;
05480 case 'T':
05481 res = ast_say_date_with_format_nl(chan, t, ints, lang, "HMS", tzone);
05482 break;
05483 case ' ':
05484 case ' ':
05485
05486 break;
05487 default:
05488
05489 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05490 }
05491
05492 if (res) {
05493 break;
05494 }
05495 }
05496 return res;
05497 }
05498
05499
05500 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)
05501 {
05502 struct timeval when = { thetime, 0 };
05503 struct ast_tm tm;
05504 int res=0, offset, sndoffset;
05505 char sndfile[256], nextmsg[256];
05506
05507 ast_localtime(&when, &tm, tzone);
05508
05509 for (offset = 0 ; format[offset] != '\0' ; offset++) {
05510 int remaining;
05511 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05512 switch (format[offset]) {
05513
05514 case '\'':
05515
05516 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
05517 sndfile[sndoffset] = format[offset];
05518 }
05519 sndfile[sndoffset] = '\0';
05520 res = wait_file(chan, ints, sndfile, lang);
05521 break;
05522 case 'A':
05523 case 'a':
05524
05525 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05526 res = wait_file(chan, ints, nextmsg, lang);
05527 break;
05528 case 'B':
05529 case 'b':
05530 case 'h':
05531
05532 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05533 res = wait_file(chan, ints, nextmsg, lang);
05534 break;
05535 case 'm':
05536
05537 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, NULL);
05538 break;
05539 case 'd':
05540 case 'e':
05541
05542 remaining = tm.tm_mday;
05543 if (tm.tm_mday > 30) {
05544 res = wait_file(chan, ints, "digits/h-30", lang);
05545 remaining -= 30;
05546 }
05547 if (tm.tm_mday > 20 && tm.tm_mday < 30) {
05548 res = wait_file(chan, ints, "digits/h-20", lang);
05549 remaining -= 20;
05550 }
05551 if (!res) {
05552 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", remaining);
05553 res = wait_file(chan, ints, nextmsg, lang);
05554 }
05555 break;
05556 case 'Y':
05557
05558 if (tm.tm_year > 100) {
05559 res = wait_file(chan, ints, "digits/2", lang);
05560 if (!res)
05561 res = wait_file(chan, ints, "digits/1000.2", lang);
05562 if (tm.tm_year > 100) {
05563 if (!res)
05564 res = ast_say_enumeration(chan, tm.tm_year - 100, ints, lang, NULL);
05565 }
05566 } else if (tm.tm_year == 100) {
05567 res = wait_file(chan, ints, "digits/h-2000", lang);
05568 } else {
05569 if (tm.tm_year < 1) {
05570
05571
05572 break;
05573 } else {
05574 res = wait_file(chan, ints, "digits/1000", lang);
05575 if (!res) {
05576 wait_file(chan, ints, "digits/900", lang);
05577 res = ast_say_enumeration(chan, tm.tm_year, ints, lang, NULL);
05578 }
05579 }
05580 }
05581 if (!res)
05582 wait_file(chan, ints, "digits/year", lang);
05583 break;
05584 case 'I':
05585 case 'l':
05586
05587 if (tm.tm_hour == 0)
05588 ast_copy_string(nextmsg, "digits/t-12", sizeof(nextmsg));
05589 else if (tm.tm_hour > 12)
05590 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour - 12);
05591 else
05592 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
05593
05594 res = wait_file(chan, ints, nextmsg, lang);
05595 break;
05596 case 'H':
05597 case 'k':
05598
05599 if (tm.tm_hour != 0) {
05600 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
05601 res = wait_file(chan, ints, nextmsg, lang);
05602 } else
05603 res = wait_file(chan, ints, "digits/t-24", lang);
05604 break;
05605 case 'M':
05606 case 'N':
05607
05608 if (tm.tm_min == 0) {
05609 if (format[offset] == 'M') {
05610 res = wait_file(chan, ints, "digits/oclock", lang);
05611 } else {
05612 res = wait_file(chan, ints, "digits/100", lang);
05613 }
05614 } else
05615 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
05616 break;
05617 case 'P':
05618 case 'p':
05619
05620 if (tm.tm_hour > 11)
05621 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
05622 else
05623 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
05624 res = wait_file(chan, ints, nextmsg, lang);
05625 break;
05626 case 'Q':
05627
05628 {
05629 struct timeval now = ast_tvnow();
05630 struct ast_tm tmnow;
05631 time_t beg_today;
05632
05633 ast_localtime(&now, &tmnow, tzone);
05634
05635
05636 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05637 if (beg_today < thetime) {
05638
05639 res = wait_file(chan, ints, "digits/today", lang);
05640 } else if (beg_today - 86400 < thetime) {
05641
05642 res = wait_file(chan, ints, "digits/yesterday", lang);
05643 } else {
05644 res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", tzone);
05645 }
05646 }
05647 break;
05648 case 'q':
05649
05650 {
05651 struct timeval now = ast_tvnow();
05652 struct ast_tm tmnow;
05653 time_t beg_today;
05654
05655 ast_localtime(&now, &tmnow, tzone);
05656
05657
05658 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05659 if (beg_today < thetime) {
05660
05661 } else if ((beg_today - 86400) < thetime) {
05662
05663 res = wait_file(chan, ints, "digits/yesterday", lang);
05664 } else if (beg_today - 86400 * 6 < thetime) {
05665
05666 res = ast_say_date_with_format(chan, thetime, ints, lang, "A", tzone);
05667 } else {
05668 res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", tzone);
05669 }
05670 }
05671 break;
05672 case 'R':
05673 res = ast_say_date_with_format(chan, thetime, ints, lang, "HM", tzone);
05674 break;
05675 case 'S':
05676
05677 res = wait_file(chan, ints, "digits/and", lang);
05678 if (!res) {
05679 if (tm.tm_sec == 1) {
05680 res = wait_file(chan, ints, "digits/1z", lang);
05681 if (!res)
05682 res = wait_file(chan, ints, "digits/second-a", lang);
05683 } else {
05684 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
05685 if (!res) {
05686 int ten, one;
05687 ten = tm.tm_sec / 10;
05688 one = tm.tm_sec % 10;
05689
05690 if (one > 1 && one < 5 && ten != 1)
05691 res = wait_file(chan, ints, "digits/seconds", lang);
05692 else
05693 res = wait_file(chan, ints, "digits/second", lang);
05694 }
05695 }
05696 }
05697 break;
05698 case 'T':
05699 res = ast_say_date_with_format(chan, thetime, ints, lang, "HMS", tzone);
05700 break;
05701 case ' ':
05702 case ' ':
05703
05704 break;
05705 default:
05706
05707 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05708 }
05709
05710 if (res)
05711 break;
05712 }
05713 return res;
05714 }
05715
05716
05717 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)
05718 {
05719 struct timeval when = { t, 0 };
05720 struct ast_tm tm;
05721 int res=0, offset, sndoffset;
05722 char sndfile[256], nextmsg[256];
05723
05724 if (format == NULL)
05725 format = "Ad 'digits/pt-de' B 'digits/pt-de' Y I 'digits/pt-e' Mp";
05726
05727 ast_localtime(&when, &tm, tzone);
05728
05729 for (offset=0 ; format[offset] != '\0' ; offset++) {
05730 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05731 switch (format[offset]) {
05732
05733 case '\'':
05734
05735 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
05736 sndfile[sndoffset] = format[offset];
05737 }
05738 sndfile[sndoffset] = '\0';
05739 snprintf(nextmsg, sizeof(nextmsg), "%s", sndfile);
05740 res = wait_file(chan, ints, nextmsg, lang);
05741 break;
05742 case 'A':
05743 case 'a':
05744
05745 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05746 res = wait_file(chan, ints, nextmsg, lang);
05747 break;
05748 case 'B':
05749 case 'b':
05750 case 'h':
05751
05752 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05753 res = wait_file(chan, ints, nextmsg, lang);
05754 break;
05755 case 'm':
05756
05757 if (!strcasecmp(lang, "pt_BR")) {
05758 res = ast_say_number(chan, tm.tm_mon+1, ints, lang, (char *) NULL);
05759 } else {
05760 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
05761 res = wait_file(chan, ints, nextmsg, lang);
05762 }
05763 break;
05764 case 'd':
05765 case 'e':
05766
05767 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
05768 break;
05769 case 'Y':
05770
05771 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
05772 break;
05773 case 'I':
05774 case 'l':
05775
05776 if (!strcasecmp(lang, "pt_BR")) {
05777 if (tm.tm_hour == 0) {
05778 if (format[offset] == 'I')
05779 res = wait_file(chan, ints, "digits/pt-a", lang);
05780 if (!res)
05781 res = wait_file(chan, ints, "digits/pt-meianoite", lang);
05782 } else if (tm.tm_hour == 12) {
05783 if (format[offset] == 'I')
05784 res = wait_file(chan, ints, "digits/pt-ao", lang);
05785 if (!res)
05786 res = wait_file(chan, ints, "digits/pt-meiodia", lang);
05787 } else {
05788 if (format[offset] == 'I') {
05789 if ((tm.tm_hour % 12) != 1)
05790 res = wait_file(chan, ints, "digits/pt-as", lang);
05791 else
05792 res = wait_file(chan, ints, "digits/pt-a", lang);
05793 }
05794 if (!res)
05795 res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
05796 }
05797 } else {
05798 if (tm.tm_hour == 0) {
05799 if (format[offset] == 'I')
05800 res = wait_file(chan, ints, "digits/pt-ah", lang);
05801 if (!res)
05802 res = wait_file(chan, ints, "digits/pt-meianoite", lang);
05803 }
05804 else if (tm.tm_hour == 12) {
05805 if (format[offset] == 'I')
05806 res = wait_file(chan, ints, "digits/pt-ao", lang);
05807 if (!res)
05808 res = wait_file(chan, ints, "digits/pt-meiodia", lang);
05809 }
05810 else {
05811 if (format[offset] == 'I') {
05812 res = wait_file(chan, ints, "digits/pt-ah", lang);
05813 if ((tm.tm_hour % 12) != 1)
05814 if (!res)
05815 res = wait_file(chan, ints, "digits/pt-sss", lang);
05816 }
05817 if (!res)
05818 res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
05819 }
05820 }
05821 break;
05822 case 'H':
05823 case 'k':
05824
05825 if (!strcasecmp(lang, "pt_BR")) {
05826 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
05827 if ((!res) && (format[offset] == 'H')) {
05828 if (tm.tm_hour > 1) {
05829 res = wait_file(chan, ints, "digits/hours", lang);
05830 } else {
05831 res = wait_file(chan, ints, "digits/hour", lang);
05832 }
05833 }
05834 } else {
05835 res = ast_say_number(chan, -tm.tm_hour, ints, lang, NULL);
05836 if (!res) {
05837 if (tm.tm_hour != 0) {
05838 int remaining = tm.tm_hour;
05839 if (tm.tm_hour > 20) {
05840 res = wait_file(chan, ints, "digits/20", lang);
05841 remaining -= 20;
05842 }
05843 if (!res) {
05844 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
05845 res = wait_file(chan, ints, nextmsg, lang);
05846 }
05847 }
05848 }
05849 }
05850 break;
05851 case 'M':
05852
05853 if (!strcasecmp(lang, "pt_BR")) {
05854 res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
05855 if (!res) {
05856 if (tm.tm_min > 1) {
05857 res = wait_file(chan, ints, "digits/minutes", lang);
05858 } else {
05859 res = wait_file(chan, ints, "digits/minute", lang);
05860 }
05861 }
05862 } else {
05863 if (tm.tm_min == 0) {
05864 res = wait_file(chan, ints, "digits/pt-hora", lang);
05865 if (tm.tm_hour != 1)
05866 if (!res)
05867 res = wait_file(chan, ints, "digits/pt-sss", lang);
05868 } else {
05869 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05870 }
05871 }
05872 break;
05873 case 'P':
05874 case 'p':
05875
05876 if (!strcasecmp(lang, "pt_BR")) {
05877 if ((tm.tm_hour != 0) && (tm.tm_hour != 12)) {
05878 res = wait_file(chan, ints, "digits/pt-da", lang);
05879 if (!res) {
05880 if ((tm.tm_hour >= 0) && (tm.tm_hour < 12))
05881 res = wait_file(chan, ints, "digits/morning", lang);
05882 else if ((tm.tm_hour >= 12) && (tm.tm_hour < 18))
05883 res = wait_file(chan, ints, "digits/afternoon", lang);
05884 else res = wait_file(chan, ints, "digits/night", lang);
05885 }
05886 }
05887 } else {
05888 if (tm.tm_hour > 12)
05889 res = wait_file(chan, ints, "digits/p-m", lang);
05890 else if (tm.tm_hour && tm.tm_hour < 12)
05891 res = wait_file(chan, ints, "digits/a-m", lang);
05892 }
05893 break;
05894 case 'Q':
05895
05896
05897
05898
05899 {
05900 struct timeval now = ast_tvnow();
05901 struct ast_tm tmnow;
05902 time_t beg_today;
05903
05904 ast_localtime(&now, &tmnow, tzone);
05905
05906
05907 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05908 if (beg_today < t) {
05909
05910 res = wait_file(chan, ints, "digits/today", lang);
05911 } else if (beg_today - 86400 < t) {
05912
05913 res = wait_file(chan, ints, "digits/yesterday", lang);
05914 } else {
05915 res = ast_say_date_with_format_pt(chan, t, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", tzone);
05916 }
05917 }
05918 break;
05919 case 'q':
05920
05921
05922
05923
05924 {
05925 struct timeval now = ast_tvnow();
05926 struct ast_tm tmnow;
05927 time_t beg_today;
05928
05929 ast_localtime(&now, &tmnow, tzone);
05930
05931
05932 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05933 if (beg_today < t) {
05934
05935 } else if ((beg_today - 86400) < t) {
05936
05937 res = wait_file(chan, ints, "digits/yesterday", lang);
05938 } else if (beg_today - 86400 * 6 < t) {
05939
05940 res = ast_say_date_with_format_pt(chan, t, ints, lang, "A", tzone);
05941 } else {
05942 res = ast_say_date_with_format_pt(chan, t, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", tzone);
05943 }
05944 }
05945 break;
05946 case 'R':
05947 res = ast_say_date_with_format_pt(chan, t, ints, lang, "H 'digits/pt-e' M", tzone);
05948 break;
05949 case 'S':
05950
05951 if (!strcasecmp(lang, "pt_BR")) {
05952 res = ast_say_number(chan, tm.tm_sec, ints, lang, NULL);
05953 if (!res) {
05954 if (tm.tm_sec > 1) {
05955 res = wait_file(chan, ints, "digits/seconds", lang);
05956 } else {
05957 res = wait_file(chan, ints, "digits/second", lang);
05958 }
05959 }
05960 } else {
05961 if (tm.tm_sec == 0) {
05962 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05963 res = wait_file(chan, ints, nextmsg, lang);
05964 } else if (tm.tm_sec < 10) {
05965 res = wait_file(chan, ints, "digits/oh", lang);
05966 if (!res) {
05967 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05968 res = wait_file(chan, ints, nextmsg, lang);
05969 }
05970 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
05971 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05972 res = wait_file(chan, ints, nextmsg, lang);
05973 } else {
05974 int ten, one;
05975 ten = (tm.tm_sec / 10) * 10;
05976 one = (tm.tm_sec % 10);
05977 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
05978 res = wait_file(chan, ints, nextmsg, lang);
05979 if (!res) {
05980
05981 if (one != 0) {
05982 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
05983 res = wait_file(chan, ints, nextmsg, lang);
05984 }
05985 }
05986 }
05987 }
05988 break;
05989 case 'T':
05990 res = ast_say_date_with_format_pt(chan, t, ints, lang, "HMS", tzone);
05991 break;
05992 case ' ':
05993 case ' ':
05994
05995 break;
05996 default:
05997
05998 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05999 }
06000
06001 if (res) {
06002 break;
06003 }
06004 }
06005 return res;
06006 }
06007
06008
06009 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)
06010 {
06011 struct timeval when = { t, 0 };
06012 struct ast_tm tm;
06013 int res=0, offset, sndoffset;
06014 char sndfile[256], nextmsg[256];
06015
06016 if (format == NULL)
06017 format = "YBdAkM";
06018
06019 ast_localtime(&when, &tm, tzone);
06020
06021 for (offset=0 ; format[offset] != '\0' ; offset++) {
06022 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
06023 switch (format[offset]) {
06024
06025 case '\'':
06026
06027 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
06028 sndfile[sndoffset] = format[offset];
06029 }
06030 sndfile[sndoffset] = '\0';
06031 res = wait_file(chan, ints, sndfile, lang);
06032 break;
06033 case 'A':
06034 case 'a':
06035
06036 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
06037 res = wait_file(chan, ints, nextmsg, lang);
06038 break;
06039 case 'B':
06040 case 'b':
06041 case 'h':
06042 case 'm':
06043
06044 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
06045 res = wait_file(chan, ints, nextmsg, lang);
06046 break;
06047 case 'd':
06048 case 'e':
06049
06050 if (!(tm.tm_mday % 10) || (tm.tm_mday < 10)) {
06051 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday);
06052 res = wait_file(chan, ints, nextmsg, lang);
06053 } else {
06054 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday - (tm.tm_mday % 10));
06055 res = wait_file(chan, ints, nextmsg, lang);
06056 if (!res) {
06057 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday % 10);
06058 res = wait_file(chan, ints, nextmsg, lang);
06059 }
06060 }
06061 if (!res) res = wait_file(chan, ints, "digits/day", lang);
06062 break;
06063 case 'Y':
06064
06065 if (tm.tm_year > 99) {
06066 res = wait_file(chan, ints, "digits/2", lang);
06067 if (!res) {
06068 res = wait_file(chan, ints, "digits/thousand", lang);
06069 }
06070 if (tm.tm_year > 100) {
06071 if (!res) {
06072 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) / 10);
06073 res = wait_file(chan, ints, nextmsg, lang);
06074 if (!res) {
06075 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) % 10);
06076 res = wait_file(chan, ints, nextmsg, lang);
06077 }
06078 }
06079 }
06080 if (!res) {
06081 res = wait_file(chan, ints, "digits/year", lang);
06082 }
06083 } else {
06084 if (tm.tm_year < 1) {
06085
06086
06087 } else {
06088 res = wait_file(chan, ints, "digits/1", lang);
06089 if (!res) {
06090 res = wait_file(chan, ints, "digits/9", lang);
06091 }
06092 if (!res) {
06093 if (tm.tm_year <= 9) {
06094
06095 res = wait_file(chan, ints, "digits/0", lang);
06096 if (!res) {
06097 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
06098 res = wait_file(chan, ints, nextmsg, lang);
06099 }
06100 } else {
06101
06102 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year / 10);
06103 res = wait_file(chan, ints, nextmsg, lang);
06104 if (!res) {
06105 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year % 10);
06106 res = wait_file(chan, ints, nextmsg, lang);
06107 }
06108 }
06109 }
06110 }
06111 if (!res) {
06112 res = wait_file(chan, ints, "digits/year", lang);
06113 }
06114 }
06115 break;
06116 case 'I':
06117 case 'l':
06118
06119 if (tm.tm_hour == 0)
06120 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
06121 else if (tm.tm_hour > 12)
06122 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
06123 else
06124 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
06125 res = wait_file(chan, ints, nextmsg, lang);
06126 if (!res) {
06127 res = wait_file(chan, ints, "digits/oclock", lang);
06128 }
06129 break;
06130 case 'H':
06131 if (tm.tm_hour < 10) {
06132 res = wait_file(chan, ints, "digits/0", lang);
06133 }
06134
06135
06136
06137 case 'k':
06138
06139 if (!(tm.tm_hour % 10) || tm.tm_hour < 10) {
06140 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
06141 res = wait_file(chan, ints, nextmsg, lang);
06142 } else {
06143 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - (tm.tm_hour % 10));
06144 res = wait_file(chan, ints, nextmsg, lang);
06145 if (!res) {
06146 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour % 10);
06147 res = wait_file(chan, ints, nextmsg, lang);
06148 }
06149 }
06150 if (!res) {
06151 res = wait_file(chan, ints, "digits/oclock", lang);
06152 }
06153 break;
06154 case 'M':
06155
06156 if (!(tm.tm_min % 10) || tm.tm_min < 10) {
06157 if (tm.tm_min < 10) {
06158 res = wait_file(chan, ints, "digits/0", lang);
06159 }
06160 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min);
06161 res = wait_file(chan, ints, nextmsg, lang);
06162 } else {
06163 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min - (tm.tm_min % 10));
06164 res = wait_file(chan, ints, nextmsg, lang);
06165 if (!res) {
06166 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min % 10);
06167 res = wait_file(chan, ints, nextmsg, lang);
06168 }
06169 }
06170 if (!res) {
06171 res = wait_file(chan, ints, "digits/minute", lang);
06172 }
06173 break;
06174 case 'P':
06175 case 'p':
06176
06177 if (tm.tm_hour > 11)
06178 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
06179 else
06180 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
06181 res = wait_file(chan, ints, nextmsg, lang);
06182 break;
06183 case 'Q':
06184
06185
06186
06187
06188 {
06189 struct timeval now = ast_tvnow();
06190 struct ast_tm tmnow;
06191 time_t beg_today;
06192
06193 ast_localtime(&now, &tmnow, tzone);
06194
06195
06196 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
06197 if (beg_today < t) {
06198
06199 res = wait_file(chan, ints, "digits/today", lang);
06200 } else if (beg_today - 86400 < t) {
06201
06202 res = wait_file(chan, ints, "digits/yesterday", lang);
06203 } else {
06204 res = ast_say_date_with_format_zh(chan, t, ints, lang, "YBdA", tzone);
06205 }
06206 }
06207 break;
06208 case 'q':
06209
06210
06211
06212
06213 {
06214 struct timeval now = ast_tvnow();
06215 struct ast_tm tmnow;
06216 time_t beg_today;
06217
06218 ast_localtime(&now, &tmnow, tzone);
06219
06220
06221 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
06222 if (beg_today < t) {
06223
06224 } else if ((beg_today - 86400) < t) {
06225
06226 res = wait_file(chan, ints, "digits/yesterday", lang);
06227 } else if (beg_today - 86400 * 6 < t) {
06228
06229 res = ast_say_date_with_format_zh(chan, t, ints, lang, "A", tzone);
06230 } else {
06231 res = ast_say_date_with_format_zh(chan, t, ints, lang, "YBdA", tzone);
06232 }
06233 }
06234 break;
06235 case 'R':
06236 res = ast_say_date_with_format_zh(chan, t, ints, lang, "kM", tzone);
06237 break;
06238 case 'S':
06239
06240 if (!(tm.tm_sec % 10) || tm.tm_sec < 10) {
06241 if (tm.tm_sec < 10) {
06242 res = wait_file(chan, ints, "digits/0", lang);
06243 }
06244 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
06245 res = wait_file(chan, ints, nextmsg, lang);
06246 } else {
06247 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec - (tm.tm_sec % 10));
06248 res = wait_file(chan, ints, nextmsg, lang);
06249 if (!res) {
06250 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec % 10);
06251 res = wait_file(chan, ints, nextmsg, lang);
06252 }
06253 }
06254 if (!res) {
06255 res = wait_file(chan, ints, "digits/second", lang);
06256 }
06257 break;
06258 case 'T':
06259 res = ast_say_date_with_format_zh(chan, t, ints, lang, "HMS", tzone);
06260 break;
06261 case ' ':
06262 case ' ':
06263
06264 break;
06265 default:
06266
06267 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
06268 }
06269
06270 if (res) {
06271 break;
06272 }
06273 }
06274 return res;
06275 }
06276
06277 static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06278 {
06279 if (!strncasecmp(lang, "en", 2)) {
06280 return ast_say_time_en(chan, t, ints, lang);
06281 } else if (!strncasecmp(lang, "de", 2)) {
06282 return ast_say_time_de(chan, t, ints, lang);
06283 } else if (!strncasecmp(lang, "fr", 2)) {
06284 return ast_say_time_fr(chan, t, ints, lang);
06285 } else if (!strncasecmp(lang, "ge", 2)) {
06286 static int deprecation_warning = 0;
06287 if (deprecation_warning++ % 10 == 0) {
06288 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
06289 }
06290 return ast_say_time_ka(chan, t, ints, lang);
06291 } else if (!strncasecmp(lang, "gr", 2)) {
06292 return ast_say_time_gr(chan, t, ints, lang);
06293 } else if (!strncasecmp(lang, "he", 2)) {
06294 return ast_say_time_he(chan, t, ints, lang);
06295 } else if (!strncasecmp(lang, "hu", 2)) {
06296 return(ast_say_time_hu(chan, t, ints, lang));
06297 } else if (!strncasecmp(lang, "ka", 2)) {
06298 return ast_say_time_ka(chan, t, ints, lang);
06299 } else if (!strncasecmp(lang, "nl", 2)) {
06300 return ast_say_time_nl(chan, t, ints, lang);
06301 } else if (!strncasecmp(lang, "pt_BR", 5)) {
06302 return ast_say_time_pt_BR(chan, t, ints, lang);
06303 } else if (!strncasecmp(lang, "pt", 2)) {
06304 return ast_say_time_pt(chan, t, ints, lang);
06305 } else if (!strncasecmp(lang, "th", 2)) {
06306 return(ast_say_time_th(chan, t, ints, lang));
06307 } else if (!strncasecmp(lang, "tw", 2)) {
06308 static int deprecation_warning = 0;
06309 if (deprecation_warning++ % 10 == 0) {
06310 ast_log(LOG_WARNING, "tw is a standard language code for Twi, not Taiwanese. Please switch to using zh_TW instead.\n");
06311 }
06312 return ast_say_time_zh(chan, t, ints, lang);
06313 } else if (!strncasecmp(lang, "zh", 2)) {
06314 return ast_say_time_zh(chan, t, ints, lang);
06315 }
06316
06317
06318 return ast_say_time_en(chan, t, ints, lang);
06319 }
06320
06321
06322 int ast_say_time_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06323 {
06324 struct timeval when = { t, 0 };
06325 struct ast_tm tm;
06326 int res = 0;
06327 int hour, pm=0;
06328
06329 ast_localtime(&when, &tm, NULL);
06330 hour = tm.tm_hour;
06331 if (!hour)
06332 hour = 12;
06333 else if (hour == 12)
06334 pm = 1;
06335 else if (hour > 12) {
06336 hour -= 12;
06337 pm = 1;
06338 }
06339 if (!res)
06340 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06341
06342 if (tm.tm_min > 9) {
06343 if (!res)
06344 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06345 } else if (tm.tm_min) {
06346 if (!res)
06347 res = ast_streamfile(chan, "digits/oh", lang);
06348 if (!res)
06349 res = ast_waitstream(chan, ints);
06350 if (!res)
06351 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06352 } else {
06353 if (!res)
06354 res = ast_streamfile(chan, "digits/oclock", lang);
06355 if (!res)
06356 res = ast_waitstream(chan, ints);
06357 }
06358 if (pm) {
06359 if (!res)
06360 res = ast_streamfile(chan, "digits/p-m", lang);
06361 } else {
06362 if (!res)
06363 res = ast_streamfile(chan, "digits/a-m", lang);
06364 }
06365 if (!res)
06366 res = ast_waitstream(chan, ints);
06367 return res;
06368 }
06369
06370
06371 int ast_say_time_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06372 {
06373 struct timeval when = { t, 0 };
06374 struct ast_tm tm;
06375 int res = 0;
06376
06377 ast_localtime(&when, &tm, NULL);
06378 if (!res)
06379 res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
06380 if (!res)
06381 res = ast_streamfile(chan, "digits/oclock", lang);
06382 if (!res)
06383 res = ast_waitstream(chan, ints);
06384 if (!res)
06385 if (tm.tm_min > 0)
06386 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06387 return res;
06388 }
06389
06390
06391 int ast_say_time_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06392 {
06393 struct timeval when = { t, 0 };
06394 struct ast_tm tm;
06395 int res = 0;
06396
06397 ast_localtime(&when, &tm, NULL);
06398 if (!res)
06399 res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
06400 if (!res)
06401 res = ast_streamfile(chan, "digits/oclock", lang);
06402 if (!res)
06403 res = ast_waitstream(chan, ints);
06404 if (!res)
06405 if (tm.tm_min > 0) {
06406 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06407 if (!res)
06408 res = ast_streamfile(chan, "digits/minute", lang);
06409 }
06410 return res;
06411 }
06412
06413
06414 int ast_say_time_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06415 {
06416 struct timeval when = { t, 0 };
06417 struct ast_tm tm;
06418 int res = 0;
06419
06420 ast_localtime(&when, &tm, NULL);
06421
06422 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
06423 if (!res)
06424 res = ast_streamfile(chan, "digits/oclock", lang);
06425 if (tm.tm_min) {
06426 if (!res)
06427 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06428 }
06429 return res;
06430 }
06431
06432
06433 int ast_say_time_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06434 {
06435 struct timeval when = { t, 0 };
06436 struct ast_tm tm;
06437 int res = 0;
06438
06439 ast_localtime(&when, &tm, NULL);
06440 if (!res)
06441 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
06442 if (!res)
06443 res = ast_streamfile(chan, "digits/nl-uur", lang);
06444 if (!res)
06445 res = ast_waitstream(chan, ints);
06446 if (!res)
06447 if (tm.tm_min > 0)
06448 res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
06449 return res;
06450 }
06451
06452
06453 int ast_say_time_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06454 {
06455 struct timeval when = { t, 0 };
06456 struct ast_tm tm;
06457 int res = 0;
06458 int hour;
06459
06460 ast_localtime(&when, &tm, NULL);
06461 hour = tm.tm_hour;
06462 if (!res)
06463 res = ast_say_number(chan, hour, ints, lang, "f");
06464 if (tm.tm_min) {
06465 if (!res)
06466 res = wait_file(chan, ints, "digits/pt-e", lang);
06467 if (!res)
06468 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06469 } else {
06470 if (!res)
06471 res = wait_file(chan, ints, "digits/pt-hora", lang);
06472 if (tm.tm_hour != 1)
06473 if (!res)
06474 res = wait_file(chan, ints, "digits/pt-sss", lang);
06475 }
06476 if (!res)
06477 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06478 return res;
06479 }
06480
06481
06482 int ast_say_time_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06483 {
06484 struct timeval when = { t, 0 };
06485 struct ast_tm tm;
06486 int res = 0;
06487
06488 ast_localtime(&when, &tm, NULL);
06489
06490 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
06491 if (!res) {
06492 if (tm.tm_hour > 1)
06493 res = wait_file(chan, ints, "digits/hours", lang);
06494 else
06495 res = wait_file(chan, ints, "digits/hour", lang);
06496 }
06497 if ((!res) && (tm.tm_min)) {
06498 res = wait_file(chan, ints, "digits/pt-e", lang);
06499 if (!res)
06500 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06501 if (!res) {
06502 if (tm.tm_min > 1)
06503 res = wait_file(chan, ints, "digits/minutes", lang);
06504 else
06505 res = wait_file(chan, ints, "digits/minute", lang);
06506 }
06507 }
06508 return res;
06509 }
06510
06511
06512 int ast_say_time_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06513 {
06514 struct timeval when = { t, 0 };
06515 struct ast_tm tm;
06516 int res = 0;
06517 int hour;
06518 ast_localtime(&when, &tm, NULL);
06519 hour = tm.tm_hour;
06520 if (!hour)
06521 hour = 24;
06522 if (!res)
06523 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06524 if (!res)
06525 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06526 return res;
06527 }
06528
06529
06530 int ast_say_time_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06531 {
06532 struct timeval when = { t, 0 };
06533 struct ast_tm tm;
06534 int res = 0;
06535 int hour, pm=0;
06536
06537 ast_localtime(&when, &tm, NULL);
06538 hour = tm.tm_hour;
06539 if (!hour)
06540 hour = 12;
06541 else if (hour == 12)
06542 pm = 1;
06543 else if (hour > 12) {
06544 hour -= 12;
06545 pm = 1;
06546 }
06547 if (pm) {
06548 if (!res)
06549 res = ast_streamfile(chan, "digits/p-m", lang);
06550 } else {
06551 if (!res)
06552 res = ast_streamfile(chan, "digits/a-m", lang);
06553 }
06554 if (!res)
06555 res = ast_waitstream(chan, ints);
06556 if (!res)
06557 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06558 if (!res)
06559 res = ast_streamfile(chan, "digits/oclock", lang);
06560 if (!res)
06561 res = ast_waitstream(chan, ints);
06562 if (!res)
06563 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06564 if (!res)
06565 res = ast_streamfile(chan, "digits/minute", lang);
06566 if (!res)
06567 res = ast_waitstream(chan, ints);
06568 return res;
06569 }
06570
06571
06572 int ast_say_time_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06573 {
06574 struct timeval when = { t, 0 };
06575 struct ast_tm tm;
06576 int res = 0;
06577 int hour;
06578
06579 ast_localtime(&when, &tm, NULL);
06580 hour = tm.tm_hour;
06581 if (!hour)
06582 hour = 12;
06583
06584 if (!res)
06585 res = ast_say_number_full_he(chan, hour, ints, lang, "f", -1, -1);
06586
06587 if (tm.tm_min > 9) {
06588 if (!res)
06589 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
06590 } else if (tm.tm_min) {
06591 if (!res) {
06592 res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
06593 }
06594 if (!res)
06595 res = ast_waitstream(chan, ints);
06596 if (!res)
06597 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
06598 } else {
06599 if (!res)
06600 res = ast_waitstream(chan, ints);
06601 }
06602 if (!res)
06603 res = ast_waitstream(chan, ints);
06604 return res;
06605 }
06606
06607
06608 static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06609 {
06610 if (!strncasecmp(lang, "en", 2)) {
06611 return ast_say_datetime_en(chan, t, ints, lang);
06612 } else if (!strncasecmp(lang, "de", 2)) {
06613 return ast_say_datetime_de(chan, t, ints, lang);
06614 } else if (!strncasecmp(lang, "fr", 2)) {
06615 return ast_say_datetime_fr(chan, t, ints, lang);
06616 } else if (!strncasecmp(lang, "ge", 2)) {
06617 static int deprecation_warning = 0;
06618 if (deprecation_warning++ % 10 == 0) {
06619 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
06620 }
06621 return ast_say_datetime_ka(chan, t, ints, lang);
06622 } else if (!strncasecmp(lang, "gr", 2)) {
06623 return ast_say_datetime_gr(chan, t, ints, lang);
06624 } else if (!strncasecmp(lang, "he", 2)) {
06625 return ast_say_datetime_he(chan, t, ints, lang);
06626 } else if (!strncasecmp(lang, "hu", 2)) {
06627 return ast_say_datetime_hu(chan, t, ints, lang);
06628 } else if (!strncasecmp(lang, "ka", 2)) {
06629 return ast_say_datetime_ka(chan, t, ints, lang);
06630 } else if (!strncasecmp(lang, "nl", 2)) {
06631 return ast_say_datetime_nl(chan, t, ints, lang);
06632 } else if (!strncasecmp(lang, "pt_BR", 5)) {
06633 return ast_say_datetime_pt_BR(chan, t, ints, lang);
06634 } else if (!strncasecmp(lang, "pt", 2)) {
06635 return ast_say_datetime_pt(chan, t, ints, lang);
06636 } else if (!strncasecmp(lang, "th", 2)) {
06637 return ast_say_datetime_th(chan, t, ints, lang);
06638 } else if (!strncasecmp(lang, "tw", 2)) {
06639 static int deprecation_warning = 0;
06640 if (deprecation_warning++ % 10 == 0) {
06641 ast_log(LOG_WARNING, "tw is a standard language code for Twi, not Taiwanese. Please switch to using zh_TW instead.\n");
06642 }
06643 return ast_say_datetime_zh(chan, t, ints, lang);
06644 } else if (!strncasecmp(lang, "zh", 2)) {
06645 return ast_say_datetime_zh(chan, t, ints, lang);
06646 }
06647
06648
06649 return ast_say_datetime_en(chan, t, ints, lang);
06650 }
06651
06652
06653 int ast_say_datetime_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06654 {
06655 struct timeval when = { t, 0 };
06656 struct ast_tm tm;
06657 char fn[256];
06658 int res = 0;
06659 int hour, pm=0;
06660
06661 ast_localtime(&when, &tm, NULL);
06662 if (!res) {
06663 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06664 res = ast_streamfile(chan, fn, lang);
06665 if (!res)
06666 res = ast_waitstream(chan, ints);
06667 }
06668 if (!res) {
06669 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06670 res = ast_streamfile(chan, fn, lang);
06671 if (!res)
06672 res = ast_waitstream(chan, ints);
06673 }
06674 if (!res)
06675 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06676
06677 hour = tm.tm_hour;
06678 if (!hour)
06679 hour = 12;
06680 else if (hour == 12)
06681 pm = 1;
06682 else if (hour > 12) {
06683 hour -= 12;
06684 pm = 1;
06685 }
06686 if (!res)
06687 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06688
06689 if (tm.tm_min > 9) {
06690 if (!res)
06691 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06692 } else if (tm.tm_min) {
06693 if (!res)
06694 res = ast_streamfile(chan, "digits/oh", lang);
06695 if (!res)
06696 res = ast_waitstream(chan, ints);
06697 if (!res)
06698 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06699 } else {
06700 if (!res)
06701 res = ast_streamfile(chan, "digits/oclock", lang);
06702 if (!res)
06703 res = ast_waitstream(chan, ints);
06704 }
06705 if (pm) {
06706 if (!res)
06707 res = ast_streamfile(chan, "digits/p-m", lang);
06708 } else {
06709 if (!res)
06710 res = ast_streamfile(chan, "digits/a-m", lang);
06711 }
06712 if (!res)
06713 res = ast_waitstream(chan, ints);
06714 if (!res)
06715 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06716 return res;
06717 }
06718
06719
06720 int ast_say_datetime_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06721 {
06722 struct timeval when = { t, 0 };
06723 struct ast_tm tm;
06724 int res = 0;
06725
06726 ast_localtime(&when, &tm, NULL);
06727 res = ast_say_date(chan, t, ints, lang);
06728 if (!res)
06729 ast_say_time(chan, t, ints, lang);
06730 return res;
06731
06732 }
06733
06734
06735 int ast_say_datetime_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06736 {
06737 struct timeval when = { t, 0 };
06738 struct ast_tm tm;
06739 int res = 0;
06740
06741 ast_localtime(&when, &tm, NULL);
06742 res = ast_say_date(chan, t, ints, lang);
06743 if (!res)
06744 ast_say_time(chan, t, ints, lang);
06745 return res;
06746 }
06747
06748
06749 int ast_say_datetime_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06750 {
06751 struct timeval when = { t, 0 };
06752 struct ast_tm tm;
06753 char fn[256];
06754 int res = 0;
06755
06756 ast_localtime(&when, &tm, NULL);
06757
06758 if (!res)
06759 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06760
06761 if (!res) {
06762 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06763 res = ast_streamfile(chan, fn, lang);
06764 if (!res)
06765 res = ast_waitstream(chan, ints);
06766 }
06767 if (!res) {
06768 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06769 res = ast_streamfile(chan, fn, lang);
06770 if (!res)
06771 res = ast_waitstream(chan, ints);
06772 }
06773
06774 if (!res)
06775 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
06776 if (!res)
06777 res = ast_streamfile(chan, "digits/oclock", lang);
06778 if (tm.tm_min > 0) {
06779 if (!res)
06780 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06781 }
06782 if (!res)
06783 res = ast_waitstream(chan, ints);
06784 if (!res)
06785 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06786 return res;
06787 }
06788
06789
06790 int ast_say_datetime_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06791 {
06792 struct timeval when = { t, 0 };
06793 struct ast_tm tm;
06794 int res = 0;
06795
06796 ast_localtime(&when, &tm, NULL);
06797 res = ast_say_date(chan, t, ints, lang);
06798 if (!res) {
06799 res = ast_streamfile(chan, "digits/nl-om", lang);
06800 if (!res)
06801 res = ast_waitstream(chan, ints);
06802 }
06803 if (!res)
06804 ast_say_time(chan, t, ints, lang);
06805 return res;
06806 }
06807
06808
06809 int ast_say_datetime_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06810 {
06811 struct timeval when = { t, 0 };
06812 struct ast_tm tm;
06813 char fn[256];
06814 int res = 0;
06815 int hour, pm=0;
06816
06817 ast_localtime(&when, &tm, NULL);
06818 if (!res) {
06819 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06820 res = ast_streamfile(chan, fn, lang);
06821 if (!res)
06822 res = ast_waitstream(chan, ints);
06823 }
06824 if (!res) {
06825 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06826 res = ast_streamfile(chan, fn, lang);
06827 if (!res)
06828 res = ast_waitstream(chan, ints);
06829 }
06830 if (!res)
06831 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06832
06833 hour = tm.tm_hour;
06834 if (!hour)
06835 hour = 12;
06836 else if (hour == 12)
06837 pm = 1;
06838 else if (hour > 12) {
06839 hour -= 12;
06840 pm = 1;
06841 }
06842 if (!res)
06843 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06844
06845 if (tm.tm_min > 9) {
06846 if (!res)
06847 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06848 } else if (tm.tm_min) {
06849 if (!res)
06850 res = ast_streamfile(chan, "digits/oh", lang);
06851 if (!res)
06852 res = ast_waitstream(chan, ints);
06853 if (!res)
06854 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06855 } else {
06856 if (!res)
06857 res = ast_streamfile(chan, "digits/oclock", lang);
06858 if (!res)
06859 res = ast_waitstream(chan, ints);
06860 }
06861 if (pm) {
06862 if (!res)
06863 res = ast_streamfile(chan, "digits/p-m", lang);
06864 } else {
06865 if (!res)
06866 res = ast_streamfile(chan, "digits/a-m", lang);
06867 }
06868 if (!res)
06869 res = ast_waitstream(chan, ints);
06870 if (!res)
06871 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06872 return res;
06873 }
06874
06875
06876 int ast_say_datetime_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06877 {
06878 struct timeval when = { t, 0 };
06879 struct ast_tm tm;
06880 int res = 0;
06881
06882 ast_localtime(&when, &tm, NULL);
06883 res = ast_say_date(chan, t, ints, lang);
06884 if (!res)
06885 res = ast_say_time(chan, t, ints, lang);
06886 return res;
06887 }
06888
06889
06890 int ast_say_datetime_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06891 {
06892 struct timeval when = { t, 0 };
06893 struct ast_tm tm;
06894 char fn[256];
06895 int res = 0;
06896 int hour;
06897 ast_localtime(&when, &tm, NULL);
06898 if (!res) {
06899 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06900 res = ast_streamfile(chan, fn, lang);
06901 if (!res)
06902 res = ast_waitstream(chan, ints);
06903 }
06904 if (!res) {
06905 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06906 res = ast_streamfile(chan, fn, lang);
06907 if (!res)
06908 res = ast_waitstream(chan, ints);
06909 }
06910 if (!res){
06911 ast_copy_string(fn, "digits/posor", sizeof(fn));
06912 res = ast_streamfile(chan, fn, lang);
06913 res = ast_say_number(chan, tm.tm_year + 1900 + 543, ints, lang, (char *) NULL);
06914 }
06915 if (!res)
06916 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06917
06918 hour = tm.tm_hour;
06919 if (!hour)
06920 hour = 24;
06921 if (!res){
06922 ast_copy_string(fn, "digits/wela", sizeof(fn));
06923 res = ast_streamfile(chan, fn, lang);
06924 }
06925 if (!res)
06926 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06927 if (!res)
06928 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06929 return res;
06930 }
06931
06932
06933 int ast_say_datetime_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06934 {
06935 struct timeval when = { t, 0 };
06936 struct ast_tm tm;
06937 char fn[256];
06938 int res = 0;
06939 int hour, pm=0;
06940
06941 ast_localtime(&when, &tm, NULL);
06942 if (!res)
06943 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06944 if (!res) {
06945 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06946 res = ast_streamfile(chan, fn, lang);
06947 if (!res)
06948 res = ast_waitstream(chan, ints);
06949 }
06950 if (!res)
06951 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06952 if (!res) {
06953 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06954 res = ast_streamfile(chan, fn, lang);
06955 if (!res)
06956 res = ast_waitstream(chan, ints);
06957 }
06958
06959 hour = tm.tm_hour;
06960 if (!hour)
06961 hour = 12;
06962 else if (hour == 12)
06963 pm = 1;
06964 else if (hour > 12) {
06965 hour -= 12;
06966 pm = 1;
06967 }
06968 if (pm) {
06969 if (!res)
06970 res = ast_streamfile(chan, "digits/p-m", lang);
06971 } else {
06972 if (!res)
06973 res = ast_streamfile(chan, "digits/a-m", lang);
06974 }
06975 if (!res)
06976 res = ast_waitstream(chan, ints);
06977 if (!res)
06978 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06979 if (!res)
06980 res = ast_streamfile(chan, "digits/oclock", lang);
06981 if (!res)
06982 res = ast_waitstream(chan, ints);
06983 if (!res)
06984 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06985 if (!res)
06986 res = ast_streamfile(chan, "digits/minute", lang);
06987 if (!res)
06988 res = ast_waitstream(chan, ints);
06989 return res;
06990 }
06991
06992
06993 int ast_say_datetime_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06994 {
06995 struct timeval when = { t, 0 };
06996 struct ast_tm tm;
06997 char fn[256];
06998 int res = 0;
06999 int hour;
07000
07001 ast_localtime(&when, &tm, NULL);
07002 if (!res) {
07003 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07004 res = ast_streamfile(chan, fn, lang);
07005 if (!res) {
07006 res = ast_waitstream(chan, ints);
07007 }
07008 }
07009 if (!res) {
07010 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07011 res = ast_streamfile(chan, fn, lang);
07012 if (!res) {
07013 res = ast_waitstream(chan, ints);
07014 }
07015 }
07016 if (!res) {
07017 res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
07018 }
07019
07020 hour = tm.tm_hour;
07021 if (!hour) {
07022 hour = 12;
07023 }
07024
07025 if (!res) {
07026 res = ast_say_number(chan, hour, ints, lang, "f");
07027 }
07028
07029 if (tm.tm_min > 9) {
07030 if (!res) {
07031 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
07032 }
07033 } else if (tm.tm_min) {
07034 if (!res) {
07035
07036 res = ast_say_number(chan, 0, ints, lang, "f");
07037 }
07038 if (!res) {
07039 res = ast_waitstream(chan, ints);
07040 }
07041 if (!res) {
07042 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
07043 }
07044 } else {
07045 if (!res) {
07046 res = ast_waitstream(chan, ints);
07047 }
07048 }
07049 if (!res) {
07050 res = ast_waitstream(chan, ints);
07051 }
07052 if (!res) {
07053 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "f");
07054 }
07055 return res;
07056 }
07057
07058 static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07059 {
07060 if (!strncasecmp(lang, "en", 2)) {
07061 return ast_say_datetime_from_now_en(chan, t, ints, lang);
07062 } else if (!strncasecmp(lang, "fr", 2)) {
07063 return ast_say_datetime_from_now_fr(chan, t, ints, lang);
07064 } else if (!strncasecmp(lang, "ge", 2)) {
07065 static int deprecation_warning = 0;
07066 if (deprecation_warning++ % 10 == 0) {
07067 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
07068 }
07069 return ast_say_datetime_from_now_ka(chan, t, ints, lang);
07070 } else if (!strncasecmp(lang, "he", 2)) {
07071 return ast_say_datetime_from_now_he(chan, t, ints, lang);
07072 } else if (!strncasecmp(lang, "ka", 2)) {
07073 return ast_say_datetime_from_now_ka(chan, t, ints, lang);
07074 } else if (!strncasecmp(lang, "pt", 2)) {
07075 return ast_say_datetime_from_now_pt(chan, t, ints, lang);
07076 }
07077
07078
07079 return ast_say_datetime_from_now_en(chan, t, ints, lang);
07080 }
07081
07082
07083 int ast_say_datetime_from_now_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07084 {
07085 int res=0;
07086 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
07087 int daydiff;
07088 struct ast_tm tm;
07089 struct ast_tm now;
07090 char fn[256];
07091
07092 ast_localtime(&when, &tm, NULL);
07093 ast_localtime(&nowtv, &now, NULL);
07094 daydiff = now.tm_yday - tm.tm_yday;
07095 if ((daydiff < 0) || (daydiff > 6)) {
07096
07097 if (!res) {
07098 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07099 res = ast_streamfile(chan, fn, lang);
07100 if (!res)
07101 res = ast_waitstream(chan, ints);
07102 }
07103 if (!res)
07104 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
07105
07106 } else if (daydiff) {
07107
07108 if (!res) {
07109 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07110 res = ast_streamfile(chan, fn, lang);
07111 if (!res)
07112 res = ast_waitstream(chan, ints);
07113 }
07114 }
07115 if (!res)
07116 res = ast_say_time(chan, t, ints, lang);
07117 return res;
07118 }
07119
07120
07121 int ast_say_datetime_from_now_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07122 {
07123 int res=0;
07124 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
07125 int daydiff;
07126 struct ast_tm tm;
07127 struct ast_tm now;
07128 char fn[256];
07129
07130 ast_localtime(&when, &tm, NULL);
07131 ast_localtime(&nowtv, &now, NULL);
07132 daydiff = now.tm_yday - tm.tm_yday;
07133 if ((daydiff < 0) || (daydiff > 6)) {
07134
07135 if (!res) {
07136 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07137 res = ast_streamfile(chan, fn, lang);
07138 if (!res)
07139 res = ast_waitstream(chan, ints);
07140 }
07141 if (!res)
07142 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
07143
07144 } else if (daydiff) {
07145
07146 if (!res) {
07147 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07148 res = ast_streamfile(chan, fn, lang);
07149 if (!res)
07150 res = ast_waitstream(chan, ints);
07151 }
07152 }
07153 if (!res)
07154 res = ast_say_time(chan, t, ints, lang);
07155 return res;
07156 }
07157
07158
07159 int ast_say_datetime_from_now_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07160 {
07161 int res=0;
07162 int daydiff;
07163 struct ast_tm tm;
07164 struct ast_tm now;
07165 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
07166 char fn[256];
07167
07168 ast_localtime(&when, &tm, NULL);
07169 ast_localtime(&nowtv, &now, NULL);
07170 daydiff = now.tm_yday - tm.tm_yday;
07171 if ((daydiff < 0) || (daydiff > 6)) {
07172
07173 if (!res)
07174 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
07175 if (!res)
07176 res = wait_file(chan, ints, "digits/pt-de", lang);
07177 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07178 if (!res)
07179 res = wait_file(chan, ints, fn, lang);
07180
07181 } else if (daydiff) {
07182
07183 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07184 if (!res)
07185 res = wait_file(chan, ints, fn, lang);
07186 }
07187 if (!strcasecmp(lang, "pt_BR")) {
07188 if (tm.tm_hour > 1) {
07189 ast_copy_string(fn, "digits/pt-as", sizeof(fn));
07190 } else {
07191 ast_copy_string(fn, "digits/pt-a", sizeof(fn));
07192 }
07193 if (!res)
07194 res = wait_file(chan, ints, fn, lang);
07195 } else {
07196 ast_copy_string(fn, "digits/pt-ah", sizeof(fn));
07197 if (!res)
07198 res = wait_file(chan, ints, fn, lang);
07199 if (tm.tm_hour != 1)
07200 if (!res)
07201 res = wait_file(chan, ints, "digits/pt-sss", lang);
07202 if (!res)
07203 res = ast_say_time(chan, t, ints, lang);
07204 }
07205 return res;
07206 }
07207
07208
07209 int ast_say_datetime_from_now_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07210 {
07211 int res = 0;
07212 struct timeval nowt = ast_tvnow(), when = { t, 0 };
07213 int daydiff;
07214 struct ast_tm tm;
07215 struct ast_tm now;
07216 char fn[256];
07217
07218 ast_localtime(&when, &tm, NULL);
07219 ast_localtime(&nowt, &now, NULL);
07220 daydiff = now.tm_yday - tm.tm_yday;
07221 if ((daydiff < 0) || (daydiff > 6)) {
07222
07223 if (!res) {
07224 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07225 res = ast_streamfile(chan, fn, lang);
07226 if (!res)
07227 res = ast_waitstream(chan, ints);
07228 }
07229 if (!res) {
07230 res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
07231 }
07232 } else if (daydiff) {
07233
07234 if (!res) {
07235 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07236 res = ast_streamfile(chan, fn, lang);
07237 if (!res) {
07238 res = ast_waitstream(chan, ints);
07239 }
07240 }
07241 }
07242 if (!res) {
07243 res = ast_say_time(chan, t, ints, lang);
07244 }
07245 return res;
07246 }
07247
07248
07249
07250
07251
07252
07253 static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang){
07254 int tmp;
07255 int left;
07256 int res;
07257 char fn[256] = "";
07258
07259
07260 if (num < 5) {
07261 snprintf(fn, sizeof(fn), "digits/female-%d", num);
07262 res = wait_file(chan, ints, fn, lang);
07263 } else if (num < 13) {
07264 res = ast_say_number(chan, num, ints, lang, (char *) NULL);
07265 } else if (num <100 ) {
07266 tmp = (num/10) * 10;
07267 left = num - tmp;
07268 snprintf(fn, sizeof(fn), "digits/%d", tmp);
07269 res = ast_streamfile(chan, fn, lang);
07270 if (!res)
07271 res = ast_waitstream(chan, ints);
07272 if (left)
07273 gr_say_number_female(left, chan, ints, lang);
07274
07275 } else {
07276 return -1;
07277 }
07278 return res;
07279 }
07280
07281
07282
07283
07284
07285
07286
07287
07288
07289
07290
07291
07292
07293
07294
07295
07296
07297
07298 static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
07299 {
07300 int res = 0;
07301 char fn[256] = "";
07302 int i=0;
07303
07304
07305 if (!num) {
07306 ast_copy_string(fn, "digits/0", sizeof(fn));
07307 res = ast_streamfile(chan, fn, ast_channel_language(chan));
07308 if (!res)
07309 return ast_waitstream(chan, ints);
07310 }
07311
07312 while (!res && num ) {
07313 i++;
07314 if (num < 13) {
07315 snprintf(fn, sizeof(fn), "digits/%d", num);
07316 num = 0;
07317 } else if (num <= 100) {
07318
07319 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
07320 num %= 10;
07321 } else if (num < 200) {
07322
07323 snprintf(fn, sizeof(fn), "digits/hundred-100");
07324 num %= 100;
07325 } else if (num < 1000) {
07326
07327 snprintf(fn, sizeof(fn), "digits/hundred-%d", (num/100)*100);
07328 num %= 100;
07329 } else if (num < 2000){
07330 snprintf(fn, sizeof(fn), "digits/xilia");
07331 num %= 1000;
07332 } else {
07333
07334 if (num < 1000000) {
07335 res = ast_say_number_full_gr(chan, (num / 1000), ints, ast_channel_language(chan), audiofd, ctrlfd);
07336 if (res)
07337 return res;
07338 num %= 1000;
07339 snprintf(fn, sizeof(fn), "digits/thousands");
07340 } else {
07341 if (num < 1000000000) {
07342 res = ast_say_number_full_gr(chan, (num / 1000000), ints, ast_channel_language(chan), audiofd, ctrlfd);
07343 if (res)
07344 return res;
07345 num %= 1000000;
07346 snprintf(fn, sizeof(fn), "digits/millions");
07347 } else {
07348 ast_debug(1, "Number '%d' is too big for me\n", num);
07349 res = -1;
07350 }
07351 }
07352 }
07353 if (!res) {
07354 if (!ast_streamfile(chan, fn, language)) {
07355 if ((audiofd > -1) && (ctrlfd > -1))
07356 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
07357 else
07358 res = ast_waitstream(chan, ints);
07359 }
07360 ast_stopstream(chan);
07361 }
07362 }
07363 return res;
07364 }
07365
07366
07367
07368
07369
07370
07371
07372
07373
07374
07375
07376 static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07377 {
07378 struct ast_tm tm;
07379 struct timeval when = { t, 0 };
07380
07381 char fn[256];
07382 int res = 0;
07383
07384
07385 ast_localtime(&when, &tm, NULL);
07386
07387 if (!res) {
07388 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07389 res = ast_streamfile(chan, fn, lang);
07390 if (!res)
07391 res = ast_waitstream(chan, ints);
07392 }
07393
07394 if (!res) {
07395 gr_say_number_female(tm.tm_mday, chan, ints, lang);
07396 }
07397
07398 if (!res) {
07399 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07400 res = ast_streamfile(chan, fn, lang);
07401 if (!res)
07402 res = ast_waitstream(chan, ints);
07403 }
07404
07405 if (!res)
07406 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
07407 return res;
07408 }
07409
07410
07411
07412
07413
07414
07415
07416
07417
07418
07419
07420
07421 static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07422 {
07423
07424 struct timeval when = { t, 0 };
07425 struct ast_tm tm;
07426 int res = 0;
07427 int hour, pm=0;
07428
07429 ast_localtime(&when, &tm, NULL);
07430 hour = tm.tm_hour;
07431
07432 if (!hour)
07433 hour = 12;
07434 else if (hour == 12)
07435 pm = 1;
07436 else if (hour > 12) {
07437 hour -= 12;
07438 pm = 1;
07439 }
07440
07441 res = gr_say_number_female(hour, chan, ints, lang);
07442 if (tm.tm_min) {
07443 if (!res)
07444 res = ast_streamfile(chan, "digits/kai", lang);
07445 if (!res)
07446 res = ast_waitstream(chan, ints);
07447 if (!res)
07448 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
07449 } else {
07450 if (!res)
07451 res = ast_streamfile(chan, "digits/hwra", lang);
07452 if (!res)
07453 res = ast_waitstream(chan, ints);
07454 }
07455 if (pm) {
07456 if (!res)
07457 res = ast_streamfile(chan, "digits/p-m", lang);
07458 } else {
07459 if (!res)
07460 res = ast_streamfile(chan, "digits/a-m", lang);
07461 }
07462 if (!res)
07463 res = ast_waitstream(chan, ints);
07464 return res;
07465 }
07466
07467
07468
07469
07470
07471 static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07472 {
07473 struct timeval when = { t, 0 };
07474 struct ast_tm tm;
07475 char fn[256];
07476 int res = 0;
07477
07478 ast_localtime(&when, &tm, NULL);
07479
07480
07481 if (!res) {
07482 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07483 res = ast_streamfile(chan, fn, lang);
07484 if (!res)
07485 res = ast_waitstream(chan, ints);
07486 }
07487
07488 if (!res) {
07489 gr_say_number_female(tm.tm_mday, chan, ints, lang);
07490 }
07491
07492 if (!res) {
07493 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07494 res = ast_streamfile(chan, fn, lang);
07495 if (!res)
07496 res = ast_waitstream(chan, ints);
07497 }
07498
07499 res = ast_say_time_gr(chan, t, ints, lang);
07500 return res;
07501 }
07502
07503
07504
07505 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)
07506 {
07507 struct timeval when = { t, 0 };
07508 struct ast_tm tm;
07509 int res=0, offset, sndoffset;
07510 char sndfile[256], nextmsg[256];
07511
07512 if (!format)
07513 format = "AdBY 'digits/at' IMp";
07514
07515 ast_localtime(&when, &tm, tzone);
07516
07517 for (offset=0 ; format[offset] != '\0' ; offset++) {
07518 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
07519 switch (format[offset]) {
07520
07521 case '\'':
07522
07523 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
07524 sndfile[sndoffset] = format[offset];
07525 }
07526 sndfile[sndoffset] = '\0';
07527 res = wait_file(chan, ints, sndfile, lang);
07528 break;
07529 case 'A':
07530 case 'a':
07531
07532 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
07533 res = wait_file(chan, ints, nextmsg, lang);
07534 break;
07535 case 'B':
07536 case 'b':
07537 case 'h':
07538
07539 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
07540 res = wait_file(chan, ints, nextmsg, lang);
07541 break;
07542 case 'd':
07543 case 'e':
07544
07545 gr_say_number_female(tm.tm_mday, chan, ints, lang);
07546 break;
07547 case 'Y':
07548
07549
07550 ast_say_number_full_gr(chan, 1900+tm.tm_year, ints, ast_channel_language(chan), -1, -1);
07551 break;
07552 case 'I':
07553 case 'l':
07554
07555 if (tm.tm_hour == 0)
07556 gr_say_number_female(12, chan, ints, lang);
07557 else if (tm.tm_hour > 12)
07558 gr_say_number_female(tm.tm_hour - 12, chan, ints, lang);
07559 else
07560 gr_say_number_female(tm.tm_hour, chan, ints, lang);
07561 break;
07562 case 'H':
07563 case 'k':
07564
07565 gr_say_number_female(tm.tm_hour, chan, ints, lang);
07566 break;
07567 case 'M':
07568
07569 if (tm.tm_min) {
07570 if (!res)
07571 res = ast_streamfile(chan, "digits/kai", lang);
07572 if (!res)
07573 res = ast_waitstream(chan, ints);
07574 if (!res)
07575 res = ast_say_number_full_gr(chan, tm.tm_min, ints, lang, -1, -1);
07576 } else {
07577 if (!res)
07578 res = ast_streamfile(chan, "digits/oclock", lang);
07579 if (!res)
07580 res = ast_waitstream(chan, ints);
07581 }
07582 break;
07583 case 'P':
07584 case 'p':
07585
07586 if (tm.tm_hour > 11)
07587 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
07588 else
07589 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
07590 res = wait_file(chan, ints, nextmsg, lang);
07591 break;
07592 case 'Q':
07593
07594
07595
07596
07597 {
07598 struct timeval now = ast_tvnow();
07599 struct ast_tm tmnow;
07600 time_t beg_today;
07601
07602 ast_localtime(&now, &tmnow, tzone);
07603
07604
07605 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
07606 if (beg_today < t) {
07607
07608 res = wait_file(chan, ints, "digits/today", lang);
07609 } else if (beg_today - 86400 < t) {
07610
07611 res = wait_file(chan, ints, "digits/yesterday", lang);
07612 } else {
07613 res = ast_say_date_with_format_gr(chan, t, ints, lang, "AdBY", tzone);
07614 }
07615 }
07616 break;
07617 case 'q':
07618
07619
07620
07621
07622 {
07623 struct timeval now = ast_tvnow();
07624 struct ast_tm tmnow;
07625 time_t beg_today;
07626
07627 ast_localtime(&now, &tmnow, tzone);
07628
07629
07630 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
07631 if (beg_today < t) {
07632
07633 } else if ((beg_today - 86400) < t) {
07634
07635 res = wait_file(chan, ints, "digits/yesterday", lang);
07636 } else if (beg_today - 86400 * 6 < t) {
07637
07638 res = ast_say_date_with_format_gr(chan, t, ints, lang, "A", tzone);
07639 } else {
07640 res = ast_say_date_with_format_gr(chan, t, ints, lang, "AdBY", tzone);
07641 }
07642 }
07643 break;
07644 case 'R':
07645 res = ast_say_date_with_format_gr(chan, t, ints, lang, "HM", tzone);
07646 break;
07647 case 'S':
07648
07649 ast_copy_string(nextmsg, "digits/kai", sizeof(nextmsg));
07650 res = wait_file(chan, ints, nextmsg, lang);
07651 if (!res)
07652 res = ast_say_number_full_gr(chan, tm.tm_sec, ints, lang, -1, -1);
07653 if (!res)
07654 ast_copy_string(nextmsg, "digits/seconds", sizeof(nextmsg));
07655 res = wait_file(chan, ints, nextmsg, lang);
07656 break;
07657 case 'T':
07658 res = ast_say_date_with_format_gr(chan, t, ints, lang, "HMS", tzone);
07659 break;
07660 case ' ':
07661 case ' ':
07662
07663 break;
07664 default:
07665
07666 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
07667 }
07668
07669 if (res) {
07670 break;
07671 }
07672 }
07673 return res;
07674 }
07675
07676
07677 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)
07678 {
07679 struct timeval when = { t, 0 };
07680 struct ast_tm tm;
07681 int res = 0, offset, sndoffset;
07682 char sndfile[256], nextmsg[256];
07683
07684 if (format == NULL)
07685 format = "A 'digits/day' eB 'digits/year' Y 'digits/at' k 'hours' M 'minutes' p";
07686
07687 ast_localtime(&when, &tm, tzone);
07688
07689 for (offset=0 ; format[offset] != '\0' ; offset++) {
07690 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
07691 switch (format[offset]) {
07692
07693 case '\'':
07694
07695 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
07696 sndfile[sndoffset] = format[offset];
07697 }
07698 sndfile[sndoffset] = '\0';
07699 res = wait_file(chan, ints, sndfile, lang);
07700 break;
07701 case 'A':
07702 case 'a':
07703
07704 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
07705 res = wait_file(chan, ints, nextmsg, lang);
07706 break;
07707 case 'B':
07708 case 'b':
07709 case 'h':
07710
07711 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
07712 res = wait_file(chan, ints, nextmsg, lang);
07713 break;
07714 case 'm':
07715
07716 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
07717 break;
07718 case 'd':
07719 case 'e':
07720
07721 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
07722 break;
07723 case 'Y':
07724
07725 if (tm.tm_year > 99) {
07726 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
07727 } else if (tm.tm_year < 1) {
07728
07729
07730 } else {
07731 res = wait_file(chan, ints, "digits/19", lang);
07732 if (!res) {
07733 if (tm.tm_year <= 9) {
07734
07735 res = wait_file(chan, ints, "digits/odd", lang);
07736 }
07737
07738 res |= ast_say_number(chan, tm.tm_year, ints, lang, (char *) NULL);
07739 }
07740 }
07741 break;
07742 case 'I':
07743 case 'l':
07744
07745 if (tm.tm_hour == 0)
07746 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
07747 else if (tm.tm_hour > 12)
07748 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
07749 else
07750 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
07751 res = wait_file(chan, ints, nextmsg, lang);
07752 break;
07753 case 'H':
07754 case 'k':
07755
07756 if (format[offset] == 'H') {
07757
07758 if (tm.tm_hour < 10) {
07759 res = wait_file(chan, ints, "digits/0", lang);
07760 }
07761 } else {
07762
07763 if (tm.tm_hour == 0) {
07764 res = wait_file(chan, ints, "digits/0", lang);
07765 }
07766 }
07767 if (!res) {
07768 if (tm.tm_hour != 0) {
07769 int remaining = tm.tm_hour;
07770 if (tm.tm_hour > 20) {
07771 res = wait_file(chan, ints, "digits/20", lang);
07772 remaining -= 20;
07773 }
07774 if (!res) {
07775 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
07776 res = wait_file(chan, ints, nextmsg, lang);
07777 }
07778 }
07779 }
07780 break;
07781 case 'M':
07782 case 'N':
07783
07784 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
07785 break;
07786 case 'P':
07787 case 'p':
07788
07789 if (tm.tm_hour > 11)
07790 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
07791 else
07792 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
07793 res = wait_file(chan, ints, nextmsg, lang);
07794 break;
07795 case 'Q':
07796
07797
07798
07799
07800 {
07801 struct timeval now = ast_tvnow();
07802 struct ast_tm tmnow;
07803 time_t beg_today;
07804
07805 gettimeofday(&now, NULL);
07806 ast_localtime(&now, &tmnow, tzone);
07807
07808
07809 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
07810 if (beg_today < t) {
07811
07812 res = wait_file(chan, ints, "digits/today", lang);
07813 } else if (beg_today - 86400 < t) {
07814
07815 res = wait_file(chan, ints, "digits/yesterday", lang);
07816 } else if (beg_today - 86400 * 6 < t) {
07817
07818 res = ast_say_date_with_format_vi(chan, t, ints, lang, "A", tzone);
07819 } else if (beg_today - 2628000 < t) {
07820
07821 res = ast_say_date_with_format_vi(chan, t, ints, lang, "A 'digits/day' dB", tzone);
07822 } else if (beg_today - 15768000 < t) {
07823
07824 res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB", tzone);
07825 } else {
07826
07827 res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB 'digits/year' Y", tzone);
07828 }
07829 }
07830 break;
07831 case 'q':
07832
07833
07834
07835
07836 {
07837 struct timeval now;
07838 struct ast_tm tmnow;
07839 time_t beg_today;
07840
07841 now = ast_tvnow();
07842 ast_localtime(&now, &tmnow, tzone);
07843
07844
07845 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
07846 if (beg_today < t) {
07847
07848 } else if ((beg_today - 86400) < t) {
07849
07850 res = wait_file(chan, ints, "digits/yesterday", lang);
07851 } else if (beg_today - 86400 * 6 < t) {
07852
07853 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
07854 } else if (beg_today - 2628000 < t) {
07855
07856 res = ast_say_date_with_format_vi(chan, t, ints, lang, "A 'digits/day' dB", tzone);
07857 } else if (beg_today - 15768000 < t) {
07858
07859 res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB", tzone);
07860 } else {
07861
07862 res = ast_say_date_with_format_vi(chan, t, ints, lang, "'digits/day' dB 'digits/year' Y", tzone);
07863 }
07864 }
07865 break;
07866 case 'R':
07867 res = ast_say_date_with_format_vi(chan, t, ints, lang, "HM", tzone);
07868 break;
07869 case 'S':
07870
07871 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
07872 break;
07873 case 'T':
07874 res = ast_say_date_with_format_vi(chan, t, ints, lang, "H 'hours' M 'minutes' S 'seconds'", tzone);
07875 break;
07876 case ' ':
07877 case ' ':
07878
07879 break;
07880 default:
07881
07882 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
07883 }
07884
07885 if (res) {
07886 break;
07887 }
07888 }
07889 return res;
07890 }
07891
07892
07893
07894
07895
07896
07897
07898
07899
07900
07901
07902
07903
07904
07905
07906
07907
07908
07909
07910
07911
07912
07913 static char* ast_translate_number_ka(int num, char* res, int res_len)
07914 {
07915 char buf[256];
07916 int digit = 0;
07917 int remaining = 0;
07918
07919
07920 if (num < 0) {
07921 strncat(res, "minus ", res_len - strlen(res) - 1);
07922 if ( num > INT_MIN ) {
07923 num = -num;
07924 } else {
07925 num = 0;
07926 }
07927 }
07928
07929
07930
07931 if (num <= 20 || num == 40 || num == 60 || num == 80 || num == 100) {
07932 snprintf(buf, sizeof(buf), "%d", num);
07933 strncat(res, buf, res_len - strlen(res) - 1);
07934 return res;
07935 }
07936
07937
07938 if (num < 40) {
07939 strncat(res, "20_ ", res_len - strlen(res) - 1);
07940 return ast_translate_number_ka(num - 20, res, res_len);
07941 }
07942
07943 if (num < 60) {
07944 strncat(res, "40_ ", res_len - strlen(res) - 1);
07945 return ast_translate_number_ka(num - 40, res, res_len);
07946 }
07947
07948 if (num < 80) {
07949 strncat(res, "60_ ", res_len - strlen(res) - 1);
07950 return ast_translate_number_ka(num - 60, res, res_len);
07951 }
07952
07953 if (num < 100) {
07954 strncat(res, "80_ ", res_len - strlen(res) - 1);
07955 return ast_translate_number_ka(num - 80, res, res_len);
07956 }
07957
07958
07959 if (num < 1000) {
07960 remaining = num % 100;
07961 digit = (num - remaining) / 100;
07962
07963 if (remaining == 0) {
07964 snprintf(buf, sizeof(buf), "%d", num);
07965 strncat(res, buf, res_len - strlen(res) - 1);
07966 return res;
07967 } else {
07968 snprintf(buf, sizeof(buf), "%d_ ", digit*100);
07969 strncat(res, buf, res_len - strlen(res) - 1);
07970 return ast_translate_number_ka(remaining, res, res_len);
07971 }
07972 }
07973
07974
07975 if (num == 1000) {
07976 strncat(res, "1000", res_len - strlen(res) - 1);
07977 return res;
07978 }
07979
07980
07981 if (num < 1000000) {
07982 remaining = num % 1000;
07983 digit = (num - remaining) / 1000;
07984
07985 if (remaining == 0) {
07986 ast_translate_number_ka(digit, res, res_len);
07987 strncat(res, " 1000", res_len - strlen(res) - 1);
07988 return res;
07989 }
07990
07991 if (digit == 1) {
07992 strncat(res, "1000_ ", res_len - strlen(res) - 1);
07993 return ast_translate_number_ka(remaining, res, res_len);
07994 }
07995
07996 ast_translate_number_ka(digit, res, res_len);
07997 strncat(res, " 1000_ ", res_len - strlen(res) - 1);
07998 return ast_translate_number_ka(remaining, res, res_len);
07999 }
08000
08001
08002 if (num == 1000000) {
08003 strncat(res, "1 1000000", res_len - strlen(res) - 1);
08004 return res;
08005 }
08006
08007
08008 if (num < 1000000000) {
08009 remaining = num % 1000000;
08010 digit = (num - remaining) / 1000000;
08011
08012 if (remaining == 0) {
08013 ast_translate_number_ka(digit, res, res_len);
08014 strncat(res, " 1000000", res_len - strlen(res) - 1);
08015 return res;
08016 }
08017
08018 ast_translate_number_ka(digit, res, res_len);
08019 strncat(res, " 1000000_ ", res_len - strlen(res) - 1);
08020 return ast_translate_number_ka(remaining, res, res_len);
08021 }
08022
08023
08024 if (num == 1000000000) {
08025 strncat(res, "1 1000000000", res_len - strlen(res) - 1);
08026 return res;
08027 }
08028
08029
08030 if (num > 1000000000) {
08031 remaining = num % 1000000000;
08032 digit = (num - remaining) / 1000000000;
08033
08034 if (remaining == 0) {
08035 ast_translate_number_ka(digit, res, res_len);
08036 strncat(res, " 1000000000", res_len - strlen(res) - 1);
08037 return res;
08038 }
08039
08040 ast_translate_number_ka(digit, res, res_len);
08041 strncat(res, " 1000000000_ ", res_len - strlen(res) - 1);
08042 return ast_translate_number_ka(remaining, res, res_len);
08043 }
08044
08045 return res;
08046
08047 }
08048
08049
08050
08051
08052 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)
08053 {
08054 int res = 0;
08055 char fn[512] = "";
08056 char* s = 0;
08057 const char* remaining = fn;
08058
08059 if (!num) {
08060 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
08061 }
08062
08063
08064 ast_translate_number_ka(num, fn, 512);
08065
08066
08067
08068 while (res == 0 && (s = strstr(remaining, " "))) {
08069 size_t len = s - remaining;
08070 char* new_string = ast_malloc(len + 1 + strlen("digits/"));
08071
08072 sprintf(new_string, "digits/");
08073 strncat(new_string, remaining, len);
08074
08075
08076 if (!ast_streamfile(chan, new_string, language)) {
08077 if ((audiofd > -1) && (ctrlfd > -1)) {
08078 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
08079 } else {
08080 res = ast_waitstream(chan, ints);
08081 }
08082 }
08083 ast_stopstream(chan);
08084
08085 ast_free(new_string);
08086
08087 remaining = s + 1;
08088 while (*remaining == ' ') {
08089 remaining++;
08090 }
08091 }
08092
08093
08094
08095 if (res == 0 && *remaining) {
08096
08097 char* new_string = ast_malloc(strlen(remaining) + 1 + strlen("digits/"));
08098 sprintf(new_string, "digits/%s", remaining);
08099
08100 if (!ast_streamfile(chan, new_string, language)) {
08101 if ((audiofd > -1) && (ctrlfd > -1)) {
08102 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
08103 } else {
08104 res = ast_waitstream(chan, ints);
08105 }
08106 }
08107 ast_stopstream(chan);
08108
08109 ast_free(new_string);
08110
08111 }
08112
08113
08114 return res;
08115
08116 }
08117
08118
08119
08120
08121
08122
08123
08124
08125
08126
08127
08128
08129
08130 static int ast_say_date_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
08131 {
08132 struct timeval when = { t, 0 };
08133 struct ast_tm tm;
08134 char fn[256];
08135 int res = 0;
08136 ast_localtime(&when, &tm, NULL);
08137
08138 if (!res) {
08139 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
08140 }
08141
08142 if (!res) {
08143 snprintf(fn, sizeof(fn), "digits/tslis %d", tm.tm_wday);
08144 res = ast_streamfile(chan, fn, lang);
08145 if (!res) {
08146 res = ast_waitstream(chan, ints);
08147 }
08148 }
08149
08150 if (!res) {
08151 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
08152
08153
08154
08155 }
08156
08157 if (!res) {
08158 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
08159 res = ast_streamfile(chan, fn, lang);
08160 if (!res) {
08161 res = ast_waitstream(chan, ints);
08162 }
08163 }
08164 return res;
08165
08166 }
08167
08168
08169
08170
08171
08172
08173 static int ast_say_time_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
08174 {
08175 struct timeval when = { t, 0 };
08176 struct ast_tm tm;
08177 int res = 0;
08178
08179 ast_localtime(&when, &tm, NULL);
08180
08181 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char*)NULL);
08182 if (!res) {
08183 res = ast_streamfile(chan, "digits/saati_da", lang);
08184 if (!res) {
08185 res = ast_waitstream(chan, ints);
08186 }
08187 }
08188
08189 if (tm.tm_min) {
08190 if (!res) {
08191 res = ast_say_number(chan, tm.tm_min, ints, lang, (char*)NULL);
08192
08193 if (!res) {
08194 res = ast_streamfile(chan, "digits/tsuti", lang);
08195 if (!res) {
08196 res = ast_waitstream(chan, ints);
08197 }
08198 }
08199 }
08200 }
08201 return res;
08202 }
08203
08204
08205
08206
08207 static int ast_say_datetime_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
08208 {
08209 struct timeval when = { t, 0 };
08210 struct ast_tm tm;
08211 int res = 0;
08212
08213 ast_localtime(&when, &tm, NULL);
08214 res = ast_say_date(chan, t, ints, lang);
08215 if (!res) {
08216 ast_say_time(chan, t, ints, lang);
08217 }
08218 return res;
08219
08220 }
08221
08222
08223
08224
08225
08226 static int ast_say_datetime_from_now_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
08227 {
08228 int res=0;
08229 int daydiff;
08230 struct ast_tm tm;
08231 struct ast_tm now;
08232 struct timeval when = { t, 0 }, nowt = ast_tvnow();
08233 char fn[256];
08234
08235 ast_localtime(&when, &tm, NULL);
08236 ast_localtime(&nowt, &now, NULL);
08237 daydiff = now.tm_yday - tm.tm_yday;
08238 if ((daydiff < 0) || (daydiff > 6)) {
08239
08240 if (!res) {
08241 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
08242 }
08243 if (!res) {
08244 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
08245 res = ast_streamfile(chan, fn, lang);
08246 if (!res) {
08247 res = ast_waitstream(chan, ints);
08248 }
08249 }
08250
08251 } else if (daydiff) {
08252
08253 if (!res) {
08254 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
08255 res = ast_streamfile(chan, fn, lang);
08256 if (!res) {
08257 res = ast_waitstream(chan, ints);
08258 }
08259 }
08260 }
08261 if (!res) {
08262 res = ast_say_time(chan, t, ints, lang);
08263 }
08264
08265 return res;
08266 }
08267
08268
08269
08270
08271
08272
08273
08274
08275
08276
08277
08278
08279 static const char *counted_noun_ending_en(int num)
08280 {
08281 if (num == 1 || num == -1) {
08282 return "";
08283 } else {
08284 return "s";
08285 }
08286 }
08287
08288
08289
08290
08291
08292
08293
08294
08295
08296
08297
08298 static const char *counted_noun_ending_slavic(int num)
08299 {
08300 if (num < 0) {
08301 num *= -1;
08302 }
08303 num %= 100;
08304 if (num >= 20) {
08305 num %= 10;
08306 }
08307 if (num == 1) {
08308 return "";
08309 }
08310 if (num > 0 && num < 5) {
08311 return "x1";
08312 } else {
08313 return "x2";
08314 }
08315 }
08316
08317 int ast_say_counted_noun(struct ast_channel *chan, int num, const char noun[])
08318 {
08319 char *temp;
08320 int temp_len;
08321 const char *ending;
08322 if (!strncasecmp(ast_channel_language(chan), "ru", 2)) {
08323 ending = counted_noun_ending_slavic(num);
08324 } else if (!strncasecmp(ast_channel_language(chan), "ua", 2)) {
08325 ending = counted_noun_ending_slavic(num);
08326 } else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) {
08327 ending = counted_noun_ending_slavic(num);
08328 } else {
08329 ending = counted_noun_ending_en(num);
08330 }
08331 temp = ast_alloca((temp_len = (strlen(noun) + strlen(ending) + 1)));
08332 snprintf(temp, temp_len, "%s%s", noun, ending);
08333 return ast_play_and_wait(chan, temp);
08334 }
08335
08336
08337
08338
08339
08340
08341
08342
08343 static const char *counted_adjective_ending_ru(int num, const char gender[])
08344 {
08345 if (num < 0) {
08346 num *= -1;
08347 }
08348 num %= 100;
08349 if (num >= 20) {
08350 num %= 10;
08351 }
08352 if (num == 1) {
08353 return gender ? gender : "";
08354 } else {
08355 return "x";
08356 }
08357 }
08358
08359 int ast_say_counted_adjective(struct ast_channel *chan, int num, const char adjective[], const char gender[])
08360 {
08361 char *temp;
08362 int temp_len;
08363 const char *ending;
08364 if (!strncasecmp(ast_channel_language(chan), "ru", 2)) {
08365 ending = counted_adjective_ending_ru(num, gender);
08366 } else if (!strncasecmp(ast_channel_language(chan), "ua", 2)) {
08367 ending = counted_adjective_ending_ru(num, gender);
08368 } else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) {
08369 ending = counted_adjective_ending_ru(num, gender);
08370 } else {
08371 ending = "";
08372 }
08373 temp = ast_alloca((temp_len = (strlen(adjective) + strlen(ending) + 1)));
08374 snprintf(temp, temp_len, "%s%s", adjective, ending);
08375 return ast_play_and_wait(chan, temp);
08376 }
08377
08378
08379
08380
08381
08382
08383 static void __attribute__((constructor)) __say_init(void)
08384 {
08385 ast_say_number_full = say_number_full;
08386 ast_say_enumeration_full = say_enumeration_full;
08387 ast_say_digit_str_full = say_digit_str_full;
08388 ast_say_character_str_full = say_character_str_full;
08389 ast_say_phonetic_str_full = say_phonetic_str_full;
08390 ast_say_datetime = say_datetime;
08391 ast_say_time = say_time;
08392 ast_say_date = say_date;
08393 ast_say_datetime_from_now = say_datetime_from_now;
08394 ast_say_date_with_format = say_date_with_format;
08395 }