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