summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoberto C. Sanchez <roberto@connexer.com>2014-03-29 10:54:01 -0400
committerRoberto C. Sanchez <roberto@connexer.com>2014-03-29 10:54:01 -0400
commit71a39f4652cd51df814c930dd268f3c9ad2aee86 (patch)
tree5994350a603908c4e4d660bc9d72c4ec43dd648e /src
parent03134fa5f6f25d92724ce4c183f9bbe12a9e37dc (diff)
Imported Upstream version 1.6.0+dfsg
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;
-
- store_op1 (op, loc, arg);
-}
-
-
-/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */
-
-static void
-insert_op2 (op, loc, arg1, arg2, end)
- re_opcode_t op;
- unsigned char *loc;
- int arg1, arg2;
- unsigned char *end;
-{
- register unsigned char *pfrom = end;
- register unsigned char *pto = end + 5;
-
- while (pfrom != loc)
- *--pto = *--pfrom;
-
- store_op2 (op, loc, arg1, arg2);
-}
-
-
-/* P points to just after a ^ in PATTERN. Return true if that ^ comes
- after an alternative or a begin-subexpression. We assume there is at
- least one character before the ^. */
-
-static boolean
-at_begline_loc_p (pattern, p, syntax)
- const char *pattern, *p;
- reg_syntax_t syntax;
-{
- const char *prev = p - 2;
- boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
-
- return
- /* After a subexpression? */
- (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
- /* After an alternative? */
- || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
-}
-
-
-/* The dual of at_begline_loc_p. This one is for $. We assume there is
- at least one character after the $, i.e., `P < PEND'. */
-
-static boolean
-at_endline_loc_p (p, pend, syntax)
- const char *p, *pend;
- reg_syntax_t syntax;
-{
- const char *next = p;
- boolean next_backslash = *next == '\\';
- const char *next_next = p + 1 < pend ? p + 1 : 0;
-
- return
- /* Before a subexpression? */
- (syntax & RE_NO_BK_PARENS ? *next == ')'
- : next_backslash && next_next && *next_next == ')')
- /* Before an alternative? */
- || (syntax & RE_NO_BK_VBAR ? *next == '|'
- : next_backslash && next_next && *next_next == '|');
-}
-
-
-/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
- false if it's not. */
-
-static boolean
-group_in_compile_stack (compile_stack, regnum)
- compile_stack_type compile_stack;
- regnum_t regnum;
-{
- int this_element;
-
- for (this_element = compile_stack.avail - 1;
- this_element >= 0;
- this_element--)
- if (compile_stack.stack[this_element].regnum == regnum)
- return true;
-
- return false;
-}
-
-
-/* Read the ending character of a range (in a bracket expression) from the
- uncompiled pattern *P_PTR (which ends at PEND). We assume the
- starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
- Then we set the translation of all bits between the starting and
- ending characters (inclusive) in the compiled pattern B.
-
- Return an error code.
-
- We use these short variable names so we can use the same macros as
- `regex_compile' itself. */
-
-static reg_errcode_t
-compile_range (p_ptr, pend, translate, syntax, b)
- const char **p_ptr, *pend;
- RE_TRANSLATE_TYPE translate;
- reg_syntax_t syntax;
- unsigned char *b;
-{
- unsigned this_char;
-
- const char *p = *p_ptr;
- unsigned int range_start, range_end;
-
- if (p == pend)
- return REG_ERANGE;
-
- /* Even though the pattern is a signed `char *', we need to fetch
- with unsigned char *'s; if the high bit of the pattern character
- is set, the range endpoints will be negative if we fetch using a
- signed char *.
-
- We also want to fetch the endpoints without translating them; the
- appropriate translation is done in the bit-setting loop below. */
- /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *. */
- range_start = ((const unsigned char *) p)[-2];
- range_end = ((const unsigned char *) p)[0];
-
- /* Have to increment the pointer into the pattern string, so the
- caller isn't still at the ending character. */
- (*p_ptr)++;
-
- /* If the start is after the end, the range is empty. */
- if (range_start > range_end)
- return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
-
- /* Here we see why `this_char' has to be larger than an `unsigned
- char' -- the range is inclusive, so if `range_end' == 0xff
- (assuming 8-bit characters), we would otherwise go into an infinite
- loop, since all characters <= 0xff. */
- for (this_char = range_start; this_char <= range_end; this_char++)
- {
- SET_LIST_BIT (TRANSLATE (this_char));
- }
-
- return REG_NOERROR;
-}
-
-/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
- BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
- characters can start a string that matches the pattern. This fastmap
- is used by re_search to skip quickly over impossible starting points.
-
- The caller must supply the address of a (1 << BYTEWIDTH)-byte data
- area as BUFP->fastmap.
-
- We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
- the pattern buffer.
-
- Returns 0 if we succeed, -2 if an internal error. */
-
-int
-re_compile_fastmap (bufp)
- struct re_pattern_buffer *bufp;
-{
- int j, k;
-#ifdef MATCH_MAY_ALLOCATE
- fail_stack_type fail_stack;
-#endif
-#ifndef REGEX_MALLOC
- char *destination;
-#endif
- /* We don't push any register information onto the failure stack. */
-//sword unsigned num_regs = 0;
-
- register char *fastmap = bufp->fastmap;
- unsigned char *pattern = bufp->buffer;
- unsigned char *p = pattern;
- register unsigned char *pend = pattern + bufp->used;
-
-#ifdef REL_ALLOC
- /* This holds the pointer to the failure stack, when
- it is allocated relocatably. */
- fail_stack_elt_t *failure_stack_ptr;
-#endif
-
- /* Assume that each path through the pattern can be null until
- proven otherwise. We set this false at the bottom of switch
- statement, to which we get only if a particular path doesn't
- match the empty string. */
- boolean path_can_be_null = true;
-
- /* We aren't doing a `succeed_n' to begin with. */
- boolean succeed_n_p = false;
-
- assert (fastmap != NULL && p != NULL);
-
- INIT_FAIL_STACK ();
- bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
- bufp->fastmap_accurate = 1; /* It will be when we're done. */
- bufp->can_be_null = 0;
-
- while (1)
- {
- if (p == pend || *p == succeed)
- {
- /* We have reached the (effective) end of pattern. */
- if (!FAIL_STACK_EMPTY ())
- {
- bufp->can_be_null |= path_can_be_null;
-
- /* Reset for next path. */
- path_can_be_null = true;
-
- p = fail_stack.stack[--fail_stack.avail].pointer;
-
- continue;
- }
- else
- break;
- }
-
- /* We should never be about to go beyond the end of the pattern. */
- assert (p < pend);
-
- switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
- {
-
- /* I guess the idea here is to simply not bother with a fastmap
- if a backreference is used, since it's too hard to figure out
- the fastmap for the corresponding group. Setting
- `can_be_null' stops `re_search_2' from using the fastmap, so
- that is all we do. */
- case duplicate:
- bufp->can_be_null = 1;
- goto done;
-
-
- /* Following are the cases which match a character. These end
- with `break'. */
-
- case exactn:
- fastmap[p[1]] = 1;
- break;
-
-
- case charset:
- for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
- if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
- fastmap[j] = 1;
- break;
-
-
- case charset_not:
- /* Chars beyond end of map must be allowed. */
- for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
- fastmap[j] = 1;
-
- for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
- if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
- fastmap[j] = 1;
- break;
-
-
- case wordchar:
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) == Sword)
- fastmap[j] = 1;
- break;
-
-
- case notwordchar:
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) != Sword)
- fastmap[j] = 1;
- break;
-
-
- case anychar:
- {
- int fastmap_newline = fastmap['\n'];
-
- /* `.' matches anything ... */
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- fastmap[j] = 1;
-
- /* ... except perhaps newline. */
- if (!(bufp->syntax & RE_DOT_NEWLINE))
- fastmap['\n'] = fastmap_newline;
-
- /* Return if we have already set `can_be_null'; if we have,
- then the fastmap is irrelevant. Something's wrong here. */
- else if (bufp->can_be_null)
- goto done;
-
- /* Otherwise, have to check alternative paths. */
- break;
- }
-
-#ifdef emacs
- case syntaxspec:
- k = *p++;
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) == (enum syntaxcode) k)
- fastmap[j] = 1;
- break;
-
-
- case notsyntaxspec:
- k = *p++;
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) != (enum syntaxcode) k)
- fastmap[j] = 1;
- break;
-
-
- /* All cases after this match the empty string. These end with
- `continue'. */
-
-
- case before_dot:
- case at_dot:
- case after_dot:
- continue;
-#endif /* emacs */
-
-
- case no_op:
- case begline:
- case endline:
- case begbuf:
- case endbuf:
- case wordbound:
- case notwordbound:
- case wordbeg:
- case wordend:
- case push_dummy_failure:
- continue;
-
-
- case jump_n:
- case pop_failure_jump:
- case maybe_pop_jump:
- case jump:
- case jump_past_alt:
- case dummy_failure_jump:
- EXTRACT_NUMBER_AND_INCR (j, p);
- p += j;
- if (j > 0)
- continue;
-
- /* Jump backward implies we just went through the body of a
- loop and matched nothing. Opcode jumped to should be
- `on_failure_jump' or `succeed_n'. Just treat it like an
- ordinary jump. For a * loop, it has pushed its failure
- point already; if so, discard that as redundant. */
- if ((re_opcode_t) *p != on_failure_jump
- && (re_opcode_t) *p != succeed_n)
- continue;
-
- p++;
- EXTRACT_NUMBER_AND_INCR (j, p);
- p += j;
-
- /* If what's on the stack is where we are now, pop it. */
- if (!FAIL_STACK_EMPTY ()
- && fail_stack.stack[fail_stack.avail - 1].pointer == p)
- fail_stack.avail--;
-
- continue;
-
-
- case on_failure_jump:
- case on_failure_keep_string_jump:
- handle_on_failure_jump:
- EXTRACT_NUMBER_AND_INCR (j, p);
-
- /* For some patterns, e.g., `(a?)?', `p+j' here points to the
- end of the pattern. We don't want to push such a point,
- since when we restore it above, entering the switch will
- increment `p' past the end of the pattern. We don't need
- to push such a point since we obviously won't find any more
- fastmap entries beyond `pend'. Such a pattern can match
- the null string, though. */
- if (p + j < pend)
- {
- if (!PUSH_PATTERN_OP (p + j, fail_stack))
- {
- RESET_FAIL_STACK ();
- return -2;
- }
- }
- else
- bufp->can_be_null = 1;
-
- if (succeed_n_p)
- {
- EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
- succeed_n_p = false;
- }
-
- continue;
-
-
- case succeed_n:
- /* Get to the number of times to succeed. */
- p += 2;
-
- /* Increment p past the n for when k != 0. */
- EXTRACT_NUMBER_AND_INCR (k, p);
- if (k == 0)
- {
- p -= 4;
- succeed_n_p = true; /* Spaghetti code alert. */
- goto handle_on_failure_jump;
- }
- continue;
-
-
- case set_number_at:
- p += 4;
- continue;
-
-
- case start_memory:
- case stop_memory:
- p += 2;
- continue;
-
-
- default:
- abort (); /* We have listed all the cases. */
- } /* switch *p++ */
-
- /* Getting here means we have found the possible starting
- characters for one path of the pattern -- and that the empty
- string does not match. We need not follow this path further.
- Instead, look at the next alternative (remembered on the
- stack), or quit if no more. The test at the top of the loop
- does these things. */
- path_can_be_null = false;
- p = pend;
- } /* while p */
-
- /* Set `can_be_null' for the last path (also the first path, if the
- pattern is empty). */
- bufp->can_be_null |= path_can_be_null;
-
- done:
- RESET_FAIL_STACK ();
- return 0;
-} /* re_compile_fastmap */
-
-/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
- ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
- this memory for recording register information. STARTS and ENDS
- must be allocated using the malloc library routine, and must each
- be at least NUM_REGS * sizeof (regoff_t) bytes long.
-
- If NUM_REGS == 0, then subsequent matches should allocate their own
- register data.
-
- Unless this function is called, the first search or match using
- PATTERN_BUFFER will allocate its own register data, without
- freeing the old data. */
-
-void
-re_set_registers (bufp, regs, num_regs, starts, ends)
- struct re_pattern_buffer *bufp;
- struct re_registers *regs;
- unsigned num_regs;
- regoff_t *starts, *ends;
-{
- if (num_regs)
- {
- bufp->regs_allocated = REGS_REALLOCATE;
- regs->num_regs = num_regs;
- regs->start = starts;
- regs->end = ends;
- }
- else
- {
- bufp->regs_allocated = REGS_UNALLOCATED;
- regs->num_regs = 0;
- regs->start = regs->end = (regoff_t *) 0;
- }
-}
-
-/* Searching routines. */
-
-/* Like re_search_2, below, but only one string is specified, and
- doesn't let you say where to stop matching. */
-
-int
-re_search (bufp, string, size, startpos, range, regs)
- struct re_pattern_buffer *bufp;
- const char *string;
- int size, startpos, range;
- struct re_registers *regs;
-{
- return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
- regs, size);
-}
-
-
-/* Using the compiled pattern in BUFP->buffer, first tries to match the
- virtual concatenation of STRING1 and STRING2, starting first at index
- STARTPOS, then at STARTPOS + 1, and so on.
-
- STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
-
- RANGE is how far to scan while trying to match. RANGE = 0 means try
- only at STARTPOS; in general, the last start tried is STARTPOS +
- RANGE.
-
- In REGS, return the indices of the virtual concatenation of STRING1
- and STRING2 that matched the entire BUFP->buffer and its contained
- subexpressions.
-
- Do not consider matching one past the index STOP in the virtual
- concatenation of STRING1 and STRING2.
-
- We return either the position in the strings at which the match was
- found, -1 if no match, or -2 if error (such as failure
- stack overflow). */
-
-int
-re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
- struct re_pattern_buffer *bufp;
- const char *string1, *string2;
- int size1, size2;
- int startpos;
- int range;
- struct re_registers *regs;
- int stop;
-{
- int val;
- register char *fastmap = bufp->fastmap;
- register RE_TRANSLATE_TYPE translate = bufp->translate;
- int total_size = size1 + size2;
- int endpos = startpos + range;
-
- /* Check for out-of-range STARTPOS. */
- if (startpos < 0 || startpos > total_size)
- return -1;
-
- /* Fix up RANGE if it might eventually take us outside
- the virtual concatenation of STRING1 and STRING2.
- Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */
- if (endpos < 0)
- range = 0 - startpos;
- else if (endpos > total_size)
- range = total_size - startpos;
-
- /* If the search isn't to be a backwards one, don't waste time in a
- search for a pattern that must be anchored. */
- if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0)
- {
- if (startpos > 0)
- return -1;
- else
- range = 1;
- }
-
-#ifdef emacs
- /* In a forward search for something that starts with \=.
- don't keep searching past point. */
- if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0)
- {
- range = PT - startpos;
- if (range <= 0)
- return -1;
- }
-#endif /* emacs */
-
- /* Update the fastmap now if not correct already. */
- if (fastmap && !bufp->fastmap_accurate)
- if (re_compile_fastmap (bufp) == -2)
- return -2;
-
- /* Loop through the string, looking for a place to start matching. */
- for (;;)
- {
- /* If a fastmap is supplied, skip quickly over characters that
- cannot be the start of a match. If the pattern can match the
- null string, however, we don't need to skip characters; we want
- the first null string. */
- if (fastmap && startpos < total_size && !bufp->can_be_null)
- {
- if (range > 0) /* Searching forwards. */
- {
- register const char *d;
- register int lim = 0;
- int irange = range;
-
- if (startpos < size1 && startpos + range >= size1)
- lim = range - (size1 - startpos);
-
- d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
-
- /* Written out as an if-else to avoid testing `translate'
- inside the loop. */
- if (translate)
- while (range > lim
- && !fastmap[(unsigned char)
- translate[(unsigned char) *d++]])
- range--;
- else
- while (range > lim && !fastmap[(unsigned char) *d++])
- range--;
-
- startpos += irange - range;
- }
- else /* Searching backwards. */
- {
- register char c = (size1 == 0 || startpos >= size1
- ? string2[startpos - size1]
- : string1[startpos]);
-
- if (!fastmap[(unsigned char) TRANSLATE (c)])
- goto advance;
- }
- }
-
- /* If can't match the null string, and that's all we have left, fail. */
- if (range >= 0 && startpos == total_size && fastmap
- && !bufp->can_be_null)
- return -1;
-
- val = re_match_2_internal (bufp, string1, size1, string2, size2,
- startpos, regs, stop);
-#ifndef REGEX_MALLOC
-#ifdef C_ALLOCA
- alloca (0);
-#endif
-#endif
-
- if (val >= 0)
- return startpos;
-
- if (val == -2)
- return -2;
-
- advance:
- if (!range)
- break;
- else if (range > 0)
- {
- range--;
- startpos++;
- }
- else
- {
- range++;
- startpos--;
- }
- }
- return -1;
-} /* re_search_2 */
-
-/* This converts PTR, a pointer into one of the search strings `string1'
- and `string2' into an offset from the beginning of that string. */
-#define POINTER_TO_OFFSET(ptr) \
- (FIRST_STRING_P (ptr) \
- ? ((regoff_t) ((ptr) - string1)) \
- : ((regoff_t) ((ptr) - string2 + size1)))
-
-/* Macros for dealing with the split strings in re_match_2. */
-
-#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
-
-/* Call before fetching a character with *d. This switches over to
- string2 if necessary. */
-#define PREFETCH() \
- while (d == dend) \
- { \
- /* End of string2 => fail. */ \
- if (dend == end_match_2) \
- goto fail; \
- /* End of string1 => advance to string2. */ \
- d = string2; \
- dend = end_match_2; \
- }
-
-
-/* Test if at very beginning or at very end of the virtual concatenation
- of `string1' and `string2'. If only one string, it's `string2'. */
-#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
-#define AT_STRINGS_END(d) ((d) == end2)
-
-
-/* Test if D points to a character which is word-constituent. We have
- two special cases to check for: if past the end of string1, look at
- the first character in string2; and if before the beginning of
- string2, look at the last character in string1. */
-#define WORDCHAR_P(d) \
- (SYNTAX ((d) == end1 ? *string2 \
- : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
- == Sword)
-
-/* Disabled due to a compiler bug -- see comment at case wordbound */
-#if 0
-/* Test if the character before D and the one at D differ with respect
- to being word-constituent. */
-#define AT_WORD_BOUNDARY(d) \
- (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
- || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
-#endif
-
-/* Free everything we malloc. */
-#ifdef MATCH_MAY_ALLOCATE
-#define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL
-#define FREE_VARIABLES() \
- do { \
- REGEX_FREE_STACK (fail_stack.stack); \
- FREE_VAR (regstart); \
- FREE_VAR (regend); \
- FREE_VAR (old_regstart); \
- FREE_VAR (old_regend); \
- FREE_VAR (best_regstart); \
- FREE_VAR (best_regend); \
- FREE_VAR (reg_info); \
- FREE_VAR (reg_dummy); \
- FREE_VAR (reg_info_dummy); \
- } while (0)
-#else
-#define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */
-#endif /* not MATCH_MAY_ALLOCATE */
-
-/* These values must meet several constraints. They must not be valid
- register values; since we have a limit of 255 registers (because
- we use only one byte in the pattern for the register number), we can
- use numbers larger than 255. They must differ by 1, because of
- NUM_FAILURE_ITEMS above. And the value for the lowest register must
- be larger than the value for the highest register, so we do not try
- to actually save any registers when none are active. */
-#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
-#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
-
-/* Matching routines. */
-
-#ifndef emacs /* Emacs never uses this. */
-/* re_match is like re_match_2 except it takes only a single string. */
-
-int
-re_match (bufp, string, size, pos, regs)
- struct re_pattern_buffer *bufp;
- const char *string;
- int size, pos;
- struct re_registers *regs;
-{
- int result = re_match_2_internal (bufp, NULL, 0, string, size,
- pos, regs, size);
-#ifndef REGEX_MALLOC
-#ifdef C_ALLOCA
- alloca (0);
-#endif
-#endif
- return result;
-}
-#endif /* not emacs */
-
-static boolean group_match_null_string_p _RE_ARGS ((unsigned char **p,
- unsigned char *end,
- register_info_type *reg_info));
-static boolean alt_match_null_string_p _RE_ARGS ((unsigned char *p,
- unsigned char *end,
- register_info_type *reg_info));
-static boolean common_op_match_null_string_p _RE_ARGS ((unsigned char **p,
- unsigned char *end,
- register_info_type *reg_info));
-static int bcmp_translate _RE_ARGS ((const char *s1, const char *s2,
- int len, char *translate));
-
-/* re_match_2 matches the compiled pattern in BUFP against the
- the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
- and SIZE2, respectively). We start matching at POS, and stop
- matching at STOP.
-
- If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
- store offsets for the substring each group matched in REGS. See the
- documentation for exactly how many groups we fill.
-
- We return -1 if no match, -2 if an internal error (such as the
- failure stack overflowing). Otherwise, we return the length of the
- matched substring. */
-
-int
-re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
- struct re_pattern_buffer *bufp;
- const char *string1, *string2;
- int size1, size2;
- int pos;
- struct re_registers *regs;
- int stop;
-{
- int result = re_match_2_internal (bufp, string1, size1, string2, size2,
- pos, regs, stop);
-#ifndef REGEX_MALLOC
-#ifdef C_ALLOCA
- alloca (0);
-#endif
-#endif
- return result;
-}
-
-/* This is a separate function so that we can force an alloca cleanup
- afterwards. */
-static int
-re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
- struct re_pattern_buffer *bufp;
- const char *string1, *string2;
- int size1, size2;
- int pos;
- struct re_registers *regs;
- int stop;
-{
- /* General temporaries. */
- int mcnt;
- unsigned char *p1;
-
- /* Just past the end of the corresponding string. */
- const char *end1, *end2;
-
- /* Pointers into string1 and string2, just past the last characters in
- each to consider matching. */
- const char *end_match_1, *end_match_2;
-
- /* Where we are in the data, and the end of the current string. */
- const char *d, *dend;
-
- /* Where we are in the pattern, and the end of the pattern. */
- unsigned char *p = bufp->buffer;
- register unsigned char *pend = p + bufp->used;
-
- /* Mark the opcode just after a start_memory, so we can test for an
- empty subpattern when we get to the stop_memory. */
- unsigned char *just_past_start_mem = 0;
-
- /* We use this to map every character in the string. */
- RE_TRANSLATE_TYPE translate = bufp->translate;
-
- /* Failure point stack. Each place that can handle a failure further
- down the line pushes a failure point on this stack. It consists of
- restart, regend, and reg_info for all registers corresponding to
- the subexpressions we're currently inside, plus the number of such
- registers, and, finally, two char *'s. The first char * is where
- to resume scanning the pattern; the second one is where to resume
- scanning the strings. If the latter is zero, the failure point is
- a ``dummy''; if a failure happens and the failure point is a dummy,
- it gets discarded and the next next one is tried. */
-#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
- fail_stack_type fail_stack;
-#endif
-#ifdef DEBUG
- static unsigned failure_id = 0;
- unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
-#endif
-
-#ifdef REL_ALLOC
- /* This holds the pointer to the failure stack, when
- it is allocated relocatably. */
- fail_stack_elt_t *failure_stack_ptr;
-#endif
-
- /* We fill all the registers internally, independent of what we
- return, for use in backreferences. The number here includes
- an element for register zero. */
- size_t num_regs = bufp->re_nsub + 1;
-
- /* The currently active registers. */
- active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG;
- active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG;
-
- /* Information on the contents of registers. These are pointers into
- the input strings; they record just what was matched (on this
- attempt) by a subexpression part of the pattern, that is, the
- regnum-th regstart pointer points to where in the pattern we began
- matching and the regnum-th regend points to right after where we
- stopped matching the regnum-th subexpression. (The zeroth register
- keeps track of what the whole pattern matches.) */
-#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
- const char **regstart, **regend;
-#endif
-
- /* If a group that's operated upon by a repetition operator fails to
- match anything, then the register for its start will need to be
- restored because it will have been set to wherever in the string we
- are when we last see its open-group operator. Similarly for a
- register's end. */
-#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
- const char **old_regstart, **old_regend;
-#endif
-
- /* The is_active field of reg_info helps us keep track of which (possibly
- nested) subexpressions we are currently in. The matched_something
- field of reg_info[reg_num] helps us tell whether or not we have
- matched any of the pattern so far this time through the reg_num-th
- subexpression. These two fields get reset each time through any
- loop their register is in. */
-#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
- register_info_type *reg_info;
-#endif
-
- /* The following record the register info as found in the above
- variables when we find a match better than any we've seen before.
- This happens as we backtrack through the failure points, which in
- turn happens only if we have not yet matched the entire string. */
- unsigned best_regs_set = false;
-#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
- const char **best_regstart, **best_regend;
-#endif
-
- /* Logically, this is `best_regend[0]'. But we don't want to have to
- allocate space for that if we're not allocating space for anything
- else (see below). Also, we never need info about register 0 for
- any of the other register vectors, and it seems rather a kludge to
- treat `best_regend' differently than the rest. So we keep track of
- the end of the best match so far in a separate variable. We
- initialize this to NULL so that when we backtrack the first time
- and need to test it, it's not garbage. */
- const char *match_end = NULL;
-
- /* This helps SET_REGS_MATCHED avoid doing redundant work. */
- int set_regs_matched_done = 0;
-
- /* Used when we pop values we don't care about. */
-#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
- const char **reg_dummy;
- register_info_type *reg_info_dummy;
-#endif
-
-#ifdef DEBUG
- /* Counts the total number of registers pushed. */
- unsigned num_regs_pushed = 0;
-#endif
-
- DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
-
- INIT_FAIL_STACK ();
-
-#ifdef MATCH_MAY_ALLOCATE
- /* Do not bother to initialize all the register variables if there are
- no groups in the pattern, as it takes a fair amount of time. If
- there are groups, we include space for register 0 (the whole
- pattern), even though we never use it, since it simplifies the
- array indexing. We should fix this. */
- if (bufp->re_nsub)
- {
- regstart = REGEX_TALLOC (num_regs, const char *);
- regend = REGEX_TALLOC (num_regs, const char *);
- old_regstart = REGEX_TALLOC (num_regs, const char *);
- old_regend = REGEX_TALLOC (num_regs, const char *);
- best_regstart = REGEX_TALLOC (num_regs, const char *);
- best_regend = REGEX_TALLOC (num_regs, const char *);
- reg_info = REGEX_TALLOC (num_regs, register_info_type);
- reg_dummy = REGEX_TALLOC (num_regs, const char *);
- reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);
-
- if (!(regstart && regend && old_regstart && old_regend && reg_info
- && best_regstart && best_regend && reg_dummy && reg_info_dummy))
- {
- FREE_VARIABLES ();
- return -2;
- }
- }
- else
- {
- /* We must initialize all our variables to NULL, so that
- `FREE_VARIABLES' doesn't try to free them. */
- regstart = regend = old_regstart = old_regend = best_regstart
- = best_regend = reg_dummy = NULL;
- reg_info = reg_info_dummy = (register_info_type *) NULL;
- }
-#endif /* MATCH_MAY_ALLOCATE */
-
- /* The starting position is bogus. */
- if (pos < 0 || pos > size1 + size2)
- {
- FREE_VARIABLES ();
- return -1;
- }
-
- /* Initialize subexpression text positions to -1 to mark ones that no
- start_memory/stop_memory has been seen for. Also initialize the
- register information struct. */
- for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
- {
- regstart[mcnt] = regend[mcnt]
- = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
-
- REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
- IS_ACTIVE (reg_info[mcnt]) = 0;
- MATCHED_SOMETHING (reg_info[mcnt]) = 0;
- EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
- }
-
- /* We move `string1' into `string2' if the latter's empty -- but not if
- `string1' is null. */
- if (size2 == 0 && string1 != NULL)
- {
- string2 = string1;
- size2 = size1;
- string1 = 0;
- size1 = 0;
- }
- end1 = string1 + size1;
- end2 = string2 + size2;
-
- /* Compute where to stop matching, within the two strings. */
- if (stop <= size1)
- {
- end_match_1 = string1 + stop;
- end_match_2 = string2;
- }
- else
- {
- end_match_1 = end1;
- end_match_2 = string2 + stop - size1;
- }
-
- /* `p' scans through the pattern as `d' scans through the data.
- `dend' is the end of the input string that `d' points within. `d'
- is advanced into the following input string whenever necessary, but
- this happens before fetching; therefore, at the beginning of the
- loop, `d' can be pointing at the end of a string, but it cannot
- equal `string2'. */
- if (size1 > 0 && pos <= size1)
- {
- d = string1 + pos;
- dend = end_match_1;
- }
- else
- {
- d = string2 + pos - size1;
- dend = end_match_2;
- }
-
- DEBUG_PRINT1 ("The compiled pattern is:\n");
- DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
- DEBUG_PRINT1 ("The string to match is: `");
- DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
- DEBUG_PRINT1 ("'\n");
-
- /* This loops over pattern commands. It exits by returning from the
- function if the match is complete, or it drops through if the match
- fails at this starting point in the input data. */
- for (;;)
- {
-#ifdef _LIBC
- DEBUG_PRINT2 ("\n%p: ", p);
-#else
- DEBUG_PRINT2 ("\n0x%x: ", p);
-#endif
-
- if (p == pend)
- { /* End of pattern means we might have succeeded. */
- DEBUG_PRINT1 ("end of pattern ... ");
-
- /* If we haven't matched the entire string, and we want the
- longest match, try backtracking. */
- if (d != end_match_2)
- {
- /* 1 if this match ends in the same string (string1 or string2)
- as the best previous match. */
- boolean same_str_p = (FIRST_STRING_P (match_end)
- == MATCHING_IN_FIRST_STRING);
- /* 1 if this match is the best seen so far. */
- boolean best_match_p;
-
- /* AIX compiler got confused when this was combined
- with the previous declaration. */
- if (same_str_p)
- best_match_p = d > match_end;
- else
- best_match_p = !MATCHING_IN_FIRST_STRING;
-
- DEBUG_PRINT1 ("backtracking.\n");
-
- if (!FAIL_STACK_EMPTY ())
- { /* More failure points to try. */
-
- /* If exceeds best match so far, save it. */
- if (!best_regs_set || best_match_p)
- {
- best_regs_set = true;
- match_end = d;
-
- DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
-
- for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
- {
- best_regstart[mcnt] = regstart[mcnt];
- best_regend[mcnt] = regend[mcnt];
- }
- }
- goto fail;
- }
-
- /* If no failure points, don't restore garbage. And if
- last match is real best match, don't restore second
- best one. */
- else if (best_regs_set && !best_match_p)
- {
- restore_best_regs:
- /* Restore best match. It may happen that `dend ==
- end_match_1' while the restored d is in string2.
- For example, the pattern `x.*y.*z' against the
- strings `x-' and `y-z-', if the two strings are
- not consecutive in memory. */
- DEBUG_PRINT1 ("Restoring best registers.\n");
-
- d = match_end;
- dend = ((d >= string1 && d <= end1)
- ? end_match_1 : end_match_2);
-
- for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
- {
- regstart[mcnt] = best_regstart[mcnt];
- regend[mcnt] = best_regend[mcnt];
- }
- }
- } /* d != end_match_2 */
-
- succeed_label:
- DEBUG_PRINT1 ("Accepting match.\n");
-
- /* If caller wants register contents data back, do it. */
- if (regs && !bufp->no_sub)
- {
- /* Have the register data arrays been allocated? */
- if (bufp->regs_allocated == REGS_UNALLOCATED)
- { /* No. So allocate them with malloc. We need one
- extra element beyond `num_regs' for the `-1' marker
- GNU code uses. */
- regs->num_regs = MAX (RE_NREGS, num_regs + 1);
- regs->start = TALLOC (regs->num_regs, regoff_t);
- regs->end = TALLOC (regs->num_regs, regoff_t);
- if (regs->start == NULL || regs->end == NULL)
- {
- FREE_VARIABLES ();
- return -2;
- }
- bufp->regs_allocated = REGS_REALLOCATE;
- }
- else if (bufp->regs_allocated == REGS_REALLOCATE)
- { /* Yes. If we need more elements than were already
- allocated, reallocate them. If we need fewer, just
- leave it alone. */
- if (regs->num_regs < num_regs + 1)
- {
- regs->num_regs = num_regs + 1;
- RETALLOC (regs->start, regs->num_regs, regoff_t);
- RETALLOC (regs->end, regs->num_regs, regoff_t);
- if (regs->start == NULL || regs->end == NULL)
- {
- FREE_VARIABLES ();
- return -2;
- }
- }
- }
- else
- {
- /* These braces fend off a "empty body in an else-statement"
- warning under GCC when assert expands to nothing. */
- assert (bufp->regs_allocated == REGS_FIXED);
- }
-
- /* Convert the pointer data in `regstart' and `regend' to
- indices. Register zero has to be set differently,
- since we haven't kept track of any info for it. */
- if (regs->num_regs > 0)
- {
- regs->start[0] = pos;
- regs->end[0] = (MATCHING_IN_FIRST_STRING
- ? ((regoff_t) (d - string1))
- : ((regoff_t) (d - string2 + size1)));
- }
-
- /* Go through the first `min (num_regs, regs->num_regs)'
- registers, since that is all we initialized. */
- for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs);
- mcnt++)
- {
- if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
- regs->start[mcnt] = regs->end[mcnt] = -1;
- else
- {
- regs->start[mcnt]
- = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
- regs->end[mcnt]
- = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
- }
- }
-
- /* If the regs structure we return has more elements than
- were in the pattern, set the extra elements to -1. If
- we (re)allocated the registers, this is the case,
- because we always allocate enough to have at least one
- -1 at the end. */
- for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++)
- regs->start[mcnt] = regs->end[mcnt] = -1;
- } /* regs && !bufp->no_sub */
-
- DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
- nfailure_points_pushed, nfailure_points_popped,
- nfailure_points_pushed - nfailure_points_popped);
- DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
-
- mcnt = d - pos - (MATCHING_IN_FIRST_STRING
- ? string1
- : string2 - size1);
-
- DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
-
- FREE_VARIABLES ();
- return mcnt;
- }
-
- /* Otherwise match next pattern command. */
- switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
- {
- /* Ignore these. Used to ignore the n of succeed_n's which
- currently have n == 0. */
- case no_op:
- DEBUG_PRINT1 ("EXECUTING no_op.\n");
- break;
-
- case succeed:
- DEBUG_PRINT1 ("EXECUTING succeed.\n");
- goto succeed_label;
-
- /* Match the next n pattern characters exactly. The following
- byte in the pattern defines n, and the n bytes after that
- are the characters to match. */
- case exactn:
- mcnt = *p++;
- DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
-
- /* This is written out as an if-else so we don't waste time
- testing `translate' inside the loop. */
- if (translate)
- {
- do
- {
- PREFETCH ();
- if ((unsigned char) translate[(unsigned char) *d++]
- != (unsigned char) *p++)
- goto fail;
- }
- while (--mcnt);
- }
- else
- {
- do
- {
- PREFETCH ();
- if (*d++ != (char) *p++) goto fail;
- }
- while (--mcnt);
- }
- SET_REGS_MATCHED ();
- break;
-
-
- /* Match any character except possibly a newline or a null. */
- case anychar:
- DEBUG_PRINT1 ("EXECUTING anychar.\n");
-
- PREFETCH ();
-
- if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
- || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
- goto fail;
-
- SET_REGS_MATCHED ();
- DEBUG_PRINT2 (" Matched `%d'.\n", *d);
- d++;
- break;
-
-
- case charset:
- case charset_not:
- {
- register unsigned char c;
- boolean not = (re_opcode_t) *(p - 1) == charset_not;
-
- DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
-
- PREFETCH ();
- c = TRANSLATE (*d); /* The character to match. */
-
- /* Cast to `unsigned' instead of `unsigned char' in case the
- bit list is a full 32 bytes long. */
- if (c < (unsigned) (*p * BYTEWIDTH)
- && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
- not = !not;
-
- p += 1 + *p;
-
- if (!not) goto fail;
-
- SET_REGS_MATCHED ();
- d++;
- break;
- }
-
-
- /* The beginning of a group is represented by start_memory.
- The arguments are the register number in the next byte, and the
- number of groups inner to this one in the next. The text
- matched within the group is recorded (in the internal
- registers data structure) under the register number. */
- case start_memory:
- DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]);
-
- /* Find out if this group can match the empty string. */
- p1 = p; /* To send to group_match_null_string_p. */
-
- if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
- REG_MATCH_NULL_STRING_P (reg_info[*p])
- = group_match_null_string_p (&p1, pend, reg_info);
-
- /* Save the position in the string where we were the last time
- we were at this open-group operator in case the group is
- operated upon by a repetition operator, e.g., with `(a*)*b'
- against `ab'; then we want to ignore where we are now in
- the string in case this attempt to match fails. */
- old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
- ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
- : regstart[*p];
- DEBUG_PRINT2 (" old_regstart: %d\n",
- POINTER_TO_OFFSET (old_regstart[*p]));
-
- regstart[*p] = d;
- DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
-
- IS_ACTIVE (reg_info[*p]) = 1;
- MATCHED_SOMETHING (reg_info[*p]) = 0;
-
- /* Clear this whenever we change the register activity status. */
- set_regs_matched_done = 0;
-
- /* This is the new highest active register. */
- highest_active_reg = *p;
-
- /* If nothing was active before, this is the new lowest active
- register. */
- if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
- lowest_active_reg = *p;
-
- /* Move past the register number and inner group count. */
- p += 2;
- just_past_start_mem = p;
-
- break;
-
-
- /* The stop_memory opcode represents the end of a group. Its
- arguments are the same as start_memory's: the register
- number, and the number of inner groups. */
- case stop_memory:
- DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);
-
- /* We need to save the string position the last time we were at
- this close-group operator in case the group is operated
- upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
- against `aba'; then we want to ignore where we are now in
- the string in case this attempt to match fails. */
- old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
- ? REG_UNSET (regend[*p]) ? d : regend[*p]
- : regend[*p];
- DEBUG_PRINT2 (" old_regend: %d\n",
- POINTER_TO_OFFSET (old_regend[*p]));
-
- regend[*p] = d;
- DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
-
- /* This register isn't active anymore. */
- IS_ACTIVE (reg_info[*p]) = 0;
-
- /* Clear this whenever we change the register activity status. */
- set_regs_matched_done = 0;
-
- /* If this was the only register active, nothing is active
- anymore. */
- if (lowest_active_reg == highest_active_reg)
- {
- lowest_active_reg = NO_LOWEST_ACTIVE_REG;
- highest_active_reg = NO_HIGHEST_ACTIVE_REG;
- }
- else
- { /* We must scan for the new highest active register, since
- it isn't necessarily one less than now: consider
- (a(b)c(d(e)f)g). When group 3 ends, after the f), the
- new highest active register is 1. */
- unsigned char r = *p - 1;
- while (r > 0 && !IS_ACTIVE (reg_info[r]))
- r--;
-
- /* If we end up at register zero, that means that we saved
- the registers as the result of an `on_failure_jump', not
- a `start_memory', and we jumped to past the innermost
- `stop_memory'. For example, in ((.)*) we save
- registers 1 and 2 as a result of the *, but when we pop
- back to the second ), we are at the stop_memory 1.
- Thus, nothing is active. */
- if (r == 0)
- {
- lowest_active_reg = NO_LOWEST_ACTIVE_REG;
- highest_active_reg = NO_HIGHEST_ACTIVE_REG;
- }
- else
- highest_active_reg = r;
- }
-
- /* If just failed to match something this time around with a
- group that's operated on by a repetition operator, try to
- force exit from the ``loop'', and restore the register
- information for this group that we had before trying this
- last match. */
- if ((!MATCHED_SOMETHING (reg_info[*p])
- || just_past_start_mem == p - 1)
- && (p + 2) < pend)
- {
- boolean is_a_jump_n = false;
-
- p1 = p + 2;
- mcnt = 0;
- switch ((re_opcode_t) *p1++)
- {
- case jump_n:
- is_a_jump_n = true;
- case pop_failure_jump:
- case maybe_pop_jump:
- case jump:
- case dummy_failure_jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- if (is_a_jump_n)
- p1 += 2;
- break;
-
- default:
- /* do nothing */ ;
- }
- p1 += mcnt;
-
- /* If the next operation is a jump backwards in the pattern
- to an on_failure_jump right before the start_memory
- corresponding to this stop_memory, exit from the loop
- by forcing a failure after pushing on the stack the
- on_failure_jump's jump in the pattern, and d. */
- if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
- && (re_opcode_t) p1[3] == start_memory && p1[4] == *p)
- {
- /* If this group ever matched anything, then restore
- what its registers were before trying this last
- failed match, e.g., with `(a*)*b' against `ab' for
- regstart[1], and, e.g., with `((a*)*(b*)*)*'
- against `aba' for regend[3].
-
- Also restore the registers for inner groups for,
- e.g., `((a*)(b*))*' against `aba' (register 3 would
- otherwise get trashed). */
-
- if (EVER_MATCHED_SOMETHING (reg_info[*p]))
- {
- unsigned r;
-
- EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
-
- /* Restore this and inner groups' (if any) registers. */
- for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1);
- r++)
- {
- regstart[r] = old_regstart[r];
-
- /* xx why this test? */
- if (old_regend[r] >= regstart[r])
- regend[r] = old_regend[r];
- }
- }
- p1++;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
-
- goto fail;
- }
- }
-
- /* Move past the register number and the inner group count. */
- p += 2;
- break;
-
-
- /* \<digit> has been turned into a `duplicate' command which is
- followed by the numeric value of <digit> as the register number. */
- case duplicate:
- {
- register const char *d2, *dend2;
- int regno = *p++; /* Get which register to match against. */
- DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
-
- /* Can't back reference a group which we've never matched. */
- if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
- goto fail;
-
- /* Where in input to try to start matching. */
- d2 = regstart[regno];
-
- /* Where to stop matching; if both the place to start and
- the place to stop matching are in the same string, then
- set to the place to stop, otherwise, for now have to use
- the end of the first string. */
-
- dend2 = ((FIRST_STRING_P (regstart[regno])
- == FIRST_STRING_P (regend[regno]))
- ? regend[regno] : end_match_1);
- for (;;)
- {
- /* If necessary, advance to next segment in register
- contents. */
- while (d2 == dend2)
- {
- if (dend2 == end_match_2) break;
- if (dend2 == regend[regno]) break;
-
- /* End of string1 => advance to string2. */
- d2 = string2;
- dend2 = regend[regno];
- }
- /* At end of register contents => success */
- if (d2 == dend2) break;
-
- /* If necessary, advance to next segment in data. */
- PREFETCH ();
-
- /* How many characters left in this segment to match. */
- mcnt = dend - d;
-
- /* Want how many consecutive characters we can match in
- one shot, so, if necessary, adjust the count. */
- if (mcnt > dend2 - d2)
- mcnt = dend2 - d2;
-
- /* Compare that many; failure if mismatch, else move
- past them. */
- if (translate
- ? bcmp_translate (d, d2, mcnt, translate)
- : bcmp (d, d2, mcnt))
- goto fail;
- d += mcnt, d2 += mcnt;
-
- /* Do this because we've match some characters. */
- SET_REGS_MATCHED ();
- }
- }
- break;
-
-
- /* begline matches the empty string at the beginning of the string
- (unless `not_bol' is set in `bufp'), and, if
- `newline_anchor' is set, after newlines. */
- case begline:
- DEBUG_PRINT1 ("EXECUTING begline.\n");
-
- if (AT_STRINGS_BEG (d))
- {
- if (!bufp->not_bol) break;
- }
- else if (d[-1] == '\n' && bufp->newline_anchor)
- {
- break;
- }
- /* In all other cases, we fail. */
- goto fail;
-
-
- /* endline is the dual of begline. */
- case endline:
- DEBUG_PRINT1 ("EXECUTING endline.\n");
-
- if (AT_STRINGS_END (d))
- {
- if (!bufp->not_eol) break;
- }
-
- /* We have to ``prefetch'' the next character. */
- else if ((d == end1 ? *string2 : *d) == '\n'
- && bufp->newline_anchor)
- {
- break;
- }
- goto fail;
-
-
- /* Match at the very beginning of the data. */
- case begbuf:
- DEBUG_PRINT1 ("EXECUTING begbuf.\n");
- if (AT_STRINGS_BEG (d))
- break;
- goto fail;
-
-
- /* Match at the very end of the data. */
- case endbuf:
- DEBUG_PRINT1 ("EXECUTING endbuf.\n");
- if (AT_STRINGS_END (d))
- break;
- goto fail;
-
-
- /* on_failure_keep_string_jump is used to optimize `.*\n'. It
- pushes NULL as the value for the string on the stack. Then
- `pop_failure_point' will keep the current value for the
- string, instead of restoring it. To see why, consider
- matching `foo\nbar' against `.*\n'. The .* matches the foo;
- then the . fails against the \n. But the next thing we want
- to do is match the \n against the \n; if we restored the
- string value, we would be back at the foo.
-
- Because this is used only in specific cases, we don't need to
- check all the things that `on_failure_jump' does, to make
- sure the right things get saved on the stack. Hence we don't
- share its code. The only reason to push anything on the
- stack at all is that otherwise we would have to change
- `anychar's code to do something besides goto fail in this
- case; that seems worse than this. */
- case on_failure_keep_string_jump:
- DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
-
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
-#ifdef _LIBC
- DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt);
-#else
- DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
-#endif
-
- PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
- break;
-
-
- /* Uses of on_failure_jump:
-
- Each alternative starts with an on_failure_jump that points
- to the beginning of the next alternative. Each alternative
- except the last ends with a jump that in effect jumps past
- the rest of the alternatives. (They really jump to the
- ending jump of the following alternative, because tensioning
- these jumps is a hassle.)
-
- Repeats start with an on_failure_jump that points past both
- the repetition text and either the following jump or
- pop_failure_jump back to this on_failure_jump. */
- case on_failure_jump:
- on_failure:
- DEBUG_PRINT1 ("EXECUTING on_failure_jump");
-
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
-#ifdef _LIBC
- DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt);
-#else
- DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
-#endif
-
- /* If this on_failure_jump comes right before a group (i.e.,
- the original * applied to a group), save the information
- for that group and all inner ones, so that if we fail back
- to this point, the group's information will be correct.
- For example, in \(a*\)*\1, we need the preceding group,
- and in \(zz\(a*\)b*\)\2, we need the inner group. */
-
- /* We can't use `p' to check ahead because we push
- a failure point to `p + mcnt' after we do this. */
- p1 = p;
-
- /* We need to skip no_op's before we look for the
- start_memory in case this on_failure_jump is happening as
- the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
- against aba. */
- while (p1 < pend && (re_opcode_t) *p1 == no_op)
- p1++;
-
- if (p1 < pend && (re_opcode_t) *p1 == start_memory)
- {
- /* We have a new highest active register now. This will
- get reset at the start_memory we are about to get to,
- but we will have saved all the registers relevant to
- this repetition op, as described above. */
- highest_active_reg = *(p1 + 1) + *(p1 + 2);
- if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
- lowest_active_reg = *(p1 + 1);
- }
-
- DEBUG_PRINT1 (":\n");
- PUSH_FAILURE_POINT (p + mcnt, d, -2);
- break;
-
-
- /* A smart repeat ends with `maybe_pop_jump'.
- We change it to either `pop_failure_jump' or `jump'. */
- case maybe_pop_jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
- {
- register unsigned char *p2 = p;
-
- /* Compare the beginning of the repeat with what in the
- pattern follows its end. If we can establish that there
- is nothing that they would both match, i.e., that we
- would have to backtrack because of (as in, e.g., `a*a')
- then we can change to pop_failure_jump, because we'll
- never have to backtrack.
-
- This is not true in the case of alternatives: in
- `(a|ab)*' we do need to backtrack to the `ab' alternative
- (e.g., if the string was `ab'). But instead of trying to
- detect that here, the alternative has put on a dummy
- failure point which is what we will end up popping. */
-
- /* Skip over open/close-group commands.
- If what follows this loop is a ...+ construct,
- look at what begins its body, since we will have to
- match at least one of that. */
- while (1)
- {
- if (p2 + 2 < pend
- && ((re_opcode_t) *p2 == stop_memory
- || (re_opcode_t) *p2 == start_memory))
- p2 += 3;
- else if (p2 + 6 < pend
- && (re_opcode_t) *p2 == dummy_failure_jump)
- p2 += 6;
- else
- break;
- }
-
- p1 = p + mcnt;
- /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
- to the `maybe_finalize_jump' of this case. Examine what
- follows. */
-
- /* If we're at the end of the pattern, we can change. */
- if (p2 == pend)
- {
- /* Consider what happens when matching ":\(.*\)"
- against ":/". I don't really understand this code
- yet. */
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT1
- (" End of pattern: change to `pop_failure_jump'.\n");
- }
-
- else if ((re_opcode_t) *p2 == exactn
- || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
- {
- register unsigned char c
- = *p2 == (unsigned char) endline ? '\n' : p2[2];
-
- if ((re_opcode_t) p1[3] == exactn && p1[5] != c)
- {
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
- c, p1[5]);
- }
-
- else if ((re_opcode_t) p1[3] == charset
- || (re_opcode_t) p1[3] == charset_not)
- {
- int not = (re_opcode_t) p1[3] == charset_not;
-
- if (c < (unsigned char) (p1[4] * BYTEWIDTH)
- && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
- not = !not;
-
- /* `not' is equal to 1 if c would match, which means
- that we can't change to pop_failure_jump. */
- if (!not)
- {
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
- }
- }
- }
- else if ((re_opcode_t) *p2 == charset)
- {
-#ifdef DEBUG
- register unsigned char c
- = *p2 == (unsigned char) endline ? '\n' : p2[2];
-#endif
-
-#if 0
- if ((re_opcode_t) p1[3] == exactn
- && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5]
- && (p2[2 + p1[5] / BYTEWIDTH]
- & (1 << (p1[5] % BYTEWIDTH)))))
-#else
- if ((re_opcode_t) p1[3] == exactn
- && ! ((int) p2[1] * BYTEWIDTH > (int) p1[4]
- && (p2[2 + p1[4] / BYTEWIDTH]
- & (1 << (p1[4] % BYTEWIDTH)))))
-#endif
- {
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
- c, p1[5]);
- }
-
- else if ((re_opcode_t) p1[3] == charset_not)
- {
- int idx;
- /* We win if the charset_not inside the loop
- lists every character listed in the charset after. */
- for (idx = 0; idx < (int) p2[1]; idx++)
- if (! (p2[2 + idx] == 0
- || (idx < (int) p1[4]
- && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
- break;
-
- if (idx == p2[1])
- {
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
- }
- }
- else if ((re_opcode_t) p1[3] == charset)
- {
- int idx;
- /* We win if the charset inside the loop
- has no overlap with the one after the loop. */
- for (idx = 0;
- idx < (int) p2[1] && idx < (int) p1[4];
- idx++)
- if ((p2[2 + idx] & p1[5 + idx]) != 0)
- break;
-
- if (idx == p2[1] || idx == p1[4])
- {
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
- }
- }
- }
- }
- p -= 2; /* Point at relative address again. */
- if ((re_opcode_t) p[-1] != pop_failure_jump)
- {
- p[-1] = (unsigned char) jump;
- DEBUG_PRINT1 (" Match => jump.\n");
- goto unconditional_jump;
- }
- /* Note fall through. */
-
-
- /* The end of a simple repeat has a pop_failure_jump back to
- its matching on_failure_jump, where the latter will push a
- failure point. The pop_failure_jump takes off failure
- points put on by this pop_failure_jump's matching
- on_failure_jump; we got through the pattern to here from the
- matching on_failure_jump, so didn't fail. */
- case pop_failure_jump:
- {
- /* We need to pass separate storage for the lowest and
- highest registers, even though we don't care about the
- actual values. Otherwise, we will restore only one
- register from the stack, since lowest will == highest in
- `pop_failure_point'. */
- active_reg_t dummy_low_reg, dummy_high_reg;
- unsigned char *pdummy;
- const char *sdummy;
-
- DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
- POP_FAILURE_POINT (sdummy, pdummy,
- dummy_low_reg, dummy_high_reg,
- reg_dummy, reg_dummy, reg_info_dummy);
- }
- /* Note fall through. */
-
- unconditional_jump:
-#ifdef _LIBC
- DEBUG_PRINT2 ("\n%p: ", p);
-#else
- DEBUG_PRINT2 ("\n0x%x: ", p);
-#endif
- /* Note fall through. */
-
- /* Unconditionally jump (without popping any failure points). */
- case jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
- DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
- p += mcnt; /* Do the jump. */
-#ifdef _LIBC
- DEBUG_PRINT2 ("(to %p).\n", p);
-#else
- DEBUG_PRINT2 ("(to 0x%x).\n", p);
-#endif
- break;
-
-
- /* We need this opcode so we can detect where alternatives end
- in `group_match_null_string_p' et al. */
- case jump_past_alt:
- DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
- goto unconditional_jump;
-
-
- /* Normally, the on_failure_jump pushes a failure point, which
- then gets popped at pop_failure_jump. We will end up at
- pop_failure_jump, also, and with a pattern of, say, `a+', we
- are skipping over the on_failure_jump, so we have to push
- something meaningless for pop_failure_jump to pop. */
- case dummy_failure_jump:
- DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
- /* It doesn't matter what we push for the string here. What
- the code at `fail' tests is the value for the pattern. */
- PUSH_FAILURE_POINT (0, 0, -2);
- goto unconditional_jump;
-
-
- /* At the end of an alternative, we need to push a dummy failure
- point in case we are followed by a `pop_failure_jump', because
- we don't want the failure point for the alternative to be
- popped. For example, matching `(a|ab)*' against `aab'
- requires that we match the `ab' alternative. */
- case push_dummy_failure:
- DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
- /* See comments just above at `dummy_failure_jump' about the
- two zeroes. */
- PUSH_FAILURE_POINT (0, 0, -2);
- break;
-
- /* Have to succeed matching what follows at least n times.
- After that, handle like `on_failure_jump'. */
- case succeed_n:
- EXTRACT_NUMBER (mcnt, p + 2);
- DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
-
- assert (mcnt >= 0);
- /* Originally, this is how many times we HAVE to succeed. */
- if (mcnt > 0)
- {
- mcnt--;
- p += 2;
- STORE_NUMBER_AND_INCR (p, mcnt);
-#ifdef _LIBC
- DEBUG_PRINT3 (" Setting %p to %d.\n", p - 2, mcnt);
-#else
- DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p - 2, mcnt);
-#endif
- }
- else if (mcnt == 0)
- {
-#ifdef _LIBC
- DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n", p+2);
-#else
- DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2);
-#endif
- p[2] = (unsigned char) no_op;
- p[3] = (unsigned char) no_op;
- goto on_failure;
- }
- break;
-
- case jump_n:
- EXTRACT_NUMBER (mcnt, p + 2);
- DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
-
- /* Originally, this is how many times we CAN jump. */
- if (mcnt)
- {
- mcnt--;
- STORE_NUMBER (p + 2, mcnt);
-#ifdef _LIBC
- DEBUG_PRINT3 (" Setting %p to %d.\n", p + 2, mcnt);
-#else
- DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p + 2, mcnt);
-#endif
- goto unconditional_jump;
- }
- /* If don't have to jump any more, skip over the rest of command. */
- else
- p += 4;
- break;
-
- case set_number_at:
- {
- DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
-
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- p1 = p + mcnt;
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
-#ifdef _LIBC
- DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt);
-#else
- DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
-#endif
- STORE_NUMBER (p1, mcnt);
- break;
- }
-
-#if 0
- /* The DEC Alpha C compiler 3.x generates incorrect code for the
- test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of
- AT_WORD_BOUNDARY, so this code is disabled. Expanding the
- macro and introducing temporary variables works around the bug. */
-
- case wordbound:
- DEBUG_PRINT1 ("EXECUTING wordbound.\n");
- if (AT_WORD_BOUNDARY (d))
- break;
- goto fail;
-
- case notwordbound:
- DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
- if (AT_WORD_BOUNDARY (d))
- goto fail;
- break;
-#else
- case wordbound:
- {
- boolean prevchar, thischar;
-
- DEBUG_PRINT1 ("EXECUTING wordbound.\n");
- if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
- break;
-
- prevchar = WORDCHAR_P (d - 1);
- thischar = WORDCHAR_P (d);
- if (prevchar != thischar)
- break;
- goto fail;
- }
-
- case notwordbound:
- {
- boolean prevchar, thischar;
-
- DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
- if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
- goto fail;
-
- prevchar = WORDCHAR_P (d - 1);
- thischar = WORDCHAR_P (d);
- if (prevchar != thischar)
- goto fail;
- break;
- }
-#endif
-
- case wordbeg:
- DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
- if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
- break;
- goto fail;
-
- case wordend:
- DEBUG_PRINT1 ("EXECUTING wordend.\n");
- if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
- && (!WORDCHAR_P (d) || AT_STRINGS_END (d)))
- break;
- goto fail;
-
-#ifdef emacs
- case before_dot:
- DEBUG_PRINT1 ("EXECUTING before_dot.\n");
- if (PTR_CHAR_POS ((unsigned char *) d) >= point)
- goto fail;
- break;
-
- case at_dot:
- DEBUG_PRINT1 ("EXECUTING at_dot.\n");
- if (PTR_CHAR_POS ((unsigned char *) d) != point)
- goto fail;
- break;
-
- case after_dot:
- DEBUG_PRINT1 ("EXECUTING after_dot.\n");
- if (PTR_CHAR_POS ((unsigned char *) d) <= point)
- goto fail;
- break;
-
- case syntaxspec:
- DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
- mcnt = *p++;
- goto matchsyntax;
-
- case wordchar:
- DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
- mcnt = (int) Sword;
- matchsyntax:
- PREFETCH ();
- /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
- d++;
- if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
- goto fail;
- SET_REGS_MATCHED ();
- break;
-
- case notsyntaxspec:
- DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
- mcnt = *p++;
- goto matchnotsyntax;
-
- case notwordchar:
- DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
- mcnt = (int) Sword;
- matchnotsyntax:
- PREFETCH ();
- /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
- d++;
- if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
- goto fail;
- SET_REGS_MATCHED ();
- break;
-
-#else /* not emacs */
- case wordchar:
- DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
- PREFETCH ();
- if (!WORDCHAR_P (d))
- goto fail;
- SET_REGS_MATCHED ();
- d++;
- break;
-
- case notwordchar:
- DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
- PREFETCH ();
- if (WORDCHAR_P (d))
- goto fail;
- SET_REGS_MATCHED ();
- d++;
- break;
-#endif /* not emacs */
-
- default:
- abort ();
- }
- continue; /* Successfully executed one pattern command; keep going. */
-
-
- /* We goto here if a matching operation fails. */
- fail:
- if (!FAIL_STACK_EMPTY ())
- { /* A restart point is known. Restore to that state. */
- DEBUG_PRINT1 ("\nFAIL:\n");
- POP_FAILURE_POINT (d, p,
- lowest_active_reg, highest_active_reg,
- regstart, regend, reg_info);
-
- /* If this failure point is a dummy, try the next one. */
- if (!p)
- goto fail;
-
- /* If we failed to the end of the pattern, don't examine *p. */
- assert (p <= pend);
- if (p < pend)
- {
- boolean is_a_jump_n = false;
-
- /* If failed to a backwards jump that's part of a repetition
- loop, need to pop this failure point and use the next one. */
- switch ((re_opcode_t) *p)
- {
- case jump_n:
- is_a_jump_n = true;
- case maybe_pop_jump:
- case pop_failure_jump:
- case jump:
- p1 = p + 1;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- p1 += mcnt;
-
- if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
- || (!is_a_jump_n
- && (re_opcode_t) *p1 == on_failure_jump))
- goto fail;
- break;
- default:
- /* do nothing */ ;
- }
- }
-
- if (d >= string1 && d <= end1)
- dend = end_match_1;
- }
- else
- break; /* Matching at this starting point really fails. */
- } /* for (;;) */
-
- if (best_regs_set)
- goto restore_best_regs;
-
- FREE_VARIABLES ();
-
- return -1; /* Failure to match. */
-} /* re_match_2 */
-
-/* Subroutine definitions for re_match_2. */
-
-
-/* We are passed P pointing to a register number after a start_memory.
-
- Return true if the pattern up to the corresponding stop_memory can
- match the empty string, and false otherwise.
-
- If we find the matching stop_memory, sets P to point to one past its number.
- Otherwise, sets P to an undefined byte less than or equal to END.
-
- We don't handle duplicates properly (yet). */
-
-static boolean
-group_match_null_string_p (p, end, reg_info)
- unsigned char **p, *end;
- register_info_type *reg_info;
-{
- int mcnt;
- /* Point to after the args to the start_memory. */
- unsigned char *p1 = *p + 2;
-
- while (p1 < end)
- {
- /* Skip over opcodes that can match nothing, and return true or
- false, as appropriate, when we get to one that can't, or to the
- matching stop_memory. */
-
- switch ((re_opcode_t) *p1)
- {
- /* Could be either a loop or a series of alternatives. */
- case on_failure_jump:
- p1++;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
-
- /* If the next operation is not a jump backwards in the
- pattern. */
-
- if (mcnt >= 0)
- {
- /* Go through the on_failure_jumps of the alternatives,
- seeing if any of the alternatives cannot match nothing.
- The last alternative starts with only a jump,
- whereas the rest start with on_failure_jump and end
- with a jump, e.g., here is the pattern for `a|b|c':
-
- /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
- /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
- /exactn/1/c
-
- So, we have to first go through the first (n-1)
- alternatives and then deal with the last one separately. */
-
-
- /* Deal with the first (n-1) alternatives, which start
- with an on_failure_jump (see above) that jumps to right
- past a jump_past_alt. */
-
- while ((re_opcode_t) p1[mcnt-3] == jump_past_alt)
- {
- /* `mcnt' holds how many bytes long the alternative
- is, including the ending `jump_past_alt' and
- its number. */
-
- if (!alt_match_null_string_p (p1, p1 + mcnt - 3,
- reg_info))
- return false;
-
- /* Move to right after this alternative, including the
- jump_past_alt. */
- p1 += mcnt;
-
- /* Break if it's the beginning of an n-th alternative
- that doesn't begin with an on_failure_jump. */
- if ((re_opcode_t) *p1 != on_failure_jump)
- break;
-
- /* Still have to check that it's not an n-th
- alternative that starts with an on_failure_jump. */
- p1++;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- if ((re_opcode_t) p1[mcnt-3] != jump_past_alt)
- {
- /* Get to the beginning of the n-th alternative. */
- p1 -= 3;
- break;
- }
- }
-
- /* Deal with the last alternative: go back and get number
- of the `jump_past_alt' just before it. `mcnt' contains
- the length of the alternative. */
- EXTRACT_NUMBER (mcnt, p1 - 2);
-
- if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info))
- return false;
-
- p1 += mcnt; /* Get past the n-th alternative. */
- } /* if mcnt > 0 */
- break;
-
-
- case stop_memory:
- assert (p1[1] == **p);
- *p = p1 + 2;
- return true;
-
-
- default:
- if (!common_op_match_null_string_p (&p1, end, reg_info))
- return false;
- }
- } /* while p1 < end */
-
- return false;
-} /* group_match_null_string_p */
-
-
-/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
- It expects P to be the first byte of a single alternative and END one
- byte past the last. The alternative can contain groups. */
-
-static boolean
-alt_match_null_string_p (p, end, reg_info)
- unsigned char *p, *end;
- register_info_type *reg_info;
-{
- int mcnt;
- unsigned char *p1 = p;
-
- while (p1 < end)
- {
- /* Skip over opcodes that can match nothing, and break when we get
- to one that can't. */
-
- switch ((re_opcode_t) *p1)
- {
- /* It's a loop. */
- case on_failure_jump:
- p1++;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- p1 += mcnt;
- break;
-
- default:
- if (!common_op_match_null_string_p (&p1, end, reg_info))
- return false;
- }
- } /* while p1 < end */
-
- return true;
-} /* alt_match_null_string_p */
-
-
-/* Deals with the ops common to group_match_null_string_p and
- alt_match_null_string_p.
-
- Sets P to one after the op and its arguments, if any. */
-
-static boolean
-common_op_match_null_string_p (p, end, reg_info)
- unsigned char **p, *end;
- register_info_type *reg_info;
-{
- int mcnt;
- boolean ret;
- int reg_no;
- unsigned char *p1 = *p;
-
- switch ((re_opcode_t) *p1++)
- {
- case no_op:
- case begline:
- case endline:
- case begbuf:
- case endbuf:
- case wordbeg:
- case wordend:
- case wordbound:
- case notwordbound:
-#ifdef emacs
- case before_dot:
- case at_dot:
- case after_dot:
-#endif
- break;
-
- case start_memory:
- reg_no = *p1;
- assert (reg_no > 0 && reg_no <= MAX_REGNUM);
- ret = group_match_null_string_p (&p1, end, reg_info);
-
- /* Have to set this here in case we're checking a group which
- contains a group and a back reference to it. */
-
- if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
- REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
-
- if (!ret)
- return false;
- break;
-
- /* If this is an optimized succeed_n for zero times, make the jump. */
- case jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- if (mcnt >= 0)
- p1 += mcnt;
- else
- return false;
- break;
-
- case succeed_n:
- /* Get to the number of times to succeed. */
- p1 += 2;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
-
- if (mcnt == 0)
- {
- p1 -= 4;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- p1 += mcnt;
- }
- else
- return false;
- break;
-
- case duplicate:
- if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
- return false;
- break;
-
- case set_number_at:
- p1 += 4;
-
- default:
- /* All other opcodes mean we cannot match the empty string. */
- return false;
- }
-
- *p = p1;
- return true;
-} /* common_op_match_null_string_p */
-
-
-/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
- bytes; nonzero otherwise. */
-
-static int
-bcmp_translate (s1, s2, len, translate)
- const char *s1, *s2;
- register int len;
- RE_TRANSLATE_TYPE translate;
-{
- register const unsigned char *p1 = (const unsigned char *) s1;
- register const unsigned char *p2 = (const unsigned char *) s2;
- while (len)
- {
- if (translate[*p1++] != translate[*p2++]) return 1;
- len--;
- }
- return 0;
-}
-
-/* Entry points for GNU code. */
-
-/* re_compile_pattern is the GNU regular expression compiler: it
- compiles PATTERN (of length SIZE) and puts the result in BUFP.
- Returns 0 if the pattern was valid, otherwise an error string.
-
- Assumes the `allocated' (and perhaps `buffer') and `translate' fields
- are set in BUFP on entry.
-
- We call regex_compile to do the actual compilation. */
-
-const char *
-re_compile_pattern (pattern, length, bufp)
- const char *pattern;
- size_t length;
- struct re_pattern_buffer *bufp;
-{
- reg_errcode_t ret;
-
- /* GNU code is written to assume at least RE_NREGS registers will be set
- (and at least one extra will be -1). */
- bufp->regs_allocated = REGS_UNALLOCATED;
-
- /* And GNU code determines whether or not to get register information
- by passing null for the REGS argument to re_match, etc., not by
- setting no_sub. */
- bufp->no_sub = 0;
-
- /* Match anchors at newline. */
- bufp->newline_anchor = 1;
-
- ret = regex_compile (pattern, length, re_syntax_options, bufp);
-
- if (!ret)
- return NULL;
- return gettext (re_error_msgid[(int) ret]);
-}
-
-/* Entry points compatible with 4.2 BSD regex library. We don't define
- them unless specifically requested. */
-
-#if defined (_REGEX_RE_COMP) || defined (_LIBC)
-
-/* BSD has one and only one pattern buffer. */
-static struct re_pattern_buffer re_comp_buf;
-
-char *
-#ifdef _LIBC
-/* Make these definitions weak in libc, so POSIX programs can redefine
- these names if they don't use our functions, and still use
- regcomp/regexec below without link errors. */
-weak_function
-#endif
-re_comp (s)
- const char *s;
-{
- reg_errcode_t ret;
-
- if (!s)
- {
- if (!re_comp_buf.buffer)
- return gettext ("No previous regular expression");
- return 0;
- }
-
- if (!re_comp_buf.buffer)
- {
- re_comp_buf.buffer = (unsigned char *) malloc (200);
- if (re_comp_buf.buffer == NULL)
- return gettext (re_error_msgid[(int) REG_ESPACE]);
- re_comp_buf.allocated = 200;
-
- re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
- if (re_comp_buf.fastmap == NULL)
- return gettext (re_error_msgid[(int) REG_ESPACE]);
- }
-
- /* Since `re_exec' always passes NULL for the `regs' argument, we
- don't need to initialize the pattern buffer fields which affect it. */
-
- /* Match anchors at newlines. */
- re_comp_buf.newline_anchor = 1;
-
- ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
-
- if (!ret)
- return NULL;
-
- /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */
- return (char *) gettext (re_error_msgid[(int) ret]);
-}
-
-
-int
-#ifdef _LIBC
-weak_function
-#endif
-re_exec (s)
- const char *s;
-{
- const int len = strlen (s);
- return
- 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
-}
-
-#endif /* _REGEX_RE_COMP */
-
-/* POSIX.2 functions. Don't define these for Emacs. */
-
-#ifndef emacs
-
-/* regcomp takes a regular expression as a string and compiles it.
-
- PREG is a regex_t *. We do not expect any fields to be initialized,
- since POSIX says we shouldn't. Thus, we set
-
- `buffer' to the compiled pattern;
- `used' to the length of the compiled pattern;
- `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
- REG_EXTENDED bit in CFLAGS is set; otherwise, to
- RE_SYNTAX_POSIX_BASIC;
- `newline_anchor' to REG_NEWLINE being set in CFLAGS;
- `fastmap' and `fastmap_accurate' to zero;
- `re_nsub' to the number of subexpressions in PATTERN.
-
- PATTERN is the address of the pattern string.
-
- CFLAGS is a series of bits which affect compilation.
-
- If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
- use POSIX basic syntax.
-
- If REG_NEWLINE is set, then . and [^...] don't match newline.
- Also, regexec will try a match beginning after every newline.
-
- If REG_ICASE is set, then we considers upper- and lowercase
- versions of letters to be equivalent when matching.
-
- If REG_NOSUB is set, then when PREG is passed to regexec, that
- routine will report only success or failure, and nothing about the
- registers.
-
- It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for
- the return codes and their meanings.) */
-
-int
-regcomp (preg, pattern, cflags)
- regex_t *preg;
- const char *pattern;
- int cflags;
-{
- reg_errcode_t ret;
- reg_syntax_t syntax
- = (cflags & REG_EXTENDED) ?
- RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
-
- /* regex_compile will allocate the space for the compiled pattern. */
- preg->buffer = 0;
- preg->allocated = 0;
- preg->used = 0;
-
- /* Don't bother to use a fastmap when searching. This simplifies the
- REG_NEWLINE case: if we used a fastmap, we'd have to put all the
- characters after newlines into the fastmap. This way, we just try
- every character. */
- preg->fastmap = 0;
-
- if (cflags & REG_ICASE)
- {
- unsigned i;
-
- preg->translate
- = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE
- * sizeof (*(RE_TRANSLATE_TYPE)0));
- if (preg->translate == NULL)
- return (int) REG_ESPACE;
-
- /* Map uppercase characters to corresponding lowercase ones. */
- for (i = 0; i < CHAR_SET_SIZE; i++)
- preg->translate[i] = ISUPPER (i) ? tolower (i) : i;
- }
- else
- preg->translate = NULL;
-
- /* If REG_NEWLINE is set, newlines are treated differently. */
- if (cflags & REG_NEWLINE)
- { /* REG_NEWLINE implies neither . nor [^...] match newline. */
- syntax &= ~RE_DOT_NEWLINE;
- syntax |= RE_HAT_LISTS_NOT_NEWLINE;
- /* It also changes the matching behavior. */
- preg->newline_anchor = 1;
- }
- else
- preg->newline_anchor = 0;
-
- preg->no_sub = !!(cflags & REG_NOSUB);
-
- /* POSIX says a null character in the pattern terminates it, so we
- can use strlen here in compiling the pattern. */
- ret = regex_compile (pattern, strlen (pattern), syntax, preg);
-
- /* POSIX doesn't distinguish between an unmatched open-group and an
- unmatched close-group: both are REG_EPAREN. */
- if (ret == REG_ERPAREN) ret = REG_EPAREN;
-
- return (int) ret;
-}
-
-
-/* regexec searches for a given pattern, specified by PREG, in the
- string STRING.
-
- If NMATCH is zero or REG_NOSUB was set in the cflags argument to
- `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
- least NMATCH elements, and we set them to the offsets of the
- corresponding matched substrings.
-
- EFLAGS specifies `execution flags' which affect matching: if
- REG_NOTBOL is set, then ^ does not match at the beginning of the
- string; if REG_NOTEOL is set, then $ does not match at the end.
-
- We return 0 if we find a match and REG_NOMATCH if not. */
-
-int
-regexec (preg, string, nmatch, pmatch, eflags)
- const regex_t *preg;
- const char *string;
- size_t nmatch;
- regmatch_t pmatch[];
- int eflags;
-{
- int ret;
- struct re_registers regs;
- regex_t private_preg;
- int len = strlen (string);
- boolean want_reg_info = !preg->no_sub && nmatch > 0;
-
- private_preg = *preg;
-
- private_preg.not_bol = !!(eflags & REG_NOTBOL);
- private_preg.not_eol = !!(eflags & REG_NOTEOL);
-
- /* The user has told us exactly how many registers to return
- information about, via `nmatch'. We have to pass that on to the
- matching routines. */
- private_preg.regs_allocated = REGS_FIXED;
-
- if (want_reg_info)
- {
- regs.num_regs = nmatch;
- regs.start = TALLOC (nmatch, regoff_t);
- regs.end = TALLOC (nmatch, regoff_t);
- if (regs.start == NULL || regs.end == NULL)
- return (int) REG_NOMATCH;
- }
-
- /* Perform the searching operation. */
- ret = re_search (&private_preg, string, len,
- /* start: */ 0, /* range: */ len,
- want_reg_info ? &regs : (struct re_registers *) 0);
-
- /* Copy the register information to the POSIX structure. */
- if (want_reg_info)
- {
- if (ret >= 0)
- {
- unsigned r;
-
- for (r = 0; r < nmatch; r++)
- {
- pmatch[r].rm_so = regs.start[r];
- pmatch[r].rm_eo = regs.end[r];
- }
- }
-
- /* If we needed the temporary register info, free the space now. */
- free (regs.start);
- free (regs.end);
- }
-
- /* We want zero return to mean success, unlike `re_search'. */
- return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
-}
-
-
-/* Returns a message corresponding to an error code, ERRCODE, returned
- from either regcomp or regexec. We don't use PREG here. */
-
-size_t
-regerror (int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
-{
- const char *msg;
- size_t msg_size;
-
- if (errcode < 0
- || errcode >= (int) (sizeof (re_error_msgid)
- / sizeof (re_error_msgid[0])))
- /* Only error codes returned by the rest of the code should be passed
- to this routine. If we are given anything else, or if other regex
- code generates an invalid error code, then the program has a bug.
- Dump core so we can fix it. */
- abort ();
-
- msg = gettext (re_error_msgid[errcode]);
-
- msg_size = strlen (msg) + 1; /* Includes the null. */
-
- if (errbuf_size != 0)
- {
- if (msg_size > errbuf_size)
- {
- strncpy (errbuf, msg, errbuf_size - 1);
- errbuf[errbuf_size - 1] = 0;
- }
- else
- strcpy (errbuf, msg);
- }
-
- return msg_size;
-}
-
-
-/* Free dynamically allocated space used by PREG. */
-
-void
-regfree (preg)
- regex_t *preg;
-{
- if (preg->buffer != NULL)
- free (preg->buffer);
- preg->buffer = NULL;
-
- preg->allocated = 0;
- preg->used = 0;
-
- if (preg->fastmap != NULL)
- free (preg->fastmap);
- preg->fastmap = NULL;
- preg->fastmap_accurate = 0;
-
- if (preg->translate != NULL)
- free (preg->translate);
- preg->translate = NULL;
-}
-
-#endif /* not emacs */
diff --git a/src/utilfuns/roman.cpp b/src/utilfuns/roman.cpp
index 85f361d..4db9540 100644
--- a/src/utilfuns/roman.cpp
+++ b/src/utilfuns/roman.cpp
@@ -1,22 +1,20 @@
/*
* roman.c
- * 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.
- *
- * 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.
- *
+ *
+ * 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>
@@ -25,9 +23,9 @@
SWORD_NAMESPACE_START
-char isroman (const char* str) {
- char * ch = (char*)str;
- for (; *ch; ch++)
+char isroman (const char *str, int maxchars) {
+ char *ch = (char*)str;
+ for (; *ch && (!maxchars || (ch-str) <= maxchars); ch++)
if (!strchr("IVXLCDMivxlcdm ", *ch))
return 0;
return 1;
diff --git a/src/utilfuns/sub.c b/src/utilfuns/sub.c
deleted file mode 100644
index fcea6e2..0000000
--- a/src/utilfuns/sub.c
+++ /dev/null
@@ -1,36 +0,0 @@
-
-#include <stdio.h>
-#include <stdlib.h>
-
-main(int argc, char **argv)
-{
- FILE *fp;
- char *buf;
- int size;
-
- if ((argc < 3) || (argc > 4)) {
- fprintf(stderr, "usage: %s <string> <substitute string> [filename]\n", *argv);
- exit(-1);
- }
-
- if (argc > 3)
- fp = fopen(argv[3], "r");
- else fp = stdin;
-
- size = strlen(argv[1]);
- buf = (char *)calloc(size + 1, 1);
-
- while ((buf[size - 1] = fgetc(fp)) != EOF) {
- if (!strcmp(buf, argv[1])) {
- printf("\n%s", argv[2]);
- memset(buf, 0, size);
- continue;
- }
- if (*buf) {
- printf("%c", *buf);
- }
- memmove(buf, &buf[1], size);
- }
- buf[size - 1] = 0;
- printf("%s", buf);
-}
diff --git a/src/utilfuns/swbuf.cpp b/src/utilfuns/swbuf.cpp
index 430a705..53dd43a 100644
--- a/src/utilfuns/swbuf.cpp
+++ b/src/utilfuns/swbuf.cpp
@@ -1,7 +1,7 @@
/******************************************************************************
* swbuf.cpp - code for SWBuf used as a transport and utility for data buffers
*
-* $Id: swbuf.cpp 2169 2008-05-18 02:50:53Z scribe $
+* $Id: swbuf.cpp 2198 2008-09-11 20:59:30Z scribe $
*
* Copyright 2003 CrossWire Bible Society (http://www.crosswire.org)
* CrossWire Bible Society
@@ -76,7 +76,7 @@ SWBuf::SWBuf(unsigned long initSize) {
* WARNING: This function can only write at most
* JUNKBUFSIZE to the string per call.
*/
-void SWBuf::setFormatted(const char *format, ...) {
+SWBuf &SWBuf::setFormatted(const char *format, ...) {
va_list argptr;
va_start(argptr, format);
@@ -90,6 +90,7 @@ void SWBuf::setFormatted(const char *format, ...) {
va_start(argptr, format);
end = vsprintf(buf, format, argptr) + buf;
va_end(argptr);
+ return *this;
}
/******************************************************************************
diff --git a/src/utilfuns/swversion.cpp b/src/utilfuns/swversion.cpp
index 9e61f06..fe112db 100644
--- a/src/utilfuns/swversion.cpp
+++ b/src/utilfuns/swversion.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 <config.h>
#include <swversion.h>
diff --git a/src/utilfuns/url.cpp b/src/utilfuns/url.cpp
index 3a50e2c..549c283 100644
--- a/src/utilfuns/url.cpp
+++ b/src/utilfuns/url.cpp
@@ -1,7 +1,7 @@
/******************************************************************************
* url.cpp - code for an URL parser utility class
*
-* $Id: url.cpp 2013 2006-11-25 22:01:04Z dglassey $
+* $Id: url.cpp 2250 2009-02-14 05:48:58Z scribe $
*
* Copyright 2003 CrossWire Bible Society (http://www.crosswire.org)
* CrossWire Bible Society
@@ -31,6 +31,27 @@
SWORD_NAMESPACE_START
+namespace {
+ typedef std::map< unsigned char, SWBuf > DataMap;
+ DataMap m;
+ static class __init {
+ public:
+ __init() {
+ for (unsigned short int c = 32; c <= 255; ++c) { //first set all encoding chars
+ if ( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || strchr("-_.!~*'()", c)) {
+ continue; //we don't need an encoding for this char
+ }
+
+ SWBuf buf;
+ buf.setFormatted("%%%-.2X", c);
+ m[c] = buf;
+ }
+ //the special encodings for certain chars
+ m[' '] = '+';
+ }
+ } ___init;
+}
+
/**
* Constructors/Destructors
*/
@@ -197,24 +218,11 @@ void URL::parse () {
}
}
+
const SWBuf URL::encode(const char *urlText) {
/*static*/ SWBuf url;
url = urlText;
- typedef std::map< unsigned char, SWBuf > DataMap;
- DataMap m;
- for (unsigned short int c = 32; c <= 255; ++c) { //first set all encoding chars
- if ( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || strchr("-_.!~*'()", c)) {
- continue; //we don't need an encoding for this char
- }
-
- SWBuf buf;
- buf.setFormatted("%%%-.2X", c);
- m[c] = buf;
- }
- //the special encodings for certain chars
- m[' '] = '+';
-
SWBuf buf;
const int length = url.length();
for (int i = 0; i < length; i++) { //fill "buf"
diff --git a/src/utilfuns/utilstr.cpp b/src/utilfuns/utilstr.cpp
index 52dc286..9a0ddc6 100644
--- a/src/utilfuns/utilstr.cpp
+++ b/src/utilfuns/utilstr.cpp
@@ -1,20 +1,26 @@
+/*
+ * 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 <ctype.h>
#include <string.h>
-#include <localemgr.h>
-
+#include <sysdata.h>
-#ifdef _ICU_
-#include <unicode/utypes.h>
-#include <unicode/ucnv.h>
-#include <unicode/ustring.h>
-#include <unicode/uchar.h>
-
-#include <unicode/unistr.h>
-#include <unicode/translit.h>
-
-#endif
SWORD_NAMESPACE_START
@@ -67,13 +73,14 @@ const unsigned char SW_toupper_array[256] =
*/
char *stdstr(char **ipstr, const char *istr, unsigned int memPadFactor) {
+ if (*ipstr)
+ delete [] *ipstr;
if (istr) {
- if (*ipstr)
- delete [] *ipstr;
int len = strlen(istr) + 1;
*ipstr = new char [ len * memPadFactor ];
memcpy(*ipstr, istr, len);
}
+ else *ipstr = 0;
return *ipstr;
}
@@ -174,68 +181,58 @@ int stricmp(const char *s1, const char *s2) {
#endif
}
+
/******************************************************************************
- * toupperstr - converts a string to uppercase string
+ * getUniCharFromUTF8 - retrieves the next Unicode codepoint from a UTF8 string
+ * and increments buf to start of next codepoint
*
- * ENT: target - string to convert
+ * ENT: buf - address of a utf8 buffer
*
- * RET: target
+ * RET: buf - incremented past last byte used in computing the current codepoint
+ * unicode codepoint value (0 with buf incremented is invalid UTF8 byte
*/
-// char *toupperstr(char *buf) {
-// char *ret = buf;
-//
-// /*if (StringHelper::getSystemStringHelper()) {
-// StringHelper::getSystemStringHelper()->upperStringLatin1( ret );
-// }
-// else*/ {
-// while (*buf) {
-// *buf++ = SW_toupper(*buf);
-// }
-// // }
-// return ret;
-// }
+__u32 getUniCharFromUTF8(const unsigned char **buf) {
+ __u32 ch = 0;
+ unsigned char multibuf[7];
+
+ //case: We're at the end
+ if (!(**buf)) {
+ return ch;
+ }
+ //case: ANSI
+ if (!(**buf & 128)) {
+ ch = **buf;
+ (*buf)++;
+ return ch;
+ }
-/******************************************************************************
- * toupperstr - converts a string to uppercase string
- *
- * ENT: target - string to convert
- *
- * RET: target
- */
+ //case: Invalid UTF-8 (illegal continuing byte in initial position)
+ if ((**buf & 128) && (!(**buf & 64))) {
+ (*buf)++;
+ return ch;
+ }
+
+ //case: 2+ byte codepoint
+ multibuf[0] = **buf;
+ multibuf[0] <<= 1;
+ int subsequent;
+ for (subsequent = 1; (multibuf[0] & 128) && (subsequent < 7); subsequent++) {
+ multibuf[0] <<= 1;
+ multibuf[subsequent] = (*buf)[subsequent];
+ multibuf[subsequent] &= 63;
+ ch <<= 6;
+ ch |= multibuf[subsequent];
+ }
+ subsequent--;
+ multibuf[0] <<= 1;
+ char significantFirstBits = 8 - (2+subsequent);
+
+ ch |= (((__s16)multibuf[0]) << (((6*subsequent)+significantFirstBits)-8));
+ *buf += (subsequent+1);
+ return ch;
+}
-// char *toupperstr_utf8(char *buf, unsigned int max) {
-// char *ret = buf;
-//
-// /* if (StringHelper::getSystemStringHelper()) {
-// StringHelper::getSystemStringHelper()->upperStringUtf8( ret );
-// return ret;
-// }*/
-//
-// #ifndef _ICU_
-// // try to decide if it's worth trying to toupper. Do we have more
-// // characters that are probably lower latin than not?
-// long performOp = 0;
-// for (const char *ch = buf; *ch; ch++)
-// performOp += (*ch > 0) ? 1 : -1;
-//
-// if (performOp > 0) {
-// while (*buf)
-// *buf = SW_toupper(*buf++);
-// }
-// #else
-// if (!max)
-// max = strlen(ret);
-// UErrorCode err = U_ZERO_ERROR;
-// UConverter *conv = ucnv_open("UTF-8", &err);
-// UnicodeString str(buf, -1, conv, err);
-// UnicodeString ustr = str.toUpper();
-// ustr.extract(ret, max, conv, err);
-// ucnv_close(conv);
-// #endif
-//
-// return ret;
-// }
SWORD_NAMESPACE_END
diff --git a/src/utilfuns/utilxml.cpp b/src/utilfuns/utilxml.cpp
index 9184102..d3af7e5 100644
--- a/src/utilfuns/utilxml.cpp
+++ b/src/utilfuns/utilxml.cpp
@@ -1,7 +1,7 @@
/******************************************************************************
* utilxml.cpp - implementaion of utility classes to handle XML processing
*
- * $Id: utilxml.cpp 2096 2007-10-07 00:40:00Z scribe $
+ * $Id: utilxml.cpp 2378 2009-05-04 23:18:51Z scribe $
*
* Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
* CrossWire Bible Society
@@ -121,6 +121,22 @@ XMLTag::XMLTag(const char *tagString) {
setText(tagString);
}
+XMLTag::XMLTag(const XMLTag& t) : attributes(t.attributes) {
+ parsed = t.parsed;
+ empty = t.empty;
+ endTag = t.endTag;
+ if (t.buf) {
+ int len = strlen(t.buf);
+ buf = new char[len + 1];
+ memcpy(buf, t.buf, len + 1);
+ }
+ if (t.name) {
+ int len = strlen(t.name);
+ name = new char[len + 1];
+ memcpy(name, t.name, len + 1);
+ }
+}
+
void XMLTag::setText(const char *tagString) {
parsed = false;
empty = false;
@@ -293,4 +309,13 @@ const char *XMLTag::toString() const {
}
+// if an eID is provided, then we check to be sure we have an attribute <tag eID="xxx"/> value xxx equiv to what is given us
+// otherwise, we return if we're a simple XML end </tag>.
+bool XMLTag::isEndTag(const char *eID) const {
+ if (eID) {
+ return (SWBuf(eID) == getAttribute("eID"));
+ }
+ return endTag;
+}
+
SWORD_NAMESPACE_END
diff --git a/src/utilfuns/win32/dirent.cpp b/src/utilfuns/win32/dirent.cpp
deleted file mode 100644
index 150bf10..0000000
--- a/src/utilfuns/win32/dirent.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
-
- Implementation of POSIX directory browsing functions and types for Win32.
-
- Kevlin Henney (mailto:kevlin@acm.org), March 1997.
-
- Copyright Kevlin Henney, 1997. All rights reserved.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose is hereby granted without fee, provided
- that this copyright and permissions notice appear in all copies and
- derivatives, and that no charge may be made for the software and its
- documentation except to cover cost of distribution.
-
- This software is supplied "as is" without express or implied warranty.
-
- But that said, if there are any problems please get in touch.
-
-*/
-
-#include <dirent.h>
-#include <errno.h>
-#include <io.h>
-#include <stdlib.h>
-#include <string.h>
-
-struct DIR
-{
- long handle; /* -1 for failed rewind */
- struct _finddata_t info;
- struct dirent result; /* d_name null iff first time */
- char *name; /* NTBS */
-};
-
-DIR *opendir(const char *name)
-{
- DIR *dir = 0;
-
- if(name && name[0])
- {
- size_t base_length = strlen(name);
- const char *all = /* the root directory is a special case... */
- strchr("/\\", name[base_length - 1]) ? "*" : "/*";
-
- if((dir = (DIR *) malloc(sizeof *dir)) != 0 &&
- (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0)
- {
- strcat(strcpy(dir->name, name), all);
-
- if((dir->handle = _findfirst(dir->name, &dir->info)) != -1)
- {
- dir->result.d_name = 0;
- }
- else /* rollback */
- {
- free(dir->name);
- free(dir);
- dir = 0;
- }
- }
- else /* rollback */
- {
- free(dir);
- dir = 0;
- errno = ENOMEM;
- }
- }
- else
- {
- errno = EINVAL;
- }
-
- return dir;
-}
-
-int closedir(DIR *dir)
-{
- int result = -1;
-
- if(dir)
- {
- if(dir->handle != -1)
- {
- result = _findclose(dir->handle);
- }
-
- free(dir->name);
- free(dir);
- }
-
- if(result == -1) /* map all errors to EBADF */
- {
- errno = EBADF;
- }
-
- return result;
-}
-
-struct dirent *readdir(DIR *dir)
-{
- struct dirent *result = 0;
-
- if(dir && dir->handle != -1)
- {
- if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
- {
- result = &dir->result;
- result->d_name = dir->info.name;
- }
- }
- else
- {
- errno = EBADF;
- }
-
- return result;
-}
-
-void rewinddir(DIR *dir)
-{
- if(dir && dir->handle != -1)
- {
- _findclose(dir->handle);
- dir->handle = _findfirst(dir->name, &dir->info);
- dir->result.d_name = 0;
- }
- else
- {
- errno = EBADF;
- }
-}
diff --git a/src/utilfuns/win32/dirent.h b/src/utilfuns/win32/dirent.h
deleted file mode 100644
index ba22833..0000000
--- a/src/utilfuns/win32/dirent.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-
- Declaration of POSIX directory browsing functions and types for Win32.
-
- Kevlin Henney (mailto:kevlin@acm.org), March 1997.
-
- Copyright Kevlin Henney, 1997. All rights reserved.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose is hereby granted without fee, provided
- that this copyright and permissions notice appear in all copies and
- derivatives, and that no charge may be made for the software and its
- documentation except to cover cost of distribution.
-
-*/
-
-#ifndef DIRENT_INCLUDED
-#define DIRENT_INCLUDED
-
-typedef struct DIR DIR;
-
-struct dirent
-{
- char *d_name;
-};
-
-DIR *opendir(const char *);
-int closedir(DIR *);
-struct dirent *readdir(DIR *);
-void rewinddir(DIR *);
-
-#endif
diff --git a/src/utilfuns/zlib/adler32.c b/src/utilfuns/zlib/adler32.c
deleted file mode 100644
index c786e9a..0000000
--- a/src/utilfuns/zlib/adler32.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: adler32.c 1688 2005-01-01 04:42:26Z scribe $ */
-
-#include "zlib.h"
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
-#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf) DO8(buf,0); DO8(buf,8);
-
-/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
- uLong adler;
- const Bytef *buf;
- uInt len;
-{
- unsigned long s1 = adler & 0xffff;
- unsigned long s2 = (adler >> 16) & 0xffff;
- int k;
-
- if (buf == Z_NULL) return 1L;
-
- while (len > 0) {
- k = len < NMAX ? len : NMAX;
- len -= k;
- while (k >= 16) {
- DO16(buf);
- buf += 16;
- k -= 16;
- }
- if (k != 0) do {
- s1 += *buf++;
- s2 += s1;
- } while (--k);
- s1 %= BASE;
- s2 %= BASE;
- }
- return (s2 << 16) | s1;
-}
diff --git a/src/utilfuns/zlib/compress.c b/src/utilfuns/zlib/compress.c
deleted file mode 100644
index 2b1f048..0000000
--- a/src/utilfuns/zlib/compress.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: compress.c 1688 2005-01-01 04:42:26Z scribe $ */
-
-#include "zlib.h"
-
-/* ===========================================================================
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
- int level;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
-#ifdef MAXSEG_64K
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-#endif
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
-
- err = deflateInit(&stream, level);
- if (err != Z_OK) return err;
-
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = deflateEnd(&stream);
- return err;
-}
-
-/* ===========================================================================
- */
-int ZEXPORT compress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
-}
diff --git a/src/utilfuns/zlib/crc32.c b/src/utilfuns/zlib/crc32.c
deleted file mode 100644
index e44440c..0000000
--- a/src/utilfuns/zlib/crc32.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: crc32.c 1688 2005-01-01 04:42:26Z scribe $ */
-
-#include "zlib.h"
-
-#define local static
-
-#ifdef DYNAMIC_CRC_TABLE
-
-local int crc_table_empty = 1;
-local uLongf crc_table[256];
-local void make_crc_table OF((void));
-
-/*
- Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
- x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
- Polynomials over GF(2) are represented in binary, one bit per coefficient,
- with the lowest powers in the most significant bit. Then adding polynomials
- is just exclusive-or, and multiplying a polynomial by x is a right shift by
- one. If we call the above polynomial p, and represent a byte as the
- polynomial q, also with the lowest power in the most significant bit (so the
- byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- where a mod b means the remainder after dividing a by b.
-
- This calculation is done using the shift-register method of multiplying and
- taking the remainder. The register is initialized to zero, and for each
- incoming bit, x^32 is added mod p to the register if the bit is a one (where
- x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- x (which is shifting right by one and adding x^32 mod p if the bit shifted
- out is a one). We start with the highest power (least significant bit) of
- q and repeat for all eight bits of q.
-
- The table is simply the CRC of all possible eight bit values. This is all
- the information needed to generate CRC's on data a byte at a time for all
- combinations of CRC register values and incoming bytes.
-*/
-local void make_crc_table()
-{
- uLong c;
- int n, k;
- uLong poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* make exclusive-or pattern from polynomial (0xedb88320L) */
- poly = 0L;
- for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
- poly |= 1L << (31 - p[n]);
-
- for (n = 0; n < 256; n++)
- {
- c = (uLong)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[n] = c;
- }
- crc_table_empty = 0;
-}
-#else
-/* ========================================================================
- * Table of CRC-32's of all single-byte values (made by make_crc_table)
- */
-local const uLongf crc_table[256] = {
- 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
- 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
- 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
- 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
- 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
- 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
- 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
- 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
- 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
- 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
- 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
- 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
- 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
- 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
- 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
- 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
- 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
- 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
- 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
- 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
- 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
- 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
- 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
- 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
- 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
- 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
- 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
- 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
- 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
- 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
- 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
- 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
- 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
- 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
- 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
- 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
- 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
- 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
- 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
- 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
- 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
- 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
- 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
- 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
- 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
- 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
- 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
- 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
- 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
- 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
- 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
- 0x2d02ef8dL
-};
-#endif
-
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
-const uLongf * ZEXPORT get_crc_table()
-{
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty) make_crc_table();
-#endif
- return (const uLongf *)crc_table;
-}
-
-/* ========================================================================= */
-#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
-#define DO2(buf) DO1(buf); DO1(buf);
-#define DO4(buf) DO2(buf); DO2(buf);
-#define DO8(buf) DO4(buf); DO4(buf);
-
-/* ========================================================================= */
-uLong ZEXPORT crc32(crc, buf, len)
- uLong crc;
- const Bytef *buf;
- uInt len;
-{
- if (buf == Z_NULL) return 0L;
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif
- crc = crc ^ 0xffffffffL;
- while (len >= 8)
- {
- DO8(buf);
- len -= 8;
- }
- if (len) do {
- DO1(buf);
- } while (--len);
- return crc ^ 0xffffffffL;
-}
diff --git a/src/utilfuns/zlib/deflate.c b/src/utilfuns/zlib/deflate.c
deleted file mode 100644
index 43ea588..0000000
--- a/src/utilfuns/zlib/deflate.c
+++ /dev/null
@@ -1,1350 +0,0 @@
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process depends on being able to identify portions
- * of the input text which are identical to earlier input (within a
- * sliding window trailing behind the input currently being processed).
- *
- * The most straightforward technique turns out to be the fastest for
- * most input files: try all possible matches and select the longest.
- * The key feature of this algorithm is that insertions into the string
- * dictionary are very simple and thus fast, and deletions are avoided
- * completely. Insertions are performed at each input character, whereas
- * string matches are performed only when the previous match ends. So it
- * is preferable to spend more time in matches to allow very fast string
- * insertions and avoid deletions. The matching algorithm for small
- * strings is inspired from that of Rabin & Karp. A brute force approach
- * is used to find longer strings when a small match has been found.
- * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- * (by Leonid Broukhis).
- * A previous version of this file used a more sophisticated algorithm
- * (by Fiala and Greene) which is guaranteed to run in linear amortized
- * time, but has a larger average cost, uses more memory and is patented.
- * However the F&G algorithm may be faster for some highly redundant
- * files if the parameter max_chain_length (described below) is too large.
- *
- * ACKNOWLEDGEMENTS
- *
- * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- * I found it in 'freeze' written by Leonid Broukhis.
- * Thanks to many people for bug reports and testing.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in ftp://ds.internic.net/rfc/rfc1951.txt
- *
- * A description of the Rabin and Karp algorithm is given in the book
- * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- * Fiala,E.R., and Greene,D.H.
- * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* @(#) $Id: deflate.c 1688 2005-01-01 04:42:26Z scribe $ */
-
-#include "deflate.h"
-
-const char deflate_copyright[] =
- " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- * Function prototypes.
- */
-typedef enum {
- need_more, /* block not completed, need more input or more output */
- block_done, /* block flush performed */
- finish_started, /* finish started, need only more output at next deflate */
- finish_done /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast OF((deflate_state *s, int flush));
-local block_state deflate_slow OF((deflate_state *s, int flush));
-local void lm_init OF((deflate_state *s));
-local void putShortMSB OF((deflate_state *s, uInt b));
-local void flush_pending OF((z_streamp strm));
-local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match OF((deflate_state *s, IPos cur_match));
-#endif
-
-#ifdef DEBUG
-local void check_match OF((deflate_state *s, IPos start, IPos match,
- int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-# define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
- ush good_length; /* reduce lazy search above this match length */
- ush max_lazy; /* do not perform lazy search above this match length */
- ush nice_length; /* quit search above this match length */
- ush max_chain;
- compress_func func;
-} config;
-
-local const config configuration_table[10] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
-/* 2 */ {4, 5, 16, 8, deflate_fast},
-/* 3 */ {4, 6, 32, 32, deflate_fast},
-
-/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
-/* 5 */ {8, 16, 32, 32, deflate_slow},
-/* 6 */ {8, 16, 128, 128, deflate_slow},
-/* 7 */ {8, 32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * If this file is compiled with -DFASTEST, the compression level is forced
- * to 1, and no hash chains are maintained.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#ifdef FASTEST
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#else
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#endif
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
- z_streamp strm;
- int level;
- const char *version;
- int stream_size;
-{
- return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
- /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- version, stream_size)
- z_streamp strm;
- int level;
- int method;
- int windowBits;
- int memLevel;
- int strategy;
- const char *version;
- int stream_size;
-{
- deflate_state *s;
- int noheader = 0;
- static const char* my_version = ZLIB_VERSION;
-
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
- if (version == Z_NULL || version[0] != my_version[0] ||
- stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
- if (strm == Z_NULL) return Z_STREAM_ERROR;
-
- strm->msg = Z_NULL;
- if (strm->zalloc == Z_NULL) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == Z_NULL) strm->zfree = zcfree;
-
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#ifdef FASTEST
- level = 1;
-#endif
-
- if (windowBits < 0) { /* undocumented feature: suppress zlib header */
- noheader = 1;
- windowBits = -windowBits;
- }
- if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
- windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
- return Z_STREAM_ERROR;
- }
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
- if (s == Z_NULL) return Z_MEM_ERROR;
- strm->state = (struct internal_state FAR *)s;
- s->strm = strm;
-
- s->noheader = noheader;
- s->w_bits = windowBits;
- s->w_size = 1 << s->w_bits;
- s->w_mask = s->w_size - 1;
-
- s->hash_bits = memLevel + 7;
- s->hash_size = 1 << s->hash_bits;
- s->hash_mask = s->hash_size - 1;
- s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-
- s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
- if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
- s->pending_buf == Z_NULL) {
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
- deflateEnd (strm);
- return Z_MEM_ERROR;
- }
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
- s->level = level;
- s->strategy = strategy;
- s->method = (Byte)method;
-
- return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
- z_streamp strm;
- const Bytef *dictionary;
- uInt dictLength;
-{
- deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
-
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
-
- s = strm->state;
- strm->adler = adler32(strm->adler, dictionary, dictLength);
-
- if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
-#ifndef USE_DICT_HEAD
- dictionary += dictLength - length; /* use the tail of the dictionary */
-#endif
- }
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
-
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
- }
- if (hash_head) hash_head = 0; /* to make compiler happy */
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
- z_streamp strm;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
-
- strm->total_in = strm->total_out = 0;
- strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
- strm->data_type = Z_UNKNOWN;
-
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-
- if (s->noheader < 0) {
- s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
- }
- s->status = s->noheader ? BUSY_STATE : INIT_STATE;
- strm->adler = 1;
- s->last_flush = Z_NO_FLUSH;
-
- _tr_init(s);
- lm_init(s);
-
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
- z_streamp strm;
- int level;
- int strategy;
-{
- deflate_state *s;
- compress_func func;
- int err = Z_OK;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
-
- if (level == Z_DEFAULT_COMPRESSION) {
- level = 6;
- }
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
- return Z_STREAM_ERROR;
- }
- func = configuration_table[s->level].func;
-
- if (func != configuration_table[level].func && strm->total_in != 0) {
- /* Flush the last buffer: */
- err = deflate(strm, Z_PARTIAL_FLUSH);
- }
- if (s->level != level) {
- s->level = level;
- s->max_lazy_match = configuration_table[level].max_lazy;
- s->good_match = configuration_table[level].good_length;
- s->nice_match = configuration_table[level].nice_length;
- s->max_chain_length = configuration_table[level].max_chain;
- }
- s->strategy = strategy;
- return err;
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
- deflate_state *s;
- uInt b;
-{
- put_byte(s, (Byte)(b >> 8));
- put_byte(s, (Byte)(b & 0xff));
-}
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
- z_streamp strm;
-{
- unsigned len = strm->state->pending;
-
- if (len > strm->avail_out) len = strm->avail_out;
- if (len == 0) return;
-
- zmemcpy(strm->next_out, strm->state->pending_out, len);
- strm->next_out += len;
- strm->state->pending_out += len;
- strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
- }
-}
-
-/* ========================================================================= */
-int ZEXPORT deflate (strm, flush)
- z_streamp strm;
- int flush;
-{
- int old_flush; /* value of flush param for previous deflate call */
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
- return Z_STREAM_ERROR;
- }
- s = strm->state;
-
- if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
- (s->status == FINISH_STATE && flush != Z_FINISH)) {
- ERR_RETURN(strm, Z_STREAM_ERROR);
- }
- if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
- s->strm = strm; /* just in case */
- old_flush = s->last_flush;
- s->last_flush = flush;
-
- /* Write the zlib header */
- if (s->status == INIT_STATE) {
-
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags = (s->level-1) >> 1;
-
- if (level_flags > 3) level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
-
- s->status = BUSY_STATE;
- putShortMSB(s, header);
-
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- strm->adler = 1L;
- }
-
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
- flush_pending(strm);
- if (strm->avail_out == 0) {
- /* Since avail_out is 0, deflate will be called again with
- * more output space, but possibly with both pending and
- * avail_in equal to zero. There won't be anything to do,
- * but this is not an error situation so make sure we
- * return OK instead of BUF_ERROR at next call of deflate:
- */
- s->last_flush = -1;
- return Z_OK;
- }
-
- /* Make sure there is something to do and avoid duplicate consecutive
- * flushes. For repeated and useless calls with Z_FINISH, we keep
- * returning Z_STREAM_END instead of Z_BUFF_ERROR.
- */
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* Start a new block or continue the current one.
- */
- if (strm->avail_in != 0 || s->lookahead != 0 ||
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
- bstate = (*(configuration_table[s->level].func))(s, flush);
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
- }
- if (bstate == need_more || bstate == finish_started) {
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
- }
- return Z_OK;
- /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
- * of deflate should use the same flush parameter to make sure
- * that the flush is complete. So we don't have to output an
- * empty block here, this will be done at next call. This also
- * ensures that for a very small output buffer, we emit at most
- * one empty block.
- */
- }
- if (bstate == block_done) {
- if (flush == Z_PARTIAL_FLUSH) {
- _tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
- _tr_stored_block(s, (char*)0, 0L, 0);
- /* For a full flush, this empty block will be recognized
- * as a special marker by inflate_sync().
- */
- if (flush == Z_FULL_FLUSH) {
- CLEAR_HASH(s); /* forget history */
- }
- }
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
- return Z_OK;
- }
- }
- }
- Assert(strm->avail_out > 0, "bug2");
-
- if (flush != Z_FINISH) return Z_OK;
- if (s->noheader) return Z_STREAM_END;
-
- /* Write the zlib trailer (adler32) */
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- flush_pending(strm);
- /* If avail_out is zero, the application will call deflate again
- * to flush the rest.
- */
- s->noheader = -1; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateEnd (strm)
- z_streamp strm;
-{
- int status;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- status = strm->state->status;
- if (status != INIT_STATE && status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
-
- /* Deallocate in reverse order of allocations: */
- TRY_FREE(strm, strm->state->pending_buf);
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-
- return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- * To simplify the source, this is not supported for 16-bit MSDOS (which
- * doesn't have enough memory anyway to duplicate compression states).
- */
-int ZEXPORT deflateCopy (dest, source)
- z_streamp dest;
- z_streamp source;
-{
-#ifdef MAXSEG_64K
- return Z_STREAM_ERROR;
-#else
- deflate_state *ds;
- deflate_state *ss;
- ushf *overlay;
-
-
- if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
- return Z_STREAM_ERROR;
- }
-
- ss = source->state;
-
- *dest = *source;
-
- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
- if (ds == Z_NULL) return Z_MEM_ERROR;
- dest->state = (struct internal_state FAR *) ds;
- *ds = *ss;
- ds->strm = dest;
-
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
- ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
- ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
-
- if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
- ds->pending_buf == Z_NULL) {
- deflateEnd (dest);
- return Z_MEM_ERROR;
- }
- /* following zmemcpy do not work for 16-bit MSDOS */
- zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
- zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
- ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
- ds->l_desc.dyn_tree = ds->dyn_ltree;
- ds->d_desc.dyn_tree = ds->dyn_dtree;
- ds->bl_desc.dyn_tree = ds->bl_tree;
-
- return Z_OK;
-#endif
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read. All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
- z_streamp strm;
- Bytef *buf;
- unsigned size;
-{
- unsigned len = strm->avail_in;
-
- if (len > size) len = size;
- if (len == 0) return 0;
-
- strm->avail_in -= len;
-
- if (!strm->state->noheader) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
- }
- zmemcpy(buf, strm->next_in, len);
- strm->next_in += len;
- strm->total_in += len;
-
- return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
- deflate_state *s;
-{
- s->window_size = (ulg)2L*s->w_size;
-
- CLEAR_HASH(s);
-
- /* Set the default configuration parameters:
- */
- s->max_lazy_match = configuration_table[s->level].max_lazy;
- s->good_match = configuration_table[s->level].good_length;
- s->nice_match = configuration_table[s->level].nice_length;
- s->max_chain_length = configuration_table[s->level].max_chain;
-
- s->strstart = 0;
- s->block_start = 0L;
- s->lookahead = 0;
- s->match_length = s->prev_length = MIN_MATCH-1;
- s->match_available = 0;
- s->ins_h = 0;
-#ifdef ASMV
- match_init(); /* initialize the asm code */
-#endif
-}
-
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-#ifndef FASTEST
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2:
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-
-#else /* FASTEST */
-/* ---------------------------------------------------------------------------
- * Optimized version for level == 1 only
- */
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- Assert(cur_match < s->strstart, "no future");
-
- match = s->window + cur_match;
-
- /* Return failure if the match length is less than 2:
- */
- if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match += 2;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
-
- if (len < MIN_MATCH) return MIN_MATCH - 1;
-
- s->match_start = cur_match;
- return len <= s->lookahead ? len : s->lookahead;
-}
-#endif /* FASTEST */
-#endif /* ASMV */
-
-#ifdef DEBUG
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
- deflate_state *s;
- IPos start, match;
- int length;
-{
- /* check that the match is indeed a match */
- if (zmemcmp(s->window + match,
- s->window + start, length) != EQUAL) {
- fprintf(stderr, " start %u, match %u, length %d\n",
- start, match, length);
- do {
- fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
- } while (--length != 0);
- z_error("invalid match");
- }
- if (z_verbose > 1) {
- fprintf(stderr,"\\[%d,%d]", start-match, length);
- do { putc(s->window[start++], stderr); } while (--length != 0);
- }
-}
-#else
-# define check_match(s, start, match, length)
-#endif
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- * At least one byte has been read, or avail_in == 0; reads are
- * performed for at least two bytes (required for the zip translate_eol
- * option -- not supported here).
- */
-local void fill_window(s)
- deflate_state *s;
-{
- register unsigned n, m;
- register Posf *p;
- unsigned more; /* Amount of free space at the end of the window. */
- uInt wsize = s->w_size;
-
- do {
- more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
- /* Deal with !@#$% 64K limit: */
- if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
- more = wsize;
-
- } else if (more == (unsigned)(-1)) {
- /* Very unlikely, but possible on 16 bit machine if strstart == 0
- * and lookahead == 1 (input done one byte at time)
- */
- more--;
-
- /* If the window is almost full and there is insufficient lookahead,
- * move the upper half to the lower one to make room in the upper half.
- */
- } else if (s->strstart >= wsize+MAX_DIST(s)) {
-
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
- s->match_start -= wsize;
- s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
- s->block_start -= (long) wsize;
-
- /* Slide the hash table (could be avoided with 32 bit values
- at the expense of memory usage). We slide even when level == 0
- to keep the hash table consistent if we switch back to level > 0
- later. (Using level 0 permanently is not an optimal usage of
- zlib, so we don't care about this pathological case.)
- */
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
-#ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
-#endif
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
-
- /* If there was no sliding:
- * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
- * more == window_size - lookahead - strstart
- * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
- * => more >= window_size - 2*WSIZE + 2
- * In the BIG_MEM or MMAP case (not yet supported),
- * window_size == input_size + MIN_LOOKAHEAD &&
- * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
- * Otherwise, window_size == 2*WSIZE so more >= 2.
- * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
- */
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- }
- /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
- * but this is not important since only literal bytes will be emitted.
- */
-
- } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, eof) { \
- _tr_flush_block(s, (s->block_start >= 0L ? \
- (charf *)&s->window[(unsigned)s->block_start] : \
- (charf *)Z_NULL), \
- (ulg)((long)s->strstart - s->block_start), \
- (eof)); \
- s->block_start = s->strstart; \
- flush_pending(s->strm); \
- Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
- deflate_state *s;
- int flush;
-{
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
- */
- ulg max_block_size = 0xffff;
- ulg max_start;
-
- if (max_block_size > s->pending_buf_size - 5) {
- max_block_size = s->pending_buf_size - 5;
- }
-
- /* Copy as much as possible from input to output: */
- for (;;) {
- /* Fill the window as much as possible: */
- if (s->lookahead <= 1) {
-
- Assert(s->strstart < s->w_size+MAX_DIST(s) ||
- s->block_start >= (long)s->w_size, "slide too late");
-
- fill_window(s);
- if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
- if (s->lookahead == 0) break; /* flush the current block */
- }
- Assert(s->block_start >= 0L, "block gone");
-
- s->strstart += s->lookahead;
- s->lookahead = 0;
-
- /* Emit a stored block if pending_buf will be full: */
- max_start = s->block_start + max_block_size;
- if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
- /* strstart == 0 is possible when wraparound on 16-bit machine */
- s->lookahead = (uInt)(s->strstart - max_start);
- s->strstart = (uInt)max_start;
- FLUSH_BLOCK(s, 0);
- }
- /* Flush if we may have to slide, otherwise block_start may become
- * negative and the data will be gone:
- */
- if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
- FLUSH_BLOCK(s, 0);
- }
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of the hash chain */
- int bflush; /* set if current block must be flushed */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- * At this point we have always match_length < MIN_MATCH
- */
- if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY) {
- s->match_length = longest_match (s, hash_head);
- }
- /* longest_match() sets match_start */
- }
- if (s->match_length >= MIN_MATCH) {
- check_match(s, s->strstart, s->match_start, s->match_length);
-
- _tr_tally_dist(s, s->strstart - s->match_start,
- s->match_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->match_length;
-
- /* Insert new strings in the hash table only if the match length
- * is not too large. This saves time but degrades compression.
- */
-#ifndef FASTEST
- if (s->match_length <= s->max_insert_length &&
- s->lookahead >= MIN_MATCH) {
- s->match_length--; /* string at strstart already in hash table */
- do {
- s->strstart++;
- INSERT_STRING(s, s->strstart, hash_head);
- /* strstart never exceeds WSIZE-MAX_MATCH, so there are
- * always MIN_MATCH bytes ahead.
- */
- } while (--s->match_length != 0);
- s->strstart++;
- } else
-#endif
- {
- s->strstart += s->match_length;
- s->match_length = 0;
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
- * matter since it will be recomputed at next deflate call.
- */
- }
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-
- /* Process the input block. */
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- */
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY) {
- s->match_length = longest_match (s, hash_head);
- }
- /* longest_match() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
- (s->match_length == MIN_MATCH &&
- s->strstart - s->match_start > TOO_FAR))) {
-
- /* If prev_match is also MIN_MATCH, match_start is garbage
- * but we will ignore the current match anyway.
- */
- s->match_length = MIN_MATCH-1;
- }
- }
- /* If there was a match at the previous step and the current
- * match is not better, output the previous match:
- */
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
- check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
- _tr_tally_dist(s, s->strstart -1 - s->prev_match,
- s->prev_length - MIN_MATCH, bflush);
-
- /* Insert in hash table all strings up to the end of the match.
- * strstart-1 and strstart are already inserted. If there is not
- * enough lookahead, the last two strings are not inserted in
- * the hash table.
- */
- s->lookahead -= s->prev_length-1;
- s->prev_length -= 2;
- do {
- if (++s->strstart <= max_insert) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
- } while (--s->prev_length != 0);
- s->match_available = 0;
- s->match_length = MIN_MATCH-1;
- s->strstart++;
-
- if (bflush) FLUSH_BLOCK(s, 0);
-
- } else if (s->match_available) {
- /* If there was no match at the previous position, output a
- * single literal. If there was a match but the current match
- * is longer, truncate the previous match to a single literal.
- */
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- if (bflush) {
- FLUSH_BLOCK_ONLY(s, 0);
- }
- s->strstart++;
- s->lookahead--;
- if (s->strm->avail_out == 0) return need_more;
- } else {
- /* There is no previous match to compare with, wait for
- * the next step to decide.
- */
- s->match_available = 1;
- s->strstart++;
- s->lookahead--;
- }
- }
- Assert (flush != Z_NO_FLUSH, "no flush?");
- if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- s->match_available = 0;
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
diff --git a/src/utilfuns/zlib/deflate.h b/src/utilfuns/zlib/deflate.h
deleted file mode 100644
index 965e0a3..0000000
--- a/src/utilfuns/zlib/deflate.h
+++ /dev/null
@@ -1,318 +0,0 @@
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-2002 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id: deflate.h 1688 2005-01-01 04:42:26Z scribe $ */
-
-#ifndef _DEFLATE_H
-#define _DEFLATE_H
-
-#include "zutil.h"
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS 256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES 30
-/* number of distance codes */
-
-#define BL_CODES 19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE 42
-#define BUSY_STATE 113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
- union {
- ush freq; /* frequency count */
- ush code; /* bit string */
- } fc;
- union {
- ush dad; /* father node in Huffman tree */
- ush len; /* length of bit string */
- } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad dl.dad
-#define Len dl.len
-
-typedef struct static_tree_desc_s static_tree_desc;
-
-typedef struct tree_desc_s {
- ct_data *dyn_tree; /* the dynamic tree */
- int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
- Bytef *pending_buf; /* output still pending */
- ulg pending_buf_size; /* size of pending_buf */
- Bytef *pending_out; /* next pending byte to output to the stream */
- int pending; /* nb of bytes in the pending buffer */
- int noheader; /* suppress zlib header and adler32 */
- Byte data_type; /* UNKNOWN, BINARY or ASCII */
- Byte method; /* STORED (for zip only) or DEFLATED */
- int last_flush; /* value of flush param for previous deflate call */
-
- /* used by deflate.c: */
-
- uInt w_size; /* LZ77 window size (32K by default) */
- uInt w_bits; /* log2(w_size) (8..16) */
- uInt w_mask; /* w_size - 1 */
-
- Bytef *window;
- /* Sliding window. Input bytes are read into the second half of the window,
- * and move to the first half later to keep a dictionary of at least wSize
- * bytes. With this organization, matches are limited to a distance of
- * wSize-MAX_MATCH bytes, but this ensures that IO is always
- * performed with a length multiple of the block size. Also, it limits
- * the window size to 64K, which is quite useful on MSDOS.
- * To do: use the user input buffer as sliding window.
- */
-
- ulg window_size;
- /* Actual size of window: 2*wSize, except when the user input buffer
- * is directly used as sliding window.
- */
-
- Posf *prev;
- /* Link to older string with same hash index. To limit the size of this
- * array to 64K, this link is maintained only for the last 32K strings.
- * An index in this array is thus a window index modulo 32K.
- */
-
- Posf *head; /* Heads of the hash chains or NIL. */
-
- uInt ins_h; /* hash index of string to be inserted */
- uInt hash_size; /* number of elements in hash table */
- uInt hash_bits; /* log2(hash_size) */
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
- /* Number of bits by which ins_h must be shifted at each input
- * step. It must be such that after MIN_MATCH steps, the oldest
- * byte no longer takes part in the hash key, that is:
- * hash_shift * MIN_MATCH >= hash_bits
- */
-
- long block_start;
- /* Window position at the beginning of the current output block. Gets
- * negative when the window is moved backwards.
- */
-
- uInt match_length; /* length of best match */
- IPos prev_match; /* previous match */
- int match_available; /* set if previous match exists */
- uInt strstart; /* start of string to insert */
- uInt match_start; /* start of matching string */
- uInt lookahead; /* number of valid bytes ahead in window */
-
- uInt prev_length;
- /* Length of the best match at previous step. Matches not greater than this
- * are discarded. This is used in the lazy match evaluation.
- */
-
- uInt max_chain_length;
- /* To speed up deflation, hash chains are never searched beyond this
- * length. A higher limit improves compression ratio but degrades the
- * speed.
- */
-
- uInt max_lazy_match;
- /* Attempt to find a better match only when the current match is strictly
- * smaller than this value. This mechanism is used only for compression
- * levels >= 4.
- */
-# define max_insert_length max_lazy_match
- /* Insert new strings in the hash table only if the match length is not
- * greater than this length. This saves time but degrades compression.
- * max_insert_length is used only for compression levels <= 3.
- */
-
- int level; /* compression level (1..9) */
- int strategy; /* favor or force Huffman coding*/
-
- uInt good_match;
- /* Use a faster search when the previous match is longer than this */
-
- int nice_match; /* Stop searching when current match exceeds this */
-
- /* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
- struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
- struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
- struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-
- struct tree_desc_s l_desc; /* desc. for literal tree */
- struct tree_desc_s d_desc; /* desc. for distance tree */
- struct tree_desc_s bl_desc; /* desc. for bit length tree */
-
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
- int heap_len; /* number of elements in the heap */
- int heap_max; /* element of largest frequency */
- /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
- * The same heap array is used to build all trees.
- */
-
- uch depth[2*L_CODES+1];
- /* Depth of each subtree used as tie breaker for trees of equal frequency
- */
-
- uchf *l_buf; /* buffer for literals or lengths */
-
- uInt lit_bufsize;
- /* Size of match buffer for literals/lengths. There are 4 reasons for
- * limiting lit_bufsize to 64K:
- * - frequencies can be kept in 16 bit counters
- * - if compression is not successful for the first block, all input
- * data is still in the window so we can still emit a stored block even
- * when input comes from standard input. (This can also be done for
- * all blocks if lit_bufsize is not greater than 32K.)
- * - if compression is not successful for a file smaller than 64K, we can
- * even emit a stored file instead of a stored block (saving 5 bytes).
- * This is applicable only for zip (not gzip or zlib).
- * - creating new Huffman trees less frequently may not provide fast
- * adaptation to changes in the input data statistics. (Take for
- * example a binary file with poorly compressible code followed by
- * a highly compressible string table.) Smaller buffer sizes give
- * fast adaptation but have of course the overhead of transmitting
- * trees more frequently.
- * - I can't count above 4
- */
-
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
- * the same number of elements. To use different lengths, an extra flag
- * array would be necessary.
- */
-
- ulg opt_len; /* bit length of current block with optimal trees */
- ulg static_len; /* bit length of current block with static trees */
- uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
-
-#ifdef DEBUG
- ulg compressed_len; /* total bit length of compressed file mod 2^32 */
- ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-#endif
-
- ush bi_buf;
- /* Output buffer. bits are inserted starting at the bottom (least
- * significant bits).
- */
- int bi_valid;
- /* Number of valid bits in bi_buf. All bits above the last valid bit
- * are always zero.
- */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
- /* in trees.c */
-void _tr_init OF((deflate_state *s));
-int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-void _tr_align OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-
-#define d_code(dist) \
- ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
-#ifndef DEBUG
-/* Inline versions of _tr_tally for speed: */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
-#else
- extern const uch _length_code[];
- extern const uch _dist_code[];
-#endif
-
-# define _tr_tally_lit(s, c, flush) \
- { uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
- s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-# define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
- dist--; \
- s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
- s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-#else
-# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-# define _tr_tally_dist(s, distance, length, flush) \
- flush = _tr_tally(s, distance, length)
-#endif
-
-#endif
diff --git a/src/utilfuns/zlib/gzio.c b/src/utilfuns/zlib/gzio.c
deleted file mode 100644
index 612c154..0000000
--- a/src/utilfuns/zlib/gzio.c
+++ /dev/null
@@ -1,875 +0,0 @@
-/* gzio.c -- IO on .gz files
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Compile this file with -DNO_DEFLATE to avoid the compression code.
- */
-
-/* @(#) $Id: gzio.c 1688 2005-01-01 04:42:26Z scribe $ */
-
-#include <stdio.h>
-
-#include "zutil.h"
-
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-#ifndef Z_BUFSIZE
-# ifdef MAXSEG_64K
-# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
-# else
-# define Z_BUFSIZE 16384
-# endif
-#endif
-#ifndef Z_PRINTF_BUFSIZE
-# define Z_PRINTF_BUFSIZE 4096
-#endif
-
-#define ALLOC(size) malloc(size)
-#define TRYFREE(p) {if (p) free(p);}
-
-static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
-typedef struct gz_stream {
- z_stream stream;
- int z_err; /* error code for last stream operation */
- int z_eof; /* set if end of input file */
- FILE *file; /* .gz file */
- Byte *inbuf; /* input buffer */
- Byte *outbuf; /* output buffer */
- uLong crc; /* crc32 of uncompressed data */
- char *msg; /* error message */
- char *path; /* path name for debugging only */
- int transparent; /* 1 if input file is not a .gz file */
- char mode; /* 'w' or 'r' */
- long startpos; /* start of compressed data in file (header skipped) */
-} gz_stream;
-
-
-local gzFile gz_open OF((const char *path, const char *mode, int fd));
-local int do_flush OF((gzFile file, int flush));
-local int get_byte OF((gz_stream *s));
-local void check_header OF((gz_stream *s));
-local int destroy OF((gz_stream *s));
-local void putLong OF((FILE *file, uLong x));
-local uLong getLong OF((gz_stream *s));
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb"). The file is given either by file descriptor
- or path name (if fd == -1).
- gz_open return NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR).
-*/
-local gzFile gz_open (path, mode, fd)
- const char *path;
- const char *mode;
- int fd;
-{
- int err;
- int level = Z_DEFAULT_COMPRESSION; /* compression level */
- int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
- char *p = (char*)mode;
- gz_stream *s;
- char fmode[80]; /* copy of mode, without the compression level */
- char *m = fmode;
-
- if (!path || !mode) return Z_NULL;
-
- s = (gz_stream *)ALLOC(sizeof(gz_stream));
- if (!s) return Z_NULL;
-
- s->stream.zalloc = (alloc_func)0;
- s->stream.zfree = (free_func)0;
- s->stream.opaque = (voidpf)0;
- s->stream.next_in = s->inbuf = Z_NULL;
- s->stream.next_out = s->outbuf = Z_NULL;
- s->stream.avail_in = s->stream.avail_out = 0;
- s->file = NULL;
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->crc = crc32(0L, Z_NULL, 0);
- s->msg = NULL;
- s->transparent = 0;
-
- s->path = (char*)ALLOC(strlen(path)+1);
- if (s->path == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- strcpy(s->path, path); /* do this early for debugging */
-
- s->mode = '\0';
- do {
- if (*p == 'r') s->mode = 'r';
- if (*p == 'w' || *p == 'a') s->mode = 'w';
- if (*p >= '0' && *p <= '9') {
- level = *p - '0';
- } else if (*p == 'f') {
- strategy = Z_FILTERED;
- } else if (*p == 'h') {
- strategy = Z_HUFFMAN_ONLY;
- } else {
- *m++ = *p; /* copy the mode */
- }
- } while (*p++ && m != fmode + sizeof(fmode));
- if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- err = Z_STREAM_ERROR;
-#else
- err = deflateInit2(&(s->stream), level,
- Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
- /* windowBits is passed < 0 to suppress zlib header */
-
- s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
-#endif
- if (err != Z_OK || s->outbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- } else {
- s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
-
- err = inflateInit2(&(s->stream), -MAX_WBITS);
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
- * present after the compressed stream.
- */
- if (err != Z_OK || s->inbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- }
- s->stream.avail_out = Z_BUFSIZE;
-
- errno = 0;
- s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
-
- if (s->file == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- if (s->mode == 'w') {
- /* Write a very simple .gz header:
- */
- fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
- Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
- s->startpos = 10L;
- /* We use 10L instead of ftell(s->file) to because ftell causes an
- * fflush on some systems. This version of the library doesn't use
- * startpos anyway in write mode, so this initialization is not
- * necessary.
- */
- } else {
- check_header(s); /* skip the .gz header */
- s->startpos = (ftell(s->file) - s->stream.avail_in);
- }
-
- return (gzFile)s;
-}
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing.
-*/
-gzFile ZEXPORT gzopen (path, mode)
- const char *path;
- const char *mode;
-{
- return gz_open (path, mode, -1);
-}
-
-/* ===========================================================================
- Associate a gzFile with the file descriptor fd. fd is not dup'ed here
- to mimic the behavio(u)r of fdopen.
-*/
-gzFile ZEXPORT gzdopen (fd, mode)
- int fd;
- const char *mode;
-{
- char name[20];
-
- if (fd < 0) return (gzFile)Z_NULL;
- sprintf(name, "<fd:%d>", fd); /* for debugging */
-
- return gz_open (name, mode, fd);
-}
-
-/* ===========================================================================
- * Update the compression level and strategy
- */
-int ZEXPORT gzsetparams (file, level, strategy)
- gzFile file;
- int level;
- int strategy;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- /* Make room to allow flushing */
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
-
- return deflateParams (&(s->stream), level, strategy);
-}
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-local int get_byte(s)
- gz_stream *s;
-{
- if (s->z_eof) return EOF;
- if (s->stream.avail_in == 0) {
- errno = 0;
- s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) s->z_err = Z_ERRNO;
- return EOF;
- }
- s->stream.next_in = s->inbuf;
- }
- s->stream.avail_in--;
- return *(s->stream.next_in)++;
-}
-
-/* ===========================================================================
- Check the gzip header of a gz_stream opened for reading. Set the stream
- mode to transparent if the gzip magic header is not present; set s->err
- to Z_DATA_ERROR if the magic header is present but the rest of the header
- is incorrect.
- IN assertion: the stream s has already been created sucessfully;
- s->stream.avail_in is zero for the first time, but may be non-zero
- for concatenated .gz files.
-*/
-local void check_header(s)
- gz_stream *s;
-{
- int method; /* method byte */
- int flags; /* flags byte */
- uInt len;
- int c;
-
- /* Check the gzip magic header */
- for (len = 0; len < 2; len++) {
- c = get_byte(s);
- if (c != gz_magic[len]) {
- if (len != 0) s->stream.avail_in++, s->stream.next_in--;
- if (c != EOF) {
- s->stream.avail_in++, s->stream.next_in--;
- s->transparent = 1;
- }
- s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
- return;
- }
- }
- method = get_byte(s);
- flags = get_byte(s);
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- s->z_err = Z_DATA_ERROR;
- return;
- }
-
- /* Discard time, xflags and OS code: */
- for (len = 0; len < 6; len++) (void)get_byte(s);
-
- if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
- len = (uInt)get_byte(s);
- len += ((uInt)get_byte(s))<<8;
- /* len is garbage if EOF but the loop below will quit anyway */
- while (len-- != 0 && get_byte(s) != EOF) ;
- }
- if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
- for (len = 0; len < 2; len++) (void)get_byte(s);
- }
- s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
-}
-
- /* ===========================================================================
- * Cleanup then free the given gz_stream. Return a zlib error code.
- Try freeing in the reverse order of allocations.
- */
-local int destroy (s)
- gz_stream *s;
-{
- int err = Z_OK;
-
- if (!s) return Z_STREAM_ERROR;
-
- TRYFREE(s->msg);
-
- if (s->stream.state != NULL) {
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- err = Z_STREAM_ERROR;
-#else
- err = deflateEnd(&(s->stream));
-#endif
- } else if (s->mode == 'r') {
- err = inflateEnd(&(s->stream));
- }
- }
- if (s->file != NULL && fclose(s->file)) {
-#ifdef ESPIPE
- if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
-#endif
- err = Z_ERRNO;
- }
- if (s->z_err < 0) err = s->z_err;
-
- TRYFREE(s->inbuf);
- TRYFREE(s->outbuf);
- TRYFREE(s->path);
- TRYFREE(s);
- return err;
-}
-
-/* ===========================================================================
- Reads the given number of uncompressed bytes from the compressed file.
- gzread returns the number of bytes actually read (0 for end of file).
-*/
-int ZEXPORT gzread (file, buf, len)
- gzFile file;
- voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
- Bytef *start = (Bytef*)buf; /* starting point for crc computation */
- Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
-
- if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
-
- if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
- if (s->z_err == Z_STREAM_END) return 0; /* EOF */
-
- next_out = (Byte*)buf;
- s->stream.next_out = (Bytef*)buf;
- s->stream.avail_out = len;
-
- while (s->stream.avail_out != 0) {
-
- if (s->transparent) {
- /* Copy first the lookahead bytes: */
- uInt n = s->stream.avail_in;
- if (n > s->stream.avail_out) n = s->stream.avail_out;
- if (n > 0) {
- zmemcpy(s->stream.next_out, s->stream.next_in, n);
- next_out += n;
- s->stream.next_out = next_out;
- s->stream.next_in += n;
- s->stream.avail_out -= n;
- s->stream.avail_in -= n;
- }
- if (s->stream.avail_out > 0) {
- s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
- s->file);
- }
- len -= s->stream.avail_out;
- s->stream.total_in += (uLong)len;
- s->stream.total_out += (uLong)len;
- if (len == 0) s->z_eof = 1;
- return (int)len;
- }
- if (s->stream.avail_in == 0 && !s->z_eof) {
-
- errno = 0;
- s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) {
- s->z_err = Z_ERRNO;
- break;
- }
- }
- s->stream.next_in = s->inbuf;
- }
- s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
-
- if (s->z_err == Z_STREAM_END) {
- /* Check CRC and original size */
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
- start = s->stream.next_out;
-
- if (getLong(s) != s->crc) {
- s->z_err = Z_DATA_ERROR;
- } else {
- (void)getLong(s);
- /* The uncompressed length returned by above getlong() may
- * be different from s->stream.total_out) in case of
- * concatenated .gz files. Check for such files:
- */
- check_header(s);
- if (s->z_err == Z_OK) {
- uLong total_in = s->stream.total_in;
- uLong total_out = s->stream.total_out;
-
- inflateReset(&(s->stream));
- s->stream.total_in = total_in;
- s->stream.total_out = total_out;
- s->crc = crc32(0L, Z_NULL, 0);
- }
- }
- }
- if (s->z_err != Z_OK || s->z_eof) break;
- }
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
-
- return (int)(len - s->stream.avail_out);
-}
-
-
-/* ===========================================================================
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-int ZEXPORT gzgetc(file)
- gzFile file;
-{
- unsigned char c;
-
- return gzread(file, &c, 1) == 1 ? c : -1;
-}
-
-
-/* ===========================================================================
- Reads bytes from the compressed file until len-1 characters are
- read, or a newline character is read and transferred to buf, or an
- end-of-file condition is encountered. The string is then terminated
- with a null character.
- gzgets returns buf, or Z_NULL in case of error.
-
- The current implementation is not optimized at all.
-*/
-char * ZEXPORT gzgets(file, buf, len)
- gzFile file;
- char *buf;
- int len;
-{
- char *b = buf;
- if (buf == Z_NULL || len <= 0) return Z_NULL;
-
- while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
- *buf = '\0';
- return b == buf && len > 0 ? Z_NULL : b;
-}
-
-
-#ifndef NO_DEFLATE
-/* ===========================================================================
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of bytes actually written (0 in case of error).
-*/
-int ZEXPORT gzwrite (file, buf, len)
- gzFile file;
- const voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.next_in = (Bytef*)buf;
- s->stream.avail_in = len;
-
- while (s->stream.avail_in != 0) {
-
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- break;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
- s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
- if (s->z_err != Z_OK) break;
- }
- s->crc = crc32(s->crc, (const Bytef *)buf, len);
-
- return (int)(len - s->stream.avail_in);
-}
-
-/* ===========================================================================
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error).
-*/
-#ifdef STDC
-#include <stdarg.h>
-
-int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
-{
- char buf[Z_PRINTF_BUFSIZE];
- va_list va;
- int len;
-
- va_start(va, format);
-#ifdef HAS_vsnprintf
- (void)vsnprintf(buf, sizeof(buf), format, va);
-#else
- (void)vsprintf(buf, format, va);
-#endif
- va_end(va);
- len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
- if (len <= 0) return 0;
-
- return gzwrite(file, buf, (unsigned)len);
-}
-#else /* not ANSI C */
-
-int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
- gzFile file;
- const char *format;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
-{
- char buf[Z_PRINTF_BUFSIZE];
- int len;
-
-#ifdef HAS_snprintf
- snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-#else
- sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-#endif
- len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
- if (len <= 0) return 0;
-
- return gzwrite(file, buf, len);
-}
-#endif
-
-/* ===========================================================================
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-int ZEXPORT gzputc(file, c)
- gzFile file;
- int c;
-{
- unsigned char cc = (unsigned char) c; /* required for big endian systems */
-
- return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
-}
-
-
-/* ===========================================================================
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-int ZEXPORT gzputs(file, s)
- gzFile file;
- const char *s;
-{
- return gzwrite(file, (char*)s, (unsigned)strlen(s));
-}
-
-
-/* ===========================================================================
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function.
-*/
-local int do_flush (file, flush)
- gzFile file;
- int flush;
-{
- uInt len;
- int done = 0;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.avail_in = 0; /* should be zero already anyway */
-
- for (;;) {
- len = Z_BUFSIZE - s->stream.avail_out;
-
- if (len != 0) {
- if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
- s->z_err = Z_ERRNO;
- return Z_ERRNO;
- }
- s->stream.next_out = s->outbuf;
- s->stream.avail_out = Z_BUFSIZE;
- }
- if (done) break;
- s->z_err = deflate(&(s->stream), flush);
-
- /* Ignore the second of two consecutive flushes: */
- if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
-
- /* deflate has finished flushing only when it hasn't used up
- * all the available space in the output buffer:
- */
- done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
-
- if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
- }
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-
-int ZEXPORT gzflush (file, flush)
- gzFile file;
- int flush;
-{
- gz_stream *s = (gz_stream*)file;
- int err = do_flush (file, flush);
-
- if (err) return err;
- fflush(s->file);
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-#endif /* NO_DEFLATE */
-
-/* ===========================================================================
- Sets the starting position for the next gzread or gzwrite on the given
- compressed file. The offset represents a number of bytes in the
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error.
- SEEK_END is not implemented, returns error.
- In this version of the library, gzseek can be extremely slow.
-*/
-z_off_t ZEXPORT gzseek (file, offset, whence)
- gzFile file;
- z_off_t offset;
- int whence;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || whence == SEEK_END ||
- s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
- return -1L;
- }
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- return -1L;
-#else
- if (whence == SEEK_SET) {
- offset -= s->stream.total_in;
- }
- if (offset < 0) return -1L;
-
- /* At this point, offset is the number of zero bytes to write. */
- if (s->inbuf == Z_NULL) {
- s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
- zmemzero(s->inbuf, Z_BUFSIZE);
- }
- while (offset > 0) {
- uInt size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (uInt)offset;
-
- size = gzwrite(file, s->inbuf, size);
- if (size == 0) return -1L;
-
- offset -= size;
- }
- return (z_off_t)s->stream.total_in;
-#endif
- }
- /* Rest of function is for reading only */
-
- /* compute absolute position */
- if (whence == SEEK_CUR) {
- offset += s->stream.total_out;
- }
- if (offset < 0) return -1L;
-
- if (s->transparent) {
- /* map to fseek */
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
-
- s->stream.total_in = s->stream.total_out = (uLong)offset;
- return offset;
- }
-
- /* For a negative seek, rewind and use positive seek */
- if ((uLong)offset >= s->stream.total_out) {
- offset -= s->stream.total_out;
- } else if (gzrewind(file) < 0) {
- return -1L;
- }
- /* offset is now the number of bytes to skip. */
-
- if (offset != 0 && s->outbuf == Z_NULL) {
- s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
- }
- while (offset > 0) {
- int size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (int)offset;
-
- size = gzread(file, s->outbuf, (uInt)size);
- if (size <= 0) return -1L;
- offset -= size;
- }
- return (z_off_t)s->stream.total_out;
-}
-
-/* ===========================================================================
- Rewinds input file.
-*/
-int ZEXPORT gzrewind (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return -1;
-
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- s->crc = crc32(0L, Z_NULL, 0);
-
- if (s->startpos == 0) { /* not a compressed file */
- rewind(s->file);
- return 0;
- }
-
- (void) inflateReset(&s->stream);
- return fseek(s->file, s->startpos, SEEK_SET);
-}
-
-/* ===========================================================================
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-*/
-z_off_t ZEXPORT gztell (file)
- gzFile file;
-{
- return gzseek(file, 0L, SEEK_CUR);
-}
-
-/* ===========================================================================
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-int ZEXPORT gzeof (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
-}
-
-/* ===========================================================================
- Outputs a long in LSB order to the given file
-*/
-local void putLong (file, x)
- FILE *file;
- uLong x;
-{
- int n;
- for (n = 0; n < 4; n++) {
- fputc((int)(x & 0xff), file);
- x >>= 8;
- }
-}
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets z_err in case
- of error.
-*/
-local uLong getLong (s)
- gz_stream *s;
-{
- uLong x = (uLong)get_byte(s);
- int c;
-
- x += ((uLong)get_byte(s))<<8;
- x += ((uLong)get_byte(s))<<16;
- c = get_byte(s);
- if (c == EOF) s->z_err = Z_DATA_ERROR;
- x += ((uLong)c)<<24;
- return x;
-}
-
-/* ===========================================================================
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state.
-*/
-int ZEXPORT gzclose (file)
- gzFile file;
-{
- int err;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return Z_STREAM_ERROR;
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- return Z_STREAM_ERROR;
-#else
- err = do_flush (file, Z_FINISH);
- if (err != Z_OK) return destroy((gz_stream*)file);
-
- putLong (s->file, s->crc);
- putLong (s->file, s->stream.total_in);
-#endif
- }
- return destroy((gz_stream*)file);
-}
-
-/* ===========================================================================
- Returns the error message for the last error which occured on the
- given compressed file. errnum is set to zlib error number. If an
- error occured in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-const char* ZEXPORT gzerror (file, errnum)
- gzFile file;
- int *errnum;
-{
- char *m;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) {
- *errnum = Z_STREAM_ERROR;
- return (const char*)ERR_MSG(Z_STREAM_ERROR);
- }
- *errnum = s->z_err;
- if (*errnum == Z_OK) return (const char*)"";
-
- m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
-
- if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
-
- TRYFREE(s->msg);
- s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
- strcpy(s->msg, s->path);
- strcat(s->msg, ": ");
- strcat(s->msg, m);
- return (const char*)s->msg;
-}
diff --git a/src/utilfuns/zlib/infblock.c b/src/utilfuns/zlib/infblock.c
deleted file mode 100644
index dd7a6d4..0000000
--- a/src/utilfuns/zlib/infblock.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/* infblock.c -- interpret and process block types to last block
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-#include "inftrees.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* Table for deflate from PKZIP's appnote.txt. */
-local const uInt border[] = { /* Order of the bit length code lengths */
- 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-/*
- Notes beyond the 1.93a appnote.txt:
-
- 1. Distance pointers never point before the beginning of the output
- stream.
- 2. Distance pointers can point back across blocks, up to 32k away.
- 3. There is an implied maximum of 7 bits for the bit length table and
- 15 bits for the actual data.
- 4. If only one code exists, then it is encoded using one bit. (Zero
- would be more efficient, but perhaps a little confusing.) If two
- codes exist, they are coded using one bit each (0 and 1).
- 5. There is no way of sending zero distance codes--a dummy must be
- sent if there are none. (History: a pre 2.0 version of PKZIP would
- store blocks with no distance codes, but this was discovered to be
- too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
- zero distance codes, which is sent as one code of zero bits in
- length.
- 6. There are up to 286 literal/length codes. Code 256 represents the
- end-of-block. Note however that the static length tree defines
- 288 codes just to fill out the Huffman codes. Codes 286 and 287
- cannot be used though, since there is no length base or extra bits
- defined for them. Similarily, there are up to 30 distance codes.
- However, static trees define 32 codes (all 5 bits) to fill out the
- Huffman codes, but the last two had better not show up in the data.
- 7. Unzip can check dynamic Huffman blocks for complete code sets.
- The exception is that a single code would not be complete (see #4).
- 8. The five bits following the block type is really the number of
- literal codes sent minus 257.
- 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
- (1+6+6). Therefore, to output three times the length, you output
- three codes (1+1+1), whereas to output four times the same length,
- you only need two codes (1+3). Hmm.
- 10. In the tree reconstruction algorithm, Code = Code + Increment
- only if BitLength(i) is not zero. (Pretty obvious.)
- 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
- 12. Note: length code 284 can represent 227-258, but length code 285
- really is 258. The last length deserves its own, short code
- since it gets used a lot in very redundant files. The length
- 258 is special since 258 - 3 (the min match length) is 255.
- 13. The literal/length and distance code bit lengths are read as a
- single stream of lengths. It is possible (and advantageous) for
- a repeat code (16, 17, or 18) to go across the boundary between
- the two sets of lengths.
- */
-
-
-void inflate_blocks_reset(s, z, c)
-inflate_blocks_statef *s;
-z_streamp z;
-uLongf *c;
-{
- if (c != Z_NULL)
- *c = s->check;
- if (s->mode == BTREE || s->mode == DTREE)
- ZFREE(z, s->sub.trees.blens);
- if (s->mode == CODES)
- inflate_codes_free(s->sub.decode.codes, z);
- s->mode = TYPE;
- s->bitk = 0;
- s->bitb = 0;
- s->read = s->write = s->window;
- if (s->checkfn != Z_NULL)
- z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
- Tracev((stderr, "inflate: blocks reset\n"));
-}
-
-
-inflate_blocks_statef *inflate_blocks_new(z, c, w)
-z_streamp z;
-check_func c;
-uInt w;
-{
- inflate_blocks_statef *s;
-
- if ((s = (inflate_blocks_statef *)ZALLOC
- (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
- return s;
- if ((s->hufts =
- (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
- {
- ZFREE(z, s);
- return Z_NULL;
- }
- if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
- {
- ZFREE(z, s->hufts);
- ZFREE(z, s);
- return Z_NULL;
- }
- s->end = s->window + w;
- s->checkfn = c;
- s->mode = TYPE;
- Tracev((stderr, "inflate: blocks allocated\n"));
- inflate_blocks_reset(s, z, Z_NULL);
- return s;
-}
-
-
-int inflate_blocks(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
- uInt t; /* temporary storage */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input based on current state */
- while (1) switch (s->mode)
- {
- case TYPE:
- NEEDBITS(3)
- t = (uInt)b & 7;
- s->last = t & 1;
- switch (t >> 1)
- {
- case 0: /* stored */
- Tracev((stderr, "inflate: stored block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- t = k & 7; /* go to byte boundary */
- DUMPBITS(t)
- s->mode = LENS; /* get length of stored block */
- break;
- case 1: /* fixed */
- Tracev((stderr, "inflate: fixed codes block%s\n",
- s->last ? " (last)" : ""));
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
-
- inflate_trees_fixed(&bl, &bd, &tl, &td, z);
- s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
- if (s->sub.decode.codes == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- }
- DUMPBITS(3)
- s->mode = CODES;
- break;
- case 2: /* dynamic */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- s->mode = TABLE;
- break;
- case 3: /* illegal */
- DUMPBITS(3)
- s->mode = BAD;
- z->msg = (char*)"invalid block type";
- r = Z_DATA_ERROR;
- LEAVE
- }
- break;
- case LENS:
- NEEDBITS(32)
- if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
- {
- s->mode = BAD;
- z->msg = (char*)"invalid stored block lengths";
- r = Z_DATA_ERROR;
- LEAVE
- }
- s->sub.left = (uInt)b & 0xffff;
- b = k = 0; /* dump bits */
- Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
- s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
- break;
- case STORED:
- if (n == 0)
- LEAVE
- NEEDOUT
- t = s->sub.left;
- if (t > n) t = n;
- if (t > m) t = m;
- zmemcpy(q, p, t);
- p += t; n -= t;
- q += t; m -= t;
- if ((s->sub.left -= t) != 0)
- break;
- Tracev((stderr, "inflate: stored end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- s->mode = s->last ? DRY : TYPE;
- break;
- case TABLE:
- NEEDBITS(14)
- s->sub.trees.table = t = (uInt)b & 0x3fff;
-#ifndef PKZIP_BUG_WORKAROUND
- if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
- {
- s->mode = BAD;
- z->msg = (char*)"too many length or distance symbols";
- r = Z_DATA_ERROR;
- LEAVE
- }
-#endif
- t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
- if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- DUMPBITS(14)
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: table sizes ok\n"));
- s->mode = BTREE;
- case BTREE:
- while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
- {
- NEEDBITS(3)
- s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
- DUMPBITS(3)
- }
- while (s->sub.trees.index < 19)
- s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
- s->sub.trees.bb = 7;
- t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
- &s->sub.trees.tb, s->hufts, z);
- if (t != Z_OK)
- {
- r = t;
- if (r == Z_DATA_ERROR)
- {
- ZFREE(z, s->sub.trees.blens);
- s->mode = BAD;
- }
- LEAVE
- }
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: bits tree ok\n"));
- s->mode = DTREE;
- case DTREE:
- while (t = s->sub.trees.table,
- s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
- {
- inflate_huft *h;
- uInt i, j, c;
-
- t = s->sub.trees.bb;
- NEEDBITS(t)
- h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
- t = h->bits;
- c = h->base;
- if (c < 16)
- {
- DUMPBITS(t)
- s->sub.trees.blens[s->sub.trees.index++] = c;
- }
- else /* c == 16..18 */
- {
- i = c == 18 ? 7 : c - 14;
- j = c == 18 ? 11 : 3;
- NEEDBITS(t + i)
- DUMPBITS(t)
- j += (uInt)b & inflate_mask[i];
- DUMPBITS(i)
- i = s->sub.trees.index;
- t = s->sub.trees.table;
- if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
- (c == 16 && i < 1))
- {
- ZFREE(z, s->sub.trees.blens);
- s->mode = BAD;
- z->msg = (char*)"invalid bit length repeat";
- r = Z_DATA_ERROR;
- LEAVE
- }
- c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
- do {
- s->sub.trees.blens[i++] = c;
- } while (--j);
- s->sub.trees.index = i;
- }
- }
- s->sub.trees.tb = Z_NULL;
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
- inflate_codes_statef *c;
-
- bl = 9; /* must be <= 9 for lookahead assumptions */
- bd = 6; /* must be <= 9 for lookahead assumptions */
- t = s->sub.trees.table;
- t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
- s->sub.trees.blens, &bl, &bd, &tl, &td,
- s->hufts, z);
- if (t != Z_OK)
- {
- if (t == (uInt)Z_DATA_ERROR)
- {
- ZFREE(z, s->sub.trees.blens);
- s->mode = BAD;
- }
- r = t;
- LEAVE
- }
- Tracev((stderr, "inflate: trees ok\n"));
- if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- s->sub.decode.codes = c;
- }
- ZFREE(z, s->sub.trees.blens);
- s->mode = CODES;
- case CODES:
- UPDATE
- if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
- return inflate_flush(s, z, r);
- r = Z_OK;
- inflate_codes_free(s->sub.decode.codes, z);
- LOAD
- Tracev((stderr, "inflate: codes end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- if (!s->last)
- {
- s->mode = TYPE;
- break;
- }
- s->mode = DRY;
- case DRY:
- FLUSH
- if (s->read != s->write)
- LEAVE
- s->mode = DONE;
- case DONE:
- r = Z_STREAM_END;
- LEAVE
- case BAD:
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-}
-
-
-int inflate_blocks_free(s, z)
-inflate_blocks_statef *s;
-z_streamp z;
-{
- inflate_blocks_reset(s, z, Z_NULL);
- ZFREE(z, s->window);
- ZFREE(z, s->hufts);
- ZFREE(z, s);
- Tracev((stderr, "inflate: blocks freed\n"));
- return Z_OK;
-}
-
-
-void inflate_set_dictionary(s, d, n)
-inflate_blocks_statef *s;
-const Bytef *d;
-uInt n;
-{
- zmemcpy(s->window, d, n);
- s->read = s->write = s->window + n;
-}
-
-
-/* Returns true if inflate is currently at the end of a block generated
- * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
- * IN assertion: s != Z_NULL
- */
-int inflate_blocks_sync_point(s)
-inflate_blocks_statef *s;
-{
- return s->mode == LENS;
-}
diff --git a/src/utilfuns/zlib/infblock.h b/src/utilfuns/zlib/infblock.h
deleted file mode 100644
index 173b226..0000000
--- a/src/utilfuns/zlib/infblock.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* infblock.h -- header to use infblock.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_blocks_state;
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-
-extern inflate_blocks_statef * inflate_blocks_new OF((
- z_streamp z,
- check_func c, /* check function */
- uInt w)); /* window size */
-
-extern int inflate_blocks OF((
- inflate_blocks_statef *,
- z_streamp ,
- int)); /* initial return code */
-
-extern void inflate_blocks_reset OF((
- inflate_blocks_statef *,
- z_streamp ,
- uLongf *)); /* check value on output */
-
-extern int inflate_blocks_free OF((
- inflate_blocks_statef *,
- z_streamp));
-
-extern void inflate_set_dictionary OF((
- inflate_blocks_statef *s,
- const Bytef *d, /* dictionary */
- uInt n)); /* dictionary length */
-
-extern int inflate_blocks_sync_point OF((
- inflate_blocks_statef *s));
diff --git a/src/utilfuns/zlib/infcodes.c b/src/utilfuns/zlib/infcodes.c
deleted file mode 100644
index 0d54ea7..0000000
--- a/src/utilfuns/zlib/infcodes.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/* infcodes.c -- process literals and length/distance pairs
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "infblock.h"
-#include "infcodes.h"
-#include "infutil.h"
-#include "inffast.h"
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- START, /* x: set up for LEN */
- LEN, /* i: get length/literal/eob next */
- LENEXT, /* i: getting length extra (have base) */
- DIST, /* i: get distance next */
- DISTEXT, /* i: getting distance extra */
- COPY, /* o: copying bytes in window, waiting for space */
- LIT, /* o: got literal, waiting for output space */
- WASH, /* o: got eob, possibly still output waiting */
- END, /* x: got eob and all data flushed */
- BADCODE} /* x: got error */
-inflate_codes_mode;
-
-/* inflate codes private state */
-struct inflate_codes_state {
-
- /* mode */
- inflate_codes_mode mode; /* current inflate_codes mode */
-
- /* mode dependent information */
- uInt len;
- union {
- struct {
- inflate_huft *tree; /* pointer into tree */
- uInt need; /* bits needed */
- } code; /* if LEN or DIST, where in tree */
- uInt lit; /* if LIT, literal */
- struct {
- uInt get; /* bits to get for extra */
- uInt dist; /* distance back to copy from */
- } copy; /* if EXT or COPY, where and how much */
- } sub; /* submode */
-
- /* mode independent information */
- Byte lbits; /* ltree bits decoded per branch */
- Byte dbits; /* dtree bits decoder per branch */
- inflate_huft *ltree; /* literal/length/eob tree */
- inflate_huft *dtree; /* distance tree */
-
-};
-
-
-inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-z_streamp z;
-{
- inflate_codes_statef *c;
-
- if ((c = (inflate_codes_statef *)
- ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
- {
- c->mode = START;
- c->lbits = (Byte)bl;
- c->dbits = (Byte)bd;
- c->ltree = tl;
- c->dtree = td;
- Tracev((stderr, "inflate: codes new\n"));
- }
- return c;
-}
-
-
-int inflate_codes(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
- uInt j; /* temporary storage */
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- unsigned long csf; /* pointer to copy strings from */
- inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input and output based on current state */
- while (1) switch (c->mode)
- { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- case START: /* x: set up for LEN */
-#ifndef SLOW
- if (m >= 258 && n >= 10)
- {
- UPDATE
- r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
- LOAD
- if (r != Z_OK)
- {
- c->mode = r == Z_STREAM_END ? WASH : BADCODE;
- break;
- }
- }
-#endif /* !SLOW */
- c->sub.code.need = c->lbits;
- c->sub.code.tree = c->ltree;
- c->mode = LEN;
- case LEN: /* i: get length/literal/eob next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e == 0) /* literal */
- {
- c->sub.lit = t->base;
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", t->base));
- c->mode = LIT;
- break;
- }
- if (e & 16) /* length */
- {
- c->sub.copy.get = e & 15;
- c->len = t->base;
- c->mode = LENEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t + t->base;
- break;
- }
- if (e & 32) /* end of block */
- {
- Tracevv((stderr, "inflate: end of block\n"));
- c->mode = WASH;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = (char*)"invalid literal/length code";
- r = Z_DATA_ERROR;
- LEAVE
- case LENEXT: /* i: getting length extra (have base) */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->len += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- c->sub.code.need = c->dbits;
- c->sub.code.tree = c->dtree;
- Tracevv((stderr, "inflate: length %u\n", c->len));
- c->mode = DIST;
- case DIST: /* i: get distance next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e & 16) /* distance */
- {
- c->sub.copy.get = e & 15;
- c->sub.copy.dist = t->base;
- c->mode = DISTEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t + t->base;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = (char*)"invalid distance code";
- r = Z_DATA_ERROR;
- LEAVE
- case DISTEXT: /* i: getting distance extra */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->sub.copy.dist += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
- c->mode = COPY;
- case COPY: /* o: copying bytes in window, waiting for space */
- csf = (unsigned long)q - c->sub.copy.dist;
- while (csf < (unsigned long)s->window) /* modulo window size-"while" instead */
- csf += (unsigned long)(s->end - s->window); /* of "if" handles invalid distances */
- while (c->len)
- {
- NEEDOUT
- OUTBYTE(*(Bytef *)csf++)
- if (csf == (unsigned long)s->end)
- csf = (unsigned long)s->window;
- c->len--;
- }
- c->mode = START;
- break;
- case LIT: /* o: got literal, waiting for output space */
- NEEDOUT
- OUTBYTE(c->sub.lit)
- c->mode = START;
- break;
- case WASH: /* o: got eob, possibly more output */
- if (k > 7) /* return unused byte, if any */
- {
- Assert(k < 16, "inflate_codes grabbed too many bytes")
- k -= 8;
- n++;
- p--; /* can always return one */
- }
- FLUSH
- if (s->read != s->write)
- LEAVE
- c->mode = END;
- case END:
- r = Z_STREAM_END;
- LEAVE
- case BADCODE: /* x: got error */
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-#ifdef NEED_DUMMY_RETURN
- return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
-#endif
-}
-
-
-void inflate_codes_free(c, z)
-inflate_codes_statef *c;
-z_streamp z;
-{
- ZFREE(z, c);
- Tracev((stderr, "inflate: codes free\n"));
-}
diff --git a/src/utilfuns/zlib/infcodes.h b/src/utilfuns/zlib/infcodes.h
deleted file mode 100644
index 46821a0..0000000
--- a/src/utilfuns/zlib/infcodes.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* infcodes.h -- header to use infcodes.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_codes_state;
-typedef struct inflate_codes_state FAR inflate_codes_statef;
-
-extern inflate_codes_statef *inflate_codes_new OF((
- uInt, uInt,
- inflate_huft *, inflate_huft *,
- z_streamp ));
-
-extern int inflate_codes OF((
- inflate_blocks_statef *,
- z_streamp ,
- int));
-
-extern void inflate_codes_free OF((
- inflate_codes_statef *,
- z_streamp ));
-
diff --git a/src/utilfuns/zlib/inffast.c b/src/utilfuns/zlib/inffast.c
deleted file mode 100644
index a7ebc64..0000000
--- a/src/utilfuns/zlib/inffast.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* inffast.c -- process literals and length/distance pairs fast
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "infblock.h"
-#include "infcodes.h"
-#include "infutil.h"
-#include "inffast.h"
-
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* macros for bit input with no checking and for returning unused bytes */
-#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
-
-/* Called with number of bytes left to write in window at least 258
- (the maximum string length) and number of input bytes available
- at least ten. The ten bytes are six bytes for the longest length/
- distance pair plus four bytes for overloading the bit buffer. */
-
-int inflate_fast(bl, bd, tl, td, s, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-inflate_blocks_statef *s;
-z_streamp z;
-{
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- uInt ml; /* mask for literal/length tree */
- uInt md; /* mask for distance tree */
- uInt c; /* bytes to copy */
- uInt d; /* distance back to copy from */
- unsigned long csp; /* copy source pointer */
-
- /* load input, output, bit values */
- LOAD
-
- /* initialize masks */
- ml = inflate_mask[bl];
- md = inflate_mask[bd];
-
- /* do until not enough input or output space for fast loop */
- do { /* assume called with m >= 258 && n >= 10 */
- /* get literal/length code */
- GRABBITS(20) /* max bits for literal/length code */
- if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- continue;
- }
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits for length */
- e &= 15;
- c = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * length %u\n", c));
-
- /* decode distance base of block to copy */
- GRABBITS(15); /* max bits for distance code */
- e = (t = td + ((uInt)b & md))->exop;
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits to add to distance base */
- e &= 15;
- GRABBITS(e) /* get extra bits (up to 13) */
- d = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * distance %u\n", d));
-
- /* do the copy */
- m -= c;
- csp = (unsigned long)q - d;
- if (csp < (unsigned long)s->window) /* wrap if needed */
- {
- do {
- csp += (unsigned long)(s->end - s->window); /* force pointer in window */
- } while (csp < (unsigned long)s->window); /* covers invalid distances */
- e = (unsigned long)s->end - csp;
- if (c > e)
- {
- c -= e; /* wrapped copy */
- do {
- *q++ = *(Bytef *)csp++;
- } while (--e);
- csp = s->window;
- do {
- *q++ = *(Bytef *)csp++;
- } while (--c);
- }
- else /* normal copy */
- {
- *q++ = *(Bytef *)csp++; c--;
- *q++ = *(Bytef *)csp++; c--;
- do {
- *q++ = *(Bytef *)csp++;
- } while (--c);
- }
- }
- else /* normal copy */
- {
- *q++ = *(Bytef *)csp++; c--;
- *q++ = *(Bytef *)csp++; c--;
- do {
- *q++ = *(Bytef *)csp++;
- } while (--c);
- }
- break;
- }
- else if ((e & 64) == 0)
- {
- t += t->base;
- e = (t += ((uInt)b & inflate_mask[e]))->exop;
- }
- else
- {
- z->msg = (char*)"invalid distance code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- break;
- }
- if ((e & 64) == 0)
- {
- t += t->base;
- if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- break;
- }
- }
- else if (e & 32)
- {
- Tracevv((stderr, "inflate: * end of block\n"));
- UNGRAB
- UPDATE
- return Z_STREAM_END;
- }
- else
- {
- z->msg = (char*)"invalid literal/length code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- } while (m >= 258 && n >= 10);
-
- /* not enough input or output--restore pointers and return */
- UNGRAB
- UPDATE
- return Z_OK;
-}
diff --git a/src/utilfuns/zlib/inffast.h b/src/utilfuns/zlib/inffast.h
deleted file mode 100644
index a31a4bb..0000000
--- a/src/utilfuns/zlib/inffast.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-extern int inflate_fast OF((
- uInt,
- uInt,
- inflate_huft *,
- inflate_huft *,
- inflate_blocks_statef *,
- z_streamp ));
diff --git a/src/utilfuns/zlib/inffixed.h b/src/utilfuns/zlib/inffixed.h
deleted file mode 100644
index 77f7e76..0000000
--- a/src/utilfuns/zlib/inffixed.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/* inffixed.h -- table for decoding fixed codes
- * Generated automatically by the maketree.c program
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-local uInt fixed_bl = 9;
-local uInt fixed_bd = 5;
-local inflate_huft fixed_tl[] = {
- {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
- {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
- {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
- {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
- {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
- {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
- {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
- {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
- {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
- {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
- {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
- {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
- {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
- {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
- {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
- {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
- {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
- {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
- {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
- {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
- {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
- {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
- {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
- {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
- {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
- {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
- {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
- {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
- {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
- {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
- {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
- {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
- {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
- {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
- {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
- {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
- {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
- {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
- {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
- {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
- {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
- {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
- {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
- {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
- {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
- {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
- {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
- {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
- {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
- {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
- {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
- {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
- {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
- {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
- {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
- {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
- {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
- {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
- {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
- {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
- {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
- {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
- {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
- {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
- {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
- {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
- {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
- {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
- {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
- {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
- {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
- {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
- {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
- {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
- {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
- {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
- {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
- {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
- {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
- {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
- {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
- {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
- {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
- {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
- {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
- {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
- {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
- {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
- {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
- {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
- {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
- {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
- {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
- {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
- {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
- {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
- {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
- {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
- {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
- {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
- {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
- {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
- {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
- {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
- {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
- {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
- {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
- {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
- {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
- {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
- {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
- {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
- {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
- {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
- {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
- {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
- {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
- {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
- {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
- {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
- {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
- {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
- {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
- {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
- };
-local inflate_huft fixed_td[] = {
- {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
- {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
- {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
- {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
- {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
- {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
- {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
- {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
- };
diff --git a/src/utilfuns/zlib/inflate.c b/src/utilfuns/zlib/inflate.c
deleted file mode 100644
index dfb2e86..0000000
--- a/src/utilfuns/zlib/inflate.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/* inflate.c -- zlib interface to inflate modules
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-
-struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
-
-typedef enum {
- METHOD, /* waiting for method byte */
- FLAG, /* waiting for flag byte */
- DICT4, /* four dictionary check bytes to go */
- DICT3, /* three dictionary check bytes to go */
- DICT2, /* two dictionary check bytes to go */
- DICT1, /* one dictionary check byte to go */
- DICT0, /* waiting for inflateSetDictionary */
- BLOCKS, /* decompressing blocks */
- CHECK4, /* four check bytes to go */
- CHECK3, /* three check bytes to go */
- CHECK2, /* two check bytes to go */
- CHECK1, /* one check byte to go */
- DONE, /* finished check, done */
- BAD} /* got an error--stay here */
-inflate_mode;
-
-/* inflate private state */
-struct internal_state {
-
- /* mode */
- inflate_mode mode; /* current inflate mode */
-
- /* mode dependent information */
- union {
- uInt method; /* if FLAGS, method byte */
- struct {
- uLong was; /* computed check value */
- uLong need; /* stream check value */
- } check; /* if CHECK, check values to compare */
- uInt marker; /* if BAD, inflateSync's marker bytes count */
- } sub; /* submode */
-
- /* mode independent information */
- int nowrap; /* flag for no wrapper */
- uInt wbits; /* log2(window size) (8..15, defaults to 15) */
- inflate_blocks_statef
- *blocks; /* current inflate_blocks state */
-
-};
-
-
-int ZEXPORT inflateReset(z)
-z_streamp z;
-{
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- z->total_in = z->total_out = 0;
- z->msg = Z_NULL;
- z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
- inflate_blocks_reset(z->state->blocks, z, Z_NULL);
- Tracev((stderr, "inflate: reset\n"));
- return Z_OK;
-}
-
-
-int ZEXPORT inflateEnd(z)
-z_streamp z;
-{
- if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->blocks != Z_NULL)
- inflate_blocks_free(z->state->blocks, z);
- ZFREE(z, z->state);
- z->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
-
-
-int ZEXPORT inflateInit2_(z, w, version, stream_size)
-z_streamp z;
-int w;
-const char *version;
-int stream_size;
-{
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != sizeof(z_stream))
- return Z_VERSION_ERROR;
-
- /* initialize state */
- if (z == Z_NULL)
- return Z_STREAM_ERROR;
- z->msg = Z_NULL;
- if (z->zalloc == Z_NULL)
- {
- z->zalloc = zcalloc;
- z->opaque = (voidpf)0;
- }
- if (z->zfree == Z_NULL) z->zfree = zcfree;
- if ((z->state = (struct internal_state FAR *)
- ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
- return Z_MEM_ERROR;
- z->state->blocks = Z_NULL;
-
- /* handle undocumented nowrap option (no zlib header or check) */
- z->state->nowrap = 0;
- if (w < 0)
- {
- w = - w;
- z->state->nowrap = 1;
- }
-
- /* set window size */
- if (w < 8 || w > 15)
- {
- inflateEnd(z);
- return Z_STREAM_ERROR;
- }
- z->state->wbits = (uInt)w;
-
- /* create inflate_blocks state */
- if ((z->state->blocks =
- inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
- == Z_NULL)
- {
- inflateEnd(z);
- return Z_MEM_ERROR;
- }
- Tracev((stderr, "inflate: allocated\n"));
-
- /* reset state */
- inflateReset(z);
- return Z_OK;
-}
-
-
-int ZEXPORT inflateInit_(z, version, stream_size)
-z_streamp z;
-const char *version;
-int stream_size;
-{
- return inflateInit2_(z, DEF_WBITS, version, stream_size);
-}
-
-
-#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
-#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-
-int ZEXPORT inflate(z, f)
-z_streamp z;
-int f;
-{
- int r;
- uInt b;
-
- if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
- return Z_STREAM_ERROR;
- f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
- r = Z_BUF_ERROR;
- while (1) switch (z->state->mode)
- {
- case METHOD:
- NEEDBYTE
- if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
- {
- z->state->mode = BAD;
- z->msg = (char*)"unknown compression method";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
- {
- z->state->mode = BAD;
- z->msg = (char*)"invalid window size";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- z->state->mode = FLAG;
- case FLAG:
- NEEDBYTE
- b = NEXTBYTE;
- if (((z->state->sub.method << 8) + b) % 31)
- {
- z->state->mode = BAD;
- z->msg = (char*)"incorrect header check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Tracev((stderr, "inflate: zlib header ok\n"));
- if (!(b & PRESET_DICT))
- {
- z->state->mode = BLOCKS;
- break;
- }
- z->state->mode = DICT4;
- case DICT4:
- NEEDBYTE
- z->state->sub.check.need = (uLong)NEXTBYTE << 24;
- z->state->mode = DICT3;
- case DICT3:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 16;
- z->state->mode = DICT2;
- case DICT2:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 8;
- z->state->mode = DICT1;
- case DICT1:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE;
- z->adler = z->state->sub.check.need;
- z->state->mode = DICT0;
- return Z_NEED_DICT;
- case DICT0:
- z->state->mode = BAD;
- z->msg = (char*)"need dictionary";
- z->state->sub.marker = 0; /* can try inflateSync */
- return Z_STREAM_ERROR;
- case BLOCKS:
- r = inflate_blocks(z->state->blocks, z, r);
- if (r == Z_DATA_ERROR)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0; /* can try inflateSync */
- break;
- }
- if (r == Z_OK)
- r = f;
- if (r != Z_STREAM_END)
- return r;
- r = f;
- inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
- if (z->state->nowrap)
- {
- z->state->mode = DONE;
- break;
- }
- z->state->mode = CHECK4;
- case CHECK4:
- NEEDBYTE
- z->state->sub.check.need = (uLong)NEXTBYTE << 24;
- z->state->mode = CHECK3;
- case CHECK3:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 16;
- z->state->mode = CHECK2;
- case CHECK2:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 8;
- z->state->mode = CHECK1;
- case CHECK1:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE;
-
- if (z->state->sub.check.was != z->state->sub.check.need)
- {
- z->state->mode = BAD;
- z->msg = (char*)"incorrect data check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Tracev((stderr, "inflate: zlib check ok\n"));
- z->state->mode = DONE;
- case DONE:
- return Z_STREAM_END;
- case BAD:
- return Z_DATA_ERROR;
- default:
- return Z_STREAM_ERROR;
- }
-#ifdef NEED_DUMMY_RETURN
- return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
-#endif
-}
-
-
-int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
-z_streamp z;
-const Bytef *dictionary;
-uInt dictLength;
-{
- uInt length = dictLength;
-
- if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
- return Z_STREAM_ERROR;
-
- if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
- z->adler = 1L;
-
- if (length >= ((uInt)1<<z->state->wbits))
- {
- length = (1<<z->state->wbits)-1;
- dictionary += dictLength - length;
- }
- inflate_set_dictionary(z->state->blocks, dictionary, length);
- z->state->mode = BLOCKS;
- return Z_OK;
-}
-
-
-int ZEXPORT inflateSync(z)
-z_streamp z;
-{
- uInt n; /* number of bytes to look at */
- Bytef *p; /* pointer to bytes */
- uInt m; /* number of marker bytes found in a row */
- uLong r, w; /* temporaries to save total_in and total_out */
-
- /* set up */
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->mode != BAD)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0;
- }
- if ((n = z->avail_in) == 0)
- return Z_BUF_ERROR;
- p = z->next_in;
- m = z->state->sub.marker;
-
- /* search */
- while (n && m < 4)
- {
- static const Byte mark[4] = {0, 0, 0xff, 0xff};
- if (*p == mark[m])
- m++;
- else if (*p)
- m = 0;
- else
- m = 4 - m;
- p++, n--;
- }
-
- /* restore */
- z->total_in += p - z->next_in;
- z->next_in = p;
- z->avail_in = n;
- z->state->sub.marker = m;
-
- /* return no joy or set up to restart on a new block */
- if (m != 4)
- return Z_DATA_ERROR;
- r = z->total_in; w = z->total_out;
- inflateReset(z);
- z->total_in = r; z->total_out = w;
- z->state->mode = BLOCKS;
- return Z_OK;
-}
-
-
-/* Returns true if inflate is currently at the end of a block generated
- * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
- * but removes the length bytes of the resulting empty stored block. When
- * decompressing, PPP checks that at the end of input packet, inflate is
- * waiting for these length bytes.
- */
-int ZEXPORT inflateSyncPoint(z)
-z_streamp z;
-{
- if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
- return Z_STREAM_ERROR;
- return inflate_blocks_sync_point(z->state->blocks);
-}
diff --git a/src/utilfuns/zlib/inftrees.c b/src/utilfuns/zlib/inftrees.c
deleted file mode 100644
index 4c32ca3..0000000
--- a/src/utilfuns/zlib/inftrees.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-
-#if !defined(BUILDFIXED) && !defined(STDC)
-# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
-#endif
-
-const char inflate_copyright[] =
- " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-
-local int huft_build OF((
- uIntf *, /* code lengths in bits */
- uInt, /* number of codes */
- uInt, /* number of "simple" codes */
- const uIntf *, /* list of base values for non-simple codes */
- const uIntf *, /* list of extra bits for non-simple codes */
- inflate_huft * FAR*,/* result: starting table */
- uIntf *, /* maximum lookup bits (returns actual) */
- inflate_huft *, /* space for trees */
- uInt *, /* hufts used in space */
- uIntf * )); /* space for values */
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- /* see note #13 above about 258 */
-local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
- 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
-local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577};
-local const uInt cpdext[30] = { /* Extra bits for distance codes */
- 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
- 12, 12, 13, 13};
-
-/*
- Huffman code decoding is performed using a multi-level table lookup.
- The fastest way to decode is to simply build a lookup table whose
- size is determined by the longest code. However, the time it takes
- to build this table can also be a factor if the data being decoded
- is not very long. The most common codes are necessarily the
- shortest codes, so those codes dominate the decoding time, and hence
- the speed. The idea is you can have a shorter table that decodes the
- shorter, more probable codes, and then point to subsidiary tables for
- the longer codes. The time it costs to decode the longer codes is
- then traded against the time it takes to make longer tables.
-
- This results of this trade are in the variables lbits and dbits
- below. lbits is the number of bits the first level table for literal/
- length codes can decode in one step, and dbits is the same thing for
- the distance codes. Subsequent tables are also less than or equal to
- those sizes. These values may be adjusted either when all of the
- codes are shorter than that, in which case the longest code length in
- bits is used, or when the shortest code is *longer* than the requested
- table size, in which case the length of the shortest code in bits is
- used.
-
- There are two different values for the two tables, since they code a
- different number of possibilities each. The literal/length table
- codes 286 possible values, or in a flat code, a little over eight
- bits. The distance table codes 30 possible values, or a little less
- than five bits, flat. The optimum values for speed end up being
- about one bit more than those, so lbits is 8+1 and dbits is 5+1.
- The optimum values may differ though from machine to machine, and
- possibly even between compilers. Your mileage may vary.
- */
-
-
-/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-#define BMAX 15 /* maximum bit length of any code */
-
-local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
-uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
-uInt n; /* number of codes (assumed <= 288) */
-uInt s; /* number of simple-valued codes (0..s-1) */
-const uIntf *d; /* list of base values for non-simple codes */
-const uIntf *e; /* list of extra bits for non-simple codes */
-inflate_huft * FAR *t; /* result: starting table */
-uIntf *m; /* maximum lookup bits, returns actual */
-inflate_huft *hp; /* space for trees */
-uInt *hn; /* hufts used in space */
-uIntf *v; /* working area: values in order of bit length */
-/* Given a list of code lengths and a maximum table size, make a set of
- tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
- if the given code set is incomplete (the tables are still built in this
- case), or Z_DATA_ERROR if the input is invalid. */
-{
-
- uInt a; /* counter for codes of length k */
- uInt c[BMAX+1]; /* bit length count table */
- uInt f; /* i repeats in table every f entries */
- int g; /* maximum code length */
- int h; /* table level */
- register uInt i; /* counter, current code */
- register uInt j; /* counter */
- register int k; /* number of bits in current code */
- int l; /* bits per table (returned in m) */
- uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
- register uIntf *p; /* pointer into c[], b[], or v[] */
- inflate_huft *q; /* points to current table */
- struct inflate_huft_s r; /* table entry for structure assignment */
- inflate_huft *u[BMAX]; /* table stack */
- register int w; /* bits before this table == (l * h) */
- uInt x[BMAX+1]; /* bit offsets, then code stack */
- uIntf *xp; /* pointer into x */
- int y; /* number of dummy codes added */
- uInt z; /* number of entries in current table */
-
-
- /* Generate counts for each bit length */
- p = c;
-#define C0 *p++ = 0;
-#define C2 C0 C0 C0 C0
-#define C4 C2 C2 C2 C2
- C4 /* clear c[]--assume BMAX+1 is 16 */
- p = b; i = n;
- do {
- c[*p++]++; /* assume all entries <= BMAX */
- } while (--i);
- if (c[0] == n) /* null input--all zero length codes */
- {
- *t = (inflate_huft *)Z_NULL;
- *m = 0;
- return Z_OK;
- }
-
-
- /* Find minimum and maximum length, bound *m by those */
- l = *m;
- for (j = 1; j <= BMAX; j++)
- if (c[j])
- break;
- k = j; /* minimum code length */
- if ((uInt)l < j)
- l = j;
- for (i = BMAX; i; i--)
- if (c[i])
- break;
- g = i; /* maximum code length */
- if ((uInt)l > i)
- l = i;
- *m = l;
-
-
- /* Adjust last length count to fill out codes, if needed */
- for (y = 1 << j; j < i; j++, y <<= 1)
- if ((y -= c[j]) < 0)
- return Z_DATA_ERROR;
- if ((y -= c[i]) < 0)
- return Z_DATA_ERROR;
- c[i] += y;
-
-
- /* Generate starting offsets into the value table for each length */
- x[1] = j = 0;
- p = c + 1; xp = x + 2;
- while (--i) { /* note that i == g from above */
- *xp++ = (j += *p++);
- }
-
-
- /* Make a table of values in order of bit lengths */
- p = b; i = 0;
- do {
- if ((j = *p++) != 0)
- v[x[j]++] = i;
- } while (++i < n);
- n = x[g]; /* set n to length of v */
-
-
- /* Generate the Huffman codes and for each, make the table entries */
- x[0] = i = 0; /* first Huffman code is zero */
- p = v; /* grab values in bit order */
- h = -1; /* no tables yet--level -1 */
- w = -l; /* bits decoded == (l * h) */
- u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
- q = (inflate_huft *)Z_NULL; /* ditto */
- z = 0; /* ditto */
-
- /* go through the bit lengths (k already is bits in shortest code) */
- for (; k <= g; k++)
- {
- a = c[k];
- while (a--)
- {
- /* here i is the Huffman code of length k bits for value *p */
- /* make tables up to required level */
- while (k > w + l)
- {
- h++;
- w += l; /* previous table always l bits */
-
- /* compute minimum size table less than or equal to l bits */
- z = g - w;
- z = z > (uInt)l ? l : z; /* table size upper limit */
- if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
- { /* too few codes for k-w bit table */
- f -= a + 1; /* deduct codes from patterns left */
- xp = c + k;
- if (j < z)
- while (++j < z) /* try smaller tables up to z bits */
- {
- if ((f <<= 1) <= *++xp)
- break; /* enough codes to use up j bits */
- f -= *xp; /* else deduct codes from patterns */
- }
- }
- z = 1 << j; /* table entries for j-bit table */
-
- /* allocate new table */
- if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
- return Z_DATA_ERROR; /* overflow of MANY */
- u[h] = q = hp + *hn;
- *hn += z;
-
- /* connect to last table, if there is one */
- if (h)
- {
- x[h] = i; /* save pattern for backing up */
- r.bits = (Byte)l; /* bits to dump before this table */
- r.exop = (Byte)j; /* bits in this table */
- j = i >> (w - l);
- r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
- u[h-1][j] = r; /* connect to last table */
- }
- else
- *t = q; /* first table is returned result */
- }
-
- /* set up table entry in r */
- r.bits = (Byte)(k - w);
- if (p >= v + n)
- r.exop = 128 + 64; /* out of values--invalid code */
- else if (*p < s)
- {
- r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
- r.base = *p++; /* simple code is just the value */
- }
- else
- {
- r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
- r.base = d[*p++ - s];
- }
-
- /* fill code-like entries with r */
- f = 1 << (k - w);
- for (j = i >> w; j < z; j += f)
- q[j] = r;
-
- /* backwards increment the k-bit code i */
- for (j = 1 << (k - 1); i & j; j >>= 1)
- i ^= j;
- i ^= j;
-
- /* backup over finished tables */
- mask = (1 << w) - 1; /* needed on HP, cc -O bug */
- while ((i & mask) != x[h])
- {
- h--; /* don't need to update q */
- w -= l;
- mask = (1 << w) - 1;
- }
- }
- }
-
-
- /* Return Z_BUF_ERROR if we were given an incomplete table */
- return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-}
-
-
-int inflate_trees_bits(c, bb, tb, hp, z)
-uIntf *c; /* 19 code lengths */
-uIntf *bb; /* bits tree desired/actual depth */
-inflate_huft * FAR *tb; /* bits tree result */
-inflate_huft *hp; /* space for trees */
-z_streamp z; /* for messages */
-{
- int r;
- uInt hn = 0; /* hufts used in space */
- uIntf *v; /* work area for huft_build */
-
- if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
- return Z_MEM_ERROR;
- r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
- tb, bb, hp, &hn, v);
- if (r == Z_DATA_ERROR)
- z->msg = (char*)"oversubscribed dynamic bit lengths tree";
- else if (r == Z_BUF_ERROR || *bb == 0)
- {
- z->msg = (char*)"incomplete dynamic bit lengths tree";
- r = Z_DATA_ERROR;
- }
- ZFREE(z, v);
- return r;
-}
-
-
-int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
-uInt nl; /* number of literal/length codes */
-uInt nd; /* number of distance codes */
-uIntf *c; /* that many (total) code lengths */
-uIntf *bl; /* literal desired/actual bit depth */
-uIntf *bd; /* distance desired/actual bit depth */
-inflate_huft * FAR *tl; /* literal/length tree result */
-inflate_huft * FAR *td; /* distance tree result */
-inflate_huft *hp; /* space for trees */
-z_streamp z; /* for messages */
-{
- int r;
- uInt hn = 0; /* hufts used in space */
- uIntf *v; /* work area for huft_build */
-
- /* allocate work area */
- if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
- return Z_MEM_ERROR;
-
- /* build literal/length tree */
- r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
- if (r != Z_OK || *bl == 0)
- {
- if (r == Z_DATA_ERROR)
- z->msg = (char*)"oversubscribed literal/length tree";
- else if (r != Z_MEM_ERROR)
- {
- z->msg = (char*)"incomplete literal/length tree";
- r = Z_DATA_ERROR;
- }
- ZFREE(z, v);
- return r;
- }
-
- /* build distance tree */
- r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
- if (r != Z_OK || (*bd == 0 && nl > 257))
- {
- if (r == Z_DATA_ERROR)
- z->msg = (char*)"oversubscribed distance tree";
- else if (r == Z_BUF_ERROR) {
-#ifdef PKZIP_BUG_WORKAROUND
- r = Z_OK;
- }
-#else
- z->msg = (char*)"incomplete distance tree";
- r = Z_DATA_ERROR;
- }
- else if (r != Z_MEM_ERROR)
- {
- z->msg = (char*)"empty distance tree with lengths";
- r = Z_DATA_ERROR;
- }
- ZFREE(z, v);
- return r;
-#endif
- }
-
- /* done */
- ZFREE(z, v);
- return Z_OK;
-}
-
-
-/* build fixed tables only once--keep them here */
-#ifdef BUILDFIXED
-local int fixed_built = 0;
-#define FIXEDH 544 /* number of hufts used by fixed tables */
-local inflate_huft fixed_mem[FIXEDH];
-local uInt fixed_bl;
-local uInt fixed_bd;
-local inflate_huft *fixed_tl;
-local inflate_huft *fixed_td;
-#else
-#include "inffixed.h"
-#endif
-
-
-int inflate_trees_fixed(bl, bd, tl, td, z)
-uIntf *bl; /* literal desired/actual bit depth */
-uIntf *bd; /* distance desired/actual bit depth */
-inflate_huft * FAR *tl; /* literal/length tree result */
-inflate_huft * FAR *td; /* distance tree result */
-z_streamp z; /* for memory allocation */
-{
-#ifdef BUILDFIXED
- /* build fixed tables if not already */
- if (!fixed_built)
- {
- int k; /* temporary variable */
- uInt f = 0; /* number of hufts used in fixed_mem */
- uIntf *c; /* length list for huft_build */
- uIntf *v; /* work area for huft_build */
-
- /* allocate memory */
- if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
- return Z_MEM_ERROR;
- if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
- {
- ZFREE(z, c);
- return Z_MEM_ERROR;
- }
-
- /* literal table */
- for (k = 0; k < 144; k++)
- c[k] = 8;
- for (; k < 256; k++)
- c[k] = 9;
- for (; k < 280; k++)
- c[k] = 7;
- for (; k < 288; k++)
- c[k] = 8;
- fixed_bl = 9;
- huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
- fixed_mem, &f, v);
-
- /* distance table */
- for (k = 0; k < 30; k++)
- c[k] = 5;
- fixed_bd = 5;
- huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
- fixed_mem, &f, v);
-
- /* done */
- ZFREE(z, v);
- ZFREE(z, c);
- fixed_built = 1;
- }
-#endif
- *bl = fixed_bl;
- *bd = fixed_bd;
- *tl = fixed_tl;
- *td = fixed_td;
- return Z_OK;
-}
diff --git a/src/utilfuns/zlib/inftrees.h b/src/utilfuns/zlib/inftrees.h
deleted file mode 100644
index 04b73b7..0000000
--- a/src/utilfuns/zlib/inftrees.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Huffman code lookup table entry--this entry is four bytes for machines
- that have 16-bit pointers (e.g. PC's in the small or medium model). */
-
-typedef struct inflate_huft_s FAR inflate_huft;
-
-struct inflate_huft_s {
- union {
- struct {
- Byte Exop; /* number of extra bits or operation */
- Byte Bits; /* number of bits in this code or subcode */
- } what;
- uInt pad; /* pad structure to a power of 2 (4 bytes for */
- } word; /* 16-bit, 8 bytes for 32-bit int's) */
- uInt base; /* literal, length base, distance base,
- or table offset */
-};
-
-/* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1004 huft structures (850 for length/literals
- and 154 for distances, the latter actually the result of an
- exhaustive search). The actual maximum is not known, but the
- value below is more than safe. */
-#define MANY 1440
-
-extern int inflate_trees_bits OF((
- uIntf *, /* 19 code lengths */
- uIntf *, /* bits tree desired/actual depth */
- inflate_huft * FAR *, /* bits tree result */
- inflate_huft *, /* space for trees */
- z_streamp)); /* for messages */
-
-extern int inflate_trees_dynamic OF((
- uInt, /* number of literal/length codes */
- uInt, /* number of distance codes */
- uIntf *, /* that many (total) code lengths */
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *, /* distance tree result */
- inflate_huft *, /* space for trees */
- z_streamp)); /* for messages */
-
-extern int inflate_trees_fixed OF((
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *, /* distance tree result */
- z_streamp)); /* for memory allocation */
diff --git a/src/utilfuns/zlib/infutil.c b/src/utilfuns/zlib/infutil.c
deleted file mode 100644
index 9a07622..0000000
--- a/src/utilfuns/zlib/infutil.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-#include "inftrees.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-
-/* And'ing with mask[n] masks the lower n bits */
-uInt inflate_mask[17] = {
- 0x0000,
- 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-
-/* copy as much as possible from the sliding window to the output area */
-int inflate_flush(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
- uInt n;
- Bytef *p;
- Bytef *q;
-
- /* local copies of source and destination pointers */
- p = z->next_out;
- q = s->read;
-
- /* compute number of bytes to copy as far as end of window */
- n = (uInt)((q <= s->write ? s->write : s->end) - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy as far as end of window */
- zmemcpy(p, q, n);
- p += n;
- q += n;
-
- /* see if more to copy at beginning of window */
- if (q == s->end)
- {
- /* wrap pointers */
- q = s->window;
- if (s->write == s->end)
- s->write = s->window;
-
- /* compute bytes to copy */
- n = (uInt)(s->write - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy */
- zmemcpy(p, q, n);
- p += n;
- q += n;
- }
-
- /* update pointers */
- z->next_out = p;
- s->read = q;
-
- /* done */
- return r;
-}
diff --git a/src/utilfuns/zlib/infutil.h b/src/utilfuns/zlib/infutil.h
deleted file mode 100644
index 4401df8..0000000
--- a/src/utilfuns/zlib/infutil.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* infutil.h -- types and macros common to blocks and codes
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-#ifndef _INFUTIL_H
-#define _INFUTIL_H
-
-typedef enum {
- TYPE, /* get type bits (3, including end bit) */
- LENS, /* get lengths for stored */
- STORED, /* processing stored block */
- TABLE, /* get table lengths */
- BTREE, /* get bit lengths tree for a dynamic block */
- DTREE, /* get length, distance trees for a dynamic block */
- CODES, /* processing fixed or dynamic block */
- DRY, /* output remaining window bytes */
- DONE, /* finished last block, done */
- BAD} /* got a data error--stuck here */
-inflate_block_mode;
-
-/* inflate blocks semi-private state */
-struct inflate_blocks_state {
-
- /* mode */
- inflate_block_mode mode; /* current inflate_block mode */
-
- /* mode dependent information */
- union {
- uInt left; /* if STORED, bytes left to copy */
- struct {
- uInt table; /* table lengths (14 bits) */
- uInt index; /* index into blens (or border) */
- uIntf *blens; /* bit lengths of codes */
- uInt bb; /* bit length tree depth */
- inflate_huft *tb; /* bit length decoding tree */
- } trees; /* if DTREE, decoding info for trees */
- struct {
- inflate_codes_statef
- *codes;
- } decode; /* if CODES, current state */
- } sub; /* submode */
- uInt last; /* true if this block is the last block */
-
- /* mode independent information */
- uInt bitk; /* bits in bit buffer */
- uLong bitb; /* bit buffer */
- inflate_huft *hufts; /* single malloc for tree space */
- Bytef *window; /* sliding window */
- Bytef *end; /* one byte after sliding window */
- Bytef *read; /* window read pointer */
- Bytef *write; /* window write pointer */
- check_func checkfn; /* check function */
- uLong check; /* check on output */
-
-};
-
-
-/* defines for inflate input/output */
-/* update pointers and return */
-#define UPDBITS {s->bitb=b;s->bitk=k;}
-#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-#define UPDOUT {s->write=q;}
-#define UPDATE {UPDBITS UPDIN UPDOUT}
-#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-/* get bytes and bits */
-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-#define NEXTBYTE (n--,*p++)
-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define DUMPBITS(j) {b>>=(j);k-=(j);}
-/* output bytes */
-#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
-#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
-#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-/* load local pointers */
-#define LOAD {LOADIN LOADOUT}
-
-/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
-extern uInt inflate_mask[17];
-
-/* copy as much as possible from the sliding window to the output area */
-extern int inflate_flush OF((
- inflate_blocks_statef *,
- z_streamp ,
- int));
-
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-#endif
diff --git a/src/utilfuns/zlib/maketree.c b/src/utilfuns/zlib/maketree.c
deleted file mode 100644
index a16d4b1..0000000
--- a/src/utilfuns/zlib/maketree.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* maketree.c -- make inffixed.h table for decoding fixed codes
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* This program is included in the distribution for completeness.
- You do not need to compile or run this program since inffixed.h
- is already included in the distribution. To use this program
- you need to compile zlib with BUILDFIXED defined and then compile
- and link this program with the zlib library. Then the output of
- this program can be piped to inffixed.h. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "zutil.h"
-#include "inftrees.h"
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* generate initialization table for an inflate_huft structure array */
-void maketree(uInt b, inflate_huft *t)
-{
- int i, e;
-
- i = 0;
- while (1)
- {
- e = t[i].exop;
- if (e && (e & (16+64)) == 0) /* table pointer */
- {
- fprintf(stderr, "maketree: cannot initialize sub-tables!\n");
- exit(1);
- }
- if (i % 4 == 0)
- printf("\n ");
- printf(" {{{%u,%u}},%u}", t[i].exop, t[i].bits, t[i].base);
- if (++i == (1<<b))
- break;
- putchar(',');
- }
- puts("");
-}
-
-/* create the fixed tables in C initialization syntax */
-void main(void)
-{
- int r;
- uInt bl, bd;
- inflate_huft *tl, *td;
- z_stream z;
-
- z.zalloc = zcalloc;
- z.opaque = (voidpf)0;
- z.zfree = zcfree;
- r = inflate_trees_fixed(&bl, &bd, &tl, &td, &z);
- if (r)
- {
- fprintf(stderr, "inflate_trees_fixed error %d\n", r);
- return;
- }
- puts("/* inffixed.h -- table for decoding fixed codes");
- puts(" * Generated automatically by the maketree.c program");
- puts(" */");
- puts("");
- puts("/* WARNING: this file should *not* be used by applications. It is");
- puts(" part of the implementation of the compression library and is");
- puts(" subject to change. Applications should only use zlib.h.");
- puts(" */");
- puts("");
- printf("local uInt fixed_bl = %d;\n", bl);
- printf("local uInt fixed_bd = %d;\n", bd);
- printf("local inflate_huft fixed_tl[] = {");
- maketree(bl, tl);
- puts(" };");
- printf("local inflate_huft fixed_td[] = {");
- maketree(bd, td);
- puts(" };");
-}
diff --git a/src/utilfuns/zlib/trees.c b/src/utilfuns/zlib/trees.c
deleted file mode 100644
index b3117b3..0000000
--- a/src/utilfuns/zlib/trees.c
+++ /dev/null
@@ -1,1214 +0,0 @@
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2002 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process uses several Huffman trees. The more
- * common source values are represented by shorter bit sequences.
- *
- * Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values). The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- * Storer, James A.
- * Data Compression: Methods and Theory, pp. 49-50.
- * Computer Science Press, 1988. ISBN 0-7167-8156-5.
- *
- * Sedgewick, R.
- * Algorithms, p290.
- * Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
-/* @(#) $Id: trees.c 1688 2005-01-01 04:42:26Z scribe $ */
-
-/* #define GEN_TREES_H */
-
-#include "deflate.h"
-
-#ifdef DEBUG
-# include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6 16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10 17
-/* repeat a zero length 3-10 times (3 bits of repeat count) */
-
-#define REPZ_11_138 18
-/* repeat a zero length 11-138 times (7 bits of repeat count) */
-
-local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
- = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local const int extra_dbits[D_CODES] /* extra bits for each distance code */
- = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
- = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local const uch bl_order[BL_CODES]
- = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
-/* non ANSI compilers may not accept trees.h */
-
-local ct_data static_ltree[L_CODES+2];
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-local ct_data static_dtree[D_CODES];
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-uch _dist_code[DIST_CODE_LEN];
-/* Distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-uch _length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-#else
-# include "trees.h"
-#endif /* GEN_TREES_H */
-
-struct static_tree_desc_s {
- const ct_data *static_tree; /* static tree or NULL */
- const intf *extra_bits; /* extra bits for each code or NULL */
- int extra_base; /* base index for extra_bits */
- int elems; /* max number of elements in the tree */
- int max_length; /* max bit length for the codes */
-};
-
-local static_tree_desc static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc static_d_desc =
-{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-
-local static_tree_desc static_bl_desc =
-{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block OF((deflate_state *s));
-local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
-local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree OF((deflate_state *s, tree_desc *desc));
-local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local int build_bl_tree OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
- int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
-local void set_data_type OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup OF((deflate_state *s));
-local void bi_flush OF((deflate_state *s));
-local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
- int header));
-
-#ifdef GEN_TREES_H
-local void gen_trees_header OF((void));
-#endif
-
-#ifndef DEBUG
-# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
- /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG */
-# define send_code(s, c, tree) \
- { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
- send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
- put_byte(s, (uch)((w) & 0xff)); \
- put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG
-local void send_bits OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
- deflate_state *s;
- int value; /* value to send */
- int length; /* number of bits */
-{
- Tracevv((stderr," l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- s->bits_sent += (ulg)length;
-
- /* If not enough room in bi_buf, use (valid) bits from bi_buf and
- * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
- * unused bits in value.
- */
- if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
- put_short(s, s->bi_buf);
- s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
- s->bi_valid += length - Buf_size;
- } else {
- s->bi_buf |= value << s->bi_valid;
- s->bi_valid += length;
- }
-}
-#else /* !DEBUG */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
- if (s->bi_valid > (int)Buf_size - len) {\
- int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
- put_short(s, s->bi_buf);\
- s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
- s->bi_valid += len - Buf_size;\
- } else {\
- s->bi_buf |= (value) << s->bi_valid;\
- s->bi_valid += len;\
- }\
-}
-#endif /* DEBUG */
-
-
-#define MAX(a,b) (a >= b ? a : b)
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables.
- */
-local void tr_static_init()
-{
-#if defined(GEN_TREES_H) || !defined(STDC)
- static int static_init_done = 0;
- int n; /* iterates over tree elements */
- int bits; /* bit counter */
- int length; /* length value */
- int code; /* code value */
- int dist; /* distance index */
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- if (static_init_done) return;
-
- /* For some embedded targets, global variables are not initialized: */
- static_l_desc.static_tree = static_ltree;
- static_l_desc.extra_bits = extra_lbits;
- static_d_desc.static_tree = static_dtree;
- static_d_desc.extra_bits = extra_dbits;
- static_bl_desc.extra_bits = extra_blbits;
-
- /* Initialize the mapping length (0..255) -> length code (0..28) */
- length = 0;
- for (code = 0; code < LENGTH_CODES-1; code++) {
- base_length[code] = length;
- for (n = 0; n < (1<<extra_lbits[code]); n++) {
- _length_code[length++] = (uch)code;
- }
- }
- Assert (length == 256, "tr_static_init: length != 256");
- /* Note that the length 255 (match length 258) can be represented
- * in two different ways: code 284 + 5 bits or code 285, so we
- * overwrite length_code[255] to use the best encoding:
- */
- _length_code[length-1] = (uch)code;
-
- /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
- dist = 0;
- for (code = 0 ; code < 16; code++) {
- base_dist[code] = dist;
- for (n = 0; n < (1<<extra_dbits[code]); n++) {
- _dist_code[dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: dist != 256");
- dist >>= 7; /* from now on, all distances are divided by 128 */
- for ( ; code < D_CODES; code++) {
- base_dist[code] = dist << 7;
- for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
- _dist_code[256 + dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
- /* Construct the codes of the static literal tree */
- for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
- n = 0;
- while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
- while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
- while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
- while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
- /* Codes 286 and 287 do not exist, but we must include them in the
- * tree construction to get a canonical Huffman tree (longest code
- * all ones)
- */
- gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
- /* The static distance tree is trivial: */
- for (n = 0; n < D_CODES; n++) {
- static_dtree[n].Len = 5;
- static_dtree[n].Code = bi_reverse((unsigned)n, 5);
- }
- static_init_done = 1;
-
-# ifdef GEN_TREES_H
- gen_trees_header();
-# endif
-#endif /* defined(GEN_TREES_H) || !defined(STDC) */
-}
-
-/* ===========================================================================
- * Genererate the file trees.h describing the static trees.
- */
-#ifdef GEN_TREES_H
-# ifndef DEBUG
-# include <stdio.h>
-# endif
-
-# define SEPARATOR(i, last, width) \
- ((i) == (last)? "\n};\n\n" : \
- ((i) % (width) == (width)-1 ? ",\n" : ", "))
-
-void gen_trees_header()
-{
- FILE *header = fopen("trees.h", "w");
- int i;
-
- Assert (header != NULL, "Can't open trees.h");
- fprintf(header,
- "/* header created automatically with -DGEN_TREES_H */\n\n");
-
- fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
- for (i = 0; i < L_CODES+2; i++) {
- fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
- static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
- }
-
- fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
- static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
- }
-
- fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
- for (i = 0; i < DIST_CODE_LEN; i++) {
- fprintf(header, "%2u%s", _dist_code[i],
- SEPARATOR(i, DIST_CODE_LEN-1, 20));
- }
-
- fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
- for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
- fprintf(header, "%2u%s", _length_code[i],
- SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
- }
-
- fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
- for (i = 0; i < LENGTH_CODES; i++) {
- fprintf(header, "%1u%s", base_length[i],
- SEPARATOR(i, LENGTH_CODES-1, 20));
- }
-
- fprintf(header, "local const int base_dist[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "%5u%s", base_dist[i],
- SEPARATOR(i, D_CODES-1, 10));
- }
-
- fclose(header);
-}
-#endif /* GEN_TREES_H */
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-void _tr_init(s)
- deflate_state *s;
-{
- tr_static_init();
-
- s->l_desc.dyn_tree = s->dyn_ltree;
- s->l_desc.stat_desc = &static_l_desc;
-
- s->d_desc.dyn_tree = s->dyn_dtree;
- s->d_desc.stat_desc = &static_d_desc;
-
- s->bl_desc.dyn_tree = s->bl_tree;
- s->bl_desc.stat_desc = &static_bl_desc;
-
- s->bi_buf = 0;
- s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG
- s->compressed_len = 0L;
- s->bits_sent = 0L;
-#endif
-
- /* Initialize the first block of the first file: */
- init_block(s);
-}
-
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
- deflate_state *s;
-{
- int n; /* iterates over tree elements */
-
- /* Initialize the trees. */
- for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
- for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
- for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
- s->dyn_ltree[END_BLOCK].Freq = 1;
- s->opt_len = s->static_len = 0L;
- s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-/* Index within the heap array of least frequent node in the Huffman tree */
-
-
-/* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
-#define pqremove(s, tree, top) \
-{\
- top = s->heap[SMALLEST]; \
- s->heap[SMALLEST] = s->heap[s->heap_len--]; \
- pqdownheap(s, tree, SMALLEST); \
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-#define smaller(tree, n, m, depth) \
- (tree[n].Freq < tree[m].Freq || \
- (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-local void pqdownheap(s, tree, k)
- deflate_state *s;
- ct_data *tree; /* the tree to restore */
- int k; /* node to move down */
-{
- int v = s->heap[k];
- int j = k << 1; /* left son of k */
- while (j <= s->heap_len) {
- /* Set j to the smallest of the two sons: */
- if (j < s->heap_len &&
- smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
- j++;
- }
- /* Exit if v is smaller than both sons */
- if (smaller(tree, v, s->heap[j], s->depth)) break;
-
- /* Exchange v with the smallest son */
- s->heap[k] = s->heap[j]; k = j;
-
- /* And continue down the tree, setting j to the left son of k */
- j <<= 1;
- }
- s->heap[k] = v;
-}
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- * above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- * array bl_count contains the frequencies for each bit length.
- * The length opt_len is updated; static_len is also updated if stree is
- * not null.
- */
-local void gen_bitlen(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- int max_code = desc->max_code;
- const ct_data *stree = desc->stat_desc->static_tree;
- const intf *extra = desc->stat_desc->extra_bits;
- int base = desc->stat_desc->extra_base;
- int max_length = desc->stat_desc->max_length;
- int h; /* heap index */
- int n, m; /* iterate over the tree elements */
- int bits; /* bit length */
- int xbits; /* extra bits */
- ush f; /* frequency */
- int overflow = 0; /* number of elements with bit length too large */
-
- for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
- /* In a first pass, compute the optimal bit lengths (which may
- * overflow in the case of the bit length tree).
- */
- tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
- for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
- n = s->heap[h];
- bits = tree[tree[n].Dad].Len + 1;
- if (bits > max_length) bits = max_length, overflow++;
- tree[n].Len = (ush)bits;
- /* We overwrite tree[n].Dad which is no longer needed */
-
- if (n > max_code) continue; /* not a leaf node */
-
- s->bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n-base];
- f = tree[n].Freq;
- s->opt_len += (ulg)f * (bits + xbits);
- if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
- }
- if (overflow == 0) return;
-
- Trace((stderr,"\nbit length overflow\n"));
- /* This happens for example on obj2 and pic of the Calgary corpus */
-
- /* Find the first bit length which could increase: */
- do {
- bits = max_length-1;
- while (s->bl_count[bits] == 0) bits--;
- s->bl_count[bits]--; /* move one leaf down the tree */
- s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
- s->bl_count[max_length]--;
- /* The brother of the overflow item also moves one step up,
- * but this does not affect bl_count[max_length]
- */
- overflow -= 2;
- } while (overflow > 0);
-
- /* Now recompute all bit lengths, scanning in increasing frequency.
- * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
- * lengths instead of fixing only the wrong ones. This idea is taken
- * from 'ar' written by Haruhiko Okumura.)
- */
- for (bits = max_length; bits != 0; bits--) {
- n = s->bl_count[bits];
- while (n != 0) {
- m = s->heap[--h];
- if (m > max_code) continue;
- if (tree[m].Len != (unsigned) bits) {
- Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
- s->opt_len += ((long)bits - (long)tree[m].Len)
- *(long)tree[m].Freq;
- tree[m].Len = (ush)bits;
- }
- n--;
- }
- }
-}
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- * zero code length.
- */
-local void gen_codes (tree, max_code, bl_count)
- ct_data *tree; /* the tree to decorate */
- int max_code; /* largest code with non zero frequency */
- ushf *bl_count; /* number of codes at each bit length */
-{
- ush next_code[MAX_BITS+1]; /* next code value for each bit length */
- ush code = 0; /* running code value */
- int bits; /* bit index */
- int n; /* code index */
-
- /* The distribution counts are first used to generate the code values
- * without bit reversal.
- */
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits-1]) << 1;
- }
- /* Check that the bit counts in bl_count are consistent. The last code
- * must be all ones.
- */
- Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
- "inconsistent bit counts");
- Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
- for (n = 0; n <= max_code; n++) {
- int len = tree[n].Len;
- if (len == 0) continue;
- /* Now reverse the bits */
- tree[n].Code = bi_reverse(next_code[len]++, len);
-
- Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
- n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
- }
-}
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- * and corresponding code. The length opt_len is updated; static_len is
- * also updated if stree is not null. The field max_code is set.
- */
-local void build_tree(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- const ct_data *stree = desc->stat_desc->static_tree;
- int elems = desc->stat_desc->elems;
- int n, m; /* iterate over heap elements */
- int max_code = -1; /* largest code with non zero frequency */
- int node; /* new node being created */
-
- /* Construct the initial heap, with least frequent element in
- * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
- * heap[0] is not used.
- */
- s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
- for (n = 0; n < elems; n++) {
- if (tree[n].Freq != 0) {
- s->heap[++(s->heap_len)] = max_code = n;
- s->depth[n] = 0;
- } else {
- tree[n].Len = 0;
- }
- }
-
- /* The pkzip format requires that at least one distance code exists,
- * and that at least one bit should be sent even if there is only one
- * possible code. So to avoid special checks later on we force at least
- * two codes of non zero frequency.
- */
- while (s->heap_len < 2) {
- node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
- tree[node].Freq = 1;
- s->depth[node] = 0;
- s->opt_len--; if (stree) s->static_len -= stree[node].Len;
- /* node is 0 or 1 so it does not have extra bits */
- }
- desc->max_code = max_code;
-
- /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
- * establish sub-heaps of increasing lengths:
- */
- for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
- /* Construct the Huffman tree by repeatedly combining the least two
- * frequent nodes.
- */
- node = elems; /* next internal node of the tree */
- do {
- pqremove(s, tree, n); /* n = node of least frequency */
- m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
- s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
- s->heap[--(s->heap_max)] = m;
-
- /* Create a new node father of n and m */
- tree[node].Freq = tree[n].Freq + tree[m].Freq;
- s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
- tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
- if (tree == s->bl_tree) {
- fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
- node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
- }
-#endif
- /* and insert the new node in the heap */
- s->heap[SMALLEST] = node++;
- pqdownheap(s, tree, SMALLEST);
-
- } while (s->heap_len >= 2);
-
- s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
- /* At this point, the fields freq and dad are set. We can now
- * generate the bit lengths.
- */
- gen_bitlen(s, (tree_desc *)desc);
-
- /* The field len is now set, we can generate the bit codes */
- gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-local void scan_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- if (nextlen == 0) max_count = 138, min_count = 3;
- tree[max_code+1].Len = (ush)0xffff; /* guard */
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- s->bl_tree[curlen].Freq += count;
- } else if (curlen != 0) {
- if (curlen != prevlen) s->bl_tree[curlen].Freq++;
- s->bl_tree[REP_3_6].Freq++;
- } else if (count <= 10) {
- s->bl_tree[REPZ_3_10].Freq++;
- } else {
- s->bl_tree[REPZ_11_138].Freq++;
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-local void send_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- /* tree[max_code+1].Len = -1; */ /* guard already set */
- if (nextlen == 0) max_count = 138, min_count = 3;
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- send_code(s, curlen, s->bl_tree); count--;
- }
- Assert(count >= 3 && count <= 6, " 3_6?");
- send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
- } else if (count <= 10) {
- send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
- } else {
- send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-local int build_bl_tree(s)
- deflate_state *s;
-{
- int max_blindex; /* index of last bit length code of non zero freq */
-
- /* Determine the bit length frequencies for literal and distance trees */
- scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
- scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
- /* Build the bit length tree: */
- build_tree(s, (tree_desc *)(&(s->bl_desc)));
- /* opt_len now includes the length of the tree representations, except
- * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
- */
-
- /* Determine the number of bit length codes to send. The pkzip format
- * requires that at least 4 bit length codes be sent. (appnote.txt says
- * 3 but the actual value used is 4.)
- */
- for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
- if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
- }
- /* Update opt_len to include the bit length tree and counts */
- s->opt_len += 3*(max_blindex+1) + 5+5+4;
- Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
- s->opt_len, s->static_len));
-
- return max_blindex;
-}
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
- deflate_state *s;
- int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
- int rank; /* index in bl_order */
-
- Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
- Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
- "too many codes");
- Tracev((stderr, "\nbl counts: "));
- send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
- send_bits(s, dcodes-1, 5);
- send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
- for (rank = 0; rank < blcodes; rank++) {
- Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
- send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
- }
- Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
- Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
- Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-/* ===========================================================================
- * Send a stored block
- */
-void _tr_stored_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-#ifdef DEBUG
- s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
- s->compressed_len += (stored_len + 4) << 3;
-#endif
- copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
- */
-void _tr_align(s)
- deflate_state *s;
-{
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-#endif
- bi_flush(s);
- /* Of the 10 bits for the empty block, we have already sent
- * (10 - bi_valid) bits. The lookahead for the last real code (before
- * the EOB of the previous block) was thus at least one plus the length
- * of the EOB plus what we have just sent of the empty static block.
- */
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L;
-#endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
-}
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
- */
-void _tr_flush_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block, or NULL if too old */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
- int max_blindex = 0; /* index of last bit length code of non zero freq */
-
- /* Build the Huffman trees unless a stored block is forced */
- if (s->level > 0) {
-
- /* Check if the file is ascii or binary */
- if (s->data_type == Z_UNKNOWN) set_data_type(s);
-
- /* Construct the literal and distance trees */
- build_tree(s, (tree_desc *)(&(s->l_desc)));
- Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
-
- build_tree(s, (tree_desc *)(&(s->d_desc)));
- Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
- /* At this point, opt_len and static_len are the total bit lengths of
- * the compressed block data, excluding the tree representations.
- */
-
- /* Build the bit length tree for the above two trees, and get the index
- * in bl_order of the last bit length code to send.
- */
- max_blindex = build_bl_tree(s);
-
- /* Determine the best encoding. Compute first the block length in bytes*/
- opt_lenb = (s->opt_len+3+7)>>3;
- static_lenb = (s->static_len+3+7)>>3;
-
- Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
- opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
- s->last_lit));
-
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
- } else {
- Assert(buf != (char*)0, "lost buf");
- opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
- }
-
-#ifdef FORCE_STORED
- if (buf != (char*)0) { /* force stored block */
-#else
- if (stored_len+4 <= opt_lenb && buf != (char*)0) {
- /* 4: two words for the lengths */
-#endif
- /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
- * Otherwise we can't have processed more than WSIZE input bytes since
- * the last block flush, because compression would have been
- * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
- * transform a block into a stored block.
- */
- _tr_stored_block(s, buf, stored_len, eof);
-
-#ifdef FORCE_STATIC
- } else if (static_lenb >= 0) { /* force static trees */
-#else
- } else if (static_lenb == opt_lenb) {
-#endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->static_len;
-#endif
- } else {
- send_bits(s, (DYN_TREES<<1)+eof, 3);
- send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
- max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->opt_len;
-#endif
- }
- Assert (s->compressed_len == s->bits_sent, "bad compressed size");
- /* The above check is made mod 2^32, for files larger than 512 MB
- * and uLong implemented on 32 bits.
- */
- init_block(s);
-
- if (eof) {
- bi_windup(s);
-#ifdef DEBUG
- s->compressed_len += 7; /* align on byte boundary */
-#endif
- }
- Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*eof));
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-int _tr_tally (s, dist, lc)
- deflate_state *s;
- unsigned dist; /* distance of matched string */
- unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
- s->d_buf[s->last_lit] = (ush)dist;
- s->l_buf[s->last_lit++] = (uch)lc;
- if (dist == 0) {
- /* lc is the unmatched char */
- s->dyn_ltree[lc].Freq++;
- } else {
- s->matches++;
- /* Here, lc is the match length - MIN_MATCH */
- dist--; /* dist = match distance - 1 */
- Assert((ush)dist < (ush)MAX_DIST(s) &&
- (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
- (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-
- s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
- s->dyn_dtree[d_code(dist)].Freq++;
- }
-
-#ifdef TRUNCATE_BLOCK
- /* Try to guess if it is profitable to stop the current block here */
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
- /* Compute an upper bound for the compressed length */
- ulg out_length = (ulg)s->last_lit*8L;
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
- (5L+extra_dbits[dcode]);
- }
- out_length >>= 3;
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
- s->last_lit, in_length, out_length,
- 100L - out_length*100L/in_length));
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
- }
-#endif
- return (s->last_lit == s->lit_bufsize-1);
- /* We avoid equality with lit_bufsize because of wraparound at 64K
- * on 16 bit machines and because stored blocks are restricted to
- * 64K-1 bytes.
- */
-}
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
- deflate_state *s;
- ct_data *ltree; /* literal tree */
- ct_data *dtree; /* distance tree */
-{
- unsigned dist; /* distance of matched string */
- int lc; /* match length or unmatched char (if dist == 0) */
- unsigned lx = 0; /* running index in l_buf */
- unsigned code; /* the code to send */
- int extra; /* number of extra bits to send */
-
- if (s->last_lit != 0) do {
- dist = s->d_buf[lx];
- lc = s->l_buf[lx++];
- if (dist == 0) {
- send_code(s, lc, ltree); /* send a literal byte */
- Tracecv(isgraph(lc), (stderr," '%c' ", lc));
- } else {
- /* Here, lc is the match length - MIN_MATCH */
- code = _length_code[lc];
- send_code(s, code+LITERALS+1, ltree); /* send the length code */
- extra = extra_lbits[code];
- if (extra != 0) {
- lc -= base_length[code];
- send_bits(s, lc, extra); /* send the extra length bits */
- }
- dist--; /* dist is now the match distance - 1 */
- code = d_code(dist);
- Assert (code < D_CODES, "bad d_code");
-
- send_code(s, code, dtree); /* send the distance code */
- extra = extra_dbits[code];
- if (extra != 0) {
- dist -= base_dist[code];
- send_bits(s, dist, extra); /* send the extra distance bits */
- }
- } /* literal or match pair ? */
-
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
- Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
-
- } while (lx < s->last_lit);
-
- send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
-}
-
-/* ===========================================================================
- * Set the data type to ASCII or BINARY, using a crude approximation:
- * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
- * IN assertion: the fields freq of dyn_ltree are set and the total of all
- * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
- */
-local void set_data_type(s)
- deflate_state *s;
-{
- int n = 0;
- unsigned ascii_freq = 0;
- unsigned bin_freq = 0;
- while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
- while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
- while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
- s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
- unsigned code; /* the value to invert */
- int len; /* its bit length */
-{
- register unsigned res = 0;
- do {
- res |= code & 1;
- code >>= 1, res <<= 1;
- } while (--len > 0);
- return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
- deflate_state *s;
-{
- if (s->bi_valid == 16) {
- put_short(s, s->bi_buf);
- s->bi_buf = 0;
- s->bi_valid = 0;
- } else if (s->bi_valid >= 8) {
- put_byte(s, (Byte)s->bi_buf);
- s->bi_buf >>= 8;
- s->bi_valid -= 8;
- }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
- deflate_state *s;
-{
- if (s->bi_valid > 8) {
- put_short(s, s->bi_buf);
- } else if (s->bi_valid > 0) {
- put_byte(s, (Byte)s->bi_buf);
- }
- s->bi_buf = 0;
- s->bi_valid = 0;
-#ifdef DEBUG
- s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
- deflate_state *s;
- charf *buf; /* the input data */
- unsigned len; /* its length */
- int header; /* true if block header must be written */
-{
- bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
-
- if (header) {
- put_short(s, (ush)len);
- put_short(s, (ush)~len);
-#ifdef DEBUG
- s->bits_sent += 2*16;
-#endif
- }
-#ifdef DEBUG
- s->bits_sent += (ulg)len<<3;
-#endif
- while (len--) {
- put_byte(s, *buf++);
- }
-}
diff --git a/src/utilfuns/zlib/trees.h b/src/utilfuns/zlib/trees.h
deleted file mode 100644
index 72facf9..0000000
--- a/src/utilfuns/zlib/trees.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* header created automatically with -DGEN_TREES_H */
-
-local const ct_data static_ltree[L_CODES+2] = {
-{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
-{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
-{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
-{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
-{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
-{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
-{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
-{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
-{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
-{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
-{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
-{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
-{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
-{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
-{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
-{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
-{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
-{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
-{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
-{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
-{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
-{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
-{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
-{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
-{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
-{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
-{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
-{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
-{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
-{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
-{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
-{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
-{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
-{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
-{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
-{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
-{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
-{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
-{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
-{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
-{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
-{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
-{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
-{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
-{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
-{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
-{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
-{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
-{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
-{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
-{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
-{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
-{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
-{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
-{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
-{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
-{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
-{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
-};
-
-local const ct_data static_dtree[D_CODES] = {
-{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
-{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
-{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
-{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
-{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
-{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
-};
-
-const uch _dist_code[DIST_CODE_LEN] = {
- 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
-10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
-18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
-};
-
-const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
-13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
-17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
-19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
-22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
-};
-
-local const int base_length[LENGTH_CODES] = {
-0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
-64, 80, 96, 112, 128, 160, 192, 224, 0
-};
-
-local const int base_dist[D_CODES] = {
- 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
- 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
- 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
-};
-
diff --git a/src/utilfuns/zlib/uncompr.c b/src/utilfuns/zlib/uncompr.c
deleted file mode 100644
index 45a4687..0000000
--- a/src/utilfuns/zlib/uncompr.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* uncompr.c -- decompress a memory buffer
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: uncompr.c 1688 2005-01-01 04:42:26Z scribe $ */
-
-#include "zlib.h"
-
-/* ===========================================================================
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted.
-*/
-int ZEXPORT uncompress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
-
- err = inflateInit(&stream);
- if (err != Z_OK) return err;
-
- err = inflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- inflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = inflateEnd(&stream);
- return err;
-}
diff --git a/src/utilfuns/zlib/zutil.c b/src/utilfuns/zlib/zutil.c
deleted file mode 100644
index 55e047c..0000000
--- a/src/utilfuns/zlib/zutil.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: zutil.c 1688 2005-01-01 04:42:26Z scribe $ */
-
-#include "zutil.h"
-
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-#ifndef STDC
-extern void exit OF((int));
-#endif
-
-const char *z_errmsg[10] = {
-"need dictionary", /* Z_NEED_DICT 2 */
-"stream end", /* Z_STREAM_END 1 */
-"", /* Z_OK 0 */
-"file error", /* Z_ERRNO (-1) */
-"stream error", /* Z_STREAM_ERROR (-2) */
-"data error", /* Z_DATA_ERROR (-3) */
-"insufficient memory", /* Z_MEM_ERROR (-4) */
-"buffer error", /* Z_BUF_ERROR (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
-
-
-const char * ZEXPORT zlibVersion()
-{
- return ZLIB_VERSION;
-}
-
-#ifdef DEBUG
-
-# ifndef verbose
-# define verbose 0
-# endif
-int z_verbose = verbose;
-
-void z_error (m)
- char *m;
-{
- fprintf(stderr, "%s\n", m);
- exit(1);
-}
-#endif
-
-/* exported to allow conversion of error code to string for compress() and
- * uncompress()
- */
-const char * ZEXPORT zError(err)
- int err;
-{
- return ERR_MSG(err);
-}
-
-
-#ifndef HAVE_MEMCPY
-
-void zmemcpy(dest, source, len)
- Bytef* dest;
- const Bytef* source;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = *source++; /* ??? to be unrolled */
- } while (--len != 0);
-}
-
-int zmemcmp(s1, s2, len)
- const Bytef* s1;
- const Bytef* s2;
- uInt len;
-{
- uInt j;
-
- for (j = 0; j < len; j++) {
- if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
- }
- return 0;
-}
-
-void zmemzero(dest, len)
- Bytef* dest;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = 0; /* ??? to be unrolled */
- } while (--len != 0);
-}
-#endif
-
-#ifdef __TURBOC__
-#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
-/* Small and medium model in Turbo C are for now limited to near allocation
- * with reduced MAX_WBITS and MAX_MEM_LEVEL
- */
-# define MY_ZCALLOC
-
-/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with an offset of 8, so we
- * must fix the pointer. Warning: the pointer must be put back to its
- * original form in order to free it, use zcfree().
- */
-
-#define MAX_PTR 10
-/* 10*64K = 640K */
-
-local int next_ptr = 0;
-
-typedef struct ptr_table_s {
- voidpf org_ptr;
- voidpf new_ptr;
-} ptr_table;
-
-local ptr_table table[MAX_PTR];
-/* This table is used to remember the original form of pointers
- * to large buffers (64K). Such pointers are normalized with a zero offset.
- * Since MSDOS is not a preemptive multitasking OS, this table is not
- * protected from concurrent access. This hack doesn't work anyway on
- * a protected system like OS/2. Use Microsoft C instead.
- */
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- voidpf buf = opaque; /* just to make some compilers happy */
- ulg bsize = (ulg)items*size;
-
- /* If we allocate less than 65520 bytes, we assume that farmalloc
- * will return a usable pointer which doesn't have to be normalized.
- */
- if (bsize < 65520L) {
- buf = farmalloc(bsize);
- if (*(ush*)&buf != 0) return buf;
- } else {
- buf = farmalloc(bsize + 16L);
- }
- if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
- table[next_ptr].org_ptr = buf;
-
- /* Normalize the pointer to seg:0 */
- *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
- *(ush*)&buf = 0;
- table[next_ptr++].new_ptr = buf;
- return buf;
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- int n;
- if (*(ush*)&ptr != 0) { /* object < 64K */
- farfree(ptr);
- return;
- }
- /* Find the original pointer */
- for (n = 0; n < next_ptr; n++) {
- if (ptr != table[n].new_ptr) continue;
-
- farfree(table[n].org_ptr);
- while (++n < next_ptr) {
- table[n-1] = table[n];
- }
- next_ptr--;
- return;
- }
- ptr = opaque; /* just to make some compilers happy */
- Assert(0, "zcfree: ptr not found");
-}
-#endif
-#endif /* __TURBOC__ */
-
-
-#if defined(M_I86) && !defined(__32BIT__)
-/* Microsoft C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
-# define _halloc halloc
-# define _hfree hfree
-#endif
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- return _halloc((long)items, size);
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- _hfree(ptr);
-}
-
-#endif /* MSC */
-
-
-#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
-#ifndef STDC
-extern voidp calloc OF((uInt items, uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-voidpf zcalloc (opaque, items, size)
- voidpf opaque;
- unsigned items;
- unsigned size;
-{
- if (opaque) items += size - size; /* make compiler happy */
- return (voidpf)calloc(items, size);
-}
-
-void zcfree (opaque, ptr)
- voidpf opaque;
- voidpf ptr;
-{
- free(ptr);
- if (opaque) return; /* make compiler happy */
-}
-
-#endif /* MY_ZCALLOC */
diff --git a/src/utilfuns/zlib/zutil.h b/src/utilfuns/zlib/zutil.h
deleted file mode 100644
index 538fc57..0000000
--- a/src/utilfuns/zlib/zutil.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id: zutil.h 1688 2005-01-01 04:42:26Z scribe $ */
-
-#ifndef _Z_UTIL_H
-#define _Z_UTIL_H
-
-#include "zlib.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
-/* (size given to avoid silly warnings with Visual C++) */
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
-#define ERR_RETURN(strm,err) \
- return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
- /* common constants */
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
- /* target dependencies */
-
-#ifdef MSDOS
-# define OS_CODE 0x00
-# if defined(__TURBOC__) || defined(__BORLANDC__)
-# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
- /* Allow compilation with ANSI keywords only enabled */
- void _Cdecl farfree( void *block );
- void *_Cdecl farmalloc( unsigned long nbytes );
-# else
-# include <alloc.h>
-# endif
-# else /* MSC or DJGPP */
-# include <malloc.h>
-# endif
-#endif
-
-#ifdef OS2
-# define OS_CODE 0x06
-#endif
-
-#ifdef WIN32 /* Window 95 & Windows NT */
-# define OS_CODE 0x0b
-#endif
-
-#if defined(VAXC) || defined(VMS)
-# define OS_CODE 0x02
-# define F_OPEN(name, mode) \
- fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
-#ifdef AMIGA
-# define OS_CODE 0x01
-#endif
-
-#if defined(ATARI) || defined(atarist)
-# define OS_CODE 0x05
-#endif
-
-#if defined(MACOS) || defined(TARGET_OS_MAC)
-# define OS_CODE 0x07
-# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fdopen */
-# else
-# ifndef fdopen
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# endif
-# endif
-#endif
-
-#ifdef __50SERIES /* Prime/PRIMOS */
-# define OS_CODE 0x0F
-#endif
-
-#ifdef TOPS20
-# define OS_CODE 0x0a
-#endif
-
-#if defined(_BEOS_) || defined(RISCOS)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-#if (defined(_MSC_VER) && (_MSC_VER > 600))
-# define fdopen(fd,type) _fdopen(fd,type)
-#endif
-
-
- /* Common defaults */
-
-#ifndef OS_CODE
-# define OS_CODE 0x03 /* assume Unix */
-#endif
-
-#ifndef F_OPEN
-# define F_OPEN(name, mode) fopen((name), (mode))
-#endif
-
- /* functions */
-
-#ifdef HAVE_STRERROR
- extern char *strerror OF((int));
-# define zstrerror(errnum) strerror(errnum)
-#else
-# define zstrerror(errnum) ""
-#endif
-
-#if defined(pyr)
-# define NO_MEMCPY
-#endif
-#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
- /* Use our own functions for small and medium model with MSC <= 5.0.
- * You may have to use the same strategy for Borland C (untested).
- * The __SC__ check is for Symantec.
- */
-# define NO_MEMCPY
-#endif
-#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-# define HAVE_MEMCPY
-#endif
-#ifdef HAVE_MEMCPY
-# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-# define zmemcpy _fmemcpy
-# define zmemcmp _fmemcmp
-# define zmemzero(dest, len) _fmemset(dest, 0, len)
-# else
-# define zmemcpy memcpy
-# define zmemcmp memcmp
-# define zmemzero(dest, len) memset(dest, 0, len)
-# endif
-#else
- extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
- extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
- extern void zmemzero OF((Bytef* dest, uInt len));
-#endif
-
-/* Diagnostic functions */
-#ifdef DEBUG
-# include <stdio.h>
- extern int z_verbose;
- extern void z_error OF((char *m));
-# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-
-typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
- uInt len));
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void zcfree OF((voidpf opaque, voidpf ptr));
-
-#define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
-#endif /* _Z_UTIL_H */