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