00001 /* 00002 * Asterisk -- An open source telephony toolkit. 00003 * 00004 * Copyright (C) 2008, Trinity College Computing Center 00005 * Written by David Chappell 00006 * 00007 * See http://www.asterisk.org for more information about 00008 * the Asterisk project. Please do not directly contact 00009 * any of the maintainers of this project for assistance; 00010 * the project provides a web site, mailing lists and IRC 00011 * channels for your use. 00012 * 00013 * This program is free software, distributed under the terms of 00014 * the GNU General Public License Version 2. See the LICENSE file 00015 * at the top of the source tree. 00016 */ 00017 00018 /*! \file 00019 * 00020 * \brief Applications to decline words according to current language 00021 * 00022 * \author David Chappell <David.Chappell@trincoll.edu> 00023 * 00024 * \ingroup applications 00025 */ 00026 00027 /*** MODULEINFO 00028 <defaultenabled>no</defaultenabled> 00029 <support_level>extended</support_level> 00030 ***/ 00031 00032 /*** DOCUMENTATION 00033 <application name="SayCountedNoun" language="en_US"> 00034 <synopsis> 00035 Say a noun in declined form in order to count things 00036 </synopsis> 00037 <syntax> 00038 <parameter name="number" required="true"> 00039 <para>The number of things</para> 00040 </parameter> 00041 <parameter name="filename" required="true"> 00042 <para>File name stem for the noun that is the the name of the things</para> 00043 </parameter> 00044 </syntax> 00045 <description> 00046 <para>Selects and plays the proper singular or plural form of a noun 00047 when saying things such as "five calls". English has simple rules 00048 for deciding when to say "call" and when to say "calls", but other 00049 languages have complicated rules which would be extremely difficult 00050 to implement in the Asterisk dialplan language.</para> 00051 <para>The correct sound file is selected by examining the 00052 <replaceable>number</replaceable> and adding the appropriate suffix 00053 to <replaceable>filename</replaceable>. If the channel language is 00054 English, then the suffix will be either empty or "s". If the channel 00055 language is Russian or some other Slavic language, then the suffix 00056 will be empty for nominative, "x1" for genative singular, and "x2" 00057 for genative plural.</para> 00058 <para>Note that combining <replaceable>filename</replaceable> with 00059 a suffix will not necessarily produce a correctly spelled plural 00060 form. For example, SayCountedNoun(2,man) will play the sound file 00061 "mans" rather than "men". This behavior is intentional. Since the 00062 file name is never seen by the end user, there is no need to 00063 implement complicated spelling rules. We simply record the word 00064 "men" in the sound file named "mans".</para> 00065 <para>This application does not automatically answer and should be 00066 preceeded by an application such as Answer() or Progress.</para> 00067 </description> 00068 <see-also> 00069 <ref type="application">SayCountedAdj</ref> 00070 <ref type="application">SayNumber</ref> 00071 </see-also> 00072 </application> 00073 <application name="SayCountedAdj" language="en_US"> 00074 <synopsis> 00075 Say a adjective in declined form in order to count things 00076 </synopsis> 00077 <syntax> 00078 <parameter name="number" required="true"> 00079 <para>The number of things</para> 00080 </parameter> 00081 <parameter name="filename" required="true"> 00082 <para>File name stem for the adjective</para> 00083 </parameter> 00084 <parameter name="gender"> 00085 <para>The gender of the noun modified, one of 'm', 'f', 'n', or 'c'</para> 00086 </parameter> 00087 </syntax> 00088 <description> 00089 <para>Selects and plays the proper form of an adjective according to 00090 the gender and of the noun which it modifies and the number of 00091 objects named by the noun-verb combination which have been counted. 00092 Used when saying things such as "5 new messages". The various 00093 singular and plural forms of the adjective are selected by adding 00094 suffixes to <replaceable>filename</replaceable>.</para> 00095 <para>If the channel language is English, then no suffix will ever 00096 be added (since, in English, adjectives are not declined). If the 00097 channel language is Russian or some other slavic language, then the 00098 suffix will the specified <replaceable>gender</replaceable> for 00099 nominative, and "x" for genative plural. (The genative singular is 00100 not used when counting things.) For example, SayCountedAdj(1,new,f) 00101 will play sound file "newa" (containing the word "novaya"), but 00102 SayCountedAdj(5,new,f) will play sound file "newx" (containing the 00103 word "novikh").</para> 00104 <para>This application does not automatically answer and should be 00105 preceeded by an application such as Answer(), Progress(), or 00106 Proceeding().</para> 00107 </description> 00108 <see-also> 00109 <ref type="application">SayCountedNoun</ref> 00110 <ref type="application">SayNumber</ref> 00111 </see-also> 00112 </application> 00113 ***/ 00114 00115 #include "asterisk.h" 00116 00117 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 385683 $") 00118 00119 #include "asterisk/logger.h" 00120 #include "asterisk/module.h" 00121 #include "asterisk/app.h" 00122 #include "asterisk/say.h" 00123 00124 static int saycountednoun_exec(struct ast_channel *chan, const char *data) 00125 { 00126 char *parse; 00127 int number; 00128 AST_DECLARE_APP_ARGS(args, 00129 AST_APP_ARG(number); 00130 AST_APP_ARG(noun); 00131 ); 00132 00133 if (ast_strlen_zero(data)) { 00134 ast_log(LOG_WARNING, "SayCountedNoun requires two arguments (<number>,<noun>)\n"); 00135 return -1; 00136 } 00137 00138 parse = ast_strdupa(data); 00139 AST_STANDARD_APP_ARGS(args, parse); 00140 00141 if (args.argc != 2) { 00142 ast_log(LOG_WARNING, "SayCountedNoun requires two arguments\n"); 00143 return -1; 00144 } 00145 00146 if (sscanf(args.number, "%d", &number) != 1) { 00147 ast_log(LOG_WARNING, "First argument must be a number between 0 and 2,147,483,647.\n"); 00148 return -1; 00149 } 00150 00151 return ast_say_counted_noun(chan, number, args.noun); 00152 } 00153 00154 static int saycountedadj_exec(struct ast_channel *chan, const char *data) 00155 { 00156 char *parse; 00157 int number; 00158 AST_DECLARE_APP_ARGS(args, 00159 AST_APP_ARG(number); 00160 AST_APP_ARG(adjective); 00161 AST_APP_ARG(gender); 00162 ); 00163 00164 if (ast_strlen_zero(data)) { 00165 ast_log(LOG_WARNING, "SayCountedAdj requires two or three arguments (<number>,<adjective>[,<gender>])\n"); 00166 return -1; 00167 } 00168 00169 parse = ast_strdupa(data); 00170 AST_STANDARD_APP_ARGS(args, parse); 00171 00172 if (args.argc < 2) { 00173 ast_log(LOG_WARNING, "SayCountedAdj requires at least two arguments\n"); 00174 return -1; 00175 } 00176 00177 if (sscanf(args.number, "%d", &number) != 1) { 00178 ast_log(LOG_WARNING, "First argument must be a number between 0 and 2,147,483,647.\n"); 00179 return -1; 00180 } 00181 00182 if (!ast_strlen_zero(args.gender)) { 00183 if (strchr("cCfFmMnN", args.gender[0])) { 00184 ast_log(LOG_WARNING, "SayCountedAdj gender option must be one of 'f', 'm', 'c', or 'n'.\n"); 00185 return -1; 00186 } 00187 } 00188 00189 return ast_say_counted_adjective(chan, number, args.adjective, args.gender); 00190 } 00191 00192 static int load_module(void) 00193 { 00194 int res; 00195 res = ast_register_application_xml("SayCountedNoun", saycountednoun_exec); 00196 res |= ast_register_application_xml("SayCountedAdj", saycountedadj_exec); 00197 return res; 00198 } 00199 00200 static int unload_module(void) 00201 { 00202 int res; 00203 res = ast_unregister_application("SayCountedNoun"); 00204 res |= ast_unregister_application("SayCountedAdj"); 00205 return res; 00206 } 00207 00208 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Decline words according to channel language");