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