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 ***/ 00030 00031 /*** DOCUMENTATION 00032 <application name="SayCountedNoun" language="en_US"> 00033 <synopsis> 00034 Say a noun in declined form in order to count things 00035 </synopsis> 00036 <syntax> 00037 <parameter name="number" required="true"> 00038 <para>The number of things</para> 00039 </parameter> 00040 <parameter name="filename" required="true"> 00041 <para>File name stem for the noun that is the the name of the things</para> 00042 </parameter> 00043 </syntax> 00044 <description> 00045 <para>Selects and plays the proper singular or plural form of a noun 00046 when saying things such as "five calls". English has simple rules 00047 for deciding when to say "call" and when to say "calls", but other 00048 languages have complicated rules which would be extremely difficult 00049 to implement in the Asterisk dialplan language.</para> 00050 <para>The correct sound file is selected by examining the 00051 <replaceable>number</replaceable> and adding the appropriate suffix 00052 to <replaceable>filename</replaceable>. If the channel language is 00053 English, then the suffix will be either empty or "s". If the channel 00054 language is Russian or some other Slavic language, then the suffix 00055 will be empty for nominative, "x1" for genative singular, and "x2" 00056 for genative plural.</para> 00057 <para>Note that combining <replaceable>filename</replaceable> with 00058 a suffix will not necessarily produce a correctly spelled plural 00059 form. For example, SayCountedNoun(2,man) will play the sound file 00060 "mans" rather than "men". This behavior is intentional. Since the 00061 file name is never seen by the end user, there is no need to 00062 implement complicated spelling rules. We simply record the word 00063 "men" in the sound file named "mans".</para> 00064 </description> 00065 <see-also> 00066 <ref type="application">SayCountedAdj</ref> 00067 <ref type="application">SayNumber</ref> 00068 </see-also> 00069 </application> 00070 <application name="SayCountedAdj" language="en_US"> 00071 <synopsis> 00072 Say a adjective in declined form in order to count things 00073 </synopsis> 00074 <syntax> 00075 <parameter name="number" required="true"> 00076 <para>The number of things</para> 00077 </parameter> 00078 <parameter name="filename" required="true"> 00079 <para>File name stem for the adjective</para> 00080 </parameter> 00081 <parameter name="gender"> 00082 <para>The gender of the noun modified, one of 'm', 'f', 'n', or 'c'</para> 00083 </parameter> 00084 </syntax> 00085 <description> 00086 <para>Selects and plays the proper form of an adjective according to 00087 the gender and of the noun which it modifies and the number of 00088 objects named by the noun-verb combination which have been counted. 00089 Used when saying things such as "5 new messages". The various 00090 singular and plural forms of the adjective are selected by adding 00091 suffixes to <replaceable>filename</replaceable>.</para> 00092 <para>If the channel language is English, then no suffix will ever 00093 be added (since, in English, adjectives are not declined). If the 00094 channel language is Russian or some other slavic language, then the 00095 suffix will the specified <replaceable>gender</replaceable> for 00096 nominative, and "x" for genative plural. (The genative singular is 00097 not used when counting things.) For example, SayCountedAdj(1,new,f) 00098 will play sound file "newa" (containing the word "novaya"), but 00099 SayCountedAdj(5,new,f) will play sound file "newx" (containing the 00100 word "novikh").</para> 00101 </description> 00102 <see-also> 00103 <ref type="application">SayCountedNoun</ref> 00104 <ref type="application">SayNumber</ref> 00105 </see-also> 00106 </application> 00107 ***/ 00108 00109 #include "asterisk.h" 00110 00111 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 271520 $") 00112 00113 #include "asterisk/logger.h" 00114 #include "asterisk/module.h" 00115 #include "asterisk/app.h" 00116 #include "asterisk/say.h" 00117 00118 static int saycountednoun_exec(struct ast_channel *chan, const char *data) 00119 { 00120 char *parse; 00121 int number; 00122 AST_DECLARE_APP_ARGS(args, 00123 AST_APP_ARG(number); 00124 AST_APP_ARG(noun); 00125 ); 00126 00127 if (ast_strlen_zero(data)) { 00128 ast_log(LOG_WARNING, "SayCountedNoun requires two arguments (<number>,<noun>)\n"); 00129 return -1; 00130 } 00131 00132 parse = ast_strdupa(data); 00133 AST_STANDARD_APP_ARGS(args, parse); 00134 00135 if (args.argc != 2) { 00136 ast_log(LOG_WARNING, "SayCountedNoun requires two arguments\n"); 00137 return -1; 00138 } 00139 00140 if (sscanf(args.number, "%d", &number) != 1) { 00141 ast_log(LOG_WARNING, "First argument must be a number between 0 and 2,147,483,647.\n"); 00142 return -1; 00143 } 00144 00145 return ast_say_counted_noun(chan, number, args.noun); 00146 } 00147 00148 static int saycountedadj_exec(struct ast_channel *chan, const char *data) 00149 { 00150 char *parse; 00151 int number; 00152 AST_DECLARE_APP_ARGS(args, 00153 AST_APP_ARG(number); 00154 AST_APP_ARG(adjective); 00155 AST_APP_ARG(gender); 00156 ); 00157 00158 if (ast_strlen_zero(data)) { 00159 ast_log(LOG_WARNING, "SayCountedAdj requires two or three arguments (<number>,<adjective>[,<gender>])\n"); 00160 return -1; 00161 } 00162 00163 parse = ast_strdupa(data); 00164 AST_STANDARD_APP_ARGS(args, parse); 00165 00166 if (args.argc < 2) { 00167 ast_log(LOG_WARNING, "SayCountedAdj requires at least two arguments\n"); 00168 return -1; 00169 } 00170 00171 if (sscanf(args.number, "%d", &number) != 1) { 00172 ast_log(LOG_WARNING, "First argument must be a number between 0 and 2,147,483,647.\n"); 00173 return -1; 00174 } 00175 00176 if (!ast_strlen_zero(args.gender)) { 00177 if (strchr("cCfFmMnN", args.gender[0])) { 00178 ast_log(LOG_WARNING, "SayCountedAdj gender option must be one of 'f', 'm', 'c', or 'n'.\n"); 00179 return -1; 00180 } 00181 } 00182 00183 return ast_say_counted_adjective(chan, number, args.adjective, args.gender); 00184 } 00185 00186 static int load_module(void) 00187 { 00188 int res; 00189 res = ast_register_application_xml("SayCountedNoun", saycountednoun_exec); 00190 res |= ast_register_application_xml("SayCountedAdj", saycountedadj_exec); 00191 return res; 00192 } 00193 00194 static int unload_module(void) 00195 { 00196 int res; 00197 res = ast_unregister_application("SayCountedNoun"); 00198 res |= ast_unregister_application("SayCountedAdj"); 00199 return res; 00200 } 00201 00202 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Decline words according to channel language");