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