[aquaskk-changes 277] CVS update: AquaSKK

Tomotaka SUWA t-suw****@users*****
2006年 12月 28日 (木) 14:51:46 JST


Index: AquaSKK/ChangeLog
diff -u AquaSKK/ChangeLog:1.34 AquaSKK/ChangeLog:1.35
--- AquaSKK/ChangeLog:1.34	Mon Dec 18 00:05:41 2006
+++ AquaSKK/ChangeLog	Thu Dec 28 14:51:45 2006
@@ -1,3 +1,13 @@
+2006-12-28  Tomotaka SUWA  <t.suw****@mac*****>
+
+	* DictionarySet.cpp, SKKDictionary.cpp: SKKEntry::CreateOkuri* と
+	SKKEntry::ParseOkuri* の呼び出しを SKKEntry のコンストラクタに修正。
+
+	* Dictionary.h: SKKEntryParser を廃止し、代わりに replace_all 関数
+	テンプレートを追加。std::string の find_* メソッドを使うのをやめ、
+	std::stringstream による解析に方針を変更。SKKOkuriHint のバグ修正。
+	SKKEntry のリファクタリング。
+
 2006-12-17  Tomotaka SUWA  <t.suw****@mac*****>
 
 	* brand-new-engine をマージ。
Index: AquaSKK/Dictionary.h
diff -u AquaSKK/Dictionary.h:1.5 AquaSKK/Dictionary.h:1.6
--- AquaSKK/Dictionary.h:1.5	Mon Dec 18 00:05:41 2006
+++ AquaSKK/Dictionary.h	Thu Dec 28 14:51:45 2006
@@ -1,5 +1,5 @@
 /* -*- C++ -*-
-  $Id: Dictionary.h,v 1.5 2006/12/17 15:05:41 t-suwa Exp $
+  $Id: Dictionary.h,v 1.6 2006/12/28 05:51:45 t-suwa Exp $
 
   MacOS X implementation of the SKK input method.
 
@@ -26,6 +26,7 @@
 
 #include <vector>
 #include <string>
+#include <sstream>
 #include <numeric>
 
 // ======================================================================
@@ -69,7 +70,7 @@
 #pragma mark -- Utility --
 
 // ======================================================================
-// オブジェクトを連結するファンクタ
+// 連結用ファンクタ
 // ======================================================================
 struct ConcatDescription {
     char delimiter_;
@@ -94,42 +95,16 @@
 };
 
 // ======================================================================
-// 部分文字列を返していく単純なパーサ
+// 置換ユーティリティ
 // ======================================================================
-class SKKEntryParser {
-    const std::string& target_;
-    const bool isOkuriAri_;	// 対象が「送りあり」かどうか
-    std::string::size_type pos1_;
-    std::string::size_type pos2_;
-
-    std::string fetch(bool first = false) {
-	if(first) {
-	    pos1_ = pos2_ = 0;
-	}
+template<unsigned char target, unsigned char replacement>
+std::string replace_all(const std::string& str) {
+    std::string tmp(str);
 
-	pos1_ = target_.find_first_not_of('/', pos2_);
-	pos2_ = target_.find_first_of('/', pos1_);
+    std::replace_if(tmp.begin(), tmp.end(), std::bind1st(std::equal_to<unsigned char>(), target), replacement);
 
-	// 見つかった?
-	if(pos1_ != std::string::npos && pos2_ != std::string::npos) {
-	    if(!isOkuriAri_ || target_[pos1_] != '[') {
-		return target_.substr(pos1_, pos2_ - pos1_);
-	    }
-	}
-	return std::string();
-    }
-
-public:
-    SKKEntryParser(const std::string& str, bool isOkuriAri = false) : target_(str), isOkuriAri_(isOkuriAri) {
-	// empty
-    }
-    std::string First() {
-	return fetch(true);
-    }
-    std::string Next() {
-	return fetch();
-    }
-};
+    return tmp;
+}
 
 // ======================================================================
 // 単一の変換候補(/候補;註釈/ → /word_;annotation_/ → Description())
@@ -152,15 +127,15 @@
     SKKCandidate() : word_(std::string()), annotation_(std::string()) {
 	// empty
     }
+    SKKCandidate(const SKKCandidate& src) : word_(src.word_), annotation_(src.annotation_) {
+	// empty
+    }
     SKKCandidate(const std::string& word, const std::string& annotation) : word_(word), annotation_(annotation) {
 	// empty
     }
     SKKCandidate(const std::string& candidate) {
 	setup(candidate);
     }
-    SKKCandidate(const SKKCandidate& src) : word_(src.word_), annotation_(src.annotation_) {
-	// empty
-    }
 
     bool IsEmpty() const {
 	return word_.empty();
@@ -192,16 +167,6 @@
     SKKCandidateContainer candidates_;
     int pos_;
 
-    void setup(const std::string& str) {
-	std::string ret;
-	SKKEntryParser parser(str);
-
-	kana_ = parser.First();
-	for(ret = parser.Next(); !ret.empty(); ret = parser.Next()) {
-	    candidates_.push_back(ret);
-	}
-    }
-
     SKKCandidate fetchCandidate(bool first = false) {
 	if(first) {
 	    pos_ = 0;
@@ -214,18 +179,21 @@
     }
 
 public:
-    SKKOkuriHint() {
-	// empty
+    SKKOkuriHint() {}
+    SKKOkuriHint(const SKKOkuriHint& src) : kana_(src.kana_), candidates_(src.candidates_) {}
+    SKKOkuriHint(const std::string& str) {
+	std::stringstream stream(replace_all<'[', ' '>(replace_all<'/', ' '>(replace_all<']', ' '>(str))));
+
+	if(stream >> kana_) {
+	    std::string tmp;
+	    while(stream >> tmp) {
+		candidates_.push_back(tmp);
+	    }
+	}
     }
     SKKOkuriHint(const std::string& kana, const SKKCandidate& candidate) : kana_(kana) {
 	candidates_.push_back(candidate);
     }
-    SKKOkuriHint(const std::string& str) {
-	setup(str);
-    }
-    SKKOkuriHint(const SKKOkuriHint& src) : kana_(src.kana_), candidates_(src.candidates_) {
-	// empty
-    }
 
     bool IsEmpty() const {
 	return kana_.empty();
@@ -260,11 +228,20 @@
     void Remove(const SKKCandidate& theCandidate) {
 	candidates_.erase(std::remove(candidates_.begin(), candidates_.end(), theCandidate), candidates_.end());
     }
+
     std::string Description() const {
-	return '[' + std::accumulate(candidates_.begin(), candidates_.end(), Kana(), ConcatDescription('/')) + "/]";
+	std::string ret;
+
+	ret = std::accumulate(candidates_.begin(), candidates_.end(), ret, ConcatDescription('/'));
+
+	return ret.empty() ? ret : '[' + Kana() + '/' + ret + ']';
     }
     std::string Word() const {
-	return '[' + std::accumulate(candidates_.begin(), candidates_.end(), Kana(), ConcatWord('/')) + "/]";
+	std::string ret;
+
+	ret = std::accumulate(candidates_.begin(), candidates_.end(), ret, ConcatWord('/'));
+
+	return ret.empty() ? ret : '[' + Kana() + '/' + ret + ']';
     }
 
     bool operator==(const SKKOkuriHint& rhs) const {
@@ -279,7 +256,6 @@
 // SKK 辞書の一行を表現するクラス
 // ======================================================================
 class SKKEntry {
-    bool isOkuriAri_;		// 送りありかどうか
     std::string key_;		// 見出し語
     SKKCandidateContainer candidates_; // 変換候補
     SKKOkuriHintContainer hints_;      // 送りありエントリのヒント情報
@@ -288,38 +264,6 @@
     int cand_pos_;
     int hint_pos_;
 
-    std::string firstHint(const std::string& str) {
-	pos1_ = pos2_ = str.find("/[");
-	return nextHint(str);
-    }
-    std::string nextHint(const std::string& str) {
-	pos1_ = str.find_first_not_of("/[", pos2_ + 1);
-	pos2_ = str.find_first_of(']', pos1_);
-
-	// 見つかった?
-	if(pos1_ != std::string::npos && pos2_ != std::string::npos) {
-	    return str.substr(pos1_, pos2_ - pos1_);
-	}
-	return std::string();
-    }
-
-    void setup(const std::string& str) {
-	std::string ret;
-	SKKEntryParser parser(str, isOkuriAri_);
-
-	// まず通常の候補を抜き出す
-	for(ret = parser.First(); !ret.empty(); ret = parser.Next()) {
-	    candidates_.push_back(ret);
-	}
-
-	if(!isOkuriAri_) return;
-
-	// 次に、送りありエントリのヒント情報を抜き出す
-	for(ret = firstHint(str); !ret.empty(); ret = nextHint(str)) {
-	    hints_.push_back(ret);
-	}
-    }
-
     SKKCandidate fetchCandidate(bool first = false) {
 	if(first) {
 	    cand_pos_ = 0;
@@ -367,7 +311,7 @@
 	// 見つかった?
 	if(i != candidates_.end()) {
 	    target = *i;
-	    Remove(target);
+	    removeCandidate(target);
 	} else {
 	    target = theCandidate;
 	}
@@ -376,37 +320,30 @@
 	candidates_.insert(candidates_.begin(), target);
     }
 
-    SKKEntry() {}
-
-    SKKEntry(bool isOkuriAri, const std::string& key, const std::string& cand) : isOkuriAri_(isOkuriAri), key_(key) {
-	setup(cand);
+    void removeCandidate(const SKKCandidate& theCandidate) {
+	candidates_.erase(std::remove(candidates_.begin(), candidates_.end(), theCandidate), candidates_.end());
     }
 
-    SKKEntry(bool isOkuriAri, const std::string& key) : isOkuriAri_(isOkuriAri), key_(key) {
-	// empry
-    }
+    SKKEntry() {}
 
 public:
-    // 辞書のエントリをパースしてエントリを作成する
-    static SKKEntry ParseOkuriAri(const std::string& key, const std::string& candidate) {
-	return SKKEntry(true, key, candidate);
-    }
-    static SKKEntry ParseOkuriNasi(const std::string& key, const std::string& candidate) {
-	return SKKEntry(false, key, candidate);
-    }
-
-    // キーだけのエントリを作成する
-    static SKKEntry CreateOkuriAri(const std::string& key) {
-	return SKKEntry(true, key);
-    }
-    static SKKEntry CreateOkuriNasi(const std::string& key) {
-	return SKKEntry(false, key);
-    }
+    SKKEntry(const std::string& key) : key_(key) {}
+    SKKEntry(const SKKEntry& src) : key_(src.key_), candidates_(src.candidates_), hints_(src.hints_),
+				    pos1_(src.pos1_), pos2_(src.pos2_) {}
+    SKKEntry(const std::string& key, const std::string& candidate) : key_(key) {
+	std::stringstream stream(replace_all<'[', ' '>(candidate));
+	std::string tmp;
+
+	if(stream >> tmp) {
+	    std::stringstream splitter(replace_all<'/', ' '>(tmp));
+	    while(splitter >> tmp) {
+		candidates_.push_back(tmp);
+	    }
 
-    // コピーコンストラクタ
-    SKKEntry(const SKKEntry& src) : isOkuriAri_(src.isOkuriAri_), key_(src.key_),
-	candidates_(src.candidates_), hints_(src.hints_), pos1_(src.pos1_), pos2_(src.pos2_) {
-	// empty
+	    while(stream >> tmp) {
+		hints_.push_back(tmp);
+	    }
+	}
     }
 
     // 候補に関する操作
@@ -490,7 +427,7 @@
 
     // 候補の削除
     void Remove(const SKKCandidate& theCandidate) {
-	candidates_.erase(std::remove(candidates_.begin(), candidates_.end(), theCandidate), candidates_.end());
+	removeCandidate(theCandidate);
 
 	// ヒントも削除
 	for(SKKOkuriHintIterator i = hints_.begin(); i != hints_.end(); /* empty */) {
Index: AquaSKK/DictionarySet.cpp
diff -u AquaSKK/DictionarySet.cpp:1.6 AquaSKK/DictionarySet.cpp:1.7
--- AquaSKK/DictionarySet.cpp:1.6	Mon Dec 18 00:05:41 2006
+++ AquaSKK/DictionarySet.cpp	Thu Dec 28 14:51:45 2006
@@ -1,5 +1,5 @@
 /*
-  $Id: DictionarySet.cpp,v 1.6 2006/12/17 15:05:41 t-suwa Exp $
+  $Id: DictionarySet.cpp,v 1.7 2006/12/28 05:51:45 t-suwa Exp $
 
   MacOS X implementation of the SKK input method.
 
@@ -194,7 +194,7 @@
 }
 
 std::string DictionarySet::FindOkuriAri(const std::string& key, const std::string& okuri, char result_delimiter) {
-    SKKEntry strict_match = SKKEntry::CreateOkuriAri(key);
+    SKKEntry strict_match(key);
     SKKEntry normal_match = strict_match;
 
     for(DictionaryPrefIterator iter = prefs_.begin(); iter != prefs_.end(); ++ iter) {
@@ -210,7 +210,7 @@
 	}
 
 	// 分解
-	SKKEntry entry = SKKEntry::ParseOkuriAri(key, result);
+	SKKEntry entry(key, result);
 
 	// ヒント情報を使う
 	for(SKKOkuriHint hint = entry.FirstHint(); !hint.IsEmpty(); hint = entry.NextHint()) {
@@ -243,7 +243,7 @@
 }
 
 std::string DictionarySet::FindOkuriNasi(const std::string& key, char result_delimiter) {
-    SKKEntry match = SKKEntry::CreateOkuriNasi(key);
+    SKKEntry match(key);
 
     for(DictionaryPrefIterator iter = prefs_.begin(); iter != prefs_.end(); ++ iter) {
 	// グループ辞書の場合、既に候補が見つかっていれば検索をやめる
@@ -258,7 +258,7 @@
 	}
 
 	// 追加
-	match.Add(SKKEntry::ParseOkuriNasi(key, result));
+	match.Add(SKKEntry(key, result));
     }
 
     return match.Join(result_delimiter);
Index: AquaSKK/Info-AquaSKKInputMethod.plist
diff -u AquaSKK/Info-AquaSKKInputMethod.plist:1.11 AquaSKK/Info-AquaSKKInputMethod.plist:1.12
--- AquaSKK/Info-AquaSKKInputMethod.plist:1.11	Mon Dec 18 00:05:41 2006
+++ AquaSKK/Info-AquaSKKInputMethod.plist	Thu Dec 28 14:51:45 2006
@@ -19,11 +19,11 @@
 	<key>CFBundlePackageType</key>
 	<string>thng</string>
 	<key>CFBundleShortVersionString</key>
-	<string>3.2</string>
+	<string>3.3 RC1</string>
 	<key>CFBundleSignature</key>
 	<string>askk</string>
 	<key>CFBundleVersion</key>
-	<string>2006-12-23</string>
+	<string>2006-12-28</string>
 	<key>CSResourcesFileMapped</key>
 	<true/>
 	<key>tsInputMethodIconFileKey</key>
Index: AquaSKK/Info-AquaSKKServer.plist
diff -u AquaSKK/Info-AquaSKKServer.plist:1.11 AquaSKK/Info-AquaSKKServer.plist:1.12
--- AquaSKK/Info-AquaSKKServer.plist:1.11	Mon Dec 18 00:05:41 2006
+++ AquaSKK/Info-AquaSKKServer.plist	Thu Dec 28 14:51:45 2006
@@ -19,11 +19,11 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>3.2</string>
+	<string>3.3 RC1</string>
 	<key>CFBundleSignature</key>
 	<string>askk</string>
 	<key>CFBundleVersion</key>
-	<string>2006-12-23</string>
+	<string>2006-12-28</string>
 	<key>NSMainNibFile</key>
 	<string>Principal</string>
 	<key>NSPrincipalClass</key>
Index: AquaSKK/SKKDictionary.cpp
diff -u AquaSKK/SKKDictionary.cpp:1.13 AquaSKK/SKKDictionary.cpp:1.14
--- AquaSKK/SKKDictionary.cpp:1.13	Mon Dec 18 00:05:41 2006
+++ AquaSKK/SKKDictionary.cpp	Thu Dec 28 14:51:45 2006
@@ -1,5 +1,5 @@
 /*
-  $Id: SKKDictionary.cpp,v 1.13 2006/12/17 15:05:41 t-suwa Exp $
+  $Id: SKKDictionary.cpp,v 1.14 2006/12/28 05:51:45 t-suwa Exp $
 
   MacOS X implementation of the SKK input method.
 
@@ -456,12 +456,12 @@
 }
 
 void SKKUserDictionary::registerOkuriAri(const std::string& index, const std::string& okuri, const std::string& kanji) {
-    SKKEntry entry = SKKEntry::CreateOkuriAri(index);
+    SKKEntry entry(index);
     EntryIterator i = std::find_if(okuriAri_.begin(), okuriAri_.end(), skkdic::UserEntryCompare(index));
 
     // 見つかった?
     if(i != okuriAri_.end()) {
-	entry = SKKEntry::ParseOkuriAri(i->first, i->second);
+	entry = SKKEntry(i->first, i->second);
 	okuriAri_.erase(std::remove(okuriAri_.begin(), okuriAri_.end(), *i), okuriAri_.end());
     }
 
@@ -473,12 +473,12 @@
 }
 
 void SKKUserDictionary::registerOkuriNasi(const std::string& index, const std::string& kanji) {
-    SKKEntry entry = SKKEntry::CreateOkuriNasi(index);
+    SKKEntry entry(index);
     EntryIterator i = std::find_if(okuriNasi_.begin(), okuriNasi_.end(), skkdic::UserEntryCompare(index));
 
     // 見つかった?
     if(i != okuriNasi_.end()) {
-	entry = SKKEntry::ParseOkuriNasi(i->first, i->second);
+	entry = SKKEntry(i->first, i->second);
 	okuriNasi_.erase(std::remove(okuriNasi_.begin(), okuriNasi_.end(), *i), okuriNasi_.end());
     }
 
@@ -497,7 +497,7 @@
 	return;
     }
 
-    SKKEntry entry = SKKEntry::ParseOkuriAri(i->first, i->second);
+    SKKEntry entry(i->first, i->second);
     entry.Remove(SKKCandidate(kanji));
 
     // まだ候補が残っている?
@@ -521,7 +521,7 @@
 	return;
     }
 
-    SKKEntry entry = SKKEntry::ParseOkuriNasi(i->first, i->second);
+    SKKEntry entry(i->first, i->second);
     entry.Remove(SKKCandidate(kanji));
 
     // まだ候補が残っている?


aquaskk-changes メーリングリストの案内