Logo Search packages:      
Sourcecode: verbiste version File versions

french-conjugator.cpp

/*  $Id: french-conjugator.cpp,v 1.9 2005/03/13 04:03:26 sarrazip Exp $
    french-conjugator.cpp - Conjugation of French verbs

    verbiste - French conjugation system
    Copyright (C) 2003-2005 Pierre Sarrazin <http://sarrazip.com/>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA.
*/


#include "Command.h"

#ifdef HAVE_GETOPT_LONG
#include <unistd.h>
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <getopt.h>
#endif

#include <iostream>
#include <vector>

using namespace std;
using namespace verbiste;


static const char *commandName = "french-conjugator";


#ifdef HAVE_GETOPT_LONG
static struct option knownOptions[] =
{
    { "help",           no_argument,            NULL, 'h' },
    { "version",        no_argument,            NULL, 'v' },
    { "mode",           required_argument,      NULL, 'm' },
    { "tense",          required_argument,      NULL, 't' },
    { "template",       required_argument,      NULL, 'l' },
    { "pronouns",       no_argument,            NULL, 'p' },

    { NULL, 0, NULL, 0 }  // marks the end
};
#endif  /* HAVE_GETOPT_LONG */


class ConjugatorCommand : public Command
{
public:

    ConjugatorCommand() throw(logic_error)
      : Command(),
      reqMode(INVALID_MODE),
      reqTense(INVALID_TENSE),
      reqTemplate(),
      includePronouns(false),
      aspirateH(false)
    {
    }

    virtual ~ConjugatorCommand()
    {
    }

    // Constraints:
    Mode reqMode;
    Tense reqTense;
    string reqTemplate;
    bool includePronouns;

protected:

    virtual void processInputWord(const std::string &inputWord);

private:

    bool aspirateH;

    void displayTense(FrenchVerbDictionary &fvd,
                  const string &radical,
                  const TemplateSpec &templ,
                  Mode mode,
                  Tense tense);

    void displayConjugation(FrenchVerbDictionary &fvd,
                  const string &infinitive,
                  const string &tname,
                  const TemplateSpec &templ);
};


void
ConjugatorCommand::displayTense(FrenchVerbDictionary &fvd,
                        const string &radical,
                        const TemplateSpec &templ,
                        Mode mode,
                        Tense tense)
{
    if (reqMode != INVALID_MODE && mode != reqMode)
      return;
    if (reqTense != INVALID_TENSE && tense != reqTense)
      return;

    cout << "- " << FrenchVerbDictionary::getModeName(mode)
            << " " << FrenchVerbDictionary::getTenseName(tense) << ":\n";


    typedef vector<string> VS;
    typedef vector<VS> VVS;

    VVS conjug;
    FrenchVerbDictionary::generateTense(radical, templ, mode, tense, conjug,
                              includePronouns, aspirateH);

    for (VVS::const_iterator p = conjug.begin(); p != conjug.end(); p++)
    {
      for (VS::const_iterator i = p->begin(); i != p->end(); i++)
      {
          if (i != p->begin())
            cout << ", ";
          cout << *i;
      }
      cout << "\n";
    }
}


void
ConjugatorCommand::displayConjugation(FrenchVerbDictionary &fvd,
                              const string &infinitive,
                              const string &tname,
                              const TemplateSpec &templ)
{
    try
    {
      aspirateH = fvd.isVerbStartingWithAspirateH(infinitive);

      string radical = FrenchVerbDictionary::getRadical(infinitive, tname);

      displayTense(fvd, radical, templ, INFINITIVE_MODE, PRESENT_TENSE);

      displayTense(fvd, radical, templ, INDICATIVE_MODE, PRESENT_TENSE);
      displayTense(fvd, radical, templ, INDICATIVE_MODE, IMPERFECT_TENSE);
      displayTense(fvd, radical, templ, INDICATIVE_MODE, FUTURE_TENSE);
      displayTense(fvd, radical, templ, INDICATIVE_MODE, PAST_TENSE);

      displayTense(fvd, radical, templ, CONDITIONAL_MODE, PRESENT_TENSE);

      displayTense(fvd, radical, templ, SUBJUNCTIVE_MODE, PRESENT_TENSE);
      displayTense(fvd, radical, templ, SUBJUNCTIVE_MODE, IMPERFECT_TENSE);

      displayTense(fvd, radical, templ, IMPERATIVE_MODE, PRESENT_TENSE);

      displayTense(fvd, radical, templ, PARTICIPLE_MODE, PRESENT_TENSE);
      displayTense(fvd, radical, templ, PARTICIPLE_MODE, PAST_TENSE);
    }
    catch (logic_error &e)
    {
      return;
    }
}


