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: 205188 $")
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 sndoffset=0;
03291 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
03292 sndfile[sndoffset] = format[offset];
03293 sndfile[sndoffset] = '\0';
03294 res = wait_file(chan,ints,sndfile,lang);
03295 break;
03296 case 'A':
03297 case 'a':
03298
03299 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
03300 res = wait_file(chan,ints,nextmsg,lang);
03301 break;
03302 case 'B':
03303 case 'b':
03304 case 'h':
03305
03306 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
03307 res = wait_file(chan,ints,nextmsg,lang);
03308 break;
03309 case 'm':
03310
03311 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, (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
03515 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)
03516 {
03517 struct tm tm;
03518 int res=0, offset, sndoffset;
03519 char sndfile[256], nextmsg[256];
03520
03521 if (!format)
03522 format = "A dBY HMS";
03523
03524 ast_localtime(&time,&tm,timezone);
03525
03526 for (offset=0 ; format[offset] != '\0' ; offset++) {
03527 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
03528 switch (format[offset]) {
03529
03530 case '\'':
03531
03532 sndoffset=0;
03533 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
03534 sndfile[sndoffset] = format[offset];
03535 sndfile[sndoffset] = '\0';
03536 res = wait_file(chan,ints,sndfile,lang);
03537 break;
03538 case 'A':
03539 case 'a':
03540
03541 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
03542 res = wait_file(chan,ints,nextmsg,lang);
03543 break;
03544 case 'B':
03545 case 'b':
03546 case 'h':
03547
03548 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
03549 res = wait_file(chan,ints,nextmsg,lang);
03550 break;
03551 case 'm':
03552
03553 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
03554 break;
03555 case 'd':
03556 case 'e':
03557
03558 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
03559 break;
03560 case 'Y':
03561
03562 {
03563 int year = tm.tm_year + 1900;
03564 if (year > 1999) {
03565 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
03566 } else {
03567 if (year < 1100) {
03568
03569
03570 } else {
03571
03572
03573 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", (year / 100) );
03574 res = wait_file(chan,ints,nextmsg,lang);
03575 if (!res) {
03576 res = wait_file(chan,ints, "digits/hundred",lang);
03577 if (!res && year % 100 != 0) {
03578 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
03579 }
03580 }
03581 }
03582 }
03583 }
03584 break;
03585 case 'I':
03586 case 'l':
03587
03588 res = wait_file(chan,ints,"digits/oclock",lang);
03589 if (tm.tm_hour == 0)
03590 snprintf(nextmsg,sizeof(nextmsg), "digits/12");
03591 else if (tm.tm_hour > 12)
03592 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
03593 else
03594 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
03595 if (!res) {
03596 res = wait_file(chan,ints,nextmsg,lang);
03597 }
03598 break;
03599 case 'H':
03600
03601 if (tm.tm_hour < 10 && tm.tm_hour > 0) {
03602 res = wait_file(chan,ints, "digits/0",lang);
03603 }
03604
03605 case 'k':
03606
03607 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
03608 break;
03609 case 'M':
03610
03611 if (tm.tm_min > 0 || format[offset+ 1 ] == 'S' ) {
03612 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
03613 }
03614 if ( !res && format[offset + 1] == 'S' ) {
03615 if (tm.tm_min == 1) {
03616 res = wait_file(chan,ints,"digits/minute",lang);
03617 } else {
03618 res = wait_file(chan,ints,"digits/minutes",lang);
03619 }
03620 }
03621 break;
03622 case 'P':
03623 case 'p':
03624
03625 if (tm.tm_hour > 11)
03626 snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
03627 else
03628 snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
03629 res = wait_file(chan,ints,nextmsg,lang);
03630 break;
03631 case 'Q':
03632
03633
03634
03635
03636 {
03637 struct timeval now;
03638 struct tm tmnow;
03639 time_t beg_today, tt;
03640
03641 gettimeofday(&now,NULL);
03642 tt = now.tv_sec;
03643 ast_localtime(&tt,&tmnow,timezone);
03644
03645
03646 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03647 if (beg_today < time) {
03648
03649 res = wait_file(chan,ints, "digits/today",lang);
03650 } else if (beg_today - 86400 < time) {
03651
03652 res = wait_file(chan,ints, "digits/yesterday",lang);
03653 } else {
03654 res = ast_say_date_with_format_da(chan, time, ints, lang, "AdBY", timezone);
03655 }
03656 }
03657 break;
03658 case 'q':
03659
03660
03661
03662
03663 {
03664 struct timeval now;
03665 struct tm tmnow;
03666 time_t beg_today, tt;
03667
03668 gettimeofday(&now,NULL);
03669 tt = now.tv_sec;
03670 ast_localtime(&tt,&tmnow,timezone);
03671
03672
03673 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03674 if (beg_today < time) {
03675
03676 } else if ((beg_today - 86400) < time) {
03677
03678 res = wait_file(chan,ints, "digits/yesterday",lang);
03679 } else if (beg_today - 86400 * 6 < time) {
03680
03681 res = ast_say_date_with_format_da(chan, time, ints, lang, "A", timezone);
03682 } else {
03683 res = ast_say_date_with_format_da(chan, time, ints, lang, "AdBY", timezone);
03684 }
03685 }
03686 break;
03687 case 'R':
03688 res = ast_say_date_with_format_da(chan, time, ints, lang, "HM", timezone);
03689 break;
03690 case 'S':
03691
03692 res = wait_file(chan,ints, "digits/and",lang);
03693 if (!res) {
03694 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
03695 if (!res) {
03696 res = wait_file(chan,ints, "digits/seconds",lang);
03697 }
03698 }
03699 break;
03700 case 'T':
03701 res = ast_say_date_with_format_da(chan, time, ints, lang, "HMS", timezone);
03702 break;
03703 case ' ':
03704 case ' ':
03705
03706 break;
03707 default:
03708
03709 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
03710 }
03711
03712 if (res) {
03713 break;
03714 }
03715 }
03716 return res;
03717 }
03718
03719
03720 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)
03721 {
03722 struct tm tm;
03723 int res=0, offset, sndoffset;
03724 char sndfile[256], nextmsg[256];
03725
03726 if (!format)
03727 format = "A dBY HMS";
03728
03729 ast_localtime(&time,&tm,timezone);
03730
03731 for (offset=0 ; format[offset] != '\0' ; offset++) {
03732 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
03733 switch (format[offset]) {
03734
03735 case '\'':
03736
03737 sndoffset=0;
03738 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
03739 sndfile[sndoffset] = format[offset];
03740 sndfile[sndoffset] = '\0';
03741 res = wait_file(chan,ints,sndfile,lang);
03742 break;
03743 case 'A':
03744 case 'a':
03745
03746 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
03747 res = wait_file(chan,ints,nextmsg,lang);
03748 break;
03749 case 'B':
03750 case 'b':
03751 case 'h':
03752
03753 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
03754 res = wait_file(chan,ints,nextmsg,lang);
03755 break;
03756 case 'm':
03757
03758 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, "m");
03759 break;
03760 case 'd':
03761 case 'e':
03762
03763 res = ast_say_enumeration(chan, tm.tm_mday, ints, lang, "m");
03764 break;
03765 case 'Y':
03766
03767 {
03768 int year = tm.tm_year + 1900;
03769 if (year > 1999) {
03770 res = ast_say_number(chan, year, ints, lang, (char *) NULL);
03771 } else {
03772 if (year < 1100) {
03773
03774
03775 } else {
03776
03777
03778 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", (year / 100) );
03779 res = wait_file(chan,ints,nextmsg,lang);
03780 if (!res) {
03781 res = wait_file(chan,ints, "digits/hundred",lang);
03782 if (!res && year % 100 != 0) {
03783 res = ast_say_number(chan, (year % 100), ints, lang, (char *) NULL);
03784 }
03785 }
03786 }
03787 }
03788 }
03789 break;
03790 case 'I':
03791 case 'l':
03792
03793 if (tm.tm_hour == 0)
03794 snprintf(nextmsg,sizeof(nextmsg), "digits/12");
03795 else if (tm.tm_hour > 12)
03796 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
03797 else
03798 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
03799 res = wait_file(chan,ints,nextmsg,lang);
03800 if (!res) {
03801 res = wait_file(chan,ints,"digits/oclock",lang);
03802 }
03803 break;
03804 case 'H':
03805 case 'k':
03806
03807 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
03808 if (!res) {
03809 res = wait_file(chan,ints,"digits/oclock",lang);
03810 }
03811 break;
03812 case 'M':
03813
03814 if (tm.tm_min > 0 || format[offset+ 1 ] == 'S' ) {
03815 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
03816 }
03817 if ( !res && format[offset + 1] == 'S' ) {
03818 if (tm.tm_min == 1) {
03819 res = wait_file(chan,ints,"digits/minute",lang);
03820 } else {
03821 res = wait_file(chan,ints,"digits/minutes",lang);
03822 }
03823 }
03824 break;
03825 case 'P':
03826 case 'p':
03827
03828 if (tm.tm_hour > 11)
03829 snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
03830 else
03831 snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
03832 res = wait_file(chan,ints,nextmsg,lang);
03833 break;
03834 case 'Q':
03835
03836
03837
03838
03839 {
03840 struct timeval now;
03841 struct tm tmnow;
03842 time_t beg_today, tt;
03843
03844 gettimeofday(&now,NULL);
03845 tt = now.tv_sec;
03846 ast_localtime(&tt,&tmnow,timezone);
03847
03848
03849 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03850 if (beg_today < time) {
03851
03852 res = wait_file(chan,ints, "digits/today",lang);
03853 } else if (beg_today - 86400 < time) {
03854
03855 res = wait_file(chan,ints, "digits/yesterday",lang);
03856 } else {
03857 res = ast_say_date_with_format_de(chan, time, ints, lang, "AdBY", timezone);
03858 }
03859 }
03860 break;
03861 case 'q':
03862
03863
03864
03865
03866 {
03867 struct timeval now;
03868 struct tm tmnow;
03869 time_t beg_today, tt;
03870
03871 gettimeofday(&now,NULL);
03872 tt = now.tv_sec;
03873 ast_localtime(&tt,&tmnow,timezone);
03874
03875
03876 beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
03877 if (beg_today < time) {
03878
03879 } else if ((beg_today - 86400) < time) {
03880
03881 res = wait_file(chan,ints, "digits/yesterday",lang);
03882 } else if (beg_today - 86400 * 6 < time) {
03883
03884 res = ast_say_date_with_format_de(chan, time, ints, lang, "A", timezone);
03885 } else {
03886 res = ast_say_date_with_format_de(chan, time, ints, lang, "AdBY", timezone);
03887 }
03888 }
03889 break;
03890 case 'R':
03891 res = ast_say_date_with_format_de(chan, time, ints, lang, "HM", timezone);
03892 break;
03893 case 'S':
03894
03895 res = wait_file(chan,ints, "digits/and",lang);
03896 if (!res) {
03897 res = ast_say_number(chan, tm.tm_sec, ints, lang, "f");
03898 if (!res) {
03899 res = wait_file(chan,ints, "digits/seconds",lang);
03900 }
03901 }
03902 break;
03903 case 'T':
03904 res = ast_say_date_with_format_de(chan, time, ints, lang, "HMS", timezone);
03905 break;
03906 case ' ':
03907 case ' ':
03908
03909 break;
03910 default:
03911
03912 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
03913 }
03914
03915 if (res) {
03916 break;
03917 }
03918 }
03919 return res;
03920 }
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942 #define IL_DATE_STR "AdBY"
03943 #define IL_TIME_STR "HM"
03944 #define IL_DATE_STR_FULL IL_DATE_STR " 'digits/at' " IL_TIME_STR
03945 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)
03946 {
03947
03948
03949
03950 struct tm tm;
03951 int res = 0, offset, sndoffset;
03952 char sndfile[256], nextmsg[256];
03953
03954 if (!format) {
03955 format = IL_DATE_STR_FULL;
03956 }
03957
03958 ast_localtime(&time, &tm, timezone);
03959
03960 for (offset = 0; format[offset] != '\0'; offset++) {
03961 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
03962 switch (format[offset]) {
03963
03964 case '\'':
03965
03966 sndoffset=0;
03967 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
03968 sndfile[sndoffset] = format[offset];
03969 sndfile[sndoffset] = '\0';
03970 res = wait_file(chan,ints,sndfile,lang);
03971 break;
03972 case 'A':
03973 case 'a':
03974
03975 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
03976 res = wait_file(chan,ints,nextmsg,lang);
03977 break;
03978 case 'B':
03979 case 'b':
03980 case 'h':
03981
03982 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
03983 res = wait_file(chan,ints,nextmsg,lang);
03984 break;
03985 case 'd':
03986 case 'e':
03987
03988
03989
03990
03991
03992
03993
03994 res = ast_say_number_full_he(chan, tm.tm_mday, ints, lang, "m", -1, -1);
03995 break;
03996 case 'Y':
03997 res = ast_say_number_full_he(chan, tm.tm_year+1900,
03998 ints, lang, "f", -1, -1
03999 );
04000 break;
04001 case 'I':
04002 case 'l':
04003 case 'H':
04004 case 'k':
04005 res = ast_say_number_full_he(chan, tm.tm_hour, ints, lang, "f", -1, -1);
04006 break;
04007 case 'M':
04008 if (tm.tm_min >= 0 && tm.tm_min <= 9)
04009 res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
04010 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
04011 break;
04012 case 'P':
04013 case 'p':
04014
04015 break;
04016 case 'Q':
04017
04018 case 'q':
04019
04020
04021
04022
04023
04024 {
04025 struct timeval now;
04026 struct tm tmnow;
04027 time_t beg_today, tt;
04028 char todo = format[offset];
04029
04030 gettimeofday(&now,NULL);
04031 tt = now.tv_sec;
04032 ast_localtime(&tt,&tmnow,timezone);
04033
04034
04035 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04036 if (beg_today < time) {
04037
04038 if (todo == 'Q') {
04039 res = wait_file(chan,
04040 ints,
04041 "digits/today",
04042 lang);
04043 }
04044 } else if (beg_today - 86400 < time) {
04045
04046 res = wait_file(chan,ints, "digits/yesterday",lang);
04047 } else if ((todo != 'Q') &&
04048 (beg_today - 86400 * 6 < time))
04049 {
04050
04051 res = ast_say_date_with_format_he(chan,
04052 time, ints, lang,
04053 "A", timezone);
04054 } else {
04055 res = ast_say_date_with_format_he(chan,
04056 time, ints, lang,
04057 IL_DATE_STR, timezone);
04058 }
04059 }
04060 break;
04061 case 'R':
04062 res = ast_say_date_with_format_he(chan, time, ints, lang, "HM", timezone);
04063 break;
04064 case 'S':
04065 res = ast_say_number_full_he(chan, tm.tm_sec,
04066 ints, lang, "f", -1, -1
04067 );
04068 break;
04069 case 'T':
04070 res = ast_say_date_with_format_he(chan, time, ints, lang, "HMS", timezone);
04071 break;
04072
04073
04074 case 'c':
04075 res = ast_say_date_with_format_he(chan, time,
04076 ints, lang, IL_DATE_STR_FULL, timezone);
04077 break;
04078 case 'x':
04079 res = ast_say_date_with_format_he(chan, time,
04080 ints, lang, IL_DATE_STR, timezone);
04081 break;
04082 case 'X':
04083 res = ast_say_date_with_format_he(chan, time,
04084 ints, lang, IL_TIME_STR, timezone);
04085 break;
04086 case ' ':
04087 case ' ':
04088
04089 break;
04090 default:
04091
04092 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04093 }
04094
04095 if (res) {
04096 break;
04097 }
04098 }
04099 return res;
04100 }
04101
04102
04103
04104 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)
04105 {
04106 struct tm tm;
04107 int res=0, offset, sndoffset;
04108 char sndfile[256], nextmsg[256];
04109
04110 if (format == NULL)
04111 format = "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y 'digits/at' IMp";
04112
04113 ast_localtime(&time,&tm,timezone);
04114
04115 for (offset=0 ; format[offset] != '\0' ; offset++) {
04116 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04117 switch (format[offset]) {
04118
04119 case '\'':
04120
04121 sndoffset=0;
04122 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
04123 sndfile[sndoffset] = format[offset];
04124 sndfile[sndoffset] = '\0';
04125 snprintf(nextmsg,sizeof(nextmsg), "%s", sndfile);
04126 res = wait_file(chan,ints,nextmsg,lang);
04127 break;
04128 case 'A':
04129 case 'a':
04130
04131 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04132 res = wait_file(chan,ints,nextmsg,lang);
04133 break;
04134 case 'B':
04135 case 'b':
04136 case 'h':
04137
04138 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04139 res = wait_file(chan,ints,nextmsg,lang);
04140 break;
04141 case 'm':
04142
04143 snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04144 res = wait_file(chan,ints,nextmsg,lang);
04145 break;
04146 case 'd':
04147 case 'e':
04148
04149 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
04150 break;
04151 case 'Y':
04152
04153 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
04154 break;
04155 case 'I':
04156 case 'l':
04157
04158 if (tm.tm_hour == 0)
04159 snprintf(nextmsg,sizeof(nextmsg), "digits/12");
04160 else if (tm.tm_hour > 12)
04161 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04162 else
04163 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
04164 res = wait_file(chan,ints,nextmsg,lang);
04165 break;
04166 case 'H':
04167 case 'k':
04168
04169 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
04170 if ((!res) && (format[offset] == 'H')) {
04171 if (tm.tm_hour == 1) {
04172 res = wait_file(chan,ints,"digits/hour",lang);
04173 } else {
04174 res = wait_file(chan,ints,"digits/hours",lang);
04175 }
04176 }
04177 break;
04178 break;
04179 case 'M':
04180
04181 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04182 if (!res) {
04183 if (tm.tm_min == 1) {
04184 res = wait_file(chan,ints,"digits/minute",lang);
04185 } else {
04186 res = wait_file(chan,ints,"digits/minutes",lang);
04187 }
04188 }
04189 break;
04190 case 'P':
04191 case 'p':
04192
04193 if (tm.tm_hour > 18)
04194 res = wait_file(chan, ints, "digits/p-m", lang);
04195 else if (tm.tm_hour > 12)
04196 res = wait_file(chan, ints, "digits/afternoon", lang);
04197 else if (tm.tm_hour)
04198 res = wait_file(chan, ints, "digits/a-m", lang);
04199 break;
04200 case 'Q':
04201
04202
04203
04204
04205 {
04206 struct timeval now;
04207 struct tm tmnow;
04208 time_t beg_today, tt;
04209
04210 gettimeofday(&now,NULL);
04211 tt = now.tv_sec;
04212 ast_localtime(&tt,&tmnow,timezone);
04213
04214
04215 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04216 if (beg_today < time) {
04217
04218 res = wait_file(chan,ints, "digits/today",lang);
04219 } else if (beg_today - 86400 < time) {
04220
04221 res = wait_file(chan,ints, "digits/yesterday",lang);
04222 } else {
04223 res = ast_say_date_with_format_es(chan, time, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", timezone);
04224 }
04225 }
04226 break;
04227 case 'q':
04228
04229
04230
04231
04232 {
04233 struct timeval now;
04234 struct tm tmnow;
04235 time_t beg_today, tt;
04236
04237 gettimeofday(&now,NULL);
04238 tt = now.tv_sec;
04239 ast_localtime(&tt,&tmnow,timezone);
04240
04241
04242 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04243 if (beg_today < time) {
04244
04245 res = wait_file(chan,ints, "digits/today",lang);
04246 } else if ((beg_today - 86400) < time) {
04247
04248 res = wait_file(chan,ints, "digits/yesterday",lang);
04249 } else if (beg_today - 86400 * 6 < time) {
04250
04251 res = ast_say_date_with_format_es(chan, time, ints, lang, "A", timezone);
04252 } else {
04253 res = ast_say_date_with_format_es(chan, time, ints, lang, "'digits/es-el' Ad 'digits/es-de' B 'digits/es-de' Y", timezone);
04254 }
04255 }
04256 break;
04257 case 'R':
04258 res = ast_say_date_with_format_es(chan, time, ints, lang, "H 'digits/and' M", timezone);
04259 break;
04260 case 'S':
04261
04262 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
04263 if (!res) {
04264 if (tm.tm_sec == 1) {
04265 res = wait_file(chan,ints,"digits/second",lang);
04266 } else {
04267 res = wait_file(chan,ints,"digits/seconds",lang);
04268 }
04269 }
04270 break;
04271 case 'T':
04272 res = ast_say_date_with_format_es(chan, time, ints, lang, "HMS", timezone);
04273 break;
04274 case ' ':
04275 case ' ':
04276
04277 break;
04278 default:
04279
04280 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04281 }
04282
04283 if (res) {
04284 break;
04285 }
04286 }
04287 return res;
04288 }
04289
04290
04291
04292
04293 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)
04294 {
04295 struct tm tm;
04296 int res=0, offset, sndoffset;
04297 char sndfile[256], nextmsg[256];
04298
04299 if (format == NULL)
04300 format = "AdBY 'digits/at' IMp";
04301
04302 ast_localtime(&time,&tm,timezone);
04303
04304 for (offset=0 ; format[offset] != '\0' ; offset++) {
04305 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04306 switch (format[offset]) {
04307
04308 case '\'':
04309
04310 sndoffset=0;
04311 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
04312 sndfile[sndoffset] = format[offset];
04313 sndfile[sndoffset] = '\0';
04314 res = wait_file(chan,ints,sndfile,lang);
04315 break;
04316 case 'A':
04317 case 'a':
04318
04319 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04320 res = wait_file(chan,ints,nextmsg,lang);
04321 break;
04322 case 'B':
04323 case 'b':
04324 case 'h':
04325
04326 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04327 res = wait_file(chan,ints,nextmsg,lang);
04328 break;
04329 case 'm':
04330
04331 snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04332 res = wait_file(chan,ints,nextmsg,lang);
04333 break;
04334 case 'd':
04335 case 'e':
04336
04337 if (tm.tm_mday == 1) {
04338 snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
04339 res = wait_file(chan,ints,nextmsg,lang);
04340 } else {
04341 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
04342 }
04343 break;
04344 case 'Y':
04345
04346 if (tm.tm_year > 99) {
04347 res = wait_file(chan,ints, "digits/2",lang);
04348 if (!res) {
04349 res = wait_file(chan,ints, "digits/thousand",lang);
04350 }
04351 if (tm.tm_year > 100) {
04352 if (!res) {
04353 res = ast_say_number(chan, tm.tm_year - 100, ints, lang, (char * ) NULL);
04354 }
04355 }
04356 } else {
04357 if (tm.tm_year < 1) {
04358
04359
04360 } else {
04361 res = wait_file(chan,ints, "digits/thousand",lang);
04362 if (!res) {
04363 wait_file(chan,ints, "digits/9",lang);
04364 wait_file(chan,ints, "digits/hundred",lang);
04365 res = ast_say_number(chan, tm.tm_year, ints, lang, (char * ) NULL);
04366 }
04367 }
04368 }
04369 break;
04370 case 'I':
04371 case 'l':
04372
04373 if (tm.tm_hour == 0)
04374 snprintf(nextmsg,sizeof(nextmsg), "digits/12");
04375 else if (tm.tm_hour > 12)
04376 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04377 else
04378 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
04379 res = wait_file(chan,ints,nextmsg,lang);
04380 if (!res)
04381 res = wait_file(chan,ints, "digits/oclock",lang);
04382 break;
04383 case 'H':
04384 case 'k':
04385
04386 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char * ) NULL);
04387 if (!res)
04388 res = wait_file(chan,ints, "digits/oclock",lang);
04389 break;
04390 case 'M':
04391
04392 if (tm.tm_min == 0) {
04393 break;
04394 }
04395 res = ast_say_number(chan, tm.tm_min, ints, lang, (char * ) NULL);
04396 break;
04397 case 'P':
04398 case 'p':
04399
04400 if (tm.tm_hour > 11)
04401 snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
04402 else
04403 snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
04404 res = wait_file(chan,ints,nextmsg,lang);
04405 break;
04406 case 'Q':
04407
04408
04409
04410
04411 {
04412 struct timeval now;
04413 struct tm tmnow;
04414 time_t beg_today, tt;
04415
04416 gettimeofday(&now,NULL);
04417 tt = now.tv_sec;
04418 ast_localtime(&tt,&tmnow,timezone);
04419
04420
04421 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04422 if (beg_today < time) {
04423
04424 res = wait_file(chan,ints, "digits/today",lang);
04425 } else if (beg_today - 86400 < time) {
04426
04427 res = wait_file(chan,ints, "digits/yesterday",lang);
04428 } else {
04429 res = ast_say_date_with_format_fr(chan, time, ints, lang, "AdBY", timezone);
04430 }
04431 }
04432 break;
04433 case 'q':
04434
04435
04436
04437
04438 {
04439 struct timeval now;
04440 struct tm tmnow;
04441 time_t beg_today, tt;
04442
04443 gettimeofday(&now,NULL);
04444 tt = now.tv_sec;
04445 ast_localtime(&tt,&tmnow,timezone);
04446
04447
04448 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04449 if (beg_today < time) {
04450
04451 } else if ((beg_today - 86400) < time) {
04452
04453 res = wait_file(chan,ints, "digits/yesterday",lang);
04454 } else if (beg_today - 86400 * 6 < time) {
04455
04456 res = ast_say_date_with_format_fr(chan, time, ints, lang, "A", timezone);
04457 } else {
04458 res = ast_say_date_with_format_fr(chan, time, ints, lang, "AdBY", timezone);
04459 }
04460 }
04461 break;
04462 case 'R':
04463 res = ast_say_date_with_format_fr(chan, time, ints, lang, "HM", timezone);
04464 break;
04465 case 'S':
04466
04467 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char * ) NULL);
04468 if (!res) {
04469 res = wait_file(chan,ints, "digits/second",lang);
04470 }
04471 break;
04472 case 'T':
04473 res = ast_say_date_with_format_fr(chan, time, ints, lang, "HMS", timezone);
04474 break;
04475 case ' ':
04476 case ' ':
04477
04478 break;
04479 default:
04480
04481 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04482 }
04483
04484 if (res) {
04485 break;
04486 }
04487 }
04488 return res;
04489 }
04490
04491 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)
04492 {
04493 struct tm tm;
04494 int res=0, offset, sndoffset;
04495 char sndfile[256], nextmsg[256];
04496
04497 if (format == NULL)
04498 format = "AdB 'digits/at' IMp";
04499
04500 ast_localtime(&time,&tm,timezone);
04501
04502 for (offset=0 ; format[offset] != '\0' ; offset++) {
04503 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04504 switch (format[offset]) {
04505
04506 case '\'':
04507
04508 sndoffset=0;
04509 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
04510 sndfile[sndoffset] = format[offset];
04511 sndfile[sndoffset] = '\0';
04512 res = wait_file(chan,ints,sndfile,lang);
04513 break;
04514 case 'A':
04515 case 'a':
04516
04517 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04518 res = wait_file(chan,ints,nextmsg,lang);
04519 break;
04520 case 'B':
04521 case 'b':
04522 case 'h':
04523
04524 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04525 res = wait_file(chan,ints,nextmsg,lang);
04526 break;
04527 case 'm':
04528
04529 snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04530 res = wait_file(chan,ints,nextmsg,lang);
04531 break;
04532 case 'd':
04533 case 'e':
04534
04535 if (tm.tm_mday == 1) {
04536 snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
04537 res = wait_file(chan,ints,nextmsg,lang);
04538 } else {
04539 if (!res) {
04540 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
04541 }
04542 }
04543 break;
04544 case 'Y':
04545
04546 if (tm.tm_year > 99) {
04547 res = wait_file(chan,ints, "digits/ore-2000",lang);
04548 if (tm.tm_year > 100) {
04549 if (!res) {
04550
04551 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
04552 res = wait_file(chan,ints,nextmsg,lang);
04553 }
04554 }
04555 } else {
04556 if (tm.tm_year < 1) {
04557
04558
04559 } else {
04560 res = wait_file(chan,ints, "digits/ore-1900",lang);
04561 if ((!res) && (tm.tm_year != 0)) {
04562 if (tm.tm_year <= 21) {
04563
04564 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
04565 res = wait_file(chan,ints,nextmsg,lang);
04566 } else {
04567
04568 int ten, one;
04569 ten = tm.tm_year / 10;
04570 one = tm.tm_year % 10;
04571 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten * 10);
04572 res = wait_file(chan,ints,nextmsg,lang);
04573 if (!res) {
04574 if (one != 0) {
04575 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
04576 res = wait_file(chan,ints,nextmsg,lang);
04577 }
04578 }
04579 }
04580 }
04581 }
04582 }
04583 break;
04584 case 'I':
04585 case 'l':
04586
04587 if (tm.tm_hour == 0)
04588 snprintf(nextmsg,sizeof(nextmsg), "digits/12");
04589 else if (tm.tm_hour > 12)
04590 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04591 else
04592 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
04593 res = wait_file(chan,ints,nextmsg,lang);
04594 break;
04595 case 'H':
04596 case 'k':
04597
04598 if (tm.tm_hour == 0) {
04599 res = wait_file(chan,ints, "digits/ore-mezzanotte",lang);
04600 } else if (tm.tm_hour == 1) {
04601 res = wait_file(chan,ints, "digits/ore-una",lang);
04602 } else {
04603 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
04604 }
04605 break;
04606 case 'M':
04607
04608 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04609 break;
04610 case 'P':
04611 case 'p':
04612
04613 if (tm.tm_hour > 11)
04614 snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
04615 else
04616 snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
04617 res = wait_file(chan,ints,nextmsg,lang);
04618 break;
04619 case 'Q':
04620
04621
04622
04623
04624 {
04625 struct timeval now;
04626 struct tm tmnow;
04627 time_t beg_today, tt;
04628
04629 gettimeofday(&now,NULL);
04630 tt = now.tv_sec;
04631 ast_localtime(&tt,&tmnow,timezone);
04632
04633
04634 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04635 if (beg_today < time) {
04636
04637 res = wait_file(chan,ints, "digits/today",lang);
04638 } else if (beg_today - 86400 < time) {
04639
04640 res = wait_file(chan,ints, "digits/yesterday",lang);
04641 } else {
04642 res = ast_say_date_with_format_it(chan, time, ints, lang, "AdB", timezone);
04643 }
04644 }
04645 break;
04646 case 'q':
04647
04648 {
04649 struct timeval now;
04650 struct tm tmnow;
04651 time_t beg_today, tt;
04652
04653 gettimeofday(&now,NULL);
04654 tt = now.tv_sec;
04655 ast_localtime(&tt,&tmnow,timezone);
04656
04657
04658 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04659 if (beg_today < time) {
04660
04661 } else if ((beg_today - 86400) < time) {
04662
04663 res = wait_file(chan,ints, "digits/yesterday",lang);
04664 } else if (beg_today - 86400 * 6 < time) {
04665
04666 res = ast_say_date_with_format_it(chan, time, ints, lang, "A", timezone);
04667 } else {
04668 res = ast_say_date_with_format_it(chan, time, ints, lang, "AdB", timezone);
04669 }
04670 }
04671 break;
04672 case 'R':
04673 res = ast_say_date_with_format_it(chan, time, ints, lang, "HM", timezone);
04674 break;
04675 case 'S':
04676
04677 if (tm.tm_sec == 0) {
04678 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
04679 res = wait_file(chan,ints,nextmsg,lang);
04680 } else if (tm.tm_sec < 10) {
04681 res = wait_file(chan,ints, "digits/oh",lang);
04682 if (!res) {
04683 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
04684 res = wait_file(chan,ints,nextmsg,lang);
04685 }
04686 } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
04687 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
04688 res = wait_file(chan,ints,nextmsg,lang);
04689 } else {
04690 int ten, one;
04691 ten = (tm.tm_sec / 10) * 10;
04692 one = (tm.tm_sec % 10);
04693 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
04694 res = wait_file(chan,ints,nextmsg,lang);
04695 if (!res) {
04696
04697 if (one != 0) {
04698 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
04699 res = wait_file(chan,ints,nextmsg,lang);
04700 }
04701 }
04702 }
04703 break;
04704 case 'T':
04705 res = ast_say_date_with_format_it(chan, time, ints, lang, "HMS", timezone);
04706 break;
04707 case ' ':
04708 case ' ':
04709
04710 break;
04711 default:
04712
04713 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04714 }
04715
04716 if (res) {
04717 break;
04718 }
04719 }
04720 return res;
04721 }
04722
04723
04724 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)
04725 {
04726 struct tm tm;
04727 int res=0, offset, sndoffset;
04728 char sndfile[256], nextmsg[256];
04729
04730 if (format == NULL)
04731 format = "ABdY 'digits/at' IMp";
04732
04733 ast_localtime(&time,&tm,timezone);
04734
04735 for (offset=0 ; format[offset] != '\0' ; offset++) {
04736 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04737 switch (format[offset]) {
04738
04739 case '\'':
04740
04741 sndoffset=0;
04742 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
04743 sndfile[sndoffset] = format[offset];
04744 sndfile[sndoffset] = '\0';
04745 res = wait_file(chan,ints,sndfile,lang);
04746 break;
04747 case 'A':
04748 case 'a':
04749
04750 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04751 res = wait_file(chan,ints,nextmsg,lang);
04752 break;
04753 case 'B':
04754 case 'b':
04755 case 'h':
04756
04757 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04758 res = wait_file(chan,ints,nextmsg,lang);
04759 break;
04760 case 'm':
04761
04762 snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
04763 res = wait_file(chan,ints,nextmsg,lang);
04764 break;
04765 case 'd':
04766 case 'e':
04767
04768 res = ast_say_number(chan, tm.tm_mday, ints, lang, NULL);
04769 break;
04770 case 'Y':
04771
04772 if (tm.tm_year > 99) {
04773 res = wait_file(chan,ints, "digits/2",lang);
04774 if (!res) {
04775 res = wait_file(chan,ints, "digits/thousand",lang);
04776 }
04777 if (tm.tm_year > 100) {
04778 if (!res) {
04779
04780 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
04781 res = wait_file(chan,ints,nextmsg,lang);
04782 }
04783 }
04784 } else {
04785 if (tm.tm_year < 1) {
04786
04787
04788 } else {
04789 res = wait_file(chan,ints, "digits/19",lang);
04790 if (!res) {
04791 if (tm.tm_year <= 9) {
04792
04793 res = wait_file(chan,ints, "digits/oh",lang);
04794 if (!res) {
04795 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
04796 res = wait_file(chan,ints,nextmsg,lang);
04797 }
04798 } else if (tm.tm_year <= 20) {
04799
04800 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
04801 res = wait_file(chan,ints,nextmsg,lang);
04802 } else {
04803
04804 int ten, one;
04805 ten = tm.tm_year / 10;
04806 one = tm.tm_year % 10;
04807 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten * 10);
04808 res = wait_file(chan,ints,nextmsg,lang);
04809 if (!res) {
04810 if (one != 0) {
04811 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
04812 res = wait_file(chan,ints,nextmsg,lang);
04813 }
04814 }
04815 }
04816 }
04817 }
04818 }
04819 break;
04820 case 'I':
04821 case 'l':
04822
04823 if (tm.tm_hour == 0)
04824 snprintf(nextmsg,sizeof(nextmsg), "digits/12");
04825 else if (tm.tm_hour > 12)
04826 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
04827 else
04828 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
04829 res = wait_file(chan,ints,nextmsg,lang);
04830 break;
04831 case 'H':
04832 case 'k':
04833
04834 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
04835 if (!res) {
04836 res = wait_file(chan,ints, "digits/nl-uur",lang);
04837 }
04838 break;
04839 case 'M':
04840
04841 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
04842 break;
04843 case 'P':
04844 case 'p':
04845
04846 if (tm.tm_hour > 11)
04847 snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
04848 else
04849 snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
04850 res = wait_file(chan,ints,nextmsg,lang);
04851 break;
04852 case 'Q':
04853
04854
04855
04856
04857 {
04858 struct timeval now;
04859 struct tm tmnow;
04860 time_t beg_today, tt;
04861
04862 gettimeofday(&now,NULL);
04863 tt = now.tv_sec;
04864 ast_localtime(&tt,&tmnow,timezone);
04865
04866
04867 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04868 if (beg_today < time) {
04869
04870 res = wait_file(chan,ints, "digits/today",lang);
04871 } else if (beg_today - 86400 < time) {
04872
04873 res = wait_file(chan,ints, "digits/yesterday",lang);
04874 } else {
04875 res = ast_say_date_with_format_nl(chan, time, ints, lang, "ABdY", timezone);
04876 }
04877 }
04878 break;
04879 case 'q':
04880
04881 {
04882 struct timeval now;
04883 struct tm tmnow;
04884 time_t beg_today, tt;
04885
04886 gettimeofday(&now,NULL);
04887 tt = now.tv_sec;
04888 ast_localtime(&tt,&tmnow,timezone);
04889
04890
04891 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
04892 if (beg_today < time) {
04893
04894 } else if ((beg_today - 86400) < time) {
04895
04896 res = wait_file(chan,ints, "digits/yesterday",lang);
04897 } else if (beg_today - 86400 * 6 < time) {
04898
04899 res = ast_say_date_with_format_nl(chan, time, ints, lang, "A", timezone);
04900 } else {
04901 res = ast_say_date_with_format_nl(chan, time, ints, lang, "ABdY", timezone);
04902 }
04903 }
04904 break;
04905 case 'R':
04906 res = ast_say_date_with_format_nl(chan, time, ints, lang, "HM", timezone);
04907 break;
04908 case 'S':
04909
04910 res = ast_say_number(chan, tm.tm_sec, ints, lang, (char *) NULL);
04911 break;
04912 case 'T':
04913 res = ast_say_date_with_format_nl(chan, time, ints, lang, "HMS", timezone);
04914 break;
04915 case ' ':
04916 case ' ':
04917
04918 break;
04919 default:
04920
04921 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
04922 }
04923
04924 if (res) {
04925 break;
04926 }
04927 }
04928 return res;
04929 }
04930
04931
04932 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)
04933 {
04934 struct tm tm;
04935 int res=0, offset, sndoffset;
04936 char sndfile[256], nextmsg[256];
04937
04938 ast_localtime(&thetime, &tm, timezone);
04939
04940 for (offset = 0 ; format[offset] != '\0' ; offset++) {
04941 int remainder;
04942 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
04943 switch (format[offset]) {
04944
04945 case '\'':
04946
04947 sndoffset = 0;
04948 for (sndoffset = 0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
04949 sndfile[sndoffset] = format[offset];
04950 sndfile[sndoffset] = '\0';
04951 res = wait_file(chan, ints, sndfile, lang);
04952 break;
04953 case 'A':
04954 case 'a':
04955
04956 snprintf(nextmsg, sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
04957 res = wait_file(chan, ints, nextmsg, lang);
04958 break;
04959 case 'B':
04960 case 'b':
04961 case 'h':
04962
04963 snprintf(nextmsg, sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
04964 res = wait_file(chan, ints, nextmsg, lang);
04965 break;
04966 case 'm':
04967
04968 res = ast_say_enumeration(chan, (tm.tm_mon + 1), ints, lang, NULL);
04969 break;
04970 case 'd':
04971 case 'e':
04972
04973 remainder = tm.tm_mday;
04974 if (tm.tm_mday > 30) {
04975 res = wait_file(chan, ints, "digits/h-30", lang);
04976 remainder -= 30;
04977 }
04978 if (tm.tm_mday > 20 && tm.tm_mday < 30) {
04979 res = wait_file(chan, ints, "digits/h-20", lang);
04980 remainder -= 20;
04981 }
04982 if (!res) {
04983 snprintf(nextmsg, sizeof(nextmsg), "digits/h-%d", remainder);
04984 res = wait_file(chan, ints, nextmsg, lang);
04985 }
04986 break;
04987 case 'Y':
04988
04989 if (tm.tm_year > 100) {
04990 res = wait_file(chan, ints, "digits/2", lang);
04991 if (!res)
04992 res = wait_file(chan, ints, "digits/1000.2",lang);
04993 if (tm.tm_year > 100) {
04994 if (!res)
04995 res = ast_say_enumeration(chan, tm.tm_year - 100, ints, lang, NULL);
04996 }
04997 } else if (tm.tm_year == 100) {
04998 res = wait_file(chan, ints, "digits/h-2000", lang);
04999 } else {
05000 if (tm.tm_year < 1) {
05001
05002
05003 break;
05004 } else {
05005 res = wait_file(chan, ints, "digits/1000", lang);
05006 if (!res) {
05007 wait_file(chan, ints, "digits/900", lang);
05008 res = ast_say_enumeration(chan, tm.tm_year, ints, lang, NULL);
05009 }
05010 }
05011 }
05012 if (!res)
05013 wait_file(chan, ints, "digits/year", lang);
05014 break;
05015 case 'I':
05016 case 'l':
05017
05018 if (tm.tm_hour == 0)
05019 snprintf(nextmsg, sizeof(nextmsg), "digits/t-12");
05020 else if (tm.tm_hour > 12)
05021 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour - 12);
05022 else
05023 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
05024
05025 res = wait_file(chan, ints, nextmsg, lang);
05026 break;
05027 case 'H':
05028 case 'k':
05029
05030 if (tm.tm_hour != 0) {
05031 snprintf(nextmsg, sizeof(nextmsg), "digits/t-%d", tm.tm_hour);
05032 res = wait_file(chan, ints, nextmsg, lang);
05033 } else
05034 res = wait_file(chan, ints, "digits/t-24", lang);
05035 break;
05036 case 'M':
05037 case 'N':
05038
05039 if (tm.tm_min == 0) {
05040 if (format[offset] == 'M') {
05041 res = wait_file(chan, ints, "digits/oclock", lang);
05042 } else {
05043 res = wait_file(chan, ints, "digits/100", lang);
05044 }
05045 } else
05046 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
05047 break;
05048 case 'P':
05049 case 'p':
05050
05051 if (tm.tm_hour > 11)
05052 snprintf(nextmsg, sizeof(nextmsg), "digits/p-m");
05053 else
05054 snprintf(nextmsg, sizeof(nextmsg), "digits/a-m");
05055 res = wait_file(chan, ints, nextmsg, lang);
05056 break;
05057 case 'Q':
05058
05059 {
05060 time_t tv_sec = time(NULL);
05061 struct tm tmnow;
05062 time_t beg_today;
05063
05064 ast_localtime(&tv_sec,&tmnow, timezone);
05065
05066
05067 beg_today = tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05068 if (beg_today < thetime) {
05069
05070 res = wait_file(chan, ints, "digits/today", lang);
05071 } else if (beg_today - 86400 < thetime) {
05072
05073 res = wait_file(chan, ints, "digits/yesterday", lang);
05074 } else {
05075 res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", timezone);
05076 }
05077 }
05078 break;
05079 case 'q':
05080
05081 {
05082 time_t tv_sec = time(NULL);
05083 struct tm tmnow;
05084 time_t beg_today;
05085
05086 ast_localtime(&tv_sec, &tmnow, timezone);
05087
05088
05089 beg_today = tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05090 if (beg_today < thetime) {
05091
05092 } else if ((beg_today - 86400) < thetime) {
05093
05094 res = wait_file(chan, ints, "digits/yesterday", lang);
05095 } else if (beg_today - 86400 * 6 < thetime) {
05096
05097 res = ast_say_date_with_format(chan, thetime, ints, lang, "A", timezone);
05098 } else {
05099 res = ast_say_date_with_format(chan, thetime, ints, lang, "AdBY", timezone);
05100 }
05101 }
05102 break;
05103 case 'R':
05104 res = ast_say_date_with_format(chan, thetime, ints, lang, "HM", timezone);
05105 break;
05106 case 'S':
05107
05108 res = wait_file(chan, ints, "digits/and", lang);
05109 if (!res) {
05110 if (tm.tm_sec == 1) {
05111 res = wait_file(chan, ints, "digits/1z", lang);
05112 if (!res)
05113 res = wait_file(chan, ints, "digits/second-a", lang);
05114 } else {
05115 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
05116 if (!res) {
05117 int ten, one;
05118 ten = tm.tm_sec / 10;
05119 one = tm.tm_sec % 10;
05120
05121 if (one > 1 && one < 5 && ten != 1)
05122 res = wait_file(chan,ints, "digits/seconds",lang);
05123 else
05124 res = wait_file(chan,ints, "digits/second",lang);
05125 }
05126 }
05127 }
05128 break;
05129 case 'T':
05130 res = ast_say_date_with_format(chan, thetime, ints, lang, "HMS", timezone);
05131 break;
05132 case ' ':
05133 case ' ':
05134
05135 break;
05136 default:
05137
05138 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05139 }
05140
05141 if (res)
05142 break;
05143 }
05144 return res;
05145 }
05146
05147
05148 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)
05149 {
05150 struct tm tm;
05151 int res=0, offset, sndoffset;
05152 char sndfile[256], nextmsg[256];
05153
05154 if (format == NULL)
05155 format = "Ad 'digits/pt-de' B 'digits/pt-de' Y I 'digits/pt-e' Mp";
05156
05157 ast_localtime(&time,&tm,timezone);
05158
05159 for (offset=0 ; format[offset] != '\0' ; offset++) {
05160 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05161 switch (format[offset]) {
05162
05163 case '\'':
05164
05165 sndoffset=0;
05166 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
05167 sndfile[sndoffset] = format[offset];
05168 sndfile[sndoffset] = '\0';
05169 snprintf(nextmsg,sizeof(nextmsg), "%s", sndfile);
05170 res = wait_file(chan,ints,nextmsg,lang);
05171 break;
05172 case 'A':
05173 case 'a':
05174
05175 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05176 res = wait_file(chan,ints,nextmsg,lang);
05177 break;
05178 case 'B':
05179 case 'b':
05180 case 'h':
05181
05182 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05183 res = wait_file(chan,ints,nextmsg,lang);
05184 break;
05185 case 'm':
05186
05187 if (!strcasecmp(lang, "pt_BR")) {
05188 res = ast_say_number(chan, tm.tm_mon+1, ints, lang, (char *) NULL);
05189 } else {
05190 snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mon +1);
05191 res = wait_file(chan,ints,nextmsg,lang);
05192 }
05193 break;
05194 case 'd':
05195 case 'e':
05196
05197 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
05198 break;
05199 case 'Y':
05200
05201 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
05202 break;
05203 case 'I':
05204 case 'l':
05205
05206 if (tm.tm_hour == 0) {
05207 if (format[offset] == 'I')
05208 res = wait_file(chan, ints, "digits/pt-a", lang);
05209 if (!res)
05210 res = wait_file(chan, ints, "digits/pt-meianoite", lang);
05211 } else if (tm.tm_hour == 12) {
05212 if (format[offset] == 'I')
05213 res = wait_file(chan, ints, "digits/pt-ao", lang);
05214 if (!res)
05215 res = wait_file(chan, ints, "digits/pt-meiodia", lang);
05216 } else {
05217 if (format[offset] == 'I') {
05218 if ((tm.tm_hour % 12) != 1)
05219 res = wait_file(chan, ints, "digits/pt-as", lang);
05220 else
05221 res = wait_file(chan, ints, "digits/pt-a", lang);
05222 }
05223 if (!res)
05224 res = ast_say_number(chan, (tm.tm_hour % 12), ints, lang, "f");
05225 }
05226 break;
05227 case 'H':
05228 case 'k':
05229
05230 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
05231 if ((!res) && (format[offset] == 'H')) {
05232 if (tm.tm_hour > 1) {
05233 res = wait_file(chan,ints,"digits/hours",lang);
05234 } else {
05235 res = wait_file(chan,ints,"digits/hour",lang);
05236 }
05237 }
05238 break;
05239 case 'M':
05240
05241 res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
05242 if (!res) {
05243 if (tm.tm_min > 1) {
05244 res = wait_file(chan,ints,"digits/minutes",lang);
05245 } else {
05246 res = wait_file(chan,ints,"digits/minute",lang);
05247 }
05248 }
05249 break;
05250 case 'P':
05251 case 'p':
05252
05253 if (!strcasecmp(lang, "pt_BR")) {
05254 if ((tm.tm_hour != 0) && (tm.tm_hour != 12)) {
05255 res = wait_file(chan, ints, "digits/pt-da", lang);
05256 if (!res) {
05257 if ((tm.tm_hour >= 0) && (tm.tm_hour < 12))
05258 res = wait_file(chan, ints, "digits/morning", lang);
05259 else if ((tm.tm_hour >= 12) && (tm.tm_hour < 18))
05260 res = wait_file(chan, ints, "digits/afternoon", lang);
05261 else res = wait_file(chan, ints, "digits/night", lang);
05262 }
05263 }
05264 } else {
05265 if (tm.tm_hour > 12)
05266 res = wait_file(chan, ints, "digits/p-m", lang);
05267 else if (tm.tm_hour && tm.tm_hour < 12)
05268 res = wait_file(chan, ints, "digits/a-m", lang);
05269 }
05270 break;
05271 case 'Q':
05272
05273
05274
05275
05276 {
05277 struct timeval now;
05278 struct tm tmnow;
05279 time_t beg_today, tt;
05280
05281 gettimeofday(&now,NULL);
05282 tt = now.tv_sec;
05283 ast_localtime(&tt,&tmnow,timezone);
05284
05285
05286 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05287 if (beg_today < time) {
05288
05289 res = wait_file(chan,ints, "digits/today",lang);
05290 } else if (beg_today - 86400 < time) {
05291
05292 res = wait_file(chan,ints, "digits/yesterday",lang);
05293 } else {
05294 res = ast_say_date_with_format_pt(chan, time, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", timezone);
05295 }
05296 }
05297 break;
05298 case 'q':
05299
05300
05301
05302
05303 {
05304 struct timeval now;
05305 struct tm tmnow;
05306 time_t beg_today, tt;
05307
05308 gettimeofday(&now,NULL);
05309 tt = now.tv_sec;
05310 ast_localtime(&tt,&tmnow,timezone);
05311
05312
05313 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05314 if (beg_today < time) {
05315
05316 } else if ((beg_today - 86400) < time) {
05317
05318 res = wait_file(chan,ints, "digits/yesterday",lang);
05319 } else if (beg_today - 86400 * 6 < time) {
05320
05321 res = ast_say_date_with_format_pt(chan, time, ints, lang, "A", timezone);
05322 } else {
05323 res = ast_say_date_with_format_pt(chan, time, ints, lang, "Ad 'digits/pt-de' B 'digits/pt-de' Y", timezone);
05324 }
05325 }
05326 break;
05327 case 'R':
05328 res = ast_say_date_with_format_pt(chan, time, ints, lang, "H 'digits/and' M", timezone);
05329 break;
05330 case 'S':
05331
05332 res = ast_say_number(chan, tm.tm_sec, ints, lang, NULL);
05333 if (!res) {
05334 if (tm.tm_sec > 1) {
05335 res = wait_file(chan,ints,"digits/seconds",lang);
05336 } else {
05337 res = wait_file(chan,ints,"digits/second",lang);
05338 }
05339 }
05340 break;
05341 case 'T':
05342 res = ast_say_date_with_format_pt(chan, time, ints, lang, "HMS", timezone);
05343 break;
05344 case ' ':
05345 case ' ':
05346
05347 break;
05348 default:
05349
05350 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05351 }
05352
05353 if (res) {
05354 break;
05355 }
05356 }
05357 return res;
05358 }
05359
05360
05361 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)
05362 {
05363 struct tm tm;
05364 int res=0, offset, sndoffset;
05365 char sndfile[256], nextmsg[256];
05366
05367 if (format == NULL)
05368 format = "YBdAkM";
05369
05370 ast_localtime(&time,&tm,timezone);
05371
05372 for (offset=0 ; format[offset] != '\0' ; offset++) {
05373 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
05374 switch (format[offset]) {
05375
05376 case '\'':
05377
05378 sndoffset=0;
05379 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
05380 sndfile[sndoffset] = format[offset];
05381 sndfile[sndoffset] = '\0';
05382 res = wait_file(chan,ints,sndfile,lang);
05383 break;
05384 case 'A':
05385 case 'a':
05386
05387 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
05388 res = wait_file(chan,ints,nextmsg,lang);
05389 break;
05390 case 'B':
05391 case 'b':
05392 case 'h':
05393 case 'm':
05394
05395 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
05396 res = wait_file(chan,ints,nextmsg,lang);
05397 break;
05398 case 'd':
05399 case 'e':
05400
05401 if (!(tm.tm_mday % 10) || (tm.tm_mday < 10)) {
05402 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_mday);
05403 res = wait_file(chan,ints,nextmsg,lang);
05404 } else {
05405 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_mday - (tm.tm_mday % 10));
05406 res = wait_file(chan,ints,nextmsg,lang);
05407 if (!res) {
05408 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_mday % 10);
05409 res = wait_file(chan,ints,nextmsg,lang);
05410 }
05411 }
05412 if (!res) res = wait_file(chan,ints,"digits/day",lang);
05413 break;
05414 case 'Y':
05415
05416 if (tm.tm_year > 99) {
05417 res = wait_file(chan,ints, "digits/2",lang);
05418 if (!res) {
05419 res = wait_file(chan,ints, "digits/thousand",lang);
05420 }
05421 if (tm.tm_year > 100) {
05422 if (!res) {
05423 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) / 10);
05424 res = wait_file(chan,ints,nextmsg,lang);
05425 if (!res) {
05426 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", (tm.tm_year - 100) % 10);
05427 res = wait_file(chan,ints,nextmsg,lang);
05428 }
05429 }
05430 }
05431 if (!res) {
05432 res = wait_file(chan,ints, "digits/year",lang);
05433 }
05434 } else {
05435 if (tm.tm_year < 1) {
05436
05437
05438 } else {
05439 res = wait_file(chan,ints, "digits/1",lang);
05440 if (!res) {
05441 res = wait_file(chan,ints, "digits/9",lang);
05442 }
05443 if (!res) {
05444 if (tm.tm_year <= 9) {
05445
05446 res = wait_file(chan,ints, "digits/0",lang);
05447 if (!res) {
05448 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
05449 res = wait_file(chan,ints,nextmsg,lang);
05450 }
05451 } else {
05452
05453 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year / 10);
05454 res = wait_file(chan,ints,nextmsg,lang);
05455 if (!res) {
05456 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year % 10);
05457 res = wait_file(chan,ints,nextmsg,lang);
05458 }
05459 }
05460 }
05461 }
05462 if (!res) {
05463 res = wait_file(chan,ints, "digits/year",lang);
05464 }
05465 }
05466 break;
05467 case 'I':
05468 case 'l':
05469
05470 if (tm.tm_hour == 0)
05471 snprintf(nextmsg,sizeof(nextmsg), "digits/12");
05472 else if (tm.tm_hour > 12)
05473 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
05474 else
05475 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
05476 res = wait_file(chan,ints,nextmsg,lang);
05477 if (!res) {
05478 res = wait_file(chan,ints, "digits/oclock",lang);
05479 }
05480 break;
05481 case 'H':
05482 if (tm.tm_hour < 10) {
05483 res = wait_file(chan, ints, "digits/0", lang);
05484 }
05485 case 'k':
05486
05487 if (!(tm.tm_hour % 10) || tm.tm_hour < 10) {
05488 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
05489 res = wait_file(chan,ints,nextmsg,lang);
05490 } else {
05491 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - (tm.tm_hour % 10));
05492 res = wait_file(chan,ints,nextmsg,lang);
05493 if (!res) {
05494 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour % 10);
05495 res = wait_file(chan,ints,nextmsg,lang);
05496 }
05497 }
05498 if (!res) {
05499 res = wait_file(chan,ints, "digits/oclock",lang);
05500 }
05501 break;
05502 case 'M':
05503
05504 if (!(tm.tm_min % 10) || tm.tm_min < 10) {
05505 if (tm.tm_min < 10) {
05506 res = wait_file(chan, ints, "digits/0", lang);
05507 }
05508 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min);
05509 res = wait_file(chan,ints,nextmsg,lang);
05510 } else {
05511 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min - (tm.tm_min % 10));
05512 res = wait_file(chan,ints,nextmsg,lang);
05513 if (!res) {
05514 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min % 10);
05515 res = wait_file(chan,ints,nextmsg,lang);
05516 }
05517 }
05518 if (!res) {
05519 res = wait_file(chan,ints, "digits/minute",lang);
05520 }
05521 break;
05522 case 'P':
05523 case 'p':
05524
05525 if (tm.tm_hour > 11)
05526 snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
05527 else
05528 snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
05529 res = wait_file(chan,ints,nextmsg,lang);
05530 break;
05531 case 'Q':
05532
05533
05534
05535
05536 {
05537 struct timeval now;
05538 struct tm tmnow;
05539 time_t beg_today, tt;
05540
05541 gettimeofday(&now,NULL);
05542 tt = now.tv_sec;
05543 ast_localtime(&tt,&tmnow,timezone);
05544
05545
05546 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05547 if (beg_today < time) {
05548
05549 res = wait_file(chan,ints, "digits/today",lang);
05550 } else if (beg_today - 86400 < time) {
05551
05552 res = wait_file(chan,ints, "digits/yesterday",lang);
05553 } else {
05554 res = ast_say_date_with_format_zh(chan, time, ints, lang, "YBdA", timezone);
05555 }
05556 }
05557 break;
05558 case 'q':
05559
05560
05561
05562
05563 {
05564 struct timeval now;
05565 struct tm tmnow;
05566 time_t beg_today, tt;
05567
05568 gettimeofday(&now,NULL);
05569 tt = now.tv_sec;
05570 ast_localtime(&tt,&tmnow,timezone);
05571
05572
05573 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
05574 if (beg_today < time) {
05575
05576 } else if ((beg_today - 86400) < time) {
05577
05578 res = wait_file(chan,ints, "digits/yesterday",lang);
05579 } else if (beg_today - 86400 * 6 < time) {
05580
05581 res = ast_say_date_with_format_zh(chan, time, ints, lang, "A", timezone);
05582 } else {
05583 res = ast_say_date_with_format_zh(chan, time, ints, lang, "YBdA", timezone);
05584 }
05585 }
05586 break;
05587 case 'R':
05588 res = ast_say_date_with_format_zh(chan, time, ints, lang, "kM", timezone);
05589 break;
05590 case 'S':
05591
05592 if (!(tm.tm_sec % 10) || tm.tm_sec < 10) {
05593 if (tm.tm_sec < 10) {
05594 res = wait_file(chan, ints, "digits/0", lang);
05595 }
05596 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
05597 res = wait_file(chan,ints,nextmsg,lang);
05598 } else {
05599 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec - (tm.tm_sec % 10));
05600 res = wait_file(chan,ints,nextmsg,lang);
05601 if (!res) {
05602 snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec % 10);
05603 res = wait_file(chan,ints,nextmsg,lang);
05604 }
05605 }
05606 if (!res) {
05607 res = wait_file(chan,ints, "digits/second",lang);
05608 }
05609 break;
05610 case 'T':
05611 res = ast_say_date_with_format_zh(chan, time, ints, lang, "HMS", timezone);
05612 break;
05613 case ' ':
05614 case ' ':
05615
05616 break;
05617 default:
05618
05619 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
05620 }
05621
05622 if (res) {
05623 break;
05624 }
05625 }
05626 return res;
05627 }
05628
05629 static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05630 {
05631 if (!strncasecmp(lang, "en", 2)) {
05632 return ast_say_time_en(chan, t, ints, lang);
05633 } else if (!strncasecmp(lang, "de", 2)) {
05634 return ast_say_time_de(chan, t, ints, lang);
05635 } else if (!strncasecmp(lang, "es", 2)) {
05636 return(ast_say_time_es(chan, t, ints, lang));
05637 } else if (!strncasecmp(lang, "fr", 2)) {
05638 return ast_say_time_fr(chan, t, ints, lang);
05639 } else if (!strncasecmp(lang, "ge", 2)) {
05640 static int deprecation_warning = 0;
05641 if (deprecation_warning++ % 10 == 0) {
05642 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
05643 }
05644 return ast_say_time_ka(chan, t, ints, lang);
05645 } else if (!strncasecmp(lang, "gr", 2)) {
05646 return ast_say_time_gr(chan, t, ints, lang);
05647 } else if (!strncasecmp(lang, "he", 2)) {
05648 return ast_say_time_he(chan, t, ints, lang);
05649 } else if (!strncasecmp(lang, "ka", 2)) {
05650 return ast_say_time_ka(chan, t, ints, lang);
05651 } else if (!strncasecmp(lang, "nl", 2)) {
05652 return ast_say_time_nl(chan, t, ints, lang);
05653 } else if (!strncasecmp(lang, "pt_BR", 5)) {
05654 return ast_say_time_pt_BR(chan, t, ints, lang);
05655 } else if (!strncasecmp(lang, "pt", 2)) {
05656 return ast_say_time_pt(chan, t, ints, lang);
05657 } else if (!strncasecmp(lang, "tw", 2)) {
05658 static int deprecation_warning = 0;
05659 if (deprecation_warning++ % 10 == 0) {
05660 ast_log(LOG_WARNING, "tw is a standard language code for Twi, not Taiwanese. Please switch to using zh_TW instead.\n");
05661 }
05662 return ast_say_time_zh(chan, t, ints, lang);
05663 } else if (!strncasecmp(lang, "zh", 2)) {
05664 return ast_say_time_zh(chan, t, ints, lang);
05665 }
05666
05667
05668 return ast_say_time_en(chan, t, ints, lang);
05669 }
05670
05671
05672 int ast_say_time_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05673 {
05674 struct tm tm;
05675 int res = 0;
05676 int hour, pm=0;
05677
05678 ast_localtime(&t, &tm, NULL);
05679 hour = tm.tm_hour;
05680 if (!hour)
05681 hour = 12;
05682 else if (hour == 12)
05683 pm = 1;
05684 else if (hour > 12) {
05685 hour -= 12;
05686 pm = 1;
05687 }
05688 if (!res)
05689 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
05690 if (tm.tm_min > 9) {
05691 if (!res)
05692 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05693 } else if (tm.tm_min) {
05694 if (!res)
05695 res = ast_streamfile(chan, "digits/oh", lang);
05696 if (!res)
05697 res = ast_waitstream(chan, ints);
05698 if (!res)
05699 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05700 } else {
05701 if (!res)
05702 res = ast_streamfile(chan, "digits/oclock", lang);
05703 if (!res)
05704 res = ast_waitstream(chan, ints);
05705 }
05706 if (pm) {
05707 if (!res)
05708 res = ast_streamfile(chan, "digits/p-m", lang);
05709 } else {
05710 if (!res)
05711 res = ast_streamfile(chan, "digits/a-m", lang);
05712 }
05713 if (!res)
05714 res = ast_waitstream(chan, ints);
05715 return res;
05716 }
05717
05718
05719 int ast_say_time_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05720 {
05721 struct tm tm;
05722 int res = 0;
05723
05724 ast_localtime(&t, &tm, NULL);
05725 if (!res)
05726 res = ast_say_number(chan, tm.tm_hour, ints, lang, "n");
05727 if (!res)
05728 res = ast_streamfile(chan, "digits/oclock", lang);
05729 if (!res)
05730 res = ast_waitstream(chan, ints);
05731 if (!res)
05732 if (tm.tm_min > 0)
05733 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
05734 return res;
05735 }
05736
05737
05738 int ast_say_time_es(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05739 {
05740 struct tm tm;
05741 int res = 0;
05742 ast_localtime(&t, &tm, NULL);
05743
05744 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
05745 if (!res) {
05746 if (tm.tm_hour != 1)
05747 res = wait_file(chan, ints, "digits/hours", lang);
05748 else
05749 res = wait_file(chan, ints, "digits/hour", lang);
05750 }
05751 if ((!res) && (tm.tm_min)) {
05752 res = wait_file(chan, ints, "digits/and", lang);
05753 if (!res)
05754 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05755 if (!res) {
05756 if (tm.tm_min > 1)
05757 res = wait_file(chan, ints, "digits/minutes", lang);
05758 else
05759 res = wait_file(chan, ints, "digits/minute", lang);
05760 }
05761 }
05762 return res;
05763 }
05764
05765
05766 int ast_say_time_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05767 {
05768 struct tm tm;
05769 int res = 0;
05770
05771 ast_localtime(&t, &tm, NULL);
05772
05773 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
05774 if (!res)
05775 res = ast_streamfile(chan, "digits/oclock", lang);
05776 if (tm.tm_min) {
05777 if (!res)
05778 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05779 }
05780 return res;
05781 }
05782
05783
05784 int ast_say_time_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05785 {
05786 struct tm tm;
05787 int res = 0;
05788
05789 ast_localtime(&t, &tm, NULL);
05790 if (!res)
05791 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char *) NULL);
05792 if (!res)
05793 res = ast_streamfile(chan, "digits/nl-uur", lang);
05794 if (!res)
05795 res = ast_waitstream(chan, ints);
05796 if (!res)
05797 if (tm.tm_min > 0)
05798 res = ast_say_number(chan, tm.tm_min, ints, lang, NULL);
05799 return res;
05800 }
05801
05802
05803 int ast_say_time_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05804 {
05805 struct tm tm;
05806 int res = 0;
05807 int hour;
05808
05809 ast_localtime(&t, &tm, NULL);
05810 hour = tm.tm_hour;
05811 if (!res)
05812 res = ast_say_number(chan, hour, ints, lang, "f");
05813 if (tm.tm_min) {
05814 if (!res)
05815 res = wait_file(chan, ints, "digits/and", lang);
05816 if (!res)
05817 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05818 } else {
05819 if (!res) {
05820 if (tm.tm_hour == 1)
05821 res = wait_file(chan, ints, "digits/hour", lang);
05822 else
05823 res = wait_file(chan, ints, "digits/hours", lang);
05824 }
05825 }
05826 if (!res)
05827 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
05828 return res;
05829 }
05830
05831
05832 int ast_say_time_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05833 {
05834 struct tm tm;
05835 int res = 0;
05836
05837 ast_localtime(&t, &tm, NULL);
05838
05839 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
05840 if (!res) {
05841 if (tm.tm_hour > 1)
05842 res = wait_file(chan, ints, "digits/hours", lang);
05843 else
05844 res = wait_file(chan, ints, "digits/hour", lang);
05845 }
05846 if ((!res) && (tm.tm_min)) {
05847 res = wait_file(chan, ints, "digits/and", lang);
05848 if (!res)
05849 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05850 if (!res) {
05851 if (tm.tm_min > 1)
05852 res = wait_file(chan, ints, "digits/minutes", lang);
05853 else
05854 res = wait_file(chan, ints, "digits/minute", lang);
05855 }
05856 }
05857 return res;
05858 }
05859
05860
05861 int ast_say_time_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05862 {
05863 struct tm tm;
05864 int res = 0;
05865 int hour, pm=0;
05866
05867 ast_localtime(&t, &tm, NULL);
05868 hour = tm.tm_hour;
05869 if (!hour)
05870 hour = 12;
05871 else if (hour == 12)
05872 pm = 1;
05873 else if (hour > 12) {
05874 hour -= 12;
05875 pm = 1;
05876 }
05877 if (pm) {
05878 if (!res)
05879 res = ast_streamfile(chan, "digits/p-m", lang);
05880 } else {
05881 if (!res)
05882 res = ast_streamfile(chan, "digits/a-m", lang);
05883 }
05884 if (!res)
05885 res = ast_waitstream(chan, ints);
05886 if (!res)
05887 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
05888 if (!res)
05889 res = ast_streamfile(chan, "digits/oclock", lang);
05890 if (!res)
05891 res = ast_waitstream(chan, ints);
05892 if (!res)
05893 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
05894 if (!res)
05895 res = ast_streamfile(chan, "digits/minute", lang);
05896 if (!res)
05897 res = ast_waitstream(chan, ints);
05898 return res;
05899 }
05900
05901
05902 int ast_say_time_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05903 {
05904 struct tm tm;
05905 int res = 0;
05906 int hour;
05907
05908 ast_localtime(&t, &tm, NULL);
05909 hour = tm.tm_hour;
05910 if (!hour)
05911 hour = 12;
05912
05913 if (!res)
05914 res = ast_say_number_full_he(chan, hour, ints, lang, "f", -1, -1);
05915
05916 if (tm.tm_min > 9) {
05917 if (!res)
05918 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
05919 } else if (tm.tm_min) {
05920 if (!res) {
05921 res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1);
05922 }
05923 if (!res)
05924 res = ast_waitstream(chan, ints);
05925 if (!res)
05926 res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1);
05927 } else {
05928 if (!res)
05929 res = ast_waitstream(chan, ints);
05930 }
05931 if (!res)
05932 res = ast_waitstream(chan, ints);
05933 return res;
05934 }
05935 static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05936 {
05937 if (!strncasecmp(lang, "en", 2)) {
05938 return ast_say_datetime_en(chan, t, ints, lang);
05939 } else if (!strncasecmp(lang, "de", 2)) {
05940 return ast_say_datetime_de(chan, t, ints, lang);
05941 } else if (!strncasecmp(lang, "fr", 2)) {
05942 return ast_say_datetime_fr(chan, t, ints, lang);
05943 } else if (!strncasecmp(lang, "ge", 2)) {
05944 static int deprecation_warning = 0;
05945 if (deprecation_warning++ % 10 == 0) {
05946 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
05947 }
05948 return ast_say_datetime_ka(chan, t, ints, lang);
05949 } else if (!strncasecmp(lang, "gr", 2)) {
05950 return ast_say_datetime_gr(chan, t, ints, lang);
05951 } else if (!strncasecmp(lang, "he", 2)) {
05952 return ast_say_datetime_he(chan, t, ints, lang);
05953 } else if (!strncasecmp(lang, "ka", 2)) {
05954 return ast_say_datetime_ka(chan, t, ints, lang);
05955 } else if (!strncasecmp(lang, "nl", 2)) {
05956 return ast_say_datetime_nl(chan, t, ints, lang);
05957 } else if (!strncasecmp(lang, "pt_BR", 5)) {
05958 return ast_say_datetime_pt_BR(chan, t, ints, lang);
05959 } else if (!strncasecmp(lang, "pt", 2)) {
05960 return ast_say_datetime_pt(chan, t, ints, lang);
05961 } else if (!strncasecmp(lang, "tw", 2)) {
05962 static int deprecation_warning = 0;
05963 if (deprecation_warning++ % 10 == 0) {
05964 ast_log(LOG_WARNING, "tw is a standard language code for Twi, not Taiwanese. Please switch to using zh_TW instead.\n");
05965 }
05966 return ast_say_datetime_zh(chan, t, ints, lang);
05967 } else if (!strncasecmp(lang, "zh", 2)) {
05968 return ast_say_datetime_zh(chan, t, ints, lang);
05969 }
05970
05971
05972 return ast_say_datetime_en(chan, t, ints, lang);
05973 }
05974
05975
05976 int ast_say_datetime_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
05977 {
05978 struct tm tm;
05979 char fn[256];
05980 int res = 0;
05981 int hour, pm=0;
05982
05983 ast_localtime(&t, &tm, NULL);
05984 if (!res) {
05985 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
05986 res = ast_streamfile(chan, fn, lang);
05987 if (!res)
05988 res = ast_waitstream(chan, ints);
05989 }
05990 if (!res) {
05991 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
05992 res = ast_streamfile(chan, fn, lang);
05993 if (!res)
05994 res = ast_waitstream(chan, ints);
05995 }
05996 if (!res)
05997 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
05998
05999 hour = tm.tm_hour;
06000 if (!hour)
06001 hour = 12;
06002 else if (hour == 12)
06003 pm = 1;
06004 else if (hour > 12) {
06005 hour -= 12;
06006 pm = 1;
06007 }
06008 if (!res)
06009 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06010
06011 if (tm.tm_min > 9) {
06012 if (!res)
06013 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06014 } else if (tm.tm_min) {
06015 if (!res)
06016 res = ast_streamfile(chan, "digits/oh", lang);
06017 if (!res)
06018 res = ast_waitstream(chan, ints);
06019 if (!res)
06020 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06021 } else {
06022 if (!res)
06023 res = ast_streamfile(chan, "digits/oclock", lang);
06024 if (!res)
06025 res = ast_waitstream(chan, ints);
06026 }
06027 if (pm) {
06028 if (!res)
06029 res = ast_streamfile(chan, "digits/p-m", lang);
06030 } else {
06031 if (!res)
06032 res = ast_streamfile(chan, "digits/a-m", lang);
06033 }
06034 if (!res)
06035 res = ast_waitstream(chan, ints);
06036 if (!res)
06037 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06038 return res;
06039 }
06040
06041
06042 int ast_say_datetime_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06043 {
06044 struct tm tm;
06045 int res = 0;
06046
06047 ast_localtime(&t, &tm, NULL);
06048 res = ast_say_date(chan, t, ints, lang);
06049 if (!res)
06050 ast_say_time(chan, t, ints, lang);
06051 return res;
06052
06053 }
06054
06055
06056 int ast_say_datetime_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06057 {
06058 struct tm tm;
06059 char fn[256];
06060 int res = 0;
06061
06062 ast_localtime(&t, &tm, NULL);
06063
06064 if (!res)
06065 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06066
06067 if (!res) {
06068 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06069 res = ast_streamfile(chan, fn, lang);
06070 if (!res)
06071 res = ast_waitstream(chan, ints);
06072 }
06073 if (!res) {
06074 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06075 res = ast_streamfile(chan, fn, lang);
06076 if (!res)
06077 res = ast_waitstream(chan, ints);
06078 }
06079
06080 if (!res)
06081 res = ast_say_number(chan, tm.tm_hour, ints, lang, "f");
06082 if (!res)
06083 res = ast_streamfile(chan, "digits/oclock", lang);
06084 if (tm.tm_min > 0) {
06085 if (!res)
06086 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06087 }
06088 if (!res)
06089 res = ast_waitstream(chan, ints);
06090 if (!res)
06091 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06092 return res;
06093 }
06094
06095
06096 int ast_say_datetime_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06097 {
06098 struct tm tm;
06099 int res = 0;
06100
06101 ast_localtime(&t, &tm, NULL);
06102 res = ast_say_date(chan, t, ints, lang);
06103 if (!res) {
06104 res = ast_streamfile(chan, "digits/nl-om", lang);
06105 if (!res)
06106 res = ast_waitstream(chan, ints);
06107 }
06108 if (!res)
06109 ast_say_time(chan, t, ints, lang);
06110 return res;
06111 }
06112
06113
06114 int ast_say_datetime_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06115 {
06116 struct tm tm;
06117 char fn[256];
06118 int res = 0;
06119 int hour, pm=0;
06120
06121 ast_localtime(&t, &tm, NULL);
06122 if (!res) {
06123 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06124 res = ast_streamfile(chan, fn, lang);
06125 if (!res)
06126 res = ast_waitstream(chan, ints);
06127 }
06128 if (!res) {
06129 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06130 res = ast_streamfile(chan, fn, lang);
06131 if (!res)
06132 res = ast_waitstream(chan, ints);
06133 }
06134 if (!res)
06135 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06136
06137 hour = tm.tm_hour;
06138 if (!hour)
06139 hour = 12;
06140 else if (hour == 12)
06141 pm = 1;
06142 else if (hour > 12) {
06143 hour -= 12;
06144 pm = 1;
06145 }
06146 if (!res)
06147 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06148
06149 if (tm.tm_min > 9) {
06150 if (!res)
06151 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06152 } else if (tm.tm_min) {
06153 if (!res)
06154 res = ast_streamfile(chan, "digits/oh", lang);
06155 if (!res)
06156 res = ast_waitstream(chan, ints);
06157 if (!res)
06158 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06159 } else {
06160 if (!res)
06161 res = ast_streamfile(chan, "digits/oclock", lang);
06162 if (!res)
06163 res = ast_waitstream(chan, ints);
06164 }
06165 if (pm) {
06166 if (!res)
06167 res = ast_streamfile(chan, "digits/p-m", lang);
06168 } else {
06169 if (!res)
06170 res = ast_streamfile(chan, "digits/a-m", lang);
06171 }
06172 if (!res)
06173 res = ast_waitstream(chan, ints);
06174 if (!res)
06175 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06176 return res;
06177 }
06178
06179
06180 int ast_say_datetime_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06181 {
06182 struct tm tm;
06183 int res = 0;
06184
06185 ast_localtime(&t, &tm, NULL);
06186 res = ast_say_date(chan, t, ints, lang);
06187 if (!res)
06188 res = ast_say_time(chan, t, ints, lang);
06189 return res;
06190 }
06191
06192
06193 int ast_say_datetime_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06194 {
06195 struct tm tm;
06196 char fn[256];
06197 int res = 0;
06198 int hour, pm=0;
06199
06200 ast_localtime(&t, &tm, NULL);
06201 if (!res)
06202 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06203 if (!res) {
06204 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06205 res = ast_streamfile(chan, fn, lang);
06206 if (!res)
06207 res = ast_waitstream(chan, ints);
06208 }
06209 if (!res)
06210 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06211 if (!res) {
06212 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06213 res = ast_streamfile(chan, fn, lang);
06214 if (!res)
06215 res = ast_waitstream(chan, ints);
06216 }
06217
06218 hour = tm.tm_hour;
06219 if (!hour)
06220 hour = 12;
06221 else if (hour == 12)
06222 pm = 1;
06223 else if (hour > 12) {
06224 hour -= 12;
06225 pm = 1;
06226 }
06227 if (pm) {
06228 if (!res)
06229 res = ast_streamfile(chan, "digits/p-m", lang);
06230 } else {
06231 if (!res)
06232 res = ast_streamfile(chan, "digits/a-m", lang);
06233 }
06234 if (!res)
06235 res = ast_waitstream(chan, ints);
06236 if (!res)
06237 res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
06238 if (!res)
06239 res = ast_streamfile(chan, "digits/oclock", lang);
06240 if (!res)
06241 res = ast_waitstream(chan, ints);
06242 if (!res)
06243 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06244 if (!res)
06245 res = ast_streamfile(chan, "digits/minute", lang);
06246 if (!res)
06247 res = ast_waitstream(chan, ints);
06248 return res;
06249 }
06250
06251
06252 int ast_say_datetime_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06253 {
06254 struct tm tm;
06255 char fn[256];
06256 int res = 0;
06257 int hour;
06258
06259 ast_localtime(&t, &tm, NULL);
06260 if (!res) {
06261 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06262 res = ast_streamfile(chan, fn, lang);
06263 if (!res) {
06264 res = ast_waitstream(chan, ints);
06265 }
06266 }
06267 if (!res) {
06268 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06269 res = ast_streamfile(chan, fn, lang);
06270 if (!res) {
06271 res = ast_waitstream(chan, ints);
06272 }
06273 }
06274 if (!res) {
06275 res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
06276 }
06277
06278 hour = tm.tm_hour;
06279 if (!hour) {
06280 hour = 12;
06281 }
06282
06283 if (!res) {
06284 res = ast_say_number(chan, hour, ints, lang, "f");
06285 }
06286
06287 if (tm.tm_min > 9) {
06288 if (!res) {
06289 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06290 }
06291 } else if (tm.tm_min) {
06292 if (!res) {
06293
06294 res = ast_say_number(chan, 0, ints, lang, "f");
06295 }
06296 if (!res) {
06297 res = ast_waitstream(chan, ints);
06298 }
06299 if (!res) {
06300 res = ast_say_number(chan, tm.tm_min, ints, lang, "f");
06301 }
06302 } else {
06303 if (!res) {
06304 res = ast_waitstream(chan, ints);
06305 }
06306 }
06307 if (!res) {
06308 res = ast_waitstream(chan, ints);
06309 }
06310 if (!res) {
06311 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "f");
06312 }
06313 return res;
06314 }
06315 static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06316 {
06317 if (!strncasecmp(lang, "en", 2)) {
06318 return ast_say_datetime_from_now_en(chan, t, ints, lang);
06319 } else if (!strncasecmp(lang, "fr", 2)) {
06320 return ast_say_datetime_from_now_fr(chan, t, ints, lang);
06321 } else if (!strncasecmp(lang, "ge", 2)) {
06322 static int deprecation_warning = 0;
06323 if (deprecation_warning++ % 10 == 0) {
06324 ast_log(LOG_WARNING, "ge is not a standard language code. Please switch to using ka instead.\n");
06325 }
06326 return ast_say_datetime_from_now_ka(chan, t, ints, lang);
06327 } else if (!strncasecmp(lang, "he", 2)) {
06328 return ast_say_datetime_from_now_he(chan, t, ints, lang);
06329 } else if (!strncasecmp(lang, "ka", 2)) {
06330 return ast_say_datetime_from_now_ka(chan, t, ints, lang);
06331 } else if (!strncasecmp(lang, "pt", 2)) {
06332 return ast_say_datetime_from_now_pt(chan, t, ints, lang);
06333 }
06334
06335
06336 return ast_say_datetime_from_now_en(chan, t, ints, lang);
06337 }
06338
06339
06340 int ast_say_datetime_from_now_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06341 {
06342 int res=0;
06343 time_t nowt;
06344 int daydiff;
06345 struct tm tm;
06346 struct tm now;
06347 char fn[256];
06348
06349 time(&nowt);
06350
06351 ast_localtime(&t, &tm, NULL);
06352 ast_localtime(&nowt,&now, NULL);
06353 daydiff = now.tm_yday - tm.tm_yday;
06354 if ((daydiff < 0) || (daydiff > 6)) {
06355
06356 if (!res) {
06357 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06358 res = ast_streamfile(chan, fn, lang);
06359 if (!res)
06360 res = ast_waitstream(chan, ints);
06361 }
06362 if (!res)
06363 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06364
06365 } else if (daydiff) {
06366
06367 if (!res) {
06368 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06369 res = ast_streamfile(chan, fn, lang);
06370 if (!res)
06371 res = ast_waitstream(chan, ints);
06372 }
06373 }
06374 if (!res)
06375 res = ast_say_time(chan, t, ints, lang);
06376 return res;
06377 }
06378
06379
06380 int ast_say_datetime_from_now_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06381 {
06382 int res=0;
06383 time_t nowt;
06384 int daydiff;
06385 struct tm tm;
06386 struct tm now;
06387 char fn[256];
06388
06389 time(&nowt);
06390
06391 ast_localtime(&t, &tm, NULL);
06392 ast_localtime(&nowt, &now, NULL);
06393 daydiff = now.tm_yday - tm.tm_yday;
06394 if ((daydiff < 0) || (daydiff > 6)) {
06395
06396 if (!res) {
06397 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06398 res = ast_streamfile(chan, fn, lang);
06399 if (!res)
06400 res = ast_waitstream(chan, ints);
06401 }
06402 if (!res)
06403 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06404
06405 } else if (daydiff) {
06406
06407 if (!res) {
06408 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06409 res = ast_streamfile(chan, fn, lang);
06410 if (!res)
06411 res = ast_waitstream(chan, ints);
06412 }
06413 }
06414 if (!res)
06415 res = ast_say_time(chan, t, ints, lang);
06416 return res;
06417 }
06418
06419
06420 int ast_say_datetime_from_now_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06421 {
06422 int res=0;
06423 time_t nowt;
06424 int daydiff;
06425 struct tm tm;
06426 struct tm now;
06427 char fn[256];
06428
06429 time(&nowt);
06430
06431 ast_localtime(&t, &tm, NULL);
06432 ast_localtime(&nowt, &now, NULL);
06433 daydiff = now.tm_yday - tm.tm_yday;
06434 if ((daydiff < 0) || (daydiff > 6)) {
06435
06436 if (!res)
06437 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
06438 if (!res)
06439 res = wait_file(chan, ints, "digits/pt-de", lang);
06440 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06441 if (!res)
06442 res = wait_file(chan, ints, fn, lang);
06443
06444 } else if (daydiff) {
06445
06446 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06447 if (!res)
06448 res = wait_file(chan, ints, fn, lang);
06449 }
06450 if (tm.tm_hour > 1)
06451 snprintf(fn, sizeof(fn), "digits/pt-as");
06452 else
06453 snprintf(fn, sizeof(fn), "digits/pt-a");
06454 if (!res)
06455 res = wait_file(chan, ints, fn, lang);
06456 if (!res)
06457 res = ast_say_time(chan, t, ints, lang);
06458 return res;
06459 }
06460
06461
06462 int ast_say_datetime_from_now_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06463 {
06464 int res = 0;
06465 time_t nowt;
06466 int daydiff;
06467 struct tm tm;
06468 struct tm now;
06469 char fn[256];
06470
06471 time(&nowt);
06472
06473 ast_localtime(&t, &tm, NULL);
06474 ast_localtime(&nowt, &now, NULL);
06475 daydiff = now.tm_yday - tm.tm_yday;
06476 if ((daydiff < 0) || (daydiff > 6)) {
06477
06478 if (!res) {
06479 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06480 res = ast_streamfile(chan, fn, lang);
06481 if (!res)
06482 res = ast_waitstream(chan, ints);
06483 }
06484 if (!res) {
06485 res = ast_say_number(chan, tm.tm_mday, ints, lang, "f");
06486 }
06487 } else if (daydiff) {
06488
06489 if (!res) {
06490 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06491 res = ast_streamfile(chan, fn, lang);
06492 if (!res) {
06493 res = ast_waitstream(chan, ints);
06494 }
06495 }
06496 }
06497 if (!res) {
06498 res = ast_say_time(chan, t, ints, lang);
06499 }
06500 return res;
06501 }
06502
06503
06504
06505
06506
06507
06508
06509 static int gr_say_number_female(int num, struct ast_channel *chan, const char *ints, const char *lang){
06510 int tmp;
06511 int left;
06512 int res;
06513 char fn[256] = "";
06514
06515
06516 if (num < 5) {
06517 snprintf(fn, sizeof(fn), "digits/female-%d", num);
06518 res = wait_file(chan, ints, fn, lang);
06519 } else if (num < 13) {
06520 res = ast_say_number(chan, num, ints, lang, (char *) NULL);
06521 } else if (num <100 ) {
06522 tmp = (num/10) * 10;
06523 left = num - tmp;
06524 snprintf(fn, sizeof(fn), "digits/%d", tmp);
06525 res = ast_streamfile(chan, fn, lang);
06526 if (!res)
06527 res = ast_waitstream(chan, ints);
06528 if (left)
06529 gr_say_number_female(left, chan, ints, lang);
06530
06531 } else {
06532 return -1;
06533 }
06534 return res;
06535 }
06536
06537
06538
06539
06540
06541
06542
06543
06544
06545
06546
06547
06548
06549
06550
06551
06552
06553
06554
06555 static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language,int audiofd, int ctrlfd)
06556 {
06557 int res = 0;
06558 char fn[256] = "";
06559 int i=0;
06560
06561
06562 if (!num) {
06563 snprintf(fn, sizeof(fn), "digits/0");
06564 res = ast_streamfile(chan, fn, chan->language);
06565 if (!res)
06566 return ast_waitstream(chan, ints);
06567 }
06568
06569 while (!res && num ) {
06570 i++;
06571 if (num < 13) {
06572 snprintf(fn, sizeof(fn), "digits/%d", num);
06573 num = 0;
06574 } else if (num <= 100) {
06575
06576 snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
06577 num -= ((num / 10) * 10);
06578 } else if (num < 200) {
06579
06580 snprintf(fn, sizeof(fn), "digits/hundred-100");
06581 num -= ((num / 100) * 100);
06582 } else if (num < 1000) {
06583
06584 snprintf(fn, sizeof(fn), "digits/hundred-%d", (num/100)*100);
06585 num -= ((num / 100) * 100);
06586 } else if (num < 2000){
06587 snprintf(fn, sizeof(fn), "digits/xilia");
06588 num -= ((num / 1000) * 1000);
06589 } else {
06590
06591 if (num < 1000000) {
06592 res = ast_say_number_full_gr(chan, (num / 1000), ints, chan->language, audiofd, ctrlfd);
06593 if (res)
06594 return res;
06595 num = num % 1000;
06596 snprintf(fn, sizeof(fn), "digits/thousands");
06597 } else {
06598 if (num < 1000000000) {
06599 res = ast_say_number_full_gr(chan, (num / 1000000), ints, chan->language ,audiofd, ctrlfd);
06600 if (res)
06601 return res;
06602 num = num % 1000000;
06603 snprintf(fn, sizeof(fn), "digits/millions");
06604 } else {
06605 ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
06606 res = -1;
06607 }
06608 }
06609 }
06610 if (!res) {
06611 if (!ast_streamfile(chan, fn, language)) {
06612 if ((audiofd > -1) && (ctrlfd > -1))
06613 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
06614 else
06615 res = ast_waitstream(chan, ints);
06616 }
06617 ast_stopstream(chan);
06618 }
06619 }
06620 return res;
06621 }
06622
06623
06624
06625
06626
06627
06628
06629
06630
06631
06632
06633
06634
06635 static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06636 {
06637 struct tm tm;
06638
06639 char fn[256];
06640 int res = 0;
06641
06642
06643 ast_localtime(&t,&tm,NULL);
06644
06645 if (!res) {
06646 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06647 res = ast_streamfile(chan, fn, lang);
06648 if (!res)
06649 res = ast_waitstream(chan, ints);
06650 }
06651
06652 if (!res) {
06653 gr_say_number_female(tm.tm_mday, chan, ints, lang);
06654 }
06655
06656 if (!res) {
06657 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06658 res = ast_streamfile(chan, fn, lang);
06659 if (!res)
06660 res = ast_waitstream(chan, ints);
06661 }
06662
06663 if (!res)
06664 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
06665 return res;
06666 }
06667
06668
06669
06670
06671
06672
06673
06674
06675
06676
06677
06678 static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06679 {
06680
06681 struct tm tm;
06682 int res = 0;
06683 int hour, pm=0;
06684
06685 ast_localtime(&t, &tm, NULL);
06686 hour = tm.tm_hour;
06687
06688 if (!hour)
06689 hour = 12;
06690 else if (hour == 12)
06691 pm = 1;
06692 else if (hour > 12) {
06693 hour -= 12;
06694 pm = 1;
06695 }
06696
06697 res = gr_say_number_female(hour, chan, ints, lang);
06698 if (tm.tm_min) {
06699 if (!res)
06700 res = ast_streamfile(chan, "digits/kai", lang);
06701 if (!res)
06702 res = ast_waitstream(chan, ints);
06703 if (!res)
06704 res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
06705 } else {
06706 if (!res)
06707 res = ast_streamfile(chan, "digits/hwra", lang);
06708 if (!res)
06709 res = ast_waitstream(chan, ints);
06710 }
06711 if (pm) {
06712 if (!res)
06713 res = ast_streamfile(chan, "digits/p-m", lang);
06714 } else {
06715 if (!res)
06716 res = ast_streamfile(chan, "digits/a-m", lang);
06717 }
06718 if (!res)
06719 res = ast_waitstream(chan, ints);
06720 return res;
06721 }
06722
06723
06724
06725 static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
06726 {
06727 struct tm tm;
06728 char fn[256];
06729 int res = 0;
06730
06731 ast_localtime(&t, &tm, NULL);
06732
06733
06734
06735 if (!res) {
06736 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
06737 res = ast_streamfile(chan, fn, lang);
06738 if (!res)
06739 res = ast_waitstream(chan, ints);
06740 }
06741
06742 if (!res) {
06743 gr_say_number_female(tm.tm_mday, chan, ints, lang);
06744 }
06745
06746 if (!res) {
06747 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
06748 res = ast_streamfile(chan, fn, lang);
06749 if (!res)
06750 res = ast_waitstream(chan, ints);
06751 }
06752
06753 res = ast_say_time_gr(chan, t, ints, lang);
06754 return res;
06755 }
06756
06757 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)
06758 {
06759
06760 struct tm tm;
06761 int res=0, offset, sndoffset;
06762 char sndfile[256], nextmsg[256];
06763
06764 if (!format)
06765 format = "AdBY 'digits/at' IMp";
06766
06767 ast_localtime(&time,&tm,timezone);
06768
06769 for (offset=0 ; format[offset] != '\0' ; offset++) {
06770 ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
06771 switch (format[offset]) {
06772
06773 case '\'':
06774
06775 sndoffset=0;
06776 for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
06777 sndfile[sndoffset] = format[offset];
06778 sndfile[sndoffset] = '\0';
06779 res = wait_file(chan,ints,sndfile,lang);
06780 break;
06781 case 'A':
06782 case 'a':
06783
06784 snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
06785 res = wait_file(chan,ints,nextmsg,lang);
06786 break;
06787 case 'B':
06788 case 'b':
06789 case 'h':
06790
06791 snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
06792 res = wait_file(chan,ints,nextmsg,lang);
06793 break;
06794 case 'd':
06795 case 'e':
06796
06797 gr_say_number_female(tm.tm_mday, chan, ints, lang);
06798 break;
06799 case 'Y':
06800
06801
06802 ast_say_number_full_gr(chan, 1900+tm.tm_year, ints, chan->language, -1, -1);
06803 break;
06804 case 'I':
06805 case 'l':
06806
06807 if (tm.tm_hour == 0)
06808 gr_say_number_female(12, chan, ints, lang);
06809 else if (tm.tm_hour > 12)
06810 gr_say_number_female(tm.tm_hour - 12, chan, ints, lang);
06811 else
06812 gr_say_number_female(tm.tm_hour, chan, ints, lang);
06813 break;
06814 case 'H':
06815 case 'k':
06816
06817 gr_say_number_female(tm.tm_hour, chan, ints, lang);
06818 break;
06819 case 'M':
06820
06821 if (tm.tm_min) {
06822 if (!res)
06823 res = ast_streamfile(chan, "digits/kai", lang);
06824 if (!res)
06825 res = ast_waitstream(chan, ints);
06826 if (!res)
06827 res = ast_say_number_full_gr(chan, tm.tm_min, ints, lang, -1, -1);
06828 } else {
06829 if (!res)
06830 res = ast_streamfile(chan, "digits/oclock", lang);
06831 if (!res)
06832 res = ast_waitstream(chan, ints);
06833 }
06834 break;
06835 case 'P':
06836 case 'p':
06837
06838 if (tm.tm_hour > 11)
06839 snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
06840 else
06841 snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
06842 res = wait_file(chan,ints,nextmsg,lang);
06843 break;
06844 case 'Q':
06845
06846
06847
06848
06849 {
06850 struct timeval now;
06851 struct tm tmnow;
06852 time_t beg_today, tt;
06853
06854 gettimeofday(&now,NULL);
06855 tt = now.tv_sec;
06856 ast_localtime(&tt,&tmnow,timezone);
06857
06858
06859 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
06860 if (beg_today < time) {
06861
06862 res = wait_file(chan,ints, "digits/today",lang);
06863 } else if (beg_today - 86400 < time) {
06864
06865 res = wait_file(chan,ints, "digits/yesterday",lang);
06866 } else {
06867 res = ast_say_date_with_format_gr(chan, time, ints, lang, "AdBY", timezone);
06868 }
06869 }
06870 break;
06871 case 'q':
06872
06873
06874
06875
06876 {
06877 struct timeval now;
06878 struct tm tmnow;
06879 time_t beg_today, tt;
06880
06881 gettimeofday(&now,NULL);
06882 tt = now.tv_sec;
06883 ast_localtime(&tt,&tmnow,timezone);
06884
06885
06886 beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
06887 if (beg_today < time) {
06888
06889 } else if ((beg_today - 86400) < time) {
06890
06891 res = wait_file(chan,ints, "digits/yesterday",lang);
06892 } else if (beg_today - 86400 * 6 < time) {
06893
06894 res = ast_say_date_with_format_gr(chan, time, ints, lang, "A", timezone);
06895 } else {
06896 res = ast_say_date_with_format_gr(chan, time, ints, lang, "AdBY", timezone);
06897 }
06898 }
06899 break;
06900 case 'R':
06901 res = ast_say_date_with_format_gr(chan, time, ints, lang, "HM", timezone);
06902 break;
06903 case 'S':
06904
06905 snprintf(nextmsg,sizeof(nextmsg), "digits/kai");
06906 res = wait_file(chan,ints,nextmsg,lang);
06907 if (!res)
06908 res = ast_say_number_full_gr(chan, tm.tm_sec, ints, lang, -1, -1);
06909 if (!res)
06910 snprintf(nextmsg,sizeof(nextmsg), "digits/seconds");
06911 res = wait_file(chan,ints,nextmsg,lang);
06912 break;
06913 case 'T':
06914 res = ast_say_date_with_format_gr(chan, time, ints, lang, "HMS", timezone);
06915 break;
06916 case ' ':
06917 case ' ':
06918
06919 break;
06920 default:
06921
06922 ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
06923 }
06924
06925 if (res) {
06926 break;
06927 }
06928 }
06929 return res;
06930 }
06931
06932
06933
06934
06935
06936
06937
06938
06939
06940
06941
06942
06943
06944
06945
06946
06947
06948
06949
06950
06951
06952
06953
06954
06955
06956
06957
06958 static char* ast_translate_number_ka(int num, char* res, int res_len)
06959 {
06960 char buf[256];
06961 int digit = 0;
06962 int remainder = 0;
06963
06964
06965 if (num < 0) {
06966 strncat(res, "minus ", res_len - strlen(res) - 1);
06967 if ( num > INT_MIN ) {
06968 num = -num;
06969 } else {
06970 num = 0;
06971 }
06972 }
06973
06974
06975
06976 if (num <= 20 || num == 40 || num == 60 || num == 80 || num == 100) {
06977 snprintf(buf, sizeof(buf), "%d", num);
06978 strncat(res, buf, res_len - strlen(res) - 1);
06979 return res;
06980 }
06981
06982
06983 if (num < 40) {
06984 strncat(res, "20_ ", res_len - strlen(res) - 1);
06985 return ast_translate_number_ka(num - 20, res, res_len);
06986 }
06987
06988 if (num < 60) {
06989 strncat(res, "40_ ", res_len - strlen(res) - 1);
06990 return ast_translate_number_ka(num - 40, res, res_len);
06991 }
06992
06993 if (num < 80) {
06994 strncat(res, "60_ ", res_len - strlen(res) - 1);
06995 return ast_translate_number_ka(num - 60, res, res_len);
06996 }
06997
06998 if (num < 100) {
06999 strncat(res, "80_ ", res_len - strlen(res) - 1);
07000 return ast_translate_number_ka(num - 80, res, res_len);
07001 }
07002
07003
07004 if (num < 1000) {
07005 remainder = num % 100;
07006 digit = (num - remainder) / 100;
07007
07008 if (remainder == 0) {
07009 snprintf(buf, sizeof(buf), "%d", num);
07010 strncat(res, buf, res_len - strlen(res) - 1);
07011 return res;
07012 } else {
07013 snprintf(buf, sizeof(buf), "%d_ ", digit*100);
07014 strncat(res, buf, res_len - strlen(res) - 1);
07015 return ast_translate_number_ka(remainder, res, res_len);
07016 }
07017 }
07018
07019
07020 if (num == 1000) {
07021 strncat(res, "1000", res_len - strlen(res) - 1);
07022 return res;
07023 }
07024
07025
07026 if (num < 1000000) {
07027 remainder = num % 1000;
07028 digit = (num - remainder) / 1000;
07029
07030 if (remainder == 0) {
07031 ast_translate_number_ka(digit, res, res_len);
07032 strncat(res, " 1000", res_len - strlen(res) - 1);
07033 return res;
07034 }
07035
07036 if (digit == 1) {
07037 strncat(res, "1000_ ", res_len - strlen(res) - 1);
07038 return ast_translate_number_ka(remainder, res, res_len);
07039 }
07040
07041 ast_translate_number_ka(digit, res, res_len);
07042 strncat(res, " 1000_ ", res_len - strlen(res) - 1);
07043 return ast_translate_number_ka(remainder, res, res_len);
07044
07045 }
07046
07047
07048 if (num == 1000000) {
07049 strncat(res, "1 1000000", res_len - strlen(res) - 1);
07050 return res;
07051 }
07052
07053
07054 if (num < 1000000000) {
07055 remainder = num % 1000000;
07056 digit = (num - remainder) / 1000000;
07057
07058 if (remainder == 0) {
07059 ast_translate_number_ka(digit, res, res_len);
07060 strncat(res, " 1000000", res_len - strlen(res) - 1);
07061 return res;
07062 }
07063
07064 ast_translate_number_ka(digit, res, res_len);
07065 strncat(res, " 1000000_ ", res_len - strlen(res) - 1);
07066 return ast_translate_number_ka(remainder, res, res_len);
07067
07068 }
07069
07070
07071 if (num == 1000000000) {
07072 strncat(res, "1 1000000000", res_len - strlen(res) - 1);
07073 return res;
07074 }
07075
07076
07077 if (num > 1000000000) {
07078 remainder = num % 1000000000;
07079 digit = (num - remainder) / 1000000000;
07080
07081 if (remainder == 0) {
07082 ast_translate_number_ka(digit, res, res_len);
07083 strncat(res, " 1000000000", res_len - strlen(res) - 1);
07084 return res;
07085 }
07086
07087 ast_translate_number_ka(digit, res, res_len);
07088 strncat(res, " 1000000000_ ", res_len - strlen(res) - 1);
07089 return ast_translate_number_ka(remainder, res, res_len);
07090
07091 }
07092
07093 return res;
07094
07095 }
07096
07097
07098
07099
07100 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)
07101 {
07102 int res = 0;
07103 char fn[512] = "";
07104 char* s = 0;
07105 const char* remainder = fn;
07106
07107 if (!num)
07108 return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
07109
07110
07111 ast_translate_number_ka(num, fn, 512);
07112
07113
07114
07115 while (res == 0 && (s = strstr(remainder, " "))) {
07116 size_t len = s - remainder;
07117 char* new_string = malloc(len + 1 + strlen("digits/"));
07118
07119 sprintf(new_string, "digits/");
07120 strncat(new_string, remainder, len);
07121
07122
07123 if (!ast_streamfile(chan, new_string, language)) {
07124 if ((audiofd > -1) && (ctrlfd > -1))
07125 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
07126 else
07127 res = ast_waitstream(chan, ints);
07128 }
07129 ast_stopstream(chan);
07130
07131 free(new_string);
07132
07133 remainder = s + 1;
07134 while (*remainder == ' ')
07135 remainder++;
07136 }
07137
07138
07139
07140 if (res == 0 && *remainder) {
07141
07142 char* new_string = malloc(strlen(remainder) + 1 + strlen("digits/"));
07143 sprintf(new_string, "digits/%s", remainder);
07144
07145 if (!ast_streamfile(chan, new_string, language)) {
07146 if ((audiofd > -1) && (ctrlfd > -1))
07147 res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
07148 else
07149 res = ast_waitstream(chan, ints);
07150 }
07151 ast_stopstream(chan);
07152
07153 free(new_string);
07154
07155 }
07156
07157
07158 return res;
07159
07160 }
07161
07162
07163
07164
07165
07166
07167
07168
07169
07170
07171
07172
07173
07174
07175
07176
07177 static int ast_say_date_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07178 {
07179 struct tm tm;
07180 char fn[256];
07181 int res = 0;
07182 ast_localtime(&t,&tm,NULL);
07183
07184 if (!res)
07185 res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
07186
07187 if (!res) {
07188 snprintf(fn, sizeof(fn), "digits/tslis %d", tm.tm_wday);
07189 res = ast_streamfile(chan, fn, lang);
07190 if (!res)
07191 res = ast_waitstream(chan, ints);
07192 }
07193
07194 if (!res) {
07195 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
07196
07197
07198
07199 }
07200
07201 if (!res) {
07202 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07203 res = ast_streamfile(chan, fn, lang);
07204 if (!res)
07205 res = ast_waitstream(chan, ints);
07206 }
07207 return res;
07208
07209 }
07210
07211
07212
07213
07214
07215
07216 static int ast_say_time_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07217 {
07218 struct tm tm;
07219 int res = 0;
07220
07221 ast_localtime(&t, &tm, NULL);
07222
07223 res = ast_say_number(chan, tm.tm_hour, ints, lang, (char*)NULL);
07224 if (!res) {
07225 res = ast_streamfile(chan, "digits/saati_da", lang);
07226 if (!res)
07227 res = ast_waitstream(chan, ints);
07228 }
07229
07230 if (tm.tm_min) {
07231 if (!res) {
07232 res = ast_say_number(chan, tm.tm_min, ints, lang, (char*)NULL);
07233
07234 if (!res) {
07235 res = ast_streamfile(chan, "digits/tsuti", lang);
07236 if (!res)
07237 res = ast_waitstream(chan, ints);
07238 }
07239 }
07240 }
07241 return res;
07242 }
07243
07244
07245
07246
07247 static int ast_say_datetime_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07248 {
07249 struct tm tm;
07250 int res = 0;
07251
07252 ast_localtime(&t, &tm, NULL);
07253 res = ast_say_date(chan, t, ints, lang);
07254 if (!res)
07255 ast_say_time(chan, t, ints, lang);
07256 return res;
07257
07258 }
07259
07260
07261
07262
07263
07264 static int ast_say_datetime_from_now_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
07265 {
07266 int res=0;
07267 time_t nowt;
07268 int daydiff;
07269 struct tm tm;
07270 struct tm now;
07271 char fn[256];
07272
07273 time(&nowt);
07274
07275 ast_localtime(&t, &tm, NULL);
07276 ast_localtime(&nowt, &now, NULL);
07277 daydiff = now.tm_yday - tm.tm_yday;
07278 if ((daydiff < 0) || (daydiff > 6)) {
07279
07280 if (!res)
07281 res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
07282 if (!res) {
07283 snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
07284 res = ast_streamfile(chan, fn, lang);
07285 if (!res)
07286 res = ast_waitstream(chan, ints);
07287 }
07288
07289 } else if (daydiff) {
07290
07291 if (!res) {
07292 snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
07293 res = ast_streamfile(chan, fn, lang);
07294 if (!res)
07295 res = ast_waitstream(chan, ints);
07296 }
07297 }
07298 if (!res)
07299 res = ast_say_time(chan, t, ints, lang);
07300
07301 return res;
07302 }
07303
07304
07305
07306
07307
07308
07309
07310
07311
07312
07313
07314 static const char *counted_noun_ending_en(int num)
07315 {
07316 if (num == 1 || num == -1) {
07317 return "";
07318 } else {
07319 return "s";
07320 }
07321 }
07322
07323
07324
07325
07326
07327
07328
07329
07330
07331
07332 static const char *counted_noun_ending_slavic(int num)
07333 {
07334 if (num < 0) {
07335 num *= -1;
07336 }
07337 num %= 100;
07338 if (num >= 20) {
07339 num %= 10;
07340 }
07341 if (num == 1) {
07342 return "";
07343 }
07344 if (num > 0 && num < 5) {
07345 return "x1";
07346 } else {
07347 return "x2";
07348 }
07349 }
07350
07351 int ast_say_counted_noun(struct ast_channel *chan, int num, const char noun[])
07352 {
07353 char *temp;
07354 int temp_len;
07355 const char *ending;
07356 if (!strncasecmp(chan->language, "ru", 2)) {
07357 ending = counted_noun_ending_slavic(num);
07358 } else if (!strncasecmp(chan->language, "ua", 2)) {
07359 ending = counted_noun_ending_slavic(num);
07360 } else if (!strncasecmp(chan->language, "pl", 2)) {
07361 ending = counted_noun_ending_slavic(num);
07362 } else {
07363 ending = counted_noun_ending_en(num);
07364 }
07365 temp = alloca((temp_len = (strlen(noun) + strlen(ending) + 1)));
07366 snprintf(temp, temp_len, "%s%s", noun, ending);
07367 return ast_play_and_wait(chan, temp);
07368 }
07369
07370
07371
07372
07373
07374
07375
07376
07377 static const char *counted_adjective_ending_ru(int num, const char gender[])
07378 {
07379 if (num < 0) {
07380 num *= -1;
07381 }
07382 num %= 100;
07383 if (num >= 20) {
07384 num %= 10;
07385 }
07386 if (num == 1) {
07387 return gender ? gender : "";
07388 } else {
07389 return "x";
07390 }
07391 }
07392
07393 int ast_say_counted_adjective(struct ast_channel *chan, int num, const char adjective[], const char gender[])
07394 {
07395 char *temp;
07396 int temp_len;
07397 const char *ending;
07398 if (!strncasecmp(chan->language, "ru", 2)) {
07399 ending = counted_adjective_ending_ru(num, gender);
07400 } else if (!strncasecmp(chan->language, "ua", 2)) {
07401 ending = counted_adjective_ending_ru(num, gender);
07402 } else if (!strncasecmp(chan->language, "pl", 2)) {
07403 ending = counted_adjective_ending_ru(num, gender);
07404 } else {
07405 ending = "";
07406 }
07407 temp = alloca((temp_len = (strlen(adjective) + strlen(ending) + 1)));
07408 snprintf(temp, temp_len, "%s%s", adjective, ending);
07409 return ast_play_and_wait(chan, temp);
07410 }
07411
07412
07413
07414
07415
07416
07417 static void __attribute__((constructor)) __say_init(void)
07418 {
07419 ast_say_number_full = say_number_full;
07420 ast_say_enumeration_full = say_enumeration_full;
07421 ast_say_digit_str_full = say_digit_str_full;
07422 ast_say_character_str_full = say_character_str_full;
07423 ast_say_phonetic_str_full = say_phonetic_str_full;
07424 ast_say_datetime = say_datetime;
07425 ast_say_time = say_time;
07426 ast_say_date = say_date;
07427 ast_say_datetime_from_now = say_datetime_from_now;
07428 ast_say_date_with_format = say_date_with_format;
07429 }