Logo Search packages:      
Sourcecode: bayonne version File versions  Download package

dutch.cpp

// Copyright (C) 2000 Open Source Telecom Corporation.
//  
// 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 <bayonne.h>
#include <cc++/strchar.h>

#ifdef      HAVE_SSTREAM
#include <sstream>
#else
#include <strstream>
#endif

#ifdef      HAVE_SSTREAM
#define     strstream   ostringstream
#endif

#ifdef      CCXX_NAMESPACES
namespace ost {
using namespace std;
#endif

class DutchTranslator : public Translator
{
private:
      char *getName(void)
            {return "dutch";};
public:
      DutchTranslator();
      char *speak(Trunk *trunk);
} dutch;

DutchTranslator::DutchTranslator() :
Translator("/bayonne/dutch")
{
      slog(Slog::levelDebug) << "TTS: loading Dutch phrasebooks..." << endl;
}

static void spell(strstream *s, const char *text);

static void order(strstream *s, int num)
{
      char *low[] = { "0th",
            "1st", "2nd", "3rd", "4th", "5th",
            "6th", "7th", "8th", "9th", "10th",
            "11th", "12th", "13th", "14th", "15th",
            "16th", "17th", "18th", "19th"};

      if(num > 100)
      {
            if(num % 100)
                  *s << ','  << num / 100 << ",hundred";
            else
                  *s << ',' << num / 100 << ",hundred,th";
            num %= 100;
      }
      if(num > 19)
      {
            if (num % 10)
                  *s << "," << num % 10 << ",and";

            *s << ',' << num / 10 * 10 << "th";
            return;
      }
      *s << ',' << low[num];
}

static void lownumber(strstream *s, int num)
{
      int tens;
      if(num >= 100)
      {
            tens = num / 100;
            if ( tens > 1 )
            {
                  *s << ',' << tens << ",hundred";
            }
            else
            {
                  *s << ",hundred";
            }
            num %= 100;
            if(!num)
                  return;
      }
      if(num < 20)
      {
            *s << ',' << num;
            return;
      }
      switch (num % 10) {
      case 1:
            *s << ",1,and";
            break;
      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
      case 7:
      case 8:
      case 9:
            *s << "," << num % 10 << ",and";
            break;
      }
      *s << ',' << (num / 10) * 10;
}

static bool number(strstream *s, const char *text)
{
      unsigned long num;
      int low_num;
      bool zero = true;

      if(!text)
            return true;

      if(!*text)
            return true;

      if(*text == '-')
      {
            *s << ",negative";
            ++text; 
      }
      num = atol(text);
      if(num > 999999999)
      {
            zero = false;
            low_num = num / 1000000000;
            lownumber(s, low_num);
            *s << ",billion";

            num %= 1000000000;
      }
      if(num > 999999)
      {
            zero = false;
            low_num = num / 1000000;
            lownumber(s, low_num);
            *s << ",million";
            num %= 1000000;
      }
      if(num > 999)
      {
            zero = false;
            low_num = num / 100;
            if ( ( low_num == 10 ) || ( low_num >= 20 ) )
            {
                  if ( low_num != 10 )
                  {
                        lownumber(s, low_num / 10 );
                  }
                  *s << ",thousand";
                  num %= 1000;
            }
            else
            {
                  lownumber(s, low_num );
                  *s << ",hundred";
                  num %= 100;
            }
            
      }
      if(num || zero)
            lownumber(s, num);

      if(num)
            zero = false;

      text = strchr(text, '.');
      if(!text)
            return zero;
      *s << ",point";
      number(s, ++text);
      return false;
}

static void spell(strstream *s, const char *text)
{
      char ch;
      if(!text)
            return;

      while((ch = *(text++)))
      {
            if(ch >= 'A' && ch <= 'Z')
                  ch += 32;

            if(ch >= '0' && ch <= '9')
                  *s << ',' << ch;
            else if(ch >= 'a' && ch <= 'z')
                  *s << ',' << ch;
            else if(ch == '.')
                  *s << ",point";
      }
}

static void sayweekday(strstream *s, const char *text)
{
      static char *days[] = {
            "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};

        time_t cl;
        struct tm *ti;
      int month, day, year;

        time(&cl);
        ti = localtime (&cl);

      if(text[2] == '/')
            sscanf(text, "%02d/%02d/%04d", &month, &day, &year);
      else if(text[2] == '.')
            sscanf(text, "%02d.%02d.%04d", &day, &month, &year);
      else if(text[4] == '-')
            sscanf(text, "%04d-%02d-%02d", &year, &month, &day);
      else
            sscanf(text, "%04d%02d%02d", &year, &month, &day);

      ti->tm_year = year;
      ti->tm_mon = month - 1;
      ti->tm_mday = day;

        if(ti->tm_year > 1000) 
            ti->tm_year -= 1900;

        mktime(ti);
      *s << ',' << days[ti->tm_wday];
}


static void saydate(strstream *s, const char *text)
{
      static char *months[] = {
            "january", "february", "march", "april",
            "may", "june", "july", "august",
            "september", "october", "november", "december"};

      time_t now;
      struct tm *dt;
      time(&now);
      dt = localtime(&now);
      int month, day, year;
      char buf[5];

      if(text[2] == '/')
            sscanf(text, "%02d/%02d/%04d", &month, &day, &year);
      else if(text[2] == '.')
            sscanf(text, "%02d.%02d.%04d", &day, &month, &year);
      else if(text[4] == '-')
            sscanf(text, "%04d-%02d-%02d", &year, &month, &day);
      else
            sscanf(text, "%04d%02d%02d", &year, &month, &day);

      --month;
      if(dt->tm_year < 100)
            dt->tm_year += 2000;
      if(month == dt->tm_mon && day == dt->tm_mday && year == dt->tm_year)
      {
            *s << ",today";
            return;
      }     

      sprintf( buf, "%d", day );
      number(s, buf);
      *s << ',' << months[month];
      if(dt->tm_year == year)
            return;

      sprintf( buf, "%d", year );
      number(s, buf);
}

static char *getchange(const char *text, int dec, char *ch)
{
      int len;
      text = strchr(text, '.');
      if(!text)
            return NULL;

      ++text;
      memset(ch, '0', dec);
      ch[dec] = 0;
      len = strlen(text);
      if(len > dec)
            len = dec;
      strncpy(ch, text, len);
      return ch;
}
      
static void sayvalue(strstream *s, const char *cu, const char *ch, int dec, const char *text)
{
      char chbuf[dec + 1];
      int currency = atoi(text);
      char cbuf[11];
      const char *change = getchange(text, dec, chbuf);

      if(!currency && !change)
      {
            *s << ",0" << cu;
      }

      if(currency)
      {
            sprintf(cbuf, "%d", currency);
            number(s, cbuf);
            *s << ',' << cu;

            if(change)
                  *s << ",and";
      }
      if(change)
      {
            number(s, change);
            *s << ',' << ch;
      }
}                 

static bool sayprimary(strstream *s, const char *text)
{
      const char *cu = keylocal.getLast("primarycurrency");
      const char *ch = keylocal.getLast("primarychange");
      const char *d = keylocal.getLast("primarydecimal");
      if(!d)
            d = "2";

      if(!cu)
            return false;

      sayvalue(s, cu, ch, atoi(d), text);
      return true;
}

static bool saylocal(strstream *s, double v, bool orflag)
{
      char tbuf[33];
      const char *cu = keylocal.getLast("localcurrency");
      const char *ch = keylocal.getLast("localchange");
      const char *d = keylocal.getLast("localdecimal");
      const char *cvt = keylocal.getLast("convertcurrency");

      if(!d)
            d = "2";

      if(!cu)
            return true;

      if(cvt)
      {
            v *= atof(cvt);
            sprintf(tbuf, "%f", v);
      }
      else
            sprintf(tbuf, "%f", v);
      if(!v)
            return false;
      *s << ",or";
      sayvalue(s, cu, ch, atoi(d), tbuf);
      return true;
}

static void saycurrency(strstream *s, const char *text)
{
      saylocal(s, atof(text), sayprimary(s, text));
}

static bool sayduration(strstream *s, const char *text)
{
      int hour = 0, minute = 0, second = 0;

      if(text[2] == '.')
      {
            if(strchr(text + 3, '.'))
                  sscanf(text, "%02d.%02d.%02d",
                        &hour, &minute, &second);
            else
                  sscanf(text, "%02d.%02d",
                        &hour, &minute);
      }
      else
      {
            if(strlen(text) > 4)
                  sscanf(text, "%02d%02d%02d",
                        &hour, &minute, &second);
            else
                  sscanf(text, "%02d%02d",
                        &hour, &minute);
      }
      if(hour)
      {
            lownumber(s, hour);
            if(hour == 1)
                  *s << ",hour";
            else
                  *s << ",hours";
      }
      if(minute)
      {
            lownumber(s, minute);
            if(minute == 1)
                  *s << ",minute";
            else
                  *s << ",minutes";
      }
      if(second)
      {
            lownumber(s, second);
            if(second == 1)
                  *s << ",second";
            else
                  *s << ",seconds";
      }
      if(hour || minute || second)
            return false;
      return true;
}
                  
static void saytime(strstream *s, const char *text)
{
      int hour = 0, minute = 0;
      char buf[3];

      if(text[2] == ':')
            sscanf(text, "%02d:%02d", &hour, &minute);
      else
            sscanf(text, "%02d%02d", &hour, &minute);

      sprintf(buf, "%d", hour);
      number(s, buf);
      *s << ",hour";
      if(minute)
      {
            sprintf(buf, "%d", minute);
            number(s, buf);
      }
}

char *DutchTranslator::speak(Trunk *trunk)
{
      char *pbuf = getPlayBuffer(trunk);
#ifdef      HAVE_SSTREAM
      ostringstream str;
#else
      strstream str(pbuf, 254);
#endif
      char rules[256];
      const char *rule = NULL;
      const char *phrase;
      bool skip = false;
      long lastnum = 0;
      char *text;
      ScriptImage *cmd = trunk->getImage();

      while(NULL != (rule = trunk->getValue(NULL)))
      {
            if(*rule != '&')
            {
                  str << ',' << rule;
                  continue;
            }
            phrase = getLast(rule + 1);
            if(!phrase)
            {
                  snprintf(rules, 256, "_dutch_%s", rule + 1);
                  phrase = cmd->getLast(rules);
            }
            if(!phrase)
            {
                  snprintf(rules, 256, "_all_%s", rule + 1);
                  phrase = cmd->getLast(rules);
            }
            if(!phrase)
                  phrase = rule;

            strncpy(rules, phrase, 254);
            rules[255] = 0;
            rule = strtok(rules, " ;,\t\n");
            while(rule)
            {
                  if(!stricmp(rule, "&exit"))
                  {
                        if(skip)
                              return NULL;
                  }
                  else if(!stricmp(rule, "&ignore") || !stricmp(rule, "&several"))
                  {
                        trunk->getValue(NULL);
                  }
                  else if(!stricmp(rule, "&use"))
                  {
                        text = trunk->getValue(NULL);
                        if(text)
                              str << ',' << text;
                  }
                  else if(!stricmp(rule, "&skip"))
                  {
                        if(skip)
                              trunk->getValue(NULL);
                  }
                  else if(!stricmp(rule, "&single") || !stricmp(rule, "&singular"))
                  {
                        text = trunk->getValue(NULL);
                        if(lastnum == 1 && !skip && text)
                              str << ',' << text;
                  }
                  else if(!stricmp(rule, "&plural"))
                  {
                        text = trunk->getValue(NULL);
                        if(lastnum != 1 && !skip && text)
                              str << ',' << text;
                  }
                  else if(!stricmp(rule, "&spell"))
                  {
                        skip = false;
                        spell(&str, trunk->getValue(""));
                  }
                  else if(!stricmp(rule, "&number"))
                  {
                        text = trunk->getValue(NULL);
                        if(text)
                        {
                              lastnum = atol(text);   
                              skip = number(&str, text);
                        }
                  }
                  else if(!stricmp(rule, "&order"))
                  {
                        skip = false;
                        text = trunk->getValue(NULL);
                        if(text)
                              order(&str, atoi(text));
                  }
                  else if(!stricmp(rule, "&duration"))
                  {
                        skip = false;
                        text = trunk->getValue(NULL);
                        if(text)
                              skip = sayduration(&str, text);
                  }
                  else if(!stricmp(rule, "&time"))
                  {
                        skip = false;
                        text = trunk->getValue(NULL);
                        if(text)
                              saytime(&str, text);
                  }
                  else if(!stricmp(rule, "&date"))
                  {
                        skip = false;
                        text = trunk->getValue(NULL);
                        if(text)
                              saydate(&str, text);
                  }
                  else if(!stricmp(rule, "&weekday"))
                  {
                        skip = false;
                        text = trunk->getValue(NULL);
                        if(text)
                              sayweekday(&str, text);
                  }
                  else if(!stricmp(rule, "&unit"))
                  {
                        skip = false;
                        text = trunk->getValue(NULL);
                        if(text)
                        {
                              lastnum = atol(text);
                              if(number(&str, text))
                                    str << ",0";
                        }
                  }
                  else if(!stricmp(rule, "&zero"))
                  {
                        skip = false;
                        text = trunk->getValue(NULL);
                        if(!lastnum && text)
                              str << ',' << text;
                  }
                  else if(!stricmp(rule, "&currency"))
                  {
                        skip = false;
                        lastnum = 1;
                        text = trunk->getValue(NULL);
                        if(text)
                        {
                              if(atof(text))
                                    saycurrency(&str, text);
                              else
                                    lastnum = 0;
                        }
                  }
                  else if(!stricmp(rule, "&primary"))
                  {
                        skip = false;
                        lastnum = 1;
                        text = trunk->getValue(NULL);
                        if(text)
                        {
                              if(atof(text))
                                    sayprimary(&str, text);
                              else
                                    lastnum = 0;
                        }
                  }
                  else if(!stricmp(rule, "&local"))
                  {
                        skip = false;
                        lastnum = 1;
                        text = trunk->getValue(NULL);
                        if(text)
                        {
                              if(!saylocal(&str, atof(text), false))
                                    lastnum = 0;
                        }
                  }
                  else 
                  {
                        skip = false;
                        str << ',' << rule;
                  }
                  rule = strtok(NULL, " ;,\t\n");
            }     
      }

#ifdef      HAVE_SSTREAM
      snprintf(pbuf, 256, "%s", str.str().c_str());
#else
      str << ends;
      pbuf[255] = 0;
#endif
      while(*pbuf)
      {
            *pbuf = tolower(*pbuf);
            ++pbuf;
      }
      return NULL;
}

#ifdef      CCXX_NAMESPACES
};
#endif      

      
      


Generated by  Doxygen 1.6.0   Back to index