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: 205222 $")
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 sndoffset=0;
03499 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
03500 sndfile[sndoffset] = format[offset];
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
03721 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)
03722 {
03723 struct timeval when = { t, 0 };
03724 struct ast_tm tm;
03725 int res=0, offset, sndoffset;
03726 char sndfile[256], nextmsg[256];
03727
03728 if (!format)
03729 format = "A dBY HMS";
03730
03731 ast_localtime(&when, &tm, tzone);
03732
03733 for (offset=0 ; format[offset] != '\0' ; offset++) {
03734 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
03735 switch (format[offset]) {
03736
03737 case '\'':
03738
03739 sndoffset=0;
03740 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
03741 sndfile[sndoffset] = format[offset];
03742 sndfile[sndoffset] = '\0';
03743 res = wait_file(chan, ints, sndfile, lang);
03744 break;
03745 case 'A':
03746 case 'a':
03747
03748 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
03749 res = wait_file(chan, ints, nextmsg, lang);
03750 break;
03751 case 'B':
03752 case 'b':
03753 case 'h':
03754
03755 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
03756 res = wait_file(chan, ints, nextmsg, lang);
03757 break;
03758 case 'm':
03759
03760 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
03761 break;
03762 case 'd':
03763 case 'e':
03764
03765 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
03766 break;
03767 case 'Y':
03768
03769 {
03770 int year = tm.tm_year + 1900;
03771 if (year > 1999) {
03772 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
03773 } else {
03774 if (year < 1100) {
03775
03776
03777 } else {
03778
03779
03780 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
03781 res = wait_file(chan, ints, nextmsg, lang);
03782 if (!res) {
03783 res = wait_file(chan, ints, "digits/hundred", lang);
03784 if (!res && year % 100 != 0) {
03785 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
03786 }
03787 }
03788 }
03789 }
03790 }
03791 break;
03792 case 'I':
03793 case 'l':
03794
03795 res = wait_file(chan, ints, "digits/oclock", lang);
03796 if (tm.tm_hour == 0)
03797 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
03798 else if (tm.tm_hour > 12)
03799 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
03800 else
03801 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
03802 if (!res) {
03803 res = wait_file(chan, ints, nextmsg, lang);
03804 }
03805 break;
03806 case 'H':
03807
03808 if (tm.tm_hour < 10 && tm.tm_hour > 0) {
03809 res = wait_file(chan, ints, "digits/0", lang);
03810 }
03811
03812 case 'k':
03813
03814 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
03815 break;
03816 case 'M':
03817
03818 if (tm.tm_min > 0 || format[offset+ 1 ] == 'S' ) {
03819 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
03820 }
03821 if ( !res && format[offset + 1] == 'S' ) {
03822 if (tm.tm_min == 1) {
03823 res = wait_file(chan, ints, "digits/minute", lang);
03824 } else {
03825 res = wait_file(chan, ints, "digits/minutes", lang);
03826 }
03827 }
03828 break;
03829 case 'P':
03830 case 'p':
03831
03832 if (tm.tm_hour > 11)
03833 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
03834 else
03835 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
03836 res = wait_file(chan, ints, nextmsg, lang);
03837 break;
03838 case 'Q':
03839
03840
03841
03842
03843 {
03844 struct timeval now = ast_tvnow();
03845 struct ast_tm tmnow;
03846 time_t beg_today;
03847
03848 ast_localtime(&now, &tmnow, tzone);
03849
03850
03851 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03852 if (beg_today < t) {
03853
03854 res = wait_file(chan, ints, "digits/today", lang);
03855 } else if (beg_today - 86400 < t) {
03856
03857 res = wait_file(chan, ints, "digits/yesterday", lang);
03858 } else {
03859 res = ast_say_date_with_format_da(chan, t, ints, lang, "AdBY", tzone);
03860 }
03861 }
03862 break;
03863 case 'q':
03864
03865
03866
03867
03868 {
03869 struct timeval now = ast_tvnow();
03870 struct ast_tm tmnow;
03871 time_t beg_today;
03872
03873 ast_localtime(&now, &tmnow, tzone);
03874
03875
03876 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03877 if (beg_today < t) {
03878
03879 } else if ((beg_today - 86400) < t) {
03880
03881 res = wait_file(chan, ints, "digits/yesterday", lang);
03882 } else if (beg_today - 86400 * 6 < t) {
03883
03884 res = ast_say_date_with_format_da(chan, t, ints, lang, "A", tzone);
03885 } else {
03886 res = ast_say_date_with_format_da(chan, t, ints, lang, "AdBY", tzone);
03887 }
03888 }
03889 break;
03890 case 'R':
03891 res = ast_say_date_with_format_da(chan, t, ints, lang, "HM", tzone);
03892 break;
03893 case 'S':
03894
03895 res = wait_file(chan, ints, "digits/and", lang);
03896 if (!res) {
03897 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
03898 if (!res) {
03899 res = wait_file(chan, ints, "digits/seconds", lang);
03900 }
03901 }
03902 break;
03903 case 'T':
03904 res = ast_say_date_with_format_da(chan, t, ints, lang, "HMS", tzone);
03905 break;
03906 case ' ':
03907 case ' ':
03908
03909 break;
03910 default:
03911
03912 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
03913 }
03914
03915 if (res) {
03916 break;
03917 }
03918 }
03919 return res;
03920 }
03921
03922
03923 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)
03924 {
03925 struct timeval when = { t, 0 };
03926 struct ast_tm tm;
03927 int res=0, offset, sndoffset;
03928 char sndfile[256], nextmsg[256];
03929
03930 if (!format)
03931 format = "A dBY HMS";
03932
03933 ast_localtime(&when, &tm, tzone);
03934
03935 for (offset=0 ; format[offset] != '\0' ; offset++) {
03936 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
03937 switch (format[offset]) {
03938
03939 case '\'':
03940
03941 sndoffset=0;
03942 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
03943 sndfile[sndoffset] = format[offset];
03944 sndfile[sndoffset] = '\0';
03945 res = wait_file(chan, ints, sndfile, lang);
03946 break;
03947 case 'A':
03948 case 'a':
03949
03950 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
03951 res = wait_file(chan, ints, nextmsg, lang);
03952 break;
03953 case 'B':
03954 case 'b':
03955 case 'h':
03956
03957 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
03958 res = wait_file(chan, ints, nextmsg, lang);
03959 break;
03960 case 'm':
03961
03962 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
03963 break;
03964 case 'd':
03965 case 'e':
03966
03967 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
03968 break;
03969 case 'Y':
03970
03971 {
03972 int year = tm.tm_year + 1900;
03973 if (year > 1999) {
03974 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
03975 } else {
03976 if (year < 1100) {
03977
03978
03979 } else {
03980
03981
03982 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
03983 res = wait_file(chan, ints, nextmsg, lang);
03984 if (!res) {
03985 res = wait_file(chan, ints, "digits/hundred", lang);
03986 if (!res && year % 100 != 0) {
03987 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
03988 }
03989 }
03990 }
03991 }
03992 }
03993 break;
03994 case 'I':
03995 case 'l':
03996
03997 if (tm.tm_hour == 0)
03998 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
03999 else if (tm.tm_hour > 12)
04000 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04001 else
04002 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04003 res = wait_file(chan, ints, nextmsg, lang);
04004 if (!res) {
04005 res = wait_file(chan, ints, "digits/oclock", lang);
04006 }
04007 break;
04008 case 'H':
04009 case 'k':
04010
04011 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
04012 if (!res) {
04013 res = wait_file(chan, ints, "digits/oclock", lang);
04014 }
04015 break;
04016 case 'M':
04017
04018 if (tm.tm_min > 0 || format[offset+ 1 ] == 'S' ) {
04019 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
04020 }
04021 if ( !res && format[offset + 1] == 'S' ) {
04022 if (tm.tm_min == 1) {
04023 res = wait_file(chan, ints, "digits/minute", lang);
04024 } else {
04025 res = wait_file(chan, ints, "digits/minutes", lang);
04026 }
04027 }
04028 break;
04029 case 'P':
04030 case 'p':
04031
04032 if (tm.tm_hour > 11)
04033 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
04034 else
04035 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
04036 res = wait_file(chan, ints, nextmsg, lang);
04037 break;
04038 case 'Q':
04039
04040
04041
04042
04043 {
04044 struct timeval now = ast_tvnow();
04045 struct ast_tm tmnow;
04046 time_t beg_today;
04047
04048 ast_localtime(&now, &tmnow, tzone);
04049
04050
04051 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04052 if (beg_today < t) {
04053
04054 res = wait_file(chan, ints, "digits/today", lang);
04055 } else if (beg_today - 86400 < t) {
04056
04057 res = wait_file(chan, ints, "digits/yesterday", lang);
04058 } else {
04059 res = ast_say_date_with_format_de(chan, t, ints, lang, "AdBY", tzone);
04060 }
04061 }
04062 break;
04063 case 'q':
04064
04065
04066
04067
04068 {
04069 struct timeval now = ast_tvnow();
04070 struct ast_tm tmnow;
04071 time_t beg_today;
04072
04073 ast_localtime(&now, &tmnow, tzone);
04074
04075
04076 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04077 if (beg_today < t) {
04078
04079 } else if ((beg_today - 86400) < t) {
04080
04081 res = wait_file(chan, ints, "digits/yesterday", lang);
04082 } else if (beg_today - 86400 * 6 < t) {
04083
04084 res = ast_say_date_with_format_de(chan, t, ints, lang, "A", tzone);
04085 } else {
04086 res = ast_say_date_with_format_de(chan, t, ints, lang, "AdBY", tzone);
04087 }
04088 }
04089 break;
04090 case 'R':
04091 res = ast_say_date_with_format_de(chan, t, ints, lang, "HM", tzone);
04092 break;
04093 case 'S':
04094
04095 res = wait_file(chan, ints, "digits/and", lang);
04096 if (!res) {
04097 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
04098 if (!res) {
04099 res = wait_file(chan, ints, "digits/seconds", lang);
04100 }
04101 }
04102 break;
04103 case 'T':
04104 res = ast_say_date_with_format_de(chan, t, ints, lang, "HMS", tzone);
04105 break;
04106 case ' ':
04107 case ' ':
04108
04109 break;
04110 default:
04111
04112 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04113 }
04114
04115 if (res) {
04116 break;
04117 }
04118 }
04119 return res;
04120 }
04121
04122
04123 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)
04124 {
04125 struct timeval when = { t, 0 };
04126 struct ast_tm tm;
04127 int res=0, offset, sndoffset;
04128 char sndfile[256], nextmsg[256];
04129
04130 if (format == NULL)
04131 format = "a 'digits/tee' e 'digits/duan' hY I 'digits/naliga' M 'digits/natee'";
04132
04133 ast_localtime(&when, &tm, tzone);
04134
04135 for (offset=0 ; format[offset] != '\0' ; offset++) {
04136 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04137 switch (format[offset]) {
04138
04139 case '\'':
04140
04141 sndoffset=0;
04142 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
04143 sndfile[sndoffset] = format[offset];
04144 sndfile[sndoffset] = '\0';
04145 res = wait_file(chan, ints, sndfile, lang);
04146 break;
04147 case 'A':
04148 case 'a':
04149
04150 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04151 res = wait_file(chan, ints, nextmsg, lang);
04152 break;
04153 case 'B':
04154 case 'b':
04155 case 'h':
04156
04157 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04158 res = wait_file(chan, ints, nextmsg, lang);
04159 break;
04160 case 'm':
04161
04162 res = ast_say_number(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
04163 break;
04164 case 'd':
04165 case 'e':
04166
04167 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
04168 break;
04169 case 'Y':
04170
04171 res = ast_say_number(chan, tm.tm_year + 1900 + 543, ints, lang, (char *) NULL);
04172 break;
04173 case 'I':
04174 case 'l':
04175
04176 if (tm.tm_hour == 0)
04177 ast_copy_string(nextmsg, "digits/24", sizeof(nextmsg));
04178 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04179 res = wait_file(chan, ints, nextmsg, lang);
04180 break;
04181 case 'H':
04182 case 'k':
04183
04184 if (tm.tm_hour == 0)
04185 ast_copy_string(nextmsg, "digits/24", sizeof(nextmsg));
04186 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04187 res = wait_file(chan, ints, nextmsg, lang);
04188 break;
04189 case 'M':
04190 case 'N':
04191 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04192 break;
04193 case 'P':
04194 case 'p':
04195 break;
04196 case 'Q':
04197
04198
04199
04200
04201 {
04202 struct timeval now = ast_tvnow();
04203 struct ast_tm tmnow;
04204 time_t beg_today;
04205
04206 ast_localtime(&now, &tmnow, tzone);
04207
04208
04209 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04210 if (beg_today < t) {
04211
04212 res = wait_file(chan, ints, "digits/today", lang);
04213 } else if (beg_today - 86400 < t) {
04214
04215 res = wait_file(chan, ints, "digits/yesterday", lang);
04216 } else if (beg_today - 86400 * 6 < t) {
04217
04218 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
04219 } else if (beg_today - 2628000 < t) {
04220
04221 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
04222 } else if (beg_today - 15768000 < t) {
04223
04224 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
04225 } else {
04226
04227 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
04228 }
04229 }
04230 break;
04231 case 'q':
04232
04233
04234
04235
04236 {
04237 struct timeval now = ast_tvnow();
04238 struct ast_tm tmnow;
04239 time_t beg_today;
04240
04241 ast_localtime(&now, &tmnow, tzone);
04242
04243
04244 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04245 if (beg_today < t) {
04246
04247 } else if ((beg_today - 86400) < t) {
04248
04249 res = wait_file(chan, ints, "digits/yesterday", lang);
04250 } else if (beg_today - 86400 * 6 < t) {
04251
04252 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
04253 } else if (beg_today - 2628000 < t) {
04254
04255 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
04256 } else if (beg_today - 15768000 < t) {
04257
04258 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
04259 } else {
04260
04261 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
04262 }
04263 }
04264 break;
04265 case 'R':
04266 res = ast_say_date_with_format_en(chan, t, ints, lang, "HM", tzone);
04267 break;
04268 case 'S':
04269 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
04270 break;
04271 case 'T':
04272 res = ast_say_date_with_format_en(chan, t, ints, lang, "HMS", tzone);
04273 break;
04274 case ' ':
04275 case ' ':
04276
04277 break;
04278 default:
04279
04280 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04281 }
04282
04283 if (res) {
04284 break;
04285 }
04286 }
04287 return res;
04288 }
04289
04290
04291
04292
04293
04294
04295
04296
04297
04298
04299
04300
04301
04302
04303
04304
04305
04306
04307
04308
04309
04310 #define IL_DATE_STR "AdBY"
04311 #define IL_TIME_STR "HM"
04312 #define IL_DATE_STR_FULL IL_DATE_STR " 'digits/at' " IL_TIME_STR
04313 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)
04314 {
04315
04316
04317
04318 struct timeval when = { t, 0 };
04319 struct ast_tm tm;
04320 int res = 0, offset, sndoffset;
04321 char sndfile[256], nextmsg[256];
04322
04323 if (!format) {
04324 format = IL_DATE_STR_FULL;
04325 }
04326
04327 ast_localtime(&when, &tm, tzone);
04328
04329 for (offset = 0; format[offset] != '\0'; offset++) {
04330 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04331 switch (format[offset]) {
04332
04333 case '\'':
04334
04335 sndoffset=0;
04336 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
04337 sndfile[sndoffset] = format[offset];
04338 sndfile[sndoffset] = '\0';
04339 res = wait_file(chan, ints, sndfile, lang);
04340 break;
04341 case 'A':
04342 case 'a':
04343
04344 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04345 res = wait_file(chan, ints, nextmsg, lang);
04346 break;
04347 case 'B':
04348 case 'b':
04349 case 'h':
04350
04351 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04352 res = wait_file(chan, ints, nextmsg, lang);
04353 break;
04354 case 'd':
04355 case 'e':
04356
04357
04358
04359
04360
04361
04362
04363 res = ast_say_number_full_he(chan, tm.tm_mday, ints, lang, "m", -1, -1);
04364 break;
04365 case 'Y':
04366 res = ast_say_number_full_he(chan, tm.tm_year + 1900, ints, lang, "f", -1, -1);
04367 break;
04368 case 'I':
04369 case 'l':
04370 case 'H':
04371 case 'k':
04372 res = ast_say_number_full_he(chan, tm.tm_hour, ints, lang, "f", -1, -1);
04373 break;
04374 case 'M':
04375 if (tm.tm_min >= 0 && tm.tm_min <= 9)
04376 res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
04377 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
04378 break;
04379 case 'P':
04380 case 'p':
04381
04382 break;
04383 case 'Q':
04384
04385 case 'q':
04386
04387
04388
04389
04390
04391 {
04392 struct timeval now = ast_tvnow();
04393 struct ast_tm tmnow;
04394 time_t beg_today;
04395 char todo = format[offset];
04396
04397 ast_localtime(&now, &tmnow, tzone);
04398
04399
04400 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04401 if (beg_today < t) {
04402
04403 if (todo == 'Q') {
04404 res = wait_file(chan, ints, "digits/today", lang);
04405 }
04406 } else if (beg_today - 86400 < t) {
04407
04408 res = wait_file(chan, ints, "digits/yesterday", lang);
04409 } else if ((todo != 'Q') && (beg_today - 86400 * 6 < t)) {
04410
04411 res = ast_say_date_with_format_he(chan, t, ints, lang, "A", tzone);
04412 } else {
04413 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
04414 }
04415 }
04416 break;
04417 case 'R':
04418 res = ast_say_date_with_format_he(chan, t, ints, lang, "HM", tzone);
04419 break;
04420 case 'S':
04421 res = ast_say_number_full_he(chan, tm.tm_sec,
04422 ints, lang, "f", -1, -1
04423 );
04424 break;
04425 case 'T':
04426 res = ast_say_date_with_format_he(chan, t, ints, lang, "HMS", tzone);
04427 break;
04428
04429
04430 case 'c':
04431 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR_FULL, tzone);
04432 break;
04433 case 'x':
04434 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
04435 break;
04436 case 'X':
04437 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_TIME_STR, tzone);
04438 break;
04439 case ' ':
04440 case ' ':
04441
04442 break;
04443 default:
04444
04445 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04446 }
04447
04448 if (res) {
04449 break;
04450 }
04451 }
04452 return res;
04453 }
04454
04455
04456
04457 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)
04458 {
04459 struct timeval when = { t, 0 };
04460 struct ast_tm tm;
04461 int res=0, offset, sndoffset;
04462 char sndfile[256], nextmsg[256];
04463
04464 if (format == NULL)
04465 format = "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y 'digits/at' IMp";
04466
04467 ast_localtime(&when, &tm, tzone);
04468
04469 for (offset=0 ; format[offset] != '\0' ; offset++) {
04470 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04471 switch (format[offset]) {
04472
04473 case '\'':
04474
04475 sndoffset=0;
04476 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
04477 sndfile[sndoffset] = format[offset];
04478 sndfile[sndoffset] = '\0';
04479 snprintf(nextmsg, sizeof(nextmsg), "%s", sndfile);
04480 res = wait_file(chan, ints, nextmsg, lang);
04481 break;
04482 case 'A':
04483 case 'a':
04484
04485 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04486 res = wait_file(chan, ints, nextmsg, lang);
04487 break;
04488 case 'B':
04489 case 'b':
04490 case 'h':
04491
04492 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04493 res = wait_file(chan, ints, nextmsg, lang);
04494 break;
04495 case 'm':
04496
04497 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04498 res = wait_file(chan, ints, nextmsg, lang);
04499 break;
04500 case 'd':
04501 case 'e':
04502
04503 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
04504 break;
04505 case 'Y':
04506
04507 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
04508 break;
04509 case 'I':
04510 case 'l':
04511
04512 if (tm.tm_hour == 0)
04513 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
04514 else if (tm.tm_hour > 12)
04515 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04516 else
04517 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04518 res = wait_file(chan, ints, nextmsg, lang);
04519 break;
04520 case 'H':
04521 case 'k':
04522
04523 res = ast_say_number(chan, tm.tm_hour, ints, lang, NULL);
04524 break;
04525 case 'M':
04526
04527 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04528 break;
04529 case 'P':
04530 case 'p':
04531
04532 if (tm.tm_hour > 18)
04533 res = wait_file(chan, ints, "digits/p-m", lang);
04534 else if (tm.tm_hour > 12)
04535 res = wait_file(chan, ints, "digits/afternoon", lang);
04536 else if (tm.tm_hour)
04537 res = wait_file(chan, ints, "digits/a-m", lang);
04538 break;
04539 case 'Q':
04540
04541
04542
04543
04544 {
04545 struct timeval now = ast_tvnow();
04546 struct ast_tm tmnow;
04547 time_t beg_today;
04548
04549 ast_localtime(&now, &tmnow, tzone);
04550
04551
04552 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04553 if (beg_today < t) {
04554
04555 res = wait_file(chan, ints, "digits/today", lang);
04556 } else if (beg_today - 86400 < t) {
04557
04558 res = wait_file(chan, ints, "digits/yesterday", lang);
04559 } else {
04560 res = ast_say_date_with_format_es(chan, t, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", tzone);
04561 }
04562 }
04563 break;
04564 case 'q':
04565
04566
04567
04568
04569 {
04570 struct timeval now = ast_tvnow();
04571 struct ast_tm tmnow;
04572 time_t beg_today;
04573
04574 ast_localtime(&now, &tmnow, tzone);
04575
04576
04577 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04578 if (beg_today < t) {
04579
04580 res = wait_file(chan, ints, "digits/today", lang);
04581 } else if ((beg_today - 86400) < t) {
04582
04583 res = wait_file(chan, ints, "digits/yesterday", lang);
04584 } else if (beg_today - 86400 * 6 < t) {
04585
04586 res = ast_say_date_with_format_es(chan, t, ints, lang, "A", tzone);
04587 } else {
04588 res = ast_say_date_with_format_es(chan, t, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", tzone);
04589 }
04590 }
04591 break;
04592 case 'R':
04593 res = ast_say_date_with_format_es(chan, t, ints, lang, "H 'digits/y' M", tzone);
04594 break;
04595 case 'S':
04596
04597 if (tm.tm_sec == 0) {
04598 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
04599 res = wait_file(chan, ints, nextmsg, lang);
04600 } else if (tm.tm_sec < 10) {
04601 res = wait_file(chan, ints, "digits/oh", lang);
04602 if (!res) {
04603 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
04604 res = wait_file(chan, ints, nextmsg, lang);
04605 }
04606 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
04607 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
04608 res = wait_file(chan, ints, nextmsg, lang);
04609 } else {
04610 int ten, one;
04611 ten = (tm.tm_sec / 10) * 10;
04612 one = (tm.tm_sec % 10);
04613 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
04614 res = wait_file(chan, ints, nextmsg, lang);
04615 if (!res) {
04616
04617 if (one != 0) {
04618 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
04619 res = wait_file(chan, ints, nextmsg, lang);
04620 }
04621 }
04622 }
04623 break;
04624 case 'T':
04625 res = ast_say_date_with_format_es(chan, t, ints, lang, "HMS", tzone);
04626 break;
04627 case ' ':
04628 case ' ':
04629
04630 break;
04631 default:
04632
04633 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04634 }
04635
04636 if (res) {
04637 break;
04638 }
04639 }
04640 return res;
04641 }
04642
04643
04644
04645
04646 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)
04647 {
04648 struct timeval when = { t, 0 };
04649 struct ast_tm tm;
04650 int res=0, offset, sndoffset;
04651 char sndfile[256], nextmsg[256];
04652
04653 if (format == NULL)
04654 format = "AdBY 'digits/at' IMp";
04655
04656 ast_localtime(&when, &tm, tzone);
04657
04658 for (offset=0 ; format[offset] != '\0' ; offset++) {
04659 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04660 switch (format[offset]) {
04661
04662 case '\'':
04663
04664 sndoffset=0;
04665 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
04666 sndfile[sndoffset] = format[offset];
04667 sndfile[sndoffset] = '\0';
04668 res = wait_file(chan, ints, sndfile, lang);
04669 break;
04670 case 'A':
04671 case 'a':
04672
04673 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04674 res = wait_file(chan, ints, nextmsg, lang);
04675 break;
04676 case 'B':
04677 case 'b':
04678 case 'h':
04679
04680 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04681 res = wait_file(chan, ints, nextmsg, lang);
04682 break;
04683 case 'm':
04684
04685 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04686 res = wait_file(chan, ints, nextmsg, lang);
04687 break;
04688 case 'd':
04689 case 'e':
04690
04691 if (tm.tm_mday == 1) {
04692 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
04693 res = wait_file(chan, ints, nextmsg, lang);
04694 } else {
04695 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
04696 }
04697 break;
04698 case 'Y':
04699
04700 if (tm.tm_year > 99) {
04701 res = wait_file(chan, ints, "digits/2", lang);
04702 if (!res) {
04703 res = wait_file(chan, ints, "digits/thousand", lang);
04704 }
04705 if (tm.tm_year > 100) {
04706 if (!res) {
04707 res = ast_say_number(chan, tm.tm_year - 100, ints, lang, (char * ) NULL);
04708 }
04709 }
04710 } else {
04711 if (tm.tm_year < 1) {
04712
04713
04714 } else {
04715 res = wait_file(chan, ints, "digits/thousand", lang);
04716 if (!res) {
04717 wait_file(chan, ints, "digits/9", lang);
04718 wait_file(chan, ints, "digits/hundred", lang);
04719 res = ast_say_number(chan, tm.tm_year, ints, lang, (char * ) NULL);
04720 }
04721 }
04722 }
04723 break;
04724 case 'I':
04725 case 'l':
04726
04727 if (tm.tm_hour == 0)
04728 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
04729 else if (tm.tm_hour > 12)
04730 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04731 else
04732 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04733 res = wait_file(chan, ints, nextmsg, lang);
04734 if (!res)
04735 res = wait_file(chan, ints, "digits/oclock", lang);
04736 break;
04737 case 'H':
04738 case 'k':
04739
04740 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char * ) NULL);
04741 if (!res)
04742 res = wait_file(chan, ints, "digits/oclock", lang);
04743 break;
04744 case 'M':
04745
04746 if (tm.tm_min == 0) {
04747 break;
04748 }
04749 res = ast_say_number(chan, tm.tm_min, ints, lang, (char * ) NULL);
04750 break;
04751 case 'P':
04752 case 'p':
04753
04754 if (tm.tm_hour > 11)
04755 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
04756 else
04757 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
04758 res = wait_file(chan, ints, nextmsg, lang);
04759 break;
04760 case 'Q':
04761
04762
04763
04764
04765 {
04766 struct timeval now = ast_tvnow();
04767 struct ast_tm tmnow;
04768 time_t beg_today;
04769
04770 ast_localtime(&now, &tmnow, tzone);
04771
04772
04773 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04774 if (beg_today < t) {
04775
04776 res = wait_file(chan, ints, "digits/today", lang);
04777 } else if (beg_today - 86400 < t) {
04778
04779 res = wait_file(chan, ints, "digits/yesterday", lang);
04780 } else {
04781 res = ast_say_date_with_format_fr(chan, t, ints, lang, "AdBY", tzone);
04782 }
04783 }
04784 break;
04785 case 'q':
04786
04787
04788
04789
04790 {
04791 struct timeval now = ast_tvnow();
04792 struct ast_tm tmnow;
04793 time_t beg_today;
04794
04795 ast_localtime(&now, &tmnow, tzone);
04796
04797
04798 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04799 if (beg_today < t) {
04800
04801 } else if ((beg_today - 86400) < t) {
04802
04803 res = wait_file(chan, ints, "digits/yesterday", lang);
04804 } else if (beg_today - 86400 * 6 < t) {
04805
04806 res = ast_say_date_with_format_fr(chan, t, ints, lang, "A", tzone);
04807 } else {
04808 res = ast_say_date_with_format_fr(chan, t, ints, lang, "AdBY", tzone);
04809 }
04810 }
04811 break;
04812 case 'R':
04813 res = ast_say_date_with_format_fr(chan, t, ints, lang, "HM", tzone);
04814 break;
04815 case 'S':
04816
04817 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char * ) NULL);
04818 if (!res) {
04819 res = wait_file(chan, ints, "digits/second", lang);
04820 }
04821 break;
04822 case 'T':
04823 res = ast_say_date_with_format_fr(chan, t, ints, lang, "HMS", tzone);
04824 break;
04825 case ' ':
04826 case ' ':
04827
04828 break;
04829 default:
04830
04831 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04832 }
04833
04834 if (res) {
04835 break;
04836 }
04837 }
04838 return res;
04839 }
04840
04841 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)
04842 {
04843 struct timeval when = { t, 0 };
04844 struct ast_tm tm;
04845 int res=0, offset, sndoffset;
04846 char sndfile[256], nextmsg[256];
04847
04848 if (format == NULL)
04849 format = "AdB 'digits/at' IMp";
04850
04851 ast_localtime(&when, &tm, tzone);
04852
04853 for (offset=0 ; format[offset] != '\0' ; offset++) {
04854 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04855 switch (format[offset]) {
04856
04857 case '\'':
04858
04859 sndoffset=0;
04860 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
04861 sndfile[sndoffset] = format[offset];
04862 sndfile[sndoffset] = '\0';
04863 res = wait_file(chan, ints, sndfile, lang);
04864 break;
04865 case 'A':
04866 case 'a':
04867
04868 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04869 res = wait_file(chan, ints, nextmsg, lang);
04870 break;
04871 case 'B':
04872 case 'b':
04873 case 'h':
04874
04875 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04876 res = wait_file(chan, ints, nextmsg, lang);
04877 break;
04878 case 'm':
04879
04880 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04881 res = wait_file(chan, ints, nextmsg, lang);
04882 break;
04883 case 'd':
04884 case 'e':
04885
04886 if (tm.tm_mday == 1) {
04887 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
04888 res = wait_file(chan, ints, nextmsg, lang);
04889 } else {
04890 if (!res) {
04891 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
04892 }
04893 }
04894 break;
04895 case 'Y':
04896
04897 if (tm.tm_year > 99) {
04898 res = wait_file(chan, ints, "digits/ore-2000", lang);
04899 if (tm.tm_year > 100) {
04900 if (!res) {
04901
04902 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
04903 res = wait_file(chan, ints, nextmsg, lang);
04904 }
04905 }
04906 } else {
04907 if (tm.tm_year < 1) {
04908
04909
04910 } else {
04911 res = wait_file(chan, ints, "digits/ore-1900", lang);
04912 if ((!res) && (tm.tm_year != 0)) {
04913 if (tm.tm_year <= 21) {
04914
04915 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
04916 res = wait_file(chan, ints, nextmsg, lang);
04917 } else {
04918
04919 int ten, one;
04920 ten = tm.tm_year / 10;
04921 one = tm.tm_year % 10;
04922 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten * 10);
04923 res = wait_file(chan, ints, nextmsg, lang);
04924 if (!res) {
04925 if (one != 0) {
04926 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
04927 res = wait_file(chan, ints, nextmsg, lang);
04928 }
04929 }
04930 }
04931 }
04932 }
04933 }
04934 break;
04935 case 'I':
04936 case 'l':
04937
04938 if (tm.tm_hour == 0)
04939 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
04940 else if (tm.tm_hour > 12)
04941 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04942 else
04943 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04944 res = wait_file(chan, ints, nextmsg, lang);
04945 break;
04946 case 'H':
04947 case 'k':
04948
04949 if (tm.tm_hour == 0) {
04950 res = wait_file(chan, ints, "digits/ore-mezzanotte", lang);
04951 } else if (tm.tm_hour == 1) {
04952 res = wait_file(chan, ints, "digits/ore-una", lang);
04953 } else {
04954 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
04955 }
04956 break;
04957 case 'M':
04958
04959 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04960 break;
04961 case 'P':
04962 case 'p':
04963
04964 if (tm.tm_hour > 11)
04965 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
04966 else
04967 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
04968 res = wait_file(chan, ints, nextmsg, lang);
04969 break;
04970 case 'Q':
04971
04972
04973
04974
04975 {
04976 struct timeval now = ast_tvnow();
04977 struct ast_tm tmnow;
04978 time_t beg_today;
04979
04980 ast_localtime(&now, &tmnow, tzone);
04981
04982
04983 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04984 if (beg_today < t) {
04985
04986 res = wait_file(chan, ints, "digits/today", lang);
04987 } else if (beg_today - 86400 < t) {
04988
04989 res = wait_file(chan, ints, "digits/yesterday", lang);
04990 } else {
04991 res = ast_say_date_with_format_it(chan, t, ints, lang, "AdB", tzone);
04992 }
04993 }
04994 break;
04995 case 'q':
04996
04997 {
04998 struct timeval now = ast_tvnow();
04999 struct ast_tm tmnow;
05000 time_t beg_today;
05001
05002 ast_localtime(&now, &tmnow, tzone);
05003
05004
05005 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05006 if (beg_today < t) {
05007
05008 } else if ((beg_today - 86400) < t) {
05009
05010 res = wait_file(chan, ints, "digits/yesterday", lang);
05011 } else if (beg_today - 86400 * 6 < t) {
05012
05013 res = ast_say_date_with_format_it(chan, t, ints, lang, "A", tzone);
05014 } else {
05015 res = ast_say_date_with_format_it(chan, t, ints, lang, "AdB", tzone);
05016 }
05017 }
05018 break;
05019 case 'R':
05020 res = ast_say_date_with_format_it(chan, t, ints, lang, "HM", tzone);
05021 break;
05022 case 'S':
05023
05024 if (tm.tm_sec == 0) {
05025 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05026 res = wait_file(chan, ints, nextmsg, lang);
05027 } else if (tm.tm_sec < 10) {
05028 res = wait_file(chan, ints, "digits/oh", lang);
05029 if (!res) {
05030 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05031 res = wait_file(chan, ints, nextmsg, lang);
05032 }
05033 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
05034 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05035 res = wait_file(chan, ints, nextmsg, lang);
05036 } else {
05037 int ten, one;
05038 ten = (tm.tm_sec / 10) * 10;
05039 one = (tm.tm_sec % 10);
05040 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
05041 res = wait_file(chan, ints, nextmsg, lang);
05042 if (!res) {
05043
05044 if (one != 0) {
05045 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
05046 res = wait_file(chan, ints, nextmsg, lang);
05047 }
05048 }
05049 }
05050 break;
05051 case 'T':
05052 res = ast_say_date_with_format_it(chan, t, ints, lang, "HMS", tzone);
05053 break;
05054 case ' ':
05055 case ' ':
05056
05057 break;
05058 default:
05059
05060 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05061 }
05062
05063 if (res) {
05064 break;
05065 }
05066 }
05067 return res;
05068 }
05069
05070
05071 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)
05072 {
05073 struct timeval when = { t, 0 };
05074 struct ast_tm tm;
05075 int res=0, offset, sndoffset;
05076 char sndfile[256], nextmsg[256];
05077
05078 if (format == NULL)
05079 format = "ABdY 'digits/at' IMp";
05080
05081 ast_localtime(&when, &tm, tzone);
05082
05083 for (offset=0 ; format[offset] != '\0' ; offset++) {
05084 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05085 switch (format[offset]) {
05086
05087 case '\'':
05088
05089 sndoffset=0;
05090 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
05091 sndfile[sndoffset] = format[offset];
05092 sndfile[sndoffset] = '\0';
05093 res = wait_file(chan, ints, sndfile, lang);
05094 break;
05095 case 'A':
05096 case 'a':
05097
05098 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05099 res = wait_file(chan, ints, nextmsg, lang);
05100 break;
05101 case 'B':
05102 case 'b':
05103 case 'h':
05104
05105 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05106 res = wait_file(chan, ints, nextmsg, lang);
05107 break;
05108 case 'm':
05109
05110 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
05111 res = wait_file(chan, ints, nextmsg, lang);
05112 break;
05113 case 'd':
05114 case 'e':
05115
05116 res = ast_say_number(chan, tm.tm_mday, ints, lang, NULL);
05117 break;
05118 case 'Y':
05119
05120 if (tm.tm_year > 99) {
05121 res = wait_file(chan, ints, "digits/2", lang);
05122 if (!res) {
05123 res = wait_file(chan, ints, "digits/thousand", lang);
05124 }
05125 if (tm.tm_year > 100) {
05126 if (!res) {
05127
05128 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
05129 res = wait_file(chan, ints, nextmsg, lang);
05130 }
05131 }
05132 } else {
05133 if (tm.tm_year < 1) {
05134
05135
05136 } else {
05137 res = wait_file(chan, ints, "digits/19", lang);
05138 if (!res) {
05139 if (tm.tm_year <= 9) {
05140
05141 res = wait_file(chan, ints, "digits/oh", lang);
05142 if (!res) {
05143 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
05144 res = wait_file(chan, ints, nextmsg, lang);
05145 }
05146 } else if (tm.tm_year <= 20) {
05147
05148 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
05149 res = wait_file(chan, ints, nextmsg, lang);
05150 } else {
05151
05152 int ten, one;
05153 ten = tm.tm_year / 10;
05154 one = tm.tm_year % 10;
05155 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten * 10);
05156 res = wait_file(chan, ints, nextmsg, lang);
05157 if (!res) {
05158 if (one != 0) {
05159 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
05160 res = wait_file(chan, ints, nextmsg, lang);
05161 }
05162 }
05163 }
05164 }
05165 }
05166 }
05167 break;
05168 case 'I':
05169 case 'l':
05170
05171 if (tm.tm_hour == 0)
05172 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
05173 else if (tm.tm_hour > 12)
05174 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
05175 else
05176 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
05177 res = wait_file(chan, ints, nextmsg, lang);
05178 break;
05179 case 'H':
05180 case 'k':
05181
05182 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
05183 if (!res) {
05184 res = wait_file(chan, ints, "digits/nl-uur", lang);
05185 }
05186 break;
05187 case 'M':
05188
05189 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05190 break;
05191 case 'P':
05192 case 'p':
05193
05194 if (tm.tm_hour > 11)
05195 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
05196 else
05197 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
05198 res = wait_file(chan, ints, nextmsg, lang);
05199 break;
05200 case 'Q':
05201
05202
05203
05204
05205 {
05206 struct timeval now = ast_tvnow();
05207 struct ast_tm tmnow;
05208 time_t beg_today;
05209
05210 ast_localtime(&now, &tmnow, tzone);
05211
05212
05213 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05214 if (beg_today < t) {
05215
05216 res = wait_file(chan, ints, "digits/today", lang);
05217 } else if (beg_today - 86400 < t) {
05218
05219 res = wait_file(chan, ints, "digits/yesterday", lang);
05220 } else {
05221 res = ast_say_date_with_format_nl(chan, t, ints, lang, "ABdY", tzone);
05222 }
05223 }
05224 break;
05225 case 'q':
05226
05227 {
05228 struct timeval now = ast_tvnow();
05229 struct ast_tm tmnow;
05230 time_t beg_today;
05231
05232 ast_localtime(&now, &tmnow, tzone);
05233
05234
05235 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05236 if (beg_today < t) {
05237
05238 } else if ((beg_today - 86400) < t) {
05239
05240 res = wait_file(chan, ints, "digits/yesterday", lang);
05241 } else if (beg_today - 86400 * 6 < t) {
05242
05243 res = ast_say_date_with_format_nl(chan, t, ints, lang, "A", tzone);
05244 } else {
05245 res = ast_say_date_with_format_nl(chan, t, ints, lang, "ABdY", tzone);
05246 }
05247 }
05248 break;
05249 case 'R':
05250 res = ast_say_date_with_format_nl(chan, t, ints, lang, "HM", tzone);
05251 break;
05252 case 'S':
05253
05254 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
05255 break;
05256 case 'T':
05257 res = ast_say_date_with_format_nl(chan, t, ints, lang, "HMS", tzone);
05258 break;
05259 case ' ':
05260 case ' ':
05261
05262 break;
05263 default:
05264
05265 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05266 }
05267
05268 if (res) {
05269 break;
05270 }
05271 }
05272 return res;
05273 }
05274
05275
05276 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)
05277 {
05278 struct timeval when = { thetime, 0 };
05279 struct ast_tm tm;
05280 int res=0, offset, sndoffset;
05281 char sndfile[256], nextmsg[256];
05282
05283 ast_localtime(&when, &tm, tzone);
05284
05285 for (offset = 0 ; format[offset] != '\0' ; offset++) {
05286 int remaining;
05287 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05288 switch (format[offset]) {
05289
05290 case '\'':
05291
05292 sndoffset = 0;
05293 for (sndoffset = 0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
05294 sndfile[sndoffset] = format[offset];
05295 sndfile[sndoffset] = '\0';
05296 res = wait_file(chan, ints, sndfile, lang);
05297 break;
05298 case 'A':
05299 case 'a':
05300
05301 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05302 res = wait_file(chan, ints, nextmsg, lang);
05303 break;
05304 case 'B':
05305 case 'b':
05306 case 'h':
05307
05308 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05309 res = wait_file(chan, ints, nextmsg, lang);
05310 break;
05311 case 'm':
05312
05313 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, NULL);
05314 break;
05315 case 'd':
05316 case 'e':
05317
05318 remaining = tm.tm_mday;
05319 if (tm.tm_mday > 30) {
05320 res = wait_file(chan, ints, "digits/h-30", lang);
05321 remaining -= 30;
05322 }
05323 if (tm.tm_mday > 20 && tm.tm_mday < 30) {
05324 res = wait_file(chan, ints, "digits/h-20", lang);
05325 remaining -= 20;
05326 }
05327 if (!res) {
05328 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", remaining);
05329 res = wait_file(chan, ints, nextmsg, lang);
05330 }
05331 break;
05332 case 'Y':
05333
05334 if (tm.tm_year > 100) {
05335 res = wait_file(chan, ints, "digits/2", lang);
05336 if (!res)
05337 res = wait_file(chan, ints, "digits/1000.2", lang);
05338 if (tm.tm_year > 100) {
05339 if (!res)
05340 res = ast_say_enumeration(chan, tm.tm_year - 100, ints, lang, NULL);
05341 }
05342 } else if (tm.tm_year == 100) {
05343 res = wait_file(chan, ints, "digits/h-2000", lang);
05344 } else {
05345 if (tm.tm_year < 1) {
05346
05347
05348 break;
05349 } else {
05350 res = wait_file(chan, ints, "digits/1000", lang);
05351 if (!res) {
05352 wait_file(chan, ints, "digits/900", lang);
05353 res = ast_say_enumeration(chan, tm.tm_year, ints, lang, NULL);
05354 }
05355 }
05356 }
05357 if (!res)
05358 wait_file(chan, ints, "digits/year", lang);
05359 break;
05360 case 'I':
05361 case 'l':
05362
05363 if (tm.tm_hour == 0)
05364 ast_copy_string(nextmsg, "digits/t-12", sizeof(nextmsg));
05365 else if (tm.tm_hour > 12)
05366 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour - 12);
05367 else
05368 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
05369
05370 res = wait_file(chan, ints, nextmsg, lang);
05371 break;
05372 case 'H':
05373 case 'k':
05374
05375 if (tm.tm_hour != 0) {
05376 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
05377 res = wait_file(chan, ints, nextmsg, lang);
05378 } else
05379 res = wait_file(chan, ints, "digits/t-24", lang);
05380 break;
05381 case 'M':
05382 case 'N':
05383
05384 if (tm.tm_min == 0) {
05385 if (format[offset] == 'M') {
05386 res = wait_file(chan, ints, "digits/oclock", lang);
05387 } else {
05388 res = wait_file(chan, ints, "digits/100", lang);
05389 }
05390 } else
05391 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
05392 break;
05393 case 'P':
05394 case 'p':
05395
05396 if (tm.tm_hour > 11)
05397 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
05398 else
05399 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
05400 res = wait_file(chan, ints, nextmsg, lang);
05401 break;
05402 case 'Q':
05403
05404 {
05405 struct timeval now = ast_tvnow();
05406 struct ast_tm tmnow;
05407 time_t beg_today;
05408
05409 ast_localtime(&now, &tmnow, tzone);
05410
05411
05412 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05413 if (beg_today < thetime) {
05414
05415 res = wait_file(chan, ints, "digits/today", lang);
05416 } else if (beg_today - 86400 < thetime) {
05417
05418 res = wait_file(chan, ints, "digits/yesterday", lang);
05419 } else {
05420 res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", tzone);
05421 }
05422 }
05423 break;
05424 case 'q':
05425
05426 {
05427 struct timeval now = ast_tvnow();
05428 struct ast_tm tmnow;
05429 time_t beg_today;
05430
05431 ast_localtime(&now, &tmnow, tzone);
05432
05433
05434 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05435 if (beg_today < thetime) {
05436
05437 } else if ((beg_today - 86400) < thetime) {
05438
05439 res = wait_file(chan, ints, "digits/yesterday", lang);
05440 } else if (beg_today - 86400 * 6 < thetime) {
05441
05442 res = ast_say_date_with_format(chan, thetime, ints, lang, "A", tzone);
05443 } else {
05444 res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", tzone);
05445 }
05446 }
05447 break;
05448 case 'R':
05449 res = ast_say_date_with_format(chan, thetime, ints, lang, "HM", tzone);
05450 break;
05451 case 'S':
05452
05453 res = wait_file(chan, ints, "digits/and", lang);
05454 if (!res) {
05455 if (tm.tm_sec == 1) {
05456 res = wait_file(chan, ints, "digits/1z", lang);
05457 if (!res)
05458 res = wait_file(chan, ints, "digits/second-a", lang);
05459 } else {
05460 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
05461 if (!res) {
05462 int ten, one;
05463 ten = tm.tm_sec / 10;
05464 one = tm.tm_sec % 10;
05465
05466 if (one > 1 && one < 5 && ten != 1)
05467 res = wait_file(chan, ints, "digits/seconds", lang);
05468 else
05469 res = wait_file(chan, ints, "digits/second", lang);
05470 }
05471 }
05472 }
05473 break;
05474 case 'T':
05475 res = ast_say_date_with_format(chan, thetime, ints, lang, "HMS", tzone);
05476 break;
05477 case ' ':
05478 case ' ':
05479
05480 break;
05481 default:
05482
05483 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05484 }
05485
05486 if (res)
05487 break;
05488 }
05489 return res;
05490 }
05491
05492
05493 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)
05494 {
05495 struct timeval when = { t, 0 };
05496 struct ast_tm tm;
05497 int res=0, offset, sndoffset;
05498 char sndfile[256], nextmsg[256];
05499
05500 if (format == NULL)
05501 format = "Ad 'digits/pt-de' B 'digits/pt-de' Y I 'digits/pt-e' Mp";
05502
05503 ast_localtime(&when, &tm, tzone);
05504
05505 for (offset=0 ; format[offset] != '\0' ; offset++) {
05506 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05507 switch (format[offset]) {
05508
05509 case '\'':
05510
05511 sndoffset=0;
05512 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
05513 sndfile[sndoffset] = format[offset];
05514 sndfile[sndoffset] = '\0';
05515 snprintf(nextmsg, sizeof(nextmsg), "%s", sndfile);
05516 res = wait_file(chan, ints, nextmsg, lang);
05517 break;
05518 case 'A':
05519 case 'a':
05520
05521 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05522 res = wait_file(chan, ints, nextmsg, lang);
05523 break;
05524 case 'B':
05525 case 'b':
05526 case 'h':
05527
05528 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05529 res = wait_file(chan, ints, nextmsg, lang);
05530 break;
05531 case 'm':
05532
05533 if (!strcasecmp(lang, "pt_BR")) {
05534 res = ast_say_number(chan, tm.tm_mon+1, ints, lang, (char *) NULL);
05535 } else {
05536 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
05537 res = wait_file(chan, ints, nextmsg, lang);
05538 }
05539 break;
05540 case 'd':
05541 case 'e':
05542
05543 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
05544 break;
05545 case 'Y':
05546
05547 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
05548 break;
05549 case 'I':
05550 case 'l':
05551
05552 if (!strcasecmp(lang, "pt_BR")) {
05553 if (tm.tm_hour == 0) {
05554 if (format[offset] == 'I')
05555 res = wait_file(chan, ints, "digits/pt-a", lang);
05556 if (!res)
05557 res = wait_file(chan, ints, "digits/pt-meianoite", lang);
05558 } else if (tm.tm_hour == 12) {
05559 if (format[offset] == 'I')
05560 res = wait_file(chan, ints, "digits/pt-ao", lang);
05561 if (!res)
05562 res = wait_file(chan, ints, "digits/pt-meiodia", lang);
05563 } else {
05564 if (format[offset] == 'I') {
05565 if ((tm.tm_hour % 12) != 1)
05566 res = wait_file(chan, ints, "digits/pt-as", lang);
05567 else
05568 res = wait_file(chan, ints, "digits/pt-a", lang);
05569 }
05570 if (!res)
05571 res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
05572 }
05573 } else {
05574 if (tm.tm_hour == 0) {
05575 if (format[offset] == 'I')
05576 res = wait_file(chan, ints, "digits/pt-ah", lang);
05577 if (!res)
05578 res = wait_file(chan, ints, "digits/pt-meianoite", lang);
05579 }
05580 else if (tm.tm_hour == 12) {
05581 if (format[offset] == 'I')
05582 res = wait_file(chan, ints, "digits/pt-ao", lang);
05583 if (!res)
05584 res = wait_file(chan, ints, "digits/pt-meiodia", lang);
05585 }
05586 else {
05587 if (format[offset] == 'I') {
05588 res = wait_file(chan, ints, "digits/pt-ah", lang);
05589 if ((tm.tm_hour % 12) != 1)
05590 if (!res)
05591 res = wait_file(chan, ints, "digits/pt-sss", lang);
05592 }
05593 if (!res)
05594 res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
05595 }
05596 }
05597 break;
05598 case 'H':
05599 case 'k':
05600
05601 if (!strcasecmp(lang, "pt_BR")) {
05602 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
05603 if ((!res) && (format[offset] == 'H')) {
05604 if (tm.tm_hour > 1) {
05605 res = wait_file(chan, ints, "digits/hours", lang);
05606 } else {
05607 res = wait_file(chan, ints, "digits/hour", lang);
05608 }
05609 }
05610 } else {
05611 res = ast_say_number(chan, -tm.tm_hour, ints, lang, NULL);
05612 if (!res) {
05613 if (tm.tm_hour != 0) {
05614 int remaining = tm.tm_hour;
05615 if (tm.tm_hour > 20) {
05616 res = wait_file(chan, ints, "digits/20", lang);
05617 remaining -= 20;
05618 }
05619 if (!res) {
05620 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
05621 res = wait_file(chan, ints, nextmsg, lang);
05622 }
05623 }
05624 }
05625 }
05626 break;
05627 case 'M':
05628
05629 if (!strcasecmp(lang, "pt_BR")) {
05630 res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
05631 if (!res) {
05632 if (tm.tm_min > 1) {
05633 res = wait_file(chan, ints, "digits/minutes", lang);
05634 } else {
05635 res = wait_file(chan, ints, "digits/minute", lang);
05636 }
05637 }
05638 } else {
05639 if (tm.tm_min == 0) {
05640 res = wait_file(chan, ints, "digits/pt-hora", lang);
05641 if (tm.tm_hour != 1)
05642 if (!res)
05643 res = wait_file(chan, ints, "digits/pt-sss", lang);
05644 } else {
05645 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05646 }
05647 }
05648 break;
05649 case 'P':
05650 case 'p':
05651
05652 if (!strcasecmp(lang, "pt_BR")) {
05653 if ((tm.tm_hour != 0) && (tm.tm_hour != 12)) {
05654 res = wait_file(chan, ints, "digits/pt-da", lang);
05655 if (!res) {
05656 if ((tm.tm_hour >= 0) && (tm.tm_hour < 12))
05657 res = wait_file(chan, ints, "digits/morning", lang);
05658 else if ((tm.tm_hour >= 12) && (tm.tm_hour < 18))
05659 res = wait_file(chan, ints, "digits/afternoon", lang);
05660 else res = wait_file(chan, ints, "digits/night", lang);
05661 }
05662 }
05663 } else {
05664 if (tm.tm_hour > 12)
05665 res = wait_file(chan, ints, "digits/p-m", lang);
05666 else if (tm.tm_hour && tm.tm_hour < 12)
05667 res = wait_file(chan, ints, "digits/a-m", lang);
05668 }
05669 break;
05670 case 'Q':
05671
05672
05673
05674
05675 {
05676 struct timeval now = ast_tvnow();
05677 struct ast_tm tmnow;
05678 time_t beg_today;
05679
05680 ast_localtime(&now, &tmnow, tzone);
05681
05682
05683 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05684 if (beg_today < t) {
05685
05686 res = wait_file(chan, ints, "digits/today", lang);
05687 } else if (beg_today - 86400 < t) {
05688
05689 res = wait_file(chan, ints, "digits/yesterday", lang);
05690 } else {
05691 res = ast_say_date_with_format_pt(chan, t, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", tzone);
05692 }
05693 }
05694 break;
05695 case 'q':
05696
05697
05698
05699
05700 {
05701 struct timeval now = ast_tvnow();
05702 struct ast_tm tmnow;
05703 time_t beg_today;
05704
05705 ast_localtime(&now, &tmnow, tzone);
05706
05707
05708 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05709 if (beg_today < t) {
05710
05711 } else if ((beg_today - 86400) < t) {
05712
05713 res = wait_file(chan, ints, "digits/yesterday", lang);
05714 } else if (beg_today - 86400 * 6 < t) {
05715
05716 res = ast_say_date_with_format_pt(chan, t, ints, lang, "A", tzone);
05717 } else {
05718 res = ast_say_date_with_format_pt(chan, t, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", tzone);
05719 }
05720 }
05721 break;
05722 case 'R':
05723 res = ast_say_date_with_format_pt(chan, t, ints, lang, "H 'digits/pt-e' M", tzone);
05724 break;
05725 case 'S':
05726
05727 if (!strcasecmp(lang, "pt_BR")) {
05728 res = ast_say_number(chan, tm.tm_sec, ints, lang, NULL);
05729 if (!res) {
05730 if (tm.tm_sec > 1) {
05731 res = wait_file(chan, ints, "digits/seconds", lang);
05732 } else {
05733 res = wait_file(chan, ints, "digits/second", lang);
05734 }
05735 }
05736 } else {
05737 if (tm.tm_sec == 0) {
05738 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05739 res = wait_file(chan, ints, nextmsg, lang);
05740 } else if (tm.tm_sec < 10) {
05741 res = wait_file(chan, ints, "digits/oh", lang);
05742 if (!res) {
05743 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05744 res = wait_file(chan, ints, nextmsg, lang);
05745 }
05746 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
05747 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05748 res = wait_file(chan, ints, nextmsg, lang);
05749 } else {
05750 int ten, one;
05751 ten = (tm.tm_sec / 10) * 10;
05752 one = (tm.tm_sec % 10);
05753 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
05754 res = wait_file(chan, ints, nextmsg, lang);
05755 if (!res) {
05756
05757 if (one != 0) {
05758 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
05759 res = wait_file(chan, ints, nextmsg, lang);
05760 }
05761 }
05762 }
05763 }
05764 break;
05765 case 'T':
05766 res = ast_say_date_with_format_pt(chan, t, ints, lang, "HMS", tzone);
05767 break;
05768 case ' ':
05769 case ' ':
05770
05771 break;
05772 default:
05773
05774 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05775 }
05776
05777 if (res) {
05778 break;
05779 }
05780 }
05781 return res;
05782 }
05783
05784
05785 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)
05786 {
05787 struct timeval when = { t, 0 };
05788 struct ast_tm tm;
05789 int res=0, offset, sndoffset;
05790 char sndfile[256], nextmsg[256];
05791
05792 if (format == NULL)
05793 format = "YBdAkM";
05794
05795 ast_localtime(&when, &tm, tzone);
05796
05797 for (offset=0 ; format[offset] != '\0' ; offset++) {
05798 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05799 switch (format[offset]) {
05800
05801 case '\'':
05802
05803 sndoffset=0;
05804 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
05805 sndfile[sndoffset] = format[offset];
05806 sndfile[sndoffset] = '\0';
05807 res = wait_file(chan, ints, sndfile, lang);
05808 break;
05809 case 'A':
05810 case 'a':
05811
05812 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05813 res = wait_file(chan, ints, nextmsg, lang);
05814 break;
05815 case 'B':
05816 case 'b':
05817 case 'h':
05818 case 'm':
05819
05820 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05821 res = wait_file(chan, ints, nextmsg, lang);
05822 break;
05823 case 'd':
05824 case 'e':
05825
05826 if (!(tm.tm_mday % 10) || (tm.tm_mday < 10)) {
05827 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday);
05828 res = wait_file(chan, ints, nextmsg, lang);
05829 } else {
05830 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday - (tm.tm_mday % 10));
05831 res = wait_file(chan, ints, nextmsg, lang);
05832 if (!res) {
05833 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday % 10);
05834 res = wait_file(chan, ints, nextmsg, lang);
05835 }
05836 }
05837 if (!res) res = wait_file(chan, ints, "digits/day", lang);
05838 break;
05839 case 'Y':
05840
05841 if (tm.tm_year > 99) {
05842 res = wait_file(chan, ints, "digits/2", lang);
05843 if (!res) {
05844 res = wait_file(chan, ints, "digits/thousand", lang);
05845 }
05846 if (tm.tm_year > 100) {
05847 if (!res) {
05848 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) / 10);
05849 res = wait_file(chan, ints, nextmsg, lang);
05850 if (!res) {
05851 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) % 10);
05852 res = wait_file(chan, ints, nextmsg, lang);
05853 }
05854 }
05855 }
05856 if (!res) {
05857 res = wait_file(chan, ints, "digits/year", lang);
05858 }
05859 } else {
05860 if (tm.tm_year < 1) {
05861
05862
05863 } else {
05864 res = wait_file(chan, ints, "digits/1", lang);
05865 if (!res) {
05866 res = wait_file(chan, ints, "digits/9", lang);
05867 }
05868 if (!res) {
05869 if (tm.tm_year <= 9) {
05870
05871 res = wait_file(chan, ints, "digits/0", lang);
05872 if (!res) {
05873 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
05874 res = wait_file(chan, ints, nextmsg, lang);
05875 }
05876 } else {
05877
05878 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year / 10);
05879 res = wait_file(chan, ints, nextmsg, lang);
05880 if (!res) {
05881 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year % 10);
05882 res = wait_file(chan, ints, nextmsg, lang);
05883 }
05884 }
05885 }
05886 }
05887 if (!res) {
05888 res = wait_file(chan, ints, "digits/year", lang);
05889 }
05890 }
05891 break;
05892 case 'I':
05893 case 'l':
05894
05895 if (tm.tm_hour == 0)
05896 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
05897 else if (tm.tm_hour > 12)
05898 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
05899 else
05900 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
05901 res = wait_file(chan, ints, nextmsg, lang);
05902 if (!res) {
05903 res = wait_file(chan, ints, "digits/oclock", lang);
05904 }
05905 break;
05906 case 'H':
05907 if (tm.tm_hour < 10) {
05908 res = wait_file(chan, ints, "digits/0", lang);
05909 }
05910 case 'k':
05911
05912 if (!(tm.tm_hour % 10) || tm.tm_hour < 10) {
05913 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
05914 res = wait_file(chan, ints, nextmsg, lang);
05915 } else {
05916 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - (tm.tm_hour % 10));
05917 res = wait_file(chan, ints, nextmsg, lang);
05918 if (!res) {
05919 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour % 10);
05920 res = wait_file(chan, ints, nextmsg, lang);
05921 }
05922 }
05923 if (!res) {
05924 res = wait_file(chan, ints, "digits/oclock", lang);
05925 }
05926 break;
05927 case 'M':
05928
05929 if (!(tm.tm_min % 10) || tm.tm_min < 10) {
05930 if (tm.tm_min < 10) {
05931 res = wait_file(chan, ints, "digits/0", lang);
05932 }
05933 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min);
05934 res = wait_file(chan, ints, nextmsg, lang);
05935 } else {
05936 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min - (tm.tm_min % 10));
05937 res = wait_file(chan, ints, nextmsg, lang);
05938 if (!res) {
05939 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min % 10);
05940 res = wait_file(chan, ints, nextmsg, lang);
05941 }
05942 }
05943 if (!res) {
05944 res = wait_file(chan, ints, "digits/minute", lang);
05945 }
05946 break;
05947 case 'P':
05948 case 'p':
05949
05950 if (tm.tm_hour > 11)
05951 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
05952 else
05953 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
05954 res = wait_file(chan, ints, nextmsg, lang);
05955 break;
05956 case 'Q':
05957
05958
05959
05960
05961 {
05962 struct timeval now = ast_tvnow();
05963 struct ast_tm tmnow;
05964 time_t beg_today;
05965
05966 ast_localtime(&now, &tmnow, tzone);
05967
05968
05969 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05970 if (beg_today < t) {
05971
05972 res = wait_file(chan, ints, "digits/today", lang);
05973 } else if (beg_today - 86400 < t) {
05974
05975 res = wait_file(chan, ints, "digits/yesterday", lang);
05976 } else {
05977 res = ast_say_date_with_format_zh(chan, t, ints, lang, "YBdA", tzone);
05978 }
05979 }
05980 break;
05981 case 'q':
05982
05983
05984
05985
05986 {
05987 struct timeval now = ast_tvnow();
05988 struct ast_tm tmnow;
05989 time_t beg_today;
05990
05991 ast_localtime(&now, &tmnow, tzone);
05992
05993
05994 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05995 if (beg_today < t) {
05996
05997 } else if ((beg_today - 86400) < t) {
05998
05999 res = wait_file(chan, ints, "digits/yesterday", lang);
06000 } else if (beg_today - 86400 * 6 < t) {
06001
06002 res = ast_say_date_with_format_zh(chan, t, ints, lang, "A", tzone);
06003 } else {
06004 res = ast_say_date_with_format_zh(chan, t, ints, lang, "YBdA", tzone);
06005 }
06006 }
06007 break;
06008 case 'R':
06009 res = ast_say_date_with_format_zh(chan, t, ints, lang, "kM", tzone);
06010 break;
06011 case 'S':
06012
06013 if (!(tm.tm_sec % 10) || tm.tm_sec < 10) {
06014 if (tm.tm_sec < 10) {
06015 res = wait_file(chan, ints, "digits/0", lang);
06016 }
06017 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
06018 res = wait_file(chan, ints, nextmsg, lang);
06019 } else {
06020 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec - (tm.tm_sec % 10));
06021 res = wait_file(chan, ints, nextmsg, lang);
06022 if (!res) {
06023 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec % 10);
06024 res = wait_file(chan, ints, nextmsg, lang);
06025 }
06026 }
06027 if (!res) {
06028 res = wait_file(chan, ints, "digits/second", lang);
06029 }
06030 break;
06031 case 'T':
06032 res = ast_say_date_with_format_zh(chan, t, ints, lang, "HMS", tzone);
06033 break;
06034 case ' ':
06035 case ' ':
06036
06037 break;
06038 default:
06039
06040 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
06041 }
06042
06043 if (res) {
06044 break;
06045 }
06046 }
06047 return res;
06048 }
06049
06050 static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06051 {
06052 if (!strncasecmp(lang, "en", 2)) {
06053 return ast_say_time_en(chan, t, ints, lang);
06054 } else if (!strncasecmp(lang, "de", 2)) {
06055 return ast_say_time_de(chan, t, ints, lang);
06056 } else if (!strncasecmp(lang, "fr", 2)) {
06057 return ast_say_time_fr(chan, t, ints, lang);
06058 } else if (!strncasecmp(lang, "ge", 2)) {
06059 static int deprecation_warning = 0;
06060 if (deprecation_warning++ % 10 == 0) {
06061 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
06062 }
06063 return ast_say_time_ka(chan, t, ints, lang);
06064 } else if (!strncasecmp(lang, "gr", 2)) {
06065 return ast_say_time_gr(chan, t, ints, lang);
06066 } else if (!strncasecmp(lang, "he", 2)) {
06067 return ast_say_time_he(chan, t, ints, lang);
06068 } else if (!strncasecmp(lang, "hu", 2)) {
06069 return(ast_say_time_hu(chan, t, ints, lang));
06070 } else if (!strncasecmp(lang, "ka", 2)) {
06071 return ast_say_time_ka(chan, t, ints, lang);
06072 } else if (!strncasecmp(lang, "nl", 2)) {
06073 return ast_say_time_nl(chan, t, ints, lang);
06074 } else if (!strncasecmp(lang, "pt_BR", 5)) {
06075 return ast_say_time_pt_BR(chan, t, ints, lang);
06076 } else if (!strncasecmp(lang, "pt", 2)) {
06077 return ast_say_time_pt(chan, t, ints, lang);
06078 } else if (!strncasecmp(lang, "th", 2)) {
06079 return(ast_say_time_th(chan, t, ints, lang));
06080 } else if (!strncasecmp(lang, "tw", 2)) {
06081 static int deprecation_warning = 0;
06082 if (deprecation_warning++ % 10 == 0) {
06083 ast_log(LOG_WARNING, "tw is a standard language code for Twi, not Taiwanese. Please switch to using zh_TW instead.\n");
06084 }
06085 return ast_say_time_zh(chan, t, ints, lang);
06086 } else if (!strncasecmp(lang, "zh", 2)) {
06087 return ast_say_time_zh(chan, t, ints, lang);
06088 }
06089
06090
06091 return ast_say_time_en(chan, t, ints, lang);
06092 }
06093
06094
06095 int ast_say_time_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06096 {
06097 struct timeval when = { t, 0 };
06098 struct ast_tm tm;
06099 int res = 0;
06100 int hour, pm=0;
06101
06102 ast_localtime(&when, &tm, NULL);
06103 hour = tm.tm_hour;
06104 if (!hour)
06105 hour = 12;
06106 else if (hour == 12)
06107 pm = 1;
06108 else if (hour > 12) {
06109 hour -= 12;
06110 pm = 1;
06111 }
06112 if (!res)
06113 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06114
06115 if (tm.tm_min > 9) {
06116 if (!res)
06117 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06118 } else if (tm.tm_min) {
06119 if (!res)
06120 res = ast_streamfile(chan, "digits/oh", lang);
06121 if (!res)
06122 res = ast_waitstream(chan, ints);
06123 if (!res)
06124 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06125 } else {
06126 if (!res)
06127 res = ast_streamfile(chan, "digits/oclock", lang);
06128 if (!res)
06129 res = ast_waitstream(chan, ints);
06130 }
06131 if (pm) {
06132 if (!res)
06133 res = ast_streamfile(chan, "digits/p-m", lang);
06134 } else {
06135 if (!res)
06136 res = ast_streamfile(chan, "digits/a-m", lang);
06137 }
06138 if (!res)
06139 res = ast_waitstream(chan, ints);
06140 return res;
06141 }
06142
06143
06144 int ast_say_time_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06145 {
06146 struct timeval when = { t, 0 };
06147 struct ast_tm tm;
06148 int res = 0;
06149
06150 ast_localtime(&when, &tm, NULL);
06151 if (!res)
06152 res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
06153 if (!res)
06154 res = ast_streamfile(chan, "digits/oclock", lang);
06155 if (!res)
06156 res = ast_waitstream(chan, ints);
06157 if (!res)
06158 if (tm.tm_min > 0)
06159 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06160 return res;
06161 }
06162
06163
06164 int ast_say_time_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06165 {
06166 struct timeval when = { t, 0 };
06167 struct ast_tm tm;
06168 int res = 0;
06169
06170 ast_localtime(&when, &tm, NULL);
06171 if (!res)
06172 res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
06173 if (!res)
06174 res = ast_streamfile(chan, "digits/oclock", lang);
06175 if (!res)
06176 res = ast_waitstream(chan, ints);
06177 if (!res)
06178 if (tm.tm_min > 0) {
06179 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06180 if (!res)
06181 res = ast_streamfile(chan, "digits/minute", lang);
06182 }
06183 return res;
06184 }
06185
06186
06187 int ast_say_time_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06188 {
06189 struct timeval when = { t, 0 };
06190 struct ast_tm tm;
06191 int res = 0;
06192
06193 ast_localtime(&when, &tm, NULL);
06194
06195 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
06196 if (!res)
06197 res = ast_streamfile(chan, "digits/oclock", lang);
06198 if (tm.tm_min) {
06199 if (!res)
06200 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06201 }
06202 return res;
06203 }
06204
06205
06206 int ast_say_time_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06207 {
06208 struct timeval when = { t, 0 };
06209 struct ast_tm tm;
06210 int res = 0;
06211
06212 ast_localtime(&when, &tm, NULL);
06213 if (!res)
06214 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
06215 if (!res)
06216 res = ast_streamfile(chan, "digits/nl-uur", lang);
06217 if (!res)
06218 res = ast_waitstream(chan, ints);
06219 if (!res)
06220 if (tm.tm_min > 0)
06221 res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
06222 return res;
06223 }
06224
06225
06226 int ast_say_time_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06227 {
06228 struct timeval when = { t, 0 };
06229 struct ast_tm tm;
06230 int res = 0;
06231 int hour;
06232
06233 ast_localtime(&when, &tm, NULL);
06234 hour = tm.tm_hour;
06235 if (!res)
06236 res = ast_say_number(chan, hour, ints, lang, "f");
06237 if (tm.tm_min) {
06238 if (!res)
06239 res = wait_file(chan, ints, "digits/pt-e", lang);
06240 if (!res)
06241 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06242 } else {
06243 if (!res)
06244 res = wait_file(chan, ints, "digits/pt-hora", lang);
06245 if (tm.tm_hour != 1)
06246 if (!res)
06247 res = wait_file(chan, ints, "digits/pt-sss", lang);
06248 }
06249 if (!res)
06250 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06251 return res;
06252 }
06253
06254
06255 int ast_say_time_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06256 {
06257 struct timeval when = { t, 0 };
06258 struct ast_tm tm;
06259 int res = 0;
06260
06261 ast_localtime(&when, &tm, NULL);
06262
06263 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
06264 if (!res) {
06265 if (tm.tm_hour > 1)
06266 res = wait_file(chan, ints, "digits/hours", lang);
06267 else
06268 res = wait_file(chan, ints, "digits/hour", lang);
06269 }
06270 if ((!res) && (tm.tm_min)) {
06271 res = wait_file(chan, ints, "digits/pt-e", lang);
06272 if (!res)
06273 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06274 if (!res) {
06275 if (tm.tm_min > 1)
06276 res = wait_file(chan, ints, "digits/minutes", lang);
06277 else
06278 res = wait_file(chan, ints, "digits/minute", lang);
06279 }
06280 }
06281 return res;
06282 }
06283
06284
06285 int ast_say_time_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06286 {
06287 struct timeval when = { t, 0 };
06288 struct ast_tm tm;
06289 int res = 0;
06290 int hour;
06291 ast_localtime(&when, &tm, NULL);
06292 hour = tm.tm_hour;
06293 if (!hour)
06294 hour = 24;
06295 if (!res)
06296 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06297 if (!res)
06298 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06299 return res;
06300 }
06301
06302
06303 int ast_say_time_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06304 {
06305 struct timeval when = { t, 0 };
06306 struct ast_tm tm;
06307 int res = 0;
06308 int hour, pm=0;
06309
06310 ast_localtime(&when, &tm, NULL);
06311 hour = tm.tm_hour;
06312 if (!hour)
06313 hour = 12;
06314 else if (hour == 12)
06315 pm = 1;
06316 else if (hour > 12) {
06317 hour -= 12;
06318 pm = 1;
06319 }
06320 if (pm) {
06321 if (!res)
06322 res = ast_streamfile(chan, "digits/p-m", lang);
06323 } else {
06324 if (!res)
06325 res = ast_streamfile(chan, "digits/a-m", lang);
06326 }
06327 if (!res)
06328 res = ast_waitstream(chan, ints);
06329 if (!res)
06330 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06331 if (!res)
06332 res = ast_streamfile(chan, "digits/oclock", lang);
06333 if (!res)
06334 res = ast_waitstream(chan, ints);
06335 if (!res)
06336 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06337 if (!res)
06338 res = ast_streamfile(chan, "digits/minute", lang);
06339 if (!res)
06340 res = ast_waitstream(chan, ints);
06341 return res;
06342 }
06343
06344
06345 int ast_say_time_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06346 {
06347 struct timeval when = { t, 0 };
06348 struct ast_tm tm;
06349 int res = 0;
06350 int hour;
06351
06352 ast_localtime(&when, &tm, NULL);
06353 hour = tm.tm_hour;
06354 if (!hour)
06355 hour = 12;
06356
06357 if (!res)
06358 res = ast_say_number_full_he(chan, hour, ints, lang, "f", -1, -1);
06359
06360 if (tm.tm_min > 9) {
06361 if (!res)
06362 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
06363 } else if (tm.tm_min) {
06364 if (!res) {
06365 res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
06366 }
06367 if (!res)
06368 res = ast_waitstream(chan, ints);
06369 if (!res)
06370 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
06371 } else {
06372 if (!res)
06373 res = ast_waitstream(chan, ints);
06374 }
06375 if (!res)
06376 res = ast_waitstream(chan, ints);
06377 return res;
06378 }
06379 static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06380 {
06381 if (!strncasecmp(lang, "en", 2)) {
06382 return ast_say_datetime_en(chan, t, ints, lang);
06383 } else if (!strncasecmp(lang, "de", 2)) {
06384 return ast_say_datetime_de(chan, t, ints, lang);
06385 } else if (!strncasecmp(lang, "fr", 2)) {
06386 return ast_say_datetime_fr(chan, t, ints, lang);
06387 } else if (!strncasecmp(lang, "ge", 2)) {
06388 static int deprecation_warning = 0;
06389 if (deprecation_warning++ % 10 == 0) {
06390 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
06391 }
06392 return ast_say_datetime_ka(chan, t, ints, lang);
06393 } else if (!strncasecmp(lang, "gr", 2)) {
06394 return ast_say_datetime_gr(chan, t, ints, lang);
06395 } else if (!strncasecmp(lang, "he", 2)) {
06396 return ast_say_datetime_he(chan, t, ints, lang);
06397 } else if (!strncasecmp(lang, "hu", 2)) {
06398 return ast_say_datetime_hu(chan, t, ints, lang);
06399 } else if (!strncasecmp(lang, "ka", 2)) {
06400 return ast_say_datetime_ka(chan, t, ints, lang);
06401 } else if (!strncasecmp(lang, "nl", 2)) {
06402 return ast_say_datetime_nl(chan, t, ints, lang);
06403 } else if (!strncasecmp(lang, "pt_BR", 5)) {
06404 return ast_say_datetime_pt_BR(chan, t, ints, lang);
06405 } else if (!strncasecmp(lang, "pt", 2)) {
06406 return ast_say_datetime_pt(chan, t, ints, lang);
06407 } else if (!strncasecmp(lang, "th", 2)) {
06408 return ast_say_datetime_th(chan, t, ints, lang);
06409 } else if (!strncasecmp(lang, "tw", 2)) {
06410 static int deprecation_warning = 0;
06411 if (deprecation_warning++ % 10 == 0) {
06412 ast_log(LOG_WARNING, "tw is a standard language code for Twi, not Taiwanese. Please switch to using zh_TW instead.\n");
06413 }
06414 return ast_say_datetime_zh(chan, t, ints, lang);
06415 } else if (!strncasecmp(lang, "zh", 2)) {
06416 return ast_say_datetime_zh(chan, t, ints, lang);
06417 }
06418
06419
06420 return ast_say_datetime_en(chan, t, ints, lang);
06421 }
06422
06423
06424 int ast_say_datetime_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06425 {
06426 struct timeval when = { t, 0 };
06427 struct ast_tm tm;
06428 char fn[256];
06429 int res = 0;
06430 int hour, pm=0;
06431
06432 ast_localtime(&when, &tm, NULL);
06433 if (!res) {
06434 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06435 res = ast_streamfile(chan, fn, lang);
06436 if (!res)
06437 res = ast_waitstream(chan, ints);
06438 }
06439 if (!res) {
06440 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06441 res = ast_streamfile(chan, fn, lang);
06442 if (!res)
06443 res = ast_waitstream(chan, ints);
06444 }
06445 if (!res)
06446 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06447
06448 hour = tm.tm_hour;
06449 if (!hour)
06450 hour = 12;
06451 else if (hour == 12)
06452 pm = 1;
06453 else if (hour > 12) {
06454 hour -= 12;
06455 pm = 1;
06456 }
06457 if (!res)
06458 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06459
06460 if (tm.tm_min > 9) {
06461 if (!res)
06462 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06463 } else if (tm.tm_min) {
06464 if (!res)
06465 res = ast_streamfile(chan, "digits/oh", lang);
06466 if (!res)
06467 res = ast_waitstream(chan, ints);
06468 if (!res)
06469 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06470 } else {
06471 if (!res)
06472 res = ast_streamfile(chan, "digits/oclock", lang);
06473 if (!res)
06474 res = ast_waitstream(chan, ints);
06475 }
06476 if (pm) {
06477 if (!res)
06478 res = ast_streamfile(chan, "digits/p-m", lang);
06479 } else {
06480 if (!res)
06481 res = ast_streamfile(chan, "digits/a-m", lang);
06482 }
06483 if (!res)
06484 res = ast_waitstream(chan, ints);
06485 if (!res)
06486 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06487 return res;
06488 }
06489
06490
06491 int ast_say_datetime_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06492 {
06493 struct timeval when = { t, 0 };
06494 struct ast_tm tm;
06495 int res = 0;
06496
06497 ast_localtime(&when, &tm, NULL);
06498 res = ast_say_date(chan, t, ints, lang);
06499 if (!res)
06500 ast_say_time(chan, t, ints, lang);
06501 return res;
06502
06503 }
06504
06505
06506 int ast_say_datetime_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06507 {
06508 struct timeval when = { t, 0 };
06509 struct ast_tm tm;
06510 int res = 0;
06511
06512 ast_localtime(&when, &tm, NULL);
06513 res = ast_say_date(chan, t, ints, lang);
06514 if (!res)
06515 ast_say_time(chan, t, ints, lang);
06516 return res;
06517 }
06518
06519
06520 int ast_say_datetime_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06521 {
06522 struct timeval when = { t, 0 };
06523 struct ast_tm tm;
06524 char fn[256];
06525 int res = 0;
06526
06527 ast_localtime(&when, &tm, NULL);
06528
06529 if (!res)
06530 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06531
06532 if (!res) {
06533 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06534 res = ast_streamfile(chan, fn, lang);
06535 if (!res)
06536 res = ast_waitstream(chan, ints);
06537 }
06538 if (!res) {
06539 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06540 res = ast_streamfile(chan, fn, lang);
06541 if (!res)
06542 res = ast_waitstream(chan, ints);
06543 }
06544
06545 if (!res)
06546 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
06547 if (!res)
06548 res = ast_streamfile(chan, "digits/oclock", lang);
06549 if (tm.tm_min > 0) {
06550 if (!res)
06551 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06552 }
06553 if (!res)
06554 res = ast_waitstream(chan, ints);
06555 if (!res)
06556 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06557 return res;
06558 }
06559
06560
06561 int ast_say_datetime_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06562 {
06563 struct timeval when = { t, 0 };
06564 struct ast_tm tm;
06565 int res = 0;
06566
06567 ast_localtime(&when, &tm, NULL);
06568 res = ast_say_date(chan, t, ints, lang);
06569 if (!res) {
06570 res = ast_streamfile(chan, "digits/nl-om", lang);
06571 if (!res)
06572 res = ast_waitstream(chan, ints);
06573 }
06574 if (!res)
06575 ast_say_time(chan, t, ints, lang);
06576 return res;
06577 }
06578
06579
06580 int ast_say_datetime_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06581 {
06582 struct timeval when = { t, 0 };
06583 struct ast_tm tm;
06584 char fn[256];
06585 int res = 0;
06586 int hour, pm=0;
06587
06588 ast_localtime(&when, &tm, NULL);
06589 if (!res) {
06590 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06591 res = ast_streamfile(chan, fn, lang);
06592 if (!res)
06593 res = ast_waitstream(chan, ints);
06594 }
06595 if (!res) {
06596 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06597 res = ast_streamfile(chan, fn, lang);
06598 if (!res)
06599 res = ast_waitstream(chan, ints);
06600 }
06601 if (!res)
06602 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06603
06604 hour = tm.tm_hour;
06605 if (!hour)
06606 hour = 12;
06607 else if (hour == 12)
06608 pm = 1;
06609 else if (hour > 12) {
06610 hour -= 12;
06611 pm = 1;
06612 }
06613 if (!res)
06614 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06615
06616 if (tm.tm_min > 9) {
06617 if (!res)
06618 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06619 } else if (tm.tm_min) {
06620 if (!res)
06621 res = ast_streamfile(chan, "digits/oh", lang);
06622 if (!res)
06623 res = ast_waitstream(chan, ints);
06624 if (!res)
06625 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06626 } else {
06627 if (!res)
06628 res = ast_streamfile(chan, "digits/oclock", lang);
06629 if (!res)
06630 res = ast_waitstream(chan, ints);
06631 }
06632 if (pm) {
06633 if (!res)
06634 res = ast_streamfile(chan, "digits/p-m", lang);
06635 } else {
06636 if (!res)
06637 res = ast_streamfile(chan, "digits/a-m", lang);
06638 }
06639 if (!res)
06640 res = ast_waitstream(chan, ints);
06641 if (!res)
06642 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06643 return res;
06644 }
06645
06646
06647 int ast_say_datetime_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06648 {
06649 struct timeval when = { t, 0 };
06650 struct ast_tm tm;
06651 int res = 0;
06652
06653 ast_localtime(&when, &tm, NULL);
06654 res = ast_say_date(chan, t, ints, lang);
06655 if (!res)
06656 res = ast_say_time(chan, t, ints, lang);
06657 return res;
06658 }
06659
06660
06661 int ast_say_datetime_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06662 {
06663 struct timeval when = { t, 0 };
06664 struct ast_tm tm;
06665 char fn[256];
06666 int res = 0;
06667 int hour;
06668 ast_localtime(&when, &tm, NULL);
06669 if (!res) {
06670 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06671 res = ast_streamfile(chan, fn, lang);
06672 if (!res)
06673 res = ast_waitstream(chan, ints);
06674 }
06675 if (!res) {
06676 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06677 res = ast_streamfile(chan, fn, lang);
06678 if (!res)
06679 res = ast_waitstream(chan, ints);
06680 }
06681 if (!res){
06682 ast_copy_string(fn, "digits/posor", sizeof(fn));
06683 res = ast_streamfile(chan, fn, lang);
06684 res = ast_say_number(chan, tm.tm_year + 1900 + 543, ints, lang, (char *) NULL);
06685 }
06686 if (!res)
06687 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06688
06689 hour = tm.tm_hour;
06690 if (!hour)
06691 hour = 24;
06692 if (!res){
06693 ast_copy_string(fn, "digits/wela", sizeof(fn));
06694 res = ast_streamfile(chan, fn, lang);
06695 }
06696 if (!res)
06697 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06698 if (!res)
06699 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06700 return res;
06701 }
06702
06703
06704 int ast_say_datetime_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06705 {
06706 struct timeval when = { t, 0 };
06707 struct ast_tm tm;
06708 char fn[256];
06709 int res = 0;
06710 int hour, pm=0;
06711
06712 ast_localtime(&when, &tm, NULL);
06713 if (!res)
06714 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06715 if (!res) {
06716 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06717 res = ast_streamfile(chan, fn, lang);
06718 if (!res)
06719 res = ast_waitstream(chan, ints);
06720 }
06721 if (!res)
06722 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06723 if (!res) {
06724 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06725 res = ast_streamfile(chan, fn, lang);
06726 if (!res)
06727 res = ast_waitstream(chan, ints);
06728 }
06729
06730 hour = tm.tm_hour;
06731 if (!hour)
06732 hour = 12;
06733 else if (hour == 12)
06734 pm = 1;
06735 else if (hour > 12) {
06736 hour -= 12;
06737 pm = 1;
06738 }
06739 if (pm) {
06740 if (!res)
06741 res = ast_streamfile(chan, "digits/p-m", lang);
06742 } else {
06743 if (!res)
06744 res = ast_streamfile(chan, "digits/a-m", lang);
06745 }
06746 if (!res)
06747 res = ast_waitstream(chan, ints);
06748 if (!res)
06749 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06750 if (!res)
06751 res = ast_streamfile(chan, "digits/oclock", lang);
06752 if (!res)
06753 res = ast_waitstream(chan, ints);
06754 if (!res)
06755 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06756 if (!res)
06757 res = ast_streamfile(chan, "digits/minute", lang);
06758 if (!res)
06759 res = ast_waitstream(chan, ints);
06760 return res;
06761 }
06762
06763
06764 int ast_say_datetime_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06765 {
06766 struct timeval when = { t, 0 };
06767 struct ast_tm tm;
06768 char fn[256];
06769 int res = 0;
06770 int hour;
06771
06772 ast_localtime(&when, &tm, NULL);
06773 if (!res) {
06774 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06775 res = ast_streamfile(chan, fn, lang);
06776 if (!res) {
06777 res = ast_waitstream(chan, ints);
06778 }
06779 }
06780 if (!res) {
06781 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06782 res = ast_streamfile(chan, fn, lang);
06783 if (!res) {
06784 res = ast_waitstream(chan, ints);
06785 }
06786 }
06787 if (!res) {
06788 res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
06789 }
06790
06791 hour = tm.tm_hour;
06792 if (!hour) {
06793 hour = 12;
06794 }
06795
06796 if (!res) {
06797 res = ast_say_number(chan, hour, ints, lang, "f");
06798 }
06799
06800 if (tm.tm_min > 9) {
06801 if (!res) {
06802 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06803 }
06804 } else if (tm.tm_min) {
06805 if (!res) {
06806
06807 res = ast_say_number(chan, 0, ints, lang, "f");
06808 }
06809 if (!res) {
06810 res = ast_waitstream(chan, ints);
06811 }
06812 if (!res) {
06813 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06814 }
06815 } else {
06816 if (!res) {
06817 res = ast_waitstream(chan, ints);
06818 }
06819 }
06820 if (!res) {
06821 res = ast_waitstream(chan, ints);
06822 }
06823 if (!res) {
06824 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "f");
06825 }
06826 return res;
06827 }
06828 static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06829 {
06830 if (!strncasecmp(lang, "en", 2)) {
06831 return ast_say_datetime_from_now_en(chan, t, ints, lang);
06832 } else if (!strncasecmp(lang, "fr", 2)) {
06833 return ast_say_datetime_from_now_fr(chan, t, ints, lang);
06834 } else if (!strncasecmp(lang, "ge", 2)) {
06835 static int deprecation_warning = 0;
06836 if (deprecation_warning++ % 10 == 0) {
06837 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
06838 }
06839 return ast_say_datetime_from_now_ka(chan, t, ints, lang);
06840 } else if (!strncasecmp(lang, "he", 2)) {
06841 return ast_say_datetime_from_now_he(chan, t, ints, lang);
06842 } else if (!strncasecmp(lang, "ka", 2)) {
06843 return ast_say_datetime_from_now_ka(chan, t, ints, lang);
06844 } else if (!strncasecmp(lang, "pt", 2)) {
06845 return ast_say_datetime_from_now_pt(chan, t, ints, lang);
06846 }
06847
06848
06849 return ast_say_datetime_from_now_en(chan, t, ints, lang);
06850 }
06851
06852
06853 int ast_say_datetime_from_now_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06854 {
06855 int res=0;
06856 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
06857 int daydiff;
06858 struct ast_tm tm;
06859 struct ast_tm now;
06860 char fn[256];
06861
06862 ast_localtime(&when, &tm, NULL);
06863 ast_localtime(&nowtv, &now, NULL);
06864 daydiff = now.tm_yday - tm.tm_yday;
06865 if ((daydiff < 0) || (daydiff > 6)) {
06866
06867 if (!res) {
06868 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06869 res = ast_streamfile(chan, fn, lang);
06870 if (!res)
06871 res = ast_waitstream(chan, ints);
06872 }
06873 if (!res)
06874 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06875
06876 } else if (daydiff) {
06877
06878 if (!res) {
06879 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06880 res = ast_streamfile(chan, fn, lang);
06881 if (!res)
06882 res = ast_waitstream(chan, ints);
06883 }
06884 }
06885 if (!res)
06886 res = ast_say_time(chan, t, ints, lang);
06887 return res;
06888 }
06889
06890
06891 int ast_say_datetime_from_now_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06892 {
06893 int res=0;
06894 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
06895 int daydiff;
06896 struct ast_tm tm;
06897 struct ast_tm now;
06898 char fn[256];
06899
06900 ast_localtime(&when, &tm, NULL);
06901 ast_localtime(&nowtv, &now, NULL);
06902 daydiff = now.tm_yday - tm.tm_yday;
06903 if ((daydiff < 0) || (daydiff > 6)) {
06904
06905 if (!res) {
06906 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06907 res = ast_streamfile(chan, fn, lang);
06908 if (!res)
06909 res = ast_waitstream(chan, ints);
06910 }
06911 if (!res)
06912 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06913
06914 } else if (daydiff) {
06915
06916 if (!res) {
06917 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06918 res = ast_streamfile(chan, fn, lang);
06919 if (!res)
06920 res = ast_waitstream(chan, ints);
06921 }
06922 }
06923 if (!res)
06924 res = ast_say_time(chan, t, ints, lang);
06925 return res;
06926 }
06927
06928
06929 int ast_say_datetime_from_now_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06930 {
06931 int res=0;
06932 int daydiff;
06933 struct ast_tm tm;
06934 struct ast_tm now;
06935 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
06936 char fn[256];
06937
06938 ast_localtime(&when, &tm, NULL);
06939 ast_localtime(&nowtv, &now, NULL);
06940 daydiff = now.tm_yday - tm.tm_yday;
06941 if ((daydiff < 0) || (daydiff > 6)) {
06942
06943 if (!res)
06944 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06945 if (!res)
06946 res = wait_file(chan, ints, "digits/pt-de", lang);
06947 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06948 if (!res)
06949 res = wait_file(chan, ints, fn, lang);
06950
06951 } else if (daydiff) {
06952
06953 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06954 if (!res)
06955 res = wait_file(chan, ints, fn, lang);
06956 }
06957 if (!strcasecmp(lang, "pt_BR")) {
06958 if (tm.tm_hour > 1) {
06959 ast_copy_string(fn, "digits/pt-as", sizeof(fn));
06960 } else {
06961 ast_copy_string(fn, "digits/pt-a", sizeof(fn));
06962 }
06963 if (!res)
06964 res = wait_file(chan, ints, fn, lang);
06965 } else {
06966 ast_copy_string(fn, "digits/pt-ah", sizeof(fn));
06967 if (!res)
06968 res = wait_file(chan, ints, fn, lang);
06969 if (tm.tm_hour != 1)
06970 if (!res)
06971 res = wait_file(chan, ints, "digits/pt-sss", lang);
06972 if (!res)
06973 res = ast_say_time(chan, t, ints, lang);
06974 }
06975 return res;
06976 }
06977
06978
06979 int ast_say_datetime_from_now_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06980 {
06981 int res = 0;
06982 struct timeval nowt = ast_tvnow(), when = { t, 0 };
06983 int daydiff;
06984 struct ast_tm tm;
06985 struct ast_tm now;
06986 char fn[256];
06987
06988 ast_localtime(&when, &tm, NULL);
06989 ast_localtime(&nowt, &now, NULL);
06990 daydiff = now.tm_yday - tm.tm_yday;
06991 if ((daydiff < 0) || (daydiff > 6)) {
06992
06993 if (!res) {
06994 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06995 res = ast_streamfile(chan, fn, lang);
06996 if (!res)
06997 res = ast_waitstream(chan, ints);
06998 }
06999 if (!res) {
07000 res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
07001 }
07002 } else if (daydiff) {
07003
07004 if (!res) {
07005 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07006 res = ast_streamfile(chan, fn, lang);
07007 if (!res) {
07008 res = ast_waitstream(chan, ints);
07009 }
07010 }
07011 }
07012 if (!res) {
07013 res = ast_say_time(chan, t, ints, lang);
07014 }
07015 return res;
07016 }
07017
07018
07019
07020
07021
07022
07023
07024 static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang){
07025 int tmp;
07026 int left;
07027 int res;
07028 char fn[256] = "";
07029
07030
07031 if (num < 5) {
07032 snprintf(fn, sizeof(fn), "digits/female-%d", num);
07033 res = wait_file(chan, ints, fn, lang);
07034 } else if (num < 13) {
07035 res = ast_say_number(chan, num, ints, lang, (char *) NULL);
07036 } else if (num <100 ) {
07037 tmp = (num/10) * 10;
07038 left = num - tmp;
07039 snprintf(fn, sizeof(fn), "digits/%d", tmp);
07040 res = ast_streamfile(chan, fn, lang);
07041 if (!res)
07042 res = ast_waitstream(chan, ints);
07043 if (left)
07044 gr_say_number_female(left, chan, ints, lang);
07045
07046 } else {
07047 return -1;
07048 }
07049 return res;
07050 }
07051
07052
07053
07054
07055
07056
07057
07058
07059
07060
07061
07062
07063
07064
07065
07066
07067
07068
07069
07070 static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
07071 {
07072 int res = 0;
07073 char fn[256] = "";
07074 int i=0;
07075
07076
07077 if (!num) {
07078 ast_copy_string(fn, "digits/0", sizeof(fn));
07079 res = ast_streamfile(chan, fn, chan->language);
07080 if (!res)
07081 return ast_waitstream(chan, ints);
07082 }
07083
07084 while (!res && num ) {
07085 i++;
07086 if (num < 13) {
07087 snprintf(fn, sizeof(fn), "digits/%d", num);
07088 num = 0;
07089 } else if (num <= 100) {
07090
07091 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
07092 num %= 10;
07093 } else if (num < 200) {
07094
07095 snprintf(fn, sizeof(fn), "digits/hundred-100");
07096 num %= 100;
07097 } else if (num < 1000) {
07098
07099 snprintf(fn, sizeof(fn), "digits/hundred-%d", (num/100)*100);
07100 num %= 100;
07101 } else if (num < 2000){
07102 snprintf(fn, sizeof(fn), "digits/xilia");
07103 num %= 1000;
07104 } else {
07105
07106 if (num < 1000000) {
07107 res = ast_say_number_full_gr(chan, (num / 1000), ints, chan->language, audiofd, ctrlfd);
07108 if (res)
07109 return res;
07110 num %= 1000;
07111 snprintf(fn, sizeof(fn), "digits/thousands");
07112 } else {
07113 if (num < 1000000000) {
07114 res = ast_say_number_full_gr(chan, (num / 1000000), ints, chan->language, audiofd, ctrlfd);
07115 if (res)
07116 return res;
07117 num %= 1000000;
07118 snprintf(fn, sizeof(fn), "digits/millions");
07119 } else {
07120 ast_debug(1, "Number '%d' is too big for me\n", num);
07121 res = -1;
07122 }
07123 }
07124 }
07125 if (!res) {
07126 if (!ast_streamfile(chan, fn, language)) {
07127 if ((audiofd > -1) && (ctrlfd > -1))
07128 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
07129 else
07130 res = ast_waitstream(chan, ints);
07131 }
07132 ast_stopstream(chan);
07133 }
07134 }
07135 return res;
07136 }
07137
07138
07139
07140
07141
07142
07143
07144
07145
07146
07147
07148
07149
07150 static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07151 {
07152 struct ast_tm tm;
07153 struct timeval when = { t, 0 };
07154
07155 char fn[256];
07156 int res = 0;
07157
07158
07159 ast_localtime(&when, &tm, NULL);
07160
07161 if (!res) {
07162 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07163 res = ast_streamfile(chan, fn, lang);
07164 if (!res)
07165 res = ast_waitstream(chan, ints);
07166 }
07167
07168 if (!res) {
07169 gr_say_number_female(tm.tm_mday, chan, ints, lang);
07170 }
07171
07172 if (!res) {
07173 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07174 res = ast_streamfile(chan, fn, lang);
07175 if (!res)
07176 res = ast_waitstream(chan, ints);
07177 }
07178
07179 if (!res)
07180 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
07181 return res;
07182 }
07183
07184
07185
07186
07187
07188
07189
07190
07191
07192
07193
07194 static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07195 {
07196
07197 struct timeval when = { t, 0 };
07198 struct ast_tm tm;
07199 int res = 0;
07200 int hour, pm=0;
07201
07202 ast_localtime(&when, &tm, NULL);
07203 hour = tm.tm_hour;
07204
07205 if (!hour)
07206 hour = 12;
07207 else if (hour == 12)
07208 pm = 1;
07209 else if (hour > 12) {
07210 hour -= 12;
07211 pm = 1;
07212 }
07213
07214 res = gr_say_number_female(hour, chan, ints, lang);
07215 if (tm.tm_min) {
07216 if (!res)
07217 res = ast_streamfile(chan, "digits/kai", lang);
07218 if (!res)
07219 res = ast_waitstream(chan, ints);
07220 if (!res)
07221 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
07222 } else {
07223 if (!res)
07224 res = ast_streamfile(chan, "digits/hwra", lang);
07225 if (!res)
07226 res = ast_waitstream(chan, ints);
07227 }
07228 if (pm) {
07229 if (!res)
07230 res = ast_streamfile(chan, "digits/p-m", lang);
07231 } else {
07232 if (!res)
07233 res = ast_streamfile(chan, "digits/a-m", lang);
07234 }
07235 if (!res)
07236 res = ast_waitstream(chan, ints);
07237 return res;
07238 }
07239
07240
07241
07242 static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07243 {
07244 struct timeval when = { t, 0 };
07245 struct ast_tm tm;
07246 char fn[256];
07247 int res = 0;
07248
07249 ast_localtime(&when, &tm, NULL);
07250
07251
07252 if (!res) {
07253 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07254 res = ast_streamfile(chan, fn, lang);
07255 if (!res)
07256 res = ast_waitstream(chan, ints);
07257 }
07258
07259 if (!res) {
07260 gr_say_number_female(tm.tm_mday, chan, ints, lang);
07261 }
07262
07263 if (!res) {
07264 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07265 res = ast_streamfile(chan, fn, lang);
07266 if (!res)
07267 res = ast_waitstream(chan, ints);
07268 }
07269
07270 res = ast_say_time_gr(chan, t, ints, lang);
07271 return res;
07272 }
07273
07274 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)
07275 {
07276 struct timeval when = { t, 0 };
07277 struct ast_tm tm;
07278 int res=0, offset, sndoffset;
07279 char sndfile[256], nextmsg[256];
07280
07281 if (!format)
07282 format = "AdBY 'digits/at' IMp";
07283
07284 ast_localtime(&when, &tm, tzone);
07285
07286 for (offset=0 ; format[offset] != '\0' ; offset++) {
07287 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
07288 switch (format[offset]) {
07289
07290 case '\'':
07291
07292 sndoffset=0;
07293 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
07294 sndfile[sndoffset] = format[offset];
07295 sndfile[sndoffset] = '\0';
07296 res = wait_file(chan, ints, sndfile, lang);
07297 break;
07298 case 'A':
07299 case 'a':
07300
07301 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
07302 res = wait_file(chan, ints, nextmsg, lang);
07303 break;
07304 case 'B':
07305 case 'b':
07306 case 'h':
07307
07308 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
07309 res = wait_file(chan, ints, nextmsg, lang);
07310 break;
07311 case 'd':
07312 case 'e':
07313
07314 gr_say_number_female(tm.tm_mday, chan, ints, lang);
07315 break;
07316 case 'Y':
07317
07318
07319 ast_say_number_full_gr(chan, 1900+tm.tm_year, ints, chan->language, -1, -1);
07320 break;
07321 case 'I':
07322 case 'l':
07323
07324 if (tm.tm_hour == 0)
07325 gr_say_number_female(12, chan, ints, lang);
07326 else if (tm.tm_hour > 12)
07327 gr_say_number_female(tm.tm_hour - 12, chan, ints, lang);
07328 else
07329 gr_say_number_female(tm.tm_hour, chan, ints, lang);
07330 break;
07331 case 'H':
07332 case 'k':
07333
07334 gr_say_number_female(tm.tm_hour, chan, ints, lang);
07335 break;
07336 case 'M':
07337
07338 if (tm.tm_min) {
07339 if (!res)
07340 res = ast_streamfile(chan, "digits/kai", lang);
07341 if (!res)
07342 res = ast_waitstream(chan, ints);
07343 if (!res)
07344 res = ast_say_number_full_gr(chan, tm.tm_min, ints, lang, -1, -1);
07345 } else {
07346 if (!res)
07347 res = ast_streamfile(chan, "digits/oclock", lang);
07348 if (!res)
07349 res = ast_waitstream(chan, ints);
07350 }
07351 break;
07352 case 'P':
07353 case 'p':
07354
07355 if (tm.tm_hour > 11)
07356 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
07357 else
07358 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
07359 res = wait_file(chan, ints, nextmsg, lang);
07360 break;
07361 case 'Q':
07362
07363
07364
07365
07366 {
07367 struct timeval now = ast_tvnow();
07368 struct ast_tm tmnow;
07369 time_t beg_today;
07370
07371 ast_localtime(&now, &tmnow, tzone);
07372
07373
07374 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
07375 if (beg_today < t) {
07376
07377 res = wait_file(chan, ints, "digits/today", lang);
07378 } else if (beg_today - 86400 < t) {
07379
07380 res = wait_file(chan, ints, "digits/yesterday", lang);
07381 } else {
07382 res = ast_say_date_with_format_gr(chan, t, ints, lang, "AdBY", tzone);
07383 }
07384 }
07385 break;
07386 case 'q':
07387
07388
07389
07390
07391 {
07392 struct timeval now = ast_tvnow();
07393 struct ast_tm tmnow;
07394 time_t beg_today;
07395
07396 ast_localtime(&now, &tmnow, tzone);
07397
07398
07399 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
07400 if (beg_today < t) {
07401
07402 } else if ((beg_today - 86400) < t) {
07403
07404 res = wait_file(chan, ints, "digits/yesterday", lang);
07405 } else if (beg_today - 86400 * 6 < t) {
07406
07407 res = ast_say_date_with_format_gr(chan, t, ints, lang, "A", tzone);
07408 } else {
07409 res = ast_say_date_with_format_gr(chan, t, ints, lang, "AdBY", tzone);
07410 }
07411 }
07412 break;
07413 case 'R':
07414 res = ast_say_date_with_format_gr(chan, t, ints, lang, "HM", tzone);
07415 break;
07416 case 'S':
07417
07418 ast_copy_string(nextmsg, "digits/kai", sizeof(nextmsg));
07419 res = wait_file(chan, ints, nextmsg, lang);
07420 if (!res)
07421 res = ast_say_number_full_gr(chan, tm.tm_sec, ints, lang, -1, -1);
07422 if (!res)
07423 ast_copy_string(nextmsg, "digits/seconds", sizeof(nextmsg));
07424 res = wait_file(chan, ints, nextmsg, lang);
07425 break;
07426 case 'T':
07427 res = ast_say_date_with_format_gr(chan, t, ints, lang, "HMS", tzone);
07428 break;
07429 case ' ':
07430 case ' ':
07431
07432 break;
07433 default:
07434
07435 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
07436 }
07437
07438 if (res) {
07439 break;
07440 }
07441 }
07442 return res;
07443 }
07444
07445
07446
07447
07448
07449
07450
07451
07452
07453
07454
07455
07456
07457
07458
07459
07460
07461
07462
07463
07464
07465
07466
07467
07468
07469
07470
07471 static char* ast_translate_number_ka(int num, char* res, int res_len)
07472 {
07473 char buf[256];
07474 int digit = 0;
07475 int remaining = 0;
07476
07477
07478 if (num < 0) {
07479 strncat(res, "minus ", res_len - strlen(res) - 1);
07480 if ( num > INT_MIN ) {
07481 num = -num;
07482 } else {
07483 num = 0;
07484 }
07485 }
07486
07487
07488
07489 if (num <= 20 || num == 40 || num == 60 || num == 80 || num == 100) {
07490 snprintf(buf, sizeof(buf), "%d", num);
07491 strncat(res, buf, res_len - strlen(res) - 1);
07492 return res;
07493 }
07494
07495
07496 if (num < 40) {
07497 strncat(res, "20_ ", res_len - strlen(res) - 1);
07498 return ast_translate_number_ka(num - 20, res, res_len);
07499 }
07500
07501 if (num < 60) {
07502 strncat(res, "40_ ", res_len - strlen(res) - 1);
07503 return ast_translate_number_ka(num - 40, res, res_len);
07504 }
07505
07506 if (num < 80) {
07507 strncat(res, "60_ ", res_len - strlen(res) - 1);
07508 return ast_translate_number_ka(num - 60, res, res_len);
07509 }
07510
07511 if (num < 100) {
07512 strncat(res, "80_ ", res_len - strlen(res) - 1);
07513 return ast_translate_number_ka(num - 80, res, res_len);
07514 }
07515
07516
07517 if (num < 1000) {
07518 remaining = num % 100;
07519 digit = (num - remaining) / 100;
07520
07521 if (remaining == 0) {
07522 snprintf(buf, sizeof(buf), "%d", num);
07523 strncat(res, buf, res_len - strlen(res) - 1);
07524 return res;
07525 } else {
07526 snprintf(buf, sizeof(buf), "%d_ ", digit*100);
07527 strncat(res, buf, res_len - strlen(res) - 1);
07528 return ast_translate_number_ka(remaining, res, res_len);
07529 }
07530 }
07531
07532
07533 if (num == 1000) {
07534 strncat(res, "1000", res_len - strlen(res) - 1);
07535 return res;
07536 }
07537
07538
07539 if (num < 1000000) {
07540 remaining = num % 1000;
07541 digit = (num - remaining) / 1000;
07542
07543 if (remaining == 0) {
07544 ast_translate_number_ka(digit, res, res_len);
07545 strncat(res, " 1000", res_len - strlen(res) - 1);
07546 return res;
07547 }
07548
07549 if (digit == 1) {
07550 strncat(res, "1000_ ", res_len - strlen(res) - 1);
07551 return ast_translate_number_ka(remaining, res, res_len);
07552 }
07553
07554 ast_translate_number_ka(digit, res, res_len);
07555 strncat(res, " 1000_ ", res_len - strlen(res) - 1);
07556 return ast_translate_number_ka(remaining, res, res_len);
07557 }
07558
07559
07560 if (num == 1000000) {
07561 strncat(res, "1 1000000", res_len - strlen(res) - 1);
07562 return res;
07563 }
07564
07565
07566 if (num < 1000000000) {
07567 remaining = num % 1000000;
07568 digit = (num - remaining) / 1000000;
07569
07570 if (remaining == 0) {
07571 ast_translate_number_ka(digit, res, res_len);
07572 strncat(res, " 1000000", res_len - strlen(res) - 1);
07573 return res;
07574 }
07575
07576 ast_translate_number_ka(digit, res, res_len);
07577 strncat(res, " 1000000_ ", res_len - strlen(res) - 1);
07578 return ast_translate_number_ka(remaining, res, res_len);
07579 }
07580
07581
07582 if (num == 1000000000) {
07583 strncat(res, "1 1000000000", res_len - strlen(res) - 1);
07584 return res;
07585 }
07586
07587
07588 if (num > 1000000000) {
07589 remaining = num % 1000000000;
07590 digit = (num - remaining) / 1000000000;
07591
07592 if (remaining == 0) {
07593 ast_translate_number_ka(digit, res, res_len);
07594 strncat(res, " 1000000000", res_len - strlen(res) - 1);
07595 return res;
07596 }
07597
07598 ast_translate_number_ka(digit, res, res_len);
07599 strncat(res, " 1000000000_ ", res_len - strlen(res) - 1);
07600 return ast_translate_number_ka(remaining, res, res_len);
07601 }
07602
07603 return res;
07604
07605 }
07606
07607
07608
07609
07610 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)
07611 {
07612 int res = 0;
07613 char fn[512] = "";
07614 char* s = 0;
07615 const char* remaining = fn;
07616
07617 if (!num)
07618 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
07619
07620
07621 ast_translate_number_ka(num, fn, 512);
07622
07623
07624
07625 while (res == 0 && (s = strstr(remaining, " "))) {
07626 size_t len = s - remaining;
07627 char* new_string = ast_malloc(len + 1 + strlen("digits/"));
07628
07629 sprintf(new_string, "digits/");
07630 strncat(new_string, remaining, len);
07631
07632
07633 if (!ast_streamfile(chan, new_string, language)) {
07634 if ((audiofd > -1) && (ctrlfd > -1))
07635 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
07636 else
07637 res = ast_waitstream(chan, ints);
07638 }
07639 ast_stopstream(chan);
07640
07641 ast_free(new_string);
07642
07643 remaining = s + 1;
07644 while (*remaining == ' ')
07645 remaining++;
07646 }
07647
07648
07649
07650 if (res == 0 && *remaining) {
07651
07652 char* new_string = ast_malloc(strlen(remaining) + 1 + strlen("digits/"));
07653 sprintf(new_string, "digits/%s", remaining);
07654
07655 if (!ast_streamfile(chan, new_string, language)) {
07656 if ((audiofd > -1) && (ctrlfd > -1))
07657 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
07658 else
07659 res = ast_waitstream(chan, ints);
07660 }
07661 ast_stopstream(chan);
07662
07663 ast_free(new_string);
07664
07665 }
07666
07667
07668 return res;
07669
07670 }
07671
07672
07673
07674
07675
07676
07677
07678
07679
07680
07681
07682
07683
07684
07685
07686
07687 static int ast_say_date_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07688 {
07689 struct timeval when = { t, 0 };
07690 struct ast_tm tm;
07691 char fn[256];
07692 int res = 0;
07693 ast_localtime(&when, &tm, NULL);
07694
07695 if (!res)
07696 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
07697
07698 if (!res) {
07699 snprintf(fn, sizeof(fn), "digits/tslis %d", tm.tm_wday);
07700 res = ast_streamfile(chan, fn, lang);
07701 if (!res)
07702 res = ast_waitstream(chan, ints);
07703 }
07704
07705 if (!res) {
07706 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
07707
07708
07709
07710 }
07711
07712 if (!res) {
07713 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07714 res = ast_streamfile(chan, fn, lang);
07715 if (!res)
07716 res = ast_waitstream(chan, ints);
07717 }
07718 return res;
07719
07720 }
07721
07722
07723
07724
07725
07726
07727 static int ast_say_time_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07728 {
07729 struct timeval when = { t, 0 };
07730 struct ast_tm tm;
07731 int res = 0;
07732
07733 ast_localtime(&when, &tm, NULL);
07734
07735 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char*)NULL);
07736 if (!res) {
07737 res = ast_streamfile(chan, "digits/saati_da", lang);
07738 if (!res)
07739 res = ast_waitstream(chan, ints);
07740 }
07741
07742 if (tm.tm_min) {
07743 if (!res) {
07744 res = ast_say_number(chan, tm.tm_min, ints, lang, (char*)NULL);
07745
07746 if (!res) {
07747 res = ast_streamfile(chan, "digits/tsuti", lang);
07748 if (!res)
07749 res = ast_waitstream(chan, ints);
07750 }
07751 }
07752 }
07753 return res;
07754 }
07755
07756
07757
07758
07759 static int ast_say_datetime_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07760 {
07761 struct timeval when = { t, 0 };
07762 struct ast_tm tm;
07763 int res = 0;
07764
07765 ast_localtime(&when, &tm, NULL);
07766 res = ast_say_date(chan, t, ints, lang);
07767 if (!res)
07768 ast_say_time(chan, t, ints, lang);
07769 return res;
07770
07771 }
07772
07773
07774
07775
07776
07777 static int ast_say_datetime_from_now_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07778 {
07779 int res=0;
07780 int daydiff;
07781 struct ast_tm tm;
07782 struct ast_tm now;
07783 struct timeval when = { t, 0 }, nowt = ast_tvnow();
07784 char fn[256];
07785
07786 ast_localtime(&when, &tm, NULL);
07787 ast_localtime(&nowt, &now, NULL);
07788 daydiff = now.tm_yday - tm.tm_yday;
07789 if ((daydiff < 0) || (daydiff > 6)) {
07790
07791 if (!res)
07792 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
07793 if (!res) {
07794 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07795 res = ast_streamfile(chan, fn, lang);
07796 if (!res)
07797 res = ast_waitstream(chan, ints);
07798 }
07799
07800 } else if (daydiff) {
07801
07802 if (!res) {
07803 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07804 res = ast_streamfile(chan, fn, lang);
07805 if (!res)
07806 res = ast_waitstream(chan, ints);
07807 }
07808 }
07809 if (!res)
07810 res = ast_say_time(chan, t, ints, lang);
07811
07812 return res;
07813 }
07814
07815
07816
07817
07818
07819
07820
07821
07822
07823
07824
07825 static const char *counted_noun_ending_en(int num)
07826 {
07827 if (num == 1 || num == -1) {
07828 return "";
07829 } else {
07830 return "s";
07831 }
07832 }
07833
07834
07835
07836
07837
07838
07839
07840
07841
07842
07843 static const char *counted_noun_ending_slavic(int num)
07844 {
07845 if (num < 0) {
07846 num *= -1;
07847 }
07848 num %= 100;
07849 if (num >= 20) {
07850 num %= 10;
07851 }
07852 if (num == 1) {
07853 return "";
07854 }
07855 if (num > 0 && num < 5) {
07856 return "x1";
07857 } else {
07858 return "x2";
07859 }
07860 }
07861
07862 int ast_say_counted_noun(struct ast_channel *chan, int num, const char noun[])
07863 {
07864 char *temp;
07865 int temp_len;
07866 const char *ending;
07867 if (!strncasecmp(chan->language, "ru", 2)) {
07868 ending = counted_noun_ending_slavic(num);
07869 } else if (!strncasecmp(chan->language, "ua", 2)) {
07870 ending = counted_noun_ending_slavic(num);
07871 } else if (!strncasecmp(chan->language, "pl", 2)) {
07872 ending = counted_noun_ending_slavic(num);
07873 } else {
07874 ending = counted_noun_ending_en(num);
07875 }
07876 temp = alloca((temp_len = (strlen(noun) + strlen(ending) + 1)));
07877 snprintf(temp, temp_len, "%s%s", noun, ending);
07878 return ast_play_and_wait(chan, temp);
07879 }
07880
07881
07882
07883
07884
07885
07886
07887
07888 static const char *counted_adjective_ending_ru(int num, const char gender[])
07889 {
07890 if (num < 0) {
07891 num *= -1;
07892 }
07893 num %= 100;
07894 if (num >= 20) {
07895 num %= 10;
07896 }
07897 if (num == 1) {
07898 return gender ? gender : "";
07899 } else {
07900 return "x";
07901 }
07902 }
07903
07904 int ast_say_counted_adjective(struct ast_channel *chan, int num, const char adjective[], const char gender[])
07905 {
07906 char *temp;
07907 int temp_len;
07908 const char *ending;
07909 if (!strncasecmp(chan->language, "ru", 2)) {
07910 ending = counted_adjective_ending_ru(num, gender);
07911 } else if (!strncasecmp(chan->language, "ua", 2)) {
07912 ending = counted_adjective_ending_ru(num, gender);
07913 } else if (!strncasecmp(chan->language, "pl", 2)) {
07914 ending = counted_adjective_ending_ru(num, gender);
07915 } else {
07916 ending = "";
07917 }
07918 temp = alloca((temp_len = (strlen(adjective) + strlen(ending) + 1)));
07919 snprintf(temp, temp_len, "%s%s", adjective, ending);
07920 return ast_play_and_wait(chan, temp);
07921 }
07922
07923
07924
07925
07926
07927
07928 static void __attribute__((constructor)) __say_init(void)
07929 {
07930 ast_say_number_full = say_number_full;
07931 ast_say_enumeration_full = say_enumeration_full;
07932 ast_say_digit_str_full = say_digit_str_full;
07933 ast_say_character_str_full = say_character_str_full;
07934 ast_say_phonetic_str_full = say_phonetic_str_full;
07935 ast_say_datetime = say_datetime;
07936 ast_say_time = say_time;
07937 ast_say_date = say_date;
07938 ast_say_datetime_from_now = say_datetime_from_now;
07939 ast_say_date_with_format = say_date_with_format;
07940 }