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