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