1 /* $Id: c-api.cpp,v 1.14 2011/01/25 02:29:44 sarrazip Exp $
2 FrenchVerbDictionary.cpp - Dictionary of verbs and conjugation templates
4 verbiste - French conjugation system
5 Copyright (C) 2003-2010 Pierre Sarrazin <http://sarrazip.com/>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 #include <verbiste/FrenchVerbDictionary.h>
25 #include <verbiste/misc-types.h>
32 using namespace verbiste;
34 #define malloc @FORBIDDEN@
35 #define free @FORBIDDEN@
38 typedef vector<string> VS;
39 typedef vector<VS> VVS;
42 const Verbiste_ModeTense verbiste_valid_modes_and_tenses[] =
44 { VERBISTE_INFINITIVE_MODE, VERBISTE_PRESENT_TENSE },
46 { VERBISTE_INDICATIVE_MODE, VERBISTE_PRESENT_TENSE },
47 { VERBISTE_INDICATIVE_MODE, VERBISTE_IMPERFECT_TENSE },
48 { VERBISTE_INDICATIVE_MODE, VERBISTE_FUTURE_TENSE },
49 { VERBISTE_INDICATIVE_MODE, VERBISTE_PAST_TENSE },
51 { VERBISTE_CONDITIONAL_MODE, VERBISTE_PRESENT_TENSE },
53 { VERBISTE_SUBJUNCTIVE_MODE, VERBISTE_PRESENT_TENSE },
54 { VERBISTE_SUBJUNCTIVE_MODE, VERBISTE_IMPERFECT_TENSE },
56 { VERBISTE_IMPERATIVE_MODE, VERBISTE_PRESENT_TENSE },
58 { VERBISTE_PARTICIPLE_MODE, VERBISTE_PRESENT_TENSE },
59 { VERBISTE_PARTICIPLE_MODE, VERBISTE_PAST_TENSE },
61 { VERBISTE_GERUND_MODE, VERBISTE_PRESENT_TENSE }, // Italian only
63 { VERBISTE_INVALID_MODE, VERBISTE_INVALID_TENSE } // marks the end
68 static FrenchVerbDictionary *fvd = NULL;
69 static string constructionLogicError;
72 /* Returns a dynamically allocated copy of the given C string.
73 Example: char *p0 = strnew("foo"); delete [] p0;
74 Example: char *p1 = strnew(""); delete [] p1;
75 Example: char *p2 = strnew(NULL); delete [] p2;
76 @param c_str '\0'-terminated string; allowed to be NULL
77 @returns a pointer to an array of characters that was
78 allocated by new[] and which must be destroyed
79 by the caller with delete[]; if 'c_str' was
80 NULL, the returned pointer is NULL.
84 strnew(const char *c_str)
88 return strcpy(new char[strlen(c_str) + 1], c_str);
92 /* Returns a dynamically allocated copy of the given string.
93 @param s string that contains no '\0' characters
94 @returns a pointer as with strnew(const char *)
98 strnew(const string &s)
100 return strnew(s.c_str());
105 verbiste_init(const char *conjugation_filename, const char *verbs_filename, const char *lang_code)
109 if (lang_code == NULL)
114 FrenchVerbDictionary::Language lang = FrenchVerbDictionary::parseLanguageCode(lang_code);
115 fvd = new FrenchVerbDictionary(conjugation_filename, verbs_filename, false, lang);
117 catch (logic_error &e)
119 constructionLogicError = e.what();
128 verbiste_get_init_error()
130 return constructionLogicError.c_str();
147 verbiste_free_string(char *str)
154 verbiste_get_mode_name(Verbiste_Mode mode)
156 return FrenchVerbDictionary::getModeName((Mode) mode);
161 verbiste_get_tense_name(Verbiste_Tense tense)
163 return FrenchVerbDictionary::getTenseName((Tense) tense);
168 Verbiste_ModeTensePersonNumber *
169 createModeTensePersonNumberArray(const vector<InflectionDesc> &vec)
171 size_t vecSize = vec.size();
173 Verbiste_ModeTensePersonNumber *array =
174 new Verbiste_ModeTensePersonNumber[vecSize + 1];
178 for (size_t i = 0; i < vecSize; i++)
180 array[i].infinitive_verb = strnew(vec[i].infinitive.c_str());
181 vec[i].mtpn.dump(array[i]);
184 array[vecSize].infinitive_verb = NULL;
185 array[vecSize].mode = VERBISTE_INVALID_MODE;
186 array[vecSize].tense = VERBISTE_INVALID_TENSE;
187 array[vecSize].person = 0;
188 array[vecSize].plural = false;
194 Verbiste_ModeTensePersonNumber *
195 verbiste_deconjugate(const char *verb)
197 vector<InflectionDesc> vec;
198 fvd->deconjugate(verb, vec);
199 return createModeTensePersonNumberArray(vec);
204 verbiste_free_mtpn_array(Verbiste_ModeTensePersonNumber *array)
209 for (size_t i = 0; array[i].infinitive_verb != NULL; i++)
210 delete [] array[i].infinitive_verb;
218 generateTense(VVS &conjug,
219 const char *infinitive,
220 const char *templateName,
222 Verbiste_Tense tense,
223 bool include_pronouns)
225 const TemplateSpec *templ = fvd->getTemplate(templateName);
228 string radical = FrenchVerbDictionary::getRadical(infinitive, templateName);
230 fvd->generateTense(radical, *templ, (Mode) mode, (Tense) tense, conjug,
232 fvd->isVerbStartingWithAspirateH(infinitive),
238 Verbiste_TemplateArray
239 verbiste_get_verb_template_array(const char *infinitive_verb)
241 if (infinitive_verb == NULL)
243 const std::set<std::string> &templateSet = fvd->getVerbTemplateSet(infinitive_verb);
244 if (templateSet.empty())
247 Verbiste_TemplateArray a = new char *[templateSet.size() + 1];
249 for (std::set<std::string>::const_iterator it = templateSet.begin();
250 it != templateSet.end(); ++it, ++i)
251 a[i] = strnew(it->c_str());
258 free_string_array(char *array[])
262 for (size_t i = 0; array[i] != NULL; ++i)
269 verbiste_free_verb_template_array(Verbiste_TemplateArray array)
271 free_string_array(array);
276 verbiste_conjugate(const char *infinitive_verb,
277 const char *template_name,
278 const Verbiste_Mode mode,
279 const Verbiste_Tense tense,
280 int include_pronouns)
283 if (::generateTense(tenseConjug, infinitive_verb, template_name, mode, tense,
284 include_pronouns != 0) != 0)
287 size_t numPersons = tenseConjug.size();
288 Verbiste_PersonArray personArray =
289 new Verbiste_InflectionArray[numPersons + 1];
291 for (size_t i = 0; i < numPersons; i++)
293 const VS &inflections = tenseConjug[i];
294 size_t numInf = inflections.size();
295 Verbiste_InflectionArray infArray = new char *[numInf + 1];
296 for (size_t j = 0; j < numInf; j++)
297 infArray[j] = strnew(inflections[j]);
298 infArray[numInf] = NULL;
299 personArray[i] = infArray;
301 personArray[numPersons] = NULL;
307 verbiste_free_person_array(Verbiste_PersonArray array)
312 for (size_t i = 0; array[i] != NULL; i++)
313 free_string_array(array[i]);