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