summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/frontend/framework/femain.cpp17
-rw-r--r--src/frontend/im/hebrewmcim.cpp13
-rw-r--r--src/frontend/im/nullim.cpp17
-rw-r--r--src/frontend/im/swinputmeth.cpp12
-rw-r--r--src/frontend/swdisp.cpp16
-rw-r--r--src/frontend/swlog.cpp17
-rw-r--r--src/keys/genarray.c17
-rw-r--r--src/keys/listkey.cpp41
-rw-r--r--src/keys/strkey.cpp21
-rw-r--r--src/keys/swkey.cpp66
-rw-r--r--src/keys/treekey.cpp3
-rw-r--r--src/keys/treekeyidx.cpp35
-rw-r--r--src/keys/versekey.cpp1193
-rw-r--r--src/keys/versetreekey.cpp238
-rw-r--r--src/mgr/Makefile.am2
-rw-r--r--src/mgr/curlftpt.cpp20
-rw-r--r--src/mgr/curlhttpt.cpp178
-rw-r--r--src/mgr/encfiltmgr.cpp7
-rw-r--r--src/mgr/filemgr.cpp4
-rw-r--r--src/mgr/ftplibftpt.cpp19
-rw-r--r--src/mgr/ftptrans.cpp23
-rw-r--r--src/mgr/installmgr.cpp262
-rw-r--r--src/mgr/localemgr.cpp33
-rw-r--r--src/mgr/swconfig.cpp52
-rw-r--r--src/mgr/swlocale.cpp104
-rw-r--r--src/mgr/swmgr.cpp253
-rw-r--r--src/mgr/versemgr.cpp369
-rw-r--r--src/modules/comments/hrefcom/hrefcom.cpp25
-rw-r--r--src/modules/comments/rawcom/rawcom.cpp66
-rw-r--r--src/modules/comments/rawcom4/rawcom4.cpp71
-rw-r--r--src/modules/comments/rawfiles/rawfiles.cpp111
-rw-r--r--src/modules/comments/swcom.cpp84
-rw-r--r--src/modules/comments/zcom/zcom.cpp73
-rw-r--r--src/modules/common/entriesblk.cpp17
-rw-r--r--src/modules/common/lzsscomprs.cpp16
-rw-r--r--src/modules/common/rawstr.cpp140
-rw-r--r--src/modules/common/rawstr4.cpp140
-rw-r--r--src/modules/common/rawverse.cpp132
-rw-r--r--src/modules/common/rawverse4.cpp129
-rw-r--r--src/modules/common/swcipher.cpp17
-rw-r--r--src/modules/common/swcomprs.cpp17
-rw-r--r--src/modules/common/zipcomprs.cpp17
-rw-r--r--src/modules/common/zstr.cpp124
-rw-r--r--src/modules/common/zverse.cpp219
-rw-r--r--src/modules/filters/Makefile.am3
-rw-r--r--src/modules/filters/cipherfil.cpp15
-rw-r--r--src/modules/filters/gbffootnotes.cpp28
-rw-r--r--src/modules/filters/gbfheadings.cpp16
-rw-r--r--src/modules/filters/gbfhtml.cpp34
-rw-r--r--src/modules/filters/gbfhtmlhref.cpp37
-rw-r--r--src/modules/filters/gbfmorph.cpp17
-rw-r--r--src/modules/filters/gbfosis.cpp58
-rw-r--r--src/modules/filters/gbfplain.cpp17
-rw-r--r--src/modules/filters/gbfredletterwords.cpp17
-rw-r--r--src/modules/filters/gbfrtf.cpp17
-rw-r--r--src/modules/filters/gbfstrongs.cpp17
-rw-r--r--src/modules/filters/gbfthml.cpp34
-rw-r--r--src/modules/filters/gbfwebif.cpp35
-rw-r--r--src/modules/filters/gbfwordjs.cpp17
-rw-r--r--src/modules/filters/greeklexattribs.cpp17
-rw-r--r--src/modules/filters/latin1utf16.cpp19
-rw-r--r--src/modules/filters/latin1utf8.cpp17
-rw-r--r--src/modules/filters/osisfootnotes.cpp46
-rw-r--r--src/modules/filters/osisheadings.cpp57
-rw-r--r--src/modules/filters/osishtmlhref.cpp165
-rw-r--r--src/modules/filters/osislemma.cpp17
-rw-r--r--src/modules/filters/osismorph.cpp17
-rw-r--r--src/modules/filters/osismorphsegmentation.cpp17
-rw-r--r--src/modules/filters/osisosis.cpp68
-rw-r--r--src/modules/filters/osisplain.cpp71
-rw-r--r--src/modules/filters/osisredletterwords.cpp17
-rw-r--r--src/modules/filters/osisrtf.cpp83
-rw-r--r--src/modules/filters/osisruby.cpp93
-rw-r--r--src/modules/filters/osisscripref.cpp17
-rw-r--r--src/modules/filters/osisstrongs.cpp42
-rw-r--r--src/modules/filters/osisvariants.cpp17
-rw-r--r--src/modules/filters/osiswebif.cpp44
-rw-r--r--src/modules/filters/osiswordjs.cpp22
-rw-r--r--src/modules/filters/papyriplain.cpp17
-rw-r--r--src/modules/filters/plainfootnotes.cpp36
-rw-r--r--src/modules/filters/plainhtml.cpp36
-rw-r--r--src/modules/filters/rtfhtml.cpp36
-rw-r--r--src/modules/filters/scsuutf8.cpp226
-rw-r--r--src/modules/filters/swoptfilter.cpp19
-rw-r--r--src/modules/filters/teihtmlhref.cpp100
-rw-r--r--src/modules/filters/teiplain.cpp34
-rw-r--r--src/modules/filters/teirtf.cpp58
-rw-r--r--src/modules/filters/thmlfootnotes.cpp28
-rw-r--r--src/modules/filters/thmlgbf.cpp35
-rw-r--r--src/modules/filters/thmlheadings.cpp17
-rw-r--r--src/modules/filters/thmlhtml.cpp35
-rw-r--r--src/modules/filters/thmlhtmlhref.cpp38
-rw-r--r--src/modules/filters/thmllemma.cpp17
-rw-r--r--src/modules/filters/thmlmorph.cpp17
-rw-r--r--src/modules/filters/thmlosis.cpp48
-rw-r--r--src/modules/filters/thmlplain.cpp213
-rw-r--r--src/modules/filters/thmlrtf.cpp35
-rw-r--r--src/modules/filters/thmlscripref.cpp30
-rw-r--r--src/modules/filters/thmlstrongs.cpp17
-rw-r--r--src/modules/filters/thmlvariants.cpp17
-rw-r--r--src/modules/filters/thmlwebif.cpp35
-rw-r--r--src/modules/filters/thmlwordjs.cpp17
-rw-r--r--src/modules/filters/unicodertf.cpp17
-rw-r--r--src/modules/filters/utf16utf8.cpp17
-rw-r--r--src/modules/filters/utf8arabicpoints.cpp61
-rw-r--r--src/modules/filters/utf8arshaping.cpp24
-rw-r--r--src/modules/filters/utf8bidireorder.cpp24
-rw-r--r--src/modules/filters/utf8cantillation.cpp17
-rw-r--r--src/modules/filters/utf8greekaccents.cpp17
-rw-r--r--src/modules/filters/utf8hebrewpoints.cpp17
-rw-r--r--src/modules/filters/utf8html.cpp17
-rw-r--r--src/modules/filters/utf8latin1.cpp16
-rw-r--r--src/modules/filters/utf8nfc.cpp24
-rw-r--r--src/modules/filters/utf8nfkd.cpp24
-rw-r--r--src/modules/filters/utf8transliterator.cpp158
-rw-r--r--src/modules/filters/utf8utf16.cpp79
-rw-r--r--src/modules/genbook/rawgenbook/rawgenbook.cpp75
-rw-r--r--src/modules/genbook/swgenbook.cpp74
-rw-r--r--src/modules/lexdict/rawld/rawld.cpp99
-rw-r--r--src/modules/lexdict/rawld4/rawld4.cpp100
-rw-r--r--src/modules/lexdict/swld.cpp85
-rw-r--r--src/modules/lexdict/zld/zld.cpp96
-rw-r--r--src/modules/swmodule.cpp259
-rw-r--r--src/modules/tests/echomod.cpp16
-rw-r--r--src/modules/texts/rawtext/rawtext.cpp452
-rw-r--r--src/modules/texts/rawtext4/rawtext4.cpp453
-rw-r--r--src/modules/texts/swtext.cpp80
-rw-r--r--src/modules/texts/ztext/ztext.cpp83
-rw-r--r--src/utilfuns/Makefile.am2
-rw-r--r--src/utilfuns/regex.c5721
-rw-r--r--src/utilfuns/roman.cpp38
-rw-r--r--src/utilfuns/sub.c36
-rw-r--r--src/utilfuns/swbuf.cpp5
-rw-r--r--src/utilfuns/swversion.cpp17
-rw-r--r--src/utilfuns/url.cpp38
-rw-r--r--src/utilfuns/utilstr.cpp135
-rw-r--r--src/utilfuns/utilxml.cpp27
-rw-r--r--src/utilfuns/win32/dirent.cpp131
-rw-r--r--src/utilfuns/win32/dirent.h32
-rw-r--r--src/utilfuns/zlib/adler32.c48
-rw-r--r--src/utilfuns/zlib/compress.c68
-rw-r--r--src/utilfuns/zlib/crc32.c162
-rw-r--r--src/utilfuns/zlib/deflate.c1350
-rw-r--r--src/utilfuns/zlib/deflate.h318
-rw-r--r--src/utilfuns/zlib/gzio.c875
-rw-r--r--src/utilfuns/zlib/infblock.c403
-rw-r--r--src/utilfuns/zlib/infblock.h39
-rw-r--r--src/utilfuns/zlib/infcodes.c251
-rw-r--r--src/utilfuns/zlib/infcodes.h27
-rw-r--r--src/utilfuns/zlib/inffast.c183
-rw-r--r--src/utilfuns/zlib/inffast.h17
-rw-r--r--src/utilfuns/zlib/inffixed.h151
-rw-r--r--src/utilfuns/zlib/inflate.c366
-rw-r--r--src/utilfuns/zlib/inftrees.c454
-rw-r--r--src/utilfuns/zlib/inftrees.h58
-rw-r--r--src/utilfuns/zlib/infutil.c87
-rw-r--r--src/utilfuns/zlib/infutil.h98
-rw-r--r--src/utilfuns/zlib/maketree.c85
-rw-r--r--src/utilfuns/zlib/trees.c1214
-rw-r--r--src/utilfuns/zlib/trees.h128
-rw-r--r--src/utilfuns/zlib/uncompr.c58
-rw-r--r--src/utilfuns/zlib/zutil.c225
-rw-r--r--src/utilfuns/zlib/zutil.h220
163 files changed, 5748 insertions, 16502 deletions
diff --git a/src/frontend/framework/femain.cpp b/src/frontend/framework/femain.cpp
index 415ab6f..e6580cb 100644
--- a/src/frontend/framework/femain.cpp
+++ b/src/frontend/framework/femain.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
#include <femain.h>
FEMain::FEMain() {
diff --git a/src/frontend/im/hebrewmcim.cpp b/src/frontend/im/hebrewmcim.cpp
index 9ec55a9..c8bb5fa 100644
--- a/src/frontend/im/hebrewmcim.cpp
+++ b/src/frontend/im/hebrewmcim.cpp
@@ -8,6 +8,19 @@
* @version 1.0
*/
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+
#include <hebrewmcim.h>
HebrewMCIM::HebrewMCIM()
diff --git a/src/frontend/im/nullim.cpp b/src/frontend/im/nullim.cpp
index a4f4aad..bceeb23 100644
--- a/src/frontend/im/nullim.cpp
+++ b/src/frontend/im/nullim.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
#include <nullim.h>
diff --git a/src/frontend/im/swinputmeth.cpp b/src/frontend/im/swinputmeth.cpp
index 7f64865..7ba60dd 100644
--- a/src/frontend/im/swinputmeth.cpp
+++ b/src/frontend/im/swinputmeth.cpp
@@ -7,6 +7,18 @@
* @version 1.0
*/
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
#include <swinputmeth.h>
SWInputMethod::SWInputMethod() {
diff --git a/src/frontend/swdisp.cpp b/src/frontend/swdisp.cpp
index e7208e0..bf46ff2 100644
--- a/src/frontend/swdisp.cpp
+++ b/src/frontend/swdisp.cpp
@@ -1,8 +1,24 @@
/******************************************************************************
* swdisp.cpp - code for base class 'swdisp'. swdisp is the basis for all
* types of displays (e.g. raw textout, curses, xwindow, etc.)
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#ifndef _WIN32_WCE
#include <iostream>
#endif
diff --git a/src/frontend/swlog.cpp b/src/frontend/swlog.cpp
index 13b025b..74b6bd4 100644
--- a/src/frontend/swlog.cpp
+++ b/src/frontend/swlog.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
//---------------------------------------------------------------------------
#include <stdarg.h>
diff --git a/src/keys/genarray.c b/src/keys/genarray.c
index 331d4af..112b0f6 100644
--- a/src/keys/genarray.c
+++ b/src/keys/genarray.c
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
diff --git a/src/keys/listkey.cpp b/src/keys/listkey.cpp
index ffafdd4..49bf369 100644
--- a/src/keys/listkey.cpp
+++ b/src/keys/listkey.cpp
@@ -1,9 +1,26 @@
/******************************************************************************
* listkey.cpp - code for base class 'ListKey'. ListKey is the basis for all
- * types of keys that have lists of specified indexes
- * (e.g. a list of verses, place, etc.)
+ * types of keys that have lists of specified indexes
+ * (e.g. a list of verses, place, etc.)
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <utilstr.h>
#include <stdlib.h>
#include <swkey.h>
@@ -41,6 +58,8 @@ ListKey::ListKey(ListKey const &k) : SWKey(k.keytext) {
void ListKey::init() {
myclass = &classdef;
+ // this is a listkey, bound is always set
+ boundSet = true;
}
@@ -281,6 +300,24 @@ const char *ListKey::getRangeText() const {
/******************************************************************************
+ * ListKey::getOSISRefRangeText - returns parsable range text for this key
+ */
+
+const char *ListKey::getOSISRefRangeText() const {
+ char *buf = new char[(arraycnt + 1) * 255];
+ buf[0] = 0;
+ for (int i = 0; i < arraycnt; i++) {
+ strcat(buf, array[i]->getOSISRefRangeText());
+ if (i < arraycnt-1)
+ strcat(buf, ";");
+ }
+ stdstr(&rangeText, buf);
+ delete [] buf;
+ return rangeText;
+}
+
+
+/******************************************************************************
* ListKey::getText - returns text key if (const char *) cast is requested
*/
diff --git a/src/keys/strkey.cpp b/src/keys/strkey.cpp
index 1d84650..4171e36 100644
--- a/src/keys/strkey.cpp
+++ b/src/keys/strkey.cpp
@@ -1,9 +1,26 @@
/******************************************************************************
* StrKey.cpp - code for class 'StrKey'- a standard string key class (used
- * for modules that index on single strings (eg. cities,
- * names, words, etc.)
+ * for modules that index on single strings (eg. cities,
+ * names, words, etc.)
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <swmacs.h>
#include <strkey.h>
#include <stdio.h>
diff --git a/src/keys/swkey.cpp b/src/keys/swkey.cpp
index 0557c40..3709cdc 100644
--- a/src/keys/swkey.cpp
+++ b/src/keys/swkey.cpp
@@ -2,16 +2,35 @@
* swkey.cpp - code for base class 'SWKey'. SWKey is the basis for all
* types of keys for indexing into modules (e.g. verse, word,
* place, etc.)
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <swkey.h>
#include <utilstr.h>
#include <string.h>
+#include <localemgr.h>
SWORD_NAMESPACE_START
static const char *classes[] = {"SWKey", "SWObject", 0};
SWClass SWKey::classdef(classes);
+SWKey::LocaleCache SWKey::localeCache;
/******************************************************************************
* SWKey Constructor - initializes instance of SWKey
@@ -21,6 +40,7 @@ SWClass SWKey::classdef(classes);
SWKey::SWKey(const char *ikey)
{
+ init();
index = 0;
persist = 0;
keytext = 0;
@@ -28,11 +48,12 @@ SWKey::SWKey(const char *ikey)
error = 0;
userData = 0;
stdstr(&keytext, ikey);
- init();
}
SWKey::SWKey(SWKey const &k)
{
+ init();
+ stdstr(&localeName, k.localeName);
index = k.index;
persist = k.persist;
userData = k.userData;
@@ -40,12 +61,14 @@ SWKey::SWKey(SWKey const &k)
rangeText = 0;
error = k.error;
setText(k.getText());
- init();
}
void SWKey::init() {
myclass = &classdef;
boundSet = false;
+ locale = 0;
+ localeName = 0;
+ setLocale(LocaleMgr::getSystemLocaleMgr()->getDefaultLocaleName());
}
SWKey *SWKey::clone() const
@@ -58,10 +81,9 @@ SWKey *SWKey::clone() const
*/
SWKey::~SWKey() {
- if (keytext)
- delete [] keytext;
- if (rangeText)
- delete [] rangeText;
+ delete [] keytext;
+ delete [] rangeText;
+ delete [] localeName;
}
@@ -80,6 +102,28 @@ char SWKey::Persist() const
/******************************************************************************
+ * SWKey::getPrivateLocale - Gets a real locale object from our name
+ *
+ * RET: locale object associated with our name
+ */
+
+SWLocale *SWKey::getPrivateLocale() const {
+ if (!locale) {
+ if ((!localeCache.name) || (strcmp(localeCache.name, localeName))) {
+ stdstr(&(localeCache.name), localeName);
+ // this line is the entire bit of work we're trying to avoid with the cache
+ // worth it? compare time examples/cmdline/search KJV "God love world" to
+ // same with this method reduced to:
+ // if (!local) local = ... (call below); return locale;
+ localeCache.locale = LocaleMgr::getSystemLocaleMgr()->getLocale(localeName);
+ }
+ locale = localeCache.locale;
+ }
+ return locale;
+}
+
+
+/******************************************************************************
* SWKey::Persist - Set/gets whether this object itself persists within a
* module that it was used to setKey or just a copy.
* (1 - persists in module; 0 - a copy is attempted
@@ -133,6 +177,7 @@ void SWKey::setText(const char *ikey) {
void SWKey::copyFrom(const SWKey &ikey) {
// not desirable Persist(ikey.Persist());
+ setLocale(ikey.getLocale());
setText((const char *)ikey);
}
@@ -157,6 +202,15 @@ const char *SWKey::getRangeText() const {
/******************************************************************************
+ * SWKey::getOSISRefRangeText - returns parsable range text for this key
+ */
+
+const char *SWKey::getOSISRefRangeText() const {
+ return getRangeText();
+}
+
+
+/******************************************************************************
* SWKey::compare - Compares another VerseKey object
*
* ENT: ikey - key to compare with this one
diff --git a/src/keys/treekey.cpp b/src/keys/treekey.cpp
index 2b217ee..ce769a1 100644
--- a/src/keys/treekey.cpp
+++ b/src/keys/treekey.cpp
@@ -1,7 +1,7 @@
/******************************************************************************
* versekey.h - code for class 'versekey'- a standard Biblical verse key
*
- * $Id: treekey.cpp 1994 2006-11-20 20:24:06Z scribe $
+ * $Id: treekey.cpp 2178 2008-06-20 15:10:47Z scribe $
*
* Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
* CrossWire Bible Society
@@ -32,6 +32,7 @@ SWClass TreeKey::classdef(classes);
void TreeKey::init() {
myclass = &classdef;
unsnappedKeyText = "";
+ posChangeListener = 0;
}
diff --git a/src/keys/treekeyidx.cpp b/src/keys/treekeyidx.cpp
index 738d17a..cc93fc0 100644
--- a/src/keys/treekeyidx.cpp
+++ b/src/keys/treekeyidx.cpp
@@ -1,7 +1,7 @@
/******************************************************************************
* versekey.h - code for class 'versekey'- a standard Biblical verse key
*
- * $Id: treekeyidx.cpp 2147 2008-03-14 06:54:18Z scribe $
+ * $Id: treekeyidx.cpp 2280 2009-03-07 15:34:36Z scribe $
*
* Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
* CrossWire Bible Society
@@ -91,7 +91,7 @@ const char *TreeKeyIdx::getLocalName() {
}
-const char *TreeKeyIdx::getUserData(int *size) {
+const char *TreeKeyIdx::getUserData(int *size) const {
unsnappedKeyText = "";
if (size)
*size = (int)currentNode.dsize;
@@ -127,12 +127,25 @@ void TreeKeyIdx::save() {
void TreeKeyIdx::root() {
error = getTreeNodeFromIdxOffset(0, &currentNode);
+ positionChanged();
+}
+
+int TreeKeyIdx::getLevel() {
+ TreeNode iterator;
+ iterator.parent = currentNode.parent;
+ int level = 0;
+ while (iterator.parent > -1) {
+ level++;
+ getTreeNodeFromIdxOffset(iterator.parent, &iterator);
+ }
+ return level;
}
bool TreeKeyIdx::parent() {
if (currentNode.parent > -1) {
error = getTreeNodeFromIdxOffset(currentNode.parent, &currentNode);
+ positionChanged();
return true;
}
return false;
@@ -142,6 +155,7 @@ bool TreeKeyIdx::parent() {
bool TreeKeyIdx::firstChild() {
if (currentNode.firstChild > -1) {
error = getTreeNodeFromIdxOffset(currentNode.firstChild, &currentNode);
+ positionChanged();
return true;
}
return false;
@@ -151,6 +165,7 @@ bool TreeKeyIdx::firstChild() {
bool TreeKeyIdx::nextSibling() {
if (currentNode.next > -1) {
error = getTreeNodeFromIdxOffset(currentNode.next, &currentNode);
+ positionChanged();
return true;
}
return false;
@@ -168,6 +183,7 @@ bool TreeKeyIdx::previousSibling() {
getTreeNodeFromIdxOffset(iterator.next, &iterator);
if (iterator.next > -1) {
error = getTreeNodeFromIdxOffset(iterator.offset, &currentNode);
+ positionChanged();
return true;
}
}
@@ -195,6 +211,7 @@ void TreeKeyIdx::append() {
currentNode.clear();
currentNode.offset = idxOffset;
currentNode.parent = parent;
+ positionChanged();
}
}
@@ -212,6 +229,7 @@ void TreeKeyIdx::appendChild() {
currentNode.offset = idxOffset;
currentNode.parent = parent;
}
+ positionChanged();
}
@@ -253,6 +271,7 @@ void TreeKeyIdx::remove() {
}
}
}
+ positionChanged();
}
}
@@ -292,7 +311,7 @@ signed char TreeKeyIdx::create(const char *ipath) {
newTree.saveTreeNode(&root);
delete [] path;
-
+
return 0;
}
@@ -394,6 +413,7 @@ unsigned long TreeKeyIdx::getOffset() const {
void TreeKeyIdx::setOffset(unsigned long offset) {
error = getTreeNodeFromIdxOffset(offset, &currentNode);
+ positionChanged();
}
@@ -461,6 +481,7 @@ void TreeKeyIdx::copyFrom(const TreeKeyIdx &ikey) {
idxfd = FileMgr::getSystemFileMgr()->open(ikey.idxfd->path, ikey.idxfd->mode, ikey.idxfd->perms);
datfd = FileMgr::getSystemFileMgr()->open(ikey.datfd->path, ikey.datfd->mode, ikey.datfd->perms);
}
+ positionChanged();
}
@@ -520,6 +541,7 @@ void TreeKeyIdx::setText(const char *ikey) {
error = KEYERR_OUTOFBOUNDS;
delete [] buf;
unsnappedKeyText = ikey;
+ positionChanged();
}
@@ -527,6 +549,7 @@ void TreeKeyIdx::setText(const char *ikey) {
void TreeKeyIdx::copyFrom(const SWKey &ikey) {
unsnappedKeyText = ikey;
SWKey::copyFrom(ikey);
+ positionChanged();
}
void TreeKeyIdx::setPosition(SW_POSITION p) {
@@ -538,6 +561,7 @@ void TreeKeyIdx::setPosition(SW_POSITION p) {
error = getTreeNodeFromIdxOffset(idxfd->seek(-4, SEEK_END), &currentNode);
break;
}
+ positionChanged();
Error(); // clear error from normalize
}
@@ -557,10 +581,15 @@ int TreeKeyIdx::compare(const SWKey &ikey) {
void TreeKeyIdx::decrement(int steps) {
error = getTreeNodeFromIdxOffset(currentNode.offset - (4*steps), &currentNode);
+ positionChanged();
}
void TreeKeyIdx::increment(int steps) {
error = getTreeNodeFromIdxOffset(currentNode.offset + (4*steps), &currentNode);
+ if (error) {
+// SWLog::getSystemLog()->logError("error: %d", error);
+ }
+ positionChanged();
/*
// assert positive
diff --git a/src/keys/versekey.cpp b/src/keys/versekey.cpp
index cb7bbfc..9c50a04 100644
--- a/src/keys/versekey.cpp
+++ b/src/keys/versekey.cpp
@@ -1,7 +1,24 @@
/******************************************************************************
* VerseKey.cpp - code for class 'VerseKey'- a standard Biblical verse key
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <swmacs.h>
#include <stdio.h>
#include <fcntl.h>
@@ -13,9 +30,9 @@
#include <swkey.h>
#include <swlog.h>
#include <versekey.h>
-#include <localemgr.h>
#include <swlocale.h>
#include <roman.h>
+#include <versemgr.h>
SWORD_NAMESPACE_START
@@ -26,23 +43,15 @@ SWClass VerseKey::classdef(classes);
* Initialize static members of VerseKey
*/
-#include <canon.h> // Initialize static members of canonical books structure
-
-struct sbook *VerseKey::builtin_books[2] = {0,0};
-const char VerseKey::builtin_BMAX[2] = {39, 27};
-long *VerseKey::offsets[2][2] = {{VerseKey::otbks, VerseKey::otcps}, {VerseKey::ntbks, VerseKey::ntcps}};
int VerseKey::instance = 0;
-VerseKey::LocaleCache VerseKey::localeCache;
/******************************************************************************
* VerseKey::init - initializes instance of VerseKey
*/
-void VerseKey::init() {
+void VerseKey::init(const char *v11n) {
myclass = &classdef;
- if (!instance)
- initstatics();
instance++;
autonorm = 1; // default auto normalization to true
@@ -50,13 +59,15 @@ void VerseKey::init() {
upperBound = 0;
lowerBound = 0;
boundSet = false;
- testament = 0;
- book = 0;
- chapter = 0;
- verse = 0;
- locale = 0;
-
- setLocale(LocaleMgr::getSystemLocaleMgr()->getDefaultLocaleName());
+ testament = 1;
+ book = 1;
+ chapter = 1;
+ verse = 1;
+ suffix = 0;
+ tmpClone = 0;
+ refSys = 0;
+
+ setVersificationSystem(v11n);
}
/******************************************************************************
@@ -104,6 +115,57 @@ VerseKey::VerseKey(VerseKey const &k) : SWKey(k)
/******************************************************************************
+ * VerseKey::setFromOther - Positions this VerseKey to another VerseKey
+ */
+
+void VerseKey::setFromOther(const VerseKey &ikey) {
+ if (refSys == ikey.refSys) {
+ testament = ikey.Testament();
+ book = ikey.Book();
+ chapter = ikey.Chapter();
+ verse = ikey.Verse();
+ suffix = ikey.getSuffix();
+ }
+ // Here is where we will do v11n system conversions in the future
+ // when we have a conversion mechanism (Ben Morgan has started
+ // thinking about this)
+ else {
+ // For now, this is the best we can do
+ setText(ikey.getText());
+ }
+}
+
+
+void VerseKey::positionFrom(const SWKey &ikey) {
+ error = 0;
+ const SWKey *fromKey = &ikey;
+ ListKey *tryList = SWDYNAMIC_CAST(ListKey, fromKey);
+ if (tryList) {
+ SWKey *k = tryList->getElement();
+ if (k) fromKey = k;
+ }
+ VerseKey *tryVerse = SWDYNAMIC_CAST(VerseKey, fromKey);
+ if (tryVerse) {
+ setFromOther(*tryVerse);
+ }
+ else {
+ SWKey::positionFrom(*fromKey);
+ parse();
+ }
+
+ // should we always perform bounds checks? Tried but seems to cause infinite recursion
+ if (_compare(UpperBound()) > 0) {
+ setFromOther(UpperBound());
+ error = KEYERR_OUTOFBOUNDS;
+ }
+ if (_compare(LowerBound()) < 0) {
+ setFromOther(LowerBound());
+ error = KEYERR_OUTOFBOUNDS;
+ }
+}
+
+
+/******************************************************************************
* VerseKey::copyFrom - Equates this VerseKey to another VerseKey
*/
@@ -114,6 +176,9 @@ void VerseKey::copyFrom(const VerseKey &ikey) {
book = ikey.Book();
chapter = ikey.Chapter();
verse = ikey.Verse();
+ suffix = ikey.getSuffix();
+ setLocale(ikey.getLocale());
+ setVersificationSystem(ikey.getVersificationSystem());
if (ikey.isBoundSet()) {
LowerBound(ikey.LowerBound());
UpperBound(ikey.UpperBound());
@@ -145,11 +210,19 @@ void VerseKey::copyFrom(const SWKey &ikey) {
}
-VerseKey::VerseKey(const char *min, const char *max) : SWKey()
+VerseKey::VerseKey(const char *min, const char *max, const char *v11n) : SWKey()
{
- init();
- LowerBound(min);
- UpperBound(max);
+ init(v11n);
+ ListKey tmpListKey = ParseVerseList(min);
+ if (tmpListKey.Count()) {
+ VerseKey *newElement = SWDYNAMIC_CAST(VerseKey, tmpListKey.GetElement(0));
+ LowerBound(*newElement);
+ }
+ tmpListKey = ParseVerseList(max, min, true);
+ if (tmpListKey.Count()) {
+ VerseKey *newElement = SWDYNAMIC_CAST(VerseKey, tmpListKey.GetElement(0));
+ UpperBound((newElement->isBoundSet())?newElement->UpperBound():*newElement);
+ }
setPosition(TOP);
}
@@ -167,117 +240,33 @@ SWKey *VerseKey::clone() const
*/
VerseKey::~VerseKey() {
- if (upperBound)
- delete upperBound;
- if (lowerBound)
- delete lowerBound;
- if (locale)
- delete [] locale;
+
+ delete tmpClone;
--instance;
}
-void VerseKey::setLocale(const char *name) {
- char *BMAX;
- struct sbook **lbooks;
- bool useCache = false;
+void VerseKey::setVersificationSystem(const char *name) {
+ const VerseMgr::System *newRefSys = VerseMgr::getSystemVerseMgr()->getVersificationSystem(name);
+ // TODO: cheese, but what should we do if requested v11n system isn't found?
+ if (!newRefSys) newRefSys = VerseMgr::getSystemVerseMgr()->getVersificationSystem("KJV");
+ if (refSys != newRefSys) {
+ refSys = newRefSys;
+ BMAX[0] = refSys->getBMAX()[0];
+ BMAX[1] = refSys->getBMAX()[1];
- if (localeCache.name)
- useCache = (!strcmp(localeCache.name, name));
-
- if (!useCache) { // if we're setting params for a new locale
- stdstr(&(localeCache.name), name);
- localeCache.abbrevsCnt = 0;
- }
-
- SWLocale *locale = (useCache) ? localeCache.locale : LocaleMgr::getSystemLocaleMgr()->getLocale(name);
- localeCache.locale = locale;
-
- if (locale) {
- locale->getBooks(&BMAX, &lbooks);
- setBooks(BMAX, lbooks);
- setBookAbbrevs(locale->getBookAbbrevs(), localeCache.abbrevsCnt);
- localeCache.abbrevsCnt = abbrevsCnt;
+ // TODO: adjust bounds for versificaion system ???
+ // TODO: when we have mapping done, rethink this
+ //necessary as our bounds might not mean anything in the new v11n system
+ ClearBounds();
}
- else {
- setBooks(builtin_BMAX, builtin_books);
- setBookAbbrevs(builtin_abbrevs, localeCache.abbrevsCnt);
- localeCache.abbrevsCnt = abbrevsCnt;
- }
- stdstr(&(this->locale), localeCache.name);
-
- if (lowerBound)
- LowerBound().setLocale(name);
- if (upperBound)
- UpperBound().setLocale(name);
-}
-
-void VerseKey::setBooks(const char *iBMAX, struct sbook **ibooks) {
- BMAX = iBMAX;
- books = ibooks;
-}
-
-void VerseKey::setBookAbbrevs(const struct abbrev *bookAbbrevs, unsigned int size) {
- abbrevs = bookAbbrevs;
- if (!size) {
- for (abbrevsCnt = 0; *abbrevs[abbrevsCnt].ab; abbrevsCnt++) {
- /*
- if (strcmp(abbrevs[abbrevsCnt-1].ab, abbrevs[abbrevsCnt].ab) > 0) {
- fprintf(stderr, "ERROR: book abbreviation (canon.h or locale) misordered at entry: %s\n", abbrevs[abbrevsCnt].ab);
- exit(-1);
- }
- */
- }
-
- if (SWLog::getSystemLog()->getLogLevel() > 0) { //make sure log is wanted, this loop stuff costs a lot of time
- for (int t = 0; t < 2; t++) {
- for (int i = 0; i < BMAX[t]; i++) {
- const int bn = getBookAbbrev(books[t][i].name);
- if ((bn-1)%39 != i) {
- SWLog::getSystemLog()->logError("VerseKey::Book: %s does not have a matching toupper abbrevs entry! book number returned was: %d(%d). Required entry should be:",
- books[t][i].name, bn, i);
- char *abbr = 0;
- stdstr(&abbr, books[t][i].name, 2);
- strstrip(abbr);
-
- StringMgr* stringMgr = StringMgr::getSystemStringMgr();
- const bool hasUTF8Support = StringMgr::hasUTF8Support();
- if (hasUTF8Support) { //we have support for UTF-8 handling; we expect UTF-8 encoded locales
- stringMgr->upperUTF8(abbr, strlen(abbr)*2);
- }
- else {
- stringMgr->upperLatin1(abbr);
- }
- SWLog::getSystemLog()->logError("%s=%d", abbr, (t*39)+i+1);
- }
- }
- }
- }
- }
- else abbrevsCnt = size;
}
-/******************************************************************************
- * VerseKey::initstatics - initializes statics. Performed only when first
- * instance on VerseKey (or descendent) is created.
- */
-
-void VerseKey::initstatics() {
- int l1, l2, chaptmp = 0;
-
- builtin_books[0] = otbooks;
- builtin_books[1] = ntbooks;
+const char *VerseKey::getVersificationSystem() const { return refSys->getName(); }
- for (l1 = 0; l1 < 2; l1++) {
- for (l2 = 0; l2 < builtin_BMAX[l1]; l2++) {
- builtin_books[l1][l2].versemax = &vm[chaptmp];
- chaptmp += builtin_books[l1][l2].chapmax;
- }
- }
-}
/******************************************************************************
@@ -288,37 +277,18 @@ void VerseKey::initstatics() {
char VerseKey::parse(bool checkAutoNormalize)
{
-
-
- testament = 2;
- book = BMAX[1];
+ testament = BMAX[1]?2:1;
+ book = BMAX[BMAX[1]?1:0];
chapter = 1;
verse = 1;
- int booklen = 0;
int error = 0;
if (keytext) {
- ListKey tmpListKey = VerseKey::ParseVerseList(keytext);
+ ListKey tmpListKey = ParseVerseList(keytext);
if (tmpListKey.Count()) {
- SWKey::setText((const char *)tmpListKey);
- for (int i = 1; i < 3; i++) {
- for (int j = 1; j <= BMAX[i-1]; j++) {
- int matchlen = strlen(books[i-1][j-1].name);
- if (!strncmp(keytext, books[i-1][j-1].name, matchlen)) {
- if (matchlen > booklen) {
- booklen = matchlen;
- testament = i;
- book = j;
- }
- }
- }
- }
-
- if (booklen) {
- sscanf(&keytext[booklen], "%d:%d", &chapter, &verse);
- }
- else error = 1;
+ this->positionFrom(*tmpListKey.getElement(0));
+ error = this->error;
} else error = 1;
}
if (checkAutoNormalize) {
@@ -338,7 +308,7 @@ char VerseKey::parse(bool checkAutoNormalize)
void VerseKey::freshtext() const
{
char buf[2024];
- int realtest = testament;
+ int realTest = testament;
int realbook = book;
if (book < 1) {
@@ -347,14 +317,18 @@ void VerseKey::freshtext() const
else sprintf(buf, "[ Testament %d Heading ]", (int)testament);
}
else {
- if (realbook > BMAX[realtest-1]) {
- realbook -= BMAX[realtest-1];
- if (realtest < 2)
- realtest++;
- if (realbook > BMAX[realtest-1])
- realbook = BMAX[realtest-1];
+ if (realbook > BMAX[realTest-1]) {
+ realbook -= BMAX[realTest-1];
+ if (realTest < 2)
+ realTest++;
+ if (realbook > BMAX[realTest-1])
+ realbook = BMAX[realTest-1];
+ }
+ sprintf(buf, "%s %d:%d", getBookName(), chapter, verse);
+ if (suffix) {
+ buf[strlen(buf)+1] = 0;
+ buf[strlen(buf)] = suffix;
}
- sprintf(buf, "%s %d:%d", books[realtest-1][realbook-1].name, chapter, verse);
}
stdstr((char **)&keytext, buf);
@@ -362,19 +336,24 @@ void VerseKey::freshtext() const
-/******************************************************************************
- * VerseKey::getBookAbbrev - Attempts to find a book abbreviation for a buffer
+/************************************************************************
+ * VerseKey::getBookAbbrev - Attempts to find a book no from a name or
+ * abbreviation
*
* ENT: abbr - key for which to search;
* RET: book number or < 0 = not valid
*/
-int VerseKey::getBookAbbrev(const char *iabbr)
+int VerseKey::getBookAbbrev(const char *iabbr) const
{
int diff, abLen, min, max, target, retVal = -1;
char *abbr = 0;
+ int abbrevsCnt;
+
+ const struct abbrev *abbrevs = getPrivateLocale()->getBookAbbrevs(&abbrevsCnt);
+
StringMgr* stringMgr = StringMgr::getSystemStringMgr();
const bool hasUTF8Support = StringMgr::hasUTF8Support();
@@ -420,7 +399,15 @@ int VerseKey::getBookAbbrev(const char *iabbr)
break;
}
- retVal = (!diff) ? abbrevs[target].book : -1;
+ if (!diff) {
+ // lets keep moving forward till we find an abbrev in our refSys
+ retVal = refSys->getBookNumberByOSISName(abbrevs[target].osis);
+ while ((retVal < 0) && (target < max) && (!strncmp(abbr, abbrevs[target+1].ab, abLen))) {
+ target++;
+ retVal = refSys->getBookNumberByOSISName(abbrevs[target].osis);
+ }
+ }
+ else retVal = -1;
}
if (retVal > 0)
break;
@@ -431,6 +418,36 @@ int VerseKey::getBookAbbrev(const char *iabbr)
/******************************************************************************
+ * VerseKey::validateCurrentLocale - be sure a locale book abbrevs set is complete
+ *
+ */
+void VerseKey::validateCurrentLocale() const {
+ if (SWLog::getSystemLog()->getLogLevel() >= SWLog::LOG_DEBUG) { //make sure log is wanted, this loop stuff costs a lot of time
+ for (int i = 0; i < refSys->getBookCount(); i++) {
+ const int bn = getBookAbbrev(getPrivateLocale()->translate(refSys->getBook(i)->getLongName()));
+ if (bn != i+1) {
+ char *abbr = 0;
+ stdstr(&abbr, getPrivateLocale()->translate(refSys->getBook(i)->getLongName()), 2);
+ strstrip(abbr);
+ SWLog::getSystemLog()->logDebug("VerseKey::Book: %s does not have a matching toupper abbrevs entry! book number returned was: %d, should be %d. Required entry to add to locale:", abbr, bn, i);
+
+ StringMgr* stringMgr = StringMgr::getSystemStringMgr();
+ const bool hasUTF8Support = StringMgr::hasUTF8Support();
+ if (hasUTF8Support) { //we have support for UTF-8 handling; we expect UTF-8 encoded locales
+ stringMgr->upperUTF8(abbr, strlen(abbr)*2);
+ }
+ else {
+ stringMgr->upperLatin1(abbr);
+ }
+ SWLog::getSystemLog()->logDebug("%s=%s\n", abbr, refSys->getBook(i)->getOSISName());
+ delete [] abbr;
+ }
+ }
+ }
+}
+
+
+/******************************************************************************
* VerseKey::ParseVerseList - Attempts to parse a buffer into separate
* verse entries returned in a ListKey
*
@@ -446,19 +463,24 @@ int VerseKey::getBookAbbrev(const char *iabbr)
* COMMENT: This code works but wreaks. Rewrite to make more maintainable.
*/
-ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool expandRange) {
- char book[2048];
- char number[2048];
+ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool expandRange, bool useChapterAsVerse) {
+
+ // hold on to our own copy of params, as threads/recursion may change outside values
+ const char *bufStart = buf;
+ SWBuf iBuf = buf;
+ buf = iBuf.c_str();
+ SWBuf iDefaultKey = defaultKey;
+ if (defaultKey) defaultKey = iDefaultKey.c_str();
+
+ char book[2048]; // TODO: bad, remove
+ char number[2048]; // TODO: bad, remove
*book = 0;
*number = 0;
int tobook = 0;
int tonumber = 0;
+ char suffix = 0;
int chap = -1, verse = -1;
int bookno = 0;
- VerseKey curKey, lBound, lastKey;
- curKey.setLocale(getLocale());
- lBound.setLocale(getLocale());
- lastKey.setLocale(getLocale());
int loop;
char comma = 0;
char dash = 0;
@@ -470,13 +492,50 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
bool inTerm = true;
int notAllDigits = 0;
- curKey.AutoNormalize(0);
- if (defaultKey) lastKey = defaultKey;
-
+ // assert we have a buffer
+ if (!buf) return internalListKey;
+
+ VerseKey *curKey = (VerseKey *)this->clone();
+ VerseKey *lastKey = (VerseKey *)this->clone();
+ lastKey->ClearBounds();
+ curKey->ClearBounds();
+
+ // some silly checks for corner cases
+ if (!strcmp(buf, "[ Module Heading ]")) {
+ curKey->Verse(0);
+ curKey->Chapter(0);
+ curKey->Book(0);
+ curKey->Testament(0);
+ lastKey->LowerBound(*curKey);
+ lastKey->UpperBound(*curKey);
+ internalListKey << *lastKey;
+ delete curKey;
+ delete lastKey;
+ return internalListKey;
+ }
+ if ((!strncmp(buf, "[ Testament ", 12)) &&
+ (isdigit(buf[12])) &&
+ (!strcmp(buf+13, " Heading ]"))) {
+ curKey->Verse(0);
+ curKey->Chapter(0);
+ curKey->Book(0);
+ curKey->Testament(buf[12]-48);
+ lastKey->LowerBound(*curKey);
+ lastKey->UpperBound(*curKey);
+ internalListKey << *lastKey;
+ delete curKey;
+ delete lastKey;
+ return internalListKey;
+ }
+
+ curKey->AutoNormalize(AutoNormalize());
+ lastKey->AutoNormalize(0);
+ if (defaultKey) *lastKey = defaultKey;
+
while (*buf) {
switch (*buf) {
case ':':
- if (buf[1] != ' ') { // for silly Mat 1:1: this verse....
+ if (buf[1] != ' ') { // for silly "Mat 1:1: this verse...."
number[tonumber] = 0;
tonumber = 0;
if (*number)
@@ -502,7 +561,7 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
break;
}
- case '-':
+ case '-':
case ',': // on number new verse
case ';': // on number new chapter
number[tonumber] = 0;
@@ -535,7 +594,8 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
for (loop = strlen(book) - 1; loop+1; loop--) {
if (book[loop] == ' ') {
- if (isroman(&book[loop+1])) {
+ // "PS C" is ok, but "II C" is not ok
+ if (isroman(&book[loop+1]) && !isroman(book,loop)) {
if (verse == -1) {
verse = chap;
chap = from_rom(&book[loop+1]);
@@ -549,49 +609,64 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
if ((!stricmp(book, "V")) || (!stricmp(book, "VER"))) { // Verse abbrev
if (verse == -1) {
verse = chap;
- chap = lastKey.Chapter();
+ chap = lastKey->Chapter();
*book = 0;
}
}
if ((!stricmp(book, "ch")) || (!stricmp(book, "chap"))) { // Verse abbrev
- strcpy(book, lastKey.getBookName());
+ strcpy(book, lastKey->getBookName());
}
bookno = getBookAbbrev(book);
}
if (((bookno > -1) || (!*book)) && ((*book) || (chap >= 0) || (verse >= 0))) {
char partial = 0;
- curKey.Verse(1);
- curKey.Chapter(1);
- curKey.Book(1);
+ curKey->Verse(1);
+ curKey->Chapter(1);
+ curKey->Book(1);
if (bookno < 0) {
- curKey.Testament(lastKey.Testament());
- curKey.Book(lastKey.Book());
+ curKey->Testament(lastKey->Testament());
+ curKey->Book(lastKey->Book());
}
else {
- curKey.Testament(1);
- curKey.Book(bookno);
+ int t = 1;
+ if (bookno > BMAX[0]) {
+ t++;
+ bookno -= BMAX[0];
+ }
+ curKey->Testament(t);
+ curKey->Book(bookno);
}
+
if (((comma)||((verse < 0)&&(bookno < 0)))&&(!lastPartial)) {
// if (comma) {
- curKey.Chapter(lastKey.Chapter());
- curKey.Verse(chap); // chap because this is the first number captured
+ curKey->Chapter(lastKey->Chapter());
+ curKey->Verse(chap); // chap because this is the first number captured
}
else {
+ if (useChapterAsVerse && verse < 0 && chap > 0 && curKey->getChapterMax() == 1) {
+ verse = chap;
+ chap = 1;
+ }
+
+
if (chap >= 0) {
- curKey.Chapter(chap);
+ curKey->Chapter(chap);
}
else {
partial++;
- curKey.Chapter(1);
+ curKey->Chapter(1);
}
if (verse >= 0) {
- curKey.Verse(verse);
+ curKey->Verse(verse);
+ if (suffix) {
+ curKey->setSuffix(suffix);
+ }
}
else {
partial++;
- curKey.Verse(1);
+ curKey->Verse(1);
}
}
@@ -599,43 +674,42 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
for (q = 0; ((buf[q]) && (buf[q] == ' ')); q++);
if ((buf[q] == '-') && (expandRange)) { // if this is a dash save lowerBound and wait for upper
buf+=q;
- lastKey.LowerBound(curKey);
- lastKey.setPosition(TOP);
- tmpListKey << lastKey;
- tmpListKey.GetElement()->userData = (void *)buf;
+ lastKey->LowerBound(*curKey);
+ lastKey->setPosition(TOP);
+ tmpListKey << *lastKey;
+ tmpListKey.GetElement()->userData = (void *)(bufStart+(buf-iBuf.c_str()));
}
else {
if (!dash) { // if last separator was not a dash just add
if (expandRange && partial) {
- lastKey.LowerBound(curKey);
+ lastKey->LowerBound(*curKey);
if (partial > 1)
- curKey.setPosition(MAXCHAPTER);
+ curKey->setPosition(MAXCHAPTER);
if (partial > 0)
- curKey = MAXVERSE;
- lastKey.UpperBound(curKey);
- lastKey = TOP;
- tmpListKey << lastKey;
- tmpListKey.GetElement()->userData = (void *)buf;
+ *curKey = MAXVERSE;
+ lastKey->UpperBound(*curKey);
+ *lastKey = TOP;
+ tmpListKey << *lastKey;
+ tmpListKey.GetElement()->userData = (void *)(bufStart+(buf-iBuf.c_str()));
}
else {
- // we store non-range entries as strings so we don't traverse
- // maybe we should consider just setting
- // lowerBound and upperBound to the same value
- tmpListKey << curKey.getText();
- tmpListKey.GetElement()->userData = (void *)buf;
- lastKey = curKey;
+ lastKey->LowerBound(*curKey);
+ lastKey->UpperBound(*curKey);
+ *lastKey = TOP;
+ tmpListKey << *lastKey;
+ tmpListKey.GetElement()->userData = (void *)(bufStart+(buf-iBuf.c_str()));
}
}
else if (expandRange) {
VerseKey *newElement = SWDYNAMIC_CAST(VerseKey, tmpListKey.GetElement());
if (newElement) {
if (partial > 1)
- curKey = MAXCHAPTER;
+ *curKey = MAXCHAPTER;
if (partial > 0)
- curKey = MAXVERSE;
- newElement->UpperBound(curKey);
+ *curKey = MAXVERSE;
+ newElement->UpperBound(*curKey);
*newElement = TOP;
- tmpListKey.GetElement()->userData = (void *)buf;
+ tmpListKey.GetElement()->userData = (void *)(bufStart+(buf-iBuf.c_str()));
}
}
}
@@ -644,6 +718,7 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
*book = 0;
chap = -1;
verse = -1;
+ suffix = 0;
if (*buf == ',')
comma = 1;
else comma = 0;
@@ -652,13 +727,13 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
else dash = 0;
break;
case 10: // ignore these
- case 13:
- case '[':
- case ']':
- case '(':
- case ')':
- case '{':
- case '}':
+ case 13:
+ case '[':
+ case ']':
+ case '(':
+ case ')':
+ case '{':
+ case '}':
break;
case '.':
if (buf > orig) // ignore (break) if preceeding char is not a digit
@@ -675,7 +750,7 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
chap = atoi(number);
*number = 0;
break;
-
+
default:
if (isdigit(*buf)) {
number[tonumber++] = *buf;
@@ -683,12 +758,17 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
else {
switch (*buf) {
case ' ': // ignore these and don't reset number
- case 'f':
case 'F':
break;
default:
- number[tonumber] = 0;
- tonumber = 0;
+ // suffixes (and oddly 'f'-- ff.)
+ if ((*buf >= 'a' && *buf <= 'z') && (chap >=0)) {
+ suffix = *buf;
+ }
+ else {
+ number[tonumber] = 0;
+ tonumber = 0;
+ }
break;
}
}
@@ -726,7 +806,8 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
for (loop = strlen(book) - 1; loop+1; loop--) {
if (book[loop] == ' ') {
- if (isroman(&book[loop+1])) {
+ // "PS C" is ok, but "II C" is not ok
+ if (isroman(&book[loop+1]) && !isroman(book,loop)) {
if (verse == -1) {
verse = chap;
chap = from_rom(&book[loop+1]);
@@ -735,92 +816,109 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
}
break;
}
- }
-
+ }
+
if ((!stricmp(book, "V")) || (!stricmp(book, "VER"))) { // Verse abbrev.
if (verse == -1) {
verse = chap;
- chap = lastKey.Chapter();
+ chap = lastKey->Chapter();
*book = 0;
}
}
-
+
if ((!stricmp(book, "ch")) || (!stricmp(book, "chap"))) { // Verse abbrev
- strcpy(book, lastKey.getBookName());
+ strcpy(book, lastKey->getBookName());
}
bookno = getBookAbbrev(book);
}
if (((bookno > -1) || (!*book)) && ((*book) || (chap >= 0) || (verse >= 0))) {
char partial = 0;
- curKey.Verse(1);
- curKey.Chapter(1);
- curKey.Book(1);
+ curKey->Verse(1);
+ curKey->Chapter(1);
+ curKey->Book(1);
if (bookno < 0) {
- curKey.Testament(lastKey.Testament());
- curKey.Book(lastKey.Book());
+ curKey->Testament(lastKey->Testament());
+ curKey->Book(lastKey->Book());
}
else {
- curKey.Testament(1);
- curKey.Book(bookno);
+ int t = 1;
+ if (bookno > BMAX[0]) {
+ t++;
+ bookno -= BMAX[0];
+ }
+ curKey->Testament(t);
+ curKey->Book(bookno);
}
if (((comma)||((verse < 0)&&(bookno < 0)))&&(!lastPartial)) {
- curKey.Chapter(lastKey.Chapter());
- curKey.Verse(chap); // chap because this is the first number captured
+ curKey->Chapter(lastKey->Chapter());
+ curKey->Verse(chap); // chap because this is the first number captured
}
else {
+ if (useChapterAsVerse && verse < 0 && chap > 0 && curKey->getChapterMax() == 1) {
+ verse = chap;
+ chap = 1;
+ }
+
+
if (chap >= 0) {
- curKey.Chapter(chap);
+ curKey->Chapter(chap);
}
else {
partial++;
- curKey.Chapter(1);
+ curKey->Chapter(1);
}
if (verse >= 0) {
- curKey.Verse(verse);
+ curKey->Verse(verse);
+ if (suffix) {
+ curKey->setSuffix(suffix);
+ }
}
else {
partial++;
- curKey.Verse(1);
+ curKey->Verse(1);
}
}
if ((*buf == '-') && (expandRange)) { // if this is a dash save lowerBound and wait for upper
- lastKey.LowerBound(curKey);
- lastKey = TOP;
- tmpListKey << lastKey;
- tmpListKey.GetElement()->userData = (void *)buf;
+ lastKey->LowerBound(*curKey);
+ *lastKey = TOP;
+ tmpListKey << *lastKey;
+ tmpListKey.GetElement()->userData = (void *)(bufStart+(buf-iBuf.c_str()));
}
else {
if (!dash) { // if last separator was not a dash just add
if (expandRange && partial) {
- lastKey.LowerBound(curKey);
+ lastKey->LowerBound(*curKey);
if (partial > 1)
- curKey = MAXCHAPTER;
+ *curKey = MAXCHAPTER;
if (partial > 0)
- curKey = MAXVERSE;
- lastKey.UpperBound(curKey);
- lastKey = TOP;
- tmpListKey << lastKey;
- tmpListKey.GetElement()->userData = (void *)buf;
+ *curKey = MAXVERSE;
+ lastKey->UpperBound(*curKey);
+ *lastKey = TOP;
+ tmpListKey << *lastKey;
+ tmpListKey.GetElement()->userData = (void *)(bufStart+(buf-iBuf.c_str()));
}
else {
- tmpListKey << curKey.getText();
- tmpListKey.GetElement()->userData = (void *)buf;
- lastKey = curKey;
+ lastKey->LowerBound(*curKey);
+ lastKey->UpperBound(*curKey);
+ *lastKey = TOP;
+ tmpListKey << *lastKey;
+// tmpListKey << curKey->getText();
+ tmpListKey.GetElement()->userData = (void *)(bufStart+(buf-iBuf.c_str()));
}
}
else if (expandRange) {
VerseKey *newElement = SWDYNAMIC_CAST(VerseKey, tmpListKey.GetElement());
if (newElement) {
if (partial > 1)
- curKey = MAXCHAPTER;
+ *curKey = MAXCHAPTER;
if (partial > 0)
- curKey = MAXVERSE;
- newElement->UpperBound(curKey);
+ *curKey = MAXVERSE;
+ newElement->UpperBound(*curKey);
*newElement = TOP;
- tmpListKey.GetElement()->userData = (void *)buf;
+ tmpListKey.GetElement()->userData = (void *)(bufStart+(buf-iBuf.c_str()));
}
}
}
@@ -830,6 +928,9 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
internalListKey = tmpListKey;
internalListKey = TOP; // Align internalListKey to first element before passing back;
+ delete curKey;
+ delete lastKey;
+
return internalListKey;
}
@@ -838,16 +939,23 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e
* VerseKey::LowerBound - sets / gets the lower boundary for this key
*/
-VerseKey &VerseKey::LowerBound(const char *lb)
+VerseKey &VerseKey::LowerBound(const VerseKey &lb)
{
- if (!lowerBound)
- initBounds();
+ initBounds();
- (*lowerBound) = lb;
- lowerBound->Normalize();
- lowerBound->setLocale( this->getLocale() );
+ lowerBound = lb.Index();
+ lowerBoundComponents.test = lb.getTestament();
+ lowerBoundComponents.book = lb.getBook();
+ lowerBoundComponents.chap = lb.getChapter();
+ lowerBoundComponents.verse = lb.getVerse();
+
+ // both this following check and UpperBound check force upperBound to
+ // change allowing LowerBound then UpperBound logic to always flow
+ // and set values without restrictions, as expected
+ if (upperBound < lowerBound) upperBound = lowerBound;
boundSet = true;
- return (*lowerBound);
+
+ return LowerBound();
}
@@ -855,40 +963,21 @@ VerseKey &VerseKey::LowerBound(const char *lb)
* VerseKey::UpperBound - sets / gets the upper boundary for this key
*/
-VerseKey &VerseKey::UpperBound(const char *ub)
+VerseKey &VerseKey::UpperBound(const VerseKey &ub)
{
- if (!upperBound)
- initBounds();
-
-// need to set upperbound parsing to resolve to max verse/chap if not specified
- (*upperBound) = ub;
- if (*upperBound < *lowerBound)
- *upperBound = *lowerBound;
- upperBound->Normalize();
- upperBound->setLocale( this->getLocale() );
-
-// until we have a proper method to resolve max verse/chap use this kludge
- int len = strlen(ub);
- bool alpha = false;
- bool versespec = false;
- bool chapspec = false;
- for (int i = 0; i < len; i++) {
- if (isalpha(ub[i]))
- alpha = true;
- if (ub[i] == ':') // if we have a : we assume verse spec
- versespec = true;
- if ((isdigit(ub[i])) && (alpha)) // if digit after alpha assume chap spec
- chapspec = true;
- }
- if (!chapspec)
- *upperBound = MAXCHAPTER;
- if (!versespec)
- *upperBound = MAXVERSE;
-
+ initBounds();
+
+ upperBound = ub.Index();
+ upperBoundComponents.test = ub.getTestament();
+ upperBoundComponents.book = ub.getBook();
+ upperBoundComponents.chap = ub.getChapter();
+ upperBoundComponents.verse = ub.getVerse();
-// -- end kludge
+ // see LowerBound comment, above
+ if (upperBound < lowerBound) upperBound = lowerBound;
boundSet = true;
- return (*upperBound);
+
+ return UpperBound();
}
@@ -898,10 +987,16 @@ VerseKey &VerseKey::UpperBound(const char *ub)
VerseKey &VerseKey::LowerBound() const
{
- if (!lowerBound)
- initBounds();
+ initBounds();
+ if (!isAutoNormalize()) {
+ tmpClone->testament = lowerBoundComponents.test;
+ tmpClone->book = lowerBoundComponents.book;
+ tmpClone->chapter = lowerBoundComponents.chap;
+ tmpClone->setVerse (lowerBoundComponents.verse);
+ }
+ else tmpClone->Index(lowerBound);
- return (*lowerBound);
+ return (*tmpClone);
}
@@ -911,10 +1006,16 @@ VerseKey &VerseKey::LowerBound() const
VerseKey &VerseKey::UpperBound() const
{
- if (!upperBound)
- initBounds();
+ initBounds();
+ if (!isAutoNormalize()) {
+ tmpClone->testament = upperBoundComponents.test;
+ tmpClone->book = upperBoundComponents.book;
+ tmpClone->chapter = upperBoundComponents.chap;
+ tmpClone->setVerse (upperBoundComponents.verse);
+ }
+ else tmpClone->Index(upperBound);
- return (*upperBound);
+ return (*tmpClone);
}
@@ -924,33 +1025,36 @@ VerseKey &VerseKey::UpperBound() const
void VerseKey::ClearBounds()
{
- initBounds();
+ delete tmpClone;
+ tmpClone = 0;
+ boundSet = false;
}
void VerseKey::initBounds() const
{
- if (!upperBound) {
- upperBound = new VerseKey();
- upperBound->AutoNormalize(0);
- upperBound->Headings(1);
- }
- if (!lowerBound) {
- lowerBound = new VerseKey();
- lowerBound->AutoNormalize(0);
- lowerBound->Headings(1);
- }
-
- lowerBound->Testament(0);
- lowerBound->Book(0);
- lowerBound->Chapter(0);
- lowerBound->Verse(0);
+ if (!tmpClone) {
+ tmpClone = (VerseKey *)this->clone();
+ tmpClone->AutoNormalize(0);
+ tmpClone->Headings(1);
+ tmpClone->Testament((BMAX[1])?2:1);
+ tmpClone->Book(BMAX[(BMAX[1])?1:0]);
+ tmpClone->Chapter(tmpClone->getChapterMax());
+ tmpClone->Verse(tmpClone->getVerseMax());
+ upperBound = tmpClone->Index();
+ upperBoundComponents.test = tmpClone->getTestament();
+ upperBoundComponents.book = tmpClone->getBook();
+ upperBoundComponents.chap = tmpClone->getChapter();
+ upperBoundComponents.verse = tmpClone->getVerse();
+
+ lowerBound = 0;
+ lowerBoundComponents.test = 0;
+ lowerBoundComponents.book = 0;
+ lowerBoundComponents.chap = 0;
+ lowerBoundComponents.verse = 0;
- upperBound->Testament(2);
- upperBound->Book(BMAX[1]);
- upperBound->Chapter(books[1][BMAX[1]-1].chapmax);
- upperBound->Verse(books[1][BMAX[1]-1].versemax[upperBound->Chapter()-1]);
- boundSet = false;
+ }
+ else tmpClone->setLocale(getLocale());
}
@@ -975,7 +1079,7 @@ const char *VerseKey::getShortText() const {
else sprintf(buf, "[ Testament %d Heading ]", (int)testament);
}
else {
- sprintf(buf, "%s %d:%d", books[testament-1][book-1].prefAbbrev, chapter, verse);
+ sprintf(buf, "%s %d:%d", getBookAbbrev(), chapter, verse);
}
stdstr(&stext, buf);
return stext;
@@ -983,13 +1087,20 @@ const char *VerseKey::getShortText() const {
const char *VerseKey::getBookName() const {
- return books[testament-1][book-1].name;
+ return getPrivateLocale()->translate(refSys->getBook(((testament>1)?BMAX[0]:0)+book-1)->getLongName());
+}
+
+
+const char *VerseKey::getOSISBookName() const {
+ return refSys->getBook(((testament>1)?BMAX[0]:0)+book-1)->getOSISName();
}
const char *VerseKey::getBookAbbrev() const {
- return books[testament-1][book-1].prefAbbrev;
+ return refSys->getBook(((testament>1)?BMAX[0]:0)+book-1)->getPreferredAbbreviation();
}
+
+
/******************************************************************************
* VerseKey::setPosition(SW_POSITION) - Positions this key
*
@@ -1000,32 +1111,50 @@ const char *VerseKey::getBookAbbrev() const {
void VerseKey::setPosition(SW_POSITION p) {
switch (p) {
- case POS_TOP:
- testament = LowerBound().Testament();
- book = LowerBound().Book();
- chapter = LowerBound().Chapter();
- verse = LowerBound().Verse();
+ case POS_TOP: {
+ const VerseKey *lb = &LowerBound();
+ testament = (lb->Testament() || headings) ? lb->Testament() : 1;
+ book = (lb->Book() || headings) ? lb->Book() : 1;
+ chapter = (lb->Chapter() || headings) ? lb->Chapter() : 1;
+ verse = (lb->Verse() || headings) ? lb->Verse() : 1;
+ suffix = lb->getSuffix();
break;
- case POS_BOTTOM:
- testament = UpperBound().Testament();
- book = UpperBound().Book();
- chapter = UpperBound().Chapter();
- verse = UpperBound().Verse();
+ }
+ case POS_BOTTOM: {
+ const VerseKey *ub = &UpperBound();
+ testament = (ub->Testament() || headings) ? ub->Testament() : 1;
+ book = (ub->Book() || headings) ? ub->Book() : 1;
+ chapter = (ub->Chapter() || headings) ? ub->Chapter() : 1;
+ verse = (ub->Verse() || headings) ? ub->Verse() : 1;
+ suffix = ub->getSuffix();
break;
+ }
case POS_MAXVERSE:
Normalize();
- verse = books[testament-1][book-1].versemax[chapter-1];
+ verse = getVerseMax();
+ suffix = 0;
break;
case POS_MAXCHAPTER:
verse = 1;
+ suffix = 0;
Normalize();
- chapter = books[testament-1][book-1].chapmax;
+ chapter = getChapterMax();
break;
- }
+ }
Normalize(1);
Error(); // clear error from normalize
}
+int VerseKey::getChapterMax() const {
+ const VerseMgr::Book *b = refSys->getBook(((testament>1)?BMAX[0]:0)+book-1);
+ return (b) ? b->getChapterMax() : -1;
+}
+
+int VerseKey::getVerseMax() const {
+ const VerseMgr::Book *b = refSys->getBook(((testament>1)?BMAX[0]:0)+book-1);
+ return (b) ? b->getVerseMax(chapter) : -1;
+}
+
/******************************************************************************
* VerseKey::increment - Increments key a number of verses
@@ -1079,11 +1208,11 @@ void VerseKey::decrement(int step) {
void VerseKey::Normalize(char autocheck)
{
- error = 0;
if (((!autocheck) || (autonorm)) // only normalize if we were explicitely called or if autonorm is turned on
&&
((!headings) || ((verse) && (chapter)))) { // this is cheeze and temporary until deciding what actions should be taken; so headings should only be turned on when positioning with Index() or incrementors
+ error = 0;
while ((testament < 3) && (testament > 0)) {
@@ -1100,40 +1229,45 @@ void VerseKey::Normalize(char autocheck)
continue;
}
- if (chapter > books[testament-1][book-1].chapmax) {
- chapter -= books[testament-1][book-1].chapmax;
+ if (chapter > getChapterMax()) {
+ chapter -= getChapterMax();
book++;
continue;
}
- if (chapter < 1) {
- if (--book > 0) {
- chapter += books[testament-1][book-1].chapmax;
- }
- else {
- if (testament > 1) {
- chapter += books[0][BMAX[0]-1].chapmax;
- }
- }
- continue;
- }
+ if (chapter < 1) {
+ if (--book > 0) {
+ chapter += getChapterMax();
+ verse = getVerseMax();
+ }
+ else {
+ if (testament > 1) {
+ chapter += refSys->getBook(BMAX[0]-1)->getChapterMax();
+ verse = refSys->getBook(BMAX[0]-1)->getVerseMax(chapter);
+ }
+ }
+ continue;
+ }
- if (verse > books[testament-1][book-1].versemax[chapter-1]) { // -1 because e.g chapter 1 of Matthew is books[1][0].versemax[0]
- verse -= books[testament-1][book-1].versemax[chapter++ - 1];
+ if (verse > getVerseMax()) { // -1 because e.g chapter 1 of Matthew is books[1][0].versemax[0]
+ verse -= getVerseMax();
+ chapter++;
continue;
}
if (verse < 1) {
if (--chapter > 0) {
- verse += books[testament-1][book-1].versemax[chapter-1];
+ verse += getVerseMax();
}
else {
if (book > 1) {
- verse += books[testament-1][book-2].versemax[books[testament-1][book-2].chapmax-1];
+ const VerseMgr::Book *prevBook = refSys->getBook(((testament>1)?BMAX[0]:0)+book-2);
+ verse += prevBook->getVerseMax(prevBook->getChapterMax());
}
else {
if (testament > 1) {
- verse += books[0][BMAX[0]-1].versemax[books[0][BMAX[0]-1].chapmax-1];
+ const VerseMgr::Book *lastOTBook = refSys->getBook(BMAX[0]-1);
+ verse += lastOTBook->getVerseMax(lastOTBook->getChapterMax());
}
}
}
@@ -1143,11 +1277,11 @@ void VerseKey::Normalize(char autocheck)
break; // If we've made it this far (all failure checks continue) we're ok
}
- if (testament > 2) {
- testament = 2;
+ if (testament > (BMAX[1]?2:1)) {
+ testament = BMAX[1]?2:1;
book = BMAX[testament-1];
- chapter = books[testament-1][book-1].chapmax;
- verse = books[testament-1][book-1].versemax[chapter-1];
+ chapter = getChapterMax();
+ verse = getVerseMax();
error = KEYERR_OUTOFBOUNDS;
}
@@ -1161,11 +1295,11 @@ void VerseKey::Normalize(char autocheck)
// should we always perform bounds checks? Tried but seems to cause infinite recursion
if (_compare(UpperBound()) > 0) {
- setText(UpperBound(), false);
+ positionFrom(UpperBound());
error = KEYERR_OUTOFBOUNDS;
}
if (_compare(LowerBound()) < 0) {
- setText(LowerBound(), false);
+ positionFrom(LowerBound());
error = KEYERR_OUTOFBOUNDS;
}
}
@@ -1173,24 +1307,24 @@ void VerseKey::Normalize(char autocheck)
/******************************************************************************
- * VerseKey::Testament - Gets testament
+ * VerseKey::getTestament - Gets testament
*
* RET: value of testament
*/
-char VerseKey::Testament() const
+char VerseKey::getTestament() const
{
return testament;
}
/******************************************************************************
- * VerseKey::Book - Gets book
+ * VerseKey::getBook - Gets book
*
* RET: value of book
*/
-char VerseKey::Book() const
+char VerseKey::getBook() const
{
return book;
}
@@ -1202,7 +1336,7 @@ char VerseKey::Book() const
* RET: value of chapter
*/
-int VerseKey::Chapter() const
+int VerseKey::getChapter() const
{
return chapter;
}
@@ -1214,14 +1348,14 @@ int VerseKey::Chapter() const
* RET: value of verse
*/
-int VerseKey::Verse() const
+int VerseKey::getVerse() const
{
return verse;
}
/******************************************************************************
- * VerseKey::Testament - Sets/gets testament
+ * VerseKey::setTestament - Sets/gets testament
*
* ENT: itestament - value which to set testament
* [MAXPOS(char)] - only get
@@ -1230,64 +1364,68 @@ int VerseKey::Verse() const
* if changed -> previous value of testament
*/
-char VerseKey::Testament(char itestament)
+void VerseKey::setTestament(char itestament)
{
- char retval = testament;
-
if (itestament != MAXPOS(char)) {
testament = itestament;
Normalize(1);
}
- return retval;
}
/******************************************************************************
- * VerseKey::Book - Sets/gets book
+ * VerseKey::setBook - Sets/gets book
*
* ENT: ibook - value which to set book
- * [MAXPOS(char)] - only get
- *
- * RET: if unchanged -> value of book
- * if changed -> previous value of book
*/
-char VerseKey::Book(char ibook)
+void VerseKey::setBook(char ibook)
{
- char retval = book;
-
- Chapter(1);
- book = ibook;
+ verse = ibook ? 1 : 0;
+ chapter = ibook ? 1 : 0;
+ book = ibook;
Normalize(1);
-
- return retval;
}
+
/******************************************************************************
- * VerseKey::Chapter - Sets/gets chapter
- *
- * ENT: ichapter - value which to set chapter
- * [MAXPOS(int)] - only get
+ * VerseKey::setBookName - Sets/gets book by name
*
- * RET: if unchanged -> value of chapter
- * if changed -> previous value of chapter
+ * ENT: bname - book name/abbrev
*/
-int VerseKey::Chapter(int ichapter)
+void VerseKey::setBookName(const char *bname)
{
- int retval = chapter;
+ int bnum = getBookAbbrev(bname);
+ if (bnum > -1) {
+ if (bnum > BMAX[0]) {
+ bnum -= BMAX[0];
+ testament = 2;
+ }
+ else testament = 1;
+ setBook(bnum);
+ }
+ else error = KEYERR_OUTOFBOUNDS;
+}
+
+
+/******************************************************************************
+ * VerseKey::setChapter - Sets/gets chapter
+ *
+ * ENT: ichapter - value which to set chapter
+ */
- Verse(1);
+void VerseKey::setChapter(int ichapter)
+{
+ verse = ichapter ? 1 : 0;
chapter = ichapter;
Normalize(1);
-
- return retval;
}
/******************************************************************************
- * VerseKey::Verse - Sets/gets verse
+ * VerseKey::setVerse - Sets/gets verse
*
* ENT: iverse - value which to set verse
* [MAXPOS(int)] - only get
@@ -1296,37 +1434,36 @@ int VerseKey::Chapter(int ichapter)
* if changed -> previous value of verse
*/
-int VerseKey::Verse(int iverse)
+void VerseKey::setVerse(int iverse)
{
- int retval = verse;
-
+ setSuffix(0);
verse = iverse;
Normalize(1);
+}
- return retval;
+
+char VerseKey::getSuffix() const {
+ return suffix;
}
+void VerseKey::setSuffix(char suf) {
+ suffix = suf;
+}
/******************************************************************************
* VerseKey::AutoNormalize - Sets/gets flag that tells VerseKey to auto-
* matically normalize itself when modified
- *
- * ENT: iautonorm - value which to set autonorm
- * [MAXPOS(char)] - only get
- *
- * RET: if unchanged -> value of autonorm
- * if changed -> previous value of autonorm
*/
-char VerseKey::AutoNormalize(char iautonorm)
+bool VerseKey::isAutoNormalize() const
{
- char retval = autonorm;
+ return autonorm;
+}
- if (iautonorm != MAXPOS(char)) {
- autonorm = iautonorm;
- Normalize(1);
- }
- return retval;
+void VerseKey::setAutoNormalize(bool iautonorm)
+{
+ autonorm = iautonorm?1:0;
+ Normalize(1);
}
@@ -1392,34 +1529,27 @@ long VerseKey::Index() const
if (!testament) { // if we want module heading
offset = 0;
- verse = 0;
+ }
+ else if (!book) { // we want testament heading
+ offset = ((testament == 2) ? refSys->getNTStartOffset():0) + 1;
}
else {
- if (!book)
- chapter = 0;
- if (!chapter)
- verse = 0;
-
- offset = offsets[testament-1][0][book];
- offset = offsets[testament-1][1][(int)offset + chapter];
- if (!(offset|verse)) // if we have a testament but nothing else.
- offset = 1;
+ offset = refSys->getOffsetFromVerse((((testament>1)?BMAX[0]:0)+book-1), chapter, verse);
}
- return (offset + verse);
+ return offset;
}
/******************************************************************************
- * VerseKey::Index - Gets index based upon current verse
+ * VerseKey::TestamentIndex - Gets index based upon current verse
*
* RET: offset
*/
-long VerseKey::NewIndex() const
+long VerseKey::TestamentIndex() const
{
- static long otMaxIndex = 32300 - 8245; // total positions - new testament positions
-// static long otMaxIndex = offsets[0][1][(int)offsets[0][0][BMAX[0]] + books[0][BMAX[0]].chapmax];
- return ((testament-1) * otMaxIndex) + Index();
+ long offset = Index();
+ return (testament > 1) ? offset - refSys->getNTStartOffset() : offset;
}
@@ -1433,60 +1563,31 @@ long VerseKey::NewIndex() const
long VerseKey::Index(long iindex)
{
- long offset;
-
-// This is the dirty stuff --------------------------------------------
-
- if (!testament)
- testament = 1;
-
- if (iindex < 1) { // if (-) or module heading
- if (testament < 2) {
- if (iindex < 0) {
- testament = 0; // previously we changed 0 -> 1
- error = KEYERR_OUTOFBOUNDS;
- }
- else testament = 0; // we want module heading
- }
- else {
- testament--;
- iindex = (offsets[testament-1][1][offsize[testament-1][1]-1] + books[testament-1][BMAX[testament-1]-1].versemax[books[testament-1][BMAX[testament-1]-1].chapmax-1]) + iindex; // What a doozy! ((offset of last chapter + number of verses in the last chapter) + iindex)
- }
+ int b;
+ error = refSys->getVerseFromOffset(iindex, &b, &chapter, &verse);
+ book = (unsigned char)b;
+ testament = 1;
+ if (book > BMAX[0]) {
+ book -= BMAX[0];
+ testament = 2;
}
+ // special case for Module and Testament heading
+ if (book < 0) { testament = 0; book = 0; }
+ if (chapter < 0) { book = 0; chapter = 0; }
-// --------------------------------------------------------------------
-
-
- if (testament) {
- if ((!error) && (iindex)) {
- offset = findindex(offsets[testament-1][1], offsize[testament-1][1], iindex);
- verse = iindex - offsets[testament-1][1][offset];
- book = findindex(offsets[testament-1][0], offsize[testament-1][0], offset);
- chapter = offset - offsets[testament-1][0][VerseKey::book];
- verse = (chapter) ? verse : 0; // funny check. if we are index=1 (testmt header) all gets set to 0 exept verse. Don't know why. Fix if you figure out. Think its in the offsets table.
- if (verse) { // only check if -1 won't give negative
- if (verse > books[testament-1][book-1].versemax[chapter-1]) {
- if (testament > 1) {
- verse = books[testament-1][book-1].versemax[chapter-1];
- error = KEYERR_OUTOFBOUNDS;
- }
- else {
- testament++;
- Index(verse - books[testament-2][book-1].versemax[chapter-1]);
- }
- }
- }
- }
- }
- if (_compare(UpperBound()) > 0) {
- *this = UpperBound();
+ long i = Index();
+
+ initBounds();
+ if (i > upperBound) {
+ i = Index(upperBound);
error = KEYERR_OUTOFBOUNDS;
}
- if (_compare(LowerBound()) < 0) {
- *this = LowerBound();
+ if (i < lowerBound) {
+ i = Index(lowerBound);
error = KEYERR_OUTOFBOUNDS;
}
- return Index();
+
+ return i;
}
@@ -1524,37 +1625,23 @@ int VerseKey::compare(const SWKey &ikey)
int VerseKey::_compare(const VerseKey &ivkey)
{
- long keyval1 = 0;
- long keyval2 = 0;
+ unsigned long keyval1 = 0;
+ unsigned long keyval2 = 0;
- keyval1 += Testament() * 1000000000;
+ keyval1 += Testament() * 1000000000;
keyval2 += ivkey.Testament() * 1000000000;
- keyval1 += Book() * 1000000;
- keyval2 += ivkey.Book() * 1000000;
- keyval1 += Chapter() * 1000;
- keyval2 += ivkey.Chapter() * 1000;
- keyval1 += Verse();
- keyval2 += ivkey.Verse();
- keyval1 -= keyval2;
- keyval1 = (keyval1) ? ((keyval1 > 0) ? 1 : -1) /*keyval1/labs(keyval1)*/:0; // -1 | 0 | 1
+ keyval1 += Book() * 10000000;
+ keyval2 += ivkey.Book() * 10000000;
+ keyval1 += Chapter() * 10000;
+ keyval2 += ivkey.Chapter() * 10000;
+ keyval1 += Verse() * 50;
+ keyval2 += ivkey.Verse() * 50;
+ keyval1 += (int)getSuffix();
+ keyval2 += (int)ivkey.getSuffix();
+ keyval1 = (keyval1 != keyval2) ? ((keyval1 > keyval2) ? 1 : -1) : 0; // -1 | 0 | 1
return keyval1;
}
-const char *VerseKey::osisotbooks[] = {
- "Gen","Exod","Lev","Num","Deut","Josh","Judg","Ruth","1Sam","2Sam",
- "1Kgs","2Kgs","1Chr","2Chr","Ezra","Neh","Esth","Job","Ps",
- "Prov", // added this. Was not in OSIS spec
- "Eccl",
- "Song","Isa","Jer","Lam","Ezek","Dan","Hos","Joel","Amos","Obad",
- "Jonah","Mic","Nah","Hab","Zeph","Hag","Zech","Mal","Bar","PrAzar",
- "Bel","Sus","1Esd","2Esd","AddEsth","EpJer","Jdt","1Macc","2Macc","3Macc",
- "4Macc","PrMan","Ps151","Sir","Tob","Wis"};
-const char *VerseKey::osisntbooks[] = {
- "Matt","Mark","Luke","John","Acts","Rom","1Cor","2Cor","Gal","Eph",
- "Phil","Col","1Thess","2Thess","1Tim","2Tim","Titus","Phlm","Heb","Jas",
- "1Pet","2Pet","1John","2John","3John","Jude","Rev"};
-const char **VerseKey::osisbooks[] = { osisotbooks, osisntbooks };
-
const char *VerseKey::getOSISRef() const {
static char buf[5][254];
@@ -1564,53 +1651,50 @@ const char *VerseKey::getOSISRef() const {
loop = 0;
if (Verse())
- sprintf(buf[loop], "%s.%d.%d", osisbooks[Testament()-1][Book()-1], (int)Chapter(), (int)Verse());
+ sprintf(buf[loop], "%s.%d.%d", getOSISBookName(), (int)Chapter(), (int)Verse());
else if (Chapter())
- sprintf(buf[loop], "%s.%d", osisbooks[Testament()-1][Book()-1], (int)Chapter());
+ sprintf(buf[loop], "%s.%d", getOSISBookName(), (int)Chapter());
else if (Book())
- sprintf(buf[loop], "%s", osisbooks[Testament()-1][Book()-1]);
+ sprintf(buf[loop], "%s", getOSISBookName());
else buf[loop][0] = 0;
return buf[loop++];
}
-const int VerseKey::getOSISBookNum(const char *bookab) {
- int i;
- for (i=0; i < 39; i++)
- {
- if (!strncmp(bookab, osisotbooks[i], strlen(osisotbooks[i])))
- {
- //printf("VerseKey::getOSISBookNum %s is OT %d\n", bookab, i+1);
- return i+1;
- }
- }
- for (i=0; i < 27; i++)
- {
- if (!strncmp(bookab, osisntbooks[i], strlen(osisotbooks[i])))
- {
- //printf("VerseKey::getOSISBookNum %s is NT %d\n", bookab, i+1);
- return i+1;
- }
- }
- return -1;
-}
-
-
/******************************************************************************
* VerseKey::getRangeText - returns parsable range text for this key
*/
const char *VerseKey::getRangeText() const {
- if (isBoundSet()) {
- char buf[1023];
- sprintf(buf, "%s-%s", (const char *)LowerBound(), (const char *)UpperBound());
- stdstr(&rangeText, buf);
+ if (isBoundSet() && lowerBound != upperBound) {
+ SWBuf buf = (const char *)LowerBound();
+ buf += "-";
+ buf += (const char *)UpperBound();
+ stdstr(&rangeText, buf.c_str());
}
else stdstr(&rangeText, getText());
return rangeText;
}
+/******************************************************************************
+ * VerseKey::getOSISRefRangeText - returns parsable range text for this key
+ */
+
+const char *VerseKey::getOSISRefRangeText() const {
+ if (isBoundSet() && (lowerBound != upperBound)) {
+ SWBuf buf = LowerBound().getOSISRef();
+ buf += "-";
+ buf += UpperBound().getOSISRef();
+ stdstr(&rangeText, buf.c_str());
+ }
+ else stdstr(&rangeText, getOSISRef());
+ return rangeText;
+}
+
+
+// TODO: this is static so we have no context. We can only parse KJV v11n now
+// possibly add a const char *versification = KJV param?
const char *VerseKey::convertToOSIS(const char *inRef, const SWKey *lastKnownKey) {
static SWBuf outRef;
@@ -1620,12 +1704,13 @@ const char *VerseKey::convertToOSIS(const char *inRef, const SWKey *lastKnownKey
ListKey verses = defLanguage.ParseVerseList(inRef, (*lastKnownKey), true);
const char *startFrag = inRef;
for (int i = 0; i < verses.Count(); i++) {
- VerseKey *element = SWDYNAMIC_CAST(VerseKey, verses.GetElement(i));
- char buf[5120];
+ SWKey *element = verses.GetElement(i);
+// VerseKey *element = SWDYNAMIC_CAST(VerseKey, verses.GetElement(i));
+ SWBuf buf;
+ // TODO: This code really needs to not use fixed size arrays
char frag[800];
char preJunk[800];
char postJunk[800];
- memset(buf, 0, 5120);
memset(frag, 0, 800);
memset(preJunk, 0, 800);
memset(postJunk, 0, 800);
@@ -1633,32 +1718,26 @@ const char *VerseKey::convertToOSIS(const char *inRef, const SWKey *lastKnownKey
outRef += *startFrag;
startFrag++;
}
- if (element) {
- memmove(frag, startFrag, ((const char *)element->userData - startFrag) + 1);
- frag[((const char *)element->userData - startFrag) + 1] = 0;
- int j;
- for (j = strlen(frag)-1; j && (strchr(" {};,()[].", frag[j])); j--);
- if (frag[j+1])
- strcpy(postJunk, frag+j+1);
- frag[j+1]=0;
- startFrag += ((const char *)element->userData - startFrag) + 1;
- sprintf(buf, "<reference osisRef=\"%s-%s\">%s</reference>%s", element->LowerBound().getOSISRef(), element->UpperBound().getOSISRef(), frag, postJunk);
- }
- else {
- memmove(frag, startFrag, ((const char *)verses.GetElement(i)->userData - startFrag) + 1);
- frag[((const char *)verses.GetElement(i)->userData - startFrag) + 1] = 0;
- int j;
- for (j = strlen(frag)-1; j && (strchr(" {};,()[].", frag[j])); j--);
- if (frag[j+1])
- strcpy(postJunk, frag+j+1);
- frag[j+1]=0;
- startFrag += ((const char *)verses.GetElement(i)->userData - startFrag) + 1;
- sprintf(buf, "<reference osisRef=\"%s\">%s</reference>%s", VerseKey(*verses.GetElement(i)).getOSISRef(), frag, postJunk);
- }
- outRef+=buf;
+ memmove(frag, startFrag, ((const char *)element->userData - startFrag) + 1);
+ frag[((const char *)element->userData - startFrag) + 1] = 0;
+ int j;
+ for (j = strlen(frag)-1; j && (strchr(" {};,()[].", frag[j])); j--);
+ if (frag[j+1])
+ strcpy(postJunk, frag+j+1);
+ frag[j+1]=0;
+ startFrag += ((const char *)element->userData - startFrag) + 1;
+ buf = "<reference osisRef=\"";
+ buf += element->getOSISRefRangeText();
+ buf += "\">";
+ buf += frag;
+ buf += "</reference>";
+ buf += postJunk;
+
+ outRef += buf;
+
}
if (startFrag < (inRef + strlen(inRef)))
- outRef+=startFrag;
+ outRef += startFrag;
return outRef.c_str();
}
SWORD_NAMESPACE_END
diff --git a/src/keys/versetreekey.cpp b/src/keys/versetreekey.cpp
index b73672d..edfbcc3 100644
--- a/src/keys/versetreekey.cpp
+++ b/src/keys/versetreekey.cpp
@@ -1,9 +1,27 @@
/******************************************************************************
* VerseTreeKey.cpp - code for class 'VerseTreeKey'- versekey using treekey
* for data retrieval
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <versetreekey.h>
+#include <ctype.h>
SWORD_NAMESPACE_START
@@ -20,7 +38,7 @@ SWClass VerseTreeKey::classdef(classes);
VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const SWKey *ikey) : VerseKey(ikey)
{
- this->treeKey = treeKey;
+ init(treeKey);
if (ikey)
parse();
}
@@ -35,7 +53,7 @@ VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const SWKey *ikey) : VerseKey(ikey)
VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const char *ikey) : VerseKey(ikey)
{
- this->treeKey = treeKey;
+ init(treeKey);
if (ikey)
parse();
}
@@ -43,13 +61,22 @@ VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const char *ikey) : VerseKey(ikey)
VerseTreeKey::VerseTreeKey(VerseTreeKey const &k) : VerseKey(k)
{
- treeKey = k.treeKey;
+ init(k.treeKey);
}
VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const char *min, const char *max) : VerseKey(min, max)
{
- this->treeKey = treeKey;
+ init(treeKey);
+}
+
+
+void VerseTreeKey::init(TreeKey *treeKey)
+{
+ myclass = &classdef;
+ this->treeKey = (TreeKey *)treeKey->clone();
+ this->treeKey->setPositionChangeListener(this);
+ internalPosChange = false;
}
@@ -59,6 +86,33 @@ SWKey *VerseTreeKey::clone() const
}
+int VerseTreeKey::getBookAbbrev(const char *iabbr)
+{
+ int bookno = VerseKey::getBookAbbrev(iabbr);
+ if (bookno < 0) {
+/*
+ vector<struct sbook>::iterator it = find(books, iabbr);
+ if (it == books.end()) {
+ TreeKey *tkey = this->treeKey;
+ int saveError = tkey->Error();
+ long bookmark = tkey->getOffset();
+ SWBuf segment;
+ internalPosChange = true;
+ do {
+ segment = (SWBuf)tkey->getLocalName();
+ } while (tkey->parent());
+ segment << 1;
+ if (saveError) {
+ error = saveError;
+ }
+ tkey->setOffset(bookmark);
+ }
+ books.push_back(sbook(iabbr));
+*/
+ }
+ return bookno;
+}
+
/******************************************************************************
* VerseTreeKey Destructor - cleans up instance of VerseTreeKey
*
@@ -66,7 +120,183 @@ SWKey *VerseTreeKey::clone() const
*/
VerseTreeKey::~VerseTreeKey() {
+ delete treeKey;
+}
+
+
+void VerseTreeKey::decrement(int steps) {
+ int treeError = 0;
+ if (!error) lastGoodOffset = getTreeKey()->getOffset();
+ do {
+ treeKey->decrement();
+ treeError = treeKey->Error();
+ // iterate until 3 levels and no versekey parse errors
+ } while (!treeError && ((treeKey->getLevel() < 3) || error));
+ if (error && !treeError) {
+ int saveError = error;
+ increment();
+ error = saveError;
+ }
+ if (treeError) {
+ treeKey->setOffset(lastGoodOffset);
+ error = treeError;
+ }
+ if (_compare(UpperBound()) > 0) {
+ positionFrom(UpperBound());
+ error = KEYERR_OUTOFBOUNDS;
+ }
+ if (_compare(LowerBound()) < 0) {
+ positionFrom(LowerBound());
+ error = KEYERR_OUTOFBOUNDS;
+ }
+}
+
+
+void VerseTreeKey::increment(int steps) {
+ int treeError = 0;
+ if (!error) lastGoodOffset = getTreeKey()->getOffset();
+ do {
+ treeKey->increment();
+ treeError = treeKey->Error();
+ // iterate until 3 levels and no versekey parse errors
+ } while (!treeError && ((treeKey->getLevel() < 3) || error));
+ if (error && !treeError) {
+ int saveError = error;
+ decrement();
+ error = saveError;
+ }
+ if (treeError) {
+ treeKey->setOffset(lastGoodOffset);
+ error = treeError;
+ }
+ // bounds
+ if (_compare(UpperBound()) > 0) {
+ positionFrom(UpperBound());
+ error = KEYERR_OUTOFBOUNDS;
+ }
+ if (_compare(LowerBound()) < 0) {
+ positionFrom(LowerBound());
+ error = KEYERR_OUTOFBOUNDS;
+ }
}
+void VerseTreeKey::positionChanged() {
+ if (!internalPosChange) {
+ TreeKey *tkey = this->TreeKey::PositionChangeListener::getTreeKey();
+ int saveError = tkey->Error();
+ long bookmark = tkey->getOffset();
+ SWBuf seg[4];
+ internalPosChange = true;
+ int legs = 0;
+ do {
+ seg[legs] = tkey->getLocalName();
+ legs++;
+ } while (tkey->parent() && (legs < 4));
+
+ legs--;
+
+ if ((legs < 2) && (!seg[0].length() || seg[0] == "/")) { //"[ Module Heading ]";
+ testament = 0;
+ book = 0;
+ chapter = 0;
+ setVerse(0);
+ }
+ else if ((legs < 2)
+ && ((!strncmp(seg[0].c_str(), "[ Testament ", 12)) && //"[ Testament n Heading ]";
+ (isdigit(seg[0][12])) &&
+ (!strcmp(seg[0].c_str()+13, " Heading ]")))) {
+ testament = (seg[0][12]-48);
+ book = 0;
+ chapter = 0;
+ setVerse(0);
+ } //path = "[ Module Heading ]";
+ else {
+ setBookName(seg[--legs]);
+ chapter = (legs > 0) ? atoi(seg[--legs]) : 0;
+ setVerse((legs > 0) ? atoi(seg[--legs]) : 0);
+ }
+
+// setText(path);
+ if (saveError) {
+ error = saveError;
+ }
+ tkey->setOffset(bookmark);
+ tkey->setError(saveError);
+ internalPosChange = false;
+ }
+}
+
+
+void VerseTreeKey::syncVerseToTree() {
+ internalPosChange = true;
+ SWBuf path;
+ if (!Testament()) path = "/"; // "[ Module Heading ]";
+ else if (!Book()) path.setFormatted("/[ Testament %d Heading ]", Testament());
+ else path.setFormatted("/%s/%d/%d", getOSISBookName(), getChapter(), getVerse());
+ if (getSuffix()) path += getSuffix();
+ long bookmark = treeKey->getOffset();
+ treeKey->setText(path);
+
+ // if our module has jacked inconsistencies, then let's put our tree back to where it was
+ if (treeKey->Error()) {
+ treeKey->setOffset(bookmark);
+ }
+
+ internalPosChange = false;
+}
+
+
+TreeKey *VerseTreeKey::getTreeKey() {
+ syncVerseToTree();
+ return treeKey;
+}
+
+// can autonormalize yet (ever?)
+void VerseTreeKey::Normalize(char autocheck) {
+ error = 0;
+}
+
+long VerseTreeKey::NewIndex() const {
+ return treeKey->getOffset();
+}
+
+
+void VerseTreeKey::setPosition(SW_POSITION p) {
+
+ if (isBoundSet()) {
+ return VerseKey::setPosition(p);
+ }
+
+ switch (p) {
+ case POS_TOP:
+ Error();
+ treeKey->setPosition(p);
+ increment();
+ decrement();
+ Error();
+ break;
+ case POS_BOTTOM:
+ Error();
+ treeKey->setPosition(p);
+ decrement();
+ increment();
+ Error();
+ break;
+ case POS_MAXVERSE:
+ case POS_MAXCHAPTER:
+ VerseKey::setPosition(p);
+ break;
+ }
+}
+
+
+/******************************************************************************
+ * VerseTreeKey::copyFrom - Equates this VerseTreeKey to another VerseTreeKey
+
+void VerseTreeKey::copyFrom(const VerseTreeKey &ikey) {
+ VerseKey::copyFrom(ikey);
+}
+ */
+
SWORD_NAMESPACE_END
diff --git a/src/mgr/Makefile.am b/src/mgr/Makefile.am
index 1b1e33b..10d7158 100644
--- a/src/mgr/Makefile.am
+++ b/src/mgr/Makefile.am
@@ -11,6 +11,7 @@ AM_CPPFLAGS += -D_FTPLIB_NO_COMPAT
if WITHCURL
FTP_SOURCES = $(mgrdir)/curlftpt.cpp
+FTP_SOURCES += $(mgrdir)/curlhttpt.cpp
else
FTP_SOURCES = $(mgrdir)/ftplibftpt.cpp
endif
@@ -22,6 +23,7 @@ libsword_la_SOURCES += $(mgrdir)/swfiltermgr.cpp
libsword_la_SOURCES += $(mgrdir)/encfiltmgr.cpp
libsword_la_SOURCES += $(mgrdir)/markupfiltmgr.cpp
libsword_la_SOURCES += $(mgrdir)/filemgr.cpp
+libsword_la_SOURCES += $(mgrdir)/versemgr.cpp
libsword_la_SOURCES += $(mgrdir)/ftptrans.cpp
libsword_la_SOURCES += $(mgrdir)/swlocale.cpp
libsword_la_SOURCES += $(mgrdir)/localemgr.cpp
diff --git a/src/mgr/curlftpt.cpp b/src/mgr/curlftpt.cpp
index bb47958..91d8e82 100644
--- a/src/mgr/curlftpt.cpp
+++ b/src/mgr/curlftpt.cpp
@@ -1,7 +1,24 @@
/*****************************************************************************
* CURLFTPTransport functions
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <curlftpt.h>
@@ -109,7 +126,8 @@ char CURLFTPTransport::getURL(const char *destPath, const char *sourceURL, SWBuf
if (session) {
curl_easy_setopt(session, CURLOPT_URL, sourceURL);
- curl_easy_setopt(session, CURLOPT_USERPWD, "ftp:installmgr@user.com");
+ SWBuf credentials = u + ":" + p;
+ curl_easy_setopt(session, CURLOPT_USERPWD, credentials.c_str());
curl_easy_setopt(session, CURLOPT_WRITEFUNCTION, my_fwrite);
if (!passive)
curl_easy_setopt(session, CURLOPT_FTPPORT, "-");
diff --git a/src/mgr/curlhttpt.cpp b/src/mgr/curlhttpt.cpp
new file mode 100644
index 0000000..8ddb1cf
--- /dev/null
+++ b/src/mgr/curlhttpt.cpp
@@ -0,0 +1,178 @@
+ /*****************************************************************************
+ * CURLHTTPTransport functions
+ *
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+
+
+#include <curlhttpt.h>
+
+#include <fcntl.h>
+
+#include <curl/curl.h>
+#include <curl/types.h>
+#include <curl/easy.h>
+
+#include <swlog.h>
+
+SWORD_NAMESPACE_START
+
+
+struct FtpFile {
+ const char *filename;
+ FILE *stream;
+ SWBuf *destBuf;
+};
+
+
+int my_httpfwrite(void *buffer, size_t size, size_t nmemb, void *stream);
+int my_httpfprogress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
+
+static CURLHTTPTransport_init _CURLHTTPTransport_init;
+
+CURLHTTPTransport_init::CURLHTTPTransport_init() {
+ //curl_global_init(CURL_GLOBAL_DEFAULT); // curl_easy_init automatically calls it if needed
+}
+
+CURLHTTPTransport_init::~CURLHTTPTransport_init() {
+// CURLFTPT d-tor cleans this up
+// curl_global_cleanup();
+}
+
+int my_httpfwrite(void *buffer, size_t size, size_t nmemb, void *stream) {
+ struct FtpFile *out=(struct FtpFile *)stream;
+ if (out && !out->stream && !out->destBuf) {
+ /* open file for writing */
+ out->stream=fopen(out->filename, "wb");
+ if (!out->stream)
+ return -1; /* failure, can't open file to write */
+ }
+ if (out->destBuf) {
+ int s = out->destBuf->size();
+ out->destBuf->size(s+(size*nmemb));
+ memcpy(out->destBuf->getRawData()+s, buffer, size*nmemb);
+ return nmemb;
+ }
+ return fwrite(buffer, size, nmemb, out->stream);
+}
+
+
+int my_httpfprogress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) {
+ if (clientp) {
+ ((StatusReporter *)clientp)->statusUpdate(dltotal, dlnow);
+ }
+ return 0;
+}
+
+
+static int myhttp_trace(CURL *handle, curl_infotype type, unsigned char *data, size_t size, void *userp) {
+ SWBuf header;
+ (void)userp; /* prevent compiler warning */
+ (void)handle; /* prevent compiler warning */
+
+ switch (type) {
+ case CURLINFO_TEXT: header = "TEXT"; break;
+ case CURLINFO_HEADER_OUT: header = "=> Send header"; break;
+ case CURLINFO_HEADER_IN: header = "<= Recv header"; break;
+
+ // these we don't want to log (HUGE)
+ case CURLINFO_DATA_OUT: header = "=> Send data";
+ case CURLINFO_SSL_DATA_OUT: header = "=> Send SSL data";
+ case CURLINFO_DATA_IN: header = "<= Recv data";
+ case CURLINFO_SSL_DATA_IN: header = "<= Recv SSL data";
+ default: /* in case a new one is introduced to shock us */
+ return 0;
+ }
+
+ if (size > 120) size = 120;
+ SWBuf text;
+ text.size(size);
+ memcpy(text.getRawData(), data, size);
+ SWLog::getSystemLog()->logDebug("CURLHTTPTransport: %s: %s", header.c_str(), text.c_str());
+ return 0;
+}
+
+CURLHTTPTransport::CURLHTTPTransport(const char *host, StatusReporter *sr) : FTPTransport(host, sr) {
+ session = (CURL *)curl_easy_init();
+}
+
+
+CURLHTTPTransport::~CURLHTTPTransport() {
+ curl_easy_cleanup(session);
+}
+
+
+char CURLHTTPTransport::getURL(const char *destPath, const char *sourceURL, SWBuf *destBuf) {
+ signed char retVal = 0;
+ struct FtpFile ftpfile = {destPath, 0, destBuf};
+
+ CURLcode res;
+
+ if (session) {
+ curl_easy_setopt(session, CURLOPT_URL, sourceURL);
+
+ SWBuf credentials = u + ":" + p;
+ curl_easy_setopt(session, CURLOPT_USERPWD, credentials.c_str());
+ curl_easy_setopt(session, CURLOPT_WRITEFUNCTION, my_httpfwrite);
+ if (!passive)
+ curl_easy_setopt(session, CURLOPT_FTPPORT, "-");
+ curl_easy_setopt(session, CURLOPT_NOPROGRESS, 0);
+ curl_easy_setopt(session, CURLOPT_PROGRESSDATA, statusReporter);
+ curl_easy_setopt(session, CURLOPT_PROGRESSFUNCTION, my_httpfprogress);
+ curl_easy_setopt(session, CURLOPT_DEBUGFUNCTION, myhttp_trace);
+ /* Set a pointer to our struct to pass to the callback */
+ curl_easy_setopt(session, CURLOPT_FILE, &ftpfile);
+
+ /* Switch on full protocol/debug output */
+ curl_easy_setopt(session, CURLOPT_VERBOSE, true);
+
+ /* FTP connection settings */
+
+#if (LIBCURL_VERSION_MAJOR > 7) || \
+ ((LIBCURL_VERSION_MAJOR == 7) && (LIBCURL_VERSION_MINOR > 10)) || \
+ ((LIBCURL_VERSION_MAJOR == 7) && (LIBCURL_VERSION_MINOR == 10) && (LIBCURL_VERSION_PATCH >= 5))
+# define EPRT_AVAILABLE 1
+#endif
+
+#ifdef EPRT_AVAILABLE
+ curl_easy_setopt(session, CURLOPT_FTP_USE_EPRT, 0);
+ SWLog::getSystemLog()->logDebug("***** using CURLOPT_FTP_USE_EPRT\n");
+#endif
+
+
+ SWLog::getSystemLog()->logDebug("***** About to perform curl easy action. \n");
+ SWLog::getSystemLog()->logDebug("***** destPath: %s \n", destPath);
+ SWLog::getSystemLog()->logDebug("***** sourceURL: %s \n", sourceURL);
+ res = curl_easy_perform(session);
+ SWLog::getSystemLog()->logDebug("***** Finished performing curl easy action. \n");
+
+ if(CURLE_OK != res) {
+ retVal = -1;
+ }
+ }
+
+ if (ftpfile.stream)
+ fclose(ftpfile.stream); /* close the local file */
+
+ return retVal;
+}
+
+
+SWORD_NAMESPACE_END
+
diff --git a/src/mgr/encfiltmgr.cpp b/src/mgr/encfiltmgr.cpp
index 970900c..cb6dab4 100644
--- a/src/mgr/encfiltmgr.cpp
+++ b/src/mgr/encfiltmgr.cpp
@@ -22,7 +22,6 @@
#include <encfiltmgr.h>
#include <utilstr.h>
-#include <scsuutf8.h>
#include <latin1utf8.h>
#include <unicodertf.h>
@@ -45,7 +44,6 @@ SWORD_NAMESPACE_START
EncodingFilterMgr::EncodingFilterMgr (char enc)
: SWFilterMgr() {
- scsuutf8 = new SCSUUTF8();
latin1utf8 = new Latin1UTF8();
encoding = enc;
@@ -72,8 +70,6 @@ EncodingFilterMgr::EncodingFilterMgr (char enc)
* EncodingFilterMgr Destructor - Cleans up instance of EncodingFilterMgr
*/
EncodingFilterMgr::~EncodingFilterMgr() {
- if (scsuutf8)
- delete scsuutf8;
if (latin1utf8)
delete latin1utf8;
if (targetenc)
@@ -88,9 +84,6 @@ void EncodingFilterMgr::AddRawFilters(SWModule *module, ConfigEntMap &section) {
if (!encoding.length() || !stricmp(encoding.c_str(), "Latin-1")) {
module->AddRawFilter(latin1utf8);
}
- else if (!stricmp(encoding.c_str(), "SCSU")) {
- module->AddRawFilter(scsuutf8);
- }
}
void EncodingFilterMgr::AddEncodingFilters(SWModule *module, ConfigEntMap &section) {
diff --git a/src/mgr/filemgr.cpp b/src/mgr/filemgr.cpp
index 4a91dfa..dd49913 100644
--- a/src/mgr/filemgr.cpp
+++ b/src/mgr/filemgr.cpp
@@ -2,7 +2,7 @@
* filemgr.cpp - implementation of class FileMgr used for pooling file
* handles
*
- * $Id: filemgr.cpp 2108 2007-10-13 20:35:02Z scribe $
+ * $Id: filemgr.cpp 2245 2009-02-10 23:22:28Z scribe $
*
* Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
* CrossWire Bible Society
@@ -481,7 +481,7 @@ char FileMgr::getLine(FileDesc *fDesc, SWBuf &line) {
line.append(chunk+start, size);
}
}
- return ((len>0) || line.length());
+ return ((len > 0) || line.length());
}
diff --git a/src/mgr/ftplibftpt.cpp b/src/mgr/ftplibftpt.cpp
index 4921dd5..108d93e 100644
--- a/src/mgr/ftplibftpt.cpp
+++ b/src/mgr/ftplibftpt.cpp
@@ -1,7 +1,24 @@
/*****************************************************************************
* FTPLibFTPTransport functions
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <stdio.h>
#include <fcntl.h>
@@ -43,7 +60,7 @@ char FTPLibFTPTransport::assureLoggedIn() {
if (ftpConnection == 0) {
SWLog::getSystemLog()->logDebug("connecting to host %s\n", host.c_str());
if (FtpConnect(host, &ftpConnection))
- if (FtpLogin("anonymous", "installmgr@user.com", ftpConnection)) {
+ if (FtpLogin(u.c_str(), p.c_str(), ftpConnection)) {
retVal = 0;
}
else {
diff --git a/src/mgr/ftptrans.cpp b/src/mgr/ftptrans.cpp
index ab0a605..76e8679 100644
--- a/src/mgr/ftptrans.cpp
+++ b/src/mgr/ftptrans.cpp
@@ -1,7 +1,25 @@
/*****************************************************************************
* FTPTransport functions
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
+
#include <ftptrans.h>
@@ -11,6 +29,9 @@
#include <dirent.h>
#include <swlog.h>
+extern "C" {
+#include <ftpparse.h>
+}
using std::vector;
@@ -40,6 +61,8 @@ void StatusReporter::statusUpdate(double dtTotal, double dlNow) {
FTPTransport::FTPTransport(const char *host, StatusReporter *statusReporter) {
this->statusReporter = statusReporter;
this->host = host;
+ u = "ftp";
+ p = "installmgr@user.com";
term = false;
}
diff --git a/src/mgr/installmgr.cpp b/src/mgr/installmgr.cpp
index 6a1704f..c3fec1a 100644
--- a/src/mgr/installmgr.cpp
+++ b/src/mgr/installmgr.cpp
@@ -2,9 +2,26 @@
* InstallMgr functions to be made into something usefully exposed by
* master Glassey
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#ifndef EXCLUDEZLIB
extern "C" {
#include <untgz.h>
@@ -28,10 +45,12 @@ extern "C" {
#ifdef CURLAVAILABLE
#include <curlftpt.h>
+#include <curlhttpt.h>
#else
#include <ftplibftpt.h>
#endif
+#include <iostream>
SWORD_NAMESPACE_START
namespace {
@@ -43,6 +62,8 @@ void removeTrailingSlash(SWBuf &buf) {
buf.size(len-1);
}
+const char *masterRepoList = "masterRepoList.conf";
+
};
@@ -66,13 +87,24 @@ FTPTransport *InstallMgr::createFTPTransport(const char *host, StatusReporter *s
#endif
}
+FTPTransport *InstallMgr::createHTTPTransport(const char *host, StatusReporter *statusReporter) {
+#ifdef CURLAVAILABLE
+ return new CURLHTTPTransport(host, statusReporter);
+#else
+ return 0;
+#endif
+}
-InstallMgr::InstallMgr(const char *privatePath, StatusReporter *sr) {
+InstallMgr::InstallMgr(const char *privatePath, StatusReporter *sr, SWBuf u, SWBuf p) {
+ userDisclaimerConfirmed = false;
statusReporter = sr;
+ this->u = u;
+ this->p = p;
this->privatePath = 0;
this->transport = 0;
+ installConf = 0;
stdstr(&(this->privatePath), privatePath);
if (this->privatePath) {
int len = strlen(this->privatePath);
@@ -80,39 +112,59 @@ InstallMgr::InstallMgr(const char *privatePath, StatusReporter *sr) {
|| (this->privatePath[len-1] == '\\'))
this->privatePath[len-1] = 0;
}
- SWBuf confPath = (SWBuf)privatePath + "/InstallMgr.conf";
+ confPath = (SWBuf)privatePath + "/InstallMgr.conf";
FileMgr::createParent(confPath.c_str());
- installConf = new SWConfig(confPath.c_str());
+ readInstallConf();
+}
- SectionMap::iterator sourcesSection;
- ConfigEntMap::iterator sourceBegin;
- ConfigEntMap::iterator sourceEnd;
+InstallMgr::~InstallMgr() {
+ delete [] privatePath;
+ delete installConf;
+ clearSources();
+}
+
+void InstallMgr::clearSources() {
+ for (InstallSourceMap::iterator it = sources.begin(); it != sources.end(); ++it) {
+ delete it->second;
+ }
sources.clear();
+}
+
+void InstallMgr::readInstallConf() {
+
+ if (installConf) delete installConf;
+
+ installConf = new SWConfig(confPath.c_str());
+
+ clearSources();
- setFTPPassive(stricmp((*installConf)["General"]["PassiveFTP"].c_str(), "false")!=0);
+ setFTPPassive(stricmp((*installConf)["General"]["PassiveFTP"].c_str(), "false") != 0);
- sourcesSection = installConf->Sections.find("Sources");
- if (sourcesSection != installConf->Sections.end()) {
- sourceBegin = sourcesSection->second.lower_bound("FTPSource");
- sourceEnd = sourcesSection->second.upper_bound("FTPSource");
+ SectionMap::iterator confSection = installConf->Sections.find("Sources");
+ ConfigEntMap::iterator sourceBegin;
+ ConfigEntMap::iterator sourceEnd;
+
+ if (confSection != installConf->Sections.end()) {
+ sourceBegin = confSection->second.lower_bound("FTPSource");
+ sourceEnd = confSection->second.upper_bound("FTPSource");
while (sourceBegin != sourceEnd) {
InstallSource *is = new InstallSource("FTP", sourceBegin->second.c_str());
sources[is->caption] = is;
- SWBuf parent = (SWBuf)privatePath + "/" + is->source + "/file";
+ SWBuf parent = (SWBuf)privatePath + "/" + is->uid + "/file";
FileMgr::createParent(parent.c_str());
- is->localShadow = (SWBuf)privatePath + "/" + is->source;
+ is->localShadow = (SWBuf)privatePath + "/" + is->uid;
sourceBegin++;
}
}
defaultMods.clear();
- sourcesSection = installConf->Sections.find("General");
- if (sourcesSection != installConf->Sections.end()) {
- sourceBegin = sourcesSection->second.lower_bound("DefaultMod");
- sourceEnd = sourcesSection->second.upper_bound("DefaultMod");
+ confSection = installConf->Sections.find("General");
+ if (confSection != installConf->Sections.end()) {
+ sourceBegin = confSection->second.lower_bound("DefaultMod");
+ sourceEnd = confSection->second.upper_bound("DefaultMod");
while (sourceBegin != sourceEnd) {
defaultMods.insert(sourceBegin->second.c_str());
@@ -122,18 +174,24 @@ InstallMgr::InstallMgr(const char *privatePath, StatusReporter *sr) {
}
-InstallMgr::~InstallMgr() {
- delete [] privatePath;
- delete installConf;
+void InstallMgr::saveInstallConf() {
+
+ installConf->Sections["Sources"].erase("FTPSource");
for (InstallSourceMap::iterator it = sources.begin(); it != sources.end(); ++it) {
- delete it->second;
+ if (it->second) {
+ installConf->Sections["Sources"].insert(ConfigEntMap::value_type("FTPSource", it->second->getConfEnt().c_str()));
+ }
}
+ (*installConf)["General"]["PassiveFTP"] = (isFTPPassive()) ? "true" : "false";
+
+ installConf->Save();
}
void InstallMgr::terminate() { if (transport) transport->terminate(); }
+
int InstallMgr::removeModule(SWMgr *manager, const char *moduleName) {
SectionMap::iterator module;
ConfigEntMap::iterator fileBegin;
@@ -148,7 +206,7 @@ int InstallMgr::removeModule(SWMgr *manager, const char *moduleName) {
// to be sure all files are closed
// this does not remove the .conf information from SWMgr
manager->deleteModule(modName);
-
+
fileBegin = module->second.lower_bound("File");
fileEnd = module->second.upper_bound("File");
@@ -201,11 +259,23 @@ int InstallMgr::removeModule(SWMgr *manager, const char *moduleName) {
int InstallMgr::ftpCopy(InstallSource *is, const char *src, const char *dest, bool dirTransfer, const char *suffix) {
+
+ // assert user disclaimer has been confirmed
+ if (!isUserDisclaimerConfirmed()) return -1;
+
int retVal = 0;
FTPTransport *trans = createFTPTransport(is->source, statusReporter);
transport = trans; // set classwide current transport for other thread terminate() call
+ if (is->u.length()) {
+ trans->setUser(is->u);
+ trans->setPasswd(is->p);
+ }
+ else {
+ trans->setUser(u);
+ trans->setPasswd(p);
+ }
trans->setPassive(passive);
-
+
SWBuf urlPrefix = (SWBuf)"ftp://" + is->source;
// let's be sure we can connect. This seems to be necessary but sucks
@@ -215,7 +285,7 @@ int InstallMgr::ftpCopy(InstallSource *is, const char *src, const char *dest, bo
// return -1;
// }
-
+
if (dirTransfer) {
SWBuf dir = (SWBuf)is->directory.c_str();
removeTrailingSlash(dir);
@@ -270,7 +340,7 @@ int InstallMgr::installModule(SWMgr *destMgr, const char *fromLocation, const ch
SWLog::getSystemLog()->logDebug("***** modName: %s \n", modName);
if (is)
- sourceDir = (SWBuf)privatePath + "/" + is->source;
+ sourceDir = (SWBuf)privatePath + "/" + is->uid;
else sourceDir = fromLocation;
removeTrailingSlash(sourceDir);
@@ -409,53 +479,16 @@ int InstallMgr::installModule(SWMgr *destMgr, const char *fromLocation, const ch
return 1;
}
+int InstallMgr::refreshRemoteSource(InstallSource *is) {
-// override this and provide an input mechanism to allow your users
-// to enter the decipher code for a module.
-// return true you added the cipher code to the config.
-// default to return 'aborted'
-bool InstallMgr::getCipherCode(const char *modName, SWConfig *config) {
- return false;
-
-/* a sample implementation, roughly taken from the windows installmgr
-
- SectionMap::iterator section;
- ConfigEntMap::iterator entry;
- SWBuf tmpBuf;
- section = config->Sections.find(modName);
- if (section != config->Sections.end()) {
- entry = section->second.find("CipherKey");
- if (entry != section->second.end()) {
- entry->second = GET_USER_INPUT();
- config->Save();
-
- // LET'S SHOW THE USER SOME SAMPLE TEXT FROM THE MODULE
- SWMgr *mgr = new SWMgr();
- SWModule *mod = mgr->Modules[modName];
- mod->setKey("Ipet 2:12");
- tmpBuf = mod->StripText();
- mod->setKey("gen 1:10");
- tmpBuf += "\n\n";
- tmpBuf += mod->StripText();
- SOME_DIALOG_CONTROL->SETTEXT(tmpBuf.c_str());
- delete mgr;
-
- // if USER CLICKS OK means we should return true
- return true;
- }
- }
- return false;
-*/
-
-}
-
+ // assert user disclaimer has been confirmed
+ if (!isUserDisclaimerConfirmed()) return -1;
-int InstallMgr::refreshRemoteSource(InstallSource *is) {
- SWBuf root = (SWBuf)privatePath + (SWBuf)"/" + is->source.c_str();
+ SWBuf root = (SWBuf)privatePath + (SWBuf)"/" + is->uid.c_str();
removeTrailingSlash(root);
SWBuf target = root + "/mods.d";
int errorCode = -1; //0 means successful
-
+
FileMgr::removeDir(target.c_str());
if (!FileMgr::existsDir(target))
@@ -463,17 +496,17 @@ int InstallMgr::refreshRemoteSource(InstallSource *is) {
#ifndef EXCLUDEZLIB
SWBuf archive = root + "/mods.d.tar.gz";
-
+
errorCode = ftpCopy(is, "mods.d.tar.gz", archive.c_str(), false);
if (!errorCode) { //sucessfully downloaded the tar,gz of module configs
FileDesc *fd = FileMgr::getSystemFileMgr()->open(archive.c_str(), FileMgr::RDONLY);
untargz(fd->getFd(), root.c_str());
FileMgr::getSystemFileMgr()->close(fd);
}
- else if (!term) //if the tar.gz download was canceled don't continue with another download
+ else
#endif
errorCode = ftpCopy(is, "mods.d", target.c_str(), true, ".conf"); //copy the whole directory
-
+
is->flush();
return errorCode;
}
@@ -536,19 +569,96 @@ map<SWModule *, int> InstallMgr::getModuleStatus(const SWMgr &base, const SWMgr
}
+/************************************************************************
+ * refreshRemoteSourceConfiguration - grab master list of know remote
+ * sources and integrate it with our configurations.
+ */
+int InstallMgr::refreshRemoteSourceConfiguration() {
+
+ // assert user disclaimer has been confirmed
+ if (!isUserDisclaimerConfirmed()) return -1;
+
+ SWBuf root = (SWBuf)privatePath;
+ removeTrailingSlash(root);
+ SWBuf masterRepoListPath = root + "/" + masterRepoList;
+ InstallSource is("FTP");
+ is.source = "ftp.crosswire.org";
+ is.directory = "/pub/sword";
+ int errorCode = ftpCopy(&is, masterRepoList, masterRepoListPath.c_str(), false);
+ if (!errorCode) { //sucessfully downloaded the repo list
+ SWConfig masterList(masterRepoListPath);
+ SectionMap::iterator sections = masterList.Sections.find("Repos");
+ if (sections != masterList.Sections.end()) {
+ for (ConfigEntMap::iterator actions = sections->second.begin(); actions != sections->second.end(); actions++) {
+ // Search through our current sources and see if we have a matching UID
+ InstallSourceMap::iterator it;
+ for (it = sources.begin(); it != sources.end(); ++it) {
+ // is this our UID?
+ if ((it->second) && (it->second->uid == actions->first)) {
+ if (actions->second == "REMOVE") {
+ // be sure to call save/reload after this
+ // or this could be dangerous
+ delete it->second;
+ it->second = 0;
+ }
+ else {
+ SWBuf key = actions->second.stripPrefix('=');
+ if (key == "FTPSource") {
+ // we might consider instantiating a temp IS
+ // from our config string and then copy only
+ // some entries. This would allow the use to
+ // change some fields and not have them overwritten
+ // but it seems like we might want to change any
+ // of the current fields so we don't do this now
+ // InstallSource i("FTP", actions->second);
+ delete it->second;
+ it->second = new InstallSource("FTP", actions->second.c_str());
+ it->second->uid = actions->first;
+ }
+ }
+ break;
+ }
+ }
+ // didn't find our UID, let's add it
+ if (it == sources.end()) {
+ SWBuf key = actions->second.stripPrefix('=');
+ if (key == "FTPSource") {
+ if (actions->second != "REMOVE") {
+ InstallSource *is = new InstallSource("FTP", actions->second.c_str());
+ is->uid = actions->first;
+ sources[is->caption] = is;
+ }
+ }
+ }
+ }
+
+ // persist and re-read
+ saveInstallConf();
+ readInstallConf();
+
+ return 0;
+ }
+ }
+ return -1;
+}
+
+
InstallSource::InstallSource(const char *type, const char *confEnt) {
this->type = type;
mgr = 0;
userData = 0;
if (confEnt) {
- char *buf = 0;
- stdstr(&buf, confEnt);
+ SWBuf buf = confEnt;
+ caption = buf.stripPrefix('|', true);
+ source = buf.stripPrefix('|', true);
+ directory = buf.stripPrefix('|', true);
+ u = buf.stripPrefix('|', true);
+ p = buf.stripPrefix('|', true);
+ uid = buf.stripPrefix('|', true);
+
+ if (!uid.length()) uid = source;
- caption = strtok(buf, "|");
- source = strtok(0, "|");
- directory = strtok(0, "|");
removeTrailingSlash(directory);
- delete [] buf;
}
}
diff --git a/src/mgr/localemgr.cpp b/src/mgr/localemgr.cpp
index ead076a..af57ca0 100644
--- a/src/mgr/localemgr.cpp
+++ b/src/mgr/localemgr.cpp
@@ -2,7 +2,7 @@
* localemgr.cpp - implementation of class LocaleMgr used to interact with
* registered locales for a sword installation
*
- * $Id: localemgr.cpp 2080 2007-09-17 06:21:29Z scribe $
+ * $Id: localemgr.cpp 2321 2009-04-13 01:17:00Z scribe $
*
* Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
* CrossWire Bible Society
@@ -49,8 +49,9 @@ public:
LocaleMgr *LocaleMgr::getSystemLocaleMgr() {
- if (!systemLocaleMgr)
- systemLocaleMgr = new LocaleMgr();
+ if (!systemLocaleMgr) {
+ setSystemLocaleMgr(new LocaleMgr());
+ }
return systemLocaleMgr;
}
@@ -60,6 +61,8 @@ void LocaleMgr::setSystemLocaleMgr(LocaleMgr *newLocaleMgr) {
if (systemLocaleMgr)
delete systemLocaleMgr;
systemLocaleMgr = newLocaleMgr;
+ SWLocale *locale = new SWLocale(0);
+ systemLocaleMgr->locales->insert(LocaleMap::value_type(locale->getName(), locale));
}
@@ -67,18 +70,29 @@ LocaleMgr::LocaleMgr(const char *iConfigPath) {
locales = new LocaleMap();
char *prefixPath = 0;
char *configPath = 0;
+ SWConfig *sysConf = 0;
char configType = 0;
SWBuf path;
std::list<SWBuf> augPaths;
+ ConfigEntMap::iterator entry;
defaultLocaleName = 0;
if (!iConfigPath) {
SWLog::getSystemLog()->logDebug("LOOKING UP LOCALE DIRECTORY...");
- SWMgr::findConfig(&configType, &prefixPath, &configPath, &augPaths);
+ SWMgr::findConfig(&configType, &prefixPath, &configPath, &augPaths, &sysConf);
+ if (sysConf) {
+ if ((entry = sysConf->Sections["Install"].find("LocalePath")) != sysConf->Sections["Install"].end()) {
+ configType = 9; // our own
+ stdstr(&prefixPath, (char *)entry->second.c_str());
+ SWLog::getSystemLog()->logDebug("LocalePath provided in sysConfig.");
+ }
+ }
SWLog::getSystemLog()->logDebug("LOOKING UP LOCALE DIRECTORY COMPLETE.");
}
- else configPath = (char *)iConfigPath;
+ else {
+ loadConfigDir(iConfigPath);
+ }
if (prefixPath) {
switch (configType) {
@@ -102,7 +116,7 @@ LocaleMgr::LocaleMgr(const char *iConfigPath) {
}
}
- if (augPaths.size()) { //load locale files from all augmented paths
+ if (augPaths.size() && configType != 9) { //load locale files from all augmented paths
std::list<SWBuf>::iterator it = augPaths.begin();
std::list<SWBuf>::iterator end = augPaths.end();
@@ -117,13 +131,16 @@ LocaleMgr::LocaleMgr(const char *iConfigPath) {
// Locales will be invalidated if you change the StringMgr
// So only use the default hardcoded locale and let the
// frontends change the locale if they want
- stdstr(&defaultLocaleName, "en_US");
+ stdstr(&defaultLocaleName, SWLocale::DEFAULT_LOCALE_NAME);
if (prefixPath)
delete [] prefixPath;
if (configPath)
delete [] configPath;
+
+ if (sysConf)
+ delete sysConf;
}
@@ -200,7 +217,7 @@ SWLocale *LocaleMgr::getLocale(const char *name) {
return (*it).second;
SWLog::getSystemLog()->logWarning("LocaleMgr::getLocale failed to find %s\n", name);
- return 0;
+ return (*locales)[SWLocale::DEFAULT_LOCALE_NAME];
}
diff --git a/src/mgr/swconfig.cpp b/src/mgr/swconfig.cpp
index 376c206..309f686 100644
--- a/src/mgr/swconfig.cpp
+++ b/src/mgr/swconfig.cpp
@@ -2,7 +2,7 @@
* swconfig.cpp - implementation of Class SWConfig used for saving and
* retrieval of configuration information
*
- * $Id: swconfig.cpp 1828 2005-06-10 16:24:46Z scribe $
+ * $Id: swconfig.cpp 2218 2008-12-23 09:33:38Z scribe $
*
* Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
* CrossWire Bible Society
@@ -28,6 +28,9 @@
SWORD_NAMESPACE_START
+SWConfig::SWConfig() {
+}
+
SWConfig::SWConfig(const char * ifilename) {
filename = ifilename;
Load();
@@ -38,6 +41,9 @@ SWConfig::~SWConfig() {
}
void SWConfig::Load() {
+
+ if (!filename.size()) return; // assert we have a filename
+
FileDesc *cfile;
char *buf, *data;
SWBuf line;
@@ -60,27 +66,30 @@ void SWConfig::Load() {
}
while (goodLine) {
- buf = new char [ line.length() + 1 ];
- strcpy(buf, line.c_str());
- if (*strstrip(buf) == '[') {
- if (!first)
- Sections.insert(SectionMap::value_type(sectname, cursect));
- else first = false;
-
- cursect.erase(cursect.begin(), cursect.end());
-
- strtok(buf, "]");
- sectname = buf+1;
- }
- else {
- strtok(buf, "=");
- if ((*buf) && (*buf != '=')) {
- if ((data = strtok(NULL, "")))
- cursect.insert(ConfigEntMap::value_type(buf, strstrip(data)));
- else cursect.insert(ConfigEntMap::value_type(buf, ""));
+ // ignore commented lines
+ if (!line.startsWith("#")) {
+ buf = new char [ line.length() + 1 ];
+ strcpy(buf, line.c_str());
+ if (*strstrip(buf) == '[') {
+ if (!first)
+ Sections.insert(SectionMap::value_type(sectname, cursect));
+ else first = false;
+
+ cursect.erase(cursect.begin(), cursect.end());
+
+ strtok(buf, "]");
+ sectname = buf+1;
}
+ else {
+ strtok(buf, "=");
+ if ((*buf) && (*buf != '=')) {
+ if ((data = strtok(NULL, "")))
+ cursect.insert(ConfigEntMap::value_type(buf, strstrip(data)));
+ else cursect.insert(ConfigEntMap::value_type(buf, ""));
+ }
+ }
+ delete [] buf;
}
- delete [] buf;
goodLine = FileMgr::getLine(cfile, line);
}
if (!first)
@@ -92,6 +101,9 @@ void SWConfig::Load() {
void SWConfig::Save() {
+
+ if (!filename.size()) return; // assert we have a filename
+
FileDesc *cfile;
SWBuf buf;
SectionMap::iterator sit;
diff --git a/src/mgr/swlocale.cpp b/src/mgr/swlocale.cpp
index facb1ee..3d09313 100644
--- a/src/mgr/swlocale.cpp
+++ b/src/mgr/swlocale.cpp
@@ -2,7 +2,7 @@
* swlocale.cpp - implementation of Class SWLocale used for retrieval
* of locale lookups
*
- * $Id: swlocale.cpp 1864 2005-11-20 06:06:40Z scribe $
+ * $Id: swlocale.cpp 2346 2009-04-27 01:53:58Z scribe $
*
* Copyright 2000 CrossWire Bible Society (http://www.crosswire.org)
* CrossWire Bible Society
@@ -25,29 +25,42 @@
#include <map>
#include <swconfig.h>
#include <versekey.h>
+#include <versemgr.h>
SWORD_NAMESPACE_START
typedef std::map < SWBuf, SWBuf, std::less < SWBuf > >LookupMap;
+const char *SWLocale::DEFAULT_LOCALE_NAME="en_US";
+
// I have bridge patterns, but this hides swconfig and map from lots o stuff
class SWLocale::Private {
public:
LookupMap lookupTable;
+ LookupMap mergedAbbrevs;
};
-SWLocale::SWLocale(const char * ifilename) {
+SWLocale::SWLocale(const char *ifilename) {
p = new Private;
ConfigEntMap::iterator confEntry;
- name = 0;
- description = 0;
- encoding = 0;
- bookAbbrevs = 0;
- BMAX = 0;
- books = 0;
- localeSource = new SWConfig(ifilename);
+ name = 0;
+ description = 0;
+ encoding = 0;
+ bookAbbrevs = 0;
+ bookLongNames = 0;
+ bookPrefAbbrev = 0;
+ if (ifilename) {
+ localeSource = new SWConfig(ifilename);
+ }
+ else {
+ localeSource = new SWConfig(0);
+ (*localeSource)["Meta"]["Name"] = DEFAULT_LOCALE_NAME;
+ (*localeSource)["Meta"]["Description"] = "English (US)";
+ bookAbbrevs = (struct abbrev *)builtin_abbrevs;
+ for (abbrevsCnt = 0; builtin_abbrevs[abbrevsCnt].osis[0]; abbrevsCnt++);
+ }
confEntry = localeSource->Sections["Meta"].find("Name");
if (confEntry != localeSource->Sections["Meta"].end())
@@ -76,15 +89,9 @@ SWLocale::~SWLocale() {
if (name)
delete [] name;
- if (bookAbbrevs)
+ if (bookAbbrevs != builtin_abbrevs)
delete [] bookAbbrevs;
- if (BMAX) {
- for (int i = 0; i < 2; i++)
- delete [] books[i];
- delete [] BMAX;
- delete [] books;
- }
delete p;
}
@@ -145,60 +152,35 @@ void SWLocale::augment(SWLocale &addFrom) {
*localeSource += *addFrom.localeSource;
}
-//#define NONNUMERICLOCALETHING 1
-const struct abbrev *SWLocale::getBookAbbrevs() {
+const struct abbrev *SWLocale::getBookAbbrevs(int *retSize) {
static const char *nullstr = "";
if (!bookAbbrevs) {
- ConfigEntMap::iterator it;
- int i, j;
- int size = localeSource->Sections["Book Abbrevs"].size();
+ // Assure all english abbrevs are present
+ for (int j = 0; builtin_abbrevs[j].osis[0]; j++) {
+ p->mergedAbbrevs[builtin_abbrevs[j].ab] = builtin_abbrevs[j].osis;
+ }
+ ConfigEntMap::iterator it = localeSource->Sections["Book Abbrevs"].begin();
+ ConfigEntMap::iterator end = localeSource->Sections["Book Abbrevs"].end();
+ for (; it != end; it++) {
+ p->mergedAbbrevs[it->first.c_str()] = it->second.c_str();
+ }
+ int size = p->mergedAbbrevs.size();
bookAbbrevs = new struct abbrev[size + 1];
- for (i = 0, j = 0, it = localeSource->Sections["Book Abbrevs"].begin(); it != localeSource->Sections["Book Abbrevs"].end(); it++, i++) {
- #ifdef NONNUMERICLOCALETHING
- int booknum = VerseKey::getOSISBookNum((*it).second.c_str());
- if (booknum != -1) {
- bookAbbrevs[j].ab = (*it).first.c_str();
- bookAbbrevs[j].book = booknum;
- j++;
- }
- #else
- bookAbbrevs[i].ab = (*it).first.c_str();
- bookAbbrevs[i].book = atoi((*it).second.c_str());
- j++;
- #endif
- //printf("SWLocale::getBookAbbrevs %s:%s %d\n",bookAbbrevs[i].ab,
- // (*it).second.c_str(), bookAbbrevs[i].book);
+ int i = 0;
+ for (LookupMap::iterator it = p->mergedAbbrevs.begin(); it != p->mergedAbbrevs.end(); it++, i++) {
+ bookAbbrevs[i].ab = it->first.c_str();
+ bookAbbrevs[i].osis = it->second.c_str();
}
- bookAbbrevs[j].ab = nullstr;
- bookAbbrevs[j].book = -1;
+
+ bookAbbrevs[i].ab = nullstr;
+ bookAbbrevs[i].osis = nullstr;
+ abbrevsCnt = size;
}
+ *retSize = abbrevsCnt;
return bookAbbrevs;
}
-void SWLocale::getBooks(char **iBMAX, struct sbook ***ibooks) {
- if (!BMAX) {
- BMAX = new char [2];
- BMAX[0] = VerseKey::builtin_BMAX[0];
- BMAX[1] = VerseKey::builtin_BMAX[1];
-
- books = new struct sbook *[2];
- books[0] = new struct sbook[BMAX[0]];
- books[1] = new struct sbook[BMAX[1]];
-
- for (int i = 0; i < 2; i++) {
- for (int j = 0; j < BMAX[i]; j++) {
- books[i][j] = VerseKey::builtin_books[i][j];
- books[i][j].name = translate(VerseKey::builtin_books[i][j].name);
- }
- }
- }
-
- *iBMAX = BMAX;
- *ibooks = books;
-}
-
-
SWORD_NAMESPACE_END
diff --git a/src/mgr/swmgr.cpp b/src/mgr/swmgr.cpp
index 86c04d7..3ee253f 100644
--- a/src/mgr/swmgr.cpp
+++ b/src/mgr/swmgr.cpp
@@ -2,7 +2,7 @@
* swmgr.cpp - implementaion of class SWMgr used to interact with an install
* base of sword modules.
*
- * $Id: swmgr.cpp 2169 2008-05-18 02:50:53Z scribe $
+ * $Id: swmgr.cpp 2374 2009-05-04 03:48:01Z scribe $
*
* Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
* CrossWire Bible Society
@@ -58,6 +58,7 @@
#include <osislemma.h>
#include <osisredletterwords.h>
#include <osismorphsegmentation.h>
+#include <osisruby.h>
#include <osisscripref.h>
#include <thmlstrongs.h>
#include <thmlfootnotes.h>
@@ -75,6 +76,7 @@
#include <utf8greekaccents.h>
#include <utf8cantillation.h>
#include <utf8hebrewpoints.h>
+#include <utf8arabicpoints.h>
#include <greeklexattribs.h>
#include <swfiltermgr.h>
#include <swcipher.h>
@@ -177,6 +179,10 @@ void SWMgr::init() {
optionFilters.insert(OptionFilterMap::value_type("OSISMorphSegmentation", tmpFilter));
cleanupFilters.push_back(tmpFilter);
+ tmpFilter = new OSISRuby();
+ optionFilters.insert(OptionFilterMap::value_type("OSISRuby", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
tmpFilter = new ThMLStrongs();
optionFilters.insert(OptionFilterMap::value_type("ThMLStrongs", tmpFilter));
cleanupFilters.push_back(tmpFilter);
@@ -209,6 +215,10 @@ void SWMgr::init() {
optionFilters.insert(OptionFilterMap::value_type("UTF8HebrewPoints", tmpFilter));
cleanupFilters.push_back(tmpFilter);
+ tmpFilter = new UTF8ArabicPoints();
+ optionFilters.insert(OptionFilterMap::value_type("UTF8ArabicPoints", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
tmpFilter = new UTF8Cantillation();
optionFilters.insert(OptionFilterMap::value_type("UTF8Cantillation", tmpFilter));
cleanupFilters.push_back(tmpFilter);
@@ -240,7 +250,24 @@ void SWMgr::init() {
teiplain = new TEIPlain();
cleanupFilters.push_back(teiplain);
-//#endif
+}
+
+
+SWBuf SWMgr::getHomeDir() {
+
+ // figure out 'home' directory for app data
+ SWBuf homeDir = getenv("HOME");
+ if (!homeDir.length()) {
+ // silly windows
+ homeDir = getenv("APPDATA");
+ }
+ if (homeDir.length()) {
+ if ((homeDir[homeDir.length()-1] != '\\') && (homeDir[homeDir.length()-1] != '/')) {
+ homeDir += "/";
+ }
+ }
+
+ return homeDir;
}
@@ -259,10 +286,10 @@ void SWMgr::commonInit(SWConfig *iconfig, SWConfig *isysconfig, bool autoload, S
}
else config = 0;
if (isysconfig) {
- sysconfig = isysconfig;
+ sysConfig = isysconfig;
mysysconfig = 0;
}
- else sysconfig = 0;
+ else sysConfig = 0;
if (autoload)
Load();
@@ -311,7 +338,7 @@ SWMgr::SWMgr(const char *iConfigPath, bool autoload, SWFilterMgr *filterMgr, boo
}
config = 0;
- sysconfig = 0;
+ sysConfig = 0;
if (autoload && configPath)
Load();
@@ -345,32 +372,46 @@ SWMgr::~SWMgr() {
}
-void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath, std::list<SWBuf> *augPaths, SWConfig *providedSysConf) {
+void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath, std::list<SWBuf> *augPaths, SWConfig **providedSysConf) {
SWBuf path;
SWBuf sysConfPath;
ConfigEntMap::iterator entry;
ConfigEntMap::iterator lastEntry;
- char *envsworddir = getenv("SWORD_PATH");
- char *envhomedir = getenv("HOME");
SWConfig *sysConf = 0;
+ SWBuf sysConfDataPath = "";
*configType = 0;
+ SWBuf homeDir = getHomeDir();
+
// check for a sysConf passed in to us
SWLog::getSystemLog()->logDebug("Checking for provided SWConfig(\"sword.conf\")...");
- if (providedSysConf) {
- sysConf = providedSysConf;
+ if (providedSysConf && *providedSysConf) {
+ sysConf = *providedSysConf;
SWLog::getSystemLog()->logDebug("found.");
}
- else {
+
+ // if we haven't been given our datapath in a sysconf, we need to track it down
+ if (!sysConf) {
// check working directory
SWLog::getSystemLog()->logDebug("Checking working directory for sword.conf...");
if (FileMgr::existsFile(".", "sword.conf")) {
SWLog::getSystemLog()->logDebug("Overriding any systemwide or ~/.sword/ sword.conf with one found in current directory.");
sysConfPath = "./sword.conf";
+ sysConf = new SWConfig(sysConfPath);
+ if ((entry = sysConf->Sections["Install"].find("DataPath")) != sysConf->Sections["Install"].end()) {
+ sysConfDataPath = (*entry).second;
+ }
+ if (providedSysConf) {
+ *providedSysConf = sysConf;
+ }
+ else {
+ delete sysConf;
+ sysConf = 0;
+ }
}
- else {
+ if (!sysConfDataPath.size()) {
SWLog::getSystemLog()->logDebug("Checking working directory for mods.conf...");
if (FileMgr::existsFile(".", "mods.conf")) {
SWLog::getSystemLog()->logDebug("found.");
@@ -388,7 +429,7 @@ void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath, s
return;
}
- // check working directory ../library/
+ // check working directory ../library/
SWLog::getSystemLog()->logDebug("Checking working directory ../library/ for mods.d...");
if (FileMgr::existsDir("../library", "mods.d")) {
SWLog::getSystemLog()->logDebug("found.");
@@ -399,13 +440,14 @@ void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath, s
}
// check environment variable SWORD_PATH
- SWLog::getSystemLog()->logDebug("Checking SWORD_PATH...");
+ SWLog::getSystemLog()->logDebug("Checking $SWORD_PATH...");
- if (envsworddir != NULL) {
+ SWBuf envsworddir = getenv("SWORD_PATH");
+ if (envsworddir.length()) {
- SWLog::getSystemLog()->logDebug("found (%s).", envsworddir);
+ SWLog::getSystemLog()->logDebug("found (%s).", envsworddir.c_str());
path = envsworddir;
- if ((envsworddir[strlen(envsworddir)-1] != '\\') && (envsworddir[strlen(envsworddir)-1] != '/'))
+ if ((envsworddir[envsworddir.length()-1] != '\\') && (envsworddir[envsworddir.length()-1] != '/'))
path += "/";
SWLog::getSystemLog()->logDebug("Checking $SWORD_PATH for mods.conf...");
@@ -446,29 +488,38 @@ void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath, s
sysConfPath = gfp;
delete [] globPaths;
- SWBuf homeDir = envhomedir;
- if (homeDir.size() > 0) {
- if ((homeDir[homeDir.size()-1] != '\\') && (homeDir[homeDir.size()-1] != '/'))
- homeDir += "/";
- homeDir += ".sword/sword.conf";
- if (FileMgr::existsFile(homeDir)) {
- SWLog::getSystemLog()->logDebug("Overriding any systemwide sword.conf with one found in users home directory.");
- sysConfPath = homeDir;
+ if (homeDir.length()) {
+ SWBuf tryPath = homeDir;
+ tryPath += ".sword/sword.conf";
+ if (FileMgr::existsFile(tryPath)) {
+ SWLog::getSystemLog()->logDebug("Overriding any systemwide sword.conf with one found in users home directory (%s)", tryPath.c_str());
+ sysConfPath = tryPath;
+ }
+ else {
+ SWBuf tryPath = homeDir;
+ tryPath += "sword/sword.conf";
+ if (FileMgr::existsFile(tryPath)) {
+ SWLog::getSystemLog()->logDebug("Overriding any systemwide sword.conf with one found in users home directory (%s)", tryPath.c_str());
+ sysConfPath = tryPath;
+ }
}
}
}
}
- if (sysConfPath.size()) {
+ if (!sysConf && sysConfPath.size()) {
sysConf = new SWConfig(sysConfPath);
}
if (sysConf) {
if ((entry = sysConf->Sections["Install"].find("DataPath")) != sysConf->Sections["Install"].end()) {
- path = (*entry).second;
- if (((*entry).second.c_str()[strlen((*entry).second.c_str())-1] != '\\') && ((*entry).second.c_str()[strlen((*entry).second.c_str())-1] != '/'))
- path += "/";
+ sysConfDataPath = (*entry).second;
+ }
+ if (sysConfDataPath.size()) {
+ if ((!sysConfDataPath.endsWith("\\")) && (!sysConfDataPath.endsWith("/")))
+ sysConfDataPath += "/";
+ path = sysConfDataPath;
SWLog::getSystemLog()->logDebug("DataPath in %s is set to %s.", sysConfPath.c_str(), path.c_str());
SWLog::getSystemLog()->logDebug("Checking for mods.conf in DataPath...");
@@ -490,6 +541,10 @@ void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath, s
*configType = 1;
}
}
+ }
+
+ // do some extra processing of sysConf if we have one
+ if (sysConf) {
if (augPaths) {
augPaths->clear();
entry = sysConf->Sections["Install"].lower_bound("AugmentPath");
@@ -501,23 +556,72 @@ void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath, s
augPaths->push_back(path);
}
}
- }
-
- if ((sysConf) && (!providedSysConf)) {
- delete sysConf;
+ if (providedSysConf) {
+ *providedSysConf = sysConf;
+ }
+ else delete sysConf;
}
if (*configType)
return;
+ // WE STILL HAVEN'T FOUND A CONFIGURATION. LET'S LOOK IN SOME OS SPECIFIC
+ // LOCATIONS
+ //
+ // for various flavors of windoze...
+ // check %ALLUSERSPROFILE%/Application Data/sword/
+
+ SWLog::getSystemLog()->logDebug("Checking $ALLUSERSPROFILE/Application Data/sword/...");
+
+ SWBuf envallusersdir = getenv("ALLUSERSPROFILE");
+ if (envallusersdir.length()) {
+ SWLog::getSystemLog()->logDebug("found (%s).", envallusersdir.c_str());
+ path = envallusersdir;
+ if ((!path.endsWith("\\")) && (!path.endsWith("/")))
+ path += "/";
+
+ path += "Application Data/sword/";
+ SWLog::getSystemLog()->logDebug("Checking %s for mods.d...", path.c_str());
+ if (FileMgr::existsDir(path.c_str(), "mods.d")) {
+ SWLog::getSystemLog()->logDebug("found.");
+ stdstr(prefixPath, path.c_str());
+ path += "mods.d";
+ stdstr(configPath, path.c_str());
+ *configType = 1;
+ return;
+ }
+ }
+
+ // for Mac OSX...
+ // check $HOME/Library/Application Support/Sword/
+
+ SWLog::getSystemLog()->logDebug("Checking $HOME/Library/Application Support/Sword/...");
+
+ SWBuf pathCheck = getHomeDir();
+ if (pathCheck.length()) {
+ SWLog::getSystemLog()->logDebug("found (%s).", pathCheck.c_str());
+ path = pathCheck;
+ if ((!path.endsWith("\\")) && (!path.endsWith("/")))
+ path += "/";
+
+ SWLog::getSystemLog()->logDebug("Checking %s for mods.d...", path.c_str());
+ if (FileMgr::existsDir(path.c_str(), "mods.d")) {
+ SWLog::getSystemLog()->logDebug("found.");
+ stdstr(prefixPath, path.c_str());
+ path += "mods.d";
+ stdstr(configPath, path.c_str());
+ *configType = 1;
+ return;
+ }
+ }
+
+ // FINALLY CHECK PERSONAL HOME DIRECTORY LOCATIONS
// check ~/.sword/
SWLog::getSystemLog()->logDebug("Checking home directory for ~/.sword...");
- if (envhomedir != NULL) {
- path = envhomedir;
- if ((envhomedir[strlen(envhomedir)-1] != '\\') && (envhomedir[strlen(envhomedir)-1] != '/'))
- path += "/";
+ if (homeDir.length()) {
+ path = homeDir;
path += ".sword/";
SWLog::getSystemLog()->logDebug(" Checking for %smods.conf...", path.c_str());
if (FileMgr::existsFile(path.c_str(), "mods.conf")) {
@@ -537,6 +641,18 @@ void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath, s
*configType = 2;
return;
}
+
+ path = homeDir;
+ path += "sword/";
+ SWLog::getSystemLog()->logDebug(" Checking for %smods.d...", path.c_str());
+ if (FileMgr::existsDir(path.c_str(), "mods.d")) {
+ SWLog::getSystemLog()->logDebug("found.");
+ stdstr(prefixPath, path.c_str());
+ path += "mods.d";
+ stdstr(configPath, path.c_str());
+ *configType = 2;
+ return;
+ }
}
}
@@ -551,21 +667,19 @@ void SWMgr::loadConfigDir(const char *ipath)
rewinddir(dir);
while ((ent = readdir(dir))) {
//check whether it ends with .conf, if it doesn't skip it!
- if (ent->d_name && (strlen(ent->d_name) > 5) && strncmp(".conf", (ent->d_name + strlen(ent->d_name) - 5), 5 )) {
+ if (!ent->d_name || (strlen(ent->d_name) <= 5) || strncmp(".conf", (ent->d_name + strlen(ent->d_name) - 5), 5 )) {
continue;
}
- if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
- newmodfile = ipath;
- if ((ipath[strlen(ipath)-1] != '\\') && (ipath[strlen(ipath)-1] != '/'))
- newmodfile += "/";
- newmodfile += ent->d_name;
- if (config) {
- SWConfig tmpConfig(newmodfile.c_str());
- *config += tmpConfig;
- }
- else config = myconfig = new SWConfig(newmodfile.c_str());
+ newmodfile = ipath;
+ if ((ipath[strlen(ipath)-1] != '\\') && (ipath[strlen(ipath)-1] != '/'))
+ newmodfile += "/";
+ newmodfile += ent->d_name;
+ if (config) {
+ SWConfig tmpConfig(newmodfile.c_str());
+ *config += tmpConfig;
}
+ else config = myconfig = new SWConfig(newmodfile.c_str());
}
closedir(dir);
@@ -646,7 +760,9 @@ signed char SWMgr::Load() {
if (!config) { // If we weren't passed a config object at construction, find a config file
if (!configPath) { // If we weren't passed a config path at construction...
SWLog::getSystemLog()->logDebug("LOOKING UP MODULE CONFIGURATION...");
- findConfig(&configType, &prefixPath, &configPath, &augPaths, sysconfig);
+ SWConfig *externalSysConf = sysConfig; // if we have a sysConf before findConfig, then we were provided one from an external source.
+ findConfig(&configType, &prefixPath, &configPath, &augPaths, &sysConfig);
+ if (!externalSysConf) mysysconfig = sysConfig; // remind us to delete our own sysConfig in d-tor
SWLog::getSystemLog()->logDebug("LOOKING UP MODULE CONFIGURATION COMPLETE.");
}
if (configPath) {
@@ -680,17 +796,18 @@ signed char SWMgr::Load() {
}
if (augmentHome) {
// augment config with ~/.sword/mods.d if it exists ---------------------
- char *envhomedir = getenv("HOME");
- if (envhomedir != NULL && configType != 2) { // 2 = user only
- SWBuf path = envhomedir;
- if ((envhomedir[strlen(envhomedir)-1] != '\\') && (envhomedir[strlen(envhomedir)-1] != '/'))
- path += "/";
+ SWBuf homeDir = getHomeDir();
+ if (homeDir.length() && configType != 2) { // 2 = user only
+ SWBuf path = homeDir;
path += ".sword/";
augmentModules(path.c_str(), mgrModeMultiMod);
+ path = homeDir;
+ path += "sword/";
+ augmentModules(path.c_str(), mgrModeMultiMod);
}
}
// -------------------------------------------------------------------------
- if ( !Modules.size() ) // config exists, but no modules
+ if (!Modules.size()) // config exists, but no modules
ret = 1;
}
@@ -718,6 +835,8 @@ SWModule *SWMgr::CreateMod(const char *name, const char *driver, ConfigEntMap &s
if ((prefixPath[strlen(prefixPath)-1] != '\\') && (prefixPath[strlen(prefixPath)-1] != '/'))
datapath += "/";
+ SWBuf versification = ((entry = section.find("Versification")) != section.end()) ? (*entry).second : (SWBuf)"KJV";
+
// DataPath - relative path to data used by module driver. May be a directory, may be a File.
// Typically not useful by outside world. See AbsoluteDataPath, PrefixPath, and RelativePrefixPath
// below.
@@ -749,9 +868,7 @@ SWModule *SWMgr::CreateMod(const char *name, const char *driver, ConfigEntMap &s
else
markup = FMT_GBF;
- if (!stricmp(encoding.c_str(), "SCSU"))
- enc = ENC_SCSU;
- else if (!stricmp(encoding.c_str(), "UTF-8")) {
+ if (!stricmp(encoding.c_str(), "UTF-8")) {
enc = ENC_UTF8;
}
else enc = ENC_LATIN1;
@@ -795,17 +912,17 @@ SWModule *SWMgr::CreateMod(const char *name, const char *driver, ConfigEntMap &s
if (compress) {
if (!stricmp(driver, "zText"))
- newmod = new zText(datapath.c_str(), name, description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str());
- else newmod = new zCom(datapath.c_str(), name, description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str());
+ newmod = new zText(datapath.c_str(), name, description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str(), versification);
+ else newmod = new zCom(datapath.c_str(), name, description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str(), versification);
}
}
if (!stricmp(driver, "RawText")) {
- newmod = new RawText(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str());
+ newmod = new RawText(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str(), versification);
}
if (!stricmp(driver, "RawText4")) {
- newmod = new RawText4(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str());
+ newmod = new RawText4(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str(), versification);
}
// backward support old drivers
@@ -814,11 +931,11 @@ SWModule *SWMgr::CreateMod(const char *name, const char *driver, ConfigEntMap &s
}
if (!stricmp(driver, "RawCom")) {
- newmod = new RawCom(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str());
+ newmod = new RawCom(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str(), versification);
}
if (!stricmp(driver, "RawCom4")) {
- newmod = new RawCom4(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str());
+ newmod = new RawCom4(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str(), versification);
}
if (!stricmp(driver, "RawFiles")) {
@@ -888,11 +1005,11 @@ SWModule *SWMgr::CreateMod(const char *name, const char *driver, ConfigEntMap &s
*/
}
- // if a specific module type is set in the config, use this
- if ((entry = section.find("Type")) != section.end())
- newmod->Type(entry->second.c_str());
+ if (newmod) {
+ // if a specific module type is set in the config, use this
+ if ((entry = section.find("Type")) != section.end())
+ newmod->Type(entry->second.c_str());
- if (newmod){
newmod->setConfig(&section);
}
diff --git a/src/mgr/versemgr.cpp b/src/mgr/versemgr.cpp
new file mode 100644
index 0000000..0673746
--- /dev/null
+++ b/src/mgr/versemgr.cpp
@@ -0,0 +1,369 @@
+/******************************************************************************
+ * versemgr.cpp - implementation of class VerseMgr used for managing
+ * versification systems
+ *
+ * $Id: versemgr.cpp 2108 2007-10-13 20:35:02Z scribe $
+ *
+ * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <versemgr.h>
+#include <vector>
+#include <map>
+#include <treekey.h>
+#include <canon.h> // KJV internal versification system
+#include <swlog.h>
+#include <algorithm>
+
+#include <canon_null.h> // null v11n system
+
+#include <canon_leningrad.h> // Leningrad Codex (WLC) v11n system
+#include <canon_mt.h> // Masoretic Text (MT) v11n system
+#include <canon_kjva.h> // KJV + Apocrypha v11n system
+#include <canon_nrsv.h> // NRSV v11n system
+#include <canon_nrsva.h> // NRSVA + Apocrypha v11n system
+
+using std::vector;
+using std::map;
+using std::distance;
+using std::lower_bound;
+
+SWORD_NAMESPACE_START
+
+
+VerseMgr *VerseMgr::getSystemVerseMgr() {
+ if (!systemVerseMgr) {
+ systemVerseMgr = new VerseMgr();
+ systemVerseMgr->registerVersificationSystem("KJV", otbooks, ntbooks, vm);
+ systemVerseMgr->registerVersificationSystem("Leningrad", otbooks_leningrad, ntbooks_null, vm_leningrad);
+ systemVerseMgr->registerVersificationSystem("MT", otbooks_mt, ntbooks_null, vm_mt);
+ systemVerseMgr->registerVersificationSystem("KJVA", otbooks_kjva, ntbooks, vm_kjva);
+ systemVerseMgr->registerVersificationSystem("NRSV", otbooks, ntbooks, vm_nrsv);
+ systemVerseMgr->registerVersificationSystem("NRSVA", otbooks_nrsva, ntbooks, vm_nrsva);
+ }
+ return systemVerseMgr;
+}
+
+
+class VerseMgr::System::Private {
+public:
+ /** Array[chapmax] of maximum verses in chapters */
+ vector<Book> books;
+ map<SWBuf, int> osisLookup;
+
+ Private() {
+ }
+ Private(const VerseMgr::System::Private &other) {
+ books = other.books;
+ osisLookup = other.osisLookup;
+ }
+ VerseMgr::System::Private &operator =(const VerseMgr::System::Private &other) {
+ books = other.books;
+ osisLookup = other.osisLookup;
+ return *this;
+ }
+};
+
+
+class VerseMgr::Book::Private {
+friend struct BookOffsetLess;
+public:
+ /** Array[chapmax] of maximum verses in chapters */
+ vector<int> verseMax;
+ vector<long> offsetPrecomputed;
+
+ Private() {
+ verseMax.clear();
+ }
+ Private(const VerseMgr::Book::Private &other) {
+ verseMax.clear();
+ verseMax = other.verseMax;
+ offsetPrecomputed = other.offsetPrecomputed;
+ }
+ VerseMgr::Book::Private &operator =(const VerseMgr::Book::Private &other) {
+ verseMax.clear();
+ verseMax = other.verseMax;
+ offsetPrecomputed = other.offsetPrecomputed;
+ return *this;
+ }
+};
+
+struct BookOffsetLess {
+ bool operator() (const VerseMgr::Book &o1, const VerseMgr::Book &o2) const { return o1.p->offsetPrecomputed[0] < o2.p->offsetPrecomputed[0]; }
+ bool operator() (const long &o1, const VerseMgr::Book &o2) const { return o1 < o2.p->offsetPrecomputed[0]; }
+ bool operator() (const VerseMgr::Book &o1, const long &o2) const { return o1.p->offsetPrecomputed[0] < o2; }
+ bool operator() (const long &o1, const long &o2) const { return o1 < o2; }
+};
+
+void VerseMgr::Book::init() {
+ p = new Private();
+}
+
+void VerseMgr::System::init() {
+ p = new Private();
+ BMAX[0] = 0;
+ BMAX[1] = 0;
+ ntStartOffset = 0;
+}
+
+
+VerseMgr::System::System(const System &other) {
+ init();
+ name = other.name;
+ BMAX[0] = other.BMAX[0];
+ BMAX[1] = other.BMAX[1];
+ (*p) = *(other.p);
+ ntStartOffset = other.ntStartOffset;
+}
+
+VerseMgr::System &VerseMgr::System::operator =(const System &other) {
+ name = other.name;
+ BMAX[0] = other.BMAX[0];
+ BMAX[1] = other.BMAX[1];
+ (*p) = *(other.p);
+ ntStartOffset = other.ntStartOffset;
+ return *this;
+}
+
+
+VerseMgr::System::~System() {
+ delete p;
+}
+
+const VerseMgr::Book *VerseMgr::System::getBook(int number) const {
+ return (number < (signed int)p->books.size()) ? &(p->books[number]) : 0;
+}
+
+
+int VerseMgr::System::getBookNumberByOSISName(const char *bookName) const {
+ map<SWBuf, int>::const_iterator it = p->osisLookup.find(bookName);
+ return (it != p->osisLookup.end()) ? it->second : -1;
+}
+
+
+void VerseMgr::System::loadFromSBook(const sbook *ot, const sbook *nt, int *chMax) {
+ int chap = 0;
+ int book = 0;
+ long offset = 0; // module heading
+ offset++; // testament heading
+ while (ot->chapmax) {
+ p->books.push_back(Book(ot->name, ot->osis, ot->prefAbbrev, ot->chapmax));
+ offset++; // book heading
+ Book &b = p->books[p->books.size()-1];
+ p->osisLookup[b.getOSISName()] = p->books.size();
+ for (int i = 0; i < ot->chapmax; i++) {
+ b.p->verseMax.push_back(chMax[chap]);
+ offset++; // chapter heading
+ b.p->offsetPrecomputed.push_back(offset);
+ offset += chMax[chap++];
+ }
+ ot++;
+ book++;
+ }
+ BMAX[0] = book;
+ book = 0;
+ ntStartOffset = offset;
+ offset++; // testament heading
+ while (nt->chapmax) {
+ p->books.push_back(Book(nt->name, nt->osis, nt->prefAbbrev, nt->chapmax));
+ offset++; // book heading
+ Book &b = p->books[p->books.size()-1];
+ p->osisLookup[b.getOSISName()] = p->books.size();
+ for (int i = 0; i < nt->chapmax; i++) {
+ b.p->verseMax.push_back(chMax[chap]);
+ offset++; // chapter heading
+ b.p->offsetPrecomputed.push_back(offset);
+ offset += chMax[chap++];
+ }
+ nt++;
+ book++;
+ }
+ BMAX[1] = book;
+
+ // TODO: build offset speed array
+}
+
+
+VerseMgr::Book::Book(const Book &other) {
+ longName = other.longName;
+ osisName = other.osisName;
+ prefAbbrev = other.prefAbbrev;
+ chapMax = other.chapMax;
+ init();
+ (*p) = *(other.p);
+}
+
+VerseMgr::Book& VerseMgr::Book::operator =(const Book &other) {
+ longName = other.longName;
+ osisName = other.osisName;
+ prefAbbrev = other.prefAbbrev;
+ chapMax = other.chapMax;
+ init();
+ (*p) = *(other.p);
+ return *this;
+}
+
+
+VerseMgr::Book::~Book() {
+ delete p;
+}
+
+
+int VerseMgr::Book::getVerseMax(int chapter) const {
+ chapter--;
+ return (p && (chapter < (signed int)p->verseMax.size()) && (chapter > -1)) ? p->verseMax[chapter] : -1;
+}
+
+
+int VerseMgr::System::getBookCount() const {
+ return (p ? p->books.size() : 0);
+}
+
+
+long VerseMgr::System::getOffsetFromVerse(int book, int chapter, int verse) const {
+ long offset = -1;
+ chapter--;
+
+ const Book *b = getBook(book);
+
+ if (!b) return -1; // assert we have a valid book
+ if ((chapter > -1) && (chapter >= (signed int)b->p->offsetPrecomputed.size())) return -1; // assert we have a valid chapter
+
+ offset = b->p->offsetPrecomputed[(chapter > -1)?chapter:0];
+ if (chapter < 0) offset--;
+
+/* old code
+ *
+ offset = offsets[testament-1][0][book];
+ offset = offsets[testament-1][1][(int)offset + chapter];
+ if (!(offset|verse)) // if we have a testament but nothing else.
+ offset = 1;
+
+*/
+
+ return (offset + verse);
+}
+
+
+char VerseMgr::System::getVerseFromOffset(long offset, int *book, int *chapter, int *verse) const {
+
+ if (offset < 1) { // just handle the module heading corner case up front (and error case)
+ (*book) = -1;
+ (*chapter) = 0;
+ (*verse) = 0;
+ return offset; // < 0 = error
+ }
+
+ // binary search for book
+ vector<Book>::iterator b = lower_bound(p->books.begin(), p->books.end(), offset, BookOffsetLess());
+ if (b == p->books.end()) b--;
+ (*book) = distance(p->books.begin(), b)+1;
+ if (offset < (*(b->p->offsetPrecomputed.begin()))-((((!(*book)) || (*book)==BMAX[0]+1))?2:1)) { // -1 for chapter headings
+ (*book)--;
+ if (b != p->books.begin()) {
+ b--;
+ }
+ }
+ vector<long>::iterator c = lower_bound(b->p->offsetPrecomputed.begin(), b->p->offsetPrecomputed.end(), offset);
+
+ // if we're a book heading, we are lessthan chapter precomputes, but greater book. This catches corner case.
+ if (c == b->p->offsetPrecomputed.end()) {
+ c--;
+ }
+ if ((offset < *c) && (c == b->p->offsetPrecomputed.begin())) {
+ (*chapter) = (offset - *c)+1; // should be 0 or -1 (for testament heading)
+ (*verse) = 0;
+ }
+ else {
+ if (offset < *c) c--;
+ (*chapter) = distance(b->p->offsetPrecomputed.begin(), c)+1;
+ (*verse) = (offset - *c);
+ }
+ return ((*chapter > 0) && (*verse > b->getVerseMax(*chapter))) ? KEYERR_OUTOFBOUNDS : 0;
+}
+
+
+/***************************************************
+ * VerseMgr
+ */
+
+class VerseMgr::Private {
+public:
+ Private() {
+ }
+ Private(const VerseMgr::Private &other) {
+ systems = other.systems;
+ }
+ VerseMgr::Private &operator =(const VerseMgr::Private &other) {
+ systems = other.systems;
+ return *this;
+ }
+ map<SWBuf, System> systems;
+};
+// ---------------- statics -----------------
+VerseMgr *VerseMgr::systemVerseMgr = 0;
+
+class __staticsystemVerseMgr {
+public:
+ __staticsystemVerseMgr() { }
+ ~__staticsystemVerseMgr() { delete VerseMgr::systemVerseMgr; }
+} _staticsystemVerseMgr;
+
+
+void VerseMgr::init() {
+ p = new Private();
+}
+
+
+VerseMgr::~VerseMgr() {
+ delete p;
+}
+
+
+void VerseMgr::setSystemVerseMgr(VerseMgr *newVerseMgr) {
+ if (systemVerseMgr)
+ delete systemVerseMgr;
+ systemVerseMgr = newVerseMgr;
+}
+
+
+const VerseMgr::System *VerseMgr::getVersificationSystem(const char *name) const {
+ map<SWBuf, System>::const_iterator it = p->systems.find(name);
+ return (it != p->systems.end()) ? &(it->second) : 0;
+}
+
+
+void VerseMgr::registerVersificationSystem(const char *name, const sbook *ot, const sbook *nt, int *chMax) {
+ p->systems[name] = name;
+ System &s = p->systems[name];
+ s.loadFromSBook(ot, nt, chMax);
+}
+
+
+void VerseMgr::registerVersificationSystem(const char *name, const TreeKey *tk) {
+}
+
+
+const StringList VerseMgr::getVersificationSystems() const {
+ StringList retVal;
+ for (map<SWBuf, System>::const_iterator it = p->systems.begin(); it != p->systems.end(); it++) {
+ retVal.push_back(it->first);
+ }
+ return retVal;
+}
+
+
+SWORD_NAMESPACE_END
diff --git a/src/modules/comments/hrefcom/hrefcom.cpp b/src/modules/comments/hrefcom/hrefcom.cpp
index 7791da2..7035b08 100644
--- a/src/modules/comments/hrefcom/hrefcom.cpp
+++ b/src/modules/comments/hrefcom/hrefcom.cpp
@@ -2,6 +2,22 @@
* hrefcom.cpp - code for class 'HREFCom'- a module that produces HTML HREFs
* pointing to actual text desired. Uses standard
* files: ot and nt using indexs ??.bks ??.cps ??.vss
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
@@ -56,14 +72,9 @@ SWBuf &HREFCom::getRawEntryBuf() {
unsigned short size;
VerseKey *key = 0;
- SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, this->key);
- }
- SWCATCH ( ... ) {}
- if (!key)
- key = new VerseKey(this->key);
+ key = &getVerseKey();
- findOffset(key->Testament(), key->Index(), &start, &size);
+ findOffset(key->Testament(), key->TestamentIndex(), &start, &size);
entrySize = size; // support getEntrySize call
SWBuf tmpbuf;
diff --git a/src/modules/comments/rawcom/rawcom.cpp b/src/modules/comments/rawcom/rawcom.cpp
index fd01c24..c0404ae 100644
--- a/src/modules/comments/rawcom/rawcom.cpp
+++ b/src/modules/comments/rawcom/rawcom.cpp
@@ -1,6 +1,22 @@
/******************************************************************************
* rawcom.cpp - code for class 'RawCom'- a module that reads raw commentary
* files: ot and nt using indexs ??.bks ??.cps ??.vss
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
@@ -23,9 +39,9 @@ SWORD_NAMESPACE_START
* idisp - Display object to use for displaying
*/
-RawCom::RawCom(const char *ipath, const char *iname, const char *idesc, SWDisplay *idisp, SWTextEncoding encoding, SWTextDirection dir, SWTextMarkup markup, const char* ilang)
+RawCom::RawCom(const char *ipath, const char *iname, const char *idesc, SWDisplay *idisp, SWTextEncoding encoding, SWTextDirection dir, SWTextMarkup markup, const char *ilang, const char *versification)
: RawVerse(ipath),
- SWCom(iname, idesc, idisp, encoding, dir, markup, ilang){
+ SWCom(iname, idesc, idisp, encoding, dir, markup, ilang, versification) {
}
@@ -53,7 +69,7 @@ SWBuf &RawCom::getRawEntryBuf() {
unsigned short size = 0;
VerseKey *key = &getVerseKey();
- findOffset(key->Testament(), key->Index(), &start, &size);
+ findOffset(key->Testament(), key->TestamentIndex(), &start, &size);
entrySize = size; // support getEntrySize call
entryBuf = "";
@@ -82,21 +98,21 @@ void RawCom::increment(int steps) {
unsigned short size;
VerseKey *tmpkey = &getVerseKey();
- findOffset(tmpkey->Testament(), tmpkey->Index(), &start, &size);
+ findOffset(tmpkey->Testament(), tmpkey->TestamentIndex(), &start, &size);
SWKey lastgood = *tmpkey;
while (steps) {
long laststart = start;
unsigned short lastsize = size;
SWKey lasttry = *tmpkey;
- (steps > 0) ? (*key)++ : (*key)--;
+ (steps > 0) ? ++(*key) : --(*key);
tmpkey = &getVerseKey();
if ((error = key->Error())) {
*key = lastgood;
break;
}
- long index = tmpkey->Index();
+ long index = tmpkey->TestamentIndex();
findOffset(tmpkey->Testament(), index, &start, &size);
if (
(((laststart != start) || (lastsize != size)) // we're a different entry
@@ -113,24 +129,15 @@ void RawCom::increment(int steps) {
void RawCom::setEntry(const char *inbuf, long len) {
VerseKey *key = &getVerseKey();
- doSetText(key->Testament(), key->Index(), inbuf, len);
+ doSetText(key->Testament(), key->TestamentIndex(), inbuf, len);
}
void RawCom::linkEntry(const SWKey *inkey) {
VerseKey *destkey = &getVerseKey();
- const VerseKey *srckey = 0;
-
- // see if we have a VerseKey * or decendant
- SWTRY {
- srckey = SWDYNAMIC_CAST(VerseKey, inkey);
- }
- SWCATCH ( ... ) {}
- // if we don't have a VerseKey * decendant, create our own
- if (!srckey)
- srckey = new VerseKey(inkey);
+ const VerseKey *srckey = &getVerseKey(inkey);
- doLinkEntry(destkey->Testament(), destkey->Index(), srckey->Index());
+ doLinkEntry(destkey->Testament(), destkey->TestamentIndex(), srckey->TestamentIndex());
if (inkey != srckey) // free our key if we created a VerseKey
delete srckey;
@@ -146,8 +153,29 @@ void RawCom::linkEntry(const SWKey *inkey) {
void RawCom::deleteEntry() {
VerseKey *key = &getVerseKey();
- doSetText(key->Testament(), key->Index(), "");
+ doSetText(key->Testament(), key->TestamentIndex(), "");
+}
+
+bool RawCom::isLinked(const SWKey *k1, const SWKey *k2) const {
+ long start1, start2;
+ unsigned short size1, size2;
+ VerseKey *vk1 = &getVerseKey(k1);
+ VerseKey *vk2 = &getVerseKey(k2);
+ if (vk1->Testament() != vk2->Testament()) return false;
+
+ findOffset(vk1->Testament(), vk1->TestamentIndex(), &start1, &size1);
+ findOffset(vk2->Testament(), vk2->TestamentIndex(), &start2, &size2);
+ if (!size1 || !size2) return false;
+ return start1 == start2;
}
+bool RawCom::hasEntry(const SWKey *k) const {
+ long start;
+ unsigned short size;
+ VerseKey *vk = &getVerseKey(k);
+
+ findOffset(vk->Testament(), vk->TestamentIndex(), &start, &size);
+ return size;
+}
SWORD_NAMESPACE_END
diff --git a/src/modules/comments/rawcom4/rawcom4.cpp b/src/modules/comments/rawcom4/rawcom4.cpp
index e59ee39..c0c4a1d 100644
--- a/src/modules/comments/rawcom4/rawcom4.cpp
+++ b/src/modules/comments/rawcom4/rawcom4.cpp
@@ -1,9 +1,24 @@
/******************************************************************************
* rawcom4.cpp - code for class 'RawCom4'- a module that reads raw commentary
* files: ot and nt using indexs ??.bks ??.cps ??.vss
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>
@@ -23,9 +38,9 @@ SWORD_NAMESPACE_START
* idisp - Display object to use for displaying
*/
-RawCom4::RawCom4(const char *ipath, const char *iname, const char *idesc, SWDisplay *idisp, SWTextEncoding encoding, SWTextDirection dir, SWTextMarkup markup, const char* ilang)
+RawCom4::RawCom4(const char *ipath, const char *iname, const char *idesc, SWDisplay *idisp, SWTextEncoding encoding, SWTextDirection dir, SWTextMarkup markup, const char *ilang, const char *versification)
: RawVerse4(ipath),
- SWCom(iname, idesc, idisp, encoding, dir, markup, ilang){
+ SWCom(iname, idesc, idisp, encoding, dir, markup, ilang, versification) {
}
@@ -53,7 +68,7 @@ SWBuf &RawCom4::getRawEntryBuf() {
unsigned long size = 0;
VerseKey *key = &getVerseKey();
- findOffset(key->Testament(), key->Index(), &start, &size);
+ findOffset(key->Testament(), key->TestamentIndex(), &start, &size);
entrySize = size; // support getEntrySize call
entryBuf = "";
@@ -82,21 +97,21 @@ void RawCom4::increment(int steps) {
unsigned long size;
VerseKey *tmpkey = &getVerseKey();
- findOffset(tmpkey->Testament(), tmpkey->Index(), &start, &size);
+ findOffset(tmpkey->Testament(), tmpkey->TestamentIndex(), &start, &size);
SWKey lastgood = *tmpkey;
while (steps) {
long laststart = start;
unsigned long lastsize = size;
SWKey lasttry = *tmpkey;
- (steps > 0) ? (*key)++ : (*key)--;
+ (steps > 0) ? ++(*key) : --(*key);
tmpkey = &getVerseKey();
if ((error = key->Error())) {
*key = lastgood;
break;
}
- long index = tmpkey->Index();
+ long index = tmpkey->TestamentIndex();
findOffset(tmpkey->Testament(), index, &start, &size);
if (
(((laststart != start) || (lastsize != size)) // we're a different entry
@@ -113,27 +128,14 @@ void RawCom4::increment(int steps) {
void RawCom4::setEntry(const char *inbuf, long len) {
VerseKey *key = &getVerseKey();
- doSetText(key->Testament(), key->Index(), inbuf, len);
+ doSetText(key->Testament(), key->TestamentIndex(), inbuf, len);
}
void RawCom4::linkEntry(const SWKey *inkey) {
VerseKey *destkey = &getVerseKey();
- const VerseKey *srckey = 0;
-
- // see if we have a VerseKey * or decendant
- SWTRY {
- srckey = SWDYNAMIC_CAST(VerseKey, inkey);
- }
- SWCATCH ( ... ) {}
- // if we don't have a VerseKey * decendant, create our own
- if (!srckey)
- srckey = new VerseKey(inkey);
-
- doLinkEntry(destkey->Testament(), destkey->Index(), srckey->Index());
-
- if (inkey != srckey) // free our key if we created a VerseKey
- delete srckey;
+ const VerseKey *srckey = &getVerseKey(inkey);
+ doLinkEntry(destkey->Testament(), destkey->TestamentIndex(), srckey->TestamentIndex());
}
@@ -146,8 +148,29 @@ void RawCom4::linkEntry(const SWKey *inkey) {
void RawCom4::deleteEntry() {
VerseKey *key = &getVerseKey();
- doSetText(key->Testament(), key->Index(), "");
+ doSetText(key->Testament(), key->TestamentIndex(), "");
+}
+
+bool RawCom4::isLinked(const SWKey *k1, const SWKey *k2) const {
+ long start1, start2;
+ unsigned long size1, size2;
+ VerseKey *vk1 = &getVerseKey(k1);
+ VerseKey *vk2 = &getVerseKey(k2);
+ if (vk1->Testament() != vk2->Testament()) return false;
+
+ findOffset(vk1->Testament(), vk1->TestamentIndex(), &start1, &size1);
+ findOffset(vk2->Testament(), vk2->TestamentIndex(), &start2, &size2);
+ if (!size1 || !size2) return false;
+ return start1 == start2;
}
+bool RawCom4::hasEntry(const SWKey *k) const {
+ long start;
+ unsigned long size;
+ VerseKey *vk = &getVerseKey(k);
+
+ findOffset(vk->Testament(), vk->TestamentIndex(), &start, &size);
+ return size;
+}
SWORD_NAMESPACE_END
diff --git a/src/modules/comments/rawfiles/rawfiles.cpp b/src/modules/comments/rawfiles/rawfiles.cpp
index 3b614d9..b0e24fc 100644
--- a/src/modules/comments/rawfiles/rawfiles.cpp
+++ b/src/modules/comments/rawfiles/rawfiles.cpp
@@ -2,9 +2,24 @@
* rawfiles.cpp - code for class 'RawFiles'- a module that produces HTML HREFs
* pointing to actual text desired. Uses standard
* files: ot and nt using indexs ??.bks ??.cps ??.vss
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>
@@ -13,6 +28,7 @@
#include <rawfiles.h>
#include <filemgr.h>
#include <versekey.h>
+#include <sysdata.h>
SWORD_NAMESPACE_START
@@ -57,16 +73,9 @@ SWBuf &RawFiles::getRawEntryBuf() {
FileDesc *datafile;
long start = 0;
unsigned short size = 0;
- VerseKey *key = 0;
-
- SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, this->key);
- }
- SWCATCH ( ... ) {}
- if (!key)
- key = new VerseKey(this->key);
+ VerseKey *key = &getVerseKey();
- findOffset(key->Testament(), key->Index(), &start, &size);
+ findOffset(key->Testament(), key->TestamentIndex(), &start, &size);
entryBuf = "";
if (size) {
@@ -88,10 +97,6 @@ SWBuf &RawFiles::getRawEntryBuf() {
}
FileMgr::getSystemFileMgr()->close(datafile);
}
-
- if (key != this->key)
- delete key;
-
return entryBuf;
}
@@ -105,17 +110,11 @@ void RawFiles::setEntry(const char *inbuf, long len) {
FileDesc *datafile;
long start;
unsigned short size;
- VerseKey *key = 0;
+ VerseKey *key = &getVerseKey();
len = (len<0)?strlen(inbuf):len;
- SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, this->key);
- }
- SWCATCH ( ... ) {}
- if (!key)
- key = new VerseKey(this->key);
- findOffset(key->Testament(), key->Index(), &start, &size);
+ findOffset(key->Testament(), key->TestamentIndex(), &start, &size);
if (size) {
SWBuf tmpbuf;
@@ -129,7 +128,7 @@ void RawFiles::setEntry(const char *inbuf, long len) {
entryBuf = path;
entryBuf += '/';
tmpbuf = getNextFilename();
- doSetText(key->Testament(), key->Index(), tmpbuf);
+ doSetText(key->Testament(), key->TestamentIndex(), tmpbuf);
entryBuf += tmpbuf;
}
datafile = FileMgr::getSystemFileMgr()->open(entryBuf, FileMgr::CREAT|FileMgr::WRONLY|FileMgr::TRUNC);
@@ -137,9 +136,6 @@ void RawFiles::setEntry(const char *inbuf, long len) {
datafile->write(inbuf, len);
}
FileMgr::getSystemFileMgr()->close(datafile);
-
- if (key != this->key)
- delete key;
}
@@ -154,36 +150,17 @@ void RawFiles::linkEntry(const SWKey *inkey) {
long start;
unsigned short size;
- const VerseKey *key = 0;
-
- SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, inkey);
- }
- SWCATCH ( ... ) {}
- if (!key)
- key = new VerseKey(this->key);
+ const VerseKey *key = &getVerseKey();
- findOffset(key->Testament(), key->Index(), &start, &size);
+ findOffset(key->Testament(), key->TestamentIndex(), &start, &size);
if (size) {
SWBuf tmpbuf;
readText(key->Testament(), start, size + 2, tmpbuf);
- if (key != inkey)
- delete key;
- key = 0;
-
- SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, inkey);
- }
- SWCATCH ( ... ) {}
- if (!key)
- key = new VerseKey(this->key);
- doSetText(key->Testament(), key->Index(), tmpbuf.c_str());
+ key = &getVerseKey(inkey);
+ doSetText(key->Testament(), key->TestamentIndex(), tmpbuf.c_str());
}
-
- if (key != inkey)
- delete key;
}
@@ -194,20 +171,8 @@ void RawFiles::linkEntry(const SWKey *inkey) {
*/
void RawFiles::deleteEntry() {
-
- VerseKey *key = 0;
-
- SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, this->key);
- }
- SWCATCH ( ... ) {}
- if (!key)
- key = new VerseKey(this->key);
-
- doSetText(key->Testament(), key->Index(), "");
-
- if (key != this->key)
- delete key;
+ VerseKey *key = &getVerseKey();
+ doSetText(key->Testament(), key->TestamentIndex(), "");
}
@@ -220,32 +185,40 @@ void RawFiles::deleteEntry() {
char *RawFiles::getNextFilename() {
static char incfile[255];
- long number;
+ __u32 number;
FileDesc *datafile;
sprintf(incfile, "%s/incfile", path);
datafile = FileMgr::getSystemFileMgr()->open(incfile, FileMgr::RDONLY);
- if (datafile->read(&number, 4) != 4)
- number = 0;
+
+ if (datafile->read(&number, 4) != 4) number = 0;
+ number = swordtoarch32(number);
+
number++;
FileMgr::getSystemFileMgr()->close(datafile);
datafile = FileMgr::getSystemFileMgr()->open(incfile, FileMgr::CREAT|FileMgr::WRONLY|FileMgr::TRUNC);
+ sprintf(incfile, "%.7d", number-1);
+
+ number = archtosword32(number);
datafile->write(&number, 4);
+
FileMgr::getSystemFileMgr()->close(datafile);
- sprintf(incfile, "%.7ld", number-1);
return incfile;
}
char RawFiles::createModule (const char *path) {
char *incfile = new char [ strlen (path) + 16 ];
- static long zero = 0;
+
+ __u32 zero = 0;
+ zero = archtosword32(zero);
+
FileDesc *datafile;
sprintf(incfile, "%s/incfile", path);
datafile = FileMgr::getSystemFileMgr()->open(incfile, FileMgr::CREAT|FileMgr::WRONLY|FileMgr::TRUNC);
- delete [] incfile;
+ delete [] incfile;
datafile->write(&zero, 4);
FileMgr::getSystemFileMgr()->close(datafile);
diff --git a/src/modules/comments/swcom.cpp b/src/modules/comments/swcom.cpp
index 94f92c9..e82751b 100644
--- a/src/modules/comments/swcom.cpp
+++ b/src/modules/comments/swcom.cpp
@@ -1,14 +1,34 @@
/******************************************************************************
* swcom.cpp - code for base class 'SWCom'- The basis for all commentary
* modules
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
+#include <utilstr.h>
#include <swcom.h>
#include <localemgr.h>
#include <versekey.h>
+
SWORD_NAMESPACE_START
+
/******************************************************************************
* SWCom Constructor - Initializes data for instance of SWCom
*
@@ -17,10 +37,14 @@ SWORD_NAMESPACE_START
* idisp - Display object to use for displaying
*/
-SWCom::SWCom(const char *imodname, const char *imoddesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang): SWModule(imodname, imoddesc, idisp, (char *)"Commentaries", enc, dir, mark, ilang) {
+SWCom::SWCom(const char *imodname, const char *imoddesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char *ilang, const char *versification): SWModule(imodname, imoddesc, idisp, "Commentaries", enc, dir, mark, ilang) {
+ this->versification = 0;
+ stdstr(&(this->versification), versification);
delete key;
- key = CreateKey();
- tmpVK = new VerseKey();
+ key = (VerseKey *)CreateKey();
+ tmpVK1 = (VerseKey *)CreateKey();
+ tmpVK2 = (VerseKey *)CreateKey();
+ tmpSecond = false;
}
@@ -29,62 +53,53 @@ SWCom::SWCom(const char *imodname, const char *imoddesc, SWDisplay *idisp, SWTex
*/
SWCom::~SWCom() {
- delete tmpVK;
+ delete tmpVK1;
+ delete tmpVK2;
+ delete [] versification;
}
-SWKey *SWCom::CreateKey() { return new VerseKey(); }
-
+SWKey *SWCom::CreateKey() const {
+ VerseKey *vk = new VerseKey();
-long SWCom::Index() const {
- VerseKey *key = 0;
- SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, this->key);
- }
- SWCATCH ( ... ) {}
- if (!key)
- key = new VerseKey(this->key);
+ vk->setVersificationSystem(versification);
- entryIndex = key->NewIndex();
+ return vk;
+}
- if (key != this->key)
- delete key;
+long SWCom::Index() const {
+ VerseKey *key = &getVerseKey();
+ entryIndex = key->Index();
return entryIndex;
}
long SWCom::Index(long iindex) {
- VerseKey *key = 0;
- SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, this->key);
- }
- SWCATCH ( ... ) {}
- if (!key)
- key = new VerseKey(this->key);
-
+ VerseKey *key = &getVerseKey();
key->Testament(1);
key->Index(iindex);
if (key != this->key) {
this->key->copyFrom(*key);
- delete key;
}
return Index();
}
-VerseKey &SWCom::getVerseKey() const {
- VerseKey *key = NULL;
+VerseKey &SWCom::getVerseKey(const SWKey *keyToConvert) const {
+ const SWKey *thisKey = keyToConvert ? keyToConvert : this->key;
+
+ VerseKey *key = 0;
// see if we have a VerseKey * or decendant
SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, this->key);
+ key = SWDYNAMIC_CAST(VerseKey, thisKey);
}
SWCATCH ( ... ) { }
if (!key) {
ListKey *lkTest = 0;
SWTRY {
- lkTest = SWDYNAMIC_CAST(ListKey, this->key);
+ lkTest = SWDYNAMIC_CAST(ListKey, thisKey);
}
SWCATCH ( ... ) { }
if (lkTest) {
@@ -95,11 +110,14 @@ VerseKey &SWCom::getVerseKey() const {
}
}
if (!key) {
- tmpVK->setLocale(LocaleMgr::getSystemLocaleMgr()->getDefaultLocaleName());
- (*tmpVK) = *(this->key);
- return (*tmpVK);
+ VerseKey *retKey = (tmpSecond) ? tmpVK1 : tmpVK2;
+ tmpSecond = !tmpSecond;
+ retKey->setLocale(LocaleMgr::getSystemLocaleMgr()->getDefaultLocaleName());
+ (*retKey) = *(thisKey);
+ return (*retKey);
}
else return *key;
}
+
SWORD_NAMESPACE_END
diff --git a/src/modules/comments/zcom/zcom.cpp b/src/modules/comments/zcom/zcom.cpp
index cdaea02..35b8946 100644
--- a/src/modules/comments/zcom/zcom.cpp
+++ b/src/modules/comments/zcom/zcom.cpp
@@ -1,9 +1,24 @@
/******************************************************************************
* rawcom.cpp - code for class 'zCom'- a module that reads raw commentary
* files: ot and nt using indexs ??.bks ??.cps ??.vss
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>
@@ -26,7 +41,7 @@ SWORD_NAMESPACE_START
* idisp - Display object to use for displaying
*/
-zCom::zCom(const char *ipath, const char *iname, const char *idesc, int iblockType, SWCompress *icomp, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang) : zVerse(ipath, -1, iblockType, icomp), SWCom(iname, idesc, idisp, enc, dir, mark, ilang)/*, SWCompress()*/
+zCom::zCom(const char *ipath, const char *iname, const char *idesc, int iblockType, SWCompress *icomp, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char *ilang, const char *versification) : zVerse(ipath, -1, iblockType, icomp), SWCom(iname, idesc, idisp, enc, dir, mark, ilang, versification)/*, SWCompress()*/
{
blockType = iblockType;
lastWriteKey = 0;
@@ -58,13 +73,14 @@ bool zCom::isWritable() {
SWBuf &zCom::getRawEntryBuf() {
long start = 0;
unsigned short size = 0;
+ unsigned long buffnum;
VerseKey *key = &getVerseKey();
- findOffset(key->Testament(), key->Index(), &start, &size);
+ findOffset(key->Testament(), key->TestamentIndex(), &start, &size, &buffnum);
entrySize = size; // support getEntrySize call
entryBuf = "";
- zReadText(key->Testament(), start, size, entryBuf);
+ zReadText(key->Testament(), start, size, buffnum, entryBuf);
rawFilter(entryBuf, key);
@@ -104,7 +120,7 @@ void zCom::setEntry(const char *inbuf, long len) {
delete lastWriteKey;
}
- doSetText(key->Testament(), key->Index(), inbuf, len);
+ doSetText(key->Testament(), key->TestamentIndex(), inbuf, len);
lastWriteKey = (VerseKey *)key->clone(); // must delete
}
@@ -112,19 +128,9 @@ void zCom::setEntry(const char *inbuf, long len) {
void zCom::linkEntry(const SWKey *inkey) {
VerseKey *destkey = &getVerseKey();
- const VerseKey *srckey = 0;
-
- // see if we have a VerseKey * or decendant
- SWTRY {
- srckey = (const VerseKey *) SWDYNAMIC_CAST(VerseKey, inkey);
- }
- SWCATCH ( ... ) {
- }
- // if we don't have a VerseKey * decendant, create our own
- if (!srckey)
- srckey = new VerseKey(inkey);
+ const VerseKey *srckey = &getVerseKey(inkey);
- doLinkEntry(destkey->Testament(), destkey->Index(), srckey->Index());
+ doLinkEntry(destkey->Testament(), destkey->TestamentIndex(), srckey->TestamentIndex());
if (inkey != srckey) // free our key if we created a VerseKey
delete srckey;
@@ -139,7 +145,7 @@ void zCom::linkEntry(const SWKey *inkey) {
void zCom::deleteEntry() {
VerseKey *key = &getVerseKey();
- doSetText(key->Testament(), key->Index(), "");
+ doSetText(key->Testament(), key->TestamentIndex(), "");
}
@@ -154,24 +160,25 @@ void zCom::deleteEntry() {
void zCom::increment(int steps) {
long start;
unsigned short size;
+ unsigned long buffnum;
VerseKey *tmpkey = &getVerseKey();
- findOffset(tmpkey->Testament(), tmpkey->Index(), &start, &size);
+ findOffset(tmpkey->Testament(), tmpkey->TestamentIndex(), &start, &size, &buffnum);
SWKey lastgood = *tmpkey;
while (steps) {
long laststart = start;
unsigned short lastsize = size;
SWKey lasttry = *tmpkey;
- (steps > 0) ? (*key)++ : (*key)--;
+ (steps > 0) ? ++(*key) : --(*key);
tmpkey = &getVerseKey();
if ((error = key->Error())) {
*key = lastgood;
break;
}
- long index = tmpkey->Index();
- findOffset(tmpkey->Testament(), index, &start, &size);
+ long index = tmpkey->TestamentIndex();
+ findOffset(tmpkey->Testament(), index, &start, &size, &buffnum);
if (
(((laststart != start) || (lastsize != size)) // we're a different entry
// && (start > 0)
@@ -184,5 +191,27 @@ void zCom::increment(int steps) {
error = (error) ? KEYERR_OUTOFBOUNDS : 0;
}
+bool zCom::isLinked(const SWKey *k1, const SWKey *k2) const {
+ long start1, start2;
+ unsigned short size1, size2;
+ unsigned long buffnum1, buffnum2;
+ VerseKey *vk1 = &getVerseKey(k1);
+ VerseKey *vk2 = &getVerseKey(k2);
+ if (vk1->Testament() != vk2->Testament()) return false;
+
+ findOffset(vk1->Testament(), vk1->TestamentIndex(), &start1, &size1, &buffnum1);
+ findOffset(vk2->Testament(), vk2->TestamentIndex(), &start2, &size2, &buffnum2);
+ return start1 == start2 && buffnum1 == buffnum2;
+}
+
+bool zCom::hasEntry(const SWKey *k) const {
+ long start;
+ unsigned short size;
+ unsigned long buffnum;
+ VerseKey *vk = &getVerseKey(k);
+
+ findOffset(vk->Testament(), vk->TestamentIndex(), &start, &size, &buffnum);
+ return size;
+}
SWORD_NAMESPACE_END
diff --git a/src/modules/common/entriesblk.cpp b/src/modules/common/entriesblk.cpp
index 216abd8..6e4c9aa 100644
--- a/src/modules/common/entriesblk.cpp
+++ b/src/modules/common/entriesblk.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
#include <entriesblk.h>
#include <stdlib.h>
#include <string.h>
diff --git a/src/modules/common/lzsscomprs.cpp b/src/modules/common/lzsscomprs.cpp
index bd8f768..00177db 100644
--- a/src/modules/common/lzsscomprs.cpp
+++ b/src/modules/common/lzsscomprs.cpp
@@ -1,6 +1,22 @@
/******************************************************************************
* lzsscomprs.cpp - code for class 'LZSSCompress'- a driver class that
* provides LZSS compression
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
#include <stdlib.h>
diff --git a/src/modules/common/rawstr.cpp b/src/modules/common/rawstr.cpp
index d2da1e9..6f17628 100644
--- a/src/modules/common/rawstr.cpp
+++ b/src/modules/common/rawstr.cpp
@@ -1,11 +1,26 @@
/******************************************************************************
* rawstr.cpp - code for class 'RawStr'- a module that reads raw text
- * files: ot and nt using indexs ??.bks ??.cps ??.vss
- * and provides lookup and parsing functions based on
- * class StrKey
+ * files: ot and nt using indexs ??.bks ??.cps ??.vss
+ * and provides lookup and parsing functions based on
+ * class StrKey
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
@@ -27,6 +42,8 @@ SWORD_NAMESPACE_START
int RawStr::instance = 0;
char RawStr::nl = '\n';
+const int RawStr::IDXENTRYSIZE = 6;
+
/******************************************************************************
@@ -88,7 +105,7 @@ RawStr::~RawStr()
* buf - address of pointer to allocate for storage of string
*/
-void RawStr::getIDXBufDat(long ioffset, char **buf)
+void RawStr::getIDXBufDat(long ioffset, char **buf) const
{
int size;
char ch;
@@ -122,9 +139,9 @@ void RawStr::getIDXBufDat(long ioffset, char **buf)
* buf - address of pointer to allocate for storage of string
*/
-void RawStr::getIDXBuf(long ioffset, char **buf)
+void RawStr::getIDXBuf(long ioffset, char **buf) const
{
- long offset;
+ __u32 offset;
if (idxfd > 0) {
idxfd->seek(ioffset, SEEK_SET);
@@ -149,17 +166,18 @@ void RawStr::getIDXBuf(long ioffset, char **buf)
* RET: error status -1 general error; -2 new file
*/
-signed char RawStr::findOffset(const char *ikey, long *start, unsigned short *size, long away, long *idxoff)
+signed char RawStr::findOffset(const char *ikey, __u32 *start, __u16 *size, long away, __u32 *idxoff) const
{
char *trybuf, *maxbuf, *key = 0, quitflag = 0;
signed char retval = -1;
long headoff, tailoff, tryoff = 0, maxoff = 0;
int diff = 0;
+ bool awayFromSubstrCheck = false;
if (idxfd->getFd() >=0) {
tailoff = maxoff = idxfd->seek(0, SEEK_END) - 6;
retval = (tailoff >= 0) ? 0 : -2; // if NOT new file
- if (*ikey) {
+ if (*ikey && retval != -2) {
headoff = 0;
stdstr(&key, ikey, 3);
@@ -203,6 +221,7 @@ signed char RawStr::findOffset(const char *ikey, long *start, unsigned short *si
if (headoff >= tailoff) {
tryoff = headoff;
if (!substr && ((tryoff != maxoff)||(strncmp(key, maxbuf, keylen)<0))) {
+ awayFromSubstrCheck = true;
away--; // if our entry doesn't startwith our key, prefer the previous entry over the next
}
}
@@ -216,17 +235,19 @@ signed char RawStr::findOffset(const char *ikey, long *start, unsigned short *si
idxfd->seek(tryoff, SEEK_SET);
- *start = *size = 0;
- idxfd->read(start, 4);
- idxfd->read(size, 2);
+ __u32 tmpStart;
+ __u16 tmpSize;
+ *start = *size = tmpStart = tmpSize = 0;
+ idxfd->read(&tmpStart, 4);
+ idxfd->read(&tmpSize, 2);
if (idxoff)
*idxoff = tryoff;
- *start = swordtoarch32(*start);
- *size = swordtoarch16(*size);
+ *start = swordtoarch32(tmpStart);
+ *size = swordtoarch16(tmpSize);
while (away) {
- long laststart = *start;
+ unsigned long laststart = *start;
unsigned short lastsize = *size;
long lasttry = tryoff;
tryoff += (away > 0) ? 6 : -6;
@@ -237,7 +258,8 @@ signed char RawStr::findOffset(const char *ikey, long *start, unsigned short *si
else if (idxfd->seek(tryoff, SEEK_SET) < 0)
bad = true;
if (bad) {
- retval = -1;
+ if(!awayFromSubstrCheck)
+ retval = -1;
*start = laststart;
*size = lastsize;
tryoff = lasttry;
@@ -245,15 +267,15 @@ signed char RawStr::findOffset(const char *ikey, long *start, unsigned short *si
*idxoff = tryoff;
break;
}
- idxfd->read(start, 4);
- idxfd->read(size, 2);
+ idxfd->read(&tmpStart, 4);
+ idxfd->read(&tmpSize, 2);
if (idxoff)
*idxoff = tryoff;
- *start = swordtoarch32(*start);
- *size = swordtoarch16(*size);
+ *start = swordtoarch32(tmpStart);
+ *size = swordtoarch16(tmpSize);
- if (((laststart != *start) || (lastsize != *size)) && (*start >= 0) && (*size))
+ if (((laststart != *start) || (lastsize != *size)) && (*size))
away += (away < 0) ? 1 : -1;
}
@@ -271,65 +293,6 @@ signed char RawStr::findOffset(const char *ikey, long *start, unsigned short *si
/******************************************************************************
- * RawStr::preptext - Prepares the text before returning it to external
- * objects
- *
- * ENT: buf - buffer where text is stored and where to store the prep'd
- * text.
- */
-
-void RawStr::prepText(SWBuf &buf) {
- unsigned int to, from;
- char space = 0, cr = 0, realdata = 0, nlcnt = 0;
- char *rawBuf = buf.getRawData();
- for (to = from = 0; rawBuf[from]; from++) {
- switch (rawBuf[from]) {
- case 10:
- if (!realdata)
- continue;
- space = (cr) ? 0 : 1;
- cr = 0;
- nlcnt++;
- if (nlcnt > 1) {
-// *to++ = nl;
- rawBuf[to++] = 10;
-// *to++ = nl[1];
-// nlcnt = 0;
- }
- continue;
- case 13:
- if (!realdata)
- continue;
-// *to++ = nl[0];
- rawBuf[to++] = 10;
- space = 0;
- cr = 1;
- continue;
- }
- realdata = 1;
- nlcnt = 0;
- if (space) {
- space = 0;
- if (rawBuf[from] != ' ') {
- rawBuf[to++] = ' ';
- from--;
- continue;
- }
- }
- rawBuf[to++] = rawBuf[from];
- }
- buf.setSize(to);
-
- while (to > 1) { // remove trailing excess
- to--;
- if ((rawBuf[to] == 10) || (rawBuf[to] == ' '))
- buf.setSize(to);
- else break;
- }
-}
-
-
-/******************************************************************************
* RawStr::readtext - gets text at a given offset
*
* ENT:
@@ -339,12 +302,12 @@ void RawStr::prepText(SWBuf &buf) {
*
*/
-void RawStr::readText(long istart, unsigned short *isize, char **idxbuf, SWBuf &buf)
+void RawStr::readText(__u32 istart, __u16 *isize, char **idxbuf, SWBuf &buf)
{
unsigned int ch;
char *idxbuflocal = 0;
getIDXBufDat(istart, &idxbuflocal);
- long start = istart;
+ __u32 start = istart;
do {
if (*idxbuf)
@@ -401,12 +364,12 @@ void RawStr::readText(long istart, unsigned short *isize, char **idxbuf, SWBuf &
void RawStr::doSetText(const char *ikey, const char *buf, long len)
{
- long start, outstart;
- long idxoff;
- long endoff;
- long shiftSize;
- unsigned short size;
- unsigned short outsize;
+ __u32 start, outstart;
+ __u32 idxoff;
+ __u32 endoff;
+ __s32 shiftSize;
+ __u16 size;
+ __u16 outsize;
static const char nl[] = {13, 10};
char *tmpbuf = 0;
char *key = 0;
@@ -526,7 +489,6 @@ void RawStr::doLinkEntry(const char *destkey, const char *srckey) {
delete [] text;
}
-
/******************************************************************************
* RawLD::CreateModule - Creates new module files
*
diff --git a/src/modules/common/rawstr4.cpp b/src/modules/common/rawstr4.cpp
index cbc8384..003b2fe 100644
--- a/src/modules/common/rawstr4.cpp
+++ b/src/modules/common/rawstr4.cpp
@@ -1,8 +1,24 @@
/******************************************************************************
* rawstr.cpp - code for class 'RawStr'- a module that reads raw text
- * files: ot and nt using indexs ??.bks ??.cps ??.vss
- * and provides lookup and parsing functions based on
- * class StrKey
+ * files: ot and nt using indexs ??.bks ??.cps ??.vss
+ * and provides lookup and parsing functions based on
+ * class StrKey
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
#include <stdio.h>
@@ -26,6 +42,7 @@ SWORD_NAMESPACE_START
*/
int RawStr4::instance = 0;
+const int RawStr4::IDXENTRYSIZE = 8;
/******************************************************************************
@@ -88,7 +105,8 @@ RawStr4::~RawStr4()
* buf - address of pointer to allocate for storage of string
*/
-void RawStr4::getIDXBufDat(long ioffset, char **buf) {
+void RawStr4::getIDXBufDat(long ioffset, char **buf) const
+{
int size;
char ch;
if (datfd > 0) {
@@ -121,14 +139,14 @@ void RawStr4::getIDXBufDat(long ioffset, char **buf) {
* buf - address of pointer to allocate for storage of string
*/
-void RawStr4::getIDXBuf(long ioffset, char **buf)
+void RawStr4::getIDXBuf(long ioffset, char **buf) const
{
- long offset;
+ __u32 offset;
if (idxfd > 0) {
idxfd->seek(ioffset, SEEK_SET);
- idxfd->read(&offset, 4);
+ idxfd->read(&offset, 4);
offset = swordtoarch32(offset);
getIDXBufDat(offset, buf);
@@ -157,17 +175,19 @@ void RawStr4::getIDXBuf(long ioffset, char **buf)
* RET: error status -1 general error; -2 new file
*/
-signed char RawStr4::findOffset(const char *ikey, long *start, unsigned long *size, long away, long *idxoff)
+signed char RawStr4::findOffset(const char *ikey, __u32 *start, __u32 *size, long away, __u32 *idxoff) const
{
char *trybuf, *maxbuf, *key = 0, quitflag = 0;
signed char retval = -1;
long headoff, tailoff, tryoff = 0, maxoff = 0;
int diff = 0;
+ bool awayFromSubstrCheck = false;
if (idxfd->getFd() >=0) {
tailoff = maxoff = idxfd->seek(0, SEEK_END) - 8;
+
retval = (tailoff >= 0) ? 0 : -2; // if NOT new file
- if (*ikey) {
+ if (*ikey && retval != -2) {
headoff = 0;
stdstr(&key, ikey, 3);
@@ -211,6 +231,7 @@ signed char RawStr4::findOffset(const char *ikey, long *start, unsigned long *si
if (headoff >= tailoff) {
tryoff = headoff;
if (!substr && ((tryoff != maxoff)||(strncmp(key, maxbuf, keylen)<0))) {
+ awayFromSubstrCheck = true;
away--; // if our entry doesn't startwith our key, prefer the previous entry over the next
}
}
@@ -224,17 +245,18 @@ signed char RawStr4::findOffset(const char *ikey, long *start, unsigned long *si
idxfd->seek(tryoff, SEEK_SET);
- *start = *size = 0;
- idxfd->read(start, 4);
- idxfd->read(size, 4);
+ __u32 tmpStart, tmpSize;
+ *start = *size = tmpStart = tmpSize = 0;
+ idxfd->read(&tmpStart, 4);
+ idxfd->read(&tmpSize, 4);
if (idxoff)
*idxoff = tryoff;
- *start = swordtoarch32(*start);
- *size = swordtoarch32(*size);
+ *start = swordtoarch32(tmpStart);
+ *size = swordtoarch32(tmpSize);
while (away) {
- long laststart = *start;
+ unsigned long laststart = *start;
unsigned long lastsize = *size;
long lasttry = tryoff;
tryoff += (away > 0) ? 8 : -8;
@@ -245,7 +267,8 @@ signed char RawStr4::findOffset(const char *ikey, long *start, unsigned long *si
else if (idxfd->seek(tryoff, SEEK_SET) < 0)
bad = true;
if (bad) {
- retval = -1;
+ if(!awayFromSubstrCheck)
+ retval = -1;
*start = laststart;
*size = lastsize;
tryoff = lasttry;
@@ -253,15 +276,15 @@ signed char RawStr4::findOffset(const char *ikey, long *start, unsigned long *si
*idxoff = tryoff;
break;
}
- idxfd->read(start, 4);
- idxfd->read(size, 4);
+ idxfd->read(&tmpStart, 4);
+ idxfd->read(&tmpSize, 4);
if (idxoff)
*idxoff = tryoff;
- *start = swordtoarch32(*start);
- *size = swordtoarch32(*size);
+ *start = swordtoarch32(tmpStart);
+ *size = swordtoarch32(tmpSize);
- if (((laststart != *start) || (lastsize != *size)) && (*start >= 0) && (*size))
+ if (((laststart != *start) || (lastsize != *size)) && (*size))
away += (away < 0) ? 1 : -1;
}
@@ -279,65 +302,6 @@ signed char RawStr4::findOffset(const char *ikey, long *start, unsigned long *si
/******************************************************************************
- * RawStr4::preptext - Prepares the text before returning it to external
- * objects
- *
- * ENT: buf - buffer where text is stored and where to store the prep'd
- * text.
- */
-
-void RawStr4::prepText(SWBuf &buf) {
- unsigned int to, from;
- char space = 0, cr = 0, realdata = 0, nlcnt = 0;
- char *rawBuf = buf.getRawData();
- for (to = from = 0; rawBuf[from]; from++) {
- switch (rawBuf[from]) {
- case 10:
- if (!realdata)
- continue;
- space = (cr) ? 0 : 1;
- cr = 0;
- nlcnt++;
- if (nlcnt > 1) {
-// *to++ = nl;
- rawBuf[to++] = 10;
-// *to++ = nl[1];
-// nlcnt = 0;
- }
- continue;
- case 13:
- if (!realdata)
- continue;
-// *to++ = nl[0];
- rawBuf[to++] = 10;
- space = 0;
- cr = 1;
- continue;
- }
- realdata = 1;
- nlcnt = 0;
- if (space) {
- space = 0;
- if (rawBuf[from] != ' ') {
- rawBuf[to++] = ' ';
- from--;
- continue;
- }
- }
- rawBuf[to++] = rawBuf[from];
- }
- buf.setSize(to);
-
- while (to > 1) { // remove trailing excess
- to--;
- if ((rawBuf[to] == 10) || (rawBuf[to] == ' '))
- buf.setSize(to);
- else break;
- }
-}
-
-
-/******************************************************************************
* RawStr4::readtext - gets text at a given offset
*
* ENT:
@@ -347,12 +311,12 @@ void RawStr4::prepText(SWBuf &buf) {
*
*/
-void RawStr4::readText(long istart, unsigned long *isize, char **idxbuf, SWBuf &buf)
+void RawStr4::readText(__u32 istart, __u32 *isize, char **idxbuf, SWBuf &buf)
{
unsigned int ch;
char *idxbuflocal = 0;
getIDXBufDat(istart, &idxbuflocal);
- long start = istart;
+ __u32 start = istart;
do {
if (*idxbuf)
@@ -408,12 +372,12 @@ void RawStr4::readText(long istart, unsigned long *isize, char **idxbuf, SWBuf &
void RawStr4::doSetText(const char *ikey, const char *buf, long len) {
- long start, outstart;
- long idxoff;
- long endoff;
- long shiftSize;
- unsigned long size;
- unsigned long outsize;
+ __u32 start, outstart;
+ __u32 idxoff;
+ __u32 endoff;
+ __s32 shiftSize;
+ __u32 size;
+ __u32 outsize;
static const char nl[] = {13, 10};
char *tmpbuf = 0;
char *key = 0;
diff --git a/src/modules/common/rawverse.cpp b/src/modules/common/rawverse.cpp
index 934082c..99beaa2 100644
--- a/src/modules/common/rawverse.cpp
+++ b/src/modules/common/rawverse.cpp
@@ -3,9 +3,26 @@
* files: ot and nt using indexs ??.bks ??.cps ??.vss
* and provides lookup and parsing functions based on
* class VerseKey
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>
@@ -96,18 +113,20 @@ RawVerse::~RawVerse()
* size - address to store the size of the entry
*/
-void RawVerse::findOffset(char testmt, long idxoff, long *start, unsigned short *size) {
+void RawVerse::findOffset(char testmt, long idxoff, long *start, unsigned short *size) const {
idxoff *= 6;
if (!testmt)
testmt = ((idxfp[1]) ? 1:2);
if (idxfp[testmt-1]->getFd() >= 0) {
idxfp[testmt-1]->seek(idxoff, SEEK_SET);
- idxfp[testmt-1]->read(start, 4);
- long len = idxfp[testmt-1]->read(size, 2); // read size
+ __s32 tmpStart;
+ __u16 tmpSize;
+ idxfp[testmt-1]->read(&tmpStart, 4);
+ long len = idxfp[testmt-1]->read(&tmpSize, 2); // read size
- *start = swordtoarch32(*start);
- *size = swordtoarch16(*size);
+ *start = swordtoarch32(tmpStart);
+ *size = swordtoarch16(tmpSize);
if (len < 2) {
*size = (unsigned short)((*start) ? (textfp[testmt-1]->seek(0, SEEK_END) - (long)*start) : 0); // if for some reason we get an error reading size, make size to end of file
@@ -121,65 +140,6 @@ void RawVerse::findOffset(char testmt, long idxoff, long *start, unsigned short
/******************************************************************************
- * RawVerse::preptext - Prepares the text before returning it to external
- * objects
- *
- * ENT: buf - buffer where text is stored and where to store the prep'd
- * text.
- */
-
-void RawVerse::prepText(SWBuf &buf) {
- unsigned int to, from;
- char space = 0, cr = 0, realdata = 0, nlcnt = 0;
- char *rawBuf = buf.getRawData();
- for (to = from = 0; rawBuf[from]; from++) {
- switch (rawBuf[from]) {
- case 10:
- if (!realdata)
- continue;
- space = (cr) ? 0 : 1;
- cr = 0;
- nlcnt++;
- if (nlcnt > 1) {
-// *to++ = nl;
- rawBuf[to++] = 10;
-// *to++ = nl[1];
-// nlcnt = 0;
- }
- continue;
- case 13:
- if (!realdata)
- continue;
-// *to++ = nl[0];
- rawBuf[to++] = 10;
- space = 0;
- cr = 1;
- continue;
- }
- realdata = 1;
- nlcnt = 0;
- if (space) {
- space = 0;
- if (rawBuf[from] != ' ') {
- rawBuf[to++] = ' ';
- from--;
- continue;
- }
- }
- rawBuf[to++] = rawBuf[from];
- }
- buf.setSize(to);
-
- while (to > 1) { // remove trailing excess
- to--;
- if ((rawBuf[to] == 10) || (rawBuf[to] == ' '))
- buf.setSize(to);
- else break;
- }
-}
-
-
-/******************************************************************************
* RawVerse::readtext - gets text at a given offset
*
* ENT: testmt - testament file to search in (0 - Old; 1 - New)
@@ -215,17 +175,16 @@ void RawVerse::readText(char testmt, long start, unsigned short size, SWBuf &buf
void RawVerse::doSetText(char testmt, long idxoff, const char *buf, long len)
{
- long start, outstart;
- unsigned short size;
- unsigned short outsize;
+ __s32 start;
+ __u16 size;
idxoff *= 6;
if (!testmt)
testmt = ((idxfp[1]) ? 1:2);
- size = outsize = (len < 0) ? strlen(buf) : len;
+ size = (len < 0) ? strlen(buf) : len;
- start = outstart = textfp[testmt-1]->seek(0, SEEK_END);
+ start = textfp[testmt-1]->seek(0, SEEK_END);
idxfp[testmt-1]->seek(idxoff, SEEK_SET);
if (size) {
@@ -239,13 +198,11 @@ void RawVerse::doSetText(char testmt, long idxoff, const char *buf, long len)
start = 0;
}
- outstart = archtosword32(start);
- outsize = archtosword16(size);
-
- idxfp[testmt-1]->write(&outstart, 4);
- idxfp[testmt-1]->write(&outsize, 2);
-
+ start = archtosword32(start);
+ size = archtosword16(size);
+ idxfp[testmt-1]->write(&start, 4);
+ idxfp[testmt-1]->write(&size, 2);
}
@@ -258,8 +215,8 @@ void RawVerse::doSetText(char testmt, long idxoff, const char *buf, long len)
*/
void RawVerse::doLinkEntry(char testmt, long destidxoff, long srcidxoff) {
- long start;
- unsigned short size;
+ __s32 start;
+ __u16 size;
destidxoff *= 6;
srcidxoff *= 6;
@@ -280,13 +237,13 @@ void RawVerse::doLinkEntry(char testmt, long destidxoff, long srcidxoff) {
/******************************************************************************
- * RawVerse::CreateModule - Creates new module files
+ * RawVerse::createModule - Creates new module files
*
* ENT: path - directory to store module files
* RET: error status
*/
-char RawVerse::createModule(const char *ipath)
+char RawVerse::createModule(const char *ipath, const char *v11n)
{
char *path = 0;
char *buf = new char [ strlen (ipath) + 20 ];
@@ -320,11 +277,16 @@ char RawVerse::createModule(const char *ipath)
fd2->getFd();
VerseKey vk;
+ vk.setVersificationSystem(v11n);
vk.Headings(1);
- long offset = 0;
- short size = 0;
+
+ __s32 offset = 0;
+ __u16 size = 0;
+ offset = archtosword32(offset);
+ size = archtosword16(size);
+
for (vk = TOP; !vk.Error(); vk++) {
- if (vk.Testament() == 1) {
+ if (vk.Testament() < 2) {
fd->write(&offset, 4);
fd->write(&size, 2);
}
@@ -333,16 +295,14 @@ char RawVerse::createModule(const char *ipath)
fd2->write(&size, 2);
}
}
+ fd2->write(&offset, 4);
+ fd2->write(&size, 2);
FileMgr::getSystemFileMgr()->close(fd);
FileMgr::getSystemFileMgr()->close(fd2);
delete [] path;
delete [] buf;
-/*
- RawVerse rv(path);
- VerseKey mykey("Rev 22:21");
-*/
return 0;
}
diff --git a/src/modules/common/rawverse4.cpp b/src/modules/common/rawverse4.cpp
index bd438ec..ee0b207 100644
--- a/src/modules/common/rawverse4.cpp
+++ b/src/modules/common/rawverse4.cpp
@@ -3,9 +3,26 @@
* files: ot and nt using indexs ??.bks ??.cps ??.vss
* and provides lookup and parsing functions based on
* class VerseKey
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>
@@ -96,18 +113,20 @@ RawVerse4::~RawVerse4()
* size - address to store the size of the entry
*/
-void RawVerse4::findOffset(char testmt, long idxoff, long *start, unsigned long *size) {
+void RawVerse4::findOffset(char testmt, long idxoff, long *start, unsigned long *size) const {
idxoff *= 8;
if (!testmt)
testmt = ((idxfp[1]) ? 1:2);
if (idxfp[testmt-1]->getFd() >= 0) {
idxfp[testmt-1]->seek(idxoff, SEEK_SET);
- idxfp[testmt-1]->read(start, 4);
- long len = idxfp[testmt-1]->read(size, 4); // read size
+ __u32 tmpStart;
+ __u32 tmpSize;
+ idxfp[testmt-1]->read(&tmpStart, 4);
+ long len = idxfp[testmt-1]->read(&tmpSize, 4); // read size
- *start = swordtoarch32(*start);
- *size = swordtoarch32(*size);
+ *start = swordtoarch32(tmpStart);
+ *size = swordtoarch32(tmpSize);
if (len < 2) {
*size = (unsigned long)((*start) ? (textfp[testmt-1]->seek(0, SEEK_END) - (long)*start) : 0); // if for some reason we get an error reading size, make size to end of file
@@ -121,65 +140,6 @@ void RawVerse4::findOffset(char testmt, long idxoff, long *start, unsigned long
/******************************************************************************
- * RawVerse4::preptext - Prepares the text before returning it to external
- * objects
- *
- * ENT: buf - buffer where text is stored and where to store the prep'd
- * text.
- */
-
-void RawVerse4::prepText(SWBuf &buf) {
- unsigned int to, from;
- char space = 0, cr = 0, realdata = 0, nlcnt = 0;
- char *rawBuf = buf.getRawData();
- for (to = from = 0; rawBuf[from]; from++) {
- switch (rawBuf[from]) {
- case 10:
- if (!realdata)
- continue;
- space = (cr) ? 0 : 1;
- cr = 0;
- nlcnt++;
- if (nlcnt > 1) {
-// *to++ = nl;
- rawBuf[to++] = 10;
-// *to++ = nl[1];
-// nlcnt = 0;
- }
- continue;
- case 13:
- if (!realdata)
- continue;
-// *to++ = nl[0];
- rawBuf[to++] = 10;
- space = 0;
- cr = 1;
- continue;
- }
- realdata = 1;
- nlcnt = 0;
- if (space) {
- space = 0;
- if (rawBuf[from] != ' ') {
- rawBuf[to++] = ' ';
- from--;
- continue;
- }
- }
- rawBuf[to++] = rawBuf[from];
- }
- buf.setSize(to);
-
- while (to > 1) { // remove trailing excess
- to--;
- if ((rawBuf[to] == 10) || (rawBuf[to] == ' '))
- buf.setSize(to);
- else break;
- }
-}
-
-
-/******************************************************************************
* RawVerse4::readtext - gets text at a given offset
*
* ENT: testmt - testament file to search in (0 - Old; 1 - New)
@@ -215,17 +175,16 @@ void RawVerse4::readText(char testmt, long start, unsigned long size, SWBuf &buf
void RawVerse4::doSetText(char testmt, long idxoff, const char *buf, long len)
{
- long start, outstart;
- unsigned long size;
- unsigned long outsize;
+ __u32 start;
+ __u32 size;
idxoff *= 8;
if (!testmt)
testmt = ((idxfp[1]) ? 1:2);
- size = outsize = (len < 0) ? strlen(buf) : len;
+ size = (len < 0) ? strlen(buf) : len;
- start = outstart = textfp[testmt-1]->seek(0, SEEK_END);
+ start = textfp[testmt-1]->seek(0, SEEK_END);
idxfp[testmt-1]->seek(idxoff, SEEK_SET);
if (size) {
@@ -239,13 +198,11 @@ void RawVerse4::doSetText(char testmt, long idxoff, const char *buf, long len)
start = 0;
}
- outstart = archtosword32(start);
- outsize = archtosword32(size);
-
- idxfp[testmt-1]->write(&outstart, 4);
- idxfp[testmt-1]->write(&outsize, 4);
-
+ start = archtosword32(start);
+ size = archtosword32(size);
+ idxfp[testmt-1]->write(&start, 4);
+ idxfp[testmt-1]->write(&size, 4);
}
@@ -258,8 +215,8 @@ void RawVerse4::doSetText(char testmt, long idxoff, const char *buf, long len)
*/
void RawVerse4::doLinkEntry(char testmt, long destidxoff, long srcidxoff) {
- long start;
- unsigned long size;
+ __u32 start;
+ __u32 size;
destidxoff *= 8;
srcidxoff *= 8;
@@ -286,7 +243,7 @@ void RawVerse4::doLinkEntry(char testmt, long destidxoff, long srcidxoff) {
* RET: error status
*/
-char RawVerse4::createModule(const char *ipath)
+char RawVerse4::createModule(const char *ipath, const char *v11n)
{
char *path = 0;
char *buf = new char [ strlen (ipath) + 20 ];
@@ -320,11 +277,15 @@ char RawVerse4::createModule(const char *ipath)
fd2->getFd();
VerseKey vk;
+ vk.setVersificationSystem(v11n);
vk.Headings(1);
- long offset = 0;
- long size = 0;
+ __u32 offset = 0;
+ __u32 size = 0;
+ offset = archtosword32(offset);
+ size = archtosword32(size);
+
for (vk = TOP; !vk.Error(); vk++) {
- if (vk.Testament() == 1) {
+ if (vk.Testament() < 2) {
fd->write(&offset, 4);
fd->write(&size, 4);
}
@@ -333,16 +294,14 @@ char RawVerse4::createModule(const char *ipath)
fd2->write(&size, 4);
}
}
+ fd2->write(&offset, 4);
+ fd2->write(&size, 4);
FileMgr::getSystemFileMgr()->close(fd);
FileMgr::getSystemFileMgr()->close(fd2);
delete [] path;
delete [] buf;
-/*
- RawVerse4 rv(path);
- VerseKey mykey("Rev 22:21");
-*/
return 0;
}
diff --git a/src/modules/common/swcipher.cpp b/src/modules/common/swcipher.cpp
index bd4d551..5ab91ea 100644
--- a/src/modules/common/swcipher.cpp
+++ b/src/modules/common/swcipher.cpp
@@ -1,8 +1,25 @@
/******************************************************************************
* swcipher.cpp - code for class 'SWCipher'- a driver class that provides
* cipher utilities.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <stdlib.h>
#include <string.h>
#include <swcipher.h>
diff --git a/src/modules/common/swcomprs.cpp b/src/modules/common/swcomprs.cpp
index 02d7d7b..378c8b1 100644
--- a/src/modules/common/swcomprs.cpp
+++ b/src/modules/common/swcomprs.cpp
@@ -1,8 +1,25 @@
/******************************************************************************
* swcomprs.cpp - code for class 'SWCompress'- a driver class that provides
* compression utilities.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <stdlib.h>
#include <string.h>
#include <swcomprs.h>
diff --git a/src/modules/common/zipcomprs.cpp b/src/modules/common/zipcomprs.cpp
index 21726bf..534d840 100644
--- a/src/modules/common/zipcomprs.cpp
+++ b/src/modules/common/zipcomprs.cpp
@@ -1,8 +1,25 @@
/******************************************************************************
* swcomprs.cpp - code for class 'ZipCompress'- a driver class that provides
* compression utilities. - using zlib
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
diff --git a/src/modules/common/zstr.cpp b/src/modules/common/zstr.cpp
index 2539ff0..5b4da64 100644
--- a/src/modules/common/zstr.cpp
+++ b/src/modules/common/zstr.cpp
@@ -2,8 +2,25 @@
* zstr.cpp - code for class 'zStr'- a module that reads compressed text
* files and provides lookup and parsing functions based on
* class StrKey
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
@@ -111,7 +128,8 @@ zStr::~zStr() {
* buf - address of pointer to allocate for storage of string
*/
-void zStr::getKeyFromDatOffset(long ioffset, char **buf) {
+void zStr::getKeyFromDatOffset(long ioffset, char **buf) const
+{
int size;
char ch;
if (datfd > 0) {
@@ -144,12 +162,13 @@ void zStr::getKeyFromDatOffset(long ioffset, char **buf) {
* buf - address of pointer to allocate for storage of string
*/
-void zStr::getKeyFromIdxOffset(long ioffset, char **buf) {
+void zStr::getKeyFromIdxOffset(long ioffset, char **buf) const
+{
__u32 offset;
if (idxfd > 0) {
idxfd->seek(ioffset, SEEK_SET);
- idxfd->read(&offset, sizeof(__u32));
+ idxfd->read(&offset, 4);
offset = swordtoarch32(offset);
getKeyFromDatOffset(offset, buf);
}
@@ -168,12 +187,14 @@ void zStr::getKeyFromIdxOffset(long ioffset, char **buf) {
* RET: error status
*/
-signed char zStr::findKeyIndex(const char *ikey, long *idxoff, long away) {
+signed char zStr::findKeyIndex(const char *ikey, long *idxoff, long away) const
+{
char *maxbuf = 0, *trybuf = 0, *key = 0, quitflag = 0;
signed char retval = 0;
__s32 headoff, tailoff, tryoff = 0, maxoff = 0;
__u32 start, size;
int diff = 0;
+ bool awayFromSubstrCheck = false;
if (idxfd->getFd() >= 0) {
tailoff = maxoff = idxfd->seek(0, SEEK_END) - IDXENTRYSIZE;
@@ -220,6 +241,7 @@ signed char zStr::findKeyIndex(const char *ikey, long *idxoff, long away) {
if (headoff >= tailoff) {
tryoff = headoff;
if (!substr && ((tryoff != maxoff)||(strncmp(key, maxbuf, keylen)<0))) {
+ awayFromSubstrCheck = true;
away--; // if our entry doesn't startwith our key, prefer the previous entry over the next
}
}
@@ -234,8 +256,8 @@ signed char zStr::findKeyIndex(const char *ikey, long *idxoff, long away) {
idxfd->seek(tryoff, SEEK_SET);
start = size = 0;
- retval = (idxfd->read(&start, sizeof(__u32))==sizeof(__u32)) ? retval : -1;
- retval = (idxfd->read(&size, sizeof(__u32))==sizeof(__u32)) ? retval : -1;
+ retval = (idxfd->read(&start, 4) == 4) ? retval : -1;
+ retval = (idxfd->read(&size, 4) == 4) ? retval : -1;
start = swordtoarch32(start);
size = swordtoarch32(size);
@@ -254,7 +276,8 @@ signed char zStr::findKeyIndex(const char *ikey, long *idxoff, long away) {
else if (idxfd->seek(tryoff, SEEK_SET) < 0)
bad = true;
if (bad) {
- retval = -1;
+ if(!awayFromSubstrCheck)
+ retval = -1;
start = laststart;
size = lastsize;
tryoff = lasttry;
@@ -262,8 +285,8 @@ signed char zStr::findKeyIndex(const char *ikey, long *idxoff, long away) {
*idxoff = tryoff;
break;
}
- idxfd->read(&start, sizeof(__u32));
- idxfd->read(&size, sizeof(__u32));
+ idxfd->read(&start, 4);
+ idxfd->read(&size, 4);
start = swordtoarch32(start);
size = swordtoarch32(size);
@@ -287,65 +310,6 @@ signed char zStr::findKeyIndex(const char *ikey, long *idxoff, long away) {
/******************************************************************************
- * zStr::preptext - Prepares the text before returning it to external
- * objects
- *
- * ENT: buf - buffer where text is stored and where to store the prep'd
- * text.
- */
-
-void zStr::prepText(SWBuf &buf) {
- unsigned int to, from;
- char space = 0, cr = 0, realdata = 0, nlcnt = 0;
- char *rawBuf = buf.getRawData();
- for (to = from = 0; rawBuf[from]; from++) {
- switch (rawBuf[from]) {
- case 10:
- if (!realdata)
- continue;
- space = (cr) ? 0 : 1;
- cr = 0;
- nlcnt++;
- if (nlcnt > 1) {
-// *to++ = nl;
- rawBuf[to++] = 10;
-// *to++ = nl[1];
-// nlcnt = 0;
- }
- continue;
- case 13:
- if (!realdata)
- continue;
-// *to++ = nl[0];
- rawBuf[to++] = 10;
- space = 0;
- cr = 1;
- continue;
- }
- realdata = 1;
- nlcnt = 0;
- if (space) {
- space = 0;
- if (rawBuf[from] != ' ') {
- rawBuf[to++] = ' ';
- from--;
- continue;
- }
- }
- rawBuf[to++] = rawBuf[from];
- }
- buf.setSize(to);
-
- while (to > 1) { // remove trailing excess
- to--;
- if ((rawBuf[to] == 10) || (rawBuf[to] == ' '))
- buf.setSize(to);
- else break;
- }
-}
-
-
-/******************************************************************************
* zStr::getText - gets text at a given offset
*
* ENT:
@@ -366,8 +330,8 @@ void zStr::getText(long offset, char **idxbuf, char **buf) {
do {
idxfd->seek(offset, SEEK_SET);
- idxfd->read(&start, sizeof(__u32));
- idxfd->read(&size, sizeof(__u32));
+ idxfd->read(&start, 4);
+ idxfd->read(&size, 4);
start = swordtoarch32(start);
size = swordtoarch32(size);
@@ -430,8 +394,8 @@ void zStr::getCompressedText(long block, long entry, char **buf) {
__u32 start = 0;
zdxfd->seek(block * ZDXENTRYSIZE, SEEK_SET);
- zdxfd->read(&start, sizeof(__u32));
- zdxfd->read(&size, sizeof(__u32));
+ zdxfd->read(&start, 4);
+ zdxfd->read(&size, 4);
start = swordtoarch32(start);
size = swordtoarch32(size);
@@ -496,8 +460,8 @@ void zStr::setText(const char *ikey, const char *buf, long len) {
else if ((!diff) && (len > 0 /*we're not deleting*/)) { // got absolute entry
do {
idxfd->seek(idxoff, SEEK_SET);
- idxfd->read(&start, sizeof(__u32));
- idxfd->read(&size, sizeof(__u32));
+ idxfd->read(&start, 4);
+ idxfd->read(&size, 4);
start = swordtoarch32(start);
size = swordtoarch32(size);
@@ -581,8 +545,8 @@ void zStr::setText(const char *ikey, const char *buf, long len) {
// add a new line to make data file easier to read in an editor
datfd->write(&nl, 2);
- idxfd->write(&outstart, sizeof(__u32));
- idxfd->write(&outsize, sizeof(__u32));
+ idxfd->write(&outstart, 4);
+ idxfd->write(&outsize, 4);
if (idxBytes) {
idxfd->write(idxBytes, shiftSize);
}
@@ -644,8 +608,8 @@ void zStr::flushCache() {
}
else {
zdxfd->seek(cacheBlockIndex * ZDXENTRYSIZE, SEEK_SET);
- zdxfd->read(&start, sizeof(__u32));
- zdxfd->read(&outsize, sizeof(__u32));
+ zdxfd->read(&start, 4);
+ zdxfd->read(&outsize, 4);
start = swordtoarch32(start);
outsize = swordtoarch32(outsize);
if (start + outsize >= zdtSize) { // last entry, just overwrite
@@ -671,8 +635,8 @@ void zStr::flushCache() {
// add a new line to make data file easier to read in an editor
zdtfd->write(&nl, 2);
- zdxfd->write(&outstart, sizeof(__u32));
- zdxfd->write(&outsize, sizeof(__u32));
+ zdxfd->write(&outstart, 4);
+ zdxfd->write(&outsize, 4);
}
delete cacheBlock;
cacheBlock = 0;
diff --git a/src/modules/common/zverse.cpp b/src/modules/common/zverse.cpp
index 3f91918..fa76467 100644
--- a/src/modules/common/zverse.cpp
+++ b/src/modules/common/zverse.cpp
@@ -1,11 +1,28 @@
/******************************************************************************
* zverse.h - code for class 'zVerse'- a module that reads raw text
- * files: ot and nt using indexs ??.bks ??.cps ??.vss
- * and provides lookup and parsing functions based on
- * class VerseKey for compressed modules
+ * files: ot and nt using indexs ??.bks ??.cps ??.vss
+ * and provides lookup and parsing functions based on
+ * class VerseKey for compressed modules
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>
@@ -129,19 +146,15 @@ zVerse::~zVerse()
* size - address to store the size of the entry
*/
-void zVerse::findOffset(char testmt, long idxoff, long *start, unsigned short *size)
+void zVerse::findOffset(char testmt, long idxoff, long *start, unsigned short *size, unsigned long *buffnum) const
{
+ __u32 ulBuffNum = 0; // buffer number
+ __u32 ulVerseStart = 0; // verse offset within buffer
+ __u16 usVerseSize = 0; // verse size
// set start to offset in
// set size to
// set
- unsigned long ulBuffNum=0; // buffer number
- unsigned long ulVerseStart=0; // verse offset within buffer
- unsigned short usVerseSize=0; // verse size
- unsigned long ulCompOffset=0; // compressed buffer start
- unsigned long ulCompSize=0; // buffer size compressed
- unsigned long ulUnCompSize=0; // buffer size uncompressed
-
- *start = *size = 0;
+ *start = *size = *buffnum = 0;
//printf ("Finding offset %ld\n", idxoff);
idxoff *= 10;
if (!testmt) {
@@ -159,10 +172,8 @@ void zVerse::findOffset(char testmt, long idxoff, long *start, unsigned short *s
return;
}
}
- else return;
-
- ulBuffNum = swordtoarch32(ulBuffNum);
-
+ else return;
+
if (compfp[testmt-1]->read(&ulVerseStart, 4) < 2)
{
printf ("Error reading ulVerseStart\n");
@@ -174,17 +185,39 @@ void zVerse::findOffset(char testmt, long idxoff, long *start, unsigned short *s
return;
}
+ *buffnum = swordtoarch32(ulBuffNum);
*start = swordtoarch32(ulVerseStart);
*size = swordtoarch16(usVerseSize);
- if (*size) {
- if (((long) ulBuffNum == cacheBufIdx) && (testmt == cacheTestament) && (cacheBuf)) {
- // have the text buffered
- return;
- }
+}
- //printf ("Got buffer number{%ld} versestart{%ld} versesize{%d}\n", ulBuffNum, ulVerseStart, usVerseSize);
+/******************************************************************************
+ * zVerse::zreadtext - gets text at a given offset
+ *
+ * ENT: testmt - testament file to search in (0 - Old; 1 - New)
+ * start - starting offset where the text is located in the file
+ * size - size of text entry + 1 (null)
+ * buf - buffer to store text
+ *
+ */
+
+void zVerse::zReadText(char testmt, long start, unsigned short size, unsigned long ulBuffNum, SWBuf &inBuf) {
+ __u32 ulCompOffset = 0; // compressed buffer start
+ __u32 ulCompSize = 0; // buffer size compressed
+ __u32 ulUnCompSize = 0; // buffer size uncompressed
+
+ if (!testmt) {
+ testmt = ((idxfp[0]) ? 1:2);
+ }
+
+ // assert we have and valid file descriptor
+ if (compfp[testmt-1]->getFd() < 1)
+ return;
+
+ if (size &&
+ !(((long) ulBuffNum == cacheBufIdx) && (testmt == cacheTestament) && (cacheBuf))) {
+ //printf ("Got buffer number{%ld} versestart{%ld} versesize{%d}\n", ulBuffNum, ulVerseStart, usVerseSize);
if (idxfp[testmt-1]->seek(ulBuffNum*12, SEEK_SET)!=(long) ulBuffNum*12)
{
@@ -226,7 +259,8 @@ void zVerse::findOffset(char testmt, long idxoff, long *start, unsigned short *s
pcCompText.setSize(ulCompSize);
rawZFilter(pcCompText, 0); // 0 = decipher
- compressor->zBuf(&ulCompSize, pcCompText.getRawData());
+ unsigned long bufSize = ulCompSize;
+ compressor->zBuf(&bufSize, pcCompText.getRawData());
if (cacheBuf) {
flushCache();
@@ -237,26 +271,13 @@ void zVerse::findOffset(char testmt, long idxoff, long *start, unsigned short *s
compressor->Buf(0, &len);
cacheBuf = (char *)calloc(len + 1, 1);
memcpy(cacheBuf, compressor->Buf(), len);
-
+ cacheBufSize = strlen(cacheBuf); // TODO: can we just use len?
cacheTestament = testmt;
cacheBufIdx = ulBuffNum;
- }
-}
-
-
-/******************************************************************************
- * zVerse::zreadtext - gets text at a given offset
- *
- * ENT: testmt - testament file to search in (0 - Old; 1 - New)
- * start - starting offset where the text is located in the file
- * size - size of text entry + 1 (null)
- * buf - buffer to store text
- *
- */
-
-void zVerse::zReadText(char testmt, long start, unsigned short size, SWBuf &inBuf) {
+ }
+
inBuf = "";
- if ( (size > 0) && cacheBuf && ((unsigned)start < strlen(cacheBuf)) ){ //TODO: optimize this, remove strlen
+ if ((size > 0) && cacheBuf && ((unsigned)start < cacheBufSize)) {
inBuf.setFillByte(0);
inBuf.setSize(size+1);
strncpy(inBuf.getRawData(), &(cacheBuf[start]), size);
@@ -290,13 +311,12 @@ void zVerse::doSetText(char testmt, long idxoff, const char *buf, long len) {
dirtyCache = true;
- unsigned long start, outstart;
- unsigned long outBufIdx = cacheBufIdx;
- unsigned short size;
- unsigned short outsize;
+ __u32 start;
+ __u16 size;
+ __u32 outBufIdx = cacheBufIdx;
idxoff *= 10;
- size = outsize = len;
+ size = len;
start = strlen(cacheBuf);
@@ -304,23 +324,23 @@ void zVerse::doSetText(char testmt, long idxoff, const char *buf, long len) {
start = outBufIdx = 0;
outBufIdx = archtosword32(outBufIdx);
- outstart = archtosword32(start);
- outsize = archtosword16(size);
+ start = archtosword32(start);
+ size = archtosword16(size);
compfp[testmt-1]->seek(idxoff, SEEK_SET);
compfp[testmt-1]->write(&outBufIdx, 4);
- compfp[testmt-1]->write(&outstart, 4);
- compfp[testmt-1]->write(&outsize, 2);
+ compfp[testmt-1]->write(&start, 4);
+ compfp[testmt-1]->write(&size, 2);
strcat(cacheBuf, buf);
}
void zVerse::flushCache() {
if (dirtyCache) {
- unsigned long idxoff;
- unsigned long start, outstart;
- unsigned long size, outsize;
- unsigned long zsize, outzsize;
+ __u32 idxoff;
+ __u32 start, outstart;
+ __u32 size, outsize;
+ __u32 zsize, outzsize;
idxoff = cacheBufIdx * 12;
if (cacheBuf) {
@@ -331,12 +351,14 @@ void zVerse::flushCache() {
// compressor = new LZSSCompress();
// }
compressor->Buf(cacheBuf);
- compressor->zBuf(&zsize);
- outzsize = zsize;
+ unsigned long tmpSize;
+ compressor->zBuf(&tmpSize);
+ outzsize = zsize = tmpSize;
SWBuf buf;
buf.setSize(zsize + 5);
- memcpy(buf.getRawData(), compressor->zBuf(&zsize), zsize);
+ memcpy(buf.getRawData(), compressor->zBuf(&tmpSize), tmpSize);
+ outzsize = zsize = tmpSize;
buf.setSize(zsize);
rawZFilter(buf, 1); // 1 = encipher
@@ -369,9 +391,9 @@ void zVerse::flushCache() {
*/
void zVerse::doLinkEntry(char testmt, long destidxoff, long srcidxoff) {
- long bufidx;
- long start;
- unsigned short size;
+ __s32 bufidx;
+ __s32 start;
+ __u16 size;
destidxoff *= 10;
srcidxoff *= 10;
@@ -400,7 +422,7 @@ void zVerse::doLinkEntry(char testmt, long destidxoff, long srcidxoff) {
* RET: error status
*/
-char zVerse::createModule(const char *ipath, int blockBound)
+char zVerse::createModule(const char *ipath, int blockBound, const char *v11n)
{
char *path = 0;
char *buf = new char [ strlen (ipath) + 20 ];
@@ -446,11 +468,16 @@ char zVerse::createModule(const char *ipath, int blockBound)
fd2->getFd();
VerseKey vk;
+ vk.setVersificationSystem(v11n);
vk.Headings(1);
- long offset = 0;
- short size = 0;
+
+ __s32 offset = 0;
+ __s16 size = 0;
+ offset = archtosword32(offset);
+ size = archtosword16(size);
+
for (vk = TOP; !vk.Error(); vk++) {
- if (vk.Testament() == 1) {
+ if (vk.Testament() < 2) {
fd->write(&offset, 4); //compBufIdxOffset
fd->write(&offset, 4);
fd->write(&size, 2);
@@ -461,78 +488,18 @@ char zVerse::createModule(const char *ipath, int blockBound)
fd2->write(&size, 2);
}
}
+ fd2->write(&offset, 4); //compBufIdxOffset
+ fd2->write(&offset, 4);
+ fd2->write(&size, 2);
FileMgr::getSystemFileMgr()->close(fd);
FileMgr::getSystemFileMgr()->close(fd2);
delete [] path;
delete [] buf;
-/*
- RawVerse rv(path);
- VerseKey mykey("Rev 22:21");
-*/
return 0;
}
-/******************************************************************************
- * zVerse::preptext - Prepares the text before returning it to external
- * objects
- *
- * ENT: buf - buffer where text is stored and where to store the prep'd
- * text.
- */
-
-void zVerse::prepText(SWBuf &buf) {
- unsigned int to, from;
- char space = 0, cr = 0, realdata = 0, nlcnt = 0;
- char *rawBuf = buf.getRawData();
- for (to = from = 0; rawBuf[from]; from++) {
- switch (rawBuf[from]) {
- case 10:
- if (!realdata)
- continue;
- space = (cr) ? 0 : 1;
- cr = 0;
- nlcnt++;
- if (nlcnt > 1) {
-// *to++ = nl;
- rawBuf[to++] = 10;
-// *to++ = nl[1];
-// nlcnt = 0;
- }
- continue;
- case 13:
- if (!realdata)
- continue;
-// *to++ = nl[0];
- rawBuf[to++] = 10;
- space = 0;
- cr = 1;
- continue;
- }
- realdata = 1;
- nlcnt = 0;
- if (space) {
- space = 0;
- if (rawBuf[from] != ' ') {
- rawBuf[to++] = ' ';
- from--;
- continue;
- }
- }
- rawBuf[to++] = rawBuf[from];
- }
- buf.setSize(to);
-
- while (to > 1) { // remove trailing excess
- to--;
- if ((rawBuf[to] == 10) || (rawBuf[to] == ' '))
- buf.setSize(to);
- else break;
- }
-}
-
-
SWORD_NAMESPACE_END
diff --git a/src/modules/filters/Makefile.am b/src/modules/filters/Makefile.am
index 7092c73..f212cbf 100644
--- a/src/modules/filters/Makefile.am
+++ b/src/modules/filters/Makefile.am
@@ -53,17 +53,18 @@ OSISFIL += $(filtersdir)/osisscripref.cpp
OSISFIL += $(filtersdir)/osisvariants.cpp
OSISFIL += $(filtersdir)/osiswordjs.cpp
OSISFIL += $(filtersdir)/osismorphsegmentation.cpp
+OSISFIL += $(filtersdir)/osisruby.cpp
libsword_la_SOURCES += $(filtersdir)/latin1utf8.cpp
libsword_la_SOURCES += $(filtersdir)/latin1utf16.cpp
libsword_la_SOURCES += $(filtersdir)/utf8utf16.cpp
libsword_la_SOURCES += $(filtersdir)/utf16utf8.cpp
-libsword_la_SOURCES += $(filtersdir)/scsuutf8.cpp
libsword_la_SOURCES += $(filtersdir)/utf8html.cpp
libsword_la_SOURCES += $(filtersdir)/utf8latin1.cpp
libsword_la_SOURCES += $(filtersdir)/utf8cantillation.cpp
libsword_la_SOURCES += $(filtersdir)/utf8hebrewpoints.cpp
+libsword_la_SOURCES += $(filtersdir)/utf8arabicpoints.cpp
libsword_la_SOURCES += $(filtersdir)/utf8greekaccents.cpp
libsword_la_SOURCES += $(filtersdir)/cipherfil.cpp
diff --git a/src/modules/filters/cipherfil.cpp b/src/modules/filters/cipherfil.cpp
index 24c665e..34d0465 100644
--- a/src/modules/filters/cipherfil.cpp
+++ b/src/modules/filters/cipherfil.cpp
@@ -1,6 +1,21 @@
/******************************************************************************
*
* cipherfil - SWFilter descendant to decipher a module
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
diff --git a/src/modules/filters/gbffootnotes.cpp b/src/modules/filters/gbffootnotes.cpp
index bef29b8..a5384cb 100644
--- a/src/modules/filters/gbffootnotes.cpp
+++ b/src/modules/filters/gbffootnotes.cpp
@@ -2,6 +2,21 @@
*
* gbffootnotes - SWFilter descendant to hide or show footnotes
* in a GBF module.
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
@@ -33,7 +48,7 @@ GBFFootnotes::~GBFFootnotes() {
char GBFFootnotes::processText (SWBuf &text, const SWKey *key, const SWModule *module)
{
-
+
SWBuf token;
bool intoken = false;
bool hide = false;
@@ -42,11 +57,10 @@ char GBFFootnotes::processText (SWBuf &text, const SWKey *key, const SWModule *m
SWBuf refs = "";
int footnoteNum = 1;
char buf[254];
- VerseKey parser = key->getText();
SWBuf orig = text;
const char *from = orig.c_str();
-
+
//XMLTag tag;
for (text = ""; *from; from++) {
@@ -61,7 +75,7 @@ char GBFFootnotes::processText (SWBuf &text, const SWKey *key, const SWModule *m
//XMLTag tag(token);
if (!strncmp(token, "RF",2)) {
// tag = token;
-
+
refs = "";
startTag = token;
hide = true;
@@ -71,7 +85,7 @@ char GBFFootnotes::processText (SWBuf &text, const SWKey *key, const SWModule *m
else if (!strncmp(token, "Rf",2)) {
if (module->isProcessEntryAttributes()) {
//tag = token;
-
+
if((tagText.length() == 1) || !strcmp(module->Name(), "IGNT")) {
if (option) { // for ASV marks text in verse then put explanation at end of verse
text.append(" <FS>[");
@@ -93,7 +107,7 @@ char GBFFootnotes::processText (SWBuf &text, const SWKey *key, const SWModule *m
startTag.setAttribute("swordFootnote", buf);
}
hide = false;
- if (option) {
+ if (option) {
text.append(startTag);
text.append(tagText);
}
@@ -120,7 +134,7 @@ char GBFFootnotes::processText (SWBuf &text, const SWKey *key, const SWModule *m
else tagText.append(*from);
}
return 0;
-
+
/*
if (!option) { // if we don't want footnotes
char token[4096]; // cheese. Fix.
diff --git a/src/modules/filters/gbfheadings.cpp b/src/modules/filters/gbfheadings.cpp
index 81a4d94..122445e 100644
--- a/src/modules/filters/gbfheadings.cpp
+++ b/src/modules/filters/gbfheadings.cpp
@@ -2,9 +2,23 @@
*
* gbfheadings - SWFilter descendant to hide or show headings
* in a GBF module.
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <gbfheadings.h>
diff --git a/src/modules/filters/gbfhtml.cpp b/src/modules/filters/gbfhtml.cpp
index a9d8434..2467e36 100644
--- a/src/modules/filters/gbfhtml.cpp
+++ b/src/modules/filters/gbfhtml.cpp
@@ -1,18 +1,24 @@
/***************************************************************************
- gbfhtml.cpp - GBF to HTML filter
- -------------------
- begin : 2001-09-03
- copyright : 2001 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * gbfhtml.cpp - GBF to HTML filter
+ * -------------------
+ * begin : 2001-09-03
+ * copyright : 2001 by CrossWire Bible Society
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <gbfhtml.h>
diff --git a/src/modules/filters/gbfhtmlhref.cpp b/src/modules/filters/gbfhtmlhref.cpp
index 7f1c254..b4cdde0 100644
--- a/src/modules/filters/gbfhtmlhref.cpp
+++ b/src/modules/filters/gbfhtmlhref.cpp
@@ -1,20 +1,27 @@
/***************************************************************************
- gbfhtmlhref.cpp - GBF to HTML filter with hrefs
- for strongs and morph tags
- -------------------
- begin : 2001-09-03
- copyright : 2001 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * gbfhtmlhref.cpp - GBF to HTML filter with hrefs
+ * for strongs and morph tags
+ * -------------------
+ * begin : 2001-09-03
+ * copyright : 2001 by CrossWire Bible Society
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
#include <stdlib.h>
#include <gbfhtmlhref.h>
#include <swmodule.h>
diff --git a/src/modules/filters/gbfmorph.cpp b/src/modules/filters/gbfmorph.cpp
index 5226db7..d7c8ab4 100644
--- a/src/modules/filters/gbfmorph.cpp
+++ b/src/modules/filters/gbfmorph.cpp
@@ -2,9 +2,24 @@
*
* gbfmorph - SWFilter descendant to hide or show morph tags
* in a GBF module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <gbfmorph.h>
diff --git a/src/modules/filters/gbfosis.cpp b/src/modules/filters/gbfosis.cpp
index 00443f9..526167a 100644
--- a/src/modules/filters/gbfosis.cpp
+++ b/src/modules/filters/gbfosis.cpp
@@ -2,9 +2,24 @@
*
* gbfstrongs - SWFilter descendant to hide or show strongs number
* in a GBF module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
@@ -317,10 +332,10 @@ char GBFOSIS::processText(SWBuf &text, const SWKey *key, const SWModule *module)
newWord = false;
//fix this if required?
- //memset(to, 0, 10);
-
+ //memset(to, 0, 10);
+
}
-
+
if (!suspendTextPassThru) {
text += (*from);
lastspace = (*from == ' ');
@@ -335,29 +350,29 @@ char GBFOSIS::processText(SWBuf &text, const SWKey *key, const SWModule *module)
if (vkey->Verse()) {
ref.appendFormatted("\t\t<verse osisID=\"%s\">", vkey->getOSISRef());
}
-
+
if (ref.length() > 0) {
-
+
text = ref + text;
-
+
if (vkey->Verse()) {
- VerseKey tmp;
- tmp = *vkey;
- tmp.AutoNormalize(0);
- tmp.Headings(1);
-
+ VerseKey *tmp = (VerseKey *)vkey->clone();
+ *tmp = *vkey;
+ tmp->AutoNormalize(0);
+ tmp->Headings(1);
+
text += "</verse>";
-
- tmp = MAXVERSE;
- if (*vkey == tmp) {
- tmp.Verse(0);
+
+ *tmp = MAXVERSE;
+ if (*vkey == *tmp) {
+ tmp->Verse(0);
// sprintf(ref, "\t</div>");
// pushString(&to, ref);
- tmp = MAXCHAPTER;
- tmp = MAXVERSE;
- if (*vkey == tmp) {
- tmp.Chapter(0);
- tmp.Verse(0);
+ *tmp = MAXCHAPTER;
+ *tmp = MAXVERSE;
+ if (*vkey == *tmp) {
+ tmp->Chapter(0);
+ tmp->Verse(0);
// sprintf(ref, "\t</div>");
// pushString(&to, ref);
/*
@@ -368,6 +383,7 @@ char GBFOSIS::processText(SWBuf &text, const SWKey *key, const SWModule *module)
*/
}
}
+ delete tmp;
}
// else if (vkey->Chapter()) {
// sprintf(ref, "\t<div type=\"chapter\" osisID=\"%s\">", vkey->getOSISRef());
diff --git a/src/modules/filters/gbfplain.cpp b/src/modules/filters/gbfplain.cpp
index 5657e20..e90bf94 100644
--- a/src/modules/filters/gbfplain.cpp
+++ b/src/modules/filters/gbfplain.cpp
@@ -2,9 +2,24 @@
*
* gbfplain - SWFilter descendant to strip out all GBF tags or convert to
* ASCII rendered symbols.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <gbfplain.h>
#include <swbuf.h>
diff --git a/src/modules/filters/gbfredletterwords.cpp b/src/modules/filters/gbfredletterwords.cpp
index a79802d..7397781 100644
--- a/src/modules/filters/gbfredletterwords.cpp
+++ b/src/modules/filters/gbfredletterwords.cpp
@@ -2,9 +2,24 @@
*
* GBFRedLetterWords - SWFilter descendant to toggle red coloring of words of
* Christ in a GBF module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <gbfredletterwords.h>
#include <swmodule.h>
diff --git a/src/modules/filters/gbfrtf.cpp b/src/modules/filters/gbfrtf.cpp
index eb39612..7471d0b 100644
--- a/src/modules/filters/gbfrtf.cpp
+++ b/src/modules/filters/gbfrtf.cpp
@@ -1,9 +1,24 @@
/******************************************************************************
*
* gbfrtf - SWFilter descendant to convert all GBF tags to RTF tags
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <gbfrtf.h>
#include <utilstr.h>
#include <ctype.h>
diff --git a/src/modules/filters/gbfstrongs.cpp b/src/modules/filters/gbfstrongs.cpp
index 610edb5..c7cf6c5 100644
--- a/src/modules/filters/gbfstrongs.cpp
+++ b/src/modules/filters/gbfstrongs.cpp
@@ -2,9 +2,24 @@
*
* gbfstrongs - SWFilter descendant to hide or show strongs number
* in a GBF module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <gbfstrongs.h>
diff --git a/src/modules/filters/gbfthml.cpp b/src/modules/filters/gbfthml.cpp
index 2664f48..4feb1fa 100644
--- a/src/modules/filters/gbfthml.cpp
+++ b/src/modules/filters/gbfthml.cpp
@@ -1,18 +1,24 @@
/***************************************************************************
- gbfthml.cpp - GBF to ThML filter
- -------------------
- begin : 1999-10-27
- copyright : 2001 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * gbfthml.cpp - GBF to ThML filter
+ * -------------------
+ * begin : 1999-10-27
+ * copyright : 2001 by CrossWire Bible Society
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <gbfthml.h>
diff --git a/src/modules/filters/gbfwebif.cpp b/src/modules/filters/gbfwebif.cpp
index e651db6..b5ff798 100644
--- a/src/modules/filters/gbfwebif.cpp
+++ b/src/modules/filters/gbfwebif.cpp
@@ -1,19 +1,26 @@
/***************************************************************************
- GBFWEBIF.cpp - GBF to HTML filter with hrefs
- for strongs and morph tags
- -------------------
- begin : 2001-09-03
- copyright : 2001 by CrossWire Bible Society
- ***************************************************************************/
+ * GBFWEBIF.cpp - GBF to HTML filter with hrefs
+ * for strongs and morph tags
+ * -------------------
+ * begin : 2001-09-03
+ * copyright : 2001 by CrossWire Bible Society
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
#include <gbfwebif.h>
#include <ctype.h>
diff --git a/src/modules/filters/gbfwordjs.cpp b/src/modules/filters/gbfwordjs.cpp
index f81ffac..c3ab166 100644
--- a/src/modules/filters/gbfwordjs.cpp
+++ b/src/modules/filters/gbfwordjs.cpp
@@ -2,9 +2,24 @@
*
* gbfstrongs - SWFilter descendant to hide or show strongs number
* in a GBF module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <gbfwordjs.h>
diff --git a/src/modules/filters/greeklexattribs.cpp b/src/modules/filters/greeklexattribs.cpp
index 1e82305..e1a60a2 100644
--- a/src/modules/filters/greeklexattribs.cpp
+++ b/src/modules/filters/greeklexattribs.cpp
@@ -2,9 +2,24 @@
*
* greeklexattribs - SWFilter descendant to set entry attributes for greek
* lexicons
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
diff --git a/src/modules/filters/latin1utf16.cpp b/src/modules/filters/latin1utf16.cpp
index 1392750..bf2f3f8 100644
--- a/src/modules/filters/latin1utf16.cpp
+++ b/src/modules/filters/latin1utf16.cpp
@@ -1,10 +1,25 @@
/******************************************************************************
*
- * Latin1UTF16 - SWFilter descendant to convert a Latin-1 character to UTF-16
+ * Latin1UTF16 - SWFilter descendant to convert a Latin-1 character to UTF-16
+ *
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
*
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <latin1utf16.h>
diff --git a/src/modules/filters/latin1utf8.cpp b/src/modules/filters/latin1utf8.cpp
index 6c0d7f1..784aafe 100644
--- a/src/modules/filters/latin1utf8.cpp
+++ b/src/modules/filters/latin1utf8.cpp
@@ -2,9 +2,24 @@
*
* Latin1UTF8 - SWFilter descendant to convert a Latin-1 character to UTF-8
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <latin1utf8.h>
diff --git a/src/modules/filters/osisfootnotes.cpp b/src/modules/filters/osisfootnotes.cpp
index 89c9c40..3d0d2d4 100644
--- a/src/modules/filters/osisfootnotes.cpp
+++ b/src/modules/filters/osisfootnotes.cpp
@@ -2,9 +2,24 @@
*
* osisfootnotes - SWFilter descendant to hide or show footnotes
* in an OSIS module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <osisfootnotes.h>
@@ -41,11 +56,17 @@ char OSISFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *m
SWBuf refs = "";
int footnoteNum = 1;
char buf[254];
- VerseKey parser(key->getText());
+ SWKey *p = (module) ? module->CreateKey() : (key) ? key->clone() : new VerseKey();
+ VerseKey *parser = SWDYNAMIC_CAST(VerseKey, p);
+ if (!parser) {
+ delete p;
+ parser = new VerseKey();
+ }
+ *parser = key->getText();
SWBuf orig = text;
const char *from = orig.c_str();
-
+
XMLTag tag;
bool strongsMarkup = false;
@@ -59,20 +80,20 @@ char OSISFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *m
continue;
}
-
+
if (*from == '<') {
intoken = true;
token = "";
continue;
}
-
-
-
+
+
+
if (*from == '>') { // process tokens
- intoken = false;
+ intoken = false;
if (!strncmp(token, "note", 4) || !strncmp(token.c_str(), "/note", 5)) {
tag = token;
-
+
if (!tag.isEndTag()) {
if (tag.getAttribute("type") && (!strcmp("x-strongsMarkup", tag.getAttribute("type"))
|| !strcmp("strongsMarkup", tag.getAttribute("type"))) // deprecated
@@ -80,7 +101,7 @@ char OSISFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *m
tag.setEmpty(false); // handle bug in KJV2003 module where some note open tags were <note ... />
strongsMarkup = true;
}
-
+
if (!tag.isEmpty()) {
// if ((!tag.isEmpty()) || (SWBuf("strongsMarkup") == tag.getAttribute("type"))) {
refs = "";
@@ -101,7 +122,7 @@ char OSISFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *m
startTag.setAttribute("swordFootnote", buf);
if ((startTag.getAttribute("type")) && (!strcmp(startTag.getAttribute("type"), "crossReference"))) {
if (!refs.length())
- refs = parser.ParseVerseList(tagText.c_str(), parser, true).getRangeText();
+ refs = parser->ParseVerseList(tagText.c_str(), *parser, true).getRangeText();
module->getEntryAttributes()["Footnote"][buf]["refList"] = refs.c_str();
}
}
@@ -122,7 +143,7 @@ char OSISFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *m
if (refs.length()) {
refs.append("; ");
}
-
+
const char* attr = strstr(token.c_str() + 9, "osisRef=\"");
const char* end = attr ? strchr(attr+9, '"') : 0;
@@ -150,6 +171,7 @@ char OSISFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *m
}
else tagText.append(*from);
}
+ delete parser;
return 0;
}
diff --git a/src/modules/filters/osisheadings.cpp b/src/modules/filters/osisheadings.cpp
index a072335..8872f24 100644
--- a/src/modules/filters/osisheadings.cpp
+++ b/src/modules/filters/osisheadings.cpp
@@ -2,9 +2,24 @@
*
*osisheadings - SWFilter descendant to hide or show headings
* in an OSIS module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <osisheadings.h>
@@ -35,6 +50,9 @@ char OSISHeadings::processText(SWBuf &text, const SWKey *key, const SWModule *mo
bool hide = false;
bool preverse = false;
bool withinTitle = false;
+ bool withinPreverseDiv = false;
+ SWBuf preverseDivID = "";
+ const char *pvDID = 0;
bool canonical = false;
SWBuf header;
int headerNum = 0;
@@ -56,27 +74,41 @@ char OSISHeadings::processText(SWBuf &text, const SWKey *key, const SWModule *mo
}
if (*from == '>') { // process tokens
intoken = false;
-
- if (!strncmp(token.c_str(), "title", 5) || !strncmp(token.c_str(), "/title", 6)) {
- withinTitle = (!strnicmp(token.c_str(), "title", 5));
- tag = token;
+ tag = token;
+
+ // <title> </title> <div subType="x-preverse"> (</div> ## when in previous)
+ if ( (!withinPreverseDiv && !strcmp(tag.getName(), "title")) ||
+ (!strcmp(tag.getName(), "div") &&
+ ((withinPreverseDiv && (tag.isEndTag(pvDID))) ||
+ (tag.getAttribute("subType") && !strcmp(tag.getAttribute("subType"), "x-preverse")))
+ )) {
+
+ withinTitle = (!tag.isEndTag(pvDID));
+ if (!strcmp(tag.getName(), "div")) {
+ withinPreverseDiv = (!tag.isEndTag(pvDID));
+ if (!pvDID) {
+ preverseDivID = tag.getAttribute("sID");
+ pvDID = (preverseDivID.length())? preverseDivID.c_str() : 0;
+ }
+ }
- if (!tag.isEndTag()) { //start tag
- if (!tag.isEmpty()) {
+ if (!tag.isEndTag(pvDID)) { //start tag
+ if (!tag.isEmpty() || pvDID) {
startTag = tag;
}
}
- if ( (tag.getAttribute("subType") && !stricmp(tag.getAttribute("subType"), "x-preverse"))
- || (tag.getAttribute("subtype") && !stricmp(tag.getAttribute("subtype"), "x-preverse")) // deprecated
- ) {
+ if ( !tag.isEndTag(pvDID) && (withinPreverseDiv
+ || (tag.getAttribute("subType") && !stricmp(tag.getAttribute("subType"), "x-preverse"))
+ || (tag.getAttribute("subtype") && !stricmp(tag.getAttribute("subtype"), "x-preverse")) // deprecated
+ )) {
hide = true;
preverse = true;
header = "";
canonical = (tag.getAttribute("canonical") && (!stricmp(tag.getAttribute("canonical"), "true")));
continue;
}
- if (!tag.isEndTag()) { //start tag
+ if (!tag.isEndTag(pvDID)) { //start tag
hide = true;
header = "";
if (option || canonical) { // we want the tag in the text
@@ -86,7 +118,7 @@ char OSISHeadings::processText(SWBuf &text, const SWKey *key, const SWModule *mo
}
continue;
}
- if (hide && tag.isEndTag()) {
+ if (hide && tag.isEndTag(pvDID)) {
if (module->isProcessEntryAttributes() && ((option || canonical) || (!preverse))) {
if (preverse) {
sprintf(buf, "%i", pvHeaderNum++);
@@ -112,6 +144,7 @@ char OSISHeadings::processText(SWBuf &text, const SWKey *key, const SWModule *mo
continue;
}
preverse = false;
+ pvDID = 0;
}
}
diff --git a/src/modules/filters/osishtmlhref.cpp b/src/modules/filters/osishtmlhref.cpp
index fe3e058..6fce987 100644
--- a/src/modules/filters/osishtmlhref.cpp
+++ b/src/modules/filters/osishtmlhref.cpp
@@ -1,17 +1,25 @@
/***************************************************************************
- osishtmlhref.cpp - OSIS to HTML with hrefs filter
- -------------------
- begin : 2003-06-24
- copyright : 2003 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation version 2 of the License. *
- * *
- ***************************************************************************/
+ * osishtmlhref.cpp - OSIS to HTML with hrefs filter
+ * -------------------
+ * begin : 2003-06-24
+ * copyright : 2003 by CrossWire Bible Society
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <ctype.h>
@@ -111,7 +119,7 @@ void processLemma(bool suspendTextPassThru, XMLTag &tag, SWBuf &buf) {
if (!suspendTextPassThru) {
buf.appendFormatted("<small><em>&lt;<a href=\"passagestudy.jsp?action=showStrongs&type=%s&value=%s\">%s</a>&gt;</em></small>",
(gh.length()) ? gh.c_str() : "",
- URL::encode(val2).c_str(),
+ URL::encode(val2).c_str(),
val2);
}
//}
@@ -188,8 +196,9 @@ bool OSISHTMLHREF::handleToken(SWBuf &buf, const char *token, BasicFilterUserDat
if ((attrib = tag.getAttribute("gloss"))) {
val = strchr(attrib, ':');
val = (val) ? (val + 1) : attrib;
- outText(" ", buf, u);
+ outText("(", buf, u);
outText(val, buf, u);
+ outText(")", buf, u);
}
if (!morphFirst) {
processLemma(u->suspendTextPassThru, tag, buf);
@@ -278,49 +287,71 @@ bool OSISHTMLHREF::handleToken(SWBuf &buf, const char *token, BasicFilterUserDat
}
}
+ // Milestoned paragraphs, created by osis2mod
+ // <div type="paragraph" sID.../>
+ // <div type="paragraph" eID.../>
+ else if (tag.isEmpty() && !strcmp(tag.getName(), "div") && tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "paragraph")) {
+ // <div type="paragraph" sID... />
+ if (tag.getAttribute("sID")) { // non-empty start tag
+ outText("<!P><br />", buf, u);
+ }
+ // <div type="paragraph" eID... />
+ else if (tag.getAttribute("eID")) {
+ outText("<!/P><br />", buf, u);
+ userData->supressAdjacentWhitespace = true;
+ }
+ }
+
// <reference> tag
else if (!strcmp(tag.getName(), "reference")) {
if (!u->inXRefNote) { // only show these if we're not in an xref note
- if ((!tag.isEndTag()) && (!tag.isEmpty())) {
- u->suspendTextPassThru = (++u->suspendLevel);
- }
- if (tag.isEndTag()) {
- if (!u->BiblicalText) {
- SWBuf refList = tag.getAttribute("passage");
- if (!refList.length())
- refList = u->lastTextNode;
- SWBuf version = tag.getAttribute("version");
-
- buf.appendFormatted("&nbsp;<a href=\"passagestudy.jsp?action=showRef&type=scripRef&value=%s&module=%s\">",
- (refList.length()) ? URL::encode(refList.c_str()).c_str() : "",
- (version.length()) ? URL::encode(version.c_str()).c_str() : "");
- buf += u->lastTextNode.c_str();
- buf += "</a>&nbsp;";
+ if (!tag.isEndTag()) {
+ SWBuf target;
+ SWBuf work;
+ SWBuf ref;
+ bool is_scripRef = false;
+
+ target = tag.getAttribute("osisRef");
+ const char* the_ref = strchr(target, ':');
+
+ if(!the_ref) {
+ // No work
+ ref = target;
+ is_scripRef = true;
}
else {
- SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
- VerseKey *vkey = NULL;
- // see if we have a VerseKey * or descendant
- SWTRY {
- vkey = SWDYNAMIC_CAST(VerseKey, u->key);
- }
- SWCATCH ( ... ) {}
- if (vkey) {
- // leave this special osis type in for crossReference notes types? Might thml use this some day? Doesn't hurt.
- //buf.appendFormatted("<a href=\"noteID=%s.x.%s\"><small><sup>*x</sup></small></a> ", vkey->getText(), footnoteNumber.c_str());
- buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=x&value=%s&module=%s&passage=%s\"><small><sup>*x</sup></small></a>",
- URL::encode(footnoteNumber.c_str()).c_str(),
- URL::encode(u->version.c_str()).c_str(),
- URL::encode(vkey->getText()).c_str());
-
- }
+ // Compensate for starting :
+ ref = the_ref + 1;
+
+ int size = target.size() - ref.size() - 1;
+ work.setSize(size);
+ strncpy(work.getRawData(), target, size);
+
+ // For Bible:Gen.3.15 or Bible.vulgate:Gen.3.15
+ if(!strncmp(work, "Bible", 5))
+ is_scripRef = true;
+ }
+
+ if(is_scripRef)
+ {
+ buf.appendFormatted("<a href=\"passagestudy.jsp?action=showRef&type=scripRef&value=%s&module=\">",
+ URL::encode(ref.c_str()).c_str()
+// (work.size()) ? URL::encode(work.c_str()).c_str() : "")
+ );
+ }
+ else
+ {
+ // Dictionary link, or something
+ buf.appendFormatted("<a href=\"sword://%s/%s\">",
+ URL::encode(work.c_str()).c_str(),
+ URL::encode(ref.c_str()).c_str()
+ );
}
- u->suspendTextPassThru = (--u->suspendLevel);
}
- }/*
- if (tag.isEndTag()) {
- u->suspendTextPassThru = false;
- }*/
+ else {
+ outText("</a>", buf, u);
+ }
+ }
}
// <l> poetry, etc
@@ -383,7 +414,26 @@ bool OSISHTMLHREF::handleToken(SWBuf &buf, const char *token, BasicFilterUserDat
outText("</b><br />", buf, u);
}
}
+
+ // <list>
+ else if (!strcmp(tag.getName(), "list")) {
+ if((!tag.isEndTag()) && (!tag.isEmpty())) {
+ outText("<ul>", buf, u);
+ }
+ else if (tag.isEndTag()) {
+ outText("</ul>", buf, u);
+ }
+ }
+ // <item>
+ else if (!strcmp(tag.getName(), "item")) {
+ if((!tag.isEndTag()) && (!tag.isEmpty())) {
+ outText("<li>", buf, u);
+ }
+ else if (tag.isEndTag()) {
+ outText("</li>", buf, u);
+ }
+ }
// <catchWord> & <rdg> tags (italicize)
else if (!strcmp(tag.getName(), "rdg") || !strcmp(tag.getName(), "catchWord")) {
if ((!tag.isEndTag()) && (!tag.isEmpty())) {
@@ -405,6 +455,16 @@ bool OSISHTMLHREF::handleToken(SWBuf &buf, const char *token, BasicFilterUserDat
if (lastText.size()) {
toupperstr(lastText);
scratch.setFormatted("%c<font size=\"-1\">%s</font>", lastText[0], lastText.c_str()+1);
+
+ const unsigned char *tmpBuf = (const unsigned char *)lastText.c_str();
+ getUniCharFromUTF8(&tmpBuf);
+ int char_length = (tmpBuf - (const unsigned char *)lastText.c_str());
+ scratch.setFormatted("%.*s<font size=\"-1\">%s</font>",
+ char_length,
+ lastText.c_str(),
+ lastText.c_str() + char_length
+ );
+
outText(scratch.c_str(), buf, u);
}
}
@@ -542,8 +602,7 @@ bool OSISHTMLHREF::handleToken(SWBuf &buf, const char *token, BasicFilterUserDat
outText(URL::encode(u->version.c_str()).c_str(), buf, u);
outText("\">", buf, u);
-// we do this because BibleCS looks for this EXACT format for an image tag
- outText("<image border=0 src=\"", buf, u);
+ outText("<img border=\"0\" src=\"", buf, u);
outText(filepath, buf, u);
outText("\" />", buf, u);
diff --git a/src/modules/filters/osislemma.cpp b/src/modules/filters/osislemma.cpp
index f5e6ff6..7b56024 100644
--- a/src/modules/filters/osislemma.cpp
+++ b/src/modules/filters/osislemma.cpp
@@ -2,9 +2,24 @@
*
* osislemma - SWFilter descendant to hide or show lemmata
* in a OSIS module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <osislemma.h>
#include <utilxml.h>
diff --git a/src/modules/filters/osismorph.cpp b/src/modules/filters/osismorph.cpp
index 69d44d5..7ceec79 100644
--- a/src/modules/filters/osismorph.cpp
+++ b/src/modules/filters/osismorph.cpp
@@ -2,9 +2,24 @@
*
* osismorph - SWFilter descendant to hide or show morph tags
* in a OSIS module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <osismorph.h>
diff --git a/src/modules/filters/osismorphsegmentation.cpp b/src/modules/filters/osismorphsegmentation.cpp
index bf32581..fef7af7 100644
--- a/src/modules/filters/osismorphsegmentation.cpp
+++ b/src/modules/filters/osismorphsegmentation.cpp
@@ -2,9 +2,24 @@
*
* osismorphsegmentation - SWFilter descendant to toggle splitting of morphemes
* (for morpheme segmented Hebrew in the WLC)
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <osismorphsegmentation.h>
#include <stdlib.h>
#include <utilxml.h>
diff --git a/src/modules/filters/osisosis.cpp b/src/modules/filters/osisosis.cpp
index 7da6089..82a6bfc 100644
--- a/src/modules/filters/osisosis.cpp
+++ b/src/modules/filters/osisosis.cpp
@@ -1,17 +1,24 @@
/***************************************************************************
- osisosis.cpp - internal OSIS to public OSIS filter
- -------------------
- begin : 2004-03-13
- copyright : 2003 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation version 2 of the License.
- * *
- ***************************************************************************/
+ * osisosis.cpp - internal OSIS to public OSIS filter
+ * -------------------
+ * begin : 2004-03-13
+ * copyright : 2003 by CrossWire Bible Society
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <osisosis.h>
@@ -55,33 +62,34 @@ char OSISOSIS::processText(SWBuf &text, const SWKey *key, const SWModule *module
if (vkey->Verse()) {
ref.appendFormatted("\t\t<verse osisID=\"%s\">", vkey->getOSISRef());
}
-
+
if (ref.length() > 0) {
-
+
text = ref + text;
-
+
if (vkey->Verse()) {
- VerseKey tmp;
- tmp = *vkey;
- tmp.AutoNormalize(0);
- tmp.Headings(1);
-
+ VerseKey *tmp = (VerseKey *)vkey->clone();
+ *tmp = *vkey;
+ tmp->AutoNormalize(0);
+ tmp->Headings(1);
+
text += "</verse>";
-
- tmp = MAXVERSE;
- if (*vkey == tmp) {
- tmp.Verse(0);
+
+ *tmp = MAXVERSE;
+ if (*vkey == *tmp) {
+ tmp->Verse(0);
// sprintf(ref, "\t</div>");
// pushString(&to, ref);
- tmp = MAXCHAPTER;
- tmp = MAXVERSE;
- if (*vkey == tmp) {
- tmp.Chapter(0);
- tmp.Verse(0);
+ *tmp = MAXCHAPTER;
+ *tmp = MAXVERSE;
+ if (*vkey == *tmp) {
+ tmp->Chapter(0);
+ tmp->Verse(0);
// sprintf(ref, "\t</div>");
// pushString(&to, ref);
}
}
+ delete tmp;
}
//
diff --git a/src/modules/filters/osisplain.cpp b/src/modules/filters/osisplain.cpp
index 62841a6..57105f0 100644
--- a/src/modules/filters/osisplain.cpp
+++ b/src/modules/filters/osisplain.cpp
@@ -1,18 +1,24 @@
-/***************************************************************************
- osisplain.cpp - OSIS to Plaintext filter
- -------------------
- begin : 2003-02-15
- copyright : 2003 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+/******************************************************************************
+ * osisplain.cpp - An SWFilter
+ * impl that provides stripping of OSIS tags
+ *
+ * $Id: osisplain.cpp 2334 2009-04-24 00:14:12Z scribe $
+ *
+ * Copyright 2001 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <osisplain.h>
@@ -22,6 +28,17 @@
SWORD_NAMESPACE_START
+namespace {
+class MyUserData : public BasicFilterUserData {
+public:
+ SWBuf w;
+ XMLTag tag;
+ VerseKey *vk;
+ char testament;
+ MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {}
+};
+}
+
OSISPlain::OSISPlain() {
setTokenStart("<");
setTokenEnd(">");
@@ -45,13 +62,18 @@ OSISPlain::OSISPlain() {
addTokenSubstitute("/lg", "\n");
}
+BasicFilterUserData *OSISPlain::createUserData(const SWModule *module, const SWKey *key) {
+ MyUserData *u = new MyUserData(module, key);
+ u->vk = SWDYNAMIC_CAST(VerseKey, u->key);
+ u->testament = (u->vk) ? u->vk->Testament() : 2; // default to NT
+ return u;
+}
+
bool OSISPlain::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
// manually process if it wasn't a simple substitution
if (!substituteToken(buf, token)) {
MyUserData *u = (MyUserData *)userData;
- VerseKey *vk = SWDYNAMIC_CAST(VerseKey, u->key);
- char testament = (vk) ? vk ->Testament() : 2; // default to NT
if (((*token == 'w') && (token[1] == ' ')) ||
((*token == '/') && (token[1] == 'w') && (!token[2]))) {
u->tag = token;
@@ -99,7 +121,7 @@ bool OSISPlain::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *
val++;
}
else {
- gh = (testament>1) ? 'G' : 'H';
+ gh = (u->testament>1) ? 'G' : 'H';
}
if ((!strcmp(val, "3588")) && (lastText.length() < 1))
show = false;
@@ -139,13 +161,13 @@ bool OSISPlain::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *
// <note> tag
else if (!strncmp(token, "note", 4)) {
if (!strstr(token, "strongsMarkup")) { // leave strong's markup notes out, in the future we'll probably have different option filters to turn different note types on or off
- buf.append(" (");
+ buf.append(" [");
}
else u->suspendTextPassThru = true;
}
else if (!strncmp(token, "/note", 5)) {
if (!u->suspendTextPassThru)
- buf.append(')');
+ buf.append("] ");
else u->suspendTextPassThru = false;
}
@@ -156,6 +178,15 @@ bool OSISPlain::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *
buf.append('\n');
}
+ // Milestoned paragraph, created by osis2mod
+ // <div type="paragraph" sID... />
+ // <div type="paragraph" eID... />
+ else if (!strcmp(u->tag.getName(), "div") && u->tag.getAttribute("type") && !strcmp(u->tag.getAttribute("type"), "paragraph") &&
+ (u->tag.isEmpty() && (u->tag.getAttribute("sID") || u->tag.getAttribute("eID")))) {
+ userData->supressAdjacentWhitespace = true;
+ buf.append('\n');
+ }
+
// <lb .../>
else if (!strncmp(token, "lb", 2)) {
userData->supressAdjacentWhitespace = true;
diff --git a/src/modules/filters/osisredletterwords.cpp b/src/modules/filters/osisredletterwords.cpp
index 727332d..9075fd8 100644
--- a/src/modules/filters/osisredletterwords.cpp
+++ b/src/modules/filters/osisredletterwords.cpp
@@ -2,9 +2,24 @@
*
* OSISRedLetterWords - SWFilter descendant to toggle red coloring for words
* of Christ in an OSIS module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <osisredletterwords.h>
#include <swmodule.h>
diff --git a/src/modules/filters/osisrtf.cpp b/src/modules/filters/osisrtf.cpp
index 0352335..84801e3 100644
--- a/src/modules/filters/osisrtf.cpp
+++ b/src/modules/filters/osisrtf.cpp
@@ -1,17 +1,25 @@
/***************************************************************************
- osisrtf.cpp - OSIS to RTF filter
- -------------------
- begin : 2003-02-15
- copyright : 2003 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation version 2 of the License. *
- * *
- ***************************************************************************/
+ * osisrtf.cpp - OSIS to RTF filter
+ * -------------------
+ * begin : 2003-02-15
+ * copyright : 2003 by CrossWire Bible Society
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <ctype.h>
@@ -272,6 +280,21 @@ bool OSISRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *us
}
}
+ // Milestoned paragraphs, created by osis2mod
+ // <div type="paragraph" sID.../>
+ // <div type="paragraph" eID.../>
+ else if (tag.isEmpty() && !strcmp(tag.getName(), "div") && tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "paragraph")) {
+ // <div type="paragraph" sID... />
+ if (tag.getAttribute("sID")) { // non-empty start tag
+ outText("{\\fi200\\par}", buf, u);
+ }
+ // <div type="paragraph" eID... />
+ else if (tag.getAttribute("eID")) {
+ outText("{\\par}", buf, u);
+ userData->supressAdjacentWhitespace = true;
+ }
+ }
+
// <reference> tag
else if (!strcmp(tag.getName(), "reference")) {
if (!u->inXRefNote) { // only show these if we're not in an xref note
@@ -316,6 +339,25 @@ bool OSISRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *us
outText("\\par}", buf, u);
}
}
+ // <list> - how do we support these better in RTF?
+ else if (!strcmp(tag.getName(), "list")) {
+ if((!tag.isEndTag()) && (!tag.isEmpty())) {
+ outText("\\par\\pard", buf, u);
+ }
+ else if (tag.isEndTag()) {
+ outText("\\par\\pard", buf, u);
+ }
+ }
+
+ // <item> - support better
+ else if (!strcmp(tag.getName(), "item")) {
+ if((!tag.isEndTag()) && (!tag.isEmpty())) {
+ outText("* ", buf, u);
+ }
+ else if (tag.isEndTag()) {
+ outText("\\par", buf, u);
+ }
+ }
// <catchWord> & <rdg> tags (italicize)
else if (!strcmp(tag.getName(), "rdg") || !strcmp(tag.getName(), "catchWord")) {
@@ -445,16 +487,10 @@ bool OSISRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *us
else if (!strcmp(tag.getName(), "divineName")) {
if ((!tag.isEndTag()) && (!tag.isEmpty())) {
- u->suspendTextPassThru = (++u->suspendLevel);
+ outText("{\\scaps ", buf, u);
}
else if (tag.isEndTag()) {
- SWBuf lastText = u->lastSuspendSegment.c_str();
- u->suspendTextPassThru = (--u->suspendLevel);
- if (lastText.size()) {
- toupperstr(lastText);
- scratch.setFormatted("{\\fs19%c\\fs16%s}", lastText[0], lastText.c_str()+1);
- outText(scratch.c_str(), buf, u);
- }
+ outText("}", buf, u);
}
}
@@ -462,10 +498,11 @@ bool OSISRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *us
else if (!strcmp(tag.getName(), "div")) {
if ((!tag.isEndTag()) && (!tag.isEmpty())) {
- outText("\\par\\par\\pard ", buf, u);
+ outText("\\pard ", buf, u);
}
else if (tag.isEndTag()) {
- }
+ outText("\\par ", buf, u);
+ }
}
// image
diff --git a/src/modules/filters/osisruby.cpp b/src/modules/filters/osisruby.cpp
new file mode 100644
index 0000000..c17ea43
--- /dev/null
+++ b/src/modules/filters/osisruby.cpp
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ * osisruby - SWFilter descendant to hide or show ruby
+ * in a OSIS module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <stdlib.h>
+#include <osisruby.h>
+#include <utilxml.h>
+
+SWORD_NAMESPACE_START
+
+const char oName[] = "Ruby";
+const char oTip[] = "Toggles Ruby On and Off if they exist";
+
+const SWBuf choices[3] = {"Off", "On", ""};
+const StringList oValues(&choices[0], &choices[2]);
+
+OSISRuby::OSISRuby() : SWOptionFilter(oName, oTip, &oValues) {
+ setOptionValue("Off");
+}
+
+
+OSISRuby::~OSISRuby() {
+}
+
+
+char OSISRuby::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
+ SWBuf token;
+ bool intoken = false;
+ bool lastspace = false;
+
+ const SWBuf orig = text;
+ const char * from = orig.c_str();
+
+ if (!option) {
+ for (text = ""; *from; ++from) {
+ if (*from == '<') {
+ intoken = true;
+ token = "";
+ continue;
+ }
+ if (*from == '>') { // process tokens
+ intoken = false;
+ if (token.startsWith("w ")) { // Word
+ XMLTag wtag(token);
+ const char *l = wtag.getAttribute("gloss");
+ if (l) {
+ wtag.setAttribute("gloss", 0);
+ token = wtag;
+ token.trim();
+ // drop <>
+ token << 1;
+ token--;
+ }
+ }
+
+ // keep token in text
+ text.append('<');
+ text.append(token);
+ text.append('>');
+
+ continue;
+ }
+ if (intoken) {
+ token += *from;
+ }
+ else {
+ text.append(*from);
+ lastspace = (*from == ' ');
+ }
+ }
+ }
+ return 0;
+}
+
+SWORD_NAMESPACE_END
diff --git a/src/modules/filters/osisscripref.cpp b/src/modules/filters/osisscripref.cpp
index 437f5f5..73c7309 100644
--- a/src/modules/filters/osisscripref.cpp
+++ b/src/modules/filters/osisscripref.cpp
@@ -2,9 +2,24 @@
*
* OSISScripref - SWFilter descendant to hide or show scripture references
* in an OSIS module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <osisscripref.h>
#include <swmodule.h>
diff --git a/src/modules/filters/osisstrongs.cpp b/src/modules/filters/osisstrongs.cpp
index 922f7fd..8c06b07 100644
--- a/src/modules/filters/osisstrongs.cpp
+++ b/src/modules/filters/osisstrongs.cpp
@@ -2,9 +2,24 @@
*
* osisstrongs - SWFilter descendant to hide or show strongs number
* in a OSIS module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
@@ -38,6 +53,7 @@ char OSISStrongs::processText(SWBuf &text, const SWKey *key, const SWModule *mod
int wordNum = 1;
char wordstr[5];
const char *wordStart = 0;
+ SWBuf page = ""; // some modules include <seg> page info, so we add these to the words
const SWBuf orig = text;
const char * from = orig.c_str();
@@ -50,6 +66,20 @@ char OSISStrongs::processText(SWBuf &text, const SWKey *key, const SWModule *mod
}
if (*from == '>') { // process tokens
intoken = false;
+
+ // possible page seg --------------------------------
+ if (token.startsWith("seg ")) {
+ XMLTag stag(token);
+ SWBuf type = stag.getAttribute("type");
+ if (type == "page") {
+ SWBuf number = stag.getAttribute("subtype");
+ if (number.length()) {
+ page = number;
+ }
+ }
+ }
+ // ---------------------------------------------------
+
if (token.startsWith("w ")) { // Word
XMLTag wtag(token);
if (module->isProcessEntryAttributes()) {
@@ -167,15 +197,17 @@ char OSISStrongs::processText(SWBuf &text, const SWKey *key, const SWModule *mod
if (lemma.length())
- module->getEntryAttributes()["Word"][wordstr]["Lemma"] = lemma;
+ module->getEntryAttributes()["Word"][wordstr]["Lemma"] = lemma;
if (lemmaClass.length())
- module->getEntryAttributes()["Word"][wordstr]["LemmaClass"] = lemmaClass;
+ module->getEntryAttributes()["Word"][wordstr]["LemmaClass"] = lemmaClass;
if (morph.length())
- module->getEntryAttributes()["Word"][wordstr]["Morph"] = morph;
+ module->getEntryAttributes()["Word"][wordstr]["Morph"] = morph;
if (morphClass.length())
- module->getEntryAttributes()["Word"][wordstr]["MorphClass"] = morphClass;
+ module->getEntryAttributes()["Word"][wordstr]["MorphClass"] = morphClass;
if (src.length())
module->getEntryAttributes()["Word"][wordstr]["Src"] = src;
+ if (page.length())
+ module->getEntryAttributes()["Word"][wordstr]["Page"] = page;
if (wtag.isEmpty()) {
int j;
diff --git a/src/modules/filters/osisvariants.cpp b/src/modules/filters/osisvariants.cpp
index 91d700c..16e0cfb 100644
--- a/src/modules/filters/osisvariants.cpp
+++ b/src/modules/filters/osisvariants.cpp
@@ -2,9 +2,24 @@
*
* osisvariants - SWFilter descendant to hide or show textual variants
* in an OSIS module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <osisvariants.h>
#include <utilstr.h>
diff --git a/src/modules/filters/osiswebif.cpp b/src/modules/filters/osiswebif.cpp
index ecc58f7..e313836 100644
--- a/src/modules/filters/osiswebif.cpp
+++ b/src/modules/filters/osiswebif.cpp
@@ -1,19 +1,25 @@
/***************************************************************************
- OSISWEBIF.cpp - OSIS to HTML filter with hrefs
- for strongs and morph tags
- -------------------
- begin : 2003-10-23
- copyright : 2003 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * OSISWEBIF.cpp - OSIS to HTML filter with hrefs
+ * for strongs and morph tags
+ * -------------------
+ * begin : 2003-10-23
+ * copyright : 2003 by CrossWire Bible Society
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <osiswebif.h>
@@ -169,6 +175,14 @@ bool OSISWEBIF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *
}
}
+ // Milestoned paragraphs, created by osis2mod
+ // <div type="paragraph" sID.../>
+ // <div type="paragraph" eID.../>
+ else if (tag.isEmpty() && !strcmp(tag.getName(), "div") && tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "paragraph")) {
+ // This is properly handled by base class.
+ return OSISHTMLHREF::handleToken(buf, token, userData);
+ }
+
// ok to leave these in
else if (!strcmp(tag.getName(), "div")) {
buf += tag;
diff --git a/src/modules/filters/osiswordjs.cpp b/src/modules/filters/osiswordjs.cpp
index dc805b4..da573d3 100644
--- a/src/modules/filters/osiswordjs.cpp
+++ b/src/modules/filters/osiswordjs.cpp
@@ -2,9 +2,24 @@
*
* osisstrongs - SWFilter descendant to hide or show strongs number
* in a OSIS module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <osiswordjs.h>
@@ -76,8 +91,11 @@ char OSISWordJS::processText(SWBuf &text, const SWKey *key, const SWModule *modu
SWBuf lemmaClass;
SWBuf lemma;
SWBuf morph;
+ SWBuf page;
SWBuf src;
char gh = 0;
+ page = module->getEntryAttributes()["Word"][wordstr]["Page"].c_str();
+ if (page.length()) page = (SWBuf)"p:" + page;
int count = atoi(module->getEntryAttributes()["Word"][wordstr]["PartCount"].c_str());
for (int i = 0; i < count; i++) {
@@ -146,7 +164,7 @@ char OSISWordJS::processText(SWBuf &text, const SWKey *key, const SWModule *modu
}
}
// 'p' = 'fillpop' to save bandwidth
- text.appendFormatted("<span class=\"clk\" onclick=\"p('%s','%s','%s','%s','','%s');\" >", lexName.c_str(), lemma.c_str(), wordID.c_str(), morph.c_str(), modName.c_str());
+ text.appendFormatted("<span class=\"clk\" onclick=\"p('%s','%s','%s','%s','%s','%s');\" >", lexName.c_str(), lemma.c_str(), wordID.c_str(), morph.c_str(), page.c_str(), modName.c_str());
wordNum++;
}
if ((*token == '/') && (token[1] == 'w') && option) { // Word
diff --git a/src/modules/filters/papyriplain.cpp b/src/modules/filters/papyriplain.cpp
index 423bfda..782b52a 100644
--- a/src/modules/filters/papyriplain.cpp
+++ b/src/modules/filters/papyriplain.cpp
@@ -1,9 +1,24 @@
/******************************************************************************
*
* papyriplain - SWFilter descendant to strip out all Papyri tags
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <papyriplain.h>
diff --git a/src/modules/filters/plainfootnotes.cpp b/src/modules/filters/plainfootnotes.cpp
index 0baf313..449f7da 100644
--- a/src/modules/filters/plainfootnotes.cpp
+++ b/src/modules/filters/plainfootnotes.cpp
@@ -1,19 +1,25 @@
/***************************************************************************
- plainfootnotes.cpp - description
- -------------------
- begin : Wed Oct 13 1999
- copyright : (C) 1999 by The team of BibleTime
- email : info@bibletime.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * plainfootnotes.cpp - description
+ * -------------------
+ * begin : Wed Oct 13 1999
+ * copyright : (C) 1999 by The team of BibleTime
+ * email : info@bibletime.de
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <plainfootnotes.h>
#include <swkey.h>
diff --git a/src/modules/filters/plainhtml.cpp b/src/modules/filters/plainhtml.cpp
index f5f2a5c..3f989fa 100644
--- a/src/modules/filters/plainhtml.cpp
+++ b/src/modules/filters/plainhtml.cpp
@@ -1,19 +1,25 @@
/***************************************************************************
- plainhtml.cpp - description
- -------------------
- begin : Thu Jun 24 1999
- copyright : (C) 1999 by Torsten Uhlmann
- email : TUhlmann@gmx.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * plainhtml.cpp - description
+ * -------------------
+ * begin : Thu Jun 24 1999
+ * copyright : (C) 1999 by Torsten Uhlmann
+ * email : TUhlmann@gmx.de
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <plainhtml.h>
#include <swbuf.h>
diff --git a/src/modules/filters/rtfhtml.cpp b/src/modules/filters/rtfhtml.cpp
index cac5068..7b55721 100644
--- a/src/modules/filters/rtfhtml.cpp
+++ b/src/modules/filters/rtfhtml.cpp
@@ -1,19 +1,25 @@
/***************************************************************************
- rtfhtml.cpp - description
- -------------------
- begin : Wed Oct 13 1999
- copyright : (C) 1999 by The team of BibleTime
- email : info@bibletime.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * rtfhtml.cpp - description
+ * -------------------
+ * begin : Wed Oct 13 1999
+ * copyright : (C) 1999 by The team of BibleTime
+ * email : info@bibletime.de
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <rtfhtml.h>
diff --git a/src/modules/filters/scsuutf8.cpp b/src/modules/filters/scsuutf8.cpp
deleted file mode 100644
index 0daff4a..0000000
--- a/src/modules/filters/scsuutf8.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/******************************************************************************
- *
- * SCSUUTF8 - SWFilter descendant to convert a SCSU character to UTF-8
- *
- */
-
-
-/* This class is based on:
- * http://czyborra.com/scsu/scsu.c written by Roman Czyborra@dds.nl
- * on Andrea's balcony in North Amsterdam on 1998-08-04
- * Thanks to Richard Verhoeven <rcb5@win.tue.nl> for his suggestion
- * to correct the haphazard "if" after UQU to "else if" on 1998-10-01
- *
- * This is a deflator to UTF-8 output for input compressed in SCSU,
- * the (Reuters) Standard Compression Scheme for Unicode as described
- * in http://www.unicode.org/unicode/reports/tr6.html
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <swmodule.h>
-
-#include <scsuutf8.h>
-
-SWORD_NAMESPACE_START
-
-SCSUUTF8::SCSUUTF8() {
-}
-
-
-unsigned char* SCSUUTF8::UTF8Output(unsigned long uchar, unsigned char* text)
-{
- /* join UTF-16 surrogates without any pairing sanity checks */
-
- static int d;
-
- if (uchar >= 0xd800 && uchar <= 0xdbff) { d = uchar & 0x3f; return text; }
- if (uchar >= 0xdc00 && uchar <= 0xdfff) { uchar = uchar + 0x2400 + d * 0x400; }
-
- /* output one character as UTF-8 multibyte sequence */
-
- if (uchar < 0x80) {
- *text++ = c;
- }
- else if (uchar < 0x800) {
- *text++ = 0xc0 | uchar >> 6;
- *text++ = 0x80 | (uchar & 0x3f);
- }
- else if (uchar < 0x10000) {
- *text++ = 0xe0 | uchar >> 12;
- *text++ = 0x80 | (uchar >> 6 & 0x3f);
- *text++ = 0x80 | (uchar & 0x3f);
- }
- else if (uchar < 0x200000) {
- *text++ = 0xf0 | uchar >> 18;
- *text++ = 0x80 | (uchar >> 12 & 0x3f);
- *text++ = 0x80 | (uchar >> 6 & 0x3f);
- *text++ = 0x80 | (uchar & 0x3f);
- }
-
- return text;
-}
-
-char SCSUUTF8::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
-/*
- unsigned char *to, *from;
- unsigned long buflen = len * FILTERPAD;
- char active = 0, mode = 0;
- if ((unsigned long)key < 2) // hack, we're en(1)/de(0)ciphering
- return -1;
-
- static unsigned short start[8] = {0x0000,0x0080,0x0100,0x0300,0x2000,0x2080,0x2100,0x3000};
- static unsigned short slide[8] = {0x0080,0x00C0,0x0400,0x0600,0x0900,0x3040,0x30A0,0xFF00};
- static unsigned short win[256] = {
- 0x0000, 0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380,
- 0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x0700, 0x0780,
- 0x0800, 0x0880, 0x0900, 0x0980, 0x0A00, 0x0A80, 0x0B00, 0x0B80,
- 0x0C00, 0x0C80, 0x0D00, 0x0D80, 0x0E00, 0x0E80, 0x0F00, 0x0F80,
- 0x1000, 0x1080, 0x1100, 0x1180, 0x1200, 0x1280, 0x1300, 0x1380,
- 0x1400, 0x1480, 0x1500, 0x1580, 0x1600, 0x1680, 0x1700, 0x1780,
- 0x1800, 0x1880, 0x1900, 0x1980, 0x1A00, 0x1A80, 0x1B00, 0x1B80,
- 0x1C00, 0x1C80, 0x1D00, 0x1D80, 0x1E00, 0x1E80, 0x1F00, 0x1F80,
- 0x2000, 0x2080, 0x2100, 0x2180, 0x2200, 0x2280, 0x2300, 0x2380,
- 0x2400, 0x2480, 0x2500, 0x2580, 0x2600, 0x2680, 0x2700, 0x2780,
- 0x2800, 0x2880, 0x2900, 0x2980, 0x2A00, 0x2A80, 0x2B00, 0x2B80,
- 0x2C00, 0x2C80, 0x2D00, 0x2D80, 0x2E00, 0x2E80, 0x2F00, 0x2F80,
- 0x3000, 0x3080, 0x3100, 0x3180, 0x3200, 0x3280, 0x3300, 0x3800,
- 0xE000, 0xE080, 0xE100, 0xE180, 0xE200, 0xE280, 0xE300, 0xE380,
- 0xE400, 0xE480, 0xE500, 0xE580, 0xE600, 0xE680, 0xE700, 0xE780,
- 0xE800, 0xE880, 0xE900, 0xE980, 0xEA00, 0xEA80, 0xEB00, 0xEB80,
- 0xEC00, 0xEC80, 0xED00, 0xED80, 0xEE00, 0xEE80, 0xEF00, 0xEF80,
- 0xF000, 0xF080, 0xF100, 0xF180, 0xF200, 0xF280, 0xF300, 0xF380,
- 0xF400, 0xF480, 0xF500, 0xF580, 0xF600, 0xF680, 0xF700, 0xF780,
- 0xF800, 0xF880, 0xF900, 0xF980, 0xFA00, 0xFA80, 0xFB00, 0xFB80,
- 0xFC00, 0xFC80, 0xFD00, 0xFD80, 0xFE00, 0xFE80, 0xFF00, 0xFF80,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x00C0, 0x0250, 0x0370, 0x0530, 0x3040, 0x30A0, 0xFF60
- };
-
- if (!len)
- return 0;
-
- memmove(&text[buflen - len], text, len);
- from = (unsigned char*)&text[buflen - len];
- to = (unsigned char *)text;
-
- // -------------------------------
-
- for (int i = 0; i < len;) {
-
-
- if (i >= len) break;
- c = from[i++];
-
- if (c >= 0x80)
- {
- to = UTF8Output (c - 0x80 + slide[active], to);
- }
- else if (c >= 0x20 && c <= 0x7F)
- {
- to = UTF8Output (c, to);
- }
- else if (c == 0x0 || c == 0x9 || c == 0xA || c == 0xC || c == 0xD)
- {
- to = UTF8Output (c, to);
- }
- else if (c >= 0x1 && c <= 0x8) // SQn
- {
- if (i >= len) break;
- d = from[i++]; // single quote
-
- to = UTF8Output (d < 0x80 ? d + start [c - 0x1] :
- d - 0x80 + slide [c - 0x1], to);
- }
- else if (c >= 0x10 && c <= 0x17) // SCn
- {
- active = c - 0x10; // change window
- }
- else if (c >= 0x18 && c <= 0x1F) // SDn
- {
- active = c - 0x18; // define window
- if (i >= len) break;
- slide [active] = win [from[i++]];
- }
- else if (c == 0xB) // SDX
- {
- if (i >= len) break;
- c = from[i++];
-
- if (i >= len) break;
- d = from[i++];
-
- slide [active = c>>5] = 0x10000 + (((c & 0x1F) << 8 | d) << 7);
- }
- else if (c == 0xE) // SQU
- {
- if (i >= len) break;
- c = from[i++]; // SQU
-
- if (i >= len) break;
- to = UTF8Output (c << 8 | from[i++], to);
- }
- else if (c == 0xF) // SCU
- {
- mode = 1; // change to Unicode mode
-
- while (mode)
- {
- if (i >= len) break;
- c = from[i++];
-
- if (c <= 0xDF || c >= 0xF3)
- {
- if (i >= len) break;
- to = UTF8Output (c << 8 | from[i++], to);
- }
- else if (c == 0xF0) // UQU
- {
- if (i >= len) break;
- c = from[i++];
-
- if (i >= len) break;
- to = UTF8Output (c << 8 | from[i++], to);
- }
- else if (c >= 0xE0 && c <= 0xE7) // UCn
- {
- active = c - 0xE0; mode = 0;
- }
- else if (c >= 0xE8 && c <= 0xEF) // UDn
- {
- if (i >= len) break;
- slide [active=c-0xE8] = win [from[i++]]; mode = 0;
- }
- else if (c == 0xF1) // UDX
- {
- if (i >= len) break;
- c = from[i++];
-
- if (i >= len) break;
- d = from[i++];
-
- slide [active = c>>5] =
- 0x10000 + (((c & 0x1F) << 8 | d) << 7); mode = 0;
- }
- }
- }
-
-
- }
-
- *to++ = 0;
- *to = 0;
-*/
- return 0;
-}
-
-SWORD_NAMESPACE_END
diff --git a/src/modules/filters/swoptfilter.cpp b/src/modules/filters/swoptfilter.cpp
index 6921190..9d6dac4 100644
--- a/src/modules/filters/swoptfilter.cpp
+++ b/src/modules/filters/swoptfilter.cpp
@@ -1,9 +1,24 @@
/******************************************************************************
*
- * swoptfilter - SWFilter descendant and base class for all option filters
+ * swoptfilter - SWFilter descendant and base class for all option filters
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <swoptfilter.h>
#include <utilstr.h>
diff --git a/src/modules/filters/teihtmlhref.cpp b/src/modules/filters/teihtmlhref.cpp
index 1d213f4..7e27667 100644
--- a/src/modules/filters/teihtmlhref.cpp
+++ b/src/modules/filters/teihtmlhref.cpp
@@ -1,18 +1,24 @@
/***************************************************************************
- teirtf.cpp - TEI to HTMLHREF filter
- -------------------
- begin : 2006-07-03
- copyright : 2006 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * teirtf.cpp - TEI to HTMLHREF filter
+ * -------------------
+ * begin : 2006-07-03
+ * copyright : 2006 by CrossWire Bible Society
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <ctype.h>
@@ -20,6 +26,7 @@
#include <utilxml.h>
#include <swmodule.h>
#include <url.h>
+#include <iostream>
SWORD_NAMESPACE_START
@@ -137,8 +144,8 @@ bool TEIHTMLHREF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData
!strcmp(tag.getName(), "case") ||
!strcmp(tag.getName(), "gram") ||
!strcmp(tag.getName(), "number") ||
- !strcmp(tag.getName(), "pron") ||
- !strcmp(tag.getName(), "def")) {
+ !strcmp(tag.getName(), "pron") /*||
+ !strcmp(tag.getName(), "def")*/) {
if ((!tag.isEndTag()) && (!tag.isEmpty())) {
buf += "<i>";
}
@@ -172,6 +179,67 @@ bool TEIHTMLHREF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData
!strcmp(tag.getName(), "usg")) {
// do nothing here
}
+ else if (!strcmp(tag.getName(), "ref")) {
+ if (!tag.isEndTag()) {
+ u->suspendTextPassThru = true;
+ SWBuf target;
+ SWBuf work;
+ SWBuf ref;
+
+ int was_osisref = false;
+ if(tag.getAttribute("osisRef"))
+ {
+ target += tag.getAttribute("osisRef");
+ was_osisref=true;
+ }
+ else if(tag.getAttribute("target"))
+ target += tag.getAttribute("target");
+
+ if(target.size())
+ {
+ const char* the_ref = strchr(target, ':');
+
+ if(!the_ref) {
+ // No work
+ ref = target;
+ }
+ else {
+ // Compensate for starting :
+ ref = the_ref + 1;
+
+ int size = target.size() - ref.size() - 1;
+ work.setSize(size);
+ strncpy(work.getRawData(), target, size);
+ }
+
+ if(was_osisref)
+ {
+ buf.appendFormatted("<a href=\"passagestudy.jsp?action=showRef&type=scripRef&value=%s&module=%s\">",
+ (ref) ? URL::encode(ref.c_str()).c_str() : "",
+ (work.size()) ? URL::encode(work.c_str()).c_str() : "");
+ }
+ else
+ {
+ // Dictionary link, or something
+ buf.appendFormatted("<a href=\"sword://%s/%s\">",
+ (work.size()) ? URL::encode(work.c_str()).c_str() : u->version.c_str(),
+ (ref) ? URL::encode(ref.c_str()).c_str() : ""
+ );
+ }
+ }
+ else
+ {
+ //std::cout << "TARGET WASN'T\n";
+ }
+
+ }
+ else {
+ buf += u->lastTextNode.c_str();
+ buf += "</a>";
+
+ u->suspendTextPassThru = false;
+ }
+ }
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
diff --git a/src/modules/filters/teiplain.cpp b/src/modules/filters/teiplain.cpp
index c721d84..90b7c7c 100644
--- a/src/modules/filters/teiplain.cpp
+++ b/src/modules/filters/teiplain.cpp
@@ -1,18 +1,24 @@
/***************************************************************************
- teiplain.cpp - TEI to Plaintext filter
- -------------------
- begin : 2006-07-05
- copyright : 2006 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * teiplain.cpp - TEI to Plaintext filter
+ * -------------------
+ * begin : 2006-07-05
+ * copyright : 2006 by CrossWire Bible Society
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <teiplain.h>
diff --git a/src/modules/filters/teirtf.cpp b/src/modules/filters/teirtf.cpp
index 006f099..8560f5c 100644
--- a/src/modules/filters/teirtf.cpp
+++ b/src/modules/filters/teirtf.cpp
@@ -1,18 +1,24 @@
/***************************************************************************
- teirtf.cpp - TEI to RTF filter
- -------------------
- begin : 2006-07-03
- copyright : 2006 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * teirtf.cpp - TEI to RTF filter
+ * -------------------
+ * begin : 2006-07-03
+ * copyright : 2006 by CrossWire Bible Society
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <ctype.h>
@@ -26,6 +32,7 @@ SWORD_NAMESPACE_START
TEIRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
BiblicalText = false;
+ inOsisRef = false;
if (module) {
version = module->Name();
BiblicalText = (!strcmp(module->Type(), "Biblical Texts"));
@@ -66,10 +73,10 @@ bool TEIRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *use
}
// <hi>
- else if (!strcmp(tag.getName(), "hi")) {
+ else if (!strcmp(tag.getName(), "hi") || !strcmp(tag.getName(), "emph")) {
SWBuf rend = tag.getAttribute("rend");
if ((!tag.isEndTag()) && (!tag.isEmpty())) {
- if (rend == "ital")
+ if (rend == "ital" || rend == "italic")
buf += "{\\i1 ";
else if (rend == "bold")
buf += "{\\b1 ";
@@ -169,6 +176,25 @@ bool TEIRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *use
}
}
+ // <lb/> tag
+ else if (!strcmp(tag.getName(), "lb")) {
+ buf += "{\\par}";
+ userData->supressAdjacentWhitespace = true;
+ }
+
+ // <ref> tag
+ else if (!strcmp(tag.getName(), "ref")) {
+ if (!tag.isEndTag() && tag.getAttribute("osisRef")) {
+ buf += "{<a href=\"\">";
+ u->inOsisRef = true;
+ }
+ else if (tag.isEndTag() && u->inOsisRef) {
+ buf += "</a>}";
+ u->inOsisRef = false;
+ }
+ }
+
+
else {
return false; // we still didn't handle token
}
diff --git a/src/modules/filters/thmlfootnotes.cpp b/src/modules/filters/thmlfootnotes.cpp
index 23c43b4..e75311a 100644
--- a/src/modules/filters/thmlfootnotes.cpp
+++ b/src/modules/filters/thmlfootnotes.cpp
@@ -2,9 +2,26 @@
*
* thmlfootnotes - SWFilter descendant to hide or show footnotes
* in a ThML module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <stdlib.h>
#include <stdio.h>
#include <thmlfootnotes.h>
@@ -39,7 +56,13 @@ char ThMLFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *m
SWBuf refs = "";
int footnoteNum = 1;
char buf[254];
- VerseKey parser = key->getText();
+ SWKey *p = (module) ? module->CreateKey() : (key) ? key->clone() : new VerseKey();
+ VerseKey *parser = SWDYNAMIC_CAST(VerseKey, p);
+ if (!parser) {
+ delete p;
+ parser = new VerseKey();
+ }
+ *parser = key->getText();
SWBuf orig = text;
const char *from = orig.c_str();
@@ -78,7 +101,7 @@ char ThMLFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *m
startTag.setAttribute("swordFootnote", buf);
if ((startTag.getAttribute("type")) && (!strcmp(startTag.getAttribute("type"), "crossReference"))) {
if (!refs.length())
- refs = parser.ParseVerseList(tagText.c_str(), parser, true).getRangeText();
+ refs = parser->ParseVerseList(tagText.c_str(), *parser, true).getRangeText();
module->getEntryAttributes()["Footnote"][buf]["refList"] = refs.c_str();
}
}
@@ -118,6 +141,7 @@ char ThMLFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *m
}
else tagText += *from;
}
+ delete parser;
return 0;
}
diff --git a/src/modules/filters/thmlgbf.cpp b/src/modules/filters/thmlgbf.cpp
index f8703b1..e2e8e1c 100644
--- a/src/modules/filters/thmlgbf.cpp
+++ b/src/modules/filters/thmlgbf.cpp
@@ -1,18 +1,25 @@
/***************************************************************************
- thmlgbf.cpp - ThML to GBF filter
- -------------------
- begin : 1999-10-28
- copyright : 2001 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * thmlgbf.cpp - ThML to GBF filter
+ * -------------------
+ * begin : 1999-10-28
+ * copyright : 2001 by CrossWire Bible Society
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <thmlgbf.h>
diff --git a/src/modules/filters/thmlheadings.cpp b/src/modules/filters/thmlheadings.cpp
index 4d6134f..e2b7c97 100644
--- a/src/modules/filters/thmlheadings.cpp
+++ b/src/modules/filters/thmlheadings.cpp
@@ -2,9 +2,24 @@
*
* thmlheadings - SWFilter descendant to hide or show headings
* in a ThML module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <thmlheadings.h>
diff --git a/src/modules/filters/thmlhtml.cpp b/src/modules/filters/thmlhtml.cpp
index efb09cd..4c66b87 100644
--- a/src/modules/filters/thmlhtml.cpp
+++ b/src/modules/filters/thmlhtml.cpp
@@ -1,18 +1,25 @@
/***************************************************************************
- thmlhtml.cpp - ThML to HTML filter
- -------------------
- begin : 1999-10-27
- copyright : 2001 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * thmlhtml.cpp - ThML to HTML filter
+ * -------------------
+ * begin : 1999-10-27
+ * copyright : 2001 by CrossWire Bible Society
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <thmlhtml.h>
diff --git a/src/modules/filters/thmlhtmlhref.cpp b/src/modules/filters/thmlhtmlhref.cpp
index 0596f75..83f5a80 100644
--- a/src/modules/filters/thmlhtmlhref.cpp
+++ b/src/modules/filters/thmlhtmlhref.cpp
@@ -1,18 +1,26 @@
/***************************************************************************
- thmlhtmlhref.cpp - ThML to HTML filter with hrefs
- -------------------
- begin : 2001-09-03
- copyright : 2001 by CrossWire Bible Society
- ***************************************************************************/
+ * thmlhtmlhref.cpp - ThML to HTML filter with hrefs
+ * -------------------
+ * begin : 2001-09-03
+ * copyright : 2001 by CrossWire Bible Society
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
#include <stdlib.h>
#include <thmlhtmlhref.h>
#include <swmodule.h>
@@ -320,8 +328,8 @@ bool ThMLHTMLHREF::handleToken(SWBuf &buf, const char *token, BasicFilterUserDat
URL::encode(u->version.c_str()).c_str());
for (c = token; *c; c++) {
- if ((*c == '/') && (*(c+1) == '\0'))
- continue;
+ if ((*c == '/') && (*(c+1) == '\0'))
+ continue;
if (c == src) {
for (;((*c) && (*c != '"')); c++)
buf += *c;
diff --git a/src/modules/filters/thmllemma.cpp b/src/modules/filters/thmllemma.cpp
index 3e5761d..53eec58 100644
--- a/src/modules/filters/thmllemma.cpp
+++ b/src/modules/filters/thmllemma.cpp
@@ -2,9 +2,24 @@
*
* thmllemma - SWFilter descendant to hide or show lemmas
* in a ThML module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <thmllemma.h>
diff --git a/src/modules/filters/thmlmorph.cpp b/src/modules/filters/thmlmorph.cpp
index 0fbef56..d3cf597 100644
--- a/src/modules/filters/thmlmorph.cpp
+++ b/src/modules/filters/thmlmorph.cpp
@@ -2,9 +2,24 @@
*
* thmlmorph - SWFilter descendant to hide or show morph tags
* in a ThML module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <thmlmorph.h>
diff --git a/src/modules/filters/thmlosis.cpp b/src/modules/filters/thmlosis.cpp
index 939be82..25fdf23 100644
--- a/src/modules/filters/thmlosis.cpp
+++ b/src/modules/filters/thmlosis.cpp
@@ -2,9 +2,24 @@
*
* thmlstrongs - SWFilter descendant to hide or show strongs number
* in a ThML module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
@@ -326,7 +341,7 @@ char ThMLOSIS::processText(SWBuf &text, const SWKey *key, const SWModule *module
}
// Footnote
- if (!strcmp(token, "note")) {
+ if (!strncmp(token, "note", 4)) {
//pushString(&to, "<note>");
text.append("<note>");
newText = true;
@@ -534,23 +549,23 @@ char ThMLOSIS::processText(SWBuf &text, const SWKey *key, const SWModule *module
text = ref + text;
if (vkey->Verse()) {
- VerseKey tmp;
- tmp = *vkey;
- tmp.AutoNormalize(0);
- tmp.Headings(1);
-
+ VerseKey *tmp = (VerseKey *)vkey->clone();
+ *tmp = *vkey;
+ tmp->AutoNormalize(0);
+ tmp->Headings(1);
+
text += "</verse>";
-
- tmp = MAXVERSE;
- if (*vkey == tmp) {
- tmp.Verse(0);
+
+ *tmp = MAXVERSE;
+ if (*vkey == *tmp) {
+ tmp->Verse(0);
// sprintf(ref, "\t</div>");
// pushString(&to, ref);
- tmp = MAXCHAPTER;
- tmp = MAXVERSE;
- if (*vkey == tmp) {
- tmp.Chapter(0);
- tmp.Verse(0);
+ *tmp = MAXCHAPTER;
+ *tmp = MAXVERSE;
+ if (*vkey == *tmp) {
+ tmp->Chapter(0);
+ tmp->Verse(0);
// sprintf(ref, "\t</div>");
// pushString(&to, ref);
/*
@@ -561,6 +576,7 @@ char ThMLOSIS::processText(SWBuf &text, const SWKey *key, const SWModule *module
*/
}
}
+ delete tmp;
}
// else if (vkey->Chapter()) {
// sprintf(ref, "\t<div type=\"chapter\" osisID=\"%s\">", vkey->getOSISRef());
diff --git a/src/modules/filters/thmlplain.cpp b/src/modules/filters/thmlplain.cpp
index 8f8379a..8c9358f 100644
--- a/src/modules/filters/thmlplain.cpp
+++ b/src/modules/filters/thmlplain.cpp
@@ -2,9 +2,24 @@
*
* thmlplain - SWFilter descendant to strip out all ThML tags or convert to
* ASCII rendered symbols.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <thmlplain.h>
#include <swbuf.h>
@@ -55,104 +70,104 @@ char ThMLPlain::processText(SWBuf &text, const SWKey *key, const SWModule *modul
else if (!strncmp("amp", token, 3)) text += '&';
else if (!strncmp("lt", token, 2)) text += '<';
else if (!strncmp("gt", token, 2)) text += '>';
- else if (!strncmp("brvbar", token, 6)) text += '';
- else if (!strncmp("sect", token, 4)) text += '';
- else if (!strncmp("copy", token, 4)) text += '';
- else if (!strncmp("laquo", token, 5)) text += '';
- else if (!strncmp("reg", token, 3)) text += '';
- else if (!strncmp("acute", token, 5)) text += '';
- else if (!strncmp("para", token, 4)) text += '';
- else if (!strncmp("raquo", token, 5)) text += '';
+ else if (!strncmp("brvbar", token, 6)) text += "¦";
+ else if (!strncmp("sect", token, 4)) text += "§";
+ else if (!strncmp("copy", token, 4)) text += "©";
+ else if (!strncmp("laquo", token, 5)) text += "«";
+ else if (!strncmp("reg", token, 3)) text += "®";
+ else if (!strncmp("acute", token, 5)) text += "´";
+ else if (!strncmp("para", token, 4)) text += "¶";
+ else if (!strncmp("raquo", token, 5)) text += "»";
- else if (!strncmp("Aacute", token, 6)) text += '';
- else if (!strncmp("Agrave", token, 6)) text += '';
- else if (!strncmp("Acirc", token, 5)) text += '';
- else if (!strncmp("Auml", token, 4)) text += '';
- else if (!strncmp("Atilde", token, 6)) text += '';
- else if (!strncmp("Aring", token, 5)) text += '';
- else if (!strncmp("aacute", token, 6)) text += '';
- else if (!strncmp("agrave", token, 6)) text += '';
- else if (!strncmp("acirc", token, 5)) text += '';
- else if (!strncmp("auml", token, 4)) text += '';
- else if (!strncmp("atilde", token, 6)) text += '';
- else if (!strncmp("aring", token, 5)) text += '';
- else if (!strncmp("Eacute", token, 6)) text += '';
- else if (!strncmp("Egrave", token, 6)) text += '';
- else if (!strncmp("Ecirc", token, 5)) text += '';
- else if (!strncmp("Euml", token, 4)) text += '';
- else if (!strncmp("eacute", token, 6)) text += '';
- else if (!strncmp("egrave", token, 6)) text += '';
- else if (!strncmp("ecirc", token, 5)) text += '';
- else if (!strncmp("euml", token, 4)) text += '';
- else if (!strncmp("Iacute", token, 6)) text += '';
- else if (!strncmp("Igrave", token, 6)) text += '';
- else if (!strncmp("Icirc", token, 5)) text += '';
- else if (!strncmp("Iuml", token, 4)) text += '';
- else if (!strncmp("iacute", token, 6)) text += '';
- else if (!strncmp("igrave", token, 6)) text += '';
- else if (!strncmp("icirc", token, 5)) text += '';
- else if (!strncmp("iuml", token, 4)) text += '';
- else if (!strncmp("Oacute", token, 6)) text += '';
- else if (!strncmp("Ograve", token, 6)) text += '';
- else if (!strncmp("Ocirc", token, 5)) text += '';
- else if (!strncmp("Ouml", token, 4)) text += '';
- else if (!strncmp("Otilde", token, 6)) text += '';
- else if (!strncmp("oacute", token, 6)) text += '';
- else if (!strncmp("ograve", token, 6)) text += '';
- else if (!strncmp("ocirc", token, 5)) text += '';
- else if (!strncmp("ouml", token, 4)) text += '';
- else if (!strncmp("otilde", token, 6)) text += '';
- else if (!strncmp("Uacute", token, 6)) text += '';
- else if (!strncmp("Ugrave", token, 6)) text += '';
- else if (!strncmp("Ucirc", token, 5)) text += '';
- else if (!strncmp("Uuml", token, 4)) text += '';
- else if (!strncmp("uacute", token, 6)) text += '';
- else if (!strncmp("ugrave", token, 6)) text += '';
- else if (!strncmp("ucirc", token, 5)) text += '';
- else if (!strncmp("uuml", token, 4)) text += '';
- else if (!strncmp("Yacute", token, 6)) text += '';
- else if (!strncmp("yacute", token, 6)) text += '';
- else if (!strncmp("yuml", token, 4)) text += '';
+ else if (!strncmp("Aacute", token, 6)) text += "Á";
+ else if (!strncmp("Agrave", token, 6)) text += "À";
+ else if (!strncmp("Acirc", token, 5)) text += "Â";
+ else if (!strncmp("Auml", token, 4)) text += "Ä";
+ else if (!strncmp("Atilde", token, 6)) text += "Ã";
+ else if (!strncmp("Aring", token, 5)) text += "Å";
+ else if (!strncmp("aacute", token, 6)) text += "á";
+ else if (!strncmp("agrave", token, 6)) text += "à";
+ else if (!strncmp("acirc", token, 5)) text += "â";
+ else if (!strncmp("auml", token, 4)) text += "ä";
+ else if (!strncmp("atilde", token, 6)) text += "ã";
+ else if (!strncmp("aring", token, 5)) text += "å";
+ else if (!strncmp("Eacute", token, 6)) text += "É";
+ else if (!strncmp("Egrave", token, 6)) text += "È";
+ else if (!strncmp("Ecirc", token, 5)) text += "Ê";
+ else if (!strncmp("Euml", token, 4)) text += "Ë";
+ else if (!strncmp("eacute", token, 6)) text += "é";
+ else if (!strncmp("egrave", token, 6)) text += "è";
+ else if (!strncmp("ecirc", token, 5)) text += "ê";
+ else if (!strncmp("euml", token, 4)) text += "ë";
+ else if (!strncmp("Iacute", token, 6)) text += "Í";
+ else if (!strncmp("Igrave", token, 6)) text += "Ì";
+ else if (!strncmp("Icirc", token, 5)) text += "Î";
+ else if (!strncmp("Iuml", token, 4)) text += "Ï";
+ else if (!strncmp("iacute", token, 6)) text += "í";
+ else if (!strncmp("igrave", token, 6)) text += "ì";
+ else if (!strncmp("icirc", token, 5)) text += "î";
+ else if (!strncmp("iuml", token, 4)) text += "ï";
+ else if (!strncmp("Oacute", token, 6)) text += "Ó";
+ else if (!strncmp("Ograve", token, 6)) text += "Ò";
+ else if (!strncmp("Ocirc", token, 5)) text += "Ô";
+ else if (!strncmp("Ouml", token, 4)) text += "Ö";
+ else if (!strncmp("Otilde", token, 6)) text += "Õ";
+ else if (!strncmp("oacute", token, 6)) text += "ó";
+ else if (!strncmp("ograve", token, 6)) text += "ò";
+ else if (!strncmp("ocirc", token, 5)) text += "ô";
+ else if (!strncmp("ouml", token, 4)) text += "ö";
+ else if (!strncmp("otilde", token, 6)) text += "õ";
+ else if (!strncmp("Uacute", token, 6)) text += "Ú";
+ else if (!strncmp("Ugrave", token, 6)) text += "Ù";
+ else if (!strncmp("Ucirc", token, 5)) text += "Û";
+ else if (!strncmp("Uuml", token, 4)) text += "Ü";
+ else if (!strncmp("uacute", token, 6)) text += "ú";
+ else if (!strncmp("ugrave", token, 6)) text += "ù";
+ else if (!strncmp("ucirc", token, 5)) text += "û";
+ else if (!strncmp("uuml", token, 4)) text += "ü";
+ else if (!strncmp("Yacute", token, 6)) text += "Ý";
+ else if (!strncmp("yacute", token, 6)) text += "ý";
+ else if (!strncmp("yuml", token, 4)) text += "ÿ";
- else if (!strncmp("deg", token, 3)) text += '';
- else if (!strncmp("plusmn", token, 6)) text += '';
- else if (!strncmp("sup2", token, 4)) text += '';
- else if (!strncmp("sup3", token, 4)) text += '';
- else if (!strncmp("sup1", token, 4)) text += '';
- else if (!strncmp("nbsp", token, 4)) text += '';
- else if (!strncmp("pound", token, 5)) text += '';
- else if (!strncmp("cent", token, 4)) text += '';
- else if (!strncmp("frac14", token, 6)) text += '';
- else if (!strncmp("frac12", token, 6)) text += '';
- else if (!strncmp("frac34", token, 6)) text += '';
- else if (!strncmp("iquest", token, 6)) text += '';
- else if (!strncmp("iexcl", token, 5)) text += '';
- else if (!strncmp("ETH", token, 3)) text += '';
- else if (!strncmp("eth", token, 3)) text += '';
- else if (!strncmp("THORN", token, 5)) text += '';
- else if (!strncmp("thorn", token, 5)) text += '';
- else if (!strncmp("AElig", token, 5)) text += '';
- else if (!strncmp("aelig", token, 5)) text += '';
- else if (!strncmp("Oslash", token, 6)) text += '';
- else if (!strncmp("curren", token, 6)) text += '';
- else if (!strncmp("Ccedil", token, 6)) text += '';
- else if (!strncmp("ccedil", token, 6)) text += '';
- else if (!strncmp("szlig", token, 5)) text += '';
- else if (!strncmp("Ntilde", token, 6)) text += '';
- else if (!strncmp("ntilde", token, 6)) text += '';
- else if (!strncmp("yen", token, 3)) text += '';
- else if (!strncmp("not", token, 3)) text += '';
- else if (!strncmp("ordf", token, 4)) text += '';
- else if (!strncmp("uml", token, 3)) text += '';
- else if (!strncmp("shy", token, 3)) text += '';
- else if (!strncmp("macr", token, 4)) text += '';
- else if (!strncmp("micro", token, 5)) text += "";
- else if (!strncmp("middot", token, 6)) text +="";
- else if (!strncmp("cedil", token, 5)) text += "";
- else if (!strncmp("ordm", token, 4)) text += "";
- else if (!strncmp("times", token, 5)) text += "";
- else if (!strncmp("divide", token, 6)) text +="";
- else if (!strncmp("oslash", token, 6)) text +="";
+ else if (!strncmp("deg", token, 3)) text += "°";
+ else if (!strncmp("plusmn", token, 6)) text += "±";
+ else if (!strncmp("sup2", token, 4)) text += "²";
+ else if (!strncmp("sup3", token, 4)) text += "³";
+ else if (!strncmp("sup1", token, 4)) text += "¹";
+ else if (!strncmp("nbsp", token, 4)) text += "º";
+ else if (!strncmp("pound", token, 5)) text += "£";
+ else if (!strncmp("cent", token, 4)) text += "¢";
+ else if (!strncmp("frac14", token, 6)) text += "¼";
+ else if (!strncmp("frac12", token, 6)) text += "½";
+ else if (!strncmp("frac34", token, 6)) text += "¾";
+ else if (!strncmp("iquest", token, 6)) text += "¿";
+ else if (!strncmp("iexcl", token, 5)) text += "¡";
+ else if (!strncmp("ETH", token, 3)) text += "Ð";
+ else if (!strncmp("eth", token, 3)) text += "ð";
+ else if (!strncmp("THORN", token, 5)) text += "Þ";
+ else if (!strncmp("thorn", token, 5)) text += "þ";
+ else if (!strncmp("AElig", token, 5)) text += "Æ";
+ else if (!strncmp("aelig", token, 5)) text += "æ";
+ else if (!strncmp("Oslash", token, 6)) text += "Ø";
+ else if (!strncmp("curren", token, 6)) text += "¤";
+ else if (!strncmp("Ccedil", token, 6)) text += "Ç";
+ else if (!strncmp("ccedil", token, 6)) text += "ç";
+ else if (!strncmp("szlig", token, 5)) text += "ß";
+ else if (!strncmp("Ntilde", token, 6)) text += "Ñ";
+ else if (!strncmp("ntilde", token, 6)) text += "ñ";
+ else if (!strncmp("yen", token, 3)) text += "¥";
+ else if (!strncmp("not", token, 3)) text += "¬";
+ else if (!strncmp("ordf", token, 4)) text += "ª";
+ else if (!strncmp("uml", token, 3)) text += "¨";
+ else if (!strncmp("shy", token, 3)) text += "­";
+ else if (!strncmp("macr", token, 4)) text += "¯";
+ else if (!strncmp("micro", token, 5)) text += "µ";
+ else if (!strncmp("middot", token, 6)) text += "·";
+ else if (!strncmp("cedil", token, 5)) text += "¸";
+ else if (!strncmp("ordm", token, 4)) text += "º";
+ else if (!strncmp("times", token, 5)) text += "×";
+ else if (!strncmp("divide", token, 6)) text += "÷";
+ else if (!strncmp("oslash", token, 6)) text += "ø";
continue;
}
@@ -177,14 +192,14 @@ char ThMLPlain::processText(SWBuf &text, const SWKey *key, const SWModule *modul
}
if (!strncmp("note", token, 4)) {
text += ' ';
- text += '(';
+ text += '[';
}
else if (!strncmp("br", token, 2))
text += '\n';
else if (!strncmp("/p", token, 2))
text += '\n';
else if (!strncmp("/note", token, 5)) {
- text += ')';
+ text += ']';
text += ' ';
}
continue;
diff --git a/src/modules/filters/thmlrtf.cpp b/src/modules/filters/thmlrtf.cpp
index 23e4a90..fdb41df 100644
--- a/src/modules/filters/thmlrtf.cpp
+++ b/src/modules/filters/thmlrtf.cpp
@@ -1,18 +1,25 @@
/***************************************************************************
- thmlrtf.cpp - ThML to RTF filter
- -------------------
- begin : 1999-10-27
- copyright : 2001 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * thmlrtf.cpp - ThML to RTF filter
+ * -------------------
+ * begin : 1999-10-27
+ * copyright : 2001 by CrossWire Bible Society
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <thmlrtf.h>
diff --git a/src/modules/filters/thmlscripref.cpp b/src/modules/filters/thmlscripref.cpp
index df2b3d2..e46d679 100644
--- a/src/modules/filters/thmlscripref.cpp
+++ b/src/modules/filters/thmlscripref.cpp
@@ -2,9 +2,24 @@
*
* thmlscripref - SWFilter descendant to hide or show scripture
* referebces in a ThML module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <thmlscripref.h>
@@ -38,7 +53,13 @@ char ThMLScripref::processText(SWBuf &text, const SWKey *key, const SWModule *mo
SWBuf refs = "";
int footnoteNum = 1;
char buf[254];
- VerseKey parser = key->getText();
+ SWKey *p = (module) ? module->CreateKey() : (key) ? key->clone() : new VerseKey();
+ VerseKey *parser = SWDYNAMIC_CAST(VerseKey, p);
+ if (!parser) {
+ delete p;
+ parser = new VerseKey();
+ }
+ *parser = key->getText();
SWBuf orig = text;
const char *from = orig.c_str();
@@ -77,8 +98,8 @@ char ThMLScripref::processText(SWBuf &text, const SWKey *key, const SWModule *mo
startTag.setAttribute("swordFootnote", buf);
SWBuf passage = startTag.getAttribute("passage");
if (passage.length())
- refs = parser.ParseVerseList(passage.c_str(), parser, true).getRangeText();
- else refs = parser.ParseVerseList(tagText.c_str(), parser, true).getRangeText();
+ refs = parser->ParseVerseList(passage.c_str(), *parser, true).getRangeText();
+ else refs = parser->ParseVerseList(tagText.c_str(), *parser, true).getRangeText();
module->getEntryAttributes()["Footnote"][buf]["refList"] = refs.c_str();
}
hide = false;
@@ -117,6 +138,7 @@ char ThMLScripref::processText(SWBuf &text, const SWKey *key, const SWModule *mo
}
else tagText += *from;
}
+ delete parser;
return 0;
}
diff --git a/src/modules/filters/thmlstrongs.cpp b/src/modules/filters/thmlstrongs.cpp
index c1ab08c..457e28b 100644
--- a/src/modules/filters/thmlstrongs.cpp
+++ b/src/modules/filters/thmlstrongs.cpp
@@ -2,9 +2,24 @@
*
* thmlstrongs - SWFilter descendant to hide or show strongs number
* in a ThML module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <thmlstrongs.h>
diff --git a/src/modules/filters/thmlvariants.cpp b/src/modules/filters/thmlvariants.cpp
index 49f9b65..4f28dbe 100644
--- a/src/modules/filters/thmlvariants.cpp
+++ b/src/modules/filters/thmlvariants.cpp
@@ -2,9 +2,24 @@
*
* thmlvariants - SWFilter descendant to hide or show textual variants
* in a ThML module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <thmlvariants.h>
#include <utilstr.h>
diff --git a/src/modules/filters/thmlwebif.cpp b/src/modules/filters/thmlwebif.cpp
index 7428754..0192703 100644
--- a/src/modules/filters/thmlwebif.cpp
+++ b/src/modules/filters/thmlwebif.cpp
@@ -1,18 +1,25 @@
/***************************************************************************
- ThMLWEBIF.cpp - ThML to HTML filter with hrefs
- -------------------
- begin : 2001-09-03
- copyright : 2001 by CrossWire Bible Society
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
+ * ThMLWEBIF.cpp - ThML to HTML filter with hrefs
+ * -------------------
+ * begin : 2001-09-03
+ * copyright : 2001 by CrossWire Bible Society
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#include <stdlib.h>
#include <thmlwebif.h>
diff --git a/src/modules/filters/thmlwordjs.cpp b/src/modules/filters/thmlwordjs.cpp
index ad8eef0..12fbeb1 100644
--- a/src/modules/filters/thmlwordjs.cpp
+++ b/src/modules/filters/thmlwordjs.cpp
@@ -2,9 +2,24 @@
*
* thmlstrongs - SWFilter descendant to hide or show strongs number
* in a ThML module.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <thmlwordjs.h>
diff --git a/src/modules/filters/unicodertf.cpp b/src/modules/filters/unicodertf.cpp
index 8c2a1f6..768aecc 100644
--- a/src/modules/filters/unicodertf.cpp
+++ b/src/modules/filters/unicodertf.cpp
@@ -2,9 +2,24 @@
*
* unicodertf - SWFilter descendant to convert a double byte unicode file
* to RTF tags
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <unicodertf.h>
diff --git a/src/modules/filters/utf16utf8.cpp b/src/modules/filters/utf16utf8.cpp
index ae0845f..a488e18 100644
--- a/src/modules/filters/utf16utf8.cpp
+++ b/src/modules/filters/utf16utf8.cpp
@@ -2,8 +2,25 @@
*
* UTF16UTF8 - SWFilter descendant to convert UTF-16 to UTF-8
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <stdlib.h>
#include <stdio.h>
diff --git a/src/modules/filters/utf8arabicpoints.cpp b/src/modules/filters/utf8arabicpoints.cpp
new file mode 100644
index 0000000..bd3169b
--- /dev/null
+++ b/src/modules/filters/utf8arabicpoints.cpp
@@ -0,0 +1,61 @@
+/******************************************************************************
+ *
+ * UTF8ArabicPoints - SWFilter descendant to remove UTF-8 Arabic vowel points
+ *
+ * $Id: utf8arabicpoints.h 1688 2008-11-30 04:42:26Z refdoc $
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <utf8arabicpoints.h>
+
+SWORD_NAMESPACE_START
+
+const char oName[] = "Arabic Vowel Points";
+const char oTip[] = "Toggles Arabic Vowel Points";
+
+const SWBuf choices[3] = {"On", "Off", ""};
+const StringList oValues(&choices[0], &choices[2]);
+
+UTF8ArabicPoints::UTF8ArabicPoints() : SWOptionFilter(oName, oTip, &oValues) {
+ setOptionValue("On");
+}
+
+UTF8ArabicPoints::~UTF8ArabicPoints(){};
+
+
+char UTF8ArabicPoints::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
+ if (!option) {
+ //The UTF-8 range 0xFC 0xE5 to 0xFC 0x63 consist of Arabic vowel marks so block those out.
+ // Also ranges 0xFE70 til OxFE7F and 0x064b-0x0655
+ SWBuf orig = text;
+ const unsigned char* from = (unsigned char*)orig.c_str();
+ for (text = ""; *from; from++) {
+ if (((*from == 0xFC) && (*(from + 1) >= 0xE5 && *(from + 1) <= 0x63)) || ((*from == 0xFE) && (*(from + 1) >= 0x70 && *(from + 1) <= 0x7F)) || ((*from == 0x06) && (*(from + 1) >= 0x4B && *(from + 1) <= 0x55))){
+ from++;
+ }
+ else {
+ text += *from;
+ }
+ }
+ }
+ return 0;
+}
+
+SWORD_NAMESPACE_END
diff --git a/src/modules/filters/utf8arshaping.cpp b/src/modules/filters/utf8arshaping.cpp
index 702fb62..09d8973 100644
--- a/src/modules/filters/utf8arshaping.cpp
+++ b/src/modules/filters/utf8arshaping.cpp
@@ -1,8 +1,24 @@
/******************************************************************************
-*
-* utf8arshaping - SWFilter descendant to perform Arabic shaping on
-* UTF-8 text
-*/
+ *
+ * utf8arshaping - SWFilter descendant to perform Arabic shaping on
+ * UTF-8 text
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#ifdef _ICU_
diff --git a/src/modules/filters/utf8bidireorder.cpp b/src/modules/filters/utf8bidireorder.cpp
index 783602c..71dc804 100644
--- a/src/modules/filters/utf8bidireorder.cpp
+++ b/src/modules/filters/utf8bidireorder.cpp
@@ -1,8 +1,24 @@
/******************************************************************************
-*
-* utf8cnormalizer - SWFilter descendant to perform reordering of UTF-8
-* text to visual order according to Unicode BiDi
-*/
+ *
+ * utf8bidireorder - SWFilter descendant to perform reordering of UTF-8
+ * text to visual order according to Unicode BiDi
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#ifdef _ICU_
diff --git a/src/modules/filters/utf8cantillation.cpp b/src/modules/filters/utf8cantillation.cpp
index 6213620..73785b4 100644
--- a/src/modules/filters/utf8cantillation.cpp
+++ b/src/modules/filters/utf8cantillation.cpp
@@ -2,9 +2,24 @@
*
* UTF8Cantillation - SWFilter descendant to remove UTF-8 Hebrew cantillation
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <utf8cantillation.h>
diff --git a/src/modules/filters/utf8greekaccents.cpp b/src/modules/filters/utf8greekaccents.cpp
index df85968..5fdb047 100644
--- a/src/modules/filters/utf8greekaccents.cpp
+++ b/src/modules/filters/utf8greekaccents.cpp
@@ -2,9 +2,24 @@
*
* UTF8GreekAccents - SWFilter descendant to remove UTF-8 Greek accents
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <utf8greekaccents.h>
diff --git a/src/modules/filters/utf8hebrewpoints.cpp b/src/modules/filters/utf8hebrewpoints.cpp
index 0476db8..ba7c746 100644
--- a/src/modules/filters/utf8hebrewpoints.cpp
+++ b/src/modules/filters/utf8hebrewpoints.cpp
@@ -2,9 +2,24 @@
*
* UTF8HebrewPoints - SWFilter descendant to remove UTF-8 Hebrew vowel points
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <utf8hebrewpoints.h>
diff --git a/src/modules/filters/utf8html.cpp b/src/modules/filters/utf8html.cpp
index 088f669..0d1dce3 100644
--- a/src/modules/filters/utf8html.cpp
+++ b/src/modules/filters/utf8html.cpp
@@ -2,9 +2,24 @@
*
* utf8html - SWFilter descendant to convert a UTF-8 stream to HTML escapes
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <utf8html.h>
diff --git a/src/modules/filters/utf8latin1.cpp b/src/modules/filters/utf8latin1.cpp
index 08b288d..25df0c1 100644
--- a/src/modules/filters/utf8latin1.cpp
+++ b/src/modules/filters/utf8latin1.cpp
@@ -2,6 +2,22 @@
*
* UTF8Latin1 - SWFilter descendant to convert UTF-8 to Latin-1
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
#include <stdlib.h>
diff --git a/src/modules/filters/utf8nfc.cpp b/src/modules/filters/utf8nfc.cpp
index 15b76b5..82d404e 100644
--- a/src/modules/filters/utf8nfc.cpp
+++ b/src/modules/filters/utf8nfc.cpp
@@ -1,8 +1,24 @@
/******************************************************************************
-*
-* utf8nfc - SWFilter descendant to perform NFC (canonical composition
-* normalization) on UTF-8 text
-*/
+ *
+ * utf8nfc - SWFilter descendant to perform NFC (canonical composition
+ * normalization) on UTF-8 text
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#ifdef _ICU_
diff --git a/src/modules/filters/utf8nfkd.cpp b/src/modules/filters/utf8nfkd.cpp
index a19d36b..1d6acf3 100644
--- a/src/modules/filters/utf8nfkd.cpp
+++ b/src/modules/filters/utf8nfkd.cpp
@@ -1,8 +1,24 @@
/******************************************************************************
-*
-* utf8nfkd - SWFilter descendant to perform NFKD (compatability decomposition
-* normalization) on UTF-8 text
-*/
+ *
+ * utf8nfkd - SWFilter descendant to perform NFKD (compatability decomposition
+ * normalization) on UTF-8 text
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#ifdef _ICU_
diff --git a/src/modules/filters/utf8transliterator.cpp b/src/modules/filters/utf8transliterator.cpp
index d99741b..552ec3e 100644
--- a/src/modules/filters/utf8transliterator.cpp
+++ b/src/modules/filters/utf8transliterator.cpp
@@ -1,8 +1,24 @@
/******************************************************************************
-*
-* utf8transliterators - SWFilter descendant to transliterate between
-* ICU-supported scripts.
-*/
+ *
+ * utf8transliterators - SWFilter descendant to transliterate between
+ * ICU-supported scripts.
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
#ifdef _ICU_
@@ -25,51 +41,48 @@ SWORD_NAMESPACE_START
const char UTF8Transliterator::optionstring[NUMTARGETSCRIPTS][16] = {
"Off",
"Latin",
- "IPA",
- "Basic Latin",
- "SBL",
- "TC",
- "Beta",
- "BGreek",
- "SERA",
- "Hugoye",
- "UNGEGN",
- "ISO",
- "ALA-LC",
- "BGN-PCGN",
- "Greek",
- "Hebrew",
- "Cyrillic",
- "Arabic",
- "Syriac",
- "Katakana",
- "Hiragana",
- "Hangul",
- "Devanagari",
- "Tamil",
- "Bengali",
- "Gurmukhi",
- "Gujarati",
- "Oriya",
- "Telugu",
- "Kannada",
- "Malayalam",
- "Thai",
- "Georgian",
- "Armenian",
- "Ethiopic",
- "Gothic",
- "Ugaritic",
- "Coptic",
- "Meroitic",
- "Linear B",
- "Cypriot",
- "Runic",
- "Ogham",
- "Thaana",
- "Glagolitic",
-// "Tengwar",
-// "Cirth"
+ // "IPA",
+ // "Basic Latin",
+ // "SBL",
+ // "TC",
+ // "Beta",
+ // "BGreek",
+ // "SERA",
+ // "Hugoye",
+ // "UNGEGN",
+ // "ISO",
+ // "ALA-LC",
+ // "BGN",
+ // "Greek",
+ // "Hebrew",
+ // "Cyrillic",
+ // "Arabic",
+ // "Syriac",
+ // "Katakana",
+ // "Hiragana",
+ // "Hangul",
+ // "Devanagari",
+ // "Tamil",
+ // "Bengali",
+ // "Gurmukhi",
+ // "Gujarati",
+ // "Oriya",
+ // "Telugu",
+ // "Kannada",
+ // "Malayalam",
+ // "Thai",
+ // "Georgian",
+ // "Armenian",
+ // "Ethiopic",
+ // "Gothic",
+ // "Ugaritic",
+ // "Coptic",
+ // "Linear B",
+ // "Cypriot",
+ // "Runic",
+ // "Ogham",
+ // "Thaana",
+ // "Glagolitic",
};
const char UTF8Transliterator::optName[] = "Transliteration";
@@ -128,6 +141,11 @@ UTF8Transliterator::UTF8Transliterator() {
#endif
}
+
+UTF8Transliterator::~UTF8Transliterator() {
+}
+
+
void UTF8Transliterator::Load(UErrorCode &status)
{
#ifndef _ICUSWORD_
@@ -374,19 +392,19 @@ char UTF8Transliterator::processText(SWBuf &text, const SWKey *key, const SWModu
case UBLOCK_MALAYALAM: scripts[SE_MALAYALAM] = true; break;
case UBLOCK_THAI: scripts[SE_THAI] = true; break;
case UBLOCK_GEORGIAN: scripts[SE_GEORGIAN] = true; break;
- case UBLOCK_ARMENIAN: scripts[SE_ARMENIAN] = true; break;
- case UBLOCK_ETHIOPIC: scripts[SE_ETHIOPIC] = true; break;
- case UBLOCK_GOTHIC: scripts[SE_GOTHIC] = true; break;
- case UBLOCK_UGARITIC: scripts[SE_UGARITIC] = true; break;
-// case UBLOCK_MEROITIC: scripts[SE_MEROITIC] = true; break;
-// case UBLOCK_LINEARB: scripts[SE_LINEARB] = true; break;
-// case UBLOCK_CYPRIOT: scripts[SE_CYPRIOT] = true; break;
- case UBLOCK_RUNIC: scripts[SE_RUNIC] = true; break;
- case UBLOCK_OGHAM: scripts[SE_OGHAM] = true; break;
- case UBLOCK_THAANA: scripts[SE_THAANA] = true; break;
-// case UBLOCK_GLAGOLITIC: scripts[SE_GLAGOLITIC] = true; break;
-// case UBLOCK_TENGWAR: scripts[SE_TENGWAR] = true; break;
-// case UBLOCK_CIRTH: scripts[SE_CIRTH] = true; break;
+ case UBLOCK_ARMENIAN: scripts[SE_ARMENIAN] = true; break;
+ case UBLOCK_ETHIOPIC: scripts[SE_ETHIOPIC] = true; break;
+ case UBLOCK_GOTHIC: scripts[SE_GOTHIC] = true; break;
+ case UBLOCK_UGARITIC: scripts[SE_UGARITIC] = true; break;
+// case UBLOCK_MEROITIC: scripts[SE_MEROITIC] = true; break;
+ case UBLOCK_LINEAR_B_SYLLABARY: scripts[SE_LINEARB] = true; break;
+ case UBLOCK_CYPRIOT_SYLLABARY: scripts[SE_CYPRIOT] = true; break;
+ case UBLOCK_RUNIC: scripts[SE_RUNIC] = true; break;
+ case UBLOCK_OGHAM: scripts[SE_OGHAM] = true; break;
+ case UBLOCK_THAANA: scripts[SE_THAANA] = true; break;
+ case UBLOCK_GLAGOLITIC: scripts[SE_GLAGOLITIC] = true; break;
+// case UBLOCK_TENGWAR: scripts[SE_TENGWAR] = true; break;
+// case UBLOCK_CIRTH: scripts[SE_CIRTH] = true; break;
case UBLOCK_CJK_RADICALS_SUPPLEMENT:
case UBLOCK_KANGXI_RADICALS:
case UBLOCK_IDEOGRAPHIC_DESCRIPTION_CHARACTERS:
@@ -445,8 +463,8 @@ char UTF8Transliterator::processText(SWBuf &text, const SWKey *key, const SWModu
addTrans("Greek-Latin/ISO", &ID);
else if (option == SE_ALALC)
addTrans("Greek-Latin/ALALC", &ID);
- else if (option == SE_BGNPCGN)
- addTrans("Greek-Latin/BGNPCGN", &ID);
+ else if (option == SE_BGN)
+ addTrans("Greek-Latin/BGN", &ID);
else if (option == SE_IPA)
addTrans("Greek-IPA/Ancient", &ID);
else {
@@ -522,8 +540,8 @@ char UTF8Transliterator::processText(SWBuf &text, const SWKey *key, const SWModu
addTrans("Georgian-Latin/ISO", &ID);
else if (option == SE_ALALC)
addTrans("Georgian-Latin/ALALC", &ID);
- else if (option == SE_BGNPCGN)
- addTrans("Georgian-Latin/BGNPCGN", &ID);
+ else if (option == SE_BGN)
+ addTrans("Georgian-Latin/BGN", &ID);
else if (option == SE_IPA)
addTrans("Georgian-IPA", &ID);
else {
@@ -536,8 +554,8 @@ char UTF8Transliterator::processText(SWBuf &text, const SWKey *key, const SWModu
addTrans("Armenian-Latin/ISO", &ID);
else if (option == SE_ALALC)
addTrans("Armenian-Latin/ALALC", &ID);
- else if (option == SE_BGNPCGN)
- addTrans("Armenian-Latin/BGNPCGN", &ID);
+ else if (option == SE_BGN)
+ addTrans("Armenian-Latin/BGN", &ID);
else if (option == SE_IPA)
addTrans("Armenian-IPA", &ID);
else {
@@ -600,8 +618,8 @@ char UTF8Transliterator::processText(SWBuf &text, const SWKey *key, const SWModu
if (scripts[SE_THAANA]) {
if (option == SE_ALALC)
addTrans("Thaana-Latin/ALALC", &ID);
- else if (option == SE_BGNPCGN)
- addTrans("Thaana-Latin/BGNPCGN", &ID);
+ else if (option == SE_BGN)
+ addTrans("Thaana-Latin/BGN", &ID);
else {
addTrans("Thaana-Latin", &ID);
scripts[SE_LATIN] = true;
diff --git a/src/modules/filters/utf8utf16.cpp b/src/modules/filters/utf8utf16.cpp
index 5c1614c..a770d5f 100644
--- a/src/modules/filters/utf8utf16.cpp
+++ b/src/modules/filters/utf8utf16.cpp
@@ -2,12 +2,30 @@
*
* UTF8UTF16 - SWFilter descendant to convert UTF-8 to UTF-16
*
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
#include <stdlib.h>
#include <stdio.h>
+#include <sysdata.h>
#include <utf8utf16.h>
+#include <utilstr.h>
#include <swbuf.h>
SWORD_NAMESPACE_START
@@ -15,61 +33,36 @@ SWORD_NAMESPACE_START
UTF8UTF16::UTF8UTF16() {
}
+
char UTF8UTF16::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
const unsigned char *from;
- unsigned long ch;
- signed short utf16;
- unsigned char from2[7];
-
SWBuf orig = text;
from = (const unsigned char *)orig.c_str();
// -------------------------------
- for (text = ""; *from; from++) {
- ch = 0;
- //case: ANSI
- if ((*from & 128) != 128) {
+ text = "";
+ while (*from) {
+
+ __u32 ch = getUniCharFromUTF8(&from);
+
+ if (!ch) continue; // invalid char
+
+ if (ch < 0x10000) {
text.setSize(text.size()+2);
- *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short)*from;
- continue;
- }
- //case: Invalid UTF-8 (illegal continuing byte in initial position)
- if ((*from & 128) && ((*from & 64) != 64)) {
- continue;
+ *((__u16 *)(text.getRawData()+(text.size()-2))) = (__u16)ch;
}
- //case: 2+ byte codepoint
- from2[0] = *from;
- from2[0] <<= 1;
- int subsequent;
- for (subsequent = 1; (from2[0] & 128) && (subsequent < 7); subsequent++) {
- from2[0] <<= 1;
- from2[subsequent] = from[subsequent];
- from2[subsequent] &= 63;
- ch <<= 6;
- ch |= from2[subsequent];
+ else {
+ __u16 utf16;
+ utf16 = (__s16)((ch - 0x10000) / 0x400 + 0xD800);
+ text.setSize(text.size()+4);
+ *((__u16 *)(text.getRawData()+(text.size()-4))) = utf16;
+ utf16 = (__s16)((ch - 0x10000) % 0x400 + 0xDC00);
+ *((__u16 *)(text.getRawData()+(text.size()-2))) = utf16;
}
- subsequent--;
- from2[0] <<= 1;
- char significantFirstBits = 8 - (2+subsequent);
-
- ch |= (((short)from2[0]) << (((6*subsequent)+significantFirstBits)-8));
- from += subsequent;
- if (ch < 0x10000) {
- text.setSize(text.size()+2);
- *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short)ch;
- }
- else {
- utf16 = (signed short)((ch - 0x10000) / 0x400 + 0xD800);
- text.setSize(text.size()+2);
- *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short)utf16;
- utf16 = (signed short)((ch - 0x10000) % 0x400 + 0xDC00);
- text.setSize(text.size()+2);
- *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short)utf16;
- }
}
text.setSize(text.size()+2);
- *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short)0;
+ *((__u16 *)(text.getRawData()+(text.size()-2))) = (__u16)0;
return 0;
diff --git a/src/modules/genbook/rawgenbook/rawgenbook.cpp b/src/modules/genbook/rawgenbook/rawgenbook.cpp
index 22cc51f..eff68f5 100644
--- a/src/modules/genbook/rawgenbook/rawgenbook.cpp
+++ b/src/modules/genbook/rawgenbook/rawgenbook.cpp
@@ -1,9 +1,26 @@
/******************************************************************************
- * rawtext.cpp - code for class 'RawGenBook'- a module that reads raw text files:
- * ot and nt using indexs ??.bks ??.cps ??.vss
+ * rawtext.cpp - code for class 'RawGenBook'- a module that reads raw text
+ * files: ot and nt using indexs ??.bks ??.cps ??.vss
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <stdio.h>
#include <fcntl.h>
@@ -82,34 +99,16 @@ SWBuf &RawGenBook::getRawEntryBuf() {
__u32 offset = 0;
__u32 size = 0;
- TreeKey *key = 0;
- SWTRY {
- key = SWDYNAMIC_CAST(TreeKey, (this->key));
- }
- SWCATCH ( ... ) {}
-
- if (!key) {
- VerseTreeKey *tkey = 0;
- SWTRY {
- tkey = SWDYNAMIC_CAST(VerseTreeKey, (this->key));
- }
- SWCATCH ( ... ) {}
- if (tkey) key = tkey->getTreeKey();
- }
-
- if (!key) {
- key = (TreeKeyIdx *)CreateKey();
- (*key) = *(this->key);
- }
+ const TreeKey &key = getTreeKey();
int dsize;
- key->getUserData(&dsize);
+ key.getUserData(&dsize);
entryBuf = "";
if (dsize > 7) {
- memcpy(&offset, key->getUserData(), 4);
+ memcpy(&offset, key.getUserData(), 4);
offset = swordtoarch32(offset);
- memcpy(&size, key->getUserData() + 4, 4);
+ memcpy(&size, key.getUserData() + 4, 4);
size = swordtoarch32(size);
entrySize = size; // support getEntrySize call
@@ -120,15 +119,12 @@ SWBuf &RawGenBook::getRawEntryBuf() {
bdtfd->read(entryBuf.getRawData(), size);
rawFilter(entryBuf, 0); // hack, decipher
- rawFilter(entryBuf, key);
+ rawFilter(entryBuf, &key);
// if (!isUnicode())
- RawStr::prepText(entryBuf);
+ SWModule::prepText(entryBuf);
}
- if (key != this->key) // free our key if we created a VerseKey
- delete key;
-
return entryBuf;
}
@@ -137,7 +133,7 @@ void RawGenBook::setEntry(const char *inbuf, long len) {
__u32 offset = archtosword32(bdtfd->seek(0, SEEK_END));
__u32 size = 0;
- TreeKeyIdx *key = ((TreeKeyIdx *)this->key);
+ TreeKeyIdx *key = ((TreeKeyIdx *)&(getTreeKey()));
char userData[8];
@@ -156,7 +152,7 @@ void RawGenBook::setEntry(const char *inbuf, long len) {
void RawGenBook::linkEntry(const SWKey *inkey) {
TreeKeyIdx *srckey = 0;
- TreeKeyIdx *key = ((TreeKeyIdx *)this->key);
+ TreeKeyIdx *key = ((TreeKeyIdx *)&(getTreeKey()));
// see if we have a VerseKey * or decendant
SWTRY {
srckey = SWDYNAMIC_CAST(TreeKeyIdx, inkey);
@@ -183,7 +179,7 @@ void RawGenBook::linkEntry(const SWKey *inkey) {
*/
void RawGenBook::deleteEntry() {
- TreeKeyIdx *key = ((TreeKeyIdx *)this->key);
+ TreeKeyIdx *key = ((TreeKeyIdx *)&(getTreeKey()));
key->remove();
}
@@ -211,9 +207,18 @@ char RawGenBook::createModule(const char *ipath) {
}
-SWKey *RawGenBook::CreateKey() {
- TreeKeyIdx *newKey = new TreeKeyIdx(path);
- return (verseKey) ? (SWKey *)new VerseTreeKey(newKey) : newKey;
+SWKey *RawGenBook::CreateKey() const {
+ TreeKey *tKey = new TreeKeyIdx(path);
+ if (verseKey) { SWKey *vtKey = new VerseTreeKey(tKey); delete tKey; return vtKey; }
+ return tKey;
+}
+
+bool RawGenBook::hasEntry(const SWKey *k) const {
+ TreeKey &key = getTreeKey(k);
+
+ int dsize;
+ key.getUserData(&dsize);
+ return (dsize > 7) && key.Error() == '\x00';
}
SWORD_NAMESPACE_END
diff --git a/src/modules/genbook/swgenbook.cpp b/src/modules/genbook/swgenbook.cpp
index 0ce16aa..e7feea2 100644
--- a/src/modules/genbook/swgenbook.cpp
+++ b/src/modules/genbook/swgenbook.cpp
@@ -1,9 +1,27 @@
/******************************************************************************
* swld.cpp - code for base class 'SWLD'. SWLD is the basis for all
- * types of Lexicon and Dictionary modules (hence the 'LD').
+ * types of Lexicon and Dictionary modules (hence the 'LD').
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <swgenbook.h>
+#include <versetreekey.h>
SWORD_NAMESPACE_START
@@ -16,14 +34,66 @@ SWORD_NAMESPACE_START
*/
SWGenBook::SWGenBook(const char *imodname, const char *imoddesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang) : SWModule(imodname, imoddesc, idisp, (char *)"Generic Books", enc, dir, mark, ilang) {
+ tmpTreeKey = 0;
}
/******************************************************************************
- * SWLD Destructor - Cleans up instance of SWLD
+ * SWLD Destructor - Cleans up instance of SWGenBook
*/
SWGenBook::~SWGenBook() {
+ delete tmpTreeKey;
+}
+
+
+TreeKey &SWGenBook::getTreeKey(const SWKey *k) const {
+ const SWKey* thiskey = k?k:this->key;
+
+ TreeKey *key = 0;
+
+ SWTRY {
+ key = SWDYNAMIC_CAST(TreeKey, (thiskey));
+ }
+ SWCATCH ( ... ) {}
+
+ if (!key) {
+ ListKey *lkTest = 0;
+ SWTRY {
+ lkTest = SWDYNAMIC_CAST(ListKey, thiskey);
+ }
+ SWCATCH ( ... ) { }
+ if (lkTest) {
+ SWTRY {
+ key = SWDYNAMIC_CAST(TreeKey, lkTest->GetElement());
+ if (!key) {
+ VerseTreeKey *tkey = 0;
+ SWTRY {
+ tkey = SWDYNAMIC_CAST(VerseTreeKey, lkTest->GetElement());
+ }
+ SWCATCH ( ... ) {}
+ if (tkey) key = tkey->getTreeKey();
+ }
+ }
+ SWCATCH ( ... ) { }
+ }
+ }
+ if (!key) {
+ VerseTreeKey *tkey = 0;
+ SWTRY {
+ tkey = SWDYNAMIC_CAST(VerseTreeKey, (thiskey));
+ }
+ SWCATCH ( ... ) {}
+ if (tkey) key = tkey->getTreeKey();
+ }
+
+ if (!key) {
+ delete tmpTreeKey;
+ tmpTreeKey = (TreeKey *)CreateKey();
+ (*tmpTreeKey) = *(thiskey);
+ return (*tmpTreeKey);
+ }
+ else return *key;
}
SWORD_NAMESPACE_END
diff --git a/src/modules/lexdict/rawld/rawld.cpp b/src/modules/lexdict/rawld/rawld.cpp
index 08be215..e6a4d57 100644
--- a/src/modules/lexdict/rawld/rawld.cpp
+++ b/src/modules/lexdict/rawld/rawld.cpp
@@ -1,11 +1,24 @@
/******************************************************************************
* rawld.cpp - code for class 'RawLD'- a module that reads raw lexicon and
* dictionary files: *.dat *.idx
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
-#include <ctype.h>
-#include <stdio.h>
#include <fcntl.h>
#include <utilstr.h>
@@ -13,6 +26,8 @@
#include <rawld.h>
#include <filemgr.h>
+#include <stdio.h>
+
SWORD_NAMESPACE_START
/******************************************************************************
@@ -44,50 +59,6 @@ bool RawLD::isWritable() {
/******************************************************************************
- * RawLD::strongsPad - Pads a key if (it-1) is 100% digits to 5 places
- * allows for final to be alpha, e.g. '123B'
- *
- * ENT: buf - buffer to check and pad
- */
-
-void RawLD::strongsPad(char *buf)
-{
- char *check;
- int size = 0;
- int len = strlen(buf);
- char subLet = 0;
- bool bang = false;
- if ((len < 8) && (len > 0)) {
- for (check = buf; *(check+1); check++) {
- if (!isdigit(*check))
- break;
- else size++;
- }
-
- if (size && ((size == (len-1)) || (size == (len-2)))) {
- if (*check == '!') {
- bang = true;
- check++;
- }
- if (isalpha(*check)) {
- subLet = toupper(*check);
- *(check-(bang?1:0)) = 0;
- }
- sprintf(buf, "%.5d", atoi(buf));
- if (subLet) {
- check = buf+(strlen(buf));
- if (bang) {
- *check++ = '!';
- }
- *check++ = subLet;
- *check = 0;
- }
- }
- }
-}
-
-
-/******************************************************************************
* RawLD::getEntry - Looks up entry from data file. 'Snaps' to closest
* entry and sets 'entrybuf'.
*
@@ -98,8 +69,8 @@ void RawLD::strongsPad(char *buf)
char RawLD::getEntry(long away)
{
- long start = 0;
- unsigned short size = 0;
+ __u32 start = 0;
+ __u16 size = 0;
char *idxbuf = 0;
char retval = 0;
@@ -191,4 +162,34 @@ void RawLD::deleteEntry() {
doSetText(*key, "");
}
+
+long RawLD::getEntryCount() const {
+ if (idxfd < 0) return 0;
+ return idxfd->seek(0, SEEK_END) / IDXENTRYSIZE;
+}
+
+
+long RawLD::getEntryForKey(const char *key) const {
+ __u32 start, offset;
+ __u16 size;
+
+ char *buf = new char [ strlen(key) + 6 ];
+ strcpy(buf, key);
+
+ strongsPad(buf);
+
+ findOffset(buf, &start, &size, 0, &offset);
+
+ delete [] buf;
+
+ return offset / IDXENTRYSIZE;
+}
+
+
+char *RawLD::getKeyForEntry(long entry) const {
+ char *key = 0;
+ getIDXBuf(entry * IDXENTRYSIZE, &key);
+ return key;
+}
+
SWORD_NAMESPACE_END
diff --git a/src/modules/lexdict/rawld4/rawld4.cpp b/src/modules/lexdict/rawld4/rawld4.cpp
index 0fd1058..6d60d9a 100644
--- a/src/modules/lexdict/rawld4/rawld4.cpp
+++ b/src/modules/lexdict/rawld4/rawld4.cpp
@@ -1,11 +1,24 @@
/******************************************************************************
* rawld.cpp - code for class 'RawLD'- a module that reads raw lexicon and
- * dictionary files: *.dat *.idx
+ * dictionary files: *.dat *.idx
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
-#include <ctype.h>
-#include <stdio.h>
#include <fcntl.h>
#include <filemgr.h>
@@ -13,6 +26,8 @@
#include <rawstr4.h>
#include <rawld4.h>
+#include <stdio.h>
+
SWORD_NAMESPACE_START
/******************************************************************************
@@ -44,50 +59,6 @@ bool RawLD4::isWritable() {
/******************************************************************************
- * RawLD4::strongsPad - Pads a key if (it-1) is 100% digits to 5 places
- * allows for final to be alpha, e.g. '123B'
- *
- * ENT: buf - buffer to check and pad
- */
-
-void RawLD4::strongsPad(char *buf)
-{
- char *check;
- int size = 0;
- int len = strlen(buf);
- char subLet = 0;
- bool bang = false;
- if ((len < 8) && (len > 0)) {
- for (check = buf; *(check+1); check++) {
- if (!isdigit(*check))
- break;
- else size++;
- }
-
- if (size && ((size == (len-1)) || (size == (len-2)))) {
- if (*check == '!') {
- bang = true;
- check++;
- }
- if (isalpha(*check)) {
- subLet = toupper(*check);
- *(check-(bang?1:0)) = 0;
- }
- sprintf(buf, "%.5d", atoi(buf));
- if (subLet) {
- check = buf+(strlen(buf));
- if (bang) {
- *check++ = '!';
- }
- *check++ = subLet;
- *check = 0;
- }
- }
- }
-}
-
-
-/******************************************************************************
* RawLD4::getEntry - Looks up entry from data file. 'Snaps' to closest
* entry and sets 'entrybuf'.
*
@@ -98,10 +69,10 @@ void RawLD4::strongsPad(char *buf)
char RawLD4::getEntry(long away)
{
- long start = 0;
- unsigned long size = 0;
+ __u32 start = 0;
+ __u32 size = 0;
char *idxbuf = 0;
- char retval = 0;
+ char retval = 0;
char *buf = new char [ strlen(*key) + 6 ];
strcpy(buf, *key);
@@ -189,4 +160,31 @@ void RawLD4::deleteEntry() {
doSetText(*key, "");
}
+long RawLD4::getEntryCount() const {
+ if (idxfd < 0) return 0;
+ return idxfd->seek(0, SEEK_END) / IDXENTRYSIZE;
+}
+
+long RawLD4::getEntryForKey(const char *key) const {
+ __u32 start, offset;
+ __u32 size;
+
+ char *buf = new char [ strlen(key) + 6 ];
+ strcpy(buf, key);
+
+ strongsPad(buf);
+
+ findOffset(buf, &start, &size, 0, &offset);
+
+ delete [] buf;
+
+ return offset / IDXENTRYSIZE;
+}
+
+char *RawLD4::getKeyForEntry(long entry) const {
+ char *key = 0;
+ getIDXBuf(entry * IDXENTRYSIZE, &key);
+ return key;
+}
+
SWORD_NAMESPACE_END
diff --git a/src/modules/lexdict/swld.cpp b/src/modules/lexdict/swld.cpp
index 518e5c0..bccf5d8 100644
--- a/src/modules/lexdict/swld.cpp
+++ b/src/modules/lexdict/swld.cpp
@@ -1,8 +1,26 @@
/******************************************************************************
* swld.cpp - code for base class 'SWLD'. SWLD is the basis for all
- * types of Lexicon and Dictionary modules (hence the 'LD').
+ * types of Lexicon and Dictionary modules (hence the 'LD').
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+#include <ctype.h>
+#include <stdio.h>
#include <swld.h>
#include <strkey.h>
@@ -36,7 +54,7 @@ SWLD::~SWLD()
}
-SWKey *SWLD::CreateKey() { return new StrKey(); }
+SWKey *SWLD::CreateKey() const { return new StrKey(); }
/******************************************************************************
@@ -78,5 +96,68 @@ void SWLD::setPosition(SW_POSITION p) {
getRawEntryBuf();
}
+bool SWLD::hasEntry(const SWKey *key) const {
+ const char *key_str = *key;
+ char *buf = new char [ strlen(key_str) + 6 ];
+ strcpy(buf, key_str);
+
+ strongsPad(buf);
+
+ bool retVal = !strcmp(buf, getKeyForEntry(getEntryForKey(buf)));
+ delete buf;
+
+ return retVal;
+}
+
+/******************************************************************************
+ * SWLD::strongsPad - Pads a key if (it-1) is 100% digits to 5 places
+ * allows for final to be alpha, e.g. '123B'
+ *
+ * ENT: buf - buffer to check and pad
+ */
+
+void SWLD::strongsPad(char *buf)
+{
+ char *check;
+ int size = 0;
+ int len = strlen(buf);
+ char subLet = 0;
+ bool bang = false, prefix=false;
+ if ((len < 9) && (len > 0)) {
+ // Handle initial G or H
+ if (*buf == 'G' || *buf == 'H' || *buf == 'g' || *buf == 'h') {
+ buf += 1;
+ len -= 1;
+ prefix = true;
+ }
+
+ for (check = buf; *(check); check++) {
+ if (!isdigit(*check))
+ break;
+ else size++;
+ }
+
+ if (size && ((size == len) || (size == len - 1) || (size == (len-2)))) {
+ if (*check == '!') {
+ bang = true;
+ check++;
+ }
+ if (isalpha(*check)) {
+ subLet = toupper(*check);
+ *(check-(bang?1:0)) = 0;
+ }
+ sprintf(buf, prefix?"%.4d":"%.5d", atoi(buf));
+ if (subLet) {
+ check = buf+(strlen(buf));
+ if (bang) {
+ *check++ = '!';
+ }
+ *check++ = subLet;
+ *check = 0;
+ }
+ }
+ }
+}
+
SWORD_NAMESPACE_END
diff --git a/src/modules/lexdict/zld/zld.cpp b/src/modules/lexdict/zld/zld.cpp
index bcb51ab..4e786bc 100644
--- a/src/modules/lexdict/zld/zld.cpp
+++ b/src/modules/lexdict/zld/zld.cpp
@@ -1,11 +1,23 @@
/******************************************************************************
* rawld.cpp - code for class 'RawLD'- a module that reads raw lexicon and
- * dictionary files: *.dat *.idx
+ * dictionary files: *.dat *.idx
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
-#include <ctype.h>
-#include <stdio.h>
#include <fcntl.h>
#include <utilstr.h>
@@ -13,6 +25,8 @@
#include <zld.h>
#include <filemgr.h>
+#include <stdio.h>
+
SWORD_NAMESPACE_START
/******************************************************************************
@@ -44,48 +58,6 @@ bool zLD::isWritable() {
/******************************************************************************
- * zLD::strongsPad - Pads a key if it is 100% digits to 5 places
- *
- * ENT: buf - buffer to check and pad
- */
-
-void zLD::strongsPad(char *buf) {
- char *check;
- int size = 0;
- int len = strlen(buf);
- char subLet = 0;
- bool bang = false;
- if ((len < 8) && (len > 0)) {
- for (check = buf; *(check+1); check++) {
- if (!isdigit(*check))
- break;
- else size++;
- }
-
- if (size && ((size == (len-1)) || (size == (len-2)))) {
- if (*check == '!') {
- bang = true;
- check++;
- }
- if (isalpha(*check)) {
- subLet = toupper(*check);
- *(check-(bang?1:0)) = 0;
- }
- sprintf(buf, "%.5d", atoi(buf));
- if (subLet) {
- check = buf+(strlen(buf));
- if (bang) {
- *check++ = '!';
- }
- *check++ = subLet;
- *check = 0;
- }
- }
- }
-}
-
-
-/******************************************************************************
* zLD::getEntry - Looks up entry from data file. 'Snaps' to closest
* entry and sets 'entrybuf'.
*
@@ -186,4 +158,36 @@ void zLD::deleteEntry() {
setText(*key, "");
}
+
+long zLD::getEntryCount() const
+{
+ if (idxfd < 0) return 0;
+ return idxfd->seek(0, SEEK_END) / IDXENTRYSIZE;
+}
+
+
+long zLD::getEntryForKey(const char* key) const
+{
+ long offset;
+ char *buf = new char [ strlen(key) + 6 ];
+ strcpy(buf, key);
+
+ strongsPad(buf);
+
+ findKeyIndex(buf, &offset);
+
+ delete [] buf;
+
+ return offset/IDXENTRYSIZE;
+}
+
+
+char *zLD::getKeyForEntry(long entry) const
+{
+ char *key = 0;
+ getKeyFromIdxOffset(entry * IDXENTRYSIZE, &key);
+ return key;
+}
+
+
SWORD_NAMESPACE_END
diff --git a/src/modules/swmodule.cpp b/src/modules/swmodule.cpp
index 8461953..3eb7ce1 100644
--- a/src/modules/swmodule.cpp
+++ b/src/modules/swmodule.cpp
@@ -1,11 +1,29 @@
/******************************************************************************
- * swmodule.cpp -code for base class 'module'. Module is the basis for all
- * types of modules (e.g. texts, commentaries, maps, lexicons,
- * etc.)
+ * swmodule.cpp - code for base class 'module'. Module is the basis for all
+ * types of modules (e.g. texts, commentaries, maps, lexicons,
+ * etc.)
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+
#include <vector>
+#include <swlog.h>
#include <sysdata.h>
#include <swmodule.h>
#include <utilstr.h>
@@ -58,7 +76,7 @@ typedef std::list<SWBuf> StringList;
* unicode - if this module is unicode
*/
-SWModule::SWModule(const char *imodname, const char *imoddesc, SWDisplay *idisp, char *imodtype, SWTextEncoding encoding, SWTextDirection direction, SWTextMarkup markup, const char* imodlang) {
+SWModule::SWModule(const char *imodname, const char *imoddesc, SWDisplay *idisp, const char *imodtype, SWTextEncoding encoding, SWTextDirection direction, SWTextMarkup markup, const char *imodlang) {
key = CreateKey();
entryBuf = "";
config = &ownConfig;
@@ -127,7 +145,7 @@ SWModule::~SWModule()
* RET: pointer to allocated key
*/
-SWKey *SWModule::CreateKey()
+SWKey *SWModule::CreateKey() const
{
return new SWKey();
}
@@ -255,7 +273,8 @@ char SWModule::Markup(signed char newmark) {
char *SWModule::Lang(const char *imodlang)
{
- return stdstr(&modlang, imodlang);
+ if (imodlang) stdstr(&modlang, imodlang);
+ return modlang;
}
@@ -395,8 +414,9 @@ void SWModule::decrement(int steps) {
* >=0 - regex
* -1 - phrase
* -2 - multiword
- * -3 - entryAttrib (eg. Word//Lemma/G1234/)
+ * -3 - entryAttrib (eg. Word//Lemma./G1234/) (Lemma with dot means check components (Lemma.[1-9]) also)
* -4 - clucene
+ * -5 - multilemma window; flags = window size
* flags - options flags for search
* justCheckIfSupported - if set, don't search, only tell if this
* function supports requested search.
@@ -408,6 +428,7 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
listKey.ClearList();
SWBuf term = istr;
+ bool includeComponents = false; // for entryAttrib e.g., /Lemma.1/
#ifdef USELUCENE
SWBuf target = getConfigEntry("AbsoluteDataPath");
@@ -431,12 +452,16 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
SWKey *resultKey = CreateKey();
regex_t preg;
vector<SWBuf> words;
+ vector<SWBuf> window;
const char *sres;
terminateSearch = false;
char perc = 1;
bool savePEA = isProcessEntryAttributes();
- // determine if we might be doing special strip searches. useful for knowing if we can use shortcuts
- bool specialStrips = (getConfigEntry("LocalStripFilter") || strchr(istr, '<'));
+
+ // determine if we might be doing special strip searches. useful for knowing if we can use shortcuts
+ bool specialStrips = (getConfigEntry("LocalStripFilter")
+ || (getConfig().has("GlobalOptionFilter", "UTF8GreekAccents"))
+ || (strchr(istr, '<')));
processEntryAttributes(searchType == -3);
@@ -454,19 +479,9 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
}
(*percent)(perc, percentUserData);
- // MAJOR KLUDGE: VerseKey::Index still return index within testament.
- // VerseKey::NewIndex should be moved to Index and Index should be some
- // VerseKey specific name
- VerseKey *vkcheck = 0;
- SWTRY {
- vkcheck = SWDYNAMIC_CAST(VerseKey, key);
- }
- SWCATCH (...) {}
- // end MAJOR KLUDGE
*this = BOTTOM;
- // fix below when we find out the bug
- long highIndex = (vkcheck)?32300/*vkcheck->NewIndex()*/:key->Index();
+ long highIndex = key->Index();
if (!highIndex)
highIndex = 1; // avoid division by zero errors.
*this = TOP;
@@ -502,6 +517,7 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
(*percent)(80, percentUserData);
// iterate thru each good module position that meets the search
+ bool checkBounds = getKey()->isBoundSet();
for (long i = 0; i < h->length(); i++) {
Document &doc = h->doc(i);
@@ -509,12 +525,15 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
lucene_wcstoutf8(utfBuffer, doc.get(_T("key")), MAX_CONV_SIZE);
*resultKey = utfBuffer; //TODO Does a key always accept utf8?
- // check to see if it sets ok (in our range?) and if so, add to our return list
- *getKey() = *resultKey;
- if (*getKey() == *resultKey) {
- listKey << *resultKey;
- listKey.GetElement()->userData = (void *)((__u32)(h->score(i)*100));
+ // check to see if it sets ok (within our bounds) and if not, skip
+ if (checkBounds) {
+ *getKey() = *resultKey;
+ if (*getKey() != *resultKey) {
+ continue;
+ }
}
+ listKey << *resultKey;
+ listKey.GetElement()->userData = (void *)((__u32)(h->score(i)*100));
}
(*percent)(98, percentUserData);
}
@@ -543,6 +562,7 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
// multi-word
case -2:
+ case -5:
// let's break the term down into our words vector
while (1) {
const char *word = term.stripPrefix(' ');
@@ -570,6 +590,10 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
}
words.push_back(word);
}
+ if ((words.size()>2) && words[2].endsWith(".")) {
+ includeComponents = true;
+ words[2]--;
+ }
break;
}
@@ -579,16 +603,12 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
(*percent)(perc, percentUserData);
- while ((searchType > -4) && !Error() && !terminateSearch) {
- long mindex = 0;
- if (vkcheck)
- mindex = vkcheck->NewIndex();
- else mindex = key->Index();
+ while ((searchType != -4) && !Error() && !terminateSearch) {
+ long mindex = key->Index();
float per = (float)mindex / highIndex;
per *= 93;
per += 5;
char newperc = (char)per;
-// char newperc = (char)(5+(93*(((float)((vkcheck)?vkcheck->NewIndex():key->Index()))/highIndex)));
if (newperc > perc) {
perc = newperc;
(*percent)(perc, percentUserData);
@@ -596,8 +616,7 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
else if (newperc < perc) {
#ifndef _MSC_VER
std::cerr << "Serious error: new percentage complete is less than previous value\n";
- std::cerr << "using vk? " << ((vkcheck)?"yes":"no") << "\n";
- std::cerr << "index: " << ((vkcheck)?vkcheck->NewIndex():key->Index()) << "\n";
+ std::cerr << "index: " << (key->Index()) << "\n";
std::cerr << "highIndex: " << highIndex << "\n";
std::cerr << "newperc ==" << (int)newperc << "%" << "is smaller than\n";
std::cerr << "perc == " << (int )perc << "% \n";
@@ -656,7 +675,7 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
} break;
// entry attributes
- case -3:
+ case -3: {
RenderText(); // force parse
AttributeTypeList &entryAttribs = getEntryAttributes();
AttributeTypeList::iterator i1Start, i1End;
@@ -685,7 +704,7 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
i2End = i1Start->second.end();
}
for (;i2Start != i2End; i2Start++) {
- if ((words.size()>2) && (words[2].length())) {
+ if ((words.size()>2) && (words[2].length()) && (!includeComponents)) {
i3Start = i2Start->second.find(words[2]);
i3End = i3Start;
if (i3End != i2Start->second.end())
@@ -697,6 +716,13 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
}
for (;i3Start != i3End; i3Start++) {
if ((words.size()>3) && (words[3].length())) {
+ if (includeComponents) {
+ SWBuf key = i3Start->first.c_str();
+ key = key.stripPrefix('.', true);
+ // we're iterating all 3 level keys, so be sure we match our
+ // prefix (e.g., Lemma, Lemma.1, Lemma.2, etc.)
+ if (key != words[2]) continue;
+ }
if (flags & SEARCHFLAG_MATCHWHOLEENTRY) {
bool found = !(((flags & REG_ICASE) == REG_ICASE) ? sword::stricmp(i3Start->second.c_str(), words[3]) : strcmp(i3Start->second.c_str(), words[3]));
sres = (found) ? i3Start->second.c_str() : 0;
@@ -719,6 +745,54 @@ ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *sc
break;
}
break;
+ }
+ case -5:
+ AttributeList &words = getEntryAttributes()["Word"];
+ SWBuf kjvWord = "";
+ SWBuf bibWord = "";
+ for (AttributeList::iterator it = words.begin(); it != words.end(); it++) {
+ int parts = atoi(it->second["PartCount"]);
+ SWBuf lemma = "";
+ SWBuf morph = "";
+ for (int i = 1; i <= parts; i++) {
+ SWBuf key = "";
+ key = (parts == 1) ? "Lemma" : SWBuf().setFormatted("Lemma.%d", i).c_str();
+ AttributeValue::iterator li = it->second.find(key);
+ if (li != it->second.end()) {
+ if (i > 1) lemma += " ";
+ key = (parts == 1) ? "LemmaClass" : SWBuf().setFormatted("LemmaClass.%d", i).c_str();
+ AttributeValue::iterator lci = it->second.find(key);
+ if (lci != it->second.end()) {
+ lemma += lci->second + ":";
+ }
+ lemma += li->second;
+ }
+ key = (parts == 1) ? "Morph" : SWBuf().setFormatted("Morph.%d", i).c_str();
+ li = it->second.find(key);
+ // silly. sometimes morph counts don't equal lemma counts
+ if (i == 1 && parts != 1 && li == it->second.end()) {
+ li = it->second.find("Morph");
+ }
+ if (li != it->second.end()) {
+ if (i > 1) morph += " ";
+ key = (parts == 1) ? "MorphClass" : SWBuf().setFormatted("MorphClass.%d", i).c_str();
+ AttributeValue::iterator lci = it->second.find(key);
+ // silly. sometimes morph counts don't equal lemma counts
+ if (i == 1 && parts != 1 && lci == it->second.end()) {
+ lci = it->second.find("MorphClass");
+ }
+ if (lci != it->second.end()) {
+ morph += lci->second + ":";
+ }
+ morph += li->second;
+ }
+ // TODO: add src tags and maybe other attributes
+ }
+ while (window.size() < (unsigned)flags) {
+
+ }
+ }
+ break;
} // end switch
}
(*this)++;
@@ -812,7 +886,7 @@ const char *SWModule::StripText(const char *buf, int len) {
* RET: this module's text at current key location massaged by RenderFilers
*/
- const char *SWModule::RenderText(SWKey *tmpKey) {
+ const char *SWModule::RenderText(const SWKey *tmpKey) {
SWKey *saveKey;
const char *retVal;
@@ -843,7 +917,7 @@ const char *SWModule::StripText(const char *buf, int len) {
* RET: this module's text at specified key location massaged by Strip filters
*/
-const char *SWModule::StripText(SWKey *tmpKey) {
+const char *SWModule::StripText(const SWKey *tmpKey) {
SWKey *saveKey;
const char *retVal;
@@ -919,8 +993,8 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
}
}
-
- // be sure we give CLucene enough file handles
+
+ // be sure we give CLucene enough file handles
FileMgr::getSystemFileMgr()->flush();
// save key information so as not to disrupt original
@@ -941,7 +1015,7 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
IndexWriter *coreWriter = NULL;
IndexWriter *fsWriter = NULL;
Directory *d = NULL;
-
+
standard::StandardAnalyzer *an = new standard::StandardAnalyzer();
SWBuf target = getConfigEntry("AbsoluteDataPath");
bool includeKeyInSearch = getConfig().has("SearchOption", "IncludeKeyInSearch");
@@ -953,19 +1027,21 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
ramDir = new RAMDirectory();
coreWriter = new IndexWriter(ramDir, an, true);
-
-
+
+
char perc = 1;
VerseKey *vkcheck = 0;
vkcheck = SWDYNAMIC_CAST(VerseKey, key);
+ VerseKey *chapMax = 0;
+ if (vkcheck) chapMax = (VerseKey *)vkcheck->clone();
TreeKeyIdx *tkcheck = 0;
tkcheck = SWDYNAMIC_CAST(TreeKeyIdx, key);
*this = BOTTOM;
- long highIndex = (vkcheck)?32300/*vkcheck->NewIndex()*/:key->Index();
+ long highIndex = key->Index();
if (!highIndex)
highIndex = 1; // avoid division by zero errors.
@@ -976,20 +1052,16 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
// position module at the beginning
*this = TOP;
- VerseKey chapMax;
SWBuf proxBuf;
SWBuf proxLem;
SWBuf strong;
const short int MAX_CONV_SIZE = 2047;
wchar_t wcharBuffer[MAX_CONV_SIZE + 1];
-
+
char err = Error();
while (!err) {
- long mindex = 0;
- if (vkcheck)
- mindex = vkcheck->NewIndex();
- else mindex = key->Index();
+ long mindex = key->Index();
proxBuf = "";
proxLem = "";
@@ -1016,7 +1088,7 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
if (content && *content) {
good = true;
-
+
// build "strong" field
AttributeTypeList::iterator words;
AttributeList::iterator word;
@@ -1046,8 +1118,10 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
}
lucene_utf8towcs(wcharBuffer, keyText, MAX_CONV_SIZE); //keyText must be utf8
+// doc->add( *(new Field("key", wcharBuffer, Field::STORE_YES | Field::INDEX_TOKENIZED)));
doc->add( *Field::Text(_T("key"), wcharBuffer ) );
+
if (includeKeyInSearch) {
c = keyText;
c += " ";
@@ -1071,12 +1145,12 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
// for VerseKeys use chapter
if (vkcheck) {
- chapMax = *vkcheck;
+ *chapMax = *vkcheck;
// we're the first verse in a chapter
if (vkcheck->Verse() == 1) {
- chapMax = MAXVERSE;
+ *chapMax = MAXVERSE;
VerseKey saveKey = *vkcheck;
- while ((!err) && (*vkcheck <= chapMax)) {
+ while ((!err) && (*vkcheck <= *chapMax)) {
//printf("building proxBuf from (%s).\nproxBuf.c_str(): %s\n", (const char *)*key, proxBuf.c_str());
//printf("building proxBuf from (%s).\n", (const char *)*key);
@@ -1112,7 +1186,7 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
proxBuf += content;
proxBuf.append(' ');
proxLem += strong;
- if (proxLem.length())
+ if (proxLem.length())
proxLem.append("\n");
}
(*this)++;
@@ -1122,7 +1196,7 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
*vkcheck = saveKey;
}
}
-
+
// for TreeKeys use siblings if we have no children
else if (tkcheck) {
if (!tkcheck->hasChildren()) {
@@ -1164,7 +1238,7 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
proxBuf += content;
proxBuf.append(' ');
proxLem += strong;
- if (proxLem.length())
+ if (proxLem.length())
proxLem.append("\n");
}
} while (tkcheck->nextSibling());
@@ -1174,11 +1248,11 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
else tkcheck->nextSibling(); // reposition from our previousSibling test
}
}
-
+
if (proxBuf.length() > 0) {
-
+
lucene_utf8towcs(wcharBuffer, proxBuf, MAX_CONV_SIZE); //keyText must be utf8
-
+
//printf("proxBuf after (%s).\nprox: %s\nproxLem: %s\n", (const char *)*key, proxBuf.c_str(), proxLem.c_str());
doc->add( *Field::UnStored(_T("prox"), wcharBuffer) );
@@ -1209,7 +1283,7 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
if (IndexReader::isLocked(d)) {
IndexReader::unlock(d);
}
-
+
fsWriter = new IndexWriter( d, an, false);
} else {
d = FSDirectory::getDirectory(target.c_str(), true);
@@ -1234,6 +1308,8 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
if (searchKey)
delete searchKey;
+ delete chapMax;
+
processEntryAttributes(savePEA);
// reset option filters back to original values
@@ -1253,7 +1329,7 @@ signed char SWModule::createSearchFramework(void (*percent)(char, void *), void
* @param buf the buffer to filter
* @param key key location from where this buffer was extracted
*/
-void SWModule::filterBuffer(OptionFilterList *filters, SWBuf &buf, SWKey *key) {
+void SWModule::filterBuffer(OptionFilterList *filters, SWBuf &buf, const SWKey *key) {
OptionFilterList::iterator it;
for (it = filters->begin(); it != filters->end(); it++) {
(*it)->processText(buf, key, this);
@@ -1265,7 +1341,7 @@ void SWModule::filterBuffer(OptionFilterList *filters, SWBuf &buf, SWKey *key) {
* @param buf the buffer to filter
* @param key key location from where this buffer was extracted
*/
-void SWModule::filterBuffer(FilterList *filters, SWBuf &buf, SWKey *key) {
+void SWModule::filterBuffer(FilterList *filters, SWBuf &buf, const SWKey *key) {
FilterList::iterator it;
for (it = filters->begin(); it != filters->end(); it++) {
(*it)->processText(buf, key, this);
@@ -1282,4 +1358,63 @@ void SWModule::setEntry(const char*, long) {
void SWModule::linkEntry(const SWKey*) {
}
+
+/******************************************************************************
+ * SWModule::prepText - Prepares the text before returning it to external
+ * objects
+ *
+ * ENT: buf - buffer where text is stored and where to store the prep'd
+ * text.
+ */
+
+void SWModule::prepText(SWBuf &buf) {
+ unsigned int to, from;
+ char space = 0, cr = 0, realdata = 0, nlcnt = 0;
+ char *rawBuf = buf.getRawData();
+ for (to = from = 0; rawBuf[from]; from++) {
+ switch (rawBuf[from]) {
+ case 10:
+ if (!realdata)
+ continue;
+ space = (cr) ? 0 : 1;
+ cr = 0;
+ nlcnt++;
+ if (nlcnt > 1) {
+// *to++ = nl;
+ rawBuf[to++] = 10;
+// *to++ = nl[1];
+// nlcnt = 0;
+ }
+ continue;
+ case 13:
+ if (!realdata)
+ continue;
+// *to++ = nl[0];
+ rawBuf[to++] = 10;
+ space = 0;
+ cr = 1;
+ continue;
+ }
+ realdata = 1;
+ nlcnt = 0;
+ if (space) {
+ space = 0;
+ if (rawBuf[from] != ' ') {
+ rawBuf[to++] = ' ';
+ from--;
+ continue;
+ }
+ }
+ rawBuf[to++] = rawBuf[from];
+ }
+ buf.setSize(to);
+
+ while (to > 1) { // remove trailing excess
+ to--;
+ if ((rawBuf[to] == 10) || (rawBuf[to] == ' '))
+ buf.setSize(to);
+ else break;
+ }
+}
+
SWORD_NAMESPACE_END
diff --git a/src/modules/tests/echomod.cpp b/src/modules/tests/echomod.cpp
index 2640773..99b00cd 100644
--- a/src/modules/tests/echomod.cpp
+++ b/src/modules/tests/echomod.cpp
@@ -1,6 +1,22 @@
/******************************************************************************
* echomod.cpp - code for class 'echomod'- a dummy test text module that just
* echos back the key
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
#include <echomod.h>
diff --git a/src/modules/texts/rawtext/rawtext.cpp b/src/modules/texts/rawtext/rawtext.cpp
index 3245da6..8641a45 100644
--- a/src/modules/texts/rawtext/rawtext.cpp
+++ b/src/modules/texts/rawtext/rawtext.cpp
@@ -1,9 +1,24 @@
/******************************************************************************
* rawtext.cpp - code for class 'RawText'- a module that reads raw text files:
* ot and nt using indexs ??.bks ??.cps ??.vss
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdio.h>
#include <fcntl.h>
#include <sysdata.h>
@@ -42,27 +57,9 @@ typedef list<long> longlist;
* idisp - Display object to use for displaying
*/
-RawText::RawText(const char *ipath, const char *iname, const char *idesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang)
- : SWText(iname, idesc, idisp, enc, dir, mark, ilang),
+RawText::RawText(const char *ipath, const char *iname, const char *idesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang, const char *versification)
+ : SWText(iname, idesc, idisp, enc, dir, mark, ilang, versification),
RawVerse(ipath) {
-
-#ifndef USELUCENE
- SWBuf fname;
- fname = path;
- char ch = fname.c_str()[strlen(fname.c_str())-1];
- if ((ch != '/') && (ch != '\\'))
- fname += "/";
-
- for (int loop = 0; loop < 2; loop++) {
- fastSearch[loop] = 0;
- SWBuf fastidxname =(fname + ((loop)?"ntwords.dat":"otwords.dat"));
- if (FileMgr::existsFile(fastidxname.c_str())) {
- fastidxname = (fname + ((loop)?"ntwords.idx":"otwords.idx"));
- if (FileMgr::existsFile(fastidxname.c_str()))
- fastSearch[loop] = new RawStr((fname + ((loop)?"ntwords":"otwords")).c_str());
- }
- }
-#endif
}
@@ -71,13 +68,6 @@ RawText::RawText(const char *ipath, const char *iname, const char *idesc, SWDisp
*/
RawText::~RawText() {
-#ifndef USELUCENE
- if (fastSearch[0])
- delete fastSearch[0];
-
- if (fastSearch[1])
- delete fastSearch[1];
-#endif
}
@@ -98,7 +88,7 @@ SWBuf &RawText::getRawEntryBuf() {
unsigned short size = 0;
VerseKey &key = getVerseKey();
- findOffset(key.Testament(), key.Index(), &start, &size);
+ findOffset(key.Testament(), key.TestamentIndex(), &start, &size);
entrySize = size; // support getEntrySize call
entryBuf = "";
@@ -114,382 +104,16 @@ SWBuf &RawText::getRawEntryBuf() {
}
-signed char RawText::createSearchFramework(void (*percent)(char, void *), void *percentUserData) {
-#ifndef USELUCENE
- SWKey *savekey = 0;
- SWKey *searchkey = 0;
- SWKey textkey;
- char *word = 0;
- char *wordBuf = 0;
-
- // dictionary holds words associated with a list
- // containing every module position that contains
- // the word. [0] Old Testament; [1] NT
- map < SWBuf, list<long> > dictionary[2];
-
-
- // save key information so as not to disrupt original
- // module position
- if (!key->Persist()) {
- savekey = CreateKey();
- *savekey = *key;
- }
- else savekey = key;
-
- searchkey = (key->Persist())?key->clone():0;
- if (searchkey) {
- searchkey->Persist(1);
- setKey(*searchkey);
- }
-
- // position module at the beginning
- *this = TOP;
-
- VerseKey *lkey = (VerseKey *)key;
-
- // iterate thru each entry in module
- while (!Error()) {
- long index = lkey->Index();
- wordBuf = (char *)calloc(sizeof(char), strlen(StripText()) + 1);
- strcpy(wordBuf, StripText());
-
- // grab each word from the text
- word = strtok(wordBuf, " !.,?;:()-=+/\\|{}[]\"<>");
- while (word) {
-
- // make word upper case
- toupperstr(word);
-
- // lookup word in dictionary (or make entry in dictionary
- // for this word) and add this module position (index) to
- // the word's associated list of module positions
- dictionary[lkey->Testament()-1][word].push_back(index);
- word = strtok(NULL, " !.,?;:()-=+/\\|{}[]\"<>");
- }
- free(wordBuf);
- (*this)++;
- }
-
- // reposition module back to where it was before we were called
- setKey(*savekey);
-
- if (!savekey->Persist())
- delete savekey;
-
- if (searchkey)
- delete searchkey;
-
-
- // --------- Let's output an index from our dictionary -----------
- FileDesc *datfd;
- FileDesc *idxfd;
- strlist::iterator it;
- longlist::iterator it2;
- unsigned long offset, entryoff;
- unsigned short size;
-
- SWBuf fname;
- fname = path;
- char ch = fname.c_str()[strlen(fname.c_str())-1];
- if ((ch != '/') && (ch != '\\'))
- fname += "/";
-
- // for old and new testament do...
- for (int loop = 0; loop < 2; loop++) {
- datfd = FileMgr::getSystemFileMgr()->open((fname + ((loop)?"ntwords.dat":"otwords.dat")).c_str(), FileMgr::CREAT|FileMgr::WRONLY, 00644);
- if (datfd->getFd() == -1)
- return -1;
- idxfd = FileMgr::getSystemFileMgr()->open((fname + ((loop)?"ntwords.idx":"otwords.idx")).c_str(), FileMgr::CREAT|FileMgr::WRONLY, 00644);
- if (idxfd->getFd() == -1) {
- FileMgr::getSystemFileMgr()->close(datfd);
- return -1;
- }
-
- // iterate thru each word in the dictionary
- for (it = dictionary[loop].begin(); it != dictionary[loop].end(); it++) {
- printf("%s: ", it->first.c_str());
-
- // get our current offset in our word.dat file and write this as the start
- // of the next entry in our database
- offset = datfd->seek(0, SEEK_CUR);
- idxfd->write(&offset, 4);
-
- // write our word out to the word.dat file, delineating with a \n
- datfd->write(it->first.c_str(), strlen(it->first.c_str()));
- datfd->write("\n", 1);
-
- // force our mod position list for this word to be unique (remove
- // duplicates that may exist if the word was found more than once
- // in the verse
- it->second.unique();
-
- // iterate thru each mod position for this word and output it to
- // our database
- unsigned short count = 0;
- for (it2 = it->second.begin(); it2 != it->second.end(); it2++) {
- entryoff= *it2;
- datfd->write(&entryoff, 4);
- count++;
- }
-
- // now see what our new position is in our word.dat file and
- // determine the size of this database entry
- size = datfd->seek(0, SEEK_CUR) - offset;
-
- // store the size of this database entry
- idxfd->write(&size, 2);
- printf("%d entries (size: %d)\n", count, size);
- }
- FileMgr::getSystemFileMgr()->close(datfd);
- FileMgr::getSystemFileMgr()->close(idxfd);
- }
- return 0;
-#else
- return SWModule::createSearchFramework(percent, percentUserData);
-#endif
-}
-
-
-void RawText::deleteSearchFramework() {
-#ifndef USELUCENE
- SWBuf target = path;
- char ch = target.c_str()[strlen(target.c_str())-1];
- if ((ch != '/') && (ch != '\\'))
- target += "/lucene";
- FileMgr::removeFile(target + "ntwords.dat");
- FileMgr::removeFile(target + "otwords.dat");
- FileMgr::removeFile(target + "ntwords.idx");
- FileMgr::removeFile(target + "otwords.idx");
-#else
- SWModule::deleteSearchFramework();
-#endif
-}
-
-
-/******************************************************************************
- * SWModule::search - Searches a module for a string
- *
- * ENT: istr - string for which to search
- * searchType - type of search to perform
- * >=0 - regex
- * -1 - phrase
- * -2 - multiword
- * flags - options flags for search
- * justCheckIfSupported - if set, don't search, only tell if this
- * function supports requested search.
- *
- * RET: ListKey set to verses that contain istr
- */
-
-ListKey &RawText::search(const char *istr, int searchType, int flags, SWKey *scope, bool *justCheckIfSupported, void (*percent)(char, void *), void *percentUserData) {
-#ifndef USELUCENE
- listKey.ClearList();
-
- if ((fastSearch[0]) && (fastSearch[1])) {
-
- switch (searchType) {
- case -2: {
-
- if ((flags & REG_ICASE) != REG_ICASE) // if haven't chosen to
- // ignore case
- break; // can't handle fast case sensitive searches
-
- // test to see if our scope for this search is bounded by a
- // VerseKey
- VerseKey *testKeyType = 0;
- SWTRY {
- testKeyType = SWDYNAMIC_CAST(VerseKey, ((scope)?scope:key));
- }
- SWCATCH ( ... ) {}
- // if we don't have a VerseKey * decendant we can't handle
- // because of scope.
- // In the future, add bool SWKey::isValid(const char *tryString);
- if (!testKeyType)
- break;
-
-
- // check if we just want to see if search is supported.
- // If we've gotten this far, then it is supported.
- if (justCheckIfSupported) {
- *justCheckIfSupported = true;
- return listKey;
- }
-
- SWKey saveKey = *testKeyType; // save current place
-
- char error = 0;
- char **words = 0;
- char *wordBuf = 0;
- int wordCount = 0;
- long start;
- unsigned short size;
- char *idxbuf = 0;
- SWBuf datBuf;
- list <long> indexes;
- list <long> indexes2;
- VerseKey vk;
- vk = TOP;
-
- (*percent)(10, percentUserData);
-
- // toupper our copy of search string
- stdstr(&wordBuf, istr);
- toupperstr(wordBuf);
-
- // get list of individual words
- words = (char **)calloc(sizeof(char *), 10);
- int allocWords = 10;
- words[wordCount] = strtok(wordBuf, " ");
- while (words[wordCount]) {
- wordCount++;
- if (wordCount == allocWords) {
- allocWords+=10;
- words = (char **)realloc(words, sizeof(char *)*allocWords);
- }
- words[wordCount] = strtok(NULL, " ");
- }
-
- (*percent)(20, percentUserData);
-
- // clear our result set
- indexes.erase(indexes.begin(), indexes.end());
-
- // search both old and new testament indexes
- for (int j = 0; j < 2; j++) {
- // iterate thru each word the user passed to us.
- for (int i = 0; i < wordCount; i++) {
-
- // clear this word's result set
- indexes2.erase(indexes2.begin(), indexes2.end());
- error = 0;
-
- // iterate thru every word in the database that starts
- // with our search word
- for (int away = 0; !error; away++) {
- idxbuf = 0;
-
- // find our word in the database and jump ahead _away_
- error = fastSearch[j]->findOffset(words[i], &start, &size, away);
-
- // get the word from the database
- fastSearch[j]->getIDXBufDat(start, &idxbuf);
-
- // check to see if it starts with our target word
- if (strlen(idxbuf) > strlen(words[i]))
- idxbuf[strlen(words[i])] = 0;
-// else words[i][strlen(idxbuf)] = 0;
- if (!strcmp(idxbuf, words[i])) {
-
- // get data for this word from database
- delete [] idxbuf;
- idxbuf = 0;
- datBuf = "";
- fastSearch[j]->readText(start, &size, &idxbuf, datBuf);
-
- // we know that the data consists of sizof(long)
- // records each a valid module position that constains
- // this word
- //
- // iterate thru each of these module positions
- long *keyindex = (long *)datBuf.getRawData();
- while (keyindex < (long *)(datBuf.getRawData() + size - (strlen(idxbuf) + 1))) {
- if (i) { // if we're not on our first word
-
- // check to see if this word is already in the result set.
- // This is our AND functionality
- if (find(indexes.begin(), indexes.end(), *keyindex) != indexes.end())
- // add to new result set
- indexes2.push_back(*keyindex);
- }
- else indexes2.push_back(*keyindex);
- keyindex++;
- }
- }
- else error = 1; // no more matches
- free(idxbuf);
- }
-
- // make new result set final result set
- indexes = indexes2;
-
- percent((char)(20 + (float)((j*wordCount)+i)/(wordCount * 2) * 78), percentUserData);
- }
-
- // indexes contains our good verses, lets return them in a listKey
- indexes.sort();
-
- // iterate thru each good module position that meets the search
- for (longlist::iterator it = indexes.begin(); it != indexes.end(); it++) {
-
- // set a temporary verse key to this module position
- vk.Testament(j+1);
- vk.Error();
- vk.Index(*it);
-
- // check scope
- // Try to set our scope key to this verse key
- if (scope) {
- *testKeyType = vk;
-
- // check to see if it set ok and if so, add to our return list
- if (*testKeyType == vk)
- listKey << (const char *) vk;
- }
- else listKey << (const char*) vk;
- }
- }
- (*percent)(98, percentUserData);
-
- free(words);
- free(wordBuf);
-
- *testKeyType = saveKey; // set current place back to original
-
- listKey = TOP;
- (*percent)(100, percentUserData);
- return listKey;
- }
-
- default:
- break;
- }
- }
-
- // check if we just want to see if search is supported
- if (justCheckIfSupported) {
- *justCheckIfSupported = false;
- return listKey;
- }
-
-#endif
- // if we don't support this search, fall back to base class
- return SWModule::search(istr, searchType, flags, scope, justCheckIfSupported, percent, percentUserData);
-}
-
-
void RawText::setEntry(const char *inbuf, long len) {
VerseKey &key = getVerseKey();
- doSetText(key.Testament(), key.Index(), inbuf, len);
+ doSetText(key.Testament(), key.TestamentIndex(), inbuf, len);
}
void RawText::linkEntry(const SWKey *inkey) {
VerseKey &destkey = getVerseKey();
- const VerseKey *srckey = 0;
-
- // see if we have a VerseKey * or decendant
- SWTRY {
- srckey = SWDYNAMIC_CAST(VerseKey, inkey);
- }
- SWCATCH ( ... ) {}
- // if we don't have a VerseKey * decendant, create our own
- if (!srckey)
- srckey = new VerseKey(inkey);
-
- doLinkEntry(destkey.Testament(), destkey.Index(), srckey->Index());
-
- if (inkey != srckey) // free our key if we created a VerseKey
- delete srckey;
+ const VerseKey *srckey = &getVerseKey(inkey);
+ doLinkEntry(destkey.Testament(), destkey.TestamentIndex(), srckey->TestamentIndex());
}
@@ -501,7 +125,7 @@ void RawText::linkEntry(const SWKey *inkey) {
void RawText::deleteEntry() {
VerseKey &key = getVerseKey();
- doSetText(key.Testament(), key.Index(), "");
+ doSetText(key.Testament(), key.TestamentIndex(), "");
}
/******************************************************************************
@@ -517,21 +141,21 @@ void RawText::increment(int steps) {
unsigned short size;
VerseKey *tmpkey = &getVerseKey();
- findOffset(tmpkey->Testament(), tmpkey->Index(), &start, &size);
+ findOffset(tmpkey->Testament(), tmpkey->TestamentIndex(), &start, &size);
SWKey lastgood = *tmpkey;
while (steps) {
long laststart = start;
unsigned short lastsize = size;
SWKey lasttry = *tmpkey;
- (steps > 0) ? (*key)++ : (*key)--;
+ (steps > 0) ? ++(*key) : --(*key);
tmpkey = &getVerseKey();
if ((error = key->Error())) {
*key = lastgood;
break;
}
- long index = tmpkey->Index();
+ long index = tmpkey->TestamentIndex();
findOffset(tmpkey->Testament(), index, &start, &size);
if (
(((laststart != start) || (lastsize != size)) // we're a different entry
@@ -545,4 +169,28 @@ void RawText::increment(int steps) {
error = (error) ? KEYERR_OUTOFBOUNDS : 0;
}
+bool RawText::isLinked(const SWKey *k1, const SWKey *k2) const {
+ long start1, start2;
+ unsigned short size1, size2;
+ VerseKey *vk1 = &getVerseKey(k1);
+ VerseKey *vk2 = &getVerseKey(k2);
+ if (vk1->Testament() != vk2->Testament()) return false;
+
+ findOffset(vk1->Testament(), vk1->TestamentIndex(), &start1, &size1);
+ findOffset(vk2->Testament(), vk2->TestamentIndex(), &start2, &size2);
+ if (!size1 || !size2) return false;
+ return start1 == start2;
+}
+
+bool RawText::hasEntry(const SWKey *k) const {
+ long start;
+ unsigned short size;
+ VerseKey *vk = &getVerseKey(k);
+
+ findOffset(vk->Testament(), vk->TestamentIndex(), &start, &size);
+ return size;
+}
+
+
+
SWORD_NAMESPACE_END
diff --git a/src/modules/texts/rawtext4/rawtext4.cpp b/src/modules/texts/rawtext4/rawtext4.cpp
index a06691e..65f5cef 100644
--- a/src/modules/texts/rawtext4/rawtext4.cpp
+++ b/src/modules/texts/rawtext4/rawtext4.cpp
@@ -1,9 +1,24 @@
/******************************************************************************
- * rawtext4.cpp - code for class 'RawText4'- a module that reads raw text files:
- * ot and nt using indexs ??.bks ??.cps ??.vss
+ * rawtext4.cpp - code for class 'RawText4'- a module that reads raw text
+ * files: ot and nt using indexs ??.bks ??.cps ??.vss
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <stdio.h>
#include <fcntl.h>
#include <sysdata.h>
@@ -42,27 +57,9 @@ typedef list<long> longlist;
* idisp - Display object to use for displaying
*/
-RawText4::RawText4(const char *ipath, const char *iname, const char *idesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang)
- : SWText(iname, idesc, idisp, enc, dir, mark, ilang),
+RawText4::RawText4(const char *ipath, const char *iname, const char *idesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang, const char *versification)
+ : SWText(iname, idesc, idisp, enc, dir, mark, ilang, versification),
RawVerse4(ipath) {
-
-#ifndef USELUCENE
- SWBuf fname;
- fname = path;
- char ch = fname.c_str()[strlen(fname.c_str())-1];
- if ((ch != '/') && (ch != '\\'))
- fname += "/";
-
- for (int loop = 0; loop < 2; loop++) {
- fastSearch[loop] = 0;
- SWBuf fastidxname =(fname + ((loop)?"ntwords.dat":"otwords.dat"));
- if (FileMgr::existsFile(fastidxname.c_str())) {
- fastidxname = (fname + ((loop)?"ntwords.idx":"otwords.idx"));
- if (FileMgr::existsFile(fastidxname.c_str()))
- fastSearch[loop] = new RawStr4((fname + ((loop)?"ntwords":"otwords")).c_str());
- }
- }
-#endif
}
@@ -71,13 +68,6 @@ RawText4::RawText4(const char *ipath, const char *iname, const char *idesc, SWDi
*/
RawText4::~RawText4() {
-#ifndef USELUCENE
- if (fastSearch[0])
- delete fastSearch[0];
-
- if (fastSearch[1])
- delete fastSearch[1];
-#endif
}
@@ -98,7 +88,7 @@ SWBuf &RawText4::getRawEntryBuf() {
unsigned long size = 0;
VerseKey &key = getVerseKey();
- findOffset(key.Testament(), key.Index(), &start, &size);
+ findOffset(key.Testament(), key.TestamentIndex(), &start, &size);
entrySize = size; // support getEntrySize call
entryBuf = "";
@@ -114,382 +104,16 @@ SWBuf &RawText4::getRawEntryBuf() {
}
-signed char RawText4::createSearchFramework(void (*percent)(char, void *), void *percentUserData) {
-#ifndef USELUCENE
- SWKey *savekey = 0;
- SWKey *searchkey = 0;
- SWKey textkey;
- char *word = 0;
- char *wordBuf = 0;
-
- // dictionary holds words associated with a list
- // containing every module position that contains
- // the word. [0] Old Testament; [1] NT
- map < SWBuf, list<long> > dictionary[2];
-
-
- // save key information so as not to disrupt original
- // module position
- if (!key->Persist()) {
- savekey = CreateKey();
- *savekey = *key;
- }
- else savekey = key;
-
- searchkey = (key->Persist())?key->clone():0;
- if (searchkey) {
- searchkey->Persist(1);
- setKey(*searchkey);
- }
-
- // position module at the beginning
- *this = TOP;
-
- VerseKey *lkey = (VerseKey *)key;
-
- // iterate thru each entry in module
- while (!Error()) {
- long index = lkey->Index();
- wordBuf = (char *)calloc(sizeof(char), strlen(StripText()) + 1);
- strcpy(wordBuf, StripText());
-
- // grab each word from the text
- word = strtok(wordBuf, " !.,?;:()-=+/\\|{}[]\"<>");
- while (word) {
-
- // make word upper case
- toupperstr(word);
-
- // lookup word in dictionary (or make entry in dictionary
- // for this word) and add this module position (index) to
- // the word's associated list of module positions
- dictionary[lkey->Testament()-1][word].push_back(index);
- word = strtok(NULL, " !.,?;:()-=+/\\|{}[]\"<>");
- }
- free(wordBuf);
- (*this)++;
- }
-
- // reposition module back to where it was before we were called
- setKey(*savekey);
-
- if (!savekey->Persist())
- delete savekey;
-
- if (searchkey)
- delete searchkey;
-
-
- // --------- Let's output an index from our dictionary -----------
- FileDesc *datfd;
- FileDesc *idxfd;
- strlist::iterator it;
- longlist::iterator it2;
- unsigned long offset, entryoff;
- unsigned long size;
-
- SWBuf fname;
- fname = path;
- char ch = fname.c_str()[strlen(fname.c_str())-1];
- if ((ch != '/') && (ch != '\\'))
- fname += "/";
-
- // for old and new testament do...
- for (int loop = 0; loop < 2; loop++) {
- datfd = FileMgr::getSystemFileMgr()->open((fname + ((loop)?"ntwords.dat":"otwords.dat")).c_str(), FileMgr::CREAT|FileMgr::WRONLY, 00644);
- if (datfd->getFd() == -1)
- return -1;
- idxfd = FileMgr::getSystemFileMgr()->open((fname + ((loop)?"ntwords.idx":"otwords.idx")).c_str(), FileMgr::CREAT|FileMgr::WRONLY, 00644);
- if (idxfd->getFd() == -1) {
- FileMgr::getSystemFileMgr()->close(datfd);
- return -1;
- }
-
- // iterate thru each word in the dictionary
- for (it = dictionary[loop].begin(); it != dictionary[loop].end(); it++) {
- printf("%s: ", it->first.c_str());
-
- // get our current offset in our word.dat file and write this as the start
- // of the next entry in our database
- offset = datfd->seek(0, SEEK_CUR);
- idxfd->write(&offset, 4);
-
- // write our word out to the word.dat file, delineating with a \n
- datfd->write(it->first.c_str(), strlen(it->first.c_str()));
- datfd->write("\n", 1);
-
- // force our mod position list for this word to be unique (remove
- // duplicates that may exist if the word was found more than once
- // in the verse
- it->second.unique();
-
- // iterate thru each mod position for this word and output it to
- // our database
- unsigned short count = 0;
- for (it2 = it->second.begin(); it2 != it->second.end(); it2++) {
- entryoff= *it2;
- datfd->write(&entryoff, 4);
- count++;
- }
-
- // now see what our new position is in our word.dat file and
- // determine the size of this database entry
- size = datfd->seek(0, SEEK_CUR) - offset;
-
- // store the size of this database entry
- idxfd->write(&size, 4);
- printf("%d entries (size: %d)\n", count, size);
- }
- FileMgr::getSystemFileMgr()->close(datfd);
- FileMgr::getSystemFileMgr()->close(idxfd);
- }
- return 0;
-#else
- return SWModule::createSearchFramework(percent, percentUserData);
-#endif
-}
-
-
-void RawText4::deleteSearchFramework() {
-#ifndef USELUCENE
- SWBuf target = path;
- char ch = target.c_str()[strlen(target.c_str())-1];
- if ((ch != '/') && (ch != '\\'))
- target += "/lucene";
- FileMgr::removeFile(target + "ntwords.dat");
- FileMgr::removeFile(target + "otwords.dat");
- FileMgr::removeFile(target + "ntwords.idx");
- FileMgr::removeFile(target + "otwords.idx");
-#else
- SWModule::deleteSearchFramework();
-#endif
-}
-
-
-/******************************************************************************
- * SWModule::search - Searches a module for a string
- *
- * ENT: istr - string for which to search
- * searchType - type of search to perform
- * >=0 - regex
- * -1 - phrase
- * -2 - multiword
- * flags - options flags for search
- * justCheckIfSupported - if set, don't search, only tell if this
- * function supports requested search.
- *
- * RET: ListKey set to verses that contain istr
- */
-
-ListKey &RawText4::search(const char *istr, int searchType, int flags, SWKey *scope, bool *justCheckIfSupported, void (*percent)(char, void *), void *percentUserData) {
-#ifndef USELUCENE
- listKey.ClearList();
-
- if ((fastSearch[0]) && (fastSearch[1])) {
-
- switch (searchType) {
- case -2: {
-
- if ((flags & REG_ICASE) != REG_ICASE) // if haven't chosen to
- // ignore case
- break; // can't handle fast case sensitive searches
-
- // test to see if our scope for this search is bounded by a
- // VerseKey
- VerseKey *testKeyType = 0;
- SWTRY {
- testKeyType = SWDYNAMIC_CAST(VerseKey, ((scope)?scope:key));
- }
- SWCATCH ( ... ) {}
- // if we don't have a VerseKey * decendant we can't handle
- // because of scope.
- // In the future, add bool SWKey::isValid(const char *tryString);
- if (!testKeyType)
- break;
-
-
- // check if we just want to see if search is supported.
- // If we've gotten this far, then it is supported.
- if (justCheckIfSupported) {
- *justCheckIfSupported = true;
- return listKey;
- }
-
- SWKey saveKey = *testKeyType; // save current place
-
- char error = 0;
- char **words = 0;
- char *wordBuf = 0;
- int wordCount = 0;
- long start;
- unsigned long size;
- char *idxbuf = 0;
- SWBuf datBuf;
- list <long> indexes;
- list <long> indexes2;
- VerseKey vk;
- vk = TOP;
-
- (*percent)(10, percentUserData);
-
- // toupper our copy of search string
- stdstr(&wordBuf, istr);
- toupperstr(wordBuf);
-
- // get list of individual words
- words = (char **)calloc(sizeof(char *), 10);
- int allocWords = 10;
- words[wordCount] = strtok(wordBuf, " ");
- while (words[wordCount]) {
- wordCount++;
- if (wordCount == allocWords) {
- allocWords+=10;
- words = (char **)realloc(words, sizeof(char *)*allocWords);
- }
- words[wordCount] = strtok(NULL, " ");
- }
-
- (*percent)(20, percentUserData);
-
- // clear our result set
- indexes.erase(indexes.begin(), indexes.end());
-
- // search both old and new testament indexes
- for (int j = 0; j < 2; j++) {
- // iterate thru each word the user passed to us.
- for (int i = 0; i < wordCount; i++) {
-
- // clear this word's result set
- indexes2.erase(indexes2.begin(), indexes2.end());
- error = 0;
-
- // iterate thru every word in the database that starts
- // with our search word
- for (int away = 0; !error; away++) {
- idxbuf = 0;
-
- // find our word in the database and jump ahead _away_
- error = fastSearch[j]->findOffset(words[i], &start, &size, away);
-
- // get the word from the database
- fastSearch[j]->getIDXBufDat(start, &idxbuf);
-
- // check to see if it starts with our target word
- if (strlen(idxbuf) > strlen(words[i]))
- idxbuf[strlen(words[i])] = 0;
-// else words[i][strlen(idxbuf)] = 0;
- if (!strcmp(idxbuf, words[i])) {
-
- // get data for this word from database
- delete [] idxbuf;
- idxbuf = 0;
- datBuf = "";
- fastSearch[j]->readText(start, &size, &idxbuf, datBuf);
-
- // we know that the data consists of sizof(long)
- // records each a valid module position that constains
- // this word
- //
- // iterate thru each of these module positions
- long *keyindex = (long *)datBuf.getRawData();
- while (keyindex < (long *)(datBuf.getRawData() + size - (strlen(idxbuf) + 1))) {
- if (i) { // if we're not on our first word
-
- // check to see if this word is already in the result set.
- // This is our AND functionality
- if (find(indexes.begin(), indexes.end(), *keyindex) != indexes.end())
- // add to new result set
- indexes2.push_back(*keyindex);
- }
- else indexes2.push_back(*keyindex);
- keyindex++;
- }
- }
- else error = 1; // no more matches
- free(idxbuf);
- }
-
- // make new result set final result set
- indexes = indexes2;
-
- percent((char)(20 + (float)((j*wordCount)+i)/(wordCount * 2) * 78), percentUserData);
- }
-
- // indexes contains our good verses, lets return them in a listKey
- indexes.sort();
-
- // iterate thru each good module position that meets the search
- for (longlist::iterator it = indexes.begin(); it != indexes.end(); it++) {
-
- // set a temporary verse key to this module position
- vk.Testament(j+1);
- vk.Error();
- vk.Index(*it);
-
- // check scope
- // Try to set our scope key to this verse key
- if (scope) {
- *testKeyType = vk;
-
- // check to see if it set ok and if so, add to our return list
- if (*testKeyType == vk)
- listKey << (const char *) vk;
- }
- else listKey << (const char*) vk;
- }
- }
- (*percent)(98, percentUserData);
-
- free(words);
- free(wordBuf);
-
- *testKeyType = saveKey; // set current place back to original
-
- listKey = TOP;
- (*percent)(100, percentUserData);
- return listKey;
- }
-
- default:
- break;
- }
- }
-
- // check if we just want to see if search is supported
- if (justCheckIfSupported) {
- *justCheckIfSupported = false;
- return listKey;
- }
-
-#endif
- // if we don't support this search, fall back to base class
- return SWModule::search(istr, searchType, flags, scope, justCheckIfSupported, percent, percentUserData);
-}
-
-
void RawText4::setEntry(const char *inbuf, long len) {
VerseKey &key = getVerseKey();
- doSetText(key.Testament(), key.Index(), inbuf, len);
+ doSetText(key.Testament(), key.TestamentIndex(), inbuf, len);
}
void RawText4::linkEntry(const SWKey *inkey) {
VerseKey &destkey = getVerseKey();
- const VerseKey *srckey = 0;
-
- // see if we have a VerseKey * or decendant
- SWTRY {
- srckey = SWDYNAMIC_CAST(VerseKey, inkey);
- }
- SWCATCH ( ... ) {}
- // if we don't have a VerseKey * decendant, create our own
- if (!srckey)
- srckey = new VerseKey(inkey);
-
- doLinkEntry(destkey.Testament(), destkey.Index(), srckey->Index());
-
- if (inkey != srckey) // free our key if we created a VerseKey
- delete srckey;
+ const VerseKey *srckey = &getVerseKey(inkey);
+ doLinkEntry(destkey.Testament(), destkey.TestamentIndex(), srckey->TestamentIndex());
}
@@ -501,7 +125,7 @@ void RawText4::linkEntry(const SWKey *inkey) {
void RawText4::deleteEntry() {
VerseKey &key = getVerseKey();
- doSetText(key.Testament(), key.Index(), "");
+ doSetText(key.Testament(), key.TestamentIndex(), "");
}
/******************************************************************************
@@ -517,21 +141,21 @@ void RawText4::increment(int steps) {
unsigned long size;
VerseKey *tmpkey = &getVerseKey();
- findOffset(tmpkey->Testament(), tmpkey->Index(), &start, &size);
+ findOffset(tmpkey->Testament(), tmpkey->TestamentIndex(), &start, &size);
SWKey lastgood = *tmpkey;
while (steps) {
long laststart = start;
unsigned long lastsize = size;
SWKey lasttry = *tmpkey;
- (steps > 0) ? (*key)++ : (*key)--;
+ (steps > 0) ? ++(*key) : --(*key);
tmpkey = &getVerseKey();
if ((error = key->Error())) {
*key = lastgood;
break;
}
- long index = tmpkey->Index();
+ long index = tmpkey->TestamentIndex();
findOffset(tmpkey->Testament(), index, &start, &size);
if (
(((laststart != start) || (lastsize != size)) // we're a different entry
@@ -545,4 +169,25 @@ void RawText4::increment(int steps) {
error = (error) ? KEYERR_OUTOFBOUNDS : 0;
}
+bool RawText4::isLinked(const SWKey *k1, const SWKey *k2) const {
+ long start1, start2;
+ unsigned long size1, size2;
+ VerseKey *vk1 = &getVerseKey(k1);
+ VerseKey *vk2 = &getVerseKey(k2);
+ if (vk1->Testament() != vk2->Testament()) return false;
+
+ findOffset(vk1->Testament(), vk1->TestamentIndex(), &start1, &size1);
+ findOffset(vk2->Testament(), vk2->TestamentIndex(), &start2, &size2);
+ return start1 == start2;
+}
+
+bool RawText4::hasEntry(const SWKey *k) const {
+ long start;
+ unsigned long size;
+ VerseKey *vk = &getVerseKey(k);
+
+ findOffset(vk->Testament(), vk->TestamentIndex(), &start, &size);
+ return size;
+}
+
SWORD_NAMESPACE_END
diff --git a/src/modules/texts/swtext.cpp b/src/modules/texts/swtext.cpp
index d0ff386..a7f5f92 100644
--- a/src/modules/texts/swtext.cpp
+++ b/src/modules/texts/swtext.cpp
@@ -1,7 +1,24 @@
/******************************************************************************
* swtext.cpp - code for base class 'SWText'- The basis for all text modules
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
+#include <utilstr.h>
#include <swtext.h>
#include <listkey.h>
#include <localemgr.h>
@@ -17,10 +34,14 @@ SWORD_NAMESPACE_START
* idisp - Display object to use for displaying
*/
-SWText::SWText(const char *imodname, const char *imoddesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang): SWModule(imodname, imoddesc, idisp, (char *)"Biblical Texts", enc, dir, mark, ilang) {
- tmpVK = new VerseKey();
+SWText::SWText(const char *imodname, const char *imoddesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang, const char *versification): SWModule(imodname, imoddesc, idisp, "Biblical Texts", enc, dir, mark, ilang) {
+ this->versification = 0;
+ stdstr(&(this->versification), versification);
delete key;
- key = CreateKey();
+ key = (VerseKey *)CreateKey();
+ tmpVK1 = (VerseKey *)CreateKey();
+ tmpVK2 = (VerseKey *)CreateKey();
+ tmpSecond = false;
skipConsecutiveLinks = false;
}
@@ -30,7 +51,9 @@ SWText::SWText(const char *imodname, const char *imoddesc, SWDisplay *idisp, SWT
*/
SWText::~SWText() {
- delete tmpVK;
+ delete tmpVK1;
+ delete tmpVK2;
+ delete [] versification;
}
@@ -38,60 +61,49 @@ SWText::~SWText() {
* SWText CreateKey - Create the correct key (VerseKey) for use with SWText
*/
-SWKey *SWText::CreateKey() {
- return new VerseKey();
-}
+SWKey *SWText::CreateKey() const {
+ VerseKey *vk = new VerseKey();
+ vk->setVersificationSystem(versification);
-long SWText::Index() const {
- VerseKey *key = 0;
- SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, this->key);
- }
- SWCATCH ( ... ) {}
- if (!key)
- key = new VerseKey(this->key);
+ return vk;
+}
- entryIndex = key->NewIndex();
- if (key != this->key)
- delete key;
+long SWText::Index() const {
+ VerseKey *key = &getVerseKey();
+ entryIndex = key->Index();
return entryIndex;
}
long SWText::Index(long iindex) {
- VerseKey *key = 0;
- SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, this->key);
- }
- SWCATCH ( ... ) {}
- if (!key)
- key = new VerseKey(this->key);
+ VerseKey *key = &getVerseKey();
key->Testament(1);
key->Index(iindex);
if (key != this->key) {
this->key->copyFrom(*key);
- delete key;
}
return Index();
}
-VerseKey &SWText::getVerseKey() const {
- VerseKey *key = NULL;
+VerseKey &SWText::getVerseKey(const SWKey *keyToConvert) const {
+ const SWKey *thisKey = keyToConvert ? keyToConvert : this->key;
+
+ VerseKey *key = 0;
// see if we have a VerseKey * or decendant
SWTRY {
- key = SWDYNAMIC_CAST(VerseKey, this->key);
+ key = SWDYNAMIC_CAST(VerseKey, thisKey);
}
SWCATCH ( ... ) { }
if (!key) {
ListKey *lkTest = 0;
SWTRY {
- lkTest = SWDYNAMIC_CAST(ListKey, this->key);
+ lkTest = SWDYNAMIC_CAST(ListKey, thisKey);
}
SWCATCH ( ... ) { }
if (lkTest) {
@@ -102,9 +114,11 @@ VerseKey &SWText::getVerseKey() const {
}
}
if (!key) {
- tmpVK->setLocale(LocaleMgr::getSystemLocaleMgr()->getDefaultLocaleName());
- (*tmpVK) = *(this->key);
- return (*tmpVK);
+ VerseKey *retKey = (tmpSecond) ? tmpVK1 : tmpVK2;
+ tmpSecond = !tmpSecond;
+ retKey->setLocale(LocaleMgr::getSystemLocaleMgr()->getDefaultLocaleName());
+ (*retKey) = *(thisKey);
+ return (*retKey);
}
else return *key;
}
diff --git a/src/modules/texts/ztext/ztext.cpp b/src/modules/texts/ztext/ztext.cpp
index b461d49..61b3008 100644
--- a/src/modules/texts/ztext/ztext.cpp
+++ b/src/modules/texts/ztext/ztext.cpp
@@ -1,9 +1,24 @@
/******************************************************************************
* ztext.cpp - code for class 'zText'- a module that reads compressed text
* files: ot and nt using indexs ??.vss
+ *
+ *
+ * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
*/
-
#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>
@@ -29,8 +44,8 @@ SWORD_NAMESPACE_START
* idisp - Display object to use for displaying
*/
-zText::zText(const char *ipath, const char *iname, const char *idesc, int iblockType, SWCompress *icomp, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang)
- : zVerse(ipath, FileMgr::RDWR, iblockType, icomp), SWText(iname, idesc, idisp, enc, dir, mark, ilang) {
+zText::zText(const char *ipath, const char *iname, const char *idesc, int iblockType, SWCompress *icomp, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char *ilang, const char *versification)
+ : zVerse(ipath, FileMgr::RDWR, iblockType, icomp), SWText(iname, idesc, idisp, enc, dir, mark, ilang, versification) {
blockType = iblockType;
lastWriteKey = 0;
}
@@ -62,14 +77,15 @@ bool zText::isWritable() { return ((idxfp[0]->getFd() > 0) && ((idxfp[0]->mode &
SWBuf &zText::getRawEntryBuf() {
long start = 0;
unsigned short size = 0;
+ unsigned long buffnum = 0;
VerseKey &key = getVerseKey();
- findOffset(key.Testament(), key.Index(), &start, &size);
+ findOffset(key.Testament(), key.TestamentIndex(), &start, &size, &buffnum);
entrySize = size; // support getEntrySize call
entryBuf = "";
- zReadText(key.Testament(), start, size, entryBuf);
-
+
+ zReadText(key.Testament(), start, size, buffnum, entryBuf);
rawFilter(entryBuf, &key);
// if (!isUnicode())
@@ -109,7 +125,7 @@ void zText::setEntry(const char *inbuf, long len) {
delete lastWriteKey;
}
- doSetText(key.Testament(), key.Index(), inbuf, len);
+ doSetText(key.Testament(), key.TestamentIndex(), inbuf, len);
lastWriteKey = (VerseKey *)key.clone(); // must delete
}
@@ -117,22 +133,8 @@ void zText::setEntry(const char *inbuf, long len) {
void zText::linkEntry(const SWKey *inkey) {
VerseKey &destkey = getVerseKey();
- const VerseKey *srckey = 0;
-
- // see if we have a VerseKey * or decendant
- SWTRY {
- srckey = (const VerseKey *) SWDYNAMIC_CAST(VerseKey, inkey);
- }
- SWCATCH ( ... ) {
- }
- // if we don't have a VerseKey * decendant, create our own
- if (!srckey)
- srckey = new VerseKey(inkey);
-
- doLinkEntry(destkey.Testament(), destkey.Index(), srckey->Index());
-
- if (inkey != srckey) // free our key if we created a VerseKey
- delete srckey;
+ const VerseKey *srckey = &getVerseKey(inkey);
+ doLinkEntry(destkey.Testament(), destkey.TestamentIndex(), srckey->TestamentIndex());
}
@@ -145,7 +147,7 @@ void zText::deleteEntry() {
VerseKey &key = getVerseKey();
- doSetText(key.Testament(), key.Index(), "");
+ doSetText(key.Testament(), key.TestamentIndex(), "");
}
@@ -157,26 +159,27 @@ void zText::deleteEntry() {
*/
void zText::increment(int steps) {
- long start;
+ long start;
unsigned short size;
+ unsigned long buffnum;
VerseKey *tmpkey = &getVerseKey();
- findOffset(tmpkey->Testament(), tmpkey->Index(), &start, &size);
+ findOffset(tmpkey->Testament(), tmpkey->TestamentIndex(), &start, &size, &buffnum);
SWKey lastgood = *tmpkey;
while (steps) {
long laststart = start;
unsigned short lastsize = size;
SWKey lasttry = *tmpkey;
- (steps > 0) ? (*key)++ : (*key)--;
+ (steps > 0) ? ++(*key) : --(*key);
tmpkey = &getVerseKey();
if ((error = key->Error())) {
*key = lastgood;
break;
}
- long index = tmpkey->Index();
- findOffset(tmpkey->Testament(), index, &start, &size);
+ long index = tmpkey->TestamentIndex();
+ findOffset(tmpkey->Testament(), index, &start, &size, &buffnum);
if (
(((laststart != start) || (lastsize != size)) // we're a different entry
@@ -190,6 +193,28 @@ void zText::increment(int steps) {
error = (error) ? KEYERR_OUTOFBOUNDS : 0;
}
+bool zText::isLinked(const SWKey *k1, const SWKey *k2) const {
+ long start1, start2;
+ unsigned short size1, size2;
+ unsigned long buffnum1, buffnum2;
+ VerseKey *vk1 = &getVerseKey(k1);
+ VerseKey *vk2 = &getVerseKey(k2);
+ if (vk1->Testament() != vk2->Testament()) return false;
+
+ findOffset(vk1->Testament(), vk1->TestamentIndex(), &start1, &size1, &buffnum1);
+ findOffset(vk2->Testament(), vk2->TestamentIndex(), &start2, &size2, &buffnum2);
+ return start1 == start2 && buffnum1 == buffnum2;
+}
+
+bool zText::hasEntry(const SWKey *k) const {
+ long start;
+ unsigned short size;
+ unsigned long buffnum;
+ VerseKey *vk = &getVerseKey(k);
+
+ findOffset(vk->Testament(), vk->TestamentIndex(), &start, &size, &buffnum);
+ return size;
+}
SWORD_NAMESPACE_END
diff --git a/src/utilfuns/Makefile.am b/src/utilfuns/Makefile.am
index 4160db0..e0fc031 100644
--- a/src/utilfuns/Makefile.am
+++ b/src/utilfuns/Makefile.am
@@ -1,7 +1,7 @@
if HAVE_VSNPRINTF
else
-CXXFLAGS += -DNO_VSNPRINTF
+AM_CXXFLAGS += -DNO_VSNPRINTF
endif
utilfunsdir = $(top_srcdir)/src/utilfuns
diff --git a/src/utilfuns/regex.c b/src/utilfuns/regex.c
deleted file mode 100644
index 09743d2..0000000
--- a/src/utilfuns/regex.c
+++ /dev/null
@@ -1,5721 +0,0 @@
-/* Extended regular expression matching and search library,
- version 0.12.
- (Implements POSIX draft P1003.2/D11.2, except for some of the
- internationalization features.)
-
- Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
-
- the C library, however. The master source lives in /gd/gnu/lib.
-
-NOTE: The canonical source of this file is maintained with the
-GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software Foundation,
-Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* AIX requires this to be the first thing in the file. */
-#if defined (_AIX) && !defined (REGEX_MALLOC)
- #pragma alloca
-#endif
-
-#undef _GNU_SOURCE
-#define _GNU_SOURCE
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if defined(STDC_HEADERS) && !defined(emacs)
-#include <stddef.h>
-#else
-/* We need this for `regex.h', and perhaps for the Emacs include files. */
-#include <sys/types.h>
-#endif
-#include <stdlib.h> // sword
-
-/* For platform which support the ISO C amendement 1 functionality we
- support user defined character classes. */
-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
-# include <wctype.h>
-# include <wchar.h>
-#endif
-
-/* This is for other GNU distributions with internationalized messages. */
-#if HAVE_LIBINTL_H || defined (_LIBC)
-# include <libintl.h>
-#else
-# define gettext(msgid) (msgid)
-#endif
-
-#ifndef gettext_noop
-/* This define is so xgettext can find the internationalizable
- strings. */
-#define gettext_noop(String) String
-#endif
-
-/* The `emacs' switch turns on certain matching commands
- that make sense only in Emacs. */
-#ifdef emacs
-
-#include "lisp.h"
-#include "buffer.h"
-#include "syntax.h"
-
-#else /* not emacs */
-
-/* If we are not linking with Emacs proper,
- we can't use the relocating allocator
- even if config.h says that we can. */
-#undef REL_ALLOC
-
-#if defined (STDC_HEADERS) || defined (_LIBC)
-#include <stdlib.h>
-#else
-//sword char *malloc ();
-//sword char *realloc ();
-#endif
-
-/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow.
- If nothing else has been done, use the method below. */
-#ifdef INHIBIT_STRING_HEADER
-#if !(defined (HAVE_BZERO) && defined (HAVE_BCOPY))
-#if !defined (bzero) && !defined (bcopy)
-#undef INHIBIT_STRING_HEADER
-#endif
-#endif
-#endif
-
-/* This is the normal way of making sure we have a bcopy and a bzero.
- This is used in most programs--a few other programs avoid this
- by defining INHIBIT_STRING_HEADER. */
-#define HAVE_STRING_H // for SWORD Project
-#ifndef INHIBIT_STRING_HEADER
-#if defined (HAVE_STRING_H) || defined (STDC_HEADERS) || defined (_LIBC)
-#include <string.h>
-#ifndef bcmp
-#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
-#endif
-#ifndef bcopy
-#define bcopy(s, d, n) memcpy ((d), (s), (n))
-#endif
-#ifndef bzero
-#define bzero(s, n) memset ((s), 0, (n))
-#endif
-#else
-#include <strings.h>
-#endif
-#endif
-
-/* Define the syntax stuff for \<, \>, etc. */
-
-/* This must be nonzero for the wordchar and notwordchar pattern
- commands in re_match_2. */
-#ifndef Sword
-#define Sword 1
-#endif
-
-#ifdef SWITCH_ENUM_BUG
-#define SWITCH_ENUM_CAST(x) ((int)(x))
-#else
-#define SWITCH_ENUM_CAST(x) (x)
-#endif
-
-#ifdef SYNTAX_TABLE
-
-extern char *re_syntax_table;
-
-#else /* not SYNTAX_TABLE */
-
-/* How many characters in the character set. */
-#define CHAR_SET_SIZE 256
-
-static char re_syntax_table[CHAR_SET_SIZE];
-
-static void
-init_syntax_once ()
-{
- register int c;
- static int done = 0;
-
- if (done)
- return;
-
- bzero (re_syntax_table, sizeof re_syntax_table);
-
- for (c = 'a'; c <= 'z'; c++)
- re_syntax_table[c] = Sword;
-
- for (c = 'A'; c <= 'Z'; c++)
- re_syntax_table[c] = Sword;
-
- for (c = '0'; c <= '9'; c++)
- re_syntax_table[c] = Sword;
-
- re_syntax_table['_'] = Sword;
-
- done = 1;
-}
-
-#endif /* not SYNTAX_TABLE */
-
-#define SYNTAX(c) re_syntax_table[c]
-
-#endif /* not emacs */
-
-/* Get the interface, including the syntax bits. */
-#include "regex.h"
-
-/* isalpha etc. are used for the character classes. */
-#include <ctype.h>
-
-/* Jim Meyering writes:
-
- "... Some ctype macros are valid only for character codes that
- isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
- using /bin/cc or gcc but without giving an ansi option). So, all
- ctype uses should be through macros like ISPRINT... If
- STDC_HEADERS is defined, then autoconf has verified that the ctype
- macros don't need to be guarded with references to isascii. ...
- Defining isascii to 1 should let any compiler worth its salt
- eliminate the && through constant folding." */
-
-#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
-#define ISASCII(c) 1
-#else
-#define ISASCII(c) isascii(c)
-#endif
-
-#ifdef isblank
-#define ISBLANK(c) (ISASCII (c) && isblank (c))
-#else
-#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
-#endif
-#ifdef isgraph
-#define ISGRAPH(c) (ISASCII (c) && isgraph (c))
-#else
-#define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
-#endif
-
-#define ISPRINT(c) (ISASCII (c) && isprint (c))
-#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
-#define ISALNUM(c) (ISASCII (c) && isalnum (c))
-#define ISALPHA(c) (ISASCII (c) && isalpha (c))
-#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
-#define ISLOWER(c) (ISASCII (c) && islower (c))
-#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
-#define ISSPACE(c) (ISASCII (c) && isspace (c))
-#define ISUPPER(c) (ISASCII (c) && isupper (c))
-#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
-
-#ifndef NULL
-#define NULL (void *)0
-#endif
-
-/* We remove any previous definition of `SIGN_EXTEND_CHAR',
- since ours (we hope) works properly with all combinations of
- machines, compilers, `char' and `unsigned char' argument types.
- (Per Bothner suggested the basic approach.) */
-#undef SIGN_EXTEND_CHAR
-#if __STDC__
-#define SIGN_EXTEND_CHAR(c) ((signed char) (c))
-#else /* not __STDC__ */
-/* As in Harbison and Steele. */
-#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
-#endif
-
-/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
- use `alloca' instead of `malloc'. This is because using malloc in
- re_search* or re_match* could cause memory leaks when C-g is used in
- Emacs; also, malloc is slower and causes storage fragmentation. On
- the other hand, malloc is more portable, and easier to debug.
-
- Because we sometimes use alloca, some routines have to be macros,
- not functions -- `alloca'-allocated space disappears at the end of the
- function it is called in. */
-
-#ifdef REGEX_MALLOC
-
-#define REGEX_ALLOCATE malloc
-#define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
-#define REGEX_FREE free
-
-#else /* not REGEX_MALLOC */
-
-/* Emacs already defines alloca, sometimes. */
-#ifndef alloca
-
-/* Make alloca work the best possible way. */
-#ifdef __GNUC__
-#define alloca __builtin_alloca
-#else /* not __GNUC__ */
-#if HAVE_ALLOCA_H
-#include <alloca.h>
-#else /* not __GNUC__ or HAVE_ALLOCA_H */
-#if 0 /* It is a bad idea to declare alloca. We always cast the result. */
-#ifndef _AIX /* Already did AIX, up at the top. */
-char *alloca ();
-#endif /* not _AIX */
-#endif
-#endif /* not HAVE_ALLOCA_H */
-#endif /* not __GNUC__ */
-
-#endif /* not alloca */
-
-#define REGEX_ALLOCATE alloca
-
-/* Assumes a `char *destination' variable. */
-#define REGEX_REALLOCATE(source, osize, nsize) \
- (destination = (char *) alloca (nsize), \
- bcopy (source, destination, osize), \
- destination)
-
-/* No need to do anything to free, after alloca. */
-#define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */
-
-#endif /* not REGEX_MALLOC */
-
-/* Define how to allocate the failure stack. */
-
-#if defined (REL_ALLOC) && defined (REGEX_MALLOC)
-
-#define REGEX_ALLOCATE_STACK(size) \
- r_alloc (&failure_stack_ptr, (size))
-#define REGEX_REALLOCATE_STACK(source, osize, nsize) \
- r_re_alloc (&failure_stack_ptr, (nsize))
-#define REGEX_FREE_STACK(ptr) \
- r_alloc_free (&failure_stack_ptr)
-
-#else /* not using relocating allocator */
-
-#ifdef REGEX_MALLOC
-
-#define REGEX_ALLOCATE_STACK malloc
-#define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
-#define REGEX_FREE_STACK free
-
-#else /* not REGEX_MALLOC */
-
-#define REGEX_ALLOCATE_STACK alloca
-
-#define REGEX_REALLOCATE_STACK(source, osize, nsize) \
- REGEX_REALLOCATE (source, osize, nsize)
-/* No need to explicitly free anything. */
-#define REGEX_FREE_STACK(arg)
-
-#endif /* not REGEX_MALLOC */
-#endif /* not using relocating allocator */
-
-
-/* True if `size1' is non-NULL and PTR is pointing anywhere inside
- `string1' or just past its end. This works if PTR is NULL, which is
- a good thing. */
-#define FIRST_STRING_P(ptr) \
- (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
-
-/* (Re)Allocate N items of type T using malloc, or fail. */
-#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
-#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
-#define RETALLOC_IF(addr, n, t) \
- if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
-#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
-
-#define BYTEWIDTH 8 /* In bits. */
-
-#define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
-
-#undef MAX
-#undef MIN
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-typedef char boolean;
-#define false 0
-#define true 1
-
-static int re_match_2_internal ();
-
-/* These are the command codes that appear in compiled regular
- expressions. Some opcodes are followed by argument bytes. A
- command code can specify any interpretation whatsoever for its
- arguments. Zero bytes may appear in the compiled regular expression. */
-
-typedef enum
-{
- no_op = 0,
-
- /* Succeed right away--no more backtracking. */
- succeed,
-
- /* Followed by one byte giving n, then by n literal bytes. */
- exactn,
-
- /* Matches any (more or less) character. */
- anychar,
-
- /* Matches any one char belonging to specified set. First
- following byte is number of bitmap bytes. Then come bytes
- for a bitmap saying which chars are in. Bits in each byte
- are ordered low-bit-first. A character is in the set if its
- bit is 1. A character too large to have a bit in the map is
- automatically not in the set. */
- charset,
-
- /* Same parameters as charset, but match any character that is
- not one of those specified. */
- charset_not,
-
- /* Start remembering the text that is matched, for storing in a
- register. Followed by one byte with the register number, in
- the range 0 to one less than the pattern buffer's re_nsub
- field. Then followed by one byte with the number of groups
- inner to this one. (This last has to be part of the
- start_memory only because we need it in the on_failure_jump
- of re_match_2.) */
- start_memory,
-
- /* Stop remembering the text that is matched and store it in a
- memory register. Followed by one byte with the register
- number, in the range 0 to one less than `re_nsub' in the
- pattern buffer, and one byte with the number of inner groups,
- just like `start_memory'. (We need the number of inner
- groups here because we don't have any easy way of finding the
- corresponding start_memory when we're at a stop_memory.) */
- stop_memory,
-
- /* Match a duplicate of something remembered. Followed by one
- byte containing the register number. */
- duplicate,
-
- /* Fail unless at beginning of line. */
- begline,
-
- /* Fail unless at end of line. */
- endline,
-
- /* Succeeds if at beginning of buffer (if emacs) or at beginning
- of string to be matched (if not). */
- begbuf,
-
- /* Analogously, for end of buffer/string. */
- endbuf,
-
- /* Followed by two byte relative address to which to jump. */
- jump,
-
- /* Same as jump, but marks the end of an alternative. */
- jump_past_alt,
-
- /* Followed by two-byte relative address of place to resume at
- in case of failure. */
- on_failure_jump,
-
- /* Like on_failure_jump, but pushes a placeholder instead of the
- current string position when executed. */
- on_failure_keep_string_jump,
-
- /* Throw away latest failure point and then jump to following
- two-byte relative address. */
- pop_failure_jump,
-
- /* Change to pop_failure_jump if know won't have to backtrack to
- match; otherwise change to jump. This is used to jump
- back to the beginning of a repeat. If what follows this jump
- clearly won't match what the repeat does, such that we can be
- sure that there is no use backtracking out of repetitions
- already matched, then we change it to a pop_failure_jump.
- Followed by two-byte address. */
- maybe_pop_jump,
-
- /* Jump to following two-byte address, and push a dummy failure
- point. This failure point will be thrown away if an attempt
- is made to use it for a failure. A `+' construct makes this
- before the first repeat. Also used as an intermediary kind
- of jump when compiling an alternative. */
- dummy_failure_jump,
-
- /* Push a dummy failure point and continue. Used at the end of
- alternatives. */
- push_dummy_failure,
-
- /* Followed by two-byte relative address and two-byte number n.
- After matching N times, jump to the address upon failure. */
- succeed_n,
-
- /* Followed by two-byte relative address, and two-byte number n.
- Jump to the address N times, then fail. */
- jump_n,
-
- /* Set the following two-byte relative address to the
- subsequent two-byte number. The address *includes* the two
- bytes of number. */
- set_number_at,
-
- wordchar, /* Matches any word-constituent character. */
- notwordchar, /* Matches any char that is not a word-constituent. */
-
- wordbeg, /* Succeeds if at word beginning. */
- wordend, /* Succeeds if at word end. */
-
- wordbound, /* Succeeds if at a word boundary. */
- notwordbound /* Succeeds if not at a word boundary. */
-
-#ifdef emacs
- ,before_dot, /* Succeeds if before point. */
- at_dot, /* Succeeds if at point. */
- after_dot, /* Succeeds if after point. */
-
- /* Matches any character whose syntax is specified. Followed by
- a byte which contains a syntax code, e.g., Sword. */
- syntaxspec,
-
- /* Matches any character whose syntax is not that specified. */
- notsyntaxspec
-#endif /* emacs */
-} re_opcode_t;
-
-/* Common operations on the compiled pattern. */
-
-/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
-
-#define STORE_NUMBER(destination, number) \
- do { \
- (destination)[0] = (number) & 0377; \
- (destination)[1] = (number) >> 8; \
- } while (0)
-
-/* Same as STORE_NUMBER, except increment DESTINATION to
- the byte after where the number is stored. Therefore, DESTINATION
- must be an lvalue. */
-
-#define STORE_NUMBER_AND_INCR(destination, number) \
- do { \
- STORE_NUMBER (destination, number); \
- (destination) += 2; \
- } while (0)
-
-/* Put into DESTINATION a number stored in two contiguous bytes starting
- at SOURCE. */
-
-#define EXTRACT_NUMBER(destination, source) \
- do { \
- (destination) = *(source) & 0377; \
- (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
- } while (0)
-
-#ifdef DEBUG
-static void extract_number _RE_ARGS ((int *dest, unsigned char *source));
-static void
-extract_number (dest, source)
- int *dest;
- unsigned char *source;
-{
- int temp = SIGN_EXTEND_CHAR (*(source + 1));
- *dest = *source & 0377;
- *dest += temp << 8;
-}
-
-#ifndef EXTRACT_MACROS /* To debug the macros. */
-#undef EXTRACT_NUMBER
-#define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
-#endif /* not EXTRACT_MACROS */
-
-#endif /* DEBUG */
-
-/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
- SOURCE must be an lvalue. */
-
-#define EXTRACT_NUMBER_AND_INCR(destination, source) \
- do { \
- EXTRACT_NUMBER (destination, source); \
- (source) += 2; \
- } while (0)
-
-#ifdef DEBUG
-static void extract_number_and_incr _RE_ARGS ((int *destination,
- unsigned char **source));
-static void
-extract_number_and_incr (destination, source)
- int *destination;
- unsigned char **source;
-{
- extract_number (destination, *source);
- *source += 2;
-}
-
-#ifndef EXTRACT_MACROS
-#undef EXTRACT_NUMBER_AND_INCR
-#define EXTRACT_NUMBER_AND_INCR(dest, src) \
- extract_number_and_incr (&dest, &src)
-#endif /* not EXTRACT_MACROS */
-
-#endif /* DEBUG */
-
-/* If DEBUG is defined, Regex prints many voluminous messages about what
- it is doing (if the variable `debug' is nonzero). If linked with the
- main program in `iregex.c', you can enter patterns and strings
- interactively. And if linked with the main program in `main.c' and
- the other test files, you can run the already-written tests. */
-
-#ifdef DEBUG
-
-/* We use standard I/O for debugging. */
-#include <stdio.h>
-
-/* It is useful to test things that ``must'' be true when debugging. */
-#include <assert.h>
-
-static int debug = 0;
-
-#define DEBUG_STATEMENT(e) e
-#define DEBUG_PRINT1(x) if (debug) printf (x)
-#define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
-#define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
-#define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
-#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
- if (debug) print_partial_compiled_pattern (s, e)
-#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
- if (debug) print_double_string (w, s1, sz1, s2, sz2)
-
-
-/* Print the fastmap in human-readable form. */
-
-void
-print_fastmap (fastmap)
- char *fastmap;
-{
- unsigned was_a_range = 0;
- unsigned i = 0;
-
- while (i < (1 << BYTEWIDTH))
- {
- if (fastmap[i++])
- {
- was_a_range = 0;
- putchar (i - 1);
- while (i < (1 << BYTEWIDTH) && fastmap[i])
- {
- was_a_range = 1;
- i++;
- }
- if (was_a_range)
- {
- printf ("-");
- putchar (i - 1);
- }
- }
- }
- putchar ('\n');
-}
-
-
-/* Print a compiled pattern string in human-readable form, starting at
- the START pointer into it and ending just before the pointer END. */
-
-void
-print_partial_compiled_pattern (start, end)
- unsigned char *start;
- unsigned char *end;
-{
- int mcnt, mcnt2;
- unsigned char *p1;
- unsigned char *p = start;
- unsigned char *pend = end;
-
- if (start == NULL)
- {
- printf ("(null)\n");
- return;
- }
-
- /* Loop over pattern commands. */
- while (p < pend)
- {
- printf ("%d:\t", p - start);
-
- switch ((re_opcode_t) *p++)
- {
- case no_op:
- printf ("/no_op");
- break;
-
- case exactn:
- mcnt = *p++;
- printf ("/exactn/%d", mcnt);
- do
- {
- putchar ('/');
- putchar (*p++);
- }
- while (--mcnt);
- break;
-
- case start_memory:
- mcnt = *p++;
- printf ("/start_memory/%d/%d", mcnt, *p++);
- break;
-
- case stop_memory:
- mcnt = *p++;
- printf ("/stop_memory/%d/%d", mcnt, *p++);
- break;
-
- case duplicate:
- printf ("/duplicate/%d", *p++);
- break;
-
- case anychar:
- printf ("/anychar");
- break;
-
- case charset:
- case charset_not:
- {
- register int c, last = -100;
- register int in_range = 0;
-
- printf ("/charset [%s",
- (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
-
- assert (p + *p < pend);
-
- for (c = 0; c < 256; c++)
- if (c / 8 < *p
- && (p[1 + (c/8)] & (1 << (c % 8))))
- {
- /* Are we starting a range? */
- if (last + 1 == c && ! in_range)
- {
- putchar ('-');
- in_range = 1;
- }
- /* Have we broken a range? */
- else if (last + 1 != c && in_range)
- {
- putchar (last);
- in_range = 0;
- }
-
- if (! in_range)
- putchar (c);
-
- last = c;
- }
-
- if (in_range)
- putchar (last);
-
- putchar (']');
-
- p += 1 + *p;
- }
- break;
-
- case begline:
- printf ("/begline");
- break;
-
- case endline:
- printf ("/endline");
- break;
-
- case on_failure_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/on_failure_jump to %d", p + mcnt - start);
- break;
-
- case on_failure_keep_string_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/on_failure_keep_string_jump to %d", p + mcnt - start);
- break;
-
- case dummy_failure_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/dummy_failure_jump to %d", p + mcnt - start);
- break;
-
- case push_dummy_failure:
- printf ("/push_dummy_failure");
- break;
-
- case maybe_pop_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/maybe_pop_jump to %d", p + mcnt - start);
- break;
-
- case pop_failure_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/pop_failure_jump to %d", p + mcnt - start);
- break;
-
- case jump_past_alt:
- extract_number_and_incr (&mcnt, &p);
- printf ("/jump_past_alt to %d", p + mcnt - start);
- break;
-
- case jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/jump to %d", p + mcnt - start);
- break;
-
- case succeed_n:
- extract_number_and_incr (&mcnt, &p);
- p1 = p + mcnt;
- extract_number_and_incr (&mcnt2, &p);
- printf ("/succeed_n to %d, %d times", p1 - start, mcnt2);
- break;
-
- case jump_n:
- extract_number_and_incr (&mcnt, &p);
- p1 = p + mcnt;
- extract_number_and_incr (&mcnt2, &p);
- printf ("/jump_n to %d, %d times", p1 - start, mcnt2);
- break;
-
- case set_number_at:
- extract_number_and_incr (&mcnt, &p);
- p1 = p + mcnt;
- extract_number_and_incr (&mcnt2, &p);
- printf ("/set_number_at location %d to %d", p1 - start, mcnt2);
- break;
-
- case wordbound:
- printf ("/wordbound");
- break;
-
- case notwordbound:
- printf ("/notwordbound");
- break;
-
- case wordbeg:
- printf ("/wordbeg");
- break;
-
- case wordend:
- printf ("/wordend");
-
-#ifdef emacs
- case before_dot:
- printf ("/before_dot");
- break;
-
- case at_dot:
- printf ("/at_dot");
- break;
-
- case after_dot:
- printf ("/after_dot");
- break;
-
- case syntaxspec:
- printf ("/syntaxspec");
- mcnt = *p++;
- printf ("/%d", mcnt);
- break;
-
- case notsyntaxspec:
- printf ("/notsyntaxspec");
- mcnt = *p++;
- printf ("/%d", mcnt);
- break;
-#endif /* emacs */
-
- case wordchar:
- printf ("/wordchar");
- break;
-
- case notwordchar:
- printf ("/notwordchar");
- break;
-
- case begbuf:
- printf ("/begbuf");
- break;
-
- case endbuf:
- printf ("/endbuf");
- break;
-
- default:
- printf ("?%d", *(p-1));
- }
-
- putchar ('\n');
- }
-
- printf ("%d:\tend of pattern.\n", p - start);
-}
-
-
-void
-print_compiled_pattern (bufp)
- struct re_pattern_buffer *bufp;
-{
- unsigned char *buffer = bufp->buffer;
-
- print_partial_compiled_pattern (buffer, buffer + bufp->used);
- printf ("%ld bytes used/%ld bytes allocated.\n",
- bufp->used, bufp->allocated);
-
- if (bufp->fastmap_accurate && bufp->fastmap)
- {
- printf ("fastmap: ");
- print_fastmap (bufp->fastmap);
- }
-
- printf ("re_nsub: %d\t", bufp->re_nsub);
- printf ("regs_alloc: %d\t", bufp->regs_allocated);
- printf ("can_be_null: %d\t", bufp->can_be_null);
- printf ("newline_anchor: %d\n", bufp->newline_anchor);
- printf ("no_sub: %d\t", bufp->no_sub);
- printf ("not_bol: %d\t", bufp->not_bol);
- printf ("not_eol: %d\t", bufp->not_eol);
- printf ("syntax: %lx\n", bufp->syntax);
- /* Perhaps we should print the translate table? */
-}
-
-
-void
-print_double_string (where, string1, size1, string2, size2)
- const char *where;
- const char *string1;
- const char *string2;
- int size1;
- int size2;
-{
- int this_char;
-
- if (where == NULL)
- printf ("(null)");
- else
- {
- if (FIRST_STRING_P (where))
- {
- for (this_char = where - string1; this_char < size1; this_char++)
- putchar (string1[this_char]);
-
- where = string2;
- }
-
- for (this_char = where - string2; this_char < size2; this_char++)
- putchar (string2[this_char]);
- }
-}
-
-void
-printchar (c)
- int c;
-{
- putc (c, stderr);
-}
-
-#else /* not DEBUG */
-
-#undef assert
-#define assert(e)
-
-#define DEBUG_STATEMENT(e)
-#define DEBUG_PRINT1(x)
-#define DEBUG_PRINT2(x1, x2)
-#define DEBUG_PRINT3(x1, x2, x3)
-#define DEBUG_PRINT4(x1, x2, x3, x4)
-#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
-#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
-
-#endif /* not DEBUG */
-
-/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
- also be assigned to arbitrarily: each pattern buffer stores its own
- syntax, so it can be changed between regex compilations. */
-/* This has no initializer because initialized variables in Emacs
- become read-only after dumping. */
-reg_syntax_t re_syntax_options;
-
-
-/* Specify the precise syntax of regexps for compilation. This provides
- for compatibility for various utilities which historically have
- different, incompatible syntaxes.
-
- The argument SYNTAX is a bit mask comprised of the various bits
- defined in regex.h. We return the old syntax. */
-
-reg_syntax_t
-re_set_syntax (syntax)
- reg_syntax_t syntax;
-{
- reg_syntax_t ret = re_syntax_options;
-
- re_syntax_options = syntax;
-#ifdef DEBUG
- if (syntax & RE_DEBUG)
- debug = 1;
- else if (debug) /* was on but now is not */
- debug = 0;
-#endif /* DEBUG */
- return ret;
-}
-
-/* This table gives an error message for each of the error codes listed
- in regex.h. Obviously the order here has to be same as there.
- POSIX doesn't require that we do anything for REG_NOERROR,
- but why not be nice? */
-
-static const char *re_error_msgid[] =
- {
- gettext_noop ("Success"), /* REG_NOERROR */
- gettext_noop ("No match"), /* REG_NOMATCH */
- gettext_noop ("Invalid regular expression"), /* REG_BADPAT */
- gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */
- gettext_noop ("Invalid character class name"), /* REG_ECTYPE */
- gettext_noop ("Trailing backslash"), /* REG_EESCAPE */
- gettext_noop ("Invalid back reference"), /* REG_ESUBREG */
- gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */
- gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */
- gettext_noop ("Unmatched \\{"), /* REG_EBRACE */
- gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */
- gettext_noop ("Invalid range end"), /* REG_ERANGE */
- gettext_noop ("Memory exhausted"), /* REG_ESPACE */
- gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */
- gettext_noop ("Premature end of regular expression"), /* REG_EEND */
- gettext_noop ("Regular expression too big"), /* REG_ESIZE */
- gettext_noop ("Unmatched ) or \\)"), /* REG_ERPAREN */
- };
-
-/* Avoiding alloca during matching, to placate r_alloc. */
-
-/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
- searching and matching functions should not call alloca. On some
- systems, alloca is implemented in terms of malloc, and if we're
- using the relocating allocator routines, then malloc could cause a
- relocation, which might (if the strings being searched are in the
- ralloc heap) shift the data out from underneath the regexp
- routines.
-
- Here's another reason to avoid allocation: Emacs
- processes input from X in a signal handler; processing X input may
- call malloc; if input arrives while a matching routine is calling
- malloc, then we're scrod. But Emacs can't just block input while
- calling matching routines; then we don't notice interrupts when
- they come in. So, Emacs blocks input around all regexp calls
- except the matching calls, which it leaves unprotected, in the
- faith that they will not malloc. */
-
-/* Normally, this is fine. */
-#define MATCH_MAY_ALLOCATE
-
-/* When using GNU C, we are not REALLY using the C alloca, no matter
- what config.h may say. So don't take precautions for it. */
-#ifdef __GNUC__
-#undef C_ALLOCA
-#endif
-
-/* The match routines may not allocate if (1) they would do it with malloc
- and (2) it's not safe for them to use malloc.
- Note that if REL_ALLOC is defined, matching would not use malloc for the
- failure stack, but we would still use it for the register vectors;
- so REL_ALLOC should not affect this. */
-#if (defined (C_ALLOCA) || defined (REGEX_MALLOC)) && defined (emacs)
-#undef MATCH_MAY_ALLOCATE
-#endif
-
-
-/* Failure stack declarations and macros; both re_compile_fastmap and
- re_match_2 use a failure stack. These have to be macros because of
- REGEX_ALLOCATE_STACK. */
-
-
-/* Number of failure points for which to initially allocate space
- when matching. If this number is exceeded, we allocate more
- space, so it is not a hard limit. */
-#ifndef INIT_FAILURE_ALLOC
-#define INIT_FAILURE_ALLOC 5
-#endif
-
-/* Roughly the maximum number of failure points on the stack. Would be
- exactly that if always used MAX_FAILURE_ITEMS items each time we failed.
- This is a variable only so users of regex can assign to it; we never
- change it ourselves. */
-
-#ifdef INT_IS_16BIT
-
-#if defined (MATCH_MAY_ALLOCATE)
-/* 4400 was enough to cause a crash on Alpha OSF/1,
- whose default stack limit is 2mb. */
-long int re_max_failures = 4000;
-#else
-long int re_max_failures = 2000;
-#endif
-
-union fail_stack_elt
-{
- unsigned char *pointer;
- long int integer;
-};
-
-typedef union fail_stack_elt fail_stack_elt_t;
-
-typedef struct
-{
- fail_stack_elt_t *stack;
- unsigned long int size;
- unsigned long int avail; /* Offset of next open position. */
-} fail_stack_type;
-
-#else /* not INT_IS_16BIT */
-
-#if defined (MATCH_MAY_ALLOCATE)
-/* 4400 was enough to cause a crash on Alpha OSF/1,
- whose default stack limit is 2mb. */
-int re_max_failures = 20000;
-#else
-int re_max_failures = 2000;
-#endif
-
-union fail_stack_elt
-{
- unsigned char *pointer;
- int integer;
-};
-
-typedef union fail_stack_elt fail_stack_elt_t;
-
-typedef struct
-{
- fail_stack_elt_t *stack;
- unsigned size;
- unsigned avail; /* Offset of next open position. */
-} fail_stack_type;
-
-#endif /* INT_IS_16BIT */
-
-#define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
-#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
-#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
-
-
-/* Define macros to initialize and free the failure stack.
- Do `return -2' if the alloc fails. */
-
-#ifdef MATCH_MAY_ALLOCATE
-#define INIT_FAIL_STACK() \
- do { \
- fail_stack.stack = (fail_stack_elt_t *) \
- REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \
- \
- if (fail_stack.stack == NULL) \
- return -2; \
- \
- fail_stack.size = INIT_FAILURE_ALLOC; \
- fail_stack.avail = 0; \
- } while (0)
-
-#define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack)
-#else
-#define INIT_FAIL_STACK() \
- do { \
- fail_stack.avail = 0; \
- } while (0)
-
-#define RESET_FAIL_STACK()
-#endif
-
-
-/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
-
- Return 1 if succeeds, and 0 if either ran out of memory
- allocating space for it or it was already too large.
-
- REGEX_REALLOCATE_STACK requires `destination' be declared. */
-
-#define DOUBLE_FAIL_STACK(fail_stack) \
- ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \
- ? 0 \
- : ((fail_stack).stack = (fail_stack_elt_t *) \
- REGEX_REALLOCATE_STACK ((fail_stack).stack, \
- (fail_stack).size * sizeof (fail_stack_elt_t), \
- ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \
- \
- (fail_stack).stack == NULL \
- ? 0 \
- : ((fail_stack).size <<= 1, \
- 1)))
-
-
-/* Push pointer POINTER on FAIL_STACK.
- Return 1 if was able to do so and 0 if ran out of memory allocating
- space to do so. */
-#define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \
- ((FAIL_STACK_FULL () \
- && !DOUBLE_FAIL_STACK (FAIL_STACK)) \
- ? 0 \
- : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \
- 1))
-
-/* Push a pointer value onto the failure stack.
- Assumes the variable `fail_stack'. Probably should only
- be called from within `PUSH_FAILURE_POINT'. */
-#define PUSH_FAILURE_POINTER(item) \
- fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item)
-
-/* This pushes an integer-valued item onto the failure stack.
- Assumes the variable `fail_stack'. Probably should only
- be called from within `PUSH_FAILURE_POINT'. */
-#define PUSH_FAILURE_INT(item) \
- fail_stack.stack[fail_stack.avail++].integer = (item)
-
-/* Push a fail_stack_elt_t value onto the failure stack.
- Assumes the variable `fail_stack'. Probably should only
- be called from within `PUSH_FAILURE_POINT'. */
-#define PUSH_FAILURE_ELT(item) \
- fail_stack.stack[fail_stack.avail++] = (item)
-
-/* These three POP... operations complement the three PUSH... operations.
- All assume that `fail_stack' is nonempty. */
-#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer
-#define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer
-#define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail]
-
-/* Used to omit pushing failure point id's when we're not debugging. */
-#ifdef DEBUG
-#define DEBUG_PUSH PUSH_FAILURE_INT
-#define DEBUG_POP(item_addr) (item_addr)->integer = POP_FAILURE_INT ()
-#else
-#define DEBUG_PUSH(item)
-#define DEBUG_POP(item_addr)
-#endif
-
-
-/* Push the information about the state we will need
- if we ever fail back to it.
-
- Requires variables fail_stack, regstart, regend, reg_info, and
- num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be
- declared.
-
- Does `return FAILURE_CODE' if runs out of memory. */
-
-#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
- do { \
- char *destination; \
- /* Must be int, so when we don't save any registers, the arithmetic \
- of 0 + -1 isn't done as unsigned. */ \
- /* Can't be int, since there is not a shred of a guarantee that int \
- is wide enough to hold a value of something to which pointer can \
- be assigned */ \
- s_reg_t this_reg; \
- \
- DEBUG_STATEMENT (failure_id++); \
- DEBUG_STATEMENT (nfailure_points_pushed++); \
- DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
- DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
- DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
- \
- DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \
- DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
- \
- /* Ensure we have enough space allocated for what we will push. */ \
- while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
- { \
- if (!DOUBLE_FAIL_STACK (fail_stack)) \
- return failure_code; \
- \
- DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
- (fail_stack).size); \
- DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
- } \
- \
- /* Push the info, starting with the registers. */ \
- DEBUG_PRINT1 ("\n"); \
- \
- if (1) \
- for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
- this_reg++) \
- { \
- DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \
- DEBUG_STATEMENT (num_regs_pushed++); \
- \
- DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
- PUSH_FAILURE_POINTER (regstart[this_reg]); \
- \
- DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
- PUSH_FAILURE_POINTER (regend[this_reg]); \
- \
- DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \
- DEBUG_PRINT2 (" match_null=%d", \
- REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
- DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
- DEBUG_PRINT2 (" matched_something=%d", \
- MATCHED_SOMETHING (reg_info[this_reg])); \
- DEBUG_PRINT2 (" ever_matched=%d", \
- EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
- DEBUG_PRINT1 ("\n"); \
- PUSH_FAILURE_ELT (reg_info[this_reg].word); \
- } \
- \
- DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\
- PUSH_FAILURE_INT (lowest_active_reg); \
- \
- DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\
- PUSH_FAILURE_INT (highest_active_reg); \
- \
- DEBUG_PRINT2 (" Pushing pattern 0x%x:\n", pattern_place); \
- DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
- PUSH_FAILURE_POINTER (pattern_place); \
- \
- DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \
- DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
- size2); \
- DEBUG_PRINT1 ("'\n"); \
- PUSH_FAILURE_POINTER (string_place); \
- \
- DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
- DEBUG_PUSH (failure_id); \
- } while (0)
-
-/* This is the number of items that are pushed and popped on the stack
- for each register. */
-#define NUM_REG_ITEMS 3
-
-/* Individual items aside from the registers. */
-#ifdef DEBUG
-#define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
-#else
-#define NUM_NONREG_ITEMS 4
-#endif
-
-/* We push at most this many items on the stack. */
-/* We used to use (num_regs - 1), which is the number of registers
- this regexp will save; but that was changed to 5
- to avoid stack overflow for a regexp with lots of parens. */
-#define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
-
-/* We actually push this many items. */
-#define NUM_FAILURE_ITEMS \
- (((0 \
- ? 0 : highest_active_reg - lowest_active_reg + 1) \
- * NUM_REG_ITEMS) \
- + NUM_NONREG_ITEMS)
-
-/* How many items can still be added to the stack without overflowing it. */
-#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
-
-
-/* Pops what PUSH_FAIL_STACK pushes.
-
- We restore into the parameters, all of which should be lvalues:
- STR -- the saved data position.
- PAT -- the saved pattern position.
- LOW_REG, HIGH_REG -- the highest and lowest active registers.
- REGSTART, REGEND -- arrays of string positions.
- REG_INFO -- array of information about each subexpression.
-
- Also assumes the variables `fail_stack' and (if debugging), `bufp',
- `pend', `string1', `size1', `string2', and `size2'. */
-
-#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
-{ \
- DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \
- s_reg_t this_reg; \
- const unsigned char *string_temp; \
- \
- assert (!FAIL_STACK_EMPTY ()); \
- \
- /* Remove failure points and point to how many regs pushed. */ \
- DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
- DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
- DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
- \
- assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
- \
- DEBUG_POP (&failure_id); \
- DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
- \
- /* If the saved string location is NULL, it came from an \
- on_failure_keep_string_jump opcode, and we want to throw away the \
- saved NULL, thus retaining our current position in the string. */ \
- string_temp = POP_FAILURE_POINTER (); \
- if (string_temp != NULL) \
- str = (const char *) string_temp; \
- \
- DEBUG_PRINT2 (" Popping string 0x%x: `", str); \
- DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
- DEBUG_PRINT1 ("'\n"); \
- \
- pat = (unsigned char *) POP_FAILURE_POINTER (); \
- DEBUG_PRINT2 (" Popping pattern 0x%x:\n", pat); \
- DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
- \
- /* Restore register info. */ \
- high_reg = (active_reg_t) POP_FAILURE_INT (); \
- DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \
- \
- low_reg = (active_reg_t) POP_FAILURE_INT (); \
- DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \
- \
- if (1) \
- for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
- { \
- DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \
- \
- reg_info[this_reg].word = POP_FAILURE_ELT (); \
- DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \
- \
- regend[this_reg] = (const char *) POP_FAILURE_POINTER (); \
- DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
- \
- regstart[this_reg] = (const char *) POP_FAILURE_POINTER (); \
- DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
- } \
- else \
- { \
- for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \
- { \
- reg_info[this_reg].word.integer = 0; \
- regend[this_reg] = 0; \
- regstart[this_reg] = 0; \
- } \
- highest_active_reg = high_reg; \
- } \
- \
- set_regs_matched_done = 0; \
- DEBUG_STATEMENT (nfailure_points_popped++); \
-} /* POP_FAILURE_POINT */
-
-
-
-/* Structure for per-register (a.k.a. per-group) information.
- Other register information, such as the
- starting and ending positions (which are addresses), and the list of
- inner groups (which is a bits list) are maintained in separate
- variables.
-
- We are making a (strictly speaking) nonportable assumption here: that
- the compiler will pack our bit fields into something that fits into
- the type of `word', i.e., is something that fits into one item on the
- failure stack. */
-
-
-/* Declarations and macros for re_match_2. */
-
-typedef union
-{
- fail_stack_elt_t word;
- struct
- {
- /* This field is one if this group can match the empty string,
- zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
-#define MATCH_NULL_UNSET_VALUE 3
- unsigned match_null_string_p : 2;
- unsigned is_active : 1;
- unsigned matched_something : 1;
- unsigned ever_matched_something : 1;
- } bits;
-} register_info_type;
-
-#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
-#define IS_ACTIVE(R) ((R).bits.is_active)
-#define MATCHED_SOMETHING(R) ((R).bits.matched_something)
-#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
-
-
-/* Call this when have matched a real character; it sets `matched' flags
- for the subexpressions which we are currently inside. Also records
- that those subexprs have matched. */
-#define SET_REGS_MATCHED() \
- do \
- { \
- if (!set_regs_matched_done) \
- { \
- active_reg_t r; \
- set_regs_matched_done = 1; \
- for (r = lowest_active_reg; r <= highest_active_reg; r++) \
- { \
- MATCHED_SOMETHING (reg_info[r]) \
- = EVER_MATCHED_SOMETHING (reg_info[r]) \
- = 1; \
- } \
- } \
- } \
- while (0)
-
-/* Registers are set to a sentinel when they haven't yet matched. */
-static char reg_unset_dummy;
-#define REG_UNSET_VALUE (&reg_unset_dummy)
-#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
-
-/* Subroutine declarations and macros for regex_compile. */
-
-static reg_errcode_t regex_compile _RE_ARGS ((const char *pattern, size_t size,
- reg_syntax_t syntax,
- struct re_pattern_buffer *bufp));
-static void store_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, int arg));
-static void store_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc,
- int arg1, int arg2));
-static void insert_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc,
- int arg, unsigned char *end));
-static void insert_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc,
- int arg1, int arg2, unsigned char *end));
-static boolean at_begline_loc_p _RE_ARGS ((const char *pattern, const char *p,
- reg_syntax_t syntax));
-static boolean at_endline_loc_p _RE_ARGS ((const char *p, const char *pend,
- reg_syntax_t syntax));
-static reg_errcode_t compile_range _RE_ARGS ((const char **p_ptr,
- const char *pend,
- char *translate,
- reg_syntax_t syntax,
- unsigned char *b));
-
-/* Fetch the next character in the uncompiled pattern---translating it
- if necessary. Also cast from a signed character in the constant
- string passed to us by the user to an unsigned char that we can use
- as an array index (in, e.g., `translate'). */
-#ifndef PATFETCH
-#define PATFETCH(c) \
- do {if (p == pend) return REG_EEND; \
- c = (unsigned char) *p++; \
- if (translate) c = (unsigned char) translate[c]; \
- } while (0)
-#endif
-
-/* Fetch the next character in the uncompiled pattern, with no
- translation. */
-#define PATFETCH_RAW(c) \
- do {if (p == pend) return REG_EEND; \
- c = (unsigned char) *p++; \
- } while (0)
-
-/* Go backwards one character in the pattern. */
-#define PATUNFETCH p--
-
-
-/* If `translate' is non-null, return translate[D], else just D. We
- cast the subscript to translate because some data is declared as
- `char *', to avoid warnings when a string constant is passed. But
- when we use a character as a subscript we must make it unsigned. */
-#ifndef TRANSLATE
-#define TRANSLATE(d) \
- (translate ? (char) translate[(unsigned char) (d)] : (d))
-#endif
-
-
-/* Macros for outputting the compiled pattern into `buffer'. */
-
-/* If the buffer isn't allocated when it comes in, use this. */
-#define INIT_BUF_SIZE 32
-
-/* Make sure we have at least N more bytes of space in buffer. */
-#define GET_BUFFER_SPACE(n) \
- while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \
- EXTEND_BUFFER ()
-
-/* Make sure we have one more byte of buffer space and then add C to it. */
-#define BUF_PUSH(c) \
- do { \
- GET_BUFFER_SPACE (1); \
- *b++ = (unsigned char) (c); \
- } while (0)
-
-
-/* Ensure we have two more bytes of buffer space and then append C1 and C2. */
-#define BUF_PUSH_2(c1, c2) \
- do { \
- GET_BUFFER_SPACE (2); \
- *b++ = (unsigned char) (c1); \
- *b++ = (unsigned char) (c2); \
- } while (0)
-
-
-/* As with BUF_PUSH_2, except for three bytes. */
-#define BUF_PUSH_3(c1, c2, c3) \
- do { \
- GET_BUFFER_SPACE (3); \
- *b++ = (unsigned char) (c1); \
- *b++ = (unsigned char) (c2); \
- *b++ = (unsigned char) (c3); \
- } while (0)
-
-
-/* Store a jump with opcode OP at LOC to location TO. We store a
- relative address offset by the three bytes the jump itself occupies. */
-#define STORE_JUMP(op, loc, to) \
- store_op1 (op, loc, (int) ((to) - (loc) - 3))
-
-/* Likewise, for a two-argument jump. */
-#define STORE_JUMP2(op, loc, to, arg) \
- store_op2 (op, loc, (int) ((to) - (loc) - 3), arg)
-
-/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
-#define INSERT_JUMP(op, loc, to) \
- insert_op1 (op, loc, (int) ((to) - (loc) - 3), b)
-
-/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */
-#define INSERT_JUMP2(op, loc, to, arg) \
- insert_op2 (op, loc, (int) ((to) - (loc) - 3), arg, b)
-
-
-/* This is not an arbitrary limit: the arguments which represent offsets
- into the pattern are two bytes long. So if 2^16 bytes turns out to
- be too small, many things would have to change. */
-/* Any other compiler which, like MSC, has allocation limit below 2^16
- bytes will have to use approach similar to what was done below for
- MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up
- reallocating to 0 bytes. Such thing is not going to work too well.
- You have been warned!! */
-#if defined(_MSC_VER) && !defined(WIN32)
-/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes.
- The REALLOC define eliminates a flurry of conversion warnings,
- but is not required. */
-#define MAX_BUF_SIZE 65500L
-#define REALLOC(p,s) realloc ((p), (size_t) (s))
-#else
-#define MAX_BUF_SIZE (1L << 16)
-#define REALLOC(p,s) realloc ((p), (s))
-#endif
-
-/* Extend the buffer by twice its current size via realloc and
- reset the pointers that pointed into the old block to point to the
- correct places in the new one. If extending the buffer results in it
- being larger than MAX_BUF_SIZE, then flag memory exhausted. */
-#define EXTEND_BUFFER() \
- do { \
- unsigned char *old_buffer = bufp->buffer; \
- if (bufp->allocated == MAX_BUF_SIZE) \
- return REG_ESIZE; \
- bufp->allocated <<= 1; \
- if (bufp->allocated > MAX_BUF_SIZE) \
- bufp->allocated = MAX_BUF_SIZE; \
- bufp->buffer = (unsigned char *) REALLOC (bufp->buffer, bufp->allocated);\
- if (bufp->buffer == NULL) \
- return REG_ESPACE; \
- /* If the buffer moved, move all the pointers into it. */ \
- if (old_buffer != bufp->buffer) \
- { \
- b = (b - old_buffer) + bufp->buffer; \
- begalt = (begalt - old_buffer) + bufp->buffer; \
- if (fixup_alt_jump) \
- fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
- if (laststart) \
- laststart = (laststart - old_buffer) + bufp->buffer; \
- if (pending_exact) \
- pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
- } \
- } while (0)
-
-
-/* Since we have one byte reserved for the register number argument to
- {start,stop}_memory, the maximum number of groups we can report
- things about is what fits in that byte. */
-#define MAX_REGNUM 255
-
-/* But patterns can have more than `MAX_REGNUM' registers. We just
- ignore the excess. */
-typedef unsigned regnum_t;
-
-
-/* Macros for the compile stack. */
-
-/* Since offsets can go either forwards or backwards, this type needs to
- be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
-/* int may be not enough when sizeof(int) == 2. */
-typedef long pattern_offset_t;
-
-typedef struct
-{
- pattern_offset_t begalt_offset;
- pattern_offset_t fixup_alt_jump;
- pattern_offset_t inner_group_offset;
- pattern_offset_t laststart_offset;
- regnum_t regnum;
-} compile_stack_elt_t;
-
-
-typedef struct
-{
- compile_stack_elt_t *stack;
- unsigned size;
- unsigned avail; /* Offset of next open position. */
-} compile_stack_type;
-
-
-#define INIT_COMPILE_STACK_SIZE 32
-
-#define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
-#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
-
-/* The next available element. */
-#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
-
-
-/* Set the bit for character C in a list. */
-#define SET_LIST_BIT(c) \
- (b[((unsigned char) (c)) / BYTEWIDTH] \
- |= 1 << (((unsigned char) c) % BYTEWIDTH))
-
-
-/* Get the next unsigned number in the uncompiled pattern. */
-#define GET_UNSIGNED_NUMBER(num) \
- { if (p != pend) \
- { \
- PATFETCH (c); \
- while (ISDIGIT (c)) \
- { \
- if (num < 0) \
- num = 0; \
- num = num * 10 + c - '0'; \
- if (p == pend) \
- break; \
- PATFETCH (c); \
- } \
- } \
- }
-
-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
-/* The GNU C library provides support for user-defined character classes
- and the functions from ISO C amendement 1. */
-# ifdef CHARCLASS_NAME_MAX
-# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
-# else
-/* This shouldn't happen but some implementation might still have this
- problem. Use a reasonable default value. */
-# define CHAR_CLASS_MAX_LENGTH 256
-# endif
-
-# define IS_CHAR_CLASS(string) wctype (string)
-#else
-# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
-
-# define IS_CHAR_CLASS(string) \
- (STREQ (string, "alpha") || STREQ (string, "upper") \
- || STREQ (string, "lower") || STREQ (string, "digit") \
- || STREQ (string, "alnum") || STREQ (string, "xdigit") \
- || STREQ (string, "space") || STREQ (string, "print") \
- || STREQ (string, "punct") || STREQ (string, "graph") \
- || STREQ (string, "cntrl") || STREQ (string, "blank"))
-#endif
-
-#ifndef MATCH_MAY_ALLOCATE
-
-/* If we cannot allocate large objects within re_match_2_internal,
- we make the fail stack and register vectors global.
- The fail stack, we grow to the maximum size when a regexp
- is compiled.
- The register vectors, we adjust in size each time we
- compile a regexp, according to the number of registers it needs. */
-
-static fail_stack_type fail_stack;
-
-/* Size with which the following vectors are currently allocated.
- That is so we can make them bigger as needed,
- but never make them smaller. */
-static int regs_allocated_size;
-
-static const char ** regstart, ** regend;
-static const char ** old_regstart, ** old_regend;
-static const char **best_regstart, **best_regend;
-static register_info_type *reg_info;
-static const char **reg_dummy;
-static register_info_type *reg_info_dummy;
-
-/* Make the register vectors big enough for NUM_REGS registers,
- but don't make them smaller. */
-
-static
-regex_grow_registers (num_regs)
- int num_regs;
-{
- if (num_regs > regs_allocated_size)
- {
- RETALLOC_IF (regstart, num_regs, const char *);
- RETALLOC_IF (regend, num_regs, const char *);
- RETALLOC_IF (old_regstart, num_regs, const char *);
- RETALLOC_IF (old_regend, num_regs, const char *);
- RETALLOC_IF (best_regstart, num_regs, const char *);
- RETALLOC_IF (best_regend, num_regs, const char *);
- RETALLOC_IF (reg_info, num_regs, register_info_type);
- RETALLOC_IF (reg_dummy, num_regs, const char *);
- RETALLOC_IF (reg_info_dummy, num_regs, register_info_type);
-
- regs_allocated_size = num_regs;
- }
-}
-
-#endif /* not MATCH_MAY_ALLOCATE */
-
-static boolean group_in_compile_stack _RE_ARGS ((compile_stack_type
- compile_stack,
- regnum_t regnum));
-
-/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
- Returns one of error codes defined in `regex.h', or zero for success.
-
- Assumes the `allocated' (and perhaps `buffer') and `translate'
- fields are set in BUFP on entry.
-
- If it succeeds, results are put in BUFP (if it returns an error, the
- contents of BUFP are undefined):
- `buffer' is the compiled pattern;
- `syntax' is set to SYNTAX;
- `used' is set to the length of the compiled pattern;
- `fastmap_accurate' is zero;
- `re_nsub' is the number of subexpressions in PATTERN;
- `not_bol' and `not_eol' are zero;
-
- The `fastmap' and `newline_anchor' fields are neither
- examined nor set. */
-
-/* Return, freeing storage we allocated. */
-#define FREE_STACK_RETURN(value) \
- return (free (compile_stack.stack), value)
-
-static reg_errcode_t
-regex_compile (pattern, size, syntax, bufp)
- const char *pattern;
- size_t size;
- reg_syntax_t syntax;
- struct re_pattern_buffer *bufp;
-{
- /* We fetch characters from PATTERN here. Even though PATTERN is
- `char *' (i.e., signed), we declare these variables as unsigned, so
- they can be reliably used as array indices. */
- register unsigned char c, c1;
-
- /* A random temporary spot in PATTERN. */
- const char *p1;
-
- /* Points to the end of the buffer, where we should append. */
- register unsigned char *b;
-
- /* Keeps track of unclosed groups. */
- compile_stack_type compile_stack;
-
- /* Points to the current (ending) position in the pattern. */
- const char *p = pattern;
- const char *pend = pattern + size;
-
- /* How to translate the characters in the pattern. */
- RE_TRANSLATE_TYPE translate = bufp->translate;
-
- /* Address of the count-byte of the most recently inserted `exactn'
- command. This makes it possible to tell if a new exact-match
- character can be added to that command or if the character requires
- a new `exactn' command. */
- unsigned char *pending_exact = 0;
-
- /* Address of start of the most recently finished expression.
- This tells, e.g., postfix * where to find the start of its
- operand. Reset at the beginning of groups and alternatives. */
- unsigned char *laststart = 0;
-
- /* Address of beginning of regexp, or inside of last group. */
- unsigned char *begalt;
-
- /* Place in the uncompiled pattern (i.e., the {) to
- which to go back if the interval is invalid. */
- const char *beg_interval;
-
- /* Address of the place where a forward jump should go to the end of
- the containing expression. Each alternative of an `or' -- except the
- last -- ends with a forward jump of this sort. */
- unsigned char *fixup_alt_jump = 0;
-
- /* Counts open-groups as they are encountered. Remembered for the
- matching close-group on the compile stack, so the same register
- number is put in the stop_memory as the start_memory. */
- regnum_t regnum = 0;
-
-#ifdef DEBUG
- DEBUG_PRINT1 ("\nCompiling pattern: ");
- if (debug)
- {
- unsigned debug_count;
-
- for (debug_count = 0; debug_count < size; debug_count++)
- putchar (pattern[debug_count]);
- putchar ('\n');
- }
-#endif /* DEBUG */
-
- /* Initialize the compile stack. */
- compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
- if (compile_stack.stack == NULL)
- return REG_ESPACE;
-
- compile_stack.size = INIT_COMPILE_STACK_SIZE;
- compile_stack.avail = 0;
-
- /* Initialize the pattern buffer. */
- bufp->syntax = syntax;
- bufp->fastmap_accurate = 0;
- bufp->not_bol = bufp->not_eol = 0;
-
- /* Set `used' to zero, so that if we return an error, the pattern
- printer (for debugging) will think there's no pattern. We reset it
- at the end. */
- bufp->used = 0;
-
- /* Always count groups, whether or not bufp->no_sub is set. */
- bufp->re_nsub = 0;
-
-#if !defined (emacs) && !defined (SYNTAX_TABLE)
- /* Initialize the syntax table. */
- init_syntax_once ();
-#endif
-
- if (bufp->allocated == 0)
- {
- if (bufp->buffer)
- { /* If zero allocated, but buffer is non-null, try to realloc
- enough space. This loses if buffer's address is bogus, but
- that is the user's responsibility. */
- RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char);
- }
- else
- { /* Caller did not allocate a buffer. Do it for them. */
- bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
- }
- if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE);
-
- bufp->allocated = INIT_BUF_SIZE;
- }
-
- begalt = b = bufp->buffer;
-
- /* Loop through the uncompiled pattern until we're at the end. */
- while (p != pend)
- {
- PATFETCH (c);
-
- switch (c)
- {
- case '^':
- {
- if ( /* If at start of pattern, it's an operator. */
- p == pattern + 1
- /* If context independent, it's an operator. */
- || syntax & RE_CONTEXT_INDEP_ANCHORS
- /* Otherwise, depends on what's come before. */
- || at_begline_loc_p (pattern, p, syntax))
- BUF_PUSH (begline);
- else
- goto normal_char;
- }
- break;
-
-
- case '$':
- {
- if ( /* If at end of pattern, it's an operator. */
- p == pend
- /* If context independent, it's an operator. */
- || syntax & RE_CONTEXT_INDEP_ANCHORS
- /* Otherwise, depends on what's next. */
- || at_endline_loc_p (p, pend, syntax))
- BUF_PUSH (endline);
- else
- goto normal_char;
- }
- break;
-
-
- case '+':
- case '?':
- if ((syntax & RE_BK_PLUS_QM)
- || (syntax & RE_LIMITED_OPS))
- goto normal_char;
- handle_plus:
- case '*':
- /* If there is no previous pattern... */
- if (!laststart)
- {
- if (syntax & RE_CONTEXT_INVALID_OPS)
- FREE_STACK_RETURN (REG_BADRPT);
- else if (!(syntax & RE_CONTEXT_INDEP_OPS))
- goto normal_char;
- }
-
- {
- /* Are we optimizing this jump? */
- boolean keep_string_p = false;
-
- /* 1 means zero (many) matches is allowed. */
- char zero_times_ok = 0, many_times_ok = 0;
-
- /* If there is a sequence of repetition chars, collapse it
- down to just one (the right one). We can't combine
- interval operators with these because of, e.g., `a{2}*',
- which should only match an even number of `a's. */
-
- for (;;)
- {
- zero_times_ok |= c != '+';
- many_times_ok |= c != '?';
-
- if (p == pend)
- break;
-
- PATFETCH (c);
-
- if (c == '*'
- || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
- ;
-
- else if (syntax & RE_BK_PLUS_QM && c == '\\')
- {
- if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
-
- PATFETCH (c1);
- if (!(c1 == '+' || c1 == '?'))
- {
- PATUNFETCH;
- PATUNFETCH;
- break;
- }
-
- c = c1;
- }
- else
- {
- PATUNFETCH;
- break;
- }
-
- /* If we get here, we found another repeat character. */
- }
-
- /* Star, etc. applied to an empty pattern is equivalent
- to an empty pattern. */
- if (!laststart)
- break;
-
- /* Now we know whether or not zero matches is allowed
- and also whether or not two or more matches is allowed. */
- if (many_times_ok)
- { /* More than one repetition is allowed, so put in at the
- end a backward relative jump from `b' to before the next
- jump we're going to put in below (which jumps from
- laststart to after this jump).
-
- But if we are at the `*' in the exact sequence `.*\n',
- insert an unconditional jump backwards to the .,
- instead of the beginning of the loop. This way we only
- push a failure point once, instead of every time
- through the loop. */
- assert (p - 1 > pattern);
-
- /* Allocate the space for the jump. */
- GET_BUFFER_SPACE (3);
-
- /* We know we are not at the first character of the pattern,
- because laststart was nonzero. And we've already
- incremented `p', by the way, to be the character after
- the `*'. Do we have to do something analogous here
- for null bytes, because of RE_DOT_NOT_NULL? */
- if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
- && zero_times_ok
- && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
- && !(syntax & RE_DOT_NEWLINE))
- { /* We have .*\n. */
- STORE_JUMP (jump, b, laststart);
- keep_string_p = true;
- }
- else
- /* Anything else. */
- STORE_JUMP (maybe_pop_jump, b, laststart - 3);
-
- /* We've added more stuff to the buffer. */
- b += 3;
- }
-
- /* On failure, jump from laststart to b + 3, which will be the
- end of the buffer after this jump is inserted. */
- GET_BUFFER_SPACE (3);
- INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
- : on_failure_jump,
- laststart, b + 3);
- pending_exact = 0;
- b += 3;
-
- if (!zero_times_ok)
- {
- /* At least one repetition is required, so insert a
- `dummy_failure_jump' before the initial
- `on_failure_jump' instruction of the loop. This
- effects a skip over that instruction the first time
- we hit that loop. */
- GET_BUFFER_SPACE (3);
- INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6);
- b += 3;
- }
- }
- break;
-
-
- case '.':
- laststart = b;
- BUF_PUSH (anychar);
- break;
-
-
- case '[':
- {
- boolean had_char_class = false;
-
- if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-
- /* Ensure that we have enough space to push a charset: the
- opcode, the length count, and the bitset; 34 bytes in all. */
- GET_BUFFER_SPACE (34);
-
- laststart = b;
-
- /* We test `*p == '^' twice, instead of using an if
- statement, so we only need one BUF_PUSH. */
- BUF_PUSH (*p == '^' ? charset_not : charset);
- if (*p == '^')
- p++;
-
- /* Remember the first position in the bracket expression. */
- p1 = p;
-
- /* Push the number of bytes in the bitmap. */
- BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
-
- /* Clear the whole map. */
- bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
-
- /* charset_not matches newline according to a syntax bit. */
- if ((re_opcode_t) b[-2] == charset_not
- && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
- SET_LIST_BIT ('\n');
-
- /* Read in characters and ranges, setting map bits. */
- for (;;)
- {
- if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-
- PATFETCH (c);
-
- /* \ might escape characters inside [...] and [^...]. */
- if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
- {
- if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
-
- PATFETCH (c1);
- SET_LIST_BIT (c1);
- continue;
- }
-
- /* Could be the end of the bracket expression. If it's
- not (i.e., when the bracket expression is `[]' so
- far), the ']' character bit gets set way below. */
- if (c == ']' && p != p1 + 1)
- break;
-
- /* Look ahead to see if it's a range when the last thing
- was a character class. */
- if (had_char_class && c == '-' && *p != ']')
- FREE_STACK_RETURN (REG_ERANGE);
-
- /* Look ahead to see if it's a range when the last thing
- was a character: if this is a hyphen not at the
- beginning or the end of a list, then it's the range
- operator. */
- if (c == '-'
- && !(p - 2 >= pattern && p[-2] == '[')
- && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
- && *p != ']')
- {
- reg_errcode_t ret
- = compile_range (&p, pend, translate, syntax, b);
- if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
- }
-
- else if (p[0] == '-' && p[1] != ']')
- { /* This handles ranges made up of characters only. */
- reg_errcode_t ret;
-
- /* Move past the `-'. */
- PATFETCH (c1);
-
- ret = compile_range (&p, pend, translate, syntax, b);
- if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
- }
-
- /* See if we're at the beginning of a possible character
- class. */
-
- else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
- { /* Leave room for the null. */
- char str[CHAR_CLASS_MAX_LENGTH + 1];
-
- PATFETCH (c);
- c1 = 0;
-
- /* If pattern is `[[:'. */
- if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-
- for (;;)
- {
- PATFETCH (c);
- if (c == ':' || c == ']' || p == pend
- || c1 == CHAR_CLASS_MAX_LENGTH)
- break;
- str[c1++] = c;
- }
- str[c1] = '\0';
-
- /* If isn't a word bracketed by `[:' and:`]':
- undo the ending character, the letters, and leave
- the leading `:' and `[' (but set bits for them). */
- if (c == ':' && *p == ']')
- {
-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
- boolean is_lower = STREQ (str, "lower");
- boolean is_upper = STREQ (str, "upper");
- wctype_t wt;
- int ch;
-
- wt = wctype (str);
- if (wt == 0)
- FREE_STACK_RETURN (REG_ECTYPE);
-
- /* Throw away the ] at the end of the character
- class. */
- PATFETCH (c);
-
- if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-
- for (ch = 0; ch < 1 << BYTEWIDTH; ++ch)
- {
- if (iswctype (btowc (ch), wt))
- SET_LIST_BIT (ch);
-
- if (translate && (is_upper || is_lower)
- && (ISUPPER (ch) || ISLOWER (ch)))
- SET_LIST_BIT (ch);
- }
-
- had_char_class = true;
-#else
- int ch;
- boolean is_alnum = STREQ (str, "alnum");
- boolean is_alpha = STREQ (str, "alpha");
- boolean is_blank = STREQ (str, "blank");
- boolean is_cntrl = STREQ (str, "cntrl");
- boolean is_digit = STREQ (str, "digit");
- boolean is_graph = STREQ (str, "graph");
- boolean is_lower = STREQ (str, "lower");
- boolean is_print = STREQ (str, "print");
- boolean is_punct = STREQ (str, "punct");
- boolean is_space = STREQ (str, "space");
- boolean is_upper = STREQ (str, "upper");
- boolean is_xdigit = STREQ (str, "xdigit");
-
- if (!IS_CHAR_CLASS (str))
- FREE_STACK_RETURN (REG_ECTYPE);
-
- /* Throw away the ] at the end of the character
- class. */
- PATFETCH (c);
-
- if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
-
- for (ch = 0; ch < (1 << BYTEWIDTH); ch++)
- {
- /* This was split into 3 if's to
- avoid an arbitrary limit in some compiler. */
- if ( (is_alnum && ISALNUM (ch))
- || (is_alpha && ISALPHA (ch))
- || (is_blank && ISBLANK (ch))
- || (is_cntrl && ISCNTRL (ch)))
- SET_LIST_BIT (ch);
- if ( (is_digit && ISDIGIT (ch))
- || (is_graph && ISGRAPH (ch))
- || (is_lower && ISLOWER (ch))
- || (is_print && ISPRINT (ch)))
- SET_LIST_BIT (ch);
- if ( (is_punct && ISPUNCT (ch))
- || (is_space && ISSPACE (ch))
- || (is_upper && ISUPPER (ch))
- || (is_xdigit && ISXDIGIT (ch)))
- SET_LIST_BIT (ch);
- if ( translate && (is_upper || is_lower)
- && (ISUPPER (ch) || ISLOWER (ch)))
- SET_LIST_BIT (ch);
- }
- had_char_class = true;
-#endif /* libc || wctype.h */
- }
- else
- {
- c1++;
- while (c1--)
- PATUNFETCH;
- SET_LIST_BIT ('[');
- SET_LIST_BIT (':');
- had_char_class = false;
- }
- }
- else
- {
- had_char_class = false;
- SET_LIST_BIT (c);
- }
- }
-
- /* Discard any (non)matching list bytes that are all 0 at the
- end of the map. Decrease the map-length byte too. */
- while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
- b[-1]--;
- b += b[-1];
- }
- break;
-
-
- case '(':
- if (syntax & RE_NO_BK_PARENS)
- goto handle_open;
- else
- goto normal_char;
-
-
- case ')':
- if (syntax & RE_NO_BK_PARENS)
- goto handle_close;
- else
- goto normal_char;
-
-
- case '\n':
- if (syntax & RE_NEWLINE_ALT)
- goto handle_alt;
- else
- goto normal_char;
-
-
- case '|':
- if (syntax & RE_NO_BK_VBAR)
- goto handle_alt;
- else
- goto normal_char;
-
-
- case '{':
- if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
- goto handle_interval;
- else
- goto normal_char;
-
-
- case '\\':
- if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
-
- /* Do not translate the character after the \, so that we can
- distinguish, e.g., \B from \b, even if we normally would
- translate, e.g., B to b. */
- PATFETCH_RAW (c);
-
- switch (c)
- {
- case '(':
- if (syntax & RE_NO_BK_PARENS)
- goto normal_backslash;
-
- handle_open:
- bufp->re_nsub++;
- regnum++;
-
- if (COMPILE_STACK_FULL)
- {
- RETALLOC (compile_stack.stack, compile_stack.size << 1,
- compile_stack_elt_t);
- if (compile_stack.stack == NULL) return REG_ESPACE;
-
- compile_stack.size <<= 1;
- }
-
- /* These are the values to restore when we hit end of this
- group. They are all relative offsets, so that if the
- whole pattern moves because of realloc, they will still
- be valid. */
- COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
- COMPILE_STACK_TOP.fixup_alt_jump
- = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
- COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
- COMPILE_STACK_TOP.regnum = regnum;
-
- /* We will eventually replace the 0 with the number of
- groups inner to this one. But do not push a
- start_memory for groups beyond the last one we can
- represent in the compiled pattern. */
- if (regnum <= MAX_REGNUM)
- {
- COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
- BUF_PUSH_3 (start_memory, regnum, 0);
- }
-
- compile_stack.avail++;
-
- fixup_alt_jump = 0;
- laststart = 0;
- begalt = b;
- /* If we've reached MAX_REGNUM groups, then this open
- won't actually generate any code, so we'll have to
- clear pending_exact explicitly. */
- pending_exact = 0;
- break;
-
-
- case ')':
- if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
-
- if (COMPILE_STACK_EMPTY) {
- if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
- goto normal_backslash;
- }
- else FREE_STACK_RETURN (REG_ERPAREN);
-
- handle_close:
- if (fixup_alt_jump)
- { /* Push a dummy failure point at the end of the
- alternative for a possible future
- `pop_failure_jump' to pop. See comments at
- `push_dummy_failure' in `re_match_2'. */
- BUF_PUSH (push_dummy_failure);
-
- /* We allocated space for this jump when we assigned
- to `fixup_alt_jump', in the `handle_alt' case below. */
- STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
- }
-
- /* See similar code for backslashed left paren above. */
- if (COMPILE_STACK_EMPTY) {
- if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
- goto normal_char;
- }
- else FREE_STACK_RETURN (REG_ERPAREN);
-
- /* Since we just checked for an empty stack above, this
- ``can't happen''. */
- assert (compile_stack.avail != 0);
- {
- /* We don't just want to restore into `regnum', because
- later groups should continue to be numbered higher,
- as in `(ab)c(de)' -- the second group is #2. */
- regnum_t this_group_regnum;
-
- compile_stack.avail--;
- begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
- fixup_alt_jump
- = COMPILE_STACK_TOP.fixup_alt_jump
- ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
- : 0;
- laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
- this_group_regnum = COMPILE_STACK_TOP.regnum;
- /* If we've reached MAX_REGNUM groups, then this open
- won't actually generate any code, so we'll have to
- clear pending_exact explicitly. */
- pending_exact = 0;
-
- /* We're at the end of the group, so now we know how many
- groups were inside this one. */
- if (this_group_regnum <= MAX_REGNUM)
- {
- unsigned char *inner_group_loc
- = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
-
- *inner_group_loc = regnum - this_group_regnum;
- BUF_PUSH_3 (stop_memory, this_group_regnum,
- regnum - this_group_regnum);
- }
- }
- break;
-
-
- case '|': /* `\|'. */
- if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
- goto normal_backslash;
- handle_alt:
- if (syntax & RE_LIMITED_OPS)
- goto normal_char;
-
- /* Insert before the previous alternative a jump which
- jumps to this alternative if the former fails. */
- GET_BUFFER_SPACE (3);
- INSERT_JUMP (on_failure_jump, begalt, b + 6);
- pending_exact = 0;
- b += 3;
-
- /* The alternative before this one has a jump after it
- which gets executed if it gets matched. Adjust that
- jump so it will jump to this alternative's analogous
- jump (put in below, which in turn will jump to the next
- (if any) alternative's such jump, etc.). The last such
- jump jumps to the correct final destination. A picture:
- _____ _____
- | | | |
- | v | v
- a | b | c
-
- If we are at `b', then fixup_alt_jump right now points to a
- three-byte space after `a'. We'll put in the jump, set
- fixup_alt_jump to right after `b', and leave behind three
- bytes which we'll fill in when we get to after `c'. */
-
- if (fixup_alt_jump)
- STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
-
- /* Mark and leave space for a jump after this alternative,
- to be filled in later either by next alternative or
- when know we're at the end of a series of alternatives. */
- fixup_alt_jump = b;
- GET_BUFFER_SPACE (3);
- b += 3;
-
- laststart = 0;
- begalt = b;
- break;
-
-
- case '{':
- /* If \{ is a literal. */
- if (!(syntax & RE_INTERVALS)
- /* If we're at `\{' and it's not the open-interval
- operator. */
- || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
- || (p - 2 == pattern && p == pend))
- goto normal_backslash;
-
- handle_interval:
- {
- /* If got here, then the syntax allows intervals. */
-
- /* At least (most) this many matches must be made. */
- int lower_bound = -1, upper_bound = -1;
-
- beg_interval = p - 1;
-
- if (p == pend)
- {
- if (syntax & RE_NO_BK_BRACES)
- goto unfetch_interval;
- else
- FREE_STACK_RETURN (REG_EBRACE);
- }
-
- GET_UNSIGNED_NUMBER (lower_bound);
-
- if (c == ',')
- {
- GET_UNSIGNED_NUMBER (upper_bound);
- if (upper_bound < 0) upper_bound = RE_DUP_MAX;
- }
- else
- /* Interval such as `{1}' => match exactly once. */
- upper_bound = lower_bound;
-
- if (lower_bound < 0 || upper_bound > RE_DUP_MAX
- || lower_bound > upper_bound)
- {
- if (syntax & RE_NO_BK_BRACES)
- goto unfetch_interval;
- else
- FREE_STACK_RETURN (REG_BADBR);
- }
-
- if (!(syntax & RE_NO_BK_BRACES))
- {
- if (c != '\\') FREE_STACK_RETURN (REG_EBRACE);
-
- PATFETCH (c);
- }
-
- if (c != '}')
- {
- if (syntax & RE_NO_BK_BRACES)
- goto unfetch_interval;
- else
- FREE_STACK_RETURN (REG_BADBR);
- }
-
- /* We just parsed a valid interval. */
-
- /* If it's invalid to have no preceding re. */
- if (!laststart)
- {
- if (syntax & RE_CONTEXT_INVALID_OPS)
- FREE_STACK_RETURN (REG_BADRPT);
- else if (syntax & RE_CONTEXT_INDEP_OPS)
- laststart = b;
- else
- goto unfetch_interval;
- }
-
- /* If the upper bound is zero, don't want to succeed at
- all; jump from `laststart' to `b + 3', which will be
- the end of the buffer after we insert the jump. */
- if (upper_bound == 0)
- {
- GET_BUFFER_SPACE (3);
- INSERT_JUMP (jump, laststart, b + 3);
- b += 3;
- }
-
- /* Otherwise, we have a nontrivial interval. When
- we're all done, the pattern will look like:
- set_number_at <jump count> <upper bound>
- set_number_at <succeed_n count> <lower bound>
- succeed_n <after jump addr> <succeed_n count>
- <body of loop>
- jump_n <succeed_n addr> <jump count>
- (The upper bound and `jump_n' are omitted if
- `upper_bound' is 1, though.) */
- else
- { /* If the upper bound is > 1, we need to insert
- more at the end of the loop. */
- unsigned nbytes = 10 + (upper_bound > 1) * 10;
-
- GET_BUFFER_SPACE (nbytes);
-
- /* Initialize lower bound of the `succeed_n', even
- though it will be set during matching by its
- attendant `set_number_at' (inserted next),
- because `re_compile_fastmap' needs to know.
- Jump to the `jump_n' we might insert below. */
- INSERT_JUMP2 (succeed_n, laststart,
- b + 5 + (upper_bound > 1) * 5,
- lower_bound);
- b += 5;
-
- /* Code to initialize the lower bound. Insert
- before the `succeed_n'. The `5' is the last two
- bytes of this `set_number_at', plus 3 bytes of
- the following `succeed_n'. */
- insert_op2 (set_number_at, laststart, 5, lower_bound, b);
- b += 5;
-
- if (upper_bound > 1)
- { /* More than one repetition is allowed, so
- append a backward jump to the `succeed_n'
- that starts this interval.
-
- When we've reached this during matching,
- we'll have matched the interval once, so
- jump back only `upper_bound - 1' times. */
- STORE_JUMP2 (jump_n, b, laststart + 5,
- upper_bound - 1);
- b += 5;
-
- /* The location we want to set is the second
- parameter of the `jump_n'; that is `b-2' as
- an absolute address. `laststart' will be
- the `set_number_at' we're about to insert;
- `laststart+3' the number to set, the source
- for the relative address. But we are
- inserting into the middle of the pattern --
- so everything is getting moved up by 5.
- Conclusion: (b - 2) - (laststart + 3) + 5,
- i.e., b - laststart.
-
- We insert this at the beginning of the loop
- so that if we fail during matching, we'll
- reinitialize the bounds. */
- insert_op2 (set_number_at, laststart, b - laststart,
- upper_bound - 1, b);
- b += 5;
- }
- }
- pending_exact = 0;
- beg_interval = NULL;
- }
- break;
-
- unfetch_interval:
- /* If an invalid interval, match the characters as literals. */
- assert (beg_interval);
- p = beg_interval;
- beg_interval = NULL;
-
- /* normal_char and normal_backslash need `c'. */
- PATFETCH (c);
-
- if (!(syntax & RE_NO_BK_BRACES))
- {
- if (p > pattern && p[-1] == '\\')
- goto normal_backslash;
- }
- goto normal_char;
-
-#ifdef emacs
- /* There is no way to specify the before_dot and after_dot
- operators. rms says this is ok. --karl */
- case '=':
- BUF_PUSH (at_dot);
- break;
-
- case 's':
- laststart = b;
- PATFETCH (c);
- BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
- break;
-
- case 'S':
- laststart = b;
- PATFETCH (c);
- BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
- break;
-#endif /* emacs */
-
-
- case 'w':
- if (re_syntax_options & RE_NO_GNU_OPS)
- goto normal_char;
- laststart = b;
- BUF_PUSH (wordchar);
- break;
-
-
- case 'W':
- if (re_syntax_options & RE_NO_GNU_OPS)
- goto normal_char;
- laststart = b;
- BUF_PUSH (notwordchar);
- break;
-
-
- case '<':
- if (re_syntax_options & RE_NO_GNU_OPS)
- goto normal_char;
- BUF_PUSH (wordbeg);
- break;
-
- case '>':
- if (re_syntax_options & RE_NO_GNU_OPS)
- goto normal_char;
- BUF_PUSH (wordend);
- break;
-
- case 'b':
- if (re_syntax_options & RE_NO_GNU_OPS)
- goto normal_char;
- BUF_PUSH (wordbound);
- break;
-
- case 'B':
- if (re_syntax_options & RE_NO_GNU_OPS)
- goto normal_char;
- BUF_PUSH (notwordbound);
- break;
-
- case '`':
- if (re_syntax_options & RE_NO_GNU_OPS)
- goto normal_char;
- BUF_PUSH (begbuf);
- break;
-
- case '\'':
- if (re_syntax_options & RE_NO_GNU_OPS)
- goto normal_char;
- BUF_PUSH (endbuf);
- break;
-
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- if (syntax & RE_NO_BK_REFS)
- goto normal_char;
-
- c1 = c - '0';
-
- if (c1 > regnum)
- FREE_STACK_RETURN (REG_ESUBREG);
-
- /* Can't back reference to a subexpression if inside of it. */
- if (group_in_compile_stack (compile_stack, (regnum_t) c1))
- goto normal_char;
-
- laststart = b;
- BUF_PUSH_2 (duplicate, c1);
- break;
-
-
- case '+':
- case '?':
- if (syntax & RE_BK_PLUS_QM)
- goto handle_plus;
- else
- goto normal_backslash;
-
- default:
- normal_backslash:
- /* You might think it would be useful for \ to mean
- not to translate; but if we don't translate it
- it will never match anything. */
- c = TRANSLATE (c);
- goto normal_char;
- }
- break;
-
-
- default:
- /* Expects the character in `c'. */
- normal_char:
- /* If no exactn currently being built. */
- if (!pending_exact
-
- /* If last exactn not at current position. */
- || pending_exact + *pending_exact + 1 != b
-
- /* We have only one byte following the exactn for the count. */
- || *pending_exact == (1 << BYTEWIDTH) - 1
-
- /* If followed by a repetition operator. */
- || *p == '*' || *p == '^'
- || ((syntax & RE_BK_PLUS_QM)
- ? *p == '\\' && (p[1] == '+' || p[1] == '?')
- : (*p == '+' || *p == '?'))
- || ((syntax & RE_INTERVALS)
- && ((syntax & RE_NO_BK_BRACES)
- ? *p == '{'
- : (p[0] == '\\' && p[1] == '{'))))
- {
- /* Start building a new exactn. */
-
- laststart = b;
-
- BUF_PUSH_2 (exactn, 0);
- pending_exact = b - 1;
- }
-
- BUF_PUSH (c);
- (*pending_exact)++;
- break;
- } /* switch (c) */
- } /* while p != pend */
-
-
- /* Through the pattern now. */
-
- if (fixup_alt_jump)
- STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
-
- if (!COMPILE_STACK_EMPTY)
- FREE_STACK_RETURN (REG_EPAREN);
-
- /* If we don't want backtracking, force success
- the first time we reach the end of the compiled pattern. */
- if (syntax & RE_NO_POSIX_BACKTRACKING)
- BUF_PUSH (succeed);
-
- free (compile_stack.stack);
-
- /* We have succeeded; set the length of the buffer. */
- bufp->used = b - bufp->buffer;
-
-#ifdef DEBUG
- if (debug)
- {
- DEBUG_PRINT1 ("\nCompiled pattern: \n");
- print_compiled_pattern (bufp);
- }
-#endif /* DEBUG */
-
-#ifndef MATCH_MAY_ALLOCATE
- /* Initialize the failure stack to the largest possible stack. This
- isn't necessary unless we're trying to avoid calling alloca in
- the search and match routines. */
- {
- int num_regs = bufp->re_nsub + 1;
-
- /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
- is strictly greater than re_max_failures, the largest possible stack
- is 2 * re_max_failures failure points. */
- if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
- {
- fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
-
-#ifdef emacs
- if (! fail_stack.stack)
- fail_stack.stack
- = (fail_stack_elt_t *) xmalloc (fail_stack.size
- * sizeof (fail_stack_elt_t));
- else
- fail_stack.stack
- = (fail_stack_elt_t *) xrealloc (fail_stack.stack,
- (fail_stack.size
- * sizeof (fail_stack_elt_t)));
-#else /* not emacs */
- if (! fail_stack.stack)
- fail_stack.stack
- = (fail_stack_elt_t *) malloc (fail_stack.size
- * sizeof (fail_stack_elt_t));
- else
- fail_stack.stack
- = (fail_stack_elt_t *) realloc (fail_stack.stack,
- (fail_stack.size
- * sizeof (fail_stack_elt_t)));
-#endif /* not emacs */
- }
-
- regex_grow_registers (num_regs);
- }
-#endif /* not MATCH_MAY_ALLOCATE */
-
- return REG_NOERROR;
-} /* regex_compile */
-
-/* Subroutines for `regex_compile'. */
-
-/* Store OP at LOC followed by two-byte integer parameter ARG. */
-
-static void
-store_op1 (op, loc, arg)
- re_opcode_t op;
- unsigned char *loc;
- int arg;
-{
- *loc = (unsigned char) op;
- STORE_NUMBER (loc + 1, arg);
-}
-
-
-/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */
-
-static void
-store_op2 (op, loc, arg1, arg2)
- re_opcode_t op;
- unsigned char *loc;
- int arg1, arg2;
-{
- *loc = (unsigned char) op;
- STORE_NUMBER (loc + 1, arg1);
- STORE_NUMBER (loc + 3, arg2);
-}
-
-
-/* Copy the bytes from LOC to END to open up three bytes of space at LOC
- for OP followed by two-byte integer parameter ARG. */
-
-static void
-insert_op1 (op, loc, arg, end)
- re_opcode_t op;
- unsigned char *loc;
- int arg;
- unsigned char *end;
-{
- register unsigned char *pfrom = end;
- register unsigned char *pto = end + 3;
-
- while (pfrom != loc)
- *--pto = *--pfrom;
-
- stor