OSDN Git Service

Commit DialogBox compile Okay
authorFrank Li <lznuaa@gmail.com>
Mon, 10 Nov 2008 03:06:27 +0000 (11:06 +0800)
committerFrank Li <lznuaa@gmail.com>
Mon, 10 Nov 2008 03:06:27 +0000 (11:06 +0800)
224 files changed:
Git/Git.vcproj
Git/GitStatusListCtrl.cpp [new file with mode: 0644]
Git/GitStatusListCtrl.h [new file with mode: 0644]
Resources/TortoiseProcENG.rc
TortoiseProc/AppUtils.h
TortoiseProc/Commands/Command.cpp
TortoiseProc/Commands/CommitCommand.cpp
TortoiseProc/CommitDlg.cpp
TortoiseProc/CommitDlg.h
TortoiseProc/ProjectProperties.cpp
TortoiseProc/ProjectProperties.h
TortoiseProc/SVNProgressDlg.h
TortoiseProc/TortoiseProc.vcproj
TortoiseProc/TortoiseProc.vcproj.FSL.B20596.user
TortoiseProc/resource.h
TortoiseShell/TortoiseShell.sln [new file with mode: 0644]
TortoiseShell/TortoiseShell.suo [new file with mode: 0644]
Utils/BugTraqAssociations.h
Utils/MiscUI/SciEdit.cpp
Utils/MiscUI/SciEdit.h
Utils/Utils.vcproj
ext/hunspell/README [new file with mode: 0644]
ext/hunspell/affentry.cxx [new file with mode: 0644]
ext/hunspell/affentry.hxx [new file with mode: 0644]
ext/hunspell/affixmgr.cxx [new file with mode: 0644]
ext/hunspell/affixmgr.hxx [new file with mode: 0644]
ext/hunspell/atypes.hxx [new file with mode: 0644]
ext/hunspell/baseaffix.hxx [new file with mode: 0644]
ext/hunspell/csutil.cxx [new file with mode: 0644]
ext/hunspell/csutil.hxx [new file with mode: 0644]
ext/hunspell/dictmgr.cxx [new file with mode: 0644]
ext/hunspell/dictmgr.hxx [new file with mode: 0644]
ext/hunspell/hashmgr.cxx [new file with mode: 0644]
ext/hunspell/hashmgr.hxx [new file with mode: 0644]
ext/hunspell/htypes.hxx [new file with mode: 0644]
ext/hunspell/hunspell.cxx [new file with mode: 0644]
ext/hunspell/hunspell.h [new file with mode: 0644]
ext/hunspell/hunspell.hxx [new file with mode: 0644]
ext/hunspell/hunspell.vcproj [new file with mode: 0644]
ext/hunspell/langnum.hxx [new file with mode: 0644]
ext/hunspell/mythes.cxx [new file with mode: 0644]
ext/hunspell/mythes.hxx [new file with mode: 0644]
ext/hunspell/suggestmgr.cxx [new file with mode: 0644]
ext/hunspell/suggestmgr.hxx [new file with mode: 0644]
ext/hunspell/utf_info.cxx [new file with mode: 0644]
ext/scintilla/License.txt [new file with mode: 0644]
ext/scintilla/README [new file with mode: 0644]
ext/scintilla/backgroundcolors.patch [new file with mode: 0644]
ext/scintilla/delbin.bat [new file with mode: 0644]
ext/scintilla/delcvs.bat [new file with mode: 0644]
ext/scintilla/doc/Design.html [new file with mode: 0644]
ext/scintilla/doc/Icons.html [new file with mode: 0644]
ext/scintilla/doc/Lexer.txt [new file with mode: 0644]
ext/scintilla/doc/SciBreak.jpg [new file with mode: 0644]
ext/scintilla/doc/SciCoding.html [new file with mode: 0644]
ext/scintilla/doc/SciRest.jpg [new file with mode: 0644]
ext/scintilla/doc/SciTEIco.png [new file with mode: 0644]
ext/scintilla/doc/SciWord.jpg [new file with mode: 0644]
ext/scintilla/doc/ScintillaDoc.html [new file with mode: 0644]
ext/scintilla/doc/ScintillaDownload.html [new file with mode: 0644]
ext/scintilla/doc/ScintillaHistory.html [new file with mode: 0644]
ext/scintilla/doc/ScintillaRelated.html [new file with mode: 0644]
ext/scintilla/doc/ScintillaToDo.html [new file with mode: 0644]
ext/scintilla/doc/ScintillaUsage.html [new file with mode: 0644]
ext/scintilla/doc/Steps.html [new file with mode: 0644]
ext/scintilla/doc/index.html [new file with mode: 0644]
ext/scintilla/gtk/Converter.h [new file with mode: 0644]
ext/scintilla/gtk/PlatGTK.cxx [new file with mode: 0644]
ext/scintilla/gtk/ScintillaGTK.cxx [new file with mode: 0644]
ext/scintilla/gtk/deps.mak [new file with mode: 0644]
ext/scintilla/gtk/makefile [new file with mode: 0644]
ext/scintilla/gtk/scintilla-marshal.c [new file with mode: 0644]
ext/scintilla/gtk/scintilla-marshal.h [new file with mode: 0644]
ext/scintilla/gtk/scintilla-marshal.list [new file with mode: 0644]
ext/scintilla/gtk/scintilla.mak [new file with mode: 0644]
ext/scintilla/include/Accessor.h [new file with mode: 0644]
ext/scintilla/include/Face.py [new file with mode: 0644]
ext/scintilla/include/HFacer.py [new file with mode: 0644]
ext/scintilla/include/KeyWords.h [new file with mode: 0644]
ext/scintilla/include/Platform.h [new file with mode: 0644]
ext/scintilla/include/PropSet.h [new file with mode: 0644]
ext/scintilla/include/SString.h [new file with mode: 0644]
ext/scintilla/include/SciLexer.h [new file with mode: 0644]
ext/scintilla/include/Scintilla.h [new file with mode: 0644]
ext/scintilla/include/Scintilla.iface [new file with mode: 0644]
ext/scintilla/include/ScintillaWidget.h [new file with mode: 0644]
ext/scintilla/include/WindowAccessor.h [new file with mode: 0644]
ext/scintilla/src/AutoComplete.cxx [new file with mode: 0644]
ext/scintilla/src/AutoComplete.h [new file with mode: 0644]
ext/scintilla/src/CallTip.cxx [new file with mode: 0644]
ext/scintilla/src/CallTip.h [new file with mode: 0644]
ext/scintilla/src/CellBuffer.cxx [new file with mode: 0644]
ext/scintilla/src/CellBuffer.h [new file with mode: 0644]
ext/scintilla/src/CharClassify.cxx [new file with mode: 0644]
ext/scintilla/src/CharClassify.h [new file with mode: 0644]
ext/scintilla/src/CharacterSet.h [new file with mode: 0644]
ext/scintilla/src/ContractionState.cxx [new file with mode: 0644]
ext/scintilla/src/ContractionState.h [new file with mode: 0644]
ext/scintilla/src/Decoration.cxx [new file with mode: 0644]
ext/scintilla/src/Decoration.h [new file with mode: 0644]
ext/scintilla/src/Document.cxx [new file with mode: 0644]
ext/scintilla/src/Document.h [new file with mode: 0644]
ext/scintilla/src/DocumentAccessor.cxx [new file with mode: 0644]
ext/scintilla/src/DocumentAccessor.h [new file with mode: 0644]
ext/scintilla/src/Editor.cxx [new file with mode: 0644]
ext/scintilla/src/Editor.h [new file with mode: 0644]
ext/scintilla/src/ExternalLexer.cxx [new file with mode: 0644]
ext/scintilla/src/ExternalLexer.h [new file with mode: 0644]
ext/scintilla/src/Indicator.cxx [new file with mode: 0644]
ext/scintilla/src/Indicator.h [new file with mode: 0644]
ext/scintilla/src/KeyMap.cxx [new file with mode: 0644]
ext/scintilla/src/KeyMap.h [new file with mode: 0644]
ext/scintilla/src/KeyWords.cxx [new file with mode: 0644]
ext/scintilla/src/LexAPDL.cxx [new file with mode: 0644]
ext/scintilla/src/LexASY.cxx [new file with mode: 0644]
ext/scintilla/src/LexAU3.cxx [new file with mode: 0644]
ext/scintilla/src/LexAVE.cxx [new file with mode: 0644]
ext/scintilla/src/LexAbaqus.cxx [new file with mode: 0644]
ext/scintilla/src/LexAda.cxx [new file with mode: 0644]
ext/scintilla/src/LexAsm.cxx [new file with mode: 0644]
ext/scintilla/src/LexAsn1.cxx [new file with mode: 0644]
ext/scintilla/src/LexBaan.cxx [new file with mode: 0644]
ext/scintilla/src/LexBash.cxx [new file with mode: 0644]
ext/scintilla/src/LexBasic.cxx [new file with mode: 0644]
ext/scintilla/src/LexBullant.cxx [new file with mode: 0644]
ext/scintilla/src/LexCLW.cxx [new file with mode: 0644]
ext/scintilla/src/LexCPP.cxx [new file with mode: 0644]
ext/scintilla/src/LexCSS.cxx [new file with mode: 0644]
ext/scintilla/src/LexCaml.cxx [new file with mode: 0644]
ext/scintilla/src/LexCmake.cxx [new file with mode: 0644]
ext/scintilla/src/LexConf.cxx [new file with mode: 0644]
ext/scintilla/src/LexCrontab.cxx [new file with mode: 0644]
ext/scintilla/src/LexCsound.cxx [new file with mode: 0644]
ext/scintilla/src/LexD.cxx [new file with mode: 0644]
ext/scintilla/src/LexEScript.cxx [new file with mode: 0644]
ext/scintilla/src/LexEiffel.cxx [new file with mode: 0644]
ext/scintilla/src/LexErlang.cxx [new file with mode: 0644]
ext/scintilla/src/LexFlagship.cxx [new file with mode: 0644]
ext/scintilla/src/LexForth.cxx [new file with mode: 0644]
ext/scintilla/src/LexFortran.cxx [new file with mode: 0644]
ext/scintilla/src/LexGAP.cxx [new file with mode: 0644]
ext/scintilla/src/LexGen.py [new file with mode: 0644]
ext/scintilla/src/LexGui4Cli.cxx [new file with mode: 0644]
ext/scintilla/src/LexHTML.cxx [new file with mode: 0644]
ext/scintilla/src/LexHaskell.cxx [new file with mode: 0644]
ext/scintilla/src/LexInno.cxx [new file with mode: 0644]
ext/scintilla/src/LexKix.cxx [new file with mode: 0644]
ext/scintilla/src/LexLisp.cxx [new file with mode: 0644]
ext/scintilla/src/LexLout.cxx [new file with mode: 0644]
ext/scintilla/src/LexLua.cxx [new file with mode: 0644]
ext/scintilla/src/LexMMIXAL.cxx [new file with mode: 0644]
ext/scintilla/src/LexMPT.cxx [new file with mode: 0644]
ext/scintilla/src/LexMSSQL.cxx [new file with mode: 0644]
ext/scintilla/src/LexMagik.cxx [new file with mode: 0644]
ext/scintilla/src/LexMatlab.cxx [new file with mode: 0644]
ext/scintilla/src/LexMetapost.cxx [new file with mode: 0644]
ext/scintilla/src/LexMySQL.cxx [new file with mode: 0644]
ext/scintilla/src/LexNsis.cxx [new file with mode: 0644]
ext/scintilla/src/LexOpal.cxx [new file with mode: 0644]
ext/scintilla/src/LexOthers.cxx [new file with mode: 0644]
ext/scintilla/src/LexPB.cxx [new file with mode: 0644]
ext/scintilla/src/LexPLM.cxx [new file with mode: 0644]
ext/scintilla/src/LexPOV.cxx [new file with mode: 0644]
ext/scintilla/src/LexPS.cxx [new file with mode: 0644]
ext/scintilla/src/LexPascal.cxx [new file with mode: 0644]
ext/scintilla/src/LexPerl.cxx [new file with mode: 0644]
ext/scintilla/src/LexPowerShell.cxx [new file with mode: 0644]
ext/scintilla/src/LexProgress.cxx [new file with mode: 0644]
ext/scintilla/src/LexPython.cxx [new file with mode: 0644]
ext/scintilla/src/LexR.cxx [new file with mode: 0644]
ext/scintilla/src/LexRebol.cxx [new file with mode: 0644]
ext/scintilla/src/LexRuby.cxx [new file with mode: 0644]
ext/scintilla/src/LexSQL.cxx [new file with mode: 0644]
ext/scintilla/src/LexScriptol.cxx [new file with mode: 0644]
ext/scintilla/src/LexSmalltalk.cxx [new file with mode: 0644]
ext/scintilla/src/LexSpecman.cxx [new file with mode: 0644]
ext/scintilla/src/LexSpice.cxx [new file with mode: 0644]
ext/scintilla/src/LexTADS3.cxx [new file with mode: 0644]
ext/scintilla/src/LexTCL.cxx [new file with mode: 0644]
ext/scintilla/src/LexTeX.cxx [new file with mode: 0644]
ext/scintilla/src/LexVB.cxx [new file with mode: 0644]
ext/scintilla/src/LexVHDL.cxx [new file with mode: 0644]
ext/scintilla/src/LexVerilog.cxx [new file with mode: 0644]
ext/scintilla/src/LexYAML.cxx [new file with mode: 0644]
ext/scintilla/src/LineMarker.cxx [new file with mode: 0644]
ext/scintilla/src/LineMarker.h [new file with mode: 0644]
ext/scintilla/src/Partitioning.h [new file with mode: 0644]
ext/scintilla/src/PositionCache.cxx [new file with mode: 0644]
ext/scintilla/src/PositionCache.h [new file with mode: 0644]
ext/scintilla/src/PropSet.cxx [new file with mode: 0644]
ext/scintilla/src/RESearch.cxx [new file with mode: 0644]
ext/scintilla/src/RESearch.h [new file with mode: 0644]
ext/scintilla/src/RunStyles.cxx [new file with mode: 0644]
ext/scintilla/src/RunStyles.h [new file with mode: 0644]
ext/scintilla/src/SVector.h [new file with mode: 0644]
ext/scintilla/src/SciTE.properties [new file with mode: 0644]
ext/scintilla/src/ScintillaBase.cxx [new file with mode: 0644]
ext/scintilla/src/ScintillaBase.h [new file with mode: 0644]
ext/scintilla/src/SplitVector.h [new file with mode: 0644]
ext/scintilla/src/Style.cxx [new file with mode: 0644]
ext/scintilla/src/Style.h [new file with mode: 0644]
ext/scintilla/src/StyleContext.cxx [new file with mode: 0644]
ext/scintilla/src/StyleContext.h [new file with mode: 0644]
ext/scintilla/src/UniConversion.cxx [new file with mode: 0644]
ext/scintilla/src/UniConversion.h [new file with mode: 0644]
ext/scintilla/src/ViewStyle.cxx [new file with mode: 0644]
ext/scintilla/src/ViewStyle.h [new file with mode: 0644]
ext/scintilla/src/WindowAccessor.cxx [new file with mode: 0644]
ext/scintilla/src/XPM.cxx [new file with mode: 0644]
ext/scintilla/src/XPM.h [new file with mode: 0644]
ext/scintilla/vcbuild/SciLexer.vcproj [new file with mode: 0644]
ext/scintilla/version.txt [new file with mode: 0644]
ext/scintilla/win32/Margin.cur [new file with mode: 0644]
ext/scintilla/win32/PlatWin.cxx [new file with mode: 0644]
ext/scintilla/win32/PlatformRes.h [new file with mode: 0644]
ext/scintilla/win32/SciTE.properties [new file with mode: 0644]
ext/scintilla/win32/ScintRes.rc [new file with mode: 0644]
ext/scintilla/win32/Scintilla.def [new file with mode: 0644]
ext/scintilla/win32/ScintillaWin.cxx [new file with mode: 0644]
ext/scintilla/win32/deps.mak [new file with mode: 0644]
ext/scintilla/win32/makefile [new file with mode: 0644]
ext/scintilla/win32/scintilla.mak [new file with mode: 0644]
ext/scintilla/win32/scintilla_vc6.mak [new file with mode: 0644]
ext/scintilla/zipsrc.bat [new file with mode: 0644]

index bcc0170..03df4c2 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\GitStatusListCtrl.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\stdafx.cpp"\r
                                >\r
                                <FileConfiguration\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\GitStatusListCtrl.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\stdafx.h"\r
                                >\r
                        </File>\r
diff --git a/Git/GitStatusListCtrl.cpp b/Git/GitStatusListCtrl.cpp
new file mode 100644 (file)
index 0000000..e184a63
--- /dev/null
@@ -0,0 +1,10 @@
+#include "StdAfx.h"\r
+#include "GitStatusListCtrl.h"\r
+\r
+CGitStatusListCtrl::CGitStatusListCtrl(void)\r
+{\r
+}\r
+\r
+CGitStatusListCtrl::~CGitStatusListCtrl(void)\r
+{\r
+}\r
diff --git a/Git/GitStatusListCtrl.h b/Git/GitStatusListCtrl.h
new file mode 100644 (file)
index 0000000..6addb94
--- /dev/null
@@ -0,0 +1,9 @@
+#pragma once\r
+\r
+class CGitStatusListCtrl :\r
+       public CListCtrl\r
+{\r
+public:\r
+       CGitStatusListCtrl(void);\r
+       ~CGitStatusListCtrl(void);\r
+};\r
index 2e041bd..cca218e 100644 (file)
Binary files a/Resources/TortoiseProcENG.rc and b/Resources/TortoiseProcENG.rc differ
index 62ab4b6..8c91e14 100644 (file)
@@ -18,7 +18,7 @@
 //\r
 #pragma once\r
 #include "HistoryCombo.h"\r
-//#include "SVNRev.h"\r
+#include "GitRev.h"\r
 \r
 class CTGitPath;\r
 \r
index 8481955..5ccb7c5 100644 (file)
 #include "Command.h"\r
 \r
 #include "AboutCommand.h"\r
+#include "CommitCommand.h"\r
 #if 0\r
 #include "AddCommand.h"\r
 #include "BlameCommand.h"\r
 #include "CatCommand.h"\r
 #include "CheckoutCommand.h"\r
 #include "CleanupCommand.h"\r
-#include "CommitCommand.h"\r
+\r
 #include "ConflictEditorCommand.h"\r
 #include "CopyCommand.h"\r
 #include "CrashCommand.h"\r
@@ -201,7 +202,9 @@ Command * CommandServer::GetCommand(const CString& sCmd)
        switch (command)\r
        {\r
        case cmdAbout:\r
-               return new AboutCommand;\r
+               return new AboutCommand;        \r
+       case cmdCommit:\r
+               return new CommitCommand;\r
 #if 0\r
        case cmdAdd:\r
                return new AddCommand;\r
@@ -213,8 +216,7 @@ Command * CommandServer::GetCommand(const CString& sCmd)
                return new CheckoutCommand;\r
        case cmdCleanup:\r
                return new CleanupCommand;\r
-       case cmdCommit:\r
-               return new CommitCommand;\r
+\r
        case cmdConflictEditor:\r
                return new ConflictEditorCommand;\r
        case cmdCopy:\r
index db4a263..80c7ece 100644 (file)
@@ -20,7 +20,7 @@
 #include "CommitCommand.h"\r
 \r
 #include "CommitDlg.h"\r
-#include "SVNProgressDlg.h"\r
+//#include "SVNProgressDlg.h"\r
 #include "StringUtils.h"\r
 #include "Hooks.h"\r
 #include "MessageBox.h"\r
@@ -44,26 +44,28 @@ bool CommitCommand::Execute()
 {\r
        bool bRet = false;\r
        bool bFailed = true;\r
-       CTSVNPathList selectedList;\r
+       CTGitPathList selectedList;\r
        if (parser.HasKey(_T("logmsg")) && (parser.HasKey(_T("logmsgfile"))))\r
        {\r
                CMessageBox::Show(hwndExplorer, IDS_ERR_TWOLOGPARAMS, IDS_APPNAME, MB_ICONERROR);\r
                return false;\r
        }\r
        CString sLogMsg = LoadLogMessage();\r
-       bool bSelectFilesForCommit = !!DWORD(CRegStdWORD(_T("Software\\TortoiseSVN\\SelectFilesForCommit"), TRUE));\r
+       bool bSelectFilesForCommit = !!DWORD(CRegStdWORD(_T("Software\\TortoiseGit\\SelectFilesForCommit"), TRUE));\r
        DWORD exitcode = 0;\r
        CString error;\r
+#if 0\r
        if (CHooks::Instance().StartCommit(pathList, sLogMsg, exitcode, error))\r
        {\r
                if (exitcode)\r
                {\r
                        CString temp;\r
                        temp.Format(IDS_ERR_HOOKFAILED, (LPCTSTR)error);\r
-                       CMessageBox::Show(hwndExplorer, temp, _T("TortoiseSVN"), MB_ICONERROR);\r
+                       CMessageBox::Show(hwndExplorer, temp, _T("TortoiseGit"), MB_ICONERROR);\r
                        return false;\r
                }\r
        }\r
+#endif\r
        while (bFailed)\r
        {\r
                bFailed = false;\r
@@ -92,26 +94,26 @@ bool CommitCommand::Execute()
                        pathList = dlg.m_updatedPathList;\r
                        sLogMsg = dlg.m_sLogMessage;\r
                        bSelectFilesForCommit = true;\r
-                       CSVNProgressDlg progDlg;\r
-                       progDlg.SetChangeList(dlg.m_sChangeList, !!dlg.m_bKeepChangeList);\r
-                       if (parser.HasVal(_T("closeonend")))\r
-                               progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend")));\r
-                       progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Commit);\r
-                       progDlg.SetOptions(dlg.m_bKeepLocks ? ProgOptKeeplocks : ProgOptNone);\r
-                       progDlg.SetPathList(dlg.m_pathList);\r
-                       progDlg.SetCommitMessage(dlg.m_sLogMessage);\r
-                       progDlg.SetDepth(dlg.m_bRecursive ? svn_depth_infinity : svn_depth_empty);\r
-                       progDlg.SetSelectedList(dlg.m_selectedPathList);\r
-                       progDlg.SetItemCount(dlg.m_itemsCount);\r
-                       progDlg.SetBugTraqProvider(dlg.m_BugTraqProvider);\r
-                       progDlg.DoModal();\r
-                       CRegDWORD err = CRegDWORD(_T("Software\\TortoiseSVN\\ErrorOccurred"), FALSE);\r
-                       err = (DWORD)progDlg.DidErrorsOccur();\r
-                       bFailed = progDlg.DidErrorsOccur();\r
-                       bRet = progDlg.DidErrorsOccur();\r
-                       CRegDWORD bFailRepeat = CRegDWORD(_T("Software\\TortoiseSVN\\CommitReopen"), FALSE);\r
-                       if (DWORD(bFailRepeat)==0)\r
-                               bFailed = false;                // do not repeat if the user chose not to in the settings.\r
+//                     CGitProgressDlg progDlg;\r
+//                     progDlg.SetChangeList(dlg.m_sChangeList, !!dlg.m_bKeepChangeList);\r
+//                     if (parser.HasVal(_T("closeonend")))\r
+//                             progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend")));\r
+//                     progDlg.SetCommand(CGitProgressDlg::GitProgress_Commit);\r
+//                     progDlg.SetOptions(dlg.m_bKeepLocks ? ProgOptKeeplocks : ProgOptNone);\r
+//                     progDlg.SetPathList(dlg.m_pathList);\r
+//                     progDlg.SetCommitMessage(dlg.m_sLogMessage);\r
+//                     progDlg.SetDepth(dlg.m_bRecursive ? Git_depth_infinity : svn_depth_empty);\r
+//                     progDlg.SetSelectedList(dlg.m_selectedPathList);\r
+//                     progDlg.SetItemCount(dlg.m_itemsCount);\r
+//                     progDlg.SetBugTraqProvider(dlg.m_BugTraqProvider);\r
+//                     progDlg.DoModal();\r
+//                     CRegDWORD err = CRegDWORD(_T("Software\\TortoiseSVN\\ErrorOccurred"), FALSE);\r
+//                     err = (DWORD)progDlg.DidErrorsOccur();\r
+//                     bFailed = progDlg.DidErrorsOccur();\r
+//                     bRet = progDlg.DidErrorsOccur();\r
+//                     CRegDWORD bFailRepeat = CRegDWORD(_T("Software\\TortoiseSVN\\CommitReopen"), FALSE);\r
+//                     if (DWORD(bFailRepeat)==0)\r
+//                             bFailed = false;                // do not repeat if the user chose not to in the settings.\r
                }\r
        }\r
        return bRet;\r
index 42807fb..40e37fa 100644 (file)
@@ -1,6 +1,6 @@
-// TortoiseSVN - a Windows shell extension for easy version control\r
+// TortoiseGit - a Windows shell extension for easy version control\r
 \r
-// Copyright (C) 2003-2008 - TortoiseSVN\r
+// Copyright (C) 2003-2008 - TortoiseGit\r
 \r
 // This program is free software; you can redistribute it and/or\r
 // modify it under the terms of the GNU General Public License\r
 #include "TortoiseProc.h"\r
 #include "CommitDlg.h"\r
 #include "DirFileEnum.h"\r
-#include "SVNConfig.h"\r
-#include "SVNProperties.h"\r
+//#include "GitConfig.h"\r
+//#include "GitProperties.h"\r
 #include "MessageBox.h"\r
 #include "AppUtils.h"\r
 #include "PathUtils.h"\r
-#include "SVN.h"\r
+//#include "Git.h"\r
 #include "Registry.h"\r
-#include "SVNStatus.h"\r
+#include "GitStatus.h"\r
 #include "HistoryDlg.h"\r
 #include "Hooks.h"\r
 \r
@@ -37,7 +37,7 @@
 static char THIS_FILE[] = __FILE__;\r
 #endif\r
 \r
-UINT CCommitDlg::WM_AUTOLISTREADY = RegisterWindowMessage(_T("TORTOISESVN_AUTOLISTREADY_MSG"));\r
+UINT CCommitDlg::WM_AUTOLISTREADY = RegisterWindowMessage(_T("TORTOISEGIT_AUTOLISTREADY_MSG"));\r
 \r
 IMPLEMENT_DYNAMIC(CCommitDlg, CResizableStandAloneDialog)\r
 CCommitDlg::CCommitDlg(CWnd* pParent /*=NULL*/)\r
@@ -80,13 +80,13 @@ BEGIN_MESSAGE_MAP(CCommitDlg, CResizableStandAloneDialog)
        ON_BN_CLICKED(IDC_SELECTALL, OnBnClickedSelectall)\r
        ON_BN_CLICKED(IDHELP, OnBnClickedHelp)\r
        ON_BN_CLICKED(IDC_SHOWUNVERSIONED, OnBnClickedShowunversioned)\r
-       ON_BN_CLICKED(IDC_HISTORY, OnBnClickedHistory)\r
+//     ON_BN_CLICKED(IDC_HISTORY, OnBnClickedHistory)\r
        ON_BN_CLICKED(IDC_BUGTRAQBUTTON, OnBnClickedBugtraqbutton)\r
        ON_EN_CHANGE(IDC_LOGMESSAGE, OnEnChangeLogmessage)\r
-       ON_REGISTERED_MESSAGE(CSVNStatusListCtrl::SVNSLNM_ITEMCOUNTCHANGED, OnSVNStatusListCtrlItemCountChanged)\r
-       ON_REGISTERED_MESSAGE(CSVNStatusListCtrl::SVNSLNM_NEEDSREFRESH, OnSVNStatusListCtrlNeedsRefresh)\r
-       ON_REGISTERED_MESSAGE(CSVNStatusListCtrl::SVNSLNM_ADDFILE, OnFileDropped)\r
-       ON_REGISTERED_MESSAGE(CSVNStatusListCtrl::SVNSLNM_CHECKCHANGED, &CCommitDlg::OnSVNStatusListCtrlCheckChanged)\r
+//     ON_REGISTERED_MESSAGE(CGitStatusListCtrl::SVNSLNM_ITEMCOUNTCHANGED, OnGitStatusListCtrlItemCountChanged)\r
+//     ON_REGISTERED_MESSAGE(CGitStatusListCtrl::SVNSLNM_NEEDSREFRESH, OnGitStatusListCtrlNeedsRefresh)\r
+//     ON_REGISTERED_MESSAGE(CGitStatusListCtrl::SVNSLNM_ADDFILE, OnFileDropped)\r
+//     ON_REGISTERED_MESSAGE(CGitStatusListCtrl::SVNSLNM_CHECKCHANGED, &CCommitDlg::OnGitStatusListCtrlCheckChanged)\r
        ON_REGISTERED_MESSAGE(WM_AUTOLISTREADY, OnAutoListReady) \r
        ON_WM_TIMER()\r
     ON_WM_SIZE()\r
