diff options
Diffstat (limited to 'src')
148 files changed, 10643 insertions, 5980 deletions
diff --git a/src/frontend/swdisp.cpp b/src/frontend/swdisp.cpp index 30be052..bdb0a74 100644 --- a/src/frontend/swdisp.cpp +++ b/src/frontend/swdisp.cpp @@ -3,10 +3,14 @@ * types of displays (e.g. raw textout, curses, xwindow, etc.) */ -#include <iostream.h> +#include <iostream> #include <swmodule.h> #include <swdisp.h> +SWORD_NAMESPACE_START + +static const char *classes[] = {"SWDisplay", "SWObject", 0}; +SWClass SWDisplay::classdef(classes); /****************************************************************************** * SWDisplay::Display - casts a module to a character pointer and displays it to @@ -20,6 +24,8 @@ char SWDisplay::Display(SWModule &imodule) { - cout << (const char *)imodule; + std::cout << (const char *)imodule; return 0; } + +SWORD_NAMESPACE_END diff --git a/src/frontend/swlog.cpp b/src/frontend/swlog.cpp index d3efbfc..03cfc23 100644 --- a/src/frontend/swlog.cpp +++ b/src/frontend/swlog.cpp @@ -2,12 +2,16 @@ #include <stdarg.h> #include <stdio.h> -#ifndef _MSC_VER -#include <iostream.h> +#include <iostream> +#if defined(_ICU_) && !defined(_ICUSWORD_) +#define _USTDIO_ +#include <unicode/ustdio.h> +#include <unicode/ustream.h> #endif #include "swlog.h" //--------------------------------------------------------------------------- +SWORD_NAMESPACE_START SWLog *SWLog::systemlog = 0; @@ -25,17 +29,25 @@ public: void SWLog::LogWarning(char *fmt, ...) { + //#ifdef _USTDIO_ + //UChar msg[2048]; + //#else char msg[2048]; + //#endif va_list argptr; - if (log) { + if (logLevel >= 2) { va_start(argptr, fmt); + //#ifdef _USTDIO_ + //u_vsprintf(msg, NULL, fmt, argptr); + //#else vsprintf(msg, fmt, argptr); + //#endif va_end(argptr); -#ifndef _MSC_VER - cerr << msg; - cerr << "\n"; +#ifndef _WIN32_WCE + std::cerr << msg; + std::cerr << std::endl; #endif } } @@ -43,17 +55,25 @@ void SWLog::LogWarning(char *fmt, ...) void SWLog::LogError(char *fmt, ...) { + //#ifdef _USTDIO_ + //UChar msg[2048]; + //#else char msg[2048]; + //#endif va_list argptr; - if (log) { + if (logLevel) { va_start(argptr, fmt); + //#ifdef _USTDIO_ + //u_vsprintf(msg, NULL, fmt, argptr); + //#else vsprintf(msg, fmt, argptr); + //#endif va_end(argptr); -#ifndef _MSC_VER - cerr << msg; - cerr << "\n"; +#ifndef _WIN32_WCE + std::cerr << msg; + std::cerr << std::endl; #endif } } @@ -61,17 +81,25 @@ void SWLog::LogError(char *fmt, ...) void SWLog::LogTimedInformation(char *fmt, ...) { + //#ifdef _USTDIO_ + //UChar msg[2048]; + //#else char msg[2048]; + //#endif va_list argptr; - if (log) { + if (logLevel >= 4) { va_start(argptr, fmt); + //#ifdef _USTDIO_ + //u_vsprintf(msg, NULL, fmt, argptr); + //#else vsprintf(msg, fmt, argptr); + //#endif va_end(argptr); -#ifndef _MSC_VER - cout << msg; - cout << "\n"; +#ifndef _WIN32_WCE + std::cout << msg; + std::cout << std::endl; #endif } } @@ -79,17 +107,27 @@ void SWLog::LogTimedInformation(char *fmt, ...) void SWLog::LogInformation(char *fmt, ...) { + //#ifdef _USTDIO_ + //UChar msg[2048]; + //#else char msg[2048]; + //#endif va_list argptr; - if (log) { + if (logLevel >= 3) { va_start(argptr, fmt); + //#ifdef _USTDIO_ + //u_vsprintf(msg, NULL, fmt, argptr); + //#else vsprintf(msg, fmt, argptr); + //#endif va_end(argptr); -#ifndef _MSC_VER - cout << msg; - cout << "\n"; +#ifndef _WIN32_WCE + std::cout << msg; + std::cout << std::endl; #endif } -} +} + +SWORD_NAMESPACE_END diff --git a/src/keys/listkey.cpp b/src/keys/listkey.cpp index 2d87f80..1dec72b 100644 --- a/src/keys/listkey.cpp +++ b/src/keys/listkey.cpp @@ -5,11 +5,12 @@ */ #include <utilfuns.h> -#include <string.h> #include <stdlib.h> #include <swkey.h> #include <listkey.h> +SWORD_NAMESPACE_START + static const char *classes[] = {"ListKey", "SWKey", "SWObject", 0}; SWClass ListKey::classdef(classes); @@ -124,10 +125,10 @@ void ListKey::add(const SWKey &ikey) { void ListKey::setPosition(SW_POSITION p) { switch (p) { case 1: // GCC won't compile P_TOP - SetToElement(0); + SetToElement(0, p); break; case 2: // GCC won't compile P_BOTTOM - SetToElement(arraycnt-1); + SetToElement(arraycnt-1, p); break; } } @@ -145,11 +146,12 @@ void ListKey::increment(int step) { Error(); // clear error for(; step && !Error(); step--) { if (arraypos < arraycnt) { - (*(array[arraypos]))++; - if (array[arraypos]->Error()) { + if (array[arraypos]->isBoundSet()) + (*(array[arraypos]))++; + if ((array[arraypos]->Error()) || (!array[arraypos]->isBoundSet())) { SetToElement(arraypos+1); } - else *this = (const char *)(*array[arraypos]); + else SWKey::setText((const char *)(*array[arraypos])); } else error = KEYERR_OUTOFBOUNDS; } @@ -168,11 +170,12 @@ void ListKey::decrement(int step) { Error(); // clear error for(; step && !Error(); step--) { if (arraypos > -1) { - (*(array[arraypos]))--; - if (array[arraypos]->Error()) { + if (array[arraypos]->isBoundSet()) + (*(array[arraypos]))--; + if ((array[arraypos]->Error()) || (!array[arraypos]->isBoundSet())) { SetToElement(arraypos-1, BOTTOM); } - else *this = (const char *)(*array[arraypos]); + else SWKey::setText((const char *)(*array[arraypos])); } else error = KEYERR_OUTOFBOUNDS; } @@ -213,10 +216,11 @@ char ListKey::SetToElement(int ielement, SW_POSITION pos) { } if (arraycnt) { - (*array[arraypos]) = pos; - *this = (const char *)(*array[arraypos]); + if (array[arraypos]->isBoundSet()) + (*array[arraypos]) = pos; + SWKey::setText((const char *)(*array[arraypos])); } - else *this = ""; + else SWKey::setText(""); return error; } @@ -230,12 +234,13 @@ char ListKey::SetToElement(int ielement, SW_POSITION pos) { * RET: Key or null on error */ -SWKey *ListKey::GetElement(int pos) { - if (pos >=0) { - if (pos >=arraycnt) - error = KEYERR_OUTOFBOUNDS; - } - else pos = arraypos; +SWKey *ListKey::getElement(int pos) { + if (pos < 0) + pos = arraypos; + + if (pos >=arraycnt) + error = KEYERR_OUTOFBOUNDS; + return (error) ? 0:array[pos]; } @@ -254,3 +259,55 @@ void ListKey::Remove() { SetToElement((arraypos)?arraypos-1:0); } } + + +/****************************************************************************** + * ListKey::getRangeText - returns parsable range text for this key + */ + +const char *ListKey::getRangeText() const { + char *buf = new char[(arraycnt + 1) * 255]; + buf[0] = 0; + for (int i = 0; i < arraycnt; i++) { + strcat(buf, array[i]->getRangeText()); + if (i < arraycnt-1) + strcat(buf, "; "); + } + stdstr(&rangeText, buf); + delete [] buf; + return rangeText; +} + + +/****************************************************************************** + * ListKey::getText - returns text key if (const char *) cast is requested + */ + +const char *ListKey::getText() const { + int pos = arraypos; + SWKey *key = (pos >= arraycnt) ? 0:array[pos]; + return (key) ? key->getText() : keytext; +} + + +void ListKey::setText(const char *ikey) { + // at least try to set the current element to this text + int pos = arraypos; + for (arraypos = 0; arraypos < arraycnt; arraypos++) { + SWKey *key = array[arraypos]; + if (key) { + key->setText(ikey); + if (!key->Error()) + break; + } + } + if (arraypos >= arraycnt) { + error = 1; + arraypos = arraycnt-1; + } + + SWKey::setText(ikey); +} + +SWORD_NAMESPACE_END + diff --git a/src/keys/strkey.cpp b/src/keys/strkey.cpp index 7e2d539..587f185 100644 --- a/src/keys/strkey.cpp +++ b/src/keys/strkey.cpp @@ -7,9 +7,9 @@ #include <swmacs.h> #include <utilfuns.h> #include <strkey.h> -#include <string.h> #include <stdio.h> +SWORD_NAMESPACE_START static const char *classes[] = {"StrKey", "SWKey", "SWObject", 0}; SWClass StrKey::classdef(classes); @@ -39,3 +39,5 @@ void StrKey::init() { StrKey::~StrKey() { } + +SWORD_NAMESPACE_END diff --git a/src/keys/swkey.cpp b/src/keys/swkey.cpp index 0ed2e75..994402f 100644 --- a/src/keys/swkey.cpp +++ b/src/keys/swkey.cpp @@ -6,7 +6,8 @@ #include <swkey.h> #include <utilfuns.h> -#include <string.h> + +SWORD_NAMESPACE_START static const char *classes[] = {"SWKey", "SWObject", 0}; SWClass SWKey::classdef(classes); @@ -19,26 +20,31 @@ SWClass SWKey::classdef(classes); SWKey::SWKey(const char *ikey) { - index = 0; - persist = 0; - keytext = 0; - error = 0; + index = 0; + persist = 0; + keytext = 0; + rangeText = 0; + error = 0; + userData = 0; stdstr(&keytext, ikey); init(); } SWKey::SWKey(SWKey const &k) { - index = k.index; - persist = k.persist; - keytext = 0; - error = k.error; - stdstr(&keytext, k.keytext); + index = k.index; + persist = k.persist; + userData = k.userData; + keytext = 0; + rangeText = 0; + error = k.error; + setText(k.getText()); init(); } void SWKey::init() { myclass = &classdef; + boundSet = false; } SWKey *SWKey::clone() const @@ -53,12 +59,14 @@ SWKey *SWKey::clone() const SWKey::~SWKey() { if (keytext) delete [] keytext; + if (rangeText) + delete [] rangeText; } /****************************************************************************** * SWKey::Persist - Gets whether this object itself persists within a - * module that it was used to SetKey or just a copy. + * module that it was used to setKey or just a copy. * (1 - persists in module; 0 - a copy is attempted * * RET: value of persist @@ -72,7 +80,7 @@ char SWKey::Persist() const /****************************************************************************** * SWKey::Persist - Set/gets whether this object itself persists within a - * module that it was used to SetKey or just a copy. + * module that it was used to setKey or just a copy. * (1 - persists in module; 0 - a copy is attempted * * ENT: ipersist - value which to set persist @@ -129,7 +137,7 @@ void SWKey::copyFrom(const SWKey &ikey) { /****************************************************************************** - * SWKey::getText - returns text key if (char *) cast is requested + * SWKey::getText - returns text key if (const char *) cast is requested */ const char *SWKey::getText() const { @@ -138,6 +146,16 @@ const char *SWKey::getText() const { /****************************************************************************** + * SWKey::getRangeText - returns parsable range text for this key + */ + +const char *SWKey::getRangeText() const { + stdstr(&rangeText, keytext); + return rangeText; +} + + +/****************************************************************************** * SWKey::compare - Compares another VerseKey object * * ENT: ikey - key to compare with this one @@ -193,3 +211,5 @@ void SWKey::increment(int) { void SWKey::decrement(int) { error = KEYERR_OUTOFBOUNDS; } + +SWORD_NAMESPACE_END diff --git a/src/keys/treekey.cpp b/src/keys/treekey.cpp index c9eddb4..ce94775 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,v 1.1 2002/01/24 08:55:27 scribe Exp $ + * $Id: treekey.cpp,v 1.3 2002/10/01 19:52:40 dglassey Exp $ * * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society @@ -22,6 +22,13 @@ #include <treekey.h> +SWORD_NAMESPACE_START + static const char *classes[] = {"TreeKey", "SWKey", "SWObject", 0}; SWClass TreeKey::classdef(classes); +void TreeKey::init() { + myclass = &classdef; +} + +SWORD_NAMESPACE_END diff --git a/src/keys/treekeyidx.cpp b/src/keys/treekeyidx.cpp index e0d0fc7..e8fb3f8 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,v 1.5 2002/03/18 20:52:45 scribe Exp $ + * $Id: treekeyidx.cpp,v 1.14 2003/06/27 01:41:07 scribe Exp $ * * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society @@ -24,7 +24,6 @@ #include <fcntl.h> #include <stdio.h> #include <errno.h> -#include <string> #ifndef __GNUC__ #include <io.h> @@ -32,13 +31,15 @@ #include <unistd.h> #endif -using namespace std; -static const char *classes[] = {"TreeKeyIdx", "TreeKey", "SWKey", "SWObject", 0}; +SWORD_NAMESPACE_START + static const char nl = '\n'; +static const char *classes[] = {"TreeKeyIdx", "TreeKey", "SWKey", "SWObject", 0}; SWClass TreeKeyIdx::classdef(classes); TreeKeyIdx::TreeKeyIdx(const TreeKeyIdx &ikey) : currentNode() { + init(); path = 0; idxfd = 0; datfd = 0; @@ -48,6 +49,7 @@ TreeKeyIdx::TreeKeyIdx(const TreeKeyIdx &ikey) : currentNode() { TreeKeyIdx::TreeKeyIdx(const char *idxPath, int fileMode) : currentNode() { char buf[127]; + init(); path = 0; stdstr(&path, idxPath); @@ -75,6 +77,11 @@ TreeKeyIdx::TreeKeyIdx(const char *idxPath, int fileMode) : currentNode() { } +void TreeKeyIdx::init() { + myclass = &classdef; +} + + TreeKeyIdx::~TreeKeyIdx () { if (path) delete [] path; @@ -121,12 +128,12 @@ void TreeKeyIdx::save() { const char *TreeKeyIdx::getFullName() const { TreeNode parent; - static string fullPath; + static SWBuf fullPath; fullPath = currentNode.name; parent.parent = currentNode.parent; while (parent.parent > -1) { getTreeNodeFromIdxOffset(parent.parent, &parent); - fullPath = ((string)parent.name) + (string) "/" + fullPath; + fullPath = ((SWBuf)parent.name) + (SWBuf) "/" + fullPath; } return fullPath.c_str(); } @@ -297,7 +304,7 @@ void TreeKeyIdx::getTreeNodeFromDatOffset(long ioffset, TreeNode *node) const { read(datfd->getFd(), &tmp, 4); node->firstChild = swordtoarch32(tmp); - string name; + SWBuf name; do { read(datfd->getFd(), &ch, 1); name += ch; @@ -329,27 +336,29 @@ void TreeKeyIdx::getTreeNodeFromDatOffset(long ioffset, TreeNode *node) const { char TreeKeyIdx::getTreeNodeFromIdxOffset(long ioffset, TreeNode *node) const { __u32 offset; - char error = 0; + char error = KEYERR_OUTOFBOUNDS; if (ioffset < 0) { ioffset = 0; - error = KEYERR_OUTOFBOUNDS; + error = 77; // out of bounds but still position to 0; } node->offset = ioffset; if (idxfd > 0) { - lseek(idxfd->getFd(), ioffset, SEEK_SET); - if (read(idxfd->getFd(), &offset, 4) == 4) { - offset = swordtoarch32(offset); - getTreeNodeFromDatOffset(offset, node); - } - else { - lseek(idxfd->getFd(), -4, SEEK_END); + if (idxfd->getFd() > 0) { + lseek(idxfd->getFd(), ioffset, SEEK_SET); if (read(idxfd->getFd(), &offset, 4) == 4) { offset = swordtoarch32(offset); + error = (error == 77) ? KEYERR_OUTOFBOUNDS : 0; getTreeNodeFromDatOffset(offset, node); } - error = KEYERR_OUTOFBOUNDS; + else { + lseek(idxfd->getFd(), -4, SEEK_END); + if (read(idxfd->getFd(), &offset, 4) == 4) { + offset = swordtoarch32(offset); + getTreeNodeFromDatOffset(offset, node); + } + } } } return error; @@ -395,6 +404,8 @@ void TreeKeyIdx::saveTreeNodeOffsets(TreeNode *node) { void TreeKeyIdx::copyFrom(const TreeKeyIdx &ikey) { + SWKey::copyFrom(ikey); + currentNode.offset = ikey.currentNode.offset; currentNode.parent = ikey.currentNode.parent; currentNode.next = ikey.currentNode.next; @@ -579,3 +590,11 @@ TreeKeyIdx::TreeNode::~TreeNode() { if (userData) delete [] userData; } + + +SWKey *TreeKeyIdx::clone() const +{ + return new TreeKeyIdx(*this); +} + +SWORD_NAMESPACE_END diff --git a/src/keys/versekey.cpp b/src/keys/versekey.cpp index 1d5adcb..b2f78e3 100644 --- a/src/keys/versekey.cpp +++ b/src/keys/versekey.cpp @@ -4,7 +4,6 @@ #include <swmacs.h> #include <utilfuns.h> -#include <string.h> #include <stdio.h> #include <fcntl.h> #include <stdlib.h> @@ -20,10 +19,9 @@ #include <swlog.h> #include <versekey.h> #include <localemgr.h> -extern "C" { #include <roman.h> -} +SWORD_NAMESPACE_START static const char *classes[] = {"VerseKey", "SWKey", "SWObject", 0}; SWClass VerseKey::classdef(classes); @@ -55,6 +53,7 @@ void VerseKey::init() { headings = 0; // default display headings option is false upperBound = 0; lowerBound = 0; + boundSet = false; testament = 0; book = 0; chapter = 0; @@ -94,7 +93,7 @@ VerseKey::VerseKey(const char *ikey) : SWKey(ikey) } -VerseKey::VerseKey(VerseKey const &k) : SWKey(k.keytext) +VerseKey::VerseKey(VerseKey const &k) : SWKey(k) { init(); autonorm = k.autonorm; @@ -103,8 +102,10 @@ VerseKey::VerseKey(VerseKey const &k) : SWKey(k.keytext) book = k.Book(); chapter = k.Chapter(); verse = k.Verse(); - LowerBound(k.LowerBound()); - UpperBound(k.UpperBound()); + if (k.isBoundSet()) { + LowerBound(k.LowerBound()); + UpperBound(k.UpperBound()); + } } @@ -169,8 +170,12 @@ void VerseKey::setLocale(const char *name) { 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; @@ -181,7 +186,7 @@ void VerseKey::setBooks(const char *iBMAX, struct sbook **ibooks) { void VerseKey::setBookAbbrevs(const struct abbrev *bookAbbrevs, unsigned int size) { abbrevs = bookAbbrevs; if (!size) { - for (abbrevsCnt = 1; *abbrevs[abbrevsCnt].ab; abbrevsCnt++) { + 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); @@ -193,7 +198,7 @@ void VerseKey::setBookAbbrevs(const struct abbrev *bookAbbrevs, unsigned int siz for (int i = 0; i < BMAX[t]; i++) { int bn = getBookAbbrev(books[t][i].name); if ((bn-1)%39 != i) { - SWLog::systemlog->LogError("Book: %s does not have a matching toupper abbrevs entry! book number returned was: %d", books[t][i].name, bn); + SWLog::systemlog->LogError("Book: %s does not have a matching toupper abbrevs entry! book number returned was: %d", books[t][i].name, bn); } } } @@ -232,36 +237,41 @@ char VerseKey::parse() { - testament = 1; - book = 1; + testament = 2; + book = BMAX[1]; chapter = 1; verse = 1; + int booklen = 0; - error = 0; + int error = 0; if (keytext) { ListKey tmpListKey = VerseKey::ParseVerseList(keytext); if (tmpListKey.Count()) { SWKey::setText((const char *)tmpListKey); - for (testament = 1; testament < 3; testament++) { - for (book = 1; book <= BMAX[testament-1]; book++) { - if (!strncmp(keytext, books[testament-1][book-1].name, strlen(books[testament-1][book-1].name))) - break; + 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 (book <= BMAX[testament-1]) - break; } - if (testament < 3) { - sscanf(&keytext[strlen(books[testament-1][book-1].name)], "%d:%d", &chapter, &verse); + if (booklen) { + sscanf(&keytext[booklen], "%d:%d", &chapter, &verse); } else error = 1; - } + } else error = 1; } Normalize(1); freshtext(); - return error; + return (this->error) ? this->error : (this->error = error); } @@ -306,35 +316,39 @@ void VerseKey::freshtext() const int VerseKey::getBookAbbrev(const char *iabbr) { - int loop, diff, abLen, min, max, target, retVal = -1; - - char *abbr = 0; - - stdstr(&abbr, iabbr); - strstrip(abbr); - abLen = strlen(abbr); - for (loop = 0; loop < abLen; loop++) - abbr[loop] = SW_toupper(abbr[loop]); - - if (abLen) { - min = 0; -// max = abbrevsCnt - 1; - max = abbrevsCnt; - while(1) { - target = min + ((max - min) / 2); - diff = strncmp(abbr, abbrevs[target].ab, abLen); - if ((!diff)||(target >= max)||(target <= min)) - break; - if (diff > 0) - min = target; - else max = target; - } - for (; target > 0; target--) { - if (strncmp(abbr, abbrevs[target-1].ab, abLen)) - break; + int loop, diff, abLen, min, max, target, retVal = -1; + + char *abbr = 0; + + for (int i = 0; i < 2; i++) { + stdstr(&abbr, iabbr); + strstrip(abbr); + if (!i) + toupperstr(abbr); + abLen = strlen(abbr); + + if (abLen) { + min = 0; +// max = abbrevsCnt - 1; + max = abbrevsCnt; + while(1) { + target = min + ((max - min) / 2); + diff = strncmp(abbr, abbrevs[target].ab, abLen); + if ((!diff)||(target >= max)||(target <= min)) + break; + if (diff > 0) + min = target; + else max = target; + } + for (; target > 0; target--) { + if (strncmp(abbr, abbrevs[target-1].ab, abLen)) + break; + } + + retVal = (!diff) ? abbrevs[target].book : -1; } - - retVal = (!diff) ? abbrevs[target].book : -1; + if (retVal > 0) + break; } delete [] abbr; return retVal; @@ -359,8 +373,8 @@ int VerseKey::getBookAbbrev(const char *iabbr) ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool expandRange) { SWKey textkey; - char book[255]; - char number[255]; + char book[2048]; + char number[2048]; int tobook = 0; int tonumber = 0; int chap = -1, verse = -1; @@ -372,13 +386,17 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e char comma = 0; char dash = 0; const char *orig = buf; + int q; ListKey tmpListKey; ListKey internalListKey; SWKey tmpDefaultKey = defaultKey; char lastPartial = 0; + bool inTerm = true; + int notAllDigits; curkey.AutoNormalize(0); tmpListKey << tmpDefaultKey; + tmpListKey.GetElement()->userData = (void *)buf; while (*buf) { switch (*buf) { @@ -390,6 +408,21 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e *number = 0; break; + case ' ': + inTerm = true; + while (true) { + if ((!*number) || (chap < 0)) + break; + for (q = 1; ((buf[q]) && (buf[q] != ' ')); q++); + if (buf[q] == ':') + break; + inTerm = false; + break; + } + if (inTerm) { + book[tobook++] = ' '; + break; + } case '-': case ',': // on number new verse case ';': // on number new chapter @@ -421,26 +454,29 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e break; } - for (loop = strlen(book) - 1; loop+1; loop--) { - if (book[loop] == ' ') { + for (loop = strlen(book) - 1; loop+1; loop--) { + if (book[loop] == ' ') { if (isroman(&book[loop+1])) { - if (verse == -1) { - verse = chap; + if (verse == -1) { + verse = chap; chap = from_rom(&book[loop+1]); book[loop] = 0; - } - } - break; - } - } - - if ((!stricmp(book, "V")) || (!stricmp(book, "VER"))) { // Verse abbrev - if (verse == -1) { - verse = chap; - chap = VerseKey(tmpListKey).Chapter(); - *book = 0; - } - } + } + } + break; + } + } + + if ((!stricmp(book, "V")) || (!stricmp(book, "VER"))) { // Verse abbrev + if (verse == -1) { + verse = chap; + chap = VerseKey(tmpListKey).Chapter(); + *book = 0; + } + } + if ((!stricmp(book, "ch")) || (!stricmp(book, "chap"))) { // Verse abbrev + strcpy(book, VerseKey(tmpListKey).getBookName()); + } bookno = getBookAbbrev(book); } if (((bookno > -1) || (!*book)) && ((*book) || (chap >= 0) || (verse >= 0))) { @@ -485,6 +521,7 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e newElement.LowerBound(curkey); newElement.setPosition(TOP); tmpListKey << newElement; + tmpListKey.GetElement()->userData = (void *)buf; } else { if (!dash) { // if last separator was not a dash just add @@ -498,8 +535,12 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e newElement.UpperBound(curkey); newElement = TOP; tmpListKey << newElement; + tmpListKey.GetElement()->userData = (void *)buf; + } + else { + tmpListKey << (const SWKey &)(const SWKey)(const char *)curkey; + tmpListKey.GetElement()->userData = (void *)buf; } - else tmpListKey << (const SWKey &)(const SWKey)(const char *)curkey; } else if (expandRange) { VerseKey *newElement = SWDYNAMIC_CAST(VerseKey, tmpListKey.GetElement()); @@ -510,6 +551,7 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e curkey = MAXVERSE; newElement->UpperBound(curkey); *newElement = TOP; + tmpListKey.GetElement()->userData = (void *)buf; } } } @@ -527,11 +569,26 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e break; case 10: // ignore these case 13: + case '[': + case ']': + case '(': + case ')': break; case '.': if (buf > orig) // ignore (break) if preceeding char is not a digit - if (!isdigit(*(buf-1))) + for (notAllDigits = tobook; notAllDigits; notAllDigits--) { + if ((!isdigit(book[notAllDigits-1])) && (!strchr(" .", book[notAllDigits-1]))) + break; + } + if (!notAllDigits) break; + + number[tonumber] = 0; + tonumber = 0; + if (*number) + chap = atoi(number); + *number = 0; + break; default: if (isdigit(*buf)) { @@ -550,7 +607,7 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e } } if (chap == -1) - book[tobook++] = SW_toupper(*buf); + book[tobook++] = *buf; } buf++; } @@ -582,15 +639,15 @@ 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])) { - if (verse == -1) { - verse = chap; - chap = from_rom(&book[loop+1]); - book[loop] = 0; - } - } - break; + if (book[loop] == ' ') { + if (isroman(&book[loop+1])) { + if (verse == -1) { + verse = chap; + chap = from_rom(&book[loop+1]); + book[loop] = 0; + } + } + break; } } @@ -602,6 +659,9 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e } } + if ((!stricmp(book, "ch")) || (!stricmp(book, "chap"))) { // Verse abbrev + strcpy(book, VerseKey(tmpListKey).getBookName()); + } bookno = getBookAbbrev(book); } if (((bookno > -1) || (!*book)) && ((*book) || (chap >= 0) || (verse >= 0))) { @@ -646,6 +706,7 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e newElement.LowerBound(curkey); newElement = TOP; tmpListKey << newElement; + tmpListKey.GetElement()->userData = (void *)buf; } else { if (!dash) { // if last separator was not a dash just add @@ -659,8 +720,12 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e newElement.UpperBound(curkey); newElement = TOP; tmpListKey << newElement; + tmpListKey.GetElement()->userData = (void *)buf; + } + else { + tmpListKey << (const SWKey &)(const SWKey)(const char *)curkey; + tmpListKey.GetElement()->userData = (void *)buf; } - else tmpListKey << (const SWKey &)(const SWKey)(const char *)curkey; } else if (expandRange) { VerseKey *newElement = SWDYNAMIC_CAST(VerseKey, tmpListKey.GetElement()); @@ -671,6 +736,7 @@ ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool e curkey = MAXVERSE; newElement->UpperBound(curkey); *newElement = TOP; + tmpListKey.GetElement()->userData = (void *)buf; } } } @@ -696,7 +762,8 @@ VerseKey &VerseKey::LowerBound(const char *lb) (*lowerBound) = lb; lowerBound->Normalize(); - + lowerBound->setLocale( this->getLocale() ); + boundSet = true; return (*lowerBound); } @@ -715,6 +782,7 @@ VerseKey &VerseKey::UpperBound(const char *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); @@ -736,7 +804,7 @@ VerseKey &VerseKey::UpperBound(const char *ub) // -- end kludge - + boundSet = true; return (*upperBound); } @@ -799,6 +867,7 @@ void VerseKey::initBounds() const 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; } @@ -1403,3 +1472,52 @@ int VerseKey::_compare(const VerseKey &ivkey) keyval1 = (keyval1) ? ((keyval1 > 0) ? 1 : -1) /*keyval1/labs(keyval1)*/:0; // -1 | 0 | 1 return keyval1; } + + +const char *VerseKey::getOSISRef() const { + static char buf[5][254]; + static char loop = 0; + + if (loop > 4) + loop = 0; + + static char *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"}; + static char *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"}; + static char **osisbooks[] = { osisotbooks, osisntbooks }; + if (Verse()) + sprintf(buf[loop], "%s.%d.%d", osisbooks[Testament()-1][Book()-1], (int)Chapter(), (int)Verse()); + else if (Chapter()) + sprintf(buf[loop], "%s.%d", osisbooks[Testament()-1][Book()-1], (int)Chapter()); + else if (Book()) + sprintf(buf[loop], "%s", osisbooks[Testament()-1][Book()-1]); + else sprintf(buf[loop], ""); + return buf[loop++]; +} + + +/****************************************************************************** + * 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); + } + else stdstr(&rangeText, getText()); + return rangeText; +} + +SWORD_NAMESPACE_END diff --git a/src/mgr/Makefile.am b/src/mgr/Makefile.am index e312702..15883b5 100644 --- a/src/mgr/Makefile.am +++ b/src/mgr/Makefile.am @@ -6,7 +6,7 @@ else globdef = endif -DEFS += $(globdef) +INCLUDES += $(globdef) libsword_la_SOURCES += $(mgrdir)/swconfig.cpp libsword_la_SOURCES += $(mgrdir)/swmgr.cpp @@ -17,3 +17,6 @@ libsword_la_SOURCES += $(mgrdir)/filemgr.cpp libsword_la_SOURCES += $(mgrdir)/swlocale.cpp libsword_la_SOURCES += $(mgrdir)/localemgr.cpp libsword_la_SOURCES += $(mgrdir)/swcacher.cpp +libsword_la_SOURCES += $(mgrdir)/swsearchable.cpp +libsword_la_SOURCES += $(mgrdir)/installmgr.cpp + diff --git a/src/mgr/encfiltmgr.cpp b/src/mgr/encfiltmgr.cpp index ab55de9..35be96a 100644 --- a/src/mgr/encfiltmgr.cpp +++ b/src/mgr/encfiltmgr.cpp @@ -31,6 +31,8 @@ #include <swmgr.h> +SWORD_NAMESPACE_START + /****************************************************************************** * EncodingFilterMgr Constructor - initializes instance of EncodingFilterMgr * @@ -80,8 +82,8 @@ void EncodingFilterMgr::AddRawFilters(SWModule *module, ConfigEntMap §ion) { ConfigEntMap::iterator entry; - string encoding = ((entry = section.find("Encoding")) != section.end()) ? (*entry).second : (string)""; - if (encoding.empty() || !stricmp(encoding.c_str(), "Latin-1")) { + SWBuf encoding = ((entry = section.find("Encoding")) != section.end()) ? (*entry).second : (SWBuf)""; + if (!encoding.length() || !stricmp(encoding.c_str(), "Latin-1")) { module->AddRawFilter(latin1utf8); } else if (!stricmp(encoding.c_str(), "SCSU")) { @@ -146,3 +148,5 @@ char EncodingFilterMgr::Encoding(char enc) { } return encoding; } + +SWORD_NAMESPACE_END diff --git a/src/mgr/filemgr.cpp b/src/mgr/filemgr.cpp index e380514..44bc768 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,v 1.21 2002/03/16 17:34:41 scribe Exp $ + * $Id: filemgr.cpp,v 1.33 2003/12/23 01:36:12 chrislit Exp $ * * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society @@ -29,19 +29,34 @@ #include <sys/types.h> #include <stdio.h> #include <string.h> -#ifndef __GNUC__ +#if !defined(__GNUC__) && !defined(_WIN32_WCE) #include <io.h> +#include <direct.h> #else #include <unistd.h> #endif +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifndef S_IRGRP +#define S_IRGRP 0 +#endif + +#ifndef S_IROTH +#define S_IROTH 0 +#endif + +SWORD_NAMESPACE_START + // ---------------- statics ----------------- FileMgr FileMgr::systemFileMgr; // --------------- end statics -------------- -FileDesc::FileDesc(FileMgr *parent, char *path, int mode, int perms, bool tryDowngrade) { +FileDesc::FileDesc(FileMgr *parent, const char *path, int mode, int perms, bool tryDowngrade) { this->parent = parent; this->path = 0; stdstr(&this->path, path); @@ -86,11 +101,11 @@ FileMgr::~FileMgr() { } -FileDesc *FileMgr::open(char *path, int mode, bool tryDowngrade) { - return open(path, mode, S_IREAD | S_IWRITE, tryDowngrade); +FileDesc *FileMgr::open(const char *path, int mode, bool tryDowngrade) { + return open(path, mode, S_IREAD | S_IWRITE|S_IRGRP|S_IROTH, tryDowngrade); } -FileDesc *FileMgr::open(char *path, int mode, int perms, bool tryDowngrade) { +FileDesc *FileMgr::open(const char *path, int mode, int perms, bool tryDowngrade) { FileDesc **tmp, *tmp2; for (tmp = &files; *tmp; tmp = &((*tmp)->next)) { @@ -126,6 +141,8 @@ signed char FileMgr::trunc(FileDesc *file) { static const char *writeTest = "x"; long size = lseek(file->getFd(), 1, SEEK_CUR); + if (size == 1) // was empty + size = 0; char nibble [ 32767 ]; bool writable = write(file->getFd(), writeTest, 1); int bytes = 0; @@ -142,19 +159,19 @@ signed char FileMgr::trunc(FileDesc *file) { if (i == 9999) return -2; - int fd = ::open(buf, O_CREAT|O_RDWR, S_IREAD|S_IWRITE); + int fd = ::open(buf, O_CREAT|O_RDWR, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH); if (fd < 0) return -3; lseek(file->getFd(), 0, SEEK_SET); - while (size > 0) { + while (size > 0) { bytes = read(file->getFd(), nibble, 32767); write(fd, nibble, (bytes < size)?bytes:size); size -= bytes; } // zero out the file ::close(file->fd); - file->fd = ::open(file->path, O_TRUNC, S_IREAD|S_IWRITE); + file->fd = ::open(file->path, O_TRUNC, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH); ::close(file->fd); file->fd = -77; // force file open by filemgr // copy tmp file back (dumb, but must preserve file permissions) @@ -166,7 +183,7 @@ signed char FileMgr::trunc(FileDesc *file) { ::close(fd); ::close(file->fd); - unlink(buf); // remove our tmp file + removeFile(buf); // remove our tmp file file->fd = -77; // causes file to be swapped out forcing open on next call to getFd() } else { // put offset back and return failure @@ -259,6 +276,82 @@ signed char FileMgr::existsDir(const char *ipath, const char *idirName) sprintf(ch, "/%s", idirName); } signed char retVal = !access(path, 04); - delete [] path; - return retVal; + delete [] path; + return retVal; +} + + +int FileMgr::createParent(const char *pName) { + char *buf = new char [ strlen(pName) + 1 ]; + int retCode = 0; + + strcpy(buf, pName); + int end = strlen(buf) - 1; + while (end) { + if ((buf[end] == '/') || (buf[end] == '\\')) + break; + end--; + } + buf[end] = 0; + if (strlen(buf)>0) { + if (access(buf, 02)) { // not exists with write access? + if ((retCode = mkdir(buf +#ifndef WIN32 + , 0755 +#endif + ))) { + createParent(buf); + retCode = mkdir(buf +#ifndef WIN32 + , 0755 +#endif + ); + } + } + } + else retCode = -1; + delete [] buf; + return retCode; +} + + +int FileMgr::createPathAndFile(const char *fName) { + int fd; + + fd = ::open(fName, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH); + if (fd < 1) { + createParent(fName); + fd = ::open(fName, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH); + } + return fd; } + + +int FileMgr::copyFile(const char *sourceFile, const char *targetFile) { + int sfd, dfd, len; + char buf[4096]; + + if ((sfd = ::open(sourceFile, O_RDONLY|O_BINARY)) < 1) + return -1; + if ((dfd = createPathAndFile(targetFile)) < 1) + return -1; + + do { + len = read(sfd, buf, 4096); + write(dfd, buf, len); + } + while(len == 4096); + ::close(dfd); + ::close(sfd); + + return 0; +} + + +int FileMgr::removeFile(const char *fName) { + return ::remove(fName); +} + + + +SWORD_NAMESPACE_END diff --git a/src/mgr/installmgr.cpp b/src/mgr/installmgr.cpp new file mode 100644 index 0000000..5fbfb05 --- /dev/null +++ b/src/mgr/installmgr.cpp @@ -0,0 +1,629 @@ +/***************************************************************************** + * InstallMgr functions to be made into something usefully exposed by + * master Glassey + * + */ + + +#ifndef EXCLUDEZLIB +extern "C" { +#include <untgz.h> +} +#endif + + +#include <installmgr.h> +#include <filemgr.h> + +#include <fcntl.h> +#ifndef __GNUC__ +#include <io.h> +#else +#include <unistd.h> +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifdef CURLAVAILABLE +#include <curl/curl.h> +#include <curl/types.h> +#include <curl/easy.h> +#endif + +#include <defs.h> +#include <vector> +#include <swmgr.h> +#include <dirent.h> + +using namespace std; + +SWORD_NAMESPACE_START + +int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream); +int my_fprogress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); + +static InstallMgr_init _InstallMgr_init; + +InstallMgr_init::InstallMgr_init() { +#ifdef CURLAVAILABLE + curl_global_init(CURL_GLOBAL_DEFAULT); +#else +// fprintf(stderr, "libCURL is needed for remote installation functions\n"); +#endif +} + +InstallMgr_init::~InstallMgr_init() { +#ifdef CURLAVAILABLE + curl_global_cleanup(); +#else +// fprintf(stderr, "libCURL is needed for remote installation functions\n"); +#endif +} + + +int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) { + struct FtpFile *out=(struct FtpFile *)stream; + if (out && !out->stream) { + /* open file for writing */ + out->stream=fopen(out->filename, "wb"); + if (!out->stream) + return -1; /* failure, can't open file to write */ + } + return fwrite(buffer, size, nmemb, out->stream); +} + + +int my_fprogress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { + if (clientp) { + ((InstallMgr *)clientp)->statusUpdate(dltotal, dlnow); + } + return 0; +} + + +InstallMgr::InstallMgr(const char *privatePath) { + this->privatePath = 0; + stdstr(&(this->privatePath), privatePath); + SWBuf confPath = (SWBuf)privatePath + "/InstallMgr.conf"; + FileMgr::createParent(confPath.c_str()); + + installConf = new SWConfig(confPath.c_str()); + + SectionMap::iterator sourcesSection; + ConfigEntMap::iterator sourceBegin; + ConfigEntMap::iterator sourceEnd; + + sources.clear(); + + sourcesSection = installConf->Sections.find("Sources"); + passive = (!stricmp((*installConf)["General"]["PassiveFTP"].c_str(), "true")); + + if (sourcesSection != installConf->Sections.end()) { + sourceBegin = sourcesSection->second.lower_bound("FTPSource"); + sourceEnd = sourcesSection->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"; + FileMgr::createParent(parent.c_str()); + is->localShadow = (SWBuf)privatePath + "/" + is->source; + sourceBegin++; + } + } +} + + +InstallMgr::~InstallMgr() { + delete [] privatePath; + delete installConf; +} + + +void InstallMgr::statusUpdate(double dltotal, double dlnow) { +} + +void InstallMgr::preDownloadStatus(long totalBytes, long completedBytes, const char *message) { +} + +char InstallMgr::FTPURLGetFile(void *session, const char *dest, const char *sourceurl) { + char retVal = 0; +#ifdef CURLAVAILABLE + struct FtpFile ftpfile = {dest, NULL}; + + CURL *curl = (CURL *)session; + CURLcode res; + + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, sourceurl); + + curl_easy_setopt(curl, CURLOPT_USERPWD, "ftp:installmgr@user.com"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); + if (!passive) + curl_easy_setopt(curl, CURLOPT_FTPPORT, "-"); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_fprogress); + /* Set a pointer to our struct to pass to the callback */ + curl_easy_setopt(curl, CURLOPT_FILE, &ftpfile); + + /* Switch on full protocol/debug output */ + curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE); + + res = curl_easy_perform(curl); + + if(CURLE_OK != res) { + retVal = -1; + } + } + + if (ftpfile.stream) + fclose(ftpfile.stream); /* close the local file */ +#else + fprintf(stderr, "libCURL is needed for remote installation functions\n"); +#endif + return retVal; +} + + + +vector<struct ftpparse> InstallMgr::FTPURLGetDir(void *session, const char *dirurl) { + + vector<struct ftpparse> dirList; + + if (!FTPURLGetFile(session, "dirlist", dirurl)) { + int fd = open("dirlist", O_RDONLY|O_BINARY); + long size = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + char *buf = new char [ size + 1 ]; + read(fd, buf, size); + close(fd); + char *start = buf; + char *end = start; + while (start < (buf+size)) { + struct ftpparse item; + bool looking = true; + for (end = start; *end; end++) { + if (looking) { + if ((*end == 10) || (*end == 13)) { + *end = 0; + looking = false; + } + } + else if ((*end != 10) && (*end != 13)) + break; + } + int status = ftpparse(&item, start, end - start); + if (status) + dirList.push_back(item); + start = end; + } + } + return dirList; +} + + +void *InstallMgr::FTPOpenSession() { + void *retVal = 0; +#ifdef CURLAVAILABLE + CURL *curl; + + retVal = curl_easy_init(); +#else + fprintf(stderr, "libCURL is needed for remote installation functions\n"); +#endif + return retVal; +} + + +void InstallMgr::FTPCloseSession(void *session) { +#ifdef CURLAVAILABLE + CURL *curl = (CURL *)session; + curl_easy_cleanup(curl); +#else + fprintf(stderr, "libCURL is needed for remote installation functions\n"); +#endif +} + + +int InstallMgr::removeModule(SWMgr *manager, const char *modName) { + SectionMap::iterator module; + ConfigEntMap::iterator fileBegin; + ConfigEntMap::iterator fileEnd, entry; + + module = manager->config->Sections.find(modName); + + if (module != manager->config->Sections.end()) { + + fileBegin = module->second.lower_bound("File"); + fileEnd = module->second.upper_bound("File"); + + SWBuf modFile; + SWBuf modDir; + entry = module->second.find("AbsoluteDataPath"); + modDir = entry->second.c_str(); + if (fileBegin != fileEnd) { // remove each file + while (fileBegin != fileEnd) { + modFile = modDir; + modFile += "/"; + modFile += fileBegin->second.c_str(); + //remove file + remove(modFile.c_str()); + fileBegin++; + } + } + else { //remove all files in DataPath directory + + DIR *dir; + struct dirent *ent; + ConfigEntMap::iterator entry; + + + if (dir = opendir(modDir.c_str())) { + rewinddir(dir); + while ((ent = readdir(dir))) { + if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) { + modFile = modDir; + modFile += "/"; + modFile += ent->d_name; + remove(modFile.c_str()); + } + } + closedir(dir); + } + if (dir = opendir(manager->configPath)) { // find and remove .conf file + rewinddir(dir); + while ((ent = readdir(dir))) { + if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) { + modFile = manager->configPath; + modFile += "/"; + modFile += ent->d_name; + SWConfig *config = new SWConfig(modFile.c_str()); + if (config->Sections.find(modName) != config->Sections.end()) { + delete config; + remove(modFile.c_str()); + } + else delete config; + } + } + closedir(dir); + } + } + 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); + + caption = strtok(buf, "|"); + source = strtok(0, "|"); + directory = strtok(0, "|"); + delete [] buf; + } +} + + +InstallSource::~InstallSource() { + if (mgr) + delete mgr; +} + + +void InstallSource::flush() { + if (mgr) { + delete mgr; + mgr = 0; + } +} + + +SWMgr *InstallSource::getMgr() { + if (!mgr) + mgr = new SWMgr(localShadow.c_str()); + return mgr; +} + + +int InstallMgr::FTPCopy(InstallSource *is, const char *src, const char *dest, bool dirTransfer, const char *suffix) { + terminate = false; + long i; + void *session = FTPOpenSession(); + SWBuf url = (SWBuf)"ftp://" + is->source + is->directory.c_str() + "/"; //dont forget the final slash + if (FTPURLGetFile(session, "dirlist", url.c_str())) { + return -1; + } + if (dirTransfer) { + SWBuf url = (SWBuf)"ftp://" + is->source + is->directory.c_str() + "/" + src + "/"; //dont forget the final slash + vector<struct ftpparse> dirList = FTPURLGetDir(session, url.c_str()); + + if (!dirList.size()) { + return -1; + } + + long totalBytes = 0; + for (i = 0; i < dirList.size(); i++) + totalBytes += dirList[i].size; + long completedBytes = 0; + for (i = 0; i < dirList.size(); i++) { + if (dirList[i].flagtrycwd != 1) { + SWBuf buffer = (SWBuf)dest + "/" + (dirList[i].name); + if (!strcmp(&buffer.c_str()[buffer.length()-strlen(suffix)], suffix)) { + SWBuf buffer2 = "Downloading ("; + buffer2.appendFormatted("%d", i+1); + buffer2 += " of "; + buffer2.appendFormatted("%d", dirList.size()); + buffer2 += "): "; + buffer2 += (dirList[i].name); + preDownloadStatus(totalBytes, completedBytes, buffer2.c_str()); + FileMgr::createParent(buffer.c_str()); // make sure parent directory exists + try { + SWBuf url = (SWBuf)"ftp://" + is->source + is->directory.c_str() + "/" + src + "/" + dirList[i].name; //dont forget the final slash + if (FTPURLGetFile(session, buffer.c_str(), url.c_str())) { + return -2; + } + completedBytes += dirList[i].size; + } + catch (...) {} + if (terminate) + break; + } + } + } + } + else { +// Synchronize((TThreadMethod)&PreDownload2); + try { + SWBuf url = (SWBuf)"ftp://" + is->source + is->directory.c_str() + "/" + src; //dont forget the final slash + if (FTPURLGetFile(session, dest, url.c_str())) { + return -1; + } + } + catch(...) { + terminate = true; + } + } + try { + FTPCloseSession(session); + } + catch(...){} + return 0; +} + + +int InstallMgr::installModule(SWMgr *destMgr, const char *fromLocation, const char *modName, InstallSource *is) { + SectionMap::iterator module, section; + ConfigEntMap::iterator fileBegin; + ConfigEntMap::iterator fileEnd; + ConfigEntMap::iterator entry; + SWBuf sourceDir; + SWBuf buffer; + bool aborted = false; + bool cipher = false; + DIR *dir; + struct dirent *ent; + SWBuf modFile; + + + if (is) + sourceDir = (SWBuf)privatePath + "/" + is->source; + else sourceDir = fromLocation; + + if (sourceDir[sourceDir.length()-1] != '/') + sourceDir += '/'; + + SWMgr mgr(sourceDir.c_str()); + + module = mgr.config->Sections.find(modName); + + if (module != mgr.config->Sections.end()) { + + entry = module->second.find("CipherKey"); + if (entry != module->second.end()) + cipher = true; + + fileEnd = module->second.upper_bound("File"); + fileBegin = module->second.lower_bound("File"); + + if (fileBegin != fileEnd) { // copy each file + if (is) { + while (fileBegin != fileEnd) { // ftp each file first + buffer = sourceDir + "/" + fileBegin->second.c_str(); + if (FTPCopy(is, fileBegin->second.c_str(), buffer.c_str())) { + aborted = true; + break; // user aborted + } + fileBegin++; + } + fileBegin = module->second.lower_bound("File"); + } + + if (!aborted) { + // DO THE INSTALL + while (fileBegin != fileEnd) { + copyFileToSWORDInstall(destMgr, sourceDir.c_str(), fileBegin->second.c_str()); + fileBegin++; + } + } + //--------------- + + if (is) { + fileBegin = module->second.lower_bound("File"); + while (fileBegin != fileEnd) { // delete each tmp ftp file + buffer = sourceDir + "/" + fileBegin->second.c_str(); + remove(buffer.c_str()); + fileBegin++; + } + } + } + else { //copy all files in DataPath directory + ConfigEntMap::iterator entry; + SWBuf sourceOrig = sourceDir; + + entry = module->second.find("DataPath"); + if (entry != module->second.end()) { + SWBuf modDir = entry->second.c_str(); + entry = module->second.find("ModDrv"); + if (entry != module->second.end()) { + if (!strcmp(entry->second.c_str(), "RawLD") || !strcmp(entry->second.c_str(), "RawLD4") || !strcmp(entry->second.c_str(), "zLD") || !strcmp(entry->second.c_str(), "RawGenBook") || !strcmp(entry->second.c_str(), "zGenBook")) { + int end = modDir.length() - 1; + while (end >= 0) { //while(end) wouldn't work for length() == 0 + if (modDir[end] == '/') + break; + + modDir--; //remove last char + end--; + } + } + + //make sure there's no trailing slash in modDir, required for Bibles and Commentaries + if ( modDir.length() && (modDir[modDir.length()-1] == '/')) //last char is a slash + modDir--; //remove the slash + } + + if (is) { + buffer = sourceDir + "/" + modDir; + if (FTPCopy(is, modDir.c_str(), buffer.c_str(), true)) { + aborted = true; // user aborted + } + } + sourceDir += "/"; + sourceDir += modDir; + if (!aborted) { + if (dir = opendir(sourceDir.c_str())) { + rewinddir(dir); + while ((ent = readdir(dir))) { + if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) { + modFile = modDir; + modFile += "/"; + modFile += ent->d_name; + copyFileToSWORDInstall(destMgr, sourceOrig.c_str(), modFile.c_str()); + } + } + closedir(dir); + } + } + if (is) { // delete tmp ftp files + if (dir = opendir(sourceDir.c_str())) { + rewinddir(dir); + while ((ent = readdir(dir))) { + if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) { + modFile = sourceOrig + "/" + modDir; + modFile += "/"; + modFile += ent->d_name; + remove(modFile.c_str()); + } + } + closedir(dir); + } + } + sourceDir = sourceOrig; + sourceDir += "/mods.d/"; + } + } + if (!aborted) { + if (dir = opendir(sourceDir.c_str())) { // find and copy .conf file + rewinddir(dir); + while ((ent = readdir(dir))) { + if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) { + modFile = sourceDir; + modFile += ent->d_name; + SWConfig *config = new SWConfig(modFile.c_str()); + if (config->Sections.find(modName) != config->Sections.end()) { + SWBuf targetFile = destMgr->configPath; //"./mods.d/"; + targetFile += "/"; + targetFile += ent->d_name; + FileMgr::copyFile(modFile.c_str(), targetFile.c_str()); + if (cipher) { + if (getCipherCode(modName, config)) { + SWMgr newDest(destMgr->prefixPath); + removeModule(&newDest, modName); + aborted = true; + } + else { + config->Save(); + FileMgr::copyFile(modFile.c_str(), targetFile.c_str()); + } + } + } + delete config; + } + } + closedir(dir); + } + } + return (aborted) ? -1 : 0; + } + return 1; +} + + +// return aborted +bool InstallMgr::getCipherCode(const char *modName, SWConfig *config) { + return false; +} + +int InstallMgr::copyFileToSWORDInstall(SWMgr *manager, const char *sourceDir, const char *fName) { + SWBuf sourcePath = sourceDir; + sourcePath += fName; + + SWBuf dest; + dest = manager->prefixPath; + if ((manager->prefixPath[strlen(manager->prefixPath)-1] != '\\') && ( manager->prefixPath[strlen(manager->prefixPath)-1] != '/')) + dest += "/"; + dest += fName; + + return FileMgr::copyFile(sourcePath.c_str(), dest.c_str()); +} + + +void InstallMgr::refreshRemoteSource(InstallSource *is) { + DIR *dir; + struct dirent *ent; + ConfigEntMap::iterator entry; + SWBuf modDir; + SWBuf modFile; + SWBuf root = privatePath; + root += (SWBuf)"/" + is->source.c_str(); + SWBuf target = root + "/mods.d"; + + if (dir = opendir(target.c_str())) { + rewinddir(dir); + while ((ent = readdir(dir))) { + if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) { + modFile = target; + modFile += "/"; + modFile += ent->d_name; + remove(modFile.c_str()); + } + } + closedir(dir); + } + + + +#ifndef EXCLUDEZLIB + SWBuf archive = root + "/mods.d.tar.gz"; + if (!FTPCopy(is, "mods.d.tar.gz", archive.c_str(), false)) { + int fd = open(archive.c_str(), O_RDONLY|O_BINARY); + untargz(fd, root.c_str()); + close(fd); + } + else +#endif + FTPCopy(is, "mods.d", target.c_str(), true, ".conf"); + is->flush(); +} + +SWORD_NAMESPACE_END + diff --git a/src/mgr/localemgr.cpp b/src/mgr/localemgr.cpp index a21896d..6c3da4a 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,v 1.11 2002/03/15 07:47:35 scribe Exp $ + * $Id: localemgr.cpp,v 1.16 2003/07/05 04:58:42 scribe Exp $ * * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society @@ -39,15 +39,18 @@ #include <localemgr.h> #include <filemgr.h> +SWORD_NAMESPACE_START + LocaleMgr LocaleMgr::systemLocaleMgr; LocaleMgr::LocaleMgr(const char *iConfigPath) { + locales = new LocaleMap(); char *prefixPath = 0; char *configPath = 0; char configType = 0; - string path; + SWBuf path; defaultLocaleName = 0; @@ -97,13 +100,14 @@ LocaleMgr::~LocaleMgr() { if (defaultLocaleName) delete [] defaultLocaleName; deleteLocales(); + delete locales; } void LocaleMgr::loadConfigDir(const char *ipath) { DIR *dir; struct dirent *ent; - string newmodfile; + SWBuf newmodfile; LocaleMap::iterator it; if ((dir = opendir(ipath))) { @@ -116,12 +120,12 @@ void LocaleMgr::loadConfigDir(const char *ipath) { newmodfile += ent->d_name; SWLocale *locale = new SWLocale(newmodfile.c_str()); if (locale->getName()) { - it = locales.find(locale->getName()); - if (it != locales.end()) { + it = locales->find(locale->getName()); + if (it != locales->end()) { *((*it).second) += *locale; delete locale; } - else locales.insert(LocaleMap::value_type(locale->getName(), locale)); + else locales->insert(LocaleMap::value_type(locale->getName(), locale)); } else delete locale; } @@ -135,36 +139,39 @@ void LocaleMgr::deleteLocales() { LocaleMap::iterator it; - for (it = locales.begin(); it != locales.end(); it++) + for (it = locales->begin(); it != locales->end(); it++) delete (*it).second; - locales.erase(locales.begin(), locales.end()); + locales->erase(locales->begin(), locales->end()); } SWLocale *LocaleMgr::getLocale(const char *name) { LocaleMap::iterator it; - it = locales.find(name); - if (it != locales.end()) + it = locales->find(name); + if (it != locales->end()) return (*it).second; return 0; } -list <string> LocaleMgr::getAvailableLocales() { - list <string> retVal; - for (LocaleMap::iterator it = locales.begin(); it != locales.end(); it++) +std::list <SWBuf> LocaleMgr::getAvailableLocales() { + std::list <SWBuf> retVal; + for (LocaleMap::iterator it = locales->begin(); it != locales->end(); it++) retVal.push_back((*it).second->getName()); return retVal; } -const char *LocaleMgr::translate(const char *name, const char *text) { +const char *LocaleMgr::translate(const char *text, const char *localeName) { SWLocale *target; - target = getLocale(name); + if (!localeName) { + localeName = getDefaultLocaleName(); + } + target = getLocale(localeName); if (target) return target->translate(text); return text; @@ -179,3 +186,5 @@ const char *LocaleMgr::getDefaultLocaleName() { void LocaleMgr::setDefaultLocaleName(const char *name) { stdstr(&defaultLocaleName, name); } + +SWORD_NAMESPACE_END diff --git a/src/mgr/markupfiltmgr.cpp b/src/mgr/markupfiltmgr.cpp index 22a34c5..07a9fb0 100644 --- a/src/mgr/markupfiltmgr.cpp +++ b/src/mgr/markupfiltmgr.cpp @@ -30,11 +30,19 @@ #include <gbfhtmlhref.h> #include <thmlrtf.h> #include <gbfrtf.h> +#include <gbfosis.h> +#include <thmlosis.h> +#include <osisrtf.h> +#include <osishtmlhref.h> +#include <gbfwebif.h> +#include <thmlwebif.h> +#include <osiswebif.h> #include <markupfiltmgr.h> #include <swmgr.h> +SWORD_NAMESPACE_START /****************************************************************************** * MarkupFilterMgr Constructor - initializes instance of MarkupFilterMgr @@ -212,23 +220,31 @@ void MarkupFilterMgr::CreateFilters(char markup) { fromosis = NULL; break; case FMT_HTMLHREF: - fromplain = NULL; + fromplain = new PLAINHTML(); fromthml = new ThMLHTMLHREF(); fromgbf = new GBFHTMLHREF(); - fromosis = NULL; + fromosis = new OSISHTMLHREF(); break; case FMT_RTF: fromplain = NULL; fromthml = new ThMLRTF(); fromgbf = new GBFRTF(); - fromosis = NULL; + fromosis = new OSISRTF(); break; case FMT_OSIS: fromplain = NULL; - fromthml = NULL; - fromgbf = NULL; + fromthml = new ThMLOSIS(); + fromgbf = new GBFOSIS(); fromosis = NULL; break; + case FMT_WEBIF: + fromplain = NULL; + fromthml = new ThMLWEBIF(); + fromgbf = new GBFWEBIF(); + fromosis = new OSISWEBIF(); + break; } } + +SWORD_NAMESPACE_END diff --git a/src/mgr/swcacher.cpp b/src/mgr/swcacher.cpp index 8128a70..ef04d98 100644 --- a/src/mgr/swcacher.cpp +++ b/src/mgr/swcacher.cpp @@ -2,7 +2,7 @@ * swcacher.h - definition of class SWCacher used to provide an interface for * objects that cache and want a standard interface for cleaning up. * - * $Id: swcacher.cpp,v 1.1 2002/03/16 01:12:37 scribe Exp $ + * $Id: swcacher.cpp,v 1.2 2002/10/01 19:52:40 dglassey Exp $ * * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society @@ -22,6 +22,8 @@ #include <swcacher.h> +SWORD_NAMESPACE_START + SWCacher::SWCacher() { } @@ -41,3 +43,5 @@ long SWCacher::resourceConsumption() { long SWCacher::lastAccess() { return 0; } + +SWORD_NAMESPACE_END diff --git a/src/mgr/swconfig.cpp b/src/mgr/swconfig.cpp index ad97d00..d9eccc6 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,v 1.5 2001/03/11 22:34:58 scribe Exp $ + * $Id: swconfig.cpp,v 1.13 2003/06/27 01:41:07 scribe Exp $ * * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society @@ -23,6 +23,7 @@ #include <swconfig.h> #include <utilfuns.h> +SWORD_NAMESPACE_START SWConfig::SWConfig(const char * ifilename) { filename = ifilename; @@ -34,25 +35,29 @@ SWConfig::~SWConfig() { } -char SWConfig::getline(FILE *fp, string &line) +char SWConfig::getline(FILE *fp, SWBuf &line) { char retval = 0; char buf[255]; + int len; line = ""; while (fgets(buf, 254, fp)) { while (buf[strlen(buf)-1] == '\n' || buf[strlen(buf)-1] == '\r') buf[strlen(buf)-1] = 0; + len = strlen(buf); + while (len>0 && buf[len-1] == '\n' || buf[len-1] == '\r') + buf[(len--)-1] = 0; - if (buf[strlen(buf)-1] == '\\') { - buf[strlen(buf)-1] = 0; + if (len>0 && buf[len-1] == '\\') { + buf[(len--)-1] = 0; line += buf; continue; } line += buf; - if (strlen(buf) < 253) { + if (len < 253) { retval = 1; break; } @@ -64,9 +69,9 @@ char SWConfig::getline(FILE *fp, string &line) void SWConfig::Load() { FILE *cfile; char *buf, *data; - string line; + SWBuf line; ConfigEntMap cursect; - string sectname; + SWBuf sectname; bool first = true; Sections.erase(Sections.begin(), Sections.end()); @@ -105,10 +110,10 @@ void SWConfig::Load() { void SWConfig::Save() { FILE *cfile; - string buf; + SWBuf buf; SectionMap::iterator sit; ConfigEntMap::iterator entry; - string sectname; + SWBuf sectname; if ((cfile = fopen(filename.c_str(), "w"))) { @@ -131,20 +136,35 @@ void SWConfig::Save() { } -SWConfig &SWConfig::operator +=(SWConfig &addFrom) -{ +void SWConfig::augment(SWConfig &addFrom) { SectionMap::iterator section; - ConfigEntMap::iterator entry; + ConfigEntMap::iterator entry, start, end; for (section = addFrom.Sections.begin(); section != addFrom.Sections.end(); section++) { for (entry = (*section).second.begin(); entry != (*section).second.end(); entry++) { - Sections[(*section).first].insert(ConfigEntMap::value_type((*entry).first, (*entry).second)); + start = Sections[section->first].lower_bound(entry->first); + end = Sections[section->first].upper_bound(entry->first); + if (start != end) { + if (((++start) != end) + || ((++(addFrom.Sections[section->first].lower_bound(entry->first))) != addFrom.Sections[section->first].upper_bound(entry->first))) { + for (--start; start != end; start++) { + if (!strcmp(start->second.c_str(), entry->second.c_str())) + break; + } + if (start == end) + Sections[(*section).first].insert(ConfigEntMap::value_type((*entry).first, (*entry).second)); + } + else Sections[section->first][entry->first.c_str()] = entry->second.c_str(); + } + else Sections[section->first][entry->first.c_str()] = entry->second.c_str(); } } - return *this; } + ConfigEntMap & SWConfig::operator [] (const char *section) { return Sections[section]; } + +SWORD_NAMESPACE_END diff --git a/src/mgr/swfiltermgr.cpp b/src/mgr/swfiltermgr.cpp index 264b5a6..26ba98a 100644 --- a/src/mgr/swfiltermgr.cpp +++ b/src/mgr/swfiltermgr.cpp @@ -2,7 +2,7 @@ * swfiltermgr.cpp - definition of class SWFilterMgr used as an interface to * manage filters on a module * - * $Id: swfiltermgr.cpp,v 1.2 2001/11/30 12:04:34 scribe Exp $ + * $Id: swfiltermgr.cpp,v 1.3 2002/10/01 19:52:40 dglassey Exp $ * * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society @@ -22,6 +22,8 @@ #include <swfiltermgr.h> +SWORD_NAMESPACE_START + SWFilterMgr::SWFilterMgr() { } @@ -88,3 +90,4 @@ void SWFilterMgr::AddStripFilters(SWModule * module, ConfigEntMap & section) { void SWFilterMgr::AddRawFilters(SWModule * module, ConfigEntMap & section) { } +SWORD_NAMESPACE_END diff --git a/src/mgr/swlocale.cpp b/src/mgr/swlocale.cpp index b630383..8cf1e96 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,v 1.3 2000/03/13 09:36:03 scribe Exp $ + * $Id: swlocale.cpp,v 1.5 2002/10/01 19:52:40 dglassey Exp $ * * Copyright 2000 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society @@ -23,6 +23,7 @@ #include <swlocale.h> #include <utilfuns.h> +SWORD_NAMESPACE_START SWLocale::SWLocale(const char * ifilename) { ConfigEntMap::iterator confEntry; @@ -93,9 +94,8 @@ const char *SWLocale::getDescription() { } -SWLocale &SWLocale::operator +=(SWLocale &addFrom) { +void SWLocale::augment(SWLocale &addFrom) { *localeSource += *addFrom.localeSource; - return *this; } @@ -139,3 +139,5 @@ void SWLocale::getBooks(char **iBMAX, struct sbook ***ibooks) { *iBMAX = BMAX; *ibooks = books; } + +SWORD_NAMESPACE_END diff --git a/src/mgr/swmgr.cpp b/src/mgr/swmgr.cpp index 36aecb0..6207b60 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,v 1.70 2002/03/22 05:26:34 scribe Exp $ + * $Id: swmgr.cpp,v 1.96 2003/12/05 21:44:33 scribe Exp $ * * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society @@ -32,7 +32,7 @@ #endif #include <sys/stat.h> #ifndef _MSC_VER -#include <iostream.h> +#include <iostream> #endif #include <dirent.h> @@ -46,14 +46,24 @@ #include <utilfuns.h> #include <gbfplain.h> #include <thmlplain.h> +#include <osisplain.h> #include <gbfstrongs.h> #include <gbffootnotes.h> #include <gbfheadings.h> +#include <gbfredletterwords.h> #include <gbfmorph.h> +#include <osisheadings.h> +#include <osisfootnotes.h> +#include <osisstrongs.h> +#include <osismorph.h> +#include <osislemma.h> +#include <osisredletterwords.h> +#include <osisscripref.h> #include <thmlstrongs.h> #include <thmlfootnotes.h> #include <thmlheadings.h> #include <thmlmorph.h> +#include <thmlvariants.h> #include <thmllemma.h> #include <thmlscripref.h> #include <cipherfil.h> @@ -67,17 +77,24 @@ #include <utf8hebrewpoints.h> #include <greeklexattribs.h> #include <swfiltermgr.h> +#ifndef EXCLUDEZLIB +#include "zipcomprs.h" +#endif - -#ifdef ICU +#ifdef _ICU_ #include <utf8transliterator.h> #endif -#ifndef EXCLUDEZLIB -#include <zipcomprs.h> +SWORD_NAMESPACE_START + +#ifdef _ICU_ +bool SWMgr::isICU = true; +#else +bool SWMgr::isICU = false; #endif + bool SWMgr::debug = false; #ifdef GLOBCONFPATH @@ -100,6 +117,10 @@ void SWMgr::init() { optionFilters.clear(); cleanupFilters.clear(); + tmpFilter = new ThMLVariants(); + optionFilters.insert(FilterMap::value_type("ThMLVariants", tmpFilter)); + cleanupFilters.push_back(tmpFilter); + tmpFilter = new GBFStrongs(); optionFilters.insert(FilterMap::value_type("GBFStrongs", tmpFilter)); cleanupFilters.push_back(tmpFilter); @@ -108,6 +129,10 @@ void SWMgr::init() { optionFilters.insert(FilterMap::value_type("GBFFootnotes", tmpFilter)); cleanupFilters.push_back(tmpFilter); + tmpFilter = new GBFRedLetterWords(); + optionFilters.insert(FilterMap::value_type("GBFRedLetterWords", tmpFilter)); + cleanupFilters.push_back(tmpFilter); + tmpFilter = new GBFMorph(); optionFilters.insert(FilterMap::value_type("GBFMorph", tmpFilter)); cleanupFilters.push_back(tmpFilter); @@ -116,6 +141,34 @@ void SWMgr::init() { optionFilters.insert(FilterMap::value_type("GBFHeadings", tmpFilter)); cleanupFilters.push_back(tmpFilter); + tmpFilter = new OSISHeadings(); + optionFilters.insert(FilterMap::value_type("OSISHeadings", tmpFilter)); + cleanupFilters.push_back(tmpFilter); + + tmpFilter = new OSISStrongs(); + optionFilters.insert(FilterMap::value_type("OSISStrongs", tmpFilter)); + cleanupFilters.push_back(tmpFilter); + + tmpFilter = new OSISMorph(); + optionFilters.insert(FilterMap::value_type("OSISMorph", tmpFilter)); + cleanupFilters.push_back(tmpFilter); + + tmpFilter = new OSISLemma(); + optionFilters.insert(FilterMap::value_type("OSISLemma", tmpFilter)); + cleanupFilters.push_back(tmpFilter); + + tmpFilter = new OSISFootnotes(); + optionFilters.insert(FilterMap::value_type("OSISFootnotes", tmpFilter)); + cleanupFilters.push_back(tmpFilter); + + tmpFilter = new OSISScripref(); + optionFilters.insert(FilterMap::value_type("OSISScripref", tmpFilter)); + cleanupFilters.push_back(tmpFilter); + + tmpFilter = new OSISRedLetterWords(); + optionFilters.insert(FilterMap::value_type("OSISRedLetterWords", tmpFilter)); + cleanupFilters.push_back(tmpFilter); + tmpFilter = new ThMLStrongs(); optionFilters.insert(FilterMap::value_type("ThMLStrongs", tmpFilter)); cleanupFilters.push_back(tmpFilter); @@ -156,18 +209,22 @@ void SWMgr::init() { optionFilters.insert(FilterMap::value_type("GreekLexAttribs", tmpFilter)); cleanupFilters.push_back(tmpFilter); -/* UTF8Transliterator needs to be handled differently because it should always available as an option, for all modules -#ifdef ICU - tmpFilter = new UTF8Transliterator(); - optionFilters.insert(FilterMap::value_type("UTF8Transliterator", tmpFilter)); - cleanupFilters.push_back(tmpFilter); +// UTF8Transliterator needs to be handled differently because it should always available as an option, for all modules +#ifdef _ICU_ + transliterator = new UTF8Transliterator(); + optionFilters.insert(FilterMap::value_type("UTF8Transliterator", transliterator)); + options.push_back(transliterator->getOptionName()); + cleanupFilters.push_back(transliterator); #endif -*/ + gbfplain = new GBFPlain(); cleanupFilters.push_back(gbfplain); thmlplain = new ThMLPlain(); cleanupFilters.push_back(thmlplain); + + osisplain = new OSISPlain(); + cleanupFilters.push_back(osisplain); } @@ -206,7 +263,7 @@ void SWMgr::commonInit(SWConfig * iconfig, SWConfig * isysconfig, bool autoload, SWMgr::SWMgr(const char *iConfigPath, bool autoload, SWFilterMgr *filterMgr) { - string path; + SWBuf path; this->filterMgr = filterMgr; if (filterMgr) @@ -215,7 +272,8 @@ SWMgr::SWMgr(const char *iConfigPath, bool autoload, SWFilterMgr *filterMgr) { init(); path = iConfigPath; - if ((iConfigPath[strlen(iConfigPath)-1] != '\\') && (iConfigPath[strlen(iConfigPath)-1] != '/')) + int len = path.length(); + if ((len < 1) || (iConfigPath[len-1] != '\\') && (iConfigPath[len-1] != '/')) path += "/"; if (FileMgr::existsFile(path.c_str(), "mods.conf")) { stdstr(&prefixPath, path.c_str()); @@ -263,9 +321,10 @@ SWMgr::~SWMgr() { } -void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath) { - string path; +void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath, std::list<SWBuf> *augPaths) { + SWBuf path; ConfigEntMap::iterator entry; + ConfigEntMap::iterator lastEntry; char *envsworddir = getenv ("SWORD_PATH"); char *envhomedir = getenv ("HOME"); @@ -275,14 +334,14 @@ void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath) { #ifndef _MSC_VER // check working directory if (debug) - cerr << "Checking working directory for mods.conf..."; + std::cerr << "Checking working directory for mods.conf..."; #endif if (FileMgr::existsFile(".", "mods.conf")) { #ifndef _MSC_VER if (debug) - cerr << "found\n"; + std::cerr << "found\n"; #endif stdstr(prefixPath, "./"); @@ -292,14 +351,14 @@ if (debug) #ifndef _MSC_VER if (debug) - cerr << "\nChecking working directory for mods.d..."; + std::cerr << "\nChecking working directory for mods.d..."; #endif if (FileMgr::existsDir(".", "mods.d")) { #ifndef _MSC_VER if (debug) - cerr << "found\n"; + std::cerr << "found\n"; #endif stdstr(prefixPath, "./"); @@ -312,14 +371,14 @@ if (debug) // check environment variable SWORD_PATH #ifndef _MSC_VER if (debug) - cerr << "\nChecking SWORD_PATH..."; + std::cerr << "\nChecking SWORD_PATH..."; #endif if (envsworddir != NULL) { #ifndef _MSC_VER if (debug) - cerr << "found (" << envsworddir << ")\n"; + std::cerr << "found (" << envsworddir << ")\n"; #endif path = envsworddir; @@ -328,14 +387,14 @@ if (debug) #ifndef _MSC_VER if (debug) - cerr << "\nChecking $SWORD_PATH for mods.conf..."; + std::cerr << "\nChecking $SWORD_PATH for mods.conf..."; #endif if (FileMgr::existsFile(path.c_str(), "mods.conf")) { #ifndef _MSC_VER if (debug) - cerr << "found\n"; + std::cerr << "found\n"; #endif stdstr(prefixPath, path.c_str()); @@ -346,14 +405,14 @@ if (debug) #ifndef _MSC_VER if (debug) - cerr << "\nChecking $SWORD_PATH for mods.d..."; + std::cerr << "\nChecking $SWORD_PATH for mods.d..."; #endif if (FileMgr::existsDir(path.c_str(), "mods.d")) { #ifndef _MSC_VER if (debug) - cerr << "found\n"; + std::cerr << "found\n"; #endif stdstr(prefixPath, path.c_str()); @@ -369,7 +428,7 @@ if (debug) #ifndef _MSC_VER if (debug) - cerr << "\nParsing " << globalConfPath << "..."; + std::cerr << "\nParsing " << globalConfPath << "..."; #endif char *globPaths = 0; @@ -377,23 +436,41 @@ if (debug) stdstr(&globPaths, globalConfPath); for (gfp = strtok(globPaths, ":"); gfp; gfp = strtok(0, ":")) { - #ifndef _MSC_VER +#ifndef _MSC_VER if (debug) - cerr << "\nChecking for " << gfp << "..."; + std::cerr << "\nChecking for " << gfp << "..."; #endif if (FileMgr::existsFile(gfp)) break; } + SWBuf sysConfPath; + if (gfp) + sysConfPath = gfp; + + SWBuf homeDir = getenv ("HOME"); + if (homeDir.size() > 0) { + if ((homeDir[homeDir.size()-1] != '\\') && (homeDir[homeDir.size()-1] != '/')) + homeDir += "/"; + homeDir += ".sword/sword.conf"; + if (FileMgr::existsFile(homeDir)) { +#ifndef _MSC_VER +if (debug) + std::cerr << "\nOverriding any systemwide sword.conf with one found in users home directory." << gfp << "..."; +#endif + sysConfPath = homeDir; + } + } + - if (gfp) { + if (sysConfPath.size()) { #ifndef _MSC_VER if (debug) - cerr << "found\n"; + std::cerr << "found\n"; #endif - SWConfig etcconf(gfp); + SWConfig etcconf(sysConfPath); if ((entry = etcconf.Sections["Install"].find("DataPath")) != etcconf.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] != '/')) @@ -401,56 +478,66 @@ if (debug) #ifndef _MSC_VER if (debug) - cerr << "DataPath in " << gfp << " is set to: " << path; + std::cerr << "DataPath in " << sysConfPath << " is set to: " << path; #endif #ifndef _MSC_VER if (debug) - cerr << "\nChecking for mods.conf in DataPath "; + std::cerr << "\nChecking for mods.conf in DataPath "; #endif if (FileMgr::existsFile(path.c_str(), "mods.conf")) { #ifndef _MSC_VER if (debug) - cerr << "found\n"; + std::cerr << "found\n"; #endif stdstr(prefixPath, path.c_str()); path += "mods.conf"; stdstr(configPath, path.c_str()); - delete [] globPaths; - return; + *configType = 1; } #ifndef _MSC_VER if (debug) - cerr << "\nChecking for mods.d in DataPath "; + std::cerr << "\nChecking for mods.d in DataPath "; #endif if (FileMgr::existsDir(path.c_str(), "mods.d")) { #ifndef _MSC_VER if (debug) - cerr << "found\n"; + std::cerr << "found\n"; #endif stdstr(prefixPath, path.c_str()); path += "mods.d"; stdstr(configPath, path.c_str()); *configType = 1; - delete [] globPaths; - return; + } + } + if (augPaths) { + augPaths->clear(); + entry = etcconf.Sections["Install"].lower_bound("AugmentPath"); + lastEntry = etcconf.Sections["Install"].upper_bound("AugmentPath"); + for (;entry != lastEntry; entry++) { + 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 += "/"; + augPaths->push_back(path); } } } delete [] globPaths; + if (*configType) + return; // check ~/.sword/ #ifndef _MSC_VER if (debug) - cerr << "\nChecking home directory for ~/.sword/mods.conf" << path; + std::cerr << "\nChecking home directory for ~/.sword/mods.conf" << path; #endif if (envhomedir != NULL) { @@ -462,7 +549,7 @@ if (debug) #ifndef _MSC_VER if (debug) - cerr << " found\n"; + std::cerr << " found\n"; #endif stdstr(prefixPath, path.c_str()); @@ -473,14 +560,14 @@ if (debug) #ifndef _MSC_VER if (debug) - cerr << "\nChecking home directory for ~/.sword/mods.d" << path; + std::cerr << "\nChecking home directory for ~/.sword/mods.d" << path; #endif if (FileMgr::existsDir(path.c_str(), "mods.d")) { #ifndef _MSC_VER if (debug) - cerr << "found\n"; + std::cerr << "found\n"; #endif stdstr(prefixPath, path.c_str()); @@ -497,7 +584,7 @@ void SWMgr::loadConfigDir(const char *ipath) { DIR *dir; struct dirent *ent; - string newmodfile; + SWBuf newmodfile; if ((dir = opendir(ipath))) { rewinddir(dir); @@ -526,6 +613,36 @@ void SWMgr::loadConfigDir(const char *ipath) } +void SWMgr::augmentModules(const char *ipath) { + SWBuf path = ipath; + if ((ipath[strlen(ipath)-1] != '\\') && (ipath[strlen(ipath)-1] != '/')) + path += "/"; + if (FileMgr::existsDir(path.c_str(), "mods.d")) { + char *savePrefixPath = 0; + char *saveConfigPath = 0; + SWConfig *saveConfig = 0; + stdstr(&savePrefixPath, prefixPath); + stdstr(&prefixPath, path.c_str()); + path += "mods.d"; + stdstr(&saveConfigPath, configPath); + stdstr(&configPath, path.c_str()); + saveConfig = config; + config = myconfig = 0; + loadConfigDir(configPath); + + CreateMods(); + + stdstr(&prefixPath, savePrefixPath); + delete []savePrefixPath; + stdstr(&configPath, saveConfigPath); + delete []saveConfigPath; + (*saveConfig) += *config; + homeConfig = myconfig; + config = myconfig = saveConfig; + } +} + + /*********************************************************************** * SWMgr::Load - loads actual modules * @@ -538,7 +655,7 @@ 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... - findConfig(&configType, &prefixPath, &configPath); + findConfig(&configType, &prefixPath, &configPath, &augPaths); if (configPath) { if (configType) loadConfigDir(configPath); @@ -565,37 +682,18 @@ signed char SWMgr::Load() { CreateMods(); + for (std::list<SWBuf>::iterator pathIt = augPaths.begin(); pathIt != augPaths.end(); pathIt++) { + augmentModules(pathIt->c_str()); + } // augment config with ~/.sword/mods.d if it exists --------------------- - char *envhomedir = getenv ("HOME"); - if (envhomedir != NULL && configType != 2) { // 2 = user only - string path = envhomedir; - if ((envhomedir[strlen(envhomedir)-1] != '\\') && (envhomedir[strlen(envhomedir)-1] != '/')) - path += "/"; - path += ".sword/"; - if (FileMgr::existsDir(path.c_str(), "mods.d")) { - char *savePrefixPath = 0; - char *saveConfigPath = 0; - SWConfig *saveConfig = 0; - stdstr(&savePrefixPath, prefixPath); - stdstr(&prefixPath, path.c_str()); - path += "mods.d"; - stdstr(&saveConfigPath, configPath); - stdstr(&configPath, path.c_str()); - saveConfig = config; - config = myconfig = 0; - loadConfigDir(configPath); - - CreateMods(); - - stdstr(&prefixPath, savePrefixPath); - delete []savePrefixPath; - stdstr(&configPath, saveConfigPath); - delete []saveConfigPath; - (*saveConfig) += *config; - homeConfig = myconfig; - config = myconfig = saveConfig; - } - } + 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 += "/"; + path += ".sword/"; + augmentModules(path.c_str()); + } // ------------------------------------------------------------------------- if ( !Modules.size() ) // config exists, but no modules ret = 1; @@ -609,65 +707,69 @@ signed char SWMgr::Load() { return ret; } -SWModule *SWMgr::CreateMod(string name, string driver, ConfigEntMap §ion) +SWModule *SWMgr::CreateMod(const char *name, const char *driver, ConfigEntMap §ion) { - string description, datapath, misc1; + SWBuf description, datapath, misc1; ConfigEntMap::iterator entry; SWModule *newmod = 0; - string lang, sourceformat, encoding; - signed char direction, enc, markup; + SWBuf lang, sourceformat, encoding; + signed char direction, enc, markup; - description = ((entry = section.find("Description")) != section.end()) ? (*entry).second : (string)""; - lang = ((entry = section.find("Lang")) != section.end()) ? (*entry).second : (string)"en"; - sourceformat = ((entry = section.find("SourceType")) != section.end()) ? (*entry).second : (string)""; - encoding = ((entry = section.find("Encoding")) != section.end()) ? (*entry).second : (string)""; + description = ((entry = section.find("Description")) != section.end()) ? (*entry).second : (SWBuf)""; + lang = ((entry = section.find("Lang")) != section.end()) ? (*entry).second : (SWBuf)"en"; + sourceformat = ((entry = section.find("SourceType")) != section.end()) ? (*entry).second : (SWBuf)""; + encoding = ((entry = section.find("Encoding")) != section.end()) ? (*entry).second : (SWBuf)""; datapath = prefixPath; if ((prefixPath[strlen(prefixPath)-1] != '\\') && (prefixPath[strlen(prefixPath)-1] != '/')) datapath += "/"; - misc1 += ((entry = section.find("DataPath")) != section.end()) ? (*entry).second : (string)""; + misc1 += ((entry = section.find("DataPath")) != section.end()) ? (*entry).second : (SWBuf)""; char *buf = new char [ strlen(misc1.c_str()) + 1 ]; char *buf2 = buf; strcpy(buf, misc1.c_str()); // for (; ((*buf2) && ((*buf2 == '.') || (*buf2 == '/') || (*buf2 == '\\'))); buf2++); for (; ((*buf2) && ((*buf2 == '/') || (*buf2 == '\\'))); buf2++); + if (!strncmp(buf2, "./", 2)) { //remove the leading ./ in the module data path to make it look better + buf2 += 2; + } if (*buf2) datapath += buf2; delete [] buf; section["AbsoluteDataPath"] = datapath; - if (!stricmp(sourceformat.c_str(), "GBF")) - markup = FMT_GBF; - else if (!stricmp(sourceformat.c_str(), "ThML")) - markup = FMT_THML; - else if (!stricmp(sourceformat.c_str(), "OSIS")) - markup = FMT_OSIS; - else - markup = FMT_PLAIN; - - if (!stricmp(encoding.c_str(), "SCSU")) - enc = ENC_SCSU; - else if (!stricmp(encoding.c_str(), "UTF-8")) - enc = ENC_UTF8; - else enc = ENC_LATIN1; + if (!stricmp(sourceformat.c_str(), "GBF")) + markup = FMT_GBF; + else if (!stricmp(sourceformat.c_str(), "ThML")) + markup = FMT_THML; + else if (!stricmp(sourceformat.c_str(), "OSIS")) + markup = FMT_OSIS; + else + markup = FMT_GBF; + + if (!stricmp(encoding.c_str(), "SCSU")) + enc = ENC_SCSU; + else if (!stricmp(encoding.c_str(), "UTF-8")) { + enc = ENC_UTF8; + } + else enc = ENC_LATIN1; if ((entry = section.find("Direction")) == section.end()) { - direction = DIRECTION_LTR; - } - else if (!stricmp((*entry).second.c_str(), "rtol")) { - direction = DIRECTION_RTL; - } - else if (!stricmp((*entry).second.c_str(), "bidi")) { - direction = DIRECTION_BIDI; - } - else { - direction = DIRECTION_LTR; - } + direction = DIRECTION_LTR; + } + else if (!stricmp((*entry).second.c_str(), "rtol")) { + direction = DIRECTION_RTL; + } + else if (!stricmp((*entry).second.c_str(), "bidi")) { + direction = DIRECTION_BIDI; + } + else { + direction = DIRECTION_LTR; + } - if ((!stricmp(driver.c_str(), "zText")) || (!stricmp(driver.c_str(), "zCom"))) { + if ((!stricmp(driver, "zText")) || (!stricmp(driver, "zCom"))) { SWCompress *compress = 0; int blockType = CHAPTERBLOCKS; - misc1 = ((entry = section.find("BlockType")) != section.end()) ? (*entry).second : (string)"CHAPTER"; + misc1 = ((entry = section.find("BlockType")) != section.end()) ? (*entry).second : (SWBuf)"CHAPTER"; if (!stricmp(misc1.c_str(), "VERSE")) blockType = VERSEBLOCKS; else if (!stricmp(misc1.c_str(), "CHAPTER")) @@ -675,7 +777,7 @@ SWModule *SWMgr::CreateMod(string name, string driver, ConfigEntMap §ion) else if (!stricmp(misc1.c_str(), "BOOK")) blockType = BOOKBLOCKS; - misc1 = ((entry = section.find("CompressType")) != section.end()) ? (*entry).second : (string)"LZSS"; + misc1 = ((entry = section.find("CompressType")) != section.end()) ? (*entry).second : (SWBuf)"LZSS"; #ifndef EXCLUDEZLIB if (!stricmp(misc1.c_str(), "ZIP")) compress = new ZipCompress(); @@ -685,48 +787,53 @@ SWModule *SWMgr::CreateMod(string name, string driver, ConfigEntMap §ion) compress = new LZSSCompress(); if (compress) { - if (!stricmp(driver.c_str(), "zText")) - newmod = new zText(datapath.c_str(), name.c_str(), description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str()); - else newmod = new zCom(datapath.c_str(), name.c_str(), description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str()); + 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()); } } - if (!stricmp(driver.c_str(), "RawText")) { - newmod = new RawText(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str()); + if (!stricmp(driver, "RawText")) { + newmod = new RawText(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str()); } // backward support old drivers - if (!stricmp(driver.c_str(), "RawGBF")) { - newmod = new RawText(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str()); + if (!stricmp(driver, "RawGBF")) { + newmod = new RawText(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str()); } - if (!stricmp(driver.c_str(), "RawCom")) { - newmod = new RawCom(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str()); + if (!stricmp(driver, "RawCom")) { + newmod = new RawCom(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str()); } - if (!stricmp(driver.c_str(), "RawFiles")) { - newmod = new RawFiles(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str()); + if (!stricmp(driver, "RawFiles")) { + newmod = new RawFiles(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str()); } - if (!stricmp(driver.c_str(), "HREFCom")) { - misc1 = ((entry = section.find("Prefix")) != section.end()) ? (*entry).second : (string)""; - newmod = new HREFCom(datapath.c_str(), misc1.c_str(), name.c_str(), description.c_str()); + if (!stricmp(driver, "HREFCom")) { + misc1 = ((entry = section.find("Prefix")) != section.end()) ? (*entry).second : (SWBuf)""; + newmod = new HREFCom(datapath.c_str(), misc1.c_str(), name, description.c_str()); } - if (!stricmp(driver.c_str(), "RawLD")) - newmod = new RawLD(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str()); + int pos; //used for position of final / in AbsoluteDataPath, but also set to 1 for modules types that need to strip module name + if (!stricmp(driver, "RawLD")) { + newmod = new RawLD(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str()); + pos = 1; + } - if (!stricmp(driver.c_str(), "RawLD4")) - newmod = new RawLD4(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str()); + if (!stricmp(driver, "RawLD4")) { + newmod = new RawLD4(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str()); + pos = 1; + } - if (!stricmp(driver.c_str(), "zLD")) { + if (!stricmp(driver, "zLD")) { SWCompress *compress = 0; int blockCount; - misc1 = ((entry = section.find("BlockCount")) != section.end()) ? (*entry).second : (string)"200"; + misc1 = ((entry = section.find("BlockCount")) != section.end()) ? (*entry).second : (SWBuf)"200"; blockCount = atoi(misc1.c_str()); blockCount = (blockCount) ? blockCount : 200; - misc1 = ((entry = section.find("CompressType")) != section.end()) ? (*entry).second : (string)"LZSS"; + misc1 = ((entry = section.find("CompressType")) != section.end()) ? (*entry).second : (SWBuf)"LZSS"; #ifndef EXCLUDEZLIB if (!stricmp(misc1.c_str(), "ZIP")) compress = new ZipCompress(); @@ -736,18 +843,31 @@ SWModule *SWMgr::CreateMod(string name, string driver, ConfigEntMap §ion) compress = new LZSSCompress(); if (compress) { - newmod = new zLD(datapath.c_str(), name.c_str(), description.c_str(), blockCount, compress, 0, enc, direction, markup, lang.c_str()); + newmod = new zLD(datapath.c_str(), name, description.c_str(), blockCount, compress, 0, enc, direction, markup, lang.c_str()); } + pos = 1; } - if (!stricmp(driver.c_str(), "RawGenBook")) { - newmod = new RawGenBook(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str()); + if (!stricmp(driver, "RawGenBook")) { + newmod = new RawGenBook(datapath.c_str(), name, description.c_str(), 0, enc, direction, markup, lang.c_str()); + pos = 1; } - // 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()); - newmod->setConfig(§ion); + if (pos == 1) { + SWBuf &dp = section["AbsoluteDataPath"]; + for (int i = dp.length() - 1; i; i--) { + if (dp[i] == '/') { + dp.setSize(i); + break; + } + } + } + + // 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()); + + newmod->setConfig(§ion); return newmod; } @@ -758,7 +878,7 @@ void SWMgr::AddGlobalOptions(SWModule *module, ConfigEntMap §ion, ConfigEntM it = optionFilters.find((*start).second); if (it != optionFilters.end()) { module->AddOptionFilter((*it).second); // add filter to module and option as a valid option - OptionsList::iterator loop; + StringList::iterator loop; for (loop = options.begin(); loop != options.end(); loop++) { if (!strcmp((*loop).c_str(), (*it).second->getOptionName())) break; @@ -769,6 +889,9 @@ void SWMgr::AddGlobalOptions(SWModule *module, ConfigEntMap §ion, ConfigEntM } if (filterMgr) filterMgr->AddGlobalOptions(module, section, start, end); +#ifdef _ICU_ + module->AddOptionFilter(transliterator); +#endif } @@ -788,11 +911,11 @@ void SWMgr::AddLocalOptions(SWModule *module, ConfigEntMap §ion, ConfigEntMa void SWMgr::AddRawFilters(SWModule *module, ConfigEntMap §ion) { - string sourceformat, cipherKey; + SWBuf sourceformat, cipherKey; ConfigEntMap::iterator entry; - cipherKey = ((entry = section.find("CipherKey")) != section.end()) ? (*entry).second : (string)""; - if (!cipherKey.empty()) { + cipherKey = ((entry = section.find("CipherKey")) != section.end()) ? (*entry).second : (SWBuf)""; + if (cipherKey.length()) { SWFilter *cipherFilter = new CipherFilter(cipherKey.c_str()); cipherFilters.insert(FilterMap::value_type(module->Name(), cipherFilter)); cleanupFilters.push_back(cipherFilter); @@ -805,22 +928,21 @@ void SWMgr::AddRawFilters(SWModule *module, ConfigEntMap §ion) { void SWMgr::AddEncodingFilters(SWModule *module, ConfigEntMap §ion) { - if (filterMgr) filterMgr->AddEncodingFilters(module, section); } void SWMgr::AddRenderFilters(SWModule *module, ConfigEntMap §ion) { - string sourceformat; + SWBuf sourceformat; ConfigEntMap::iterator entry; - sourceformat = ((entry = section.find("SourceType")) != section.end()) ? (*entry).second : (string)""; + sourceformat = ((entry = section.find("SourceType")) != section.end()) ? (*entry).second : (SWBuf)""; // Temporary: To support old module types - // TODO: Remove at 1.6.0 release? - if (sourceformat.empty()) { - sourceformat = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (string)""; + // TODO: Remove at 1.6.0 release? + if (!sourceformat.length()) { + sourceformat = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (SWBuf)""; if (!stricmp(sourceformat.c_str(), "RawGBF")) sourceformat = "GBF"; else sourceformat = ""; @@ -839,13 +961,13 @@ void SWMgr::AddRenderFilters(SWModule *module, ConfigEntMap §ion) { void SWMgr::AddStripFilters(SWModule *module, ConfigEntMap §ion) { - string sourceformat; + SWBuf sourceformat; ConfigEntMap::iterator entry; - sourceformat = ((entry = section.find("SourceType")) != section.end()) ? (*entry).second : (string)""; + sourceformat = ((entry = section.find("SourceType")) != section.end()) ? (*entry).second : (SWBuf)""; // Temporary: To support old module types - if (sourceformat.empty()) { - sourceformat = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (string)""; + if (!sourceformat.length()) { + sourceformat = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (SWBuf)""; if (!stricmp(sourceformat.c_str(), "RawGBF")) sourceformat = "GBF"; else sourceformat = ""; @@ -857,6 +979,9 @@ void SWMgr::AddStripFilters(SWModule *module, ConfigEntMap §ion) else if (!stricmp(sourceformat.c_str(), "ThML")) { module->AddStripFilter(thmlplain); } + else if (!stricmp(sourceformat.c_str(), "OSIS")) { + module->AddStripFilter(osisplain); + } if (filterMgr) filterMgr->AddStripFilters(module, section); @@ -870,13 +995,13 @@ void SWMgr::CreateMods() { ConfigEntMap::iterator end; ConfigEntMap::iterator entry; SWModule *newmod; - string driver, misc1; + SWBuf driver, misc1; for (it = config->Sections.begin(); it != config->Sections.end(); it++) { ConfigEntMap §ion = (*it).second; newmod = 0; - driver = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (string)""; - if (!driver.empty()) { + driver = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (SWBuf)""; + if (driver.length()) { newmod = CreateMod((*it).first, driver, section); if (newmod) { start = (*it).second.lower_bound("GlobalOptionFilter"); @@ -915,8 +1040,8 @@ void SWMgr::InstallScan(const char *dirname) DIR *dir; struct dirent *ent; int conffd = 0; - string newmodfile; - string targetName; + SWBuf newmodfile; + SWBuf targetName; if (!access(dirname, 04)) { if ((dir = opendir(dirname))) { @@ -1008,15 +1133,15 @@ const char *SWMgr::getGlobalOptionTip(const char *option) } -OptionsList SWMgr::getGlobalOptions() +StringList SWMgr::getGlobalOptions() { return options; } -OptionsList SWMgr::getGlobalOptionValues(const char *option) +StringList SWMgr::getGlobalOptionValues(const char *option) { - OptionsList options; + StringList options; for (FilterMap::iterator it = optionFilters.begin(); it != optionFilters.end(); it++) { if ((*it).second->getOptionName()) { if (!stricmp(option, (*it).second->getOptionName())) { @@ -1052,3 +1177,5 @@ signed char SWMgr::setCipherKey(const char *modName, const char *key) { } return -1; } + +SWORD_NAMESPACE_END diff --git a/src/mgr/swsearchable.cpp b/src/mgr/swsearchable.cpp new file mode 100644 index 0000000..d81375d --- /dev/null +++ b/src/mgr/swsearchable.cpp @@ -0,0 +1,42 @@ +/****************************************************************************** + * swsearchable.h - definition of class SWSearchable used to provide an + * interface for objects that be searched. + * + * $Id: swsearchable.cpp,v 1.1 2003/08/29 06:00:16 scribe Exp $ + * + * 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 <swsearchable.h> + +SWORD_NAMESPACE_START + +void SWSearchable::nullPercent(char percent, void *percentUserData) {} + +SWSearchable::SWSearchable() { +} + + +SWSearchable::~SWSearchable() { +} + + // special search framework +signed char SWSearchable::createSearchFramework() { + return 0; +} + + +SWORD_NAMESPACE_END diff --git a/src/mgr/swsourcemgr.cpp b/src/mgr/swsourcemgr.cpp new file mode 100644 index 0000000..58df9f0 --- /dev/null +++ b/src/mgr/swsourcemgr.cpp @@ -0,0 +1,91 @@ +/****************************************************************************** + * swsourcemgr.cpp - implementaion of class SWMgr used to interact with an install + * base of sword modules. + * + * $Id: swsourcemgr.cpp,v 1.2 2003/06/27 01:41:07 scribe Exp $ + * + * Copyright 2002 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 "swsourcemgr.h" + #include "filemgr.h" + #include "utilstr.h" + #include "swconfig.h" + #include <dirent.h> + + SWORD_NAMESPACE_START + + SWSourceMgr::SWSourceMgr(const char *iConfigPath) { + SWBuf path; + + //init(); + + path = iConfigPath; + if ((iConfigPath[strlen(iConfigPath)-1] != '\\') && (iConfigPath[strlen(iConfigPath)-1] != '/')) + path += "/"; + if (FileMgr::existsFile(path.c_str(), "mods.conf")) { + stdstr(&prefixPath, path.c_str()); + path += "mods.conf"; + stdstr(&configPath, path.c_str()); + } + else { + if (FileMgr::existsDir(path.c_str(), "mods.d")) { + stdstr(&prefixPath, path.c_str()); + path += "mods.d"; + stdstr(&configPath, path.c_str()); + configType = 1; + } + } + + if (configPath) + loadConfigDir(configPath); +} + +void SWSourceMgr::loadConfigDir(const char *ipath) +{ + DIR *dir; + struct dirent *ent; + SWBuf newmodfile; + + if ((dir = opendir(ipath))) { + rewinddir(dir); + while ((ent = readdir(dir))) { + 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()); + } + } + closedir(dir); + if (!config) { // if no .conf file exist yet, create a default + newmodfile = ipath; + if ((ipath[strlen(ipath)-1] != '\\') && (ipath[strlen(ipath)-1] != '/')) + newmodfile += "/"; + newmodfile += "globals.conf"; + config = myconfig = new SWConfig(newmodfile.c_str()); + } + } +} + + + + SWORD_NAMESPACE_END diff --git a/src/modules/comments/hrefcom/hrefcom.cpp b/src/modules/comments/hrefcom/hrefcom.cpp index a80e5b6..42b2745 100644 --- a/src/modules/comments/hrefcom/hrefcom.cpp +++ b/src/modules/comments/hrefcom/hrefcom.cpp @@ -15,11 +15,11 @@ #include <unistd.h> #endif -#include <string.h> #include <utilfuns.h> #include <rawverse.h> #include <hrefcom.h> +SWORD_NAMESPACE_START /****************************************************************************** * HREFCom Constructor - Initializes data for instance of HREFCom @@ -55,10 +55,9 @@ HREFCom::~HREFCom() * RET: string buffer with verse */ -char *HREFCom::getRawEntry() { +SWBuf &HREFCom::getRawEntryBuf() { long start; unsigned short size; - char *tmpbuf; VerseKey *key = 0; #ifndef _WIN32_WCE @@ -72,26 +71,20 @@ char *HREFCom::getRawEntry() { if (!key) key = new VerseKey(this->key); - findoffset(key->Testament(), key->Index(), &start, &size); + findOffset(key->Testament(), key->Index(), &start, &size); entrySize = size; // support getEntrySize call - unsigned long newsize = ((size + 2) + strlen(prefix)) * FILTERPAD; - if (newsize > entrybufallocsize) { - if (entrybuf) - delete [] entrybuf; - entrybuf = new char [ newsize ]; - entrybufallocsize = newsize; - } - tmpbuf = new char [ size + 10 ]; - - gettext(key->Testament(), start, size + 2, tmpbuf); - sprintf(entrybuf, "%s%s", prefix, tmpbuf); - preptext(entrybuf); + SWBuf tmpbuf; - delete [] tmpbuf; + readText(key->Testament(), start, size, tmpbuf); + entryBuf = prefix; + entryBuf += tmpbuf.c_str(); + prepText(entryBuf); if (key != this->key) delete key; - return entrybuf; + return entryBuf; } + +SWORD_NAMESPACE_END diff --git a/src/modules/comments/rawcom/rawcom.cpp b/src/modules/comments/rawcom/rawcom.cpp index ca93c64..e34af2e 100644 --- a/src/modules/comments/rawcom/rawcom.cpp +++ b/src/modules/comments/rawcom/rawcom.cpp @@ -14,11 +14,11 @@ #include <unistd.h> #endif -#include <string.h> #include <utilfuns.h> #include <rawverse.h> #include <rawcom.h> +SWORD_NAMESPACE_START /****************************************************************************** * RawCom Constructor - Initializes data for instance of RawCom @@ -44,206 +44,98 @@ RawCom::~RawCom() /****************************************************************************** - * RawCom::operator char * - Returns the correct verse when char * cast + * RawCom::getRawEntry() - Returns the correct verse when char * cast * is requested * * RET: string buffer with verse */ -char *RawCom::getRawEntry() { +SWBuf &RawCom::getRawEntryBuf() { long start = 0; unsigned short size = 0; - VerseKey *key = 0; + VerseKey *key = &getVerseKey(); -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!key) - key = new VerseKey(this->key); - - - findoffset(key->Testament(), key->Index(), &start, &size); + findOffset(key->Testament(), key->Index(), &start, &size); entrySize = size; // support getEntrySize call - unsigned long newsize = (size + 2) * FILTERPAD; - if (newsize > entrybufallocsize) { - if (entrybuf) - delete [] entrybuf; - entrybuf = new char [ newsize ]; - entrybufallocsize = newsize; - } - *entrybuf = 0; - - gettext(key->Testament(), start, (size + 2), entrybuf); - - rawFilter(entrybuf, size, key); + entryBuf = ""; + readText(key->Testament(), start, size, entryBuf); - if (!isUnicode()) - preptext(entrybuf); + rawFilter(entryBuf, 0); // hack, decipher + rawFilter(entryBuf, key); - if (key != this->key) - delete key; +// if (!isUnicode()) + prepText(entryBuf); - return entrybuf; + return entryBuf; } /****************************************************************************** - * RawCom::operator += - Increments module key a number of entries + * RawCom::increment - Increments module key a number of entries * - * ENT: increment - Number of entries to jump forward + * ENT: steps - Number of entries to jump forward * * RET: *this */ -SWModule &RawCom::operator +=(int increment) -{ +void RawCom::increment(int steps) { long start; unsigned short size; - VerseKey *tmpkey = 0; - -#ifndef _WIN32_WCE - try { -#endif - tmpkey = SWDYNAMIC_CAST(VerseKey, key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!tmpkey) - tmpkey = new VerseKey(key); + VerseKey *tmpkey = &getVerseKey(); - findoffset(tmpkey->Testament(), tmpkey->Index(), &start, &size); + findOffset(tmpkey->Testament(), tmpkey->Index(), &start, &size); SWKey lastgood = *tmpkey; - while (increment) { + while (steps) { long laststart = start; unsigned short lastsize = size; SWKey lasttry = *tmpkey; - (increment > 0) ? (*key)++ : (*key)--; - if (tmpkey != key) - delete tmpkey; - tmpkey = 0; -#ifndef _WIN32_WCE - try { -#endif - tmpkey = SWDYNAMIC_CAST(VerseKey, key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!tmpkey) - tmpkey = new VerseKey(key); + (steps > 0) ? (*key)++ : (*key)--; + tmpkey = &getVerseKey(); if ((error = key->Error())) { *key = lastgood; break; } long index = tmpkey->Index(); - findoffset(tmpkey->Testament(), index, &start, &size); - if ((((laststart != start) || (lastsize != size))||(!skipConsecutiveLinks)) && (start >= 0) && (size)) { - increment += (increment < 0) ? 1 : -1; + findOffset(tmpkey->Testament(), index, &start, &size); + if ( + (((laststart != start) || (lastsize != size)) // we're a different entry +// && (start > 0) + && (size)) // and we actually have a size + ||(!skipConsecutiveLinks)) { // or we don't want to skip consecutive links + steps += (steps < 0) ? 1 : -1; lastgood = *tmpkey; } } error = (error) ? KEYERR_OUTOFBOUNDS : 0; - - if (tmpkey != key) - delete tmpkey; - - return *this; } -SWModule &RawCom::setentry(const char *inbuf, long len) { - VerseKey *key = 0; - // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - // if we don't have a VerseKey * decendant, create our own - if (!key) - key = new VerseKey(this->key); - - settext(key->Testament(), key->Index(), inbuf, len); - - if (this->key != key) // free our key if we created a VerseKey - delete key; - return *this; -} - -SWModule &RawCom::operator <<(const char *inbuf) { - VerseKey *key = 0; - // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - // if we don't have a VerseKey * decendant, create our own - if (!key) - key = new VerseKey(this->key); - - settext(key->Testament(), key->Index(), inbuf); - - if (this->key != key) // free our key if we created a VerseKey - delete key; - - return *this; +void RawCom::setEntry(const char *inbuf, long len) { + VerseKey *key = &getVerseKey(); + doSetText(key->Testament(), key->Index(), inbuf, len); } -SWModule &RawCom::operator <<(const SWKey *inkey) { - VerseKey *destkey = 0; +void RawCom::linkEntry(const SWKey *inkey) { + VerseKey *destkey = &getVerseKey(); const VerseKey *srckey = 0; - // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE - try { -#endif - destkey = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - // if we don't have a VerseKey * decendant, create our own - if (!destkey) - destkey = new VerseKey(this->key); // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE try { -#endif srckey = SWDYNAMIC_CAST(VerseKey, inkey); -#ifndef _WIN32_WCE } catch ( ... ) {} -#endif // if we don't have a VerseKey * decendant, create our own if (!srckey) srckey = new VerseKey(inkey); - linkentry(destkey->Testament(), destkey->Index(), srckey->Index()); - - if (this->key != destkey) // free our key if we created a VerseKey - delete destkey; + doLinkEntry(destkey->Testament(), destkey->Index(), srckey->Index()); if (inkey != srckey) // free our key if we created a VerseKey delete srckey; - - return *this; } @@ -255,21 +147,38 @@ SWModule &RawCom::operator <<(const SWKey *inkey) { void RawCom::deleteEntry() { - VerseKey *key = 0; + VerseKey *key = &getVerseKey(); + doSetText(key->Testament(), key->Index(), ""); +} -#ifndef _WIN32_WCE + +VerseKey &RawCom::getVerseKey() { + static VerseKey tmpVK; + VerseKey *key; + // see if we have a VerseKey * or decendant try { -#endif key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE } - catch ( ... ) {} -#endif - if (!key) - key = new VerseKey(this->key); + catch ( ... ) { } + if (!key) { + ListKey *lkTest = 0; + try { + lkTest = SWDYNAMIC_CAST(ListKey, this->key); + } + catch ( ... ) { } + if (lkTest) { + try { + key = SWDYNAMIC_CAST(VerseKey, lkTest->GetElement()); + } + catch ( ... ) { } + } + } + if (!key) { + tmpVK = *(this->key); + return tmpVK; + } + else return *key; +} - settext(key->Testament(), key->Index(), ""); - if (key != this->key) - delete key; -} +SWORD_NAMESPACE_END diff --git a/src/modules/comments/rawfiles/rawfiles.cpp b/src/modules/comments/rawfiles/rawfiles.cpp index c8e9388..9ffa00f 100644 --- a/src/modules/comments/rawfiles/rawfiles.cpp +++ b/src/modules/comments/rawfiles/rawfiles.cpp @@ -15,7 +15,6 @@ #include <unistd.h> #endif -#include <string.h> #include <utilfuns.h> #include <rawverse.h> #include <rawfiles.h> @@ -25,6 +24,7 @@ #define O_BINARY 0 // If it hasn't been defined than we probably #endif // don't need it. +SWORD_NAMESPACE_START /****************************************************************************** * RawFiles Constructor - Initializes data for instance of RawFiles @@ -49,13 +49,13 @@ RawFiles::~RawFiles() /****************************************************************************** - * RawFiles::operator char * - Returns the correct verse when char * cast + * RawFiles::getRawEntry - Returns the correct verse when char * cast * is requested * * RET: string buffer with verse */ -char *RawFiles::getRawEntry() { +SWBuf &RawFiles::getRawEntryBuf() { FileDesc *datafile; long start = 0; unsigned short size = 0; @@ -73,148 +73,125 @@ char *RawFiles::getRawEntry() { if (!key) key = new VerseKey(this->key); - findoffset(key->Testament(), key->Index(), &start, &size); - - if (entrybuf) - delete [] entrybuf; + findOffset(key->Testament(), key->Index(), &start, &size); + entryBuf = ""; if (size) { - tmpbuf = new char [ (size + 2) + strlen(path) + 5 ]; - sprintf(tmpbuf,"%s/",path); - gettext(key->Testament(), start, (size + 2), tmpbuf+strlen(tmpbuf)); - datafile = FileMgr::systemFileMgr.open(tmpbuf, O_RDONLY|O_BINARY); - delete [] tmpbuf; + SWBuf tmpbuf = path; + tmpbuf += '/'; + readText(key->Testament(), start, size, entryBuf); + tmpbuf += entryBuf; + entryBuf = ""; + datafile = FileMgr::systemFileMgr.open(tmpbuf.c_str(), O_RDONLY|O_BINARY); if (datafile->getFd() > 0) { size = lseek(datafile->getFd(), 0, SEEK_END); - entrybuf = new char [ size * FILTERPAD ]; - memset(entrybuf, 0, size * FILTERPAD); + char *tmpBuf = new char [ size + 1 ]; + memset(tmpBuf, 0, size + 1); lseek(datafile->getFd(), 0, SEEK_SET); - read(datafile->getFd(), entrybuf, size); - preptext(entrybuf); - } - else { - entrybuf = new char [2]; - entrybuf[0] = 0; - entrybuf[1] = 0; + read(datafile->getFd(), tmpBuf, size); + entryBuf = tmpBuf; + delete [] tmpBuf; +// preptext(entrybuf); } FileMgr::systemFileMgr.close(datafile); } - else { - entrybuf = new char [2]; - entrybuf[0] = 0; - entrybuf[1] = 0; - } if (key != this->key) delete key; - return entrybuf; + return entryBuf; } /****************************************************************************** - * RawFiles::operator << (char *)- Update the modules current key entry with + * RawFiles::setEntry(char *)- Update the modules current key entry with * provided text - * - * RET: *this */ -SWModule &RawFiles::operator <<(const char *inbuf) { +void RawFiles::setEntry(const char *inbuf, long len) { FileDesc *datafile; long start; unsigned short size; - char *tmpbuf; VerseKey *key = 0; -#ifndef _WIN32_WCE + len = (len<0)?strlen(inbuf):len; try { -#endif key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE } catch ( ... ) {} -#endif if (!key) key = new VerseKey(this->key); - findoffset(key->Testament(), key->Index(), &start, &size); + findOffset(key->Testament(), key->Index(), &start, &size); if (size) { - tmpbuf = new char [ (size + 2) + strlen(path) + 1 ]; - sprintf(tmpbuf, "%s/", path); - gettext(key->Testament(), start, (size + 2), tmpbuf+strlen(tmpbuf)); + SWBuf tmpbuf; + entryBuf = path; + entryBuf += '/'; + readText(key->Testament(), start, size, tmpbuf); + entryBuf += tmpbuf; } else { - tmpbuf = new char [ 16 + strlen(path) + 1 ]; - sprintf(tmpbuf, "%s/%s", path, getnextfilename()); - settext(key->Testament(), key->Index(), tmpbuf+strlen(path)+1); + SWBuf tmpbuf; + entryBuf = path; + entryBuf += '/'; + tmpbuf = getNextFilename(); + doSetText(key->Testament(), key->Index(), tmpbuf); + entryBuf += tmpbuf; } - datafile = FileMgr::systemFileMgr.open(tmpbuf, O_CREAT|O_WRONLY|O_BINARY|O_TRUNC); - delete [] tmpbuf; + datafile = FileMgr::systemFileMgr.open(entryBuf, O_CREAT|O_WRONLY|O_BINARY|O_TRUNC); if (datafile->getFd() > 0) { - write(datafile->getFd(), inbuf, strlen(inbuf)); + write(datafile->getFd(), inbuf, len); } FileMgr::systemFileMgr.close(datafile); if (key != this->key) delete key; - - return *this; } /****************************************************************************** - * RawFiles::operator << (SWKey *)- Link the modules current key entry with + * RawFiles::linkEntry(SWKey *)- Link the modules current key entry with * another module entry * * RET: *this */ -SWModule &RawFiles::operator <<(const SWKey *inkey) { +void RawFiles::linkEntry(const SWKey *inkey) { long start; unsigned short size; char *tmpbuf; const VerseKey *key = 0; -#ifndef _WIN32_WCE try { -#endif key = SWDYNAMIC_CAST(VerseKey, inkey); -#ifndef _WIN32_WCE } catch ( ... ) {} -#endif if (!key) key = new VerseKey(this->key); - findoffset(key->Testament(), key->Index(), &start, &size); + findOffset(key->Testament(), key->Index(), &start, &size); if (size) { - tmpbuf = new char [ size + 2]; - gettext(key->Testament(), start, size + 2, tmpbuf); + SWBuf tmpbuf; + readText(key->Testament(), start, size + 2, tmpbuf); if (key != inkey) delete key; key = 0; -#ifndef _WIN32_WCE try { -#endif key = SWDYNAMIC_CAST(VerseKey, inkey); -#ifndef _WIN32_WCE } catch ( ... ) {} -#endif if (!key) key = new VerseKey(this->key); - settext(key->Testament(), key->Index(), tmpbuf); + doSetText(key->Testament(), key->Index(), tmpbuf.c_str()); } if (key != inkey) delete key; - - return *this; } @@ -239,7 +216,7 @@ void RawFiles::deleteEntry() { if (!key) key = new VerseKey(this->key); - settext(key->Testament(), key->Index(), ""); + doSetText(key->Testament(), key->Index(), ""); if (key != this->key) delete key; @@ -247,13 +224,13 @@ void RawFiles::deleteEntry() { /****************************************************************************** - * RawFiles::getnextfilename - generates a valid filename in which to store + * RawFiles::getNextfilename - generates a valid filename in which to store * an entry * * RET: filename */ -char *RawFiles::getnextfilename() { +char *RawFiles::getNextFilename() { static char incfile[255]; long number; FileDesc *datafile; @@ -289,3 +266,4 @@ char RawFiles::createModule (const char *path) { +SWORD_NAMESPACE_END diff --git a/src/modules/comments/swcom.cpp b/src/modules/comments/swcom.cpp index 1feb0cf..3f2b940 100644 --- a/src/modules/comments/swcom.cpp +++ b/src/modules/comments/swcom.cpp @@ -5,6 +5,7 @@ #include <swcom.h> +SWORD_NAMESPACE_START /****************************************************************************** * SWCom Constructor - Initializes data for instance of SWCom @@ -28,3 +29,43 @@ SWCom::SWCom(const char *imodname, const char *imoddesc, SWDisplay *idisp, SWTex SWCom::~SWCom() { } + + +long SWCom::Index() const { + VerseKey *key = 0; + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) {} + if (!key) + key = new VerseKey(this->key); + + entryIndex = key->NewIndex(); + + if (key != this->key) + delete key; + + return entryIndex; +} + +long SWCom::Index(long iindex) { + VerseKey *key = 0; + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) {} + if (!key) + key = new VerseKey(this->key); + + key->Testament(1); + key->Index(iindex); + + if (key != this->key) { + this->key->copyFrom(*key); + delete key; + } + + return Index(); +} + +SWORD_NAMESPACE_END diff --git a/src/modules/comments/zcom/zcom.cpp b/src/modules/comments/zcom/zcom.cpp index c53fd1e..744a509 100644 --- a/src/modules/comments/zcom/zcom.cpp +++ b/src/modules/comments/zcom/zcom.cpp @@ -14,11 +14,11 @@ #include <unistd.h> #endif -#include <string.h> #include <utilfuns.h> #include <zverse.h> #include <zcom.h> +SWORD_NAMESPACE_START /****************************************************************************** * zCom Constructor - Initializes data for instance of zCom @@ -49,51 +49,28 @@ zCom::~zCom() { } /****************************************************************************** - * zCom::operator char * - Returns the correct verse when char * cast + * zCom::getRawEntry - Returns the correct verse when char * cast * is requested * * RET: string buffer with verse */ -char *zCom::getRawEntry() { +SWBuf &zCom::getRawEntryBuf() { long start = 0; unsigned short size = 0; - VerseKey *key = 0; + VerseKey *key = &getVerseKey(); -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - // if we don't have a VerseKey * decendant, create our own - if (!key) - key = new VerseKey(this->key); - - findoffset(key->Testament(), key->Index(), &start, &size); + findOffset(key->Testament(), key->Index(), &start, &size); entrySize = size; // support getEntrySize call - unsigned long newsize = (size + 2) * FILTERPAD; - if (newsize > entrybufallocsize) { - if (entrybuf) - delete [] entrybuf; - entrybuf = new char [ newsize ]; - entrybufallocsize = newsize; - } - *entrybuf = 0; + entryBuf = ""; + zReadText(key->Testament(), start, size, entryBuf); - swgettext(key->Testament(), start, (size + 2), entrybuf); + rawFilter(entryBuf, key); - rawFilter(entrybuf, size, key); +// if (!isUnicode()) + prepText(entryBuf); - if (!isUnicode()) - preptext(entrybuf); - - if (this->key != key) // free our key if we created a VerseKey - delete key; - - return entrybuf; + return entryBuf; } @@ -115,21 +92,8 @@ bool zCom::sameBlock(VerseKey *k1, VerseKey *k2) { return true; } -SWModule &zCom::setentry(const char *inbuf, long len) { - VerseKey *key = 0; - // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - // if we don't have a VerseKey * decendant, create our own - if (!key) - key = new VerseKey(this->key); - +void zCom::setEntry(const char *inbuf, long len) { + VerseKey *key = &getVerseKey(); // see if we've jumped across blocks since last write if (lastWriteKey) { @@ -139,60 +103,30 @@ SWModule &zCom::setentry(const char *inbuf, long len) { delete lastWriteKey; } - settext(key->Testament(), key->Index(), inbuf, len); + doSetText(key->Testament(), key->Index(), inbuf, len); lastWriteKey = (VerseKey *)key->clone(); // must delete - - if (this->key != key) // free our key if we created a VerseKey - delete key; - - return *this; -} - -SWModule &zCom::operator <<(const char *inbuf) { - return setentry(inbuf, 0); } -SWModule &zCom::operator <<(const SWKey *inkey) { - VerseKey *destkey = 0; +void zCom::linkEntry(const SWKey *inkey) { + VerseKey *destkey = &getVerseKey(); const VerseKey *srckey = 0; - // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE - try { -#endif - destkey = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - // if we don't have a VerseKey * decendant, create our own - if (!destkey) - destkey = new VerseKey(this->key); // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE try { -#endif srckey = (const VerseKey *) SWDYNAMIC_CAST(VerseKey, inkey); -#ifndef _WIN32_WCE } catch ( ... ) { } -#endif // if we don't have a VerseKey * decendant, create our own if (!srckey) srckey = new VerseKey(inkey); - linkentry(destkey->Testament(), destkey->Index(), srckey->Index()); - - if (this->key != destkey) // free our key if we created a VerseKey - delete destkey; + doLinkEntry(destkey->Testament(), destkey->Index(), srckey->Index()); if (inkey != srckey) // free our key if we created a VerseKey delete srckey; - - return *this; } /****************************************************************************** @@ -203,88 +137,80 @@ SWModule &zCom::operator <<(const SWKey *inkey) { void zCom::deleteEntry() { - VerseKey *key = 0; - -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!key) - key = new VerseKey(this->key); - - settext(key->Testament(), key->Index(), ""); - - if (key != this->key) - delete key; + VerseKey *key = &getVerseKey(); + doSetText(key->Testament(), key->Index(), ""); } /****************************************************************************** - * zCom::operator += - Increments module key a number of entries + * zCom::increment - Increments module key a number of entries * * ENT: increment - Number of entries to jump forward * * RET: *this */ -SWModule &zCom::operator +=(int increment) { +void zCom::increment(int steps) { long start; unsigned short size; - VerseKey *tmpkey = 0; - -#ifndef _WIN32_WCE - try { -#endif - tmpkey = SWDYNAMIC_CAST(VerseKey, key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!tmpkey) - tmpkey = new VerseKey(key); + VerseKey *tmpkey = &getVerseKey(); - findoffset(tmpkey->Testament(), tmpkey->Index(), &start, &size); + findOffset(tmpkey->Testament(), tmpkey->Index(), &start, &size); SWKey lastgood = *tmpkey; - while (increment) { + while (steps) { long laststart = start; unsigned short lastsize = size; SWKey lasttry = *tmpkey; - (increment > 0) ? (*key)++ : (*key)--; - if (tmpkey != key) - delete tmpkey; - tmpkey = 0; -#ifndef _WIN32_WCE - try { -#endif - tmpkey = SWDYNAMIC_CAST(VerseKey, key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!tmpkey) - tmpkey = new VerseKey(key); + (steps > 0) ? (*key)++ : (*key)--; + tmpkey = &getVerseKey(); if ((error = key->Error())) { *key = lastgood; break; } long index = tmpkey->Index(); - findoffset(tmpkey->Testament(), index, &start, &size); - if ((((laststart != start) || (lastsize != size))||(!skipConsecutiveLinks)) && (start >= 0) && (size)) { - increment += (increment < 0) ? 1 : -1; + findOffset(tmpkey->Testament(), index, &start, &size); + if ( + (((laststart != start) || (lastsize != size)) // we're a different entry +// && (start > 0) + && (size)) // and we actually have a size + ||(!skipConsecutiveLinks)) { // or we don't want to skip consecutive links + steps += (steps < 0) ? 1 : -1; lastgood = *tmpkey; } } error = (error) ? KEYERR_OUTOFBOUNDS : 0; +} - if (tmpkey != key) - delete tmpkey; - return *this; +VerseKey &zCom::getVerseKey() { + static VerseKey tmpVK; + VerseKey *key; + // see if we have a VerseKey * or decendant + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) { } + if (!key) { + ListKey *lkTest = 0; + try { + lkTest = SWDYNAMIC_CAST(ListKey, this->key); + } + catch ( ... ) { } + if (lkTest) { + try { + key = SWDYNAMIC_CAST(VerseKey, lkTest->GetElement()); + } + catch ( ... ) { } + } + } + if (!key) { + tmpVK = *(this->key); + return tmpVK; + } + else return *key; } + +SWORD_NAMESPACE_END diff --git a/src/modules/common/Makefile.am b/src/modules/common/Makefile.am index ac235d8..b411660 100644 --- a/src/modules/common/Makefile.am +++ b/src/modules/common/Makefile.am @@ -17,6 +17,5 @@ libsword_la_SOURCES += $(commondir)/zverse.cpp libsword_la_SOURCES += $(commondir)/zstr.cpp libsword_la_SOURCES += $(commondir)/entriesblk.cpp -DEFS += -DUNIX libsword_la_SOURCES += $(commondir)/sapphire.cpp diff --git a/src/modules/common/entriesblk.cpp b/src/modules/common/entriesblk.cpp index d38cf53..f4fbdeb 100644 --- a/src/modules/common/entriesblk.cpp +++ b/src/modules/common/entriesblk.cpp @@ -2,6 +2,8 @@ #include <stdlib.h> #include <string.h> +SWORD_NAMESPACE_START + const int EntriesBlock::METAHEADERSIZE = 4; // count(4); const int EntriesBlock::METAENTRYSIZE = 8; @@ -164,3 +166,4 @@ void EntriesBlock::removeEntry(int entryIndex) { } +SWORD_NAMESPACE_END diff --git a/src/modules/common/lzsscomprs.cpp b/src/modules/common/lzsscomprs.cpp index 3606fbc..bd8f768 100644 --- a/src/modules/common/lzsscomprs.cpp +++ b/src/modules/common/lzsscomprs.cpp @@ -3,10 +3,11 @@ * provides LZSS compression */ -#include <string.h> #include <stdlib.h> +#include <string.h> #include <lzsscomprs.h> +SWORD_NAMESPACE_START /****************************************************************************** * LZSSCompress Statics @@ -663,3 +664,5 @@ void LZSSCompress::Decode(void) } slen = totalLen; } + +SWORD_NAMESPACE_END diff --git a/src/modules/common/rawstr.cpp b/src/modules/common/rawstr.cpp index 787946c..5c4ef0e 100644 --- a/src/modules/common/rawstr.cpp +++ b/src/modules/common/rawstr.cpp @@ -16,11 +16,13 @@ #include <unistd.h> #endif -#include <string.h> #include <stdlib.h> #include <utilfuns.h> #include <rawstr.h> #include <sysdata.h> + +SWORD_NAMESPACE_START + /****************************************************************************** * RawStr Statics */ @@ -93,7 +95,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) { int size; char ch; @@ -103,14 +105,13 @@ void RawStr::getidxbufdat(long ioffset, char **buf) if ((ch == '\\') || (ch == 10) || (ch == 13)) break; } - *buf = (*buf) ? (char *)realloc(*buf, size + 1) : (char *)malloc(size + 1); + *buf = (*buf) ? (char *)realloc(*buf, size*2 + 1) : (char *)malloc(size*2 + 1); if (size) { lseek(datfd->getFd(), ioffset, SEEK_SET); read(datfd->getFd(), *buf, size); } (*buf)[size] = 0; - for (size--; size > 0; size--) - (*buf)[size] = SW_toupper((*buf)[size]); + toupperstr_utf8(*buf, size*2); } else { *buf = (*buf) ? (char *)realloc(*buf, 1) : (char *)malloc(1); @@ -128,7 +129,7 @@ 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) { char *trybuf, *targetbuf; long offset; @@ -139,18 +140,7 @@ void RawStr::getidxbuf(long ioffset, char **buf) offset = swordtoarch32(offset); - getidxbufdat(offset, buf); - for (trybuf = targetbuf = *buf; *trybuf; trybuf++, targetbuf++) { -/* - if (*trybuf == '-') { // ignore '-' because alphabetized silly in file - targetbuf--; - continue; - } -*/ - *targetbuf = SW_toupper(*trybuf); - } - *targetbuf = 0; - trybuf = 0; + getIDXBufDat(offset, buf); } } @@ -164,39 +154,30 @@ void RawStr::getidxbuf(long ioffset, char **buf) * away - number of entries before of after to jump * (default = 0) * - * RET: error status + * 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, long *start, unsigned short *size, long away, long *idxoff) { - char *trybuf, *targetbuf, *key, quitflag = 0; - signed char retval = 0; + char *trybuf, *targetbuf, *key = 0, quitflag = 0; + signed char retval = -1; long headoff, tailoff, tryoff = 0, maxoff = 0; if (idxfd->getFd() >=0) { tailoff = maxoff = lseek(idxfd->getFd(), 0, SEEK_END) - 6; + retval = (tailoff >= 0) ? 0 : -2; // if NOT new file if (*ikey) { headoff = 0; - key = new char [ strlen(ikey) + 1 ]; - strcpy(key, ikey); + stdstr(&key, ikey, 3); + toupperstr_utf8(key, strlen(key)*3); - for (trybuf = targetbuf = key; *trybuf; trybuf++, targetbuf++) { - /* - if (*trybuf == '-') { // ignore '-' because alphabetized silly in file - targetbuf--; - continue; - } - */ - *targetbuf = SW_toupper(*trybuf); - } - *targetbuf = 0; trybuf = 0; while (headoff < tailoff) { tryoff = (lastoff == -1) ? headoff + ((((tailoff / 6) - (headoff / 6))) / 2) * 6 : lastoff; lastoff = -1; - getidxbuf(tryoff, &trybuf); + getIDXBuf(tryoff, &trybuf); if (!*trybuf && tryoff) { // In case of extra entry at end of idx (not first entry) tryoff += (tryoff > (maxoff / 2))?-6:6; @@ -288,11 +269,12 @@ signed char RawStr::findoffset(const char *ikey, long *start, unsigned short *si * text. */ -void RawStr::preptext(char *buf) { - char *to, *from, space = 0, cr = 0, realdata = 0, nlcnt = 0; - - for (to = from = buf; *from; from++) { - switch (*from) { +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; @@ -301,14 +283,16 @@ void RawStr::preptext(char *buf) { nlcnt++; if (nlcnt > 1) { // *to++ = nl; - *to++ = nl; + rawBuf[to++] = 10; +// *to++ = nl[1]; // nlcnt = 0; } continue; case 13: if (!realdata) continue; - *to++ = nl; +// *to++ = nl[0]; + rawBuf[to++] = 10; space = 0; cr = 1; continue; @@ -317,27 +301,27 @@ void RawStr::preptext(char *buf) { nlcnt = 0; if (space) { space = 0; - if (*from != ' ') { - *to++ = ' '; + if (rawBuf[from] != ' ') { + rawBuf[to++] = ' '; from--; continue; } } - *to++ = *from; + rawBuf[to++] = rawBuf[from]; } - *to = 0; + buf.setSize(to); - while (to > (buf+1)) { // remove trailing excess + while (to > 1) { // remove trailing excess to--; - if ((*to == 10) || (*to == ' ')) - *to = 0; + if ((rawBuf[to] == 10) || (rawBuf[to] == ' ')) + buf.setSize(to); else break; } } /****************************************************************************** - * RawStr::gettext - gets text at a given offset + * RawStr::readtext - gets text at a given offset * * ENT: * start - starting offset where the text is located in the file @@ -346,40 +330,41 @@ void RawStr::preptext(char *buf) { * */ -void RawStr::gettext(long istart, unsigned short isize, char *idxbuf, char *buf) +void RawStr::readText(long istart, unsigned short *isize, char **idxbuf, SWBuf &buf) { - char *ch; + unsigned int ch; char *idxbuflocal = 0; - getidxbufdat(istart, &idxbuflocal); + getIDXBufDat(istart, &idxbuflocal); long start = istart; - unsigned short size = isize; do { - memset(buf, 0, size); + if (*idxbuf) + delete [] *idxbuf; + buf = ""; + buf.setFillByte(0); + buf.setSize(++(*isize)); + + *idxbuf = new char [ (*isize) ]; + lseek(datfd->getFd(), start, SEEK_SET); - read(datfd->getFd(), buf, (int)(size - 2)); + read(datfd->getFd(), buf.getRawData(), (int)((*isize) - 1)); - for (ch = buf; *ch; ch++) { // skip over index string - if (*ch == 10) { + for (ch = 0; buf[ch]; ch++) { // skip over index string + if (buf[ch] == 10) { ch++; break; } } - size -= (unsigned short)(ch-buf); - memmove(buf, ch, size); - buf[size] = 0; - buf[size+1] = 0; - + buf = SWBuf(buf.c_str()+ch); // resolve link - if (!strncmp(buf, "@LINK", 5)) { - for (ch = buf; *ch; ch++) { // null before nl - if (*ch == 10) { - *ch = 0; + if (!strncmp(buf.c_str(), "@LINK", 5)) { + for (ch = 0; buf[ch]; ch++) { // null before nl + if (buf[ch] == 10) { + buf[ch] = 0; break; } } - findoffset(buf + 6, &start, &size); - // TODO: FIX! THIS IS WRONG!!! buf is not reallocated for the appropriate size! + findOffset(buf.c_str() + 6, &start, isize); } else break; } @@ -387,9 +372,9 @@ void RawStr::gettext(long istart, unsigned short isize, char *idxbuf, char *buf) if (idxbuflocal) { int localsize = strlen(idxbuflocal); - localsize = (localsize < (size - 1)) ? localsize : (size - 1); - strncpy(idxbuf, idxbuflocal, localsize); - idxbuf[localsize] = 0; + localsize = (localsize < (*isize - 1)) ? localsize : (*isize - 1); + strncpy(*idxbuf, idxbuflocal, localsize); + (*idxbuf)[localsize] = 0; free(idxbuflocal); } } @@ -403,7 +388,7 @@ void RawStr::gettext(long istart, unsigned short isize, char *idxbuf, char *buf) * len - length of buffer (0 - null terminated) */ -void RawStr::settext(const char *ikey, const char *buf, long len) +void RawStr::doSetText(const char *ikey, const char *buf, long len) { long start, outstart; @@ -420,19 +405,22 @@ void RawStr::settext(const char *ikey, const char *buf, long len) char *outbuf = 0; char *ch = 0; - findoffset(ikey, &start, &size, 0, &idxoff); - stdstr(&key, ikey); - for (ch = key; *ch; ch++) - *ch = SW_toupper(*ch); - ch = 0; + char errorStatus = findOffset(ikey, &start, &size, 0, &idxoff); + stdstr(&key, ikey, 2); + toupperstr_utf8(key, strlen(key)*2); + + len = (len < 0) ? strlen(buf) : len; - getidxbufdat(start, &dbKey); + getIDXBufDat(start, &dbKey); if (strcmp(key, dbKey) < 0) { } else if (strcmp(key, dbKey) > 0) { - idxoff += 6; - } else if ((!strcmp(key, dbKey)) && (len || strlen(buf) /*we're not deleting*/)) { // got absolute entry + if (errorStatus != -2) // not a new file + idxoff += 6; + else idxoff = 0; + } + else if ((!strcmp(key, dbKey)) && (len>0 /*we're not deleting*/)) { // got absolute entry do { tmpbuf = new char [ size + 2 ]; memset(tmpbuf, 0, size + 2); @@ -448,14 +436,14 @@ void RawStr::settext(const char *ikey, const char *buf, long len) memmove(tmpbuf, ch, size - (unsigned short)(ch-tmpbuf)); // resolve link - if (!strncmp(tmpbuf, "@LINK", 5) && (len ? len : strlen(buf))) { + if (!strncmp(tmpbuf, "@LINK", 5) && (len)) { for (ch = tmpbuf; *ch; ch++) { // null before nl if (*ch == 10) { *ch = 0; break; } } - findoffset(tmpbuf + 6, &start, &size, 0, &idxoff); + findOffset(tmpbuf + 6, &start, &size, 0, &idxoff); } else break; } @@ -472,11 +460,11 @@ void RawStr::settext(const char *ikey, const char *buf, long len) read(idxfd->getFd(), idxBytes, shiftSize); } - outbuf = new char [ (len ? len : strlen(buf)) + strlen(key) + 5 ]; + outbuf = new char [ len + strlen(key) + 5 ]; sprintf(outbuf, "%s%c%c", key, 13, 10); size = strlen(outbuf); - memcpy (outbuf + size, buf, len ? len : strlen(buf)); - size = outsize = size + (len ? len : strlen(buf)); + memcpy(outbuf + size, buf, len); + size = outsize = size + (len); start = outstart = lseek(datfd->getFd(), 0, SEEK_END); @@ -484,7 +472,7 @@ void RawStr::settext(const char *ikey, const char *buf, long len) outsize = archtosword16(size); lseek(idxfd->getFd(), idxoff, SEEK_SET); - if (len ? len : strlen(buf)) { + if (len > 0) { lseek(datfd->getFd(), start, SEEK_SET); write(datfd->getFd(), outbuf, (int)size); @@ -521,10 +509,10 @@ void RawStr::settext(const char *ikey, const char *buf, long len) * srcidxoff - source offset into .vss */ -void RawStr::linkentry(const char *destkey, const char *srckey) { +void RawStr::doLinkEntry(const char *destkey, const char *srckey) { char *text = new char [ strlen(destkey) + 7 ]; sprintf(text, "@LINK %s", destkey); - settext(srckey, text); + doSetText(srckey, text); delete [] text; } @@ -563,3 +551,5 @@ signed char RawStr::createModule(const char *ipath) return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/common/rawstr4.cpp b/src/modules/common/rawstr4.cpp index d5926ff..e278675 100644 --- a/src/modules/common/rawstr4.cpp +++ b/src/modules/common/rawstr4.cpp @@ -15,12 +15,13 @@ #include <unistd.h> #endif -#include <string.h> #include <stdlib.h> #include <utilfuns.h> #include <rawstr4.h> #include <sysdata.h> +SWORD_NAMESPACE_START + /****************************************************************************** * RawStr Statics */ @@ -93,8 +94,7 @@ 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) { int size; char ch; if (datfd > 0) { @@ -103,14 +103,13 @@ void RawStr4::getidxbufdat(long ioffset, char **buf) if ((ch == '\\') || (ch == 10) || (ch == 13)) break; } - *buf = (*buf) ? (char *)realloc(*buf, size + 1) : (char *)malloc(size + 1); + *buf = (*buf) ? (char *)realloc(*buf, size*2 + 1) : (char *)malloc(size*2 + 1); if (size) { lseek(datfd->getFd(), ioffset, SEEK_SET); read(datfd->getFd(), *buf, size); } (*buf)[size] = 0; - for (size--; size > 0; size--) - (*buf)[size] = SW_toupper((*buf)[size]); + toupperstr_utf8(*buf, size*2); } else { *buf = (*buf) ? (char *)realloc(*buf, 1) : (char *)malloc(1); @@ -128,7 +127,7 @@ 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) { char *trybuf, *targetbuf; long offset; @@ -139,18 +138,16 @@ void RawStr4::getidxbuf(long ioffset, char **buf) offset = swordtoarch32(offset); - getidxbufdat(offset, buf); + getIDXBufDat(offset, buf); + +/* What the heck is this supposed to do?????? for (trybuf = targetbuf = *buf; *trybuf; trybuf++, targetbuf++) { -/* - if (*trybuf == '-') { // ignore '-' because alphabetized silly in file - targetbuf--; - continue; - } -*/ - *targetbuf = SW_toupper(*trybuf); + *targetbuf = *trybuf; } *targetbuf = 0; trybuf = 0; + toupperstr_utf8(targetbuf); +*/ } } @@ -164,39 +161,30 @@ void RawStr4::getidxbuf(long ioffset, char **buf) * away - number of entries before of after to jump * (default = 0) * - * RET: error status + * 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, long *start, unsigned long *size, long away, long *idxoff) { - char *trybuf, *targetbuf, *key, quitflag = 0; - signed char retval = 0; + char *trybuf, *targetbuf, *key = 0, quitflag = 0; + signed char retval = -1; long headoff, tailoff, tryoff = 0, maxoff = 0; if (idxfd->getFd() >=0) { + tailoff = maxoff = lseek(idxfd->getFd(), 0, SEEK_END) - 8; + retval = (tailoff >= 0) ? 0 : -2; // if NOT new file if (*ikey) { headoff = 0; - tailoff = maxoff = lseek(idxfd->getFd(), 0, SEEK_END) - 8; - key = new char [ strlen(ikey) + 1 ]; - strcpy(key, ikey); + stdstr(&key, ikey, 3); + toupperstr_utf8(key, strlen(key)*3); - for (trybuf = targetbuf = key; *trybuf; trybuf++, targetbuf++) { - /* - if (*trybuf == '-') { // ignore '-' because alphabetized silly in file - targetbuf--; - continue; - } - */ - *targetbuf = SW_toupper(*trybuf); - } - *targetbuf = 0; trybuf = 0; while (headoff < tailoff) { tryoff = (lastoff == -1) ? headoff + ((((tailoff / 8) - (headoff / 8))) / 2) * 8 : lastoff; lastoff = -1; - getidxbuf(tryoff, &trybuf); + getIDXBuf(tryoff, &trybuf); if (!*trybuf) { // In case of extra entry at end of idx tryoff += (tryoff > (maxoff / 2))?-8:8; @@ -288,12 +276,12 @@ signed char RawStr4::findoffset(const char *ikey, long *start, unsigned long *si * text. */ -void RawStr4::preptext(char *buf) -{ - char *to, *from, space = 0, cr = 0, realdata = 0, nlcnt = 0; - - for (to = from = buf; *from; from++) { - switch (*from) { +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; @@ -302,14 +290,16 @@ void RawStr4::preptext(char *buf) nlcnt++; if (nlcnt > 1) { // *to++ = nl; - *to++ = nl; + rawBuf[to++] = 10; +// *to++ = nl[1]; // nlcnt = 0; } continue; case 13: if (!realdata) continue; - *to++ = nl; +// *to++ = nl[0]; + rawBuf[to++] = 10; space = 0; cr = 1; continue; @@ -318,27 +308,27 @@ void RawStr4::preptext(char *buf) nlcnt = 0; if (space) { space = 0; - if (*from != ' ') { - *to++ = ' '; + if (rawBuf[from] != ' ') { + rawBuf[to++] = ' '; from--; continue; } } - *to++ = *from; + rawBuf[to++] = rawBuf[from]; } - *to = 0; + buf.setSize(to); - while (to > (buf+1)) { // remove trailing excess + while (to > 1) { // remove trailing excess to--; - if ((*to == 10) || (*to == ' ')) - *to = 0; + if ((rawBuf[to] == 10) || (rawBuf[to] == ' ')) + buf.setSize(to); else break; } } /****************************************************************************** - * RawStr4::gettext - gets text at a given offset + * RawStr4::readtext - gets text at a given offset * * ENT: * start - starting offset where the text is located in the file @@ -347,36 +337,41 @@ void RawStr4::preptext(char *buf) * */ -void RawStr4::gettext(long istart, unsigned long isize, char *idxbuf, char *buf) +void RawStr4::readText(long istart, unsigned long *isize, char **idxbuf, SWBuf &buf) { - char *ch; + unsigned int ch; char *idxbuflocal = 0; - getidxbufdat(istart, &idxbuflocal); + getIDXBufDat(istart, &idxbuflocal); long start = istart; - unsigned long size = isize; do { - memset(buf, 0, size); + if (*idxbuf) + delete [] *idxbuf; + *idxbuf = new char [ (*isize) ]; + + buf = ""; + buf.setFillByte(0); + buf.setSize(*isize); lseek(datfd->getFd(), start, SEEK_SET); - read(datfd->getFd(), buf, (int)(size - 1)); + read(datfd->getFd(), buf.getRawData(), (int)((*isize) - 1)); - for (ch = buf; *ch; ch++) { // skip over index string - if (*ch == 10) { + for (ch = 0; buf[ch]; ch++) { // skip over index string + if (buf[ch] == 10) { ch++; break; } } - memmove(buf, ch, size - (unsigned long)(ch-buf)); - + buf = SWBuf(buf.c_str()+ch); // resolve link - if (!strncmp(buf, "@LINK", 5)) { - for (ch = buf; *ch; ch++) { // null before nl - if (*ch == 10) { - *ch = 0; + if (!strncmp(buf.c_str(), "@LINK", 5)) { + for (ch = 0; buf[ch]; ch++) { // null before nl + if (buf[ch] == 10) { + buf[ch] = 0; break; } } - findoffset(buf + 8, &start, &size); + findOffset(buf.c_str() + 6, &start, isize); + } else break; } @@ -384,9 +379,9 @@ void RawStr4::gettext(long istart, unsigned long isize, char *idxbuf, char *buf) if (idxbuflocal) { int localsize = strlen(idxbuflocal); - localsize = (localsize < (size - 1)) ? localsize : (size - 1); - strncpy(idxbuf, idxbuflocal, localsize); - idxbuf[localsize] = 0; + localsize = (localsize < (*isize - 1)) ? localsize : (*isize - 1); + strncpy(*idxbuf, idxbuflocal, localsize); + (*idxbuf)[localsize] = 0; free(idxbuflocal); } } @@ -400,8 +395,7 @@ void RawStr4::gettext(long istart, unsigned long isize, char *idxbuf, char *buf) * len - length of buffer (0 - null terminated) */ -void RawStr4::settext(const char *ikey, const char *buf, long len) -{ +void RawStr4::doSetText(const char *ikey, const char *buf, long len) { long start, outstart; long idxoff; @@ -417,19 +411,21 @@ void RawStr4::settext(const char *ikey, const char *buf, long len) char *outbuf = 0; char *ch = 0; - findoffset(ikey, &start, &size, 0, &idxoff); - stdstr(&key, ikey); - for (ch = key; *ch; ch++) - *ch = SW_toupper(*ch); - ch = 0; + char errorStatus = findOffset(ikey, &start, &size, 0, &idxoff); + stdstr(&key, ikey, 3); + toupperstr_utf8(key, strlen(key)*3); - getidxbufdat(start, &dbKey); + len = (len < 0) ? strlen(buf) : len; + getIDXBufDat(start, &dbKey); if (strcmp(key, dbKey) < 0) { } else if (strcmp(key, dbKey) > 0) { - idxoff += 8; - } else if ((!strcmp(key, dbKey)) && (len || strlen(buf) /*we're not deleting*/)) { // got absolute entry + if (errorStatus != -2) // not a new file + idxoff += 8; + else idxoff = 0; + } + else if ((!strcmp(key, dbKey)) && (len>0/*we're not deleting*/)) { // got absolute entry do { tmpbuf = new char [ size + 2 ]; memset(tmpbuf, 0, size + 2); @@ -445,14 +441,15 @@ void RawStr4::settext(const char *ikey, const char *buf, long len) memmove(tmpbuf, ch, size - (unsigned long)(ch-tmpbuf)); // resolve link - if (!strncmp(tmpbuf, "@LINK", 5) && (len ? len : strlen(buf))) { + if (!strncmp(tmpbuf, "@LINK", 5) && (len > 0)) { for (ch = tmpbuf; *ch; ch++) { // null before nl if (*ch == 10) { *ch = 0; break; } } - findoffset(tmpbuf + 8, &start, &size, 0, &idxoff); + findOffset(tmpbuf + 8, &start, &size, 0, &idxoff); + ++size; } else break; } @@ -469,11 +466,11 @@ void RawStr4::settext(const char *ikey, const char *buf, long len) read(idxfd->getFd(), idxBytes, shiftSize); } - outbuf = new char [ (len ? len : strlen(buf)) + strlen(key) + 5 ]; + outbuf = new char [ len + strlen(key) + 5 ]; sprintf(outbuf, "%s%c%c", key, 13, 10); size = strlen(outbuf); - memcpy (outbuf + size, buf, len ? len : strlen(buf)); - size = outsize = size + (len ? len : strlen(buf)); + memcpy(outbuf + size, buf, len); + size = outsize = size + len; start = outstart = lseek(datfd->getFd(), 0, SEEK_END); @@ -481,7 +478,7 @@ void RawStr4::settext(const char *ikey, const char *buf, long len) outsize = archtosword32(size); lseek(idxfd->getFd(), idxoff, SEEK_SET); - if (len ? len : strlen(buf)) { + if (len>0) { lseek(datfd->getFd(), start, SEEK_SET); write(datfd->getFd(), outbuf, (long)size); @@ -518,10 +515,10 @@ void RawStr4::settext(const char *ikey, const char *buf, long len) * srcidxoff - source offset into .vss */ -void RawStr4::linkentry(const char *destkey, const char *srckey) { +void RawStr4::doLinkEntry(const char *destkey, const char *srckey) { char *text = new char [ strlen(destkey) + 7 ]; sprintf(text, "@LINK %s", destkey); - settext(srckey, text); + doSetText(srckey, text); delete [] text; } @@ -560,3 +557,5 @@ signed char RawStr4::createModule(const char *ipath) return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/common/rawverse.cpp b/src/modules/common/rawverse.cpp index 3374da5..b5bff9f 100644 --- a/src/modules/common/rawverse.cpp +++ b/src/modules/common/rawverse.cpp @@ -18,7 +18,6 @@ #include <unistd.h> #endif -#include <string.h> #include <utilfuns.h> #include <rawverse.h> #include <versekey.h> @@ -28,12 +27,14 @@ #define O_BINARY 0 // If it hasn't been defined than we probably #endif // don't need it. +SWORD_NAMESPACE_START /****************************************************************************** * RawVerse Statics */ - int RawVerse::instance = 0; +int RawVerse::instance = 0; +const char *RawVerse::nl = "\r\n"; /****************************************************************************** @@ -48,7 +49,6 @@ RawVerse::RawVerse(const char *ipath, int fileMode) { char *buf; - nl = '\n'; path = 0; stdstr(&path, ipath); buf = new char [ strlen(path) + 80 ]; @@ -105,7 +105,7 @@ 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) { idxoff *= 6; if (!testmt) testmt = ((idxfp[1]) ? 1:2); @@ -137,12 +137,12 @@ void RawVerse::findoffset(char testmt, long idxoff, long *start, unsigned short * text. */ -void RawVerse::preptext(char *buf) -{ - char *to, *from, space = 0, cr = 0, realdata = 0, nlcnt = 0; - - for (to = from = buf; *from; from++) { - switch (*from) { +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; @@ -151,14 +151,16 @@ void RawVerse::preptext(char *buf) nlcnt++; if (nlcnt > 1) { // *to++ = nl; - *to++ = nl; + rawBuf[to++] = 10; +// *to++ = nl[1]; // nlcnt = 0; } continue; case 13: if (!realdata) continue; - *to++ = nl; +// *to++ = nl[0]; + rawBuf[to++] = 10; space = 0; cr = 1; continue; @@ -167,27 +169,27 @@ void RawVerse::preptext(char *buf) nlcnt = 0; if (space) { space = 0; - if (*from != ' ') { - *to++ = ' '; + if (rawBuf[from] != ' ') { + rawBuf[to++] = ' '; from--; continue; } } - *to++ = *from; + rawBuf[to++] = rawBuf[from]; } - *to = 0; + buf.setSize(to); - while (to > (buf+1)) { // remove trailing excess + while (to > 1) { // remove trailing excess to--; - if ((*to == 10) || (*to == ' ')) - *to = 0; + if ((rawBuf[to] == 10) || (rawBuf[to] == ' ')) + buf.setSize(to); else break; } } /****************************************************************************** - * RawVerse::gettext - gets text at a given offset + * RawVerse::readtext - 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 @@ -196,12 +198,16 @@ void RawVerse::preptext(char *buf) * */ -void RawVerse::gettext(char testmt, long start, unsigned short size, char *buf) { - memset(buf, 0, size+1); +void RawVerse::readText(char testmt, long start, unsigned short size, SWBuf &buf) { + buf = ""; + buf.setFillByte(0); + buf.setSize(size + 1); + if (!testmt) + testmt = ((idxfp[1]) ? 1:2); if (size) { if (textfp[testmt-1]->getFd() >= 0) { lseek(textfp[testmt-1]->getFd(), start, SEEK_SET); - read(textfp[testmt-1]->getFd(), buf, (int)size - 2); + read(textfp[testmt-1]->getFd(), buf.getRawData(), (int)size); } } } @@ -216,18 +222,17 @@ void RawVerse::gettext(char testmt, long start, unsigned short size, char *buf) * len - length of buffer (0 - null terminated) */ -void RawVerse::settext(char testmt, long idxoff, const char *buf, long len) +void RawVerse::doSetText(char testmt, long idxoff, const char *buf, long len) { long start, outstart; unsigned short size; unsigned short outsize; - static const char nl[] = {13, 10}; idxoff *= 6; if (!testmt) testmt = ((idxfp[1]) ? 1:2); - size = outsize = len ? len : strlen(buf); + size = outsize = (len < 0) ? strlen(buf) : len; start = outstart = lseek(textfp[testmt-1]->getFd(), 0, SEEK_END); lseek(idxfp[testmt-1]->getFd(), idxoff, SEEK_SET); @@ -237,7 +242,7 @@ void RawVerse::settext(char testmt, long idxoff, const char *buf, long len) write(textfp[testmt-1]->getFd(), buf, (int)size); // add a new line to make data file easier to read in an editor - write(textfp[testmt-1]->getFd(), &nl, 2); + write(textfp[testmt-1]->getFd(), nl, 2); } else { start = 0; @@ -261,7 +266,7 @@ void RawVerse::settext(char testmt, long idxoff, const char *buf, long len) * srcidxoff - source offset into .vss */ -void RawVerse::linkentry(char testmt, long destidxoff, long srcidxoff) { +void RawVerse::doLinkEntry(char testmt, long destidxoff, long srcidxoff) { long start; unsigned short size; @@ -336,6 +341,7 @@ char RawVerse::createModule(const char *ipath) FileMgr::systemFileMgr.close(fd2); delete [] path; + delete [] buf; /* RawVerse rv(path); VerseKey mykey("Rev 22:21"); @@ -343,3 +349,5 @@ char RawVerse::createModule(const char *ipath) return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/common/sapphire.cpp b/src/modules/common/sapphire.cpp index 686bccb..1c97934 100644 --- a/src/modules/common/sapphire.cpp +++ b/src/modules/common/sapphire.cpp @@ -30,6 +30,8 @@ #include "sapphire.h" +SWORD_NAMESPACE_START + unsigned char sapphire::keyrand(int limit, unsigned char *user_key, unsigned char keysize, @@ -226,3 +228,4 @@ void sapphire::hash_final(unsigned char *hash, // Destination hash[i] = encrypt(0); } +SWORD_NAMESPACE_END diff --git a/src/modules/common/swcipher.cpp b/src/modules/common/swcipher.cpp index d221b8b..bd4d551 100644 --- a/src/modules/common/swcipher.cpp +++ b/src/modules/common/swcipher.cpp @@ -3,10 +3,11 @@ * cipher utilities. */ -#include <string.h> #include <stdlib.h> +#include <string.h> #include <swcipher.h> +SWORD_NAMESPACE_START /****************************************************************************** * SWCipher Constructor - Initializes data for instance of SWCipher @@ -30,7 +31,7 @@ SWCipher::~SWCipher() } -char *SWCipher::Buf(const char *ibuf, unsigned int ilen) +char *SWCipher::Buf(const char *ibuf, unsigned long ilen) { if (ibuf) { @@ -54,14 +55,14 @@ char *SWCipher::Buf(const char *ibuf, unsigned int ilen) } -char *SWCipher::cipherBuf(unsigned int *ilen, const char *ibuf) +char *SWCipher::cipherBuf(unsigned long *ilen, const char *ibuf) { if (ibuf) { if (buf) free(buf); - buf = (char *) malloc(*ilen); + buf = (char *) malloc(*ilen+1); memcpy(buf, ibuf, *ilen); len = *ilen; cipher = true; @@ -69,7 +70,7 @@ char *SWCipher::cipherBuf(unsigned int *ilen, const char *ibuf) Encode(); - *ilen = (short)len; + *ilen = len; return buf; } @@ -86,7 +87,7 @@ void SWCipher::Encode(void) { if (!cipher) { work = master; - for (int i = 0; i < len; i++) + for (unsigned long i = 0; i < len; i++) buf[i] = work.encrypt(buf[i]); cipher = true; } @@ -105,8 +106,10 @@ void SWCipher::Decode(void) { if (cipher) { work = master; - for (int i = 0; i < len; i++) + unsigned long i; + for (i = 0; i < len; i++) buf[i] = work.decrypt(buf[i]); + buf[i] = 0; cipher = false; } } @@ -121,3 +124,5 @@ void SWCipher::setCipherKey(const char *ikey) { unsigned char *key = (unsigned char *)ikey; master.initialize(key, strlen((char *)key)); } + +SWORD_NAMESPACE_END diff --git a/src/modules/common/swcomprs.cpp b/src/modules/common/swcomprs.cpp index 4bd2e5e..02d7d7b 100644 --- a/src/modules/common/swcomprs.cpp +++ b/src/modules/common/swcomprs.cpp @@ -3,10 +3,11 @@ * compression utilities. */ -#include <string.h> #include <stdlib.h> +#include <string.h> #include <swcomprs.h> +SWORD_NAMESPACE_START /****************************************************************************** * SWCompress Constructor - Initializes data for instance of SWCompress @@ -188,3 +189,5 @@ void SWCompress::cycleStream() { zlen = slen = totlen; } + +SWORD_NAMESPACE_END diff --git a/src/modules/common/zipcomprs.cpp b/src/modules/common/zipcomprs.cpp index 01ba430..6a5ed22 100644 --- a/src/modules/common/zipcomprs.cpp +++ b/src/modules/common/zipcomprs.cpp @@ -3,13 +3,14 @@ * compression utilities. - using zlib */ -#include <string.h> -#include <string> #include <stdlib.h> +#include <string.h> #include <stdio.h> #include <zipcomprs.h> #include <zlib.h> +SWORD_NAMESPACE_START + /****************************************************************************** * ZipCompress Constructor - Initializes data for instance of ZipCompress * @@ -156,3 +157,5 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, //printf("Finished decoding\n"); free (zbuf); } + +SWORD_NAMESPACE_END diff --git a/src/modules/common/zstr.cpp b/src/modules/common/zstr.cpp index fc02572..92a4960 100644 --- a/src/modules/common/zstr.cpp +++ b/src/modules/common/zstr.cpp @@ -14,7 +14,6 @@ #include <unistd.h> #endif -#include <string.h> #include <stdlib.h> #include <utilfuns.h> #include <zstr.h> @@ -23,6 +22,8 @@ #include <sysdata.h> #include <entriesblk.h> +SWORD_NAMESPACE_START + /****************************************************************************** * zStr Statics */ @@ -124,14 +125,13 @@ void zStr::getKeyFromDatOffset(long ioffset, char **buf) { if ((ch == '\\') || (ch == 10) || (ch == 13)) break; } - *buf = (*buf) ? (char *)realloc(*buf, size + 1) : (char *)malloc(size + 1); + *buf = (*buf) ? (char *)realloc(*buf, size*2 + 1) : (char *)malloc(size*2 + 1); if (size) { lseek(datfd->getFd(), ioffset, SEEK_SET); read(datfd->getFd(), *buf, size); } (*buf)[size] = 0; - for (size--; size > 0; size--) - (*buf)[size] = SW_toupper((*buf)[size]); + toupperstr_utf8(*buf, size*2); } else { *buf = (*buf) ? (char *)realloc(*buf, 1) : (char *)malloc(1); @@ -183,8 +183,8 @@ signed char zStr::findKeyIndex(const char *ikey, long *idxoff, long away) { tailoff = maxoff = lseek(idxfd->getFd(), 0, SEEK_END) - IDXENTRYSIZE; if (*ikey) { headoff = 0; - stdstr(&key, ikey); - toupperstr(key); + stdstr(&key, ikey, 3); + toupperstr_utf8(key, strlen(key)*3); while (headoff < tailoff) { tryoff = (lastoff == -1) ? headoff + (((((tailoff / IDXENTRYSIZE) - (headoff / IDXENTRYSIZE))) / 2) * IDXENTRYSIZE) : lastoff; @@ -281,11 +281,12 @@ signed char zStr::findKeyIndex(const char *ikey, long *idxoff, long away) { * text. */ -void zStr::prepText(char *buf) { - char *to, *from, space = 0, cr = 0, realdata = 0, nlcnt = 0; - - for (to = from = buf; *from; from++) { - switch (*from) { +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; @@ -294,14 +295,16 @@ void zStr::prepText(char *buf) { nlcnt++; if (nlcnt > 1) { // *to++ = nl; - *to++ = nl; + rawBuf[to++] = 10; +// *to++ = nl[1]; // nlcnt = 0; } continue; case 13: if (!realdata) continue; - *to++ = nl; +// *to++ = nl[0]; + rawBuf[to++] = 10; space = 0; cr = 1; continue; @@ -310,27 +313,27 @@ void zStr::prepText(char *buf) { nlcnt = 0; if (space) { space = 0; - if (*from != ' ') { - *to++ = ' '; + if (rawBuf[from] != ' ') { + rawBuf[to++] = ' '; from--; continue; } } - *to++ = *from; + rawBuf[to++] = rawBuf[from]; } - *to = 0; + buf.setSize(to); - while (to > (buf+1)) { // remove trailing excess + while (to > 1) { // remove trailing excess to--; - if ((*to == 10) || (*to == ' ')) - *to = 0; + if ((rawBuf[to] == 10) || (rawBuf[to] == ' ')) + buf.setSize(to); else break; } } /****************************************************************************** - * zStr::gettext - gets text at a given offset + * zStr::getText - gets text at a given offset * * ENT: * offset - idxoffset where the key is located. @@ -355,8 +358,8 @@ void zStr::getText(long offset, char **idxbuf, char **buf) { start = swordtoarch32(start); size = swordtoarch32(size); - *buf = (*buf) ? (char *)realloc(*buf, size + 1) : (char *)malloc(size + 1); - *idxbuf = (*idxbuf) ? (char *)realloc(*idxbuf, size + 1) : (char *)malloc(size + 1); + *buf = (*buf) ? (char *)realloc(*buf, size*2 + 1) : (char *)malloc(size*2 + 1); + *idxbuf = (*idxbuf) ? (char *)realloc(*idxbuf, size*2 + 1) : (char *)malloc(size*2 + 1); memset(*buf, 0, size + 1); memset(*idxbuf, 0, size + 1); lseek(datfd->getFd(), start, SEEK_SET); @@ -378,7 +381,7 @@ void zStr::getText(long offset, char **idxbuf, char **buf) { break; } } - findKeyIndex(*buf + IDXENTRYSIZE, &offset); + findKeyIndex(*buf + 6, &offset); } else break; } @@ -419,21 +422,24 @@ void zStr::getCompressedText(long block, long entry, char **buf) { start = swordtoarch32(start); size = swordtoarch32(size); - *buf = (*buf) ? (char *)realloc(*buf, size + 1) : (char *)malloc(size + 1); - + SWBuf buf; + buf.setSize(size + 5); lseek(zdtfd->getFd(), start, SEEK_SET); - read(zdtfd->getFd(), *buf, size); + read(zdtfd->getFd(), buf.getRawData(), size); flushCache(); unsigned long len = size; - compressor->zBuf(&len, *buf); - char * rawBuf = compressor->Buf(0, &len); + buf.setSize(size); + rawZFilter(buf, 0); // 0 = decipher + + compressor->zBuf(&len, buf.getRawData()); + char *rawBuf = compressor->Buf(0, &len); cacheBlock = new EntriesBlock(rawBuf, len); cacheBlockIndex = block; } size = cacheBlock->getEntrySize(entry); - *buf = (*buf) ? (char *)realloc(*buf, size + 1) : (char *)malloc(size + 1); + *buf = (*buf) ? (char *)realloc(*buf, size*2 + 1) : (char *)malloc(size*2 + 1); strcpy(*buf, cacheBlock->getEntry(entry)); } @@ -461,8 +467,9 @@ void zStr::setText(const char *ikey, const char *buf, long len) { char *outbuf = 0; char *ch = 0; - stdstr(&key, ikey); - toupperstr(key); + len = (len < 0) ? strlen(buf) : len; + stdstr(&key, ikey, 3); + toupperstr_utf8(key, strlen(key)*3); char notFound = findKeyIndex(ikey, &idxoff, 0); if (!notFound) { @@ -473,7 +480,7 @@ void zStr::setText(const char *ikey, const char *buf, long len) { else if (diff > 0) { idxoff += IDXENTRYSIZE; } - else if ((!diff) && (len || strlen(buf) /*we're not deleting*/)) { // got absolute entry + else if ((!diff) && (len > 0 /*we're not deleting*/)) { // got absolute entry do { lseek(idxfd->getFd(), idxoff, SEEK_SET); read(idxfd->getFd(), &start, sizeof(__u32)); @@ -495,7 +502,7 @@ void zStr::setText(const char *ikey, const char *buf, long len) { memmove(tmpbuf, ch, size - (unsigned long)(ch-tmpbuf)); // resolve link - if (!strncmp(tmpbuf, "@LINK", 5) && (len ? len : strlen(buf))) { + if (!strncmp(tmpbuf, "@LINK", 5) && (len)) { for (ch = tmpbuf; *ch; ch++) { // null before nl if (*ch == 10) { *ch = 0; @@ -521,10 +528,10 @@ void zStr::setText(const char *ikey, const char *buf, long len) { read(idxfd->getFd(), idxBytes, shiftSize); } - outbuf = new char [ (len ? len : strlen(buf)) + strlen(key) + 5 ]; + outbuf = new char [ len + strlen(key) + 5 ]; sprintf(outbuf, "%s%c%c", key, 13, 10); size = strlen(outbuf); - if (len ? len : strlen(buf)) { // NOT a link + if (len > 0) { // NOT a link if (!cacheBlock) { flushCache(); cacheBlock = new EntriesBlock(); @@ -544,8 +551,8 @@ void zStr::setText(const char *ikey, const char *buf, long len) { size += (sizeof(__u32) * 2); } else { // link - memcpy(outbuf + size, buf, len ? len : strlen(buf)); - size += (len ? len : strlen(buf)); + memcpy(outbuf + size, buf, len); + size += len; } start = lseek(datfd->getFd(), 0, SEEK_END); @@ -554,7 +561,7 @@ void zStr::setText(const char *ikey, const char *buf, long len) { outsize = archtosword32(size); lseek(idxfd->getFd(), idxoff, SEEK_SET); - if (len ? len : strlen(buf)) { + if (len > 0) { lseek(datfd->getFd(), start, SEEK_SET); write(datfd->getFd(), outbuf, size); @@ -610,6 +617,12 @@ void zStr::flushCache() { compressor->Buf(rawBuf, &size); compressor->zBuf(&size); + SWBuf buf; + buf.setSize(size + 5); + memcpy(buf.getRawData(), compressor->zBuf(&size), size); // 1 = encipher + buf.setSize(size); + rawZFilter(buf, 1); // 1 = encipher + long zdxSize = lseek(zdxfd->getFd(), 0, SEEK_END); long zdtSize = lseek(zdtfd->getFd(), 0, SEEK_END); @@ -640,20 +653,18 @@ void zStr::flushCache() { lseek(zdxfd->getFd(), cacheBlockIndex * ZDXENTRYSIZE, SEEK_SET); lseek(zdtfd->getFd(), start, SEEK_SET); - rawBuf = compressor->zBuf(&size); - write(zdtfd->getFd(), rawBuf, size); + write(zdtfd->getFd(), buf, size); // add a new line to make data file easier to read in an editor write(zdtfd->getFd(), &nl, 2); write(zdxfd->getFd(), &outstart, sizeof(__u32)); write(zdxfd->getFd(), &outsize, sizeof(__u32)); - - delete cacheBlock; } + delete cacheBlock; + cacheBlock = 0; } cacheBlockIndex = -1; - cacheBlock = 0; cacheDirty = false; } @@ -703,3 +714,5 @@ signed char zStr::createModule(const char *ipath) { return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/common/zverse.cpp b/src/modules/common/zverse.cpp index 8d30797..1f7f25d 100644 --- a/src/modules/common/zverse.cpp +++ b/src/modules/common/zverse.cpp @@ -18,17 +18,18 @@ #include <unistd.h> #endif -#include <string.h> #include <utilfuns.h> #include <versekey.h> #include <zverse.h> #include <sysdata.h> +#include <swbuf.h> #ifndef O_BINARY #define O_BINARY 0 #endif +SWORD_NAMESPACE_START /****************************************************************************** * zVerse Statics @@ -133,7 +134,7 @@ 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) { // set start to offset in // set size to @@ -221,14 +222,17 @@ void zVerse::findoffset(char testmt, long idxoff, long *start, unsigned short *s printf ("Error: could not seek to right place in compressed text\n"); return; } - pcCompText = new char[ulCompSize]; + SWBuf pcCompText; + pcCompText.setSize(ulCompSize+5); - if (read(textfp[testmt-1]->getFd(), pcCompText, ulCompSize)<(long)ulCompSize) - { + if (read(textfp[testmt-1]->getFd(), pcCompText.getRawData(), ulCompSize)<(long)ulCompSize) { printf ("Error reading compressed text\n"); return; } - compressor->zBuf(&ulCompSize, pcCompText); + pcCompText.setSize(ulCompSize); + rawZFilter(pcCompText, 0); // 0 = decipher + + compressor->zBuf(&ulCompSize, pcCompText.getRawData()); if (cacheBuf) { flushCache(); @@ -247,7 +251,7 @@ void zVerse::findoffset(char testmt, long idxoff, long *start, unsigned short *s /****************************************************************************** - * zVerse::swgettext - gets text at a given offset + * 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 @@ -256,12 +260,15 @@ void zVerse::findoffset(char testmt, long idxoff, long *start, unsigned short *s * */ -void zVerse::swgettext(char testmt, long start, unsigned short size, char *inbuf) -{ - memset(inbuf, 0, size); - if (size > 2) { - strncpy(inbuf, &(cacheBuf[start]), size-2); +void zVerse::zReadText(char testmt, long start, unsigned short size, SWBuf &inBuf) { + inBuf = ""; + inBuf.setFillByte(0); + inBuf.setSize(size+1); + if (size > 0) { + if (cacheBuf) + strncpy(inBuf.getRawData(), &(cacheBuf[start]), size); } + inBuf.setSize(strlen(inBuf.c_str())); } @@ -274,16 +281,19 @@ void zVerse::swgettext(char testmt, long start, unsigned short size, char *inbuf * len - length of buffer (0 - null terminated) */ -void zVerse::settext(char testmt, long idxoff, const char *buf, long len) -{ +void zVerse::doSetText(char testmt, long idxoff, const char *buf, long len) { + + len = (len < 0) ? strlen(buf) : len; + if (!testmt) + testmt = ((idxfp[0]) ? 1:2); if ((!dirtyCache) || (cacheBufIdx < 0)) { cacheBufIdx = lseek(idxfp[testmt-1]->getFd(), 0, SEEK_END) / 12; cacheTestament = testmt; if (cacheBuf) free(cacheBuf); - cacheBuf = (char *)calloc(len ? len : strlen(buf)+1, 1); + cacheBuf = (char *)calloc(len + 1, 1); } - else cacheBuf = (char *)((cacheBuf)?realloc(cacheBuf, strlen(cacheBuf)+(len ? len : strlen(buf)+1)):calloc((len ? len : strlen(buf)+1), 1)); + else cacheBuf = (char *)((cacheBuf)?realloc(cacheBuf, strlen(cacheBuf)+(len + 1)):calloc((len + 1), 1)); dirtyCache = true; @@ -293,7 +303,7 @@ void zVerse::settext(char testmt, long idxoff, const char *buf, long len) unsigned short outsize; idxoff *= 10; - size = outsize = len ? len : strlen(buf); + size = outsize = len; start = strlen(cacheBuf); @@ -320,28 +330,38 @@ void zVerse::flushCache() { unsigned long zsize, outzsize; idxoff = cacheBufIdx * 12; - size = outsize = zsize = outzsize = strlen(cacheBuf); - if (size) { -// if (compressor) { -// delete compressor; -// compressor = new LZSSCompress(); -// } - compressor->Buf(cacheBuf); - compressor->zBuf(&zsize); - outzsize = zsize; - - start = outstart = lseek(textfp[cacheTestament-1]->getFd(), 0, SEEK_END); - - outstart = archtosword32(start); - outsize = archtosword32(size); - outzsize = archtosword32(zsize); - - write(textfp[cacheTestament-1]->getFd(), compressor->zBuf(&zsize), zsize); - - lseek(idxfp[cacheTestament-1]->getFd(), idxoff, SEEK_SET); - write(idxfp[cacheTestament-1]->getFd(), &outstart, 4); - write(idxfp[cacheTestament-1]->getFd(), &outzsize, 4); - write(idxfp[cacheTestament-1]->getFd(), &outsize, 4); + if (cacheBuf) { + size = outsize = zsize = outzsize = strlen(cacheBuf); + if (size) { + // if (compressor) { + // delete compressor; + // compressor = new LZSSCompress(); + // } + compressor->Buf(cacheBuf); + compressor->zBuf(&zsize); + outzsize = zsize; + + SWBuf buf; + buf.setSize(zsize + 5); + memcpy(buf.getRawData(), compressor->zBuf(&zsize), zsize); + buf.setSize(zsize); + rawZFilter(buf, 1); // 1 = encipher + + start = outstart = lseek(textfp[cacheTestament-1]->getFd(), 0, SEEK_END); + + outstart = archtosword32(start); + outsize = archtosword32(size); + outzsize = archtosword32(zsize); + + write(textfp[cacheTestament-1]->getFd(), buf, zsize); + + lseek(idxfp[cacheTestament-1]->getFd(), idxoff, SEEK_SET); + write(idxfp[cacheTestament-1]->getFd(), &outstart, 4); + write(idxfp[cacheTestament-1]->getFd(), &outzsize, 4); + write(idxfp[cacheTestament-1]->getFd(), &outsize, 4); + } + free(cacheBuf); + cacheBuf = 0; } dirtyCache = false; } @@ -355,7 +375,7 @@ void zVerse::flushCache() { * srcidxoff - source offset into .vss */ -void zVerse::linkentry(char testmt, long destidxoff, long srcidxoff) { +void zVerse::doLinkEntry(char testmt, long destidxoff, long srcidxoff) { long bufidx; long start; unsigned short size; @@ -446,6 +466,7 @@ char zVerse::createModule(const char *ipath, int blockBound) FileMgr::systemFileMgr.close(fd2); delete [] path; + delete [] buf; /* RawVerse rv(path); VerseKey mykey("Rev 22:21"); @@ -463,12 +484,12 @@ char zVerse::createModule(const char *ipath, int blockBound) * text. */ -void zVerse::preptext(char *buf) -{ - char *to, *from, space = 0, cr = 0, realdata = 0, nlcnt = 0; - - for (to = from = buf; *from; from++) { - switch (*from) { +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; @@ -477,14 +498,16 @@ void zVerse::preptext(char *buf) nlcnt++; if (nlcnt > 1) { // *to++ = nl; - *to++ = nl; + rawBuf[to++] = 10; +// *to++ = nl[1]; // nlcnt = 0; } continue; case 13: if (!realdata) continue; - *to++ = nl; +// *to++ = nl[0]; + rawBuf[to++] = 10; space = 0; cr = 1; continue; @@ -493,21 +516,23 @@ void zVerse::preptext(char *buf) nlcnt = 0; if (space) { space = 0; - if (*from != ' ') { - *to++ = ' '; + if (rawBuf[from] != ' ') { + rawBuf[to++] = ' '; from--; continue; } } - *to++ = *from; + 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; } - *to = 0; - - if (to > buf) { - for (to--; to > buf; to--) { // remove trailing excess - if ((*to == 10) || (*to == ' ')) - *to = 0; - else break; - } - } } + + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/Makefile.am b/src/modules/filters/Makefile.am index c58fb5f..c9a6bef 100644 --- a/src/modules/filters/Makefile.am +++ b/src/modules/filters/Makefile.am @@ -1,22 +1,24 @@ filtersdir = $(top_srcdir)/src/modules/filters libsword_la_SOURCES += $(filtersdir)/swbasicfilter.cpp +libsword_la_SOURCES += $(filtersdir)/swoptfilter.cpp libsword_la_SOURCES += $(filtersdir)/gbfhtml.cpp libsword_la_SOURCES += $(filtersdir)/gbfhtmlhref.cpp +libsword_la_SOURCES += $(filtersdir)/gbfwebif.cpp libsword_la_SOURCES += $(filtersdir)/gbfplain.cpp libsword_la_SOURCES += $(filtersdir)/gbfrtf.cpp libsword_la_SOURCES += $(filtersdir)/plainhtml.cpp -libsword_la_SOURCES += $(filtersdir)/rwphtml.cpp -libsword_la_SOURCES += $(filtersdir)/rwprtf.cpp libsword_la_SOURCES += $(filtersdir)/cipherfil.cpp libsword_la_SOURCES += $(filtersdir)/rtfhtml.cpp libsword_la_SOURCES += $(filtersdir)/gbfstrongs.cpp libsword_la_SOURCES += $(filtersdir)/gbffootnotes.cpp libsword_la_SOURCES += $(filtersdir)/gbfheadings.cpp +libsword_la_SOURCES += $(filtersdir)/gbfredletterwords.cpp libsword_la_SOURCES += $(filtersdir)/gbfmorph.cpp libsword_la_SOURCES += $(filtersdir)/plainfootnotes.cpp + libsword_la_SOURCES += $(filtersdir)/thmlstrongs.cpp libsword_la_SOURCES += $(filtersdir)/thmlfootnotes.cpp libsword_la_SOURCES += $(filtersdir)/thmlheadings.cpp @@ -30,8 +32,24 @@ libsword_la_SOURCES += $(filtersdir)/thmlgbf.cpp libsword_la_SOURCES += $(filtersdir)/thmlrtf.cpp libsword_la_SOURCES += $(filtersdir)/thmlhtml.cpp libsword_la_SOURCES += $(filtersdir)/thmlhtmlhref.cpp +libsword_la_SOURCES += $(filtersdir)/thmlwebif.cpp + +libsword_la_SOURCES += $(filtersdir)/thmlosis.cpp +libsword_la_SOURCES += $(filtersdir)/gbfosis.cpp libsword_la_SOURCES += $(filtersdir)/thmlplain.cpp +libsword_la_SOURCES += $(filtersdir)/osisheadings.cpp +libsword_la_SOURCES += $(filtersdir)/osisfootnotes.cpp +libsword_la_SOURCES += $(filtersdir)/osishtmlhref.cpp +libsword_la_SOURCES += $(filtersdir)/osiswebif.cpp +libsword_la_SOURCES += $(filtersdir)/osismorph.cpp +libsword_la_SOURCES += $(filtersdir)/osisstrongs.cpp +libsword_la_SOURCES += $(filtersdir)/osisplain.cpp +libsword_la_SOURCES += $(filtersdir)/osisrtf.cpp +libsword_la_SOURCES += $(filtersdir)/osislemma.cpp +libsword_la_SOURCES += $(filtersdir)/osisredletterwords.cpp +libsword_la_SOURCES += $(filtersdir)/osisscripref.cpp + libsword_la_SOURCES += $(filtersdir)/unicodertf.cpp libsword_la_SOURCES += $(filtersdir)/latin1utf8.cpp libsword_la_SOURCES += $(filtersdir)/latin1utf16.cpp @@ -41,25 +59,34 @@ libsword_la_SOURCES += $(filtersdir)/scsuutf8.cpp libsword_la_SOURCES += $(filtersdir)/utf8html.cpp libsword_la_SOURCES += $(filtersdir)/utf8latin1.cpp -libsword_la_SOURCES += $(filtersdir)/thmlolb.cpp +libsword_la_SOURCES += $(filtersdir)/utf8cantillation.cpp +libsword_la_SOURCES += $(filtersdir)/utf8hebrewpoints.cpp +libsword_la_SOURCES += $(filtersdir)/utf8greekaccents.cpp libsword_la_SOURCES += $(filtersdir)/greeklexattribs.cpp -if ICU -ICUDEFS = -D_ICU_ SWICUSRC = $(filtersdir)/utf8transliterator.cpp SWICUSRC += $(filtersdir)/utf8nfc.cpp SWICUSRC += $(filtersdir)/utf8nfkd.cpp SWICUSRC += $(filtersdir)/utf8arshaping.cpp SWICUSRC += $(filtersdir)/utf8bidireorder.cpp + +if ICU +ICUDEFS = -D_ICU_ +DISTSWICUSRC = +SWREALICUSRC = $(SWICUSRC) +else +if ICUSWORD +ICUDEFS = -D_ICU_ -D_ICUSWORD_ +DISTSWICUSRC = +SWREALICUSRC = $(SWICUSRC) else -SWICUSRC = -ICUDEFS = +DISTSWICUSRC = $(SWICUSRC) +SWREALICUSRC = +endif endif -libsword_la_SOURCES += $(SWICUSRC) -DEFS += $(ICUDEFS) -libsword_la_SOURCES += $(filtersdir)/utf8cantillation.cpp -libsword_la_SOURCES += $(filtersdir)/utf8hebrewpoints.cpp -libsword_la_SOURCES += $(filtersdir)/utf8greekaccents.cpp +INCLUDES += $(ICUDEFS) +libsword_la_SOURCES += $(SWREALICUSRC) +EXTRA_DIST = $(DISTSWICUSRC) diff --git a/src/modules/filters/cipherfil.cpp b/src/modules/filters/cipherfil.cpp index ad55396..abdd0fc 100644 --- a/src/modules/filters/cipherfil.cpp +++ b/src/modules/filters/cipherfil.cpp @@ -1,13 +1,13 @@ /****************************************************************************** * - * cipherfil - SWFilter decendant to decipher a module + * cipherfil - SWFilter descendant to decipher a module */ #include <stdlib.h> -#include <string.h> #include <cipherfil.h> +SWORD_NAMESPACE_START CipherFilter::CipherFilter(const char *key) { cipher = new SWCipher((unsigned char *)key); @@ -24,15 +24,21 @@ SWCipher *CipherFilter::getCipher() { } -char CipherFilter::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) { - unsigned int len; -// len = strlen(text); - len = maxlen; - if (len > 0) { - cipher->cipherBuf(&len, text); - strncpy(text, cipher->Buf(), (len < (unsigned int)maxlen) ? len : maxlen); - } - text[maxlen] = 0; - text[maxlen+1] = 0; +char CipherFilter::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + if (text.length() > 2) { //check if it's large enough to substract 2 in the next step. + unsigned long len = text.length(); + if (!key) { // hack, using key to determine encipher, or decipher + cipher->cipherBuf(&len, text.getRawData()); //set buffer to enciphered text + memcpy(text.getRawData(), cipher->Buf(), len); +// text = cipher->Buf(); //get the deciphered buffer + } + else if ((unsigned long)key == 1) { + cipher->Buf(text.getRawData(), len); + memcpy(text.getRawData(), cipher->cipherBuf(&len), len); +// text = cipher->cipherBuf(&len); + } + } return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/gbffootnotes.cpp b/src/modules/filters/gbffootnotes.cpp index c5b7b90..38f1106 100644 --- a/src/modules/filters/gbffootnotes.cpp +++ b/src/modules/filters/gbffootnotes.cpp @@ -1,62 +1,142 @@ /****************************************************************************** * - * gbffootnotes - SWFilter decendant to hide or show footnotes + * gbffootnotes - SWFilter descendant to hide or show footnotes * in a GBF module. */ #include <stdlib.h> -#include <string.h> #include <gbffootnotes.h> +#include <swmodule.h> +#include <swbuf.h> +#include <versekey.h> +#include <utilxml.h> #ifndef __GNUC__ #else #include <unixstr.h> #endif +SWORD_NAMESPACE_START -const char GBFFootnotes::on[] = "On"; -const char GBFFootnotes::off[] = "Off"; -const char GBFFootnotes::optName[] = "Footnotes"; -const char GBFFootnotes::optTip[] = "Toggles Footnotes On and Off if they exist"; +const char oName[] = "Footnotes"; +const char oTip[] = "Toggles Footnotes On and Off if they exist"; +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); -GBFFootnotes::GBFFootnotes() { - option = false; - options.push_back(on); - options.push_back(off); + +GBFFootnotes::GBFFootnotes() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); } GBFFootnotes::~GBFFootnotes() { } -void GBFFootnotes::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} -const char *GBFFootnotes::getOptionValue() +char GBFFootnotes::processText (SWBuf &text, const SWKey *key, const SWModule *module) { - return (option) ? on:off; -} + + SWBuf token; + bool intoken = false; + bool hide = false; + SWBuf tagText; + XMLTag startTag; + SWBuf refs = ""; + int footnoteNum = 1; + char buf[254]; + VerseKey parser = key->getText(); -char GBFFootnotes::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ + SWBuf orig = text; + const char *from = orig.c_str(); + + for (text = ""; *from; from++) { + if (*from == '<') { + intoken = true; + token = ""; + continue; + } + if (*from == '>') { // process tokens + intoken = false; + + XMLTag tag(token); + if (!strcmp(tag.getName(), "RF")) { + refs = ""; + startTag = tag; + hide = true; + tagText = ""; + continue; + } + else if (!strcmp(tag.getName(), "Rf")) { + if (module->isProcessEntryAttributes()) { + if(tagText.length() == 1 || !strcmp(module->Name(), "IGNT")) { + if (option) { // for ASV marks text in verse then put explanation at end of verse + text += " <FA>("; + text.append(tagText); + text += ")<Fr>"; + hide = false; + continue; + } + } + SWBuf fc = module->getEntryAttributes()["Footnote"]["count"]["value"]; + footnoteNum = (fc.length()) ? atoi(fc.c_str()) : 0; + sprintf(buf, "%i", ++footnoteNum); + module->getEntryAttributes()["Footnote"]["count"]["value"] = buf; + StringList attributes = startTag.getAttributeNames(); + for (StringList::iterator it = attributes.begin(); it != attributes.end(); it++) { + module->getEntryAttributes()["Footnote"][buf][it->c_str()] = startTag.getAttribute(it->c_str()); + } + module->getEntryAttributes()["Footnote"][buf]["body"] = tagText; + startTag.setAttribute("swordFootnote", buf); + } + hide = false; + if (option) { + text += startTag; + text.append(tagText); + } + else continue; + } + if (!hide) { + text += '<'; + text.append(token); + text += '>'; + } + else { + tagText += '<'; + tagText.append(token); + tagText += '>'; + } + continue; + } + if (intoken) { //copy token + token += *from; + } + else if (!hide) { //copy text which is not inside a token + text += *from; + } + else tagText += *from; + } + return 0; + + + + + + + + + /* if (!option) { // if we don't want footnotes - char *to, *from, token[4096]; // cheese. Fix. + char token[4096]; // cheese. Fix. int tokpos = 0; bool intoken = false; int len; bool hide = false; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- - - for (to = text; *from; from++) { + const char *from; + SWBuf orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) { if (*from == '<') { intoken = true; tokpos = 0; @@ -93,10 +173,9 @@ char GBFFootnotes::ProcessText(char *text, int maxlen, const SWKey *key, const S } // if not a footnote token, keep token in text if (!hide) { - *to++ = '<'; - for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; + text += '<'; + text += token; + text += '>'; } continue; } @@ -107,12 +186,12 @@ char GBFFootnotes::ProcessText(char *text, int maxlen, const SWKey *key, const S } else { if (!hide) { - *to++ = *from; + text += *from; } } } - *to++ = 0; - *to = 0; } - return 0; + return 0;*/ } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/gbfheadings.cpp b/src/modules/filters/gbfheadings.cpp index 590e2fa..01a34ca 100644 --- a/src/modules/filters/gbfheadings.cpp +++ b/src/modules/filters/gbfheadings.cpp @@ -1,62 +1,47 @@ /****************************************************************************** * - * gbfheadings - SWFilter decendant to hide or show headings + * gbfheadings - SWFilter descendant to hide or show headings * in a GBF module. */ #include <stdlib.h> -#include <string.h> #include <gbfheadings.h> #ifndef __GNUC__ #else #include <unixstr.h> #endif +SWORD_NAMESPACE_START -const char GBFHeadings::on[] = "On"; -const char GBFHeadings::off[] = "Off"; -const char GBFHeadings::optName[] = "Headings"; -const char GBFHeadings::optTip[] = "Toggles Headings On and Off if they exist"; +const char oName[] = "Headings"; +const char oTip[] = "Toggles Headings On and Off if they exist"; -GBFHeadings::GBFHeadings() { - option = false; - options.push_back(on); - options.push_back(off); +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +GBFHeadings::GBFHeadings() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); } GBFHeadings::~GBFHeadings() { } -void GBFHeadings::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} - -const char *GBFHeadings::getOptionValue() -{ - return (option) ? on:off; -} -char GBFHeadings::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ +char GBFHeadings::processText (SWBuf &text, const SWKey *key, const SWModule *module) { if (!option) { // if we don't want headings - char *to, *from, token[2048]; // cheese. Fix. + char token[2048]; // cheese. Fix. int tokpos = 0; bool intoken = false; int len; bool hide = false; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- - - for (to = text; *from; from++) { + const char *from; + SWBuf orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) { if (*from == '<') { intoken = true; tokpos = 0; @@ -82,10 +67,10 @@ char GBFHeadings::ProcessText(char *text, int maxlen, const SWKey *key, const SW } // if not a heading token, keep token in text if (!hide) { - *to++ = '<'; + text += '<'; for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; + text += *tok; + text += '>'; } continue; } @@ -96,12 +81,12 @@ char GBFHeadings::ProcessText(char *text, int maxlen, const SWKey *key, const SW } else { if (!hide) { - *to++ = *from; + text += *from; } } } - *to++ = 0; - *to = 0; } return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/gbfhtml.cpp b/src/modules/filters/gbfhtml.cpp index 73d445a..775bc06 100644 --- a/src/modules/filters/gbfhtml.cpp +++ b/src/modules/filters/gbfhtml.cpp @@ -1,9 +1,8 @@ /*************************************************************************** - gbfhtml.cpp - description + gbfhtml.cpp - GBF to HTML filter ------------------- - begin : Thu Jun 24 1999 - copyright : (C) 1999 by Torsten Uhlmann - email : TUhlmann@gmx.de + begin : 2001-09-03 + copyright : 2001 by CrossWire Bible Society ***************************************************************************/ /*************************************************************************** @@ -16,521 +15,154 @@ ***************************************************************************/ #include <stdlib.h> -#include <string.h> #include <gbfhtml.h> +#include <ctype.h> +SWORD_NAMESPACE_START -GBFHTML::GBFHTML() -{ +GBFHTML::GBFHTML() { + setTokenStart("<"); + setTokenEnd(">"); + + setTokenCaseSensitive(true); + + addTokenSubstitute("Rf", ")</small></font>"); + addTokenSubstitute("Rx", "</a>"); + addTokenSubstitute("FI", "<i>"); // italics begin + addTokenSubstitute("Fi", "</i>"); + addTokenSubstitute("FB", "<n>"); // bold begin + addTokenSubstitute("Fb", "</n>"); + addTokenSubstitute("FR", "<font color=\"#FF0000\">"); // words of Jesus begin + addTokenSubstitute("Fr", "</font>"); + addTokenSubstitute("FU", "<u>"); // underline begin + addTokenSubstitute("Fu", "</u>"); + addTokenSubstitute("FO", "<cite>"); // Old Testament quote begin + addTokenSubstitute("Fo", "</cite>"); + addTokenSubstitute("FS", "<sup>"); // Superscript begin// Subscript begin + addTokenSubstitute("Fs", "</sup>"); + addTokenSubstitute("FV", "<sub>"); // Subscript begin + addTokenSubstitute("Fv", "</sub>"); + addTokenSubstitute("TT", "<big>"); // Book title begin + addTokenSubstitute("Tt", "</big>"); + addTokenSubstitute("PP", "<cite>"); // poetry begin + addTokenSubstitute("Pp", "</cite>"); + addTokenSubstitute("Fn", "</font>"); // font end + addTokenSubstitute("CL", "<br />"); // new line + addTokenSubstitute("CM", "<!P><br />"); // paragraph <!P> is a non showing comment that can be changed in the front end to <P> if desired + addTokenSubstitute("CG", ""); // ??? + addTokenSubstitute("CT", ""); // ??? + addTokenSubstitute("JR", "<div align=\"right\">"); // right align begin + addTokenSubstitute("JC", "<div align=\"center\">"); // center align begin + addTokenSubstitute("JL", "</div>"); // align end + } -char GBFHTML::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ - char *to, *from, token[2048]; - int tokpos = 0; - bool intoken = false; - bool hasFootnotePreTag = false; - bool isRightJustified = false; - bool isCentered = false; - int len; +bool GBFHTML::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { const char *tok; + char val[128]; + char *valto; + const char *num; + MyUserData *u = (MyUserData *)userData; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else - from = text; // ------------------------------- - - for (to = text; *from; from++) - { - if (*from == '\n') { - *from = ' '; - } - if (*from == '<') { - intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; - continue; + if (!substituteToken(buf, token)) { + // deal with OSIS note tags. Just hide till OSISRTF + if (!strncmp(token, "note ", 5)) { + // let's stop text from going to output + u->suspendTextPassThru = true; } - if (*from == '>') { - intoken = false; - // process desired tokens - switch (*token) { - case 'W': // Strongs - switch(token[1]) - { - case 'G': // Greek - case 'H': // Hebrew - case 'T': // Tense - *to++ = ' '; - *to++ = '<'; - *to++ = 's'; - *to++ = 'm'; - *to++ = 'a'; - *to++ = 'l'; - *to++ = 'l'; - *to++ = '>'; - *to++ = '<'; - *to++ = 'e'; - *to++ = 'm'; - *to++ = '>'; - for (tok = token+2; *tok; tok++) - *to++ = *tok; - *to++ = '<'; - *to++ = '/'; - *to++ = 'e'; - *to++ = 'm'; - *to++ = '>'; - *to++ = '<'; - *to++ = '/'; - *to++ = 's'; - *to++ = 'm'; - *to++ = 'a'; - *to++ = 'l'; - *to++ = 'l'; - *to++ = '>'; - *to++ = ' '; - continue; - } - break; - case 'R': - switch(token[1]) - { - case 'X': - *to++ = '<'; - *to++ = 'a'; - *to++ = ' '; - *to++ = 'h'; - *to++ = 'r'; - *to++ = 'e'; - *to++ = 'f'; - *to++ = '='; - *to++ = '\"'; - for (tok = token + 3; *tok; tok++) { - if(*tok != '<' && *tok+1 != 'R' && *tok+2 != 'x') { - *to++ = *tok; - } - else { - break; - } - } - *to++ = '\"'; - *to++ = '>'; - continue; - case 'x': - *to++ = '<'; - *to++ = '/'; - *to++ = 'a'; - *to++ = '>'; - continue; - case 'B': //word(s) explained in footnote - *to++ = '<'; - *to++ = 'i'; - *to++ = '>'; - hasFootnotePreTag = true; //we have the RB tag - continue; - case 'F': // footnote begin - if (hasFootnotePreTag) { - *to++ = '<'; - *to++ = '/'; - *to++ = 'i'; - *to++ = '>'; - *to++ = ' '; - } - *to++ = '<'; - *to++ = 'f'; - *to++ = 'o'; - *to++ = 'n'; - *to++ = 't'; - *to++ = ' '; - *to++ = 'c'; - *to++ = 'o'; - *to++ = 'l'; - *to++ = 'o'; - *to++ = 'r'; - *to++ = '='; - *to++ = '\"'; - *to++ = '#'; - *to++ = '8'; - *to++ = '0'; - *to++ = '0'; - *to++ = '0'; - *to++ = '0'; - *to++ = '0'; - *to++ = '\"'; - *to++ = '>'; + + else if (!strncmp(token, "/note", 5)) { + u->suspendTextPassThru = false; + } - *to++ = ' '; - *to++ = '<'; - *to++ = 's'; - *to++ = 'm'; - *to++ = 'a'; - *to++ = 'l'; - *to++ = 'l'; - *to++ = '>'; - *to++ = '('; + else if (!strncmp(token, "w", 1)) { + // OSIS Word (temporary until OSISRTF is done) + valto = val; + num = strstr(token, "lemma=\"x-Strongs:"); + if (num) { + for (num+=17; ((*num) && (*num != '\"')); num++) + *valto++ = *num; + *valto = 0; + if (atoi((!isdigit(*val))?val+1:val) < 5627) { + buf += " <small><em><"; + for (tok = (!isdigit(*val))?val+1:val; *tok; tok++) + buf += *tok; + buf += "></em></small> "; + } + } + valto = val; + num = strstr(token, "morph=\"x-Robinson:"); + if (num) { + for (num+=18; ((*num) && (*num != '\"')); num++) + *valto++ = *num; + *valto = 0; + // normal robinsons tense + buf += " <small><em>("; + for (tok = val; *tok; tok++) + buf += *tok; + buf += ")</em></small> "; + } + } + + else if (!strncmp(token, "WG", 2) || !strncmp(token, "WH", 2)) { // strong's numbers + buf += " <small><em><"; + for (tok = token + 2; *tok; tok++) + buf += *tok; + buf += "></em></small> "; + } - continue; - case 'f': // footnote end - *to++ = ')'; - *to++ = '<'; - *to++ = '/'; - *to++ = 's'; - *to++ = 'm'; - *to++ = 'a'; - *to++ = 'l'; - *to++ = 'l'; - *to++ = '>'; - *to++ = ' '; - *to++ = '<'; - *to++ = '/'; - *to++ = 'f'; - *to++ = 'o'; - *to++ = 'n'; - *to++ = 't'; - *to++ = '>'; - hasFootnotePreTag = false; - continue; - } - break; + else if (!strncmp(token, "WTG", 3) || !strncmp(token, "WTH", 3)) { // strong's numbers tense + buf += " <small><em><"; + for (tok = token + 3; *tok; tok++) + if(*tok != '\"') + buf += *tok; + buf += ")</em></small> "; + } - case 'F': // font tags - switch(token[1]) - { - case 'I': // italic start - *to++ = '<'; - *to++ = 'i'; - *to++ = '>'; - continue; - case 'i': // italic end - *to++ = '<'; - *to++ = '/'; - *to++ = 'i'; - *to++ = '>'; - continue; - case 'B': // bold start - *to++ = '<'; - *to++ = 'b'; - *to++ = '>'; - continue; - case 'b': // bold end - *to++ = '<'; - *to++ = '/'; - *to++ = 'b'; - *to++ = '>'; - continue; - case 'R': // words of Jesus begin - *to++ = '<'; - *to++ = 'f'; - *to++ = 'o'; - *to++ = 'n'; - *to++ = 't'; - *to++ = ' '; - *to++ = 'c'; - *to++ = 'o'; - *to++ = 'l'; - *to++ = 'o'; - *to++ = 'r'; - *to++ = '='; - *to++ = '#'; - *to++ = 'F'; - *to++ = 'F'; - *to++ = '0'; - *to++ = '0'; - *to++ = '0'; - *to++ = '0'; - *to++ = '>'; - continue; - case 'r': // words of Jesus end - *to++ = '<'; - *to++ = '/'; - *to++ = 'f'; - *to++ = 'o'; - *to++ = 'n'; - *to++ = 't'; - *to++ = '>'; - continue; - case 'U': // Underline start - *to++ = '<'; - *to++ = 'u'; - *to++ = '>'; - continue; - case 'u': // Underline end - *to++ = '<'; - *to++ = '/'; - *to++ = 'u'; - *to++ = '>'; - continue; - case 'O': // Old Testament quote begin - *to++ = '<'; - *to++ = 'c'; - *to++ = 'i'; - *to++ = 't'; - *to++ = 'e'; - *to++ = '>'; - continue; - case 'o': // Old Testament quote end - *to++ = '<'; - *to++ = '/'; - *to++ = 'c'; - *to++ = 'i'; - *to++ = 't'; - *to++ = 'e'; - *to++ = '>'; - continue; - case 'S': // Superscript begin - *to++ = '<'; - *to++ = 's'; - *to++ = 'u'; - *to++ = 'p'; - *to++ = '>'; - continue; - case 's': // Superscript end - *to++ = '<'; - *to++ = '/'; - *to++ = 's'; - *to++ = 'u'; - *to++ = 'p'; - *to++ = '>'; - continue; - case 'V': // Subscript begin - *to++ = '<'; - *to++ = 's'; - *to++ = 'u'; - *to++ = 'b'; - *to++ = '>'; - continue; - case 'v': // Subscript end - *to++ = '<'; - *to++ = '/'; - *to++ = 's'; - *to++ = 'u'; - *to++ = 'b'; - *to++ = '>'; - continue; - case 'N': - *to++ = '<'; - *to++ = 'f'; - *to++ = 'o'; - *to++ = 'n'; - *to++ = 't'; - *to++ = ' '; - *to++ = 'f'; - *to++ = 'a'; - *to++ = 'c'; - *to++ = 'e'; - *to++ = '='; - *to++ = '"'; - for (tok = token + 2; *tok; tok++) - *to++ = *tok; - *to++ = '"'; - *to++ = '>'; - continue; - case 'n': - *to++ = '<'; - *to++ = '/'; - *to++ = 'f'; - *to++ = 'o'; - *to++ = 'n'; - *to++ = 't'; - *to++ = '>'; - continue; - } - break; - case 'C': // special character tags - switch(token[1]) - { - case 'A': // ASCII value - *to++ = (char)atoi(&token[2]); - continue; - case 'G': - //*to++ = ' '; - continue; - case 'L': // line break - *to++ = '<'; - *to++ = 'b'; - *to++ = 'r'; - *to++ = ' '; - *to++ = '/'; - *to++ = '>'; - *to++ = ' '; - continue; - case 'M': // new paragraph - *to++ = '<'; - *to++ = 'b'; - *to++ = 'r'; - *to++ = ' '; - *to++ = '/'; - *to++ = '>'; - continue; - case 'T': - //*to++ = ' '; - continue; - } - break; - case 'J': //Justification - switch(token[1]) - { - case 'R': //right - *to++ = '<'; - *to++ = 'd'; - *to++ = 'i'; - *to++ = 'v'; - *to++ = ' '; - *to++ = 'a'; - *to++ = 'l'; - *to++ = 'i'; - *to++ = 'g'; - *to++ = 'n'; - *to++ = '='; - *to++ = '\"'; - *to++ = 'r'; - *to++ = 'i'; - *to++ = 'g'; - *to++ = 'h'; - *to++ = 't'; - *to++ = '\"'; - *to++ = '>'; - isRightJustified = true; - continue; + else if (!strncmp(token, "RX", 2)) { + buf += "<i>"; + for (tok = token + 3; *tok; tok++) { + if(*tok != '<' && *tok+1 != 'R' && *tok+2 != 'x') { + buf += *tok; + } + else { + break; + } + } + buf += "</i>"; + } - case 'C': //center - *to++ = '<'; - *to++ = 'd'; - *to++ = 'i'; - *to++ = 'v'; - *to++ = ' '; - *to++ = 'a'; - *to++ = 'l'; - *to++ = 'i'; - *to++ = 'g'; - *to++ = 'n'; - *to++ = '='; - *to++ = '\"'; - *to++ = 'c'; - *to++ = 'e'; - *to++ = 'n'; - *to++ = 't'; - *to++ = 'e'; - *to++ = 'r'; - *to++ = '\"'; - *to++ = '>'; - isCentered = true; - continue; + else if (!strncmp(token, "RB", 2)) { + buf += "<i>"; + u->hasFootnotePreTag = true; + } - case 'L': //left, reset right and center - if (isCentered) { - *to++ = '<'; - *to++ = '/'; - *to++ = 'c'; - *to++ = 'e'; - *to++ = 'n'; - *to++ = 't'; - *to++ = 'e'; - *to++ = 'r'; - *to++ = '>'; - isCentered = false; - } - if (isRightJustified) { - *to++ = '<'; - *to++ = '/'; - *to++ = 'd'; - *to++ = 'i'; - *to++ = 'v'; - *to++ = '>'; - isRightJustified = false; - } - continue; - } - break; - case 'T': // title formatting - switch(token[1]) - { - case 'T': // Book title begin - *to++ = '<'; - *to++ = 'b'; - *to++ = 'i'; - *to++ = 'g'; - *to++ = '>'; - continue; - case 't': - *to++ = '<'; - *to++ = '/'; - *to++ = 'b'; - *to++ = 'i'; - *to++ = 'g'; - *to++ = '>'; - continue;/* - case 'S': - *to++ = '<'; - *to++ = 'b'; - *to++ = 'r'; - *to++ = ' '; - *to++ = '/'; - *to++ = '>'; - *to++ = '<'; - *to++ = 'b'; - *to++ = 'i'; - *to++ = 'g'; - *to++ = '>'; - continue; - case 's': - *to++ = '<'; - *to++ = '/'; - *to++ = 'b'; - *to++ = 'i'; - *to++ = 'g'; - *to++ = '>'; - *to++ = '<'; - *to++ = 'b'; - *to++ = 'r'; - *to++ = ' '; - *to++ = '/'; - *to++ = '>'; - continue;*/ - } - break; - - case 'P': // special formatting - switch(token[1]) - { - case 'P': // Poetry begin - *to++ = '<'; - *to++ = 'c'; - *to++ = 'i'; - *to++ = 't'; - *to++ = 'e'; - *to++ = '>'; - continue; - case 'p': - *to++ = '<'; - *to++ = '/'; - *to++ = 'c'; - *to++ = 'i'; - *to++ = 't'; - *to++ = 'e'; - *to++ = '>'; - continue; - } - break; + else if (!strncmp(token, "RF", 2)) { + if (u->hasFootnotePreTag) { + u->hasFootnotePreTag = false; + buf += "</i> "; } - continue; + buf += "<font color=\"#800000\"><small> ("; + } + + else if (!strncmp(token, "FN", 2)) { + buf += "<font face=\""; + for (tok = token + 2; *tok; tok++) + if(*tok != '\"') + buf += *tok; + buf += "\">"; + } + + else if (!strncmp(token, "CA", 2)) { // ASCII value + buf += (char)atoi(&token[2]); + } + + else { + return false; } - if (intoken) { - if (tokpos < 2045) { - token[tokpos++] = *from; - token[tokpos+2] = 0; - } - } - else - *to++ = *from; } - *to++ = 0; - *to = 0; - return 0; + return true; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/gbfhtmlhref.cpp b/src/modules/filters/gbfhtmlhref.cpp index 30b27ba..4061150 100644 --- a/src/modules/filters/gbfhtmlhref.cpp +++ b/src/modules/filters/gbfhtmlhref.cpp @@ -16,8 +16,13 @@ ***************************************************************************/ #include <stdlib.h> -#include <string.h> #include <gbfhtmlhref.h> +#include <swmodule.h> +#include <utilxml.h> +#include <versekey.h> +#include <ctype.h> + +SWORD_NAMESPACE_START GBFHTMLHREF::GBFHTMLHREF() { setTokenStart("<"); @@ -25,12 +30,13 @@ GBFHTMLHREF::GBFHTMLHREF() { setTokenCaseSensitive(true); - addTokenSubstitute("Rf", ")</small></font>"); + //addTokenSubstitute("Rf", ")</small></font>"); + addTokenSubstitute("FA", "<font color=\"#800000\">"); // for ASV footnotes to mark text addTokenSubstitute("Rx", "</a>"); addTokenSubstitute("FI", "<i>"); // italics begin addTokenSubstitute("Fi", "</i>"); - addTokenSubstitute("FB", "<n>"); // bold begin - addTokenSubstitute("Fb", "</n>"); + addTokenSubstitute("FB", "<b>"); // bold begin + addTokenSubstitute("Fb", "</b>"); addTokenSubstitute("FR", "<font color=\"#FF0000\">"); // words of Jesus begin addTokenSubstitute("Fr", "</font>"); addTokenSubstitute("FU", "<u>"); // underline begin @@ -57,87 +63,160 @@ GBFHTMLHREF::GBFHTMLHREF() { } -bool GBFHTMLHREF::handleToken(char **buf, const char *token, DualStringMap &userData) { +bool GBFHTMLHREF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { const char *tok; + char val[128]; + char *valto; + const char *num; + MyUserData *u = (MyUserData *)userData; if (!substituteToken(buf, token)) { - if (!strncmp(token, "WG", 2) || !strncmp(token, "WH", 2)) { // strong's numbers - pushString(buf, " <small><em><<a href=\"#"); + XMLTag tag(token); + if (!strncmp(token, "w", 1)) { + // OSIS Word (temporary until OSISRTF is done) + valto = val; + num = strstr(token, "lemma=\"x-Strongs:"); + if (num) { + for (num+=17; ((*num) && (*num != '\"')); num++) + *valto++ = *num; + *valto = 0; + if (atoi((!isdigit(*val))?val+1:val) < 5627) { + buf += " <small><em><<a href=\"type=Strongs value="; + for (tok = val; *tok; tok++) + buf += *tok; + buf += "\">"; + for (tok = (!isdigit(*val))?val+1:val; *tok; tok++) + buf += *tok; + buf += "</a>></em></small> "; + //cout << buf; + + } + /* forget these for now + else { + // verb morph + sprintf(wordstr, "%03d", word-1); + module->getEntryAttributes()["Word"][wordstr]["Morph"] = val; + } + */ + } + valto = val; + num = strstr(token, "morph=\"x-Robinson:"); + if (num) { + for (num+=18; ((*num) && (*num != '\"')); num++) + *valto++ = *num; + *valto = 0; + buf += " <small><em>(<a href=\"type=morph class=Robinson value="; + for (tok = val; *tok; tok++) + // normal robinsons tense + buf += *tok; + buf += "\">"; + for (tok = val; *tok; tok++) + //if(*tok != '\"') + buf += *tok; + buf += "</a>)</em></small> "; + } + } + + else if (!strncmp(token, "WG", 2) || !strncmp(token, "WH", 2)) { // strong's numbers + buf += " <small><em><<a href=\"type=Strongs value="; for (tok = token+1; *tok; tok++) //if(token[i] != '\"') - *(*buf)++ = *tok; - *(*buf)++ = '\"'; - *(*buf)++ = '>'; + buf += *tok; + buf += "\">"; for (tok = token + 2; *tok; tok++) //if(token[i] != '\"') - *(*buf)++ = *tok; - pushString(buf, "</a>></em></small>"); + buf += *tok; + buf += "</a>></em></small>"; } else if (!strncmp(token, "WTG", 3) || !strncmp(token, "WTH", 3)) { // strong's numbers tense - pushString(buf, " <small><em>(<A HREF=\"#"); + buf += " <small><em>(<a href=\"type=Strongs value="; for (tok = token + 2; *tok; tok++) if(*tok != '\"') - *(*buf)++ = *tok; - *(*buf)++ = '\"'; - *(*buf)++ = '>'; + buf += *tok; + buf += "\">"; for (tok = token + 3; *tok; tok++) if(*tok != '\"') - *(*buf)++ = *tok; - pushString(buf, "</a>)</em></small>"); + buf += *tok; + buf += "</a>)</em></small>"; } else if (!strncmp(token, "WT", 2) && strncmp(token, "WTH", 3) && strncmp(token, "WTG", 3)) { // morph tags - pushString(buf, " <small><em>(<a href=\"M"); + buf += " <small><em>(<a href=\"type=morph class=none value="; for (tok = token + 2; *tok; tok++) if(*tok != '\"') - *(*buf)++ = *tok; - *(*buf)++ = '\"'; - *(*buf)++ = '>'; + buf += *tok; + buf += "\">"; for (tok = token + 2; *tok; tok++) if(*tok != '\"') - *(*buf)++ = *tok; - pushString(buf, "</a>)</em></small>"); + buf += *tok; + buf += "</a>)</em></small>"; } - else if (!strncmp(token, "RX", 2)) { - pushString(buf, "<a href=\""); + else if (!strcmp(tag.getName(), "RX")) { + buf += "<a href=\""; for (tok = token + 3; *tok; tok++) { if(*tok != '<' && *tok+1 != 'R' && *tok+2 != 'x') { - *(*buf)++ = *tok; + buf += *tok; } else { break; } } - *(*buf)++ = '\"'; - *(*buf)++ = '>'; + buf += "\">"; } - + else if (!strcmp(tag.getName(), "RF")) { + SWBuf type = tag.getAttribute("type"); + SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) { } + if (vkey) { + // leave this special osis type in for crossReference notes types? Might thml use this some day? Doesn't hurt. + //char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n'); + buf.appendFormatted("<a href=\"noteID=%s.%c.%s\"><small><sup>*%c</sup></small></a> ", vkey->getText(), 'n', footnoteNumber.c_str(), 'n'); + } + u->suspendTextPassThru = true; + } + else if (!strcmp(tag.getName(), "Rf")) { + u->suspendTextPassThru = false; + } +/* else if (!strncmp(token, "RB", 2)) { - pushString(buf, "<i>"); - userData["hasFootnotePreTag"] = "true"; + buf += "<i> "; + u->hasFootnotePreTag = true; } + else if (!strncmp(token, "Rf", 2)) { + buf += " <a href=\"note="; + buf += u->lastTextNode.c_str(); + buf += "\">"; + buf += "<small><sup>*n</sup></small></a> "; + // let's let text resume to output again + u->suspendTextPassThru = false; + } + else if (!strncmp(token, "RF", 2)) { - if(userData["hasFootnotePreTag"] == "true") { - userData["hasFootnotePreTag"] = "false"; - pushString(buf, "</i> "); + if (u->hasFootnotePreTag) { + u->hasFootnotePreTag = false; + buf += "</i> "; } - pushString(buf, "<font color=\"#800000\"><small> ("); + u->suspendTextPassThru = true; } - +*/ else if (!strncmp(token, "FN", 2)) { - pushString(buf, "<font face=\""); + buf += "<font face=\""; for (tok = token + 2; *tok; tok++) if(*tok != '\"') - *(*buf)++ = *tok; - *(*buf)++ = '\"'; - *(*buf)++ = '>'; + buf += *tok; + buf += "\">"; } else if (!strncmp(token, "CA", 2)) { // ASCII value - *(*buf)++ = (char)atoi(&token[2]); + buf += (char)atoi(&token[2]); } else { @@ -146,3 +225,5 @@ bool GBFHTMLHREF::handleToken(char **buf, const char *token, DualStringMap &user } return true; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/gbfmorph.cpp b/src/modules/filters/gbfmorph.cpp index f8d336e..996baf9 100644 --- a/src/modules/filters/gbfmorph.cpp +++ b/src/modules/filters/gbfmorph.cpp @@ -1,62 +1,47 @@ /****************************************************************************** * - * gbfmorph - SWFilter decendant to hide or show morph tags + * gbfmorph - SWFilter descendant to hide or show morph tags * in a GBF module. */ #include <stdlib.h> -#include <string.h> #include <gbfmorph.h> #ifndef __GNUC__ #else #include <unixstr.h> #endif +SWORD_NAMESPACE_START -const char GBFMorph::on[] = "On"; -const char GBFMorph::off[] = "Off"; -const char GBFMorph::optName[] = "Morphological Tags"; -const char GBFMorph::optTip[] = "Toggles Morphological Tags On and Off if they exist"; +const char oName[] = "Morphological Tags"; +const char oTip[] = "Toggles Morphological Tags On and Off if they exist"; +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); -GBFMorph::GBFMorph() { - option = false; - options.push_back(on); - options.push_back(off); +GBFMorph::GBFMorph() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); } GBFMorph::~GBFMorph() { } -void GBFMorph::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} - -const char *GBFMorph::getOptionValue() -{ - return (option) ? on:off; -} -char GBFMorph::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ +char GBFMorph::processText(SWBuf &text, const SWKey *key, const SWModule *module) { if (!option) { // if we don't want morph tags - char *to, *from, token[2048]; // cheese. Fix. + const char *from; + char token[2048]; // cheese. Fix. int tokpos = 0; bool intoken = false; int len; bool lastspace = false; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- + SWBuf orig = text; + from = orig.c_str(); - for (to = text; *from; from++) { + for (text = ""; *from; from++) { if (*from == '<') { intoken = true; tokpos = 0; @@ -70,15 +55,14 @@ char GBFMorph::ProcessText(char *text, int maxlen, const SWKey *key, const SWMod if (*token == 'W' && token[1] == 'T') { // Morph if ((from[1] == ' ') || (from[1] == ',') || (from[1] == ';') || (from[1] == '.') || (from[1] == '?') || (from[1] == '!') || (from[1] == ')') || (from[1] == '\'') || (from[1] == '\"')) { if (lastspace) - to--; + text--; } continue; } // if not a morph tag token, keep token in text - *to++ = '<'; - for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; + text += '<'; + text += token; + text += '>'; continue; } if (intoken) { @@ -87,12 +71,12 @@ char GBFMorph::ProcessText(char *text, int maxlen, const SWKey *key, const SWMod token[tokpos+2] = 0; } else { - *to++ = *from; + text += *from; lastspace = (*from == ' '); } } - *to++ = 0; - *to = 0; } return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/gbfosis.cpp b/src/modules/filters/gbfosis.cpp new file mode 100644 index 0000000..b5dd8e1 --- /dev/null +++ b/src/modules/filters/gbfosis.cpp @@ -0,0 +1,439 @@ +/****************************************************************************** + * + * gbfstrongs - SWFilter descendant to hide or show strongs number + * in a GBF module. + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <gbfosis.h> +#include <swmodule.h> +#include <versekey.h> +#include <swlog.h> +#include <stdarg.h> +#ifndef __GNUC__ +#else +#include <unixstr.h> +#endif + +SWORD_NAMESPACE_START + +GBFOSIS::GBFOSIS() { +} + + +GBFOSIS::~GBFOSIS() { +} + + +char GBFOSIS::processText(SWBuf &text, const SWKey *key, const SWModule *module) { +/* + char *to, *from, token[2048]; // cheese. Fix. + int tokpos = 0; + bool intoken = false; + int len; + bool lastspace = false; + int word = 1; + char val[128]; + char buf[128]; + char wordstr[5]; + char *valto; + char *ch; + char *textStart, *textEnd; + char *wordStart, *wordEnd; + char *fromStart; + bool newText = false; + bool newWord = false; + SWBuf tmp; + bool suspendTextPassThru = false; + bool keepToken = false; + bool handled = false; + + len = strlen(text) + 1; // shift string to right of buffer + if (len < maxlen) { + memmove(&text[maxlen - len], text, len); + from = &text[maxlen - len]; + } + else from = text; + + textStart = from; + fromStart = from; + wordStart = text; + + static QuoteStack quoteStack; + + // ------------------------------- + + for (to = text; *from; from++) { + if (*from == '<') { + intoken = true; + tokpos = 0; + token[0] = 0; + token[1] = 0; + token[2] = 0; + textEnd = from-1; + wordEnd = to; + continue; + } + if (*from == '>') { // process tokens + intoken = false; + keepToken = false; + suspendTextPassThru = false; + newWord = true; + handled = false; + + while (wordStart < (text+maxlen)) { +// if (strchr(" ,;.?!()'\"", *wordStart)) + if (strchr(";, .:?!()'\"", *wordStart) && wordStart[0] && wordStart[1]) + wordStart++; + else break; + } + while (wordEnd > wordStart) { + if (strchr(" ,;.:?!()'\"", *wordEnd)) + wordEnd--; + else break; + } + + // Scripture Reference + if (!strncmp(token, "scripRef", 8)) { + // pushString(buf, "<reference work=\"Bible.KJV\" reference=\""); + suspendTextPassThru = true; + newText = true; + handled = true; + } + else if (!strncmp(token, "/scripRef", 9)) { + tmp = ""; + tmp.append(textStart, (int)(textEnd - textStart)+1); + pushString(&to, convertToOSIS(tmp.c_str(), key)); + lastspace = false; + suspendTextPassThru = false; + handled = true; + } + + // Footnote + if (!strcmp(token, "RF")) { + // pushString(buf, "<reference work=\"Bible.KJV\" reference=\""); + pushString(&to, "<note type=\"x-StudyNote\">"); + newText = true; + lastspace = false; + handled = true; + } + else if (!strcmp(token, "Rf")) { + pushString(&to, "</note>"); + lastspace = false; + handled = true; + } + // hebrew titles + if (!strcmp(token, "TH")) { + pushString(&to, "<title type=\"psalm\">"); + newText = true; + lastspace = false; + handled = true; + } + else if (!strcmp(token, "Th")) { + pushString(&to, "</title>"); + lastspace = false; + handled = true; + } + // Italics assume transchange + if (!strcmp(token, "FI")) { + pushString(&to, "<transChange type=\"added\">"); + newText = true; + lastspace = false; + handled = true; + } + else if (!strcmp(token, "Fi")) { + pushString(&to, "</transChange>"); + lastspace = false; + handled = true; + } + // Paragraph break. For now use empty paragraph element + if (!strcmp(token, "CM")) { + pushString(&to, "<milestone type=\"x-p\" />"); + newText = true; + lastspace = false; + handled = true; + } + + // Figure + else if (!strncmp(token, "img ", 4)) { + const char *src = strstr(token, "src"); + if (!src) // assert we have a src attribute + continue; +// return false; + + pushString(&to, "<figure src=\""); + const char *c; + for (c = src;((*c) && (*c != '"')); c++); + +// uncomment for SWORD absolute path logic +// if (*(c+1) == '/') { +// pushString(buf, "file:"); +// pushString(buf, module->getConfigEntry("AbsoluteDataPath")); +// if (*((*buf)-1) == '/') +// c++; // skip '/' +// } +// end of uncomment for asolute path logic + + for (c++;((*c) && (*c != '"')); c++) + *to++ = *c; + + pushString(&to, "\" />"); + lastspace = false; + handled = true; + } + + // Strongs numbers + else if (*token == 'W' && (token[1] == 'G' || token[1] == 'H')) { // Strongs + bool divineName = false; + if (module->isProcessEntryAttributes()) { + valto = val; + for (unsigned int i = 1; ((token[i]) && (i < 150)); i++) + *valto++ = token[i]; + *valto = 0; + // normal strongs number + strstrip(val); + if (!strncmp(wordStart, "<w ", 3)) { + strtok(wordStart, ">"); + char *attStart = strstr(wordStart, "lemma"); + if (attStart) { + attStart += 7; + sprintf(buf, "x-Strongs:%s|", val); + } + else { + attStart = wordStart + 3; + sprintf(buf, "lemma=\"x-Strongs:%s\" ", val); + } + wordStart[strlen(wordStart)] = '>'; + memmove(attStart+strlen(buf), attStart, (to-attStart)+1); + memcpy(attStart, buf, strlen(buf)); + to+=strlen(buf); + } + else { + if (!strcmp(val, "H03068")) { //divineName + sprintf(buf, "<divineName><w lemma=\"x-Strongs:%s\">", val); + divineName = true; + } + else sprintf(buf, "<w lemma=\"x-Strongs:%s\">", val); + + memmove(wordStart+strlen(buf), wordStart, (to-wordStart)+1); + memcpy(wordStart, buf, strlen(buf)); + to+=strlen(buf); + + if (divineName) { + wordStart += 12; + pushString(&to, "</w></divineName>"); + } + else pushString(&to, "</w>"); + + module->getEntryAttributes()["Word"][wordstr]["Strongs"] = val; + lastspace = false; + } + } + handled = true; + } + + // Morphology + else if (*token == 'W' && token[1] == 'T' && (token[2] == 'G' || token[2] == 'H')) { // Strongs + valto = val; + for (unsigned int i = 1; ((token[i]) && (i < 150)); i++) + *valto++ = token[i]; + *valto = 0; + strstrip(val); + if (!strncmp(wordStart, "<w ", 3)) { + strtok(wordStart, ">"); + char *attStart = strstr(wordStart, "morph"); + if (attStart) { + attStart += 7; + sprintf(buf, "x-%s:%s|", "StrongsMorph", val); + } + else { + attStart = wordStart + 3; + sprintf(buf, "morph=\"x-%s:%s\" ", "StrongsMorph", val); + } + wordStart[strlen(wordStart)] = '>'; + memmove(attStart+strlen(buf), attStart, (to-attStart)+1); + memcpy(attStart, buf, strlen(buf)); + to+=strlen(buf); + } + else { + sprintf(buf, "<w morph=\"x-%s:%s\">", "StrongsMorph", val); + memmove(wordStart+strlen(buf), wordStart, (to-wordStart)+1); + memcpy(wordStart, buf, strlen(buf)); + to+=strlen(buf); + pushString(&to, "</w>"); + lastspace = false; + } + handled = true; + } + + if (!keepToken) { + if (!handled) { + SWLog::systemlog->LogError("Unprocessed Token: <%s>", token); +// exit(-1); + } + if (from[1] && strchr(" ,;.:?!()'\"", from[1])) { + if (lastspace) + to--; + } + if (newText) {textStart = from+1; newText = false; } +// if (newWord) {wordStart = to; newWord = false; } + continue; + } + // if not a strongs token, keep token in text + *to++ = '<'; + for (char *tok = token; *tok; tok++) + *to++ = *tok; + *to++ = '>'; + if (newText) {textStart = to; newWord = false; } +// if (newWord) {wordStart = to; newWord = false; } + continue; + } + if (intoken) { + if ((tokpos < 2045) && ((*from != 10)&&(*from != 13))) { + token[tokpos++] = *from; + token[tokpos+2] = 0; + } + } + else { + switch (*from) { + case '\'': + case '\"': + case '`': +// quoteStack.handleQuote(fromStart, from, &to); + *to++ = *from; + from++; + break; + default: + if (newWord && (*from != ' ')) {wordStart = to; newWord = false; memset(to, 0, 10); } + if (!suspendTextPassThru) { + *to++ = *from; + lastspace = (*from == ' '); + } + } + } + } + + VerseKey *vkey = SWDYNAMIC_CAST(VerseKey, key); + if (vkey) { + char ref[254]; + if (vkey->Verse()) + sprintf(ref, "\t\t<verse osisID=\"%s\">", vkey->getOSISRef()); + else *ref = 0; + if (*ref) { + memmove(text+strlen(ref), text, maxlen-strlen(ref)-1); + memcpy(text, ref, strlen(ref)); + to+=strlen(ref); + if (vkey->Verse()) { + VerseKey tmp; + tmp = *vkey; + tmp.AutoNormalize(0); + tmp.Headings(1); + sprintf(ref, "</verse>"); + pushString(&to, ref); + 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); +// sprintf(ref, "\t</div>"); +// pushString(&to, ref); + if (!quoteStack.empty()) { + SWLog::systemlog->LogError("popping unclosed quote at end of book"); + quoteStack.clear(); + } + } + } + } + +// +// else if (vkey->Chapter()) { +// sprintf(ref, "\t<div type=\"chapter\" osisID=\"%s\">", vkey->getOSISRef()); +// } +// else sprintf(ref, "\t<div type=\"book\" osisID=\"%s\">", vkey->getOSISRef()); +// + } + } + *to++ = 0; + *to = 0; +*/ + return 0; +} + + +const char *GBFOSIS::convertToOSIS(const char *inRef, const SWKey *key) { + static SWBuf outRef; + + outRef = ""; + + VerseKey defLanguage; + ListKey verses = defLanguage.ParseVerseList(inRef, (*key), true); + const char *startFrag = inRef; + for (int i = 0; i < verses.Count(); i++) { + VerseKey *element = SWDYNAMIC_CAST(VerseKey, verses.GetElement(i)); + char buf[5120]; + char frag[800]; + if (element) { + memmove(frag, startFrag, ((const char *)element->userData - startFrag) + 1); + frag[((const char *)element->userData - startFrag) + 1] = 0; + startFrag = (const char *)element->userData + 1; + sprintf(buf, "<reference osisRef=\"%s-%s\">%s</reference>", element->LowerBound().getOSISRef(), element->UpperBound().getOSISRef(), frag); + } + else { + memmove(frag, startFrag, ((const char *)verses.GetElement(i)->userData - startFrag) + 1); + frag[((const char *)verses.GetElement(i)->userData - startFrag) + 1] = 0; + startFrag = (const char *)verses.GetElement(i)->userData + 1; + sprintf(buf, "<reference osisRef=\"%s\">%s</reference>", VerseKey(*verses.GetElement(i)).getOSISRef(), frag); + } + outRef+=buf; + } + return outRef.c_str(); +} + + +QuoteStack::QuoteStack() { + clear(); +} + + +void QuoteStack::clear() { + while (!quotes.empty()) quotes.pop(); +} + + +QuoteStack::~QuoteStack() { + clear(); +} + + +void QuoteStack::handleQuote(char *buf, char *quotePos, SWBuf &text) { +//QuoteInstance(char startChar = '\"', char level = 1, string uniqueID = "", char continueCount = 0) { + if (!quotes.empty()) { + QuoteInstance last = quotes.top(); + if (last.startChar == *quotePos) { + text += "</quote>"; + quotes.pop(); + } + else { + quotes.push(QuoteInstance(*quotePos, last.level+1)); + quotes.top().pushStartStream(text); + } + } + else { + quotes.push(QuoteInstance(*quotePos)); + quotes.top().pushStartStream(text); + } +} + +void QuoteStack::QuoteInstance::pushStartStream(SWBuf &text) { + text.appendFormatted("<quote level=\"%d\">", level); +} + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/gbfplain.cpp b/src/modules/filters/gbfplain.cpp index 65766d3..f519a25 100644 --- a/src/modules/filters/gbfplain.cpp +++ b/src/modules/filters/gbfplain.cpp @@ -1,34 +1,28 @@ /****************************************************************************** * - * gbfplain - SWFilter decendant to strip out all GBF tags or convert to + * gbfplain - SWFilter descendant to strip out all GBF tags or convert to * ASCII rendered symbols. */ #include <stdlib.h> -#include <string.h> #include <gbfplain.h> +SWORD_NAMESPACE_START GBFPlain::GBFPlain() { } -char GBFPlain::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char GBFPlain::processText (SWBuf &text, const SWKey *key, const SWModule *module) { - char *to, *from, token[2048]; + char token[2048]; int tokpos = 0; bool intoken = false; - int len; - - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- - - for (to = text; *from; from++) { + const char *from; + SWBuf orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) { if (*from == '<') { intoken = true; tokpos = 0; @@ -46,34 +40,30 @@ char GBFPlain::ProcessText(char *text, int maxlen, const SWKey *key, const SWMod case 'G': // Greek case 'H': // Hebrew case 'T': // Tense - *to++ = ' '; - *to++ = '<'; + text += " <"; for (char *tok = token + 2; *tok; tok++) - *to++ = *tok; - *to++ = '>'; - *to++ = ' '; + text += *tok; + text += "> "; continue; } break; case 'R': switch(token[1]) { case 'F': // footnote begin - *to++ = ' '; - *to++ = '['; + text += " ["; continue; case 'f': // footnote end - *to++ = ']'; - *to++ = ' '; + text += "] "; continue; } break; case 'C': switch(token[1]) { case 'A': // ASCII value - *to++ = (char)atoi(&token[2]); + text += (char)atoi(&token[2]); continue; case 'G': - *to++ = '>'; + text += ">"; continue; /* Bug in WEB case 'L': @@ -82,11 +72,10 @@ char GBFPlain::ProcessText(char *text, int maxlen, const SWKey *key, const SWMod */ case 'L': // Bug in WEB. Use above entry when fixed case 'N': // new line - *to++ = '\n'; + text += '\n'; continue; case 'M': // new paragraph - *to++ = '\n'; - *to++ = '\n'; + text += "\n\n"; continue; } break; @@ -98,9 +87,9 @@ char GBFPlain::ProcessText(char *text, int maxlen, const SWKey *key, const SWMod token[tokpos++] = *from; token[tokpos+2] = 0; } - else *to++ = *from; + else text += *from; } - *to++ = 0; - *to = 0; return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/gbfredletterwords.cpp b/src/modules/filters/gbfredletterwords.cpp new file mode 100644 index 0000000..df7438d --- /dev/null +++ b/src/modules/filters/gbfredletterwords.cpp @@ -0,0 +1,98 @@ +/****************************************************************************** + * + * GBFRedLetterWords - SWFilter descendant to toggle red coloring of words of + * Christ in a GBF module. + */ + + +#include <stdlib.h> +#include <gbfredletterwords.h> +#include <swmodule.h> +#ifndef __GNUC__ +#else +#include <unixstr.h> +#endif +#include <ctype.h> + +SWORD_NAMESPACE_START + +const char oName[] = "Words of Christ in Red"; +const char oTip[] = "Toggles Red Coloring for Words of Christ On and Off if they are marked"; + +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +GBFRedLetterWords::GBFRedLetterWords() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); +} + + +GBFRedLetterWords::~GBFRedLetterWords() { +} + + +char GBFRedLetterWords::processText(SWBuf &text, const SWKey *key, const SWModule *module) { +/** This function removes the red letter words in Bible like the WEB +* The words are marked by <FR> as start and <Fr> as end tag. +*/ + if (!option) { // if we don't want footnotes + char token[4096]; // cheese. Fix. + int tokpos = 0; + bool intoken = false; + int len; + bool hide = false; + + const char *from; + SWBuf orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) { + if (*from == '<') { + intoken = true; + tokpos = 0; +// memset(token, 0, 4096); + token[0] = 0; + token[1] = 0; + token[2] = 0; + continue; + } + if (*from == '>') { // process tokens + intoken = false; + /*switch (*token) { + case 'F': // Font attribute + switch(token[1]) { + case 'R': // Begin red letter words + hide = true; + break; + case 'r': // end red letter words + hide = false; + break; + } + continue; // skip token + }*/ + + //hide the token if either FR or Fr was detected + hide = (token[0] == 'F' && ( (token[1] == 'R') || (token[1] == 'r') )); + + // if not a red letter word token, keep token in text + if (!hide) { + text += '<'; + for (char *tok = token; *tok; tok++) + text += *tok; + text += '>'; + } + continue; + } + if (intoken) { + if (tokpos < 4090) + token[tokpos++] = *from; + token[tokpos+2] = 0; // +2 cuz we init token with 2 extra '0' because of switch statement + } + else { + text += *from; + } + } + } + return 0; +} + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/gbfrtf.cpp b/src/modules/filters/gbfrtf.cpp index 5f7d064..4a18fbf 100644 --- a/src/modules/filters/gbfrtf.cpp +++ b/src/modules/filters/gbfrtf.cpp @@ -1,35 +1,42 @@ /****************************************************************************** * - * gbfrtf - SWFilter decendant to convert all GBF tags to RTF tags + * gbfrtf - SWFilter descendant to convert all GBF tags to RTF tags */ -#include <stdlib.h> -#include <string.h> #include <gbfrtf.h> #include <ctype.h> +SWORD_NAMESPACE_START + GBFRTF::GBFRTF() { } -char GBFRTF::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char GBFRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) { - unsigned char *to, *from; char token[2048]; + char val[128]; + char *valto; + char *num; int tokpos = 0; bool intoken = false; int len; const char *tok; + SWBuf strongnum; + SWBuf strongtense; + bool hideText = false; + int wordLen = 0; + int wordCount = 0; + int i; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = (unsigned char *)&text[maxlen - len]; - } - else from = (unsigned char *)text; // ------------------------------- - for (to = (unsigned char *)text; *from; from++) { + const char *from; + SWBuf orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) { if (*from == '<') { + wordLen = wordCount; + wordCount = 0; intoken = true; tokpos = 0; token[0] = 0; @@ -40,39 +47,80 @@ char GBFRTF::ProcessText(char *text, int maxlen, const SWKey *key, const SWModul if (*from == '>') { intoken = false; // process desired tokens + // deal with OSIS note tags. Just hide till OSISRTF + if (!strncmp(token, "note ", 5)) { + hideText = true; + } + if (!strncmp(token, "/note", 5)) { + hideText = false; + } + switch (*token) { + case 'w': // OSIS Word (temporary until OSISRTF is done) + strongnum = ""; + strongtense = ""; + valto = val; + num = strstr(token, "lemma=\"x-Strongs:"); + if (num) { + for (num+=17; ((*num) && (*num != '\"')); num++) + *valto++ = *num; + *valto = 0; + if (atoi((!isdigit(*val))?val+1:val) < 5627) { + // normal strongs number + strongnum += "{\\cf3 \\sub <"; + for (tok = (!isdigit(*val))?val+1:val; *tok; tok++) + strongnum += *tok; + strongnum += ">}"; + } + /* forget these for now + else { + // verb morph + sprintf(wordstr, "%03d", word-1); + module->getEntryAttributes()["Word"][wordstr]["Morph"] = val; + } + */ + } + valto = val; + num = strstr(token, "morph=\"x-Robinson:"); + if (num) { + for (num+=18; ((*num) && (*num != '\"')); num++) + *valto++ = *num; + *valto = 0; + // normal robinsons tense + strongtense += "{\\cf4 \\sub ("; + for (tok = val; *tok; tok++) + strongtense += *tok; + strongtense += ")}"; + } + continue; + + case '/': + if (token[1] == 'w') { + if ((wordCount > 0) || (strongnum != "{\\cf3 \\sub <3588>}")) { + //for (i = 0; i < strongnum.length(); i++) + text += strongnum; + //for (i = 0; i < strongtense.length(); i++) + text += strongtense; + } + } + continue; + case 'W': // Strongs switch(token[1]) { case 'G': // Greek case 'H': // Hebrew - *to++ = '{'; - *to++ = '\\'; - *to++ = 'f'; - *to++ = 's'; - *to++ = '1'; - *to++ = '7'; - *to++ = ' '; - *to++ = '<'; + text += "{\\cf3 \\sub <"; for (tok = token + 2; *tok; tok++) - *to++ = *tok; - *to++ = '>'; - *to++ = '}'; + text += *tok; + text += ">}"; continue; case 'T': // Tense - *to++ = '{'; - *to++ = '\\'; - *to++ = 'f'; - *to++ = 's'; - *to++ = '1'; - *to++ = '7'; - *to++ = ' '; - *to++ = '('; + text += "{\\cf4 \\sub ("; bool separate = false; for (tok = token + 2; *tok; tok++) { if (separate) { - *to++ = ';'; - *to++ = ' '; + text += "; "; separate = false; } switch (*tok) { @@ -80,7 +128,7 @@ char GBFRTF::ProcessText(char *text, int maxlen, const SWKey *key, const SWModul case 'H': for (tok++; *tok; tok++) { if (isdigit(*tok)) { - *to++ = *tok; + text += *tok; separate = true; } else { @@ -91,176 +139,134 @@ char GBFRTF::ProcessText(char *text, int maxlen, const SWKey *key, const SWModul break; default: for (; *tok; tok++) { - *to++ = *tok; + text += *tok; } } } - *to++ = ')'; - *to++ = '}'; + text += ")}"; continue; } break; case 'R': switch(token[1]) { case 'X': - *to++ = '#'; + text += "<a href=\"\">"; continue; case 'x': - *to++ = '|'; + text += "</a>"; continue; case 'F': // footnote begin - *to++ = '{'; - *to++ = '\\'; - *to++ = 'i'; - *to++ = '1'; - *to++ = ' '; - *to++ = '\\'; - *to++ = 'f'; - *to++ = 's'; - *to++ = '1'; - *to++ = '7'; - *to++ = ' '; - *to++ = '('; + text += "{\\i1 \\sub ("; continue; case 'f': // footnote end - *to++ = ')'; - *to++ = ' '; - *to++ = '}'; + text += ") }"; continue; } break; case 'F': // font tags switch(token[1]) { case 'I': // italic start - *to++ = '\\'; - *to++ = 'i'; - *to++ = '1'; - *to++ = ' '; + text += "\\i1 "; continue; case 'i': // italic end - *to++ = '\\'; - *to++ = 'i'; - *to++ = '0'; - *to++ = ' '; + text += "\\i0 "; continue; case 'B': // bold start - *to++ = '\\'; - *to++ = 'b'; - *to++ = '1'; - *to++ = ' '; + text += "\\b1 "; continue; case 'b': // bold end - *to++ = '\\'; - *to++ = 'b'; - *to++ = '0'; - *to++ = ' '; + text += "\\b0 "; continue; case 'N': - *to++ = '{'; - if (!strnicmp(token+2, "Symbol", 6)) { - *to++ = '\\'; - *to++ = 'f'; - *to++ = '7'; - *to++ = ' '; - } + text += '{'; + if (!strnicmp(token+2, "Symbol", 6)) + text += "\\f7 "; + if (!strnicmp(token+2, "Courier", 7)) + text += "\\f8 "; continue; case 'n': - *to++ = '}'; + text += '}'; continue; case 'S': - *to++ = '{'; - *to++ = '\\'; - *to++ = 's'; - *to++ = 'u'; - *to++ = 'p'; - *to++ = 'e'; - *to++ = 'r'; - *to++ = ' '; + text += "{\\super "; continue; case 's': - *to++ = '}'; + text += '}'; continue; case 'R': - *to++ = '{'; - *to++ = '\\'; - *to++ = 'c'; - *to++ = 'f'; - *to++ = '6'; - *to++ = ' '; + text += "{\\cf6 "; continue; case 'r': - *to++ = '}'; + text += '}'; + continue; + case 'O': + case 'C': + text += "\\scaps1 "; + continue; + case 'o': + case 'c': + text += "\\scaps0 "; + continue; + case 'V': + text += "{\\sub "; + continue; + case 'v': + text += '}'; + continue; + case 'U': + text += "\\ul1 "; + continue; + case 'u': + text += "\\ul0 "; continue; } break; case 'C': // special character tags switch(token[1]) { case 'A': // ASCII value - *to++ = (char)atoi(&token[2]); + text += (char)atoi(&token[2]); continue; case 'G': - *to++ = '>'; + text += '>'; continue; case 'L': // line break - *to++ = '\\'; - *to++ = 'l'; - *to++ = 'i'; - *to++ = 'n'; - *to++ = 'e'; - *to++ = ' '; + text += "\\line "; continue; case 'M': // new paragraph - *to++ = '\\'; - *to++ = 'p'; - *to++ = 'a'; - *to++ = 'r'; - *to++ = ' '; + text += "\\par "; continue; case 'T': - *to++ = '<'; + text += '<'; } break; case 'T': // title formatting switch(token[1]) { case 'T': // Book title begin - *to++ = '{'; - *to++ = '\\'; - *to++ = 'f'; - *to++ = 's'; - *to++ = '2'; - *to++ = '2'; - *to++ = ' '; - continue; + text += "{\\large "; + continue; case 't': - *to++ = '}'; - continue; + text += '}'; + continue; case 'S': - *to++ = '\\'; - *to++ = 'p'; - *to++ = 'a'; - *to++ = 'r'; - *to++ = ' '; - *to++ = '{'; - *to++ = '\\'; - *to++ = 'i'; - *to++ = '1'; - *to++ = '\\'; - *to++ = 'b'; - *to++ = '1'; - *to++ = ' '; + text += "\\par {\\i1\\b1 "; continue; case 's': - *to++ = '}'; - *to++ = '\\'; - *to++ = 'p'; - *to++ = 'a'; - *to++ = 'r'; - *to++ = ' '; + text += "}\\par "; continue; } break; - + case 'J': // Strongs + switch(token[1]) { + case 'L': + text += "\\ql "; + case 'C': + text += "\\qc "; + case 'R': + text += "\\qr "; + case 'F': + text += "\\qj "; + } } continue; } @@ -269,9 +275,15 @@ char GBFRTF::ProcessText(char *text, int maxlen, const SWKey *key, const SWModul token[tokpos++] = *from; token[tokpos+2] = 0; } - else *to++ = *from; + else { + if (!hideText) { + wordCount++; + text += *from; + } + } } - *to++ = 0; - *to = 0; return 0; } + +SWORD_NAMESPACE_END + diff --git a/src/modules/filters/gbfstrongs.cpp b/src/modules/filters/gbfstrongs.cpp index 40fc958..bd5088a 100644 --- a/src/modules/filters/gbfstrongs.cpp +++ b/src/modules/filters/gbfstrongs.cpp @@ -1,98 +1,116 @@ /****************************************************************************** * - * gbfstrongs - SWFilter decendant to hide or show strongs number + * gbfstrongs - SWFilter descendant to hide or show strongs number * in a GBF module. */ #include <stdlib.h> -#include <string.h> #include <gbfstrongs.h> +#include <swmodule.h> #ifndef __GNUC__ #else #include <unixstr.h> #endif +#include <ctype.h> +SWORD_NAMESPACE_START -const char GBFStrongs::on[] = "On"; -const char GBFStrongs::off[] = "Off"; -const char GBFStrongs::optName[] = "Strong's Numbers"; -const char GBFStrongs::optTip[] = "Toggles Strong's Numbers On and Off if they exist"; +const char oName[] = "Strong's Numbers"; +const char oTip[] = "Toggles Strong's Numbers On and Off if they exist"; +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); -GBFStrongs::GBFStrongs() { - option = false; - options.push_back(on); - options.push_back(off); +GBFStrongs::GBFStrongs() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); } GBFStrongs::~GBFStrongs() { } -void GBFStrongs::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} -const char *GBFStrongs::getOptionValue() -{ - return (option) ? on:off; -} +char GBFStrongs::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + char token[2048]; // cheese. Fix. + int tokpos = 0; + bool intoken = false; + int len; + bool lastspace = false; + int word = 1; + char val[128]; + char wordstr[5]; + char *valto; + char *ch; + unsigned int textStart = 0, textEnd = 0; + bool newText = false; + SWBuf tmp; + const char *from; -char GBFStrongs::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ - if (!option) { // if we don't want strongs - char *to, *from, token[2048]; // cheese. Fix. - int tokpos = 0; - bool intoken = false; - int len; - bool lastspace = false; + SWBuf orig = text; + from = orig.c_str(); - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; + for (text = ""; *from; from++) { + if (*from == '<') { + intoken = true; + tokpos = 0; + token[0] = 0; + token[1] = 0; + token[2] = 0; + textEnd = text.size(); + continue; } - else from = text; // ------------------------------- + if (*from == '>') { // process tokens + intoken = false; - for (to = text; *from; from++) { - if (*from == '<') { - intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; - continue; - } - if (*from == '>') { // process tokens - intoken = false; - if (*token == 'W' && (token[1] == 'G' || token[1] == 'H')) { // Strongs - if ((from[1] == ' ') || (from[1] == ',') || (from[1] == ';') || (from[1] == '.') || (from[1] == '?') || (from[1] == '!') || (from[1] == ')') || (from[1] == '\'') || (from[1] == '\"')) { - if (lastspace) - to--; - } - continue; + if (*token == 'W' && (token[1] == 'G' || token[1] == 'H')) { // Strongs + if (module->isProcessEntryAttributes()) { + valto = val; + for (unsigned int i = 2; ((token[i]) && (i < 150)); i++) + *valto++ = token[i]; + *valto = 0; + if (atoi((!isdigit(*val))?val+1:val) < 5627) { + // normal strongs number + sprintf(wordstr, "%03d", word++); + module->getEntryAttributes()["Word"][wordstr]["Strongs"] = val; + tmp = ""; + tmp.append(text.c_str()+textStart, (int)(textEnd - textStart)); + module->getEntryAttributes()["Word"][wordstr]["Text"] = tmp; + newText = true; + } + else { + // verb morph + sprintf(wordstr, "%03d", word-1); + module->getEntryAttributes()["Word"][wordstr]["Morph"] = val; + } + } + if (!option) { + if ((from[1] == ' ') || (from[1] == ',') || (from[1] == ';') || (from[1] == '.') || (from[1] == '?') || (from[1] == '!') || (from[1] == ')') || (from[1] == '\'') || (from[1] == '\"')) { + if (lastspace) + text--; + } + if (newText) {textStart = text.size(); newText = false; } + continue; } - // if not a strongs token, keep token in text - *to++ = '<'; - for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; - continue; - } - if (intoken) { - if (tokpos < 2045) - token[tokpos++] = *from; - token[tokpos+2] = 0; - } - else { - *to++ = *from; - lastspace = (*from == ' '); } + // if not a strongs token, keep token in text + text += '<'; + text += token; + text += '>'; + if (newText) {textStart = text.size(); newText = false; } + continue; + } + if (intoken) { + if (tokpos < 2045) + token[tokpos++] = *from; + token[tokpos+2] = 0; + } + else { + text += *from; + lastspace = (*from == ' '); } - *to++ = 0; - *to = 0; } return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/gbfthml.cpp b/src/modules/filters/gbfthml.cpp index ca03e71..03b8d8a 100644 --- a/src/modules/filters/gbfthml.cpp +++ b/src/modules/filters/gbfthml.cpp @@ -15,32 +15,27 @@ ***************************************************************************/ #include <stdlib.h> -#include <string.h> #include <gbfthml.h> +SWORD_NAMESPACE_START GBFThML::GBFThML() { } -char GBFThML::ProcessText(char *text, int maxlen) -{ - char *to, *from, token[2048]; +char GBFThML::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + const char *from; + char token[2048]; int tokpos = 0; bool intoken = false; int len; const char *tok; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- + SWBuf orig = text; + from = orig.c_str(); - for (to = text; *from; from++) - { + for (text = ""; *from; from++) { if (*from == '<') { intoken = true; tokpos = 0; @@ -58,75 +53,17 @@ char GBFThML::ProcessText(char *text, int maxlen) switch(token[1]) { case 'G': case 'H': - *to++ = '<'; - *to++ = 's'; - *to++ = 'y'; - *to++ = 'n'; - *to++ = 'c'; - *to++ = ' '; - *to++ = 't'; - *to++ = 'y'; - *to++ = 'p'; - *to++ = 'e'; - *to++ = '='; - *to++ = '"'; - *to++ = 'S'; - *to++ = 't'; - *to++ = 'r'; - *to++ = 'o'; - *to++ = 'n'; - *to++ = 'g'; - *to++ = 's'; - *to++ = '"'; - *to++ = ' '; - *to++ = 'v'; - *to++ = 'a'; - *to++ = 'l'; - *to++ = 'u'; - *to++ = 'e'; - *to++ = '='; - *to++ = '"'; + text += "<sync type=\"Strongs\" value=\""; for (tok = token + 1; *tok; tok++) - *to++ = *tok; - *to++ = '"'; - *to++ = ' '; - *to++ = '/'; - *to++ = '>'; + text += *tok; + text += "\" />"; continue; case 'T': // Tense - *to++ = '<'; - *to++ = 's'; - *to++ = 'y'; - *to++ = 'n'; - *to++ = 'c'; - *to++ = ' '; - *to++ = 't'; - *to++ = 'y'; - *to++ = 'p'; - *to++ = 'e'; - *to++ = '='; - *to++ = '"'; - *to++ = 'M'; - *to++ = 'o'; - *to++ = 'r'; - *to++ = 'p'; - *to++ = 'h'; - *to++ = '"'; - *to++ = ' '; - *to++ = 'v'; - *to++ = 'a'; - *to++ = 'l'; - *to++ = 'u'; - *to++ = 'e'; - *to++ = '='; - *to++ = '"'; + text += "<sync type=\"Morph\" value=\""; for (tok = token + 2; *tok; tok++) - *to++ = *tok; - *to++ = '"'; - *to++ = ' '; - *to++ = '/'; - *to++ = '>'; + text += *tok; + text += "\" />"; continue; } break; @@ -134,234 +71,99 @@ char GBFThML::ProcessText(char *text, int maxlen) switch(token[1]) { case 'X': - *to++ = '<'; - *to++ = 'a'; - *to++ = ' '; - *to++ = 'h'; - *to++ = 'r'; - *to++ = 'e'; - *to++ = 'f'; - *to++ = '='; - *to++ = '\"'; - for (tok = token + 3; *tok; tok++) { + text += "<a href=\""; + for (tok = token + 3; *tok; tok++) { if(*tok != '<' && *tok+1 != 'R' && *tok+2 != 'x') { - *to++ = *tok; + text += *tok; } else { break; } - } - *to++ = '\"'; - *to++ = '>'; - continue; + } + text += "\">"; + continue; case 'x': - *to++ = '<'; - *to++ = '/'; - *to++ = 'a'; - *to++ = '>'; - continue; + text += "</a>"; + continue; case 'F': // footnote begin - *to++ = '<'; - *to++ = 'n'; - *to++ = 'o'; - *to++ = 't'; - *to++ = 'e'; - *to++ = ' '; - *to++ = 'p'; - *to++ = 'l'; - *to++ = 'a'; - *to++ = 'c'; - *to++ = 'e'; - *to++ = '='; - *to++ = '"'; - *to++ = 'f'; - *to++ = 'o'; - *to++ = 'o'; - *to++ = 't'; - *to++ = '"'; - *to++ = '>'; - continue; + text += "<note>"; + continue; case 'f': // footnote end - *to++ = '<'; - *to++ = '/'; - *to++ = 'n'; - *to++ = 'o'; - *to++ = 't'; - *to++ = 'e'; - *to++ = '>'; - continue; + text += "</note>"; + continue; } break; case 'F': // font tags switch(token[1]) { case 'N': - *to++ = '<'; - *to++ = 'f'; - *to++ = 'o'; - *to++ = 'n'; - *to++ = 't'; - *to++ = ' '; - *to++ = 'f'; - *to++ = 'a'; - *to++ = 'c'; - *to++ = 'e'; - *to++ = '='; - *to++ = '"'; - for (tok = token + 2; *tok; tok++) - *to++ = *tok; - *to++ = '"'; - *to++ = '>'; - continue; + text += "<font face=\""; + for (tok = token + 2; *tok; tok++) + text += *tok; + text += "\">"; + continue; case 'n': - *to++ = '<'; - *to++ = '/'; - *to++ = 'f'; - *to++ = 'o'; - *to++ = 'n'; - *to++ = 't'; - *to++ = '>'; - continue; + text += "</font>"; + continue; case 'I': // italic start - *to++ = '<'; - *to++ = 'i'; - *to++ = '>'; - continue; + text += "<i>"; + continue; case 'i': // italic end - *to++ = '<'; - *to++ = '/'; - *to++ = 'i'; - *to++ = '>'; - continue; + text += "</i>"; + continue; case 'B': // bold start - *to++ = '<'; - *to++ = 'b'; - *to++ = '>'; - continue; + text += "<b>"; + continue; case 'b': // bold end - *to++ = '<'; - *to++ = '/'; - *to++ = 'b'; - *to++ = '>'; - continue; + text += "</b>"; + continue; case 'R': // words of Jesus begin - *to++ = '<'; - *to++ = 'f'; - *to++ = 'o'; - *to++ = 'n'; - *to++ = 't'; - *to++ = ' '; - *to++ = 'c'; - *to++ = 'o'; - *to++ = 'l'; - *to++ = 'o'; - *to++ = 'r'; - *to++ = '='; - *to++ = '\"'; - *to++ = '#'; - *to++ = 'f'; - *to++ = 'f'; - *to++ = '0'; - *to++ = '0'; - *to++ = '0'; - *to++ = '0'; - *to++ = '\"'; - *to++ = '>'; - continue; + text += "<font color=\"#ff0000\">"; + continue; case 'r': // words of Jesus end - *to++ = '<'; - *to++ = '/'; - *to++ = 'f'; - *to++ = 'o'; - *to++ = 'n'; - *to++ = 't'; - *to++ = '>'; - continue; + text += "</font>"; + continue; case 'U': // Underline start - *to++ = '<'; - *to++ = 'u'; - *to++ = '>'; - continue; + text += "<u>"; + continue; case 'u': // Underline end - *to++ = '<'; - *to++ = '/'; - *to++ = 'u'; - *to++ = '>'; - continue; + text += "</u>"; + continue; case 'O': // Old Testament quote begin - *to++ = '<'; - *to++ = 'c'; - *to++ = 'i'; - *to++ = 't'; - *to++ = 'e'; - *to++ = '>'; - continue; + text += "<cite>"; + continue; case 'o': // Old Testament quote end - *to++ = '<'; - *to++ = '/'; - *to++ = 'c'; - *to++ = 'i'; - *to++ = 't'; - *to++ = 'e'; - *to++ = '>'; - continue; + text += "</cite>"; + continue; case 'S': // Superscript begin - *to++ = '<'; - *to++ = 's'; - *to++ = 'u'; - *to++ = 'p'; - *to++ = '>'; - continue; + text += "<sup>"; + continue; case 's': // Superscript end - *to++ = '<'; - *to++ = '/'; - *to++ = 's'; - *to++ = 'u'; - *to++ = 'p'; - *to++ = '>'; - continue; + text += "</sup>"; + continue; case 'V': // Subscript begin - *to++ = '<'; - *to++ = 's'; - *to++ = 'u'; - *to++ = 'b'; - *to++ = '>'; - continue; + text += "<sub>"; + continue; case 'v': // Subscript end - *to++ = '<'; - *to++ = '/'; - *to++ = 's'; - *to++ = 'u'; - *to++ = 'b'; - *to++ = '>'; - continue; + text += "</sub>"; + continue; } break; case 'C': // special character tags switch(token[1]) { case 'A': // ASCII value - *to++ = (char)atoi(&token[2]); + text += (char)atoi(&token[2]); continue; case 'G': //*to++ = ' '; continue; case 'L': // line break - *to++ = '<'; - *to++ = 'b'; - *to++ = 'r'; - *to++ = ' '; - *to++ = '/'; - *to++ = '>'; - *to++ = ' '; + text += "<br /> "; continue; case 'M': // new paragraph - *to++ = '<'; - *to++ = 'p'; - *to++ = ' '; - *to++ = '/'; - *to++ = '>'; + text += "<p />"; continue; case 'T': //*to++ = ' '; @@ -372,76 +174,28 @@ char GBFThML::ProcessText(char *text, int maxlen) switch(token[1]) { case 'T': // Book title begin - *to++ = '<'; - *to++ = 'b'; - *to++ = 'i'; - *to++ = 'g'; - *to++ = '>'; - continue; + text += "<big>"; + continue; case 't': - *to++ = '<'; - *to++ = '/'; - *to++ = 'b'; - *to++ = 'i'; - *to++ = 'g'; - *to++ = '>'; - continue; + text += "</big>"; + continue; case 'S': - *to++ = '<'; - *to++ = 'd'; - *to++ = 'i'; - *to++ = 'v'; - *to++ = ' '; - *to++ = 'c'; - *to++ = 'l'; - *to++ = 'a'; - *to++ = 's'; - *to++ = 's'; - *to++ = '='; - *to++ = '\"'; - *to++ = 's'; - *to++ = 'e'; - *to++ = 'c'; - *to++ = 'h'; - *to++ = 'e'; - *to++ = 'a'; - *to++ = 'd'; - *to++ = '\"'; - *to++ = '>'; - continue; + text += "<div class=\"sechead\">"; + continue; case 's': - *to++ = '<'; - *to++ = '/'; - *to++ = 'd'; - *to++ = 'i'; - *to++ = 'v'; - *to++ = '>'; - continue; + text += "</div>"; + continue; } break; case 'P': // special formatting - switch(token[1]) - { + switch(token[1]) { case 'P': // Poetry begin - *to++ = '<'; - *to++ = 'v'; - *to++ = 'e'; - *to++ = 'r'; - *to++ = 's'; - *to++ = 'e'; - *to++ = '>'; - continue; + text += "<verse>"; + continue; case 'p': - *to++ = '<'; - *to++ = '/'; - *to++ = 'v'; - *to++ = 'e'; - *to++ = 'r'; - *to++ = 's'; - *to++ = 'e'; - *to++ = '>'; - continue; + text += "</verse>"; + continue; } break; } @@ -452,12 +206,11 @@ char GBFThML::ProcessText(char *text, int maxlen) token[tokpos++] = *from; token[tokpos+2] = 0; } - else *to++ = *from; + else text += *from; } - *to++ = 0; - *to = 0; return 0; } +SWORD_NAMESPACE_END diff --git a/src/modules/filters/gbfwebif.cpp b/src/modules/filters/gbfwebif.cpp new file mode 100644 index 0000000..131f359 --- /dev/null +++ b/src/modules/filters/gbfwebif.cpp @@ -0,0 +1,161 @@ +/*************************************************************************** + GBFWEBIF.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. * + * * + ***************************************************************************/ + +#include <gbfwebif.h> +#include <ctype.h> +#include <utilweb.h> + +SWORD_NAMESPACE_START + +GBFWEBIF::GBFWEBIF() : baseURL(""), passageStudyURL(baseURL + "passagestudy.jsp") { +//all is done in GBFHTMLHREF since it inherits form this class + addTokenSubstitute("FR", "<span class=\"wordsOfJesus\">"); // words of Jesus begin + addTokenSubstitute("Fr", "</span>"); +} + +bool GBFWEBIF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { + const char *tok; + char val[128]; + char *valto; + const char *num; + SWBuf url; + + if (!substituteToken(buf, token)) { + if (!strncmp(token, "w", 1)) { + // OSIS Word (temporary until OSISRTF is done) + valto = val; + num = strstr(token, "lemma=\"x-Strongs:"); + + if (num) { + for (num+=17; ((*num) && (*num != '\"')); num++) + *valto++ = *num; + *valto = 0; + + if (atoi((!isdigit(*val))?val+1:val) < 5627) { + buf += " <small><em><"; + url = ""; + for (tok = val; *tok; tok++) { + url += *tok; + } + if ((url.length() > 1) && strchr("GH", url[0])) { + if (isdigit(url[1])) + url = url.c_str()+1; + } + buf.appendFormatted("<a href=\"%s?showStrong=%s#cv\">", passageStudyURL.c_str(), encodeURL(url).c_str()); + + for (tok = (!isdigit(*val))?val+1:val; *tok; tok++) { + buf += *tok; + } + buf += "</a>></em></small> "; + } + } + valto = val; + num = strstr(token, "morph=\"x-Robinson:"); + if (num) { + for (num+=18; ((*num) && (*num != '\"')); num++) + *valto++ = *num; + *valto = 0; + buf += " <small><em>("; + url = ""; + for (tok = val; *tok; tok++) { + // normal robinsons tense + buf += *tok; + } + buf.appendFormatted("<a href=\"%s?showMorph=%s#cv\">", passageStudyURL.c_str(), encodeURL(url).c_str()); + + for (tok = val; *tok; tok++) { + buf += *tok; + } + buf += "</a>)</em></small> "; + } + } + + else if (!strncmp(token, "WG", 2) || !strncmp(token, "WH", 2)) { // strong's numbers + buf += " <small><em><"; + url = ""; + + for (tok = token+1; *tok; tok++) { + url += *tok; + } + if ((url.length() > 1) && strchr("GH", url[0])) { + if (isdigit(url[1])) + url = url.c_str()+1; + } + buf.appendFormatted("<a href=\"%s?showStrong=%s#cv\">", passageStudyURL.c_str(), encodeURL(url).c_str()); + + for (tok = token + 2; *tok; tok++) { + buf += *tok; + } + buf += "</a>></em></small>"; + } + + else if (!strncmp(token, "WTG", 3) || !strncmp(token, "WTH", 3)) { // strong's numbers tense + buf += " <small><em>("; + url = ""; + for (tok = token + 2; *tok; tok++) { + if(*tok != '\"') + url += *tok; + } + if ((url.length() > 1) && strchr("GH", url[0])) { + if (isdigit(url[1])) + url = url.c_str()+1; + } + buf.appendFormatted("<a href=\"%s?showStrong=%s#cv\">", passageStudyURL.c_str(), encodeURL(url).c_str()); + + for (tok = token + 3; *tok; tok++) + if(*tok != '\"') + buf += *tok; + buf += "</a>)</em></small>"; + } + + else if (!strncmp(token, "WT", 2) && strncmp(token, "WTH", 3) && strncmp(token, "WTG", 3)) { // morph tags + buf += " <small><em>("; + for (tok = token + 2; *tok; tok++) { + if(*tok != '\"') + buf += *tok; + } + buf.appendFormatted("<a href=\"%s?showMorph=%s#cv\">", passageStudyURL.c_str(), encodeURL(url).c_str()); + + for (tok = token + 2; *tok; tok++) { + if(*tok != '\"') + buf += *tok; + } + buf += "</a>)</em></small>"; + } + + else if (!strncmp(token, "RX", 2)) { + buf += "<a href=\""; + for (tok = token + 3; *tok; tok++) { + if(*tok != '<' && *tok+1 != 'R' && *tok+2 != 'x') { + buf += *tok; + } + else { + break; + } + } + + buf.appendFormatted("a href=\"%s?key=%s#cv\">", passageStudyURL.c_str(), encodeURL(url).c_str()); + } + + else { + return GBFHTMLHREF::handleToken(buf, token, userData); + } + } + return true; +} + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/greeklexattribs.cpp b/src/modules/filters/greeklexattribs.cpp index fb166df..073ba39 100644 --- a/src/modules/filters/greeklexattribs.cpp +++ b/src/modules/filters/greeklexattribs.cpp @@ -1,46 +1,87 @@ /****************************************************************************** * - * greeklexattribs - SWFilter decendant to set entry attributes for greek - * lexicons + * greeklexattribs - SWFilter descendant to set entry attributes for greek + * lexicons */ #include <stdlib.h> -#include <string.h> +#include <ctype.h> +#include <string> #include <greeklexattribs.h> #include <swmodule.h> +using std::string; + +SWORD_NAMESPACE_START GreekLexAttribs::GreekLexAttribs() { } -char GreekLexAttribs::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) { +char GreekLexAttribs::processText(SWBuf &text, const SWKey *key, const SWModule *module) { if (module->isProcessEntryAttributes()) { - char *from; + const char *from; bool inAV = false; string phrase; string freq; - char *currentPhrase = 0; + char val[128], *valto; + char wordstr[7]; + const char *currentPhrase = 0, *ch = 0; + const char *currentPhraseEnd = 0; + int number = 0; - for (from = text; *from; from++) { + for (from = text.c_str(); *from; from++) { if (inAV) { if (currentPhrase == 0) { if (isalpha(*from)) currentPhrase = from; } else { - if ((!isalpha(*from)) && (*from != ' ')) { + if ((!isalpha(*from)) && (*from != ' ') && (*from != '+') && (*from !='(') && (*from != ')') && (*from != '\'')) { + if (*from == '<') { + if (!currentPhraseEnd) + currentPhraseEnd = from - 1; + for (; *from && *from != '>'; from++) { + if (!strncmp(from, "value=\"", 7)) { + valto = val; + from += 7; + for (unsigned int i = 0; from[i] != '\"' && i < 127; i++) + *valto++ = from[i]; + *valto = 0; + sprintf(wordstr, "%03d", number+1); + module->getEntryAttributes()["AVPhrase"][wordstr]["CompoundedWith"] = val; + from += strlen(val); + } + } + continue; + } + phrase = ""; - phrase.append(currentPhrase, (int)(from - currentPhrase)-1); + phrase.append(currentPhrase, (int)(((currentPhraseEnd>currentPhrase)?currentPhraseEnd:from) - currentPhrase)-1); currentPhrase = from; while (*from && isdigit(*from)) from++; freq = ""; freq.append(currentPhrase, (int)(from - currentPhrase)); - module->getEntryAttributes()["AVPhrase"][phrase]["Frequency"] = freq; - currentPhrase = 0; + if ((freq.length() > 0) && (phrase.length() > 0)) { + sprintf(wordstr, "%03d", ++number); + if ((strchr(phrase.c_str(), '(') > phrase.c_str()) && (strchr(phrase.c_str(), ')') > phrase.c_str() + 1)) { + string tmp = phrase.substr(0, phrase.find_first_of("(")); + phrase.erase(phrase.find_first_of("("), 1); + phrase.erase(phrase.find_first_of(")"), 1); + phrase.erase(0,phrase.find_first_not_of("\r\n\v\t ")); phrase.erase(phrase.find_last_not_of("\r\n\v\t ")+1); + module->getEntryAttributes()["AVPhrase"][wordstr]["Alt"] = phrase.c_str(); + phrase = tmp; + } + phrase.erase(0,phrase.find_first_not_of("\r\n\v\t ")); phrase.erase(phrase.find_last_not_of("\r\n\v\t ")+1); + freq.erase(0,freq.find_first_not_of("\r\n\v\t ")); freq.erase(freq.find_last_not_of("\r\n\v\t ")+1); + module->getEntryAttributes()["AVPhrase"][wordstr]["Phrase"] = phrase.c_str(); + module->getEntryAttributes()["AVPhrase"][wordstr]["Frequency"] = freq.c_str(); + currentPhrase = 0; + currentPhraseEnd = 0; + } } } if (*from == ';') inAV = false; @@ -56,3 +97,4 @@ char GreekLexAttribs::ProcessText(char *text, int maxlen, const SWKey *key, cons } +SWORD_NAMESPACE_END diff --git a/src/modules/filters/latin1utf16.cpp b/src/modules/filters/latin1utf16.cpp index 75ee998..8067381 100644 --- a/src/modules/filters/latin1utf16.cpp +++ b/src/modules/filters/latin1utf16.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * Latin1UTF16 - SWFilter decendant to convert a Latin-1 character to UTF-16 + * Latin1UTF16 - SWFilter descendant to convert a Latin-1 character to UTF-16 * */ @@ -9,112 +9,111 @@ #include <stdio.h> #include <latin1utf16.h> +SWORD_NAMESPACE_START + Latin1UTF16::Latin1UTF16() { } -char Latin1UTF16::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ - unsigned char *from; - unsigned short *to; +char Latin1UTF16::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + const unsigned char *from; int len; + if ((unsigned long)key < 2) // hack, we're en(1)/de(0)ciphering + return -1; + - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = (unsigned char*)&text[maxlen - len]; - } - else - from = (unsigned char*)text; - // ------------------------------- - - for (to = (unsigned short*)text; *from; from++) { - switch (*from) { + SWBuf orig = text; + from = (const unsigned char *)orig.c_str(); + + for (text = ""; *from; from++) { + text.setSize(text.size()+2); + switch (*from) { case 0x80: // '€' - *to++ = 0x20AC; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x20AC; break; case 0x82: // '‚' - *to++ = 0x201A; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x201A; break; case 0x83: // 'ƒ' - *to++ = 0x0192; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x0192; break; case 0x84: // '„' - *to++ = 0x201E; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x201E; break; case 0x85: // '…' - *to++ = 0x2026; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x2026; break; case 0x86: // '†' - *to++ = 0x2020; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x2020; break; case 0x87: // '‡' - *to++ = 0x2021; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x2021; break; case 0x88: // 'ˆ' - *to++ = 0x02C6; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x02C6; break; case 0x89: // '‰' - *to++ = 0x2030; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x2030; break; case 0x8A: // 'Š' - *to++ = 0x0160; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x0160; break; case 0x8B: // '‹' - *to++ = 0x2039; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x2039; break; case 0x8C: // 'Œ' - *to++ = 0x0152; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x0152; break; case 0x8E: // 'Ž' - *to++ = 0x017D; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x017D; break; case 0x91: // '‘' - *to++ = 0x2018; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x2018; break; case 0x92: // '’' - *to++ = 0x2019; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x2019; break; case 0x93: // '“' - *to++ = 0x201C; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x201C; break; case 0x94: // '”' - *to++ = 0x201D; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x201D; break; case 0x95: // '•' - *to++ = 0x2022; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x2022; break; case 0x96: // '–' - *to++ = 0x2013; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x2013; break; case 0x97: // '—' - *to++ = 0x2014; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x2014; break; case 0x98: // '˜' - *to++ = 0x02DC; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x02DC; break; case 0x99: // '™' - *to++ = 0x2122; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x2122; break; case 0x9A: // 'š' - *to++ = 0x0161; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x0161; break; case 0x9B: // '›' - *to++ = 0x203A; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x203A; break; case 0x9C: // 'œ' - *to++ = 0x0153; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x0153; break; case 0x9E: // 'ž' - *to++ = 0x017E; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x017E; break; case 0x9F: // 'Ÿ' - *to++ = 0x0178; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) 0x0178; break; - default: - *to++ = (unsigned short)*from; - } + default: + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short) *from; + } } - *to = 0; return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/latin1utf8.cpp b/src/modules/filters/latin1utf8.cpp index 91af8dc..6d7d87b 100644 --- a/src/modules/filters/latin1utf8.cpp +++ b/src/modules/filters/latin1utf8.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * Latin1UTF8 - SWFilter decendant to convert a Latin-1 character to UTF-8 + * Latin1UTF8 - SWFilter descendant to convert a Latin-1 character to UTF-8 * */ @@ -10,170 +10,164 @@ #include <latin1utf8.h> #include <swmodule.h> +SWORD_NAMESPACE_START + Latin1UTF8::Latin1UTF8() { } -char Latin1UTF8::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char Latin1UTF8::processText(SWBuf &text, const SWKey *key, const SWModule *module) { - unsigned char *to, *from; - int len; - - len = strlen(text) + 1; - if (len == maxlen + 1) - maxlen = (maxlen + 1) * FILTERPAD; - // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = (unsigned char*)&text[maxlen - len]; - } - else - from = (unsigned char*)text; // ------------------------------- + const unsigned char *from; + if ((unsigned long)key < 2) // hack, we're en(1)/de(0)ciphering + return -1; + SWBuf orig = text; + from = (const unsigned char *)orig.c_str(); - for (to = (unsigned char*)text; *from; from++) { + for (text = ""; *from; from++) { if (*from < 0x80) { - *to++ = *from; + text += *from; } else if (*from < 0xc0) { switch(*from) { case 0x80: // '€' - *to++ = 0xe2; // 'â' - *to++ = 0x82; // '‚' - *to++ = 0xac; // '¬' + text += 0xe2; // 'â' + text += 0x82; // '‚' + text += 0xac; // '¬' break; case 0x82: // '‚' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0x9a; // 'š' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0x9a; // 'š' break; case 0x83: // 'ƒ' - *to++ = 0xc6; // 'Æ' - *to++ = 0x92; // '’' + text += 0xc6; // 'Æ' + text += 0x92; // '’' break; case 0x84: // '„' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0x9e; // 'ž' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0x9e; // 'ž' break; case 0x85: // '…' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0xa6; // '¦' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0xa6; // '¦' break; case 0x86: // '†' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0xa0; // ' ' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0xa0; // ' ' break; case 0x87: // '‡' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0xa1; // '¡' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0xa1; // '¡' break; case 0x88: // 'ˆ' - *to++ = 0xcb; // 'Ë' - *to++ = 0x86; // '†' + text += 0xcb; // 'Ë' + text += 0x86; // '†' break; case 0x89: // '‰' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0xb0; // '°' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0xb0; // '°' break; case 0x8A: // 'Š' - *to++ = 0xc5; // 'Å' - *to++ = 0xa0; // ' ' + text += 0xc5; // 'Å' + text += 0xa0; // ' ' break; case 0x8B: // '‹' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0xb9; // '¹' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0xb9; // '¹' break; case 0x8C: // 'Œ' - *to++ = 0xc5; // 'Å' - *to++ = 0x92; // '’' + text += 0xc5; // 'Å' + text += 0x92; // '’' break; case 0x8E: // 'Ž' - *to++ = 0xc5; // 'Å' - *to++ = 0xbd; // '½' + text += 0xc5; // 'Å' + text += 0xbd; // '½' break; case 0x91: // '‘' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0x98; // '˜' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0x98; // '˜' break; case 0x92: // '’' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0x99; // '™' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0x99; // '™' break; case 0x93: // '“' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0x9c; // 'œ' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0x9c; // 'œ' break; case 0x94: // '”' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0x9d; // '' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0x9d; // '' break; case 0x95: // '•' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0xa2; // '¢' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0xa2; // '¢' break; case 0x96: // '–' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0x93; // '“' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0x93; // '“' break; case 0x97: // '—' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0x94; // '”' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0x94; // '”' break; case 0x98: // '˜' - *to++ = 0xcb; // 'Ë' - *to++ = 0x9c; // 'œ' + text += 0xcb; // 'Ë' + text += 0x9c; // 'œ' break; case 0x99: // '™' - *to++ = 0xe2; // 'â' - *to++ = 0x84; // '„' - *to++ = 0xa2; // '¢' + text += 0xe2; // 'â' + text += 0x84; // '„' + text += 0xa2; // '¢' break; case 0x9A: // 'š' - *to++ = 0xc5; // 'Å' - *to++ = 0xa1; // '¡' + text += 0xc5; // 'Å' + text += 0xa1; // '¡' break; case 0x9B: // '›' - *to++ = 0xe2; // 'â' - *to++ = 0x80; // '€' - *to++ = 0xba; // 'º' + text += 0xe2; // 'â' + text += 0x80; // '€' + text += 0xba; // 'º' break; case 0x9C: // 'œ' - *to++ = 0xc5; // 'Å' - *to++ = 0x93; // '“' + text += 0xc5; // 'Å' + text += 0x93; // '“' break; case 0x9E: // 'ž' - *to++ = 0xc5; // 'Å' - *to++ = 0xbe; // '¾' + text += 0xc5; // 'Å' + text += 0xbe; // '¾' break; case 0x9F: // 'Ÿ' - *to++ = 0xc5; // 'Å' - *to++ = 0xb8; // '¸' + text += 0xc5; // 'Å' + text += 0xb8; // '¸' break; default: - *to++ = 0xC2; - *to++ = *from; + text += 0xC2; + text += *from; } } else { - *to++ = 0xC3; - *to++ = (*from - 0x40); + text += 0xC3; + text += (*from - 0x40); } } - *to++ = 0; - *to = 0; return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/osisfootnotes.cpp b/src/modules/filters/osisfootnotes.cpp new file mode 100644 index 0000000..59a7cae --- /dev/null +++ b/src/modules/filters/osisfootnotes.cpp @@ -0,0 +1,138 @@ +/****************************************************************************** + * + * osisfootnotes - SWFilter descendant to hide or show footnotes + * in an OSIS module. + */ + + +#include <stdlib.h> +#include <osisfootnotes.h> +#include <swmodule.h> +#include <swbuf.h> +#include <versekey.h> +#include <utilxml.h> +#ifndef __GNUC__ +#else +#include <unixstr.h> +#endif + +SWORD_NAMESPACE_START + +const char oName[] = "Footnotes"; +const char oTip[] = "Toggles Footnotes On and Off if they exist"; + +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +OSISFootnotes::OSISFootnotes() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); +} + + +OSISFootnotes::~OSISFootnotes() { +} + + +char OSISFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + SWBuf token; + bool intoken = false; + bool hide = false; + SWBuf tagText; + XMLTag startTag; + SWBuf refs = ""; + int footnoteNum = 1; + char buf[254]; + VerseKey parser = key->getText(); + + SWBuf orig = text; + const char *from = orig.c_str(); + + for (text = ""; *from; from++) { + + // remove all newlines temporarily to fix kjv2003 module + if ((*from == 10) || (*from == 13)) { + if ((text.length()>1) && (text[text.length()-2] != ' ') && (*(from+1) != ' ')) + text += ' '; + continue; + } + + + if (*from == '<') { + intoken = true; + token = ""; + continue; + } + if (*from == '>') { // process tokens + intoken = false; + + XMLTag tag(token); + if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag()) { + if (SWBuf("strongsMarkup") == tag.getAttribute("type")) { // handle bug in KJV2003 module where some note open tags were <note ... /> + tag.setEmpty(false); + } + if (!tag.isEmpty()) { +// if ((!tag.isEmpty()) || (SWBuf("strongsMarkup") == tag.getAttribute("type"))) { + refs = ""; + startTag = tag; + hide = true; + tagText = ""; + continue; + } + } + if (hide && tag.isEndTag()) { + if (module->isProcessEntryAttributes()) { + sprintf(buf, "%i", footnoteNum++); + StringList attributes = startTag.getAttributeNames(); + for (StringList::iterator it = attributes.begin(); it != attributes.end(); it++) { + module->getEntryAttributes()["Footnote"][buf][it->c_str()] = startTag.getAttribute(it->c_str()); + } + module->getEntryAttributes()["Footnote"][buf]["body"] = tagText; + 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(); + module->getEntryAttributes()["Footnote"][buf]["refList"] = refs.c_str(); + } + } + hide = false; + if ((option) || ((startTag.getAttribute("type") && (!strcmp(startTag.getAttribute("type"), "crossReference"))))) { // we want the tag in the text; crossReferences are handled by another filter + text += startTag; + text.append(tagText); + } + else continue; + } + } + + // if not a heading token, keep token in text + if ((!strcmp(tag.getName(), "reference")) && (!tag.isEndTag())) { + SWBuf osisRef = tag.getAttribute("osisRef"); + if (refs.length()) + refs += "; "; + refs += osisRef; + } + if (!hide) { + text += '<'; + text.append(token); + text += '>'; + } + else { + tagText += '<'; + tagText.append(token); + tagText += '>'; + } + continue; + } + if (intoken) { //copy token + token += *from; + } + else if (!hide) { //copy text which is not inside a token + text += *from; + } + else tagText += *from; + } + return 0; +} + +SWORD_NAMESPACE_END + diff --git a/src/modules/filters/osisheadings.cpp b/src/modules/filters/osisheadings.cpp new file mode 100644 index 0000000..8ec9ce3 --- /dev/null +++ b/src/modules/filters/osisheadings.cpp @@ -0,0 +1,118 @@ +/****************************************************************************** + * + *osisheadings - SWFilter descendant to hide or show headings + * in an OSIS module. + */ + + +#include <stdlib.h> +#include <osisheadings.h> +#include <swmodule.h> +#include <utilxml.h> +#ifndef __GNUC__ +#else +#include <unixstr.h> +#endif + +SWORD_NAMESPACE_START + +const char oName[] = "Headings"; +const char oTip[] = "Toggles Headings On and Off if they exist"; + +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +OSISHeadings::OSISHeadings() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); +} + + +OSISHeadings::~OSISHeadings() { +} + + +char OSISHeadings::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + SWBuf token; + bool intoken = false; + bool hide = false; + bool preverse = false; + SWBuf header; + int headerNum = 0; + int pvHeaderNum = 0; + char buf[254]; + + SWBuf orig = text; + const char *from = orig.c_str(); + + for (text = ""; *from; from++) { + if (*from == '<') { + intoken = true; + token = ""; + continue; + } + if (*from == '>') { // process tokens + intoken = false; + + XMLTag tag(token); + if (!stricmp(tag.getName(), "title")) { + if ((tag.getAttribute("subtype")) && (!stricmp(tag.getAttribute("subtype"), "x-preverse"))) { + hide = true; + preverse = true; + header = ""; + continue; + } + if (!tag.isEndTag()) { + hide = true; + header = ""; + if (option) { // we want the tag in the text + text += '<'; + text.append(token); + text += '>'; + } + continue; + } + if (hide && tag.isEndTag()) { + + if (module->isProcessEntryAttributes() && option) { + if (preverse) { + sprintf(buf, "%i", pvHeaderNum++); + module->getEntryAttributes()["Heading"]["Preverse"][buf] = header; + } + else { + sprintf(buf, "%i", headerNum++); + module->getEntryAttributes()["Heading"]["Interverse"][buf] = header; + if (option) { // we want the tag in the text + text.append(header); + } + } + } + hide = false; + if ((!option) || (preverse)) { // we don't want the tag in the text anymore + preverse = false; + continue; + } + preverse = false; + } + } + + // if not a heading token, keep token in text + if (!hide) { + text += '<'; + text.append(token); + text += '>'; + } + continue; + } + if (intoken) { //copy token + token += *from; + } + else if (!hide) { //copy text which is not inside a token + text += *from; + } + else header += *from; + } + return 0; +} + +SWORD_NAMESPACE_END + diff --git a/src/modules/filters/osishtmlhref.cpp b/src/modules/filters/osishtmlhref.cpp new file mode 100644 index 0000000..26e6dff --- /dev/null +++ b/src/modules/filters/osishtmlhref.cpp @@ -0,0 +1,339 @@ +/*************************************************************************** + 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; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <stdlib.h> +#include <osishtmlhref.h> +#include <utilxml.h> +#include <versekey.h> +#include <swmodule.h> + +SWORD_NAMESPACE_START + + +OSISHTMLHREF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) { + osisQToTick = ((!module->getConfigEntry("OSISqToTick")) || (strcmp(module->getConfigEntry("OSISqToTick"), "false"))); +} + + +OSISHTMLHREF::OSISHTMLHREF() { + setTokenStart("<"); + setTokenEnd(">"); + + setEscapeStart("&"); + setEscapeEnd(";"); + + setEscapeStringCaseSensitive(true); + + addEscapeStringSubstitute("amp", "&"); + addEscapeStringSubstitute("apos", "'"); + addEscapeStringSubstitute("lt", "<"); + addEscapeStringSubstitute("gt", ">"); + addEscapeStringSubstitute("quot", "\""); + addTokenSubstitute("lg", "<br />"); + addTokenSubstitute("/lg", "<br />"); + + setTokenCaseSensitive(true); +} + + +bool OSISHTMLHREF::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; + XMLTag tag(token); + + // <w> tag + if (!strcmp(tag.getName(), "w")) { + + // start <w> tag + if ((!tag.isEmpty()) && (!tag.isEndTag())) { + u->w = token; + } + + // end or empty <w> tag + else { + bool endTag = tag.isEndTag(); + SWBuf lastText; + bool show = true; // to handle unplaced article in kjv2003-- temporary till combined + + if (endTag) { + tag = u->w.c_str(); + lastText = u->lastTextNode.c_str(); + } + else lastText = "stuff"; + + const char *attrib; + const char *val; + if (attrib = tag.getAttribute("xlit")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" %s", val); + } + if (attrib = tag.getAttribute("gloss")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" %s", val); + } + if (attrib = tag.getAttribute("lemma")) { + int count = tag.getAttributePartCount("lemma"); + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + do { + attrib = tag.getAttribute("lemma", i); + if (i < 0) i = 0; // to handle our -1 condition + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + const char *val2 = val; + if ((strchr("GH", *val)) && (isdigit(val[1]))) + val2++; + if ((!strcmp(val2, "3588")) && (lastText.length() < 1)) + show = false; + else buf.appendFormatted(" <small><em><<a href=\"type=Strongs value=%s\">%s</a>></em></small> ", val, val2); + } while (++i < count); + } + if ((attrib = tag.getAttribute("morph")) && (show)) { + SWBuf savelemma = tag.getAttribute("savlm"); + if ((strstr(savelemma.c_str(), "3588")) && (lastText.length() < 1)) + show = false; + if (show) { + int count = tag.getAttributePartCount("morph"); + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + do { + attrib = tag.getAttribute("morph", i); + if (i < 0) i = 0; // to handle our -1 condition + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + const char *val2 = val; + if ((*val == 'T') && (strchr("GH", val[1])) && (isdigit(val[2]))) + val2+=2; + buf.appendFormatted(" <small><em>(<a href=\"type=morph class=%s value=%s\">%s</a>)</em></small> ", tag.getAttribute("morph"), val, val2); + } while (++i < count); + } + } + if (attrib = tag.getAttribute("POS")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" %s", val); + } + + /*if (endTag) + buf += "}";*/ + } + } + + // <note> tag + else if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + SWBuf type = tag.getAttribute("type"); + + if (type != "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 + SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) { } + if (vkey) { + char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n'); + buf.appendFormatted("<a href=\"noteID=%s.%c.%s\"><small><sup>*%c</sup></small></a> ", vkey->getText(), ch, footnoteNumber.c_str(), ch); + } + } + u->suspendTextPassThru = true; + } + } + if (tag.isEndTag()) { + u->suspendTextPassThru = false; + } + } + + // <p> paragraph tag + else if (!strcmp(tag.getName(), "p")) { + if ((!tag.isEndTag()) && (!tag.isEmpty())) { // non-empty start tag + buf += "<!P><br />"; + } + else if (tag.isEndTag()) { // end tag + buf += "<!/P><br />"; + userData->supressAdjacentWhitespace = true; + } + else { // empty paragraph break marker + buf += "<!P><br />"; + userData->supressAdjacentWhitespace = true; + } + } + + // <reference> tag + else if (!strcmp(tag.getName(), "reference")) { + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + buf += "<a href=\"\">"; + } + else if (tag.isEndTag()) { + buf += "</a>"; + } + } + + // <l> poetry, etc + else if (!strcmp(tag.getName(), "l")) { + if (tag.isEmpty()) { + buf += "<br />"; + } + else if (tag.isEndTag()) { + buf += "<br />"; + } + else if (tag.getAttribute("sID")) { // empty line marker + buf += "<br />"; + } + } + + // <milestone type="line"/> + else if ((!strcmp(tag.getName(), "milestone")) && (tag.getAttribute("type")) && (!strcmp(tag.getAttribute("type"), "line"))) { + buf += "<br />"; + userData->supressAdjacentWhitespace = true; + } + + // <title> + else if (!strcmp(tag.getName(), "title")) { + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + buf += "<b>"; + } + else if (tag.isEndTag()) { + buf += "</b><br />"; + } + } + + // <hi> hi? hi contrast? + else if (!strcmp(tag.getName(), "hi")) { + SWBuf type = tag.getAttribute("type"); + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + if (type == "b" || type == "x-b") { + buf += "<b> "; + u->inBold = true; + } + else { // all other types + buf += "<i> "; + u->inBold = false; + } + } + else if (tag.isEndTag()) { + if(u->inBold) { + buf += "</b>"; + u->inBold = false; + } + else + buf += "</i>"; + } + else { // empty hi marker + // what to do? is this even valid? + } + } + + // <q> quote + else if (!strcmp(tag.getName(), "q")) { + SWBuf type = tag.getAttribute("type"); + SWBuf who = tag.getAttribute("who"); + const char *lev = tag.getAttribute("level"); + int level = (lev) ? atoi(lev) : 1; + + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + /*buf += "{";*/ + + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + + if (who == "Jesus") { + buf += "<font color=\"red\"> "; + } + } + else if (tag.isEndTag()) { + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + //buf += "</font>"; + } + else { // empty quote marker + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + } + } + + // <transChange> + else if (!strcmp(tag.getName(), "transChange")) { + SWBuf type = tag.getAttribute("type"); + + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + +// just do all transChange tags this way for now +// if (type == "supplied") + buf += "<i>"; + } + else if (tag.isEndTag()) { + buf += "</i>"; + } + else { // empty transChange marker? + } + } + + // image + else if (!strcmp(tag.getName(), "figure")) { + const char *src = tag.getAttribute("src"); + if (!src) // assert we have a src attribute + return false; + + char* filepath = new char[strlen(u->module->getConfigEntry("AbsoluteDataPath")) + strlen(token)]; + *filepath = 0; + strcpy(filepath, userData->module->getConfigEntry("AbsoluteDataPath")); + strcat(filepath, src); + +// we do this because BibleCS looks for this EXACT format for an image tag + buf+="<image src=\""; + buf+=filepath; + buf+="\" />"; +/* + char imgc; + for (c = filepath + strlen(filepath); c > filepath && *c != '.'; c--); + c++; + FILE* imgfile; + if (stricmp(c, "jpg") || stricmp(c, "jpeg")) { + imgfile = fopen(filepath, "r"); + if (imgfile != NULL) { + buf += "{\\nonshppict {\\pict\\jpegblip "; + while (feof(imgfile) != EOF) { + buf.appendFormatted("%2x", fgetc(imgfile)); + } + fclose(imgfile); + buf += "}}"; + } + } + else if (stricmp(c, "png")) { + buf += "{\\*\\shppict {\\pict\\pngblip "; + + buf += "}}"; + } +*/ + delete [] filepath; + } + + else { + return false; // we still didn't handle token + } + } + return true; +} + + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/osislemma.cpp b/src/modules/filters/osislemma.cpp new file mode 100644 index 0000000..e31c002 --- /dev/null +++ b/src/modules/filters/osislemma.cpp @@ -0,0 +1,78 @@ +/****************************************************************************** + * + * osislemma - SWFilter descendant to hide or show lemmata + * in a OSIS module. + */ + + +#include <stdlib.h> +#include <osislemma.h> +#include <utilxml.h> +#ifndef __GNUC__ +#else +#include <unixstr.h> +#endif + +SWORD_NAMESPACE_START + +const char oName[] = "Lemmas"; +const char oTip[] = "Toggles Lemmas On and Off if they exist"; + +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +OSISLemma::OSISLemma() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); +} + + +OSISLemma::~OSISLemma() { +} + + +char OSISLemma::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + if (!option) { // if we don't want lemmas + const char *from; + char token[2048]; // cheese. Fix. + int tokpos = 0; + bool intoken = false; + bool lastspace = false; + SWBuf orig = text; + from = orig.c_str(); + + for (text = ""; *from; from++) { + if (*from == '<') { + intoken = true; + tokpos = 0; + token[0] = 0; + continue; + } + if (*from == '>') { // process tokens + intoken = false; + XMLTag tag(token); + if ((!strcmp(tag.getName(), "w")) && (!tag.isEndTag())) { // Lemma + SWBuf lemma = tag.getAttribute("lemma"); + if (lemma.length()) { + tag.setAttribute("lemma", 0); + tag.setAttribute("savlm", lemma.c_str()); + } + } + // keep tag, possibly with the lemma removed + text += tag; + continue; + } + if (intoken) { + if (tokpos < 2045) + token[tokpos++] = *from; + token[tokpos] = 0; + } + else { + text += *from; + lastspace = (*from == ' '); + } + } + } + return 0; +} + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/osismorph.cpp b/src/modules/filters/osismorph.cpp new file mode 100644 index 0000000..1b2d116 --- /dev/null +++ b/src/modules/filters/osismorph.cpp @@ -0,0 +1,75 @@ +/****************************************************************************** + * + * osismorph - SWFilter descendant to hide or show morph tags + * in a OSIS module. + */ + + +#include <stdlib.h> +#include <osismorph.h> +#include <utilxml.h> +#ifndef __GNUC__ +#else +#include <unixstr.h> +#endif + +SWORD_NAMESPACE_START + +const char oName[] = "Morphological Tags"; +const char oTip[] = "Toggles Morphological Tags On and Off if they exist"; + +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +OSISMorph::OSISMorph() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); +} + + +OSISMorph::~OSISMorph() { +} + + +char OSISMorph::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + if (!option) { // if we don't want morph tags + const char *from; + char token[2048]; // cheese. Fix. + int tokpos = 0; + bool intoken = false; + bool lastspace = false; + SWBuf orig = text; + from = orig.c_str(); + + for (text = ""; *from; from++) { + if (*from == '<') { + intoken = true; + tokpos = 0; + token[0] = 0; + continue; + } + if (*from == '>') { // process tokens + intoken = false; + XMLTag tag(token); + if ((!strcmp(tag.getName(), "w")) && (!tag.isEndTag())) { // Morph + if (tag.getAttribute("morph")) + tag.setAttribute("morph", 0); + } + // keep tag, possibly with the morph removed + text += tag; + continue; + } + if (intoken) { + if (tokpos < 2045) + token[tokpos++] = *from; + token[tokpos] = 0; + } + else { + text += *from; + lastspace = (*from == ' '); + } + } + } + return 0; +} + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/osisplain.cpp b/src/modules/filters/osisplain.cpp new file mode 100644 index 0000000..7a12a27 --- /dev/null +++ b/src/modules/filters/osisplain.cpp @@ -0,0 +1,151 @@ +/*************************************************************************** + 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. * + * * + ***************************************************************************/ + +#include <stdlib.h> +#include <osisplain.h> +#include <utilxml.h> +#include <ctype.h> + +SWORD_NAMESPACE_START + +OSISPlain::OSISPlain() { + setTokenStart("<"); + setTokenEnd(">"); + + setEscapeStart("&"); + setEscapeEnd(";"); + + setEscapeStringCaseSensitive(true); + + addEscapeStringSubstitute("amp", "&"); + addEscapeStringSubstitute("apos", "'"); + addEscapeStringSubstitute("lt", "<"); + addEscapeStringSubstitute("gt", ">"); + addEscapeStringSubstitute("quot", "\""); + + + addTokenSubstitute("title", "\n"); + addTokenSubstitute("/title", "\n"); + addTokenSubstitute("/l", "\n"); + addTokenSubstitute("lg", "\n"); + addTokenSubstitute("/lg", "\n"); + + setTokenCaseSensitive(true); +} + + +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; + XMLTag tag(token); + if (((*token == 'w') && (token[1] == ' ')) || + ((*token == '/') && (token[1] == 'w') && (!token[2]))) { + bool start = false; + if (*token == 'w') { + if (token[strlen(token)-1] != '/') { + u->w = token; + return true; + } + start = true; + } + tag = (start) ? token : u->w.c_str(); + bool show = true; // to handle unplaced article in kjv2003-- temporary till combined + + SWBuf lastText = (start) ? "stuff" : u->lastTextNode.c_str(); + + const char *attrib; + const char *val; + if (attrib = tag.getAttribute("xlit")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" <%s>", val); + } + if (attrib = tag.getAttribute("gloss")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" <%s>", val); + } + if (attrib = tag.getAttribute("lemma")) { + int count = tag.getAttributePartCount("lemma"); + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + do { + attrib = tag.getAttribute("lemma", i); + if (i < 0) i = 0; // to handle our -1 condition + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + if ((strchr("GH", *val)) && (isdigit(val[1]))) + val++; + if ((!strcmp(val, "3588")) && (lastText.length() < 1)) + show = false; + else buf.appendFormatted(" <%s>}", val); + } while (++i < count); + } + if ((attrib = tag.getAttribute("morph")) && (show)) { + int count = tag.getAttributePartCount("morph"); + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + do { + attrib = tag.getAttribute("morph", i); + if (i < 0) i = 0; // to handle our -1 condition + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + if ((*val == 'T') && (strchr("GH", val[1])) && (isdigit(val[2]))) + val+=2; + buf.appendFormatted(" (%s)", val); + } while (++i < count); + } + if (attrib = tag.getAttribute("POS")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" <%s>", val); + } + } + + // <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 += " ("; + } + else u->suspendTextPassThru = true; + } + else if (!strncmp(token, "/note", 5)) { + if (!u->suspendTextPassThru) + buf += ")"; + else u->suspendTextPassThru = false; + } + + // <p> paragraph tag + else if (((*token == 'p') && ((token[1] == ' ') || (!token[1]))) || + ((*token == '/') && (token[1] == 'p') && (!token[2]))) { + userData->supressAdjacentWhitespace = true; + buf += "\n"; + } + + // <milestone type="line"/> + else if ((!strcmp(tag.getName(), "milestone")) && (tag.getAttribute("type")) && (!strcmp(tag.getAttribute("type"), "line"))) { + userData->supressAdjacentWhitespace = true; + buf += "\n"; + } + + else { + return false; // we still didn't handle token + } + } + return true; +} + + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/osisredletterwords.cpp b/src/modules/filters/osisredletterwords.cpp new file mode 100644 index 0000000..a9a4834 --- /dev/null +++ b/src/modules/filters/osisredletterwords.cpp @@ -0,0 +1,77 @@ +/****************************************************************************** + * + * OSISRedLetterWords - SWFilter descendant to toggle red coloring for words + * of Christ in an OSIS module. + */ + + +#include <stdlib.h> +#include <osisredletterwords.h> +#include <swmodule.h> +#include <utilxml.h> +#ifndef __GNUC__ +#else +#include <unixstr.h> +#endif + +SWORD_NAMESPACE_START + +const char oName[] = "Words of Christ in Red"; +const char oTip[] = "Toggles Red Coloring for Words of Christ On and Off if they are marked"; + +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +OSISRedLetterWords::OSISRedLetterWords() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("On"); +} + + +OSISRedLetterWords::~OSISRedLetterWords() { +} + + +char OSISRedLetterWords::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + SWBuf token; + bool intoken = false; + char buf[254]; + + 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; + + XMLTag tag(token); + if (!stricmp(tag.getName(), "q")) { + if ((tag.getAttribute("who")) && (!stricmp(tag.getAttribute("who"), "Jesus"))) { + tag.setAttribute("who", 0); + text += tag; // tag toString already has < and > + continue; + } + } + // if we haven't modified, still use original token instead of tag, so we don't reorder attribs and stuff. It doesn't really matter, but this is less intrusive to the original markup. + text += '<'; + text.append(token); + text += '>'; + continue; + } + if (intoken) { //copy token + token += *from; + } + else { //copy text which is not inside a token + text += *from; + } + } + return 0; +} + +SWORD_NAMESPACE_END + diff --git a/src/modules/filters/osisrtf.cpp b/src/modules/filters/osisrtf.cpp new file mode 100644 index 0000000..e94e8ae --- /dev/null +++ b/src/modules/filters/osisrtf.cpp @@ -0,0 +1,333 @@ +/*************************************************************************** + 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; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <stdlib.h> +#include <osisrtf.h> +#include <utilxml.h> +#include <versekey.h> +#include <swmodule.h> + +SWORD_NAMESPACE_START + + +OSISRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) { + inXRefNote = false; + BiblicalText = false; + if (module) { + version = module->Name(); + BiblicalText = (!strcmp(module->Type(), "Biblical Texts")); + } + osisQToTick = ((!module->getConfigEntry("OSISqToTick")) || (strcmp(module->getConfigEntry("OSISqToTick"), "false"))); +} + + +OSISRTF::OSISRTF() { + setTokenStart("<"); + setTokenEnd(">"); + + setEscapeStart("&"); + setEscapeEnd(";"); + + setEscapeStringCaseSensitive(true); + + addEscapeStringSubstitute("amp", "&"); + addEscapeStringSubstitute("apos", "'"); + addEscapeStringSubstitute("lt", "<"); + addEscapeStringSubstitute("gt", ">"); + addEscapeStringSubstitute("quot", "\""); + addTokenSubstitute("lg", "{\\par}"); + addTokenSubstitute("/lg", "{\\par}"); + + setTokenCaseSensitive(true); +} + + +bool OSISRTF::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; + XMLTag tag(token); + + // <w> tag + if (!strcmp(tag.getName(), "w")) { + + // start <w> tag + if ((!tag.isEmpty()) && (!tag.isEndTag())) { + buf += "{"; + u->w = token; + } + + // end or empty <w> tag + else { + bool endTag = tag.isEndTag(); + SWBuf lastText; + bool show = true; // to handle unplaced article in kjv2003-- temporary till combined + + if (endTag) { + tag = u->w.c_str(); + lastText = u->lastTextNode.c_str(); + } + else lastText = "stuff"; + + const char *attrib; + const char *val; + if (attrib = tag.getAttribute("xlit")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" {\\fs15 <%s>}", val); + } + if (attrib = tag.getAttribute("gloss")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" {\\fs15 <%s>}", val); + } + if (attrib = tag.getAttribute("lemma")) { + int count = tag.getAttributePartCount("lemma"); + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + do { + attrib = tag.getAttribute("lemma", i); + if (i < 0) i = 0; // to handle our -1 condition + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + if ((strchr("GH", *val)) && (isdigit(val[1]))) + val++; + if ((!strcmp(val, "3588")) && (lastText.length() < 1)) + show = false; + else buf.appendFormatted(" {\\cf3 \\sub <%s>}", val); + } while (++i < count); + } + if ((attrib = tag.getAttribute("morph")) && (show)) { + SWBuf savelemma = tag.getAttribute("savlm"); + if ((strstr(savelemma.c_str(), "3588")) && (lastText.length() < 1)) + show = false; + if (show) { + int count = tag.getAttributePartCount("morph"); + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + do { + attrib = tag.getAttribute("morph", i); + if (i < 0) i = 0; // to handle our -1 condition + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + if ((*val == 'T') && (strchr("GH", val[1])) && (isdigit(val[2]))) + val+=2; + buf.appendFormatted(" {\\cf4 \\sub (%s)}", val); + } while (++i < count); + } + } + if (attrib = tag.getAttribute("POS")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" {\\fs15 <%s>}", val); + } + + if (endTag) + buf += "}"; + } + } + + // <note> tag + else if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + SWBuf type = tag.getAttribute("type"); + + if (type != "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 + SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) { } + if (vkey) { + char ch = ((!strcmp(type.c_str(), "crossReference")) || (!strcmp(type.c_str(), "x-cross-ref"))) ? 'x':'n'; + buf.appendFormatted("{\\super <a href=\"\">*%c%i.%s</a>} ", ch, vkey->Verse(), footnoteNumber.c_str()); + u->inXRefNote = (ch == 'x'); + } + } + u->suspendTextPassThru = true; + } + } + if (tag.isEndTag()) { + u->suspendTextPassThru = false; + u->inXRefNote = false; + } + } + + // <p> paragraph tag + else if (!strcmp(tag.getName(), "p")) { + if ((!tag.isEndTag()) && (!tag.isEmpty())) { // non-empty start tag + buf += "{\\par "; + } + else if (tag.isEndTag()) { // end tag + buf += "\\par}"; + userData->supressAdjacentWhitespace = true; + } + else { // empty paragraph break marker + buf += "{\\par\\par}"; + 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())) { + buf += "{<a href=\"\">"; + } + else if (tag.isEndTag()) { + buf += "</a>}"; + } + } + } + + // <l> poetry + else if (!strcmp(tag.getName(), "l")) { + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + buf += "{"; + } + else if (tag.isEndTag()) { + buf += "\\par}"; + } + else if (tag.getAttribute("sID")) { // empty line marker + buf += "{\\par}"; + } + } + + // <milestone type="line"/> + else if ((!strcmp(tag.getName(), "milestone")) && (tag.getAttribute("type")) && (!strcmp(tag.getAttribute("type"), "line"))) { + buf += "{\\par}"; + userData->supressAdjacentWhitespace = true; + } + + // <title> + else if (!strcmp(tag.getName(), "title")) { + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + buf += "{\\par\\i1\\b1 "; + } + else if (tag.isEndTag()) { + buf += "\\par}"; + } + } + + // <hi> + else if (!strcmp(tag.getName(), "hi")) { + SWBuf type = tag.getAttribute("type"); + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + if (type == "b" || type == "x-b") + buf += "{\\b1 "; + else // all other types + buf += "{\\i1 "; + } + else if (tag.isEndTag()) { + buf += "}"; + } + } + + // <q> quote + else if (!strcmp(tag.getName(), "q")) { + SWBuf type = tag.getAttribute("type"); + SWBuf who = tag.getAttribute("who"); + const char *lev = tag.getAttribute("level"); + int level = (lev) ? atoi(lev) : 1; + + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + buf += "{"; + + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + + if (who == "Jesus") + buf += "\\cf6 "; + } + else if (tag.isEndTag()) { + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + buf += "}"; + } + else { // empty quote marker + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + } + } + + // <transChange> + else if (!strcmp(tag.getName(), "transChange")) { + SWBuf type = tag.getAttribute("type"); + + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + +// just do all transChange tags this way for now +// if (type == "supplied") + buf += "{\\i1 "; + } + else if (tag.isEndTag()) { + buf += "}"; + } + } + + // image + else if (!strcmp(tag.getName(), "figure")) { + const char *src = tag.getAttribute("src"); + if (!src) // assert we have a src attribute + return false; + + char* filepath = new char[strlen(u->module->getConfigEntry("AbsoluteDataPath")) + strlen(token)]; + *filepath = 0; + strcpy(filepath, userData->module->getConfigEntry("AbsoluteDataPath")); + strcat(filepath, src); + +// we do this because BibleCS looks for this EXACT format for an image tag + buf+="<img src=\""; + buf+=filepath; + buf+="\" />"; +/* + char imgc; + for (c = filepath + strlen(filepath); c > filepath && *c != '.'; c--); + c++; + FILE* imgfile; + if (stricmp(c, "jpg") || stricmp(c, "jpeg")) { + imgfile = fopen(filepath, "r"); + if (imgfile != NULL) { + buf += "{\\nonshppict {\\pict\\jpegblip "; + while (feof(imgfile) != EOF) { + buf.appendFormatted("%2x", fgetc(imgfile)); + } + fclose(imgfile); + buf += "}}"; + } + } + else if (stricmp(c, "png")) { + buf += "{\\*\\shppict {\\pict\\pngblip "; + + buf += "}}"; + } +*/ + delete [] filepath; + } + else { + return false; // we still didn't handle token + } + } + return true; +} + + +SWORD_NAMESPACE_END + diff --git a/src/modules/filters/osisscripref.cpp b/src/modules/filters/osisscripref.cpp new file mode 100644 index 0000000..566e08a --- /dev/null +++ b/src/modules/filters/osisscripref.cpp @@ -0,0 +1,104 @@ +/****************************************************************************** + * + * OSISScripref - SWFilter descendant to hide or show scripture references + * in an OSIS module. + */ + + +#include <stdlib.h> +#include <osisscripref.h> +#include <swmodule.h> +#include <utilxml.h> +#ifndef __GNUC__ +#else +#include <unixstr.h> +#endif + +SWORD_NAMESPACE_START + +const char oName[] = "Cross-references"; +const char oTip[] = "Toggles Scripture Cross-references On and Off if they exist"; + +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +OSISScripref::OSISScripref() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("On"); +} + + +OSISScripref::~OSISScripref() { +} + + +char OSISScripref::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + SWBuf token; + bool intoken = false; + bool hide = false; + SWBuf tagText; + XMLTag startTag; + int tagTextNum = 1; + int footnoteNum = 1; + char buf[254]; + + SWBuf orig = text; + const char *from = orig.c_str(); + + for (text = ""; *from; from++) { + if (*from == '<') { + intoken = true; + token = ""; + continue; + } + if (*from == '>') { // process tokens + intoken = false; + + XMLTag tag(token); + if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag() && (!tag.isEmpty())) { + startTag = tag; + if ((tag.getAttribute("type")) && (!strcmp(tag.getAttribute("type"), "crossReference"))) { + hide = true; + tagText = ""; + if (option) { // we want the tag in the text + text += '<'; + text.append(token); + text += '>'; + } + continue; + } + } + if (hide && tag.isEndTag()) { + hide = false; + if (option) { // we want the tag in the text + text.append(tagText); // end tag gets added further down + } + else continue; // don't let the end tag get added to the text + } + } + + // if not a heading token, keep token in text + if (!hide) { + text += '<'; + text.append(token); + text += '>'; + } + else { + tagText += '<'; + tagText.append(token); + tagText += '>'; + } + continue; + } + if (intoken) { //copy token + token += *from; + } + else if (!hide) { //copy text which is not inside a token + text += *from; + } + else tagText += *from; + } + return 0; +} + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/osisstrongs.cpp b/src/modules/filters/osisstrongs.cpp new file mode 100644 index 0000000..7949b50 --- /dev/null +++ b/src/modules/filters/osisstrongs.cpp @@ -0,0 +1,128 @@ +/****************************************************************************** + * + * osisstrongs - SWFilter descendant to hide or show strongs number + * in a OSIS module. + */ + + +#include <stdlib.h> +#include <osisstrongs.h> +#include <swmodule.h> +#ifndef __GNUC__ +#else +#include <unixstr.h> +#endif +#include <ctype.h> + +SWORD_NAMESPACE_START + +const char oName[] = "Strong's Numbers"; +const char oTip[] = "Toggles Strong's Numbers On and Off if they exist"; + +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + + +OSISStrongs::OSISStrongs() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); +} + + +OSISStrongs::~OSISStrongs() { +} + + +char OSISStrongs::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + const char *from; + char token[2048]; // cheese. Fix. + int tokpos = 0; + bool intoken = false; + int len; + bool lastspace = false; + int word = 1; + char val[128]; + char wordstr[5]; + char *valto; + char *ch; + unsigned int textStart = 0, textEnd = 0; + bool newText = false; + SWBuf tmp; + + SWBuf orig = text; + from = orig.c_str(); + + len = strlen(text) + 1; // shift string to right of buffer + + for (text = ""; *from; from++) { + if (*from == '<') { + intoken = true; + tokpos = 0; + token[0] = 0; + token[1] = 0; + token[2] = 0; + textEnd = text.size(); + continue; + } + if (*from == '>') { // process tokens + intoken = false; + if ((*token == 'w') && (token[1] == ' ')) { // Word + if (module->isProcessEntryAttributes()) { + valto = val; + char *num = strstr(token, "lemma=\"x-Strongs:"); + if (num) { + for (num+=17; ((*num) && (*num != '\"')); num++) + *valto++ = *num; + *valto = 0; + if (atoi((!isdigit(*val))?val+1:val) < 5627) { + // normal strongs number + sprintf(wordstr, "%03d", word++); + module->getEntryAttributes()["Word"][wordstr]["Strongs"] = val; + tmp = ""; + tmp.append(text.c_str()+textStart, (int)(textEnd - textStart)); + module->getEntryAttributes()["Word"][wordstr]["Text"] = tmp; + newText = true; + } + else { + // verb morph + sprintf(wordstr, "%03d", word-1); + module->getEntryAttributes()["Word"][wordstr]["Morph"] = val; + } + } + } + if (!option) { + char *num = strstr(token, "lemma=\"x-Strongs:"); + if (num) { + memcpy(num, "savlm", 5); +/* + for (int i = 0; i < 17; i++) + *num++ = ' '; + for (; ((*num) && (*num!='\"')); num++) + *num = ' '; + if (*num) + *num = ' '; +*/ + } + } + } + // if not a strongs token, keep token in text + text += '<'; + for (char *tok = token; *tok; tok++) + text += *tok; + text += '>'; + if (newText) {textStart = text.size(); newText = false; } + continue; + } + if (intoken) { + if (tokpos < 2045) + token[tokpos++] = *from; + token[tokpos+2] = 0; + } + else { + text += *from; + lastspace = (*from == ' '); + } + } + return 0; +} + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/osiswebif.cpp b/src/modules/filters/osiswebif.cpp new file mode 100644 index 0000000..f2db7b7 --- /dev/null +++ b/src/modules/filters/osiswebif.cpp @@ -0,0 +1,212 @@ +/*************************************************************************** + 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. * + * * + ***************************************************************************/ + +#include <stdlib.h> +#include <osiswebif.h> +#include <utilxml.h> +#include <versekey.h> +#include <swmodule.h> +#include <ctype.h> + + +SWORD_NAMESPACE_START + + +OSISWEBIF::OSISWEBIF() : baseURL(""), passageStudyURL(baseURL + "passagestudy.jsp") { +} + +bool OSISWEBIF::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; + XMLTag tag(token); + + // <w> tag + if (!strcmp(tag.getName(), "w")) { + + // start <w> tag + if ((!tag.isEmpty()) && (!tag.isEndTag())) { + u->w = token; + } + + // end or empty <w> tag + else { + bool endTag = tag.isEndTag(); + SWBuf lastText; + bool show = true; // to handle unplaced article in kjv2003-- temporary till combined + + if (endTag) { + tag = u->w.c_str(); + lastText = u->lastTextNode.c_str(); + } + else lastText = "stuff"; + + const char *attrib; + const char *val; + if (attrib = tag.getAttribute("xlit")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" %s", val); + } + if (attrib = tag.getAttribute("gloss")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" %s", val); + } + if (attrib = tag.getAttribute("lemma")) { + int count = tag.getAttributePartCount("lemma"); + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + do { + attrib = tag.getAttribute("lemma", i); + if (i < 0) i = 0; // to handle our -1 condition + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + const char *val2 = val; + if ((strchr("GH", *val)) && (isdigit(val[1]))) + val2++; + if ((!strcmp(val2, "3588")) && (lastText.length() < 1)) + show = false; + else buf.appendFormatted(" <small><em><<a href=\"%s?showStrong=%s#cv\">%s</a>></em></small> ", passageStudyURL.c_str(), encodeURL(val2).c_str(), val2); + } while (++i < count); + } + if ((attrib = tag.getAttribute("morph")) && (show)) { + SWBuf savelemma = tag.getAttribute("savlm"); + if ((strstr(savelemma.c_str(), "3588")) && (lastText.length() < 1)) + show = false; + if (show) { + int count = tag.getAttributePartCount("morph"); + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + do { + attrib = tag.getAttribute("morph", i); + if (i < 0) i = 0; // to handle our -1 condition + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + const char *val2 = val; + if ((*val == 'T') && (strchr("GH", val[1])) && (isdigit(val[2]))) + val2+=2; + buf.appendFormatted(" <small><em>(<a href=\"%s?showMorph=%s#cv\">%s</a>)</em></small> ", passageStudyURL.c_str(), encodeURL(val2).c_str(), val2); + } while (++i < count); + } + } + if (attrib = tag.getAttribute("POS")) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" %s", val); + } + + /*if (endTag) + buf += "}";*/ + } + } + + // <note> tag + else if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + SWBuf type = tag.getAttribute("type"); + + if (type != "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 + SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) { } + if (vkey) { + char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n'); +// buf.appendFormatted("<a href=\"noteID=%s.%c.%s\"><small><sup>*%c</sup></small></a> ", vkey->getText(), ch, footnoteNumber.c_str(), ch); + } + } + u->suspendTextPassThru = true; + } + } + if (tag.isEndTag()) { + u->suspendTextPassThru = false; + } + } + // <title> + else if (!strcmp(tag.getName(), "title")) { + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + buf += "<h3>"; + } + else if (tag.isEndTag()) { + buf += "</h3>"; + } + } + + // <q> quote + else if (!strcmp(tag.getName(), "q")) { + SWBuf type = tag.getAttribute("type"); + SWBuf who = tag.getAttribute("who"); + const char *lev = tag.getAttribute("level"); + int level = (lev) ? atoi(lev) : 1; + + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + /*buf += "{";*/ + + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + + if (who == "Jesus") { + buf += "<span class=\"wordsOfJesus\"> "; + } + } + else if (tag.isEndTag()) { + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + buf += "</span>"; + } + else { // empty quote marker + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + } + } + + // <transChange> + else if (!strcmp(tag.getName(), "transChange")) { + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + SWBuf type = tag.getAttribute("type"); + u->lastTransChange = type; + +// just do all transChange tags this way for now + if ((type == "added") || (type == "supplied")) + buf += "<i>"; + else if (type == "tenseChange") + buf += "*"; + } + else if (tag.isEndTag()) { + SWBuf type = u->lastTransChange; + if ((type == "added") || (type == "supplied")) + buf += "</i>"; + } + else { // empty transChange marker? + } + } + else { + return OSISHTMLHREF::handleToken(buf, token, userData); + } + } + return true; +} + + +SWORD_NAMESPACE_END + diff --git a/src/modules/filters/plainfootnotes.cpp b/src/modules/filters/plainfootnotes.cpp index 96fc4d8..0ae50ef 100644 --- a/src/modules/filters/plainfootnotes.cpp +++ b/src/modules/filters/plainfootnotes.cpp @@ -19,84 +19,65 @@ #include <swkey.h> #include <stdlib.h> -#include <string.h> #ifndef __GNUC__ #else #include <unixstr.h> #endif -const char PLAINFootnotes::on[] = "On"; -const char PLAINFootnotes::off[] = "Off"; -const char PLAINFootnotes::optName[] = "Footnotes"; -const char PLAINFootnotes::optTip[] = "Toggles Footnotes On and Off In Bible Texts If They Exist"; +SWORD_NAMESPACE_START -PLAINFootnotes::PLAINFootnotes(){ - option = false; - options.push_back(on); - options.push_back(off); -} - -PLAINFootnotes::~PLAINFootnotes(){ -} +const char oName[] = "Footnotes"; +const char oTip[] = "Toggles Footnotes On and Off In Bible Texts If They Exist"; +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); -void PLAINFootnotes::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); +PLAINFootnotes::PLAINFootnotes() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); } -const char *PLAINFootnotes::getOptionValue() -{ - return (option) ? on:off; +PLAINFootnotes::~PLAINFootnotes(){ } -char PLAINFootnotes::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ - char token[2048]; - int tokpos = 0; - bool intoken = false; - bool lastspace = false; - +char PLAINFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *module) { if (!option) { // if we don't want footnotes - char *to, *from; - int len; - bool hide = false; + //char token[2048]; + //SWBuf token; + //int tokpos = 0; + //bool intoken = false; + //bool lastspace = false; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) - { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- + bool hide = false; - for (to = text; *from; from++) { - if (*from == '{') // Footnote start + SWBuf orig = text; + const char *from = orig.c_str(); + for (text = ""; *from; from++) { + if (*from == '{') // Footnote start { hide = true; continue; } - if (*from == '}') // Footnote end + else if (*from == '}') // Footnote end { - hide=false; + hide = false; continue; } - if (intoken) { - if (tokpos < 2045) - token[tokpos++] = *from; - token[tokpos+2] = 0; - } - else { + + //if (intoken) { + //if (tokpos < 2045) + // token += *from; + // token[tokpos+2] = 0; + //} + //else { if (!hide) { - *to++ = *from; - lastspace = (*from == ' '); + text = *from; + //lastspace = (*from == ' '); } - } + //} } - *to++ = 0; - *to = 0; } return 0; } +SWORD_NAMESPACE_END diff --git a/src/modules/filters/plainhtml.cpp b/src/modules/filters/plainhtml.cpp index fefb029..19f4bc2 100644 --- a/src/modules/filters/plainhtml.cpp +++ b/src/modules/filters/plainhtml.cpp @@ -15,120 +15,56 @@ * * ***************************************************************************/ -#include <stdlib.h> -#include <string.h> #include <plainhtml.h> +SWORD_NAMESPACE_START PLAINHTML::PLAINHTML() { } -char PLAINHTML::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char PLAINHTML::processText(SWBuf &text, const SWKey *key, const SWModule *module) { - char *to, *from; - int len; int count = 0; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- - for (to = text; *from; from++) + SWBuf orig = text; + const char *from = orig.c_str(); + for (text = ""; *from; from++) { - if ((*from == '\n') && (from[1] == '\n')) // paragraph + if ((*from == '\n') && (from[1] == '\n')) // two newlinea are a paragraph { - *to++ = '<'; - *to++ = 'P'; - *to++ = '>'; + text += "<P>"; from++; continue; } else { - if ((*from == '\n')) // && (from[1] != '\n')) // new line + if ((*from == '\n')) // && (from[1] != '\n')) // only one new line { - *to++ = '<'; - *to++ = 'B'; - *to++ = 'R'; - *to++ = '>'; + text += "<BR>"; continue; } } - if (*from == '{') { - *to++ = '<'; - *to++ = 'F'; - *to++ = 'O'; - *to++ = 'N'; - *to++ = 'T'; - *to++ = ' '; - *to++ = 'C'; - *to++ = 'O'; - *to++ = 'L'; - *to++ = 'O'; - *to++ = 'R'; - *to++ = '='; - *to++ = '#'; - *to++ = '8'; - *to++ = '0'; - *to++ = '0'; - *to++ = '0'; - *to++ = '0'; - *to++ = '0'; - *to++ = '>'; - - *to++ = '<'; - *to++ = 'S'; - *to++ = 'M'; - *to++ = 'A'; - *to++ = 'L'; - *to++ = 'L'; - *to++ = '>'; - *to++ = ' '; - *to++ = '('; + if (*from == '{') { //footnote start + text += "<FONT COLOR=\"#80000\"><SMALL> ("; continue; } - - if (*from == '}') + else if (*from == '}') //footnote end { - *to++ = ')'; - *to++ = ' '; - *to++ = '<'; - *to++ = '/'; - *to++ = 'S'; - *to++ = 'M'; - *to++ = 'A'; - *to++ = 'L'; - *to++ = 'L'; - *to++ = '>'; - - *to++ = '<'; - *to++ = '/'; - *to++ = 'F'; - *to++ = 'O'; - *to++ = 'N'; - *to++ = 'T'; - *to++ = '>'; + text += ") </SMALL></FONT>"; continue; } - - if ((*from == ' ') && (count > 5000)) + else if ((*from == ' ') && (count > 5000)) { - *to++ = '<'; - *to++ = 'W'; - *to++ = 'B'; - *to++ = 'R'; - *to++ = '>'; + text += "<WBR>"; count = 0; continue; } - *to++ = *from; + text += *from; count++; } - *to++ = 0; - *to = 0; return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/rtfhtml.cpp b/src/modules/filters/rtfhtml.cpp index f0b842b..6b228fb 100644 --- a/src/modules/filters/rtfhtml.cpp +++ b/src/modules/filters/rtfhtml.cpp @@ -16,54 +16,41 @@ ***************************************************************************/ #include <stdlib.h> -#include <string.h> #include <rtfhtml.h> +SWORD_NAMESPACE_START RTFHTML::RTFHTML() { } -char RTFHTML::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char RTFHTML::processText(SWBuf &text, const SWKey *key, const SWModule *module) { - char *to, *from; - int len; bool center = false; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- - for (to = text; *from; from++) { + const char *from; + SWBuf orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) + { if (*from == '\\') // a RTF command { - if ((from[1] == 'p') && (from[2] == 'a') && (from[3] == 'r') && (from[4] == 'd')) - { // switch all modifier off + if ( !strncmp(from+1, "pard", 4) ) + //(from[1] == 'p') && (from[2] == 'a') && (from[3] == 'r') && (from[4] == 'd')) + { // switch all modifiers off if (center) { - *to++ = '<'; - *to++ = '/'; - *to++ = 'C'; - *to++ = 'E'; - *to++ = 'N'; - *to++ = 'T'; - *to++ = 'E'; - *to++ = 'R'; - *to++ = '>'; + text += "</CENTER>"; center = false; } from += 4; continue; } - if ((from[1] == 'p') && (from[2] == 'a') && (from[3] == 'r')) + if ( !strncmp(from+1, "par", 3) ) + //(from[1] == 'p') && (from[2] == 'a') && (from[3] == 'r')) { - *to++ = '<'; - *to++ = 'P'; - *to++ = '>'; - *to++ = '\n'; + text += "<P>\n"; from += 3; continue; } @@ -72,18 +59,12 @@ char RTFHTML::ProcessText(char *text, int maxlen, const SWKey *key, const SWModu from += 1; continue; } - if ((from[1] == 'q') && (from[2] == 'c')) // center on + if ( !strncmp(from+1, "qc", 2) ) + //(from[1] == 'q') && (from[2] == 'c')) // center on { if (!center) { - *to++ = '<'; - *to++ = 'C'; - *to++ = 'E'; - *to++ = 'N'; - *to++ = 'T'; - *to++ = 'E'; - *to++ = 'R'; - *to++ = '>'; + text += "<CENTER>"; center = true; } from += 2; @@ -91,9 +72,9 @@ char RTFHTML::ProcessText(char *text, int maxlen, const SWKey *key, const SWModu } } - *to++ = *from; + text += *from; } - *to++ = 0; - *to = 0; return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/rwphtml.cpp b/src/modules/filters/rwphtml.cpp deleted file mode 100644 index 6f8ae4f..0000000 --- a/src/modules/filters/rwphtml.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/*************************************************************************** - rwphtml.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. * - * * - ***************************************************************************/ - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <rwphtml.h> - -RWPHTML::RWPHTML() -{ -} - - -char RWPHTML::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ - char *to, *from; - signed char greek_str[500]; - bool inverse = false; - bool first_letter = false; - int len; - - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } else - from = text; - for (to = text; *from; from++) { - if (*from == '\\') { - ++from; - int i=0; - first_letter = true; - greek_str[0] = '\0'; - while (*from != '\\') { /* get the greek word or phrase */ - greek_str[i++] = *from; - greek_str[i + 1] = '\0'; - from++; - } /* convert to symbol font as best we can */ - strcpy(to,"<I> </I><FONT FACE=\"symbol\">"); - to += strlen(to); - for (int j = 0; j < i; j++) { - if ((first_letter) - && (greek_str[j] == 'h')) { - if (greek_str[j + 1] == 'o') { - *to++ = 'o'; - first_letter = false; - ++j; - continue; - } else if (greek_str[j + 1] == 'a') { - *to++ = 'a'; - first_letter = false; - ++j; - continue; - } else if (greek_str[j + 1] == 'w') { - *to++ = 'w'; - first_letter = false; - ++j; - continue; - } else if (greek_str[j + 1] == 'u') { - *to++ = 'u'; - first_letter = false; - ++j; - continue; - } else if (greek_str[j + 1] == - -109) { - *to++ = 'w'; - first_letter = false; - ++j; - continue; - } else if (greek_str[j + 1] == - -120) { - *to++ = 'h'; - first_letter = false; - ++j; - continue; - } else if (greek_str[j + 1] == 'i') { - *to++ = 'i'; - first_letter = false; - ++j; - continue; - }else if (greek_str[j + 1] == 'e') { - *to++ = 'e'; - first_letter = false; - ++j; - continue; - } - first_letter = false; - } - if ((greek_str[j] == 't') - && (greek_str[j + 1] == 'h')) { - *to++ = 'q'; - ++j; - continue; - } - if ((greek_str[j] == 'c') - && (greek_str[j + 1] == 'h')) { - *to++ = 'c'; - ++j; - continue; - } - if ((greek_str[j] == 'p') - && (greek_str[j + 1] == 'h')) { - ++j; - *to++ = 'f'; - continue; - } - if (greek_str[j] == -120) { - *to++ = 'h'; - continue; - } - if (greek_str[j] == -125) { - *to++ = 'a'; - continue; - } - if (greek_str[j] == -109) { - if(greek_str[j+1] == 'i') ++j; - *to++ = 'w'; - continue; - } - if (greek_str[j] == ' ') - first_letter = true; - if (greek_str[j] == 's') { - if(isalpha(greek_str[j + 1])) *to++ = 's'; - else if(!isprint(greek_str[j] )) *to++ = 's'; - else *to++ = 'V'; - continue; - } - if (greek_str[j] == '\'') { - continue; - } - *to++ = greek_str[j]; - } - strcpy(to,"</FONT><I> </I>"); - to += strlen(to); - continue; - } - if (*from == '#') { // verse markings (e.g. "#Mark 1:1|") - inverse = true; - strcpy(to,"<FONT COLOR=#0000FF>"); - to += strlen(to); - continue; - } - if ((*from == '|') && (inverse)) { - inverse = false; - strcpy(to,"</FONT>"); - to += strlen(to); - continue; - } - if (*from == '{') { - strcpy(to,"<BR><STRONG>"); - to += strlen(to); - if ((from - &text[maxlen - len]) > 10) { // not the beginning of the entry - strcpy(to,"<P>"); - to += strlen(to); - } - continue; - } - if (*from == '}') { - strcpy(to," </STRONG>"); - to += strlen(to); - continue; - } - if ((*from == '\n') && (from[1] == '\n')) { - strcpy(to,"<P>"); - to += strlen(to); - continue; - } - *to++ = *from; - } - *to++ = 0; - *to = 0; - return 0; -} diff --git a/src/modules/filters/rwprtf.cpp b/src/modules/filters/rwprtf.cpp deleted file mode 100644 index 8f7b074..0000000 --- a/src/modules/filters/rwprtf.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/****************************************************************************** - * - * rwprtf - SWFilter decendant to convert all GBF tags to RTF tags - */ - - -#include <stdlib.h> -#include <string.h> -#include <rwprtf.h> - - -RWPRTF::RWPRTF() { - -} - - -char RWPRTF::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ - char *to, *from; - bool ingreek = false; - bool inverse = false; - int len; - - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- - for (to = text; *from; from++) { - if (*from == '\\') { - if(!ingreek) { - ingreek = true; - *to++ = '['; - *to++ = '{'; - *to++ = '\\'; - *to++ = 'f'; - *to++ = '8'; - *to++ = ' '; - continue; - } - else { - ingreek = false; - *to++ = '}'; - *to++ = ']'; - continue; - } - } - - if ((ingreek) && ((*from == 'h') || (*from == 'H'))) - continue; // 'h's are mostly useless in RWP translitterations. The greek is more correct without them. - - if (*from == '#') { // verse markings (e.g. "#Mark 1:1|") - inverse = true; - *to++ = '{'; - *to++ = '\\'; - *to++ = 'c'; - *to++ = 'f'; - *to++ = '2'; - *to++ = ' '; - *to++ = '#'; - continue; - } - if ((*from == '|') && (inverse)) { - inverse = false; - *to++ = '|'; - *to++ = '}'; - continue; - } - - if (*from == '{') { - *to++ = '{'; - *to++ = '\\'; - *to++ = 'b'; - *to++ = ' '; - if ((from - &text[maxlen - len]) > 10) { // not the beginning of the entry - *to++ = '\\'; - *to++ = 'p'; - *to++ = 'a'; - *to++ = 'r'; - *to++ = ' '; - } - continue; - } - - if (*from == '}') { - // this is kinda neat... DO NOTHING - } - if ((*from == '\n') && (from[1] == '\n')) { - *to++ = '\\'; - *to++ = 'p'; - *to++ = 'a'; - *to++ = 'r'; - *to++ = '\\'; - *to++ = 'p'; - *to++ = 'a'; - *to++ = 'r'; - *to++ = ' '; - continue; - } - - *to++ = *from; - } - *to++ = 0; - *to = 0; - return 0; -} diff --git a/src/modules/filters/scsuutf8.cpp b/src/modules/filters/scsuutf8.cpp index d0d5ceb..aff265d 100644 --- a/src/modules/filters/scsuutf8.cpp +++ b/src/modules/filters/scsuutf8.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * SCSUUTF8 - SWFilter decendant to convert a SCSU character to UTF-8 + * SCSUUTF8 - SWFilter descendant to convert a SCSU character to UTF-8 * */ @@ -22,6 +22,8 @@ #include <scsuutf8.h> +SWORD_NAMESPACE_START + SCSUUTF8::SCSUUTF8() { } @@ -59,11 +61,13 @@ unsigned char* SCSUUTF8::UTF8Output(unsigned long uchar, unsigned char* text) return text; } -char SCSUUTF8::ProcessText(char *text, int len, const SWKey *key, const SWModule *module) -{ +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}; @@ -103,7 +107,7 @@ char SCSUUTF8::ProcessText(char *text, int len, const SWKey *key, const SWModule }; if (!len) - return 0; + return 0; memmove(&text[buflen - len], text, len); from = (unsigned char*)&text[buflen - len]; @@ -114,95 +118,95 @@ char SCSUUTF8::ProcessText(char *text, int len, const SWKey *key, const SWModule for (int i = 0; i < len;) { - if (i >= len) break; - c = from[i++]; + if (i >= len) break; + c = from[i++]; - if (c >= 0x80) + if (c >= 0x80) { to = UTF8Output (c - 0x80 + slide[active], to); } - else if (c >= 0x20 && c <= 0x7F) + else if (c >= 0x20 && c <= 0x7F) { to = UTF8Output (c, to); } - else if (c == 0x0 || c == 0x9 || c == 0xA || c == 0xC || c == 0xD) + else if (c == 0x0 || c == 0x9 || c == 0xA || c == 0xC || c == 0xD) { to = UTF8Output (c, to); } - else if (c >= 0x1 && c <= 0x8) /* SQn */ + else if (c >= 0x1 && c <= 0x8) // SQn { - if (i >= len) break; - /* single quote */ d = from[i++]; + 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 */ + else if (c >= 0x10 && c <= 0x17) // SCn { - /* change window */ active = c - 0x10; + active = c - 0x10; // change window } - else if (c >= 0x18 && c <= 0x1F) /* SDn */ + else if (c >= 0x18 && c <= 0x1F) // SDn { - /* define window */ active = c - 0x18; - if (i >= len) break; + active = c - 0x18; // define window + if (i >= len) break; slide [active] = win [from[i++]]; } - else if (c == 0xB) /* SDX */ + else if (c == 0xB) // SDX { - if (i >= len) break; - c = from[i++]; + if (i >= len) break; + c = from[i++]; - if (i >= len) break; - d = from[i++]; + if (i >= len) break; + d = from[i++]; slide [active = c>>5] = 0x10000 + (((c & 0x1F) << 8 | d) << 7); } - else if (c == 0xE) /* SQU */ + else if (c == 0xE) // SQU { - if (i >= len) break; - /* SQU */ c = from[i++]; + if (i >= len) break; + c = from[i++]; // SQU - if (i >= len) break; - to = UTF8Output (c << 8 | from[i++], to); - } - else if (c == 0xF) /* SCU */ + if (i >= len) break; + to = UTF8Output (c << 8 | from[i++], to); + } + else if (c == 0xF) // SCU { - /* change to Unicode mode */ mode = 1; + mode = 1; // change to Unicode mode while (mode) { - if (i >= len) break; - c = from[i++]; + if (i >= len) break; + c = from[i++]; - if (c <= 0xDF || c >= 0xF3) + if (c <= 0xDF || c >= 0xF3) { - if (i >= len) break; + if (i >= len) break; to = UTF8Output (c << 8 | from[i++], to); } - else if (c == 0xF0) /* UQU */ + else if (c == 0xF0) // UQU { - if (i >= len) break; + if (i >= len) break; c = from[i++]; - if (i >= len) break; - to = UTF8Output (c << 8 | from[i++], to); + if (i >= len) break; + to = UTF8Output (c << 8 | from[i++], to); } - else if (c >= 0xE0 && c <= 0xE7) /* UCn */ + else if (c >= 0xE0 && c <= 0xE7) // UCn { active = c - 0xE0; mode = 0; } - else if (c >= 0xE8 && c <= 0xEF) /* UDn */ + else if (c >= 0xE8 && c <= 0xEF) // UDn { - if (i >= len) break; + if (i >= len) break; slide [active=c-0xE8] = win [from[i++]]; mode = 0; } - else if (c == 0xF1) /* UDX */ + else if (c == 0xF1) // UDX { - if (i >= len) break; + if (i >= len) break; c = from[i++]; - if (i >= len) break; - d = from[i++]; + if (i >= len) break; + d = from[i++]; slide [active = c>>5] = 0x10000 + (((c & 0x1F) << 8 | d) << 7); mode = 0; @@ -215,6 +219,8 @@ char SCSUUTF8::ProcessText(char *text, int len, const SWKey *key, const SWModule *to++ = 0; *to = 0; +*/ return 0; } +SWORD_NAMESPACE_END diff --git a/src/modules/filters/swbasicfilter.cpp b/src/modules/filters/swbasicfilter.cpp index 2865085..55c8843 100644 --- a/src/modules/filters/swbasicfilter.cpp +++ b/src/modules/filters/swbasicfilter.cpp @@ -4,7 +4,7 @@ * many filters will need and can use as a starting * point. * - * $Id: swbasicfilter.cpp,v 1.17 2002/03/11 19:01:28 scribe Exp $ + * $Id: swbasicfilter.cpp,v 1.33 2003/10/24 02:43:46 scribe Exp $ * * Copyright 2001 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society @@ -23,16 +23,23 @@ */ #include <stdlib.h> -#include <string.h> #include <swbasicfilter.h> #include <stdio.h> #include <stdarg.h> +SWORD_NAMESPACE_START + +const char SWBasicFilter::INITIALIZE = 1; +const char SWBasicFilter::PRECHAR = 2; +const char SWBasicFilter::POSTCHAR = 4; +const char SWBasicFilter::FINALIZE = 8; + SWBasicFilter::SWBasicFilter() { - tokenStart = 0; - tokenEnd = 0; - escStart = 0; - escEnd = 0; + processStages = 0; + tokenStart = 0; + tokenEnd = 0; + escStart = 0; + escEnd = 0; setTokenStart("<"); setTokenEnd(">"); @@ -40,9 +47,9 @@ SWBasicFilter::SWBasicFilter() { setEscapeEnd(";"); escStringCaseSensitive = false; - tokenCaseSensitive = false; - passThruUnknownToken = false; - passThruUnknownEsc = false; + tokenCaseSensitive = false; + passThruUnknownToken = false; + passThruUnknownEsc = false; } @@ -87,10 +94,18 @@ void SWBasicFilter::addTokenSubstitute(const char *findString, const char *repla if (!tokenCaseSensitive) { stdstr(&buf, findString); toupperstr(buf); - tokenSubMap.insert(DualStringMap::value_type(buf, replaceString)); + tokenSubMap[buf] = replaceString; delete [] buf; } - else tokenSubMap.insert(DualStringMap::value_type(findString, replaceString)); + else tokenSubMap[findString] = replaceString; +} + + +void SWBasicFilter::replaceTokenSubstitute(const char *findString, const char *replaceString) { + if (tokenSubMap.find(findString) != tokenSubMap.end()) { + tokenSubMap.erase( tokenSubMap.find(findString) ); //erase entry + } + addTokenSubstitute(findString, replaceString); } @@ -106,19 +121,15 @@ void SWBasicFilter::addEscapeStringSubstitute(const char *findString, const char else escSubMap.insert(DualStringMap::value_type(findString, replaceString)); } - -void SWBasicFilter::pushString(char **buf, const char *format, ...) { - va_list argptr; - - va_start(argptr, format); - *buf += vsprintf(*buf, format, argptr); - va_end(argptr); - -// *buf += strlen(*buf); +void SWBasicFilter::replaceEscapeStringSubstitute(const char *findString, const char *replaceString) { + if (escSubMap.find(findString) != escSubMap.end()) { + escSubMap.erase( escSubMap.find(findString) ); //erase entry + } + addEscapeStringSubstitute(findString, replaceString); } -bool SWBasicFilter::substituteToken(char **buf, const char *token) { +bool SWBasicFilter::substituteToken(SWBuf &buf, const char *token) { DualStringMap::iterator it; if (!tokenCaseSensitive) { @@ -131,14 +142,14 @@ bool SWBasicFilter::substituteToken(char **buf, const char *token) { it = tokenSubMap.find(token); if (it != tokenSubMap.end()) { - pushString(buf, it->second.c_str()); + buf += it->second.c_str(); return true; } return false; } -bool SWBasicFilter::substituteEscapeString(char **buf, const char *escString) { +bool SWBasicFilter::substituteEscapeString(SWBuf &buf, const char *escString) { DualStringMap::iterator it; if (!escStringCaseSensitive) { @@ -151,72 +162,76 @@ bool SWBasicFilter::substituteEscapeString(char **buf, const char *escString) { it = escSubMap.find(escString); if (it != escSubMap.end()) { - pushString(buf, it->second.c_str()); + buf += it->second.c_str(); return true; } return false; } -bool SWBasicFilter::handleToken(char **buf, const char *token, DualStringMap &userData) { +bool SWBasicFilter::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { return substituteToken(buf, token); } -bool SWBasicFilter::handleEscapeString(char **buf, const char *escString, DualStringMap &userData) { +bool SWBasicFilter::handleEscapeString(SWBuf &buf, const char *escString, BasicFilterUserData *userData) { return substituteEscapeString(buf, escString); } void SWBasicFilter::setEscapeStart(const char *escStart) { stdstr(&(this->escStart), escStart); + escStartLen = strlen(escStart); } void SWBasicFilter::setEscapeEnd(const char *escEnd) { stdstr(&(this->escEnd), escEnd); + escEndLen = strlen(escEnd); } void SWBasicFilter::setTokenStart(const char *tokenStart) { stdstr(&(this->tokenStart), tokenStart); + tokenStartLen = strlen(tokenStart); } void SWBasicFilter::setTokenEnd(const char *tokenEnd) { stdstr(&(this->tokenEnd), tokenEnd); + tokenEndLen = strlen(tokenEnd); } -char SWBasicFilter::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) { - this->key = key; - this->module = module; - char *to, *from, token[4096]; +char SWBasicFilter::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + char *from; + char token[4096]; int tokpos = 0; - bool intoken = false; - int len; + bool intoken = false; bool inEsc = false; - char escStartLen = strlen(escStart); - char escEndLen = strlen(escEnd); char escStartPos = 0, escEndPos = 0; - char tokenStartLen = strlen(tokenStart); - char tokenEndLen = strlen(tokenEnd); char tokenStartPos = 0, tokenEndPos = 0; - DualStringMap userData; - string lastTextNode; + SWBuf lastTextNode; + BasicFilterUserData *userData = createUserData(module, key); - bool suspendTextPassThru = false; - userData["suspendTextPassThru"] = "false"; + SWBuf orig = text; + from = orig.getRawData(); + text = ""; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; + if (processStages & INITIALIZE) { + if (processStage(INITIALIZE, text, from, userData)) { // processStage handled it all + delete userData; + return 0; + } } - else from = text; // ------------------------------- + for (;*from; from++) { + + if (processStages & PRECHAR) { + if (processStage(PRECHAR, text, from, userData)) // processStage handled this char + continue; + } - for (to = text; *from; from++) { if (*from == tokenStart[tokenStartPos]) { if (tokenStartPos == (tokenStartLen - 1)) { intoken = true; @@ -247,15 +262,14 @@ char SWBasicFilter::ProcessText(char *text, int maxlen, const SWKey *key, const if (*from == escEnd[escEndPos]) { if (escEndPos == (escEndLen - 1)) { intoken = false; - userData["lastTextNode"] = lastTextNode; - if ((!handleEscapeString(&to, token, userData)) && (passThruUnknownEsc)) { - pushString(&to, escStart); - pushString(&to, token); - pushString(&to, escEnd); + userData->lastTextNode = lastTextNode; + if ((!handleEscapeString(text, token, userData)) && (passThruUnknownEsc)) { + text += escStart; + text += token; + text += escEnd; } escEndPos = escStartPos = tokenEndPos = tokenStartPos = 0; lastTextNode = ""; - suspendTextPassThru = (!userData["suspendTextPassThru"].compare("true")); continue; } } @@ -265,15 +279,14 @@ char SWBasicFilter::ProcessText(char *text, int maxlen, const SWKey *key, const if (*from == tokenEnd[tokenEndPos]) { if (tokenEndPos == (tokenEndLen - 1)) { intoken = false; - userData["lastTextNode"] = lastTextNode; - if ((!handleToken(&to, token, userData)) && (passThruUnknownToken)) { - pushString(&to, tokenStart); - pushString(&to, token); - pushString(&to, tokenEnd); + userData->lastTextNode = lastTextNode; + if ((!handleToken(text, token, userData)) && (passThruUnknownToken)) { + text += tokenStart; + text += token; + text += tokenEnd; } escEndPos = escStartPos = tokenEndPos = tokenStartPos = 0; lastTextNode = ""; - suspendTextPassThru = (!userData["suspendTextPassThru"].compare("true")); continue; } } @@ -285,15 +298,24 @@ char SWBasicFilter::ProcessText(char *text, int maxlen, const SWKey *key, const token[tokpos+2] = 0; } else { - if (!suspendTextPassThru) - *to++ = *from; - lastTextNode += *from; + if ((!userData->supressAdjacentWhitespace) || (*from != ' ')) { + if (!userData->suspendTextPassThru) + text += *from; + lastTextNode += *from; + } + userData->supressAdjacentWhitespace = false; } + + if (processStages & POSTCHAR) + processStage(POSTCHAR, text, from, userData); + } - *to++ = 0; - *to = 0; - return 0; -} + if (processStages & FINALIZE) + processStage(FINALIZE, text, from, userData); + delete userData; + return 0; +} +SWORD_NAMESPACE_END diff --git a/src/modules/filters/swoptfilter.cpp b/src/modules/filters/swoptfilter.cpp new file mode 100644 index 0000000..4eb3c82 --- /dev/null +++ b/src/modules/filters/swoptfilter.cpp @@ -0,0 +1,38 @@ +/****************************************************************************** + * + * swoptfilter - SWFilter descendant and base class for all option filters + */ + + +#include <swoptfilter.h> + +SWORD_NAMESPACE_START + + +SWOptionFilter::SWOptionFilter(const char *oName, const char *oTip, const StringList *oValues) { + optName = oName; + optTip = oTip; + optValues = oValues; +} + + +SWOptionFilter::~SWOptionFilter() { +} + + +void SWOptionFilter::setOptionValue(const char *ival) { + for (StringList::const_iterator loop = optValues->begin(); loop != optValues->end(); loop++) { + if (!stricmp(loop->c_str(), ival)) { + optionValue = *loop; + option = (!stricmp(ival, "On")); // convenience for boolean filters + break; + } + } +} + +const char *SWOptionFilter::getOptionValue() { + return optionValue; +} + + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlfootnotes.cpp b/src/modules/filters/thmlfootnotes.cpp index d9b1f0e..8b52d98 100644 --- a/src/modules/filters/thmlfootnotes.cpp +++ b/src/modules/filters/thmlfootnotes.cpp @@ -1,103 +1,127 @@ /****************************************************************************** * - * thmlfootnotes - SWFilter decendant to hide or show footnotes + * thmlfootnotes - SWFilter descendant to hide or show footnotes * in a ThML module. */ #include <stdlib.h> -#include <string.h> #include <thmlfootnotes.h> +#include <swmodule.h> +#include <swbuf.h> +#include <versekey.h> +#include <utilxml.h> #ifndef __GNUC__ #else #include <unixstr.h> #endif +SWORD_NAMESPACE_START -const char ThMLFootnotes::on[] = "On"; -const char ThMLFootnotes::off[] = "Off"; -const char ThMLFootnotes::optName[] = "Footnotes"; -const char ThMLFootnotes::optTip[] = "Toggles Footnotes On and Off if they exist"; +const char oName[] = "Footnotes"; +const char oTip[] = "Toggles Footnotes On and Off if they exist"; +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); -ThMLFootnotes::ThMLFootnotes() { - option = false; - options.push_back(on); - options.push_back(off); +ThMLFootnotes::ThMLFootnotes() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); } ThMLFootnotes::~ThMLFootnotes() { } -void ThMLFootnotes::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} -const char *ThMLFootnotes::getOptionValue() -{ - return (option) ? on:off; -} +char ThMLFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + SWBuf token; + bool intoken = false; + bool hide = false; + SWBuf tagText; + XMLTag startTag; + SWBuf refs = ""; + int footnoteNum = 1; + char buf[254]; + VerseKey parser = key->getText(); -char ThMLFootnotes::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ - if (!option) { // if we don't want footnotes - char *to, *from, token[2048]; // cheese. Fix. - int tokpos = 0; - bool intoken = false; - int len; - bool hide = false; + SWBuf orig = text; + const char *from = orig.c_str(); - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; + for (text = ""; *from; from++) { + if (*from == '<') { + intoken = true; + token = ""; + continue; } - else from = text; // ------------------------------- + if (*from == '>') { // process tokens + intoken = false; - for (to = text; *from; from++) { - if (*from == '<') { - intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; - continue; - } - if (*from == '>') { // process tokens - intoken = false; - if (!strncmp(token, "note", 4)) { - hide = true; - continue; + XMLTag tag(token); + if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + refs = ""; + startTag = tag; + hide = true; + tagText = ""; + continue; + } } - else if (!strncmp(token, "/note", 5)) { - hide = false; - continue; + if (hide && tag.isEndTag()) { + if (module->isProcessEntryAttributes()) { + SWBuf fc = module->getEntryAttributes()["Footnote"]["count"]["value"]; + footnoteNum = (fc.length()) ? atoi(fc.c_str()) : 0; + sprintf(buf, "%i", ++footnoteNum); + module->getEntryAttributes()["Footnote"]["count"]["value"] = buf; + StringList attributes = startTag.getAttributeNames(); + for (StringList::iterator it = attributes.begin(); it != attributes.end(); it++) { + module->getEntryAttributes()["Footnote"][buf][it->c_str()] = startTag.getAttribute(it->c_str()); + } + module->getEntryAttributes()["Footnote"][buf]["body"] = tagText; + 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(); + module->getEntryAttributes()["Footnote"][buf]["refList"] = refs.c_str(); + } + } + hide = false; + if ((option) || ((startTag.getAttribute("type") && (!strcmp(startTag.getAttribute("type"), "crossReference"))))) { // we want the tag in the text; crossReferences are handled by another filter + text += startTag; + text.append(tagText); + } + else continue; } + } - // if not a footnote token, keep token in text - if (!hide) { - *to++ = '<'; - for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; - } - continue; + // if not a note token, keep token in text + if ((!strcmp(tag.getName(), "scripRef")) && (!tag.isEndTag())) { + SWBuf osisRef = tag.getAttribute("passage"); + if (refs.length()) + refs += "; "; + refs += osisRef; } - if (intoken) { - if (tokpos < 2045) - token[tokpos++] = *from; - token[tokpos+2] = 0; + if (!hide) { + text += '<'; + text.append(token); + text += '>'; } - else { - if (!hide) { - *to++ = *from; - } + else { + tagText += '<'; + tagText.append(token); + tagText += '>'; } + continue; + } + if (intoken) { //copy token + token += *from; } - *to++ = 0; - *to = 0; + else if (!hide) { //copy text which is not inside a token + text += *from; + } + else tagText += *from; } return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlgbf.cpp b/src/modules/filters/thmlgbf.cpp index 66d9a20..a65ddaf 100644 --- a/src/modules/filters/thmlgbf.cpp +++ b/src/modules/filters/thmlgbf.cpp @@ -15,18 +15,18 @@ ***************************************************************************/ #include <stdlib.h> -#include <string.h> #include <thmlgbf.h> +SWORD_NAMESPACE_START ThMLGBF::ThMLGBF() { } -char ThMLGBF::ProcessText(char *text, int maxlen) -{ - char *to, *from, token[2048]; +char ThMLGBF::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + const char *from; + char token[2048]; int tokpos = 0; bool intoken = false; int len; @@ -34,13 +34,10 @@ char ThMLGBF::ProcessText(char *text, int maxlen) bool sechead = false; bool title = false; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- - for (to = text; *from; from++) { + SWBuf orig = text; + from = orig.c_str(); + + for (text = ""; *from; from++) { if (*from == '<') { intoken = true; tokpos = 0; @@ -60,102 +57,102 @@ char ThMLGBF::ProcessText(char *text, int maxlen) if (*from == ';' && ampersand) { intoken = false; - if (!strncmp("nbsp", token, 4)) *to++ = ' '; - else if (!strncmp("quot", token, 4)) *to++ = '"'; - else if (!strncmp("amp", token, 3)) *to++ = '&'; - else if (!strncmp("lt", token, 2)) *to++ = '<'; - else if (!strncmp("gt", token, 2)) *to++ = '>'; - else if (!strncmp("brvbar", token, 6)) *to++ = '|'; - else if (!strncmp("sect", token, 4)) *to++ = '§'; - else if (!strncmp("copy", token, 4)) *to++ = '©'; - else if (!strncmp("laquo", token, 5)) *to++ = '«'; - else if (!strncmp("reg", token, 3)) *to++ = '®'; - else if (!strncmp("acute", token, 5)) *to++ = '´'; - else if (!strncmp("para", token, 4)) *to++ = '¶'; - else if (!strncmp("raquo", token, 5)) *to++ = '»'; + if (!strncmp("nbsp", token, 4)) text += ' '; + else if (!strncmp("quot", token, 4)) text += '"'; + 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("Aacute", token, 6)) *to++ = 'Á'; - else if (!strncmp("Agrave", token, 6)) *to++ = 'À'; - else if (!strncmp("Acirc", token, 5)) *to++ = 'Â'; - else if (!strncmp("Auml", token, 4)) *to++ = 'Ä'; - else if (!strncmp("Atilde", token, 6)) *to++ = 'Ã'; - else if (!strncmp("Aring", token, 5)) *to++ = 'Å'; - else if (!strncmp("aacute", token, 6)) *to++ = 'á'; - else if (!strncmp("agrave", token, 6)) *to++ = 'à'; - else if (!strncmp("acirc", token, 5)) *to++ = 'â'; - else if (!strncmp("auml", token, 4)) *to++ = 'ä'; - else if (!strncmp("atilde", token, 6)) *to++ = 'ã'; - else if (!strncmp("aring", token, 5)) *to++ = 'å'; - else if (!strncmp("Eacute", token, 6)) *to++ = 'É'; - else if (!strncmp("Egrave", token, 6)) *to++ = 'È'; - else if (!strncmp("Ecirc", token, 5)) *to++ = 'Ê'; - else if (!strncmp("Euml", token, 4)) *to++ = 'Ë'; - else if (!strncmp("eacute", token, 6)) *to++ = 'é'; - else if (!strncmp("egrave", token, 6)) *to++ = 'è'; - else if (!strncmp("ecirc", token, 5)) *to++ = 'ê'; - else if (!strncmp("euml", token, 4)) *to++ = 'ë'; - else if (!strncmp("Iacute", token, 6)) *to++ = 'Í'; - else if (!strncmp("Igrave", token, 6)) *to++ = 'Ì'; - else if (!strncmp("Icirc", token, 5)) *to++ = 'Î'; - else if (!strncmp("Iuml", token, 4)) *to++ = 'Ï'; - else if (!strncmp("iacute", token, 6)) *to++ = 'í'; - else if (!strncmp("igrave", token, 6)) *to++ = 'ì'; - else if (!strncmp("icirc", token, 5)) *to++ = 'î'; - else if (!strncmp("iuml", token, 4)) *to++ = 'ï'; - else if (!strncmp("Oacute", token, 6)) *to++ = 'Ó'; - else if (!strncmp("Ograve", token, 6)) *to++ = 'Ò'; - else if (!strncmp("Ocirc", token, 5)) *to++ = 'Ô'; - else if (!strncmp("Ouml", token, 4)) *to++ = 'Ö'; - else if (!strncmp("Otilde", token, 6)) *to++ = 'Õ'; - else if (!strncmp("oacute", token, 6)) *to++ = 'ó'; - else if (!strncmp("ograve", token, 6)) *to++ = 'ò'; - else if (!strncmp("ocirc", token, 5)) *to++ = 'ô'; - else if (!strncmp("ouml", token, 4)) *to++ = 'ö'; - else if (!strncmp("otilde", token, 6)) *to++ = 'õ'; - else if (!strncmp("Uacute", token, 6)) *to++ = 'Ú'; - else if (!strncmp("Ugrave", token, 6)) *to++ = 'Ù'; - else if (!strncmp("Ucirc", token, 5)) *to++ = 'Û'; - else if (!strncmp("Uuml", token, 4)) *to++ = 'Ü'; - else if (!strncmp("uacute", token, 6)) *to++ = 'ú'; - else if (!strncmp("ugrave", token, 6)) *to++ = 'ù'; - else if (!strncmp("ucirc", token, 5)) *to++ = 'û'; - else if (!strncmp("uuml", token, 4)) *to++ = 'ü'; - else if (!strncmp("Yacute", token, 6)) *to++ = 'Ý'; - else if (!strncmp("yacute", token, 6)) *to++ = 'ý'; - else if (!strncmp("yuml", token, 4)) *to++ = 'ÿ'; + 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)) *to++ = '°'; - else if (!strncmp("plusmn", token, 6)) *to++ = '±'; - else if (!strncmp("sup2", token, 4)) *to++ = '²'; - else if (!strncmp("sup3", token, 4)) *to++ = '³'; - else if (!strncmp("sup1", token, 4)) *to++ = '¹'; - else if (!strncmp("nbsp", token, 4)) *to++ = 'º'; - else if (!strncmp("pound", token, 5)) *to++ = '£'; - else if (!strncmp("cent", token, 4)) *to++ = '¢'; - else if (!strncmp("frac14", token, 6)) *to++ = '¼'; - else if (!strncmp("frac12", token, 6)) *to++ = '½'; - else if (!strncmp("frac34", token, 6)) *to++ = '¾'; - else if (!strncmp("iquest", token, 6)) *to++ = '¿'; - else if (!strncmp("iexcl", token, 5)) *to++ = '¡'; - else if (!strncmp("ETH", token, 3)) *to++ = 'Ð'; - else if (!strncmp("eth", token, 3)) *to++ = 'ð'; - else if (!strncmp("THORN", token, 5)) *to++ = 'Þ'; - else if (!strncmp("thorn", token, 5)) *to++ = 'þ'; - else if (!strncmp("AElig", token, 5)) *to++ = 'Æ'; - else if (!strncmp("aelig", token, 5)) *to++ = 'æ'; - else if (!strncmp("Oslash", token, 6)) *to++ = 'Ø'; - else if (!strncmp("curren", token, 6)) *to++ = '¤'; - else if (!strncmp("Ccedil", token, 6)) *to++ = 'Ç'; - else if (!strncmp("ccedil", token, 6)) *to++ = 'ç'; - else if (!strncmp("szlig", token, 5)) *to++ = 'ß'; - else if (!strncmp("Ntilde", token, 6)) *to++ = 'Ñ'; - else if (!strncmp("ntilde", token, 6)) *to++ = 'ñ'; - else if (!strncmp("yen", token, 3)) *to++ = '¥'; - else if (!strncmp("not", token, 3)) *to++ = '¬'; - else if (!strncmp("ordf", token, 4)) *to++ = 'ª'; - else if (!strncmp("uml", token, 3)) *to++ = '¨'; - else if (!strncmp("shy", token, 3)) *to++ = ''; - else if (!strncmp("macr", token, 4)) *to++ = '¯'; + 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 += '¯'; continue; } @@ -163,152 +160,95 @@ char ThMLGBF::ProcessText(char *text, int maxlen) intoken = false; // process desired tokens if (!strncmp(token, "sync type=\"Strongs\" value=\"", 27)) { - *to++ = '<'; - *to++ = 'W'; + text += "<W"; for (unsigned int i = 27; token[i] != '\"'; i++) - *to++ = token[i]; - *to++ = '>'; + text += token[i]; + text += '>'; continue; } if (!strncmp(token, "sync type=\"morph\" value=\"", 25)) { - *to++ = '<'; - *to++ = 'W'; - *to++ = 'T'; + text += "<WT"; for (unsigned int i = 25; token[i] != '\"'; i++) - *to++ = token[i]; - *to++ = '>'; + text += token[i]; + text += '>'; continue; } else if (!strncmp(token, "scripRef", 8)) { - *to++ = '<'; - *to++ = 'R'; - *to++ = 'X'; - *to++ = '>'; + text += "<RX>"; continue; } - else if (!strncmp(token, "/scripRef", 9)) { - *to++ = '<'; - *to++ = 'R'; - *to++ = 'x'; - *to++ = '>'; + else if (!strncmp(token, "/scripRef", 9)) { + text += "<Rx>"; continue; } else if (!strncmp(token, "note", 4)) { - *to++ = '<'; - *to++ = 'R'; - *to++ = 'F'; - *to++ = '>'; + text += "<RF>"; continue; } else if (!strncmp(token, "/note", 5)) { - *to++ = '<'; - *to++ = 'R'; - *to++ = 'f'; - *to++ = '>'; + text += "<Rf>"; continue; } else if (!strncmp(token, "sup", 3)) { - *to++ = '<'; - *to++ = 'F'; - *to++ = 'S'; - *to++ = '>'; + text += "<FS>"; } else if (!strncmp(token, "/sup", 4)) { - *to++ = '<'; - *to++ = 'F'; - *to++ = 's'; - *to++ = '>'; + text += "<Fs>"; } else if (!strnicmp(token, "font color=#ff0000", 18)) { - *to++ = '<'; - *to++ = 'F'; - *to++ = 'R'; - *to++ = '>'; + text += "<FR>"; continue; } else if (!strnicmp(token, "/font", 5)) { - *to++ = '<'; - *to++ = 'F'; - *to++ = 'r'; - *to++ = '>'; + text += "<Fr>"; continue; } else if (!strncmp(token, "div class=\"sechead\"", 19)) { - *to++ = '<'; - *to++ = 'T'; - *to++ = 'S'; - *to++ = '>'; + text += "<TS>"; sechead = true; continue; } else if (sechead && !strncmp(token, "/div", 19)) { - *to++ = '<'; - *to++ = 'T'; - *to++ = 's'; - *to++ = '>'; + text += "<Ts>"; sechead = false; continue; } else if (!strncmp(token, "div class=\"title\"", 19)) { - *to++ = '<'; - *to++ = 'T'; - *to++ = 'T'; - *to++ = '>'; + text += "<TT>"; title = true; continue; } else if (title && !strncmp(token, "/div", 19)) { - *to++ = '<'; - *to++ = 'T'; - *to++ = 't'; - *to++ = '>'; + text += "<Tt>"; title = false; continue; } else if (!strnicmp(token, "br", 2)) { - *to++ = '<'; - *to++ = 'C'; - *to++ = 'L'; - *to++ = '>'; + text += "<CL>"; continue; } else switch(*token) { case 'I': // font tags case 'i': - *to++ = '<'; - *to++ = 'F'; - *to++ = 'I'; - *to++ = '>'; + text += "<FI>"; continue; case 'B': // bold start case 'b': - *to++ = '<'; - *to++ = 'F'; - *to++ = 'B'; - *to++ = '>'; + text += "<FB>"; continue; case '/': switch(token[1]) { case 'P': case 'p': - *to++ = '<'; - *to++ = 'C'; - *to++ = 'M'; - *to++ = '>'; + text += "<CM>"; continue; case 'I': case 'i': // italic end - *to++ = '<'; - *to++ = 'F'; - *to++ = 'i'; - *to++ = '>'; + text += "<Fi>"; continue; case 'B': // bold start case 'b': - *to++ = '<'; - *to++ = 'F'; - *to++ = 'b'; - *to++ = '>'; + text += "<Fb>"; continue; } } @@ -319,12 +259,25 @@ char ThMLGBF::ProcessText(char *text, int maxlen) token[tokpos++] = *from; token[tokpos+2] = 0; } - else *to++ = *from; + else text += *from; } - *to++ = 0; - *to = 0; + + orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) { //loop to remove extra spaces + if ((strchr(" \t\n\r", *from))) { + while (*(from+1) && (strchr(" \t\n\r", *(from+1)))) { + from++; + } + text += " "; + } + else { + text += *from; + } + } + text += (char)0; + return 0; } - - +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlheadings.cpp b/src/modules/filters/thmlheadings.cpp index 00b8a23..bc764bb 100644 --- a/src/modules/filters/thmlheadings.cpp +++ b/src/modules/filters/thmlheadings.cpp @@ -1,107 +1,96 @@ /****************************************************************************** * - * thmlheadings - SWFilter decendant to hide or show headings + * thmlheadings - SWFilter descendant to hide or show headings * in a ThML module. */ #include <stdlib.h> -#include <string.h> #include <thmlheadings.h> +#include <utilxml.h> + +#include <iostream> + #ifndef __GNUC__ #else #include <unixstr.h> #endif +SWORD_NAMESPACE_START -const char ThMLHeadings::on[] = "On"; -const char ThMLHeadings::off[] = "Off"; -const char ThMLHeadings::optName[] = "Headings"; -const char ThMLHeadings::optTip[] = "Toggles Headings On and Off if they exist"; +const char oName[] = "Headings"; +const char oTip[] = "Toggles Headings On and Off if they exist"; +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); -ThMLHeadings::ThMLHeadings() { - option = false; - options.push_back(on); - options.push_back(off); +ThMLHeadings::ThMLHeadings() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); } ThMLHeadings::~ThMLHeadings() { } -void ThMLHeadings::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} - -const char *ThMLHeadings::getOptionValue() -{ - return (option) ? on:off; -} -char ThMLHeadings::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ +char ThMLHeadings::processText(SWBuf &text, const SWKey *key, const SWModule *module) { if (!option) { // if we don't want headings - char *to, *from, token[2048]; // cheese. Fix. - int tokpos = 0; + SWBuf token; bool intoken = false; - int len; bool hide = false; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- + SWBuf orig = text; + const char *from = orig.c_str(); - for (to = text; *from; from++) { + for (text = ""; *from; from++) { if (*from == '<') { intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; + token = ""; continue; } if (*from == '>') { // process tokens intoken = false; - if (!strnicmp(token, "div class=\"sechead\"", 19)) { + + XMLTag tag(token); + + if (!stricmp(tag.getName(), "div")) { //we only want a div tag + //std::cout << tag.toString() << " " << tag.isEndTag() << std::endl; + + if (tag.getAttribute("class") && !stricmp(tag.getAttribute("class"), "sechead")) { hide = true; continue; - } - if (!strnicmp(token, "div class=\"title\"", 17)) { + } + + if (tag.getAttribute("class") && !stricmp(tag.getAttribute("class"), "title")) { hide = true; continue; - } - else if (hide && !strnicmp(token, "/div", 4)) { - hide = false; - continue; + } + + if (hide && tag.isEndTag()) { + hide = false; + continue; + } + } // if not a heading token, keep token in text if (!hide) { - *to++ = '<'; - for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; + text += '<'; + text += token; + text += '>'; } continue; } - if (intoken) { - if (tokpos < 2045) - token[tokpos++] = *from; - token[tokpos+2] = 0; + + if (intoken) { //copy token + token += *from; } - else { - if (!hide) { - *to++ = *from; - } + else if (!hide) { //copy text which is not inside a token + text += *from; } } - *to++ = 0; - *to = 0; } return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlhtml.cpp b/src/modules/filters/thmlhtml.cpp index 9cb8679..40b3320 100644 --- a/src/modules/filters/thmlhtml.cpp +++ b/src/modules/filters/thmlhtml.cpp @@ -15,10 +15,11 @@ ***************************************************************************/ #include <stdlib.h> -#include <string.h> #include <thmlhtml.h> #include <swmodule.h> +#include <utilxml.h> +SWORD_NAMESPACE_START ThMLHTML::ThMLHTML() { setTokenStart("<"); @@ -128,84 +129,98 @@ ThMLHTML::ThMLHTML() { */ setTokenCaseSensitive(true); - addTokenSubstitute("/scripRef", " </a>"); addTokenSubstitute("note", " <font color=\"#800000\"><small>("); addTokenSubstitute("/note", ")</small></font> "); } -bool ThMLHTML::handleToken(char **buf, const char *token, DualStringMap &userData) { - if (!substituteToken(buf, token)) { - // manually process if it wasn't a simple substitution - if (!strncmp(token, "sync type=\"Strongs\" value=\"", 27)) { - if (token[27] == 'H' || token[27] == 'G' || token[27] == 'A') { - pushString(buf, "<small><em>"); - for (const char *tok = token + 5; *tok; tok++) - if(*tok != '\"') - *(*buf)++ = *tok; - pushString(buf, "</em></small>"); - } - else if (token[27] == 'T') { - pushString(buf, "<small><i>"); - for (unsigned int i = 29; token[i] != '\"'; i++) - *(*buf)++ = token[i]; - pushString(buf, "</i></small>"); - } - } - else if (!strncmp(token, "sync type=\"morph\" value=\"", 25)) { - pushString(buf, "<small><em>"); - for (unsigned int i = 25; token[i] != '\"'; i++) - *(*buf)++ = token[i]; - pushString(buf, "</em></small>"); - } - else if (!strncmp(token, "sync type=\"lemma\" value=\"", 25)) { - pushString(buf, "<small><em>("); - for (unsigned int i = 25; token[i] != '\"'; i++) - *(*buf)++ = token[i]; - pushString(buf, ")</em></small>"); +bool ThMLHTML::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { + if (!substituteToken(buf, token)) { // manually process if it wasn't a simple substitution + MyUserData *u = (MyUserData *)userData; + XMLTag tag(token); + if (!strcmp(tag.getName(), "sync")) { + if (tag.getAttribute("type") && tag.getAttribute("value") && !strcmp(tag.getAttribute("type"), "Strongs")) { + const char* value = tag.getAttribute("value"); + if (*value == 'H' || *value == 'G' || *value == 'A') { + value++; + buf += "<small><em>"; + buf += value; + buf += "</em></small>"; + } + else if (*value == 'T') { + value += 2; + + buf += "<small><i>"; + buf += value; + buf += "</i></small>"; + } + } + else if (tag.getAttribute("type") && tag.getAttribute("value") && !strcmp(tag.getAttribute("type"), "morph")) { + buf += "<small><em>"; + buf += tag.getAttribute("value"); + buf += "</em></small>"; + } + else if (tag.getAttribute("type") && tag.getAttribute("value") && !strcmp(tag.getAttribute("type"), "lemma")) { + buf += "<small><em>("; + buf += tag.getAttribute("value"); + buf += ")</em></small>"; + } } - else if (!strncmp(token, "scripRef", 8)) { - pushString(buf, "<a href=\""); - for (const char *tok = token + 9; *tok; tok++) - if(*tok != '\"') - *(*buf)++ = *tok; - *(*buf)++ = '\"'; - *(*buf)++ = '>'; + else if (!strcmp(tag.getName(), "div")) { + if (tag.isEndTag() && (u->SecHead)) { + buf += "</i></b><br />"; + u->SecHead = false; + } + else if (tag.getAttribute("class")) { + if (!strcmp(tag.getAttribute("class"), "sechead")) { + u->SecHead = true; + buf += "<br /><b><i>"; + } + else if (!strcmp(tag.getAttribute("class"), "title")) { + u->SecHead = true; + buf += "<br /><b><i>"; + } + } } - else if (!strncmp(token, "img ", 4)) { + else if (!strcmp(tag.getName(), "img")) { const char *src = strstr(token, "src"); if (!src) // assert we have a src attribute return false; - *(*buf)++ = '<'; + buf += '<'; for (const char *c = token; *c; c++) { if (c == src) { for (;((*c) && (*c != '"')); c++) - *(*buf)++ = *c; + buf += *c; if (!*c) { c--; continue; } - *(*buf)++ = '"'; + buf += '"'; if (*(c+1) == '/') { - pushString(buf, "file:"); - pushString(buf, module->getConfigEntry("AbsoluteDataPath")); - if (*((*buf)-1) == '/') + buf += "file:"; + buf += userData->module->getConfigEntry("AbsoluteDataPath"); + if (buf[buf.length()-2] == '/') c++; // skip '/' } continue; } - *(*buf)++ = *c; + buf += *c; } - *(*buf)++ = '>'; + buf += '>'; } - else if(!strncmp(token, "note", 4)) { - pushString(buf, " <font color=\"#800000\"><small>("); - } + else if (!strcmp(tag.getName(), "scripRef")) { //do nothing with scrip refs, we leave them out + } else { - return false; // we still didn't handle token + buf += '<'; + buf += token; + buf += '>'; + +// return false; // we still didn't handle token } } return true; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlhtmlhref.cpp b/src/modules/filters/thmlhtmlhref.cpp index ce7e3fd..b94b8ae 100644 --- a/src/modules/filters/thmlhtmlhref.cpp +++ b/src/modules/filters/thmlhtmlhref.cpp @@ -15,255 +15,195 @@ ***************************************************************************/ #include <stdlib.h> -#include <string.h> #include <thmlhtmlhref.h> #include <swmodule.h> +#include <utilxml.h> +#include <versekey.h> +SWORD_NAMESPACE_START -ThMLHTMLHREF::ThMLHTMLHREF() { - setTokenStart("<"); - setTokenEnd(">"); -/* - setEscapeStart("&"); - setEscapeEnd(";"); - setEscapeStringCaseSensitive(true); +ThMLHTMLHREF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) { + if (module) { + version = module->Name(); + BiblicalText = (!strcmp(module->Type(), "Biblical Texts")); + } +} - addEscapeStringSubstitute("nbsp", " "); - addEscapeStringSubstitute("quot", "\""); - addEscapeStringSubstitute("amp", "&"); - addEscapeStringSubstitute("lt", "<"); - addEscapeStringSubstitute("gt", ">"); - addEscapeStringSubstitute("brvbar", "|"); - addEscapeStringSubstitute("sect", "§"); - addEscapeStringSubstitute("copy", "©"); - addEscapeStringSubstitute("laquo", "«"); - addEscapeStringSubstitute("reg", "®"); - addEscapeStringSubstitute("acute", "´"); - addEscapeStringSubstitute("para", "¶"); - addEscapeStringSubstitute("raquo", "»"); - addEscapeStringSubstitute("Aacute", "Á"); - addEscapeStringSubstitute("Agrave", "À"); - addEscapeStringSubstitute("Acirc", "Â"); - addEscapeStringSubstitute("Auml", "Ä"); - addEscapeStringSubstitute("Atilde", "Ã"); - addEscapeStringSubstitute("Aring", "Å"); - addEscapeStringSubstitute("aacute", "á"); - addEscapeStringSubstitute("agrave", "à"); - addEscapeStringSubstitute("acirc", "â"); - addEscapeStringSubstitute("auml", "ä"); - addEscapeStringSubstitute("atilde", "ã"); - addEscapeStringSubstitute("aring", "å"); - addEscapeStringSubstitute("Eacute", "É"); - addEscapeStringSubstitute("Egrave", "È"); - addEscapeStringSubstitute("Ecirc", "Ê"); - addEscapeStringSubstitute("Euml", "Ë"); - addEscapeStringSubstitute("eacute", "é"); - addEscapeStringSubstitute("egrave", "è"); - addEscapeStringSubstitute("ecirc", "ê"); - addEscapeStringSubstitute("euml", "ë"); - addEscapeStringSubstitute("Iacute", "Í"); - addEscapeStringSubstitute("Igrave", "Ì"); - addEscapeStringSubstitute("Icirc", "Î"); - addEscapeStringSubstitute("Iuml", "Ï"); - addEscapeStringSubstitute("iacute", "í"); - addEscapeStringSubstitute("igrave", "ì"); - addEscapeStringSubstitute("icirc", "î"); - addEscapeStringSubstitute("iuml", "ï"); - addEscapeStringSubstitute("Oacute", "Ó"); - addEscapeStringSubstitute("Ograve", "Ò"); - addEscapeStringSubstitute("Ocirc", "Ô"); - addEscapeStringSubstitute("Ouml", "Ö"); - addEscapeStringSubstitute("Otilde", "Õ"); - addEscapeStringSubstitute("oacute", "ó"); - addEscapeStringSubstitute("ograve", "ò"); - addEscapeStringSubstitute("ocirc", "ô"); - addEscapeStringSubstitute("ouml", "ö"); - addEscapeStringSubstitute("otilde", "õ"); - addEscapeStringSubstitute("Uacute", "Ú"); - addEscapeStringSubstitute("Ugrave", "Ù"); - addEscapeStringSubstitute("Ucirc", "Û"); - addEscapeStringSubstitute("Uuml", "Ü"); - addEscapeStringSubstitute("uacute", "ú"); - addEscapeStringSubstitute("ugrave", "ù"); - addEscapeStringSubstitute("ucirc", "û"); - addEscapeStringSubstitute("uuml", "ü"); - addEscapeStringSubstitute("Yacute", "Ý"); - addEscapeStringSubstitute("yacute", "ý"); - addEscapeStringSubstitute("yuml", "ÿ"); +ThMLHTMLHREF::ThMLHTMLHREF() { + setTokenStart("<"); + setTokenEnd(">"); - addEscapeStringSubstitute("deg", "°"); - addEscapeStringSubstitute("plusmn", "±"); - addEscapeStringSubstitute("sup2", "²"); - addEscapeStringSubstitute("sup3", "³"); - addEscapeStringSubstitute("sup1", "¹"); - addEscapeStringSubstitute("nbsp", "º"); - addEscapeStringSubstitute("pound", "£"); - addEscapeStringSubstitute("cent", "¢"); - addEscapeStringSubstitute("frac14", "¼"); - addEscapeStringSubstitute("frac12", "½"); - addEscapeStringSubstitute("frac34", "¾"); - addEscapeStringSubstitute("iquest", "¿"); - addEscapeStringSubstitute("iexcl", "¡"); - addEscapeStringSubstitute("ETH", "Ð"); - addEscapeStringSubstitute("eth", "ð"); - addEscapeStringSubstitute("THORN", "Þ"); - addEscapeStringSubstitute("thorn", "þ"); - addEscapeStringSubstitute("AElig", "Æ"); - addEscapeStringSubstitute("aelig", "æ"); - addEscapeStringSubstitute("Oslash", "Ø"); - addEscapeStringSubstitute("curren", "¤"); - addEscapeStringSubstitute("Ccedil", "Ç"); - addEscapeStringSubstitute("ccedil", "ç"); - addEscapeStringSubstitute("szlig", "ß"); - addEscapeStringSubstitute("Ntilde", "Ñ"); - addEscapeStringSubstitute("ntilde", "ñ"); - addEscapeStringSubstitute("yen", "¥"); - addEscapeStringSubstitute("not", "¬"); - addEscapeStringSubstitute("ordf", "ª"); - addEscapeStringSubstitute("uml", "¨"); - addEscapeStringSubstitute("shy", ""); - addEscapeStringSubstitute("macr", "¯"); -*/ setTokenCaseSensitive(true); - - addTokenSubstitute("note", " <font color=\"#800000\"><small>("); - addTokenSubstitute("/note", ")</small></font> "); + addTokenSubstitute("scripture", "<i> "); addTokenSubstitute("/scripture", "</i> "); } -bool ThMLHTMLHREF::handleToken(char **buf, const char *token, DualStringMap &userData) { +bool ThMLHTMLHREF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { const char *tok; - if (!substituteToken(buf, token)) { - // manually process if it wasn't a simple substitution - if (!strncmp(token, "sync ", 5)) { - pushString(buf, "<a href=\""); - for (tok = token + 5; *(tok+1); tok++) - if(*tok != '\"') - *(*buf)++ = *tok; - *(*buf)++ = '\"'; - *(*buf)++ = '>'; - - //scan for value and add it to the buffer - for (tok = token + 5; *tok; tok++) { - if (!strncmp(tok, "value=\"", 7)) { - tok += 7; - for (;*tok != '\"'; tok++) - *(*buf)++ = *tok; - break; - } + if (!substituteToken(buf, token)) { // manually process if it wasn't a simple substitution + MyUserData *u = (MyUserData *)userData; + + XMLTag tag(token); + if ((!tag.isEndTag()) && (!tag.isEmpty())) + u->startTag = tag; + + if (tag.getName() && !strcmp(tag.getName(), "sync")) { + SWBuf value = tag.getAttribute("value"); + if (tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "morph")) { //> + buf += "<small><em>(<a href=\""; + buf += "type="; + buf += tag.getAttribute("type"); + + //const char* value = tag.getAttribute("value"); + buf += " value="; + buf += (value.length()) ? value.c_str() : ""; + buf += "\">"; + buf += (value.length()) ? value.c_str() : ""; + buf += "</a>) </em></small>"; + } + else if (tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "Strongs")) { + buf += "<small><em><<a href=\""; + buf += "type="; + buf += tag.getAttribute("type"); + + //const char* value = tag.getAttribute("value"); + buf += " value="; + buf += (value.length()) ? value.c_str() : ""; + buf += "\">"; + value<<1; + buf += (value.length()) ? value.c_str() : ""; + buf += "</a>> </em></small>"; + } + else if (tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "Dict")) { + if (!tag.isEndTag()) + buf += "<b>"; + else buf += "</b>"; } - pushString(buf, "</a>"); + } - - else if (!strncmp(token, "scripture ", 10)) { - userData["inscriptRef"] = "true"; - pushString(buf, "<i>"); - } - - else if (!strncmp(token, "scripRef p", 10) || !strncmp(token, "scripRef v", 10)) { - userData["inscriptRef"] = "true"; - pushString(buf, "<a href=\""); - for (const char *tok = token + 9; *(tok+1); tok++) - if(*tok != '\"') - *(*buf)++ = *tok; - *(*buf)++ = '\"'; - *(*buf)++ = '>'; - } - - // we're starting a scripRef like "<scripRef>John 3:16</scripRef>" - else if (!strcmp(token, "scripRef")) { - userData["inscriptRef"] = "false"; - // let's stop text from going to output - userData["suspendTextPassThru"] = "true"; + // <note> tag + else if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + SWBuf type = tag.getAttribute("type"); + SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) { } + if (vkey) { + // leave this special osis type in for crossReference notes types? Might thml use this some day? Doesn't hurt. + char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n'); + buf.appendFormatted("<a href=\"noteID=%s.%c.%s\"><small><sup>*%c</sup></small></a> ", vkey->getText(), ch, footnoteNumber.c_str(), ch); + } + u->suspendTextPassThru = true; + } + } + if (tag.isEndTag()) { + u->suspendTextPassThru = false; + } } - - // we've ended a scripRef - else if (!strcmp(token, "/scripRef")) { - if (userData["inscriptRef"] == "true") { // like "<scripRef passage="John 3:16">John 3:16</scripRef>" - userData["inscriptRef"] = "false"; - pushString(buf, "</a>"); + // <scripRef> tag + else if (!strcmp(tag.getName(), "scripRef")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + u->suspendTextPassThru = true; + } } - - else { // like "<scripRef>John 3:16</scripRef>" - pushString(buf, "<a href=\"passage="); - //char *strbuf = (char *)userData["lastTextNode"].c_str(); - pushString(buf, userData["lastTextNode"].c_str()); - *(*buf)++ = '\"'; - *(*buf)++ = '>'; - pushString(buf, userData["lastTextNode"].c_str()); + if (tag.isEndTag()) { // </scripRef> + if (!u->BiblicalText) { + SWBuf refList = u->startTag.getAttribute("passage"); + if (!refList.length()) + refList = u->lastTextNode; + SWBuf version = tag.getAttribute("version"); + buf += " <a href=\""; + if (version.length()) { + buf += "version="; + buf += version; + buf += " "; + } + buf += "passage="; + buf += refList.c_str(); + buf += "\">"; + buf += u->lastTextNode.c_str(); + buf += "</a> "; + } + else { + SWBuf footnoteNumber = u->startTag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) {} + 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()); + } + } + // let's let text resume to output again - userData["suspendTextPassThru"] = "false"; - pushString(buf, "</a>"); + u->suspendTextPassThru = false; } } - - else if (!strncmp(token, "div class=\"sechead\"", 19)) { - userData["SecHead"] = "true"; - pushString(buf, "<br /><b><i>"); - } - else if (!strncmp(token, "div class=\"title\"", 19)) { - userData["SecHead"] = "true"; - pushString(buf, "<br /><b><i>"); - } - else if (!strncmp(token, "/div", 4)) { - if (userData["SecHead"] == "true") { - pushString(buf, "</i></b><br />"); - userData["SecHead"] = "false"; + else if (tag.getName() && !strcmp(tag.getName(), "div")) { + if (tag.isEndTag() && u->SecHead) { + buf += "</i></b><br />"; + u->SecHead = false; + } + else if (tag.getAttribute("class")) { + if (!stricmp(tag.getAttribute("class"), "sechead")) { + u->SecHead = true; + buf += "<br /><b><i>"; + } + else if (!stricmp(tag.getAttribute("class"), "title")) { + u->SecHead = true; + buf += "<br /><b><i>"; + } } } - - else if (!strncmp(token, "sync type=\"Strongs\" value=\"T", 28)) { - pushString(buf, "<a href=\""); - for (tok = token + 5; *(tok+1); tok++) - if(*tok != '\"') - *(*buf)++ = *tok; - *(*buf)++ = '\"'; - *(*buf)++ = '>'; - for (tok = token + 29; *(tok+2); tok++) - if(*tok != '\"') - *(*buf)++ = *tok; - pushString(buf, "</a>"); - } - else if (!strncmp(token, "img ", 4)) { + else if (tag.getName() && (!strcmp(tag.getName(), "img") || !strcmp(tag.getName(), "image"))) { const char *src = strstr(token, "src"); if (!src) // assert we have a src attribute return false; - *(*buf)++ = '<'; + buf += '<'; for (const char *c = token; *c; c++) { if (c == src) { for (;((*c) && (*c != '"')); c++) - *(*buf)++ = *c; + buf += *c; if (!*c) { c--; continue; } - *(*buf)++ = '"'; + buf += '"'; if (*(c+1) == '/') { - pushString(buf, "file:"); - pushString(buf, module->getConfigEntry("AbsoluteDataPath")); - if (*((*buf)-1) == '/') + buf += "file:"; + buf += userData->module->getConfigEntry("AbsoluteDataPath"); + if (buf[buf.length()-2] == '/') c++; // skip '/' } continue; } - *(*buf)++ = *c; + buf += *c; } - *(*buf)++ = '>'; + buf += '>'; } - else if (!strncmp(token, "note", 4)) { - pushString(buf, " <small><font color=\"#800000\">("); - } else { - *(*buf)++ = '<'; - for (const char *tok = token; *tok; tok++) - *(*buf)++ = *tok; - *(*buf)++ = '>'; + buf += '<'; + /*for (const char *tok = token; *tok; tok++) + buf += *tok;*/ + buf += token; + buf += '>'; //return false; // we still didn't handle token } } return true; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmllemma.cpp b/src/modules/filters/thmllemma.cpp index 33856db..02939df 100644 --- a/src/modules/filters/thmllemma.cpp +++ b/src/modules/filters/thmllemma.cpp @@ -1,97 +1,69 @@ /****************************************************************************** * - * thmllemma - SWFilter decendant to hide or show lemmas + * thmllemma - SWFilter descendant to hide or show lemmas * in a ThML module. */ #include <stdlib.h> -#include <string.h> #include <thmllemma.h> #ifndef __GNUC__ #else #include <unixstr.h> #endif +SWORD_NAMESPACE_START -const char ThMLLemma::on[] = "On"; -const char ThMLLemma::off[] = "Off"; -const char ThMLLemma::optName[] = "Lemmas"; -const char ThMLLemma::optTip[] = "Toggles Lemmas On and Off if they exist"; +const char oName[] = "Lemmas"; +const char oTip[] = "Toggles Lemmas On and Off if they exist"; -ThMLLemma::ThMLLemma() { - option = false; - options.push_back(on); - options.push_back(off); +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +ThMLLemma::ThMLLemma() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); } ThMLLemma::~ThMLLemma() { } -void ThMLLemma::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} - -const char *ThMLLemma::getOptionValue() -{ - return (option) ? on:off; -} -char ThMLLemma::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ +char ThMLLemma::processText(SWBuf &text, const SWKey *key, const SWModule *module) { if (!option) { // if we don't want lemmas - char *to, *from, token[2048]; // cheese. Fix. - int tokpos = 0; bool intoken = false; - int len; - bool lastspace = false; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- - - for (to = text; *from; from++) { + SWBuf token; + SWBuf orig = text; + const char *from = orig.c_str(); + for (text = ""; *from; from++) { if (*from == '<') { intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; + token = ""; continue; } - if (*from == '>') { // process tokens + else if (*from == '>') { // process tokens intoken = false; - if (!strnicmp(token, "sync type=\"lemma\" ", 18)) { // Lemma - if ((from[1] == ' ') || (from[1] == ',') || (from[1] == ';') || (from[1] == '.') || (from[1] == '?') || (from[1] == '!') || (from[1] == ')') || (from[1] == '\'') || (from[1] == '\"')) { - if (lastspace) - to--; - } - continue; + if (!strnicmp(token.c_str(), "sync", 4) && strstr(token.c_str(), " type=\"lemma\"")) { // Lemma + continue; } + // if not a lemma token, keep token in text - *to++ = '<'; - for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; + text += '<'; + text.append(token); + text += '>'; continue; } + if (intoken) { - if (tokpos < 2045) - token[tokpos++] = *from; - token[tokpos+2] = 0; - } - else { - *to++ = *from; - lastspace = (*from == ' '); + token += *from; } + else { + text += *from; + } } - *to++ = 0; - *to = 0; } return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlmorph.cpp b/src/modules/filters/thmlmorph.cpp index f95bede..606ae7e 100644 --- a/src/modules/filters/thmlmorph.cpp +++ b/src/modules/filters/thmlmorph.cpp @@ -1,98 +1,69 @@ /****************************************************************************** * - * thmlmorph - SWFilter decendant to hide or show morph tags + * thmlmorph - SWFilter descendant to hide or show morph tags * in a ThML module. */ #include <stdlib.h> -#include <string.h> #include <thmlmorph.h> #ifndef __GNUC__ #else #include <unixstr.h> #endif +SWORD_NAMESPACE_START -const char ThMLMorph::on[] = "On"; -const char ThMLMorph::off[] = "Off"; -const char ThMLMorph::optName[] = "Morphological Tags"; -const char ThMLMorph::optTip[] = "Toggles Morphological Tags On and Off if they exist"; +const char oName[] = "Morphological Tags"; +const char oTip[] = "Toggles Morphological Tags On and Off if they exist"; +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); -ThMLMorph::ThMLMorph() { - option = false; - options.push_back(on); - options.push_back(off); +ThMLMorph::ThMLMorph() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); } ThMLMorph::~ThMLMorph() { } -void ThMLMorph::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} - -const char *ThMLMorph::getOptionValue() -{ - return (option) ? on:off; -} -char ThMLMorph::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ +char ThMLMorph::processText(SWBuf &text, const SWKey *key, const SWModule *module) { if (!option) { // if we don't want morph tags - char *to, *from, token[2048]; // cheese. Fix. - int tokpos = 0; bool intoken = false; - int len; - bool lastspace = false; - - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- - for (to = text; *from; from++) { + SWBuf token; + SWBuf orig = text; + const char *from = orig.c_str(); + for (text = ""; *from; from++) { if (*from == '<') { intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; + token = ""; continue; } if (*from == '>') { // process tokens intoken = false; - if (!strnicmp(token, "sync type=\"morph\" ", 18)) { // Morph - if ((from[1] == ' ') || (from[1] == ',') || (from[1] == ';') || (from[1] == '.') || (from[1] == '?') || (from[1] == '!') || (from[1] == ')') || (from[1] == '\'') || (from[1] == '\"')) { - if (lastspace) - to--; - } + if (!strncmp(token.c_str(), "sync ", 5) && strstr(token.c_str(), "type=\"morph\"")) { // Morph continue; } + // if not a morph tag token, keep token in text - *to++ = '<'; - for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; + text += '<'; + text += token; + text += '>'; continue; } + if (intoken) { - if (tokpos < 2045) - token[tokpos++] = *from; - token[tokpos+2] = 0; + token += *from; } else { - *to++ = *from; - lastspace = (*from == ' '); + text += *from; } } - *to++ = 0; - *to = 0; } return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlolb.cpp b/src/modules/filters/thmlolb.cpp deleted file mode 100644 index 2b31fab..0000000 --- a/src/modules/filters/thmlolb.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/*************************************************************************** - thmlolb.cpp - ThML to OLB filter - ------------------- - begin : 2001-05-10 - 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. * - * * - ***************************************************************************/ - -#include <stdlib.h> -#include <string.h> -#include <thmlolb.h> - - -ThMLOLB::ThMLOLB() -{ -} - - -char ThMLOLB::ProcessText(char *text, int maxlen) -{ - char *to, *from, token[2048]; - int tokpos = 0; - bool intoken = false; - int len; - bool ampersand = false; - int i; - - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- - for (to = text; *from; from++) - { - if (*from == '<') { - intoken = true; - tokpos = 0; - memset(token, 0, 2048); - ampersand = false; - continue; - } - else if (*from == '&') { - intoken = true; - tokpos = 0; - memset(token, 0, 2048); - ampersand = true; - continue; - } - if (*from == ';' && ampersand) { - intoken = false; - - if (!strncmp("nbsp", token, 4)) *to++ = ' '; - else if (!strncmp("quot", token, 4)) *to++ = '"'; - else if (!strncmp("amp", token, 3)) *to++ = '&'; - else if (!strncmp("lt", token, 2)) *to++ = '<'; - else if (!strncmp("gt", token, 2)) *to++ = '>'; - else if (!strncmp("brvbar", token, 6)) *to++ = '|'; - else if (!strncmp("sect", token, 4)) *to++ = '§'; - else if (!strncmp("copy", token, 4)) *to++ = '©'; - else if (!strncmp("laquo", token, 5)) *to++ = '«'; - else if (!strncmp("reg", token, 3)) *to++ = '®'; - else if (!strncmp("acute", token, 5)) *to++ = '´'; - else if (!strncmp("para", token, 4)) *to++ = '¶'; - else if (!strncmp("raquo", token, 5)) *to++ = '»'; - - else if (!strncmp("Aacute", token, 6)) *to++ = 'Á'; - else if (!strncmp("Agrave", token, 6)) *to++ = 'À'; - else if (!strncmp("Acirc", token, 5)) *to++ = 'Â'; - else if (!strncmp("Auml", token, 4)) *to++ = 'Ä'; - else if (!strncmp("Atilde", token, 6)) *to++ = 'Ã'; - else if (!strncmp("Aring", token, 5)) *to++ = 'Å'; - else if (!strncmp("aacute", token, 6)) *to++ = 'á'; - else if (!strncmp("agrave", token, 6)) *to++ = 'à'; - else if (!strncmp("acirc", token, 5)) *to++ = 'â'; - else if (!strncmp("auml", token, 4)) *to++ = 'ä'; - else if (!strncmp("atilde", token, 6)) *to++ = 'ã'; - else if (!strncmp("aring", token, 5)) *to++ = 'å'; - else if (!strncmp("Eacute", token, 6)) *to++ = 'É'; - else if (!strncmp("Egrave", token, 6)) *to++ = 'È'; - else if (!strncmp("Ecirc", token, 5)) *to++ = 'Ê'; - else if (!strncmp("Euml", token, 4)) *to++ = 'Ë'; - else if (!strncmp("eacute", token, 6)) *to++ = 'é'; - else if (!strncmp("egrave", token, 6)) *to++ = 'è'; - else if (!strncmp("ecirc", token, 5)) *to++ = 'ê'; - else if (!strncmp("euml", token, 4)) *to++ = 'ë'; - else if (!strncmp("Iacute", token, 6)) *to++ = 'Í'; - else if (!strncmp("Igrave", token, 6)) *to++ = 'Ì'; - else if (!strncmp("Icirc", token, 5)) *to++ = 'Î'; - else if (!strncmp("Iuml", token, 4)) *to++ = 'Ï'; - else if (!strncmp("iacute", token, 6)) *to++ = 'í'; - else if (!strncmp("igrave", token, 6)) *to++ = 'ì'; - else if (!strncmp("icirc", token, 5)) *to++ = 'î'; - else if (!strncmp("iuml", token, 4)) *to++ = 'ï'; - else if (!strncmp("Oacute", token, 6)) *to++ = 'Ó'; - else if (!strncmp("Ograve", token, 6)) *to++ = 'Ò'; - else if (!strncmp("Ocirc", token, 5)) *to++ = 'Ô'; - else if (!strncmp("Ouml", token, 4)) *to++ = 'Ö'; - else if (!strncmp("Otilde", token, 6)) *to++ = 'Õ'; - else if (!strncmp("oacute", token, 6)) *to++ = 'ó'; - else if (!strncmp("ograve", token, 6)) *to++ = 'ò'; - else if (!strncmp("ocirc", token, 5)) *to++ = 'ô'; - else if (!strncmp("ouml", token, 4)) *to++ = 'ö'; - else if (!strncmp("otilde", token, 6)) *to++ = 'õ'; - else if (!strncmp("Uacute", token, 6)) *to++ = 'Ú'; - else if (!strncmp("Ugrave", token, 6)) *to++ = 'Ù'; - else if (!strncmp("Ucirc", token, 5)) *to++ = 'Û'; - else if (!strncmp("Uuml", token, 4)) *to++ = 'Ü'; - else if (!strncmp("uacute", token, 6)) *to++ = 'ú'; - else if (!strncmp("ugrave", token, 6)) *to++ = 'ù'; - else if (!strncmp("ucirc", token, 5)) *to++ = 'û'; - else if (!strncmp("uuml", token, 4)) *to++ = 'ü'; - else if (!strncmp("Yacute", token, 6)) *to++ = 'Ý'; - else if (!strncmp("yacute", token, 6)) *to++ = 'ý'; - else if (!strncmp("yuml", token, 4)) *to++ = 'ÿ'; - - else if (!strncmp("deg", token, 3)) *to++ = '°'; - else if (!strncmp("plusmn", token, 6)) *to++ = '±'; - else if (!strncmp("sup2", token, 4)) *to++ = '²'; - else if (!strncmp("sup3", token, 4)) *to++ = '³'; - else if (!strncmp("sup1", token, 4)) *to++ = '¹'; - else if (!strncmp("nbsp", token, 4)) *to++ = 'º'; - else if (!strncmp("pound", token, 5)) *to++ = '£'; - else if (!strncmp("cent", token, 4)) *to++ = '¢'; - else if (!strncmp("frac14", token, 6)) *to++ = '¼'; - else if (!strncmp("frac12", token, 6)) *to++ = '½'; - else if (!strncmp("frac34", token, 6)) *to++ = '¾'; - else if (!strncmp("iquest", token, 6)) *to++ = '¿'; - else if (!strncmp("iexcl", token, 5)) *to++ = '¡'; - else if (!strncmp("ETH", token, 3)) *to++ = 'Ð'; - else if (!strncmp("eth", token, 3)) *to++ = 'ð'; - else if (!strncmp("THORN", token, 5)) *to++ = 'Þ'; - else if (!strncmp("thorn", token, 5)) *to++ = 'þ'; - else if (!strncmp("AElig", token, 5)) *to++ = 'Æ'; - else if (!strncmp("aelig", token, 5)) *to++ = 'æ'; - else if (!strncmp("Oslash", token, 6)) *to++ = 'Ø'; - else if (!strncmp("curren", token, 6)) *to++ = '¤'; - else if (!strncmp("Ccedil", token, 6)) *to++ = 'Ç'; - else if (!strncmp("ccedil", token, 6)) *to++ = 'ç'; - else if (!strncmp("szlig", token, 5)) *to++ = 'ß'; - else if (!strncmp("Ntilde", token, 6)) *to++ = 'Ñ'; - else if (!strncmp("ntilde", token, 6)) *to++ = 'ñ'; - else if (!strncmp("yen", token, 3)) *to++ = '¥'; - else if (!strncmp("not", token, 3)) *to++ = '¬'; - else if (!strncmp("ordf", token, 4)) *to++ = 'ª'; - else if (!strncmp("uml", token, 3)) *to++ = '¨'; - else if (!strncmp("shy", token, 3)) *to++ = ''; - else if (!strncmp("macr", token, 4)) *to++ = '¯'; - continue; - - } - else if (*from == '>' && !ampersand) - { - intoken = false; - // process desired tokens - if (!strncmp(token, "sync type=\"Strongs\" value=\"G", 27)) { - *to++ = '<'; - for (i = 28; token[i] != '\"'; i++) - *to++ = token[i]; - *to++ = '>'; - continue; - } - else if (!strncmp(token, "sync type=\"Strongs\" value=\"H", 27)) { - *to++ = '<'; - for (i = 28; token[i] != '\"'; i++) - *to++ = token[i]; - *to++ = '>'; - continue; - } - else if (!strncmp(token, "scripRef", 8)) { - *to++ = '#'; - continue; - } - else if (!strncmp(token, "/scripRef", 9)) { - *to++ = ' '; - continue; - } - else if (!strncmp(token, "note ", 5)) { - *to++ = '{'; - continue; - } - else if (!strncmp(token, "/note", 5)) { - *to++ = '}'; - continue; - } - else if (!strnicmp(token, "font", 4)) { - *to++ = '\\'; - *to++ = '\\'; - continue; - } - else if (!strnicmp(token, "/font", 5)) { - *to++ = '\\'; - *to++ = '\\'; - continue; - } - else switch(*token) { - case 'I': // font tags - case 'i': - *to++ = '\\'; - *to++ = '@'; - continue; - case 'B': // bold start - case 'b': - *to++ = '\\'; - *to++ = '$'; - continue; - case '/': - switch(token[1]) { - case 'I': - case 'i': // italic end - *to++ = '\\'; - *to++ = '@'; - continue; - case 'B': // bold start - case 'b': - *to++ = '\\'; - *to++ = '$'; - continue; - } - } - continue; - } - if (intoken) { - if (tokpos < 2047) - token[tokpos++] = *from; - } - else *to++ = *from; - } - *to++ = 0; - *to = 0; - return 0; -} - - - diff --git a/src/modules/filters/thmlosis.cpp b/src/modules/filters/thmlosis.cpp new file mode 100644 index 0000000..7208610 --- /dev/null +++ b/src/modules/filters/thmlosis.cpp @@ -0,0 +1,385 @@ +/****************************************************************************** + * + * thmlstrongs - SWFilter descendant to hide or show strongs number + * in a ThML module. + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <thmlosis.h> +#include <swmodule.h> +#include <swlog.h> +#include <versekey.h> +#include <stdarg.h> +#ifndef __GNUC__ +#else +#include <unixstr.h> +#endif + +SWORD_NAMESPACE_START + +ThMLOSIS::ThMLOSIS() { +} + + +ThMLOSIS::~ThMLOSIS() { +} + + +char ThMLOSIS::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + /* + + const char *from; + char token[2048]; // cheese. Fix. + int tokpos = 0; + bool intoken = false; + int len; + bool lastspace = false; + int word = 1; + char val[128]; + char buf[128]; + char wordstr[5]; + char *valto; + char *ch; + char *textStart, *textEnd; + char *wordStart, *wordEnd; + bool newText = false; + bool newWord = false; + SWBuf tmp; + bool suspendTextPassThru = false; + bool keepToken = false; + bool handled = false; + SWBuf divEnd = ""; + + + wordStart = text; + + SWBuf orig = text; + from = orig.c_str(); + + for (text = ""; *from; from++) { + + if (*from == '<') { + intoken = true; + tokpos = 0; + token[0] = 0; + token[1] = 0; + token[2] = 0; + textEnd = from-1; + wordEnd = to; + continue; + } + if (*from == '>') { // process tokens + intoken = false; + keepToken = false; + suspendTextPassThru = false; + newWord = true; + handled = false; + + while (wordStart < (text+maxlen)) { +// if (strchr(" ,;.?!()'\"", *wordStart)) + if (strchr(";,: .?!()'\"", *wordStart)) + wordStart++; + else break; + } + while (wordEnd > wordStart) { + if (strchr(" ,;:.?!()'\"", *wordEnd)) + wordEnd--; + else break; + } + + // section titles + if (!strcmp(token, "div class=\"sechead\"")) { + pushString(&to, "<title>"); + divEnd = "</title>"; + newText = true; + lastspace = false; + handled = true; + } + else if (!strcmp(token, "/div")) { + pushString(&to, divEnd.c_str()); + lastspace = false; + handled = true; + } + // Scripture Reference + if (!strncmp(token, "scripRef", 8)) { + // pushString(buf, "<reference osisRef=\""); + suspendTextPassThru = true; + newText = true; + handled = true; + } + else if (!strncmp(token, "/scripRef", 9)) { + tmp = ""; + tmp.append(textStart, (int)(textEnd - textStart)+1); + pushString(&to, convertToOSIS(tmp.c_str(), key)); + suspendTextPassThru = false; + handled = true; + } +// Usage of italics to represent transChange isn't domaninant; +// solution: mark in OSIS instead, assume no semantics other than emphasis +// of italicized text +// if (!strcmp(module->Type(), "Biblical Texts")) { +// // Italics assume transchange for Biblical texts +// if (!stricmp(token, "i")) { +// pushString(&to, "<transChange type=\"added\">"); +// newText = true; +// lastspace = false; +// handled = true; +// } +// else if (!stricmp(token, "/i")) { +// pushString(&to, "</transChange>"); +// lastspace = false; +// handled = true; +// } +// } +// else { +// // otherwise, italics are just italics +//-- end italics for transchange + if (!stricmp(token, "i")) { + pushString(&to, "<hi type=\"i\">"); + newText = true; + lastspace = false; + handled = true; + } + else if (!stricmp(token, "/i")) { + pushString(&to, "</hi>"); + lastspace = false; + handled = true; + } +// } + + if (!strcmp(token, "b")) { + pushString(&to, "<hi type=\"b\">"); + newText = true; + lastspace = false; + handled = true; + } + else if (!strcmp(token, "/b")) { + pushString(&to, "</hi>"); + lastspace = false; + handled = true; + } + + // Footnote + if (!strcmp(token, "note")) { + pushString(&to, "<note>"); + newText = true; + lastspace = false; + handled = true; + } + else if (!strcmp(token, "/note")) { + pushString(&to, "</note>"); + lastspace = false; + handled = true; + } + + // Figure + else if (!strncmp(token, "img ", 4)) { + const char *src = strstr(token, "src"); + if (!src) // assert we have a src attribute + continue; +// return false; + + pushString(&to, "<figure src=\""); + const char *c; + for (c = src;((*c) && (*c != '"')); c++); + +// uncomment for SWORD absolute path logic +// if (*(c+1) == '/') { +// pushString(buf, "file:"); +// pushString(buf, module->getConfigEntry("AbsoluteDataPath")); +// if (*((*buf)-1) == '/') +// c++; // skip '/' +// } +// end of uncomment for asolute path logic + + for (c++;((*c) && (*c != '"')); c++) + *to++ = *c; + + pushString(&to, "\" />"); + handled = true; + } + + // Strongs numbers + else if (!strnicmp(token, "sync type=\"Strongs\" ", 20)) { // Strongs + if (module->isProcessEntryAttributes()) { + valto = val; + for (unsigned int i = 27; token[i] != '\"' && i < 150; i++) + *valto++ = token[i]; + *valto = 0; + if (atoi((!isdigit(*val))?val+1:val) < 5627) { + // normal strongs number + strstrip(val); + sprintf(buf, "<w lemma=\"x-Strong:%s\">", val); + memmove(wordStart+strlen(buf), wordStart, (to-wordStart)+1); + memcpy(wordStart, buf, strlen(buf)); + to+=strlen(buf); + pushString(&to, "</w>"); + module->getEntryAttributes()["Word"][wordstr]["Strongs"] = val; +// tmp = ""; +// tmp.append(textStart, (int)(wordEnd - wordStart)); +// module->getEntryAttributes()["Word"][wordstr]["Text"] = tmp; + } + else { + // verb morph + sprintf(wordstr, "%03d", word-1); + module->getEntryAttributes()["Word"][wordstr]["Morph"] = val; + } + } + handled = true; + } + + // Morphology + else if (!strncmp(token, "sync type=\"morph\"", 17)) { + for (ch = token+17; *ch; ch++) { + if (!strncmp(ch, "class=\"", 7)) { + valto = val; + for (unsigned int i = 7; ch[i] != '\"' && i < 127; i++) + *valto++ = ch[i]; + *valto = 0; + sprintf(wordstr, "%03d", word-1); + strstrip(val); + module->getEntryAttributes()["Word"][wordstr]["MorphClass"] = val; + } + if (!strncmp(ch, "value=\"", 7)) { + valto = val; + for (unsigned int i = 7; ch[i] != '\"' && i < 127; i++) + *valto++ = ch[i]; + *valto = 0; + sprintf(wordstr, "%03d", word-1); + strstrip(val); + module->getEntryAttributes()["Word"][wordstr]["Morph"] = val; + } + } + if (!strncmp(wordStart, "<w ", 3)) { + + const char *cls = "Unknown", *morph; + + if (module->getEntryAttributes()["Word"][wordstr]["Morph"].size() > 0) { + if (module->getEntryAttributes()["Word"][wordstr]["MorphClass"].size() > 0) + cls = module->getEntryAttributes()["Word"][wordstr]["MorphClass"].c_str(); + morph = module->getEntryAttributes()["Word"][wordstr]["Morph"].c_str(); + + sprintf(buf, "morph=\"x-%s:%s\" ", cls, morph); + memmove(wordStart+3+strlen(buf), wordStart+3, (to-wordStart)+1); + memcpy(wordStart+3, buf, strlen(buf)); + to+=strlen(buf); + } + } + handled = true; + } + + if (!keepToken) { // if we don't want strongs + if (!handled) { + SWLog::systemlog->LogError("Unprocessed Token: <%s>", token); +// exit(-1); + } + if (strchr(" ,:;.?!()'\"", from[1])) { + if (lastspace) + to--; + } + if (newText) {textStart = from+1; newText = false; } +// if (newWord) {wordStart = to; newWord = false; } + continue; + } + // if not a strongs token, keep token in text + *to++ = '<'; + for (char *tok = token; *tok; tok++) + *to++ = *tok; + *to++ = '>'; + if (newText) {textStart = to; newWord = false; } +// if (newWord) {wordStart = to; newWord = false; } + continue; + } + if (intoken) { + if ((tokpos < 2045) && ((*from != 10)&&(*from != 13))) { + token[tokpos++] = *from; + token[tokpos+2] = 0; + } + } + else { + if (newWord && (*from != ' ')) {wordStart = to; newWord = false; memset(to, 0, 10); } + if (!suspendTextPassThru) { + *to++ = *from; + lastspace = (*from == ' '); + } + } + } + + VerseKey *vkey = SWDYNAMIC_CAST(VerseKey, key); + if (vkey) { + char ref[254]; + if (vkey->Verse()) + sprintf(ref, "<verse osisID=\"%s\">", vkey->getOSISRef()); + else *ref = 0; + if (*ref) { + memmove(text+strlen(ref), text, maxlen-strlen(ref)-1); + memcpy(text, ref, strlen(ref)); + to+=strlen(ref); + if (vkey->Verse()) { + VerseKey tmp; + tmp = *vkey; + tmp.AutoNormalize(0); + tmp.Headings(1); + sprintf(ref, "</verse>"); + pushString(&to, ref); + 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); +// sprintf(ref, "\t</div>"); +// pushString(&to, ref); + } + } + } + +// else if (vkey->Chapter()) +// sprintf(ref, "\t<div type=\"chapter\" osisID=\"%s\">", vkey->getOSISRef()); +// else sprintf(ref, "\t<div type=\"book\" osisID=\"%s\">", vkey->getOSISRef()); + } + } + *to++ = 0; + *to = 0; +*/ + return 0; +} + + +const char *ThMLOSIS::convertToOSIS(const char *inRef, const SWKey *key) { + static SWBuf outRef; + + outRef = ""; + + VerseKey defLanguage; + ListKey verses = defLanguage.ParseVerseList(inRef, (*key), true); + const char *startFrag = inRef; + for (int i = 0; i < verses.Count(); i++) { + VerseKey *element = SWDYNAMIC_CAST(VerseKey, verses.GetElement(i)); + char buf[5120]; + char frag[5120]; + if (element) { + memmove(frag, startFrag, ((const char *)element->userData - startFrag) + 1); + frag[((const char *)element->userData - startFrag) + 1] = 0; + startFrag = (const char *)element->userData + 1; + sprintf(buf, "<reference osisRef=\"%s-%s\">%s</reference>", element->LowerBound().getOSISRef(), element->UpperBound().getOSISRef(), frag); + } + else { + memmove(frag, startFrag, ((const char *)verses.GetElement(i)->userData - startFrag) + 1); + frag[((const char *)verses.GetElement(i)->userData - startFrag) + 1] = 0; + startFrag = (const char *)verses.GetElement(i)->userData + 1; + sprintf(buf, "<reference osisRef=\"%s\">%s</reference>", VerseKey(*verses.GetElement(i)).getOSISRef(), frag); + } + outRef+=buf; + } + return outRef.c_str(); +} + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlplain.cpp b/src/modules/filters/thmlplain.cpp index 5609f16..a04d6c3 100644 --- a/src/modules/filters/thmlplain.cpp +++ b/src/modules/filters/thmlplain.cpp @@ -1,35 +1,30 @@ /****************************************************************************** * - * thmlplain - SWFilter decendant to strip out all ThML tags or convert to + * thmlplain - SWFilter descendant to strip out all ThML tags or convert to * ASCII rendered symbols. */ #include <stdlib.h> -#include <string.h> #include <thmlplain.h> +SWORD_NAMESPACE_START ThMLPlain::ThMLPlain() { } - -char ThMLPlain::ProcessText(char *text, int maxlen) +char ThMLPlain::processText(SWBuf &text, const SWKey *key, const SWModule *module) { - char *to, *from, token[2048]; + char token[2048]; int tokpos = 0; bool intoken = false; - int len; bool ampersand = false; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; // ------------------------------- - - for (to = text; *from; from++) { + const char *from; + SWBuf orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) + { if (*from == 10 || *from == 13) from++; if (*from == '<') { @@ -53,102 +48,102 @@ char ThMLPlain::ProcessText(char *text, int maxlen) if (*from == ';' && ampersand) { intoken = false; - if (!strncmp("nbsp", token, 4)) *to++ = ' '; - else if (!strncmp("quot", token, 4)) *to++ = '"'; - else if (!strncmp("amp", token, 3)) *to++ = '&'; - else if (!strncmp("lt", token, 2)) *to++ = '<'; - else if (!strncmp("gt", token, 2)) *to++ = '>'; - else if (!strncmp("brvbar", token, 6)) *to++ = '|'; - else if (!strncmp("sect", token, 4)) *to++ = '§'; - else if (!strncmp("copy", token, 4)) *to++ = '©'; - else if (!strncmp("laquo", token, 5)) *to++ = '«'; - else if (!strncmp("reg", token, 3)) *to++ = '®'; - else if (!strncmp("acute", token, 5)) *to++ = '´'; - else if (!strncmp("para", token, 4)) *to++ = '¶'; - else if (!strncmp("raquo", token, 5)) *to++ = '»'; + if (!strncmp("nbsp", token, 4)) text += ' '; + else if (!strncmp("quot", token, 4)) text += '"'; + 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("Aacute", token, 6)) *to++ = 'Á'; - else if (!strncmp("Agrave", token, 6)) *to++ = 'À'; - else if (!strncmp("Acirc", token, 5)) *to++ = 'Â'; - else if (!strncmp("Auml", token, 4)) *to++ = 'Ä'; - else if (!strncmp("Atilde", token, 6)) *to++ = 'Ã'; - else if (!strncmp("Aring", token, 5)) *to++ = 'Å'; - else if (!strncmp("aacute", token, 6)) *to++ = 'á'; - else if (!strncmp("agrave", token, 6)) *to++ = 'à'; - else if (!strncmp("acirc", token, 5)) *to++ = 'â'; - else if (!strncmp("auml", token, 4)) *to++ = 'ä'; - else if (!strncmp("atilde", token, 6)) *to++ = 'ã'; - else if (!strncmp("aring", token, 5)) *to++ = 'å'; - else if (!strncmp("Eacute", token, 6)) *to++ = 'É'; - else if (!strncmp("Egrave", token, 6)) *to++ = 'È'; - else if (!strncmp("Ecirc", token, 5)) *to++ = 'Ê'; - else if (!strncmp("Euml", token, 4)) *to++ = 'Ë'; - else if (!strncmp("eacute", token, 6)) *to++ = 'é'; - else if (!strncmp("egrave", token, 6)) *to++ = 'è'; - else if (!strncmp("ecirc", token, 5)) *to++ = 'ê'; - else if (!strncmp("euml", token, 4)) *to++ = 'ë'; - else if (!strncmp("Iacute", token, 6)) *to++ = 'Í'; - else if (!strncmp("Igrave", token, 6)) *to++ = 'Ì'; - else if (!strncmp("Icirc", token, 5)) *to++ = 'Î'; - else if (!strncmp("Iuml", token, 4)) *to++ = 'Ï'; - else if (!strncmp("iacute", token, 6)) *to++ = 'í'; - else if (!strncmp("igrave", token, 6)) *to++ = 'ì'; - else if (!strncmp("icirc", token, 5)) *to++ = 'î'; - else if (!strncmp("iuml", token, 4)) *to++ = 'ï'; - else if (!strncmp("Oacute", token, 6)) *to++ = 'Ó'; - else if (!strncmp("Ograve", token, 6)) *to++ = 'Ò'; - else if (!strncmp("Ocirc", token, 5)) *to++ = 'Ô'; - else if (!strncmp("Ouml", token, 4)) *to++ = 'Ö'; - else if (!strncmp("Otilde", token, 6)) *to++ = 'Õ'; - else if (!strncmp("oacute", token, 6)) *to++ = 'ó'; - else if (!strncmp("ograve", token, 6)) *to++ = 'ò'; - else if (!strncmp("ocirc", token, 5)) *to++ = 'ô'; - else if (!strncmp("ouml", token, 4)) *to++ = 'ö'; - else if (!strncmp("otilde", token, 6)) *to++ = 'õ'; - else if (!strncmp("Uacute", token, 6)) *to++ = 'Ú'; - else if (!strncmp("Ugrave", token, 6)) *to++ = 'Ù'; - else if (!strncmp("Ucirc", token, 5)) *to++ = 'Û'; - else if (!strncmp("Uuml", token, 4)) *to++ = 'Ü'; - else if (!strncmp("uacute", token, 6)) *to++ = 'ú'; - else if (!strncmp("ugrave", token, 6)) *to++ = 'ù'; - else if (!strncmp("ucirc", token, 5)) *to++ = 'û'; - else if (!strncmp("uuml", token, 4)) *to++ = 'ü'; - else if (!strncmp("Yacute", token, 6)) *to++ = 'Ý'; - else if (!strncmp("yacute", token, 6)) *to++ = 'ý'; - else if (!strncmp("yuml", token, 4)) *to++ = 'ÿ'; + 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)) *to++ = '°'; - else if (!strncmp("plusmn", token, 6)) *to++ = '±'; - else if (!strncmp("sup2", token, 4)) *to++ = '²'; - else if (!strncmp("sup3", token, 4)) *to++ = '³'; - else if (!strncmp("sup1", token, 4)) *to++ = '¹'; - else if (!strncmp("nbsp", token, 4)) *to++ = 'º'; - else if (!strncmp("pound", token, 5)) *to++ = '£'; - else if (!strncmp("cent", token, 4)) *to++ = '¢'; - else if (!strncmp("frac14", token, 6)) *to++ = '¼'; - else if (!strncmp("frac12", token, 6)) *to++ = '½'; - else if (!strncmp("frac34", token, 6)) *to++ = '¾'; - else if (!strncmp("iquest", token, 6)) *to++ = '¿'; - else if (!strncmp("iexcl", token, 5)) *to++ = '¡'; - else if (!strncmp("ETH", token, 3)) *to++ = 'Ð'; - else if (!strncmp("eth", token, 3)) *to++ = 'ð'; - else if (!strncmp("THORN", token, 5)) *to++ = 'Þ'; - else if (!strncmp("thorn", token, 5)) *to++ = 'þ'; - else if (!strncmp("AElig", token, 5)) *to++ = 'Æ'; - else if (!strncmp("aelig", token, 5)) *to++ = 'æ'; - else if (!strncmp("Oslash", token, 6)) *to++ = 'Ø'; - else if (!strncmp("curren", token, 6)) *to++ = '¤'; - else if (!strncmp("Ccedil", token, 6)) *to++ = 'Ç'; - else if (!strncmp("ccedil", token, 6)) *to++ = 'ç'; - else if (!strncmp("szlig", token, 5)) *to++ = 'ß'; - else if (!strncmp("Ntilde", token, 6)) *to++ = 'Ñ'; - else if (!strncmp("ntilde", token, 6)) *to++ = 'ñ'; - else if (!strncmp("yen", token, 3)) *to++ = '¥'; - else if (!strncmp("not", token, 3)) *to++ = '¬'; - else if (!strncmp("ordf", token, 4)) *to++ = 'ª'; - else if (!strncmp("uml", token, 3)) *to++ = '¨'; - else if (!strncmp("shy", token, 3)) *to++ = ''; - else if (!strncmp("macr", token, 4)) *to++ = '¯'; + 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 += '¯'; continue; } @@ -156,32 +151,32 @@ char ThMLPlain::ProcessText(char *text, int maxlen) intoken = false; // process desired tokens if (!strncmp(token, "sync type=\"Strongs\" value=\"", 27)) { - *to++ = ' '; - *to++ = '<'; + text += ' '; + text += '<'; for (unsigned int i = 27; token[i] != '\"'; i++) - *to++ = token[i]; - *to++ = '>'; + text += token[i]; + text += '>'; continue; } if (!strncmp(token, "sync type=\"morph\" value=\"", 25)) { - *to++ = ' '; - *to++ = '('; + text += ' '; + text += '('; for (unsigned int i = 25; token[i] != '\"'; i++) - *to++ = token[i]; - *to++ = ')'; + text += token[i]; + text += ')'; continue; } if (!strncmp("note", token, 4)) { - *to++ = ' '; - *to++ = '('; + text += ' '; + text += '('; } else if (!strncmp("br", token, 2)) - *to++ = '\n'; + text += '\n'; else if (!strncmp("/p", token, 2)) - *to++ = '\n'; + text += '\n'; else if (!strncmp("/note", token, 5)) { - *to++ = ')'; - *to++ = ' '; + text += ')'; + text += ' '; } continue; } @@ -190,12 +185,26 @@ char ThMLPlain::ProcessText(char *text, int maxlen) token[tokpos++] = *from; token[tokpos+2] = 0; } - else *to++ = *from; + else text += *from; } - *to++ = 0; - *to = 0; + + orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) { //loop to remove extra spaces + if ((strchr(" \t\n\r", *from))) { + while (*(from+1) && (strchr(" \t\n\r", *(from+1)))) { + from++; + } + text += " "; + } + else { + text += *from; + } + } + text += (char)0; return 0; } +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlrtf.cpp b/src/modules/filters/thmlrtf.cpp index 76289ec..4487921 100644 --- a/src/modules/filters/thmlrtf.cpp +++ b/src/modules/filters/thmlrtf.cpp @@ -15,12 +15,14 @@ ***************************************************************************/ #include <stdlib.h> -#include <string.h> #include <thmlrtf.h> +#include <swmodule.h> +#include <utilxml.h> +#include <versekey.h> +SWORD_NAMESPACE_START -ThMLRTF::ThMLRTF() -{ +ThMLRTF::ThMLRTF() { setTokenStart("<"); setTokenEnd(">"); @@ -30,6 +32,7 @@ ThMLRTF::ThMLRTF() setEscapeStringCaseSensitive(true); addEscapeStringSubstitute("nbsp", " "); + addEscapeStringSubstitute("apos", "'"); addEscapeStringSubstitute("quot", "\""); addEscapeStringSubstitute("amp", "&"); addEscapeStringSubstitute("lt", "<"); @@ -128,87 +131,178 @@ ThMLRTF::ThMLRTF() setTokenCaseSensitive(true); - addTokenSubstitute("/scripRef", "|}"); - addTokenSubstitute("/note", ") }"); - - addTokenSubstitute("br", "\\line "); - addTokenSubstitute("br /", "\\line "); - addTokenSubstitute("i", "{\\i1 "); - addTokenSubstitute("/i", "}"); - addTokenSubstitute("b", "{\\b1 "); - addTokenSubstitute("/b", "}"); - addTokenSubstitute("p", "\\par "); - - //we need uppercase forms for the moment to support a few early ThML modules that aren't XHTML compliant - addTokenSubstitute("BR", "\\line "); - addTokenSubstitute("I", "{\\i1 "); - addTokenSubstitute("/I", "}"); - addTokenSubstitute("B", "{\\b1 "); - addTokenSubstitute("/B", "}"); - addTokenSubstitute("P", "\\par "); + + addTokenSubstitute("br", "\\line "); + addTokenSubstitute("br /", "\\line "); + addTokenSubstitute("i", "{\\i1 "); + addTokenSubstitute("/i", "}"); + addTokenSubstitute("b", "{\\b1 "); + addTokenSubstitute("/b", "}"); + addTokenSubstitute("p", "\\par "); + + //we need uppercase forms for the moment to support a few early ThML modules that aren't XHTML compliant + addTokenSubstitute("BR", "\\line "); + addTokenSubstitute("I", "{\\i1 "); + addTokenSubstitute("/I", "}"); + addTokenSubstitute("B", "{\\b1 "); + addTokenSubstitute("/B", "}"); + addTokenSubstitute("P", "\\par "); + addTokenSubstitute("scripture", "{\\i1 "); + addTokenSubstitute("/scripture", "}"); } -bool ThMLRTF::handleToken(char **buf, const char *token, DualStringMap &userData) { - if (!substituteToken(buf, token)) { - // manually process if it wasn't a simple substitution - if (!strncmp(token, "sync type=\"Strongs\" value=\"", 27)) { -/* if (token[27] == 'H' || token[27] == 'G' || token[27] == 'A') { - pushString(buf, " {\\fs15 <"); - for (unsigned int i = 28; token[i] != '\"'; i++) - *(*buf)++ = token[i]; - pushString(buf, ">}"); - } - else if (token[27] == 'T') { - pushString(buf, " {\\fs15 ("); - for (unsigned int i = 28; token[i] != '\"'; i++) - *(*buf)++ = token[i]; - pushString(buf, ")}"); + +char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + SWBasicFilter::processText(text, key, module); //handle tokens as usual + const char *from; + SWBuf orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) { //loop to remove extra spaces + if ((strchr(" \t\n\r", *from))) { + while (*(from+1) && (strchr(" \t\n\r", *(from+1)))) { + from++; } + text += " "; + } + else { + text += *from; + } + } + text += (char)0; + return 0; +} + + +ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) { + if (module) { + version = module->Name(); + BiblicalText = (!strcmp(module->Type(), "Biblical Texts")); + } +} + + +bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { + const char *tok; + if (!substituteToken(buf, token)) { // manually process if it wasn't a simple substitution + MyUserData *u = (MyUserData *)userData; + XMLTag tag(token); + if ((!tag.isEndTag()) && (!tag.isEmpty())) + u->startTag = tag; + if (tag.getName() && !strcmp(tag.getName(), "sync")) { + SWBuf value = tag.getAttribute("value"); + if (tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "morph")) { //> + buf.appendFormatted(" {\\cf4 \\sub (%s)}", value.c_str()); + } + else if( tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "Strongs")) { + if (value[0] == 'H' || value[0] == 'G' || value[0] == 'A') { + value<<1; + buf.appendFormatted(" {\\cf3 \\sub <%s>}", value.c_str()); + } + else if (value[0] == 'T') { + value<<1; + buf.appendFormatted(" {\\cf4 \\sub (%s)}", value.c_str()); + } + } + else if (tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "Dict")) { + if (!tag.isEndTag()) + buf += "{\\b "; + else buf += "}"; + } } - else if (!strncmp(token, "sync type=\"morph\" ", 18)) { - pushString(buf, " {\\fs15 ("); - for (const char *tok = token + 5; *tok; tok++) { - if (!strncmp(tok, "value=\"", 7)) { - tok += 7; - for (;*tok != '\"'; tok++) - *(*buf)++ = *tok; - break; + // <note> tag + else if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + SWBuf type = tag.getAttribute("type"); + SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) { } + if (vkey) { + // leave this special osis type in for crossReference notes types? Might thml use this some day? Doesn't hurt. + char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n'); + buf.appendFormatted("{\\super <a href=\"\">*%c%i.%s</a>} ", ch, vkey->Verse(), footnoteNumber.c_str()); + } + u->suspendTextPassThru = true; } } + if (tag.isEndTag()) { + u->suspendTextPassThru = false; + } + } + - pushString(buf, ")}"); -*/ } - else if (!strncmp(token, "sync type=\"lemma\" value=\"", 25)) { - pushString(buf, "{\\fs15 ("); - for (unsigned int i = 25; token[i] != '\"'; i++) - *(*buf)++ = token[i]; - pushString(buf, ")}"); + else if (!strcmp(tag.getName(), "scripRef")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + u->suspendTextPassThru = true; + } + } + if (tag.isEndTag()) { // </scripRef> + if (!u->BiblicalText) { + SWBuf refList = u->startTag.getAttribute("passage"); + if (!refList.length()) + refList = u->lastTextNode; + SWBuf version = tag.getAttribute("version"); + buf += "<a href=\"\">"; + buf += refList.c_str(); +// buf += u->lastTextNode.c_str(); + buf += "</a>"; + } + else { + SWBuf footnoteNumber = u->startTag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) {} + if (vkey) { + // leave this special osis type in for crossReference notes types? Might thml use this some day? Doesn't hurt. + buf.appendFormatted("{\\super <a href=\"\">*x%i.%s</a>} ", vkey->Verse(), footnoteNumber.c_str()); + } + } + + // let's let text resume to output again + u->suspendTextPassThru = false; + } } - else if (!strncmp(token, "scripRef", 8)) { - pushString(buf, "{\\cf2 #"); + + else if (tag.getName() && !strcmp(tag.getName(), "div")) { + if (tag.isEndTag() && u->SecHead) { + buf += "\\par}"; + u->SecHead = false; + } + else if (tag.getAttribute("class")) { + if (!stricmp(tag.getAttribute("class"), "sechead")) { + u->SecHead = true; + buf += "{\\par\\i1\\b1 "; + } + else if (!stricmp(tag.getAttribute("class"), "title")) { + u->SecHead = true; + buf += "{\\par\\i1\\b1 "; + } + } } - else if (!strncmp(token, "div", 3)) { - *(*buf)++ = '{'; - if (!strncmp(token, "div class=\"title\"", 17)) { - pushString(buf, "\\par\\i1\\b1 "); - userData["sechead"] = "true"; - } - else if (!strncmp(token, "div class=\"sechead\"", 19)) { - pushString(buf, "\\par\\i1\\b1 "); - userData["sechead"] = "true"; - } - } - else if (!strncmp(token, "/div", 4)) { - *(*buf)++ = '}'; - if (userData["sechead"] == "true") { - pushString(buf, "\\par "); - userData["sechead"] == "false"; - } - } - else if (!strncmp(token, "note", 4)) { - pushString(buf, " {\\i1\\fs15 ("); - } + else if (tag.getName() && (!strcmp(tag.getName(), "img") || !strcmp(tag.getName(), "image"))) { + const char *src = tag.getAttribute("src"); + if (!src) // assert we have a src attribute + return false; + char* filepath = new char[strlen(u->module->getConfigEntry("AbsoluteDataPath")) + strlen(token)]; + *filepath = 0; + strcpy(filepath, userData->module->getConfigEntry("AbsoluteDataPath")); + strcat(filepath, src); + +// we do this because BibleCS looks for this EXACT format for an image tag + buf+="<img src=\""; + buf+=filepath; + buf+="\" />"; + delete [] filepath; + } else { return false; // we still didn't handle token } @@ -217,3 +311,4 @@ bool ThMLRTF::handleToken(char **buf, const char *token, DualStringMap &userData } +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlscripref.cpp b/src/modules/filters/thmlscripref.cpp index 23edd6d..7b93f90 100644 --- a/src/modules/filters/thmlscripref.cpp +++ b/src/modules/filters/thmlscripref.cpp @@ -1,103 +1,126 @@ /****************************************************************************** * - * thmlscripref - SWFilter decendant to hide or show scripture references - * in a ThML module. + * thmlscripref - SWFilter descendant to hide or show scripture + * referebces in a ThML module. */ #include <stdlib.h> -#include <string.h> #include <thmlscripref.h> +#include <utilxml.h> +#include <versekey.h> +#include <swmodule.h> #ifndef __GNUC__ #else #include <unixstr.h> #endif +SWORD_NAMESPACE_START -const char ThMLScripref::on[] = "On"; -const char ThMLScripref::off[] = "Off"; -const char ThMLScripref::optName[] = "Scripture Cross-references"; -const char ThMLScripref::optTip[] = "Toggles Scripture Cross-references On and Off if they exist"; +const char oName[] = "Cross-references"; +const char oTip[] = "Toggles Scripture Cross-references On and Off if they exist"; +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); -ThMLScripref::ThMLScripref() { - option = false; - options.push_back(on); - options.push_back(off); +ThMLScripref::ThMLScripref() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("On"); } ThMLScripref::~ThMLScripref() { } -void ThMLScripref::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} -const char *ThMLScripref::getOptionValue() -{ - return (option) ? on:off; -} +char ThMLScripref::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + SWBuf token; + bool intoken = false; + bool hide = false; + SWBuf tagText; + XMLTag startTag; + SWBuf refs = ""; + int footnoteNum = 1; + char buf[254]; + VerseKey parser = key->getText(); -char ThMLScripref::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ - if (!option) { // if we don't want scriprefs - char *to, *from, token[2048]; // cheese. Fix. - int tokpos = 0; - bool intoken = false; - int len; - bool hide = false; + SWBuf orig = text; + const char *from = orig.c_str(); - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; + for (text = ""; *from; from++) { + if (*from == '<') { + intoken = true; + token = ""; + continue; } - else from = text; // ------------------------------- + if (*from == '>') { // process tokens + intoken = false; - for (to = text; *from; from++) { - if (*from == '<') { - intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; - continue; - } - if (*from == '>') { // process tokens - intoken = false; - if (!strnicmp(token, "scripRef", 8)) { - hide = true; - continue; + XMLTag tag(token); + if (!strcmp(tag.getName(), "scripRef")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + refs = ""; + startTag = tag; + hide = true; + tagText = ""; + continue; + } } - else if (!strnicmp(token, "/scripRef", 9)) { - hide = false; - continue; + if (hide && tag.isEndTag()) { + if (module->isProcessEntryAttributes()) { + SWBuf fc = module->getEntryAttributes()["Footnote"]["count"]["value"]; + footnoteNum = (fc.length()) ? atoi(fc.c_str()) : 0; + sprintf(buf, "%i", ++footnoteNum); + module->getEntryAttributes()["Footnote"]["count"]["value"] = buf; + StringList attributes = startTag.getAttributeNames(); + for (StringList::iterator it = attributes.begin(); it != attributes.end(); it++) { + module->getEntryAttributes()["Footnote"][buf][it->c_str()] = startTag.getAttribute(it->c_str()); + } + module->getEntryAttributes()["Footnote"][buf]["body"] = tagText; + 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(); + module->getEntryAttributes()["Footnote"][buf]["refList"] = refs.c_str(); + } + hide = false; + if (option) { // we want the tag in the text + text += startTag; + text.append(tagText); + } + else continue; } + } - // if not a scripref token, keep token in text - if (!hide) { - *to++ = '<'; - for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; - } - continue; + // if not a scripRef token, keep token in text + if ((!strcmp(tag.getName(), "scripRef")) && (!tag.isEndTag())) { + SWBuf osisRef = tag.getAttribute("passage"); + if (refs.length()) + refs += "; "; + refs += osisRef; } - if (intoken) { - if (tokpos < 2045) - token[tokpos++] = *from; - token[tokpos+2] = 0; + if (!hide) { + text += '<'; + text.append(token); + text += '>'; } - else { - if (!hide) { - *to++ = *from; - } + else { + tagText += '<'; + tagText.append(token); + tagText += '>'; } + continue; + } + if (intoken) { //copy token + token += *from; } - *to++ = 0; - *to = 0; + else if (!hide) { //copy text which is not inside a token + text += *from; + } + else tagText += *from; } return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlstrongs.cpp b/src/modules/filters/thmlstrongs.cpp index 8d0466c..4a53e25 100644 --- a/src/modules/filters/thmlstrongs.cpp +++ b/src/modules/filters/thmlstrongs.cpp @@ -1,50 +1,40 @@ /****************************************************************************** * - * thmlstrongs - SWFilter decendant to hide or show strongs number + * thmlstrongs - SWFilter descendant to hide or show strongs number * in a ThML module. */ #include <stdlib.h> #include <stdio.h> -#include <string.h> #include <thmlstrongs.h> #include <swmodule.h> #ifndef __GNUC__ #else #include <unixstr.h> #endif +#include <ctype.h> +SWORD_NAMESPACE_START -const char ThMLStrongs::on[] = "On"; -const char ThMLStrongs::off[] = "Off"; -const char ThMLStrongs::optName[] = "Strong's Numbers"; -const char ThMLStrongs::optTip[] = "Toggles Strong's Numbers On and Off if they exist"; +const char oName[] = "Strong's Numbers"; +const char oTip[] = "Toggles Strong's Numbers On and Off if they exist"; +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); -ThMLStrongs::ThMLStrongs() { - option = false; - options.push_back(on); - options.push_back(off); +ThMLStrongs::ThMLStrongs() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); } ThMLStrongs::~ThMLStrongs() { } -void ThMLStrongs::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} - -const char *ThMLStrongs::getOptionValue() -{ - return (option) ? on:off; -} -char ThMLStrongs::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ - char *to, *from, token[2048]; // cheese. Fix. +char ThMLStrongs::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + char token[2048]; // cheese. Fix. + const char *from; int tokpos = 0; bool intoken = false; int len; @@ -54,23 +44,21 @@ char ThMLStrongs::ProcessText(char *text, int maxlen, const SWKey *key, const SW char wordstr[5]; char *valto; char *ch; + unsigned int textStart = 0, textEnd = 0; + SWBuf tmp; + bool newText = false; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; - - // ------------------------------- + SWBuf orig = text; + from = orig.c_str(); - for (to = text; *from; from++) { + for (text = ""; *from; from++) { if (*from == '<') { intoken = true; tokpos = 0; token[0] = 0; token[1] = 0; token[2] = 0; + textEnd = text.length(); continue; } if (*from == '>') { // process tokens @@ -81,15 +69,28 @@ char ThMLStrongs::ProcessText(char *text, int maxlen, const SWKey *key, const SW for (unsigned int i = 27; token[i] != '\"' && i < 150; i++) *valto++ = token[i]; *valto = 0; - sprintf(wordstr, "%03d", word++); - module->getEntryAttributes()["Word"][wordstr]["Strongs"] = val; + if (atoi((!isdigit(*val))?val+1:val) < 5627) { + // normal strongs number + sprintf(wordstr, "%03d", word++); + module->getEntryAttributes()["Word"][wordstr]["Strongs"] = val; + tmp = ""; + tmp.append(text.c_str()+textStart, (int)(textEnd - textStart)); + module->getEntryAttributes()["Word"][wordstr]["Text"] = tmp; + newText = true; + } + else { + // verb morph + sprintf(wordstr, "%03d", word-1); + module->getEntryAttributes()["Word"][wordstr]["Morph"] = val; + } } if (!option) { // if we don't want strongs if ((from[1] == ' ') || (from[1] == ',') || (from[1] == ';') || (from[1] == '.') || (from[1] == '?') || (from[1] == '!') || (from[1] == ')') || (from[1] == '\'') || (from[1] == '\"')) { if (lastspace) - to--; + text--; } + if (newText) {textStart = text.length(); newText = false; } continue; } } @@ -116,10 +117,10 @@ char ThMLStrongs::ProcessText(char *text, int maxlen, const SWKey *key, const SW } } // if not a strongs token, keep token in text - *to++ = '<'; - for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; + text += '<'; + text += token; + text += '>'; + if (newText) {textStart = text.length(); newText = false; } continue; } if (intoken) { @@ -128,11 +129,11 @@ char ThMLStrongs::ProcessText(char *text, int maxlen, const SWKey *key, const SW token[tokpos+2] = 0; } else { - *to++ = *from; + text += *from; lastspace = (*from == ' '); } } - *to++ = 0; - *to = 0; return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlvariants.cpp b/src/modules/filters/thmlvariants.cpp index fda0950..b8ab653 100644 --- a/src/modules/filters/thmlvariants.cpp +++ b/src/modules/filters/thmlvariants.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * - * thmlvariants - SWFilter decendant to hide or show textual variants + * thmlvariants - SWFilter descendant to hide or show textual variants * in a ThML module. */ #include <stdlib.h> -#include <string.h> #include <thmlvariants.h> #ifndef __GNUC__ #else #include <unixstr.h> #endif +SWORD_NAMESPACE_START const char ThMLVariants::primary[] = "Primary Reading"; const char ThMLVariants::secondary[] = "Secondary Reading"; @@ -35,7 +35,9 @@ ThMLVariants::~ThMLVariants() { void ThMLVariants::setOptionValue(const char *ival) { - option = (!stricmp(ival, primary)); + if (!stricmp(ival, primary)) option = 0; + else if (!stricmp(ival, secondary)) option = 1; + else option = 2; } const char *ThMLVariants::getOptionValue() @@ -51,128 +53,54 @@ const char *ThMLVariants::getOptionValue() } } -char ThMLVariants::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char ThMLVariants::processText(SWBuf &text, const SWKey *key, const SWModule *module) { - if (option == 0) { //we want primary only - char *to, *from, token[2048]; // cheese. Fix. - int tokpos = 0; + if ( option == 0 || option == 1) { //we want primary or variant only bool intoken = false; - int len; bool hide = false; - - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; - // ------------------------------- + SWBuf token; + SWBuf orig = text; + const char *from = orig.c_str(); - for (to = text; *from; from++) { + //we use a fixed comparision string to make sure the loop is as fast as the original two blocks with almost the same code + const char* variantCompareString = (option == 0) ? "div type=\"variant\" class=\"1\"" : "div type=\"variant\" class=\"2\""; + + for (text = ""; *from; from++) { if (*from == '<') { intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; + token = ""; continue; } - if (*from == '>') { // process tokens + else if (*from == '>') { // process tokens intoken = false; - if (!strncmp(token, "div type=\"variant\"", 19)) { - hide = true; - continue; - } - else if (!strncmp(token, "/div", 4)) { - hide = false; - continue; + + if ( !strncmp(token.c_str(), variantCompareString, 28)) { //only one of the variants, length of the two strings is 28 in both cases + hide = true; + continue; } - - // if not a footnote token, keep token in text - if (!hide) { - *to++ = '<'; - for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; - } - continue; - } - if (intoken) { - if (tokpos < 2045) - token[tokpos++] = *from; - token[tokpos+2] = 0; - } - else { if (!hide) { - *to++ = *from; - } - } - } - *to++ = 0; - *to = 0; - - } - else if (option == 1) { //we want variant only - char *to, *from, token[2048]; // cheese. Fix. - int tokpos = 0; - bool intoken = false; - int len; - bool hide = false; - - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = &text[maxlen - len]; - } - else from = text; - - // ------------------------------- - - for (to = text; *from; from++) { - if (*from == '<') { - intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; - continue; - } - if (*from == '>') { // process tokens - intoken = false; - if (!strncmp(token, "div type=\"primary\"", 19)) { - hide = true; - continue; + text += '<'; + text.append(token); + text += '>'; } - else if (!strncmp(token, "/div", 4)) { - hide = false; - continue; + if (!strncmp(token.c_str(), "/div", 4)) { + hide = false; + continue; } - // if not a footnote token, keep token in text - if (!hide) { - *to++ = '<'; - for (char *tok = token; *tok; tok++) - *to++ = *tok; - *to++ = '>'; - } continue; } if (intoken) { - if (tokpos < 2045) - token[tokpos++] = *from; - token[tokpos+2] = 0; + token += *from; } - else { - if (!hide) { - *to++ = *from; - } + else if (!hide) { + text += *from; } } - *to++ = 0; - *to = 0; } + return 0; } @@ -181,3 +109,4 @@ char ThMLVariants::ProcessText(char *text, int maxlen, const SWKey *key, const S +SWORD_NAMESPACE_END diff --git a/src/modules/filters/thmlwebif.cpp b/src/modules/filters/thmlwebif.cpp new file mode 100644 index 0000000..f082e1e --- /dev/null +++ b/src/modules/filters/thmlwebif.cpp @@ -0,0 +1,104 @@ +/*************************************************************************** + 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. * + * * + ***************************************************************************/ + +#include <stdlib.h> +#include <thmlwebif.h> +#include <swmodule.h> +#include <utilweb.h> +#include <utilxml.h> +#include <ctype.h> + +SWORD_NAMESPACE_START + +ThMLWEBIF::ThMLWEBIF() : baseURL(""), passageStudyURL(baseURL + "passagestudy.jsp") { + //all's done in ThMLHTMLHREF +} + +bool ThMLWEBIF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { + const char *tok; + + if (!substituteToken(buf, token)) { // manually process if it wasn't a simple substitution + MyUserData *u = (MyUserData *)userData; + XMLTag tag(token); + SWBuf url; + if (!strcmp(tag.getName(), "sync")) { + const char* value = tag.getAttribute("value"); + url = value; + if ((url.length() > 1) && strchr("GH", url[0])) { + if (isdigit(url[1])) + url = url.c_str()+1; + } + + if(tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "morph")){ + buf += "<small><em> ("; + buf.appendFormatted("<a href=\"%s?showMorph=%s#cv\">", passageStudyURL.c_str(), encodeURL(url).c_str() ); + } + else { + if (value) { + value++; //skip leading G, H or T + //url = value; + } + + buf += "<small><em> <"; + buf.appendFormatted("<a href=\"%s?showStrong=%s#cv\">", passageStudyURL.c_str(), encodeURL(url).c_str() ); + } + + buf += value; + buf += "</a>"; + + if (tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "morph")) { + buf += ") </em></small>"; + } + else { + buf += "> </em></small>"; + } + } + else if (!strcmp(tag.getName(), "scripRef")) { + if (tag.isEndTag()) { + if (u->inscriptRef) { // like "<scripRef passage="John 3:16">John 3:16</scripRef>" + u->inscriptRef = false; + buf += "</a>"; + } + else { // end of scripRef like "<scripRef>John 3:16</scripRef>" + url = u->lastTextNode; + buf.appendFormatted("<a href=\"%s?key=%s#cv\">", passageStudyURL.c_str(), encodeURL(url).c_str()); + buf += u->lastTextNode.c_str(); + buf += "</a>"; + + // let's let text resume to output again + u->suspendTextPassThru = false; + } + } + else if (tag.getAttribute("passage")) { //passage given + u->inscriptRef = true; + + buf.appendFormatted("<a href=\"%s?key=%s#cv\">", passageStudyURL.c_str(), encodeURL(tag.getAttribute("passage")).c_str()); + } + else { //no passage given + u->inscriptRef = false; + // let's stop text from going to output + u->suspendTextPassThru = true; + } + } + else { + return ThMLHTMLHREF::handleToken(buf,token,userData); + } + } + return true; +} + + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/unicodertf.cpp b/src/modules/filters/unicodertf.cpp index b53a2d7..0a2bca8 100644 --- a/src/modules/filters/unicodertf.cpp +++ b/src/modules/filters/unicodertf.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * unicodertf - SWFilter decendant to convert a double byte unicode file + * unicodertf - SWFilter descendant to convert a double byte unicode file * to RTF tags */ @@ -9,62 +9,78 @@ #include <stdio.h> #include <unicodertf.h> +SWORD_NAMESPACE_START + UnicodeRTF::UnicodeRTF() { } -char UnicodeRTF::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char UnicodeRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) { - unsigned char *to, *from, *maxto; - int len; - char digit[10]; - short ch; // must be signed per unicode spec (negative is ok for big numbers > 32768) + const unsigned char *from; + char digit[10]; + unsigned long ch; + signed short utf16; + unsigned char from2[7]; - len = strlenw(text) + 2; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = (unsigned char*)&text[maxlen - len]; - } - else from = (unsigned char*)text; - maxto =(unsigned char*)text + maxlen; + SWBuf orig = text; + + from = (const unsigned char *)orig.c_str(); // ------------------------------- - for (to = (unsigned char*)text; *from && (to <= maxto); from++) { - ch = 0; - if ((*from & 128) != 128) { - *to++ = *from; - continue; - } - if ((*from & 128) && ((*from & 64) != 64)) { - // error - *from = 'x'; - continue; - } - *from <<= 1; - int subsequent; - for (subsequent = 1; (*from & 128); subsequent++) { - *from <<= 1; - from[subsequent] &= 63; - ch <<= 6; - ch |= from[subsequent]; - } - subsequent--; - *from <<=1; - char significantFirstBits = 8 - (2+subsequent); - - ch |= (((short)*from) << (((6*subsequent)+significantFirstBits)-8)); - from += subsequent; - *to++ = '\\'; - *to++ = 'u'; - sprintf(digit, "%d", ch); - for (char *dig = digit; *dig; dig++) - *to++ = *dig; - *to++ = '?'; + for (text = ""; *from; from++) { + ch = 0; + //case: ANSI + if ((*from & 128) != 128) { + text += *from; + continue; + } + //case: Invalid UTF-8 (illegal continuing byte in initial position) + if ((*from & 128) && ((*from & 64) != 64)) { + continue; + } + //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]; + } + subsequent--; + from2[0] <<= 1; + char significantFirstBits = 8 - (2+subsequent); + + ch |= (((short)from2[0]) << (((6*subsequent)+significantFirstBits)-8)); + from += subsequent; + if (ch < 0x10000) { + utf16 = (signed short)ch; + text += '\\'; + text += 'u'; + sprintf(digit, "%d", utf16); + text += digit; + text += '?'; + } + else { + utf16 = (signed short)((ch - 0x10000) / 0x400 + 0xD800); + text += '\\'; + text += 'u'; + sprintf(digit, "%d", utf16); + text += digit; + text += '?'; + utf16 = (signed short)((ch - 0x10000) % 0x400 + 0xDC00); + text += '\\'; + text += 'u'; + sprintf(digit, "%d", utf16); + text += digit; + text += '?'; + } } - - if (to != maxto) { - *to++ = 0; - } - *to = 0; + return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/utf16utf8.cpp b/src/modules/filters/utf16utf8.cpp index 5a7719f..ef1593b 100644 --- a/src/modules/filters/utf16utf8.cpp +++ b/src/modules/filters/utf16utf8.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * UTF16UTF8 - SWFilter decendant to convert UTF-16 to UTF-8 + * UTF16UTF8 - SWFilter descendant to convert UTF-16 to UTF-8 * */ @@ -9,38 +9,36 @@ #include <utf16utf8.h> +SWORD_NAMESPACE_START + UTF16UTF8::UTF16UTF8() { } -char UTF16UTF8::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char UTF16UTF8::processText(SWBuf &text, const SWKey *key, const SWModule *module) { unsigned short *from; - unsigned char *to; int len; unsigned long uchar; unsigned short schar; + if ((unsigned long)key < 2) // hack, we're en(1)/de(0)ciphering + return -1; len = 0; - from = (unsigned short*) text; + from = (unsigned short*) text.c_str(); while (*from) { len += 2; from++; } - // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = (unsigned short*)&text[maxlen - len]; - } - else - from = (unsigned short*)text; - + SWBuf orig = text; + from = (unsigned short*)orig.c_str(); + // ------------------------------- - for (to = (unsigned char*)text; *from; from++) { + for (text = ""; *from; from++) { uchar = 0; if (*from < 0xD800 || *from > 0xDFFF) { @@ -66,26 +64,24 @@ char UTF16UTF8::ProcessText(char *text, int maxlen, const SWKey *key, const SWMo } if (uchar < 0x80) { - *to++ = uchar; + text += uchar; } else if (uchar < 0x800) { - *to++ = 0xc0 | (uchar >> 6); - *to++ = 0x80 | (uchar & 0x3f); + text += 0xc0 | (uchar >> 6); + text += 0x80 | (uchar & 0x3f); } else if (uchar < 0x10000) { - *to++ = 0xe0 | (uchar >> 12); - *to++ = 0x80 | (uchar >> 6) & 0x3f; - *to++ = 0x80 | uchar & 0x3f; + text += 0xe0 | (uchar >> 12); + text += 0x80 | (uchar >> 6) & 0x3f; + text += 0x80 | uchar & 0x3f; } else if (uchar < 0x200000) { - *to++ = 0xF0 | (uchar >> 18); - *to++ = 0x80 | (uchar >> 12) & 0x3F; - *to++ = 0x80 | (uchar >> 6) & 0x3F; - *to++ = 0x80 | uchar & 0x3F; + text += 0xF0 | (uchar >> 18); + text += 0x80 | (uchar >> 12) & 0x3F; + text += 0x80 | (uchar >> 6) & 0x3F; + text += 0x80 | uchar & 0x3F; } } - *to++ = 0; - *to = 0; return 0; } @@ -93,3 +89,4 @@ char UTF16UTF8::ProcessText(char *text, int maxlen, const SWKey *key, const SWMo +SWORD_NAMESPACE_END diff --git a/src/modules/filters/utf8arshaping.cpp b/src/modules/filters/utf8arshaping.cpp index 5121f48..3246adc 100644 --- a/src/modules/filters/utf8arshaping.cpp +++ b/src/modules/filters/utf8arshaping.cpp @@ -1,13 +1,12 @@ /****************************************************************************** * -* utf8arshaping - SWFilter decendant to perform Arabic shaping on +* utf8arshaping - SWFilter descendant to perform Arabic shaping on * UTF-8 text */ #ifdef _ICU_ #include <stdlib.h> -#include <string.h> #ifdef __GNUC__ #include <unixstr.h> @@ -15,34 +14,39 @@ #include <utf8arshaping.h> -UTF8arShaping::UTF8arShaping() { - - conv = ucnv_open("UTF-8", &err); +SWORD_NAMESPACE_START +UTF8arShaping::UTF8arShaping() { + conv = ucnv_open("UTF-8", &err); } UTF8arShaping::~UTF8arShaping() { ucnv_close(conv); } -char UTF8arShaping::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char UTF8arShaping::processText(SWBuf &text, const SWKey *key, const SWModule *module) { UChar *ustr, *ustr2; + if ((unsigned long)key < 2) // hack, we're en(1)/de(0)ciphering + return -1; - int32_t len = strlen(text); + int32_t len = text.length(); ustr = new UChar[len]; ustr2 = new UChar[len]; // Convert UTF-8 string to UTF-16 (UChars) - len = ucnv_toUChars(conv, ustr, len, text, -1, &err); + len = ucnv_toUChars(conv, ustr, len, text.c_str(), -1, &err); len = u_shapeArabic(ustr, len, ustr2, len, U_SHAPE_LETTERS_SHAPE | U_SHAPE_DIGITS_EN2AN, &err); - ucnv_fromUChars(conv, text, maxlen, ustr2, len, &err); + text.setSize(text.size()*2); + len = ucnv_fromUChars(conv, text.getRawData(), text.size(), ustr2, len, &err); + text.setSize(len); delete [] ustr2; delete [] ustr; return 0; } +SWORD_NAMESPACE_END #endif diff --git a/src/modules/filters/utf8bidireorder.cpp b/src/modules/filters/utf8bidireorder.cpp index 8fa7280..902047a 100644 --- a/src/modules/filters/utf8bidireorder.cpp +++ b/src/modules/filters/utf8bidireorder.cpp @@ -1,13 +1,12 @@ /****************************************************************************** * -* utf8cnormalizer - SWFilter decendant to perform reordering of UTF-8 +* utf8cnormalizer - SWFilter descendant to perform reordering of UTF-8 * text to visual order according to Unicode BiDi */ #ifdef _ICU_ #include <stdlib.h> -#include <string.h> #ifdef __GNUC__ #include <unixstr.h> @@ -15,6 +14,8 @@ #include <utf8bidireorder.h> +SWORD_NAMESPACE_START + UTF8BiDiReorder::UTF8BiDiReorder() { conv = ucnv_open("UTF-8", &err); @@ -25,15 +26,17 @@ UTF8BiDiReorder::~UTF8BiDiReorder() { ucnv_close(conv); } -char UTF8BiDiReorder::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char UTF8BiDiReorder::processText(SWBuf &text, const SWKey *key, const SWModule *module) { UChar *ustr, *ustr2; + if ((unsigned long)key < 2) // hack, we're en(1)/de(0)ciphering + return -1; - int32_t len = strlen(text); + int32_t len = text.length(); ustr = new UChar[len]; //each char could become a surrogate pair // Convert UTF-8 string to UTF-16 (UChars) - len = ucnv_toUChars(conv, ustr, len, text, -1, &err); + len = ucnv_toUChars(conv, ustr, len, text.c_str(), -1, &err); ustr2 = new UChar[len]; UBiDi* bidi = ubidi_openSized(len + 1, 0, &err); @@ -45,11 +48,14 @@ char UTF8BiDiReorder::ProcessText(char *text, int maxlen, const SWKey *key, cons // len = ubidi_writeReverse(ustr, len, ustr2, len, // UBIDI_DO_MIRRORING | UBIDI_REMOVE_BIDI_CONTROLS, &err); - ucnv_fromUChars(conv, text, maxlen, ustr2, len, &err); + text.setSize(text.size()*2); + len = ucnv_fromUChars(conv, text.getRawData(), text.size(), ustr2, len, &err); + text.setSize(len); delete [] ustr2; delete [] ustr; return 0; } +SWORD_NAMESPACE_END #endif diff --git a/src/modules/filters/utf8cantillation.cpp b/src/modules/filters/utf8cantillation.cpp index 84cb513..6213620 100644 --- a/src/modules/filters/utf8cantillation.cpp +++ b/src/modules/filters/utf8cantillation.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * UTF8Cantillation - SWFilter decendant to remove UTF-8 Hebrew cantillation + * UTF8Cantillation - SWFilter descendant to remove UTF-8 Hebrew cantillation * */ @@ -9,56 +9,47 @@ #include <stdio.h> #include <utf8cantillation.h> +SWORD_NAMESPACE_START -const char UTF8Cantillation::on[] = "On"; -const char UTF8Cantillation::off[] = "Off"; -const char UTF8Cantillation::optName[] = "Hebrew Cantillation"; -const char UTF8Cantillation::optTip[] = "Toggles Hebrew Cantillation Marks"; +const char oName[] = "Hebrew Cantillation"; +const char oTip[] = "Toggles Hebrew Cantillation Marks"; -UTF8Cantillation::UTF8Cantillation() { - option = false; - options.push_back(on); - options.push_back(off); +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +UTF8Cantillation::UTF8Cantillation() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("Off"); } -UTF8Cantillation::~UTF8Cantillation(){}; -void UTF8Cantillation::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} +UTF8Cantillation::~UTF8Cantillation(){}; -const char *UTF8Cantillation::getOptionValue() -{ - return (option) ? on:off; -} -char UTF8Cantillation::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ +char UTF8Cantillation::processText(SWBuf &text, const SWKey *key, const SWModule *module) { if (!option) { - unsigned char *to, *from; - to = (unsigned char*)text; - //The UTF-8 range 0xD6 0x90 to 0xD6 0xAF and 0xD7 0x84 consist of Hebrew cantillation marks so block those out. - for (from = (unsigned char*)text; *from; from++) { - if (*from != 0xD6) { - if (*from == 0xD7 && *(from + 1) == 0x84) { - from++; - } - else { - *to++ = *from; - } - } - else if (*(from + 1) < 0x90 || *(from + 1) > 0xAF) { - *to++ = *from; - from++; - *to++ = *from; - } - else { - from++; - } + //The UTF-8 range 0xD6 0x90 to 0xD6 0xAF and 0xD7 0x84 consist of Hebrew cantillation marks so block those out. + SWBuf orig = text; + const unsigned char* from = (unsigned char*)orig.c_str(); + for (text = ""; *from; from++) { + if (*from != 0xD6) { + if (*from == 0xD7 && *(from + 1) == 0x84) { + from++; + } + else { + text += *from; + } + } + else if (*(from + 1) < 0x90 || *(from + 1) > 0xAF) { + text += *from; + from++; + text += *from; + } + else { + from++; + } + } } - *to++ = 0; - *to = 0; - } return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/utf8greekaccents.cpp b/src/modules/filters/utf8greekaccents.cpp index b0e5dc8..05ef59b 100644 --- a/src/modules/filters/utf8greekaccents.cpp +++ b/src/modules/filters/utf8greekaccents.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * UTF8GreekAccents - SWFilter decendant to remove UTF-8 Greek accents + * UTF8GreekAccents - SWFilter descendant to remove UTF-8 Greek accents * */ @@ -9,239 +9,235 @@ #include <stdio.h> #include <utf8greekaccents.h> +SWORD_NAMESPACE_START -const char UTF8GreekAccents::on[] = "On"; -const char UTF8GreekAccents::off[] = "Off"; -const char UTF8GreekAccents::optName[] = "Greek Accents"; -const char UTF8GreekAccents::optTip[] = "Toggles Greek Accents"; +const char oName[] = "Greek Accents"; +const char oTip[] = "Toggles Greek Accents"; -UTF8GreekAccents::UTF8GreekAccents() { - option = true; - options.push_back(on); - options.push_back(off); +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +UTF8GreekAccents::UTF8GreekAccents() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("On"); } UTF8GreekAccents::~UTF8GreekAccents(){}; -void UTF8GreekAccents::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} - -const char *UTF8GreekAccents::getOptionValue() -{ - return (option) ? on:off; -} -char UTF8GreekAccents::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ - if (!option) { - unsigned char *to, *from; - - to = (unsigned char*)text; - for (from = (unsigned char*)text; *from; from++) { - //first just remove combining characters - if (*from == 0xE2 && *(from + 1) == 0x80 && *(from + 2) == 0x99) - from += 2; - else if (*from == 0xCC && *(from + 1)) { - if (*(from + 1) == 0x80 || *(from + 1) == 0x81 || *(from + 1) == 0x82 || *(from + 1) == 0x88 || *(from + 1) == 0x93 || *(from + 1) == 0x94) - from++; - } - else if (*from == 0xCD && *(from + 1) == 0xBA) - from++; - //now converted pre-composed characters to their alphabetic bases, discarding the accents - - //Greek - //capital alpha - else if ((*from == 0xCE && *(from + 1) == 0x86)) { - *to++ = 0xCE; - *to++ = 0x91; - from++; - } - //capital epsilon - else if ((*from == 0xCE && *(from + 1) == 0x88)) { - *to++ = 0xCE; - *to++ = 0x95; - from++; - } - //capital eta - else if ((*from == 0xCE && *(from + 1) == 0x89)) { - *to++ = 0xCE; - *to++ = 0x97; - from++; - } - //capital iota - else if ((*from == 0xCE && (*(from + 1) == 0x8A || *(from + 1) == 0xAA))) { - *to++ = 0xCE; - *to++ = 0x99; - from++; - } - //capital omicron - else if ((*from == 0xCE && *(from + 1) == 0x8C)) { - *to++ = 0xCE; - *to++ = 0x9F; - from++; - } - //capital upsilon - else if ((*from == 0xCE && (*(from + 1) == 0x8E || *(from + 1) == 0xAB))) { - *to++ = 0xCE; - *to++ = 0xA5; - from++; - } - //capital omega - else if ((*from == 0xCE && *(from + 1) == 0x8F)) { - *to++ = 0xCE; - *to++ = 0xA9; - from++; - } - - //alpha - else if ((*from == 0xCE && *(from + 1) == 0xAC)) { - *to++ = 0xCE; - *to++ = 0xB1; - from++; - } - //epsilon - else if ((*from == 0xCE && *(from + 1) == 0xAD)) { - *to++ = 0xCE; - *to++ = 0xB5; - from++; - } - //eta - else if ((*from == 0xCE && *(from + 1) == 0xAE)) { - *to++ = 0xCE; - *to++ = 0xB7; - from++; - } - //iota - else if ((*from == 0xCE && *(from + 1) == 0xAF) || (*from == 0xCF && *(from + 1) == 0x8A)) { - *to++ = 0xCE; - *to++ = 0xB9; - from++; - } - //omicron - else if ((*from == 0xCF && *(from + 1) == 0x8C)) { - *to++ = 0xCE; - *to++ = 0xBF; - from++; - } - //upsilon - else if ((*from == 0xCE && *(from + 1) == 0x88) || (*from == 0xCF && (*(from + 1) == 0x8B || *(from + 1) == 0x8D))) { - *to++ = 0xCF; - *to++ = 0x85; - from++; - } - //omega - else if ((*from == 0xCF && *(from + 1) == 0x8E)) { - *to++ = 0xCF; - *to++ = 0x89; - from++; - } - - //Extended Greek - //capital alpha - else if (*from == 0xE1 && ((*(from + 1) == 0xBC || *(from + 1) == 0xBE) && *(from + 2) >= 0x88 && *(from + 2) <= 0x8F) || (*(from + 1) == 0xBE && *(from + 2) >= 0xB8 && *(from + 2) <= 0xBC)) { - *to++ = 0xCE; - *to++ = 0x91; - from+=2; - } - //capital epsilon - else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0x98 && *(from + 2) <= 0x9D) || (*(from + 1) == 0xBF && (*(from + 2) == 0x88 || *(from + 2) == 0x89)))) { - *to++ = 0xCE; - *to++ = 0x95; - from+=2; - } - //capital eta - else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0xA8 && *(from + 2) <= 0xAF) || (*(from + 1) == 0xBE && *(from + 2) >= 0x98 && *(from + 2) <= 0x9F) || (*(from + 1) == 0xBF && *(from + 2) >= 0x8A && *(from + 2) <= 0x8C))) { - *to++ = 0xCE; - *to++ = 0x97; - from+=2; - } - //capital iota - else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0xB8 && *(from + 2) <= 0xBF) || (*(from + 1) == 0xBF && *(from + 2) >= 0x98 && *(from + 2) <= 0x9B))) { - *to++ = 0xCE; - *to++ = 0x99; - from+=2; - } - //capital omicron - else if (*from == 0xE1 && ((*(from + 1) == 0xBD && *(from + 2) >= 0x88 && *(from + 2) <= 0x8D) || (*(from + 1) == 0xBF && *(from + 2) == 0xB8 || *(from + 2) == 0xB9))) { - *to++ = 0xCE; - *to++ = 0x9F; - from+=2; - } - //capital upsilon - else if (*from == 0xE1 && ((*(from + 1) == 0xBD && *(from + 2) >= 0x99 && *(from + 2) <= 0x9F) || (*(from + 1) == 0xBF && *(from + 2) >= 0xA8 && *(from + 2) <= 0xAB))) { - *to++ = 0xCE; - *to++ = 0xA5; - from+=2; - } - //capital omega - else if (*from == 0xE1 && (((*(from + 1) == 0xBD || *(from + 1) == 0xBE) && *(from + 2) >= 0xA8 && *(from + 2) <= 0xAF) || (*(from + 1) == 0xBF && *(from + 2) >= 0xBA && *(from + 2) <= 0xBC))) { - *to++ = 0xCE; - *to++ = 0xA9; - from+=2; - } - //capital rho - else if (*from == 0xE1 && *(from + 1) == 0xBF && *(from + 2) == 0xAC) { - *to++ = 0xCE; - *to++ = 0xA1; - from+=2; - } - - //alpha - else if (*from == 0xE1 && ((*(from + 1) == 0xBC || *(from + 1) == 0xBE) && *(from + 2) >= 0x80 && *(from + 2) <= 0x87) || (*(from + 1) == 0xBD && (*(from + 2) == 0xB0 || *(from + 2) == 0xB1)) || (*(from + 1) == 0xBE && *(from + 2) >= 0xB0 && *(from + 2) <= 0xB7)) { - *to++ = 0xCE; - *to++ = 0xB1; - from+=2; - } - //epsilon - else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0x90 && *(from + 2) <= 0x95) || (*(from + 1) == 0xBD && (*(from + 2) == 0xB2 || *(from + 2) == 0xB3)))) { - *to++ = 0xCE; - *to++ = 0xB5; - from+=2; - } - //eta - else if (*from == 0xE1 && ((*(from + 1) == 0xBE && *(from + 2) >= 0x90 && *(from + 2) <= 0x97) || (*(from + 1) == 0xBC && *(from + 2) >= 0xA0 && *(from + 2) <= 0xA7) || (*(from + 1) == 0xBF && *(from + 2) >= 0x82 && *(from + 2) <= 0x87) || (*(from + 1) == 0xBD && (*(from + 2) == 0xB4 || *(from + 2) == 0xB5)))) { - *to++ = 0xCE; - *to++ = 0xB7; - from+=2; - } - //iota - else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0xB0 && *(from + 2) <= 0xB7) || (*(from + 1) == 0xBD && (*(from + 2) == 0xB6 || *(from + 2) == 0xB7)) || (*(from + 1) == 0xBF && *(from + 2) >= 0x90 && *(from + 2) <= 0x97))) { - *to++ = 0xCE; - *to++ = 0xB9; - from+=2; - } - //omicron - else if (*from == 0xE1 && (*(from + 1) == 0xBD && ((*(from + 2) >= 0x80 && *(from + 2) <= 0x85) || (*(from + 2) == 0xB8 || *(from + 2) == 0xB9)))) { - *to++ = 0xCE; - *to++ = 0xBF; - from+=2; - } - //upsilon - else if (*from == 0xE1 && ((*(from + 1) == 0xBD && ((*(from + 2) >= 0x90 && *(from + 2) <= 0x97) || *(from + 2) == 0xBA || *(from + 2) == 0xBB)) || (*(from + 1) == 0xBF && ((*(from + 2) >= 0xA0 && *(from + 2) <= 0xA3) || *(from + 2) == 0xA6 || *(from + 2) == 0xA7)))) { - *to++ = 0xCF; - *to++ = 0x85; - from+=2; - } - //omega - else if (*from == 0xE1 && ((*(from + 1) == 0xBD && ((*(from + 2) >= 0xA0 && *(from + 2) <= 0xA7) || (*(from + 2) == 0xBC || *(from + 2) == 0xBD))) || (*(from + 1) == 0xBE && (*(from + 2) >= 0xA0 && *(from + 2) <= 0xA7)) || (*(from + 1) == 0xBF && *(from + 2) >= 0xB2 && *(from + 2) <= 0xB7))) { - *to++ = 0xCF; - *to++ = 0x89; - from+=2; - } - //rho - else if (*from == 0xE1 && *(from + 1) == 0xBF && (*(from + 2) == 0xA4 && *(from + 2) == 0xA5)) { - *to++ = 0xCF; - *to++ = 0x81; - from+=2; - } - else - *to++ = *from; +char UTF8GreekAccents::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + + if (!option) { //we don't want greek accents + //unsigned char *to, *from; + //to = (unsigned char*)text; + //for (from = (unsigned char*)text; *from; from++) { + + SWBuf orig = text; + const unsigned char* from = (unsigned char*)orig.c_str(); + for (text = ""; *from; from++) { + //first just remove combining characters + if (*from == 0xE2 && *(from + 1) == 0x80 && *(from + 2) == 0x99) { + from += 2; + } + else if (*from == 0xCC && *(from + 1)) { + if (*(from + 1) == 0x80 || *(from + 1) == 0x81 || *(from + 1) == 0x82 || *(from + 1) == 0x88 || *(from + 1) == 0x93 || *(from + 1) == 0x94) { + from++; + } + } + else if (*from == 0xCD && *(from + 1) == 0xBA) { + from++; + } + //now converted pre-composed characters to their alphabetic bases, discarding the accents + + //Greek + //capital alpha + else if ((*from == 0xCE && *(from + 1) == 0x86)) { + text += 0xCE; + text += 0x91; + from++; + } + //capital epsilon + else if ((*from == 0xCE && *(from + 1) == 0x88)) { + text += 0xCE; + text += 0x95; + from++; + } + //capital eta + else if ((*from == 0xCE && *(from + 1) == 0x89)) { + text += 0xCE; + text += 0x97; + from++; + } + //capital iota + else if ((*from == 0xCE && (*(from + 1) == 0x8A || *(from + 1) == 0xAA))) { + text += 0xCE; + text += 0x99; + from++; + } + //capital omicron + else if ((*from == 0xCE && *(from + 1) == 0x8C)) { + text += 0xCE; + text += 0x9F; + from++; + } + //capital upsilon + else if ((*from == 0xCE && (*(from + 1) == 0x8E || *(from + 1) == 0xAB))) { + text += 0xCE; + text += 0xA5; + from++; + } + //capital omega + else if ((*from == 0xCE && *(from + 1) == 0x8F)) { + text += 0xCE; + text += 0xA9; + from++; + } + + //alpha + else if ((*from == 0xCE && *(from + 1) == 0xAC)) { + text += 0xCE; + text += 0xB1; + from++; + } + //epsilon + else if ((*from == 0xCE && *(from + 1) == 0xAD)) { + text += 0xCE; + text += 0xB5; + from++; + } + //eta + else if ((*from == 0xCE && *(from + 1) == 0xAE)) { + text += 0xCE; + text += 0xB7; + from++; + } + //iota + else if ((*from == 0xCE && *(from + 1) == 0xAF) || (*from == 0xCF && *(from + 1) == 0x8A)) { + text += 0xCE; + text += 0xB9; + from++; + } + //omicron + else if ((*from == 0xCF && *(from + 1) == 0x8C)) { + text += 0xCE; + text += 0xBF; + from++; + } + //upsilon + else if ((*from == 0xCE && *(from + 1) == 0x88) || (*from == 0xCF && (*(from + 1) == 0x8B || *(from + 1) == 0x8D))) { + text += 0xCF; + text += 0x85; + from++; + } + //omega + else if ((*from == 0xCF && *(from + 1) == 0x8E)) { + text += 0xCF; + text += 0x89; + from++; + } + + //Extended Greek + //capital alpha + else if (*from == 0xE1 && ((*(from + 1) == 0xBC || *(from + 1) == 0xBE) && *(from + 2) >= 0x88 && *(from + 2) <= 0x8F) || (*(from + 1) == 0xBE && *(from + 2) >= 0xB8 && *(from + 2) <= 0xBC)) { + text += 0xCE; + text += 0x91; + from+=2; + } + //capital epsilon + else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0x98 && *(from + 2) <= 0x9D) || (*(from + 1) == 0xBF && (*(from + 2) == 0x88 || *(from + 2) == 0x89)))) { + text += 0xCE; + text += 0x95; + from+=2; + } + //capital eta + else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0xA8 && *(from + 2) <= 0xAF) || (*(from + 1) == 0xBE && *(from + 2) >= 0x98 && *(from + 2) <= 0x9F) || (*(from + 1) == 0xBF && *(from + 2) >= 0x8A && *(from + 2) <= 0x8C))) { + text += 0xCE; + text += 0x97; + from+=2; + } + //capital iota + else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0xB8 && *(from + 2) <= 0xBF) || (*(from + 1) == 0xBF && *(from + 2) >= 0x98 && *(from + 2) <= 0x9B))) { + text += 0xCE; + text += 0x99; + from+=2; + } + //capital omicron + else if (*from == 0xE1 && ((*(from + 1) == 0xBD && *(from + 2) >= 0x88 && *(from + 2) <= 0x8D) || (*(from + 1) == 0xBF && *(from + 2) == 0xB8 || *(from + 2) == 0xB9))) { + text += 0xCE; + text += 0x9F; + from+=2; + } + //capital upsilon + else if (*from == 0xE1 && ((*(from + 1) == 0xBD && *(from + 2) >= 0x99 && *(from + 2) <= 0x9F) || (*(from + 1) == 0xBF && *(from + 2) >= 0xA8 && *(from + 2) <= 0xAB))) { + text += 0xCE; + text += 0xA5; + from+=2; + } + //capital omega + else if (*from == 0xE1 && (((*(from + 1) == 0xBD || *(from + 1) == 0xBE) && *(from + 2) >= 0xA8 && *(from + 2) <= 0xAF) || (*(from + 1) == 0xBF && *(from + 2) >= 0xBA && *(from + 2) <= 0xBC))) { + text += 0xCE; + text += 0xA9; + from+=2; + } + //capital rho + else if (*from == 0xE1 && *(from + 1) == 0xBF && *(from + 2) == 0xAC) { + text += 0xCE; + text += 0xA1; + from+=2; + } + + //alpha + else if (*from == 0xE1 && ((*(from + 1) == 0xBC || *(from + 1) == 0xBE) && *(from + 2) >= 0x80 && *(from + 2) <= 0x87) || (*(from + 1) == 0xBD && (*(from + 2) == 0xB0 || *(from + 2) == 0xB1)) || (*(from + 1) == 0xBE && *(from + 2) >= 0xB0 && *(from + 2) <= 0xB7)) { + text += 0xCE; + text += 0xB1; + from+=2; + } + //epsilon + else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0x90 && *(from + 2) <= 0x95) || (*(from + 1) == 0xBD && (*(from + 2) == 0xB2 || *(from + 2) == 0xB3)))) { + text += 0xCE; + text += 0xB5; + from+=2; + } + //eta + else if (*from == 0xE1 && ((*(from + 1) == 0xBE && *(from + 2) >= 0x90 && *(from + 2) <= 0x97) || (*(from + 1) == 0xBC && *(from + 2) >= 0xA0 && *(from + 2) <= 0xA7) || (*(from + 1) == 0xBF && *(from + 2) >= 0x82 && *(from + 2) <= 0x87) || (*(from + 1) == 0xBD && (*(from + 2) == 0xB4 || *(from + 2) == 0xB5)))) { + text += 0xCE; + text += 0xB7; + from+=2; + } + //iota + else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0xB0 && *(from + 2) <= 0xB7) || (*(from + 1) == 0xBD && (*(from + 2) == 0xB6 || *(from + 2) == 0xB7)) || (*(from + 1) == 0xBF && *(from + 2) >= 0x90 && *(from + 2) <= 0x97))) { + text += 0xCE; + text += 0xB9; + from+=2; + } + //omicron + else if (*from == 0xE1 && (*(from + 1) == 0xBD && ((*(from + 2) >= 0x80 && *(from + 2) <= 0x85) || (*(from + 2) == 0xB8 || *(from + 2) == 0xB9)))) { + text += 0xCE; + text += 0xBF; + from+=2; + } + //upsilon + else if (*from == 0xE1 && ((*(from + 1) == 0xBD && ((*(from + 2) >= 0x90 && *(from + 2) <= 0x97) || *(from + 2) == 0xBA || *(from + 2) == 0xBB)) || (*(from + 1) == 0xBF && ((*(from + 2) >= 0xA0 && *(from + 2) <= 0xA3) || *(from + 2) == 0xA6 || *(from + 2) == 0xA7)))) { + text += 0xCF; + text += 0x85; + from+=2; + } + //omega + else if (*from == 0xE1 && ((*(from + 1) == 0xBD && ((*(from + 2) >= 0xA0 && *(from + 2) <= 0xA7) || (*(from + 2) == 0xBC || *(from + 2) == 0xBD))) || (*(from + 1) == 0xBE && (*(from + 2) >= 0xA0 && *(from + 2) <= 0xA7)) || (*(from + 1) == 0xBF && *(from + 2) >= 0xB2 && *(from + 2) <= 0xB7))) { + text += 0xCF; + text += 0x89; + from+=2; + } + //rho + else if (*from == 0xE1 && *(from + 1) == 0xBF && (*(from + 2) == 0xA4 && *(from + 2) == 0xA5)) { + text += 0xCF; + text += 0x81; + from+=2; + } + else { //no characters we filter + text += *from; + } + } } - *to++ = 0; - *to = 0; - } return 0; } @@ -250,3 +246,4 @@ char UTF8GreekAccents::ProcessText(char *text, int maxlen, const SWKey *key, con +SWORD_NAMESPACE_END diff --git a/src/modules/filters/utf8hebrewpoints.cpp b/src/modules/filters/utf8hebrewpoints.cpp index e5b50e1..0476db8 100644 --- a/src/modules/filters/utf8hebrewpoints.cpp +++ b/src/modules/filters/utf8hebrewpoints.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * UTF8HebrewPoints - SWFilter decendant to remove UTF-8 Hebrew vowel points + * UTF8HebrewPoints - SWFilter descendant to remove UTF-8 Hebrew vowel points * */ @@ -9,47 +9,36 @@ #include <stdio.h> #include <utf8hebrewpoints.h> +SWORD_NAMESPACE_START -const char UTF8HebrewPoints::on[] = "On"; -const char UTF8HebrewPoints::off[] = "Off"; -const char UTF8HebrewPoints::optName[] = "Hebrew Vowel Points"; -const char UTF8HebrewPoints::optTip[] = "Toggles Hebrew Vowel Points"; +const char oName[] = "Hebrew Vowel Points"; +const char oTip[] = "Toggles Hebrew Vowel Points"; -UTF8HebrewPoints::UTF8HebrewPoints() { - option = true; - options.push_back(on); - options.push_back(off); +const SWBuf choices[3] = {"On", "Off", ""}; +const StringList oValues(&choices[0], &choices[2]); + +UTF8HebrewPoints::UTF8HebrewPoints() : SWOptionFilter(oName, oTip, &oValues) { + setOptionValue("On"); } UTF8HebrewPoints::~UTF8HebrewPoints(){}; -void UTF8HebrewPoints::setOptionValue(const char *ival) -{ - option = (!stricmp(ival, on)); -} - -const char *UTF8HebrewPoints::getOptionValue() -{ - return (option) ? on:off; -} -char UTF8HebrewPoints::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ +char UTF8HebrewPoints::processText(SWBuf &text, const SWKey *key, const SWModule *module) { if (!option) { - unsigned char *to, *from; - - to = (unsigned char*)text; //The UTF-8 range 0xD6 0xB0 to 0xD6 0xBF excluding 0xD6 0x consist of Hebrew cantillation marks so block those out. - for (from = (unsigned char*)text; *from; from++) { + SWBuf orig = text; + const unsigned char* from = (unsigned char*)orig.c_str(); + for (text = ""; *from; from++) { if ((*from == 0xD6) && (*(from + 1) >= 0xB0 && *(from + 1) <= 0xBF) && (*(from + 1) != 0xBE)) { from++; } else { - *to++ = *from; + text += *from; } } - *to++ = 0; - *to = 0; - } + } return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/utf8html.cpp b/src/modules/filters/utf8html.cpp index 7487815..94fbdc1 100644 --- a/src/modules/filters/utf8html.cpp +++ b/src/modules/filters/utf8html.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * utf8html - SWFilter decendant to convert a UTF-8 stream to HTML escapes + * utf8html - SWFilter descendant to convert a UTF-8 stream to HTML escapes * */ @@ -9,29 +9,32 @@ #include <stdio.h> #include <utf8html.h> +SWORD_NAMESPACE_START + UTF8HTML::UTF8HTML() { } -char UTF8HTML::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char UTF8HTML::processText(SWBuf &text, const SWKey *key, const SWModule *module) { - unsigned char *to, *from; + unsigned char *from; int len; char digit[10]; unsigned long ch; + if ((unsigned long)key < 2) // hack, we're en(1)/de(0)ciphering + return -1; + + len = strlenw(text.c_str()) + 2; // shift string to right of buffer + + SWBuf orig = text; + from = (unsigned char *)orig.c_str(); - len = strlenw(text) + 2; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = (unsigned char*)&text[maxlen - len]; - } - else from = (unsigned char*)text; // ------------------------------- - for (to = (unsigned char*)text; *from; from++) { + for (text = ""; *from; from++) { ch = 0; if ((*from & 128) != 128) { // if (*from != ' ') - *to++ = *from; + text += *from; continue; } if ((*from & 128) && ((*from & 64) != 64)) { @@ -53,14 +56,14 @@ char UTF8HTML::ProcessText(char *text, int maxlen, const SWKey *key, const SWMod ch |= (((short)*from) << (((6*subsequent)+significantFirstBits)-8)); from += subsequent; - *to++ = '&'; - *to++ = '#'; + text += '&'; + text += '#'; sprintf(digit, "%d", ch); for (char *dig = digit; *dig; dig++) - *to++ = *dig; - *to++ = ';'; + text += *dig; + text += ';'; } - *to++ = 0; - *to = 0; return 0; } + +SWORD_NAMESPACE_END diff --git a/src/modules/filters/utf8latin1.cpp b/src/modules/filters/utf8latin1.cpp index 6cc1acd..6ab4c9c 100644 --- a/src/modules/filters/utf8latin1.cpp +++ b/src/modules/filters/utf8latin1.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * UTF8Latin1 - SWFilter decendant to convert UTF-8 to Latin-1 + * UTF8Latin1 - SWFilter descendant to convert UTF-8 to Latin-1 * */ @@ -9,31 +9,32 @@ #include <utf8latin1.h> +SWORD_NAMESPACE_START + UTF8Latin1::UTF8Latin1(char rchar) : replacementChar(rchar) { } -char UTF8Latin1::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char UTF8Latin1::processText(SWBuf &text, const SWKey *key, const SWModule *module) { unsigned char *from; - unsigned short *to; int len; unsigned long uchar; unsigned char significantFirstBits, subsequent; - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = (unsigned char*)&text[maxlen - len]; + if ((unsigned long)key < 2) {// hack, we're en(1)/de(0)ciphering + return -1; } - else - from = (unsigned char*)text; - + len = strlen(text.c_str()) + 1; // shift string to right of buffer + + SWBuf orig = text; + from = (unsigned char*)orig.c_str(); + // ------------------------------- - for (to = (unsigned short*)text; *from; from++) { + for (text = ""; *from; from++) { uchar = 0; if ((*from & 128) != 128) { // if (*from != ' ') @@ -60,15 +61,14 @@ char UTF8Latin1::ProcessText(char *text, int maxlen, const SWKey *key, const SWM } if (uchar < 0xff) { - *to++ = (unsigned char)uchar; + text += (unsigned char)uchar; } else { - *to++ = replacementChar; + text += replacementChar; } } - *to++ = 0; - *to = 0; - return 0; } +SWORD_NAMESPACE_END + diff --git a/src/modules/filters/utf8nfc.cpp b/src/modules/filters/utf8nfc.cpp index df9e090..5500224 100644 --- a/src/modules/filters/utf8nfc.cpp +++ b/src/modules/filters/utf8nfc.cpp @@ -1,13 +1,12 @@ /****************************************************************************** * -* utf8nfc - SWFilter decendant to perform NFC (canonical composition +* utf8nfc - SWFilter descendant to perform NFC (canonical composition * normalization) on UTF-8 text */ #ifdef _ICU_ #include <stdlib.h> -#include <string.h> #ifdef __GNUC__ #include <unixstr.h> @@ -15,6 +14,8 @@ #include <utf8nfc.h> +SWORD_NAMESPACE_START + UTF8NFC::UTF8NFC() { conv = ucnv_open("UTF-8", &err); } @@ -23,19 +24,24 @@ UTF8NFC::~UTF8NFC() { ucnv_close(conv); } -char UTF8NFC::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char UTF8NFC::processText(SWBuf &text, const SWKey *key, const SWModule *module) { - int32_t len = strlen(text) * 2; + if ((unsigned long)key < 2) // hack, we're en(1)/de(0)ciphering + return -1; + + int32_t len = text.length() * 2; source = new UChar[len + 1]; //each char could become a surrogate pair // Convert UTF-8 string to UTF-16 (UChars) - len = ucnv_toUChars(conv, source, len, text, -1, &err); + len = ucnv_toUChars(conv, source, len, text.c_str(), -1, &err); target = new UChar[len + 1]; //canonical composition unorm_normalize(source, len, UNORM_NFC, 0, target, len, &err); - ucnv_fromUChars(conv, text, maxlen, target, -1, &err); + text.setSize(text.size()*2); + len = ucnv_fromUChars(conv, text.getRawData(), text.size(), target, -1, &err); + text.setSize(len); delete [] source; delete [] target; @@ -43,4 +49,5 @@ char UTF8NFC::ProcessText(char *text, int maxlen, const SWKey *key, const SWModu return 0; } +SWORD_NAMESPACE_END #endif diff --git a/src/modules/filters/utf8nfkd.cpp b/src/modules/filters/utf8nfkd.cpp index 450cbbf..6da24f8 100644 --- a/src/modules/filters/utf8nfkd.cpp +++ b/src/modules/filters/utf8nfkd.cpp @@ -1,13 +1,12 @@ /****************************************************************************** * -* utf8nfkd - SWFilter decendant to perform NFKD (compatability decomposition +* utf8nfkd - SWFilter descendant to perform NFKD (compatability decomposition * normalization) on UTF-8 text */ #ifdef _ICU_ #include <stdlib.h> -#include <string.h> #ifdef __GNUC__ #include <unixstr.h> @@ -15,6 +14,8 @@ #include <utf8nfkd.h> +SWORD_NAMESPACE_START + UTF8NFKD::UTF8NFKD() { conv = ucnv_open("UTF-8", &err); } @@ -23,24 +24,30 @@ UTF8NFKD::~UTF8NFKD() { ucnv_close(conv); } -char UTF8NFKD::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char UTF8NFKD::processText(SWBuf &text, const SWKey *key, const SWModule *module) { - int32_t len = strlen(text) * 2; + if ((unsigned long)key < 2) // hack, we're en(1)/de(0)ciphering + return -1; + + int32_t len = text.length() * 2; source = new UChar[len + 1]; //each char could become a surrogate pair // Convert UTF-8 string to UTF-16 (UChars) - len = ucnv_toUChars(conv, source, len, text, -1, &err); + len = ucnv_toUChars(conv, source, len, text.c_str(), -1, &err); target = new UChar[len + 1]; //compatability decomposition unorm_normalize(source, len, UNORM_NFKD, 0, target, len, &err); - ucnv_fromUChars(conv, text, maxlen, target, -1, &err); + text.setSize(text.size()*2); + len = ucnv_fromUChars(conv, text.getRawData(), text.size(), target, -1, &err); + text.setSize(len); - delete [] source; - delete [] target; + delete [] source; + delete [] target; return 0; } +SWORD_NAMESPACE_END #endif diff --git a/src/modules/filters/utf8transliterator.cpp b/src/modules/filters/utf8transliterator.cpp index 7bc068a..b753c0c 100644 --- a/src/modules/filters/utf8transliterator.cpp +++ b/src/modules/filters/utf8transliterator.cpp @@ -1,27 +1,43 @@ /****************************************************************************** * -* utf8transliterators - SWFilter decendant to transliterate between +* utf8transliterators - SWFilter descendant to transliterate between * ICU-supported scripts. */ #ifdef _ICU_ #include <stdlib.h> -#include <string.h> #ifdef __GNUC__ #include <unixstr.h> #endif +#include <unicode/ucnv.h> +#include <unicode/uchar.h> #include <utf8transliterator.h> +#ifndef _ICUSWORD_ +#include "unicode/resbund.h" +#endif +#include <swlog.h> + +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", @@ -29,7 +45,6 @@ const char UTF8Transliterator::optionstring[NUMTARGETSCRIPTS][16] = { "Syriac", "Katakana", "Hiragana", - "Jamo", "Hangul", "Devanagari", "Tamil", @@ -46,19 +61,253 @@ const char UTF8Transliterator::optionstring[NUMTARGETSCRIPTS][16] = { "Ethiopic", "Gothic", "Ugaritic", - "Coptic" - */ + "Coptic", + "Meroitic", + "Linear B", + "Cypriot", + "Runic", + "Ogham", + "Thaana", + "Glagolitic", + "Tengwar", + "Cirth" }; const char UTF8Transliterator::optName[] = "Transliteration"; const char UTF8Transliterator::optTip[] = "Transliterates between scripts"; +SWTransMap UTF8Transliterator::transMap; + +#ifndef _ICUSWORD_ + +const char UTF8Transliterator::SW_RB_RULE_BASED_IDS[] = "RuleBasedTransliteratorIDs"; +const char UTF8Transliterator::SW_RB_RULE[] = "Rule"; +#ifdef SWICU_DATA +const char UTF8Transliterator::SW_RESDATA[] = SWICU_DATA; +#else +const char UTF8Transliterator::SW_RESDATA[] = "/usr/local/lib/sword/"; +#endif + +class SWCharString { + public: + inline SWCharString(const UnicodeString& str); + inline ~SWCharString(); + inline operator const char*() { return ptr; } + private: + char buf[128]; + char* ptr; +}; +SWCharString::SWCharString(const UnicodeString& str) { + // TODO This isn't quite right -- we should probably do + // preflighting here to determine the real length. + if (str.length() >= (int32_t)sizeof(buf)) { + ptr = new char[str.length() + 8]; + } else { + ptr = buf; + } + str.extract(0, 0x7FFFFFFF, ptr, ""); +} + +SWCharString::~SWCharString() { + if (ptr != buf) { + delete[] ptr; + } +} + +#endif // _ICUSWORD_ + + UTF8Transliterator::UTF8Transliterator() { option = 0; unsigned long i; for (i = 0; i < NUMTARGETSCRIPTS; i++) { options.push_back(optionstring[i]); } +#ifndef _ICUSWORD_ + utf8status = U_ZERO_ERROR; + Load(utf8status); +#endif +} + +void UTF8Transliterator::Load(UErrorCode &status) +{ +#ifndef _ICUSWORD_ + static const char translit_swordindex[] = "translit_swordindex"; + + UResourceBundle *bundle, *transIDs, *colBund; + bundle = ures_openDirect(SW_RESDATA, translit_swordindex, &status); + if (U_FAILURE(status)) { + SWLog::systemlog->LogError("no resource index to load"); + SWLog::systemlog->LogError("status %s", u_errorName(status)); + return; + } + + transIDs = ures_getByKey(bundle, SW_RB_RULE_BASED_IDS, 0, &status); + UParseError parseError; + + int32_t row, maxRows; + if (U_SUCCESS(status)) { + maxRows = ures_getSize(transIDs); + for (row = 0; row < maxRows; row++) { + colBund = ures_getByIndex(transIDs, row, 0, &status); + + if (U_SUCCESS(status) && ures_getSize(colBund) == 4) { + UnicodeString id = ures_getUnicodeStringByIndex(colBund, 0, &status); + UChar type = ures_getUnicodeStringByIndex(colBund, 1, &status).charAt(0); + UnicodeString resString = ures_getUnicodeStringByIndex(colBund, 2, &status); + SWLog::systemlog->LogInformation("ok so far"); + + if (U_SUCCESS(status)) { + switch (type) { + case 0x66: // 'f' + case 0x69: // 'i' + // 'file' or 'internal'; + // row[2]=resource, row[3]=direction + { + UBool visible = (type == 0x0066 /*f*/); + UTransDirection dir = + (ures_getUnicodeStringByIndex(colBund, 3, &status).charAt(0) == + 0x0046 /*F*/) ? + UTRANS_FORWARD : UTRANS_REVERSE; + //registry->put(id, resString, dir, visible); + SWLog::systemlog->LogInformation("instantiating %s ...", resString.getBuffer()); + registerTrans(id, resString, dir, status); + SWLog::systemlog->LogInformation("done."); + } + break; + case 0x61: // 'a' + // 'alias'; row[2]=createInstance argument + //registry->put(id, resString, TRUE); + break; + } + } + else SWLog::systemlog->LogError("Failed to get resString"); + } + else SWLog::systemlog->LogError("Failed to get row"); + ures_close(colBund); + } + } + else + { + SWLog::systemlog->LogError("no resource index to load"); + SWLog::systemlog->LogError("status %s", u_errorName(status)); + } + + ures_close(transIDs); + ures_close(bundle); + +#endif // _ICUSWORD_ +} + +void UTF8Transliterator::registerTrans(const UnicodeString& ID, const UnicodeString& resource, + UTransDirection dir, UErrorCode &status ) +{ +#ifndef _ICUSWORD_ + SWLog::systemlog->LogInformation("registering ID locally %s", ID.getBuffer()); + SWTransData swstuff; + swstuff.resource = resource; + swstuff.dir = dir; + SWTransPair swpair; + swpair.first = ID; + swpair.second = swstuff; + transMap.insert(swpair); +#endif +} + +bool UTF8Transliterator::checkTrans(const UnicodeString& ID, UErrorCode &status ) +{ +#ifndef _ICUSWORD_ + Transliterator *trans = Transliterator::createInstance(ID, UTRANS_FORWARD, status); + if (!U_FAILURE(status)) + { + // already have it, clean up and return true + SWLog::systemlog->LogInformation("already have it %s", ID.getBuffer()); + delete trans; + return true; + } + status = U_ZERO_ERROR; + + SWTransMap::iterator swelement; + if ((swelement = transMap.find(ID)) != transMap.end()) + { + SWLog::systemlog->LogInformation("found element in map"); + SWTransData swstuff = (*swelement).second; + UParseError parseError; + //UErrorCode status; + //std::cout << "unregistering " << ID << std::endl; + //Transliterator::unregister(ID); + SWLog::systemlog->LogInformation("resource is %s", swstuff.resource.getBuffer()); + + // Get the rules + //std::cout << "importing: " << ID << ", " << resource << std::endl; + SWCharString ch(swstuff.resource); + UResourceBundle *bundle = ures_openDirect(SW_RESDATA, ch, &status); + const UnicodeString rules = ures_getUnicodeStringByKey(bundle, SW_RB_RULE, &status); + ures_close(bundle); + //parser.parse(rules, isReverse ? UTRANS_REVERSE : UTRANS_FORWARD, + // parseError, status); + if (U_FAILURE(status)) { + SWLog::systemlog->LogError("Failed to get rules"); + SWLog::systemlog->LogError("status %s", u_errorName(status)); + return false; + } + + + Transliterator *trans = Transliterator::createFromRules(ID, rules, swstuff.dir, + parseError,status); + if (U_FAILURE(status)) { + SWLog::systemlog->LogError("Failed to create transliterator"); + SWLog::systemlog->LogError("status %s", u_errorName(status)); + SWLog::systemlog->LogError("Parse error: line %s", parseError.line); + SWLog::systemlog->LogError("Parse error: offset %d", parseError.offset); + SWLog::systemlog->LogError("Parse error: preContext %s", *parseError.preContext); + SWLog::systemlog->LogError("Parse error: postContext %s", *parseError.postContext); + SWLog::systemlog->LogError("rules were"); +// SWLog::systemlog->LogError((const char *)rules); + return false; + } + + Transliterator::registerInstance(trans); + return true; + + //Transliterator *trans = instantiateTrans(ID, swstuff.resource, swstuff.dir, parseError, status); + //return trans; + } + else + { + return false; + } +#else +return true; +#endif // _ICUSWORD_ +} + +bool UTF8Transliterator::addTrans(const char* newTrans, SWBuf* transList) { +#ifdef _ICUSWORD_ + UErrorCode status; + if (checkTrans(UnicodeString(newTrans), status)) { +#endif + *transList += newTrans; + *transList += ";"; + return true; +#ifdef _ICUSWORD_ + } + else { + return false; + } +#endif +} + +Transliterator * UTF8Transliterator::createTrans(const UnicodeString& ID, UTransDirection dir, UErrorCode &status ) +{ + Transliterator *trans = Transliterator::createInstance(ID,UTRANS_FORWARD,status); + if (U_FAILURE(status)) { + delete trans; + return NULL; + } + else { + return trans; + } } void UTF8Transliterator::setOptionValue(const char *ival) @@ -75,20 +324,16 @@ const char *UTF8Transliterator::getOptionValue() return (NUMTARGETSCRIPTS > option) ? optionstring[option] : 0; } -char UTF8Transliterator::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) +char UTF8Transliterator::processText(SWBuf &text, const SWKey *key, const SWModule *module) { if (option) { // if we want transliteration unsigned long i, j; UErrorCode err = U_ZERO_ERROR; UConverter * conv = NULL; conv = ucnv_open("UTF-8", &err); + SWBuf ID; bool compat = false; - bool noNFC = false; - - if (option == SE_JAMO) { - noNFC = true; - } // Convert UTF-8 string to UTF-16 (UChars) j = strlen(text); @@ -107,8 +352,9 @@ char UTF8Transliterator::ProcessText(char *text, int maxlen, const SWKey *key, c for (i = 0; i < len; i++) { j = ublock_getCode(source[i]); + scripts[SE_LATIN] = true; switch (j) { - case UBLOCK_BASIC_LATIN: scripts[SE_LATIN] = true; break; + //case UBLOCK_BASIC_LATIN: scripts[SE_LATIN] = true; break; case UBLOCK_GREEK: scripts[SE_GREEK] = true; break; case UBLOCK_HEBREW: scripts[SE_HEBREW] = true; break; case UBLOCK_CYRILLIC: scripts[SE_CYRILLIC] = true; break; @@ -132,8 +378,16 @@ char UTF8Transliterator::ProcessText(char *text, int maxlen, const SWKey *key, c case UBLOCK_ARMENIAN: scripts[SE_ARMENIAN] = true; break; case UBLOCK_ETHIOPIC: scripts[SE_ETHIOPIC] = true; break; case UBLOCK_GOTHIC: scripts[SE_GOTHIC] = true; break; - // needs Unicode 3.2? or 4.0? support from ICU - //case UBLOCK_UGARITIC: scripts[SE_UGARITIC] = 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_CJK_RADICALS_SUPPLEMENT: case UBLOCK_KANGXI_RADICALS: case UBLOCK_IDEOGRAPHIC_DESCRIPTION_CHARACTERS: @@ -153,11 +407,11 @@ char UTF8Transliterator::ProcessText(char *text, int maxlen, const SWKey *key, c compat = true; break; - default: scripts[SE_LATIN] = true; + //default: scripts[SE_LATIN] = true; } - } + } scripts[option] = false; //turn off the reflexive transliteration - + //return if we have no transliteration to do for this text j = 0; for (i = 0; !j && i < NUMSCRIPTS; i++) { @@ -168,312 +422,468 @@ char UTF8Transliterator::ProcessText(char *text, int maxlen, const SWKey *key, c return 0; } - UnicodeString id; if (compat) { - id = UnicodeString("NFKD"); + addTrans("NFKD", &ID); } else { - id = UnicodeString("NFD"); + addTrans("NFD", &ID); } //Simple X to Latin transliterators if (scripts[SE_GREEK]) { - if (option == SE_BETA) - id += UnicodeString(";Greek-Beta"); - else if (option == SE_BGREEK) - id += UnicodeString(";Greek-BGreek"); + if (strnicmp (((SWModule*)module)->Lang(), "cop", 3)) { + if (option == SE_SBL) + addTrans("Greek-Latin/SBL", &ID); + else if (option == SE_TC) + addTrans("Greek-Latin/TC", &ID); + else if (option == SE_BETA) + addTrans("Greek-Latin/Beta", &ID); + else if (option == SE_BGREEK) + addTrans("Greek-Latin/BGreek", &ID); + else if (option == SE_UNGEGN) + addTrans("Greek-Latin/UNGEGN", &ID); + else if (option == SE_ISO) + 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_IPA) + addTrans("Greek-IPA/Ancient", &ID); + else { + addTrans("Greek-Latin", &ID); + scripts[SE_LATIN] = true; + } + } else { - if (!strnicmp (((SWModule*)module)->Lang(), "cop", 3)) { - id += UnicodeString(";Coptic-Latin"); - } - else { - id += UnicodeString(";Greek-Latin"); - } - scripts[SE_LATIN] = true; + if (option == SE_SBL) + addTrans("Coptic-Latin/SBL", &ID); + else if (option == SE_TC) + addTrans("Coptic-Latin/TC", &ID); + else if (option == SE_BETA) + addTrans("Coptic-Latin/Beta", &ID); + else if (option == SE_IPA) + addTrans("Coptic-IPA", &ID); + else { + addTrans("Coptic-Latin", &ID); + scripts[SE_LATIN] = true; + } } } if (scripts[SE_HEBREW]) { - if (option == SE_BETA) - id += UnicodeString(";Hebrew-CCAT"); + if (option == SE_SBL) + addTrans("Hebrew-Latin/SBL", &ID); + else if (option == SE_TC) + addTrans("Hebrew-Latin/TC", &ID); + else if (option == SE_BETA) + addTrans("Hebrew-Latin/Beta", &ID); + else if (option == SE_UNGEGN) + addTrans("Hebrew-Latin/UNGEGN", &ID); + else if (option == SE_ALALC) + addTrans("Hebrew-Latin/ALALC", &ID); else if (option == SE_SYRIAC) - id += UnicodeString(";Hebrew-Syriac"); + addTrans("Hebrew-Syriac", &ID); else { - id += UnicodeString(";Hebrew-Latin"); - scripts[SE_LATIN] = true; + addTrans("Hebrew-Latin", &ID); + scripts[SE_LATIN] = true; } } if (scripts[SE_CYRILLIC]) { - id += UnicodeString(";Cyrillic-Latin"); - scripts[SE_LATIN] = true; + if (option == SE_GLAGOLITIC) + addTrans("Cyrillic-Glagolitic", &ID); + else { + addTrans("Cyrillic-Latin", &ID); + scripts[SE_LATIN] = true; + } } if (scripts[SE_ARABIC]) { - id += UnicodeString(";Arabic-Latin"); + addTrans("Arabic-Latin", &ID); scripts[SE_LATIN] = true; } if (scripts[SE_SYRIAC]) { - if (option == SE_BETA) - id += UnicodeString(";Syriac-CCAT"); + if (option == SE_TC) + addTrans("Syriac-Latin/TC", &ID); + else if (option == SE_BETA) + addTrans("Syriac-Latin/Beta", &ID); + else if (option == SE_HUGOYE) + addTrans("Syriac-Latin/Hugoye", &ID); else if (option == SE_HEBREW) - id += UnicodeString(";Syriac-Hebrew"); + addTrans("Syriac-Hebrew", &ID); else { - id += UnicodeString(";Syriac-Latin"); + addTrans("Syriac-Latin", &ID); scripts[SE_LATIN] = true; } } if (scripts[SE_THAI]) { - id += UnicodeString(";Thai-Latin"); + addTrans("Thai-Latin", &ID); scripts[SE_LATIN] = true; } if (scripts[SE_GEORGIAN]) { - id += UnicodeString(";Georgian-Latin"); - scripts[SE_LATIN] = true; + if (option == SE_ISO) + 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_IPA) + addTrans("Georgian-IPA", &ID); + else { + addTrans("Georgian-Latin", &ID); + scripts[SE_LATIN] = true; + } } if (scripts[SE_ARMENIAN]) { - id += UnicodeString(";Armenian-Latin"); - scripts[SE_LATIN] = true; - } + if (option == SE_ISO) + 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_IPA) + addTrans("Armenian-IPA", &ID); + else { + addTrans("Armenian-Latin", &ID); + scripts[SE_LATIN] = true; + } + } if (scripts[SE_ETHIOPIC]) { - id += UnicodeString(";Ethiopic-Latin"); - scripts[SE_LATIN] = true; + if (option == SE_UNGEGN) + addTrans("Ethiopic-Latin/UNGEGN", &ID); + else if (option == SE_ISO) + addTrans("Ethiopic-Latin/ISO", &ID); + else if (option == SE_ALALC) + addTrans("Ethiopic-Latin/ALALC", &ID); + else if (option == SE_SERA) + addTrans("Ethiopic-Latin/SERA", &ID); + else { + addTrans("Ethiopic-Latin", &ID); + scripts[SE_LATIN] = true; + } } if (scripts[SE_GOTHIC]) { - id += UnicodeString(";Gothic-Latin"); - scripts[SE_LATIN] = true; + if (option == SE_BASICLATIN) + addTrans("Gothic-Latin/Basic", &ID); + else if (option == SE_IPA) + addTrans("Gothic-IPA", &ID); + else { + addTrans("Gothic-Latin", &ID); + scripts[SE_LATIN] = true; + } } if (scripts[SE_UGARITIC]) { - id += UnicodeString(";Ugaritic-Latin"); + if (option == SE_SBL) + addTrans("Ugaritic-Latin/SBL", &ID); + else { + addTrans("Ugaritic-Latin", &ID); + scripts[SE_LATIN] = true; + } + } + if (scripts[SE_MEROITIC]) { + addTrans("Meroitic-Latin", &ID); scripts[SE_LATIN] = true; } - if (scripts[SE_HAN]) { - if (!strnicmp (((SWModule*)module)->Lang(), "ja", 2)) { - id += UnicodeString(";Kanji-OnRomaji"); - } - else { - id += UnicodeString(";Han-Pinyin"); - } + if (scripts[SE_LINEARB]) { + addTrans("LinearB-Latin", &ID); + scripts[SE_LATIN] = true; + } + if (scripts[SE_CYPRIOT]) { + addTrans("Cypriot-Latin", &ID); + scripts[SE_LATIN] = true; + } + if (scripts[SE_RUNIC]) { + addTrans("Runic-Latin", &ID); + scripts[SE_LATIN] = true; + } + if (scripts[SE_OGHAM]) { + addTrans("Ogham-Latin", &ID); + scripts[SE_LATIN] = true; + } + if (scripts[SE_THAANA]) { + if (option == SE_ALALC) + addTrans("Thaana-Latin/ALALC", &ID); + else if (option == SE_BGNPCGN) + addTrans("Thaana-Latin/BGNPCGN", &ID); + else { + addTrans("Thaana-Latin", &ID); + scripts[SE_LATIN] = true; + } + } + if (scripts[SE_GLAGOLITIC]) { + if (option == SE_ISO) + addTrans("Glagolitic-Latin/ISO", &ID); + else if (option == SE_ALALC) + addTrans("Glagolitic-Latin/ALALC", &ID); + else if (option == SE_ALALC) + addTrans("Glagolitic-Cyrillic", &ID); + else { + addTrans("Glagolitic-Latin", &ID); + scripts[SE_LATIN] = true; + } + } + if (scripts[SE_THAI]) { + addTrans("Thai-Latin", &ID); + scripts[SE_LATIN] = true; + } + if (scripts[SE_THAI]) { + addTrans("Thai-Latin", &ID); + scripts[SE_LATIN] = true; + } + + if (scripts[SE_HAN]) { + if (!strnicmp (((SWModule*)module)->Lang(), "ja", 2)) { + addTrans("Kanji-Romaji", &ID); + } + else { + addTrans("Han-Latin", &ID); + } scripts[SE_LATIN] = true; } // Inter-Kana and Kana to Latin transliterators if (option == SE_HIRAGANA && scripts[SE_KATAKANA]) { - id += UnicodeString(";Katakana-Hiragana"); + addTrans("Katakana-Hiragana", &ID); scripts[SE_HIRAGANA] = true; } else if (option == SE_KATAKANA && scripts[SE_HIRAGANA]) { - id += UnicodeString(";Hiragana-Katakana"); + addTrans("Hiragana-Katakana", &ID); scripts[SE_KATAKANA] = true; } else { if (scripts[SE_KATAKANA]) { - id += UnicodeString(";Katakana-Latin"); + addTrans("Katakana-Latin", &ID); scripts[SE_LATIN] = true; } if (scripts[SE_HIRAGANA]) { - id += UnicodeString(";Hiragana-Latin"); + addTrans("Hiragana-Latin", &ID); scripts[SE_LATIN] = true; } } - // Inter-Korean and Korean to Latin transliterators - if (option == SE_HANGUL && scripts[SE_JAMO]) { - noNFC = false; - scripts[SE_HANGUL] = true; - } - else if (option == SE_JAMO && scripts[SE_HANGUL]) { - noNFC = true; - scripts[SE_JAMO] = true; + // Korean to Latin transliterators + if (scripts[SE_HANGUL]) { + addTrans("Hangul-Latin", &ID); + scripts[SE_LATIN] = true; } - else { - if (scripts[SE_HANGUL]) { - id += UnicodeString(";Hangul-Latin"); - scripts[SE_LATIN] = true; - } - if (scripts[SE_JAMO]) { - id += UnicodeString(";Jamo-Latin"); - scripts[SE_LATIN] = true; - } + if (scripts[SE_JAMO]) { + addTrans("Jamo-Latin", &ID); + scripts[SE_LATIN] = true; } // Indic-Latin if (option < SE_DEVANAGARI || option > SE_MALAYALAM) { // Indic to Latin if (scripts[SE_TAMIL]) { - id += UnicodeString(";Tamil-Latin"); + addTrans("Tamil-Latin", &ID); scripts[SE_LATIN] = true; } if (scripts[SE_BENGALI]) { - id += UnicodeString(";Bengali-Latin"); + addTrans("Bengali-Latin", &ID); scripts[SE_LATIN] = true; } if (scripts[SE_GURMUKHI]) { - id += UnicodeString(";Gurmukhi-Latin"); + addTrans("Gurmukhi-Latin", &ID); scripts[SE_LATIN] = true; } if (scripts[SE_GUJARATI]) { - id += UnicodeString(";Gujarati-Latin"); + addTrans("Gujarati-Latin", &ID); scripts[SE_LATIN] = true; } if (scripts[SE_ORIYA]) { - id += UnicodeString(";Oriya-Latin"); + addTrans("Oriya-Latin", &ID); scripts[SE_LATIN] = true; } if (scripts[SE_TELUGU]) { - id += UnicodeString(";Telugu-Latin"); + addTrans("Telugu-Latin", &ID); scripts[SE_LATIN] = true; } if (scripts[SE_KANNADA]) { - id += UnicodeString(";Kannada-Latin"); + addTrans("Kannada-Latin", &ID); scripts[SE_LATIN] = true; } if (scripts[SE_MALAYALAM]) { - id += UnicodeString(";Malayalam-Latin"); + addTrans("Malayalam-Latin", &ID); scripts[SE_LATIN] = true; } } else { if (scripts[SE_LATIN]) { - id += UnicodeString(";Latin-InterIndic"); + addTrans("Latin-InterIndic", &ID); } if (scripts[SE_DEVANAGARI]) { - id += UnicodeString(";Devanagari-InterIndic"); + addTrans("Devanagari-InterIndic", &ID); } if (scripts[SE_TAMIL]) { - id += UnicodeString(";Tamil-InterIndic"); + addTrans("Tamil-InterIndic", &ID); } if (scripts[SE_BENGALI]) { - id += UnicodeString(";Bengali-InterIndic"); + addTrans("Bengali-InterIndic", &ID); } if (scripts[SE_GURMUKHI]) { - id += UnicodeString(";Gurmurkhi-InterIndic"); + addTrans("Gurmurkhi-InterIndic", &ID); } if (scripts[SE_GUJARATI]) { - id += UnicodeString(";Gujarati-InterIndic"); + addTrans("Gujarati-InterIndic", &ID); } if (scripts[SE_ORIYA]) { - id += UnicodeString(";Oriya-InterIndic"); + addTrans("Oriya-InterIndic", &ID); } if (scripts[SE_TELUGU]) { - id += UnicodeString(";Telugu-InterIndic"); + addTrans("Telugu-InterIndic", &ID); } if (scripts[SE_KANNADA]) { - id += UnicodeString(";Kannada-InterIndic"); + addTrans("Kannada-InterIndic", &ID); } if (scripts[SE_MALAYALAM]) { - id += UnicodeString(";Malayalam-InterIndic"); + addTrans("Malayalam-InterIndic", &ID); } switch(option) { case SE_DEVANAGARI: - id += UnicodeString(";InterIndic-Devanagari"); + addTrans("InterIndic-Devanagari", &ID); break; case SE_TAMIL: - id += UnicodeString(";InterIndic-Tamil"); + addTrans("InterIndic-Tamil", &ID); break; case SE_BENGALI: - id += UnicodeString(";InterIndic-Bengali"); + addTrans("InterIndic-Bengali", &ID); break; case SE_GURMUKHI: - id += UnicodeString(";InterIndic-Gurmukhi"); + addTrans("InterIndic-Gurmukhi", &ID); break; case SE_GUJARATI: - id += UnicodeString(";InterIndic-Gujarati"); + addTrans("InterIndic-Gujarati", &ID); break; case SE_ORIYA: - id += UnicodeString(";InterIndic-Oriya"); + addTrans("InterIndic-Oriya", &ID); break; case SE_TELUGU: - id += UnicodeString(";InterIndic-Telugu"); + addTrans("InterIndic-Telugu", &ID); break; case SE_KANNADA: - id += UnicodeString(";InterIndic-Kannada"); + addTrans("InterIndic-Kannada", &ID); break; case SE_MALAYALAM: - id += UnicodeString(";InterIndic-Malayalam"); + addTrans("InterIndic-Malayalam", &ID); break; default: - id += UnicodeString(";InterIndic-Latin"); + addTrans("InterIndic-Latin", &ID); scripts[SE_LATIN] = true; break; } } + if (scripts[SE_TENGWAR]) { + addTrans("Tengwar-Latin", &ID); + scripts[SE_LATIN] = true; + } + if (scripts[SE_CIRTH]) { + addTrans("Cirth-Latin", &ID); + scripts[SE_LATIN] = true; + } + if (scripts[SE_LATIN]) { switch (option) { case SE_GREEK: - id += UnicodeString(";Latin-Greek"); + addTrans("Latin-Greek", &ID); break; case SE_HEBREW: - id += UnicodeString(";Latin-Hebrew"); + addTrans("Latin-Hebrew", &ID); break; case SE_CYRILLIC: - id += UnicodeString(";Latin-Cyrillic"); + addTrans("Latin-Cyrillic", &ID); break; case SE_ARABIC: - id += UnicodeString(";Latin-Arabic"); + addTrans("Latin-Arabic", &ID); break; case SE_SYRIAC: - id += UnicodeString(";Latin-Syriac"); + addTrans("Latin-Syriac", &ID); break; case SE_THAI: - id += UnicodeString(";Latin-Thai"); + addTrans("Latin-Thai", &ID); break; case SE_GEORGIAN: - id += UnicodeString(";Latin-Georgian"); + addTrans("Latin-Georgian", &ID); break; case SE_ARMENIAN: - id += UnicodeString(";Latin-Armenian"); + addTrans("Latin-Armenian", &ID); break; case SE_ETHIOPIC: - id += UnicodeString(";Latin-Ethiopic"); + addTrans("Latin-Ethiopic", &ID); break; case SE_GOTHIC: - id += UnicodeString(";Latin-Gothic"); + addTrans("Latin-Gothic", &ID); break; case SE_UGARITIC: - id += UnicodeString(";Latin-Ugaritic"); + addTrans("Latin-Ugaritic", &ID); break; case SE_COPTIC: - id += UnicodeString(";Latin-Coptic"); + addTrans("Latin-Coptic", &ID); break; case SE_KATAKANA: - id += UnicodeString(";Latin-Katakana"); + addTrans("Latin-Katakana", &ID); break; case SE_HIRAGANA: - id += UnicodeString(";Latin-Hiragana"); + addTrans("Latin-Hiragana", &ID); break; case SE_JAMO: - id += UnicodeString(";Latin-Jamo"); + addTrans("Latin-Jamo", &ID); break; case SE_HANGUL: - id += UnicodeString(";Latin-Hangul"); + addTrans("Latin-Hangul", &ID); + break; + case SE_MEROITIC: + addTrans("Latin-Meroitic", &ID); + break; + case SE_LINEARB: + addTrans("Latin-LinearB", &ID); + break; + case SE_CYPRIOT: + addTrans("Latin-Cypriot", &ID); + break; + case SE_RUNIC: + addTrans("Latin-Runic", &ID); + break; + case SE_OGHAM: + addTrans("Latin-Ogham", &ID); + break; + case SE_THAANA: + addTrans("Latin-Thaana", &ID); + break; + case SE_GLAGOLITIC: + addTrans("Latin-Glagolitic", &ID); + break; + case SE_TENGWAR: + addTrans("Latin-Tengwar", &ID); + break; + case SE_CIRTH: + addTrans("Latin-Cirth", &ID); break; } } if (option == SE_BASICLATIN) { - id += UnicodeString(";Any-Latin1"); - } - - if (noNFC) { - id += UnicodeString(";NFD"); - } else { - id += UnicodeString(";NFC"); + addTrans("Any-Latin1", &ID); } - UParseError perr; + addTrans("NFC", &ID); err = U_ZERO_ERROR; - Transliterator * trans = Transliterator::createInstance(id, UTRANS_FORWARD, perr, err); - if (trans) { + Transliterator * trans = createTrans(UnicodeString(ID), UTRANS_FORWARD, err); + if (trans && !U_FAILURE(err)) { UnicodeString target = UnicodeString(source); - trans->transliterate(target); - len = ucnv_fromUChars(conv, text, maxlen, target.getBuffer(), target.length(), &err); - if (len < maxlen) *(text + len) = 0; - else *(text + maxlen) = 0; - delete trans; + trans->transliterate(target); + text.setSize(text.size()*2); + len = ucnv_fromUChars(conv, text.getRawData(), text.size(), target.getBuffer(), target.length(), &err); + text.setSize(len); + delete trans; } ucnv_close(conv); } return 0; } + +SWORD_NAMESPACE_END #endif + + + diff --git a/src/modules/filters/utf8utf16.cpp b/src/modules/filters/utf8utf16.cpp index 9aea6fe..2fddf4c 100644 --- a/src/modules/filters/utf8utf16.cpp +++ b/src/modules/filters/utf8utf16.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * UTF8UTF16 - SWFilter decendant to convert UTF-8 to UTF-16 + * UTF8UTF16 - SWFilter descendant to convert UTF-8 to UTF-16 * */ @@ -9,71 +9,70 @@ #include <utf8utf16.h> +SWORD_NAMESPACE_START + UTF8UTF16::UTF8UTF16() { } -char UTF8UTF16::ProcessText(char *text, int maxlen, const SWKey *key, const SWModule *module) -{ - unsigned char *from; - unsigned short *to; +char UTF8UTF16::processText(SWBuf &text, const SWKey *key, const SWModule *module) { + const unsigned char *from; - int len; - unsigned long uchar; - unsigned char significantFirstBits, subsequent; - unsigned short schar; - - len = strlen(text) + 1; // shift string to right of buffer - if (len < maxlen) { - memmove(&text[maxlen - len], text, len); - from = (unsigned char*)&text[maxlen - len]; - } - else - from = (unsigned char*)text; + int len; + unsigned long uchar, uchars[10]; + unsigned char significantFirstBits, subsequent; + unsigned short schar; + if ((unsigned long)key < 2) // hack, we're en(1)/de(0)ciphering + return -1; + - // ------------------------------- - - for (to = (unsigned short*)text; *from; from++) { - uchar = 0; - if ((*from & 128) != 128) { - // if (*from != ' ') - uchar = *from; - } - else if ((*from & 128) && ((*from & 64) != 64)) { - // error, do nothing - continue; - } - else { - *from <<= 1; - for (subsequent = 1; (*from & 128); subsequent++) { - *from <<= 1; - from[subsequent] &= 63; - uchar <<= 6; - uchar |= from[subsequent]; - } - subsequent--; - *from <<=1; - significantFirstBits = 8 - (2+subsequent); - - uchar |= (((short)*from) << (((6*subsequent)+significantFirstBits)-8)); - from += subsequent; - } + SWBuf orig = text; + from = (const unsigned char *)orig.c_str(); - if (uchar < 0x1ffff) { - *to++ = (unsigned short)uchar; - } - else { - uchar -= 0x10000; - schar = 0xD800 | (uchar & 0x03ff); - uchar >>= 10; - uchar |= 0xDC00; - *to++ = (unsigned short)schar; - *to++ = (unsigned short)uchar; - } - } - *to = (unsigned short)0; + for (text = ""; *from; from++) { + uchar = 0; + if ((*from & 128) != 128) { + //if (*from != ' ') + uchar = *from; + } + else if ((*from & 128) && ((*from & 64) != 64)) { + // error, do nothing + continue; + } + else { + uchars[0] = *from; + uchars[0] <<= 1; + for (subsequent = 1; (uchars[0] & 128) && (subsequent < 10); subsequent++) { + uchars[0] <<= 1; + uchars[subsequent] = from[subsequent]; + uchars[subsequent] &= 63; + uchar <<= 6; + uchar |= uchars[subsequent]; + } + subsequent--; + uchars[0] <<=1; + significantFirstBits = 8 - (2+subsequent); + + uchar |= (((short)uchars[0]) << (((6*subsequent)+significantFirstBits)-8)); + from += subsequent; + } - return 0; + if (uchar < 0x1ffff) { + text.setSize(text.size()+2); + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short)uchar; + } + else { + uchar -= 0x10000; + schar = 0xD800 | (uchar & 0x03ff); + uchar >>= 10; + uchar |= 0xDC00; + text.setSize(text.size()+4); + *((unsigned short *)(text.getRawData()+(text.size()-4))) = (unsigned short)schar; + *((unsigned short *)(text.getRawData()+(text.size()-2))) = (unsigned short)uchar; + } + } + return 0; } +SWORD_NAMESPACE_END diff --git a/src/modules/genbook/rawgenbook/rawgenbook.cpp b/src/modules/genbook/rawgenbook/rawgenbook.cpp index fab309f..4850509 100644 --- a/src/modules/genbook/rawgenbook/rawgenbook.cpp +++ b/src/modules/genbook/rawgenbook/rawgenbook.cpp @@ -13,7 +13,6 @@ #include <unistd.h> #endif -#include <string.h> #include <utilfuns.h> #include <rawgenbook.h> #include <rawstr.h> @@ -22,6 +21,8 @@ #define O_BINARY 0 #endif +SWORD_NAMESPACE_START + /****************************************************************************** * RawGenBook Constructor - Initializes data for instance of RawGenBook * @@ -35,7 +36,6 @@ RawGenBook::RawGenBook(const char *ipath, const char *iname, const char *idesc, int fileMode = O_RDWR; char *buf = new char [ strlen (ipath) + 20 ]; - entryBuf = 0; path = 0; stdstr(&path, ipath); @@ -66,43 +66,35 @@ RawGenBook::~RawGenBook() { if (path) delete [] path; - if (entryBuf) - delete [] entryBuf; } /****************************************************************************** - * RawGenBook::operator char * - Returns the correct verse when char * cast + * RawGenBook::getRawEntry - Returns the correct verse when char * cast * is requested * * RET: string buffer with verse */ -char *RawGenBook::getRawEntry() { +SWBuf &RawGenBook::getRawEntryBuf() { __u32 offset = 0; __u32 size = 0; TreeKeyIdx *key = 0; -#ifndef _WIN32_WCE try { -#endif key = SWDYNAMIC_CAST(TreeKeyIdx, (this->key)); -#ifndef _WIN32_WCE } catch ( ... ) {} -#endif if (!key) { key = (TreeKeyIdx *)CreateKey(); (*key) = *(this->key); } - if (entryBuf) - delete [] entryBuf; - int dsize; key->getUserData(&dsize); + entryBuf = ""; if (dsize > 7) { memcpy(&offset, key->getUserData(), 4); offset = swordtoarch32(offset); @@ -112,21 +104,16 @@ char *RawGenBook::getRawEntry() { entrySize = size; // support getEntrySize call - entryBuf = new char [ (size + 2) * FILTERPAD ]; - *entryBuf = 0; + entryBuf.setFillByte(0); + entryBuf.setSize(size); lseek(bdtfd->getFd(), offset, SEEK_SET); - read(bdtfd->getFd(), entryBuf, size); + read(bdtfd->getFd(), entryBuf.getRawData(), size); - rawFilter(entryBuf, size, key); + rawFilter(entryBuf, 0); // hack, decipher + rawFilter(entryBuf, key); - if (!isUnicode()) - RawStr::preptext(entryBuf); - } - else { - entryBuf = new char [2]; - entryBuf[0] = 0; - entryBuf[1] = 0; - entrySize = 0; +// if (!isUnicode()) + RawStr::prepText(entryBuf); } if (key != this->key) // free our key if we created a VerseKey @@ -136,17 +123,7 @@ char *RawGenBook::getRawEntry() { } - -#ifdef _MSC_VER -SWModule &RawGenBook::operator =(SW_POSITION p) { -#else -RawGenBook &RawGenBook::operator =(SW_POSITION p) { -#endif - SWModule::operator =(p); - return *this; -} - -SWModule &RawGenBook::setentry(const char *inbuf, long len) { +void RawGenBook::setEntry(const char *inbuf, long len) { __u32 offset = archtosword32(lseek(bdtfd->getFd(), 0, SEEK_END)); __u32 size = 0; @@ -164,27 +141,17 @@ SWModule &RawGenBook::setentry(const char *inbuf, long len) { memcpy(userData+4, &size, 4); key->setUserData(userData, 8); key->save(); - - return *this; -} - -SWModule &RawGenBook::operator <<(const char *inbuf) { - return setentry(inbuf, 0); } -SWModule &RawGenBook::operator <<(const SWKey *inkey) { +void RawGenBook::linkEntry(const SWKey *inkey) { TreeKeyIdx *srckey = 0; TreeKeyIdx *key = ((TreeKeyIdx *)this->key); // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE try { -#endif srckey = SWDYNAMIC_CAST(TreeKeyIdx, inkey); -#ifndef _WIN32_WCE } catch ( ... ) {} -#endif // if we don't have a VerseKey * decendant, create our own if (!srckey) { srckey = (TreeKeyIdx *)CreateKey(); @@ -196,8 +163,6 @@ SWModule &RawGenBook::operator <<(const SWKey *inkey) { if (inkey != srckey) // free our key if we created a VerseKey delete srckey; - - return *this; } @@ -240,3 +205,5 @@ SWKey *RawGenBook::CreateKey() { TreeKeyIdx *newKey = new TreeKeyIdx(path); return newKey; } + +SWORD_NAMESPACE_END diff --git a/src/modules/genbook/swgenbook.cpp b/src/modules/genbook/swgenbook.cpp index 589b0b9..3381ef8 100644 --- a/src/modules/genbook/swgenbook.cpp +++ b/src/modules/genbook/swgenbook.cpp @@ -5,6 +5,7 @@ #include <swgenbook.h> +SWORD_NAMESPACE_START /****************************************************************************** * SWLD Constructor - Initializes data for instance of SWLD @@ -25,3 +26,4 @@ SWGenBook::SWGenBook(const char *imodname, const char *imoddesc, SWDisplay *idis SWGenBook::~SWGenBook() { } +SWORD_NAMESPACE_END diff --git a/src/modules/lexdict/rawld/rawld.cpp b/src/modules/lexdict/rawld/rawld.cpp index b22c28b..6fccc68 100644 --- a/src/modules/lexdict/rawld/rawld.cpp +++ b/src/modules/lexdict/rawld/rawld.cpp @@ -14,11 +14,11 @@ #include <unistd.h> #endif -#include <string.h> #include <utilfuns.h> #include <rawstr.h> #include <rawld.h> +SWORD_NAMESPACE_START /****************************************************************************** * RawLD Constructor - Initializes data for instance of RawLD @@ -88,15 +88,11 @@ char RawLD::getEntry(long away) strongsPad(buf); - *entrybuf = 0; - if (!(retval = findoffset(buf, &start, &size, away))) { + if (!(retval = findOffset(buf, &start, &size, away))) { + readText(start, &size, &idxbuf, entryBuf); + rawFilter(entryBuf, 0); // hack, decipher + rawFilter(entryBuf, key); entrySize = size; // support getEntrySize call - if (entrybuf) - delete [] entrybuf; - entrybuf = new char [ ++size * FILTERPAD ]; - idxbuf = new char [ size * FILTERPAD ]; - - gettext(start, size + 1, idxbuf, entrybuf); if (!key->Persist()) // If we have our own key *key = idxbuf; // reset it to entry index buffer @@ -104,8 +100,7 @@ char RawLD::getEntry(long away) delete [] idxbuf; } else { - entrybuf = new char [ 5 ]; - *entrybuf = 0; + entryBuf = ""; } delete [] buf; @@ -114,82 +109,55 @@ char RawLD::getEntry(long away) /****************************************************************************** - * RawLD::operator char * - Returns the correct entry when char * cast + * RawLD::getRawEntry - Returns the correct entry when char * cast * is requested * * RET: string buffer with entry */ -char *RawLD::getRawEntry() { - if (!getEntry() && !isUnicode()) { - preptext(entrybuf); +SWBuf &RawLD::getRawEntryBuf() { + + char ret = getEntry(); + if (!ret) { +// if (!isUnicode()) + prepText(entryBuf); } + else error = ret; - return entrybuf; + return entryBuf; } /****************************************************************************** - * RawLD::operator += - Increments module key a number of entries + * RawLD::increment - Increments module key a number of entries * * ENT: increment - Number of entries to jump forward * * RET: *this */ -SWModule &RawLD::operator +=(int increment) -{ +void RawLD::increment(int steps) { char tmperror; if (key->Traversable()) { - *key += increment; + *key += steps; error = key->Error(); - increment = 0; + steps = 0; } - tmperror = (getEntry(increment)) ? KEYERR_OUTOFBOUNDS : 0; + tmperror = (getEntry(steps)) ? KEYERR_OUTOFBOUNDS : 0; error = (error)?error:tmperror; *key = entkeytxt; - return *this; -} - - -/****************************************************************************** - * RawLD::operator =(SW_POSITION) - Positions this key if applicable - */ - -SWModule &RawLD::operator =(SW_POSITION p) -{ - if (!key->Traversable()) { - switch (p) { - case POS_TOP: - *key = ""; - break; - case POS_BOTTOM: - *key = "zzzzzzzzz"; - break; - } - } - else *key = p; - return *this; } -SWModule &RawLD::setentry(const char *inbuf, long len) { - settext(*key, inbuf, len); - - return *this; -} - -SWModule &RawLD::operator <<(const char *inbuf) { - return setentry(inbuf, 0); +void RawLD::setEntry(const char *inbuf, long len) { + doSetText(*key, inbuf, len); } -SWModule &RawLD::operator <<(const SWKey *inkey) { - linkentry(*key, *inkey); - - return *this; +void RawLD::linkEntry(const SWKey *inkey) { + doLinkEntry(*key, *inkey); } @@ -200,5 +168,7 @@ SWModule &RawLD::operator <<(const SWKey *inkey) { */ void RawLD::deleteEntry() { - settext(*key, ""); + doSetText(*key, ""); } + +SWORD_NAMESPACE_END diff --git a/src/modules/lexdict/rawld4/rawld4.cpp b/src/modules/lexdict/rawld4/rawld4.cpp index 61d2786..a32ce25 100644 --- a/src/modules/lexdict/rawld4/rawld4.cpp +++ b/src/modules/lexdict/rawld4/rawld4.cpp @@ -14,11 +14,11 @@ #include <unistd.h> #endif -#include <string.h> #include <utilfuns.h> #include <rawstr4.h> #include <rawld4.h> +SWORD_NAMESPACE_START /****************************************************************************** * RawLD Constructor - Initializes data for instance of RawLD @@ -88,25 +88,18 @@ char RawLD4::getEntry(long away) strongsPad(buf); - *entrybuf = 0; - if (!(retval = findoffset(buf, &start, &size, away))) { + entryBuf = ""; + if (!(retval = findOffset(buf, &start, &size, away))) { + readText(start, &size, &idxbuf, entryBuf); + rawFilter(entryBuf, 0); // hack, decipher + rawFilter(entryBuf, key); entrySize = size; // support getEntrySize call - if (entrybuf) - delete [] entrybuf; - entrybuf = new char [ ++size * FILTERPAD ]; - idxbuf = new char [ size * FILTERPAD ]; - - gettext(start, size, idxbuf, entrybuf); if (!key->Persist()) // If we have our own key *key = idxbuf; // reset it to entry index buffer stdstr(&entkeytxt, idxbuf); // set entry key text that module 'snapped' to. delete [] idxbuf; } - else { - entrybuf = new char [ 5 ]; - *entrybuf = 0; - } delete [] buf; return retval; @@ -114,82 +107,55 @@ char RawLD4::getEntry(long away) /****************************************************************************** - * RawLD4::operator char * - Returns the correct entry when char * cast + * RawLD4::getRawEntry - Returns the correct entry when char * cast * is requested * * RET: string buffer with entry */ -char *RawLD4::getRawEntry() { - if (!getEntry() && !isUnicode()) { - preptext(entrybuf); +SWBuf &RawLD4::getRawEntryBuf() { + + char ret = getEntry(); + if (!ret) { +// if (!isUnicode()) + prepText(entryBuf); } + else error = ret; - return entrybuf; + return entryBuf; } /****************************************************************************** - * RawLD4::operator += - Increments module key a number of entries + * RawLD4::increment - Increments module key a number of entries * * ENT: increment - Number of entries to jump forward * * RET: *this */ -SWModule &RawLD4::operator +=(int increment) -{ +void RawLD4::increment(int steps) { char tmperror; if (key->Traversable()) { - *key += increment; + *key += steps; error = key->Error(); - increment = 0; + steps = 0; } - tmperror = (getEntry(increment)) ? KEYERR_OUTOFBOUNDS : 0; + tmperror = (getEntry(steps)) ? KEYERR_OUTOFBOUNDS : 0; error = (error)?error:tmperror; *key = entkeytxt; - return *this; } -/****************************************************************************** - * RawLD4::operator =(SW_POSITION) - Positions this key if applicable - */ - -SWModule &RawLD4::operator =(SW_POSITION p) -{ - if (!key->Traversable()) { - switch (p) { - case POS_TOP: - *key = ""; - break; - case POS_BOTTOM: - *key = "zzzzzzzzz"; - break; - } - } - else *key = p; - return *this; +void RawLD4::setEntry(const char *inbuf, long len) { + doSetText(*key, inbuf, len); } -SWModule &RawLD4::setentry(const char *inbuf, long len) { - settext(*key, inbuf, len); - - return *this; -} - -SWModule &RawLD4::operator <<(const char *inbuf) { - return setentry(inbuf, 0); -} - - -SWModule &RawLD4::operator <<(const SWKey *inkey) { - linkentry(*key, *inkey); - - return *this; +void RawLD4::linkEntry(const SWKey *inkey) { + doLinkEntry(*key, *inkey); } @@ -200,5 +166,7 @@ SWModule &RawLD4::operator <<(const SWKey *inkey) { */ void RawLD4::deleteEntry() { - settext(*key, ""); + doSetText(*key, ""); } + +SWORD_NAMESPACE_END diff --git a/src/modules/lexdict/swld.cpp b/src/modules/lexdict/swld.cpp index 97adc36..f8421cc 100644 --- a/src/modules/lexdict/swld.cpp +++ b/src/modules/lexdict/swld.cpp @@ -5,6 +5,7 @@ #include <swld.h> +SWORD_NAMESPACE_START /****************************************************************************** * SWLD Constructor - Initializes data for instance of SWLD @@ -47,9 +48,31 @@ SWLD::~SWLD() const char *SWLD::KeyText(const char *ikeytext) { if (key->Persist() && !ikeytext) { - getRawEntry(); // force module key to snap to entry + getRawEntryBuf(); // force module key to snap to entry return entkeytxt; } else return SWModule::KeyText(ikeytext); } + +/****************************************************************************** + * SWLD::setPosition(SW_POSITION) - Positions this key if applicable + */ + +void SWLD::setPosition(SW_POSITION p) { + if (!key->Traversable()) { + switch (p) { + case POS_TOP: + *key = ""; + break; + case POS_BOTTOM: + *key = "zzzzzzzzz"; + break; + } + } + else *key = p; + getRawEntryBuf(); +} + + +SWORD_NAMESPACE_END diff --git a/src/modules/lexdict/zld/zld.cpp b/src/modules/lexdict/zld/zld.cpp index 371b8a2..dd3fe8e 100644 --- a/src/modules/lexdict/zld/zld.cpp +++ b/src/modules/lexdict/zld/zld.cpp @@ -14,11 +14,11 @@ #include <unistd.h> #endif -#include <string.h> #include <utilfuns.h> #include <zstr.h> #include <zld.h> +SWORD_NAMESPACE_START /****************************************************************************** * RawLD Constructor - Initializes data for instance of RawLD @@ -29,8 +29,8 @@ * idisp - Display object to use for displaying */ -zLD::zLD(const char *ipath, const char *iname, const char *idesc, long blockCount, SWCompress *icomp, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang) : zStr(ipath, -1, blockCount, icomp), SWLD(iname, idesc, idisp, enc, dir, mark, ilang) -{ +zLD::zLD(const char *ipath, const char *iname, const char *idesc, long blockCount, SWCompress *icomp, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang) : zStr(ipath, -1, blockCount, icomp), SWLD(iname, idesc, idisp, enc, dir, mark, ilang) { + } @@ -38,8 +38,8 @@ zLD::zLD(const char *ipath, const char *iname, const char *idesc, long blockCoun * RawLD Destructor - Cleans up instance of RawLD */ -zLD::~zLD() -{ +zLD::~zLD() { + } @@ -49,8 +49,7 @@ zLD::~zLD() * ENT: buf - buffer to check and pad */ -void zLD::strongsPad(char *buf) -{ +void zLD::strongsPad(char *buf) { const char *check; long size = 0; int len = strlen(buf); @@ -76,8 +75,7 @@ void zLD::strongsPad(char *buf) * RET: error status */ -char zLD::getEntry(long away) -{ +char zLD::getEntry(long away) { char *idxbuf = 0; char *ebuf = 0; char retval = 0; @@ -88,12 +86,13 @@ char zLD::getEntry(long away) strongsPad(buf); - *entrybuf = 0; + entryBuf = ""; if (!(retval = findKeyIndex(buf, &index, away))) { getText(index, &idxbuf, &ebuf); size = strlen(ebuf) + 1; - entrybuf = new char [ size * FILTERPAD ]; - strcpy(entrybuf, ebuf); + entryBuf = ebuf; + + rawFilter(entryBuf, key); entrySize = size; // support getEntrySize call if (!key->Persist()) // If we have our own key @@ -103,11 +102,6 @@ char zLD::getEntry(long away) free(idxbuf); free(ebuf); } - else { - entrybuf = new char [ 5 ]; - entrybuf[0] = 0; - entrybuf[1] = 0; - } delete [] buf; return retval; @@ -115,82 +109,51 @@ char zLD::getEntry(long away) /****************************************************************************** - * zLD::operator char * - Returns the correct entry when char * cast + * zLD::getRawEntry - Returns the correct entry when char * cast * is requested * * RET: string buffer with entry */ -char *zLD::getRawEntry() { - if (!getEntry() && !isUnicode()) { - prepText(entrybuf); +SWBuf &zLD::getRawEntryBuf() { + if (!getEntry() /*&& !isUnicode()*/) { + prepText(entryBuf); } - return entrybuf; + return entryBuf; } /****************************************************************************** - * zLD::operator += - Increments module key a number of entries + * zLD::increment - Increments module key a number of entries * * ENT: increment - Number of entries to jump forward * * RET: *this */ -SWModule &zLD::operator +=(int increment) -{ +void zLD::increment(int steps) { char tmperror; if (key->Traversable()) { - *key += increment; + *key += steps; error = key->Error(); - increment = 0; + steps = 0; } - tmperror = (getEntry(increment)) ? KEYERR_OUTOFBOUNDS : 0; + tmperror = (getEntry(steps)) ? KEYERR_OUTOFBOUNDS : 0; error = (error)?error:tmperror; *key = entkeytxt; - return *this; -} - - -/****************************************************************************** - * zLD::operator =(SW_POSITION) - Positions this key if applicable - */ - -SWModule &zLD::operator =(SW_POSITION p) -{ - if (!key->Traversable()) { - switch (p) { - case POS_TOP: - *key = ""; - break; - case POS_BOTTOM: - *key = "zzzzzzzzz"; - break; - } - } - else *key = p; - return *this; } -SWModule &zLD::setentry(const char *inbuf, long len) { +void zLD::setEntry(const char *inbuf, long len) { setText(*key, inbuf, len); - - return *this; -} - -SWModule &zLD::operator <<(const char *inbuf) { - return setentry(inbuf, 0); } -SWModule &zLD::operator <<(const SWKey *inkey) { - linkEntry(*key, *inkey); - - return *this; +void zLD::linkEntry(const SWKey *inkey) { + zStr::linkEntry(*key, *inkey); } @@ -203,3 +166,5 @@ SWModule &zLD::operator <<(const SWKey *inkey) { void zLD::deleteEntry() { setText(*key, ""); } + +SWORD_NAMESPACE_END diff --git a/src/modules/swmodule.cpp b/src/modules/swmodule.cpp index c407894..08ad2a9 100644 --- a/src/modules/swmodule.cpp +++ b/src/modules/swmodule.cpp @@ -4,18 +4,18 @@ * etc.) */ -#include <string.h> #include <swmodule.h> #include <utilfuns.h> #include <regex.h> // GNU #include <swfilter.h> #include <versekey.h> // KLUDGE for Search #ifndef _MSC_VER -#include <iostream.h> +#include <iostream> #endif +SWORD_NAMESPACE_START + SWDisplay SWModule::rawdisp; -void SWModule::nullPercent(char percent, void *percentUserData) {} /****************************************************************************** * SWModule Constructor - Initializes data for instance of SWModule @@ -28,13 +28,10 @@ void SWModule::nullPercent(char percent, void *percentUserData) {} * 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, char *imodtype, SWTextEncoding encoding, SWTextDirection direction, SWTextMarkup markup, const char* imodlang) { key = CreateKey(); - entrybuf = new char [1]; - *entrybuf = 0; + entryBuf = ""; config = &ownConfig; - entrybufallocsize = 0; modname = 0; error = 0; moddesc = 0; @@ -65,8 +62,6 @@ SWModule::SWModule(const char *imodname, const char *imoddesc, SWDisplay *idisp, SWModule::~SWModule() { - if (entrybuf) - delete [] entrybuf; if (modname) delete [] modname; if (moddesc) @@ -132,11 +127,14 @@ char SWModule::Error() * RET: pointer to modname */ -char *SWModule::Name(const char *imodname) -{ +char *SWModule::Name(const char *imodname) { return stdstr(&modname, imodname); } +char *SWModule::Name() const { + return modname; +} + /****************************************************************************** * SWModule::Description - Sets/gets module description @@ -147,11 +145,14 @@ char *SWModule::Name(const char *imodname) * RET: pointer to moddesc */ -char *SWModule::Description(const char *imoddesc) -{ +char *SWModule::Description(const char *imoddesc) { return stdstr(&moddesc, imoddesc); } +char *SWModule::Description() const { + return moddesc; +} + /****************************************************************************** * SWModule::Type - Sets/gets module type @@ -162,11 +163,14 @@ char *SWModule::Description(const char *imoddesc) * RET: pointer to modtype */ -char *SWModule::Type(const char *imodtype) -{ +char *SWModule::Type(const char *imodtype) { return stdstr(&modtype, imodtype); } +char *SWModule::Type() const { + return modtype; +} + /****************************************************************************** * SWModule::Direction - Sets/gets module direction * @@ -257,20 +261,27 @@ char SWModule::Display() /****************************************************************************** - * SWModule::SetKey - Sets a key to this module for position to a particular - * record or set of records + * SWModule::getKey - Gets the key from this module that points to the position + * record + * + * RET: key object + */ + +SWKey *SWModule::getKey() const { + return key; +} + + +/****************************************************************************** + * SWModule::setKey - Sets a key to this module for position to a particular + * record * * ENT: ikey - key with which to set this module * * RET: error status */ -char SWModule::SetKey(const SWKey &ikey) { - return SetKey(&ikey); -} - -char SWModule::SetKey(const SWKey *ikey) -{ +char SWModule::setKey(const SWKey *ikey) { SWKey *oldKey = 0; if (key) { @@ -292,33 +303,14 @@ char SWModule::SetKey(const SWKey *ikey) /****************************************************************************** - * SWModule::KeyText - Sets/gets module KeyText - * - * ENT: ikeytext - value which to set keytext - * [0] - only get - * - * RET: pointer to keytext - */ - -const char *SWModule::KeyText(const char *ikeytext) -{ - if (ikeytext) - SetKey(ikeytext); - - return *key; -} - - -/****************************************************************************** - * SWModule::operator =(SW_POSITION) - Positions this modules to an entry + * SWModule::setPosition(SW_POSITION) - Positions this modules to an entry * * ENT: p - position (e.g. TOP, BOTTOM) * * RET: *this */ -SWModule &SWModule::operator =(SW_POSITION p) -{ +void SWModule::setPosition(SW_POSITION p) { *key = p; char saveError = key->Error(); @@ -335,41 +327,34 @@ SWModule &SWModule::operator =(SW_POSITION p) } error = saveError; - return *this; } /****************************************************************************** - * SWModule::operator += - Increments module key a number of entries + * SWModule::increment - Increments module key a number of entries * * ENT: increment - Number of entries to jump forward * * RET: *this */ -SWModule &SWModule::operator +=(int increment) -{ - (*key) += increment; +void SWModule::increment(int steps) { + (*key) += steps; error = key->Error(); - - return *this; } /****************************************************************************** - * SWModule::operator -= - Decrements module key a number of entries + * SWModule::decrement - Decrements module key a number of entries * * ENT: decrement - Number of entries to jump backward * * RET: *this */ -SWModule &SWModule::operator -=(int increment) -{ - (*key) -= increment; +void SWModule::decrement(int steps) { + (*key) -= steps; error = key->Error(); - - return *this; } @@ -381,6 +366,7 @@ SWModule &SWModule::operator -=(int increment) * >=0 - regex * -1 - phrase * -2 - multiword + * -3 - entryAttrib * flags - options flags for search * justCheckIfSupported - if set, don't search, only tell if this * function supports requested search. @@ -388,8 +374,7 @@ SWModule &SWModule::operator -=(int increment) * RET: listkey set to verses that contain istr */ -ListKey &SWModule::Search(const char *istr, int searchType, int flags, SWKey *scope, bool *justCheckIfSupported, void (*percent)(char, void *), void *percentUserData) -{ +ListKey &SWModule::search(const char *istr, int searchType, int flags, SWKey *scope, bool *justCheckIfSupported, void (*percent)(char, void *), void *percentUserData) { SWKey *savekey = 0; SWKey *searchkey = 0; regex_t preg; @@ -402,7 +387,8 @@ ListKey &SWModule::Search(const char *istr, int searchType, int flags, SWKey *sc char perc = 1; bool savePEA = isProcessEntryAttributes(); - processEntryAttributes(false); + processEntryAttributes(searchType == -3); + listkey.ClearList(); if (!key->Persist()) { @@ -414,7 +400,7 @@ ListKey &SWModule::Search(const char *istr, int searchType, int flags, SWKey *sc searchkey = (scope)?scope->clone():(key->Persist())?key->clone():0; if (searchkey) { searchkey->Persist(1); - SetKey(*searchkey); + setKey(*searchkey); } (*percent)(perc, percentUserData); @@ -460,6 +446,32 @@ ListKey &SWModule::Search(const char *istr, int searchType, int flags, SWKey *sc } } + if (searchType == -3) { + wordBuf = (char *)calloc(sizeof(char), strlen(istr) + 1); + char *checkSlash = wordBuf; + strcpy(wordBuf, istr); + words = (char **)calloc(sizeof(char *), 10); + int allocWords = 10; + while (*checkSlash == '/') + words[wordCount++] = checkSlash++; + words[wordCount] = strtok(wordBuf, "/"); + while (words[wordCount]) { + wordCount++; + if (wordCount == allocWords) { + allocWords+=10; + words = (char **)realloc(words, sizeof(char *)*allocWords); + } + checkSlash = words[wordCount-1] + (strlen(words[wordCount-1]))+1; + while (*checkSlash == '/') + words[wordCount++] = checkSlash++; + words[wordCount] = strtok(NULL, "/"); + } + for (int i = 0; i < wordCount; i++) { + if (words[i][0] == '/') + words[i][0] = 0; + } + } + perc = 5; (*percent)(perc, percentUserData); @@ -481,12 +493,12 @@ ListKey &SWModule::Search(const char *istr, int searchType, int flags, SWKey *sc } else if (newperc < perc) { #ifndef _MSC_VER - cerr << "Serious error: new percentage complete is less than previous value\n"; - cerr << "using vk? " << ((vkcheck)?"yes":"no") << "\n"; - cerr << "index: " << ((vkcheck)?vkcheck->NewIndex():key->Index()) << "\n"; - cerr << "highIndex: " << highIndex << "\n"; - cerr << "newperc ==" << (int)newperc << "%" << "is smaller than\n"; - cerr << "perc == " << (int )perc << "% \n"; + 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 << "highIndex: " << highIndex << "\n"; + std::cerr << "newperc ==" << (int)newperc << "%" << "is smaller than\n"; + std::cerr << "perc == " << (int )perc << "% \n"; #endif } if (searchType >= 0) { @@ -495,27 +507,79 @@ ListKey &SWModule::Search(const char *istr, int searchType, int flags, SWKey *sc listkey << textkey; } } - else { - if (searchType == -1) { - sres = ((flags & REG_ICASE) == REG_ICASE) ? stristr(StripText(), istr) : strstr(StripText(), istr); - if (sres) { - textkey = KeyText(); - listkey << textkey; - } - } - if (searchType == -2) { - int i; - const char *stripBuf = StripText(); - for (i = 0; i < wordCount; i++) { - sres = ((flags & REG_ICASE) == REG_ICASE) ? stristr(stripBuf, words[i]) : strstr(stripBuf, words[i]); - if (!sres) - break; - } - if (i == wordCount) { + else if (searchType == -1) { + sres = ((flags & REG_ICASE) == REG_ICASE) ? stristr(StripText(), istr) : strstr(StripText(), istr); + if (sres) { textkey = KeyText(); listkey << textkey; + } + } + else if (searchType == -2) { + int i; + const char *stripBuf = StripText(); + for (i = 0; i < wordCount; i++) { + sres = ((flags & REG_ICASE) == REG_ICASE) ? stristr(stripBuf, words[i]) : strstr(stripBuf, words[i]); + if (!sres) + break; + } + if (i == wordCount) { + textkey = KeyText(); + listkey << textkey; + } + } + else if (searchType == -3) { + int i; + RenderText(); // force parse + AttributeTypeList &entryAttribs = getEntryAttributes(); + AttributeTypeList::iterator i1Start, i1End; + AttributeList::iterator i2Start, i2End; + AttributeValue::iterator i3Start, i3End; + + if ((words[0]) && (words[0][0])) { + i1Start = entryAttribs.find(words[0]); + i1End = i1Start; + if (i1End != entryAttribs.end()) + i1End++; + } + else { + i1Start = entryAttribs.begin(); + i1End = entryAttribs.end(); + } + for (;i1Start != i1End; i1Start++) { + if ((words[1]) && (words[1][0])) { + i2Start = i1Start->second.find(words[1]); + i2End = i2Start; + if (i2End != i1Start->second.end()) + i2End++; } - + else { + i2Start = i1Start->second.begin(); + i2End = i1Start->second.end(); + } + for (;i2Start != i2End; i2Start++) { + if ((words[2]) && (words[2][0])) { + i3Start = i2Start->second.find(words[2]); + i3End = i3Start; + if (i3End != i2Start->second.end()) + i3End++; + } + else { + i3Start = i2Start->second.begin(); + i3End = i2Start->second.end(); + } + for (;i3Start != i3End; i3Start++) { + sres = ((flags & REG_ICASE) == REG_ICASE) ? stristr(i3Start->second.c_str(), words[3]) : strstr(i3Start->second.c_str(), words[3]); + if (sres) { + textkey = KeyText(); + listkey << textkey; + break; + } + } + if (i3Start != i3End) + break; + } + if (i2Start != i2End) + break; } } (*this)++; @@ -528,7 +592,7 @@ ListKey &SWModule::Search(const char *istr, int searchType, int flags, SWKey *sc free(wordBuf); } - SetKey(*savekey); + setKey(*savekey); if (!savekey->Persist()) delete savekey; @@ -553,7 +617,7 @@ ListKey &SWModule::Search(const char *istr, int searchType, int flags, SWKey *sc * RET: this module's text at specified key location massaged by Strip filters */ -const char *SWModule::StripText(char *buf, int len) +const char *SWModule::StripText(const char *buf, int len) { return RenderText(buf, len, false); } @@ -567,26 +631,29 @@ const char *SWModule::StripText(char *buf, int len) * RET: listkey set to verses that contain istr */ - const char *SWModule::RenderText(char *buf, int len, bool render) { + const char *SWModule::RenderText(const char *buf, int len, bool render) { entryAttributes.clear(); - char *tmpbuf = (buf) ? buf : getRawEntry(); + + static SWBuf local; + if (buf) + local = buf; + + SWBuf &tmpbuf = (buf) ? local : getRawEntryBuf(); SWKey *key = 0; static char *null = ""; if (tmpbuf) { - unsigned long size = (len < 0) ? getEntrySize() * FILTERPAD : len; - if (size < 0) - size = strlen(tmpbuf); + unsigned long size = (len < 0) ? ((getEntrySize()<0) ? strlen(tmpbuf) : getEntrySize()) : len; if (size > 0) { key = (SWKey *)*this; - optionFilter(tmpbuf, size, key); + optionFilter(tmpbuf, key); if (render) { - renderFilter(tmpbuf, size, key); - encodingFilter(tmpbuf, size, key); + renderFilter(tmpbuf, key); + encodingFilter(tmpbuf, key); } - else stripFilter(tmpbuf, size, key); + else stripFilter(tmpbuf, key); } } else { @@ -616,11 +683,11 @@ const char *SWModule::StripText(char *buf, int len) } else savekey = key; - SetKey(*tmpKey); + setKey(*tmpKey); retVal = RenderText(); - SetKey(*savekey); + setKey(*savekey); if (!savekey->Persist()) delete savekey; @@ -648,11 +715,11 @@ const char *SWModule::StripText(SWKey *tmpKey) } else savekey = key; - SetKey(*tmpKey); + setKey(*tmpKey); retVal = StripText(); - SetKey(*savekey); + setKey(*savekey); if (!savekey->Persist()) delete savekey; @@ -661,11 +728,6 @@ const char *SWModule::StripText(SWKey *tmpKey) } -SWModule::operator const char*() { - return RenderText(); -} - - const char *SWModule::getConfigEntry(const char *key) const { ConfigEntMap::iterator it = config->find(key); return (it != config->end()) ? it->second.c_str() : 0; @@ -675,3 +737,5 @@ const char *SWModule::getConfigEntry(const char *key) const { void SWModule::setConfig(ConfigEntMap *config) { this->config = config; } + +SWORD_NAMESPACE_END diff --git a/src/modules/texts/Makefile.am b/src/modules/texts/Makefile.am index b48d93e..2c4479e 100644 --- a/src/modules/texts/Makefile.am +++ b/src/modules/texts/Makefile.am @@ -4,4 +4,3 @@ libsword_la_SOURCES += $(textsdir)/swtext.cpp include ../src/modules/texts/rawtext/Makefile.am include ../src/modules/texts/ztext/Makefile.am -include ../src/modules/texts/rawgbf/Makefile.am diff --git a/src/modules/texts/rawgbf/rawgbf.cpp b/src/modules/texts/rawgbf/rawgbf.cpp index 0866585..6b8516f 100644 --- a/src/modules/texts/rawgbf/rawgbf.cpp +++ b/src/modules/texts/rawgbf/rawgbf.cpp @@ -19,6 +19,7 @@ #include <rawverse.h> #include <rawgbf.h> +SWORD_NAMESPACE_START /****************************************************************************** * RawGBF Constructor - Initializes data for instance of RawGBF @@ -73,7 +74,7 @@ RawGBF::operator char*() delete [] entrybuf; entrybuf = new char [ size * 3 ]; // extra for conversion to RTF or other. - gettext(key->Testament(), start, size + 1, entrybuf); + readtext(key->Testament(), start, size + 1, entrybuf); preptext(entrybuf); RenderText(entrybuf, size * 3); @@ -82,3 +83,5 @@ RawGBF::operator char*() return entrybuf; } + +SWORD_NAMESPACE_END diff --git a/src/modules/texts/rawtext/rawtext.cpp b/src/modules/texts/rawtext/rawtext.cpp index acc1cfd..1e1048d 100644 --- a/src/modules/texts/rawtext/rawtext.cpp +++ b/src/modules/texts/rawtext/rawtext.cpp @@ -13,20 +13,35 @@ #include <unistd.h> #endif -#include <string.h> #include <utilfuns.h> #include <rawverse.h> #include <rawtext.h> +#include <regex.h> // GNU +#ifdef USELUCENE +#include <CLucene/CLucene.h> +using namespace lucene::search; +using namespace lucene::queryParser; +#else #include <map> #include <list> #include <algorithm> -#include <regex.h> // GNU + +using std::map; +using std::list; +using std::find; + +#endif #ifndef O_BINARY #define O_BINARY 0 #endif +SWORD_NAMESPACE_START + +typedef map < SWBuf, list<long> > strlist; +typedef list<long> longlist; + /****************************************************************************** * RawText Constructor - Initializes data for instance of RawText * @@ -39,7 +54,20 @@ RawText::RawText(const char *ipath, const char *iname, const char *idesc, SWDisp : SWText(iname, idesc, idisp, enc, dir, mark, ilang), RawVerse(ipath) { - string fname; +#ifdef USELUCENE + SWBuf fname; + fname = path; + ir = 0; + is = 0; + char ch = fname.c_str()[strlen(fname.c_str())-1]; + if ((ch != '/') && (ch != '\\')) + fname += "/lucene"; + if (IndexReader::indexExists(fname.c_str())) { + ir = &IndexReader::open(fname); + is = new IndexSearcher(*ir); + } +#else + SWBuf fname; fname = path; char ch = fname.c_str()[strlen(fname.c_str())-1]; if ((ch != '/') && (ch != '\\')) @@ -47,13 +75,14 @@ RawText::RawText(const char *ipath, const char *iname, const char *idesc, SWDisp for (int loop = 0; loop < 2; loop++) { fastSearch[loop] = 0; - string fastidxname =(fname + ((loop)?"ntwords.dat":"otwords.dat")); + SWBuf fastidxname =(fname + ((loop)?"ntwords.dat":"otwords.dat")); if (!access(fastidxname.c_str(), 04)) { fastidxname = (fname + ((loop)?"ntwords.idx":"otwords.idx")); if (!access(fastidxname.c_str(), 04)) fastSearch[loop] = new RawStr((fname + ((loop)?"ntwords":"otwords")).c_str()); } } +#endif } @@ -61,68 +90,159 @@ RawText::RawText(const char *ipath, const char *iname, const char *idesc, SWDisp * RawText Destructor - Cleans up instance of RawText */ -RawText::~RawText() -{ +RawText::~RawText() { +#ifdef USELUCENE + if (is) + is->close(); + + if (ir) + delete ir; +#else if (fastSearch[0]) delete fastSearch[0]; if (fastSearch[1]) delete fastSearch[1]; +#endif +} + + +VerseKey &RawText::getVerseKey() { + static VerseKey tmpVK; + VerseKey *key; + // see if we have a VerseKey * or decendant + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) { } + if (!key) { + ListKey *lkTest = 0; + try { + lkTest = SWDYNAMIC_CAST(ListKey, this->key); + } + catch ( ... ) { } + if (lkTest) { + try { + key = SWDYNAMIC_CAST(VerseKey, lkTest->GetElement()); + } + catch ( ... ) { } + } + } + if (!key) { + tmpVK = *(this->key); + return tmpVK; + } + else return *key; } /****************************************************************************** - * RawText::operator char * - Returns the correct verse when char * cast + * RawText::getRawEntry - Returns the correct verse when char * cast * is requested * * RET: string buffer with verse */ -char *RawText::getRawEntry() { +SWBuf &RawText::getRawEntryBuf() { long start = 0; unsigned short size = 0; - VerseKey *key = 0; + VerseKey &key = getVerseKey(); - // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE + findOffset(key.Testament(), key.Index(), &start, &size); + entrySize = size; // support getEntrySize call + + entryBuf = ""; + readText(key.Testament(), start, size, entryBuf); + + rawFilter(entryBuf, 0); // hack, decipher + rawFilter(entryBuf, &key); + +// if (!isUnicode()) + prepText(entryBuf); + + return entryBuf; +} + + +signed char RawText::createSearchFramework() { +#ifdef USELUCENE + SWKey *savekey = 0; + SWKey *searchkey = 0; + SWKey textkey; + char *word = 0; + char *wordBuf = 0; + + + // save key information so as not to disrupt original + // module position + if (!key->Persist()) { + savekey = CreateKey(); + *savekey = *key; } - catch ( ... ) { } -#endif - // if we don't have a VerseKey * decendant, create our own - if (!key) - key = new VerseKey(this->key); + else savekey = key; - findoffset(key->Testament(), key->Index(), &start, &size); - entrySize = size; // support getEntrySize call + 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 + + IndexWriter* writer = NULL; + Directory* d = NULL; + + lucene::analysis::SimpleAnalyzer& an = *new lucene::analysis::SimpleAnalyzer(); + SWBuf target = path; + char ch = target.c_str()[strlen(target.c_str())-1]; + if ((ch != '/') && (ch != '\\')) + target += "/lucene"; - unsigned long newsize = (size + 2) * FILTERPAD; - if (newsize > entrybufallocsize) { - if (entrybuf) - delete [] entrybuf; - entrybuf = new char [ newsize ]; - entrybufallocsize = newsize; + if (IndexReader::indexExists(target.c_str())) { + d = &FSDirectory::getDirectory(target.c_str(), false); + if (IndexReader::isLocked(*d)) { + IndexReader::unlock(*d); + } + + writer = new IndexWriter(*d, an, false); + } else { + d = &FSDirectory::getDirectory(target.c_str(), true); + writer = new IndexWriter( *d ,an, true); } - *entrybuf = 0; - gettext(key->Testament(), start, (size + 2), entrybuf); - rawFilter(entrybuf, size, key); + + while (!Error()) { + Document &doc = *new Document(); + doc.add( Field::Text(_T("key"), (const char *)*lkey ) ); + doc.add( Field::Text(_T("content"), StripText()) ); + writer->addDocument(doc); + delete &doc; - if (!isUnicode()) - preptext(entrybuf); + (*this)++; + } - if (this->key != key) // free our key if we created a VerseKey - delete key; + writer->optimize(); + writer->close(); + delete writer; + delete &an; - return entrybuf; -} + // reposition module back to where it was before we were called + setKey(*savekey); + if (!savekey->Persist()) + delete savekey; -signed char RawText::createSearchFramework() { + if (searchkey) + delete searchkey; + + +#else SWKey *savekey = 0; SWKey *searchkey = 0; SWKey textkey; @@ -132,7 +252,7 @@ signed char RawText::createSearchFramework() { // dictionary holds words associated with a list // containing every module position that contains // the word. [0] Old Testament; [1] NT - map < string, list<long> > dictionary[2]; + map < SWBuf, list<long> > dictionary[2]; // save key information so as not to disrupt original @@ -146,7 +266,7 @@ signed char RawText::createSearchFramework() { searchkey = (key->Persist())?key->clone():0; if (searchkey) { searchkey->Persist(1); - SetKey(*searchkey); + setKey(*searchkey); } // position module at the beginning @@ -164,9 +284,8 @@ signed char RawText::createSearchFramework() { word = strtok(wordBuf, " !.,?;:()-=+/\\|{}[]\"<>"); while (word) { - // make work upper case - for (unsigned int i = 0; i < strlen(word); i++) - word[i] = SW_toupper(word[i]); + // 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 @@ -179,7 +298,7 @@ signed char RawText::createSearchFramework() { } // reposition module back to where it was before we were called - SetKey(*savekey); + setKey(*savekey); if (!savekey->Persist()) delete savekey; @@ -191,12 +310,12 @@ signed char RawText::createSearchFramework() { // --------- Let's output an index from our dictionary ----------- int datfd; int idxfd; - map < string, list<long> >::iterator it; - list<long>::iterator it2; + strlist::iterator it; + longlist::iterator it2; unsigned long offset, entryoff; unsigned short size; - string fname; + SWBuf fname; fname = path; char ch = fname.c_str()[strlen(fname.c_str())-1]; if ((ch != '/') && (ch != '\\')) @@ -249,12 +368,13 @@ signed char RawText::createSearchFramework() { close(datfd); close(idxfd); } +#endif return 0; } /****************************************************************************** - * SWModule::Search - Searches a module for a string + * SWModule::search - Searches a module for a string * * ENT: istr - string for which to search * searchType - type of search to perform @@ -268,8 +388,89 @@ signed char RawText::createSearchFramework() { * 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) -{ +ListKey &RawText::search(const char *istr, int searchType, int flags, SWKey *scope, bool *justCheckIfSupported, void (*percent)(char, void *), void *percentUserData) { +#ifdef USELUCENE + listkey.ClearList(); + + if ((is) && (ir)) { + + switch (searchType) { + case -2: { // let lucene replace multiword for now + + + // test to see if our scope for this search is bounded by a + // VerseKey + VerseKey *testKeyType = 0, vk; + try { + testKeyType = SWDYNAMIC_CAST(VerseKey, ((scope)?scope:key)); + } + catch ( ... ) {} + // 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; + } + + (*percent)(10, percentUserData); + + standard::StandardAnalyzer analyzer; + Query &q = QueryParser::Parse(istr, _T("content"), analyzer); + (*percent)(20, percentUserData); + Hits &h = is->search(q); + (*percent)(80, percentUserData); + + + // iterate thru each good module position that meets the search + for (long i = 0; i < h.Length(); i++) { + Document &doc = h.doc(i); + + // set a temporary verse key to this module position + vk = doc.get(_T("key")); + + // 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; + listkey.GetElement()->userData = (void *)(int)(h.score(i)*100); + } + else { + listkey << (const char*) vk; + listkey.GetElement()->userData = (void *)(int)(h.score(i)*100); + } + } + (*percent)(98, percentUserData); + + delete &h; + delete &q; + + 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; + } +#else listkey.ClearList(); if ((fastSearch[0]) && (fastSearch[1])) { @@ -284,14 +485,10 @@ ListKey &RawText::Search(const char *istr, int searchType, int flags, SWKey *sco // test to see if our scope for this search is bounded by a // VerseKey VerseKey *testKeyType = 0; -#ifndef _WIN32_WCE try { -#endif testKeyType = SWDYNAMIC_CAST(VerseKey, ((scope)?scope:key)); -#ifndef _WIN32_WCE } catch ( ... ) {} -#endif // 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); @@ -315,7 +512,7 @@ ListKey &RawText::Search(const char *istr, int searchType, int flags, SWKey *sco long start; unsigned short size; char *idxbuf = 0; - char *datbuf = 0; + SWBuf datBuf; list <long> indexes; list <long> indexes2; VerseKey vk; @@ -325,8 +522,7 @@ ListKey &RawText::Search(const char *istr, int searchType, int flags, SWKey *sco // toupper our copy of search string stdstr(&wordBuf, istr); - for (unsigned int i = 0; i < strlen(wordBuf); i++) - wordBuf[i] = SW_toupper(wordBuf[i]); + toupperstr(wordBuf); // get list of individual words words = (char **)calloc(sizeof(char *), 10); @@ -361,10 +557,10 @@ ListKey &RawText::Search(const char *istr, int searchType, int flags, SWKey *sco idxbuf = 0; // find our word in the database and jump ahead _away_ - error = fastSearch[j]->findoffset(words[i], &start, &size, away); + error = fastSearch[j]->findOffset(words[i], &start, &size, away); // get the word from the database - fastSearch[j]->getidxbufdat(start, &idxbuf); + fastSearch[j]->getIDXBufDat(start, &idxbuf); // check to see if it starts with our target word if (strlen(idxbuf) > strlen(words[i])) @@ -373,18 +569,18 @@ ListKey &RawText::Search(const char *istr, int searchType, int flags, SWKey *sco if (!strcmp(idxbuf, words[i])) { // get data for this word from database - free(idxbuf); - idxbuf = (char *)calloc(size+2, 1); - datbuf = (char *)calloc(size+2, 1); - fastSearch[j]->gettext(start, size + 2, idxbuf, datbuf); + 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; - while (keyindex < (long *)(datbuf + size - (strlen(idxbuf) + 1))) { + 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. @@ -396,7 +592,6 @@ ListKey &RawText::Search(const char *istr, int searchType, int flags, SWKey *sco else indexes2.push_back(*keyindex); keyindex++; } - free(datbuf); } else error = 1; // no more matches free(idxbuf); @@ -412,7 +607,7 @@ ListKey &RawText::Search(const char *istr, int searchType, int flags, SWKey *sco indexes.sort(); // iterate thru each good module position that meets the search - for (list <long>::iterator it = indexes.begin(); it != indexes.end(); it++) { + for (longlist::iterator it = indexes.begin(); it != indexes.end(); it++) { // set a temporary verse key to this module position vk.Testament(j+1); @@ -454,85 +649,35 @@ ListKey &RawText::Search(const char *istr, int searchType, int flags, SWKey *sco return listkey; } - // if we don't support this search, fall back to base class - return SWModule::Search(istr, searchType, flags, scope, justCheckIfSupported, percent, percentUserData); -} - -#ifdef _MSC_VER -SWModule &RawText::operator =(SW_POSITION p) { -#else -RawText &RawText::operator =(SW_POSITION p) { #endif - SWModule::operator =(p); - return *this; + // if we don't support this search, fall back to base class + return SWModule::search(istr, searchType, flags, scope, justCheckIfSupported, percent, percentUserData); } -SWModule &RawText::setentry(const char *inbuf, long len) { - VerseKey *key = 0; - // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - // if we don't have a VerseKey * decendant, create our own - if (!key) - key = new VerseKey(this->key); - - settext(key->Testament(), key->Index(), inbuf, len); - - if (this->key != key) // free our key if we created a VerseKey - delete key; - return *this; -} - -SWModule &RawText::operator <<(const char *inbuf) { - return setentry(inbuf, 0); +void RawText::setEntry(const char *inbuf, long len) { + VerseKey &key = getVerseKey(); + doSetText(key.Testament(), key.Index(), inbuf, len); } -SWModule &RawText::operator <<(const SWKey *inkey) { - VerseKey *destkey = 0; +void RawText::linkEntry(const SWKey *inkey) { + VerseKey &destkey = getVerseKey(); const VerseKey *srckey = 0; - // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE - try { -#endif - destkey = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - // if we don't have a VerseKey * decendant, create our own - if (!destkey) - destkey = new VerseKey(this->key); // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE try { -#endif srckey = SWDYNAMIC_CAST(VerseKey, inkey); -#ifndef _WIN32_WCE } catch ( ... ) {} -#endif // if we don't have a VerseKey * decendant, create our own if (!srckey) srckey = new VerseKey(inkey); - linkentry(destkey->Testament(), destkey->Index(), srckey->Index()); - - if (this->key != destkey) // free our key if we created a VerseKey - delete destkey; + doLinkEntry(destkey.Testament(), destkey.Index(), srckey->Index()); if (inkey != srckey) // free our key if we created a VerseKey delete srckey; - - return *this; } @@ -543,88 +688,49 @@ SWModule &RawText::operator <<(const SWKey *inkey) { */ void RawText::deleteEntry() { - - VerseKey *key = 0; - -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!key) - key = new VerseKey(this->key); - - settext(key->Testament(), key->Index(), ""); - - if (key != this->key) - delete key; + VerseKey &key = getVerseKey(); + doSetText(key.Testament(), key.Index(), ""); } /****************************************************************************** - * RawText::operator += - Increments module key a number of entries + * RawText::increment - Increments module key a number of entries * * ENT: increment - Number of entries to jump forward * * RET: *this */ -SWModule &RawText::operator +=(int increment) -{ +void RawText::increment(int steps) { long start; unsigned short size; - VerseKey *tmpkey = 0; - -#ifndef _WIN32_WCE - try { -#endif - tmpkey = SWDYNAMIC_CAST(VerseKey, key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!tmpkey) - tmpkey = new VerseKey(key); + VerseKey *tmpkey = &getVerseKey(); - findoffset(tmpkey->Testament(), tmpkey->Index(), &start, &size); + findOffset(tmpkey->Testament(), tmpkey->Index(), &start, &size); SWKey lastgood = *tmpkey; - while (increment) { + while (steps) { long laststart = start; unsigned short lastsize = size; SWKey lasttry = *tmpkey; - (increment > 0) ? (*key)++ : (*key)--; - if (tmpkey != key) - delete tmpkey; - tmpkey = 0; -#ifndef _WIN32_WCE - try { -#endif - tmpkey = SWDYNAMIC_CAST(VerseKey, key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!tmpkey) - tmpkey = new VerseKey(key); + (steps > 0) ? (*key)++ : (*key)--; + tmpkey = &getVerseKey(); if ((error = key->Error())) { *key = lastgood; break; } long index = tmpkey->Index(); - findoffset(tmpkey->Testament(), index, &start, &size); - if ((((laststart != start) || (lastsize != size))||(!skipConsecutiveLinks)) && (start >= 0) && (size)) { - increment += (increment < 0) ? 1 : -1; + findOffset(tmpkey->Testament(), index, &start, &size); + if ( + (((laststart != start) || (lastsize != size)) // we're a different entry +// && (start > 0) + && (size)) // and we actually have a size + ||(!skipConsecutiveLinks)) { // or we don't want to skip consecutive links + steps += (steps < 0) ? 1 : -1; lastgood = *tmpkey; } } error = (error) ? KEYERR_OUTOFBOUNDS : 0; - - if (tmpkey != key) - delete tmpkey; - - return *this; } + +SWORD_NAMESPACE_END diff --git a/src/modules/texts/swtext.cpp b/src/modules/texts/swtext.cpp index 85da8a3..8610dae 100644 --- a/src/modules/texts/swtext.cpp +++ b/src/modules/texts/swtext.cpp @@ -5,6 +5,7 @@ #include <swtext.h> #include <listkey.h> +SWORD_NAMESPACE_START /****************************************************************************** * SWText Constructor - Initializes data for instance of SWText @@ -18,6 +19,7 @@ SWText::SWText(const char *imodname, const char *imoddesc, SWDisplay *idisp, SWT { delete key; key = CreateKey(); + skipConsecutiveLinks = false; } @@ -37,3 +39,43 @@ SWKey *SWText::CreateKey() { return new VerseKey(); } + + +long SWText::Index() const { + VerseKey *key = 0; + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) {} + if (!key) + key = new VerseKey(this->key); + + entryIndex = key->NewIndex(); + + if (key != this->key) + delete key; + + return entryIndex; +} + +long SWText::Index(long iindex) { + VerseKey *key = 0; + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) {} + if (!key) + key = new VerseKey(this->key); + + key->Testament(1); + key->Index(iindex); + + if (key != this->key) { + this->key->copyFrom(*key); + delete key; + } + + return Index(); +} + +SWORD_NAMESPACE_END diff --git a/src/modules/texts/ztext/ztext.cpp b/src/modules/texts/ztext/ztext.cpp index 6e243b9..1fe0e7a 100644 --- a/src/modules/texts/ztext/ztext.cpp +++ b/src/modules/texts/ztext/ztext.cpp @@ -14,13 +14,19 @@ #include <unistd.h> #endif -#include <iostream.h> -#include <string.h> #include <utilfuns.h> -//#include <rawverse.h> #include <ztext.h> -//#include <zlib.h> +#include <regex.h> // GNU + + +#ifdef USELUCENE +#include <CLucene/CLucene.h> +using namespace lucene::search; +using namespace lucene::queryParser; +#endif + +SWORD_NAMESPACE_START /****************************************************************************** * zText Constructor - Initializes data for instance of zText @@ -33,10 +39,23 @@ * 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, -1, iblockType, icomp), SWText(iname, idesc, idisp, enc, dir, mark, ilang)/*, SWCompress()*/ -{ +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, -1, iblockType, icomp), SWText(iname, idesc, idisp, enc, dir, mark, ilang) { blockType = iblockType; lastWriteKey = 0; +#ifdef USELUCENE + SWBuf fname; + fname = path; + ir = 0; + is = 0; + char ch = fname.c_str()[strlen(fname.c_str())-1]; + if ((ch != '/') && (ch != '\\')) + fname += "/lucene"; + if (IndexReader::indexExists(fname.c_str())) { + ir = &IndexReader::open(fname); + is = new IndexSearcher(*ir); + } +#endif } @@ -50,6 +69,14 @@ zText::~zText() if (lastWriteKey) delete lastWriteKey; + +#ifdef USELUCENE + if (is) + is->close(); + + if (ir) + delete ir; +#endif } @@ -59,96 +86,23 @@ zText::~zText() * RET: buffer with verse */ -char *zText::getRawEntry() -{ -/* - long start; - unsigned long size; - unsigned long destsize; - char *tmpbuf; - char *dest; - VerseKey *lkey = (VerseKey *) SWModule::key; - char sizebuf[3]; - - lkey->Verse(0); - if (chapcache != lkey->Index()) { - findoffset(lkey->Testament(), lkey->Index(), &start, &((unsigned short) size)); - gettext(lkey->Testament(), start, 3, sizebuf); - memcpy(&size, sizebuf, 2); - tmpbuf = new char [ size + 1 ]; - gettext(lkey->Testament(), start + 2, size + 1 , tmpbuf); - //zBuf(&size, tmpbuf); - dest = new char [ (size*4) + 1 ]; - uncompress((Bytef *)dest, &destsize, (Bytef *) tmpbuf, size); - chapcache = lkey->Index(); - delete [] tmpbuf; - } - - //findoffset(key->Testament(), key->Index(), &start, &size); - findoffset(lkey->Testament(), lkey->Index(), &start, &((unsigned short) size)); - - if (versebuf) - delete [] versebuf; - versebuf = new char [ size + 1 ]; - //memcpy(versebuf, Buf(), size); - memcpy(versebuf, dest, destsize); - delete [] dest; - - preptext(versebuf); - - return versebuf; -*/ - +SWBuf &zText::getRawEntryBuf() { long start = 0; unsigned short size = 0; - VerseKey *key = 0; - - //printf ("zText char *\n"); - - // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - // if we don't have a VerseKey * decendant, create our own - if (!key) - key = new VerseKey(this->key); + VerseKey &key = getVerseKey(); - //printf ("checking cache\n"); - //printf ("finding offset\n"); - findoffset(key->Testament(), key->Index(), &start, &size); + findOffset(key.Testament(), key.Index(), &start, &size); entrySize = size; // support getEntrySize call + + entryBuf = ""; + zReadText(key.Testament(), start, size, entryBuf); - //printf ("deleting previous buffer\n"); - unsigned long newsize = (size + 2) * FILTERPAD; - if (newsize > entrybufallocsize) { - if (entrybuf) - delete [] entrybuf; - entrybuf = new char [ newsize ]; - entrybufallocsize = newsize; - } - *entrybuf = 0; - - //printf ("getting text\n"); - swgettext(key->Testament(), start, (size + 2), entrybuf); - //printf ("got text\n"); - - rawFilter(entrybuf, size, key); - - //printf ("preparing text\n"); - if (!isUnicode()) - preptext(entrybuf); - - if (this->key != key) // free our key if we created a VerseKey - delete key; + rawFilter(entryBuf, &key); - //printf ("returning text\n"); - return entrybuf; +// if (!isUnicode()) + prepText(entryBuf); + return entryBuf; } @@ -171,177 +125,316 @@ bool zText::sameBlock(VerseKey *k1, VerseKey *k2) { } -SWModule &zText::setentry(const char *inbuf, long len) { - VerseKey *key = 0; - // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - // if we don't have a VerseKey * decendant, create our own - if (!key) - key = new VerseKey(this->key); - +void zText::setEntry(const char *inbuf, long len) { + VerseKey &key = getVerseKey(); // see if we've jumped across blocks since last write if (lastWriteKey) { - if (!sameBlock(lastWriteKey, key)) { + if (!sameBlock(lastWriteKey, &key)) { flushCache(); } delete lastWriteKey; } - settext(key->Testament(), key->Index(), inbuf, len); + doSetText(key.Testament(), key.Index(), inbuf, len); - lastWriteKey = (VerseKey *)key->clone(); // must delete - - if (this->key != key) // free our key if we created a VerseKey - delete key; - - return *this; -} - -SWModule &zText::operator <<(const char *inbuf) { - return setentry(inbuf, 0); + lastWriteKey = (VerseKey *)key.clone(); // must delete } -SWModule &zText::operator <<(const SWKey *inkey) { - VerseKey *destkey = 0; +void zText::linkEntry(const SWKey *inkey) { + VerseKey &destkey = getVerseKey(); const VerseKey *srckey = 0; - // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE - try { -#endif - destkey = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - // if we don't have a VerseKey * decendant, create our own - if (!destkey) - destkey = new VerseKey(this->key); // see if we have a VerseKey * or decendant -#ifndef _WIN32_WCE try { -#endif srckey = (const VerseKey *) SWDYNAMIC_CAST(VerseKey, inkey); -#ifndef _WIN32_WCE } catch ( ... ) { } -#endif // if we don't have a VerseKey * decendant, create our own if (!srckey) srckey = new VerseKey(inkey); - linkentry(destkey->Testament(), destkey->Index(), srckey->Index()); - - if (this->key != destkey) // free our key if we created a VerseKey - delete destkey; + doLinkEntry(destkey.Testament(), destkey.Index(), srckey->Index()); if (inkey != srckey) // free our key if we created a VerseKey delete srckey; - - return *this; } /****************************************************************************** * zFiles::deleteEntry - deletes this entry * - * RET: *this */ void zText::deleteEntry() { - VerseKey *key = 0; + VerseKey &key = getVerseKey(); -#ifndef _WIN32_WCE - try { -#endif - key = SWDYNAMIC_CAST(VerseKey, this->key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!key) - key = new VerseKey(this->key); - - settext(key->Testament(), key->Index(), ""); - - if (key != this->key) - delete key; + doSetText(key.Testament(), key.Index(), ""); } /****************************************************************************** - * zText::operator += - Increments module key a number of entries + * zText::increment - Increments module key a number of entries * * ENT: increment - Number of entries to jump forward * - * RET: *this */ -SWModule &zText::operator +=(int increment) -{ +void zText::increment(int steps) { long start; unsigned short size; - VerseKey *tmpkey = 0; - -#ifndef _WIN32_WCE - try { -#endif - tmpkey = SWDYNAMIC_CAST(VerseKey, key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!tmpkey) - tmpkey = new VerseKey(key); + VerseKey *tmpkey = &getVerseKey(); - findoffset(tmpkey->Testament(), tmpkey->Index(), &start, &size); + findOffset(tmpkey->Testament(), tmpkey->Index(), &start, &size); SWKey lastgood = *tmpkey; - while (increment) { + while (steps) { long laststart = start; unsigned short lastsize = size; SWKey lasttry = *tmpkey; - (increment > 0) ? (*key)++ : (*key)--; - if (tmpkey != key) - delete tmpkey; - tmpkey = 0; -#ifndef _WIN32_WCE - try { -#endif - tmpkey = SWDYNAMIC_CAST(VerseKey, key); -#ifndef _WIN32_WCE - } - catch ( ... ) {} -#endif - if (!tmpkey) - tmpkey = new VerseKey(key); + (steps > 0) ? (*key)++ : (*key)--; + tmpkey = &getVerseKey(); if ((error = key->Error())) { *key = lastgood; break; } long index = tmpkey->Index(); - findoffset(tmpkey->Testament(), index, &start, &size); - if ((((laststart != start) || (lastsize != size))||(!skipConsecutiveLinks)) && (start >= 0) && (size)) { - increment += (increment < 0) ? 1 : -1; + findOffset(tmpkey->Testament(), index, &start, &size); + + if ( + (((laststart != start) || (lastsize != size)) // we're a different entry +// && (start > 0) + && (size)) // and we actually have a size + ||(!skipConsecutiveLinks)) { // or we don't want to skip consecutive links + steps += (steps < 0) ? 1 : -1; lastgood = *tmpkey; } } error = (error) ? KEYERR_OUTOFBOUNDS : 0; +} - if (tmpkey != key) - delete tmpkey; - return *this; +VerseKey &zText::getVerseKey() { + static VerseKey tmpVK; + VerseKey *key; + // see if we have a VerseKey * or decendant + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) { } + if (!key) { + ListKey *lkTest = 0; + try { + lkTest = SWDYNAMIC_CAST(ListKey, this->key); + } + catch ( ... ) { } + if (lkTest) { + try { + key = SWDYNAMIC_CAST(VerseKey, lkTest->GetElement()); + } + catch ( ... ) { } + } + } + if (!key) { + tmpVK = *(this->key); + return tmpVK; + } + else return *key; } + + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +signed char zText::createSearchFramework() { +#ifdef USELUCENE + SWKey *savekey = 0; + SWKey *searchkey = 0; + SWKey textkey; + char *word = 0; + char *wordBuf = 0; + + + // 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 + + IndexWriter* writer = NULL; + Directory* d = NULL; + + lucene::analysis::SimpleAnalyzer& an = *new lucene::analysis::SimpleAnalyzer(); + SWBuf target = path; + char ch = target.c_str()[strlen(target.c_str())-1]; + if ((ch != '/') && (ch != '\\')) + target += "/lucene"; + + if (IndexReader::indexExists(target.c_str())) { + d = &FSDirectory::getDirectory(target.c_str(), false); + if (IndexReader::isLocked(*d)) { + IndexReader::unlock(*d); + } + + writer = new IndexWriter(*d, an, false); + } else { + d = &FSDirectory::getDirectory(target.c_str(), true); + writer = new IndexWriter( *d ,an, true); + } + + + + while (!Error()) { + Document &doc = *new Document(); + doc.add( Field::Text(_T("key"), (const char *)*lkey ) ); + doc.add( Field::Text(_T("content"), StripText()) ); + writer->addDocument(doc); + delete &doc; + + (*this)++; + } + + writer->optimize(); + writer->close(); + delete writer; + delete &an; + + // reposition module back to where it was before we were called + setKey(*savekey); + + if (!savekey->Persist()) + delete savekey; + + if (searchkey) + delete searchkey; + + +#endif + return 0; +} + + +/****************************************************************************** + * 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 &zText::search(const char *istr, int searchType, int flags, SWKey *scope, bool *justCheckIfSupported, void (*percent)(char, void *), void *percentUserData) { +#ifdef USELUCENE + listkey.ClearList(); + + if ((is) && (ir)) { + + switch (searchType) { + case -2: { // let lucene replace multiword for now + + + // test to see if our scope for this search is bounded by a + // VerseKey + VerseKey *testKeyType = 0, vk; + try { + testKeyType = SWDYNAMIC_CAST(VerseKey, ((scope)?scope:key)); + } + catch ( ... ) {} + // 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; + } + + (*percent)(10, percentUserData); + + standard::StandardAnalyzer analyzer; + Query &q = QueryParser::Parse(istr, _T("content"), analyzer); + (*percent)(20, percentUserData); + Hits &h = is->search(q); + (*percent)(80, percentUserData); + + + // iterate thru each good module position that meets the search + for (long i = 0; i < h.Length(); i++) { + Document &doc = h.doc(i); + + // set a temporary verse key to this module position + vk = doc.get(_T("key")); + + // 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; + listkey.GetElement()->userData = (void *)(int)(h.score(i)*100); + } + else { + listkey << (const char*) vk; + listkey.GetElement()->userData = (void *)(int)(h.score(i)*100); + } + } + (*percent)(98, percentUserData); + + delete &h; + delete &q; + + 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); +} + + +SWORD_NAMESPACE_END diff --git a/src/utilfuns/Greek2Greek.cpp b/src/utilfuns/Greek2Greek.cpp index 7e81f0f..d39e00b 100644 --- a/src/utilfuns/Greek2Greek.cpp +++ b/src/utilfuns/Greek2Greek.cpp @@ -22,8 +22,8 @@ //***************************************************************************** #include <stdio.h> -#include <string.h> #include <ctype.h> +#include <string.h> #include "Greek2Greek.h" #include "GreekChars.h" @@ -34,6 +34,8 @@ // method of transliteration. //***************************************************************************** +SWORD_NAMESPACE_START + unsigned char Greek2bGreek( unsigned char *sResult, unsigned char *sGreekText, @@ -899,3 +901,5 @@ int main() } #endif // __TEST + +SWORD_NAMESPACE_END diff --git a/src/utilfuns/Makefile.am b/src/utilfuns/Makefile.am index e7b2258..2f8c78c 100644 --- a/src/utilfuns/Makefile.am +++ b/src/utilfuns/Makefile.am @@ -2,9 +2,21 @@ utilfunsdir = $(top_srcdir)/src/utilfuns libsword_la_SOURCES += $(utilfunsdir)/Greek2Greek.cpp libsword_la_SOURCES += $(utilfunsdir)/utilstr.cpp +libsword_la_SOURCES += $(utilfunsdir)/utilweb.cpp +libsword_la_SOURCES += $(utilfunsdir)/utilxml.cpp libsword_la_SOURCES += $(utilfunsdir)/unixstr.cpp libsword_la_SOURCES += $(utilfunsdir)/swunicod.cpp libsword_la_SOURCES += $(utilfunsdir)/swversion.cpp +libsword_la_SOURCES += $(utilfunsdir)/swbuf.cpp +libsword_la_SOURCES += $(utilfunsdir)/ftpparse.c + +if ZLIB +UNTGZ = $(utilfunsdir)/zlib/untgz.c +else +UNTGZ = +endif +libsword_la_SOURCES += $(UNTGZ) + if MINGW SWREGEX = $(utilfunsdir)/regex.c @@ -14,6 +26,6 @@ endif libsword_la_SOURCES += $(SWREGEX) -libsword_la_SOURCES += $(utilfunsdir)/roman.c +libsword_la_SOURCES += $(utilfunsdir)/roman.cpp diff --git a/src/utilfuns/ftpparse.c b/src/utilfuns/ftpparse.c new file mode 100644 index 0000000..58a692e --- /dev/null +++ b/src/utilfuns/ftpparse.c @@ -0,0 +1,446 @@ +/* ftpparse.c, ftpparse.h: library for parsing FTP LIST responses +20001223 +D. J. Bernstein, djb@cr.yp.to +http://cr.yp.to/ftpparse.html + +Commercial use is fine, if you let me know what programs you're using this in. + +Currently covered formats: +EPLF. +UNIX ls, with or without gid. +Microsoft FTP Service. +Windows NT FTP Server. +VMS. +WFTPD. +NetPresenz (Mac). +NetWare. +MSDOS. + +Definitely not covered: +Long VMS filenames, with information split across two lines. +NCSA Telnet FTP server. Has LIST = NLST (and bad NLST for directories). +*/ + +#include <ftpparse.h> + +static long totai(long year,long month,long mday) +{ + long result; + if (month >= 2) month -= 2; + else { month += 10; --year; } + result = (mday - 1) * 10 + 5 + 306 * month; + result /= 10; + if (result == 365) { year -= 3; result = 1460; } + else result += 365 * (year % 4); + year /= 4; + result += 1461 * (year % 25); + year /= 25; + if (result == 36524) { year -= 3; result = 146096; } + else { result += 36524 * (year % 4); } + year /= 4; + result += 146097 * (year - 5); + result += 11017; + return result * 86400; +} + +static int flagneedbase = 1; +static time_t base; /* time() value on this OS at the beginning of 1970 TAI */ +static long now; /* current time */ +static int flagneedcurrentyear = 1; +static long currentyear; /* approximation to current year */ + +static void initbase(void) +{ + struct tm *t; + if (!flagneedbase) return; + + base = 0; + t = gmtime(&base); + base = -(totai(t->tm_year + 1900,t->tm_mon,t->tm_mday) + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec); + /* assumes the right time_t, counting seconds. */ + /* base may be slightly off if time_t counts non-leap seconds. */ + flagneedbase = 0; +} + +static void initnow(void) +{ + long day; + long year; + + initbase(); + now = time((time_t *) 0) - base; + + if (flagneedcurrentyear) { + day = now / 86400; + if ((now % 86400) < 0) --day; + day -= 11017; + year = 5 + day / 146097; + day = day % 146097; + if (day < 0) { day += 146097; --year; } + year *= 4; + if (day == 146096) { year += 3; day = 36524; } + else { year += day / 36524; day %= 36524; } + year *= 25; + year += day / 1461; + day %= 1461; + year *= 4; + if (day == 1460) { year += 3; day = 365; } + else { year += day / 365; day %= 365; } + day *= 10; + if ((day + 5) / 306 >= 10) ++year; + currentyear = year; + flagneedcurrentyear = 0; + } +} + +/* UNIX ls does not show the year for dates in the last six months. */ +/* So we have to guess the year. */ +/* Apparently NetWare uses ``twelve months'' instead of ``six months''; ugh. */ +/* Some versions of ls also fail to show the year for future dates. */ +static long guesstai(long month,long mday) +{ + long year; + long t; + + initnow(); + + for (year = currentyear - 1;year < currentyear + 100;++year) { + t = totai(year,month,mday); + if (now - t < 350 * 86400) + return t; + } +} + +static int check(char *buf,char *monthname) +{ + if ((buf[0] != monthname[0]) && (buf[0] != monthname[0] - 32)) return 0; + if ((buf[1] != monthname[1]) && (buf[1] != monthname[1] - 32)) return 0; + if ((buf[2] != monthname[2]) && (buf[2] != monthname[2] - 32)) return 0; + return 1; +} + +static char *months[12] = { + "jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec" +} ; + +static int getmonth(char *buf,int len) +{ + int i; + if (len == 3) + for (i = 0;i < 12;++i) + if (check(buf,months[i])) return i; + return -1; +} + +static long getlong(char *buf,int len) +{ + long u = 0; + while (len-- > 0) + u = u * 10 + (*buf++ - '0'); + return u; +} + +int ftpparse(struct ftpparse *fp,char *buf,int len) +{ + int i; + int j; + int state; + long size; + long year; + long month; + long mday; + long hour; + long minute; + + fp->name = 0; + fp->namelen = 0; + fp->flagtrycwd = 0; + fp->flagtryretr = 0; + fp->sizetype = FTPPARSE_SIZE_UNKNOWN; + fp->size = 0; + fp->mtimetype = FTPPARSE_MTIME_UNKNOWN; + fp->mtime = 0; + fp->idtype = FTPPARSE_ID_UNKNOWN; + fp->id = 0; + fp->idlen = 0; + + if (len < 2) /* an empty name in EPLF, with no info, could be 2 chars */ + return 0; + + switch(*buf) { + /* see http://pobox.com/~djb/proto/eplf.txt */ + /* "+i8388621.29609,m824255902,/,\tdev" */ + /* "+i8388621.44468,m839956783,r,s10376,\tRFCEPLF" */ + case '+': + i = 1; + for (j = 1;j < len;++j) { + if (buf[j] == 9) { + fp->name = buf + j + 1; + fp->namelen = len - j - 1; + return 1; + } + if (buf[j] == ',') { + switch(buf[i]) { + case '/': + fp->flagtrycwd = 1; + break; + case 'r': + fp->flagtryretr = 1; + break; + case 's': + fp->sizetype = FTPPARSE_SIZE_BINARY; + fp->size = getlong(buf + i + 1,j - i - 1); + break; + case 'm': + fp->mtimetype = FTPPARSE_MTIME_LOCAL; + initbase(); + fp->mtime = base + getlong(buf + i + 1,j - i - 1); + break; + case 'i': + fp->idtype = FTPPARSE_ID_FULL; + fp->id = buf + i + 1; + fp->idlen = j - i - 1; + } + i = j + 1; + } + } + return 0; + + /* UNIX-style listing, without inum and without blocks */ + /* "-rw-r--r-- 1 root other 531 Jan 29 03:26 README" */ + /* "dr-xr-xr-x 2 root other 512 Apr 8 1994 etc" */ + /* "dr-xr-xr-x 2 root 512 Apr 8 1994 etc" */ + /* "lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin" */ + /* Also produced by Microsoft's FTP servers for Windows: */ + /* "---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z" */ + /* "d--------- 1 owner group 0 May 9 19:45 Softlib" */ + /* Also WFTPD for MSDOS: */ + /* "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 message.ftp" */ + /* Also NetWare: */ + /* "d [R----F--] supervisor 512 Jan 16 18:53 login" */ + /* "- [R----F--] rhesus 214059 Oct 20 15:27 cx.exe" */ + /* Also NetPresenz for the Mac: */ + /* "-------r-- 326 1391972 1392298 Nov 22 1995 MegaPhone.sit" */ + /* "drwxrwxr-x folder 2 May 10 1996 network" */ + case 'b': + case 'c': + case 'd': + case 'l': + case 'p': + case 's': + case '-': + + if (*buf == 'd') fp->flagtrycwd = 1; + if (*buf == '-') fp->flagtryretr = 1; + if (*buf == 'l') fp->flagtrycwd = fp->flagtryretr = 1; + + state = 1; + i = 0; + for (j = 1;j < len;++j) + if ((buf[j] == ' ') && (buf[j - 1] != ' ')) { + switch(state) { + case 1: /* skipping perm */ + state = 2; + break; + case 2: /* skipping nlink */ + state = 3; + if ((j - i == 6) && (buf[i] == 'f')) /* for NetPresenz */ + state = 4; + break; + case 3: /* skipping uid */ + state = 4; + break; + case 4: /* getting tentative size */ + size = getlong(buf + i,j - i); + state = 5; + break; + case 5: /* searching for month, otherwise getting tentative size */ + month = getmonth(buf + i,j - i); + if (month >= 0) + state = 6; + else + size = getlong(buf + i,j - i); + break; + case 6: /* have size and month */ + mday = getlong(buf + i,j - i); + state = 7; + break; + case 7: /* have size, month, mday */ + if ((j - i == 4) && (buf[i + 1] == ':')) { + hour = getlong(buf + i,1); + minute = getlong(buf + i + 2,2); + fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; + initbase(); + fp->mtime = base + guesstai(month,mday) + hour * 3600 + minute * 60; + } else if ((j - i == 5) && (buf[i + 2] == ':')) { + hour = getlong(buf + i,2); + minute = getlong(buf + i + 3,2); + fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; + initbase(); + fp->mtime = base + guesstai(month,mday) + hour * 3600 + minute * 60; + } + else if (j - i >= 4) { + year = getlong(buf + i,j - i); + fp->mtimetype = FTPPARSE_MTIME_REMOTEDAY; + initbase(); + fp->mtime = base + totai(year,month,mday); + } + else + return 0; + fp->name = buf + j + 1; + fp->namelen = len - j - 1; + state = 8; + break; + case 8: /* twiddling thumbs */ + break; + } + i = j + 1; + while ((i < len) && (buf[i] == ' ')) ++i; + } + + if (state != 8) + return 0; + + fp->size = size; + fp->sizetype = FTPPARSE_SIZE_BINARY; + + if (*buf == 'l') + for (i = 0;i + 3 < fp->namelen;++i) + if (fp->name[i] == ' ') + if (fp->name[i + 1] == '-') + if (fp->name[i + 2] == '>') + if (fp->name[i + 3] == ' ') { + fp->namelen = i; + break; + } + + /* eliminate extra NetWare spaces */ + if ((buf[1] == ' ') || (buf[1] == '[')) + if (fp->namelen > 3) + if (fp->name[0] == ' ') + if (fp->name[1] == ' ') + if (fp->name[2] == ' ') { + fp->name += 3; + fp->namelen -= 3; + } + + return 1; + } + + /* MultiNet (some spaces removed from examples) */ + /* "00README.TXT;1 2 30-DEC-1996 17:44 [SYSTEM] (RWED,RWED,RE,RE)" */ + /* "CORE.DIR;1 1 8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)" */ + /* and non-MutliNet VMS: */ + /* "CII-MANUAL.TEX;1 213/216 29-JAN-1996 03:33:12 [ANONYMOU,ANONYMOUS] (RWED,RWED,,)" */ + for (i = 0;i < len;++i) + if (buf[i] == ';') + break; + if (i < len) { + fp->name = buf; + fp->namelen = i; + if (i > 4) + if (buf[i - 4] == '.') + if (buf[i - 3] == 'D') + if (buf[i - 2] == 'I') + if (buf[i - 1] == 'R') { + fp->namelen -= 4; + fp->flagtrycwd = 1; + } + if (!fp->flagtrycwd) + fp->flagtryretr = 1; + while (buf[i] != ' ') if (++i == len) return 0; + while (buf[i] == ' ') if (++i == len) return 0; + while (buf[i] != ' ') if (++i == len) return 0; + while (buf[i] == ' ') if (++i == len) return 0; + j = i; + while (buf[j] != '-') if (++j == len) return 0; + mday = getlong(buf + i,j - i); + while (buf[j] == '-') if (++j == len) return 0; + i = j; + while (buf[j] != '-') if (++j == len) return 0; + month = getmonth(buf + i,j - i); + if (month < 0) return 0; + while (buf[j] == '-') if (++j == len) return 0; + i = j; + while (buf[j] != ' ') if (++j == len) return 0; + year = getlong(buf + i,j - i); + while (buf[j] == ' ') if (++j == len) return 0; + i = j; + while (buf[j] != ':') if (++j == len) return 0; + hour = getlong(buf + i,j - i); + while (buf[j] == ':') if (++j == len) return 0; + i = j; + while ((buf[j] != ':') && (buf[j] != ' ')) if (++j == len) return 0; + minute = getlong(buf + i,j - i); + + fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; + initbase(); + fp->mtime = base + totai(year,month,mday) + hour * 3600 + minute * 60; + + return 1; + } + + /* MSDOS format */ + /* 04-27-00 09:09PM <DIR> licensed */ + /* 07-18-00 10:16AM <DIR> pub */ + /* 04-14-00 03:47PM 589 readme.htm */ + if ((*buf >= '0') && (*buf <= '9')) { + i = 0; + j = 0; + while (buf[j] != '-') if (++j == len) return 0; + month = getlong(buf + i,j - i) - 1; + while (buf[j] == '-') if (++j == len) return 0; + i = j; + while (buf[j] != '-') if (++j == len) return 0; + mday = getlong(buf + i,j - i); + while (buf[j] == '-') if (++j == len) return 0; + i = j; + while (buf[j] != ' ') if (++j == len) return 0; + year = getlong(buf + i,j - i); + if (year < 50) year += 2000; + if (year < 1000) year += 1900; + while (buf[j] == ' ') if (++j == len) return 0; + i = j; + while (buf[j] != ':') if (++j == len) return 0; + hour = getlong(buf + i,j - i); + while (buf[j] == ':') if (++j == len) return 0; + i = j; + while ((buf[j] != 'A') && (buf[j] != 'P')) if (++j == len) return 0; + minute = getlong(buf + i,j - i); + if (hour == 12) hour = 0; + if (buf[j] == 'A') if (++j == len) return 0; + if (buf[j] == 'P') { hour += 12; if (++j == len) return 0; } + if (buf[j] == 'M') if (++j == len) return 0; + + while (buf[j] == ' ') if (++j == len) return 0; + if (buf[j] == '<') { + fp->flagtrycwd = 1; + while (buf[j] != ' ') if (++j == len) return 0; + } + else { + i = j; + while (buf[j] != ' ') if (++j == len) return 0; + fp->size = getlong(buf + i,j - i); + fp->sizetype = FTPPARSE_SIZE_BINARY; + fp->flagtryretr = 1; + } + while (buf[j] == ' ') if (++j == len) return 0; + + fp->name = buf + j; + fp->namelen = len - j; + + fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; + initbase(); + fp->mtime = base + totai(year,month,mday) + hour * 3600 + minute * 60; + + return 1; + } + + /* Some useless lines, safely ignored: */ + /* "Total of 11 Files, 10966 Blocks." (VMS) */ + /* "total 14786" (UNIX) */ + /* "DISK$ANONFTP:[ANONYMOUS]" (VMS) */ + /* "Directory DISK$PCSA:[ANONYM]" (VMS) */ + + return 0; +} diff --git a/src/utilfuns/roman.c b/src/utilfuns/roman.cpp index 3c6d190..85f361d 100644 --- a/src/utilfuns/roman.c +++ b/src/utilfuns/roman.cpp @@ -22,17 +22,20 @@ #include <stdlib.h> #include <string.h> #include <roman.h> + +SWORD_NAMESPACE_START + char isroman (const char* str) { char * ch = (char*)str; - for (; *ch; ch++) - if (!strchr ("IVXLCDMivxlcdm ", *ch)) + for (; *ch; ch++) + if (!strchr("IVXLCDMivxlcdm ", *ch)) return 0; return 1; } int from_rom(const char* str) { int i, n = strlen(str); - short * num= calloc(n, sizeof(short)); + short * num= (short *) calloc(n, sizeof(short)); for (i = 0; str[i]; i++) { switch(str[i]) { case 'i': @@ -80,3 +83,5 @@ int from_rom(const char* str) { free(num); return n; } + +SWORD_NAMESPACE_END diff --git a/src/utilfuns/swbuf.cpp b/src/utilfuns/swbuf.cpp new file mode 100644 index 0000000..18f966e --- /dev/null +++ b/src/utilfuns/swbuf.cpp @@ -0,0 +1,163 @@ +/****************************************************************************** +* swbuf.cpp - code for SWBuf used as a transport and utility for data buffers +* +* $Id: swbuf.cpp,v 1.14 2003/08/13 03:56:14 scribe Exp $ +* +* Copyright 2003 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 <swbuf.h> + +#include <stdlib.h> +#include <stdarg.h> +#include <stdio.h> + +SWORD_NAMESPACE_START + +char *SWBuf::nullStr = ""; +char SWBuf::junkBuf[JUNKBUFSIZE]; + +/****************************************************************************** +* SWBuf Constructor - Creates an empty SWBuf object or an SWBuf initialized +* to a value from a const char * +* +*/ +SWBuf::SWBuf(const char *initVal, unsigned long initSize) { + init(initSize); + set(initVal); +} + +/****************************************************************************** +* SWBuf Constructor - Creates an SWBuf initialized +* to a value from another SWBuf +* +*/ +SWBuf::SWBuf(const SWBuf &other, unsigned long initSize) { + init(initSize); + set(other); +} + +/****************************************************************************** +* SWBuf Constructor - Creates an SWBuf initialized +* to a value from a char +* +*/ +SWBuf::SWBuf(char initVal, unsigned long initSize) { + init(initSize); + + allocSize = 15; + buf = (char *)calloc(allocSize, 1); + *buf = initVal; + end = buf+1; + endAlloc = buf + allocSize-1; +} + +/* +SWBuf::SWBuf(unsigned long initSize) { + init(initSize); + set((const char *)0); +} +*/ + + +void SWBuf::init(unsigned long initSize) { + fillByte = ' '; + allocSize = 0; + endAlloc = 0; + buf = 0; + end = 0; + if (initSize) + assureSize(initSize); +} + +/****************************************************************************** +* SWBuf Destructor - Cleans up instance of SWBuf +*/ +SWBuf::~SWBuf() { + if (buf) + free(buf); +} + +/****************************************************************************** +* SWBuf::set - sets this buf to a new value +*/ +void SWBuf::set(const char *newVal) { + if (newVal) { + unsigned long len = strlen(newVal) + 1; + assureSize(len); + memcpy(buf, newVal, len); + end = buf + (len - 1); + } + else { + assureSize(1); + end = buf; + *end = 0; + } +} + + +/****************************************************************************** +* SWBuf::set - sets this buf to a new value +*/ +void SWBuf::set(const SWBuf &newVal) { + unsigned long len = newVal.length() + 1; + assureSize(len); + memcpy(buf, newVal.c_str(), len); + end = buf + (len-1); +} + + +/****************************************************************************** +* SWBuf::append - appends a value to the current value of this SWBuf +*/ +void SWBuf::append(const char *str, long max) { + unsigned long len = (max > -1) ? max : strlen(str); + assureMore(++len); + memcpy(end, str, len-1); + end += (len-1); + *end = 0; +} + + +/****************************************************************************** +* SWBuf::setSize - Size this buffer to a specific length +*/ +void SWBuf::setSize(unsigned long len) { + assureSize(len+1); + if ((end - buf) < len) + memset(end, fillByte, len - (end-buf)); + end = buf + len; + *end = 0; +} + +/****************************************************************************** +* SWBuf::appendFormatted - appends formatted strings to the current value of this SWBuf +* WARNING: This function can only write at most +* JUNKBUFSIZE to the string per call. +*/ +void SWBuf::appendFormatted(const char *format, ...) { + va_list argptr; + + va_start(argptr, format); + int len = vsprintf(junkBuf, format, argptr)+1; + va_end(argptr); + assureMore(len); + va_start(argptr, format); + end += vsprintf(end, format, argptr); + va_end(argptr); +} + +SWORD_NAMESPACE_END diff --git a/src/utilfuns/swunicod.cpp b/src/utilfuns/swunicod.cpp index f42fd86..64b40ab 100644 --- a/src/utilfuns/swunicod.cpp +++ b/src/utilfuns/swunicod.cpp @@ -17,6 +17,7 @@ */ #include "swunicod.h" +SWORD_NAMESPACE_START unsigned char* UTF32to8 (unsigned long utf32, unsigned char * utf8) { unsigned int i; for (i = 0; i < 6; i++) utf8[i] = 0; @@ -107,10 +108,6 @@ unsigned char* UTF32to8 (unsigned long utf32, unsigned char * utf8) { return utf8; } -/** Converts a UTF-8 encoded 1-6 byte array into a 32-bit unsigned integer UTF-32 value - * @param utf8 pointer to an array of 6 unsigned chars containing the UTF-8 value, starting in the utf8[0] - * @param utf32 the UTF-32 Unicode code point value - */ unsigned long UTF8to32 (unsigned char * utf8) { unsigned char i = utf8[0]; @@ -137,3 +134,5 @@ unsigned long UTF8to32 (unsigned char * utf8) { } return utf32; } + +SWORD_NAMESPACE_END diff --git a/src/utilfuns/swversion.cpp b/src/utilfuns/swversion.cpp index 14a6f4b..a6c3917 100644 --- a/src/utilfuns/swversion.cpp +++ b/src/utilfuns/swversion.cpp @@ -1,8 +1,9 @@ #include <swversion.h> -#include <string.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> +SWORD_NAMESPACE_START SWVersion SWVersion::currentVersion(SWORDVER); @@ -57,7 +58,7 @@ int SWVersion::compare(const SWVersion &vi) const { } -SWVersion::operator const char *() const { +const char *SWVersion::getText() const { // 255 is safe because there is no way 4 integers (plus 3 '.'s) can have // a string representation that will overrun this buffer @@ -76,3 +77,5 @@ SWVersion::operator const char *() const { return buf; } + +SWORD_NAMESPACE_END diff --git a/src/utilfuns/unixstr.cpp b/src/utilfuns/unixstr.cpp index 7a975a2..bbb0ab7 100644 --- a/src/utilfuns/unixstr.cpp +++ b/src/utilfuns/unixstr.cpp @@ -1,7 +1,10 @@ // Include only if your UNIX compiler does not include stricmp but does include strcasecmp #include <unixstr.h> +#include <string.h> +SWORD_NAMESPACE_START int stricmp(const char *s1, const char *s2) { return strcasecmp(s1, s2); } +SWORD_NAMESPACE_END diff --git a/src/utilfuns/utilconf.cpp b/src/utilfuns/utilconf.cpp index 5a32ca0..b7e333d 100644 --- a/src/utilfuns/utilconf.cpp +++ b/src/utilfuns/utilconf.cpp @@ -1,4 +1,3 @@ -#include <string.h> #include <utilstr.h> @@ -13,7 +12,11 @@ * RET: error status */ +SWORD_NAMESPACE_START + char getconfent(char *filename, char *entryname, char *buf, int len) { return 0; } + +SWORD_NAMESPACE_END diff --git a/src/utilfuns/utilstr.cpp b/src/utilfuns/utilstr.cpp index 366c54f..79904c6 100644 --- a/src/utilfuns/utilstr.cpp +++ b/src/utilfuns/utilstr.cpp @@ -1,6 +1,19 @@ -#include <string.h> #include <utilstr.h> #include <ctype.h> +#include <string.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 /****************************************************************************** * stdstr - Sets/gets a string @@ -12,12 +25,12 @@ * RET: *ipstr */ -char *stdstr(char **ipstr, const char *istr) { +char *stdstr(char **ipstr, const char *istr, unsigned int memPadFactor) { if (istr) { if (*ipstr) delete [] *ipstr; int len = strlen(istr) + 1; - *ipstr = new char [ len ]; + *ipstr = new char [ len * memPadFactor ]; memcpy(*ipstr, istr, len); } return *ipstr; @@ -41,8 +54,8 @@ char *strstrip(char *istr) { return istr; rtmp = istr + (len - 1); - while (*rtmp == ' ') *(rtmp--) = 0; - while (*tmp == ' ') tmp++; + while ((rtmp > istr)&&((*rtmp == ' ')||(*rtmp == '\t')||(*rtmp == 10)||(*rtmp == 13))) *(rtmp--) = 0; + while ((*tmp == ' ')||(*tmp == '\t')||(*tmp == 10)||(*tmp == 13)) tmp++; memmove(istr, tmp, (rtmp - tmp) + 1); istr[(rtmp - tmp) + 1] = 0; @@ -95,18 +108,17 @@ const char *stristr(const char *s1, const char *s2) { */ const char strnicmp(const char *s1, const char *s2, int len) { - - int tLen = strlen(s2); - int cLen = strlen(s1); - char diff; - int i; - for (i = 0; ((i < len) && (i < tLen) && (i < cLen)); i++) { - if ((diff = SW_toupper(*s1) - SW_toupper(*s2))) - return diff; + int tLen = strlen(s2); + int cLen = strlen(s1); + char diff; + int i; + for (i = 0; ((i < len) && (i < tLen) && (i < cLen)); i++) { + if ((diff = SW_toupper(*s1) - SW_toupper(*s2))) + return diff; s1++; s2++; - } - return (i < len) ? cLen - tLen : 0; + } + return (i < len) ? cLen - tLen : 0; } /****************************************************************************** @@ -145,8 +157,48 @@ unsigned int strlenw(const char *s1) { char *toupperstr(char *buf) { char *ret = buf; + while (*buf) *buf = SW_toupper(*buf++); return ret; } + + +/****************************************************************************** + * toupperstr - converts a string to uppercase string + * + * ENT: target - string to convert + * + * RET: target + */ + +char *toupperstr_utf8(char *buf, unsigned int max) { + char *ret = buf; + +#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) { + 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/utilweb.cpp b/src/utilfuns/utilweb.cpp new file mode 100644 index 0000000..a3dfa0d --- /dev/null +++ b/src/utilfuns/utilweb.cpp @@ -0,0 +1,35 @@ +#include <utilxml.h> +#include <stdio.h> +#include <map> + +SWORD_NAMESPACE_START + +using std::map; + +typedef map<unsigned char,SWBuf> DataMap; + +const SWBuf encodeURL( const SWBuf& url ) { + 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 + } + + char s[5]; + sprintf(s, "%-.2X", c); //left-aligned, 2 digits, uppercase hex + m[c] = SWBuf("%") + s; //encoded char is "% + 2 digit hex code of char" + } + //the special encodings for certain chars + m[' '] = '+'; + + SWBuf buf; + const int length = url.length(); + for (int i = 0; i <= length; i++) { //fill "buf" + const char& c = url[i]; + buf += (!m[c].length()) ? (SWBuf)c : (SWBuf)m[c]; + } + + return buf; +} + +SWORD_NAMESPACE_END diff --git a/src/utilfuns/utilxml.cpp b/src/utilfuns/utilxml.cpp new file mode 100644 index 0000000..6914cc9 --- /dev/null +++ b/src/utilfuns/utilxml.cpp @@ -0,0 +1,202 @@ + +#include <utilxml.h> +#include <ctype.h> +#include <utilstr.h> + +SWORD_NAMESPACE_START + +void XMLTag::parse() const { + int i; + int start; + char *name = 0; + char *value = 0; + if (!buf) + return; + for (i = 0; ((buf[i]) && (!isalpha(buf[i]))); i++); + for (; buf[i]; i++) { + if (buf[i] == ' ') { + for (; ((buf[i]) && (!isalpha(buf[i]))); i++); + if (buf[i]) { // we have an attribute name + start = i; + for (; ((buf[i]) && (!strchr(" =", buf[i]))); i++); + if (i-start) { + if (name) + delete [] name; + name = new char [ (i-start) + 1 ]; + strncpy(name, buf+start, i-start); + name[i-start] = 0; + } + for (; ((buf[i]) && (strchr(" =\"", buf[i]))); i++); + if (buf[i]) { // we have attribute value + start = i; + for (; ((buf[i]) && (buf[i] != '\"')); i++); + if (i-start) { + if (value) + delete [] value; + value = new char [ (i-start) + 1 ]; + strncpy(value, buf+start, i-start); + value[i-start] = 0; + attributes[name] = value; + } + } + } + } + if (!buf[i]) + break; + } + for (;i;i--) { + if (buf[i] == '/') + empty = true; + if (!strchr(" \n>\t", buf[i])) + break; + } + + parsed = true; + if (name) delete [] name; + if (value) delete [] value; +} + + +XMLTag::XMLTag(const char *tagString) { + + name = 0; + buf = 0; + setText(tagString); +} + +void XMLTag::setText(const char *tagString) { + parsed = false; + empty = false; + endTag = false; + + if (buf) { + delete [] buf; + buf = 0; + } + + if (!tagString) // assert tagString before proceeding + return; + + stdstr(&buf, tagString); + + int start = 0; + int i; + + // skip beginning silliness + for (i = 0; ((tagString[i]) && (!isalpha(tagString[i]))); i++) { + if (tagString[i] == '/') + endTag = true; + } + start = i; + for (; ((tagString[i]) && (!strchr(" />", tagString[i]))); i++); + if (i-start) { + if (name) + delete [] name; + name = new char [ (i-start) + 1 ]; + strncpy(name, tagString+start, i-start); + name[i-start] = 0; + if (tagString[i] == '/') + empty = true; + } +} + +XMLTag::~XMLTag() { + if (buf) + delete [] buf; + if (name) + delete [] name; +} + +const StringList XMLTag::getAttributeNames() const { + StringList retVal; + + if (!parsed) + parse(); + + for (StringPairMap::iterator it = attributes.begin(); it != attributes.end(); it++) + retVal.push_back(it->first.c_str()); + + return retVal; +} + + +const char *XMLTag::getPart(const char *buf, int partNum, char partSplit) const { + for (; (buf && partNum); partNum--) { + buf = strchr(buf, partSplit); + if (buf) + buf++; + } + if (buf) { + const char *end = strchr(buf, partSplit); + junkBuf = buf; + if (end) + junkBuf.setSize(end - buf); + return junkBuf.c_str(); + } + return 0; +} + + +int XMLTag::getAttributePartCount(const char *attribName, char partSplit) const { + int count; + const char *buf = getAttribute(attribName); + for (count = 0; buf; count++) { + buf = strchr(buf, partSplit); + if (buf) + buf++; + } + return count; +} + + +const char *XMLTag::getAttribute(const char *attribName, int partNum, char partSplit) const { + if (!parsed) + parse(); + + StringPairMap::iterator it = attributes.find(attribName); + const char *retVal = (it == attributes.end()) ? 0 : it->second.c_str(); + if ((retVal) && (partNum > -1)) + retVal = getPart(retVal, partNum, partSplit); + + return retVal; +} + + +const char *XMLTag::setAttribute(const char *attribName, const char *attribValue) { + if (!parsed) + parse(); + if (attribValue) + attributes[attribName] = attribValue; + else attributes.erase(attribName); + return attribValue; +} + +const char *XMLTag::toString() const { + SWBuf tag = "<"; + if (!parsed) + parse(); + + if (isEndTag()) + tag += "/"; + + tag += getName(); + for (StringPairMap::iterator it = attributes.begin(); it != attributes.end(); it++) { + tag.appendFormatted(" %s=\"%s\"", it->first.c_str(), it->second.c_str()); + } + + if (isEmpty()) + tag += "/"; + + tag += ">"; + + + if (buf) + delete [] buf; + buf = new char [ tag.length() + 1 ]; + strcpy(buf, tag.c_str()); + + return buf; +} + + +SWORD_NAMESPACE_END diff --git a/src/utilfuns/zlib/adler32.c b/src/utilfuns/zlib/adler32.c index 14e3abd..f29cf42 100644 --- a/src/utilfuns/zlib/adler32.c +++ b/src/utilfuns/zlib/adler32.c @@ -1,9 +1,9 @@ /* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: adler32.c,v 1.1 2001/03/23 09:00:15 scribe Exp $ */ +/* @(#) $Id: adler32.c,v 1.2 2002/10/07 22:28:15 scribe Exp $ */ #include "zlib.h" diff --git a/src/utilfuns/zlib/compress.c b/src/utilfuns/zlib/compress.c index df5fca8..8562957 100644 --- a/src/utilfuns/zlib/compress.c +++ b/src/utilfuns/zlib/compress.c @@ -1,9 +1,9 @@ /* compress.c -- compress a memory buffer - * Copyright (C) 1995-1998 Jean-loup Gailly. + * Copyright (C) 1995-2002 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: compress.c,v 1.1 2001/03/23 09:00:15 scribe Exp $ */ +/* @(#) $Id: compress.c,v 1.2 2002/10/07 22:28:15 scribe Exp $ */ #include "zlib.h" diff --git a/src/utilfuns/zlib/crc32.c b/src/utilfuns/zlib/crc32.c index fe80e8a..8577b4a 100644 --- a/src/utilfuns/zlib/crc32.c +++ b/src/utilfuns/zlib/crc32.c @@ -1,9 +1,9 @@ /* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: crc32.c,v 1.1 2001/03/23 09:00:15 scribe Exp $ */ +/* @(#) $Id: crc32.c,v 1.2 2002/10/07 22:28:15 scribe Exp $ */ #include "zlib.h" diff --git a/src/utilfuns/zlib/deflate.c b/src/utilfuns/zlib/deflate.c index a232eea..1d26f37 100644 --- a/src/utilfuns/zlib/deflate.c +++ b/src/utilfuns/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-1998 Jean-loup Gailly. + * Copyright (C) 1995-2002 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -47,12 +47,12 @@ * */ -/* @(#) $Id: deflate.c,v 1.1 2001/03/23 09:00:15 scribe Exp $ */ +/* @(#) $Id: deflate.c,v 1.2 2002/10/07 22:28:15 scribe Exp $ */ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly "; + " 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 @@ -242,7 +242,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, windowBits = -windowBits; } if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } diff --git a/src/utilfuns/zlib/deflate.h b/src/utilfuns/zlib/deflate.h index e55d52a..64f6345 100644 --- a/src/utilfuns/zlib/deflate.h +++ b/src/utilfuns/zlib/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-1998 Jean-loup Gailly + * Copyright (C) 1995-2002 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id: deflate.h,v 1.1 2001/03/23 09:00:15 scribe Exp $ */ +/* @(#) $Id: deflate.h,v 1.2 2002/10/07 22:28:15 scribe Exp $ */ #ifndef _DEFLATE_H #define _DEFLATE_H diff --git a/src/utilfuns/zlib/gzio.c b/src/utilfuns/zlib/gzio.c index a2c5b58..645dae1 100644 --- a/src/utilfuns/zlib/gzio.c +++ b/src/utilfuns/zlib/gzio.c @@ -1,11 +1,11 @@ /* gzio.c -- IO on .gz files - * Copyright (C) 1995-1998 Jean-loup Gailly. + * 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,v 1.1 2001/03/23 09:00:15 scribe Exp $ */ +/* @(#) $Id: gzio.c,v 1.2 2002/10/07 22:28:15 scribe Exp $ */ #include <stdio.h> diff --git a/src/utilfuns/zlib/infblock.c b/src/utilfuns/zlib/infblock.c index f4920fa..dd7a6d4 100644 --- a/src/utilfuns/zlib/infblock.c +++ b/src/utilfuns/zlib/infblock.c @@ -1,5 +1,5 @@ /* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -249,10 +249,12 @@ int r; &s->sub.trees.tb, s->hufts, z); if (t != Z_OK) { - ZFREE(z, s->sub.trees.blens); r = t; if (r == Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); s->mode = BAD; + } LEAVE } s->sub.trees.index = 0; @@ -313,11 +315,13 @@ int r; t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), s->sub.trees.blens, &bl, &bd, &tl, &td, s->hufts, z); - ZFREE(z, s->sub.trees.blens); if (t != Z_OK) { if (t == (uInt)Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); s->mode = BAD; + } r = t; LEAVE } @@ -329,6 +333,7 @@ int r; } s->sub.decode.codes = c; } + ZFREE(z, s->sub.trees.blens); s->mode = CODES; case CODES: UPDATE diff --git a/src/utilfuns/zlib/infblock.h b/src/utilfuns/zlib/infblock.h index bd25c80..173b226 100644 --- a/src/utilfuns/zlib/infblock.h +++ b/src/utilfuns/zlib/infblock.h @@ -1,5 +1,5 @@ /* infblock.h -- header to use infblock.c - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/src/utilfuns/zlib/infcodes.c b/src/utilfuns/zlib/infcodes.c index cfd0807..0d54ea7 100644 --- a/src/utilfuns/zlib/infcodes.c +++ b/src/utilfuns/zlib/infcodes.c @@ -1,5 +1,5 @@ /* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -92,10 +92,9 @@ int r; uInt n; /* bytes available there */ Bytef *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ - Bytef *f; /* pointer to copy strings from */ + unsigned long csf; /* pointer to copy strings from */ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - long tryF; -// f = q + /* copy input/output information to locals (UPDATE macro restores) */ LOAD @@ -104,128 +103,120 @@ int r; { /* 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; - } - } + 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; + 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 + 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; + 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 + 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; + 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 */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - tryF = (long)q - c->sub.copy.dist; -// f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); - else f = (Bytef *)tryF; -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; + 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; + 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 */ - { + if (k > 7) /* return unused byte, if any */ + { Assert(k < 16, "inflate_codes grabbed too many bytes") k -= 8; n++; diff --git a/src/utilfuns/zlib/infcodes.h b/src/utilfuns/zlib/infcodes.h index 6c750d8..46821a0 100644 --- a/src/utilfuns/zlib/infcodes.h +++ b/src/utilfuns/zlib/infcodes.h @@ -1,5 +1,5 @@ /* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/src/utilfuns/zlib/inffast.c b/src/utilfuns/zlib/inffast.c index 61a78ee..a7ebc64 100644 --- a/src/utilfuns/zlib/inffast.c +++ b/src/utilfuns/zlib/inffast.c @@ -1,5 +1,5 @@ /* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -44,7 +44,7 @@ z_streamp z; uInt md; /* mask for distance tree */ uInt c; /* bytes to copy */ uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ + unsigned long csp; /* copy source pointer */ /* load input, output, bit values */ LOAD @@ -59,94 +59,107 @@ z_streamp z; 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; + 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)); + 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)); + /* 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; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (uInt)(q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } 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) + /* 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 diff --git a/src/utilfuns/zlib/inffast.h b/src/utilfuns/zlib/inffast.h index 8facec5..a31a4bb 100644 --- a/src/utilfuns/zlib/inffast.h +++ b/src/utilfuns/zlib/inffast.h @@ -1,5 +1,5 @@ /* inffast.h -- header to use inffast.c - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/src/utilfuns/zlib/inflate.c b/src/utilfuns/zlib/inflate.c index 32e9b8d..dfb2e86 100644 --- a/src/utilfuns/zlib/inflate.c +++ b/src/utilfuns/zlib/inflate.c @@ -1,5 +1,5 @@ /* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/src/utilfuns/zlib/inftrees.c b/src/utilfuns/zlib/inftrees.c index ef1e0b6..4c32ca3 100644 --- a/src/utilfuns/zlib/inftrees.c +++ b/src/utilfuns/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -11,7 +11,7 @@ #endif const char inflate_copyright[] = - " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; + " 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 @@ -104,8 +104,7 @@ 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), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - lengths), or Z_MEM_ERROR if not enough memory. */ + case), or Z_DATA_ERROR if the input is invalid. */ { uInt a; /* counter for codes of length k */ @@ -231,7 +230,7 @@ uIntf *v; /* working area: values in order of bit length */ /* allocate new table */ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ - return Z_MEM_ERROR; /* not enough memory */ + return Z_DATA_ERROR; /* overflow of MANY */ u[h] = q = hp + *hn; *hn += z; diff --git a/src/utilfuns/zlib/inftrees.h b/src/utilfuns/zlib/inftrees.h index 85853e0..04b73b7 100644 --- a/src/utilfuns/zlib/inftrees.h +++ b/src/utilfuns/zlib/inftrees.h @@ -1,5 +1,5 @@ /* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/src/utilfuns/zlib/infutil.c b/src/utilfuns/zlib/infutil.c index 824dab5..9a07622 100644 --- a/src/utilfuns/zlib/infutil.c +++ b/src/utilfuns/zlib/infutil.c @@ -1,5 +1,5 @@ /* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/src/utilfuns/zlib/infutil.h b/src/utilfuns/zlib/infutil.h index 99d1135..4401df8 100644 --- a/src/utilfuns/zlib/infutil.h +++ b/src/utilfuns/zlib/infutil.h @@ -1,5 +1,5 @@ /* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995-1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/src/utilfuns/zlib/maketree.c b/src/utilfuns/zlib/maketree.c index 949d786..a16d4b1 100644 --- a/src/utilfuns/zlib/maketree.c +++ b/src/utilfuns/zlib/maketree.c @@ -1,5 +1,5 @@ /* maketree.c -- make inffixed.h table for decoding fixed codes - * Copyright (C) 1998 Mark Adler + * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/src/utilfuns/zlib/trees.c b/src/utilfuns/zlib/trees.c index 4d59d6e..52c33f1 100644 --- a/src/utilfuns/zlib/trees.c +++ b/src/utilfuns/zlib/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-1998 Jean-loup Gailly + * Copyright (C) 1995-2002 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -29,7 +29,7 @@ * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ -/* @(#) $Id: trees.c,v 1.1 2001/03/23 09:00:15 scribe Exp $ */ +/* @(#) $Id: trees.c,v 1.2 2002/10/07 22:28:15 scribe Exp $ */ /* #define GEN_TREES_H */ diff --git a/src/utilfuns/zlib/uncompr.c b/src/utilfuns/zlib/uncompr.c index 0c1051a..42492a7 100644 --- a/src/utilfuns/zlib/uncompr.c +++ b/src/utilfuns/zlib/uncompr.c @@ -1,9 +1,9 @@ /* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-1998 Jean-loup Gailly. + * Copyright (C) 1995-2002 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: uncompr.c,v 1.1 2001/03/23 09:00:15 scribe Exp $ */ +/* @(#) $Id: uncompr.c,v 1.2 2002/10/07 22:28:15 scribe Exp $ */ #include "zlib.h" diff --git a/src/utilfuns/zlib/zutil.c b/src/utilfuns/zlib/zutil.c index 2eb7b46..e1c7a6c 100644 --- a/src/utilfuns/zlib/zutil.c +++ b/src/utilfuns/zlib/zutil.c @@ -1,9 +1,9 @@ /* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-1998 Jean-loup Gailly. + * Copyright (C) 1995-2002 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zutil.c,v 1.1 2001/03/23 09:00:15 scribe Exp $ */ +/* @(#) $Id: zutil.c,v 1.2 2002/10/07 22:28:15 scribe Exp $ */ #include "zutil.h" diff --git a/src/utilfuns/zlib/zutil.h b/src/utilfuns/zlib/zutil.h index 53278ba..bd6348d 100644 --- a/src/utilfuns/zlib/zutil.h +++ b/src/utilfuns/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-1998 Jean-loup Gailly. + * Copyright (C) 1995-2002 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id: zutil.h,v 1.1 2001/03/23 09:00:15 scribe Exp $ */ +/* @(#) $Id: zutil.h,v 1.2 2002/10/07 22:28:15 scribe Exp $ */ #ifndef _Z_UTIL_H #define _Z_UTIL_H |