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