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