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