@@ -97,40 +97,41 @@ BOOL CCommitDlg::OnInitDialog()
 {\r
        CResizableStandAloneDialog::OnInitDialog();\r
        \r
-       m_regAddBeforeCommit = CRegDWORD(_T("Software\\TortoiseSVN\\AddBeforeCommit"), TRUE);\r
+       m_regAddBeforeCommit = CRegDWORD(_T("Software\\TortoiseGit\\AddBeforeCommit"), TRUE);\r
        m_bShowUnversioned = m_regAddBeforeCommit;\r
 \r
-       m_History.SetMaxHistoryItems((LONG)CRegDWORD(_T("Software\\TortoiseSVN\\MaxHistoryItems"), 25));\r
+       m_History.SetMaxHistoryItems((LONG)CRegDWORD(_T("Software\\TortoiseGit\\MaxHistoryItems"), 25));\r
 \r
-       m_regKeepChangelists = CRegDWORD(_T("Software\\TortoiseSVN\\KeepChangeLists"), FALSE);\r
+       m_regKeepChangelists = CRegDWORD(_T("Software\\TortoiseGit\\KeepChangeLists"), FALSE);\r
        m_bKeepChangeList = m_regKeepChangelists;\r
 \r
-       SVNConfig config;\r
-       m_bKeepLocks = config.KeepLocks();\r
+//     GitConfig config;\r
+//     m_bKeepLocks = config.KeepLocks();\r
 \r
        UpdateData(FALSE);\r
        \r
-       m_ListCtrl.Init(SVNSLC_COLEXT | SVNSLC_COLTEXTSTATUS | SVNSLC_COLPROPSTATUS | SVNSLC_COLLOCK, _T("CommitDlg"));\r
-       m_ListCtrl.SetSelectButton(&m_SelectAll);\r
-       m_ListCtrl.SetStatLabel(GetDlgItem(IDC_STATISTICS));\r
-       m_ListCtrl.SetCancelBool(&m_bCancelled);\r
-       m_ListCtrl.SetEmptyString(IDS_COMMITDLG_NOTHINGTOCOMMIT);\r
-       m_ListCtrl.EnableFileDrop();\r
-       m_ListCtrl.SetBackgroundImage(IDI_COMMIT_BKG);\r
+//     m_ListCtrl.Init(GitSLC_COLEXT | GitSLC_COLTEXTSTATUS | GitSLC_COLPROPSTATUS | GitSLC_COLLOCK, _T("CommitDlg"));\r
+//     m_ListCtrl.SetSelectButton(&m_SelectAll);\r
+//     m_ListCtrl.SetStatLabel(GetDlgItem(IDC_STATISTICS));\r
+//     m_ListCtrl.SetCancelBool(&m_bCancelled);\r
+//     m_ListCtrl.SetEmptyString(IDS_COMMITDLG_NOTHINGTOCOMMIT);\r
+//     m_ListCtrl.EnableFileDrop();\r
+//     m_ListCtrl.SetBackgroundImage(IDI_COMMIT_BKG);\r
        \r
-       m_ProjectProperties.ReadPropsPathList(m_pathList);\r
+//     m_ProjectProperties.ReadPropsPathList(m_pathList);\r
        m_cLogMessage.Init(m_ProjectProperties);\r
-       m_cLogMessage.SetFont((CString)CRegString(_T("Software\\TortoiseSVN\\LogFontName"), _T("Courier New")), (DWORD)CRegDWORD(_T("Software\\TortoiseSVN\\LogFontSize"), 8));\r
+       m_cLogMessage.SetFont((CString)CRegString(_T("Software\\TortoiseGit\\LogFontName"), _T("Courier New")), (DWORD)CRegDWORD(_T("Software\\TortoiseGit\\LogFontSize"), 8));\r
        m_cLogMessage.RegisterContextMenuHandler(this);\r
 \r
        OnEnChangeLogmessage();\r
 \r
        m_tooltips.Create(this);\r
        m_tooltips.AddTool(IDC_EXTERNALWARNING, IDS_COMMITDLG_EXTERNALS);\r
-       m_tooltips.AddTool(IDC_HISTORY, IDS_COMMITDLG_HISTORY_TT);\r
+//     m_tooltips.AddTool(IDC_HISTORY, IDS_COMMITDLG_HISTORY_TT);\r
        \r
        m_SelectAll.SetCheck(BST_INDETERMINATE);\r
-       \r
+\r
+#if 0\r
        CBugTraqAssociations bugtraq_associations;\r
        bugtraq_associations.Load();\r
 \r
@@ -180,7 +181,7 @@ BOOL CCommitDlg::OnInitDialog()
                GetDlgItem(IDC_BUGTRAQBUTTON)->EnableWindow(FALSE);\r
                GetDlgItem(IDC_LOGMESSAGE)->SetFocus();\r
        }\r
-\r
+#endif\r
        if (!m_sLogMessage.IsEmpty())\r
                m_cLogMessage.SetText(m_sLogMessage);\r
                \r
@@ -199,7 +200,7 @@ BOOL CCommitDlg::OnInitDialog()
        AddAnchor(IDC_BUGTRAQBUTTON, TOP_RIGHT);\r
        AddAnchor(IDC_COMMIT_TO, TOP_LEFT, TOP_RIGHT);\r
        AddAnchor(IDC_MESSAGEGROUP, TOP_LEFT, TOP_RIGHT);\r
-       AddAnchor(IDC_HISTORY, TOP_LEFT);\r
+//     AddAnchor(IDC_HISTORY, TOP_LEFT);\r
        AddAnchor(IDC_LOGMESSAGE, TOP_LEFT, TOP_RIGHT);\r
        \r
        AddAnchor(IDC_LISTGROUP, TOP_LEFT, BOTTOM_RIGHT);\r
@@ -217,7 +218,7 @@ BOOL CCommitDlg::OnInitDialog()
        if (hWndExplorer)\r
                CenterWindow(CWnd::FromHandle(hWndExplorer));\r
        EnableSaveRestore(_T("CommitDlg"));\r
-       DWORD yPos = CRegDWORD(_T("Software\\TortoiseSVN\\TortoiseProc\\ResizableState\\CommitDlgSizer"));\r
+       DWORD yPos = CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\ResizableState\\CommitDlgSizer"));\r
        RECT rcDlg, rcLogMsg, rcFileList;\r
        GetClientRect(&rcDlg);\r
        m_cLogMessage.GetWindowRect(&rcLogMsg);\r
@@ -260,12 +261,12 @@ BOOL CCommitDlg::OnInitDialog()
                m_pThread->m_bAutoDelete = FALSE;\r
                m_pThread->ResumeThread();\r
        }\r
-       CRegDWORD err = CRegDWORD(_T("Software\\TortoiseSVN\\ErrorOccurred"), FALSE);\r
-       CRegDWORD historyhint = CRegDWORD(_T("Software\\TortoiseSVN\\HistoryHintShown"), FALSE);\r
+       CRegDWORD err = CRegDWORD(_T("Software\\TortoiseGit\\ErrorOccurred"), FALSE);\r
+       CRegDWORD historyhint = CRegDWORD(_T("Software\\TortoiseGit\\HistoryHintShown"), FALSE);\r
        if ((((DWORD)err)!=FALSE)&&((((DWORD)historyhint)==FALSE)))\r
        {\r
                historyhint = TRUE;\r
-               ShowBalloon(IDC_HISTORY, IDS_COMMITDLG_HISTORYHINT_TT, IDI_INFORMATION);\r
+//             ShowBalloon(IDC_HISTORY, IDS_COMMITDLG_HISTORYHINT_TT, IDI_INFORMATION);\r
        }\r
        err = FALSE;\r
 \r
@@ -305,7 +306,8 @@ void CCommitDlg::OnOK()
                        return;\r
        }\r
 \r
-       CRegDWORD regUnversionedRecurse (_T("Software\\TortoiseSVN\\UnversionedRecurse"), TRUE);\r
+#if 0\r
+       CRegDWORD regUnversionedRecurse (_T("Software\\TortoiseGit\\UnversionedRecurse"), TRUE);\r
        if (!(DWORD)regUnversionedRecurse)\r
        {\r
                // Find unversioned directories which are marked for commit. The user might expect them\r
@@ -314,15 +316,15 @@ void CCommitDlg::OnOK()
                int nListItems = m_ListCtrl.GetItemCount();\r
                for (int j=0; j<nListItems; j++)\r
                {\r
-                       const CSVNStatusListCtrl::FileEntry * entry = m_ListCtrl.GetListEntry(j);\r
-                       if (entry->IsChecked() && (entry->status == svn_wc_status_unversioned) && entry->IsFolder() )\r
+                       const CGitStatusListCtrl::FileEntry * entry = m_ListCtrl.GetListEntry(j);\r
+                       if (entry->IsChecked() && (entry->status == Git_wc_status_unversioned) && entry->IsFolder() )\r
                        {\r
                                if (CMessageBox::Show(this->m_hWnd, IDS_COMMITDLG_UNVERSIONEDFOLDERWARNING, IDS_APPNAME, MB_YESNO | MB_ICONWARNING)!=IDYES)\r
                                        return;\r
                        }\r
                }\r
        }\r
-\r
+#endif\r
        m_pathwatcher.Stop();\r
        InterlockedExchange(&m_bBlock, TRUE);\r
        CDWordArray arDeleted;\r
@@ -332,30 +334,31 @@ void CCommitDlg::OnOK()
        m_bRecursive = true;\r
        int nListItems = m_ListCtrl.GetItemCount();\r
 \r
-       CTSVNPathList itemsToAdd;\r
-       CTSVNPathList itemsToRemove;\r
+       CTGitPathList itemsToAdd;\r
+       CTGitPathList itemsToRemove;\r
        bool bCheckedInExternal = false;\r
        bool bHasConflicted = false;\r
        std::set<CString> checkedLists;\r
        std::set<CString> uncheckedLists;\r
