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