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