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