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