From 98f2c717f5c7d0d532e5ee53c55370bff01e3b33 Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Thu, 15 Apr 2010 11:02:07 +0800 Subject: [PATCH] Split SpecialTable.{h, cc} --- src/DynamicSpecialPhrase.cc | 183 ++++++++++++++++++ src/DynamicSpecialPhrase.h | 34 ++++ src/Makefile.am | 8 +- src/PinyinEditor.h | 6 +- src/{SpecialTable.cc => SpecialPhrase.cc} | 16 +- src/SpecialPhrase.h | 24 +++ src/SpecialPhraseTable.cc | 270 +++++++++++++++++++++++++++ src/{SpecialTable.h => SpecialPhraseTable.h} | 26 +-- 8 files changed, 535 insertions(+), 32 deletions(-) create mode 100644 src/DynamicSpecialPhrase.cc create mode 100644 src/DynamicSpecialPhrase.h rename src/{SpecialTable.cc => SpecialPhrase.cc} (94%) create mode 100644 src/SpecialPhrase.h create mode 100644 src/SpecialPhraseTable.cc rename src/{SpecialTable.h => SpecialPhraseTable.h} (52%) diff --git a/src/DynamicSpecialPhrase.cc b/src/DynamicSpecialPhrase.cc new file mode 100644 index 0000000..f7b6b4f --- /dev/null +++ b/src/DynamicSpecialPhrase.cc @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include "DynamicSpecialPhrase.h" + +namespace PY { + +std::string +DynamicSpecialPhrase::text (void) +{ + /* get the current time */ + std::time (&m_time); + + std::string result; + + size_t pos = 0; + size_t pnext; + gint s = 0; + while (s != 2) { + switch (s) { + case 0: + pnext = m_text.find ("${", pos); + if (pnext == m_text.npos) { + result += m_text.substr (pos); + s = 2; + } + else { + result += m_text.substr (pos, pnext - pos); + pos = pnext + 2; + s = 1; + } + break; + case 1: + pnext = m_text.find ("}", pos); + if (pnext == m_text.npos) { + result += "${"; + result += m_text.substr (pos); + s = 2; + } + else { + result += variable (m_text.substr(pos, pnext - pos)); + pos = pnext + 1; + s = 0; + } + break; + default: + g_assert_not_reached (); + } + } + return result; +} + +inline const std::string +DynamicSpecialPhrase::dec (gint d, const gchar *fmt) +{ + char string [32]; + std::snprintf (string, sizeof (string), fmt, d); + return string; +} + +inline const std::string +DynamicSpecialPhrase::year_cn (gboolean yy) +{ + static const gchar * digits[] = { + "〇", "一", "二", "三", "四", + "五", "六", "七", "八", "九" + }; + + gint year = localtime (&m_time)->tm_year + 1900; + gint bit = 0; + if (yy) { + year %= 100; + bit = 2; + } + + std::string result; + while (year != 0 || bit > 0) { + result.insert(0, digits[year % 10]); + year /= 10; + bit -= 1; + } + return result; +} + +inline const std::string +DynamicSpecialPhrase::month_cn (void) +{ + static const gchar *month_num[] = { + "一", "二", "三", "四", "五", "六", "七", "八", + "九", "十", "十一", "十二" + }; + return month_num[localtime (&m_time)->tm_mon]; +} + +inline const std::string +DynamicSpecialPhrase::weekday_cn (void) +{ + static const gchar *week_num[] = { + "日", "一", "二", "三", "四", "五", "六" + }; + return week_num[localtime (&m_time)->tm_wday]; +} + +inline const std::string +DynamicSpecialPhrase::hour_cn (guint i) +{ + static const gchar *hour_num[] = { + "零", "一", "二", "三", "四", + "五", "六", "七", "八", "九", + "十", "十一", "十二", "十三", "十四", + "十五", "十六", "十七", "十八", "十九", + "二十", "二十一", "二十二", "二十三", + }; + return hour_num[i]; +} + +inline const std::string +DynamicSpecialPhrase::fullhour_cn (void) +{ + return hour_cn (localtime (&m_time)->tm_hour); +} + +inline const std::string +DynamicSpecialPhrase::halfhour_cn (void) +{ + return hour_cn (localtime (&m_time)->tm_hour % 12); +} + +inline const std::string +DynamicSpecialPhrase::day_cn (void) +{ + static const gchar *day_num[] = { + "", "一", "二", "三", "四", + "五", "六", "七", "八", "九", + "", "十","二十", "三十" + }; + guint day = localtime (&m_time)->tm_mday; + return std::string (day_num[day / 10 + 10]) + day_num[day % 10]; +} + +inline const std::string +DynamicSpecialPhrase::minsec_cn (guint i) +{ + static const gchar *num[] = { + "", "一", "二", "三", "四", + "五", "六", "七", "八", "九", + "零", "十","二十", "三十", "四十" + "五十", "六十" + }; + return std::string (num[i / 10 + 10]) + num[i % 10]; +} + +inline const std::string +DynamicSpecialPhrase::variable (const std::string &name) +{ + if (name == "year") return dec (localtime (&m_time)->tm_year + 1900); + if (name == "year_yy") return dec ((localtime (&m_time)->tm_year + 1900) % 100, "%02d"); + if (name == "month") return dec (localtime (&m_time)->tm_mon + 1); + if (name == "month_mm") return dec (localtime (&m_time)->tm_mon + 1, "%02d"); + if (name == "day") return dec (localtime (&m_time)->tm_mday); + if (name == "day_dd") return dec (localtime (&m_time)->tm_mday, "%02d"); + if (name == "weekday") return dec (localtime (&m_time)->tm_wday + 1); + if (name == "fullhour") return dec (localtime (&m_time)->tm_hour, "%02d"); + if (name == "falfhour") return dec (localtime (&m_time)->tm_hour % 12, "%02d"); + if (name == "ampm") return localtime (&m_time)->tm_hour < 12 ? "AM" : "PM"; + if (name == "minute") return dec (localtime (&m_time)->tm_min, "%02d"); + if (name == "second") return dec (localtime (&m_time)->tm_sec, "%02d"); + if (name == "year_cn") return year_cn (); + if (name == "year_yy_cn") return year_cn (TRUE); + if (name == "month_cn") return month_cn (); + if (name == "day_cn") return day_cn (); + if (name == "weekday_cn") return weekday_cn (); + if (name == "fullhour_cn") return fullhour_cn (); + if (name == "halfhour_cn") return halfhour_cn (); + if (name == "ampm_cn") return localtime (&m_time)->tm_hour < 12 ? "上午" : "下午"; + if (name == "minute_cn") return minsec_cn (localtime (&m_time)->tm_min); + if (name == "second_cn") return minsec_cn (localtime (&m_time)->tm_sec); + + return "${" + name + "}"; +} + +}; diff --git a/src/DynamicSpecialPhrase.h b/src/DynamicSpecialPhrase.h new file mode 100644 index 0000000..5ffe49c --- /dev/null +++ b/src/DynamicSpecialPhrase.h @@ -0,0 +1,34 @@ +#ifndef __DYNAMIC_SPECIAL_PHRASE_H_ +#define __DYNAMIC_SPECIAL_PHRASE_H_ + +#include +#include +#include +#include "SpecialPhrase.h" + +namespace PY { + +class DynamicSpecialPhrase : public SpecialPhrase { +public: + DynamicSpecialPhrase (const std::string &text, guint pos) : + SpecialPhrase (pos), m_text (text) { } + + std::string text (void); + const std::string dec (gint d, const gchar *fmt = "%d"); + const std::string year_cn (gboolean yy = FALSE); + const std::string month_cn (void); + const std::string weekday_cn (void); + const std::string hour_cn (guint i); + const std::string fullhour_cn (void); + const std::string halfhour_cn (void); + const std::string day_cn (void); + const std::string minsec_cn (guint i); + const std::string variable (const std::string &name); + +private: + std::string m_text; + time_t m_time; +}; + +}; +#endif diff --git a/src/Makefile.am b/src/Makefile.am index bd3329a..1bdbb29 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -51,7 +51,8 @@ ibus_engine_c_sources = \ PinyinParser.cc \ PinyinProperties.cc \ SimpTradConverter.cc \ - SpecialTable.cc \ + DynamicSpecialPhrase.cc \ + SpecialPhraseTable.cc \ $(NULL) ibus_engine_built_h_sources = \ PinyinParserTable.h \ @@ -86,7 +87,10 @@ ibus_engine_h_sources = \ Property.h \ SimpTradConverter.h \ SimpTradConverterTable.h \ - SpecialTable.h \ + SpecialPhrase.h \ + StaticSpecialPhrase.h \ + DynamicSpecialPhrase.h \ + SpecialPhraseTable.h \ String.h \ Text.h \ Types.h \ diff --git a/src/PinyinEditor.h b/src/PinyinEditor.h index aaa2f8a..1ae3fb0 100644 --- a/src/PinyinEditor.h +++ b/src/PinyinEditor.h @@ -6,13 +6,13 @@ #include "Database.h" #include "PinyinParser.h" #include "PhraseEditor.h" -#include "SpecialTable.h" +#include "SpecialPhraseTable.h" namespace PY { #define MAX_PINYIN_LEN 64 -class SpecialTable; +class SpecialPhraseTable; class PinyinEditor : public Editor { public: @@ -56,7 +56,7 @@ protected: m_special_phrases.clear (); if (begin < end) { - SpecialTable::instance ().lookup ( + SpecialPhraseTable::instance ().lookup ( m_text.substr (begin, m_cursor - begin), m_special_phrases); } diff --git a/src/SpecialTable.cc b/src/SpecialPhrase.cc similarity index 94% rename from src/SpecialTable.cc rename to src/SpecialPhrase.cc index 2cd6be9..125078d 100644 --- a/src/SpecialTable.cc +++ b/src/SpecialPhrase.cc @@ -3,11 +3,11 @@ #include #include #include -#include "SpecialTable.h" +#include "SpecialPhraseTable.h" namespace PY { -SpecialTable SpecialTable::m_instance; +SpecialPhraseTable SpecialPhraseTable::m_instance; class StaticPhrase : public SpecialPhrase { public: @@ -183,7 +183,7 @@ private: }; -SpecialTable::SpecialTable (void) +SpecialPhraseTable::SpecialPhraseTable (void) { gchar * path = g_build_filename (g_get_user_config_dir (), "ibus", "ibus-pinyin", "phrases.txt", NULL); @@ -195,7 +195,7 @@ SpecialTable::SpecialTable (void) } gboolean -SpecialTable::load (const gchar *file) +SpecialPhraseTable::load (const gchar *file) { std::ifstream in (file); if (in.fail ()) @@ -235,8 +235,8 @@ phraseCmp (const SpecialPhrase *first, #endif void -SpecialTable::insert (const std::string &command, - SpecialPhrase *phrase) +SpecialPhraseTable::insert (const std::string &command, + SpecialPhrase *phrase) { if (m_map.find (command) == m_map.end ()) { m_map[command] = List (); @@ -249,8 +249,8 @@ SpecialTable::insert (const std::string &command, } gboolean -SpecialTable::lookup (const std::string &command, - std::vector &result) +SpecialPhraseTable::lookup (const std::string &command, + std::vector &result) { result.clear (); diff --git a/src/SpecialPhrase.h b/src/SpecialPhrase.h new file mode 100644 index 0000000..9126c6d --- /dev/null +++ b/src/SpecialPhrase.h @@ -0,0 +1,24 @@ +#ifndef __PY_SPECIAL_PHRASE_H_ +#define __PY_SPECIAL_PHRASE_H_ + +#include +#include + +namespace PY { + +class SpecialPhrase { +public: + SpecialPhrase (guint pos) : m_position (pos) { } + + guint position (void) const { + return m_position; + } + + virtual std::string text (void) = 0; +private: + guint m_position; +}; + +}; + +#endif diff --git a/src/SpecialPhraseTable.cc b/src/SpecialPhraseTable.cc new file mode 100644 index 0000000..ca4c9b7 --- /dev/null +++ b/src/SpecialPhraseTable.cc @@ -0,0 +1,270 @@ +#include +#include +#include +#include +#include +#include "DynamicSpecialPhrase.h" +#include "SpecialPhraseTable.h" + +namespace PY { + +SpecialPhraseTable SpecialPhraseTable::m_instance; + +class StaticSpecialPhrase : public SpecialPhrase { +public: + StaticSpecialPhrase (const std::string &text, guint pos) : + SpecialPhrase (pos), m_text (text) { } + + std::string text (void) { return m_text; } + +private: + std::string m_text; +}; + +class DynamicPhrase : public SpecialPhrase { +public: + DynamicPhrase (const std::string &text, guint pos) : + SpecialPhrase (pos), m_text (text) { } + + std::string text (void) { + /* get the current time */ + std::time (&m_time); + + std::string result; + + size_t pos = 0; + size_t pnext; + gint s = 0; + while (s != 2) { + switch (s) { + case 0: + pnext = m_text.find ("${", pos); + if (pnext == m_text.npos) { + result += m_text.substr (pos); + s = 2; + } + else { + result += m_text.substr (pos, pnext - pos); + pos = pnext + 2; + s = 1; + } + break; + case 1: + pnext = m_text.find ("}", pos); + if (pnext == m_text.npos) { + result += "${"; + result += m_text.substr (pos); + s = 2; + } + else { + result += variable (m_text.substr(pos, pnext - pos)); + pos = pnext + 1; + s = 0; + } + break; + default: + g_assert_not_reached (); + } + } + return result; + } + + const std::string dec (gint d, const gchar *fmt = "%d") { + char string [32]; + std::snprintf (string, sizeof (string), fmt, d); + return string; + } + + const std::string year_cn (gboolean yy = FALSE) { + static const gchar * digits[] = { + "〇", "一", "二", "三", "四", + "五", "六", "七", "八", "九" + }; + + gint year = localtime (&m_time)->tm_year + 1900; + gint bit = 0; + if (yy) { + year %= 100; + bit = 2; + } + + std::string result; + while (year != 0 || bit > 0) { + result.insert(0, digits[year % 10]); + year /= 10; + bit -= 1; + } + return result; + } + + const std::string month_cn (void) { + static const gchar *month_num[] = { + "一", "二", "三", "四", "五", "六", "七", "八", + "九", "十", "十一", "十二" + }; + return month_num[localtime (&m_time)->tm_mon]; + } + + const std::string weekday_cn (void) { + static const gchar *week_num[] = { + "日", "一", "二", "三", "四", "五", "六" + }; + return week_num[localtime (&m_time)->tm_wday]; + } + + const std::string hour_cn (guint i) { + static const gchar *hour_num[] = { + "零", "一", "二", "三", "四", + "五", "六", "七", "八", "九", + "十", "十一", "十二", "十三", "十四", + "十五", "十六", "十七", "十八", "十九", + "二十", "二十一", "二十二", "二十三", + }; + return hour_num[i]; + } + + const std::string fullhour_cn (void) { + return hour_cn (localtime (&m_time)->tm_hour); + } + + const std::string halfhour_cn (void) { + return hour_cn (localtime (&m_time)->tm_hour % 12); + } + + const std::string day_cn (void) { + static const gchar *day_num[] = { + "", "一", "二", "三", "四", + "五", "六", "七", "八", "九", + "", "十","二十", "三十" + }; + guint day = localtime (&m_time)->tm_mday; + return std::string (day_num[day / 10 + 10]) + day_num[day % 10]; + } + + const std::string minsec_cn (guint i) { + static const gchar *num[] = { + "", "一", "二", "三", "四", + "五", "六", "七", "八", "九", + "零", "十","二十", "三十", "四十" + "五十", "六十" + }; + return std::string (num[i / 10 + 10]) + num[i % 10]; + } + + const std::string variable (const std::string &name) { + if (name == "year") return dec (localtime (&m_time)->tm_year + 1900); + if (name == "year_yy") return dec ((localtime (&m_time)->tm_year + 1900) % 100, "%02d"); + if (name == "month") return dec (localtime (&m_time)->tm_mon + 1); + if (name == "month_mm") return dec (localtime (&m_time)->tm_mon + 1, "%02d"); + if (name == "day") return dec (localtime (&m_time)->tm_mday); + if (name == "day_dd") return dec (localtime (&m_time)->tm_mday, "%02d"); + if (name == "weekday") return dec (localtime (&m_time)->tm_wday + 1); + if (name == "fullhour") return dec (localtime (&m_time)->tm_hour, "%02d"); + if (name == "falfhour") return dec (localtime (&m_time)->tm_hour % 12, "%02d"); + if (name == "ampm") return localtime (&m_time)->tm_hour < 12 ? "AM" : "PM"; + if (name == "minute") return dec (localtime (&m_time)->tm_min, "%02d"); + if (name == "second") return dec (localtime (&m_time)->tm_sec, "%02d"); + if (name == "year_cn") return year_cn (); + if (name == "year_yy_cn") return year_cn (TRUE); + if (name == "month_cn") return month_cn (); + if (name == "day_cn") return day_cn (); + if (name == "weekday_cn") return weekday_cn (); + if (name == "fullhour_cn") return fullhour_cn (); + if (name == "halfhour_cn") return halfhour_cn (); + if (name == "ampm_cn") return localtime (&m_time)->tm_hour < 12 ? "上午" : "下午"; + if (name == "minute_cn") return minsec_cn (localtime (&m_time)->tm_min); + if (name == "second_cn") return minsec_cn (localtime (&m_time)->tm_sec); + + return "${" + name + "}"; + } + +private: + std::string m_text; + time_t m_time; + +}; + +SpecialPhraseTable::SpecialPhraseTable (void) +{ + gchar * path = g_build_filename (g_get_user_config_dir (), + "ibus", "ibus-pinyin", "phrases.txt", NULL); + + load ("phrases.txt") || + load (path) || + load (PKGDATADIR G_DIR_SEPARATOR_S "phrases.txt"); + g_free (path); +} + +gboolean +SpecialPhraseTable::load (const gchar *file) +{ + std::ifstream in (file); + if (in.fail ()) + return FALSE; + + std::string line; + while (!in.eof ()) { + getline (in, line); + if (line.size () == 0 || line[0] == ';') + continue; + size_t pos = line.find ('='); + if (pos == line.npos) + continue; + + std::string command = line.substr(0, pos); + std::string phrase = line.substr(pos + 1); + if (command.empty () || phrase.empty ()) + continue; + + if (phrase[0] != '#') { + insert (command, new StaticSpecialPhrase (phrase, 0)); + } + else if (phrase.size () > 1) { + insert (command, new DynamicPhrase (phrase.substr (1), 0)); + } + } + return TRUE; +} + +#if 0 +static bool +phraseCmp (const SpecialPhrase *first, + const SpecialPhrase *second) +{ + return first->position () <= second->position (); +} +#endif + +void +SpecialPhraseTable::insert (const std::string &command, + SpecialPhrase *phrase) +{ + if (m_map.find (command) == m_map.end ()) { + m_map[command] = List (); + } + List & list = m_map[command]; + list.push_back (phrase); +#if 0 + list.sort (phraseCmp); +#endif +} + +gboolean +SpecialPhraseTable::lookup (const std::string &command, + std::vector &result) +{ + result.clear (); + + if (m_map.find (command) == m_map.end ()) + return FALSE; + + List list = m_map[command]; + for (List::iterator it = list.begin (); it != list.end (); it ++) { + result.push_back ((*it)->text ()); + } + + return result.size () > 0; +} + +}; + diff --git a/src/SpecialTable.h b/src/SpecialPhraseTable.h similarity index 52% rename from src/SpecialTable.h rename to src/SpecialPhraseTable.h index 851d32e..f2da1c5 100644 --- a/src/SpecialTable.h +++ b/src/SpecialPhraseTable.h @@ -1,30 +1,18 @@ -#ifndef __PY_SPECIAL_TABLE_H_ -#define __PY_SPECIAL_TABLE_H_ +#ifndef __PY_SPECIAL_PHRASE_TABLE_H_ +#define __PY_SPECIAL_PHRASE_TABLE_H_ #include #include #include #include #include +#include "SpecialPhrase.h" namespace PY { -class SpecialPhrase { -public: - SpecialPhrase (guint pos) : m_position (pos) { } - - guint position (void) const { - return m_position; - } - - virtual std::string text (void) = 0; -private: - guint m_position; -}; - -class SpecialTable { +class SpecialPhraseTable { private: - SpecialTable (void); + SpecialPhraseTable (void); public: void insert (const std::string & command, SpecialPhrase *phrase); @@ -34,7 +22,7 @@ private: gboolean load (const gchar *file); public: - static SpecialTable & instance (void) { return m_instance; } + static SpecialPhraseTable & instance (void) { return m_instance; } private: typedef std::list List; @@ -42,7 +30,7 @@ private: Map m_map; private: - static SpecialTable m_instance; + static SpecialPhraseTable m_instance; }; }; -- 2.7.4