/*virtual*/
void
ConjugatorCommand::processInputWord(const string &inputWord)
{
    const char *tname = (reqTemplate.empty() ? NULL : reqTemplate.c_str());

    if (tname == NULL)  // if no specific template requested
    {
      // Use the template associated with the verb, if known:
      tname = fvd->getVerbTemplate(inputWord);
    }

    if (tname != NULL)
    {
      const TemplateSpec *templ = fvd->getTemplate(tname);

      if (templ != NULL)
          displayConjugation(*fvd, inputWord, tname, *templ);
    }

    cout << "-" << endl;  // marks the end of the answer, and flushes it
}


static
void
displayVersionNo()
{
    cout << commandName << ' ' << VERSION << '\n';
}


static
void
displayHelp()
{
    cout << '\n';

    displayVersionNo();

    cout << "Part of " << PACKAGE << " " << VERSION << "\n";

    cout <<
"\n"
"Copyright (C) 2003-2005 Pierre Sarrazin <http://sarrazip.com/>\n"
"This program is free software; you may redistribute it under the terms of\n"
"the GNU General Public License.  This program has absolutely no warranty.\n"
    ;

    cout <<
"\n"
"Known options:\n"
"--help             Display this help page and exit\n"
"--version          Display this program's version number and exit\n"
"--mode=M           Only display mode M (infinitive, indicative, etc)\n"
"--tense=T          Only display tense T (present, past, etc)\n"
"--template=T       Use template T to conjugate the verbs\n"
"--pronouns         Include pronouns in the displayed conjugation\n"
"\n"
"See the " << commandName << "(1) manual page for details.\n"
"\n"
    ;
}


int
main(int argc, char *argv[])
{
    Mode reqMode = INVALID_MODE;
    Tense reqTense = INVALID_TENSE;
    string reqTemplate;
    bool includePronouns = false;

    #ifdef HAVE_GETOPT_LONG

    /*  Interpret the command-line options:
    */
    int c;
    try { do
    {
      c = getopt_long(argc, argv, "hvm:t:l:p", knownOptions, NULL);

      switch (c)
      {
          case EOF:
            break;  // nothing to do

          case 'm':
            reqMode = FrenchVerbDictionary::convertModeName(optarg);
            if (reqMode == INVALID_MODE)
            {
                cerr << commandName << ": invalid mode " << optarg << "\n";
                return EXIT_FAILURE;
            }
            break;

          case 't':
            reqTense = FrenchVerbDictionary::convertTenseName(optarg);
            if (reqTense == INVALID_TENSE)
            {
                cerr << commandName << ": invalid tense " << optarg << "\n";
                return EXIT_FAILURE;
            }
            break;

          case 'l':
            reqTemplate = optarg;
            break;

          case 'p':
            includePronouns = true;
            break;

          case 'v':
            displayVersionNo();
            return EXIT_SUCCESS;

          case 'h':
            displayHelp();
            return EXIT_SUCCESS;

          default:
            displayHelp();
            return EXIT_FAILURE;
      }
    } while (c != EOF && c != '?');
    } catch (const exception &e)
    {
      cerr << "Exception: " << e.what() << endl;
      return EXIT_FAILURE;
    }

    #else  /* ndef HAVE_GETOPT_LONG */

    int optind = 1;

    #endif  /* ndef HAVE_GETOPT_LONG */

    ConjugatorCommand cmd;
    cmd.reqMode = reqMode;
    cmd.reqTense = reqTense;
    cmd.reqTemplate = reqTemplate;
    cmd.includePronouns = includePronouns;

    if (!reqTemplate.empty() &&
            cmd.getFrenchVerbDictionary().getTemplate(reqTemplate) == NULL)
    {
      cerr << commandName << ": invalid conjugation template "
                                  << optarg << "\n";
      return EXIT_FAILURE;
    }

    return cmd.run(argc - optind, argv + optind);
}

Generated by  Doxygen 1.6.0   Back to index