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