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 </description> 00066 <see-also> 00067 <ref type="application">SayCountedAdj</ref> 00068 <ref type="application">SayNumber</ref> 00069 </see-also> 00070 </application> 00071 <application name="SayCountedAdj" language="en_US"> 00072 <synopsis> 00073 Say a adjective in declined form in order to count things 00074 </synopsis> 00075 <syntax> 00076 <parameter name="number" required="true"> 00077 <para>The number of things</para> 00078 </parameter> 00079 <parameter name="filename" required="true"> 00080 <para>File name stem for the adjective</para> 00081 </parameter> 00082 <parameter name="gender"> 00083 <para>The gender of the noun modified, one of 'm', 'f', 'n', or 'c'</para> 00084 </parameter> 00085 </syntax> 00086 <description> 00087 <para>Selects and plays the proper form of an adjective according to 00088 the gender and of the noun which it modifies and the number of 00089 objects named by the noun-verb combination which have been counted. 00090 Used when saying things such as "5 new messages". The various 00091 singular and plural forms of the adjective are selected by adding 00092 suffixes to <replaceable>filename</replaceable>.</para> 00093 <para>If the channel language is English, then no suffix will ever 00094 be added (since, in English, adjectives are not declined). If the 00095 channel language is Russian or some other slavic language, then the 00096 suffix will the specified <replaceable>gender</replaceable> for 00097 nominative, and "x" for genative plural. (The genative singular is 00098 not used when counting things.) For example, SayCountedAdj(1,new,f) 00099 will play sound file "newa" (containing the word "novaya"), but 00100 SayCountedAdj(5,new,f) will play sound file "newx" (containing the 00101 word "novikh").</para> 00102 </description> 00103 <see-also> 00104 <ref type="application">SayCountedNoun</ref> 00105 <ref type="application">SayNumber</ref> 00106 </see-also> 00107 </application> 00108 ***/ 00109 00110 #include "asterisk.h" 00111 00112 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $") 00113 00114 #include "asterisk/logger.h" 00115 #include "asterisk/module.h" 00116 #include "asterisk/app.h" 00117 #include "asterisk/say.h" 00118 00119 static int saycountednoun_exec(struct ast_channel *chan, const char *data) 00120 { 00121 char *parse; 00122 int number; 00123 AST_DECLARE_APP_ARGS(args, 00124 AST_APP_ARG(number); 00125 AST_APP_ARG(noun); 00126 ); 00127 00128 if (ast_strlen_zero(data)) { 00129 ast_log(LOG_WARNING, "SayCountedNoun requires two arguments (<number>,<noun>)\n"); 00130 return -1; 00131 } 00132 00133 parse = ast_strdupa(data); 00134 AST_STANDARD_APP_ARGS(args, parse); 00135 00136 if (args.argc != 2) { 00137 ast_log(LOG_WARNING, "SayCountedNoun requires two arguments\n"); 00138 return -1; 00139 } 00140 00141 if (sscanf(args.number, "%d", &number) != 1) { 00142 ast_log(LOG_WARNING, "First argument must be a number between 0 and 2,147,483,647.\n"); 00143 return -1; 00144 } 00145 00146 return ast_say_counted_noun(chan, number, args.noun); 00147 } 00148 00149 static int saycountedadj_exec(struct ast_channel *chan, const char *data) 00150 { 00151 char *parse; 00152 int number; 00153 AST_DECLARE_APP_ARGS(args, 00154 AST_APP_ARG(number); 00155 AST_APP_ARG(adjective); 00156 AST_APP_ARG(gender); 00157 ); 00158 00159 if (ast_strlen_zero(data)) { 00160 ast_log(LOG_WARNING, "SayCountedAdj requires two or three arguments (<number>,<adjective>[,<gender>])\n"); 00161 return -1; 00162 } 00163 00164 parse = ast_strdupa(data); 00165 AST_STANDARD_APP_ARGS(args, parse); 00166 00167 if (args.argc < 2) { 00168 ast_log(LOG_WARNING, "SayCountedAdj requires at least two arguments\n"); 00169 return -1; 00170 } 00171 00172 if (sscanf(args.number, "%d", &number) != 1) { 00173 ast_log(LOG_WARNING, "First argument must be a number between 0 and 2,147,483,647.\n"); 00174 return -1; 00175 } 00176 00177 if (!ast_strlen_zero(args.gender)) { 00178 if (strchr("cCfFmMnN", args.gender[0])) { 00179 ast_log(LOG_WARNING, "SayCountedAdj gender option must be one of 'f', 'm', 'c', or 'n'.\n"); 00180 return -1; 00181 } 00182 } 00183 00184 return ast_say_counted_adjective(chan, number, args.adjective, args.gender); 00185 } 00186 00187 static int load_module(void) 00188 { 00189 int res; 00190 res = ast_register_application_xml("SayCountedNoun", saycountednoun_exec); 00191 res |= ast_register_application_xml("SayCountedAdj", saycountedadj_exec); 00192 return res; 00193 } 00194 00195 static int unload_module(void) 00196 { 00197 int res; 00198 res = ast_unregister_application("SayCountedNoun"); 00199 res |= ast_unregister_application("SayCountedAdj"); 00200 return res; 00201 } 00202 00203 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Decline words according to channel language");