+#if 0\r
        for (int j=0; j<nListItems; j++)\r
        {\r
-               const CSVNStatusListCtrl::FileEntry * entry = m_ListCtrl.GetListEntry(j);\r
+               const CGitStatusListCtrl::FileEntry * entry = m_ListCtrl.GetListEntry(j);\r
                if (entry->IsChecked())\r
                {\r
-                       if (entry->status == svn_wc_status_unversioned)\r
+                       if (entry->status == Git_wc_status_unversioned)\r
                        {\r
                                itemsToAdd.AddPath(entry->GetPath());\r
                        }\r
-                       if (entry->status == svn_wc_status_conflicted)\r
+                       if (entry->status == Git_wc_status_conflicted)\r
                        {\r
                                bHasConflicted = true;\r
                        }\r
-                       if (entry->status == svn_wc_status_missing)\r
+                       if (entry->status == Git_wc_status_missing)\r
                        {\r
                                itemsToRemove.AddPath(entry->GetPath());\r
                        }\r
-                       if (entry->status == svn_wc_status_deleted)\r
+                       if (entry->status == Git_wc_status_deleted)\r
                        {\r
                                arDeleted.Add(j);\r
                        }\r
@@ -367,17 +370,17 @@ void CCommitDlg::OnOK()
                }\r
                else\r
                {\r
-                       if ((entry->status != svn_wc_status_unversioned)        &&\r
-                               (entry->status != svn_wc_status_ignored))\r
+                       if ((entry->status != Git_wc_status_unversioned)        &&\r
+                               (entry->status != Git_wc_status_ignored))\r
                        {\r
                                nUnchecked++;\r
                                uncheckedLists.insert(entry->GetChangeList());\r
                                if (m_bRecursive)\r
                                {\r
-                                       // This algorithm is for the sake of simplicity of the complexity O(N²)\r
+                                       // This algorithm is for the sake of simplicity of the complexity O(N?\r
                                        for (int k=0; k<nListItems; k++)\r
                                        {\r
-                                               const CSVNStatusListCtrl::FileEntry * entryK = m_ListCtrl.GetListEntry(k);\r
+                                               const CGitStatusListCtrl::FileEntry * entryK = m_ListCtrl.GetListEntry(k);\r
                                                if (entryK->IsChecked() && entryK->GetPath().IsAncestorOf(entry->GetPath())  )\r
                                                {\r
                                                        // Fall back to a non-recursive commit to prevent items being\r
@@ -391,12 +394,15 @@ void CCommitDlg::OnOK()
                        }\r
                }\r
        }\r
+#endif\r
+\r
+#if 0\r
        if (m_pathwatcher.GetNumberOfChangedPaths() && m_bRecursive)\r
        {\r
                // There are paths which got changed (touched at least).\r
                // We have to find out if this affects the selection in the commit dialog\r
                // If it could affect the selection, revert back to a non-recursive commit\r
-               CTSVNPathList changedList = m_pathwatcher.GetChangedPaths();\r
+               CTGitPathList changedList = m_pathwatcher.GetChangedPaths();\r
                changedList.RemoveDuplicates();\r
                for (int i=0; i<changedList.GetCount(); ++i)\r
                {\r
@@ -415,7 +421,7 @@ void CCommitDlg::OnOK()
                        else if (!m_ListCtrl.IsPathShown(changedList[i]))\r
                        {\r
                                // a path which is not shown in the list has changed\r
-                               CSVNStatusListCtrl::FileEntry * entry = m_ListCtrl.GetListEntry(changedList[i]);\r
+                               CGitStatusListCtrl::FileEntry * entry = m_ListCtrl.GetListEntry(changedList[i]);\r
                                if (entry)\r
                                {\r
                                        // check if the changed path would get committed by a recursive commit\r
@@ -436,10 +442,10 @@ void CCommitDlg::OnOK()
        // Now, do all the adds - make sure that the list is sorted so that parents \r
        // are added before their children\r
        itemsToAdd.SortByPathname();\r
-       SVN svn;\r
-       if (!svn.Add(itemsToAdd, &m_ProjectProperties, svn_depth_empty, FALSE, FALSE, TRUE))\r
+       Git Git;\r
+       if (!Git.Add(itemsToAdd, &m_ProjectProperties, Git_depth_empty, FALSE, FALSE, TRUE))\r
        {\r
-               CMessageBox::Show(m_hWnd, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
+               CMessageBox::Show(m_hWnd, Git.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
                InterlockedExchange(&m_bBlock, FALSE);\r
                Refresh();\r
                return;\r
@@ -448,7 +454,7 @@ void CCommitDlg::OnOK()
        // Remove any missing items\r
        // Not sure that this sort is really necessary - indeed, it might be better to do a reverse sort at this point\r
        itemsToRemove.SortByPathname();\r
-       svn.Remove(itemsToRemove, TRUE);\r
+       Git.Remove(itemsToRemove, TRUE);\r
 \r
        //the next step: find all deleted files and check if they're \r
        //inside a deleted folder. If that's the case, then remove those\r
@@ -460,7 +466,7 @@ void CCommitDlg::OnOK()
        {\r
                if (m_ListCtrl.GetCheck(arDeleted.GetAt(i)))\r
                {\r
-                       const CTSVNPath& path = m_ListCtrl.GetListEntry(arDeleted.GetAt(i))->GetPath();\r
+                       const CTGitPath& path = m_ListCtrl.GetListEntry(arDeleted.GetAt(i))->GetPath();\r
                        if (path.IsDirectory())\r
                        {\r
                                //now find all children of this directory\r
@@ -468,7 +474,7 @@ void CCommitDlg::OnOK()
                                {\r
                                        if (i!=j)\r
                                        {\r
-                                               CSVNStatusListCtrl::FileEntry* childEntry = m_ListCtrl.GetListEntry(arDeleted.GetAt(j));\r
+                                               CGitStatusListCtrl::FileEntry* childEntry = m_ListCtrl.GetListEntry(arDeleted.GetAt(j));\r
                                                if (childEntry->IsChecked())\r
                                                {\r
                                                        if (path.IsAncestorOf(childEntry->GetPath()))\r
@@ -502,6 +508,7 @@ void CCommitDlg::OnOK()
                if (uncheckedLists.find(*checkedLists.begin()) == uncheckedLists.end())\r
                        m_sChangeList = *checkedLists.begin();\r
        }\r
+#endif\r
        UpdateData();\r
        m_regAddBeforeCommit = m_bShowUnversioned;\r
        if (!GetDlgItem(IDC_KEEPLOCK)->IsWindowEnabled())\r
@@ -534,7 +541,7 @@ void CCommitDlg::SaveSplitterPos()
 {\r
        if (!IsIconic())\r
        {\r
-               CRegDWORD regPos = CRegDWORD(_T("Software\\TortoiseSVN\\TortoiseProc\\ResizableState\\CommitDlgSizer"));\r
+               CRegDWORD regPos = CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\ResizableState\\CommitDlgSizer"));\r
                RECT rectSplitter;\r
                m_wndSplitter.GetWindowRect(&rectSplitter);\r
                ScreenToClient(&rectSplitter);\r
@@ -565,16 +572,17 @@ UINT CCommitDlg::StatusThread()
 \r
     // read the list of recent log entries before querying the WC for status\r
     // -> the user may select one and modify / update it while we are crawling the WC\r
+#if 0\r
        if (m_History.GetCount()==0)\r
        {\r
                CString reg;\r
                if (m_ListCtrl.m_sUUID.IsEmpty() && m_pathList.GetCount()>0)\r
                {\r
-                       SVN svn;\r
-                       reg.Format(_T("Software\\TortoiseSVN\\History\\commit%s"), (LPCTSTR)svn.GetUUIDFromPath(m_pathList[0]));\r
+                       Git Git;\r
+                       reg.Format(_T("Software\\TortoiseGit\\History\\commit%s"), (LPCTSTR)Git.GetUUIDFromPath(m_pathList[0]));\r
                }\r
                else\r
-                       reg.Format(_T("Software\\TortoiseSVN\\History\\commit%s"), (LPCTSTR)m_ListCtrl.m_sUUID);\r
+                       reg.Format(_T("Software\\TortoiseGit\\History\\commit%s"), (LPCTSTR)m_ListCtrl.m_sUUID);\r
                m_History.Load(reg, _T("logmsgs"));\r
        }\r
 \r
@@ -582,15 +590,15 @@ UINT CCommitDlg::StatusThread()
        BOOL success = m_ListCtrl.GetStatus(m_pathList);\r
        m_ListCtrl.CheckIfChangelistsArePresent(false);\r
 \r
-       DWORD dwShow = SVNSLC_SHOWVERSIONEDBUTNORMALANDEXTERNALSFROMDIFFERENTREPOS | SVNSLC_SHOWLOCKS | SVNSLC_SHOWINCHANGELIST;\r
-       dwShow |= DWORD(m_regAddBeforeCommit) ? SVNSLC_SHOWUNVERSIONED : 0;\r
+       DWORD dwShow = GitSLC_SHOWVERSIONEDBUTNORMALANDEXTERNALSFROMDIFFERENTREPOS | GitSLC_SHOWLOCKS | GitSLC_SHOWINCHANGELIST;\r
+       dwShow |= DWORD(m_regAddBeforeCommit) ? GitSLC_SHOWUNVERSIONED : 0;\r
        if (success)\r
        {\r
                if (m_checkedPathList.GetCount())\r
                        m_ListCtrl.Show(dwShow, m_checkedPathList);\r
                else\r
                {\r
-                       DWORD dwCheck = m_bSelectFilesForCommit ? SVNSLC_SHOWDIRECTS|SVNSLC_SHOWMODIFIED|SVNSLC_SHOWADDED|SVNSLC_SHOWREMOVED|SVNSLC_SHOWREPLACED|SVNSLC_SHOWMERGED|SVNSLC_SHOWLOCKS : 0;\r
+                       DWORD dwCheck = m_bSelectFilesForCommit ? GitSLC_SHOWDIRECTS|GitSLC_SHOWMODIFIED|GitSLC_SHOWADDED|GitSLC_SHOWREMOVED|GitSLC_SHOWREPLACED|GitSLC_SHOWMERGED|GitSLC_SHOWLOCKS : 0;\r
                        m_ListCtrl.Show(dwShow, dwCheck);\r
                        m_bSelectFilesForCommit = true;\r
                }\r
@@ -618,12 +626,12 @@ UINT CCommitDlg::StatusThread()
                {\r
                        m_bShowUnversioned = TRUE;\r
                        GetDlgItem(IDC_SHOWUNVERSIONED)->SendMessage(BM_SETCHECK, BST_CHECKED);\r
-                       DWORD dwShow = SVNSLC_SHOWVERSIONEDBUTNORMALANDEXTERNALSFROMDIFFERENTREPOS | SVNSLC_SHOWUNVERSIONED | SVNSLC_SHOWLOCKS;\r
+                       DWORD dwShow = GitSLC_SHOWVERSIONEDBUTNORMALANDEXTERNALSFROMDIFFERENTREPOS | GitSLC_SHOWUNVERSIONED | GitSLC_SHOWLOCKS;\r
                        m_ListCtrl.Show(dwShow);\r
                }\r
        }\r
 \r
-       CTSVNPath commonDir = m_ListCtrl.GetCommonDirectory(false);\r
+       CTGitPath commonDir = m_ListCtrl.GetCommonDirectory(false);\r
        SetWindowText(m_sWindowTitle + _T(" - ") + commonDir.GetWinPathString());\r
 \r
        m_autolist.clear();\r
@@ -631,7 +639,7 @@ UINT CCommitDlg::StatusThread()
        // auto completion list.\r
        m_pathwatcher.ClearChangedPaths();\r
        InterlockedExchange(&m_bBlock, FALSE);\r
-       if ((DWORD)CRegDWORD(_T("Software\\TortoiseSVN\\Autocompletion"), TRUE)==TRUE)\r
+       if ((DWORD)CRegDWORD(_T("Software\\TortoiseGit\\Autocompletion"), TRUE)==TRUE)\r
        {\r
                m_ListCtrl.Block(TRUE, TRUE);\r
                GetAutocompletionList();\r
@@ -652,6 +660,7 @@ UINT CCommitDlg::StatusThread()
        InterlockedExchange(&m_bThreadRunning, FALSE);\r
        // force the cursor to normal\r
        RefreshCursor();\r
+#endif\r
        return 0;\r
 }\r
 \r
@@ -705,7 +714,7 @@ void CCommitDlg::OnBnClickedSelectall()
                state = BST_UNCHECKED;\r
                m_SelectAll.SetCheck(state);\r
        }\r
-       m_ListCtrl.SelectAll(state == BST_CHECKED);\r
+//     m_ListCtrl.SelectAll(state == BST_CHECKED);\r
 }\r
 \r
 BOOL CCommitDlg::PreTranslateMessage(MSG* pMsg)\r
@@ -774,6 +783,7 @@ void CCommitDlg::OnBnClickedHelp()
 \r
 void CCommitDlg::OnBnClickedShowunversioned()\r
 {\r
+#if 0\r
        m_tooltips.Pop();       // hide the tooltips\r
        UpdateData();\r
        m_regAddBeforeCommit = m_bShowUnversioned;\r
@@ -781,11 +791,12 @@ void CCommitDlg::OnBnClickedShowunversioned()
        {\r
                DWORD dwShow = m_ListCtrl.GetShowFlags();\r
                if (DWORD(m_regAddBeforeCommit))\r
-                       dwShow |= SVNSLC_SHOWUNVERSIONED;\r
+                       dwShow |= GitSLC_SHOWUNVERSIONED;\r
                else\r
-                       dwShow &= ~SVNSLC_SHOWUNVERSIONED;\r
+                       dwShow &= ~GitSLC_SHOWUNVERSIONED;\r
                m_ListCtrl.Show(dwShow);\r
        }\r
+#endif\r
 }\r
 \r
 void CCommitDlg::OnStnClickedExternalwarning()\r
@@ -798,22 +809,24 @@ void CCommitDlg::OnEnChangeLogmessage()
        UpdateOKButton();\r
 }\r
 \r
-LRESULT CCommitDlg::OnSVNStatusListCtrlItemCountChanged(WPARAM, LPARAM)\r
+LRESULT CCommitDlg::OnGitStatusListCtrlItemCountChanged(WPARAM, LPARAM)\r
 {\r
+#if 0\r
        if ((m_ListCtrl.GetItemCount() == 0)&&(m_ListCtrl.HasUnversionedItems())&&(!m_bShowUnversioned))\r
        {\r
                if (CMessageBox::Show(*this, IDS_COMMITDLG_NOTHINGTOCOMMITUNVERSIONED, IDS_APPNAME, MB_ICONINFORMATION | MB_YESNO)==IDYES)\r
                {\r
                        m_bShowUnversioned = TRUE;\r
-                       DWORD dwShow = SVNSLC_SHOWVERSIONEDBUTNORMALANDEXTERNALSFROMDIFFERENTREPOS | SVNSLC_SHOWUNVERSIONED | SVNSLC_SHOWLOCKS;\r
+                       DWORD dwShow = GitSLC_SHOWVERSIONEDBUTNORMALANDEXTERNALSFROMDIFFERENTREPOS | GitSLC_SHOWUNVERSIONED | GitSLC_SHOWLOCKS;\r
                        m_ListCtrl.Show(dwShow);\r
                        UpdateData(FALSE);\r
                }\r
        }\r
+#endif\r
        return 0;\r
 }\r
 \r
-LRESULT CCommitDlg::OnSVNStatusListCtrlNeedsRefresh(WPARAM, LPARAM)\r
+LRESULT CCommitDlg::OnGitStatusListCtrlNeedsRefresh(WPARAM, LPARAM)\r
 {\r
        Refresh();\r
        return 0;\r
@@ -821,6 +834,7 @@ LRESULT CCommitDlg::OnSVNStatusListCtrlNeedsRefresh(WPARAM, LPARAM)
 \r
 LRESULT CCommitDlg::OnFileDropped(WPARAM, LPARAM lParam)\r
 {\r
+#if 0\r
        BringWindowToTop();\r
        SetForegroundWindow();\r
        SetActiveWindow();\r
@@ -833,14 +847,14 @@ LRESULT CCommitDlg::OnFileDropped(WPARAM, LPARAM lParam)
        // When the timer expires, we start the refresh thread,\r
        // but only if it isn't already running - otherwise we\r
        // restart the timer.\r
-       CTSVNPath path;\r
+       CTGitPath path;\r
        path.SetFromWin((LPCTSTR)lParam);\r
 \r
        // just add all the items we get here.\r
        // if the item is versioned, the add will fail but nothing\r
        // more will happen.\r
-       SVN svn;\r
-       svn.Add(CTSVNPathList(path), &m_ProjectProperties, svn_depth_empty, false, true, true);\r
+       Git Git;\r
+       Git.Add(CTGitPathList(path), &m_ProjectProperties, Git_depth_empty, false, true, true);\r
 \r
        if (!m_ListCtrl.HasPath(path))\r
        {\r
@@ -879,6 +893,7 @@ LRESULT CCommitDlg::OnFileDropped(WPARAM, LPARAM lParam)
        // Always start the timer, since the status of an existing item might have changed\r
        SetTimer(REFRESHTIMER, 200, NULL);\r
        ATLTRACE(_T("Item %s dropped, timer started\n"), path.GetWinPath());\r
+#endif\r
        return 0;\r
 }\r
 \r
@@ -934,7 +949,7 @@ void CCommitDlg::GetAutocompletionList()
        \r
        std::map<CString, CString> mapRegex;\r
        CString sRegexFile = CPathUtils::GetAppDirectory();\r
-       CRegDWORD regtimeout = CRegDWORD(_T("Software\\TortoiseSVN\\AutocompleteParseTimeout"), 5);\r
+       CRegDWORD regtimeout = CRegDWORD(_T("Software\\TortoiseGit\\AutocompleteParseTimeout"), 5);\r
        DWORD timeoutvalue = regtimeout*1000;\r
        sRegexFile += _T("autolist.txt");\r
        if (!m_bRunThread)\r
@@ -942,7 +957,7 @@ void CCommitDlg::GetAutocompletionList()
        ParseRegexFile(sRegexFile, mapRegex);\r
        SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, sRegexFile.GetBuffer(MAX_PATH+1));\r
        sRegexFile.ReleaseBuffer();\r
-       sRegexFile += _T("\\TortoiseSVN\\autolist.txt");\r
+       sRegexFile += _T("\\TortoiseGit\\autolist.txt");\r
        if (PathFileExists(sRegexFile))\r
        {\r
                ParseRegexFile(sRegexFile, mapRegex);\r
@@ -962,14 +977,16 @@ void CCommitDlg::GetAutocompletionList()
                // stop parsing after timeout\r
                if ((!m_bRunThread) || (GetTickCount() - starttime > timeoutvalue))\r
                        return;\r
-               const CSVNStatusListCtrl::FileEntry * entry = m_ListCtrl.GetListEntry(i);\r
-               if (!entry)\r
-                       continue;\r
+\r
+//             const CGitStatusListCtrl::FileEntry * entry = m_ListCtrl.GetListEntry(i);\r
+//             if (!entry)\r
+//                     continue;\r
                \r
                // add the path parts to the auto completion list too\r
-               CString sPartPath = entry->GetRelativeSVNPath();\r
-               m_autolist.insert(sPartPath);\r
+//             CString sPartPath = entry->GetRelativeGitPath();\r
+//             m_autolist.insert(sPartPath);\r
 \r
+#if 0\r
                int pos = 0;\r
                int lastPos = 0;\r
                while ((pos = sPartPath.Find('/', pos)) >= 0)\r
@@ -981,14 +998,14 @@ void CCommitDlg::GetAutocompletionList()
 \r
                // Last inserted entry is a file name.\r
                // Some users prefer to also list file name without extension.\r
-               if (CRegDWORD(_T("Software\\TortoiseSVN\\AutocompleteRemovesExtensions"), FALSE))\r
+               if (CRegDWORD(_T("Software\\TortoiseGit\\AutocompleteRemovesExtensions"), FALSE))\r
                {\r
                        int dotPos = sPartPath.ReverseFind('.');\r
                        if ((dotPos >= 0) && (dotPos > lastPos))\r
                                m_autolist.insert(sPartPath.Mid(lastPos, dotPos - lastPos));\r
                }\r
 \r
-               if ((entry->status <= svn_wc_status_normal)||(entry->status == svn_wc_status_ignored))\r
+               if ((entry->status <= Git_wc_status_normal)||(entry->status == Git_wc_status_ignored))\r
                        continue;\r
 \r
                CString sExt = entry->GetPath().GetFileExtension();\r
@@ -999,16 +1016,17 @@ void CCommitDlg::GetAutocompletionList()
                        continue;\r
 \r
                ScanFile(entry->GetPath().GetWinPathString(), rdata);\r
-               if ((entry->textstatus != svn_wc_status_unversioned) &&\r
-                       (entry->textstatus != svn_wc_status_none) &&\r
-                       (entry->textstatus != svn_wc_status_ignored) &&\r
-                       (entry->textstatus != svn_wc_status_added) &&\r
-                       (entry->textstatus != svn_wc_status_normal))\r
+               if ((entry->textstatus != Git_wc_status_unversioned) &&\r
+                       (entry->textstatus != Git_wc_status_none) &&\r
+                       (entry->textstatus != Git_wc_status_ignored) &&\r
+                       (entry->textstatus != Git_wc_status_added) &&\r
+                       (entry->textstatus != Git_wc_status_normal))\r
                {\r
-                       CTSVNPath basePath = SVN::GetPristinePath(entry->GetPath());\r
+                       CTGitPath basePath = Git::GetPristinePath(entry->GetPath());\r
                        if (!basePath.IsEmpty())\r
                                ScanFile(basePath.GetWinPathString(), rdata);\r
                }\r
+#endif\r
        }\r
        ATLTRACE(_T("Auto completion list loaded in %d msec\n"), GetTickCount() - starttime);\r
 }\r
@@ -1089,6 +1107,7 @@ void CCommitDlg::InsertMenuItems(CMenu& mPopup, int& nCmd)
 \r
 bool CCommitDlg::HandleMenuItemClick(int cmd, CSciEdit * pSciEdit)\r
 {\r
+#if 0\r
        if (m_bBlock)\r
                return false;\r
        if (cmd == m_nPopupPasteListCmd)\r
@@ -1098,19 +1117,19 @@ bool CCommitDlg::HandleMenuItemClick(int cmd, CSciEdit * pSciEdit)
                int nListItems = m_ListCtrl.GetItemCount();\r
                for (int i=0; i<nListItems; ++i)\r
                {\r
-                       CSVNStatusListCtrl::FileEntry * entry = m_ListCtrl.GetListEntry(i);\r
+                       CGitStatusListCtrl::FileEntry * entry = m_ListCtrl.GetListEntry(i);\r
                        if (entry->IsChecked())\r
                        {\r
                                CString line;\r
-                               svn_wc_status_kind status = entry->status;\r
-                               if (status == svn_wc_status_unversioned)\r
-                                       status = svn_wc_status_added;\r
-                               if (status == svn_wc_status_missing)\r
-                                       status = svn_wc_status_deleted;\r
-                               WORD langID = (WORD)CRegStdWORD(_T("Software\\TortoiseSVN\\LanguageID"), GetUserDefaultLangID());\r
+                               Git_wc_status_kind status = entry->status;\r
+                               if (status == Git_wc_status_unversioned)\r
+                                       status = Git_wc_status_added;\r
+                               if (status == Git_wc_status_missing)\r
+                                       status = Git_wc_status_deleted;\r
+                               WORD langID = (WORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), GetUserDefaultLangID());\r
                                if (m_ProjectProperties.bFileListInEnglish)\r
                                        langID = 1033;\r
-                               SVNStatus::GetStatusString(AfxGetResourceHandle(), status, buf, sizeof(buf)/sizeof(TCHAR), langID);\r
+                               GitStatus::GetStatusString(AfxGetResourceHandle(), status, buf, sizeof(buf)/sizeof(TCHAR), langID);\r
                                line.Format(_T("%-10s %s\r\n"), buf, (LPCTSTR)m_ListCtrl.GetItemText(i,0));\r
                                logmsg += line;\r
                        }\r
@@ -1118,6 +1137,7 @@ bool CCommitDlg::HandleMenuItemClick(int cmd, CSciEdit * pSciEdit)
                pSciEdit->InsertText(logmsg);\r
                return true;\r
        }\r
+#endif\r
        return false;\r
 }\r
 \r
@@ -1151,6 +1171,7 @@ void CCommitDlg::OnBnClickedHistory()
        m_tooltips.Pop();       // hide the tooltips\r
        if (m_pathList.GetCount() == 0)\r
                return;\r
+#if 0\r
        CHistoryDlg historyDlg;\r
        historyDlg.SetHistory(m_History);\r
        if (historyDlg.DoModal() != IDOK)\r
@@ -1172,10 +1193,12 @@ void CCommitDlg::OnBnClickedHistory()
 \r
        UpdateOKButton();\r
        GetDlgItem(IDC_LOGMESSAGE)->SetFocus();\r
+#endif\r
 }\r
 \r
 void CCommitDlg::OnBnClickedBugtraqbutton()\r
 {\r
+#if 0\r
        m_tooltips.Pop();       // hide the tooltips\r
        CString sMsg = m_cLogMessage.GetText();\r
 \r
@@ -1187,7 +1210,7 @@ void CCommitDlg::OnBnClickedBugtraqbutton()
        SAFEARRAY *pathList = SafeArrayCreateVector(VT_BSTR, 0, m_pathList.GetCount());\r
 \r
        for (LONG index = 0; index < m_pathList.GetCount(); ++index)\r
-               SafeArrayPutElement(pathList, &index, m_pathList[index].GetSVNPathString().AllocSysString());\r
+               SafeArrayPutElement(pathList, &index, m_pathList[index].GetGitPathString().AllocSysString());\r
 \r
        BSTR originalMessage = sMsg.AllocSysString();\r
        BSTR temp = NULL;\r
@@ -1197,13 +1220,13 @@ void CCommitDlg::OnBnClickedBugtraqbutton()
        HRESULT hr = m_BugTraqProvider.QueryInterface(&pProvider2);\r
        if (SUCCEEDED(hr))\r
        {\r
-               CString common = m_ListCtrl.GetCommonURL(false).GetSVNPathString();\r
+               CString common = m_ListCtrl.GetCommonURL(false).GetGitPathString();\r
                BSTR repositoryRoot = common.AllocSysString();\r
                if (FAILED(hr = pProvider2->GetCommitMessage2(GetSafeHwnd(), parameters, repositoryRoot, commonRoot, pathList, originalMessage, &temp)))\r
                {\r
                        CString sErr;\r
                        sErr.Format(IDS_ERR_FAILEDISSUETRACKERCOM, m_bugtraq_association.GetProviderName(), _com_error(hr).ErrorMessage());\r
-                       CMessageBox::Show(m_hWnd, sErr, _T("TortoiseSVN"), MB_ICONERROR);\r
+                       CMessageBox::Show(m_hWnd, sErr, _T("TortoiseGit"), MB_ICONERROR);\r
                }\r
                else\r
                        m_cLogMessage.SetText(temp);\r
@@ -1217,7 +1240,7 @@ void CCommitDlg::OnBnClickedBugtraqbutton()
                {\r
                        CString sErr;\r
                        sErr.Format(IDS_ERR_FAILEDISSUETRACKERCOM, (LPCTSTR)m_bugtraq_association.GetProviderName(), _com_error(hr).ErrorMessage());\r
-                       CMessageBox::Show(m_hWnd, sErr, _T("TortoiseSVN"), MB_ICONERROR);\r
+                       CMessageBox::Show(m_hWnd, sErr, _T("TortoiseGit"), MB_ICONERROR);\r
                        return;\r
                }\r
 \r
@@ -1225,7 +1248,7 @@ void CCommitDlg::OnBnClickedBugtraqbutton()
                {\r
                        CString sErr;\r
                        sErr.Format(IDS_ERR_FAILEDISSUETRACKERCOM, m_bugtraq_association.GetProviderName(), _com_error(hr).ErrorMessage());\r
-                       CMessageBox::Show(m_hWnd, sErr, _T("TortoiseSVN"), MB_ICONERROR);\r
+                       CMessageBox::Show(m_hWnd, sErr, _T("TortoiseGit"), MB_ICONERROR);\r
                }\r
                else\r
                        m_cLogMessage.SetText(temp);\r
@@ -1234,9 +1257,10 @@ void CCommitDlg::OnBnClickedBugtraqbutton()
        m_cLogMessage.SetFocus();\r
 \r
        SysFreeString(temp);\r
+#endif\r
 }\r
 \r
-LRESULT CCommitDlg::OnSVNStatusListCtrlCheckChanged(WPARAM, LPARAM)\r
+LRESULT CCommitDlg::OnGitStatusListCtrlCheckChanged(WPARAM, LPARAM)\r
 {\r
        UpdateOKButton();\r
        return 0;\r
@@ -1244,6 +1268,7 @@ LRESULT CCommitDlg::OnSVNStatusListCtrlCheckChanged(WPARAM, LPARAM)
 \r
 void CCommitDlg::UpdateOKButton()\r
 {\r
+#if 0\r
        BOOL bValidLogSize = FALSE;\r
 \r
     if (m_cLogMessage.GetText().GetLength() >= m_ProjectProperties.nMinLogSize)\r
@@ -1251,6 +1276,7 @@ void CCommitDlg::UpdateOKButton()
 \r
        LONG nSelectedItems = m_ListCtrl.GetSelected();\r
        DialogEnableWindow(IDOK, bValidLogSize && nSelectedItems>0);\r
+#endif\r
 }\r
 \r
 \r
index 704f20b..b63bb02 100644 (file)
@@ -1,6 +1,6 @@
-// TortoiseSVN - a Windows shell extension for easy version control\r
+// TortoiseGit - a Windows shell extension for easy version control\r
 \r
-// Copyright (C) 2003-2008 - TortoiseSVN\r
+// Copyright (C) 2003-2008 - TortoiseGit\r
 \r
 // This program is free software; you can redistribute it and/or\r
 // modify it under the terms of the GNU General Public License\r
@@ -19,7 +19,7 @@
 #pragma once\r
 \r
 #include "StandAloneDlg.h"\r
-#include "SVNStatusListCtrl.h"\r
+#include "GitStatusListCtrl.h"\r
 #include "ProjectProperties.h"\r
 #include "RegHistory.h"\r
 #include "Registry.h"\r
@@ -28,7 +28,7 @@
 #include "PathWatcher.h"\r
 #include "BugTraqAssociations.h"\r
 #include "Tooltip.h"\r
-#include "..\IBugTraqProvider\IBugTraqProvider_h.h"\r
+//#include "..\IBugTraqProvider\IBugTraqProvider_h.h"\r
 \r
 #include <regex>\r
 using namespace std;\r
@@ -76,9 +76,9 @@ protected:
        afx_msg void OnBnClickedBugtraqbutton();\r
        afx_msg void OnEnChangeLogmessage();\r
        afx_msg void OnStnClickedExternalwarning();\r
-       afx_msg LRESULT OnSVNStatusListCtrlItemCountChanged(WPARAM, LPARAM);\r
-       afx_msg LRESULT OnSVNStatusListCtrlNeedsRefresh(WPARAM, LPARAM);\r
-       afx_msg LRESULT OnSVNStatusListCtrlCheckChanged(WPARAM, LPARAM);\r
+       afx_msg LRESULT OnGitStatusListCtrlItemCountChanged(WPARAM, LPARAM);\r
+       afx_msg LRESULT OnGitStatusListCtrlNeedsRefresh(WPARAM, LPARAM);\r
+       afx_msg LRESULT OnGitStatusListCtrlCheckChanged(WPARAM, LPARAM);\r
        afx_msg LRESULT OnAutoListReady(WPARAM, LPARAM);\r
        afx_msg LRESULT OnFileDropped(WPARAM, LPARAM lParam);\r
        afx_msg void OnTimer(UINT_PTR nIDEvent);\r
@@ -95,10 +95,10 @@ protected:
 \r
 \r
 public:\r
-       CTSVNPathList           m_pathList;\r
-       CTSVNPathList           m_updatedPathList;\r
-       CTSVNPathList           m_selectedPathList;\r
-       CTSVNPathList           m_checkedPathList;\r
+       CTGitPathList           m_pathList;\r
+       CTGitPathList           m_updatedPathList;\r
+       CTGitPathList           m_selectedPathList;\r
+       CTGitPathList           m_checkedPathList;\r
        BOOL                            m_bRecursive;\r
        CSciEdit                        m_cLogMessage;\r
        CString                         m_sLogMessage;\r
@@ -108,12 +108,12 @@ public:
        BOOL                            m_bKeepChangeList;\r
        INT_PTR                         m_itemsCount;\r
        bool                            m_bSelectFilesForCommit;\r
-       CComPtr<IBugTraqProvider> m_BugTraqProvider;\r
+//     CComPtr<IBugTraqProvider> m_BugTraqProvider;\r
 \r
 private:\r
        CWinThread*                     m_pThread;\r
        std::set<CString>       m_autolist;\r
-       CSVNStatusListCtrl      m_ListCtrl;\r
+       CGitStatusListCtrl      m_ListCtrl;\r
        BOOL                            m_bShowUnversioned;\r
        volatile LONG           m_bBlock;\r
        volatile LONG           m_bThreadRunning;\r
@@ -133,6 +133,6 @@ private:
        CRect                           m_LogMsgOrigRect;\r
        CPathWatcher            m_pathwatcher;\r
 \r
-       CBugTraqAssociation m_bugtraq_association;\r
+//     CBugTraqAssociation m_bugtraq_association;\r
 \r
 };\r
index 348d4a6..4510fdf 100644 (file)
@@ -1,6 +1,6 @@
-// TortoiseSVN - a Windows shell extension for easy version control\r
+// TortoiseGit - a Windows shell extension for easy version control\r
 \r
-// Copyright (C) 2003-2008 - TortoiseSVN\r
+// Copyright (C) 2003-2008 - TortoiseGit\r
 \r
 // This program is free software; you can redistribute it and/or\r
 // modify it under the terms of the GNU General Public License\r
@@ -20,8 +20,8 @@
 #include "TortoiseProc.h"\r
 #include "UnicodeUtils.h"\r
 #include "ProjectProperties.h"\r
-#include "SVNProperties.h"\r
-#include "TSVNPath.h"\r
+//#include "GitProperties.h"\r
+#include "TGitPath.h"\r
 #include <regex>\r
 \r
 using namespace std;\r
@@ -44,7 +44,7 @@ ProjectProperties::~ProjectProperties(void)
 }\r
 \r
 \r
-BOOL ProjectProperties::ReadPropsPathList(const CTSVNPathList& pathList)\r
+BOOL ProjectProperties::ReadPropsPathList(const CTGitPathList& pathList)\r
 {\r
        for(int nPath = 0; nPath < pathList.GetCount(); nPath++)\r
        {\r
@@ -56,7 +56,7 @@ BOOL ProjectProperties::ReadPropsPathList(const CTSVNPathList& pathList)
        return FALSE;\r
 }\r
 \r
-BOOL ProjectProperties::ReadProps(CTSVNPath path)\r
+BOOL ProjectProperties::ReadProps(CTGitPath path)\r
 {\r
        BOOL bFoundBugtraqLabel = FALSE;\r
        BOOL bFoundBugtraqMessage = FALSE;\r
@@ -80,10 +80,10 @@ BOOL ProjectProperties::ReadProps(CTSVNPath path)
 \r
        if (!path.IsDirectory())\r
                path = path.GetContainingDirectory();\r
-               \r
+#if 0          \r
        for (;;)\r
        {\r
-               SVNProperties props(path, SVNRev::REV_WC, false);\r
+               GitProperties props(path, GitRev::REV_WC, false);\r
                for (int i=0; i<props.GetCount(); ++i)\r
                {\r
                        CString sPropName = props.GetItemName(i).c_str();\r
@@ -261,7 +261,8 @@ BOOL ProjectProperties::ReadProps(CTSVNPath path)
                        return FALSE;\r
                }\r
        }\r
-       //return FALSE;         //never reached\r
+#endif\r
+       return FALSE;           //never reached\r
 }\r
 \r
 CString ProjectProperties::GetBugIDFromLog(CString& msg)\r
@@ -677,8 +678,8 @@ BOOL ProjectProperties::HasBugID(const CString& sMessage)
        }\r
        return FALSE;\r
 }\r
-\r
-void ProjectProperties::InsertAutoProps(svn_config_t *cfg)\r
+#if 0\r
+void ProjectProperties::InsertAutoProps(Git_config_t *cfg)\r
 {\r
        // every line is an autoprop\r
        CString sPropsData = sAutoProps;\r
@@ -699,7 +700,7 @@ void ProjectProperties::InsertAutoProps(svn_config_t *cfg)
                                CString value = sLine.Mid(equalpos);\r
                                key.Trim(_T(" ="));\r
                                value.Trim(_T(" ="));\r
-                               svn_config_set(cfg, SVN_CONFIG_SECTION_AUTO_PROPS, (LPCSTR)CUnicodeUtils::GetUTF8(key), (LPCSTR)CUnicodeUtils::GetUTF8(value));\r
+                               Git_config_set(cfg, Git_CONFIG_SECTION_AUTO_PROPS, (LPCSTR)CUnicodeUtils::GetUTF8(key), (LPCSTR)CUnicodeUtils::GetUTF8(value));\r
                                bEnableAutoProps = true;\r
                        }\r
                }\r
@@ -709,10 +710,11 @@ void ProjectProperties::InsertAutoProps(svn_config_t *cfg)
                        sPropsData.Empty();\r
        }\r
        if (bEnableAutoProps)\r
-               svn_config_set(cfg, SVN_CONFIG_SECTION_MISCELLANY, SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS, "yes");\r
+               Git_config_set(cfg, Git_CONFIG_SECTION_MISCELLANY, Git_CONFIG_OPTION_ENABLE_AUTO_PROPS, "yes");\r
 }\r
+#endif\r
 \r
-bool ProjectProperties::AddAutoProps(const CTSVNPath& path)\r
+bool ProjectProperties::AddAutoProps(const CTGitPath& path)\r
 {\r
        if (!path.IsDirectory())\r
                return true;    // no error, but nothing to do\r
@@ -720,7 +722,8 @@ bool ProjectProperties::AddAutoProps(const CTSVNPath& path)
        bool bRet = true;\r
 \r
        char buf[1024] = {0};\r
-       SVNProperties props(path, SVNRev::REV_WC, false);\r
+#if 0\r
+       GitProperties props(path, GitRev::REV_WC, false);\r
        if (!sLabel.IsEmpty())\r
                bRet = props.Add(BUGTRAQPROPNAME_LABEL, WideToMultibyte((LPCTSTR)sLabel)) && bRet;\r
        if (!sMessage.IsEmpty())\r
@@ -769,6 +772,7 @@ bool ProjectProperties::AddAutoProps(const CTSVNPath& path)
                bRet = props.Add(PROJECTPROPNAME_WEBVIEWER_PATHREV, WideToMultibyte((LPCTSTR)sWebViewerPathRev)) && bRet;\r
        if (!sAutoProps.IsEmpty())\r
                bRet = props.Add(PROJECTPROPNAME_AUTOPROPS, WideToMultibyte((LPCTSTR)sAutoProps)) && bRet;\r
+#endif\r
        return bRet;\r
 }\r
 \r
@@ -808,12 +812,12 @@ public:
        PropTest()\r
        {\r
                CString msg = _T("this is a test logmessage: issue 222\nIssue #456, #678, 901  #456");\r
-               CString sUrl = _T("http://tortoisesvn.tigris.org/issues/show_bug.cgi?id=%BUGID%");\r
+               CString sUrl = _T("http://tortoiseGit.tigris.org/issues/show_bug.cgi?id=%BUGID%");\r
                CString sCheckRe = _T("[Ii]ssue #?(\\d+)(,? ?#?(\\d+))+");\r
                CString sBugIDRe = _T("(\\d+)");\r
                ProjectProperties props;\r
                props.sCheckRe = _T("PAF-[0-9]+");\r
-               props.sUrl = _T("http://tortoisesvn.tigris.org/issues/show_bug.cgi?id=%BUGID%");\r
+               props.sUrl = _T("http://tortoiseGit.tigris.org/issues/show_bug.cgi?id=%BUGID%");\r
                CString sRet = props.FindBugID(_T("This is a test for PAF-88"));\r
                ATLASSERT(sRet.IsEmpty());\r
                props.sCheckRe = _T("[Ii]ssue #?(\\d+)");\r
@@ -822,19 +826,19 @@ public:
                ATLASSERT(sRet.Compare(_T("99"))==0);\r
                props.sCheckRe = _T("[Ii]ssues?:?(\\s*(,|and)?\\s*#\\d+)+");\r
                props.sBugIDRe = _T("(\\d+)");\r
-               props.sUrl = _T("http://tortoisesvn.tigris.org/issues/show_bug.cgi?id=%BUGID%");\r
+               props.sUrl = _T("http://tortoiseGit.tigris.org/issues/show_bug.cgi?id=%BUGID%");\r
                sRet = props.FindBugID(_T("This is a test for Issue #7463,#666"));\r
                ATLASSERT(props.HasBugID(_T("This is a test for Issue #7463,#666")));\r
                ATLASSERT(!props.HasBugID(_T("This is a test for Issue 7463,666")));\r
                sRet.Trim();\r
                ATLASSERT(sRet.Compare(_T("666 7463"))==0);\r
                props.sCheckRe = _T("^\\[(\\d+)\\].*");\r
-               props.sUrl = _T("http://tortoisesvn.tigris.org/issues/show_bug.cgi?id=%BUGID%");\r
+               props.sUrl = _T("http://tortoiseGit.tigris.org/issues/show_bug.cgi?id=%BUGID%");\r
                sRet = props.FindBugID(_T("[000815] some stupid programming error fixed"));\r
                sRet.Trim();\r
                ATLASSERT(sRet.Compare(_T("000815"))==0);\r
                props.sCheckRe = _T("\\[\\[(\\d+)\\]\\]\\]");\r
-               props.sUrl = _T("http://tortoisesvn.tigris.org/issues/show_bug.cgi?id=%BUGID%");\r
+               props.sUrl = _T("http://tortoiseGit.tigris.org/issues/show_bug.cgi?id=%BUGID%");\r
                sRet = props.FindBugID(_T("test test [[000815]]] some stupid programming error fixed"));\r
                sRet.Trim();\r
                ATLASSERT(sRet.Compare(_T("000815"))==0);\r
index aa5553e..0f0bf95 100644 (file)
@@ -19,7 +19,7 @@
 #pragma once\r
 #include <iostream>\r
 #include <string>\r
-#include "TSVNPath.h"\r
+#include "TGitPath.h"\r
 using namespace std;\r
 \r
 #define BUGTRAQPROPNAME_LABEL             _T("bugtraq:label")\r
@@ -64,13 +64,13 @@ public:
         * then the properties are read from the parent folder of that file.\r
         * \param path path to a file or a folder\r
         */\r
-       BOOL ReadProps(CTSVNPath path);\r
+       BOOL ReadProps(CTGitPath path);\r
        /**\r
         * Reads the properties from all paths found in a path list.\r
         * This method calls ReadProps() for each path .\r
         * \param list of paths\r
         */\r
-       BOOL ReadPropsPathList(const CTSVNPathList& pathList);\r
+       BOOL ReadPropsPathList(const CTGitPathList& pathList);\r
 \r
        /**\r
         * Searches for the BugID inside a log message. If one is found,\r
@@ -109,18 +109,18 @@ public:
        CString GetBugIDUrl(const CString& sBugID);\r
 \r
        /**\r
-        * Inserts the tsvn:autoprops into the Subversion config section.\r
+        * Inserts the tGit:autoprops into the Subversion config section.\r
         * Call this before an import or an add operation.\r
         */\r
-       void InsertAutoProps(svn_config_t *cfg);\r
+       //void InsertAutoProps(git_config_t *cfg);\r
 \r
        /**\r
         * Adds all the project properties to the specified entry\r
         */\r
-       bool AddAutoProps(const CTSVNPath& path);\r
+       bool AddAutoProps(const CTGitPath& path);\r
 \r
        /**\r
-        * Returns the log message summary if the tsvn:logsummaryregex property is\r
+        * Returns the log message summary if the tGit:logsummaryregex property is\r
         * set and there are actually some matches.\r
         * Otherwise, an empty string is returned.\r
         */\r
@@ -129,7 +129,7 @@ public:
        /**\r
         * Returns the path from which the properties were read.\r
         */\r
-       CTSVNPath GetPropsPath() {return propsPath;}\r
+       CTGitPath GetPropsPath() {return propsPath;}\r
 public:\r
        /** The label to show in the commit dialog where the issue number/bug id\r
         * is entered. Example: "Bug-ID: " or "Issue-No.:". Default is "Bug-ID :" */\r
@@ -205,7 +205,7 @@ public:
        CString         sLogSummaryRe;\r
 private:\r
        CString         sAutoProps;\r
-       CTSVNPath       propsPath;\r
+       CTGitPath       propsPath;\r
 #ifdef DEBUG\r
        friend class PropTest;\r
 #endif\r
index 6c15c06..b5d249a 100644 (file)
@@ -21,7 +21,7 @@
 #include "StandAloneDlg.h"\r
 #include "TSVNPath.h"\r
 #include "ProjectProperties.h"\r
-#include "SVN.h"\r
+#include "Git.h"\r
 #include "Colors.h"\r
 #include "..\IBugTraqProvider\IBugTraqProvider_h.h"\r
 #include "afxwin.h"\r
@@ -71,7 +71,7 @@ typedef enum
  * in a listbox. Since several Subversion commands have similar notify\r
  * messages they are grouped together in this single class.\r
  */\r
-class CSVNProgressDlg : public CResizableStandAloneDialog, public SVN\r
+class CsProgressDlg : public CResizableStandAloneDialog, public SVN\r
 {\r
 public:\r
        typedef enum\r
index 1164639..79a06b2 100644 (file)
@@ -48,7 +48,7 @@
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="&quot;../ext/ResizableLib&quot;,&quot;../Git&quot;;&quot;../../ext/apr-util/include&quot;;&quot;../../ext/apr-util/xml/expat/lib&quot;;../../ext/Subversion/subversion/include;../../ext/Subversion/subversion/libsvn_client;../../ext/apr/include;../../ext/boost;..\TortoiseProc;..\Utils;..\SVN;..\..\ext\ResizableLib;..\crashrpt;..\TortoiseShell;&quot;..\..\ext\libintl\libintl3-win32\inc&quot;;..\..\ext\scintilla\include;..\Utils\TreePropSheet;..\Utils\ColourPickerXP;..\Utils\NewMenu;..\Utils\MiscUI;..\LogCache;&quot;../../ext/cyrus-sasl/include&quot;;../../../common/openssl/inc32;.\RevisionGraph"\r
+                               AdditionalIncludeDirectories="../ext/ResizableLib;../Git;&quot;../../ext/apr-util/include&quot;;&quot;../../ext/apr-util/xml/expat/lib&quot;;../../ext/Subversion/subversion/include;../../ext/Subversion/subversion/libsvn_client;../../ext/apr/include;../../ext/boost;..\TortoiseProc;..\Utils;..\SVN;..\..\ext\ResizableLib;..\crashrpt;..\TortoiseShell;&quot;..\..\ext\libintl\libintl3-win32\inc&quot;;..\ext\hunspell;..\ext\scintilla\include;..\Utils\TreePropSheet;..\Utils\ColourPickerXP;..\Utils\NewMenu;..\Utils\MiscUI;..\LogCache;&quot;../../ext/cyrus-sasl/include&quot;;../../../common/openssl/inc32;.\RevisionGraph"\r
                                PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;SVN_DEBUG;ENABLE_NLS;THESAURUS"\r
                                MinimalRebuild="true"\r
                                ExceptionHandling="2"\r
@@ -76,7 +76,7 @@
                                Name="VCLinkerTool"\r
                                AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib"\r
                                LinkIncremental="2"\r
-                               IgnoreDefaultLibraryNames=""\r
+                               IgnoreDefaultLibraryNames="libcd.lib;libc;shell32;LIBCMTD;"\r
                                DelayLoadDLLs="gdiplus.dll"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
                        Name="Utils"\r
                        Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;h;hpp;hxx;hm;inl;inc"\r
                        >\r
+                       <File\r
+                               RelativePath=".\ProjectProperties.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ProjectProperties.h"\r
+                               >\r
+                       </File>\r
                        <Filter\r
                                Name="General"\r
                                >\r
                        <Filter\r
                                Name="UI"\r
                                >\r
+                               <File\r
+                                       RelativePath="..\Utils\MiscUI\SciEdit.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\Utils\MiscUI\SciEdit.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\Utils\MiscUI\StandAloneDlg.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\Utils\MiscUI\StandAloneDlg.h"\r
+                                       >\r
+                               </File>\r
                        </Filter>\r
                        <Filter\r
                                Name="3rd Party"\r
                                >\r
                        </File>\r
                        <Filter\r
+                               Name="Commit"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\Commands\CommitCommand.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Commands\CommitCommand.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\CommitDlg.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\CommitDlg.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
                                Name="About"\r
                                >\r
                                <File\r
index 16bbce6..9a9e0c0 100644 (file)
@@ -11,7 +11,7 @@
                        <DebugSettings\r
                                Command="$(TargetPath)"\r
                                WorkingDirectory=""\r
-                               CommandArguments=""\r
+                               CommandArguments="/command:commit"\r
                                Attach="false"\r
                                DebuggerType="3"\r
                                Remote="1"\r
@@ -22,7 +22,7 @@
                                SQLDebugging=""\r
                                Environment=""\r
                                EnvironmentMerge="true"\r
-                               DebuggerFlavor=""\r
+                               DebuggerFlavor="0"\r
                                MPIRunCommand=""\r
                                MPIRunArguments=""\r
                                MPIRunWorkingDirectory=""\r
index 1dca728..228bb80 100644 (file)
Binary files a/TortoiseProc/resource.h and b/TortoiseProc/resource.h differ
diff --git a/TortoiseShell/TortoiseShell.sln b/TortoiseShell/TortoiseShell.sln
new file mode 100644 (file)
index 0000000..95b3037
--- /dev/null
@@ -0,0 +1,63 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 10.00\r
+# Visual Studio 2008\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TortoiseShell", "TortoiseShell.vcproj", "{E873DD32-5A31-4DE1-8341-A56A2A5489EA}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TortoiseProc", "..\TortoiseProc\TortoiseProc.vcproj", "{50797F06-39C5-4802-8E2B-7B7A4EF03214}"\r
+       ProjectSection(ProjectDependencies) = postProject\r
+               {A2C38606-3D96-4A2C-B5C5-22CEAC523B37} = {A2C38606-3D96-4A2C-B5C5-22CEAC523B37}\r
+               {A5498556-CE09-4095-8335-08FC8370552D} = {A5498556-CE09-4095-8335-08FC8370552D}\r
+               {12E5B4AE-D7EF-4A57-A22D-6F9F9D8CE1FB} = {12E5B4AE-D7EF-4A57-A22D-6F9F9D8CE1FB}\r
+               {7CA5B1EB-8CC9-40A6-96D8-83649C1A870B} = {7CA5B1EB-8CC9-40A6-96D8-83649C1A870B}\r
+               {4BE529FB-C2F2-49F7-A897-054B955564CF} = {4BE529FB-C2F2-49F7-A897-054B955564CF}\r
+       EndProjectSection\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ResizableLib", "..\ext\ResizableLib\ResizableLib.vcproj", "{4BE529FB-C2F2-49F7-A897-054B955564CF}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Utils", "..\Utils\Utils.vcproj", "{A2C38606-3D96-4A2C-B5C5-22CEAC523B37}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Git", "..\Git\Git.vcproj", "{7CA5B1EB-8CC9-40A6-96D8-83649C1A870B}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SciLexer", "..\ext\scintilla\vcbuild\SciLexer.vcproj", "{A5498556-CE09-4095-8335-08FC8370552D}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hunspell", "..\ext\hunspell\hunspell.vcproj", "{12E5B4AE-D7EF-4A57-A22D-6F9F9D8CE1FB}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Win32 = Debug|Win32\r
+               Release|Win32 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {E873DD32-5A31-4DE1-8341-A56A2A5489EA}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {E873DD32-5A31-4DE1-8341-A56A2A5489EA}.Debug|Win32.Build.0 = Debug|Win32\r
+               {E873DD32-5A31-4DE1-8341-A56A2A5489EA}.Release|Win32.ActiveCfg = Release|Win32\r
+               {E873DD32-5A31-4DE1-8341-A56A2A5489EA}.Release|Win32.Build.0 = Release|Win32\r
+               {50797F06-39C5-4802-8E2B-7B7A4EF03214}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {50797F06-39C5-4802-8E2B-7B7A4EF03214}.Debug|Win32.Build.0 = Debug|Win32\r
+               {50797F06-39C5-4802-8E2B-7B7A4EF03214}.Release|Win32.ActiveCfg = Release|Win32\r
+               {50797F06-39C5-4802-8E2B-7B7A4EF03214}.Release|Win32.Build.0 = Release|Win32\r
+               {4BE529FB-C2F2-49F7-A897-054B955564CF}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {4BE529FB-C2F2-49F7-A897-054B955564CF}.Debug|Win32.Build.0 = Debug|Win32\r
+               {4BE529FB-C2F2-49F7-A897-054B955564CF}.Release|Win32.ActiveCfg = Release|Win32\r
+               {4BE529FB-C2F2-49F7-A897-054B955564CF}.Release|Win32.Build.0 = Release|Win32\r
+               {A2C38606-3D96-4A2C-B5C5-22CEAC523B37}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {A2C38606-3D96-4A2C-B5C5-22CEAC523B37}.Debug|Win32.Build.0 = Debug|Win32\r
+               {A2C38606-3D96-4A2C-B5C5-22CEAC523B37}.Release|Win32.ActiveCfg = Release|Win32\r
+               {A2C38606-3D96-4A2C-B5C5-22CEAC523B37}.Release|Win32.Build.0 = Release|Win32\r
+               {7CA5B1EB-8CC9-40A6-96D8-83649C1A870B}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {7CA5B1EB-8CC9-40A6-96D8-83649C1A870B}.Debug|Win32.Build.0 = Debug|Win32\r
+               {7CA5B1EB-8CC9-40A6-96D8-83649C1A870B}.Release|Win32.ActiveCfg = Release|Win32\r
+               {7CA5B1EB-8CC9-40A6-96D8-83649C1A870B}.Release|Win32.Build.0 = Release|Win32\r
+               {A5498556-CE09-4095-8335-08FC8370552D}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {A5498556-CE09-4095-8335-08FC8370552D}.Debug|Win32.Build.0 = Debug|Win32\r
+               {A5498556-CE09-4095-8335-08FC8370552D}.Release|Win32.ActiveCfg = Release|Win32\r
+               {A5498556-CE09-4095-8335-08FC8370552D}.Release|Win32.Build.0 = Release|Win32\r
+               {12E5B4AE-D7EF-4A57-A22D-6F9F9D8CE1FB}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {12E5B4AE-D7EF-4A57-A22D-6F9F9D8CE1FB}.Debug|Win32.Build.0 = Debug|Win32\r
+               {12E5B4AE-D7EF-4A57-A22D-6F9F9D8CE1FB}.Release|Win32.ActiveCfg = Release|Win32\r
+               {12E5B4AE-D7EF-4A57-A22D-6F9F9D8CE1FB}.Release|Win32.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/TortoiseShell/TortoiseShell.suo b/TortoiseShell/TortoiseShell.suo
new file mode 100644 (file)
index 0000000..fd8c50d
Binary files /dev/null and b/TortoiseShell/TortoiseShell.suo differ
index e0c82ac..54b5210 100644 (file)
@@ -1,6 +1,6 @@
-// TortoiseSVN - a Windows shell extension for easy version control\r
+// TortoiseGit - a Windows shell extension for easy version control\r
 \r
-// Copyright (C) 2008 - TortoiseSVN\r
+// Copyright (C) 2008 - TortoiseGit\r
 \r
 // This program is free software; you can redistribute it and/or\r
 // modify it under the terms of the GNU General Public License\r
@@ -29,7 +29,7 @@ struct CBugTraqProvider
  */\r
 class CBugTraqAssociation\r
 {\r
-       CTSVNPath m_path;\r
+       CTGitPath m_path;\r
        CBugTraqProvider m_provider;\r
        CString m_parameters;\r
 \r
@@ -46,7 +46,7 @@ public:
                m_provider.name = szProviderName;\r
        }\r
 \r
-       const CTSVNPath &GetPath() const { return m_path; }\r
+       const CTGitPath &GetPath() const { return m_path; }\r
        CString GetProviderName() const { return m_provider.name; }\r
        CLSID GetProviderClass() const { return m_provider.clsid; }\r
        CString GetProviderClassAsString() const;\r
@@ -65,9 +65,9 @@ public:
        void Save() const;\r
 \r
        void Add(const CBugTraqAssociation &assoc);\r
-       void RemoveByPath(const CTSVNPath &path);\r
+       void RemoveByPath(const CTGitPath &path);\r
 \r
-       bool FindProvider(const CTSVNPathList &pathList, CBugTraqAssociation *assoc) const;\r
+       bool FindProvider(const CTGitPathList &pathList, CBugTraqAssociation *assoc) const;\r
 \r
        typedef inner_t::const_iterator const_iterator;\r
        const_iterator begin() const { return m_inner.begin(); }\r
@@ -77,14 +77,14 @@ public:
        static CString LookupProviderName(const CLSID &provider_clsid);\r
 \r
 private:\r
-       bool FindProviderForPathList(const CTSVNPathList &pathList, CBugTraqAssociation *assoc) const;\r
-       bool FindProviderForPath(CTSVNPath path, CBugTraqAssociation *assoc) const;\r
+       bool FindProviderForPathList(const CTGitPathList &pathList, CBugTraqAssociation *assoc) const;\r
+       bool FindProviderForPath(CTGitPath path, CBugTraqAssociation *assoc) const;\r
 \r
        struct FindByPathPred\r
        {\r
-               const CTSVNPath &m_path;\r
+               const CTGitPath &m_path;\r
 \r
-               FindByPathPred(const CTSVNPath &path)\r
+               FindByPathPred(const CTGitPath &path)\r
                        : m_path(path) { }\r
 \r
                bool operator() (const CBugTraqAssociation *assoc) const\r
index b304fd4..e1b3686 100644 (file)
 //\r
 #include "StdAfx.h"\r
 #include "resource.h"\r
-#include "AppUtils.h"\r
-#include "PathUtils.h"\r
-#include "UnicodeUtils.h"\r
+//#include "AppUtils.h"\r
+#include "..\PathUtils.h"\r
+#include "..\UnicodeUtils.h"\r
 #include <string>\r
-#include "registry.h"\r
+#include "..\registry.h"\r
 #include ".\sciedit.h"\r
 \r
 using namespace std;\r
@@ -151,6 +151,7 @@ void CSciEdit::Init(LONG lLanguage)
        Call(SCI_ASSIGNCMDKEY, SCK_HOME + (SCMOD_SHIFT << 16), SCI_HOMEWRAPEXTEND);\r
 }\r
 \r
+\r
 void CSciEdit::Init(const ProjectProperties& props)\r
 {\r
        Init(props.lProjectLanguage);\r
index b061558..5678f50 100644 (file)
@@ -19,8 +19,8 @@
 #pragma once\r
 #include "scintilla.h"\r
 #include "SciLexer.h"\r
-#include "..\..\..\ext\hunspell\\hunspell.hxx"\r
-#include "..\..\..\ext\hunspell\\mythes.hxx"\r
+#include "hunspell.hxx"\r
+#include "mythes.hxx"\r
 #include "ProjectProperties.h"\r
 #include "PersonalDictionary.h"\r
 #include <regex>\r
index fcc3ded..b452ddb 100644 (file)
@@ -43,7 +43,7 @@
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="../git;../;"\r
+                               AdditionalIncludeDirectories="../git;../;../ext/scintilla/include;../ext/hunspell"\r
                                PreprocessorDefinitions="WIN32;_DEBUG;_LIB"\r
                                MinimalRebuild="true"\r
                                BasicRuntimeChecks="3"\r
                        UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
                        >\r
                        <File\r
+                               RelativePath=".\resource.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\stdafx.h"\r
                                >\r
                        </File>\r
                        Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"\r
                        UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
                        >\r
+                       <File\r
+                               RelativePath=".\resource.rc"\r
+                               >\r
+                       </File>\r
                </Filter>\r
                <Filter\r
                        Name="MiscUi"\r
diff --git a/ext/hunspell/README b/ext/hunspell/README
new file mode 100644 (file)
index 0000000..dc5b360
--- /dev/null
@@ -0,0 +1,21 @@
+Hunspell spell checker and morphological analyser library\r
+\r
+Documentation, tests, examples: http://hunspell.sourceforge.net\r
+\r
+Author of Hunspell:\r
+László Németh (nemethl (at) gyorsposta.hu)\r
+\r
+Hunspell based on OpenOffice.org's Myspell. MySpell's author:\r
+Kevin Hendricks (kevin.hendricks (at) sympatico.ca)\r
+\r
+License: GPL 2.0/LGPL 2.1/MPL 1.1 tri-license\r
+\r
+The contents of this library may be used under the terms of\r
+the GNU General Public License Version 2 or later (the "GPL"), or\r
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL",\r
+see http://gnu.org/copyleft/lesser.html) or the Mozilla Public License\r
+Version 1.1 or later (the "MPL", see http://mozilla.org/MPL/MPL-1.1.html).\r
+\r
+Software distributed under these licenses is distributed on an "AS IS" basis,\r
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the licences\r
+for the specific language governing rights and limitations under the licenses.\r
diff --git a/ext/hunspell/affentry.cxx b/ext/hunspell/affentry.cxx
new file mode 100644 (file)
index 0000000..ce727b0
--- /dev/null
@@ -0,0 +1,870 @@
+#include "license.hunspell"\r
+#include "license.myspell"\r
+\r
+#ifndef MOZILLA_CLIENT\r
+#include <cstdlib>\r
+#include <cstring>\r
+#include <cctype>\r
+#include <cstdio>\r
+#else\r
+#include <stdlib.h> \r
+#include <string.h>\r
+#include <stdio.h> \r
+#include <ctype.h>\r
+#endif\r
+\r
+#include "affentry.hxx"\r
+#include "csutil.hxx"\r
+\r
+#ifndef MOZILLA_CLIENT\r
+#ifndef W32\r
+using namespace std;\r
+#endif\r
+#endif\r
+\r
+\r
+PfxEntry::PfxEntry(AffixMgr* pmgr, affentry* dp)\r
+{\r
+  // register affix manager\r
+  pmyMgr = pmgr;\r
+\r
+  // set up its intial values\r
\r
+  aflag = dp->aflag;         // flag \r
+  strip = dp->strip;         // string to strip\r
+  appnd = dp->appnd;         // string to append\r
+  stripl = dp->stripl;       // length of strip string\r
+  appndl = dp->appndl;       // length of append string\r
+  numconds = dp->numconds;   // number of conditions to match\r
+  opts = dp->opts;         // cross product flag\r
+  // then copy over all of the conditions\r
+  memcpy(&conds.base[0],&dp->conds.base[0],SETSIZE*sizeof(conds.base[0]));\r
+  next = NULL;\r
+  nextne = NULL;\r
+  nexteq = NULL;\r
+#ifdef HUNSPELL_EXPERIMENTAL\r
+  morphcode = dp->morphcode;\r
+#endif\r
+  contclass = dp->contclass;\r
+  contclasslen = dp->contclasslen;\r
+}\r
+\r
+\r
+PfxEntry::~PfxEntry()\r
+{\r
+    aflag = 0;\r
+    if (appnd) free(appnd);\r
+    if (strip) free(strip);\r
+    pmyMgr = NULL;\r
+    appnd = NULL;\r
+    strip = NULL;\r
+    if (opts & aeUTF8) {\r
+        for (int i = 0; i < 8; i++) {\r
+            if (conds.utf8.wchars[i]) free(conds.utf8.wchars[i]);\r
+        }\r
+    }\r
+#ifdef HUNSPELL_EXPERIMENTAL\r
+    if (morphcode && !(opts & aeALIASM)) free(morphcode);\r
+#endif\r
+    if (contclass && !(opts & aeALIASF)) free(contclass);\r
+}\r
+\r
+// add prefix to this word assuming conditions hold\r
+char * PfxEntry::add(const char * word, int len)\r
+{\r
+    char tword[MAXWORDUTF8LEN + 4];\r
+\r
+    if ((len > stripl) && (len >= numconds) && test_condition(word) &&\r
+       (!stripl || (strncmp(word, strip, stripl) == 0)) && \r
+       ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) {\r
+    /* we have a match so add prefix */\r
+              char * pp = tword;\r
+              if (appndl) {\r
+                  strcpy(tword,appnd);\r
+                  pp += appndl;\r
+               }\r
+               strcpy(pp, (word + stripl));\r
+               return mystrdup(tword);\r
+     }\r
+     return NULL;    \r
+}\r
+\r
+\r
+inline int PfxEntry::test_condition(const char * st)\r
+{\r
+    int cond;\r
+    unsigned char * cp = (unsigned char *)st;\r
+    if (!(opts & aeUTF8)) { // 256-character codepage\r
+        for (cond = 0;  cond < numconds;  cond++) {\r
+            if ((conds.base[*cp++] & (1 << cond)) == 0) return 0;\r
+        }\r
+    } else { // UTF-8 encoding\r
+      unsigned short wc;\r
+      for (cond = 0;  cond < numconds;  cond++) {\r
+        // a simple 7-bit ASCII character in UTF-8\r
+        if ((*cp >> 7) == 0) {\r
+            // also check limit (end of word)\r
+            if ((!*cp) || ((conds.utf8.ascii[*cp++] & (1 << cond)) == 0)) return 0;\r
+        // UTF-8 multibyte character\r
+        } else {\r
+            // not dot wildcard in rule\r
+            if (!conds.utf8.all[cond]) {\r
+                if (conds.utf8.neg[cond]) {\r
+                    u8_u16((w_char *) &wc, 1, (char *) cp);\r
+                    if (conds.utf8.wchars[cond] && \r
+                        flag_bsearch((unsigned short *)conds.utf8.wchars[cond],\r
+                            wc, (short) conds.utf8.wlen[cond])) return 0;\r
+                } else {\r
+                    if (!conds.utf8.wchars[cond]) return 0;\r
+                    u8_u16((w_char *) &wc, 1, (char *) cp);\r
+                    if (!flag_bsearch((unsigned short *)conds.utf8.wchars[cond],\r
+                         wc, (short)conds.utf8.wlen[cond])) return 0;\r
+                }\r
+            }\r
+            // jump to next UTF-8 character\r
+            for(cp++; (*cp & 0xc0) == 0x80; cp++);\r
+        }\r
+      }\r
+    }\r
+    return 1;\r
+}\r
+\r
+\r
+// check if this prefix entry matches \r
+struct hentry * PfxEntry::checkword(const char * word, int len, char in_compound, const FLAG needflag)\r
+{\r
+    int                 tmpl;   // length of tmpword\r
+    struct hentry *     he;     // hash entry of root word or NULL\r
+    char                tmpword[MAXWORDUTF8LEN + 4];\r
+\r
+    // on entry prefix is 0 length or already matches the beginning of the word.\r
+    // So if the remaining root word has positive length\r
+    // and if there are enough chars in root word and added back strip chars\r
+    // to meet the number of characters conditions, then test it\r
+\r
+     tmpl = len - appndl;\r
+\r
+     if ((tmpl > 0) &&  (tmpl + stripl >= numconds)) {\r
+\r
+            // generate new root word by removing prefix and adding\r
+            // back any characters that would have been stripped\r
+\r
+            if (stripl) strcpy (tmpword, strip);\r
+            strcpy ((tmpword + stripl), (word + appndl));\r
+\r
+            // now make sure all of the conditions on characters\r
+            // are met.  Please see the appendix at the end of\r
+            // this file for more info on exactly what is being\r
+            // tested\r
+\r
+            // if all conditions are met then check if resulting\r
+            // root word in the dictionary\r
+\r
+            if (test_condition(tmpword)) {\r
+                tmpl += stripl;\r
+                if ((he = pmyMgr->lookup(tmpword)) != NULL) {\r
+                   do {\r
+                      if (TESTAFF(he->astr, aflag, he->alen) &&\r
+                        // forbid single prefixes with pseudoroot flag\r
+                        ! TESTAFF(contclass, pmyMgr->get_pseudoroot(), contclasslen) &&\r
+                        // needflag\r
+                        ((!needflag) || TESTAFF(he->astr, needflag, he->alen) ||\r
+                         (contclass && TESTAFF(contclass, needflag, contclasslen))))\r
+                            return he;\r
+                      he = he->next_homonym; // check homonyms\r
+                   } while (he);\r
+                }\r
+                \r
+                // prefix matched but no root word was found \r
+                // if aeXPRODUCT is allowed, try again but now \r
+                // ross checked combined with a suffix\r
+\r
+                //if ((opts & aeXPRODUCT) && in_compound) {\r
+                if ((opts & aeXPRODUCT)) {\r
+                   he = pmyMgr->suffix_check(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this, NULL, \r
+                        0, NULL, FLAG_NULL, needflag, in_compound);\r
+                   if (he) return he;\r
+                }\r
+            }\r
+     }\r
+    return NULL;\r
+}\r
+\r
+// check if this prefix entry matches \r
+struct hentry * PfxEntry::check_twosfx(const char * word, int len,\r
+    char in_compound, const FLAG needflag)\r
+{\r
+    int                 tmpl;   // length of tmpword\r
+    struct hentry *     he;     // hash entry of root word or NULL\r
+    char                tmpword[MAXWORDUTF8LEN + 4];\r
+\r
+    // on entry prefix is 0 length or already matches the beginning of the word.\r
+    // So if the remaining root word has positive length\r
+    // and if there are enough chars in root word and added back strip chars\r
+    // to meet the number of characters conditions, then test it\r
+\r
+     tmpl = len - appndl;\r
+\r
+     if ((tmpl > 0) &&  (tmpl + stripl >= numconds)) {\r
+\r
+            // generate new root word by removing prefix and adding\r
+            // back any characters that would have been stripped\r
+\r
+            if (stripl) strcpy (tmpword, strip);\r
+            strcpy ((tmpword + stripl), (word + appndl));\r
+\r
+            // now make sure all of the conditions on characters\r
+            // are met.  Please see the appendix at the end of\r
+            // this file for more info on exactly what is being\r
+            // tested\r
+\r
+            // if all conditions are met then check if resulting\r
+            // root word in the dictionary\r
+\r
+            if (test_condition(tmpword)) {\r
+                tmpl += stripl;\r
+\r
+                // prefix matched but no root word was found \r
+                // if aeXPRODUCT is allowed, try again but now \r
+                // cross checked combined with a suffix\r
+\r
+                if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {\r
+                   he = pmyMgr->suffix_check_twosfx(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this, needflag);\r
+                   if (he) return he;\r
+                }\r
+            }\r
+     }\r
+    return NULL;\r
+}\r
+\r
+#ifdef HUNSPELL_EXPERIMENTAL\r
+// check if this prefix entry matches \r
+char * PfxEntry::check_twosfx_morph(const char * word, int len,\r
+         char in_compound, const FLAG needflag)\r
+{\r
+    int                 tmpl;   // length of tmpword\r
+    char                tmpword[MAXWORDUTF8LEN + 4];\r
+\r
+    // on entry prefix is 0 length or already matches the beginning of the word.\r
+    // So if the remaining root word has positive length\r
+    // and if there are enough chars in root word and added back strip chars\r
+    // to meet the number of characters conditions, then test it\r
+\r
+     tmpl = len - appndl;\r
+\r
+     if ((tmpl > 0) &&  (tmpl + stripl >= numconds)) {\r
+\r
+            // generate new root word by removing prefix and adding\r
+            // back any characters that would have been stripped\r
+\r
+            if (stripl) strcpy (tmpword, strip);\r
+            strcpy ((tmpword + stripl), (word + appndl));\r
+\r
+            // now make sure all of the conditions on characters\r
+            // are met.  Please see the appendix at the end of\r
+            // this file for more info on exactly what is being\r
+            // tested\r
+\r
+            // if all conditions are met then check if resulting\r
+            // root word in the dictionary\r
+\r
+            if (test_condition(tmpword)) {\r
+                tmpl += stripl;\r
+\r
+                // prefix matched but no root word was found \r
+                // if aeXPRODUCT is allowed, try again but now \r
+                // ross checked combined with a suffix\r
+\r
+                if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {\r
+                    return pmyMgr->suffix_check_twosfx_morph(tmpword, tmpl,\r
+                             aeXPRODUCT, (AffEntry *)this, needflag);\r
+                }\r
+            }\r
+     }\r
+    return NULL;\r
+}\r
+\r
+// check if this prefix entry matches \r
+char * PfxEntry::check_morph(const char * word, int len, char in_compound, const FLAG needflag)\r
+{\r
+    int                 tmpl;   // length of tmpword\r
+    struct hentry *     he;     // hash entry of root word or NULL\r
+    char                tmpword[MAXWORDUTF8LEN + 4];\r
+    char                result[MAXLNLEN];\r
+    char * st;\r
+    \r
+    *result = '\0';\r
+\r
+    // on entry prefix is 0 length or already matches the beginning of the word.\r
+    // So if the remaining root word has positive length\r
+    // and if there are enough chars in root word and added back strip chars\r
+    // to meet the number of characters conditions, then test it\r
+\r
+     tmpl = len - appndl;\r
+\r
+     if ((tmpl > 0) &&  (tmpl + stripl >= numconds)) {\r
+\r
+            // generate new root word by removing prefix and adding\r
+            // back any characters that would have been stripped\r
+\r
+            if (stripl) strcpy (tmpword, strip);\r
+            strcpy ((tmpword + stripl), (word + appndl));\r
+\r
+            // now make sure all of the conditions on characters\r
+            // are met.  Please see the appendix at the end of\r
+            // this file for more info on exactly what is being\r
+            // tested\r
+\r
+            // if all conditions are met then check if resulting\r
+            // root word in the dictionary\r
+\r
+            if (test_condition(tmpword)) {\r
+                tmpl += stripl;\r
+                if ((he = pmyMgr->lookup(tmpword)) != NULL) {\r
+                    do {\r
+                      if (TESTAFF(he->astr, aflag, he->alen) &&\r
+                        // forbid single prefixes with pseudoroot flag\r
+                        ! TESTAFF(contclass, pmyMgr->get_pseudoroot(), contclasslen) &&\r
+                        // needflag\r
+                        ((!needflag) || TESTAFF(he->astr, needflag, he->alen) ||\r
+                         (contclass && TESTAFF(contclass, needflag, contclasslen)))) {\r
+                            if (morphcode) strcat(result, morphcode); else strcat(result,getKey());\r
+                            if (he->description) {\r
+                                if ((*(he->description)=='[')||(*(he->description)=='<')) strcat(result,he->word);\r
+                                strcat(result,he->description);\r
+                            }\r
+                            strcat(result, "\n");\r
+                      }\r
+                      he = he->next_homonym;\r
+                    } while (he);\r
+                }\r
+\r
+                // prefix matched but no root word was found \r
+                // if aeXPRODUCT is allowed, try again but now \r
+                // ross checked combined with a suffix\r
+\r
+                if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {\r
+                   st = pmyMgr->suffix_check_morph(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this, \r
+                     FLAG_NULL, needflag);\r
+                   if (st) {\r
+                        strcat(result, st);\r
+                        free(st);\r
+                   }\r
+                }\r
+            }\r
+     }\r
+     \r
+    if (*result) return mystrdup(result);\r
+    return NULL;\r
+}\r
+#endif // END OF HUNSPELL_EXPERIMENTAL CODE\r
+\r
+SfxEntry::SfxEntry(AffixMgr * pmgr, affentry* dp)\r
+{\r
+  // register affix manager\r
+  pmyMgr = pmgr;\r
+\r
+  // set up its intial values\r
+  aflag = dp->aflag;         // char flag \r
+  strip = dp->strip;         // string to strip\r
+  appnd = dp->appnd;         // string to append\r
+  stripl = dp->stripl;       // length of strip string\r
+  appndl = dp->appndl;       // length of append string\r
+  numconds = dp->numconds;   // number of conditions to match\r
+  opts = dp->opts;         // cross product flag\r
+\r
+  // then copy over all of the conditions\r
+  memcpy(&conds.base[0],&dp->conds.base[0],SETSIZE*sizeof(conds.base[0]));\r
+\r
+  rappnd = myrevstrdup(appnd);\r
+\r
+#ifdef HUNSPELL_EXPERIMENTAL\r
+  morphcode = dp->morphcode;\r
+#endif\r
+  contclass = dp->contclass;\r
+  contclasslen = dp->contclasslen;\r
+}\r
+\r
+\r
+SfxEntry::~SfxEntry()\r
+{\r
+    aflag = 0;\r
+    if (appnd) free(appnd);\r
+    if (rappnd) free(rappnd);\r
+    if (strip) free(strip);\r
+    pmyMgr = NULL;\r
+    appnd = NULL;\r
+    strip = NULL;    \r
+    if (opts & aeUTF8) {\r
+        for (int i = 0; i < 8; i++) {\r
+            if (conds.utf8.wchars[i]) free(conds.utf8.wchars[i]);  \r
+        }\r
+    }\r
+#ifdef HUNSPELL_EXPERIMENTAL\r
+    if (morphcode && !(opts & aeALIASM)) free(morphcode);\r
+#endif\r
+    if (contclass && !(opts & aeALIASF)) free(contclass);\r
+}\r
+\r
+// add suffix to this word assuming conditions hold\r
+char * SfxEntry::add(const char * word, int len)\r
+{\r
+    char                tword[MAXWORDUTF8LEN + 4];\r
+\r
+     /* make sure all conditions match */\r
+     if ((len > stripl) && (len >= numconds) && test_condition(word + len, word) &&\r
+        (!stripl || (strcmp(word + len - stripl, strip) == 0)) &&\r
+        ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) {\r
+              /* we have a match so add suffix */\r
+              strcpy(tword,word);\r
+              if (appndl) {\r
+                  strcpy(tword + len - stripl, appnd);\r
+              } else {\r
+                  *(tword + len - stripl) = '\0';\r
+              }\r
+              return mystrdup(tword);\r
+     }\r
+     return NULL;\r
+}\r
+\r
+\r
+inline int SfxEntry::test_condition(const char * st, const char * beg)\r
+{\r
+    int cond;\r
+    unsigned char * cp = (unsigned char *) st;\r
+    if (!(opts & aeUTF8)) { // 256-character codepage\r
+        // Dömölki affix algorithm\r
+        for (cond = numconds;  --cond >= 0; ) {\r
+            if ((conds.base[*--cp] & (1 << cond)) == 0) return 0;\r
+        }\r
+    } else { // UTF-8 encoding\r
+      unsigned short wc;\r
+      for (cond = numconds;  --cond >= 0; ) {\r
+        // go to next character position and check limit\r
+        if ((char *) --cp < beg) return 0;\r
+        // a simple 7-bit ASCII character in UTF-8\r
+        if ((*cp >> 7) == 0) {\r
+            if ((conds.utf8.ascii[*cp] & (1 << cond)) == 0) return 0;\r
+        // UTF-8 multibyte character\r
+        } else {\r
+            // go to first character of UTF-8 multibyte character\r
+            for (; (*cp & 0xc0) == 0x80; cp--);\r
+            // not dot wildcard in rule\r
+            if (!conds.utf8.all[cond]) {\r
+                if (conds.utf8.neg[cond]) {\r
+                    u8_u16((w_char *) &wc, 1, (char *) cp);\r
+                    if (conds.utf8.wchars[cond] && \r
+                        flag_bsearch((unsigned short *)conds.utf8.wchars[cond],\r
+                            wc, (short) conds.utf8.wlen[cond])) return 0;\r
+                } else {\r
+                    if (!conds.utf8.wchars[cond]) return 0;\r
+                    u8_u16((w_char *) &wc, 1, (char *) cp);\r
+                    if (!flag_bsearch((unsigned short *)conds.utf8.wchars[cond],\r
+                         wc, (short)conds.utf8.wlen[cond])) return 0;\r
+                }\r
+            }\r
+        }\r
+      }\r
+    }\r
+    return 1;\r
+}\r
+\r
+\r
+\r
+// see if this suffix is present in the word \r
+struct hentry * SfxEntry::checkword(const char * word, int len, int optflags,\r
+    AffEntry* ppfx, char ** wlst, int maxSug, int * ns, const FLAG cclass, const FLAG needflag,\r
+    const FLAG badflag)\r
+{\r
+    int                 tmpl;            // length of tmpword \r
+    struct hentry *     he;              // hash entry pointer\r
+    unsigned char *     cp;\r
+    char                tmpword[MAXWORDUTF8LEN + 4];\r
+    PfxEntry* ep = (PfxEntry *) ppfx;\r
+\r
+    // if this suffix is being cross checked with a prefix\r
+    // but it does not support cross products skip it\r
+\r
+    if (((optflags & aeXPRODUCT) != 0) && ((opts & aeXPRODUCT) == 0))\r
+        return NULL;\r
+\r
+    // upon entry suffix is 0 length or already matches the end of the word.\r
+    // So if the remaining root word has positive length\r
+    // and if there are enough chars in root word and added back strip chars\r
+    // to meet the number of characters conditions, then test it\r
+\r
+    tmpl = len - appndl;\r
+    // the second condition is not enough for UTF-8 strings\r
+    // it checked in test_condition()\r
+    \r
+    if ((tmpl > 0)  &&  (tmpl + stripl >= numconds)) {\r
+\r
+            // generate new root word by removing suffix and adding\r
+            // back any characters that would have been stripped or\r
+            // or null terminating the shorter string\r
+\r
+            strcpy (tmpword, word);\r
+            cp = (unsigned char *)(tmpword + tmpl);\r
+            if (stripl) {\r
+                strcpy ((char *)cp, strip);\r
+                tmpl += stripl;\r
+                cp = (unsigned char *)(tmpword + tmpl);\r
+            } else *cp = '\0';\r
+\r
+            // now make sure all of the conditions on characters\r
+            // are met.  Please see the appendix at the end of\r
+            // this file for more info on exactly what is being            // tested\r
+\r
+            // if all conditions are met then check if resulting\r
+            // root word in the dictionary\r
+\r
+            if (test_condition((char *) cp, (char *) tmpword)) {\r
+\r
+#ifdef SZOSZABLYA_POSSIBLE_ROOTS\r
+                fprintf(stdout,"%s %s %c\n", word, tmpword, aflag);\r
+#endif\r
+                if ((he = pmyMgr->lookup(tmpword)) != NULL) {\r
+                    do {\r
+                        // check conditional suffix (enabled by prefix)\r
+                        if ((TESTAFF(he->astr, aflag, he->alen) || (ep && ep->getCont() &&\r
+                                    TESTAFF(ep->getCont(), aflag, ep->getContLen()))) && \r
+                            (((optflags & aeXPRODUCT) == 0) || \r
+                            TESTAFF(he->astr, ep->getFlag(), he->alen) ||\r
+                             // enabled by prefix\r
+                            ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen))\r
+                            ) &&\r
+                            // handle cont. class\r
+                            ((!cclass) || \r
+                                ((contclass) && TESTAFF(contclass, cclass, contclasslen))\r
+                            ) &&\r
+                            // check only in compound homonyms (bad flags)\r
+                            (!badflag || !TESTAFF(he->astr, badflag, he->alen)\r
+                            ) &&                            \r
+                            // handle required flag\r
+                            ((!needflag) || \r
+                              (TESTAFF(he->astr, needflag, he->alen) ||\r
+                              ((contclass) && TESTAFF(contclass, needflag, contclasslen)))\r
+                            )\r
+                        ) return he;\r
+                        he = he->next_homonym; // check homonyms\r
+                    } while (he);\r
+\r
+                // obsolote stemming code (used only by the \r
+                // experimental SuffixMgr:suggest_pos_stems)\r
+                // store resulting root in wlst\r
+                } else if (wlst && (*ns < maxSug)) {\r
+                    int cwrd = 1;\r
+                    for (int k=0; k < *ns; k++) \r
+                        if (strcmp(tmpword, wlst[k]) == 0) cwrd = 0;\r
+                    if (cwrd) {\r
+                        wlst[*ns] = mystrdup(tmpword);\r
+                        if (wlst[*ns] == NULL) {\r
+                            for (int j=0; j<*ns; j++) free(wlst[j]);\r
+                            *ns = -1;\r
+                            return NULL;\r
+                        }\r
+                        (*ns)++;\r
+                    }\r
+                }\r
+            }\r
+    }\r
+    return NULL;\r
+}\r
+\r
+// see if two-level suffix is present in the word \r
+struct hentry * SfxEntry::check_twosfx(const char * word, int len, int optflags,\r
+    AffEntry* ppfx, const FLAG needflag)\r
+{\r
+    int                 tmpl;            // length of tmpword \r
+    struct hentry *     he;              // hash entry pointer\r
+    unsigned char *     cp;\r
+    char                tmpword[MAXWORDUTF8LEN + 4];\r
+    PfxEntry* ep = (PfxEntry *) ppfx;\r
+\r
+\r
+    // if this suffix is being cross checked with a prefix\r
+    // but it does not support cross products skip it\r
+\r
+    if ((optflags & aeXPRODUCT) != 0 &&  (opts & aeXPRODUCT) == 0)\r
+        return NULL;\r
+\r
+    // upon entry suffix is 0 length or already matches the end of the word.\r
+    // So if the remaining root word has positive length\r
+    // and if there are enough chars in root word and added back strip chars\r
+    // to meet the number of characters conditions, then test it\r
+\r
+    tmpl = len - appndl;\r
+\r
+    if ((tmpl > 0)  &&  (tmpl + stripl >= numconds)) {\r
+\r
+            // generate new root word by removing suffix and adding\r
+            // back any characters that would have been stripped or\r
+            // or null terminating the shorter string\r
+\r
+            strcpy (tmpword, word);\r
+            cp = (unsigned char *)(tmpword + tmpl);\r
+            if (stripl) {\r
+                strcpy ((char *)cp, strip);\r
+                tmpl += stripl;\r
+                cp = (unsigned char *)(tmpword + tmpl);\r
+            } else *cp = '\0';\r
+\r
+            // now make sure all of the conditions on characters\r
+            // are met.  Please see the appendix at the end of\r
+            // this file for more info on exactly what is being\r
+            // tested\r
+\r
+            // if all conditions are met then recall suffix_check\r
+\r
+            if (test_condition((char *) cp, (char *) tmpword)) {\r
+                if (ppfx) {\r
+                    // handle conditional suffix\r
+                    if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) \r
+                        he = pmyMgr->suffix_check(tmpword, tmpl, 0, NULL, NULL, 0, NULL, (FLAG) aflag, needflag);\r
+                    else\r
+                        he = pmyMgr->suffix_check(tmpword, tmpl, optflags, ppfx, NULL, 0, NULL, (FLAG) aflag, needflag);\r
+                } else {\r
+                    he = pmyMgr->suffix_check(tmpword, tmpl, 0, NULL, NULL, 0, NULL, (FLAG) aflag, needflag);\r
+                }\r
+                if (he) return he;\r
+            }\r
+    }\r
+    return NULL;\r
+}\r
+\r
+#ifdef HUNSPELL_EXPERIMENTAL\r
+// see if two-level suffix is present in the word \r
+char * SfxEntry::check_twosfx_morph(const char * word, int len, int optflags,\r
+    AffEntry* ppfx, const FLAG needflag)\r
+{\r
+    int                 tmpl;            // length of tmpword \r
+    unsigned char *     cp;\r
+    char                tmpword[MAXWORDUTF8LEN + 4];\r
+    PfxEntry* ep = (PfxEntry *) ppfx;\r
+    char * st;\r
+\r
+    char result[MAXLNLEN];\r
+    \r
+    *result = '\0';\r
+\r
+    // if this suffix is being cross checked with a prefix\r
+    // but it does not support cross products skip it\r
+\r
+    if ((optflags & aeXPRODUCT) != 0 &&  (opts & aeXPRODUCT) == 0)\r
+        return NULL;\r
+\r
+    // upon entry suffix is 0 length or already matches the end of the word.\r
+    // So if the remaining root word has positive length\r
+    // and if there are enough chars in root word and added back strip chars\r
+    // to meet the number of characters conditions, then test it\r
+\r
+    tmpl = len - appndl;\r
+\r
+    if ((tmpl > 0)  &&  (tmpl + stripl >= numconds)) {\r
+\r
+            // generate new root word by removing suffix and adding\r
+            // back any characters that would have been stripped or\r
+            // or null terminating the shorter string\r
+\r
+            strcpy (tmpword, word);\r
+            cp = (unsigned char *)(tmpword + tmpl);\r
+            if (stripl) {\r
+                strcpy ((char *)cp, strip);\r
+                tmpl += stripl;\r
+                cp = (unsigned char *)(tmpword + tmpl);\r
+            } else *cp = '\0';\r
+\r
+            // now make sure all of the conditions on characters\r
+            // are met.  Please see the appendix at the end of\r
+            // this file for more info on exactly what is being\r
+            // tested\r
+\r
+            // if all conditions are met then recall suffix_check\r
+\r
+            if (test_condition((char *) cp, (char *) tmpword)) {\r
+                if (ppfx) {\r
+                    // handle conditional suffix\r
+                    if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) {\r
+                        st = pmyMgr->suffix_check_morph(tmpword, tmpl, 0, NULL, aflag, needflag);\r
+                        if (st) {\r
+                            if (((PfxEntry *) ppfx)->getMorph()) {\r
+                                strcat(result, ((PfxEntry *) ppfx)->getMorph());\r
+                            }\r
+                            strcat(result,st);\r
+                            free(st);\r
+                            mychomp(result);\r
+                        }\r
+                    } else {\r
+                        st = pmyMgr->suffix_check_morph(tmpword, tmpl, optflags, ppfx, aflag, needflag);\r
+                        if (st) {\r
+                            strcat(result, st);\r
+                            free(st);\r
+                            mychomp(result);\r
+                        }\r
+                    }\r
+                } else {\r
+                        st = pmyMgr->suffix_check_morph(tmpword, tmpl, 0, NULL, aflag, needflag);\r
+                        if (st) {\r
+                            strcat(result, st);\r
+                            free(st);\r
+                            mychomp(result);\r
+                        }\r
+                }\r
+                if (*result) return mystrdup(result);\r
+            }\r
+    }\r
+    return NULL;\r
+}\r
+#endif // END OF HUNSPELL_EXPERIMENTAL CODE\r
+\r
+// get next homonym with same affix\r
+struct hentry * SfxEntry::get_next_homonym(struct hentry * he, int optflags, AffEntry* ppfx, \r
+    const FLAG cclass, const FLAG needflag)\r
+{\r
+    PfxEntry* ep = (PfxEntry *) ppfx;\r
+\r
+    while (he->next_homonym) {\r
+        he = he->next_homonym;\r
+        if ((TESTAFF(he->astr, aflag, he->alen) || (ep && ep->getCont() && TESTAFF(ep->getCont(), aflag, ep->getContLen()))) && \r
+                            ((optflags & aeXPRODUCT) == 0 || \r
+                            TESTAFF(he->astr, ep->getFlag(), he->alen) ||\r
+                             // handle conditional suffix\r
+                            ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen))\r
+                            ) &&\r
+                            // handle cont. class\r
+                            ((!cclass) || \r
+                                ((contclass) && TESTAFF(contclass, cclass, contclasslen))\r
+                            ) &&\r
+                            // handle required flag\r
+                            ((!needflag) || \r
+                              (TESTAFF(he->astr, needflag, he->alen) ||\r
+                              ((contclass) && TESTAFF(contclass, needflag, contclasslen)))\r
+                            )\r
+                        ) return he;\r
+    }\r
+    return NULL;\r
+}\r
+\r
+\r
+#if 0\r
+\r
+Appendix:  Understanding Affix Code\r
+\r
+\r
+An affix is either a  prefix or a suffix attached to root words to make \r
+other words.\r
+\r
+Basically a Prefix or a Suffix is set of AffEntry objects\r
+which store information about the prefix or suffix along \r
+with supporting routines to check if a word has a particular \r
+prefix or suffix or a combination.\r
+\r
+The structure affentry is defined as follows:\r
+\r
+struct affentry\r
+{\r
+   unsigned short aflag;    // ID used to represent the affix\r
+   char * strip;            // string to strip before adding affix\r
+   char * appnd;            // the affix string to add\r
+   unsigned char stripl;    // length of the strip string\r
+   unsigned char appndl;    // length of the affix string\r
+   char numconds;           // the number of conditions that must be met\r
+   char opts;               // flag: aeXPRODUCT- combine both prefix and suffix \r
+   char   conds[SETSIZE];   // array which encodes the conditions to be met\r
+};\r
+\r
+\r
+Here is a suffix borrowed from the en_US.aff file.  This file \r
+is whitespace delimited.\r
+\r
+SFX D Y 4 \r
+SFX D   0     e          d\r
+SFX D   y     ied        [^aeiou]y\r
+SFX D   0     ed         [^ey]\r
+SFX D   0     ed         [aeiou]y\r
+\r
+This information can be interpreted as follows:\r
+\r
+In the first line has 4 fields\r
+\r
+Field\r
+-----\r
+1     SFX - indicates this is a suffix\r
+2     D   - is the name of the character flag which represents this suffix\r
+3     Y   - indicates it can be combined with prefixes (cross product)\r
+4     4   - indicates that sequence of 4 affentry structures are needed to\r
+               properly store the affix information\r
+\r
+The remaining lines describe the unique information for the 4 SfxEntry \r
+objects that make up this affix.  Each line can be interpreted\r
+as follows: (note fields 1 and 2 are as a check against line 1 info)\r
+\r
+Field\r
+-----\r
+1     SFX         - indicates this is a suffix\r
+2     D           - is the name of the character flag for this affix\r
+3     y           - the string of chars to strip off before adding affix\r
+                         (a 0 here indicates the NULL string)\r
+4     ied         - the string of affix characters to add\r
+5     [^aeiou]y   - the conditions which must be met before the affix\r
+                    can be applied\r
+\r
+Field 5 is interesting.  Since this is a suffix, field 5 tells us that\r
+there are 2 conditions that must be met.  The first condition is that \r
+the next to the last character in the word must *NOT* be any of the \r
+following "a", "e", "i", "o" or "u".  The second condition is that\r
+the last character of the word must end in "y".\r
+\r
+So how can we encode this information concisely and be able to \r
+test for both conditions in a fast manner?  The answer is found\r
+but studying the wonderful ispell code of Geoff Kuenning, et.al. \r
+(now available under a normal BSD license).\r
+\r
+If we set up a conds array of 256 bytes indexed (0 to 255) and access it\r
+using a character (cast to an unsigned char) of a string, we have 8 bits\r
+of information we can store about that character.  Specifically we\r
+could use each bit to say if that character is allowed in any of the \r
+last (or first for prefixes) 8 characters of the word.\r
+\r
+Basically, each character at one end of the word (up to the number \r
+of conditions) is used to index into the conds array and the resulting \r
+value found there says whether the that character is valid for a \r
+specific character position in the word.  \r
+\r
+For prefixes, it does this by setting bit 0 if that char is valid \r
+in the first position, bit 1 if valid in the second position, and so on. \r
+\r
+If a bit is not set, then that char is not valid for that postion in the\r
+word.\r
+\r
+If working with suffixes bit 0 is used for the character closest \r
+to the front, bit 1 for the next character towards the end, ..., \r
+with bit numconds-1 representing the last char at the end of the string. \r
+\r
+Note: since entries in the conds[] are 8 bits, only 8 conditions \r
+(read that only 8 character positions) can be examined at one\r
+end of a word (the beginning for prefixes and the end for suffixes.\r
+\r
+So to make this clearer, lets encode the conds array values for the \r
+first two affentries for the suffix D described earlier.\r
+\r
+\r
+  For the first affentry:    \r
+     numconds = 1             (only examine the last character)\r
+\r
+     conds['e'] =  (1 << 0)   (the word must end in an E)\r
+     all others are all 0\r
+\r
+  For the second affentry:\r
+     numconds = 2             (only examine the last two characters)     \r
+\r
+     conds[X] = conds[X] | (1 << 0)     (aeiou are not allowed)\r
+         where X is all characters *but* a, e, i, o, or u\r
+         \r
+\r
+     conds['y'] = (1 << 1)     (the last char must be a y)\r
+     all other bits for all other entries in the conds array are zero\r
+\r
+\r
+#endif\r
+\r
diff --git a/ext/hunspell/affentry.hxx b/ext/hunspell/affentry.hxx
new file mode 100644 (file)
index 0000000..bb21773
--- /dev/null
@@ -0,0 +1,131 @@
+#ifndef _AFFIX_HXX_
+#define _AFFIX_HXX_
+
+#include "atypes.hxx"
+#include "baseaffix.hxx"
+#include "affixmgr.hxx"
+
+/* A Prefix Entry  */
+
+class PfxEntry : public AffEntry
+{
+       AffixMgr*    pmyMgr;
+
+       PfxEntry * next;
+       PfxEntry * nexteq;
+       PfxEntry * nextne;
+       PfxEntry * flgnxt;
+
+public:
+
+  PfxEntry(AffixMgr* pmgr, affentry* dp );
+  ~PfxEntry();
+
+  inline bool          allowCross() { return ((opts & aeXPRODUCT) != 0); }
+  struct hentry *      checkword(const char * word, int len, char in_compound, 
+                            const FLAG needflag = FLAG_NULL);
+
+  struct hentry *      check_twosfx(const char * word, int len, char in_compound, const FLAG needflag = NULL);
+
+  char *      check_morph(const char * word, int len, char in_compound,
+                            const FLAG needflag = FLAG_NULL);
+
+  char *      check_twosfx_morph(const char * word, int len,
+                  char in_compound, const FLAG needflag = FLAG_NULL);
+
+  inline FLAG getFlag()   { return aflag;   }
+  inline const char *  getKey()    { return appnd;  } 
+  char *               add(const char * word, int len);
+
+  inline short getKeyLen() { return appndl; } 
+
+  inline const char *  getMorph()    { return morphcode;  } 
+
+  inline const unsigned short * getCont()    { return contclass;  } 
+  inline short           getContLen()    { return contclasslen;  } 
+
+  inline PfxEntry *    getNext()   { return next;   }
+  inline PfxEntry *    getNextNE() { return nextne; }
+  inline PfxEntry *    getNextEQ() { return nexteq; }
+  inline PfxEntry *    getFlgNxt() { return flgnxt; }
+
+  inline void   setNext(PfxEntry * ptr)   { next = ptr;   }
+  inline void   setNextNE(PfxEntry * ptr) { nextne = ptr; }
+  inline void   setNextEQ(PfxEntry * ptr) { nexteq = ptr; }
+  inline void   setFlgNxt(PfxEntry * ptr) { flgnxt = ptr; }
+  
+  inline int    test_condition(const char * st);
+};
+
+
+
+
+/* A Suffix Entry */
+
+class SfxEntry : public AffEntry
+{
+       AffixMgr*    pmyMgr;
+       char *       rappnd;
+
+       SfxEntry *   next;
+       SfxEntry *   nexteq;
+       SfxEntry *   nextne;
+       SfxEntry *   flgnxt;
+           
+       SfxEntry *   l_morph;
+       SfxEntry *   r_morph;
+       SfxEntry *   eq_morph;
+
+public:
+
+  SfxEntry(AffixMgr* pmgr, affentry* dp );
+  ~SfxEntry();
+
+  inline bool          allowCross() { return ((opts & aeXPRODUCT) != 0); }
+  struct hentry *   checkword(const char * word, int len, int optflags, 
+                    AffEntry* ppfx, char ** wlst, int maxSug, int * ns,
+//                    const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, char in_compound=IN_CPD_NOT);
+                    const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, const FLAG badflag = 0);
+
+  struct hentry *   check_twosfx(const char * word, int len, int optflags, AffEntry* ppfx, const FLAG needflag = NULL);
+
+  char *      check_twosfx_morph(const char * word, int len, int optflags,
+                 AffEntry* ppfx, const FLAG needflag = FLAG_NULL);
+  struct hentry * get_next_homonym(struct hentry * he);
+  struct hentry * get_next_homonym(struct hentry * word, int optflags, AffEntry* ppfx, 
+    const FLAG cclass, const FLAG needflag);
+
+
+  inline FLAG getFlag()   { return aflag;   }
+  inline const char *  getKey()    { return rappnd; } 
+  char *               add(const char * word, int len);
+
+
+  inline const char *  getMorph()    { return morphcode;  } 
+
+  inline const unsigned short * getCont()    { return contclass;  } 
+  inline short           getContLen()    { return contclasslen;  } 
+  inline const char *  getAffix()    { return appnd; } 
+
+  inline short getKeyLen() { return appndl; } 
+
+  inline SfxEntry *    getNext()   { return next;   }
+  inline SfxEntry *    getNextNE() { return nextne; }
+  inline SfxEntry *    getNextEQ() { return nexteq; }
+
+  inline SfxEntry *    getLM() { return l_morph; }
+  inline SfxEntry *    getRM() { return r_morph; }
+  inline SfxEntry *    getEQM() { return eq_morph; }
+  inline SfxEntry *    getFlgNxt() { return flgnxt; }
+
+  inline void   setNext(SfxEntry * ptr)   { next = ptr;   }
+  inline void   setNextNE(SfxEntry * ptr) { nextne = ptr; }
+  inline void   setNextEQ(SfxEntry * ptr) { nexteq = ptr; }
+  inline void   setFlgNxt(SfxEntry * ptr) { flgnxt = ptr; }
+
+  inline int    test_condition(const char * st, const char * begin);
+};
+
+#endif
+
+
diff --git a/ext/hunspell/affixmgr.cxx b/ext/hunspell/affixmgr.cxx
new file mode 100644 (file)
index 0000000..4846580
--- /dev/null
@@ -0,0 +1,3958 @@
+#include "license.hunspell"\r
+#include "license.myspell"\r
+\r
+#ifndef MOZILLA_CLIENT\r
+#include <cstdlib>\r
+#include <cstring>\r
+#include <cctype>\r
+#include <cstdio>\r
+#else\r
+#include <stdlib.h> \r
+#include <string.h>\r
+#include <stdio.h> \r
+#include <ctype.h>\r
+#endif\r
+\r
+#include "affixmgr.hxx"\r
+#include "affentry.hxx"\r
+#include "langnum.hxx"\r
+\r
+#include "csutil.hxx"\r
+\r
+#ifndef MOZILLA_CLIENT\r
+#ifndef W32\r
+using namespace std;\r
+#endif\r
+#endif\r
+\r
+AffixMgr::AffixMgr(const char * affpath, HashMgr* ptr) \r
+{\r
+  // register hash manager and load affix data from aff file\r
+  pHMgr = ptr;\r
+  trystring = NULL;\r
+  encoding=NULL;\r
+  utf8 = 0;\r
+  complexprefixes = 0;\r
+  maptable = NULL;\r
+  nummap = 0;\r
+  breaktable = NULL;\r
+  numbreak = 0;\r
+  reptable = NULL;\r
+  numrep = 0;\r
+  checkcpdtable = NULL;\r
+  numcheckcpd = 0;\r
+  defcpdtable = NULL;\r
+  numdefcpd = 0;\r
+  compoundflag = FLAG_NULL; // permits word in compound forms\r
+  compoundbegin = FLAG_NULL; // may be first word in compound forms\r
+  compoundmiddle = FLAG_NULL; // may be middle word in compound forms\r
+  compoundend = FLAG_NULL; // may be last word in compound forms\r
+  compoundroot = FLAG_NULL; // compound word signing flag\r
+  compoundpermitflag = FLAG_NULL; // compound permitting flag for suffixed word\r
+  compoundforbidflag = FLAG_NULL; // compound fordidden flag for suffixed word\r
+  checkcompounddup = 0; // forbid double words in compounds\r
+  checkcompoundrep = 0; // forbid bad compounds (may be non compound word with a REP substitution)\r
+  checkcompoundcase = 0; // forbid upper and lowercase combinations at word bounds\r
+  checkcompoundtriple = 0; // forbid compounds with triple letters\r
+  forbiddenword = FLAG_NULL; // forbidden word signing flag\r
+  nosuggest = FLAG_NULL; // don't suggest words signed with NOSUGGEST flag\r
+  lang = NULL; // language\r
+  langnum = 0; // language code (see http://l10n.openoffice.org/languages.html)\r
+  pseudoroot = FLAG_NULL; // forbidden root, allowed only with suffixes\r
+  cpdwordmax = -1; // default: unlimited wordcount in compound words\r
+  cpdmin = -1;  // undefined\r
+  cpdmaxsyllable = 0; // default: unlimited syllablecount in compound words\r
+  cpdvowels=NULL; // vowels (for calculating of Hungarian compounding limit, O(n) search! XXX)\r
+  cpdvowels_utf16=NULL; // vowels for UTF-8 encoding (bsearch instead of O(n) search)\r
+  cpdvowels_utf16_len=0; // vowels\r
+  pfxappnd=NULL; // previous prefix for counting the syllables of prefix BUG\r
+  sfxappnd=NULL; // previous suffix for counting a special syllables BUG\r
+  cpdsyllablenum=NULL; // syllable count incrementing flag\r
+  checknum=0; // checking numbers, and word with numbers\r
+  wordchars=NULL; // letters + spec. word characters\r
+  wordchars_utf16=NULL; // letters + spec. word characters\r
+  wordchars_utf16_len=0; // letters + spec. word characters\r
+  ignorechars=NULL; // letters + spec. word characters\r
+  ignorechars_utf16=NULL; // letters + spec. word characters\r
+  ignorechars_utf16_len=0; // letters + spec. word characters\r
+  version=NULL; // affix and dictionary file version string\r
+  havecontclass=0; // flags of possible continuing classes (double affix)\r
+  // LEMMA_PRESENT: not put root into the morphological output. Lemma presents\r
+  // in morhological description in dictionary file. It's often combined with PSEUDOROOT.\r
+  lemma_present = FLAG_NULL; \r
+  circumfix = FLAG_NULL; \r
+  onlyincompound = FLAG_NULL; \r
+  flag_mode = FLAG_CHAR; // default one-character flags in affix and dic file\r
+  maxngramsugs = -1; // undefined\r
+  nosplitsugs = 0;\r
+  sugswithdots = 0;\r
+  keepcase = 0;\r
+  checksharps = 0;\r
+\r
+  derived = NULL; // XXX not threadsafe variable for experimental stemming\r
+  sfx = NULL;\r
+  pfx = NULL;\r
+\r
+  for (int i=0; i < SETSIZE; i++) {\r
+     pStart[i] = NULL;\r
+     sStart[i] = NULL;\r
+     pFlag[i] = NULL;\r
+     sFlag[i] = NULL;\r
+  }\r
+\r
+  for (int j=0; j < CONTSIZE; j++) {\r
+    contclasses[j] = 0;\r
+  }\r
+\r
+  if (parse_file(affpath)) {\r
+     HUNSPELL_WARNING(stderr, "Failure loading aff file %s\n",affpath);\r
+     wordchars = mystrdup("qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM");\r
+  }\r
+  \r
+  if (cpdmin == -1) cpdmin = MINCPDLEN;\r
+\r
+}\r
+\r
+\r
+AffixMgr::~AffixMgr() \r
+{\r
\r
+  // pass through linked prefix entries and clean up\r
+  for (int i=0; i < SETSIZE ;i++) {\r
+       pFlag[i] = NULL;\r
+       PfxEntry * ptr = (PfxEntry *)pStart[i];\r
+       PfxEntry * nptr = NULL;\r
+       while (ptr) {\r
+            nptr = ptr->getNext();\r
+            delete(ptr);\r
+            ptr = nptr;\r
+            nptr = NULL;\r
+       }  \r
+  }\r
+\r
+  // pass through linked suffix entries and clean up\r
+  for (int j=0; j < SETSIZE ; j++) {\r
+       sFlag[j] = NULL;\r
+       SfxEntry * ptr = (SfxEntry *)sStart[j];\r
+       SfxEntry * nptr = NULL;\r
+       while (ptr) {\r
+            nptr = ptr->getNext();\r
+            delete(ptr);\r
+            ptr = nptr;\r
+            nptr = NULL;\r
+       }\r
+       sStart[j] = NULL;\r
+  }\r
+\r
+  if (trystring) free(trystring);\r
+  trystring=NULL;\r
+  if (encoding) free(encoding);\r
+  encoding=NULL;\r
+  if (maptable) {  \r
+     for (int j=0; j < nummap; j++) {\r
+        if (maptable[j].set) free(maptable[j].set);\r
+        if (maptable[j].set_utf16) free(maptable[j].set_utf16);\r
+        maptable[j].set = NULL;\r
+        maptable[j].len = 0;\r
+     }\r
+     free(maptable);  \r
+     maptable = NULL;\r
+  }\r
+  nummap = 0;\r
+  if (breaktable) {\r
+     for (int j=0; j < numbreak; j++) {\r
+        if (breaktable[j]) free(breaktable[j]);\r
+        breaktable[j] = NULL;\r
+     }\r
+     free(breaktable);  \r
+     breaktable = NULL;\r
+  }\r
+  numbreak = 0;\r
+  if (reptable) {  \r
+     for (int j=0; j < numrep; j++) {\r
+        free(reptable[j].pattern);\r
+        free(reptable[j].pattern2);\r
+        reptable[j].pattern = NULL;\r
+        reptable[j].pattern2 = NULL;\r
+     }\r
+     free(reptable);  \r
+     reptable = NULL;\r
+  }\r
+  if (defcpdtable) {  \r
+     for (int j=0; j < numdefcpd; j++) {\r
+        free(defcpdtable[j].def);\r
+        defcpdtable[j].def = NULL;\r
+     }\r
+     free(defcpdtable);  \r
+     defcpdtable = NULL;\r
+  }\r
+  numrep = 0;\r
+  if (checkcpdtable) {  \r
+     for (int j=0; j < numcheckcpd; j++) {\r
+        free(checkcpdtable[j].pattern);\r
+        free(checkcpdtable[j].pattern2);\r
+        checkcpdtable[j].pattern = NULL;\r
+        checkcpdtable[j].pattern2 = NULL;\r
+     }\r
+     free(checkcpdtable);  \r
+     checkcpdtable = NULL;\r
+  }\r
+  numcheckcpd = 0;\r
+  FREE_FLAG(compoundflag);\r
+  FREE_FLAG(compoundbegin);\r
+  FREE_FLAG(compoundmiddle);\r
+  FREE_FLAG(compoundend);\r
+  FREE_FLAG(compoundpermitflag);\r
+  FREE_FLAG(compoundforbidflag);\r
+  FREE_FLAG(compoundroot);\r
+  FREE_FLAG(forbiddenword);\r
+  FREE_FLAG(nosuggest);\r
+  FREE_FLAG(pseudoroot);\r
+  FREE_FLAG(lemma_present);\r
+  FREE_FLAG(circumfix);\r
+  FREE_FLAG(onlyincompound);\r
+  \r
+  cpdwordmax = 0;\r
+  pHMgr = NULL;\r
+  cpdmin = 0;\r
+  cpdmaxsyllable = 0;\r
+  if (cpdvowels) free(cpdvowels);\r
+  if (cpdvowels_utf16) free(cpdvowels_utf16);\r
+  if (cpdsyllablenum) free(cpdsyllablenum);\r
+  free_utf_tbl();\r
+  if (lang) free(lang);\r
+  if (wordchars) free(wordchars);\r
+  if (wordchars_utf16) free(wordchars_utf16);\r
+  if (ignorechars) free(ignorechars);\r
+  if (ignorechars_utf16) free(ignorechars_utf16);\r
+  if (version) free(version);\r
+  if (derived) free(derived);\r
+  checknum=0;\r
+}\r
+\r
+\r
+// read in aff file and build up prefix and suffix entry objects \r
+int  AffixMgr::parse_file(const char * affpath)\r
+{\r
+\r
+  // io buffers\r
+  char line[MAXLNLEN+1];\r
\r
+  // affix type\r
+  char ft;\r
+  \r
+  // checking flag duplication\r
+  char dupflags[CONTSIZE];\r
+  char dupflags_ini = 1;\r
+\r
+  // first line indicator for removing byte order mark\r
+  int firstline = 1;\r
+  \r
+  // open the affix file\r
+  FILE * afflst;\r
+  afflst = fopen(affpath,"r");\r
+  if (!afflst) {\r
+    HUNSPELL_WARNING(stderr, "error: could not open affix description file %s\n",affpath);\r
+    return 1;\r
+  }\r
+\r
+  // step one is to parse the affix file building up the internal\r
+  // affix data structures\r
+\r
+\r
+    // read in each line ignoring any that do not\r
+    // start with a known line type indicator\r
+    while (fgets(line,MAXLNLEN,afflst)) {\r
+       mychomp(line);\r
+\r
+       /* remove byte order mark */\r
+       if (firstline) {\r
+         firstline = 0;\r
+         if (strncmp(line,"",3) == 0) {\r
+            memmove(line, line+3, strlen(line+3)+1);\r
+            HUNSPELL_WARNING(stderr, "warning: affix file begins with byte order mark: possible incompatibility with old Hunspell versions\n");\r
+         }\r
+       }\r
+\r
+       /* parse in the try string */\r
+       if (strncmp(line,"TRY",3) == 0) {\r
+          if (parse_string(line, &trystring, "TRY")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the name of the character set used by the .dict and .aff */\r
+       if (strncmp(line,"SET",3) == 0) {\r
+          if (parse_string(line, &encoding, "SET")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+          if (strcmp(encoding, "UTF-8") == 0) {\r
+             utf8 = 1;\r
+#ifndef OPENOFFICEORG\r
+#ifndef MOZILLA_CLIENT\r
+             if (initialize_utf_tbl()) return 1;\r
+#endif\r
+#endif\r
+          }\r
+       }\r
+\r
+       /* parse COMPLEXPREFIXES for agglutinative languages with right-to-left writing system */\r
+       if (strncmp(line,"COMPLEXPREFIXES",15) == 0)\r
+                   complexprefixes = 1;\r
+\r
+       /* parse in the flag used by the controlled compound words */\r
+       if (strncmp(line,"COMPOUNDFLAG",12) == 0) {\r
+          if (parse_flag(line, &compoundflag, "COMPOUNDFLAG")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by compound words */\r
+       if (strncmp(line,"COMPOUNDBEGIN",13) == 0) {\r
+          if (complexprefixes) {\r
+            if (parse_flag(line, &compoundend, "COMPOUNDBEGIN")) {\r
+              fclose(afflst);\r
+              return 1;\r
+            }\r
+          } else {\r
+            if (parse_flag(line, &compoundbegin, "COMPOUNDBEGIN")) {\r
+              fclose(afflst);\r
+              return 1;\r
+            }\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by compound words */\r
+       if (strncmp(line,"COMPOUNDMIDDLE",14) == 0) {\r
+          if (parse_flag(line, &compoundmiddle, "COMPOUNDMIDDLE")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+       /* parse in the flag used by compound words */\r
+       if (strncmp(line,"COMPOUNDEND",11) == 0) {\r
+          if (complexprefixes) {\r
+            if (parse_flag(line, &compoundbegin, "COMPOUNDEND")) {\r
+              fclose(afflst);\r
+              return 1;\r
+            }\r
+          } else {\r
+            if (parse_flag(line, &compoundend, "COMPOUNDEND")) {\r
+              fclose(afflst);\r
+              return 1;\r
+            }\r
+          }\r
+       }\r
+\r
+       /* parse in the data used by compound_check() method */\r
+       if (strncmp(line,"COMPOUNDWORDMAX",15) == 0) {\r
+          if (parse_num(line, &cpdwordmax, "COMPOUNDWORDMAX")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag sign compounds in dictionary */\r
+       if (strncmp(line,"COMPOUNDROOT",12) == 0) {\r
+          if (parse_flag(line, &compoundroot, "COMPOUNDROOT")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by compound_check() method */\r
+       if (strncmp(line,"COMPOUNDPERMITFLAG",18) == 0) {\r
+          if (parse_flag(line, &compoundpermitflag, "COMPOUNDPERMITFLAG")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by compound_check() method */\r
+       if (strncmp(line,"COMPOUNDFORBIDFLAG",18) == 0) {\r
+          if (parse_flag(line, &compoundforbidflag, "COMPOUNDFORBIDFLAG")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       if (strncmp(line,"CHECKCOMPOUNDDUP",16) == 0) {\r
+                   checkcompounddup = 1;\r
+       }\r
+\r
+       if (strncmp(line,"CHECKCOMPOUNDREP",16) == 0) {\r
+                   checkcompoundrep = 1;\r
+       }\r
+\r
+       if (strncmp(line,"CHECKCOMPOUNDTRIPLE",19) == 0) {\r
+                   checkcompoundtriple = 1;\r
+       }\r
+\r
+       if (strncmp(line,"CHECKCOMPOUNDCASE",17) == 0) {\r
+                   checkcompoundcase = 1;\r
+       }\r
+\r
+       if (strncmp(line,"NOSUGGEST",9) == 0) {\r
+          if (parse_flag(line, &nosuggest, "NOSUGGEST")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by forbidden words */\r
+       if (strncmp(line,"FORBIDDENWORD",13) == 0) {\r
+          if (parse_flag(line, &forbiddenword, "FORBIDDENWORD")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by forbidden words */\r
+       if (strncmp(line,"LEMMA_PRESENT",13) == 0) {\r
+          if (parse_flag(line, &lemma_present, "LEMMA_PRESENT")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by circumfixes */\r
+       if (strncmp(line,"CIRCUMFIX",9) == 0) {\r
+          if (parse_flag(line, &circumfix, "CIRCUMFIX")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by fogemorphemes */\r
+       if (strncmp(line,"ONLYINCOMPOUND",14) == 0) {\r
+          if (parse_flag(line, &onlyincompound, "ONLYINCOMPOUND")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by `pseudoroots' */\r
+       if (strncmp(line,"PSEUDOROOT",10) == 0) {\r
+          if (parse_flag(line, &pseudoroot, "PSEUDOROOT")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by `pseudoroots' */\r
+       if (strncmp(line,"NEEDAFFIX",9) == 0) {\r
+          if (parse_flag(line, &pseudoroot, "NEEDAFFIX")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the minimal length for words in compounds */\r
+       if (strncmp(line,"COMPOUNDMIN",11) == 0) {\r
+          if (parse_num(line, &cpdmin, "COMPOUNDMIN")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+          if (cpdmin < 1) cpdmin = 1;\r
+       }\r
+\r
+       /* parse in the max. words and syllables in compounds */\r
+       if (strncmp(line,"COMPOUNDSYLLABLE",16) == 0) {\r
+          if (parse_cpdsyllable(line)) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by compound_check() method */\r
+       if (strncmp(line,"SYLLABLENUM",11) == 0) {\r
+          if (parse_string(line, &cpdsyllablenum, "SYLLABLENUM")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the flag used by the controlled compound words */\r
+       if (strncmp(line,"CHECKNUM",8) == 0) {\r
+           checknum=1;\r
+       }\r
+\r
+       /* parse in the extra word characters */\r
+       if (strncmp(line,"WORDCHARS",9) == 0) {\r
+          if (parse_array(line, &wordchars, &wordchars_utf16, &wordchars_utf16_len, "WORDCHARS", utf8)) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the ignored characters (for example, Arabic optional diacretics charachters */\r
+       if (strncmp(line,"IGNORE",6) == 0) {\r
+          if (parse_array(line, &ignorechars, &ignorechars_utf16, &ignorechars_utf16_len, "IGNORE", utf8)) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the typical fault correcting table */\r
+       if (strncmp(line,"REP",3) == 0) {\r
+          if (parse_reptable(line, afflst)) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the checkcompoundpattern table */\r
+       if (strncmp(line,"CHECKCOMPOUNDPATTERN",20) == 0) {\r
+          if (parse_checkcpdtable(line, afflst)) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the defcompound table */\r
+       if (strncmp(line,"COMPOUNDRULE",12) == 0) {\r
+          if (parse_defcpdtable(line, afflst)) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the related character map table */\r
+       if (strncmp(line,"MAP",3) == 0) {\r
+          if (parse_maptable(line, afflst)) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the word breakpoints table */\r
+       if (strncmp(line,"BREAK",5) == 0) {\r
+          if (parse_breaktable(line, afflst)) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       /* parse in the language for language specific codes */\r
+       if (strncmp(line,"LANG",4) == 0) {\r
+          if (parse_string(line, &lang, "LANG")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+          langnum = get_lang_num(lang);\r
+       }\r
+\r
+       if (strncmp(line,"VERSION",7) == 0) {\r
+          if (parse_string(line, &version, "VERSION")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       if (strncmp(line,"MAXNGRAMSUGS",12) == 0) {\r
+          if (parse_num(line, &maxngramsugs, "MAXNGRAMSUGS")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       if (strncmp(line,"NOSPLITSUGS",11) == 0) {\r
+                   nosplitsugs=1;\r
+       }\r
+\r
+       if (strncmp(line,"SUGSWITHDOTS",12) == 0) {\r
+                   sugswithdots=1;\r
+       }\r
+\r
+       /* parse in the flag used by forbidden words */\r
+       if (strncmp(line,"KEEPCASE",8) == 0) {\r
+          if (parse_flag(line, &keepcase, "KEEPCASE")) {\r
+             fclose(afflst);\r
+             return 1;\r
+          }\r
+       }\r
+\r
+       if (strncmp(line,"CHECKSHARPS",11) == 0) {\r
+                   checksharps=1;\r
+       }\r
+\r
+       /* parse this affix: P - prefix, S - suffix */\r
+       ft = ' ';\r
+       if (strncmp(line,"PFX",3) == 0) ft = complexprefixes ? 'S' : 'P';\r
+       if (strncmp(line,"SFX",3) == 0) ft = complexprefixes ? 'P' : 'S';\r
+       if (ft != ' ') {\r
+          if (dupflags_ini) {\r
+            for (int i = 0; i < CONTSIZE; i++) dupflags[i] = 0;\r
+            dupflags_ini = 0;\r
+          }\r
+          if (parse_affix(line, ft, afflst, dupflags)) {\r
+             fclose(afflst);\r
+             process_pfx_tree_to_list();\r
+             process_sfx_tree_to_list();\r
+             return 1;\r
+          }\r
+       }\r
+\r
+    }\r
+    fclose(afflst);\r
+\r
+    // convert affix trees to sorted list\r
+    process_pfx_tree_to_list();\r
+    process_sfx_tree_to_list();\r
+\r
+    // now we can speed up performance greatly taking advantage of the \r
+    // relationship between the affixes and the idea of "subsets".\r
+\r
+    // View each prefix as a potential leading subset of another and view\r
+    // each suffix (reversed) as a potential trailing subset of another.\r
+\r
+    // To illustrate this relationship if we know the prefix "ab" is found in the\r
+    // word to examine, only prefixes that "ab" is a leading subset of need be examined.\r
+    // Furthermore is "ab" is not present then none of the prefixes that "ab" is\r
+    // is a subset need be examined.\r
+    // The same argument goes for suffix string that are reversed.\r
+\r
+    // Then to top this off why not examine the first char of the word to quickly\r
+    // limit the set of prefixes to examine (i.e. the prefixes to examine must \r
+    // be leading supersets of the first character of the word (if they exist)\r
\r
+    // To take advantage of this "subset" relationship, we need to add two links\r
+    // from entry.  One to take next if the current prefix is found (call it nexteq)\r
+    // and one to take next if the current prefix is not found (call it nextne).\r
+\r
+    // Since we have built ordered lists, all that remains is to properly intialize \r
+    // the nextne and nexteq pointers that relate them\r
+\r
+    process_pfx_order();\r
+    process_sfx_order();\r
+\r
+    // expand wordchars string, based on csutil (for external tokenization)\r
+\r
+    char * enc = get_encoding();\r
+    csconv = get_current_cs(enc);\r
+    free(enc);\r
+    enc = NULL;\r
+\r
+    char expw[MAXLNLEN];\r
+    if (wordchars) {\r
+        strcpy(expw, wordchars);\r
+        free(wordchars);\r
+    } else *expw = '\0';\r
+\r
+    for (int i = 0; i <= 255; i++) {\r
+        if ( (csconv[i].cupper != csconv[i].clower) &&\r
+            (! strchr(expw, (char) i))) {\r
+                *(expw + strlen(expw) + 1) = '\0';\r
+                *(expw + strlen(expw)) = (char) i;\r
+        }\r
+    }\r
+\r
+    wordchars = mystrdup(expw);\r
+\r
+    // temporary BREAK definition for German dash handling (OOo issue 64400)\r
+    if ((langnum == LANG_de) && (!breaktable)) {\r
+        breaktable = (char **) malloc(sizeof(char *));\r
+        if (!breaktable) return 1;\r
+        breaktable[0] = mystrdup("-");\r
+        numbreak = 1;\r
+    }\r
+    return 0;\r
+}\r
+\r
+\r
+// we want to be able to quickly access prefix information\r
+// both by prefix flag, and sorted by prefix string itself \r
+// so we need to set up two indexes\r
+\r
+int AffixMgr::build_pfxtree(AffEntry* pfxptr)\r
+{\r
+  PfxEntry * ptr;\r
+  PfxEntry * pptr;\r
+  PfxEntry * ep = (PfxEntry*) pfxptr;\r
+\r
+  // get the right starting points\r
+  const char * key = ep->getKey();\r
+  const unsigned char flg = (unsigned char) (ep->getFlag() & 0x00FF);\r
+\r
+  // first index by flag which must exist\r
+  ptr = (PfxEntry*)pFlag[flg];\r
+  ep->setFlgNxt(ptr);\r
+  pFlag[flg] = (AffEntry *) ep;\r
+\r
+\r
+  // handle the special case of null affix string\r
+  if (strlen(key) == 0) {\r
+    // always inset them at head of list at element 0\r
+     ptr = (PfxEntry*)pStart[0];\r
+     ep->setNext(ptr);\r
+     pStart[0] = (AffEntry*)ep;\r
+     return 0;\r
+  }\r
+\r
+  // now handle the normal case\r
+  ep->setNextEQ(NULL);\r
+  ep->setNextNE(NULL);\r
+\r
+  unsigned char sp = *((const unsigned char *)key);\r
+  ptr = (PfxEntry*)pStart[sp];\r
+  \r
+  // handle the first insert \r
+  if (!ptr) {\r
+     pStart[sp] = (AffEntry*)ep;\r
+     return 0;\r
+  }\r
+\r
+\r
+  // otherwise use binary tree insertion so that a sorted\r
+  // list can easily be generated later\r
+  pptr = NULL;\r
+  for (;;) {\r
+    pptr = ptr;\r
+    if (strcmp(ep->getKey(), ptr->getKey() ) <= 0) {\r
+       ptr = ptr->getNextEQ();\r
+       if (!ptr) {\r
+          pptr->setNextEQ(ep);\r
+          break;\r
+       }\r
+    } else {\r
+       ptr = ptr->getNextNE();\r
+       if (!ptr) {\r
+          pptr->setNextNE(ep);\r
+          break;\r
+       }\r
+    }\r
+  }\r
+  return 0;\r
+}\r
+\r
+// we want to be able to quickly access suffix information\r
+// both by suffix flag, and sorted by the reverse of the\r
+// suffix string itself; so we need to set up two indexes\r
+int AffixMgr::build_sfxtree(AffEntry* sfxptr)\r
+{\r
+  SfxEntry * ptr;\r
+  SfxEntry * pptr;\r
+  SfxEntry * ep = (SfxEntry *) sfxptr;\r
+\r
+  /* get the right starting point */\r
+  const char * key = ep->getKey();\r
+  const unsigned char flg = (unsigned char) (ep->getFlag() & 0x00FF);\r
+\r
+  // first index by flag which must exist\r
+  ptr = (SfxEntry*)sFlag[flg];\r
+  ep->setFlgNxt(ptr);\r
+  sFlag[flg] = (AffEntry *) ep;\r
+\r
+  // next index by affix string\r
+\r
+  // handle the special case of null affix string\r
+  if (strlen(key) == 0) {\r
+    // always inset them at head of list at element 0\r
+     ptr = (SfxEntry*)sStart[0];\r
+     ep->setNext(ptr);\r
+     sStart[0] = (AffEntry*)ep;\r
+     return 0;\r
+  }\r
+\r
+  // now handle the normal case\r
+  ep->setNextEQ(NULL);\r
+  ep->setNextNE(NULL);\r
+\r
+  unsigned char sp = *((const unsigned char *)key);\r
+  ptr = (SfxEntry*)sStart[sp];\r
+  \r
+  // handle the first insert \r
+  if (!ptr) {\r
+     sStart[sp] = (AffEntry*)ep;\r
+     return 0;\r
+  }\r
+\r
+  // otherwise use binary tree insertion so that a sorted\r
+  // list can easily be generated later\r
+  pptr = NULL;\r
+  for (;;) {\r
+    pptr = ptr;\r
+    if (strcmp(ep->getKey(), ptr->getKey() ) <= 0) {\r
+       ptr = ptr->getNextEQ();\r
+       if (!ptr) {\r
+          pptr->setNextEQ(ep);\r
+          break;\r
+       }\r
+    } else {\r
+       ptr = ptr->getNextNE();\r
+       if (!ptr) {\r
+          pptr->setNextNE(ep);\r
+          break;\r
+       }\r
+    }\r
+  }\r
+  return 0;\r
+}\r
+\r
+// convert from binary tree to sorted list\r
+int AffixMgr::process_pfx_tree_to_list()\r
+{\r
+  for (int i=1; i< SETSIZE; i++) {\r
+    pStart[i] = process_pfx_in_order(pStart[i],NULL);\r
+  }\r
+  return 0;\r
+}\r
+\r
+\r
+AffEntry* AffixMgr::process_pfx_in_order(AffEntry* ptr, AffEntry* nptr)\r
+{\r
+  if (ptr) {\r
+    nptr = process_pfx_in_order(((PfxEntry*) ptr)->getNextNE(), nptr);\r
+    ((PfxEntry*) ptr)->setNext((PfxEntry*) nptr);\r
+    nptr = process_pfx_in_order(((PfxEntry*) ptr)->getNextEQ(), ptr);\r
+  }\r
+  return nptr;\r
+}\r
+\r
+\r
+// convert from binary tree to sorted list\r
+int AffixMgr:: process_sfx_tree_to_list()\r
+{\r
+  for (int i=1; i< SETSIZE; i++) {\r
+    sStart[i] = process_sfx_in_order(sStart[i],NULL);\r
+  }\r
+  return 0;\r
+}\r
+\r
+AffEntry* AffixMgr::process_sfx_in_order(AffEntry* ptr, AffEntry* nptr)\r
+{\r
+  if (ptr) {\r
+    nptr = process_sfx_in_order(((SfxEntry*) ptr)->getNextNE(), nptr);\r
+    ((SfxEntry*) ptr)->setNext((SfxEntry*) nptr);\r
+    nptr = process_sfx_in_order(((SfxEntry*) ptr)->getNextEQ(), ptr);\r
+  }\r
+  return nptr;\r
+}\r
+\r
+\r
+// reinitialize the PfxEntry links NextEQ and NextNE to speed searching\r
+// using the idea of leading subsets this time\r
+int AffixMgr::process_pfx_order()\r
+{\r
+    PfxEntry* ptr;\r
+\r
+    // loop through each prefix list starting point\r
+    for (int i=1; i < SETSIZE; i++) {\r
+\r
+         ptr = (PfxEntry*)pStart[i];\r
+\r
+         // look through the remainder of the list\r
+         //  and find next entry with affix that \r
+         // the current one is not a subset of\r
+         // mark that as destination for NextNE\r
+         // use next in list that you are a subset\r
+         // of as NextEQ\r
+\r
+         for (; ptr != NULL; ptr = ptr->getNext()) {\r
+\r
+             PfxEntry * nptr = ptr->getNext();\r
+             for (; nptr != NULL; nptr = nptr->getNext()) {\r
+                 if (! isSubset( ptr->getKey() , nptr->getKey() )) break;\r
+             }\r
+             ptr->setNextNE(nptr);\r
+             ptr->setNextEQ(NULL);\r
+             if ((ptr->getNext()) && isSubset(ptr->getKey() , (ptr->getNext())->getKey())) \r
+                 ptr->setNextEQ(ptr->getNext());\r
+         }\r
+\r
+         // now clean up by adding smart search termination strings:\r
+         // if you are already a superset of the previous prefix\r
+         // but not a subset of the next, search can end here\r
+         // so set NextNE properly\r
+\r
+         ptr = (PfxEntry *) pStart[i];\r
+         for (; ptr != NULL; ptr = ptr->getNext()) {\r
+             PfxEntry * nptr = ptr->getNext();\r
+             PfxEntry * mptr = NULL;\r
+             for (; nptr != NULL; nptr = nptr->getNext()) {\r
+                 if (! isSubset(ptr->getKey(),nptr->getKey())) break;\r
+                 mptr = nptr;\r
+             }\r
+             if (mptr) mptr->setNextNE(NULL);\r
+         }\r
+    }\r
+    return 0;\r
+}\r
+\r
+// initialize the SfxEntry links NextEQ and NextNE to speed searching\r
+// using the idea of leading subsets this time\r
+int AffixMgr::process_sfx_order()\r
+{\r
+    SfxEntry* ptr;\r
+\r
+    // loop through each prefix list starting point\r
+    for (int i=1; i < SETSIZE; i++) {\r
+\r
+         ptr = (SfxEntry *) sStart[i];\r
+\r
+         // look through the remainder of the list\r
+         //  and find next entry with affix that \r
+         // the current one is not a subset of\r
+         // mark that as destination for NextNE\r
+         // use next in list that you are a subset\r
+         // of as NextEQ\r
+\r
+         for (; ptr != NULL; ptr = ptr->getNext()) {\r
+             SfxEntry * nptr = ptr->getNext();\r
+             for (; nptr != NULL; nptr = nptr->getNext()) {\r
+                 if (! isSubset(ptr->getKey(),nptr->getKey())) break;\r
+             }\r
+             ptr->setNextNE(nptr);\r
+             ptr->setNextEQ(NULL);\r
+             if ((ptr->getNext()) && isSubset(ptr->getKey(),(ptr->getNext())->getKey())) \r
+                 ptr->setNextEQ(ptr->getNext());\r
+         }\r
+\r
+\r
+         // now clean up by adding smart search termination strings:\r
+         // if you are already a superset of the previous suffix\r
+         // but not a subset of the next, search can end here\r
+         // so set NextNE properly\r
+\r
+         ptr = (SfxEntry *) sStart[i];\r
+         for (; ptr != NULL; ptr = ptr->getNext()) {\r
+             SfxEntry * nptr = ptr->getNext();\r
+             SfxEntry * mptr = NULL;\r
+             for (; nptr != NULL; nptr = nptr->getNext()) {\r
+                 if (! isSubset(ptr->getKey(),nptr->getKey())) break;\r
+                 mptr = nptr;\r
+             }\r
+             if (mptr) mptr->setNextNE(NULL);\r
+         }\r
+    }\r
+    return 0;\r
+}\r
+\r
+\r
+\r
+// takes aff file condition string and creates the\r
+// conds array - please see the appendix at the end of the\r
+// file affentry.cxx which describes what is going on here\r
+// in much more detail\r
+\r
+int AffixMgr::encodeit(struct affentry * ptr, char * cs)\r
+{\r
+  unsigned char c;\r
+  int i, j, k;\r
+  unsigned char mbr[MAXLNLEN];\r
+  w_char wmbr[MAXLNLEN];\r
+  w_char * wpos = wmbr;\r
+\r
+  // now clear the conditions array */\r
+  for (i=0;i<SETSIZE;i++) ptr->conds.base[i] = (unsigned char) 0;\r
+\r
+  // now parse the string to create the conds array */\r
+  int nc = strlen(cs);\r
+  unsigned char neg = 0;   // complement indicator\r
+  int grp = 0;   // group indicator\r
+  unsigned char n = 0;     // number of conditions\r
+  int ec = 0;    // end condition indicator\r
+  int nm = 0;    // number of member in group\r
+\r
+  // if no condition just return\r
+  if (strcmp(cs,".")==0) {\r
+    ptr->numconds = 0;\r
+    return 0;\r
+  }\r
+\r
+  i = 0;\r
+  while (i < nc) {\r
+    c = *((unsigned char *)(cs + i));\r
+\r
+    // start group indicator\r
+    if (c == '[') {\r
+       grp = 1;\r
+       c = 0;\r
+    }\r
+\r
+    // complement flag\r
+    if ((grp == 1) && (c == '^')) {\r
+       neg = 1;\r
+       c = 0;\r
+    }\r
+\r
+    // end goup indicator\r
+    if (c == ']') {\r
+       ec = 1;\r
+       c = 0;\r
+    }\r
+\r
+    // add character of group to list\r
+    if ((grp == 1) && (c != 0)) {\r
+      *(mbr + nm) = c;\r
+      nm++;\r
+      c = 0;\r
+    }\r
+\r
+    // end of condition \r
+    if (c != 0) {\r
+       ec = 1;\r
+    }\r
+\r
+  if (ec) {    \r
+    if (!utf8) {\r
+      if (grp == 1) {\r
+        if (neg == 0) {\r
+          // set the proper bits in the condition array vals for those chars\r
+          for (j=0;j<nm;j++) {\r
+             k = (unsigned int) mbr[j];\r
+             ptr->conds.base[k] = ptr->conds.base[k] | ((unsigned char)1 << n);\r
+          }\r
+        } else {\r
+          // complement so set all of them and then unset indicated ones\r
+           for (j=0;j<SETSIZE;j++) ptr->conds.base[j] = ptr->conds.base[j] | ((unsigned char)1 << n);\r
+           for (j=0;j<nm;j++) {\r
+             k = (unsigned int) mbr[j];\r
+             ptr->conds.base[k] = ptr->conds.base[k] & ~((unsigned char)1 << n);\r
+           }\r
+        }\r
+        neg = 0;\r
+        grp = 0;   \r
+        nm = 0;\r
+      } else {\r
+         // not a group so just set the proper bit for this char\r
+         // but first handle special case of . inside condition\r
+         if (c == '.') {\r
+            // wild card character so set them all\r
+            for (j=0;j<SETSIZE;j++) ptr->conds.base[j] = ptr->conds.base[j] | ((unsigned char)1 << n);\r
+         } else {  \r
+            ptr->conds.base[(unsigned int) c] = ptr->conds.base[(unsigned int)c] | ((unsigned char)1 << n);\r
+         }\r
+      }\r
+      n++;\r
+      ec = 0;\r
+    } else { // UTF-8 character set\r
+      if (grp == 1) {\r
+        ptr->conds.utf8.neg[n] = neg;\r
+        if (neg == 0) {\r
+          // set the proper bits in the condition array vals for those chars\r
+          for (j=0;j<nm;j++) {\r
+             k = (unsigned int) mbr[j];\r
+             if (k >> 7) {\r
+                u8_u16(wpos, 1, (char *) mbr + j);\r
+                wpos++;\r
+                if ((k & 0xe0) == 0xe0) j+=2; else j++; // 3-byte UTF-8 character\r
+             } else {\r
+                ptr->conds.utf8.ascii[k] = ptr->conds.utf8.ascii[k] | ((unsigned char)1 << n);\r
+             }\r
+          }\r
+        } else { // neg == 1\r
+          // complement so set all of them and then unset indicated ones\r
+           for (j=0;j<(SETSIZE/2);j++) ptr->conds.utf8.ascii[j] = ptr->conds.utf8.ascii[j] | ((unsigned char)1 << n);\r
+           for (j=0;j<nm;j++) {\r
+             k = (unsigned int) mbr[j];\r
+             if (k >> 7) {\r
+                u8_u16(wpos, 1, (char *) mbr + j);\r
+                wpos++;\r
+                if ((k & 0xe0) == 0xe0) j+=2; else j++; // 3-byte UTF-8 character\r
+             } else {\r
+                ptr->conds.utf8.ascii[k] = ptr->conds.utf8.ascii[k] & ~((unsigned char)1 << n);\r
+             }\r
+           }\r
+        }\r
+        neg = 0;\r
+        grp = 0;   \r
+        nm = 0;\r
+        ptr->conds.utf8.wlen[n] = wpos - wmbr;\r
+        if ((wpos - wmbr) != 0) {\r
+            ptr->conds.utf8.wchars[n] = (w_char *) malloc(sizeof(w_char) * (wpos - wmbr));\r
+            if (!ptr->conds.utf8.wchars[n]) return 1;\r
+            memcpy(ptr->conds.utf8.wchars[n], wmbr, sizeof(w_char) * (wpos - wmbr));\r
+            flag_qsort((unsigned short *) ptr->conds.utf8.wchars[n], 0, ptr->conds.utf8.wlen[n]);\r
+            wpos = wmbr;\r
+        }\r
+      } else { // grp == 0\r
+         // is UTF-8 character?\r
+         if (c >> 7) {\r
+            ptr->conds.utf8.wchars[n] = (w_char *) malloc(sizeof(w_char));\r
+            if (!ptr->conds.utf8.wchars[n]) return 1;\r
+            ptr->conds.utf8.wlen[n] = 1;\r
+            u8_u16(ptr->conds.utf8.wchars[n], 1, cs + i);\r
+            if ((c & 0xe0) == 0xe0) i+=2; else i++; // 3-byte UFT-8 character\r
+         } else {\r
+            ptr->conds.utf8.wchars[n] = NULL;\r
+            // not a group so just set the proper bit for this char\r
+            // but first handle special case of . inside condition\r
+            if (c == '.') {\r
+                ptr->conds.utf8.all[n] = 1;\r
+                // wild card character so set them all\r
+                for (j=0;j<(SETSIZE/2);j++) ptr->conds.utf8.ascii[j] = ptr->conds.utf8.ascii[j] | ((unsigned char)1 << n);\r
+            } else {\r
+                ptr->conds.utf8.all[n] = 0;\r
+                ptr->conds.utf8.ascii[(unsigned int) c] = ptr->conds.utf8.ascii[(unsigned int)c] | ((unsigned char)1 << n);\r
+            }\r
+         }\r
+         neg = 0;\r
+      }\r
+      n++;\r
+      ec = 0;\r
+      neg = 0;\r
+    }  \r
+  }\r
+\r
+    i++;\r
+  }\r
+  ptr->numconds = n;\r
+  return 0;\r
+}\r
+\r
+ // return 1 if s1 is a leading subset of s2\r
+/* inline int AffixMgr::isSubset(const char * s1, const char * s2)\r
+ {\r
+    while ((*s1 == *s2) && *s1) {\r
+        s1++;\r
+        s2++;\r
+    }\r
+    return (*s1 == '\0');\r
+ }\r
+*/\r
+\r
+ // return 1 if s1 is a leading subset of s2 (dots are for infixes)\r
+inline int AffixMgr::isSubset(const char * s1, const char * s2)\r
+ {\r
+    while (((*s1 == *s2) || (*s1 == '.')) && (*s1 != '\0')) {\r
+        s1++;\r
+        s2++;\r
+    }\r
+    return (*s1 == '\0');\r
+ }\r
+\r
+\r
+// check word for prefixes\r
+struct hentry * AffixMgr::prefix_check(const char * word, int len, char in_compound,\r
+    const FLAG needflag)\r
+{\r
+    struct hentry * rv= NULL;\r
+\r
+    pfx = NULL;\r
+    pfxappnd = NULL;\r
+    sfxappnd = NULL;\r
+    \r
+    // first handle the special case of 0 length prefixes\r
+    PfxEntry * pe = (PfxEntry *) pStart[0];\r
+    while (pe) {\r
+        if (\r
+            // fogemorpheme\r
+              ((in_compound != IN_CPD_NOT) || !(pe->getCont() &&\r
+                  (TESTAFF(pe->getCont(), onlyincompound, pe->getContLen())))) &&\r
+            // permit prefixes in compounds\r
+              ((in_compound != IN_CPD_END) || (pe->getCont() &&\r
+                  (TESTAFF(pe->getCont(), compoundpermitflag, pe->getContLen()))))\r
+              ) {\r
+                    // check prefix\r
+                    rv = pe->checkword(word, len, in_compound, needflag);\r
+                    if (rv) {\r
+                        pfx=(AffEntry *)pe; // BUG: pfx not stateless\r
+                        return rv;\r
+                    }\r
+             }\r
+       pe = pe->getNext();\r
+    }\r
+  \r
+    // now handle the general case\r
+    unsigned char sp = *((const unsigned char *)word);\r
+    PfxEntry * pptr = (PfxEntry *)pStart[sp];\r
+\r
+    while (pptr) {\r
+        if (isSubset(pptr->getKey(),word)) {\r
+             if (\r
+            // fogemorpheme\r
+              ((in_compound != IN_CPD_NOT) || !(pptr->getCont() &&\r
+                  (TESTAFF(pptr->getCont(), onlyincompound, pptr->getContLen())))) &&\r
+            // permit prefixes in compounds\r
+              ((in_compound != IN_CPD_END) || (pptr->getCont() &&\r
+                  (TESTAFF(pptr->getCont(), compoundpermitflag, pptr->getContLen()))))\r
+              ) {\r
+            // check prefix\r
+                  rv = pptr->checkword(word, len, in_compound, needflag);\r
+                  if (rv) {\r
+                    pfx=(AffEntry *)pptr; // BUG: pfx not stateless\r
+                    return rv;\r
+                  }\r
+             }\r
+             pptr = pptr->getNextEQ();\r
+        } else {\r
+             pptr = pptr->getNextNE();\r
+        }\r
+    }\r
+    \r
+    return NULL;\r
+}\r
+\r
+// check word for prefixes\r
+struct hentry * AffixMgr::prefix_check_twosfx(const char * word, int len,\r
+    char in_compound, const FLAG needflag)\r
+{\r
+    struct hentry * rv= NULL;\r
+\r
+    pfx = NULL;\r
+    sfxappnd = NULL;\r
+    \r
+    // first handle the special case of 0 length prefixes\r
+    PfxEntry * pe = (PfxEntry *) pStart[0];\r
+    \r
+    while (pe) {\r
+        rv = pe->check_twosfx(word, len, in_compound, needflag);\r
+        if (rv) return rv;\r
+        pe = pe->getNext();\r
+    }\r
+  \r
+    // now handle the general case\r
+    unsigned char sp = *((const unsigned char *)word);\r
+    PfxEntry * pptr = (PfxEntry *)pStart[sp];\r
+\r
+    while (pptr) {\r
+        if (isSubset(pptr->getKey(),word)) {\r
+            rv = pptr->check_twosfx(word, len, in_compound, needflag);\r
+            if (rv) {\r
+                pfx = (AffEntry *)pptr;\r
+                return rv;\r
+            }\r
+            pptr = pptr->getNextEQ();\r
+        } else {\r
+             pptr = pptr->getNextNE();\r
+        }\r
+    }\r
+    \r
+    return NULL;\r
+}\r
+\r
+#ifdef HUNSPELL_EXPERIMENTAL\r
+// check word for prefixes\r
+char * AffixMgr::prefix_check_morph(const char * word, int len, char in_compound,\r
+    const FLAG needflag)\r
+{\r
+    char * st;\r
+\r
+    char result[MAXLNLEN];\r
+    result[0] = '\0';\r
+\r
+    pfx = NULL;\r
+    sfxappnd = NULL;\r
+    \r
+    // first handle the special case of 0 length prefixes\r
+    PfxEntry * pe = (PfxEntry *) pStart[0];\r
+    while (pe) {\r
+       st = pe->check_morph(word,len,in_compound, needflag);\r
+       if (st) {\r
+            strcat(result, st);\r
+            free(st);\r
+       }\r
+       // if (rv) return rv;\r
+       pe = pe->getNext();\r
+    }\r
+  \r
+    // now handle the general case\r
+    unsigned char sp = *((const unsigned char *)word);\r
+    PfxEntry * pptr = (PfxEntry *)pStart[sp];\r
+\r
+    while (pptr) {\r
+        if (isSubset(pptr->getKey(),word)) {\r
+            st = pptr->check_morph(word,len,in_compound, needflag);\r
+            if (st) {\r
+              // fogemorpheme\r
+              if ((in_compound != IN_CPD_NOT) || !((pptr->getCont() && \r
+                        (TESTAFF(pptr->getCont(), onlyincompound, pptr->getContLen()))))) {\r
+                    strcat(result, st);\r
+                    pfx = (AffEntry *)pptr;\r
+                }\r
+                free(st);\r
+            }\r
+            pptr = pptr->getNextEQ();\r
+        } else {\r
+            pptr = pptr->getNextNE();\r
+        }\r
+    }\r
+    \r
+    if (*result) return mystrdup(result);\r
+    return NULL;\r
+}\r
+\r
+\r
+// check word for prefixes\r
+char * AffixMgr::prefix_check_twosfx_morph(const char * word, int len,\r
+    char in_compound, const FLAG needflag)\r
+{\r
+    char * st;\r
+\r
+    char result[MAXLNLEN];\r
+    result[0] = '\0';\r
+\r
+    pfx = NULL;\r
+    sfxappnd = NULL;\r
+    \r
+    // first handle the special case of 0 length prefixes\r
+    PfxEntry * pe = (PfxEntry *) pStart[0];\r
+    while (pe) {\r
+        st = pe->check_twosfx_morph(word,len,in_compound, needflag);\r
+        if (st) {\r
+            strcat(result, st);\r
+            free(st);\r
+        }\r
+        pe = pe->getNext();\r
+    }\r
+  \r
+    // now handle the general case\r
+    unsigned char sp = *((const unsigned char *)word);\r
+    PfxEntry * pptr = (PfxEntry *)pStart[sp];\r
+\r
+    while (pptr) {\r
+        if (isSubset(pptr->getKey(),word)) {\r
+            st = pptr->check_twosfx_morph(word, len, in_compound, needflag);\r
+            if (st) {\r
+                strcat(result, st);\r
+                free(st);\r
+                pfx = (AffEntry *)pptr;\r
+            }\r
+            pptr = pptr->getNextEQ();\r
+        } else {\r
+            pptr = pptr->getNextNE();\r
+        }\r
+    }\r
+    \r
+    if (*result) return mystrdup(result);\r
+    return NULL;\r
+}\r
+#endif // END OF HUNSPELL_EXPERIMENTAL CODE\r
+\r
+\r
+// Is word a non compound with a REP substitution (see checkcompoundrep)?\r
+int AffixMgr::cpdrep_check(const char * word, int wl)\r
+{\r
+  char candidate[MAXLNLEN];\r
+  const char * r;\r
+  int lenr, lenp;\r
+\r
+  if ((wl < 2) || !numrep) return 0;\r
+\r
+  for (int i=0; i < numrep; i++ ) {\r
+      r = word;\r
+      lenr = strlen(reptable[i].pattern2);\r
+      lenp = strlen(reptable[i].pattern);\r
+      // search every occurence of the pattern in the word\r
+      while ((r=strstr(r, reptable[i].pattern)) != NULL) {\r
+          strcpy(candidate, word);\r
+          if (r-word + lenr + strlen(r+lenp) >= MAXLNLEN) break;\r
+          strcpy(candidate+(r-word),reptable[i].pattern2);\r
+          strcpy(candidate+(r-word)+lenr, r+lenp);\r
+          if (candidate_check(candidate,strlen(candidate))) return 1;\r
+          r++; // search for the next letter\r
+      }\r
+   }\r
+   return 0;\r
+}\r
+\r
+// forbid compoundings when there are special patterns at word bound\r
+int AffixMgr::cpdpat_check(const char * word, int pos)\r
+{\r
+  int len;\r
+  for (int i = 0; i < numcheckcpd; i++) {\r
+      if (isSubset(checkcpdtable[i].pattern2, word + pos) &&\r
+        (len = strlen(checkcpdtable[i].pattern)) && (pos > len) &&\r
+        (strncmp(word + pos - len, checkcpdtable[i].pattern, len) == 0)) return 1;\r
+  }\r
+  return 0;\r
+}\r
+\r
+// forbid compounding with neighbouring upper and lower case characters at word bounds\r
+int AffixMgr::cpdcase_check(const char * word, int pos)\r
+{\r
+  if (utf8) {\r
+      w_char u, w;\r
+      const char * p;\r
+      u8_u16(&u, 1, word + pos);\r
+      for (p = word + pos - 1; (*p & 0xc0) == 0x80; p--);\r
+      u8_u16(&w, 1, p);\r
+      unsigned short a = (u.h << 8) + u.l;\r
+      unsigned short b = (w.h << 8) + w.l;\r
+      if (((unicodetoupper(a, langnum) == a) || (unicodetoupper(b, langnum) == b))) return 1;\r
+  } else {\r
+      unsigned char a = *(word + pos - 1);\r
+      unsigned char b = *(word + pos);\r
+      if ((csconv[a].ccase || csconv[b].ccase) && (a != '-') && (b != '-')) return 1;\r
+  }\r
+  return 0;\r
+}\r
+\r
+// check compound patterns\r
+int AffixMgr::defcpd_check(hentry *** words, short wnum, hentry * rv, hentry ** def, char all)\r
+{\r
+  signed short btpp[MAXWORDLEN]; // metacharacter (*, ?) positions for backtracking\r
+  signed short btwp[MAXWORDLEN]; // word positions for metacharacters\r
+  int btnum[MAXWORDLEN]; // number of matched characters in metacharacter positions\r
+  short bt = 0;  \r
+  int i;\r
+  int ok;\r
+  int w = 0;\r
+  if (!*words) {\r
+    w = 1;\r
+    *words = def;\r
+  }\r
+  (*words)[wnum] = rv;\r
+\r
+  for (i = 0; i < numdefcpd; i++) {\r
+    signed short pp = 0; // pattern position\r
+    signed short wp = 0; // "words" position\r
+    int ok2;\r
+    ok = 1;\r
+    ok2 = 1;\r
+    do {\r
+      while ((pp < defcpdtable[i].len) && (wp <= wnum)) {\r
+        if (((pp+1) < defcpdtable[i].len) &&\r
+          ((defcpdtable[i].def[pp+1] == '*') || (defcpdtable[i].def[pp+1] == '?'))) {\r
+            int wend = (defcpdtable[i].def[pp+1] == '?') ? wp : wnum;\r
+            ok2 = 1;\r
+            pp+=2;\r
+            btpp[bt] = pp;\r
+            btwp[bt] = wp;\r
+            while (wp <= wend) {\r
+                if (!(*words)[wp]->alen || \r
+                  !TESTAFF((*words)[wp]->astr, defcpdtable[i].def[pp-2], (*words)[wp]->alen)) {\r
+                    ok2 = 0;\r
+                    break;\r
+                }\r
+                wp++;\r
+            }\r
+            if (wp <= wnum) ok2 = 0;\r
+            btnum[bt] = wp - btwp[bt];\r
+            if (btnum[bt] > 0) bt++;\r
+            if (ok2) break;\r
+        } else {\r
+            ok2 = 1;\r
+            if (!(*words)[wp] || !(*words)[wp]->alen || \r
+              !TESTAFF((*words)[wp]->astr, defcpdtable[i].def[pp], (*words)[wp]->alen)) {\r
+                ok = 0;\r
+                break;\r
+            }\r
+            pp++;\r
+            wp++;\r
+            if ((defcpdtable[i].len == pp) && !(wp > wnum)) ok = 0;\r
+        }\r
+      }\r
+    if (ok && ok2) { \r
+        int r = pp;\r
+        while ((defcpdtable[i].len > r) && ((r+1) < defcpdtable[i].len) &&\r
+            ((defcpdtable[i].def[r+1] == '*') || (defcpdtable[i].def[r+1] == '?'))) r+=2;\r
+        if (defcpdtable[i].len <= r) return 1;\r
+    }    \r
+    // backtrack\r
+    if (bt) do {\r
+        ok = 1;\r
+        btnum[bt - 1]--;\r
+        pp = btpp[bt - 1];\r
+        wp = btwp[bt - 1] + btnum[bt - 1];\r
+    } while ((btnum[bt - 1] < 0) && --bt);\r
+  } while (bt);\r
+\r
+  if (ok && ok2 && (!all || (defcpdtable[i].len <= pp))) return 1; \r
+  // check zero ending\r
+  while (ok && ok2 && (defcpdtable[i].len > pp) && ((pp+1) < defcpdtable[i].len) &&\r
+    ((defcpdtable[i].def[pp+1] == '*') || (defcpdtable[i].def[pp+1] == '?'))) pp+=2;\r
+  if (ok && ok2 && (defcpdtable[i].len <= pp)) return 1;\r
+  }\r
+  (*words)[wnum] = NULL;\r
+  if (w) *words = NULL;\r
+  return 0;\r
+}\r
+\r
+inline int AffixMgr::candidate_check(const char * word, int len)\r
+{\r
+  struct hentry * rv=NULL;\r
+  \r
+  rv = lookup(word);\r
+  if (rv) return 1;\r
+\r
+//  rv = prefix_check(word,len,1);\r
+//  if (rv) return 1;\r
+  \r
+  rv = affix_check(word,len);\r
+  if (rv) return 1;\r
+  return 0;\r
+}\r
+\r
+// calculate number of syllable for compound-checking\r
+short AffixMgr::get_syllable(const char * word, int wlen)\r
+{\r
+    if (cpdmaxsyllable==0) return 0;\r
+    \r
+    short num=0;\r
+\r
+    if (!utf8) {\r
+        for (int i=0; i<wlen; i++) {\r
+            if (strchr(cpdvowels, word[i])) num++;\r
+        }\r
+    } else if (cpdvowels_utf16) {\r
+        w_char w[MAXWORDUTF8LEN];\r
+        int i = u8_u16(w, MAXWORDUTF8LEN, word);\r
+        for (; i; i--) {\r
+            if (flag_bsearch((unsigned short *) cpdvowels_utf16,\r
+                ((unsigned short *) w)[i - 1], cpdvowels_utf16_len)) num++;\r
+        }\r
+    }\r
+    return num;\r
+}\r
+\r
+// check if compound word is correctly spelled\r
+// hu_mov_rule = spec. Hungarian rule (XXX)\r
+struct hentry * AffixMgr::compound_check(const char * word, int len, \r
+    short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words = NULL,\r
+    char hu_mov_rule = 0, int * cmpdstemnum = NULL, int * cmpdstem = NULL, char is_sug = 0)\r
+{\r
+    int i; \r
+    short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2;\r
+    int oldcmpdstemnum = 0;\r
+    struct hentry * rv = NULL;\r
+    struct hentry * rv_first;\r
+    struct hentry * rwords[MAXWORDLEN]; // buffer for COMPOUND pattern checking\r
+    char st [MAXWORDUTF8LEN + 4];\r
+    char ch;\r
+    int cmin;\r
+    int cmax;\r
+    \r
+    int checked_prefix;\r
+\r
+#ifdef HUNSTEM\r
+    if (cmpdstemnum) {\r
+        if (wordnum == 0) {\r
+            *cmpdstemnum = 1;\r
+        } else {\r
+            (*cmpdstemnum)++;\r
+        }\r
+    }\r
+#endif\r
+    if (utf8) {\r
+        for (cmin = 0, i = 0; (i < cpdmin) && word[cmin]; i++) {\r
+          cmin++;\r
+          for (; (word[cmin] & 0xc0) == 0x80; cmin++);\r
+        }\r
+        for (cmax = len, i = 0; (i < (cpdmin - 1)) && cmax; i++) {\r
+          cmax--;\r
+          for (; (word[cmax] & 0xc0) == 0x80; cmax--);\r
+        }\r
+    } else {\r
+        cmin = cpdmin;\r
+        cmax = len - cpdmin + 1;\r
+    }\r
+\r
+    strcpy(st, word);\r
+\r
+    for (i = cmin; i < cmax; i++) {\r
+\r
+        oldnumsyllable = numsyllable;\r
+        oldwordnum = wordnum;\r
+        checked_prefix = 0;\r
+\r
+        // go to end of the UTF-8 character\r
+        if (utf8) {\r
+            for (; (st[i] & 0xc0) == 0x80; i++);\r
+            if (i >= cmax) return NULL;\r
+        }\r
+\r
+        \r
+        ch = st[i];\r
+        st[i] = '\0';\r
+\r
+        sfx = NULL;\r
+        pfx = NULL;\r
+        \r
+        // FIRST WORD\r
+        \r
+        rv = lookup(st); // perhaps without prefix\r
+\r
+        // search homonym with compound flag\r
+        while ((rv) && !hu_mov_rule &&\r
+            ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) ||\r
+                !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) ||\r
+                  (compoundbegin && !wordnum &&\r
+                        TESTAFF(rv->astr, compoundbegin, rv->alen)) ||\r
+                  (compoundmiddle && wordnum && !words &&\r
+                    TESTAFF(rv->astr, compoundmiddle, rv->alen)) ||\r
+                  (numdefcpd &&\r
+                    ((!words && !wordnum && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)) ||\r
+                    (words && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0))))\r
+                  ))) {\r
+            rv = rv->next_homonym;\r
+        }\r
+\r
+        if (!rv) {\r
+            if (compoundflag && \r
+             !(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) {\r
+                if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,\r
+                        FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule &&\r
+                    ((SfxEntry*)sfx)->getCont() &&\r
+                        ((compoundforbidflag && TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, \r
+                            ((SfxEntry*)sfx)->getContLen())) || (compoundend &&\r
+                        TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, \r
+                            ((SfxEntry*)sfx)->getContLen())))) {\r
+                        rv = NULL;\r
+                }\r
+            }\r
+            if (rv ||\r
+              (((wordnum == 0) && compoundbegin &&\r
+                ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||\r
+                (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) ||\r
+              ((wordnum > 0) && compoundmiddle &&\r
+                ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||\r
+                (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle)))))\r
+              ) checked_prefix = 1;\r
+        // else check forbiddenwords and pseudoroot\r
+        } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||\r
+            TESTAFF(rv->astr, pseudoroot, rv->alen) || \r
+            (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen))\r
+             )) {\r
+                st[i] = ch;\r
+                continue;\r
+        }\r
+\r
+            // check non_compound flag in suffix and prefix\r
+            if ((rv) && !hu_mov_rule &&\r
+                ((pfx && ((PfxEntry*)pfx)->getCont() &&\r
+                    TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, \r
+                        ((PfxEntry*)pfx)->getContLen())) ||\r
+                (sfx && ((SfxEntry*)sfx)->getCont() &&\r
+                    TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, \r
+                        ((SfxEntry*)sfx)->getContLen())))) {\r
+                    rv = NULL;\r
+            }\r
+\r
+            // check compoundend flag in suffix and prefix\r
+            if ((rv) && !checked_prefix && compoundend && !hu_mov_rule &&\r
+                ((pfx && ((PfxEntry*)pfx)->getCont() &&\r
+                    TESTAFF(((PfxEntry*)pfx)->getCont(), compoundend, \r
+                        ((PfxEntry*)pfx)->getContLen())) ||\r
+                (sfx && ((SfxEntry*)sfx)->getCont() &&\r
+                    TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, \r
+                        ((SfxEntry*)sfx)->getContLen())))) {\r
+                    rv = NULL;\r
+            }\r
+            \r
+            // check compoundmiddle flag in suffix and prefix\r
+            if ((rv) && !checked_prefix && (wordnum==0) && compoundmiddle && !hu_mov_rule &&\r
+                ((pfx && ((PfxEntry*)pfx)->getCont() &&\r
+                    TESTAFF(((PfxEntry*)pfx)->getCont(), compoundmiddle, \r
+                        ((PfxEntry*)pfx)->getContLen())) ||\r
+                (sfx && ((SfxEntry*)sfx)->getCont() &&\r
+                    TESTAFF(((SfxEntry*)sfx)->getCont(), compoundmiddle, \r
+                        ((SfxEntry*)sfx)->getContLen())))) {\r
+                    rv = NULL;\r
+            }       \r
+\r
+        // check forbiddenwords\r
+        if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||\r
+            (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) {\r
+                return NULL;\r
+            }\r
+\r
+        // increment word number, if the second root has a compoundroot flag\r
+        if ((rv) && compoundroot && \r
+            (TESTAFF(rv->astr, compoundroot, rv->alen))) {\r
+                wordnum++;\r
+        }\r
+\r
+        // first word is acceptable in compound words?\r
+        if (((rv) && \r
+          ( checked_prefix || (words && words[wnum]) ||\r
+            (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||\r
+            ((oldwordnum == 0) && compoundbegin && TESTAFF(rv->astr, compoundbegin, rv->alen)) ||\r
+            ((oldwordnum > 0) && compoundmiddle && TESTAFF(rv->astr, compoundmiddle, rv->alen))// ||\r
+//            (numdefcpd && )\r
+\r
+// LANG_hu section: spec. Hungarian rule\r
+            || ((langnum == LANG_hu) && hu_mov_rule && (\r
+                    TESTAFF(rv->astr, 'F', rv->alen) || // XXX hardwired Hungarian dictionary codes\r
+                    TESTAFF(rv->astr, 'G', rv->alen) ||\r
+                    TESTAFF(rv->astr, 'H', rv->alen)\r
+                )\r
+              )\r
+// END of LANG_hu section\r
+          )\r
+          && ! (( checkcompoundtriple && // test triple letters\r
+                   (word[i-1]==word[i]) && (\r
+                      ((i>1) && (word[i-1]==word[i-2])) || \r
+                      ((word[i-1]==word[i+1])) // may be word[i+1] == '\0'\r
+                   )\r
+               ) ||\r
+               ( \r
+                 // test CHECKCOMPOUNDPATTERN\r
+                 numcheckcpd && cpdpat_check(word, i)\r
+               ) ||\r
+               ( \r
+                 checkcompoundcase && cpdcase_check(word, i)\r
+               ))\r
+         )\r
+// LANG_hu section: spec. Hungarian rule\r
+         || ((!rv) && (langnum == LANG_hu) && hu_mov_rule && (rv = affix_check(st,i)) &&\r
+              (sfx && ((SfxEntry*)sfx)->getCont() && ( // XXX hardwired Hungarian dic. codes\r
+                        TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) 'x', ((SfxEntry*)sfx)->getContLen()) ||\r
+                        TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) '%', ((SfxEntry*)sfx)->getContLen())\r
+                    )                \r
+               )\r
+             )\r
+// END of LANG_hu section\r
+         ) {\r
+\r
+// LANG_hu section: spec. Hungarian rule\r
+            if (langnum == LANG_hu) {\r
+                // calculate syllable number of the word            \r
+                numsyllable += get_syllable(st, i);\r
+\r
+                // + 1 word, if syllable number of the prefix > 1 (hungarian convention)\r
+                if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++;\r
+            }\r
+// END of LANG_hu section\r
+\r
+#ifdef HUNSTEM\r
+            if (cmpdstem) cmpdstem[*cmpdstemnum - 1] = i;\r
+#endif\r
+\r
+            // NEXT WORD(S)\r
+            rv_first = rv;\r
+            rv = lookup((word+i)); // perhaps without prefix\r
+\r
+        // search homonym with compound flag\r
+        while ((rv) && ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) ||\r
+                        !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) ||\r
+                          (compoundend && !words && TESTAFF(rv->astr, compoundend, rv->alen)) ||\r
+                           (numdefcpd && words && defcpd_check(&words, wnum + 1, rv, NULL,1))))) {\r
+            rv = rv->next_homonym;\r
+        }\r
+\r
+            if (rv && words && words[wnum + 1]) return rv;\r
+\r
+            oldnumsyllable2 = numsyllable;\r
+            oldwordnum2 = wordnum;\r
+\r
+// LANG_hu section: spec. Hungarian rule, XXX hardwired dictionary code\r
+            if ((rv) && (langnum == LANG_hu) && (TESTAFF(rv->astr, 'I', rv->alen)) && !(TESTAFF(rv->astr, 'J', rv->alen))) {\r
+                numsyllable--;\r
+            }\r
+// END of LANG_hu section\r
+\r
+            // increment word number, if the second root has a compoundroot flag\r
+            if ((rv) && (compoundroot) && \r
+                (TESTAFF(rv->astr, compoundroot, rv->alen))) {\r
+                    wordnum++;\r
+            }\r
+\r
+            // check forbiddenwords\r
+            if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||\r
+               (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) return NULL;\r
+\r
+            // second word is acceptable, as a root?\r
+            // hungarian conventions: compounding is acceptable,\r
+            // when compound forms consist of 2 words, or if more,\r
+            // then the syllable number of root words must be 6, or lesser.\r
+\r
+            if ((rv) && (\r
+                      (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||\r
+                      (compoundend && TESTAFF(rv->astr, compoundend, rv->alen))\r
+                    )\r
+                && (\r
+                      ((cpdwordmax==-1) || (wordnum+1<cpdwordmax)) || \r
+                      ((cpdmaxsyllable==0) || \r
+                          (numsyllable + get_syllable(rv->word,rv->wlen)<=cpdmaxsyllable))\r
+                    )\r
+                && (\r
+                     (!checkcompounddup || (rv != rv_first))\r
+                   )\r
+                )\r
+                 {\r
+                      // forbid compound word, if it is a non compound word with typical fault\r
+                      if (checkcompoundrep && cpdrep_check(word,len)) return NULL;\r
+                      return rv;\r
+            }\r
+\r
+            numsyllable = oldnumsyllable2 ;\r
+            wordnum = oldwordnum2;\r
+\r
+            // perhaps second word has prefix or/and suffix\r
+            sfx = NULL;\r
+            sfxflag = FLAG_NULL;\r
+            rv = (compoundflag) ? affix_check((word+i),strlen(word+i), compoundflag, IN_CPD_END) : NULL;\r
+            if (!rv && compoundend) {\r
+                sfx = NULL;\r
+                pfx = NULL;\r
+                rv = affix_check((word+i),strlen(word+i), compoundend, IN_CPD_END);\r
+            }\r
+            \r
+            if (!rv && numdefcpd && words) {\r
+                rv = affix_check((word+i),strlen(word+i), 0, IN_CPD_END);\r
+                if (rv && defcpd_check(&words, wnum + 1, rv, NULL, 1)) return rv;\r
+            }\r
+\r
+            // check non_compound flag in suffix and prefix\r
+            if ((rv) && \r
+                ((pfx && ((PfxEntry*)pfx)->getCont() &&\r
+                    TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, \r
+                        ((PfxEntry*)pfx)->getContLen())) ||\r
+                (sfx && ((SfxEntry*)sfx)->getCont() &&\r
+                    TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, \r
+                        ((SfxEntry*)sfx)->getContLen())))) {\r
+                    rv = NULL;\r
+            }\r
+\r
+            // check forbiddenwords\r
+            if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||\r
+               (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) return NULL;\r
+\r
+            // pfxappnd = prefix of word+i, or NULL\r
+            // calculate syllable number of prefix.\r
+            // hungarian convention: when syllable number of prefix is more,\r
+            // than 1, the prefix+word counts as two words.\r
+\r
+            if (langnum == LANG_hu) {\r
+                // calculate syllable number of the word\r
+                numsyllable += get_syllable(word + i, strlen(word + i));\r
+                \r
+                // - affix syllable num.\r
+                // XXX only second suffix (inflections, not derivations)\r
+                if (sfxappnd) {\r
+                    char * tmp = myrevstrdup(sfxappnd);\r
+                    numsyllable -= get_syllable(tmp, strlen(tmp));\r
+                    free(tmp);\r
+                }\r
+                \r
+                // + 1 word, if syllable number of the prefix > 1 (hungarian convention)\r
+                if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++;\r
+\r
+                // increment syllable num, if last word has a SYLLABLENUM flag\r
+                // and the suffix is beginning `s'\r
+            \r
+                if (cpdsyllablenum) {\r
+                    switch (sfxflag) {\r
+                        case 'c': { numsyllable+=2; break; }\r
+                        case 'J': { numsyllable += 1; break; }\r
+                        case 'I': { if (TESTAFF(rv->astr, 'J', rv->alen)) numsyllable += 1; break; }\r
+                    }\r
+                }\r
+            }\r
+            \r
+            // increment word number, if the second word has a compoundroot flag\r
+            if ((rv) && (compoundroot) && \r
+                (TESTAFF(rv->astr, compoundroot, rv->alen))) {\r
+                    wordnum++;\r
+            }\r
+\r
+            // second word is acceptable, as a word with prefix or/and suffix?\r
+            // hungarian conventions: compounding is acceptable,\r
+            // when compound forms consist 2 word, otherwise\r
+            // the syllable number of root words is 6, or lesser.\r
+            if ((rv) && \r
+                    (\r
+                      ((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) || \r
+                      ((cpdmaxsyllable == 0) || \r
+                          (numsyllable <= cpdmaxsyllable))\r
+                    )\r
+                && (\r
+                   (!checkcompounddup || (rv != rv_first))\r
+                   )) {\r
+                    // forbid compound word, if it is a non compound word with typical fault\r
+                    if (checkcompoundrep && cpdrep_check(word, len)) return NULL;\r
+                    return rv;\r
+            }\r
+\r
+            numsyllable = oldnumsyllable2;\r
+            wordnum = oldwordnum2;\r
+#ifdef HUNSTEM\r
+            if (cmpdstemnum) oldcmpdstemnum = *cmpdstemnum;\r
+#endif\r
+            // perhaps second word is a compound word (recursive call)\r
+            if (wordnum < maxwordnum) {\r
+                rv = compound_check((word+i),strlen(word+i), wordnum+1,\r
+                     numsyllable, maxwordnum, wnum + 1, words,\r
+                     0, cmpdstemnum, cmpdstem, is_sug);\r
+            } else {\r
+                rv=NULL;\r
+            }\r
+            if (rv) {\r
+                // forbid compound word, if it is a non compound word with typical fault\r
+                if (checkcompoundrep && cpdrep_check(word, len)) return NULL;\r
+                return rv;\r
+            } else {\r
+#ifdef HUNSTEM\r
+            if (cmpdstemnum) *cmpdstemnum = oldcmpdstemnum;\r
+#endif\r
+            }\r
+        }\r
+        st[i] = ch;\r
+        wordnum = oldwordnum;\r
+        numsyllable = oldnumsyllable;\r
+    }\r
+    \r
+    return NULL;\r
+}    \r
+\r
+#ifdef HUNSPELL_EXPERIMENTAL\r
+// check if compound word is correctly spelled\r
+// hu_mov_rule = spec. Hungarian rule (XXX)\r
+int AffixMgr::compound_check_morph(const char * word, int len, \r
+    short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words,\r
+    char hu_mov_rule = 0, char ** result = NULL, char * partresult = NULL)\r
+{\r
+    int i;\r
+    short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2;\r
+    int ok = 0;\r
+\r
+    struct hentry * rv = NULL;\r
+    struct hentry * rv_first;\r
+    struct hentry * rwords[MAXWORDLEN]; // buffer for COMPOUND pattern checking\r
+    char st [MAXWORDUTF8LEN + 4];\r
+    char ch;\r
+    \r
+    int checked_prefix;\r
+    char presult[MAXLNLEN];\r
+\r
+    int cmin;\r
+    int cmax;\r
+    \r
+    if (utf8) {\r
+        for (cmin = 0, i = 0; (i < cpdmin) && word[cmin]; i++) {\r
+          cmin++;\r
+          for (; (word[cmin] & 0xc0) == 0x80; cmin++);\r
+        }\r
+        for (cmax = len, i = 0; (i < (cpdmin - 1)) && cmax; i++) {\r
+          cmax--;\r
+          for (; (word[cmax] & 0xc0) == 0x80; cmax--);\r
+        }\r
+    } else {\r
+        cmin = cpdmin;\r
+        cmax = len - cpdmin + 1;\r
+    }\r
+\r
+    strcpy(st, word);\r
+\r
+    for (i = cmin; i < cmax; i++) {\r
+        oldnumsyllable = numsyllable;\r
+        oldwordnum = wordnum;\r
+        checked_prefix = 0;\r
+\r
+        // go to end of the UTF-8 character\r
+        if (utf8) {\r
+            for (; (st[i] & 0xc0) == 0x80; i++);\r
+            if (i >= cmax) return 0;\r
+        }\r
+        \r
+        ch = st[i];\r
+        st[i] = '\0';\r
+        sfx = NULL;\r
+\r
+        // FIRST WORD\r
+        *presult = '\0';\r
+        if (partresult) strcat(presult, partresult);\r
+        \r
+        rv = lookup(st); // perhaps without prefix\r
+\r
+        // search homonym with compound flag\r
+        while ((rv) && !hu_mov_rule && \r
+            ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) ||\r
+                !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) ||\r
+                (compoundbegin && !wordnum &&\r
+                        TESTAFF(rv->astr, compoundbegin, rv->alen)) ||\r
+                (compoundmiddle && wordnum && !words &&\r
+                    TESTAFF(rv->astr, compoundmiddle, rv->alen)) ||\r
+                  (numdefcpd &&\r
+                    ((!words && !wordnum && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)) ||\r
+                    (words && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0))))\r
+                  ))) {\r
+            rv = rv->next_homonym;\r
+        }\r
+\r
+        if (rv)  {\r
+            if (rv->description) {\r
+                if ((!rv->astr) || !TESTAFF(rv->astr, lemma_present, rv->alen))\r
+                                        strcat(presult, st);\r
+                strcat(presult, rv->description);\r
+            }\r
+        }\r
+        \r
+        if (!rv) {\r
+            if (compoundflag && \r
+             !(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) {\r
+                if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,\r
+                        FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule &&\r
+                    ((SfxEntry*)sfx)->getCont() &&\r
+                        ((compoundforbidflag && TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, \r
+                            ((SfxEntry*)sfx)->getContLen())) || (compoundend &&\r
+                        TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, \r
+                            ((SfxEntry*)sfx)->getContLen())))) {\r
+                        rv = NULL;\r
+                }\r
+            }\r
+            \r
+            if (rv ||\r
+              (((wordnum == 0) && compoundbegin &&\r
+                ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||\r
+                (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) ||\r
+              ((wordnum > 0) && compoundmiddle &&\r
+                ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||\r
+                (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle)))))\r
+              ) {\r
+                //char * p = prefix_check_morph(st, i, 0, compound);\r
+                char * p = NULL;\r
+                if (compoundflag) p = affix_check_morph(st, i, compoundflag);\r
+                if (!p || (*p == '\0')) {\r
+                   if ((wordnum == 0) && compoundbegin) {\r
+                     p = affix_check_morph(st, i, compoundbegin);\r
+                   } else if ((wordnum > 0) && compoundmiddle) {\r
+                     p = affix_check_morph(st, i, compoundmiddle);                   \r
+                   }\r
+                }\r
+                if (*p != '\0') {\r
+                    line_uniq(p);\r
+                    if (strchr(p, '\n')) {\r
+                        strcat(presult, "(");\r
+                        strcat(presult, line_join(p, '|'));\r
+                        strcat(presult, ")");\r
+                      } else {\r
+                        strcat(presult, p);\r
+                      }\r
+                }\r
+                if (presult[strlen(presult) - 1] == '\n') {\r
+                    presult[strlen(presult) - 1] = '\0';\r
+                }\r
+                checked_prefix = 1;\r
+                //strcat(presult, "+");\r
+            }\r
+        // else check forbiddenwords\r
+        } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||\r
+            TESTAFF(rv->astr, pseudoroot, rv->alen))) {\r
+                st[i] = ch;\r
+                continue;\r
+        }\r
+\r
+            // check non_compound flag in suffix and prefix\r
+            if ((rv) && !hu_mov_rule &&\r
+                ((pfx && ((PfxEntry*)pfx)->getCont() &&\r
+                    TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, \r
+                        ((PfxEntry*)pfx)->getContLen())) ||\r
+                (sfx && ((SfxEntry*)sfx)->getCont() &&\r
+                    TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, \r
+                        ((SfxEntry*)sfx)->getContLen())))) {\r
+                    continue;\r
+            }\r
+\r
+            // check compoundend flag in suffix and prefix\r
+            if ((rv) && !checked_prefix && compoundend && !hu_mov_rule &&\r
+                ((pfx && ((PfxEntry*)pfx)->getCont() &&\r
+                    TESTAFF(((PfxEntry*)pfx)->getCont(), compoundend, \r
+                        ((PfxEntry*)pfx)->getContLen())) ||\r
+                (sfx && ((SfxEntry*)sfx)->getCont() &&\r
+                    TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, \r
+                        ((SfxEntry*)sfx)->getContLen())))) {\r
+                    continue;\r
+            }\r
+\r
+            // check compoundmiddle flag in suffix and prefix\r
+            if ((rv) && !checked_prefix && (wordnum==0) && compoundmiddle && !hu_mov_rule &&\r
+                ((pfx && ((PfxEntry*)pfx)->getCont() &&\r
+                    TESTAFF(((PfxEntry*)pfx)->getCont(), compoundmiddle, \r
+                        ((PfxEntry*)pfx)->getContLen())) ||\r
+                (sfx && ((SfxEntry*)sfx)->getCont() &&\r
+                    TESTAFF(((SfxEntry*)sfx)->getCont(), compoundmiddle, \r
+                        ((SfxEntry*)sfx)->getContLen())))) {\r
+                    rv = NULL;\r
+            }       \r
+\r
+        // check forbiddenwords\r
+        if ((rv) && (rv->astr) && TESTAFF(rv->astr, forbiddenword, rv->alen)) continue;\r
+\r
+        // increment word number, if the second root has a compoundroot flag\r
+        if ((rv) && (compoundroot) && \r
+            (TESTAFF(rv->astr, compoundroot, rv->alen))) {\r
+                wordnum++;\r
+        }\r
+\r
+        // first word is acceptable in compound words?\r
+        if (((rv) && \r
+          ( checked_prefix || (words && words[wnum]) ||\r
+            (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||\r
+            ((oldwordnum == 0) && compoundbegin && TESTAFF(rv->astr, compoundbegin, rv->alen)) ||\r
+            ((oldwordnum > 0) && compoundmiddle && TESTAFF(rv->astr, compoundmiddle, rv->alen)) \r
+// LANG_hu section: spec. Hungarian rule\r
+            || ((langnum == LANG_hu) && // hu_mov_rule\r
+                hu_mov_rule && (\r
+                    TESTAFF(rv->astr, 'F', rv->alen) ||\r
+                    TESTAFF(rv->astr, 'G', rv->alen) ||\r
+                    TESTAFF(rv->astr, 'H', rv->alen)\r
+                )\r
+              )\r
+// END of LANG_hu section\r
+          )\r
+          && ! (( checkcompoundtriple && // test triple letters\r
+                   (word[i-1]==word[i]) && (\r
+                      ((i>1) && (word[i-1]==word[i-2])) || \r
+                      ((word[i-1]==word[i+1])) // may be word[i+1] == '\0'\r
+                   )\r
+               ) ||\r
+               (\r
+                   // test CHECKCOMPOUNDPATTERN\r
+                   numcheckcpd && cpdpat_check(word, i)\r
+               ) ||\r
+               ( \r
+                 checkcompoundcase && cpdcase_check(word, i)\r
+               ))\r
+         )\r
+// LANG_hu section: spec. Hungarian rule\r
+         || ((!rv) && (langnum == LANG_hu) && hu_mov_rule && (rv = affix_check(st,i)) &&\r
+              (sfx && ((SfxEntry*)sfx)->getCont() && (\r
+                        TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) 'x', ((SfxEntry*)sfx)->getContLen()) ||\r
+                        TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) '%', ((SfxEntry*)sfx)->getContLen())\r
+                    )                \r
+               )\r
+             )\r
+// END of LANG_hu section\r
+         ) {\r
+\r
+// LANG_hu section: spec. Hungarian rule\r
+            if (langnum == LANG_hu) {\r
+                // calculate syllable number of the word\r
+                numsyllable += get_syllable(st, i);\r
+\r
+                // + 1 word, if syllable number of the prefix > 1 (hungarian convention)\r
+                if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++;\r
+            }\r
+// END of LANG_hu section\r
+\r
+            // NEXT WORD(S)\r
+            rv_first = rv;\r
+            rv = lookup((word+i)); // perhaps without prefix\r
+\r
+        // search homonym with compound flag\r
+        while ((rv) && ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) ||\r
+                        !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) ||\r
+                          (compoundend && !words && TESTAFF(rv->astr, compoundend, rv->alen)) ||\r
+                           (numdefcpd && defcpd_check(&words, wnum + 1, rv, NULL,1))))) {\r
+            rv = rv->next_homonym;\r
+        }\r
+\r
+            if (rv && words && words[wnum + 1]) {\r
+                  strcat(*result, presult);\r
+                  if (complexprefixes && rv->description) strcat(*result, rv->description);\r
+                  if (rv->description && ((!rv->astr) || \r
+                     !TESTAFF(rv->astr, lemma_present, rv->alen)))\r
+                        strcat(*result, rv->word);\r
+                  if (!complexprefixes && rv->description) strcat(*result, rv->description);\r
+                  strcat(*result, "\n");\r
+                  ok = 1;\r
+                  return 0;\r
+            }\r
+\r
+            oldnumsyllable2 = numsyllable;\r
+            oldwordnum2 = wordnum;\r
+\r
+// LANG_hu section: spec. Hungarian rule\r
+            if ((rv) && (langnum == LANG_hu) && (TESTAFF(rv->astr, 'I', rv->alen)) && !(TESTAFF(rv->astr, 'J', rv->alen))) {\r
+                numsyllable--;\r
+            }\r
+// END of LANG_hu section\r
+            // increment word number, if the second root has a compoundroot flag\r
+            if ((rv) && (compoundroot) && \r
+                (TESTAFF(rv->astr, compoundroot, rv->alen))) {\r
+                    wordnum++;\r
+            }\r
+\r
+            // check forbiddenwords\r
+            if ((rv) && (rv->astr) && TESTAFF(rv->astr, forbiddenword, rv->alen)) {\r
+                st[i] = ch;\r
+                continue;\r
+            }\r
+                    \r
+            // second word is acceptable, as a root?\r
+            // hungarian conventions: compounding is acceptable,\r
+            // when compound forms consist of 2 words, or if more,\r
+            // then the syllable number of root words must be 6, or lesser.\r
+            if ((rv) && (\r
+                      (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||\r
+                      (compoundend && TESTAFF(rv->astr, compoundend, rv->alen))\r
+                    )\r
+                && (\r
+                      ((cpdwordmax==-1) || (wordnum+1<cpdwordmax)) || \r
+                      ((cpdmaxsyllable==0) || \r
+                          (numsyllable+get_syllable(rv->word,rv->wlen)<=cpdmaxsyllable))\r
+                    )\r
+                && (\r
+                     (!checkcompounddup || (rv != rv_first))\r
+                   )\r
+                )\r
+                 {\r
+                      // bad compound word\r
+                      strcat(*result, presult);\r
+                                          \r
+                      if (rv->description) {\r
+                        if (complexprefixes) strcat(*result, rv->description);\r
+                        if ((!rv->astr) || !TESTAFF(rv->astr, lemma_present, rv->alen))\r
+                                               strcat(*result, rv->word);\r
+                        if (!complexprefixes) strcat(*result, rv->description);\r
+                      }\r
+                      strcat(*result, "\n");\r
+                              ok = 1;\r
+            }\r
+\r
+            numsyllable = oldnumsyllable2 ;\r
+            wordnum = oldwordnum2;\r
+\r
+            // perhaps second word has prefix or/and suffix\r
+            sfx = NULL;\r
+            sfxflag = FLAG_NULL;\r
+\r
+            if (compoundflag) rv = affix_check((word+i),strlen(word+i), compoundflag); else rv = NULL;\r
+\r
+            if (!rv && compoundend) {\r
+                sfx = NULL;\r
+                pfx = NULL;\r
+                rv = affix_check((word+i),strlen(word+i), compoundend);\r
+            }\r
+\r
+            if (!rv && numdefcpd && words) {\r
+                rv = affix_check((word+i),strlen(word+i), 0, IN_CPD_END);\r
+                if (rv && words && defcpd_check(&words, wnum + 1, rv, NULL, 1)) {\r
+                      char * m = NULL;\r
+                      if (compoundflag) m = affix_check_morph((word+i),strlen(word+i), compoundflag);\r
+                      if ((!m || *m == '\0') && compoundend)\r
+                            m = affix_check_morph((word+i),strlen(word+i), compoundend);\r
+                      strcat(*result, presult);\r
+                      if (m) {\r
+                        line_uniq(m);\r
+                        if (strchr(m, '\n')) {\r
+                            strcat(*result, "(");\r
+                            strcat(*result, line_join(m, '|'));\r
+                            strcat(*result, ")");\r
+                        } else {\r
+                            strcat(*result, m);\r
+                        }\r
+                        free(m);\r
+                      }\r
+                      strcat(*result, "\n");\r
+                      ok = 1;\r
+                }\r
+            }\r
+\r
+            // check non_compound flag in suffix and prefix\r
+            if ((rv) && \r
+                ((pfx && ((PfxEntry*)pfx)->getCont() &&\r
+                    TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, \r
+                        ((PfxEntry*)pfx)->getContLen())) ||\r
+                (sfx && ((SfxEntry*)sfx)->getCont() &&\r
+                    TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, \r
+                        ((SfxEntry*)sfx)->getContLen())))) {\r
+                    rv = NULL;\r
+            }\r
+\r
+            // check forbiddenwords\r
+            if ((rv) && (rv->astr) && (TESTAFF(rv->astr,forbiddenword,rv->alen))\r
+                    && (! TESTAFF(rv->astr, pseudoroot, rv->alen))) {\r
+                        st[i] = ch;\r
+                        continue;\r
+                    }\r
+\r
+            if (langnum == LANG_hu) {\r
+                // calculate syllable number of the word\r
+                numsyllable += get_syllable(word + i, strlen(word + i));\r
+\r
+                // - affix syllable num.\r
+                // XXX only second suffix (inflections, not derivations)\r
+                if (sfxappnd) {\r
+                    char * tmp = myrevstrdup(sfxappnd);\r
+                    numsyllable -= get_syllable(tmp, strlen(tmp));\r
+                    free(tmp);\r
+                }\r
+\r
+                // + 1 word, if syllable number of the prefix > 1 (hungarian convention)\r
+                if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++;\r
+\r
+                // increment syllable num, if last word has a SYLLABLENUM flag\r
+                // and the suffix is beginning `s'\r
+\r
+                if (cpdsyllablenum) {\r
+                    switch (sfxflag) {\r
+                        case 'c': { numsyllable+=2; break; }\r
+                        case 'J': { numsyllable += 1; break; }\r
+                        case 'I': { if (rv && TESTAFF(rv->astr, 'J', rv->alen)) numsyllable += 1; break; }\r
+                    }\r
+                }\r
+            }\r
+\r
+            // increment word number, if the second word has a compoundroot flag\r
+            if ((rv) && (compoundroot) && \r
+                (TESTAFF(rv->astr, compoundroot, rv->alen))) {\r
+                    wordnum++;\r
+            }\r
+            // second word is acceptable, as a word with prefix or/and suffix?\r
+            // hungarian conventions: compounding is acceptable,\r
+            // when compound forms consist 2 word, otherwise\r
+            // the syllable number of root words is 6, or lesser.\r
+            if ((rv) && \r
+                    (\r
+                      ((cpdwordmax==-1) || (wordnum+1<cpdwordmax)) || \r
+                      ((cpdmaxsyllable==0) || \r
+                          (numsyllable <= cpdmaxsyllable))\r
+                    )\r
+                && (\r
+                   (!checkcompounddup || (rv != rv_first))\r
+                   )) {\r
+                      char * m = NULL;\r
+                      if (compoundflag) m = affix_check_morph((word+i),strlen(word+i), compoundflag);\r
+                      if ((!m || *m == '\0') && compoundend)\r
+                            m = affix_check_morph((word+i),strlen(word+i), compoundend);\r
+                      strcat(*result, presult);\r
+                      if (m) {\r
+                        line_uniq(m);\r
+                        if (strchr(m, '\n')) {\r
+                            strcat(*result, "(");\r
+                            strcat(*result, line_join(m, '|'));\r
+                            strcat(*result, ")");\r
+                        } else {\r
+                            strcat(*result, m);\r
+                        }\r
+                        free(m);\r
+                      }\r
+                      strcat(*result, "\n");\r
+                      ok = 1;\r
+            }\r
+\r
+            numsyllable = oldnumsyllable2;\r
+            wordnum = oldwordnum2;\r
+\r
+            // perhaps second word is a compound word (recursive call)\r
+            if ((wordnum < maxwordnum) && (ok == 0)) {\r
+                        compound_check_morph((word+i),strlen(word+i), wordnum+1, \r
+                             numsyllable, maxwordnum, wnum + 1, words, 0, result, presult);\r
+            } else {\r
+                rv=NULL;\r
+            }\r
+        }\r
+        st[i] = ch;\r
+        wordnum = oldwordnum;\r
+        numsyllable = oldnumsyllable;\r
+    }\r
+    return 0;\r
+}    \r
+#endif // END OF HUNSPELL_EXPERIMENTAL CODE\r
+\r
+ // return 1 if s1 (reversed) is a leading subset of end of s2\r
+/* inline int AffixMgr::isRevSubset(const char * s1, const char * end_of_s2, int len)\r
+ {\r
+    while ((len > 0) && *s1 && (*s1 == *end_of_s2)) {\r
+        s1++;\r
+        end_of_s2--;\r
+        len--;\r
+    }\r
+    return (*s1 == '\0');\r
+ }\r
+ */\r
+\r
+inline int AffixMgr::isRevSubset(const char * s1, const char * end_of_s2, int len)\r
+ {\r
+    while ((len > 0) && (*s1 != '\0') && ((*s1 == *end_of_s2) || (*s1 == '.'))) {\r
+        s1++;\r
+        end_of_s2--;\r
+        len--;\r
+    }\r
+    return (*s1 == '\0');\r
+ }\r
+\r
+// check word for suffixes\r
+\r
+struct hentry * AffixMgr::suffix_check (const char * word, int len, \r
+       int sfxopts, AffEntry * ppfx, char ** wlst, int maxSug, int * ns, \r
+       const FLAG cclass, const FLAG needflag, char in_compound)\r
+{\r
+    struct hentry * rv = NULL;\r
+    char result[MAXLNLEN];\r
+\r
+    PfxEntry* ep = (PfxEntry *) ppfx;\r
+\r
+    // first handle the special case of 0 length suffixes\r
+    SfxEntry * se = (SfxEntry *) sStart[0];\r
+\r
+    while (se) {\r
+        if (!cclass || se->getCont()) {\r
+            // suffixes are not allowed in beginning of compounds\r
+            if ((((in_compound != IN_CPD_BEGIN)) || // && !cclass\r
+             // except when signed with compoundpermitflag flag\r
+             (se->getCont() && compoundpermitflag &&\r
+                TESTAFF(se->getCont(),compoundpermitflag,se->getContLen()))) && (!circumfix ||\r
+              // no circumfix flag in prefix and suffix\r
+              ((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(),\r
+                   circumfix, ep->getContLen())) &&\r
+               (!se->getCont() || !(TESTAFF(se->getCont(),circumfix,se->getContLen())))) ||\r
+              // circumfix flag in prefix AND suffix\r
+              ((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(),\r
+                   circumfix, ep->getContLen())) &&\r
+               (se->getCont() && (TESTAFF(se->getCont(),circumfix,se->getContLen())))))  &&\r
+            // fogemorpheme\r
+              (in_compound || \r
+                 !((se->getCont() && (TESTAFF(se->getCont(), onlyincompound, se->getContLen()))))) &&\r
+            // pseudoroot on prefix or first suffix\r
+              (cclass || \r
+                   !(se->getCont() && TESTAFF(se->getCont(), pseudoroot, se->getContLen())) ||\r
+                   (ppfx && !((ep->getCont()) &&\r
+                     TESTAFF(ep->getCont(), pseudoroot,\r
+                       ep->getContLen())))\r
+              )\r
+            ) {\r
+                rv = se->checkword(word,len, sfxopts, ppfx, wlst, maxSug, ns, (FLAG) cclass, \r
+                    needflag, (in_compound ? 0 : onlyincompound));\r
+                if (rv) {\r
+                    sfx=(AffEntry *)se; // BUG: sfx not stateless\r
+                    return rv;\r
+                }\r
+            }\r
+        }\r
+       se = se->getNext();\r
+    }\r
+  \r
+    // now handle the general case\r
+    unsigned char sp = *((const unsigned char *)(word + len - 1));\r
+    SfxEntry * sptr = (SfxEntry *) sStart[sp];\r
+\r
+    while (sptr) {\r
+        if (isRevSubset(sptr->getKey(), word + len - 1, len)\r
+        ) {\r
+            // suffixes are not allowed in beginning of compounds\r
+            if ((((in_compound != IN_CPD_BEGIN)) || // && !cclass\r
+             // except when signed with compoundpermitflag flag\r
+             (sptr->getCont() && compoundpermitflag &&\r
+                TESTAFF(sptr->getCont(),compoundpermitflag,sptr->getContLen()))) && (!circumfix ||\r
+              // no circumfix flag in prefix and suffix\r
+              ((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(),\r
+                   circumfix, ep->getContLen())) &&\r
+               (!sptr->getCont() || !(TESTAFF(sptr->getCont(),circumfix,sptr->getContLen())))) ||\r
+              // circumfix flag in prefix AND suffix\r
+              ((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(),\r
+                   circumfix, ep->getContLen())) &&\r
+               (sptr->getCont() && (TESTAFF(sptr->getCont(),circumfix,sptr->getContLen())))))  &&\r
+            // fogemorpheme\r
+              (in_compound || \r
+                 !((sptr->getCont() && (TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))))) &&\r
+            // pseudoroot on prefix or first suffix\r
+              (cclass || \r
+                  !(sptr->getCont() && TESTAFF(sptr->getCont(), pseudoroot, sptr->getContLen())) ||\r
+                  (ppfx && !((ep->getCont()) &&\r
+                     TESTAFF(ep->getCont(), pseudoroot,\r
+                       ep->getContLen())))\r
+              )\r
+            ) {\r
+                rv = sptr->checkword(word,len, sfxopts, ppfx, wlst,\r
+                    maxSug, ns, cclass, needflag, (in_compound ? 0 : onlyincompound));\r
+                if (rv) {\r
+                    sfx=(AffEntry *)sptr; // BUG: sfx not stateless\r
+                    sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless\r
+                    if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless\r
+                    if (cclass || sptr->getCont()) {\r
+                                if (!derived) {\r
+                                        derived = mystrdup(word);\r
+                                } else {\r
+                                        strcpy(result, derived); // XXX check size\r
+                                        strcat(result, "\n");\r
+                                        strcat(result, word);\r
+                                        free(derived);\r
+                                        derived = mystrdup(result);\r
+                                }\r
+                    }\r
+                    return rv;\r
+                }\r
+             }\r
+             sptr = sptr->getNextEQ();\r
+        } else {\r
+             sptr = sptr->getNextNE();\r
+        }\r
+    }\r
+\r
+    return NULL;\r
+}\r
+\r
+// check word for two-level suffixes\r
+\r
+struct hentry * AffixMgr::suffix_check_twosfx(const char * word, int len, \r
+       int sfxopts, AffEntry * ppfx, const FLAG needflag)\r
+{\r
+    struct hentry * rv = NULL;\r
+\r
+    // first handle the special case of 0 length suffixes\r
+    SfxEntry * se = (SfxEntry *) sStart[0];\r
+    while (se) {\r
+        if (contclasses[se->getFlag()])\r
+        {\r
+            rv = se->check_twosfx(word,len, sfxopts, ppfx, needflag);\r
+            if (rv) return rv;\r
+        }\r
+        se = se->getNext();\r
+    }\r
+  \r
+    // now handle the general case\r
+    unsigned char sp = *((const unsigned char *)(word + len - 1));\r
+    SfxEntry * sptr = (SfxEntry *) sStart[sp];\r
+\r
+    while (sptr) {\r
+        if (isRevSubset(sptr->getKey(), word + len - 1, len)) {\r
+            if (contclasses[sptr->getFlag()])\r
+            {\r
+                rv = sptr->check_twosfx(word,len, sfxopts, ppfx, needflag);\r
+                if (rv) {\r
+                    sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless\r
+                    if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless\r
+                    return rv;\r
+                }\r
+            }\r
+            sptr = sptr->getNextEQ();\r
+        } else {\r
+             sptr = sptr->getNextNE();\r
+        }\r
+    }\r
+\r
+    return NULL;\r
+}\r
+\r
+#ifdef HUNSPELL_EXPERIMENTAL\r
+char * AffixMgr::suffix_check_twosfx_morph(const char * word, int len, \r
+       int sfxopts, AffEntry * ppfx, const FLAG needflag)\r
+{\r
+    char result[MAXLNLEN];\r
+    char result2[MAXLNLEN];\r
+    char result3[MAXLNLEN];\r
+    \r
+    char * st;\r
+\r
+    result[0] = '\0';\r
+    result2[0] = '\0';\r
+    result3[0] = '\0';\r
+\r
+    // first handle the special case of 0 length suffixes\r
+    SfxEntry * se = (SfxEntry *) sStart[0];\r
+    while (se) {\r
+        if (contclasses[se->getFlag()])\r
+        {\r
+            st = se->check_twosfx_morph(word,len, sfxopts, ppfx, needflag);\r
+            if (st) {\r
+                if (ppfx) {\r
+                    if (((PfxEntry *) ppfx)->getMorph()) strcat(result, ((PfxEntry *) ppfx)->getMorph());\r
+                }\r
+                strcat(result, st);\r
+                free(st);\r
+                if (se->getMorph()) strcat(result, se->getMorph());\r
+                strcat(result, "\n");\r
+            }\r
+        }\r
+        se = se->getNext();\r
+    }\r
+  \r
+    // now handle the general case\r
+    unsigned char sp = *((const unsigned char *)(word + len - 1));\r
+    SfxEntry * sptr = (SfxEntry *) sStart[sp];\r
+\r
+    while (sptr) {\r
+        if (isRevSubset(sptr->getKey(), word + len - 1, len)) {\r
+            if (contclasses[sptr->getFlag()]) \r
+            {\r
+                st = sptr->check_twosfx_morph(word,len, sfxopts, ppfx, needflag);\r
+                if (st) {\r
+                    sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless\r
+                    if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless\r
+                    strcpy(result2, st);\r
+                    free(st);\r
+\r
+                result3[0] = '\0';\r
+#ifdef DEBUG\r
+                unsigned short flag = sptr->getFlag();\r
+                if (flag_mode == FLAG_NUM) {\r
+                    sprintf(result3, "<%d>", sptr->getKey());\r
+                } else if (flag_mode == FLAG_LONG) {\r
+                    sprintf(result3, "<%c%c>", flag >> 8, (flag << 8) >>8);\r
+                } else sprintf(result3, "<%c>", flag);\r
+                strcat(result3, ":");\r
+#endif\r
+                if (sptr->getMorph()) strcat(result3, sptr->getMorph());\r
+