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: 298962 $")
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
02196 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)
02197 {
02198 int playh = 0;
02199 int start = 1;
02200 char fn[256] = "";
02201 int cn = 1;
02202 int res = 0;
02203
02204 if (!num) {
02205 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02206 }
02207 if (options && !strncasecmp(options, "n", 1)) cn = -1;
02208
02209 while (num || playh) {
02210 if (num < 0) {
02211 ast_copy_string(fn, "digits/minus", sizeof(fn));
02212 if ( num > INT_MIN ) {
02213 num = -num;
02214 } else {
02215 num = 0;
02216 }
02217 } else if (playh) {
02218 ast_copy_string(fn, "digits/hundred", sizeof(fn));
02219 playh = 0;
02220 } else if (start && num < 200 && num > 99 && cn == -1) {
02221
02222 snprintf(fn, sizeof(fn), "digits/hundred");
02223 num -= 100;
02224 } else if (num == 1 && cn == -1) {
02225 ast_copy_string(fn, "digits/1N", sizeof(fn));
02226 num = 0;
02227 } else if (num < 20) {
02228 snprintf(fn, sizeof(fn), "digits/%d", num);
02229 num = 0;
02230 } else if (num < 100) {
02231 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
02232 num %= 10;
02233 } else if (num < 1000) {
02234
02235 snprintf(fn, sizeof(fn), "digits/%d", (num/100));
02236 playh++;
02237 num %= 100;
02238 } else if (num < 1000000) {
02239
02240 res = ast_say_number_full_se(chan, num / 1000, ints, language, "c", audiofd, ctrlfd);
02241 if (res) {
02242 return res;
02243 }
02244 num %= 1000;
02245 ast_copy_string(fn, "digits/thousand", sizeof(fn));
02246 } else if (num < 1000000000) {
02247
02248 res = ast_say_number_full_se(chan, num / 1000000, ints, language, "n", audiofd, ctrlfd);
02249 if (res) {
02250 return res;
02251 }
02252 num %= 1000000;
02253 ast_copy_string(fn, "digits/million", sizeof(fn));
02254 } else {
02255 ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
02256 return -1;
02257 }
02258
02259 if (!ast_streamfile(chan, fn, language)) {
02260 if ((audiofd > -1) && (ctrlfd > -1)) {
02261 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02262 } else {
02263 res = ast_waitstream(chan, ints);
02264 }
02265 ast_stopstream(chan);
02266 if (res) {
02267 return res;
02268 }
02269 }
02270 start = 0;
02271 }
02272 return 0;
02273 }
02274
02275
02276 static int ast_say_number_full_zh(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
02277 {
02278 int res = 0;
02279 int playh = 0;
02280 int playt = 0;
02281 int playz = 0;
02282 int last_length = 0;
02283 char buf[20] = "";
02284 char fn[256] = "";
02285 if (!num)
02286 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02287
02288 while (!res && (num || playh || playt || playz)) {
02289 if (num < 0) {
02290 ast_copy_string(fn, "digits/minus", sizeof(fn));
02291 if ( num > INT_MIN ) {
02292 num = -num;
02293 } else {
02294 num = 0;
02295 }
02296 } else if (playz) {
02297 snprintf(fn, sizeof(fn), "digits/0");
02298 last_length = 0;
02299 playz = 0;
02300 } else if (playh) {
02301 ast_copy_string(fn, "digits/hundred", sizeof(fn));
02302 playh = 0;
02303 } else if (playt) {
02304 snprintf(fn, sizeof(fn), "digits/thousand");
02305 playt = 0;
02306 } else if (num < 10) {
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 snprintf(fn, sizeof(fn), "digits/%d", num);
02314 num = 0;
02315 } else if (num < 100) {
02316 snprintf(buf, 10, "%d", num);
02317 if (last_length - strlen(buf) > 1 && last_length != 0) {
02318 last_length = strlen(buf);
02319 playz++;
02320 continue;
02321 }
02322 last_length = strlen(buf);
02323 snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
02324 num %= 10;
02325 } else {
02326 if (num < 1000){
02327 snprintf(buf, 10, "%d", num);
02328 if (last_length - strlen(buf) > 1 && last_length != 0) {
02329 last_length = strlen(buf);
02330 playz++;
02331 continue;
02332 }
02333 snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
02334 playh++;
02335 snprintf(buf, 10, "%d", num);
02336 ast_log(LOG_DEBUG, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
02337 last_length = strlen(buf);
02338 num -= ((num / 100) * 100);
02339 } else if (num < 10000){
02340 snprintf(buf, 10, "%d", num);
02341 snprintf(fn, sizeof(fn), "digits/%d", (num / 1000));
02342 playt++;
02343 snprintf(buf, 10, "%d", num);
02344 ast_log(LOG_DEBUG, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
02345 last_length = strlen(buf);
02346 num -= ((num / 1000) * 1000);
02347 } else if (num < 100000000) {
02348 res = ast_say_number_full_zh(chan, num / 10000, ints, language, audiofd, ctrlfd);
02349 if (res)
02350 return res;
02351 snprintf(buf, 10, "%d", num);
02352 ast_log(LOG_DEBUG, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
02353 num -= ((num / 10000) * 10000);
02354 last_length = strlen(buf);
02355 snprintf(fn, sizeof(fn), "digits/wan");
02356 } else {
02357 if (num < 1000000000) {
02358 res = ast_say_number_full_zh(chan, num / 100000000, ints, language, audiofd, ctrlfd);
02359 if (res)
02360 return res;
02361 snprintf(buf, 10, "%d", num);
02362 ast_log(LOG_DEBUG, "Number '%d' %d %d\n", num, (int)strlen(buf), last_length);
02363 last_length = strlen(buf);
02364 num -= ((num / 100000000) * 100000000);
02365 snprintf(fn, sizeof(fn), "digits/yi");
02366 } else {
02367 ast_debug(1, "Number '%d' is too big for me\n", num);
02368 res = -1;
02369 }
02370 }
02371 }
02372 if (!res) {
02373 if (!ast_streamfile(chan, fn, language)) {
02374 if ((audiofd > -1) && (ctrlfd > -1))
02375 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02376 else
02377 res = ast_waitstream(chan, ints);
02378 }
02379 ast_stopstream(chan);
02380 }
02381 }
02382 return res;
02383 }
02384
02385
02386
02387 static int get_lastdigits_ru(int num) {
02388 if (num < 20) {
02389 return num;
02390 } else if (num < 100) {
02391 return get_lastdigits_ru(num % 10);
02392 } else if (num < 1000) {
02393 return get_lastdigits_ru(num % 100);
02394 }
02395 return 0;
02396 }
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413 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)
02414 {
02415 int res = 0;
02416 int lastdigits = 0;
02417 char fn[256] = "";
02418 if (!num)
02419 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02420
02421 while (!res && (num)) {
02422 if (num < 0) {
02423 ast_copy_string(fn, "digits/minus", sizeof(fn));
02424 if ( num > INT_MIN ) {
02425 num = -num;
02426 } else {
02427 num = 0;
02428 }
02429 } else if (num < 20) {
02430 if (options && strlen(options) == 1 && num < 3) {
02431 snprintf(fn, sizeof(fn), "digits/%d%s", num, options);
02432 } else {
02433 snprintf(fn, sizeof(fn), "digits/%d", num);
02434 }
02435 num = 0;
02436 } else if (num < 100) {
02437 snprintf(fn, sizeof(fn), "digits/%d", num - (num % 10));
02438 num %= 10;
02439 } else if (num < 1000){
02440 snprintf(fn, sizeof(fn), "digits/%d", num - (num % 100));
02441 num %= 100;
02442 } else if (num < 1000000) {
02443 lastdigits = get_lastdigits_ru(num / 1000);
02444
02445 if (lastdigits < 3) {
02446 res = ast_say_number_full_ru(chan, num / 1000, ints, language, "f", audiofd, ctrlfd);
02447 } else {
02448 res = ast_say_number_full_ru(chan, num / 1000, ints, language, NULL, audiofd, ctrlfd);
02449 }
02450 if (res)
02451 return res;
02452 if (lastdigits == 1) {
02453 ast_copy_string(fn, "digits/thousand", sizeof(fn));
02454 } else if (lastdigits > 1 && lastdigits < 5) {
02455 ast_copy_string(fn, "digits/thousands-i", sizeof(fn));
02456 } else {
02457 ast_copy_string(fn, "digits/thousands", sizeof(fn));
02458 }
02459 num %= 1000;
02460 } else if (num < 1000000000) {
02461 lastdigits = get_lastdigits_ru(num / 1000000);
02462
02463 res = ast_say_number_full_ru(chan, num / 1000000, ints, language, NULL, audiofd, ctrlfd);
02464 if (res)
02465 return res;
02466 if (lastdigits == 1) {
02467 ast_copy_string(fn, "digits/million", sizeof(fn));
02468 } else if (lastdigits > 1 && lastdigits < 5) {
02469 ast_copy_string(fn, "digits/million-a", sizeof(fn));
02470 } else {
02471 ast_copy_string(fn, "digits/millions", sizeof(fn));
02472 }
02473 num %= 1000000;
02474 } else {
02475 ast_debug(1, "Number '%d' is too big for me\n", num);
02476 res = -1;
02477 }
02478 if (!res) {
02479 if (!ast_streamfile(chan, fn, language)) {
02480 if ((audiofd > -1) && (ctrlfd > -1))
02481 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02482 else
02483 res = ast_waitstream(chan, ints);
02484 }
02485 ast_stopstream(chan);
02486 }
02487 }
02488 return res;
02489 }
02490
02491 static int ast_say_number_full_th(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
02492 {
02493 int res = 0;
02494 int playh = 0;
02495 char fn[256] = "";
02496 if (!num)
02497 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02498
02499 while(!res && (num || playh)) {
02500 if (num < 0) {
02501 ast_copy_string(fn, "digits/lop", sizeof(fn));
02502 if ( num > INT_MIN ) {
02503 num = -num;
02504 } else {
02505 num = 0;
02506 }
02507 } else if (playh) {
02508 ast_copy_string(fn, "digits/roi", sizeof(fn));
02509 playh = 0;
02510 } else if (num < 100) {
02511 if ((num <= 20) || ((num % 10) == 1)) {
02512 snprintf(fn, sizeof(fn), "digits/%d", num);
02513 num = 0;
02514 } else {
02515 snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
02516 num %= 10;
02517 }
02518 } else if (num < 1000) {
02519 snprintf(fn, sizeof(fn), "digits/%d", (num/100));
02520 playh++;
02521 num %= 100;
02522 } else if (num < 10000) {
02523 res = ast_say_number_full_th(chan, num / 1000, ints, language, audiofd, ctrlfd);
02524 if (res)
02525 return res;
02526 num %= 1000;
02527 ast_copy_string(fn, "digits/pan", sizeof(fn));
02528 } else if (num < 100000) {
02529 res = ast_say_number_full_th(chan, num / 10000, ints, language, audiofd, ctrlfd);
02530 if (res)
02531 return res;
02532 num %= 10000;
02533 ast_copy_string(fn, "digits/muan", sizeof(fn));
02534 } else if (num < 1000000) {
02535 res = ast_say_number_full_th(chan, num / 100000, ints, language, audiofd, ctrlfd);
02536 if (res)
02537 return res;
02538 num %= 100000;
02539 ast_copy_string(fn, "digits/san", sizeof(fn));
02540 } else {
02541 res = ast_say_number_full_th(chan, num / 1000000, ints, language, audiofd, ctrlfd);
02542 if (res)
02543 return res;
02544 num %= 1000000;
02545 ast_copy_string(fn, "digits/larn", sizeof(fn));
02546 }
02547 if (!res) {
02548 if(!ast_streamfile(chan, fn, language)) {
02549 if ((audiofd > -1) && (ctrlfd > -1))
02550 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02551 else
02552 res = ast_waitstream(chan, ints);
02553 }
02554 ast_stopstream(chan);
02555 }
02556 }
02557 return res;
02558 }
02559
02560
02561
02562 static int say_enumeration_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
02563 {
02564 if (!strncasecmp(language, "en", 2)) {
02565 return ast_say_enumeration_full_en(chan, num, ints, language, audiofd, ctrlfd);
02566 } else if (!strncasecmp(language, "da", 2)) {
02567 return ast_say_enumeration_full_da(chan, num, ints, language, options, audiofd, ctrlfd);
02568 } else if (!strncasecmp(language, "de", 2)) {
02569 return ast_say_enumeration_full_de(chan, num, ints, language, options, audiofd, ctrlfd);
02570 } else if (!strncasecmp(language, "he", 2)) {
02571 return ast_say_enumeration_full_he(chan, num, ints, language, options, audiofd, ctrlfd);
02572 }
02573
02574
02575 return ast_say_enumeration_full_en(chan, num, ints, language, audiofd, ctrlfd);
02576 }
02577
02578
02579
02580 static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
02581 {
02582 int res = 0, t = 0;
02583 char fn[256] = "";
02584
02585 while (!res && num) {
02586 if (num < 0) {
02587 ast_copy_string(fn, "digits/minus", sizeof(fn));
02588 if ( num > INT_MIN ) {
02589 num = -num;
02590 } else {
02591 num = 0;
02592 }
02593 } else if (num < 20) {
02594 snprintf(fn, sizeof(fn), "digits/h-%d", num);
02595 num = 0;
02596 } else if (num < 100) {
02597 int tens = num / 10;
02598 num = num % 10;
02599 if (num == 0) {
02600 snprintf(fn, sizeof(fn), "digits/h-%d", (tens * 10));
02601 } else {
02602 snprintf(fn, sizeof(fn), "digits/%d", (tens * 10));
02603 }
02604 } else if (num < 1000) {
02605 int hundreds = num / 100;
02606 num = num % 100;
02607 if (hundreds > 1 || t == 1) {
02608 res = ast_say_number_full_en(chan, hundreds, ints, language, audiofd, ctrlfd);
02609 }
02610 if (res)
02611 return res;
02612 if (num) {
02613 ast_copy_string(fn, "digits/hundred", sizeof(fn));
02614 } else {
02615 ast_copy_string(fn, "digits/h-hundred", sizeof(fn));
02616 }
02617 } else if (num < 1000000) {
02618 int thousands = num / 1000;
02619 num = num % 1000;
02620 if (thousands > 1 || t == 1) {
02621 res = ast_say_number_full_en(chan, thousands, ints, language, audiofd, ctrlfd);
02622 }
02623 if (res)
02624 return res;
02625 if (num) {
02626 ast_copy_string(fn, "digits/thousand", sizeof(fn));
02627 } else {
02628 ast_copy_string(fn, "digits/h-thousand", sizeof(fn));
02629 }
02630 t = 1;
02631 } else if (num < 1000000000) {
02632 int millions = num / 1000000;
02633 num = num % 1000000;
02634 t = 1;
02635 res = ast_say_number_full_en(chan, millions, ints, language, audiofd, ctrlfd);
02636 if (res)
02637 return res;
02638 if (num) {
02639 ast_copy_string(fn, "digits/million", sizeof(fn));
02640 } else {
02641 ast_copy_string(fn, "digits/h-million", sizeof(fn));
02642 }
02643 } else if (num < INT_MAX) {
02644 int billions = num / 1000000000;
02645 num = num % 1000000000;
02646 t = 1;
02647 res = ast_say_number_full_en(chan, billions, ints, language, audiofd, ctrlfd);
02648 if (res)
02649 return res;
02650 if (num) {
02651 ast_copy_string(fn, "digits/billion", sizeof(fn));
02652 } else {
02653 ast_copy_string(fn, "digits/h-billion", sizeof(fn));
02654 }
02655 } else if (num == INT_MAX) {
02656 ast_copy_string(fn, "digits/h-last", sizeof(fn));
02657 num = 0;
02658 } else {
02659 ast_debug(1, "Number '%d' is too big for me\n", num);
02660 res = -1;
02661 }
02662
02663 if (!res) {
02664 if (!ast_streamfile(chan, fn, language)) {
02665 if ((audiofd > -1) && (ctrlfd > -1)) {
02666 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02667 } else {
02668 res = ast_waitstream(chan, ints);
02669 }
02670 }
02671 ast_stopstream(chan);
02672 }
02673 }
02674 return res;
02675 }
02676
02677
02678 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)
02679 {
02680
02681 int res = 0, t = 0;
02682 char fn[256] = "", fna[256] = "";
02683 char *gender;
02684
02685 if (options && !strncasecmp(options, "f", 1)) {
02686 gender = "F";
02687 } else if (options && !strncasecmp(options, "n", 1)) {
02688 gender = "N";
02689 } else {
02690 gender = "";
02691 }
02692
02693 if (!num)
02694 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02695
02696 while (!res && num) {
02697 if (num < 0) {
02698 ast_copy_string(fn, "digits/minus", sizeof(fn));
02699 if ( num > INT_MIN ) {
02700 num = -num;
02701 } else {
02702 num = 0;
02703 }
02704 } else if (num < 100 && t) {
02705 ast_copy_string(fn, "digits/and", sizeof(fn));
02706 t = 0;
02707 } else if (num < 20) {
02708 snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
02709 num = 0;
02710 } else if (num < 100) {
02711 int ones = num % 10;
02712 if (ones) {
02713 snprintf(fn, sizeof(fn), "digits/%d-and", ones);
02714 num -= ones;
02715 } else {
02716 snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
02717 num = 0;
02718 }
02719 } else if (num == 100 && t == 0) {
02720 snprintf(fn, sizeof(fn), "digits/h-hundred%s", gender);
02721 num = 0;
02722 } else if (num < 1000) {
02723 int hundreds = num / 100;
02724 num = num % 100;
02725 if (hundreds == 1) {
02726 ast_copy_string(fn, "digits/1N", sizeof(fn));
02727 } else {
02728 snprintf(fn, sizeof(fn), "digits/%d", hundreds);
02729 }
02730 if (num) {
02731 ast_copy_string(fna, "digits/hundred", sizeof(fna));
02732 } else {
02733 snprintf(fna, sizeof(fna), "digits/h-hundred%s", gender);
02734 }
02735 t = 1;
02736 } else if (num < 1000000) {
02737 int thousands = num / 1000;
02738 num = num % 1000;
02739 if (thousands == 1) {
02740 if (num) {
02741 ast_copy_string(fn, "digits/1N", sizeof(fn));
02742 ast_copy_string(fna, "digits/thousand", sizeof(fna));
02743 } else {
02744 if (t) {
02745 ast_copy_string(fn, "digits/1N", sizeof(fn));
02746 snprintf(fna, sizeof(fna), "digits/h-thousand%s", gender);
02747 } else {
02748 snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
02749 }
02750 }
02751 } else {
02752 res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
02753 if (res) {
02754 return res;
02755 }
02756 if (num) {
02757 ast_copy_string(fn, "digits/thousand", sizeof(fn));
02758 } else {
02759 snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
02760 }
02761 }
02762 t = 1;
02763 } else if (num < 1000000000) {
02764 int millions = num / 1000000;
02765 num = num % 1000000;
02766 if (millions == 1) {
02767 if (num) {
02768 ast_copy_string(fn, "digits/1F", sizeof(fn));
02769 ast_copy_string(fna, "digits/million", sizeof(fna));
02770 } else {
02771 ast_copy_string(fn, "digits/1N", sizeof(fn));
02772 snprintf(fna, sizeof(fna), "digits/h-million%s", gender);
02773 }
02774 } else {
02775 res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
02776 if (res) {
02777 return res;
02778 }
02779 if (num) {
02780 ast_copy_string(fn, "digits/millions", sizeof(fn));
02781 } else {
02782 snprintf(fn, sizeof(fn), "digits/h-million%s", gender);
02783 }
02784 }
02785 t = 1;
02786 } else if (num < INT_MAX) {
02787 int billions = num / 1000000000;
02788 num = num % 1000000000;
02789 if (billions == 1) {
02790 if (num) {
02791 ast_copy_string(fn, "digits/1F", sizeof(fn));
02792 ast_copy_string(fna, "digits/milliard", sizeof(fna));
02793 } else {
02794 ast_copy_string(fn, "digits/1N", sizeof(fn));
02795 snprintf(fna, sizeof(fna), "digits/h-milliard%s", gender);
02796 }
02797 } else {
02798 res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
02799 if (res)
02800 return res;
02801 if (num) {
02802 ast_copy_string(fn, "digits/milliards", sizeof(fna));
02803 } else {
02804 snprintf(fn, sizeof(fna), "digits/h-milliard%s", gender);
02805 }
02806 }
02807 t = 1;
02808 } else if (num == INT_MAX) {
02809 snprintf(fn, sizeof(fn), "digits/h-last%s", gender);
02810 num = 0;
02811 } else {
02812 ast_debug(1, "Number '%d' is too big for me\n", num);
02813 res = -1;
02814 }
02815
02816 if (!res) {
02817 if (!ast_streamfile(chan, fn, language)) {
02818 if ((audiofd > -1) && (ctrlfd > -1))
02819 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02820 else
02821 res = ast_waitstream(chan, ints);
02822 }
02823 ast_stopstream(chan);
02824 if (!res) {
02825 if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
02826 if ((audiofd > -1) && (ctrlfd > -1)) {
02827 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02828 } else {
02829 res = ast_waitstream(chan, ints);
02830 }
02831 }
02832 ast_stopstream(chan);
02833 strcpy(fna, "");
02834 }
02835 }
02836 }
02837 return res;
02838 }
02839
02840
02841 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)
02842 {
02843
02844 int res = 0, t = 0;
02845 char fn[256] = "", fna[256] = "";
02846 char *gender;
02847
02848 if (options && !strncasecmp(options, "f", 1)) {
02849 gender = "F";
02850 } else if (options && !strncasecmp(options, "n", 1)) {
02851 gender = "N";
02852 } else {
02853 gender = "";
02854 }
02855
02856 if (!num)
02857 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
02858
02859 while (!res && num) {
02860 if (num < 0) {
02861 ast_copy_string(fn, "digits/minus", sizeof(fn));
02862 if ( num > INT_MIN ) {
02863 num = -num;
02864 } else {
02865 num = 0;
02866 }
02867 } else if (num < 100 && t) {
02868 ast_copy_string(fn, "digits/and", sizeof(fn));
02869 t = 0;
02870 } else if (num < 20) {
02871 snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
02872 num = 0;
02873 } else if (num < 100) {
02874 int ones = num % 10;
02875 if (ones) {
02876 snprintf(fn, sizeof(fn), "digits/%d-and", ones);
02877 num -= ones;
02878 } else {
02879 snprintf(fn, sizeof(fn), "digits/h-%d%s", num, gender);
02880 num = 0;
02881 }
02882 } else if (num == 100 && t == 0) {
02883 snprintf(fn, sizeof(fn), "digits/h-hundred%s", gender);
02884 num = 0;
02885 } else if (num < 1000) {
02886 int hundreds = num / 100;
02887 num = num % 100;
02888 if (hundreds == 1) {
02889 ast_copy_string(fn, "digits/1N", sizeof(fn));
02890 } else {
02891 snprintf(fn, sizeof(fn), "digits/%d", hundreds);
02892 }
02893 if (num) {
02894 ast_copy_string(fna, "digits/hundred", sizeof(fna));
02895 } else {
02896 snprintf(fna, sizeof(fna), "digits/h-hundred%s", gender);
02897 }
02898 t = 1;
02899 } else if (num < 1000000) {
02900 int thousands = num / 1000;
02901 num = num % 1000;
02902 if (thousands == 1) {
02903 if (num) {
02904 ast_copy_string(fn, "digits/1N", sizeof(fn));
02905 ast_copy_string(fna, "digits/thousand", sizeof(fna));
02906 } else {
02907 if (t) {
02908 ast_copy_string(fn, "digits/1N", sizeof(fn));
02909 snprintf(fna, sizeof(fna), "digits/h-thousand%s", gender);
02910 } else {
02911 snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
02912 }
02913 }
02914 } else {
02915 res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
02916 if (res) {
02917 return res;
02918 }
02919 if (num) {
02920 ast_copy_string(fn, "digits/thousand", sizeof(fn));
02921 } else {
02922 snprintf(fn, sizeof(fn), "digits/h-thousand%s", gender);
02923 }
02924 }
02925 t = 1;
02926 } else if (num < 1000000000) {
02927 int millions = num / 1000000;
02928 num = num % 1000000;
02929 if (millions == 1) {
02930 if (num) {
02931 ast_copy_string(fn, "digits/1F", sizeof(fn));
02932 ast_copy_string(fna, "digits/million", sizeof(fna));
02933 } else {
02934 ast_copy_string(fn, "digits/1N", sizeof(fn));
02935 snprintf(fna, sizeof(fna), "digits/h-million%s", gender);
02936 }
02937 } else {
02938 res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
02939 if (res) {
02940 return res;
02941 }
02942 if (num) {
02943 ast_copy_string(fn, "digits/millions", sizeof(fn));
02944 } else {
02945 snprintf(fn, sizeof(fn), "digits/h-million%s", gender);
02946 }
02947 }
02948 t = 1;
02949 } else if (num < INT_MAX) {
02950 int billions = num / 1000000000;
02951 num = num % 1000000000;
02952 if (billions == 1) {
02953 if (num) {
02954 ast_copy_string(fn, "digits/1F", sizeof(fn));
02955 ast_copy_string(fna, "digits/milliard", sizeof(fna));
02956 } else {
02957 ast_copy_string(fn, "digits/1N", sizeof(fn));
02958 snprintf(fna, sizeof(fna), "digits/h-milliard%s", gender);
02959 }
02960 } else {
02961 res = ast_say_number_full_de(chan, billions, ints, language, options, audiofd, ctrlfd);
02962 if (res)
02963 return res;
02964 if (num) {
02965 ast_copy_string(fn, "digits/milliards", sizeof(fna));
02966 } else {
02967 snprintf(fn, sizeof(fna), "digits/h-milliard%s", gender);
02968 }
02969 }
02970 t = 1;
02971 } else if (num == INT_MAX) {
02972 snprintf(fn, sizeof(fn), "digits/h-last%s", gender);
02973 num = 0;
02974 } else {
02975 ast_debug(1, "Number '%d' is too big for me\n", num);
02976 res = -1;
02977 }
02978
02979 if (!res) {
02980 if (!ast_streamfile(chan, fn, language)) {
02981 if ((audiofd > -1) && (ctrlfd > -1))
02982 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02983 else
02984 res = ast_waitstream(chan, ints);
02985 }
02986 ast_stopstream(chan);
02987 if (!res) {
02988 if (strlen(fna) != 0 && !ast_streamfile(chan, fna, language)) {
02989 if ((audiofd > -1) && (ctrlfd > -1)) {
02990 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
02991 } else {
02992 res = ast_waitstream(chan, ints);
02993 }
02994 }
02995 ast_stopstream(chan);
02996 strcpy(fna, "");
02997 }
02998 }
02999 }
03000 return res;
03001 }
03002
03003 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)
03004 {
03005 int res = 0;
03006 char fn[256] = "";
03007 int mf = -1;
03008 ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: started. num: %d, options=\"%s\"\n", num, options);
03009
03010 if (options && !strncasecmp(options, "m", 1)) {
03011 mf = -1;
03012 }
03013
03014 ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: num: %d, options=\"%s\", mf=%d\n", num, options, mf);
03015
03016 while (!res && num) {
03017 if (num < 0) {
03018 snprintf(fn, sizeof(fn), "digits/minus");
03019 if (num > INT_MIN) {
03020 num = -num;
03021 } else {
03022 num = 0;
03023 }
03024 } else if (num < 21) {
03025 if (mf < 0) {
03026 if (num < 10) {
03027 snprintf(fn, sizeof(fn), "digits/f-0%d", num);
03028 } else {
03029 snprintf(fn, sizeof(fn), "digits/f-%d", num);
03030 }
03031 } else {
03032 if (num < 10) {
03033 snprintf(fn, sizeof(fn), "digits/m-0%d", num);
03034 } else {
03035 snprintf(fn, sizeof(fn), "digits/m-%d", num);
03036 }
03037 }
03038 num = 0;
03039 } else if ((num < 100) && num >= 20) {
03040 snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
03041 num = num % 10;
03042 } else if ((num >= 100) && (num < 1000)) {
03043 int tmpnum = num / 100;
03044 snprintf(fn, sizeof(fn), "digits/%d00", tmpnum);
03045 num = num - (tmpnum * 100);
03046 } else if ((num >= 1000) && (num < 10000)) {
03047 int tmpnum = num / 1000;
03048 snprintf(fn, sizeof(fn), "digits/%dk", tmpnum);
03049 num = num - (tmpnum * 1000);
03050 } else if (num < 20000) {
03051 snprintf(fn, sizeof(fn), "digits/m-%d", (num / 1000));
03052 num = num % 1000;
03053 } else if (num < 1000000) {
03054 res = ast_say_number_full_he(chan, num / 1000, ints, language, "m", audiofd, ctrlfd);
03055 if (res) {
03056 return res;
03057 }
03058 snprintf(fn, sizeof(fn), "digits/1k");
03059 num = num % 1000;
03060 } else if (num < 2000000) {
03061 snprintf(fn, sizeof(fn), "digits/1m");
03062 num = num % 1000000;
03063 } else if (num < 3000000) {
03064 snprintf(fn, sizeof(fn), "digits/2m");
03065 num = num - 2000000;
03066 } else if (num < 1000000000) {
03067 res = ast_say_number_full_he(chan, num / 1000000, ints, language, "m", audiofd, ctrlfd);
03068 if (res) {
03069 return res;
03070 }
03071 snprintf(fn, sizeof(fn), "digits/1m");
03072 num = num % 1000000;
03073 } else {
03074 ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
03075 res = -1;
03076 }
03077 if (!res) {
03078 if (!ast_streamfile(chan, fn, language)) {
03079 if ((audiofd > -1) && (ctrlfd > -1)) {
03080 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
03081 } else {
03082 res = ast_waitstream(chan, ints);
03083 }
03084 }
03085 ast_stopstream(chan);
03086 }
03087 }
03088 return res;
03089 }
03090
03091 static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03092 {
03093 if (!strncasecmp(lang, "en", 2)) {
03094 return ast_say_date_en(chan, t, ints, lang);
03095 } else if (!strncasecmp(lang, "da", 2)) {
03096 return ast_say_date_da(chan, t, ints, lang);
03097 } else if (!strncasecmp(lang, "de", 2)) {
03098 return ast_say_date_de(chan, t, ints, lang);
03099 } else if (!strncasecmp(lang, "fr", 2)) {
03100 return ast_say_date_fr(chan, t, ints, lang);
03101 } else if (!strncasecmp(lang, "ge", 2)) {
03102 static int deprecation_warning = 0;
03103 if (deprecation_warning++ % 10 == 0) {
03104 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
03105 }
03106 return ast_say_date_ka(chan, t, ints, lang);
03107 } else if (!strncasecmp(lang, "gr", 2)) {
03108 return ast_say_date_gr(chan, t, ints, lang);
03109 } else if (!strncasecmp(lang, "he", 2)) {
03110 return ast_say_date_he(chan, t, ints, lang);
03111 } else if (!strncasecmp(lang, "hu", 2)) {
03112 return ast_say_date_hu(chan, t, ints, lang);
03113 } else if (!strncasecmp(lang, "ka", 2)) {
03114 return ast_say_date_ka(chan, t, ints, lang);
03115 } else if (!strncasecmp(lang, "nl", 2)) {
03116 return ast_say_date_nl(chan, t, ints, lang);
03117 } else if (!strncasecmp(lang, "pt", 2)) {
03118 return ast_say_date_pt(chan, t, ints, lang);
03119 } else if (!strncasecmp(lang, "th", 2)) {
03120 return ast_say_date_th(chan, t, ints, lang);
03121 }
03122
03123
03124 return ast_say_date_en(chan, t, ints, lang);
03125 }
03126
03127
03128 int ast_say_date_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03129 {
03130 struct ast_tm tm;
03131 struct timeval when = { t, 0 };
03132 char fn[256];
03133 int res = 0;
03134 ast_localtime(&when, &tm, NULL);
03135 if (!res) {
03136 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03137 res = ast_streamfile(chan, fn, lang);
03138 if (!res)
03139 res = ast_waitstream(chan, ints);
03140 }
03141 if (!res) {
03142 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03143 res = ast_streamfile(chan, fn, lang);
03144 if (!res)
03145 res = ast_waitstream(chan, ints);
03146 }
03147 if (!res)
03148 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03149 if (!res)
03150 res = ast_waitstream(chan, ints);
03151 if (!res)
03152 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03153 return res;
03154 }
03155
03156
03157 int ast_say_date_da(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03158 {
03159 struct timeval when = { t, 0 };
03160 struct ast_tm tm;
03161 char fn[256];
03162 int res = 0;
03163 ast_localtime(&when, &tm, NULL);
03164 if (!res) {
03165 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03166 res = ast_streamfile(chan, fn, lang);
03167 if (!res)
03168 res = ast_waitstream(chan, ints);
03169 }
03170 if (!res)
03171 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03172 if (!res)
03173 res = ast_waitstream(chan, ints);
03174 if (!res) {
03175 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03176 res = ast_streamfile(chan, fn, lang);
03177 if (!res)
03178 res = ast_waitstream(chan, ints);
03179 }
03180 if (!res) {
03181
03182 int year = tm.tm_year + 1900;
03183 if (year > 1999) {
03184 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
03185 } else {
03186 if (year < 1100) {
03187
03188
03189 } else {
03190
03191 snprintf(fn, sizeof(fn), "digits/%d", (year / 100));
03192 res = wait_file(chan, ints, fn, lang);
03193 if (!res) {
03194 res = wait_file(chan, ints, "digits/hundred", lang);
03195 if (!res && year % 100 != 0) {
03196 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
03197 }
03198 }
03199 }
03200 }
03201 }
03202 return res;
03203 }
03204
03205
03206 int ast_say_date_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03207 {
03208 struct timeval when = { t, 0 };
03209 struct ast_tm tm;
03210 char fn[256];
03211 int res = 0;
03212 ast_localtime(&when, &tm, NULL);
03213 if (!res) {
03214 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03215 res = ast_streamfile(chan, fn, lang);
03216 if (!res)
03217 res = ast_waitstream(chan, ints);
03218 }
03219 if (!res)
03220 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03221 if (!res)
03222 res = ast_waitstream(chan, ints);
03223 if (!res) {
03224 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03225 res = ast_streamfile(chan, fn, lang);
03226 if (!res)
03227 res = ast_waitstream(chan, ints);
03228 }
03229 if (!res) {
03230
03231 int year = tm.tm_year + 1900;
03232 if (year > 1999) {
03233 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
03234 } else {
03235 if (year < 1100) {
03236
03237
03238 } else {
03239
03240
03241 snprintf(fn, sizeof(fn), "digits/%d", (year / 100) );
03242 res = wait_file(chan, ints, fn, lang);
03243 if (!res) {
03244 res = wait_file(chan, ints, "digits/hundred", lang);
03245 if (!res && year % 100 != 0) {
03246 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
03247 }
03248 }
03249 }
03250 }
03251 }
03252 return res;
03253 }
03254
03255
03256 int ast_say_date_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03257 {
03258 struct timeval when = { t, 0 };
03259 struct ast_tm tm;
03260 char fn[256];
03261 int res = 0;
03262 ast_localtime(&when, &tm, NULL);
03263
03264 if (!res)
03265 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03266 if (!res)
03267 res = ast_waitstream(chan, ints);
03268 if (!res) {
03269 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03270 res = ast_streamfile(chan, fn, lang);
03271 if (!res)
03272 res = ast_waitstream(chan, ints);
03273 }
03274 if (!res)
03275 ast_say_number(chan, tm.tm_mday , ints, lang, (char *) NULL);
03276 if (!res)
03277 res = ast_waitstream(chan, ints);
03278 if (!res) {
03279 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03280 res = ast_streamfile(chan, fn, lang);
03281 if (!res)
03282 res = ast_waitstream(chan, ints);
03283 }
03284 return res;
03285 }
03286
03287
03288 int ast_say_date_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03289 {
03290 struct timeval when = { t, 0 };
03291 struct ast_tm tm;
03292 char fn[256];
03293 int res = 0;
03294 ast_localtime(&when, &tm, NULL);
03295 if (!res) {
03296 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03297 res = ast_streamfile(chan, fn, lang);
03298 if (!res)
03299 res = ast_waitstream(chan, ints);
03300 }
03301 if (!res)
03302 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03303 if (!res)
03304 res = ast_waitstream(chan, ints);
03305 if (!res) {
03306 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03307 res = ast_streamfile(chan, fn, lang);
03308 if (!res)
03309 res = ast_waitstream(chan, ints);
03310 }
03311 if (!res)
03312 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03313 return res;
03314 }
03315
03316
03317 int ast_say_date_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03318 {
03319 struct timeval when = { t, 0 };
03320 struct ast_tm tm;
03321 char fn[256];
03322 int res = 0;
03323 ast_localtime(&when, &tm, NULL);
03324 if (!res) {
03325 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03326 res = ast_streamfile(chan, fn, lang);
03327 if (!res)
03328 res = ast_waitstream(chan, ints);
03329 }
03330 if (!res)
03331 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03332 if (!res) {
03333 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03334 res = ast_streamfile(chan, fn, lang);
03335 if (!res)
03336 res = ast_waitstream(chan, ints);
03337 }
03338 if (!res)
03339 res = ast_waitstream(chan, ints);
03340 if (!res)
03341 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03342 return res;
03343 }
03344
03345
03346 int ast_say_date_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03347 {
03348 struct timeval when = { t, 0 };
03349 struct ast_tm tm;
03350 char fn[256];
03351 int res = 0;
03352 ast_localtime(&when, &tm, NULL);
03353 if (!res) {
03354 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03355 res = ast_streamfile(chan, fn, lang);
03356 ast_copy_string(fn, "digits/tee", sizeof(fn));
03357 res = ast_streamfile(chan, fn, lang);
03358 if (!res)
03359 res = ast_waitstream(chan, ints);
03360 }
03361 if (!res)
03362 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
03363 if (!res)
03364 res = ast_waitstream(chan, ints);
03365 if (!res) {
03366 ast_copy_string(fn, "digits/duan", sizeof(fn));
03367 res = ast_streamfile(chan, fn, lang);
03368 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03369 res = ast_streamfile(chan, fn, lang);
03370 if (!res)
03371 res = ast_waitstream(chan, ints);
03372 }
03373 if (!res){
03374 ast_copy_string(fn, "digits/posor", sizeof(fn));
03375 res = ast_streamfile(chan, fn, lang);
03376 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03377 }
03378 return res;
03379 }
03380
03381
03382 int ast_say_date_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03383 {
03384 struct timeval when = { t, 0 };
03385 struct ast_tm tm;
03386 char fn[256];
03387 int res = 0;
03388
03389 ast_localtime(&when, &tm, NULL);
03390 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03391 if (!res)
03392 res = wait_file(chan, ints, fn, lang);
03393 if (!res)
03394 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
03395 if (!res)
03396 res = wait_file(chan, ints, "digits/pt-de", lang);
03397 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03398 if (!res)
03399 res = wait_file(chan, ints, fn, lang);
03400 if (!res)
03401 res = wait_file(chan, ints, "digits/pt-de", lang);
03402 if (!res)
03403 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03404
03405 return res;
03406 }
03407
03408
03409 int ast_say_date_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
03410 {
03411 struct timeval when = { t, 0 };
03412 struct ast_tm tm;
03413 char fn[256];
03414 int res = 0;
03415 ast_localtime(&when, &tm, NULL);
03416 if (!res) {
03417 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
03418 res = ast_streamfile(chan, fn, lang);
03419 if (!res) {
03420 res = ast_waitstream(chan, ints);
03421 }
03422 }
03423 if (!res) {
03424 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
03425 res = ast_streamfile(chan, fn, lang);
03426 if (!res) {
03427 res = ast_waitstream(chan, ints);
03428 }
03429 }
03430 if (!res) {
03431 res = ast_say_number(chan, tm.tm_mday, ints, lang, "m");
03432 }
03433 if (!res) {
03434 res = ast_waitstream(chan, ints);
03435 }
03436 if (!res) {
03437 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "m");
03438 }
03439 return res;
03440 }
03441
03442 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)
03443 {
03444 if (!strncasecmp(lang, "en", 2)) {
03445 return ast_say_date_with_format_en(chan, t, ints, lang, format, tzone);
03446 } else if (!strncasecmp(lang, "da", 2)) {
03447 return ast_say_date_with_format_da(chan, t, ints, lang, format, tzone);
03448 } else if (!strncasecmp(lang, "de", 2)) {
03449 return ast_say_date_with_format_de(chan, t, ints, lang, format, tzone);
03450 } else if (!strncasecmp(lang, "es", 2)) {
03451 return ast_say_date_with_format_es(chan, t, ints, lang, format, tzone);
03452 } else if (!strncasecmp(lang, "he", 2)) {
03453 return ast_say_date_with_format_he(chan, t, ints, lang, format, tzone);
03454 } else if (!strncasecmp(lang, "fr", 2)) {
03455 return ast_say_date_with_format_fr(chan, t, ints, lang, format, tzone);
03456 } else if (!strncasecmp(lang, "gr", 2)) {
03457 return ast_say_date_with_format_gr(chan, t, ints, lang, format, tzone);
03458 } else if (!strncasecmp(lang, "it", 2)) {
03459 return ast_say_date_with_format_it(chan, t, ints, lang, format, tzone);
03460 } else if (!strncasecmp(lang, "mx", 2)) {
03461 static int deprecation_warning = 0;
03462 if (deprecation_warning++ % 10 == 0) {
03463 ast_log(LOG_WARNING, "mx is not a standard language code. Please switch to using es_MX instead.\n");
03464 }
03465 return ast_say_date_with_format_es(chan, t, ints, lang, format, tzone);
03466 } else if (!strncasecmp(lang, "nl", 2)) {
03467 return ast_say_date_with_format_nl(chan, t, ints, lang, format, tzone);
03468 } else if (!strncasecmp(lang, "pl", 2)) {
03469 return ast_say_date_with_format_pl(chan, t, ints, lang, format, tzone);
03470 } else if (!strncasecmp(lang, "pt", 2)) {
03471 return ast_say_date_with_format_pt(chan, t, ints, lang, format, tzone);
03472 } else if (!strncasecmp(lang, "th", 2)) {
03473 return ast_say_date_with_format_th(chan, t, ints, lang, format, tzone);
03474 } else if (!strncasecmp(lang, "tw", 2)) {
03475 static int deprecation_warning = 0;
03476 if (deprecation_warning++ % 10 == 0) {
03477 ast_log(LOG_WARNING, "tw is a standard language code for Twi, not Taiwanese. Please switch to using zh_TW instead.\n");
03478 }
03479 return ast_say_date_with_format_zh(chan, t, ints, lang, format, tzone);
03480 } else if (!strncasecmp(lang, "zh", 2)) {
03481 return ast_say_date_with_format_zh(chan, t, ints, lang, format, tzone);
03482 }
03483
03484
03485 return ast_say_date_with_format_en(chan, t, ints, lang, format, tzone);
03486 }
03487
03488
03489 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)
03490 {
03491 struct timeval when = { t, 0 };
03492 struct ast_tm tm;
03493 int res=0, offset, sndoffset;
03494 char sndfile[256], nextmsg[256];
03495
03496 if (format == NULL)
03497 format = "ABdY 'digits/at' IMp";
03498
03499 ast_localtime(&when, &tm, tzone);
03500
03501 for (offset=0 ; format[offset] != '\0' ; offset++) {
03502 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
03503 switch (format[offset]) {
03504
03505 case '\'':
03506
03507 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
03508 sndfile[sndoffset] = format[offset];
03509 }
03510 sndfile[sndoffset] = '\0';
03511 res = wait_file(chan, ints, sndfile, lang);
03512 break;
03513 case 'A':
03514 case 'a':
03515
03516 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
03517 res = wait_file(chan, ints, nextmsg, lang);
03518 break;
03519 case 'B':
03520 case 'b':
03521 case 'h':
03522
03523 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
03524 res = wait_file(chan, ints, nextmsg, lang);
03525 break;
03526 case 'm':
03527
03528 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
03529 break;
03530 case 'd':
03531 case 'e':
03532
03533 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, (char *) NULL);
03534 break;
03535 case 'Y':
03536
03537 if (tm.tm_year > 99) {
03538 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
03539 } else if (tm.tm_year < 1) {
03540
03541
03542 } else {
03543 res = wait_file(chan, ints, "digits/19", lang);
03544 if (!res) {
03545 if (tm.tm_year <= 9) {
03546
03547 res = wait_file(chan, ints, "digits/oh", lang);
03548 }
03549
03550 res |= ast_say_number(chan, tm.tm_year, ints, lang, (char *) NULL);
03551 }
03552 }
03553 break;
03554 case 'I':
03555 case 'l':
03556
03557 if (tm.tm_hour == 0)
03558 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
03559 else if (tm.tm_hour > 12)
03560 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
03561 else
03562 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
03563 res = wait_file(chan, ints, nextmsg, lang);
03564 break;
03565 case 'H':
03566 case 'k':
03567
03568 if (format[offset] == 'H') {
03569
03570 if (tm.tm_hour < 10) {
03571 res = wait_file(chan, ints, "digits/oh", lang);
03572 }
03573 } else {
03574
03575 if (tm.tm_hour == 0) {
03576 res = wait_file(chan, ints, "digits/oh", lang);
03577 }
03578 }
03579 if (!res) {
03580 if (tm.tm_hour != 0) {
03581 int remaining = tm.tm_hour;
03582 if (tm.tm_hour > 20) {
03583 res = wait_file(chan, ints, "digits/20", lang);
03584 remaining -= 20;
03585 }
03586 if (!res) {
03587 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
03588 res = wait_file(chan, ints, nextmsg, lang);
03589 }
03590 }
03591 }
03592 break;
03593 case 'M':
03594 case 'N':
03595
03596 if (tm.tm_min == 0) {
03597 if (format[offset] == 'M') {
03598 res = wait_file(chan, ints, "digits/oclock", lang);
03599 } else {
03600 res = wait_file(chan, ints, "digits/hundred", lang);
03601 }
03602 } else if (tm.tm_min < 10) {
03603 res = wait_file(chan, ints, "digits/oh", lang);
03604 if (!res) {
03605 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min);
03606 res = wait_file(chan, ints, nextmsg, lang);
03607 }
03608 } else {
03609 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
03610 }
03611 break;
03612 case 'P':
03613 case 'p':
03614
03615 if (tm.tm_hour > 11)
03616 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
03617 else
03618 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
03619 res = wait_file(chan, ints, nextmsg, lang);
03620 break;
03621 case 'Q':
03622
03623
03624
03625
03626 {
03627 struct timeval now = ast_tvnow();
03628 struct ast_tm tmnow;
03629 time_t beg_today;
03630
03631 gettimeofday(&now, NULL);
03632 ast_localtime(&now, &tmnow, tzone);
03633
03634
03635 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03636 if (beg_today < t) {
03637
03638 res = wait_file(chan, ints, "digits/today", lang);
03639 } else if (beg_today - 86400 < t) {
03640
03641 res = wait_file(chan, ints, "digits/yesterday", lang);
03642 } else if (beg_today - 86400 * 6 < t) {
03643
03644 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
03645 } else if (beg_today - 2628000 < t) {
03646
03647 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
03648 } else if (beg_today - 15768000 < t) {
03649
03650 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
03651 } else {
03652
03653 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
03654 }
03655 }
03656 break;
03657 case 'q':
03658
03659
03660
03661
03662 {
03663 struct timeval now;
03664 struct ast_tm tmnow;
03665 time_t beg_today;
03666
03667 now = ast_tvnow();
03668 ast_localtime(&now, &tmnow, tzone);
03669
03670
03671 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03672 if (beg_today < t) {
03673
03674 } else if ((beg_today - 86400) < t) {
03675
03676 res = wait_file(chan, ints, "digits/yesterday", lang);
03677 } else if (beg_today - 86400 * 6 < t) {
03678
03679 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
03680 } else if (beg_today - 2628000 < t) {
03681
03682 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
03683 } else if (beg_today - 15768000 < t) {
03684
03685 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
03686 } else {
03687
03688 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
03689 }
03690 }
03691 break;
03692 case 'R':
03693 res = ast_say_date_with_format_en(chan, t, ints, lang, "HM", tzone);
03694 break;
03695 case 'S':
03696
03697 if (tm.tm_sec == 0) {
03698 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
03699 res = wait_file(chan, ints, nextmsg, lang);
03700 } else if (tm.tm_sec < 10) {
03701 res = wait_file(chan, ints, "digits/oh", lang);
03702 if (!res) {
03703 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
03704 res = wait_file(chan, ints, nextmsg, lang);
03705 }
03706 } else {
03707 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
03708 }
03709 break;
03710 case 'T':
03711 res = ast_say_date_with_format_en(chan, t, ints, lang, "HMS", tzone);
03712 break;
03713 case ' ':
03714 case ' ':
03715
03716 break;
03717 default:
03718
03719 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
03720 }
03721
03722 if (res) {
03723 break;
03724 }
03725 }
03726 return res;
03727 }
03728
03729 static char next_item(const char *format)
03730 {
03731 const char *next = ast_skip_blanks(format);
03732 return *next;
03733 }
03734
03735
03736 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)
03737 {
03738 struct timeval when = { t, 0 };
03739 struct ast_tm tm;
03740 int res=0, offset, sndoffset;
03741 char sndfile[256], nextmsg[256];
03742
03743 if (!format)
03744 format = "A dBY HMS";
03745
03746 ast_localtime(&when, &tm, tzone);
03747
03748 for (offset=0 ; format[offset] != '\0' ; offset++) {
03749 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
03750 switch (format[offset]) {
03751
03752 case '\'':
03753
03754 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
03755 sndfile[sndoffset] = format[offset];
03756 }
03757 sndfile[sndoffset] = '\0';
03758 res = wait_file(chan, ints, sndfile, lang);
03759 break;
03760 case 'A':
03761 case 'a':
03762
03763 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
03764 res = wait_file(chan, ints, nextmsg, lang);
03765 break;
03766 case 'B':
03767 case 'b':
03768 case 'h':
03769
03770 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
03771 res = wait_file(chan, ints, nextmsg, lang);
03772 break;
03773 case 'm':
03774
03775 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
03776 break;
03777 case 'd':
03778 case 'e':
03779
03780 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
03781 break;
03782 case 'Y':
03783
03784 {
03785 int year = tm.tm_year + 1900;
03786 if (year > 1999) {
03787 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
03788 } else {
03789 if (year < 1100) {
03790
03791
03792 } else {
03793
03794
03795 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
03796 res = wait_file(chan, ints, nextmsg, lang);
03797 if (!res) {
03798 res = wait_file(chan, ints, "digits/hundred", lang);
03799 if (!res && year % 100 != 0) {
03800 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
03801 }
03802 }
03803 }
03804 }
03805 }
03806 break;
03807 case 'I':
03808 case 'l':
03809
03810 res = wait_file(chan, ints, "digits/oclock", lang);
03811 if (tm.tm_hour == 0)
03812 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
03813 else if (tm.tm_hour > 12)
03814 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
03815 else
03816 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
03817 if (!res) {
03818 res = wait_file(chan, ints, nextmsg, lang);
03819 }
03820 break;
03821 case 'H':
03822
03823 if (tm.tm_hour < 10 && tm.tm_hour > 0) {
03824 res = wait_file(chan, ints, "digits/0", lang);
03825 }
03826
03827 case 'k':
03828
03829 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
03830 break;
03831 case 'M':
03832
03833 if (tm.tm_min > 0 || next_item(&format[offset + 1]) == 'S') {
03834 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
03835 }
03836 if (!res && next_item(&format[offset + 1]) == 'S') {
03837 if (tm.tm_min == 1) {
03838 res = wait_file(chan, ints, "digits/minute", lang);
03839 } else {
03840 res = wait_file(chan, ints, "digits/minutes", lang);
03841 }
03842 }
03843 break;
03844 case 'P':
03845 case 'p':
03846
03847 if (tm.tm_hour > 11)
03848 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
03849 else
03850 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
03851 res = wait_file(chan, ints, nextmsg, lang);
03852 break;
03853 case 'Q':
03854
03855
03856
03857
03858 {
03859 struct timeval now = ast_tvnow();
03860 struct ast_tm tmnow;
03861 time_t beg_today;
03862
03863 ast_localtime(&now, &tmnow, tzone);
03864
03865
03866 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03867 if (beg_today < t) {
03868
03869 res = wait_file(chan, ints, "digits/today", lang);
03870 } else if (beg_today - 86400 < t) {
03871
03872 res = wait_file(chan, ints, "digits/yesterday", lang);
03873 } else {
03874 res = ast_say_date_with_format_da(chan, t, ints, lang, "AdBY", tzone);
03875 }
03876 }
03877 break;
03878 case 'q':
03879
03880
03881
03882
03883 {
03884 struct timeval now = ast_tvnow();
03885 struct ast_tm tmnow;
03886 time_t beg_today;
03887
03888 ast_localtime(&now, &tmnow, tzone);
03889
03890
03891 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03892 if (beg_today < t) {
03893
03894 } else if ((beg_today - 86400) < t) {
03895
03896 res = wait_file(chan, ints, "digits/yesterday", lang);
03897 } else if (beg_today - 86400 * 6 < t) {
03898
03899 res = ast_say_date_with_format_da(chan, t, ints, lang, "A", tzone);
03900 } else {
03901 res = ast_say_date_with_format_da(chan, t, ints, lang, "AdBY", tzone);
03902 }
03903 }
03904 break;
03905 case 'R':
03906 res = ast_say_date_with_format_da(chan, t, ints, lang, "HM", tzone);
03907 break;
03908 case 'S':
03909
03910 res = wait_file(chan, ints, "digits/and", lang);
03911 if (!res) {
03912 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
03913 if (!res) {
03914 res = wait_file(chan, ints, "digits/seconds", lang);
03915 }
03916 }
03917 break;
03918 case 'T':
03919 res = ast_say_date_with_format_da(chan, t, ints, lang, "HMS", tzone);
03920 break;
03921 case ' ':
03922 case ' ':
03923
03924 break;
03925 default:
03926
03927 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
03928 }
03929
03930 if (res) {
03931 break;
03932 }
03933 }
03934 return res;
03935 }
03936
03937
03938 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)
03939 {
03940 struct timeval when = { t, 0 };
03941 struct ast_tm tm;
03942 int res=0, offset, sndoffset;
03943 char sndfile[256], nextmsg[256];
03944
03945 if (!format)
03946 format = "A dBY HMS";
03947
03948 ast_localtime(&when, &tm, tzone);
03949
03950 for (offset=0 ; format[offset] != '\0' ; offset++) {
03951 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
03952 switch (format[offset]) {
03953
03954 case '\'':
03955
03956 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
03957 sndfile[sndoffset] = format[offset];
03958 }
03959 sndfile[sndoffset] = '\0';
03960 res = wait_file(chan, ints, sndfile, lang);
03961 break;
03962 case 'A':
03963 case 'a':
03964
03965 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
03966 res = wait_file(chan, ints, nextmsg, lang);
03967 break;
03968 case 'B':
03969 case 'b':
03970 case 'h':
03971
03972 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
03973 res = wait_file(chan, ints, nextmsg, lang);
03974 break;
03975 case 'm':
03976
03977 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
03978 break;
03979 case 'd':
03980 case 'e':
03981
03982 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
03983 break;
03984 case 'Y':
03985
03986 {
03987 int year = tm.tm_year + 1900;
03988 if (year > 1999) {
03989 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
03990 } else {
03991 if (year < 1100) {
03992
03993
03994 } else {
03995
03996
03997 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (year / 100) );
03998 res = wait_file(chan, ints, nextmsg, lang);
03999 if (!res) {
04000 res = wait_file(chan, ints, "digits/hundred", lang);
04001 if (!res && year % 100 != 0) {
04002 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
04003 }
04004 }
04005 }
04006 }
04007 }
04008 break;
04009 case 'I':
04010 case 'l':
04011
04012 if (tm.tm_hour == 0)
04013 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
04014 else if (tm.tm_hour > 12)
04015 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04016 else
04017 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04018 res = wait_file(chan, ints, nextmsg, lang);
04019 if (!res) {
04020 res = wait_file(chan, ints, "digits/oclock", lang);
04021 }
04022 break;
04023 case 'H':
04024 case 'k':
04025
04026 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
04027 if (!res) {
04028 res = wait_file(chan, ints, "digits/oclock", lang);
04029 }
04030 break;
04031 case 'M':
04032
04033 if (next_item(&format[offset + 1]) == 'S') {
04034 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
04035 } else if (tm.tm_min > 0) {
04036 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04037 }
04038
04039 if (!res && next_item(&format[offset + 1]) == 'S') {
04040 if (tm.tm_min == 1) {
04041 res = wait_file(chan, ints, "digits/minute", lang);
04042 } else {
04043 res = wait_file(chan, ints, "digits/minutes", lang);
04044 }
04045 }
04046 break;
04047 case 'P':
04048 case 'p':
04049
04050 if (tm.tm_hour > 11)
04051 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
04052 else
04053 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
04054 res = wait_file(chan, ints, nextmsg, lang);
04055 break;
04056 case 'Q':
04057
04058
04059
04060
04061 {
04062 struct timeval now = ast_tvnow();
04063 struct ast_tm tmnow;
04064 time_t beg_today;
04065
04066 ast_localtime(&now, &tmnow, tzone);
04067
04068
04069 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04070 if (beg_today < t) {
04071
04072 res = wait_file(chan, ints, "digits/today", lang);
04073 } else if (beg_today - 86400 < t) {
04074
04075 res = wait_file(chan, ints, "digits/yesterday", lang);
04076 } else {
04077 res = ast_say_date_with_format_de(chan, t, ints, lang, "AdBY", tzone);
04078 }
04079 }
04080 break;
04081 case 'q':
04082
04083
04084
04085
04086 {
04087 struct timeval now = ast_tvnow();
04088 struct ast_tm tmnow;
04089 time_t beg_today;
04090
04091 ast_localtime(&now, &tmnow, tzone);
04092
04093
04094 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04095 if (beg_today < t) {
04096
04097 } else if ((beg_today - 86400) < t) {
04098
04099 res = wait_file(chan, ints, "digits/yesterday", lang);
04100 } else if (beg_today - 86400 * 6 < t) {
04101
04102 res = ast_say_date_with_format_de(chan, t, ints, lang, "A", tzone);
04103 } else {
04104 res = ast_say_date_with_format_de(chan, t, ints, lang, "AdBY", tzone);
04105 }
04106 }
04107 break;
04108 case 'R':
04109 res = ast_say_date_with_format_de(chan, t, ints, lang, "HM", tzone);
04110 break;
04111 case 'S':
04112
04113 res = wait_file(chan, ints, "digits/and", lang);
04114 if (!res) {
04115 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
04116 if (!res) {
04117 res = wait_file(chan, ints, tm.tm_sec == 1 ? "digits/second" : "digits/seconds", lang);
04118 }
04119 }
04120 break;
04121 case 'T':
04122 res = ast_say_date_with_format_de(chan, t, ints, lang, "HMS", tzone);
04123 break;
04124 case ' ':
04125 case ' ':
04126
04127 break;
04128 default:
04129
04130 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04131 }
04132
04133 if (res) {
04134 break;
04135 }
04136 }
04137 return res;
04138 }
04139
04140
04141 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)
04142 {
04143 struct timeval when = { t, 0 };
04144 struct ast_tm tm;
04145 int res=0, offset, sndoffset;
04146 char sndfile[256], nextmsg[256];
04147
04148 if (format == NULL)
04149 format = "a 'digits/tee' e 'digits/duan' hY I 'digits/naliga' M 'digits/natee'";
04150
04151 ast_localtime(&when, &tm, tzone);
04152
04153 for (offset=0 ; format[offset] != '\0' ; offset++) {
04154 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04155 switch (format[offset]) {
04156
04157 case '\'':
04158
04159 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
04160 sndfile[sndoffset] = format[offset];
04161 }
04162 sndfile[sndoffset] = '\0';
04163 res = wait_file(chan, ints, sndfile, lang);
04164 break;
04165 case 'A':
04166 case 'a':
04167
04168 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04169 res = wait_file(chan, ints, nextmsg, lang);
04170 break;
04171 case 'B':
04172 case 'b':
04173 case 'h':
04174
04175 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04176 res = wait_file(chan, ints, nextmsg, lang);
04177 break;
04178 case 'm':
04179
04180 res = ast_say_number(chan, (tm.tm_mon + 1), ints, lang, (char *) NULL);
04181 break;
04182 case 'd':
04183 case 'e':
04184
04185 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
04186 break;
04187 case 'Y':
04188
04189 res = ast_say_number(chan, tm.tm_year + 1900 + 543, ints, lang, (char *) NULL);
04190 break;
04191 case 'I':
04192 case 'l':
04193
04194 if (tm.tm_hour == 0)
04195 ast_copy_string(nextmsg, "digits/24", sizeof(nextmsg));
04196 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04197 res = wait_file(chan, ints, nextmsg, lang);
04198 break;
04199 case 'H':
04200 case 'k':
04201
04202 if (tm.tm_hour == 0)
04203 ast_copy_string(nextmsg, "digits/24", sizeof(nextmsg));
04204 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04205 res = wait_file(chan, ints, nextmsg, lang);
04206 break;
04207 case 'M':
04208 case 'N':
04209 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04210 break;
04211 case 'P':
04212 case 'p':
04213 break;
04214 case 'Q':
04215
04216
04217
04218
04219 {
04220 struct timeval now = ast_tvnow();
04221 struct ast_tm tmnow;
04222 time_t beg_today;
04223
04224 ast_localtime(&now, &tmnow, tzone);
04225
04226
04227 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04228 if (beg_today < t) {
04229
04230 res = wait_file(chan, ints, "digits/today", lang);
04231 } else if (beg_today - 86400 < t) {
04232
04233 res = wait_file(chan, ints, "digits/yesterday", lang);
04234 } else if (beg_today - 86400 * 6 < t) {
04235
04236 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
04237 } else if (beg_today - 2628000 < t) {
04238
04239 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
04240 } else if (beg_today - 15768000 < t) {
04241
04242 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
04243 } else {
04244
04245 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
04246 }
04247 }
04248 break;
04249 case 'q':
04250
04251
04252
04253
04254 {
04255 struct timeval now = ast_tvnow();
04256 struct ast_tm tmnow;
04257 time_t beg_today;
04258
04259 ast_localtime(&now, &tmnow, tzone);
04260
04261
04262 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04263 if (beg_today < t) {
04264
04265 } else if ((beg_today - 86400) < t) {
04266
04267 res = wait_file(chan, ints, "digits/yesterday", lang);
04268 } else if (beg_today - 86400 * 6 < t) {
04269
04270 res = ast_say_date_with_format_en(chan, t, ints, lang, "A", tzone);
04271 } else if (beg_today - 2628000 < t) {
04272
04273 res = ast_say_date_with_format_en(chan, t, ints, lang, "ABd", tzone);
04274 } else if (beg_today - 15768000 < t) {
04275
04276 res = ast_say_date_with_format_en(chan, t, ints, lang, "Bd", tzone);
04277 } else {
04278
04279 res = ast_say_date_with_format_en(chan, t, ints, lang, "BdY", tzone);
04280 }
04281 }
04282 break;
04283 case 'R':
04284 res = ast_say_date_with_format_en(chan, t, ints, lang, "HM", tzone);
04285 break;
04286 case 'S':
04287 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
04288 break;
04289 case 'T':
04290 res = ast_say_date_with_format_en(chan, t, ints, lang, "HMS", tzone);
04291 break;
04292 case ' ':
04293 case ' ':
04294
04295 break;
04296 default:
04297
04298 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04299 }
04300
04301 if (res) {
04302 break;
04303 }
04304 }
04305 return res;
04306 }
04307
04308
04309
04310
04311
04312
04313
04314
04315
04316
04317
04318
04319
04320
04321
04322
04323
04324
04325
04326
04327
04328 #define IL_DATE_STR "AdBY"
04329 #define IL_TIME_STR "HM"
04330 #define IL_DATE_STR_FULL IL_DATE_STR " 'digits/at' " IL_TIME_STR
04331 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)
04332 {
04333
04334
04335
04336 struct timeval when = { t, 0 };
04337 struct ast_tm tm;
04338 int res = 0, offset, sndoffset;
04339 char sndfile[256], nextmsg[256];
04340
04341 if (!format) {
04342 format = IL_DATE_STR_FULL;
04343 }
04344
04345 ast_localtime(&when, &tm, tzone);
04346
04347 for (offset = 0; format[offset] != '\0'; offset++) {
04348 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04349 switch (format[offset]) {
04350
04351 case '\'':
04352
04353 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
04354 sndfile[sndoffset] = format[offset];
04355 }
04356 sndfile[sndoffset] = '\0';
04357 res = wait_file(chan, ints, sndfile, lang);
04358 break;
04359 case 'A':
04360 case 'a':
04361
04362 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04363 res = wait_file(chan, ints, nextmsg, lang);
04364 break;
04365 case 'B':
04366 case 'b':
04367 case 'h':
04368
04369 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04370 res = wait_file(chan, ints, nextmsg, lang);
04371 break;
04372 case 'd':
04373 case 'e':
04374
04375
04376
04377
04378
04379
04380
04381 res = ast_say_number_full_he(chan, tm.tm_mday, ints, lang, "m", -1, -1);
04382 break;
04383 case 'Y':
04384 res = ast_say_number_full_he(chan, tm.tm_year + 1900, ints, lang, "f", -1, -1);
04385 break;
04386 case 'I':
04387 case 'l':
04388 case 'H':
04389 case 'k':
04390 res = ast_say_number_full_he(chan, tm.tm_hour, ints, lang, "f", -1, -1);
04391 break;
04392 case 'M':
04393 if (tm.tm_min >= 0 && tm.tm_min <= 9)
04394 res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
04395 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
04396 break;
04397 case 'P':
04398 case 'p':
04399
04400 break;
04401 case 'Q':
04402
04403 case 'q':
04404
04405
04406
04407
04408
04409 {
04410 struct timeval now = ast_tvnow();
04411 struct ast_tm tmnow;
04412 time_t beg_today;
04413 char todo = format[offset];
04414
04415 ast_localtime(&now, &tmnow, tzone);
04416
04417
04418 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04419 if (beg_today < t) {
04420
04421 if (todo == 'Q') {
04422 res = wait_file(chan, ints, "digits/today", lang);
04423 }
04424 } else if (beg_today - 86400 < t) {
04425
04426 res = wait_file(chan, ints, "digits/yesterday", lang);
04427 } else if ((todo != 'Q') && (beg_today - 86400 * 6 < t)) {
04428
04429 res = ast_say_date_with_format_he(chan, t, ints, lang, "A", tzone);
04430 } else {
04431 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
04432 }
04433 }
04434 break;
04435 case 'R':
04436 res = ast_say_date_with_format_he(chan, t, ints, lang, "HM", tzone);
04437 break;
04438 case 'S':
04439 res = ast_say_number_full_he(chan, tm.tm_sec,
04440 ints, lang, "f", -1, -1
04441 );
04442 break;
04443 case 'T':
04444 res = ast_say_date_with_format_he(chan, t, ints, lang, "HMS", tzone);
04445 break;
04446
04447
04448 case 'c':
04449 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR_FULL, tzone);
04450 break;
04451 case 'x':
04452 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_DATE_STR, tzone);
04453 break;
04454 case 'X':
04455 res = ast_say_date_with_format_he(chan, t, ints, lang, IL_TIME_STR, tzone);
04456 break;
04457 case ' ':
04458 case ' ':
04459
04460 break;
04461 default:
04462
04463 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04464 }
04465
04466 if (res) {
04467 break;
04468 }
04469 }
04470 return res;
04471 }
04472
04473
04474
04475 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)
04476 {
04477 struct timeval when = { t, 0 };
04478 struct ast_tm tm;
04479 int res=0, offset, sndoffset;
04480 char sndfile[256], nextmsg[256];
04481
04482 if (format == NULL)
04483 format = "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y 'digits/at' IMp";
04484
04485 ast_localtime(&when, &tm, tzone);
04486
04487 for (offset=0 ; format[offset] != '\0' ; offset++) {
04488 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04489 switch (format[offset]) {
04490
04491 case '\'':
04492
04493 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
04494 sndfile[sndoffset] = format[offset];
04495 }
04496 sndfile[sndoffset] = '\0';
04497 snprintf(nextmsg, sizeof(nextmsg), "%s", sndfile);
04498 res = wait_file(chan, ints, nextmsg, lang);
04499 break;
04500 case 'A':
04501 case 'a':
04502
04503 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04504 res = wait_file(chan, ints, nextmsg, lang);
04505 break;
04506 case 'B':
04507 case 'b':
04508 case 'h':
04509
04510 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04511 res = wait_file(chan, ints, nextmsg, lang);
04512 break;
04513 case 'm':
04514
04515 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04516 res = wait_file(chan, ints, nextmsg, lang);
04517 break;
04518 case 'd':
04519 case 'e':
04520
04521 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
04522 break;
04523 case 'Y':
04524
04525 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
04526 break;
04527 case 'I':
04528 case 'l':
04529
04530 if (tm.tm_hour == 0)
04531 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
04532 else if (tm.tm_hour > 12)
04533 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04534 else
04535 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04536 res = wait_file(chan, ints, nextmsg, lang);
04537 break;
04538 case 'H':
04539 case 'k':
04540
04541 res = ast_say_number(chan, tm.tm_hour, ints, lang, NULL);
04542 break;
04543 case 'M':
04544
04545 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04546 break;
04547 case 'P':
04548 case 'p':
04549
04550 if (tm.tm_hour > 18)
04551 res = wait_file(chan, ints, "digits/p-m", lang);
04552 else if (tm.tm_hour > 12)
04553 res = wait_file(chan, ints, "digits/afternoon", lang);
04554 else if (tm.tm_hour)
04555 res = wait_file(chan, ints, "digits/a-m", lang);
04556 break;
04557 case 'Q':
04558
04559
04560
04561
04562 {
04563 struct timeval now = ast_tvnow();
04564 struct ast_tm tmnow;
04565 time_t beg_today;
04566
04567 ast_localtime(&now, &tmnow, tzone);
04568
04569
04570 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04571 if (beg_today < t) {
04572
04573 res = wait_file(chan, ints, "digits/today", lang);
04574 } else if (beg_today - 86400 < t) {
04575
04576 res = wait_file(chan, ints, "digits/yesterday", lang);
04577 } else {
04578 res = ast_say_date_with_format_es(chan, t, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", tzone);
04579 }
04580 }
04581 break;
04582 case 'q':
04583
04584
04585
04586
04587 {
04588 struct timeval now = ast_tvnow();
04589 struct ast_tm tmnow;
04590 time_t beg_today;
04591
04592 ast_localtime(&now, &tmnow, tzone);
04593
04594
04595 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04596 if (beg_today < t) {
04597
04598 res = wait_file(chan, ints, "digits/today", lang);
04599 } else if ((beg_today - 86400) < t) {
04600
04601 res = wait_file(chan, ints, "digits/yesterday", lang);
04602 } else if (beg_today - 86400 * 6 < t) {
04603
04604 res = ast_say_date_with_format_es(chan, t, ints, lang, "A", tzone);
04605 } else {
04606 res = ast_say_date_with_format_es(chan, t, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", tzone);
04607 }
04608 }
04609 break;
04610 case 'R':
04611 res = ast_say_date_with_format_es(chan, t, ints, lang, "H 'digits/y' M", tzone);
04612 break;
04613 case 'S':
04614
04615 if (tm.tm_sec == 0) {
04616 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
04617 res = wait_file(chan, ints, nextmsg, lang);
04618 } else if (tm.tm_sec < 10) {
04619 res = wait_file(chan, ints, "digits/oh", lang);
04620 if (!res) {
04621 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
04622 res = wait_file(chan, ints, nextmsg, lang);
04623 }
04624 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
04625 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
04626 res = wait_file(chan, ints, nextmsg, lang);
04627 } else {
04628 int ten, one;
04629 ten = (tm.tm_sec / 10) * 10;
04630 one = (tm.tm_sec % 10);
04631 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
04632 res = wait_file(chan, ints, nextmsg, lang);
04633 if (!res) {
04634
04635 if (one != 0) {
04636 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
04637 res = wait_file(chan, ints, nextmsg, lang);
04638 }
04639 }
04640 }
04641 break;
04642 case 'T':
04643 res = ast_say_date_with_format_es(chan, t, ints, lang, "HMS", tzone);
04644 break;
04645 case ' ':
04646 case ' ':
04647
04648 break;
04649 default:
04650
04651 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04652 }
04653
04654 if (res) {
04655 break;
04656 }
04657 }
04658 return res;
04659 }
04660
04661
04662
04663
04664 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)
04665 {
04666 struct timeval when = { t, 0 };
04667 struct ast_tm tm;
04668 int res=0, offset, sndoffset;
04669 char sndfile[256], nextmsg[256];
04670
04671 if (format == NULL)
04672 format = "AdBY 'digits/at' IMp";
04673
04674 ast_localtime(&when, &tm, tzone);
04675
04676 for (offset=0 ; format[offset] != '\0' ; offset++) {
04677 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04678 switch (format[offset]) {
04679
04680 case '\'':
04681
04682 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
04683 sndfile[sndoffset] = format[offset];
04684 }
04685 sndfile[sndoffset] = '\0';
04686 res = wait_file(chan, ints, sndfile, lang);
04687 break;
04688 case 'A':
04689 case 'a':
04690
04691 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04692 res = wait_file(chan, ints, nextmsg, lang);
04693 break;
04694 case 'B':
04695 case 'b':
04696 case 'h':
04697
04698 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04699 res = wait_file(chan, ints, nextmsg, lang);
04700 break;
04701 case 'm':
04702
04703 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04704 res = wait_file(chan, ints, nextmsg, lang);
04705 break;
04706 case 'd':
04707 case 'e':
04708
04709 if (tm.tm_mday == 1) {
04710 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
04711 res = wait_file(chan, ints, nextmsg, lang);
04712 } else {
04713 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
04714 }
04715 break;
04716 case 'Y':
04717
04718 if (tm.tm_year > 99) {
04719 res = wait_file(chan, ints, "digits/2", lang);
04720 if (!res) {
04721 res = wait_file(chan, ints, "digits/thousand", lang);
04722 }
04723 if (tm.tm_year > 100) {
04724 if (!res) {
04725 res = ast_say_number(chan, tm.tm_year - 100, ints, lang, (char * ) NULL);
04726 }
04727 }
04728 } else {
04729 if (tm.tm_year < 1) {
04730
04731
04732 } else {
04733 res = wait_file(chan, ints, "digits/thousand", lang);
04734 if (!res) {
04735 wait_file(chan, ints, "digits/9", lang);
04736 wait_file(chan, ints, "digits/hundred", lang);
04737 res = ast_say_number(chan, tm.tm_year, ints, lang, (char * ) NULL);
04738 }
04739 }
04740 }
04741 break;
04742 case 'I':
04743 case 'l':
04744
04745 if (tm.tm_hour == 0)
04746 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
04747 else if (tm.tm_hour > 12)
04748 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04749 else
04750 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04751 res = wait_file(chan, ints, nextmsg, lang);
04752 if (!res)
04753 res = wait_file(chan, ints, "digits/oclock", lang);
04754 break;
04755 case 'H':
04756 case 'k':
04757
04758 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char * ) NULL);
04759 if (!res)
04760 res = wait_file(chan, ints, "digits/oclock", lang);
04761 break;
04762 case 'M':
04763
04764 if (tm.tm_min == 0) {
04765 break;
04766 }
04767 res = ast_say_number(chan, tm.tm_min, ints, lang, (char * ) NULL);
04768 break;
04769 case 'P':
04770 case 'p':
04771
04772 if (tm.tm_hour > 11)
04773 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
04774 else
04775 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
04776 res = wait_file(chan, ints, nextmsg, lang);
04777 break;
04778 case 'Q':
04779
04780
04781
04782
04783 {
04784 struct timeval now = ast_tvnow();
04785 struct ast_tm tmnow;
04786 time_t beg_today;
04787
04788 ast_localtime(&now, &tmnow, tzone);
04789
04790
04791 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04792 if (beg_today < t) {
04793
04794 res = wait_file(chan, ints, "digits/today", lang);
04795 } else if (beg_today - 86400 < t) {
04796
04797 res = wait_file(chan, ints, "digits/yesterday", lang);
04798 } else {
04799 res = ast_say_date_with_format_fr(chan, t, ints, lang, "AdBY", tzone);
04800 }
04801 }
04802 break;
04803 case 'q':
04804
04805
04806
04807
04808 {
04809 struct timeval now = ast_tvnow();
04810 struct ast_tm tmnow;
04811 time_t beg_today;
04812
04813 ast_localtime(&now, &tmnow, tzone);
04814
04815
04816 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04817 if (beg_today < t) {
04818
04819 } else if ((beg_today - 86400) < t) {
04820
04821 res = wait_file(chan, ints, "digits/yesterday", lang);
04822 } else if (beg_today - 86400 * 6 < t) {
04823
04824 res = ast_say_date_with_format_fr(chan, t, ints, lang, "A", tzone);
04825 } else {
04826 res = ast_say_date_with_format_fr(chan, t, ints, lang, "AdBY", tzone);
04827 }
04828 }
04829 break;
04830 case 'R':
04831 res = ast_say_date_with_format_fr(chan, t, ints, lang, "HM", tzone);
04832 break;
04833 case 'S':
04834
04835 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char * ) NULL);
04836 if (!res) {
04837 res = wait_file(chan, ints, "digits/second", lang);
04838 }
04839 break;
04840 case 'T':
04841 res = ast_say_date_with_format_fr(chan, t, ints, lang, "HMS", tzone);
04842 break;
04843 case ' ':
04844 case ' ':
04845
04846 break;
04847 default:
04848
04849 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04850 }
04851
04852 if (res) {
04853 break;
04854 }
04855 }
04856 return res;
04857 }
04858
04859 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)
04860 {
04861 struct timeval when = { t, 0 };
04862 struct ast_tm tm;
04863 int res=0, offset, sndoffset;
04864 char sndfile[256], nextmsg[256];
04865
04866 if (format == NULL)
04867 format = "AdB 'digits/at' IMp";
04868
04869 ast_localtime(&when, &tm, tzone);
04870
04871 for (offset=0 ; format[offset] != '\0' ; offset++) {
04872 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04873 switch (format[offset]) {
04874
04875 case '\'':
04876
04877 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
04878 sndfile[sndoffset] = format[offset];
04879 }
04880 sndfile[sndoffset] = '\0';
04881 res = wait_file(chan, ints, sndfile, lang);
04882 break;
04883 case 'A':
04884 case 'a':
04885
04886 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04887 res = wait_file(chan, ints, nextmsg, lang);
04888 break;
04889 case 'B':
04890 case 'b':
04891 case 'h':
04892
04893 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04894 res = wait_file(chan, ints, nextmsg, lang);
04895 break;
04896 case 'm':
04897
04898 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04899 res = wait_file(chan, ints, nextmsg, lang);
04900 break;
04901 case 'd':
04902 case 'e':
04903
04904 if (tm.tm_mday == 1) {
04905 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
04906 res = wait_file(chan, ints, nextmsg, lang);
04907 } else {
04908 if (!res) {
04909 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
04910 }
04911 }
04912 break;
04913 case 'Y':
04914
04915 if (tm.tm_year > 99) {
04916 res = wait_file(chan, ints, "digits/ore-2000", lang);
04917 if (tm.tm_year > 100) {
04918 if (!res) {
04919
04920 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
04921 res = wait_file(chan, ints, nextmsg, lang);
04922 }
04923 }
04924 } else {
04925 if (tm.tm_year < 1) {
04926
04927
04928 } else {
04929 res = wait_file(chan, ints, "digits/ore-1900", lang);
04930 if ((!res) && (tm.tm_year != 0)) {
04931 if (tm.tm_year <= 21) {
04932
04933 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
04934 res = wait_file(chan, ints, nextmsg, lang);
04935 } else {
04936
04937 int ten, one;
04938 ten = tm.tm_year / 10;
04939 one = tm.tm_year % 10;
04940 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten * 10);
04941 res = wait_file(chan, ints, nextmsg, lang);
04942 if (!res) {
04943 if (one != 0) {
04944 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
04945 res = wait_file(chan, ints, nextmsg, lang);
04946 }
04947 }
04948 }
04949 }
04950 }
04951 }
04952 break;
04953 case 'I':
04954 case 'l':
04955
04956 if (tm.tm_hour == 0)
04957 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
04958 else if (tm.tm_hour > 12)
04959 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04960 else
04961 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
04962 res = wait_file(chan, ints, nextmsg, lang);
04963 break;
04964 case 'H':
04965 case 'k':
04966
04967 if (tm.tm_hour == 0) {
04968 res = wait_file(chan, ints, "digits/ore-mezzanotte", lang);
04969 } else if (tm.tm_hour == 1) {
04970 res = wait_file(chan, ints, "digits/ore-una", lang);
04971 } else {
04972 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
04973 }
04974 break;
04975 case 'M':
04976
04977 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04978 break;
04979 case 'P':
04980 case 'p':
04981
04982 if (tm.tm_hour > 11)
04983 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
04984 else
04985 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
04986 res = wait_file(chan, ints, nextmsg, lang);
04987 break;
04988 case 'Q':
04989
04990
04991
04992
04993 {
04994 struct timeval now = ast_tvnow();
04995 struct ast_tm tmnow;
04996 time_t beg_today;
04997
04998 ast_localtime(&now, &tmnow, tzone);
04999
05000
05001 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05002 if (beg_today < t) {
05003
05004 res = wait_file(chan, ints, "digits/today", lang);
05005 } else if (beg_today - 86400 < t) {
05006
05007 res = wait_file(chan, ints, "digits/yesterday", lang);
05008 } else {
05009 res = ast_say_date_with_format_it(chan, t, ints, lang, "AdB", tzone);
05010 }
05011 }
05012 break;
05013 case 'q':
05014
05015 {
05016 struct timeval now = ast_tvnow();
05017 struct ast_tm tmnow;
05018 time_t beg_today;
05019
05020 ast_localtime(&now, &tmnow, tzone);
05021
05022
05023 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05024 if (beg_today < t) {
05025
05026 } else if ((beg_today - 86400) < t) {
05027
05028 res = wait_file(chan, ints, "digits/yesterday", lang);
05029 } else if (beg_today - 86400 * 6 < t) {
05030
05031 res = ast_say_date_with_format_it(chan, t, ints, lang, "A", tzone);
05032 } else {
05033 res = ast_say_date_with_format_it(chan, t, ints, lang, "AdB", tzone);
05034 }
05035 }
05036 break;
05037 case 'R':
05038 res = ast_say_date_with_format_it(chan, t, ints, lang, "HM", tzone);
05039 break;
05040 case 'S':
05041
05042 if (tm.tm_sec == 0) {
05043 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05044 res = wait_file(chan, ints, nextmsg, lang);
05045 } else if (tm.tm_sec < 10) {
05046 res = wait_file(chan, ints, "digits/oh", lang);
05047 if (!res) {
05048 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05049 res = wait_file(chan, ints, nextmsg, lang);
05050 }
05051 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
05052 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05053 res = wait_file(chan, ints, nextmsg, lang);
05054 } else {
05055 int ten, one;
05056 ten = (tm.tm_sec / 10) * 10;
05057 one = (tm.tm_sec % 10);
05058 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
05059 res = wait_file(chan, ints, nextmsg, lang);
05060 if (!res) {
05061
05062 if (one != 0) {
05063 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
05064 res = wait_file(chan, ints, nextmsg, lang);
05065 }
05066 }
05067 }
05068 break;
05069 case 'T':
05070 res = ast_say_date_with_format_it(chan, t, ints, lang, "HMS", tzone);
05071 break;
05072 case ' ':
05073 case ' ':
05074
05075 break;
05076 default:
05077
05078 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05079 }
05080
05081 if (res) {
05082 break;
05083 }
05084 }
05085 return res;
05086 }
05087
05088
05089 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)
05090 {
05091 struct timeval when = { t, 0 };
05092 struct ast_tm tm;
05093 int res=0, offset, sndoffset;
05094 char sndfile[256], nextmsg[256];
05095
05096 if (format == NULL)
05097 format = "ABdY 'digits/at' IMp";
05098
05099 ast_localtime(&when, &tm, tzone);
05100
05101 for (offset=0 ; format[offset] != '\0' ; offset++) {
05102 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05103 switch (format[offset]) {
05104
05105 case '\'':
05106
05107 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
05108 sndfile[sndoffset] = format[offset];
05109 }
05110 sndfile[sndoffset] = '\0';
05111 res = wait_file(chan, ints, sndfile, lang);
05112 break;
05113 case 'A':
05114 case 'a':
05115
05116 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05117 res = wait_file(chan, ints, nextmsg, lang);
05118 break;
05119 case 'B':
05120 case 'b':
05121 case 'h':
05122
05123 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05124 res = wait_file(chan, ints, nextmsg, lang);
05125 break;
05126 case 'm':
05127
05128 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
05129 res = wait_file(chan, ints, nextmsg, lang);
05130 break;
05131 case 'd':
05132 case 'e':
05133
05134 res = ast_say_number(chan, tm.tm_mday, ints, lang, NULL);
05135 break;
05136 case 'Y':
05137
05138 if (tm.tm_year > 99) {
05139 res = wait_file(chan, ints, "digits/2", lang);
05140 if (!res) {
05141 res = wait_file(chan, ints, "digits/thousand", lang);
05142 }
05143 if (tm.tm_year > 100) {
05144 if (!res) {
05145
05146 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
05147 res = wait_file(chan, ints, nextmsg, lang);
05148 }
05149 }
05150 } else {
05151 if (tm.tm_year < 1) {
05152
05153
05154 } else {
05155 res = wait_file(chan, ints, "digits/19", lang);
05156 if (!res) {
05157 if (tm.tm_year <= 9) {
05158
05159 res = wait_file(chan, ints, "digits/oh", lang);
05160 if (!res) {
05161 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
05162 res = wait_file(chan, ints, nextmsg, lang);
05163 }
05164 } else if (tm.tm_year <= 20) {
05165
05166 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
05167 res = wait_file(chan, ints, nextmsg, lang);
05168 } else {
05169
05170 int ten, one;
05171 ten = tm.tm_year / 10;
05172 one = tm.tm_year % 10;
05173 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten * 10);
05174 res = wait_file(chan, ints, nextmsg, lang);
05175 if (!res) {
05176 if (one != 0) {
05177 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
05178 res = wait_file(chan, ints, nextmsg, lang);
05179 }
05180 }
05181 }
05182 }
05183 }
05184 }
05185 break;
05186 case 'I':
05187 case 'l':
05188
05189 if (tm.tm_hour == 0)
05190 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
05191 else if (tm.tm_hour > 12)
05192 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
05193 else
05194 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
05195 res = wait_file(chan, ints, nextmsg, lang);
05196 break;
05197 case 'H':
05198 case 'k':
05199
05200 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
05201 if (!res) {
05202 res = wait_file(chan, ints, "digits/nl-uur", lang);
05203 }
05204 break;
05205 case 'M':
05206
05207 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05208 break;
05209 case 'P':
05210 case 'p':
05211
05212 if (tm.tm_hour > 11)
05213 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
05214 else
05215 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
05216 res = wait_file(chan, ints, nextmsg, lang);
05217 break;
05218 case 'Q':
05219
05220
05221
05222
05223 {
05224 struct timeval now = ast_tvnow();
05225 struct ast_tm tmnow;
05226 time_t beg_today;
05227
05228 ast_localtime(&now, &tmnow, tzone);
05229
05230
05231 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05232 if (beg_today < t) {
05233
05234 res = wait_file(chan, ints, "digits/today", lang);
05235 } else if (beg_today - 86400 < t) {
05236
05237 res = wait_file(chan, ints, "digits/yesterday", lang);
05238 } else {
05239 res = ast_say_date_with_format_nl(chan, t, ints, lang, "ABdY", tzone);
05240 }
05241 }
05242 break;
05243 case 'q':
05244
05245 {
05246 struct timeval now = ast_tvnow();
05247 struct ast_tm tmnow;
05248 time_t beg_today;
05249
05250 ast_localtime(&now, &tmnow, tzone);
05251
05252
05253 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05254 if (beg_today < t) {
05255
05256 } else if ((beg_today - 86400) < t) {
05257
05258 res = wait_file(chan, ints, "digits/yesterday", lang);
05259 } else if (beg_today - 86400 * 6 < t) {
05260
05261 res = ast_say_date_with_format_nl(chan, t, ints, lang, "A", tzone);
05262 } else {
05263 res = ast_say_date_with_format_nl(chan, t, ints, lang, "ABdY", tzone);
05264 }
05265 }
05266 break;
05267 case 'R':
05268 res = ast_say_date_with_format_nl(chan, t, ints, lang, "HM", tzone);
05269 break;
05270 case 'S':
05271
05272 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
05273 break;
05274 case 'T':
05275 res = ast_say_date_with_format_nl(chan, t, ints, lang, "HMS", tzone);
05276 break;
05277 case ' ':
05278 case ' ':
05279
05280 break;
05281 default:
05282
05283 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05284 }
05285
05286 if (res) {
05287 break;
05288 }
05289 }
05290 return res;
05291 }
05292
05293
05294 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)
05295 {
05296 struct timeval when = { thetime, 0 };
05297 struct ast_tm tm;
05298 int res=0, offset, sndoffset;
05299 char sndfile[256], nextmsg[256];
05300
05301 ast_localtime(&when, &tm, tzone);
05302
05303 for (offset = 0 ; format[offset] != '\0' ; offset++) {
05304 int remaining;
05305 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05306 switch (format[offset]) {
05307
05308 case '\'':
05309
05310 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
05311 sndfile[sndoffset] = format[offset];
05312 }
05313 sndfile[sndoffset] = '\0';
05314 res = wait_file(chan, ints, sndfile, lang);
05315 break;
05316 case 'A':
05317 case 'a':
05318
05319 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05320 res = wait_file(chan, ints, nextmsg, lang);
05321 break;
05322 case 'B':
05323 case 'b':
05324 case 'h':
05325
05326 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05327 res = wait_file(chan, ints, nextmsg, lang);
05328 break;
05329 case 'm':
05330
05331 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, NULL);
05332 break;
05333 case 'd':
05334 case 'e':
05335
05336 remaining = tm.tm_mday;
05337 if (tm.tm_mday > 30) {
05338 res = wait_file(chan, ints, "digits/h-30", lang);
05339 remaining -= 30;
05340 }
05341 if (tm.tm_mday > 20 && tm.tm_mday < 30) {
05342 res = wait_file(chan, ints, "digits/h-20", lang);
05343 remaining -= 20;
05344 }
05345 if (!res) {
05346 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", remaining);
05347 res = wait_file(chan, ints, nextmsg, lang);
05348 }
05349 break;
05350 case 'Y':
05351
05352 if (tm.tm_year > 100) {
05353 res = wait_file(chan, ints, "digits/2", lang);
05354 if (!res)
05355 res = wait_file(chan, ints, "digits/1000.2", lang);
05356 if (tm.tm_year > 100) {
05357 if (!res)
05358 res = ast_say_enumeration(chan, tm.tm_year - 100, ints, lang, NULL);
05359 }
05360 } else if (tm.tm_year == 100) {
05361 res = wait_file(chan, ints, "digits/h-2000", lang);
05362 } else {
05363 if (tm.tm_year < 1) {
05364
05365
05366 break;
05367 } else {
05368 res = wait_file(chan, ints, "digits/1000", lang);
05369 if (!res) {
05370 wait_file(chan, ints, "digits/900", lang);
05371 res = ast_say_enumeration(chan, tm.tm_year, ints, lang, NULL);
05372 }
05373 }
05374 }
05375 if (!res)
05376 wait_file(chan, ints, "digits/year", lang);
05377 break;
05378 case 'I':
05379 case 'l':
05380
05381 if (tm.tm_hour == 0)
05382 ast_copy_string(nextmsg, "digits/t-12", sizeof(nextmsg));
05383 else if (tm.tm_hour > 12)
05384 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour - 12);
05385 else
05386 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
05387
05388 res = wait_file(chan, ints, nextmsg, lang);
05389 break;
05390 case 'H':
05391 case 'k':
05392
05393 if (tm.tm_hour != 0) {
05394 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
05395 res = wait_file(chan, ints, nextmsg, lang);
05396 } else
05397 res = wait_file(chan, ints, "digits/t-24", lang);
05398 break;
05399 case 'M':
05400 case 'N':
05401
05402 if (tm.tm_min == 0) {
05403 if (format[offset] == 'M') {
05404 res = wait_file(chan, ints, "digits/oclock", lang);
05405 } else {
05406 res = wait_file(chan, ints, "digits/100", lang);
05407 }
05408 } else
05409 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
05410 break;
05411 case 'P':
05412 case 'p':
05413
05414 if (tm.tm_hour > 11)
05415 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
05416 else
05417 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
05418 res = wait_file(chan, ints, nextmsg, lang);
05419 break;
05420 case 'Q':
05421
05422 {
05423 struct timeval now = ast_tvnow();
05424 struct ast_tm tmnow;
05425 time_t beg_today;
05426
05427 ast_localtime(&now, &tmnow, tzone);
05428
05429
05430 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05431 if (beg_today < thetime) {
05432
05433 res = wait_file(chan, ints, "digits/today", lang);
05434 } else if (beg_today - 86400 < thetime) {
05435
05436 res = wait_file(chan, ints, "digits/yesterday", lang);
05437 } else {
05438 res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", tzone);
05439 }
05440 }
05441 break;
05442 case 'q':
05443
05444 {
05445 struct timeval now = ast_tvnow();
05446 struct ast_tm tmnow;
05447 time_t beg_today;
05448
05449 ast_localtime(&now, &tmnow, tzone);
05450
05451
05452 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05453 if (beg_today < thetime) {
05454
05455 } else if ((beg_today - 86400) < thetime) {
05456
05457 res = wait_file(chan, ints, "digits/yesterday", lang);
05458 } else if (beg_today - 86400 * 6 < thetime) {
05459
05460 res = ast_say_date_with_format(chan, thetime, ints, lang, "A", tzone);
05461 } else {
05462 res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", tzone);
05463 }
05464 }
05465 break;
05466 case 'R':
05467 res = ast_say_date_with_format(chan, thetime, ints, lang, "HM", tzone);
05468 break;
05469 case 'S':
05470
05471 res = wait_file(chan, ints, "digits/and", lang);
05472 if (!res) {
05473 if (tm.tm_sec == 1) {
05474 res = wait_file(chan, ints, "digits/1z", lang);
05475 if (!res)
05476 res = wait_file(chan, ints, "digits/second-a", lang);
05477 } else {
05478 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
05479 if (!res) {
05480 int ten, one;
05481 ten = tm.tm_sec / 10;
05482 one = tm.tm_sec % 10;
05483
05484 if (one > 1 && one < 5 && ten != 1)
05485 res = wait_file(chan, ints, "digits/seconds", lang);
05486 else
05487 res = wait_file(chan, ints, "digits/second", lang);
05488 }
05489 }
05490 }
05491 break;
05492 case 'T':
05493 res = ast_say_date_with_format(chan, thetime, ints, lang, "HMS", tzone);
05494 break;
05495 case ' ':
05496 case ' ':
05497
05498 break;
05499 default:
05500
05501 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05502 }
05503
05504 if (res)
05505 break;
05506 }
05507 return res;
05508 }
05509
05510
05511 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)
05512 {
05513 struct timeval when = { t, 0 };
05514 struct ast_tm tm;
05515 int res=0, offset, sndoffset;
05516 char sndfile[256], nextmsg[256];
05517
05518 if (format == NULL)
05519 format = "Ad 'digits/pt-de' B 'digits/pt-de' Y I 'digits/pt-e' Mp";
05520
05521 ast_localtime(&when, &tm, tzone);
05522
05523 for (offset=0 ; format[offset] != '\0' ; offset++) {
05524 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05525 switch (format[offset]) {
05526
05527 case '\'':
05528
05529 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
05530 sndfile[sndoffset] = format[offset];
05531 }
05532 sndfile[sndoffset] = '\0';
05533 snprintf(nextmsg, sizeof(nextmsg), "%s", sndfile);
05534 res = wait_file(chan, ints, nextmsg, lang);
05535 break;
05536 case 'A':
05537 case 'a':
05538
05539 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05540 res = wait_file(chan, ints, nextmsg, lang);
05541 break;
05542 case 'B':
05543 case 'b':
05544 case 'h':
05545
05546 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05547 res = wait_file(chan, ints, nextmsg, lang);
05548 break;
05549 case 'm':
05550
05551 if (!strcasecmp(lang, "pt_BR")) {
05552 res = ast_say_number(chan, tm.tm_mon+1, ints, lang, (char *) NULL);
05553 } else {
05554 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
05555 res = wait_file(chan, ints, nextmsg, lang);
05556 }
05557 break;
05558 case 'd':
05559 case 'e':
05560
05561 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
05562 break;
05563 case 'Y':
05564
05565 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
05566 break;
05567 case 'I':
05568 case 'l':
05569
05570 if (!strcasecmp(lang, "pt_BR")) {
05571 if (tm.tm_hour == 0) {
05572 if (format[offset] == 'I')
05573 res = wait_file(chan, ints, "digits/pt-a", lang);
05574 if (!res)
05575 res = wait_file(chan, ints, "digits/pt-meianoite", lang);
05576 } else if (tm.tm_hour == 12) {
05577 if (format[offset] == 'I')
05578 res = wait_file(chan, ints, "digits/pt-ao", lang);
05579 if (!res)
05580 res = wait_file(chan, ints, "digits/pt-meiodia", lang);
05581 } else {
05582 if (format[offset] == 'I') {
05583 if ((tm.tm_hour % 12) != 1)
05584 res = wait_file(chan, ints, "digits/pt-as", lang);
05585 else
05586 res = wait_file(chan, ints, "digits/pt-a", lang);
05587 }
05588 if (!res)
05589 res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
05590 }
05591 } else {
05592 if (tm.tm_hour == 0) {
05593 if (format[offset] == 'I')
05594 res = wait_file(chan, ints, "digits/pt-ah", lang);
05595 if (!res)
05596 res = wait_file(chan, ints, "digits/pt-meianoite", lang);
05597 }
05598 else if (tm.tm_hour == 12) {
05599 if (format[offset] == 'I')
05600 res = wait_file(chan, ints, "digits/pt-ao", lang);
05601 if (!res)
05602 res = wait_file(chan, ints, "digits/pt-meiodia", lang);
05603 }
05604 else {
05605 if (format[offset] == 'I') {
05606 res = wait_file(chan, ints, "digits/pt-ah", lang);
05607 if ((tm.tm_hour % 12) != 1)
05608 if (!res)
05609 res = wait_file(chan, ints, "digits/pt-sss", lang);
05610 }
05611 if (!res)
05612 res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
05613 }
05614 }
05615 break;
05616 case 'H':
05617 case 'k':
05618
05619 if (!strcasecmp(lang, "pt_BR")) {
05620 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
05621 if ((!res) && (format[offset] == 'H')) {
05622 if (tm.tm_hour > 1) {
05623 res = wait_file(chan, ints, "digits/hours", lang);
05624 } else {
05625 res = wait_file(chan, ints, "digits/hour", lang);
05626 }
05627 }
05628 } else {
05629 res = ast_say_number(chan, -tm.tm_hour, ints, lang, NULL);
05630 if (!res) {
05631 if (tm.tm_hour != 0) {
05632 int remaining = tm.tm_hour;
05633 if (tm.tm_hour > 20) {
05634 res = wait_file(chan, ints, "digits/20", lang);
05635 remaining -= 20;
05636 }
05637 if (!res) {
05638 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", remaining);
05639 res = wait_file(chan, ints, nextmsg, lang);
05640 }
05641 }
05642 }
05643 }
05644 break;
05645 case 'M':
05646
05647 if (!strcasecmp(lang, "pt_BR")) {
05648 res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
05649 if (!res) {
05650 if (tm.tm_min > 1) {
05651 res = wait_file(chan, ints, "digits/minutes", lang);
05652 } else {
05653 res = wait_file(chan, ints, "digits/minute", lang);
05654 }
05655 }
05656 } else {
05657 if (tm.tm_min == 0) {
05658 res = wait_file(chan, ints, "digits/pt-hora", lang);
05659 if (tm.tm_hour != 1)
05660 if (!res)
05661 res = wait_file(chan, ints, "digits/pt-sss", lang);
05662 } else {
05663 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05664 }
05665 }
05666 break;
05667 case 'P':
05668 case 'p':
05669
05670 if (!strcasecmp(lang, "pt_BR")) {
05671 if ((tm.tm_hour != 0) && (tm.tm_hour != 12)) {
05672 res = wait_file(chan, ints, "digits/pt-da", lang);
05673 if (!res) {
05674 if ((tm.tm_hour >= 0) && (tm.tm_hour < 12))
05675 res = wait_file(chan, ints, "digits/morning", lang);
05676 else if ((tm.tm_hour >= 12) && (tm.tm_hour < 18))
05677 res = wait_file(chan, ints, "digits/afternoon", lang);
05678 else res = wait_file(chan, ints, "digits/night", lang);
05679 }
05680 }
05681 } else {
05682 if (tm.tm_hour > 12)
05683 res = wait_file(chan, ints, "digits/p-m", lang);
05684 else if (tm.tm_hour && tm.tm_hour < 12)
05685 res = wait_file(chan, ints, "digits/a-m", lang);
05686 }
05687 break;
05688 case 'Q':
05689
05690
05691
05692
05693 {
05694 struct timeval now = ast_tvnow();
05695 struct ast_tm tmnow;
05696 time_t beg_today;
05697
05698 ast_localtime(&now, &tmnow, tzone);
05699
05700
05701 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05702 if (beg_today < t) {
05703
05704 res = wait_file(chan, ints, "digits/today", lang);
05705 } else if (beg_today - 86400 < t) {
05706
05707 res = wait_file(chan, ints, "digits/yesterday", lang);
05708 } else {
05709 res = ast_say_date_with_format_pt(chan, t, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", tzone);
05710 }
05711 }
05712 break;
05713 case 'q':
05714
05715
05716
05717
05718 {
05719 struct timeval now = ast_tvnow();
05720 struct ast_tm tmnow;
05721 time_t beg_today;
05722
05723 ast_localtime(&now, &tmnow, tzone);
05724
05725
05726 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05727 if (beg_today < t) {
05728
05729 } else if ((beg_today - 86400) < t) {
05730
05731 res = wait_file(chan, ints, "digits/yesterday", lang);
05732 } else if (beg_today - 86400 * 6 < t) {
05733
05734 res = ast_say_date_with_format_pt(chan, t, ints, lang, "A", tzone);
05735 } else {
05736 res = ast_say_date_with_format_pt(chan, t, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", tzone);
05737 }
05738 }
05739 break;
05740 case 'R':
05741 res = ast_say_date_with_format_pt(chan, t, ints, lang, "H 'digits/pt-e' M", tzone);
05742 break;
05743 case 'S':
05744
05745 if (!strcasecmp(lang, "pt_BR")) {
05746 res = ast_say_number(chan, tm.tm_sec, ints, lang, NULL);
05747 if (!res) {
05748 if (tm.tm_sec > 1) {
05749 res = wait_file(chan, ints, "digits/seconds", lang);
05750 } else {
05751 res = wait_file(chan, ints, "digits/second", lang);
05752 }
05753 }
05754 } else {
05755 if (tm.tm_sec == 0) {
05756 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05757 res = wait_file(chan, ints, nextmsg, lang);
05758 } else if (tm.tm_sec < 10) {
05759 res = wait_file(chan, ints, "digits/oh", lang);
05760 if (!res) {
05761 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05762 res = wait_file(chan, ints, nextmsg, lang);
05763 }
05764 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
05765 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
05766 res = wait_file(chan, ints, nextmsg, lang);
05767 } else {
05768 int ten, one;
05769 ten = (tm.tm_sec / 10) * 10;
05770 one = (tm.tm_sec % 10);
05771 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", ten);
05772 res = wait_file(chan, ints, nextmsg, lang);
05773 if (!res) {
05774
05775 if (one != 0) {
05776 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", one);
05777 res = wait_file(chan, ints, nextmsg, lang);
05778 }
05779 }
05780 }
05781 }
05782 break;
05783 case 'T':
05784 res = ast_say_date_with_format_pt(chan, t, ints, lang, "HMS", tzone);
05785 break;
05786 case ' ':
05787 case ' ':
05788
05789 break;
05790 default:
05791
05792 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05793 }
05794
05795 if (res) {
05796 break;
05797 }
05798 }
05799 return res;
05800 }
05801
05802
05803 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)
05804 {
05805 struct timeval when = { t, 0 };
05806 struct ast_tm tm;
05807 int res=0, offset, sndoffset;
05808 char sndfile[256], nextmsg[256];
05809
05810 if (format == NULL)
05811 format = "YBdAkM";
05812
05813 ast_localtime(&when, &tm, tzone);
05814
05815 for (offset=0 ; format[offset] != '\0' ; offset++) {
05816 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05817 switch (format[offset]) {
05818
05819 case '\'':
05820
05821 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
05822 sndfile[sndoffset] = format[offset];
05823 }
05824 sndfile[sndoffset] = '\0';
05825 res = wait_file(chan, ints, sndfile, lang);
05826 break;
05827 case 'A':
05828 case 'a':
05829
05830 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05831 res = wait_file(chan, ints, nextmsg, lang);
05832 break;
05833 case 'B':
05834 case 'b':
05835 case 'h':
05836 case 'm':
05837
05838 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05839 res = wait_file(chan, ints, nextmsg, lang);
05840 break;
05841 case 'd':
05842 case 'e':
05843
05844 if (!(tm.tm_mday % 10) || (tm.tm_mday < 10)) {
05845 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday);
05846 res = wait_file(chan, ints, nextmsg, lang);
05847 } else {
05848 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday - (tm.tm_mday % 10));
05849 res = wait_file(chan, ints, nextmsg, lang);
05850 if (!res) {
05851 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_mday % 10);
05852 res = wait_file(chan, ints, nextmsg, lang);
05853 }
05854 }
05855 if (!res) res = wait_file(chan, ints, "digits/day", lang);
05856 break;
05857 case 'Y':
05858
05859 if (tm.tm_year > 99) {
05860 res = wait_file(chan, ints, "digits/2", lang);
05861 if (!res) {
05862 res = wait_file(chan, ints, "digits/thousand", lang);
05863 }
05864 if (tm.tm_year > 100) {
05865 if (!res) {
05866 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) / 10);
05867 res = wait_file(chan, ints, nextmsg, lang);
05868 if (!res) {
05869 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) % 10);
05870 res = wait_file(chan, ints, nextmsg, lang);
05871 }
05872 }
05873 }
05874 if (!res) {
05875 res = wait_file(chan, ints, "digits/year", lang);
05876 }
05877 } else {
05878 if (tm.tm_year < 1) {
05879
05880
05881 } else {
05882 res = wait_file(chan, ints, "digits/1", lang);
05883 if (!res) {
05884 res = wait_file(chan, ints, "digits/9", lang);
05885 }
05886 if (!res) {
05887 if (tm.tm_year <= 9) {
05888
05889 res = wait_file(chan, ints, "digits/0", lang);
05890 if (!res) {
05891 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year);
05892 res = wait_file(chan, ints, nextmsg, lang);
05893 }
05894 } else {
05895
05896 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year / 10);
05897 res = wait_file(chan, ints, nextmsg, lang);
05898 if (!res) {
05899 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_year % 10);
05900 res = wait_file(chan, ints, nextmsg, lang);
05901 }
05902 }
05903 }
05904 }
05905 if (!res) {
05906 res = wait_file(chan, ints, "digits/year", lang);
05907 }
05908 }
05909 break;
05910 case 'I':
05911 case 'l':
05912
05913 if (tm.tm_hour == 0)
05914 ast_copy_string(nextmsg, "digits/12", sizeof(nextmsg));
05915 else if (tm.tm_hour > 12)
05916 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
05917 else
05918 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
05919 res = wait_file(chan, ints, nextmsg, lang);
05920 if (!res) {
05921 res = wait_file(chan, ints, "digits/oclock", lang);
05922 }
05923 break;
05924 case 'H':
05925 if (tm.tm_hour < 10) {
05926 res = wait_file(chan, ints, "digits/0", lang);
05927 }
05928 case 'k':
05929
05930 if (!(tm.tm_hour % 10) || tm.tm_hour < 10) {
05931 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour);
05932 res = wait_file(chan, ints, nextmsg, lang);
05933 } else {
05934 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour - (tm.tm_hour % 10));
05935 res = wait_file(chan, ints, nextmsg, lang);
05936 if (!res) {
05937 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_hour % 10);
05938 res = wait_file(chan, ints, nextmsg, lang);
05939 }
05940 }
05941 if (!res) {
05942 res = wait_file(chan, ints, "digits/oclock", lang);
05943 }
05944 break;
05945 case 'M':
05946
05947 if (!(tm.tm_min % 10) || tm.tm_min < 10) {
05948 if (tm.tm_min < 10) {
05949 res = wait_file(chan, ints, "digits/0", lang);
05950 }
05951 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min);
05952 res = wait_file(chan, ints, nextmsg, lang);
05953 } else {
05954 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min - (tm.tm_min % 10));
05955 res = wait_file(chan, ints, nextmsg, lang);
05956 if (!res) {
05957 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_min % 10);
05958 res = wait_file(chan, ints, nextmsg, lang);
05959 }
05960 }
05961 if (!res) {
05962 res = wait_file(chan, ints, "digits/minute", lang);
05963 }
05964 break;
05965 case 'P':
05966 case 'p':
05967
05968 if (tm.tm_hour > 11)
05969 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
05970 else
05971 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
05972 res = wait_file(chan, ints, nextmsg, lang);
05973 break;
05974 case 'Q':
05975
05976
05977
05978
05979 {
05980 struct timeval now = ast_tvnow();
05981 struct ast_tm tmnow;
05982 time_t beg_today;
05983
05984 ast_localtime(&now, &tmnow, tzone);
05985
05986
05987 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05988 if (beg_today < t) {
05989
05990 res = wait_file(chan, ints, "digits/today", lang);
05991 } else if (beg_today - 86400 < t) {
05992
05993 res = wait_file(chan, ints, "digits/yesterday", lang);
05994 } else {
05995 res = ast_say_date_with_format_zh(chan, t, ints, lang, "YBdA", tzone);
05996 }
05997 }
05998 break;
05999 case 'q':
06000
06001
06002
06003
06004 {
06005 struct timeval now = ast_tvnow();
06006 struct ast_tm tmnow;
06007 time_t beg_today;
06008
06009 ast_localtime(&now, &tmnow, tzone);
06010
06011
06012 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
06013 if (beg_today < t) {
06014
06015 } else if ((beg_today - 86400) < t) {
06016
06017 res = wait_file(chan, ints, "digits/yesterday", lang);
06018 } else if (beg_today - 86400 * 6 < t) {
06019
06020 res = ast_say_date_with_format_zh(chan, t, ints, lang, "A", tzone);
06021 } else {
06022 res = ast_say_date_with_format_zh(chan, t, ints, lang, "YBdA", tzone);
06023 }
06024 }
06025 break;
06026 case 'R':
06027 res = ast_say_date_with_format_zh(chan, t, ints, lang, "kM", tzone);
06028 break;
06029 case 'S':
06030
06031 if (!(tm.tm_sec % 10) || tm.tm_sec < 10) {
06032 if (tm.tm_sec < 10) {
06033 res = wait_file(chan, ints, "digits/0", lang);
06034 }
06035 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec);
06036 res = wait_file(chan, ints, nextmsg, lang);
06037 } else {
06038 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec - (tm.tm_sec % 10));
06039 res = wait_file(chan, ints, nextmsg, lang);
06040 if (!res) {
06041 snprintf(nextmsg, sizeof(nextmsg), "digits/%d", tm.tm_sec % 10);
06042 res = wait_file(chan, ints, nextmsg, lang);
06043 }
06044 }
06045 if (!res) {
06046 res = wait_file(chan, ints, "digits/second", lang);
06047 }
06048 break;
06049 case 'T':
06050 res = ast_say_date_with_format_zh(chan, t, ints, lang, "HMS", tzone);
06051 break;
06052 case ' ':
06053 case ' ':
06054
06055 break;
06056 default:
06057
06058 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
06059 }
06060
06061 if (res) {
06062 break;
06063 }
06064 }
06065 return res;
06066 }
06067
06068 static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06069 {
06070 if (!strncasecmp(lang, "en", 2)) {
06071 return ast_say_time_en(chan, t, ints, lang);
06072 } else if (!strncasecmp(lang, "de", 2)) {
06073 return ast_say_time_de(chan, t, ints, lang);
06074 } else if (!strncasecmp(lang, "fr", 2)) {
06075 return ast_say_time_fr(chan, t, ints, lang);
06076 } else if (!strncasecmp(lang, "ge", 2)) {
06077 static int deprecation_warning = 0;
06078 if (deprecation_warning++ % 10 == 0) {
06079 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
06080 }
06081 return ast_say_time_ka(chan, t, ints, lang);
06082 } else if (!strncasecmp(lang, "gr", 2)) {
06083 return ast_say_time_gr(chan, t, ints, lang);
06084 } else if (!strncasecmp(lang, "he", 2)) {
06085 return ast_say_time_he(chan, t, ints, lang);
06086 } else if (!strncasecmp(lang, "hu", 2)) {
06087 return(ast_say_time_hu(chan, t, ints, lang));
06088 } else if (!strncasecmp(lang, "ka", 2)) {
06089 return ast_say_time_ka(chan, t, ints, lang);
06090 } else if (!strncasecmp(lang, "nl", 2)) {
06091 return ast_say_time_nl(chan, t, ints, lang);
06092 } else if (!strncasecmp(lang, "pt_BR", 5)) {
06093 return ast_say_time_pt_BR(chan, t, ints, lang);
06094 } else if (!strncasecmp(lang, "pt", 2)) {
06095 return ast_say_time_pt(chan, t, ints, lang);
06096 } else if (!strncasecmp(lang, "th", 2)) {
06097 return(ast_say_time_th(chan, t, ints, lang));
06098 } else if (!strncasecmp(lang, "tw", 2)) {
06099 static int deprecation_warning = 0;
06100 if (deprecation_warning++ % 10 == 0) {
06101 ast_log(LOG_WARNING, "tw is a standard language code for Twi, not Taiwanese. Please switch to using zh_TW instead.\n");
06102 }
06103 return ast_say_time_zh(chan, t, ints, lang);
06104 } else if (!strncasecmp(lang, "zh", 2)) {
06105 return ast_say_time_zh(chan, t, ints, lang);
06106 }
06107
06108
06109 return ast_say_time_en(chan, t, ints, lang);
06110 }
06111
06112
06113 int ast_say_time_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06114 {
06115 struct timeval when = { t, 0 };
06116 struct ast_tm tm;
06117 int res = 0;
06118 int hour, pm=0;
06119
06120 ast_localtime(&when, &tm, NULL);
06121 hour = tm.tm_hour;
06122 if (!hour)
06123 hour = 12;
06124 else if (hour == 12)
06125 pm = 1;
06126 else if (hour > 12) {
06127 hour -= 12;
06128 pm = 1;
06129 }
06130 if (!res)
06131 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06132
06133 if (tm.tm_min > 9) {
06134 if (!res)
06135 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06136 } else if (tm.tm_min) {
06137 if (!res)
06138 res = ast_streamfile(chan, "digits/oh", lang);
06139 if (!res)
06140 res = ast_waitstream(chan, ints);
06141 if (!res)
06142 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06143 } else {
06144 if (!res)
06145 res = ast_streamfile(chan, "digits/oclock", lang);
06146 if (!res)
06147 res = ast_waitstream(chan, ints);
06148 }
06149 if (pm) {
06150 if (!res)
06151 res = ast_streamfile(chan, "digits/p-m", lang);
06152 } else {
06153 if (!res)
06154 res = ast_streamfile(chan, "digits/a-m", lang);
06155 }
06156 if (!res)
06157 res = ast_waitstream(chan, ints);
06158 return res;
06159 }
06160
06161
06162 int ast_say_time_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06163 {
06164 struct timeval when = { t, 0 };
06165 struct ast_tm tm;
06166 int res = 0;
06167
06168 ast_localtime(&when, &tm, NULL);
06169 if (!res)
06170 res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
06171 if (!res)
06172 res = ast_streamfile(chan, "digits/oclock", lang);
06173 if (!res)
06174 res = ast_waitstream(chan, ints);
06175 if (!res)
06176 if (tm.tm_min > 0)
06177 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06178 return res;
06179 }
06180
06181
06182 int ast_say_time_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06183 {
06184 struct timeval when = { t, 0 };
06185 struct ast_tm tm;
06186 int res = 0;
06187
06188 ast_localtime(&when, &tm, NULL);
06189 if (!res)
06190 res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
06191 if (!res)
06192 res = ast_streamfile(chan, "digits/oclock", lang);
06193 if (!res)
06194 res = ast_waitstream(chan, ints);
06195 if (!res)
06196 if (tm.tm_min > 0) {
06197 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06198 if (!res)
06199 res = ast_streamfile(chan, "digits/minute", lang);
06200 }
06201 return res;
06202 }
06203
06204
06205 int ast_say_time_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06206 {
06207 struct timeval when = { t, 0 };
06208 struct ast_tm tm;
06209 int res = 0;
06210
06211 ast_localtime(&when, &tm, NULL);
06212
06213 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
06214 if (!res)
06215 res = ast_streamfile(chan, "digits/oclock", lang);
06216 if (tm.tm_min) {
06217 if (!res)
06218 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06219 }
06220 return res;
06221 }
06222
06223
06224 int ast_say_time_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06225 {
06226 struct timeval when = { t, 0 };
06227 struct ast_tm tm;
06228 int res = 0;
06229
06230 ast_localtime(&when, &tm, NULL);
06231 if (!res)
06232 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
06233 if (!res)
06234 res = ast_streamfile(chan, "digits/nl-uur", lang);
06235 if (!res)
06236 res = ast_waitstream(chan, ints);
06237 if (!res)
06238 if (tm.tm_min > 0)
06239 res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
06240 return res;
06241 }
06242
06243
06244 int ast_say_time_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06245 {
06246 struct timeval when = { t, 0 };
06247 struct ast_tm tm;
06248 int res = 0;
06249 int hour;
06250
06251 ast_localtime(&when, &tm, NULL);
06252 hour = tm.tm_hour;
06253 if (!res)
06254 res = ast_say_number(chan, hour, ints, lang, "f");
06255 if (tm.tm_min) {
06256 if (!res)
06257 res = wait_file(chan, ints, "digits/pt-e", lang);
06258 if (!res)
06259 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06260 } else {
06261 if (!res)
06262 res = wait_file(chan, ints, "digits/pt-hora", lang);
06263 if (tm.tm_hour != 1)
06264 if (!res)
06265 res = wait_file(chan, ints, "digits/pt-sss", lang);
06266 }
06267 if (!res)
06268 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06269 return res;
06270 }
06271
06272
06273 int ast_say_time_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06274 {
06275 struct timeval when = { t, 0 };
06276 struct ast_tm tm;
06277 int res = 0;
06278
06279 ast_localtime(&when, &tm, NULL);
06280
06281 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
06282 if (!res) {
06283 if (tm.tm_hour > 1)
06284 res = wait_file(chan, ints, "digits/hours", lang);
06285 else
06286 res = wait_file(chan, ints, "digits/hour", lang);
06287 }
06288 if ((!res) && (tm.tm_min)) {
06289 res = wait_file(chan, ints, "digits/pt-e", lang);
06290 if (!res)
06291 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06292 if (!res) {
06293 if (tm.tm_min > 1)
06294 res = wait_file(chan, ints, "digits/minutes", lang);
06295 else
06296 res = wait_file(chan, ints, "digits/minute", lang);
06297 }
06298 }
06299 return res;
06300 }
06301
06302
06303 int ast_say_time_th(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;
06309 ast_localtime(&when, &tm, NULL);
06310 hour = tm.tm_hour;
06311 if (!hour)
06312 hour = 24;
06313 if (!res)
06314 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06315 if (!res)
06316 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06317 return res;
06318 }
06319
06320
06321 int ast_say_time_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06322 {
06323 struct timeval when = { t, 0 };
06324 struct ast_tm tm;
06325 int res = 0;
06326 int hour, pm=0;
06327
06328 ast_localtime(&when, &tm, NULL);
06329 hour = tm.tm_hour;
06330 if (!hour)
06331 hour = 12;
06332 else if (hour == 12)
06333 pm = 1;
06334 else if (hour > 12) {
06335 hour -= 12;
06336 pm = 1;
06337 }
06338 if (pm) {
06339 if (!res)
06340 res = ast_streamfile(chan, "digits/p-m", lang);
06341 } else {
06342 if (!res)
06343 res = ast_streamfile(chan, "digits/a-m", lang);
06344 }
06345 if (!res)
06346 res = ast_waitstream(chan, ints);
06347 if (!res)
06348 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06349 if (!res)
06350 res = ast_streamfile(chan, "digits/oclock", lang);
06351 if (!res)
06352 res = ast_waitstream(chan, ints);
06353 if (!res)
06354 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06355 if (!res)
06356 res = ast_streamfile(chan, "digits/minute", lang);
06357 if (!res)
06358 res = ast_waitstream(chan, ints);
06359 return res;
06360 }
06361
06362
06363 int ast_say_time_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06364 {
06365 struct timeval when = { t, 0 };
06366 struct ast_tm tm;
06367 int res = 0;
06368 int hour;
06369
06370 ast_localtime(&when, &tm, NULL);
06371 hour = tm.tm_hour;
06372 if (!hour)
06373 hour = 12;
06374
06375 if (!res)
06376 res = ast_say_number_full_he(chan, hour, ints, lang, "f", -1, -1);
06377
06378 if (tm.tm_min > 9) {
06379 if (!res)
06380 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
06381 } else if (tm.tm_min) {
06382 if (!res) {
06383 res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
06384 }
06385 if (!res)
06386 res = ast_waitstream(chan, ints);
06387 if (!res)
06388 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
06389 } else {
06390 if (!res)
06391 res = ast_waitstream(chan, ints);
06392 }
06393 if (!res)
06394 res = ast_waitstream(chan, ints);
06395 return res;
06396 }
06397 static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06398 {
06399 if (!strncasecmp(lang, "en", 2)) {
06400 return ast_say_datetime_en(chan, t, ints, lang);
06401 } else if (!strncasecmp(lang, "de", 2)) {
06402 return ast_say_datetime_de(chan, t, ints, lang);
06403 } else if (!strncasecmp(lang, "fr", 2)) {
06404 return ast_say_datetime_fr(chan, t, ints, lang);
06405 } else if (!strncasecmp(lang, "ge", 2)) {
06406 static int deprecation_warning = 0;
06407 if (deprecation_warning++ % 10 == 0) {
06408 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
06409 }
06410 return ast_say_datetime_ka(chan, t, ints, lang);
06411 } else if (!strncasecmp(lang, "gr", 2)) {
06412 return ast_say_datetime_gr(chan, t, ints, lang);
06413 } else if (!strncasecmp(lang, "he", 2)) {
06414 return ast_say_datetime_he(chan, t, ints, lang);
06415 } else if (!strncasecmp(lang, "hu", 2)) {
06416 return ast_say_datetime_hu(chan, t, ints, lang);
06417 } else if (!strncasecmp(lang, "ka", 2)) {
06418 return ast_say_datetime_ka(chan, t, ints, lang);
06419 } else if (!strncasecmp(lang, "nl", 2)) {
06420 return ast_say_datetime_nl(chan, t, ints, lang);
06421 } else if (!strncasecmp(lang, "pt_BR", 5)) {
06422 return ast_say_datetime_pt_BR(chan, t, ints, lang);
06423 } else if (!strncasecmp(lang, "pt", 2)) {
06424 return ast_say_datetime_pt(chan, t, ints, lang);
06425 } else if (!strncasecmp(lang, "th", 2)) {
06426 return ast_say_datetime_th(chan, t, ints, lang);
06427 } else if (!strncasecmp(lang, "tw", 2)) {
06428 static int deprecation_warning = 0;
06429 if (deprecation_warning++ % 10 == 0) {
06430 ast_log(LOG_WARNING, "tw is a standard language code for Twi, not Taiwanese. Please switch to using zh_TW instead.\n");
06431 }
06432 return ast_say_datetime_zh(chan, t, ints, lang);
06433 } else if (!strncasecmp(lang, "zh", 2)) {
06434 return ast_say_datetime_zh(chan, t, ints, lang);
06435 }
06436
06437
06438 return ast_say_datetime_en(chan, t, ints, lang);
06439 }
06440
06441
06442 int ast_say_datetime_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06443 {
06444 struct timeval when = { t, 0 };
06445 struct ast_tm tm;
06446 char fn[256];
06447 int res = 0;
06448 int hour, pm=0;
06449
06450 ast_localtime(&when, &tm, NULL);
06451 if (!res) {
06452 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06453 res = ast_streamfile(chan, fn, lang);
06454 if (!res)
06455 res = ast_waitstream(chan, ints);
06456 }
06457 if (!res) {
06458 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06459 res = ast_streamfile(chan, fn, lang);
06460 if (!res)
06461 res = ast_waitstream(chan, ints);
06462 }
06463 if (!res)
06464 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06465
06466 hour = tm.tm_hour;
06467 if (!hour)
06468 hour = 12;
06469 else if (hour == 12)
06470 pm = 1;
06471 else if (hour > 12) {
06472 hour -= 12;
06473 pm = 1;
06474 }
06475 if (!res)
06476 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06477
06478 if (tm.tm_min > 9) {
06479 if (!res)
06480 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06481 } else if (tm.tm_min) {
06482 if (!res)
06483 res = ast_streamfile(chan, "digits/oh", lang);
06484 if (!res)
06485 res = ast_waitstream(chan, ints);
06486 if (!res)
06487 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06488 } else {
06489 if (!res)
06490 res = ast_streamfile(chan, "digits/oclock", lang);
06491 if (!res)
06492 res = ast_waitstream(chan, ints);
06493 }
06494 if (pm) {
06495 if (!res)
06496 res = ast_streamfile(chan, "digits/p-m", lang);
06497 } else {
06498 if (!res)
06499 res = ast_streamfile(chan, "digits/a-m", lang);
06500 }
06501 if (!res)
06502 res = ast_waitstream(chan, ints);
06503 if (!res)
06504 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06505 return res;
06506 }
06507
06508
06509 int ast_say_datetime_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06510 {
06511 struct timeval when = { t, 0 };
06512 struct ast_tm tm;
06513 int res = 0;
06514
06515 ast_localtime(&when, &tm, NULL);
06516 res = ast_say_date(chan, t, ints, lang);
06517 if (!res)
06518 ast_say_time(chan, t, ints, lang);
06519 return res;
06520
06521 }
06522
06523
06524 int ast_say_datetime_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06525 {
06526 struct timeval when = { t, 0 };
06527 struct ast_tm tm;
06528 int res = 0;
06529
06530 ast_localtime(&when, &tm, NULL);
06531 res = ast_say_date(chan, t, ints, lang);
06532 if (!res)
06533 ast_say_time(chan, t, ints, lang);
06534 return res;
06535 }
06536
06537
06538 int ast_say_datetime_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06539 {
06540 struct timeval when = { t, 0 };
06541 struct ast_tm tm;
06542 char fn[256];
06543 int res = 0;
06544
06545 ast_localtime(&when, &tm, NULL);
06546
06547 if (!res)
06548 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06549
06550 if (!res) {
06551 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06552 res = ast_streamfile(chan, fn, lang);
06553 if (!res)
06554 res = ast_waitstream(chan, ints);
06555 }
06556 if (!res) {
06557 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06558 res = ast_streamfile(chan, fn, lang);
06559 if (!res)
06560 res = ast_waitstream(chan, ints);
06561 }
06562
06563 if (!res)
06564 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
06565 if (!res)
06566 res = ast_streamfile(chan, "digits/oclock", lang);
06567 if (tm.tm_min > 0) {
06568 if (!res)
06569 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06570 }
06571 if (!res)
06572 res = ast_waitstream(chan, ints);
06573 if (!res)
06574 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06575 return res;
06576 }
06577
06578
06579 int ast_say_datetime_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06580 {
06581 struct timeval when = { t, 0 };
06582 struct ast_tm tm;
06583 int res = 0;
06584
06585 ast_localtime(&when, &tm, NULL);
06586 res = ast_say_date(chan, t, ints, lang);
06587 if (!res) {
06588 res = ast_streamfile(chan, "digits/nl-om", lang);
06589 if (!res)
06590 res = ast_waitstream(chan, ints);
06591 }
06592 if (!res)
06593 ast_say_time(chan, t, ints, lang);
06594 return res;
06595 }
06596
06597
06598 int ast_say_datetime_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06599 {
06600 struct timeval when = { t, 0 };
06601 struct ast_tm tm;
06602 char fn[256];
06603 int res = 0;
06604 int hour, pm=0;
06605
06606 ast_localtime(&when, &tm, NULL);
06607 if (!res) {
06608 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06609 res = ast_streamfile(chan, fn, lang);
06610 if (!res)
06611 res = ast_waitstream(chan, ints);
06612 }
06613 if (!res) {
06614 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06615 res = ast_streamfile(chan, fn, lang);
06616 if (!res)
06617 res = ast_waitstream(chan, ints);
06618 }
06619 if (!res)
06620 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06621
06622 hour = tm.tm_hour;
06623 if (!hour)
06624 hour = 12;
06625 else if (hour == 12)
06626 pm = 1;
06627 else if (hour > 12) {
06628 hour -= 12;
06629 pm = 1;
06630 }
06631 if (!res)
06632 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06633
06634 if (tm.tm_min > 9) {
06635 if (!res)
06636 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06637 } else if (tm.tm_min) {
06638 if (!res)
06639 res = ast_streamfile(chan, "digits/oh", lang);
06640 if (!res)
06641 res = ast_waitstream(chan, ints);
06642 if (!res)
06643 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06644 } else {
06645 if (!res)
06646 res = ast_streamfile(chan, "digits/oclock", lang);
06647 if (!res)
06648 res = ast_waitstream(chan, ints);
06649 }
06650 if (pm) {
06651 if (!res)
06652 res = ast_streamfile(chan, "digits/p-m", lang);
06653 } else {
06654 if (!res)
06655 res = ast_streamfile(chan, "digits/a-m", lang);
06656 }
06657 if (!res)
06658 res = ast_waitstream(chan, ints);
06659 if (!res)
06660 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06661 return res;
06662 }
06663
06664
06665 int ast_say_datetime_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06666 {
06667 struct timeval when = { t, 0 };
06668 struct ast_tm tm;
06669 int res = 0;
06670
06671 ast_localtime(&when, &tm, NULL);
06672 res = ast_say_date(chan, t, ints, lang);
06673 if (!res)
06674 res = ast_say_time(chan, t, ints, lang);
06675 return res;
06676 }
06677
06678
06679 int ast_say_datetime_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06680 {
06681 struct timeval when = { t, 0 };
06682 struct ast_tm tm;
06683 char fn[256];
06684 int res = 0;
06685 int hour;
06686 ast_localtime(&when, &tm, NULL);
06687 if (!res) {
06688 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06689 res = ast_streamfile(chan, fn, lang);
06690 if (!res)
06691 res = ast_waitstream(chan, ints);
06692 }
06693 if (!res) {
06694 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06695 res = ast_streamfile(chan, fn, lang);
06696 if (!res)
06697 res = ast_waitstream(chan, ints);
06698 }
06699 if (!res){
06700 ast_copy_string(fn, "digits/posor", sizeof(fn));
06701 res = ast_streamfile(chan, fn, lang);
06702 res = ast_say_number(chan, tm.tm_year + 1900 + 543, ints, lang, (char *) NULL);
06703 }
06704 if (!res)
06705 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06706
06707 hour = tm.tm_hour;
06708 if (!hour)
06709 hour = 24;
06710 if (!res){
06711 ast_copy_string(fn, "digits/wela", sizeof(fn));
06712 res = ast_streamfile(chan, fn, lang);
06713 }
06714 if (!res)
06715 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06716 if (!res)
06717 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06718 return res;
06719 }
06720
06721
06722 int ast_say_datetime_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06723 {
06724 struct timeval when = { t, 0 };
06725 struct ast_tm tm;
06726 char fn[256];
06727 int res = 0;
06728 int hour, pm=0;
06729
06730 ast_localtime(&when, &tm, NULL);
06731 if (!res)
06732 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06733 if (!res) {
06734 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06735 res = ast_streamfile(chan, fn, lang);
06736 if (!res)
06737 res = ast_waitstream(chan, ints);
06738 }
06739 if (!res)
06740 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06741 if (!res) {
06742 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06743 res = ast_streamfile(chan, fn, lang);
06744 if (!res)
06745 res = ast_waitstream(chan, ints);
06746 }
06747
06748 hour = tm.tm_hour;
06749 if (!hour)
06750 hour = 12;
06751 else if (hour == 12)
06752 pm = 1;
06753 else if (hour > 12) {
06754 hour -= 12;
06755 pm = 1;
06756 }
06757 if (pm) {
06758 if (!res)
06759 res = ast_streamfile(chan, "digits/p-m", lang);
06760 } else {
06761 if (!res)
06762 res = ast_streamfile(chan, "digits/a-m", lang);
06763 }
06764 if (!res)
06765 res = ast_waitstream(chan, ints);
06766 if (!res)
06767 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06768 if (!res)
06769 res = ast_streamfile(chan, "digits/oclock", lang);
06770 if (!res)
06771 res = ast_waitstream(chan, ints);
06772 if (!res)
06773 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06774 if (!res)
06775 res = ast_streamfile(chan, "digits/minute", lang);
06776 if (!res)
06777 res = ast_waitstream(chan, ints);
06778 return res;
06779 }
06780
06781
06782 int ast_say_datetime_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06783 {
06784 struct timeval when = { t, 0 };
06785 struct ast_tm tm;
06786 char fn[256];
06787 int res = 0;
06788 int hour;
06789
06790 ast_localtime(&when, &tm, NULL);
06791 if (!res) {
06792 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06793 res = ast_streamfile(chan, fn, lang);
06794 if (!res) {
06795 res = ast_waitstream(chan, ints);
06796 }
06797 }
06798 if (!res) {
06799 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06800 res = ast_streamfile(chan, fn, lang);
06801 if (!res) {
06802 res = ast_waitstream(chan, ints);
06803 }
06804 }
06805 if (!res) {
06806 res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
06807 }
06808
06809 hour = tm.tm_hour;
06810 if (!hour) {
06811 hour = 12;
06812 }
06813
06814 if (!res) {
06815 res = ast_say_number(chan, hour, ints, lang, "f");
06816 }
06817
06818 if (tm.tm_min > 9) {
06819 if (!res) {
06820 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06821 }
06822 } else if (tm.tm_min) {
06823 if (!res) {
06824
06825 res = ast_say_number(chan, 0, ints, lang, "f");
06826 }
06827 if (!res) {
06828 res = ast_waitstream(chan, ints);
06829 }
06830 if (!res) {
06831 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06832 }
06833 } else {
06834 if (!res) {
06835 res = ast_waitstream(chan, ints);
06836 }
06837 }
06838 if (!res) {
06839 res = ast_waitstream(chan, ints);
06840 }
06841 if (!res) {
06842 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "f");
06843 }
06844 return res;
06845 }
06846 static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06847 {
06848 if (!strncasecmp(lang, "en", 2)) {
06849 return ast_say_datetime_from_now_en(chan, t, ints, lang);
06850 } else if (!strncasecmp(lang, "fr", 2)) {
06851 return ast_say_datetime_from_now_fr(chan, t, ints, lang);
06852 } else if (!strncasecmp(lang, "ge", 2)) {
06853 static int deprecation_warning = 0;
06854 if (deprecation_warning++ % 10 == 0) {
06855 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
06856 }
06857 return ast_say_datetime_from_now_ka(chan, t, ints, lang);
06858 } else if (!strncasecmp(lang, "he", 2)) {
06859 return ast_say_datetime_from_now_he(chan, t, ints, lang);
06860 } else if (!strncasecmp(lang, "ka", 2)) {
06861 return ast_say_datetime_from_now_ka(chan, t, ints, lang);
06862 } else if (!strncasecmp(lang, "pt", 2)) {
06863 return ast_say_datetime_from_now_pt(chan, t, ints, lang);
06864 }
06865
06866
06867 return ast_say_datetime_from_now_en(chan, t, ints, lang);
06868 }
06869
06870
06871 int ast_say_datetime_from_now_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06872 {
06873 int res=0;
06874 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
06875 int daydiff;
06876 struct ast_tm tm;
06877 struct ast_tm now;
06878 char fn[256];
06879
06880 ast_localtime(&when, &tm, NULL);
06881 ast_localtime(&nowtv, &now, NULL);
06882 daydiff = now.tm_yday - tm.tm_yday;
06883 if ((daydiff < 0) || (daydiff > 6)) {
06884
06885 if (!res) {
06886 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06887 res = ast_streamfile(chan, fn, lang);
06888 if (!res)
06889 res = ast_waitstream(chan, ints);
06890 }
06891 if (!res)
06892 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06893
06894 } else if (daydiff) {
06895
06896 if (!res) {
06897 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06898 res = ast_streamfile(chan, fn, lang);
06899 if (!res)
06900 res = ast_waitstream(chan, ints);
06901 }
06902 }
06903 if (!res)
06904 res = ast_say_time(chan, t, ints, lang);
06905 return res;
06906 }
06907
06908
06909 int ast_say_datetime_from_now_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06910 {
06911 int res=0;
06912 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
06913 int daydiff;
06914 struct ast_tm tm;
06915 struct ast_tm now;
06916 char fn[256];
06917
06918 ast_localtime(&when, &tm, NULL);
06919 ast_localtime(&nowtv, &now, NULL);
06920 daydiff = now.tm_yday - tm.tm_yday;
06921 if ((daydiff < 0) || (daydiff > 6)) {
06922
06923 if (!res) {
06924 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06925 res = ast_streamfile(chan, fn, lang);
06926 if (!res)
06927 res = ast_waitstream(chan, ints);
06928 }
06929 if (!res)
06930 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06931
06932 } else if (daydiff) {
06933
06934 if (!res) {
06935 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06936 res = ast_streamfile(chan, fn, lang);
06937 if (!res)
06938 res = ast_waitstream(chan, ints);
06939 }
06940 }
06941 if (!res)
06942 res = ast_say_time(chan, t, ints, lang);
06943 return res;
06944 }
06945
06946
06947 int ast_say_datetime_from_now_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06948 {
06949 int res=0;
06950 int daydiff;
06951 struct ast_tm tm;
06952 struct ast_tm now;
06953 struct timeval nowtv = ast_tvnow(), when = { t, 0 };
06954 char fn[256];
06955
06956 ast_localtime(&when, &tm, NULL);
06957 ast_localtime(&nowtv, &now, NULL);
06958 daydiff = now.tm_yday - tm.tm_yday;
06959 if ((daydiff < 0) || (daydiff > 6)) {
06960
06961 if (!res)
06962 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06963 if (!res)
06964 res = wait_file(chan, ints, "digits/pt-de", lang);
06965 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06966 if (!res)
06967 res = wait_file(chan, ints, fn, lang);
06968
06969 } else if (daydiff) {
06970
06971 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06972 if (!res)
06973 res = wait_file(chan, ints, fn, lang);
06974 }
06975 if (!strcasecmp(lang, "pt_BR")) {
06976 if (tm.tm_hour > 1) {
06977 ast_copy_string(fn, "digits/pt-as", sizeof(fn));
06978 } else {
06979 ast_copy_string(fn, "digits/pt-a", sizeof(fn));
06980 }
06981 if (!res)
06982 res = wait_file(chan, ints, fn, lang);
06983 } else {
06984 ast_copy_string(fn, "digits/pt-ah", sizeof(fn));
06985 if (!res)
06986 res = wait_file(chan, ints, fn, lang);
06987 if (tm.tm_hour != 1)
06988 if (!res)
06989 res = wait_file(chan, ints, "digits/pt-sss", lang);
06990 if (!res)
06991 res = ast_say_time(chan, t, ints, lang);
06992 }
06993 return res;
06994 }
06995
06996
06997 int ast_say_datetime_from_now_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06998 {
06999 int res = 0;
07000 struct timeval nowt = ast_tvnow(), when = { t, 0 };
07001 int daydiff;
07002 struct ast_tm tm;
07003 struct ast_tm now;
07004 char fn[256];
07005
07006 ast_localtime(&when, &tm, NULL);
07007 ast_localtime(&nowt, &now, NULL);
07008 daydiff = now.tm_yday - tm.tm_yday;
07009 if ((daydiff < 0) || (daydiff > 6)) {
07010
07011 if (!res) {
07012 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07013 res = ast_streamfile(chan, fn, lang);
07014 if (!res)
07015 res = ast_waitstream(chan, ints);
07016 }
07017 if (!res) {
07018 res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
07019 }
07020 } else if (daydiff) {
07021
07022 if (!res) {
07023 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07024 res = ast_streamfile(chan, fn, lang);
07025 if (!res) {
07026 res = ast_waitstream(chan, ints);
07027 }
07028 }
07029 }
07030 if (!res) {
07031 res = ast_say_time(chan, t, ints, lang);
07032 }
07033 return res;
07034 }
07035
07036
07037
07038
07039
07040
07041
07042 static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang){
07043 int tmp;
07044 int left;
07045 int res;
07046 char fn[256] = "";
07047
07048
07049 if (num < 5) {
07050 snprintf(fn, sizeof(fn), "digits/female-%d", num);
07051 res = wait_file(chan, ints, fn, lang);
07052 } else if (num < 13) {
07053 res = ast_say_number(chan, num, ints, lang, (char *) NULL);
07054 } else if (num <100 ) {
07055 tmp = (num/10) * 10;
07056 left = num - tmp;
07057 snprintf(fn, sizeof(fn), "digits/%d", tmp);
07058 res = ast_streamfile(chan, fn, lang);
07059 if (!res)
07060 res = ast_waitstream(chan, ints);
07061 if (left)
07062 gr_say_number_female(left, chan, ints, lang);
07063
07064 } else {
07065 return -1;
07066 }
07067 return res;
07068 }
07069
07070
07071
07072
07073
07074
07075
07076
07077
07078
07079
07080
07081
07082
07083
07084
07085
07086
07087
07088 static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
07089 {
07090 int res = 0;
07091 char fn[256] = "";
07092 int i=0;
07093
07094
07095 if (!num) {
07096 ast_copy_string(fn, "digits/0", sizeof(fn));
07097 res = ast_streamfile(chan, fn, chan->language);
07098 if (!res)
07099 return ast_waitstream(chan, ints);
07100 }
07101
07102 while (!res && num ) {
07103 i++;
07104 if (num < 13) {
07105 snprintf(fn, sizeof(fn), "digits/%d", num);
07106 num = 0;
07107 } else if (num <= 100) {
07108
07109 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
07110 num %= 10;
07111 } else if (num < 200) {
07112
07113 snprintf(fn, sizeof(fn), "digits/hundred-100");
07114 num %= 100;
07115 } else if (num < 1000) {
07116
07117 snprintf(fn, sizeof(fn), "digits/hundred-%d", (num/100)*100);
07118 num %= 100;
07119 } else if (num < 2000){
07120 snprintf(fn, sizeof(fn), "digits/xilia");
07121 num %= 1000;
07122 } else {
07123
07124 if (num < 1000000) {
07125 res = ast_say_number_full_gr(chan, (num / 1000), ints, chan->language, audiofd, ctrlfd);
07126 if (res)
07127 return res;
07128 num %= 1000;
07129 snprintf(fn, sizeof(fn), "digits/thousands");
07130 } else {
07131 if (num < 1000000000) {
07132 res = ast_say_number_full_gr(chan, (num / 1000000), ints, chan->language, audiofd, ctrlfd);
07133 if (res)
07134 return res;
07135 num %= 1000000;
07136 snprintf(fn, sizeof(fn), "digits/millions");
07137 } else {
07138 ast_debug(1, "Number '%d' is too big for me\n", num);
07139 res = -1;
07140 }
07141 }
07142 }
07143 if (!res) {
07144 if (!ast_streamfile(chan, fn, language)) {
07145 if ((audiofd > -1) && (ctrlfd > -1))
07146 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
07147 else
07148 res = ast_waitstream(chan, ints);
07149 }
07150 ast_stopstream(chan);
07151 }
07152 }
07153 return res;
07154 }
07155
07156
07157
07158
07159
07160
07161
07162
07163
07164
07165
07166
07167
07168 static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07169 {
07170 struct ast_tm tm;
07171 struct timeval when = { t, 0 };
07172
07173 char fn[256];
07174 int res = 0;
07175
07176
07177 ast_localtime(&when, &tm, NULL);
07178
07179 if (!res) {
07180 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07181 res = ast_streamfile(chan, fn, lang);
07182 if (!res)
07183 res = ast_waitstream(chan, ints);
07184 }
07185
07186 if (!res) {
07187 gr_say_number_female(tm.tm_mday, chan, ints, lang);
07188 }
07189
07190 if (!res) {
07191 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07192 res = ast_streamfile(chan, fn, lang);
07193 if (!res)
07194 res = ast_waitstream(chan, ints);
07195 }
07196
07197 if (!res)
07198 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
07199 return res;
07200 }
07201
07202
07203
07204
07205
07206
07207
07208
07209
07210
07211
07212 static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07213 {
07214
07215 struct timeval when = { t, 0 };
07216 struct ast_tm tm;
07217 int res = 0;
07218 int hour, pm=0;
07219
07220 ast_localtime(&when, &tm, NULL);
07221 hour = tm.tm_hour;
07222
07223 if (!hour)
07224 hour = 12;
07225 else if (hour == 12)
07226 pm = 1;
07227 else if (hour > 12) {
07228 hour -= 12;
07229 pm = 1;
07230 }
07231
07232 res = gr_say_number_female(hour, chan, ints, lang);
07233 if (tm.tm_min) {
07234 if (!res)
07235 res = ast_streamfile(chan, "digits/kai", lang);
07236 if (!res)
07237 res = ast_waitstream(chan, ints);
07238 if (!res)
07239 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
07240 } else {
07241 if (!res)
07242 res = ast_streamfile(chan, "digits/hwra", lang);
07243 if (!res)
07244 res = ast_waitstream(chan, ints);
07245 }
07246 if (pm) {
07247 if (!res)
07248 res = ast_streamfile(chan, "digits/p-m", lang);
07249 } else {
07250 if (!res)
07251 res = ast_streamfile(chan, "digits/a-m", lang);
07252 }
07253 if (!res)
07254 res = ast_waitstream(chan, ints);
07255 return res;
07256 }
07257
07258
07259
07260 static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07261 {
07262 struct timeval when = { t, 0 };
07263 struct ast_tm tm;
07264 char fn[256];
07265 int res = 0;
07266
07267 ast_localtime(&when, &tm, NULL);
07268
07269
07270 if (!res) {
07271 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07272 res = ast_streamfile(chan, fn, lang);
07273 if (!res)
07274 res = ast_waitstream(chan, ints);
07275 }
07276
07277 if (!res) {
07278 gr_say_number_female(tm.tm_mday, chan, ints, lang);
07279 }
07280
07281 if (!res) {
07282 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07283 res = ast_streamfile(chan, fn, lang);
07284 if (!res)
07285 res = ast_waitstream(chan, ints);
07286 }
07287
07288 res = ast_say_time_gr(chan, t, ints, lang);
07289 return res;
07290 }
07291
07292 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)
07293 {
07294 struct timeval when = { t, 0 };
07295 struct ast_tm tm;
07296 int res=0, offset, sndoffset;
07297 char sndfile[256], nextmsg[256];
07298
07299 if (!format)
07300 format = "AdBY 'digits/at' IMp";
07301
07302 ast_localtime(&when, &tm, tzone);
07303
07304 for (offset=0 ; format[offset] != '\0' ; offset++) {
07305 ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
07306 switch (format[offset]) {
07307
07308 case '\'':
07309
07310 for (sndoffset = 0; !strchr("\'\0", format[++offset]) && (sndoffset < sizeof(sndfile) - 1) ; sndoffset++) {
07311 sndfile[sndoffset] = format[offset];
07312 }
07313 sndfile[sndoffset] = '\0';
07314 res = wait_file(chan, ints, sndfile, lang);
07315 break;
07316 case 'A':
07317 case 'a':
07318
07319 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
07320 res = wait_file(chan, ints, nextmsg, lang);
07321 break;
07322 case 'B':
07323 case 'b':
07324 case 'h':
07325
07326 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
07327 res = wait_file(chan, ints, nextmsg, lang);
07328 break;
07329 case 'd':
07330 case 'e':
07331
07332 gr_say_number_female(tm.tm_mday, chan, ints, lang);
07333 break;
07334 case 'Y':
07335
07336
07337 ast_say_number_full_gr(chan, 1900+tm.tm_year, ints, chan->language, -1, -1);
07338 break;
07339 case 'I':
07340 case 'l':
07341
07342 if (tm.tm_hour == 0)
07343 gr_say_number_female(12, chan, ints, lang);
07344 else if (tm.tm_hour > 12)
07345 gr_say_number_female(tm.tm_hour - 12, chan, ints, lang);
07346 else
07347 gr_say_number_female(tm.tm_hour, chan, ints, lang);
07348 break;
07349 case 'H':
07350 case 'k':
07351
07352 gr_say_number_female(tm.tm_hour, chan, ints, lang);
07353 break;
07354 case 'M':
07355
07356 if (tm.tm_min) {
07357 if (!res)
07358 res = ast_streamfile(chan, "digits/kai", lang);
07359 if (!res)
07360 res = ast_waitstream(chan, ints);
07361 if (!res)
07362 res = ast_say_number_full_gr(chan, tm.tm_min, ints, lang, -1, -1);
07363 } else {
07364 if (!res)
07365 res = ast_streamfile(chan, "digits/oclock", lang);
07366 if (!res)
07367 res = ast_waitstream(chan, ints);
07368 }
07369 break;
07370 case 'P':
07371 case 'p':
07372
07373 if (tm.tm_hour > 11)
07374 ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg));
07375 else
07376 ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg));
07377 res = wait_file(chan, ints, nextmsg, lang);
07378 break;
07379 case 'Q':
07380
07381
07382
07383
07384 {
07385 struct timeval now = ast_tvnow();
07386 struct ast_tm tmnow;
07387 time_t beg_today;
07388
07389 ast_localtime(&now, &tmnow, tzone);
07390
07391
07392 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
07393 if (beg_today < t) {
07394
07395 res = wait_file(chan, ints, "digits/today", lang);
07396 } else if (beg_today - 86400 < t) {
07397
07398 res = wait_file(chan, ints, "digits/yesterday", lang);
07399 } else {
07400 res = ast_say_date_with_format_gr(chan, t, ints, lang, "AdBY", tzone);
07401 }
07402 }
07403 break;
07404 case 'q':
07405
07406
07407
07408
07409 {
07410 struct timeval now = ast_tvnow();
07411 struct ast_tm tmnow;
07412 time_t beg_today;
07413
07414 ast_localtime(&now, &tmnow, tzone);
07415
07416
07417 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
07418 if (beg_today < t) {
07419
07420 } else if ((beg_today - 86400) < t) {
07421
07422 res = wait_file(chan, ints, "digits/yesterday", lang);
07423 } else if (beg_today - 86400 * 6 < t) {
07424
07425 res = ast_say_date_with_format_gr(chan, t, ints, lang, "A", tzone);
07426 } else {
07427 res = ast_say_date_with_format_gr(chan, t, ints, lang, "AdBY", tzone);
07428 }
07429 }
07430 break;
07431 case 'R':
07432 res = ast_say_date_with_format_gr(chan, t, ints, lang, "HM", tzone);
07433 break;
07434 case 'S':
07435
07436 ast_copy_string(nextmsg, "digits/kai", sizeof(nextmsg));
07437 res = wait_file(chan, ints, nextmsg, lang);
07438 if (!res)
07439 res = ast_say_number_full_gr(chan, tm.tm_sec, ints, lang, -1, -1);
07440 if (!res)
07441 ast_copy_string(nextmsg, "digits/seconds", sizeof(nextmsg));
07442 res = wait_file(chan, ints, nextmsg, lang);
07443 break;
07444 case 'T':
07445 res = ast_say_date_with_format_gr(chan, t, ints, lang, "HMS", tzone);
07446 break;
07447 case ' ':
07448 case ' ':
07449
07450 break;
07451 default:
07452
07453 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
07454 }
07455
07456 if (res) {
07457 break;
07458 }
07459 }
07460 return res;
07461 }
07462
07463
07464
07465
07466
07467
07468
07469
07470
07471
07472
07473
07474
07475
07476
07477
07478
07479
07480
07481
07482
07483
07484
07485
07486
07487
07488
07489 static char* ast_translate_number_ka(int num, char* res, int res_len)
07490 {
07491 char buf[256];
07492 int digit = 0;
07493 int remaining = 0;
07494
07495
07496 if (num < 0) {
07497 strncat(res, "minus ", res_len - strlen(res) - 1);
07498 if ( num > INT_MIN ) {
07499 num = -num;
07500 } else {
07501 num = 0;
07502 }
07503 }
07504
07505
07506
07507 if (num <= 20 || num == 40 || num == 60 || num == 80 || num == 100) {
07508 snprintf(buf, sizeof(buf), "%d", num);
07509 strncat(res, buf, res_len - strlen(res) - 1);
07510 return res;
07511 }
07512
07513
07514 if (num < 40) {
07515 strncat(res, "20_ ", res_len - strlen(res) - 1);
07516 return ast_translate_number_ka(num - 20, res, res_len);
07517 }
07518
07519 if (num < 60) {
07520 strncat(res, "40_ ", res_len - strlen(res) - 1);
07521 return ast_translate_number_ka(num - 40, res, res_len);
07522 }
07523
07524 if (num < 80) {
07525 strncat(res, "60_ ", res_len - strlen(res) - 1);
07526 return ast_translate_number_ka(num - 60, res, res_len);
07527 }
07528
07529 if (num < 100) {
07530 strncat(res, "80_ ", res_len - strlen(res) - 1);
07531 return ast_translate_number_ka(num - 80, res, res_len);
07532 }
07533
07534
07535 if (num < 1000) {
07536 remaining = num % 100;
07537 digit = (num - remaining) / 100;
07538
07539 if (remaining == 0) {
07540 snprintf(buf, sizeof(buf), "%d", num);
07541 strncat(res, buf, res_len - strlen(res) - 1);
07542 return res;
07543 } else {
07544 snprintf(buf, sizeof(buf), "%d_ ", digit*100);
07545 strncat(res, buf, res_len - strlen(res) - 1);
07546 return ast_translate_number_ka(remaining, res, res_len);
07547 }
07548 }
07549
07550
07551 if (num == 1000) {
07552 strncat(res, "1000", res_len - strlen(res) - 1);
07553 return res;
07554 }
07555
07556
07557 if (num < 1000000) {
07558 remaining = num % 1000;
07559 digit = (num - remaining) / 1000;
07560
07561 if (remaining == 0) {
07562 ast_translate_number_ka(digit, res, res_len);
07563 strncat(res, " 1000", res_len - strlen(res) - 1);
07564 return res;
07565 }
07566
07567 if (digit == 1) {
07568 strncat(res, "1000_ ", res_len - strlen(res) - 1);
07569 return ast_translate_number_ka(remaining, res, res_len);
07570 }
07571
07572 ast_translate_number_ka(digit, res, res_len);
07573 strncat(res, " 1000_ ", res_len - strlen(res) - 1);
07574 return ast_translate_number_ka(remaining, res, res_len);
07575 }
07576
07577
07578 if (num == 1000000) {
07579 strncat(res, "1 1000000", res_len - strlen(res) - 1);
07580 return res;
07581 }
07582
07583
07584 if (num < 1000000000) {
07585 remaining = num % 1000000;
07586 digit = (num - remaining) / 1000000;
07587
07588 if (remaining == 0) {
07589 ast_translate_number_ka(digit, res, res_len);
07590 strncat(res, " 1000000", res_len - strlen(res) - 1);
07591 return res;
07592 }
07593
07594 ast_translate_number_ka(digit, res, res_len);
07595 strncat(res, " 1000000_ ", res_len - strlen(res) - 1);
07596 return ast_translate_number_ka(remaining, res, res_len);
07597 }
07598
07599
07600 if (num == 1000000000) {
07601 strncat(res, "1 1000000000", res_len - strlen(res) - 1);
07602 return res;
07603 }
07604
07605
07606 if (num > 1000000000) {
07607 remaining = num % 1000000000;
07608 digit = (num - remaining) / 1000000000;
07609
07610 if (remaining == 0) {
07611 ast_translate_number_ka(digit, res, res_len);
07612 strncat(res, " 1000000000", res_len - strlen(res) - 1);
07613 return res;
07614 }
07615
07616 ast_translate_number_ka(digit, res, res_len);
07617 strncat(res, " 1000000000_ ", res_len - strlen(res) - 1);
07618 return ast_translate_number_ka(remaining, res, res_len);
07619 }
07620
07621 return res;
07622
07623 }
07624
07625
07626
07627
07628 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)
07629 {
07630 int res = 0;
07631 char fn[512] = "";
07632 char* s = 0;
07633 const char* remaining = fn;
07634
07635 if (!num)
07636 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
07637
07638
07639 ast_translate_number_ka(num, fn, 512);
07640
07641
07642
07643 while (res == 0 && (s = strstr(remaining, " "))) {
07644 size_t len = s - remaining;
07645 char* new_string = ast_malloc(len + 1 + strlen("digits/"));
07646
07647 sprintf(new_string, "digits/");
07648 strncat(new_string, remaining, len);
07649
07650
07651 if (!ast_streamfile(chan, new_string, language)) {
07652 if ((audiofd > -1) && (ctrlfd > -1))
07653 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
07654 else
07655 res = ast_waitstream(chan, ints);
07656 }
07657 ast_stopstream(chan);
07658
07659 ast_free(new_string);
07660
07661 remaining = s + 1;
07662 while (*remaining == ' ')
07663 remaining++;
07664 }
07665
07666
07667
07668 if (res == 0 && *remaining) {
07669
07670 char* new_string = ast_malloc(strlen(remaining) + 1 + strlen("digits/"));
07671 sprintf(new_string, "digits/%s", remaining);
07672
07673 if (!ast_streamfile(chan, new_string, language)) {
07674 if ((audiofd > -1) && (ctrlfd > -1))
07675 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
07676 else
07677 res = ast_waitstream(chan, ints);
07678 }
07679 ast_stopstream(chan);
07680
07681 ast_free(new_string);
07682
07683 }
07684
07685
07686 return res;
07687
07688 }
07689
07690
07691
07692
07693
07694
07695
07696
07697
07698
07699
07700
07701
07702
07703
07704
07705 static int ast_say_date_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07706 {
07707 struct timeval when = { t, 0 };
07708 struct ast_tm tm;
07709 char fn[256];
07710 int res = 0;
07711 ast_localtime(&when, &tm, NULL);
07712
07713 if (!res)
07714 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
07715
07716 if (!res) {
07717 snprintf(fn, sizeof(fn), "digits/tslis %d", tm.tm_wday);
07718 res = ast_streamfile(chan, fn, lang);
07719 if (!res)
07720 res = ast_waitstream(chan, ints);
07721 }
07722
07723 if (!res) {
07724 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
07725
07726
07727
07728 }
07729
07730 if (!res) {
07731 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07732 res = ast_streamfile(chan, fn, lang);
07733 if (!res)
07734 res = ast_waitstream(chan, ints);
07735 }
07736 return res;
07737
07738 }
07739
07740
07741
07742
07743
07744
07745 static int ast_say_time_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07746 {
07747 struct timeval when = { t, 0 };
07748 struct ast_tm tm;
07749 int res = 0;
07750
07751 ast_localtime(&when, &tm, NULL);
07752
07753 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char*)NULL);
07754 if (!res) {
07755 res = ast_streamfile(chan, "digits/saati_da", lang);
07756 if (!res)
07757 res = ast_waitstream(chan, ints);
07758 }
07759
07760 if (tm.tm_min) {
07761 if (!res) {
07762 res = ast_say_number(chan, tm.tm_min, ints, lang, (char*)NULL);
07763
07764 if (!res) {
07765 res = ast_streamfile(chan, "digits/tsuti", lang);
07766 if (!res)
07767 res = ast_waitstream(chan, ints);
07768 }
07769 }
07770 }
07771 return res;
07772 }
07773
07774
07775
07776
07777 static int ast_say_datetime_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07778 {
07779 struct timeval when = { t, 0 };
07780 struct ast_tm tm;
07781 int res = 0;
07782
07783 ast_localtime(&when, &tm, NULL);
07784 res = ast_say_date(chan, t, ints, lang);
07785 if (!res)
07786 ast_say_time(chan, t, ints, lang);
07787 return res;
07788
07789 }
07790
07791
07792
07793
07794
07795 static int ast_say_datetime_from_now_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07796 {
07797 int res=0;
07798 int daydiff;
07799 struct ast_tm tm;
07800 struct ast_tm now;
07801 struct timeval when = { t, 0 }, nowt = ast_tvnow();
07802 char fn[256];
07803
07804 ast_localtime(&when, &tm, NULL);
07805 ast_localtime(&nowt, &now, NULL);
07806 daydiff = now.tm_yday - tm.tm_yday;
07807 if ((daydiff < 0) || (daydiff > 6)) {
07808
07809 if (!res)
07810 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
07811 if (!res) {
07812 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07813 res = ast_streamfile(chan, fn, lang);
07814 if (!res)
07815 res = ast_waitstream(chan, ints);
07816 }
07817
07818 } else if (daydiff) {
07819
07820 if (!res) {
07821 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07822 res = ast_streamfile(chan, fn, lang);
07823 if (!res)
07824 res = ast_waitstream(chan, ints);
07825 }
07826 }
07827 if (!res)
07828 res = ast_say_time(chan, t, ints, lang);
07829
07830 return res;
07831 }
07832
07833
07834
07835
07836
07837
07838
07839
07840
07841
07842
07843 static const char *counted_noun_ending_en(int num)
07844 {
07845 if (num == 1 || num == -1) {
07846 return "";
07847 } else {
07848 return "s";
07849 }
07850 }
07851
07852
07853
07854
07855
07856
07857
07858
07859
07860
07861 static const char *counted_noun_ending_slavic(int num)
07862 {
07863 if (num < 0) {
07864 num *= -1;
07865 }
07866 num %= 100;
07867 if (num >= 20) {
07868 num %= 10;
07869 }
07870 if (num == 1) {
07871 return "";
07872 }
07873 if (num > 0 && num < 5) {
07874 return "x1";
07875 } else {
07876 return "x2";
07877 }
07878 }
07879
07880 int ast_say_counted_noun(struct ast_channel *chan, int num, const char noun[])
07881 {
07882 char *temp;
07883 int temp_len;
07884 const char *ending;
07885 if (!strncasecmp(chan->language, "ru", 2)) {
07886 ending = counted_noun_ending_slavic(num);
07887 } else if (!strncasecmp(chan->language, "ua", 2)) {
07888 ending = counted_noun_ending_slavic(num);
07889 } else if (!strncasecmp(chan->language, "pl", 2)) {
07890 ending = counted_noun_ending_slavic(num);
07891 } else {
07892 ending = counted_noun_ending_en(num);
07893 }
07894 temp = alloca((temp_len = (strlen(noun) + strlen(ending) + 1)));
07895 snprintf(temp, temp_len, "%s%s", noun, ending);
07896 return ast_play_and_wait(chan, temp);
07897 }
07898
07899
07900
07901
07902
07903
07904
07905
07906 static const char *counted_adjective_ending_ru(int num, const char gender[])
07907 {
07908 if (num < 0) {
07909 num *= -1;
07910 }
07911 num %= 100;
07912 if (num >= 20) {
07913 num %= 10;
07914 }
07915 if (num == 1) {
07916 return gender ? gender : "";
07917 } else {
07918 return "x";
07919 }
07920 }
07921
07922 int ast_say_counted_adjective(struct ast_channel *chan, int num, const char adjective[], const char gender[])
07923 {
07924 char *temp;
07925 int temp_len;
07926 const char *ending;
07927 if (!strncasecmp(chan->language, "ru", 2)) {
07928 ending = counted_adjective_ending_ru(num, gender);
07929 } else if (!strncasecmp(chan->language, "ua", 2)) {
07930 ending = counted_adjective_ending_ru(num, gender);
07931 } else if (!strncasecmp(chan->language, "pl", 2)) {
07932 ending = counted_adjective_ending_ru(num, gender);
07933 } else {
07934 ending = "";
07935 }
07936 temp = alloca((temp_len = (strlen(adjective) + strlen(ending) + 1)));
07937 snprintf(temp, temp_len, "%s%s", adjective, ending);
07938 return ast_play_and_wait(chan, temp);
07939 }
07940
07941
07942
07943
07944
07945
07946 static void __attribute__((constructor)) __say_init(void)
07947 {
07948 ast_say_number_full = say_number_full;
07949 ast_say_enumeration_full = say_enumeration_full;
07950 ast_say_digit_str_full = say_digit_str_full;
07951 ast_say_character_str_full = say_character_str_full;
07952 ast_say_phonetic_str_full = say_phonetic_str_full;
07953 ast_say_datetime = say_datetime;
07954 ast_say_time = say_time;
07955 ast_say_date = say_date;
07956 ast_say_datetime_from_now = say_datetime_from_now;
07957 ast_say_date_with_format = say_date_with_format;
07958 }