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