summaryrefslogtreecommitdiff
path: root/src/keys/versekey.cpp
diff options
context:
space:
mode:
authorRoberto C. Sanchez <roberto@connexer.com>2014-03-29 10:53:52 -0400
committerRoberto C. Sanchez <roberto@connexer.com>2014-03-29 10:53:52 -0400
commit148bd343f3e7e32d141f66b5b5c9b98b2975b0b3 (patch)
tree31078963b85110d57310759016e60e8d26ccb1e6 /src/keys/versekey.cpp
parent8c8aa6b07e595cfac56838b5964ab3e96051f1b2 (diff)
Imported Upstream version 1.5.8
Diffstat (limited to 'src/keys/versekey.cpp')
-rw-r--r--src/keys/versekey.cpp1523
1 files changed, 0 insertions, 1523 deletions
diff --git a/src/keys/versekey.cpp b/src/keys/versekey.cpp
deleted file mode 100644
index b2f78e3..0000000
--- a/src/keys/versekey.cpp
+++ /dev/null
@@ -1,1523 +0,0 @@
-/******************************************************************************
- * VerseKey.cpp - code for class 'VerseKey'- a standard Biblical verse key
- */
-
-#include <swmacs.h>
-#include <utilfuns.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <stdlib.h>
-
-#ifndef __GNUC__
-#include <io.h>
-#else
-#include <unistd.h>
-#endif
-
-#include <utilstr.h>
-#include <swkey.h>
-#include <swlog.h>
-#include <versekey.h>
-#include <localemgr.h>
-#include <roman.h>
-
-SWORD_NAMESPACE_START
-
-static const char *classes[] = {"VerseKey", "SWKey", "SWObject", 0};
-SWClass VerseKey::classdef(classes);
-
-/******************************************************************************
- * Initialize static members of VerseKey
- */
-
-#include <canon.h> // Initialize static members of canonical books structure
-
-struct sbook *VerseKey::builtin_books[2] = {0,0};
-const char VerseKey::builtin_BMAX[2] = {39, 27};
-long *VerseKey::offsets[2][2] = {{VerseKey::otbks, VerseKey::otcps}, {VerseKey::ntbks, VerseKey::ntcps}};
-int VerseKey::instance = 0;
-VerseKey::LocaleCache VerseKey::localeCache;
-
-
-/******************************************************************************
- * VerseKey::init - initializes instance of VerseKey
- */
-
-void VerseKey::init() {
- myclass = &classdef;
- if (!instance)
- initstatics();
-
- instance++;
- autonorm = 1; // default auto normalization to true
- headings = 0; // default display headings option is false
- upperBound = 0;
- lowerBound = 0;
- boundSet = false;
- testament = 0;
- book = 0;
- chapter = 0;
- verse = 0;
- locale = 0;
-
- setLocale(LocaleMgr::systemLocaleMgr.getDefaultLocaleName());
-}
-
-/******************************************************************************
- * VerseKey Constructor - initializes instance of VerseKey
- *
- * ENT: ikey - base key (will take various forms of 'BOOK CH:VS'. See
- * VerseKey::parse for more detailed information)
- */
-
-VerseKey::VerseKey(const SWKey *ikey) : SWKey(*ikey)
-{
- init();
- if (ikey)
- parse();
-}
-
-
-/******************************************************************************
- * VerseKey Constructor - initializes instance of VerseKey
- *
- * ENT: ikey - text key (will take various forms of 'BOOK CH:VS'. See
- * VerseKey::parse for more detailed information)
- */
-
-VerseKey::VerseKey(const char *ikey) : SWKey(ikey)
-{
- init();
- if (ikey)
- parse();
-}
-
-
-VerseKey::VerseKey(VerseKey const &k) : SWKey(k)
-{
- init();
- autonorm = k.autonorm;
- headings = k.headings;
- testament = k.Testament();
- book = k.Book();
- chapter = k.Chapter();
- verse = k.Verse();
- if (k.isBoundSet()) {
- LowerBound(k.LowerBound());
- UpperBound(k.UpperBound());
- }
-}
-
-
-VerseKey::VerseKey(const char *min, const char *max) : SWKey()
-{
- init();
- LowerBound(min);
- UpperBound(max);
- setPosition(TOP);
-}
-
-
-SWKey *VerseKey::clone() const
-{
- return new VerseKey(*this);
-}
-
-
-/******************************************************************************
- * VerseKey Destructor - cleans up instance of VerseKey
- *
- * ENT: ikey - text key
- */
-
-VerseKey::~VerseKey() {
- if (upperBound)
- delete upperBound;
- if (lowerBound)
- delete lowerBound;
- if (locale)
- delete [] locale;
-
- --instance;
-}
-
-
-void VerseKey::setLocale(const char *name) {
- char *BMAX;
- struct sbook **books;
- bool useCache = false;
-
- if (localeCache.name)
- useCache = (!strcmp(localeCache.name, name));
-
- if (!useCache) { // if we're setting params for a new locale
- stdstr(&(localeCache.name), name);
- localeCache.abbrevsCnt = 0;
- }
-
- SWLocale *locale = (useCache) ? localeCache.locale : LocaleMgr::systemLocaleMgr.getLocale(name);
- localeCache.locale = locale;
-
- if (locale) {
- locale->getBooks(&BMAX, &books);
- setBooks(BMAX, books);
- setBookAbbrevs(locale->getBookAbbrevs(), localeCache.abbrevsCnt);
- localeCache.abbrevsCnt = abbrevsCnt;
- }
- else {
- setBooks(builtin_BMAX, builtin_books);
- setBookAbbrevs(builtin_abbrevs, localeCache.abbrevsCnt);
- localeCache.abbrevsCnt = abbrevsCnt;
- }
- stdstr(&(this->locale), localeCache.name);
-
- if (lowerBound)
- LowerBound().setLocale(name);
- if (upperBound)
- UpperBound().setLocale(name);
-}
-
-void VerseKey::setBooks(const char *iBMAX, struct sbook **ibooks) {
- BMAX = iBMAX;
- books = ibooks;
-}
-
-
-void VerseKey::setBookAbbrevs(const struct abbrev *bookAbbrevs, unsigned int size) {
- abbrevs = bookAbbrevs;
- if (!size) {
- for (abbrevsCnt = 0; *abbrevs[abbrevsCnt].ab; abbrevsCnt++) {
- /*
- if (strcmp(abbrevs[abbrevsCnt-1].ab, abbrevs[abbrevsCnt].ab) > 0) {
- fprintf(stderr, "ERROR: book abbreviation (canon.h or locale) misordered at entry: %s\n", abbrevs[abbrevsCnt].ab);
- exit(-1);
- }
- */
- }
- for (int t = 0; t < 2; t++) {
- 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);
- }
- }
- }
- }
- else abbrevsCnt = size;
-}
-
-
-/******************************************************************************
- * VerseKey::initstatics - initializes statics. Performed only when first
- * instance on VerseKey (or descendent) is created.
- */
-
-void VerseKey::initstatics() {
- int l1, l2, chaptmp = 0;
-
- builtin_books[0] = otbooks;
- builtin_books[1] = ntbooks;
-
- for (l1 = 0; l1 < 2; l1++) {
- for (l2 = 0; l2 < builtin_BMAX[l1]; l2++) {
- builtin_books[l1][l2].versemax = &vm[chaptmp];
- chaptmp += builtin_books[l1][l2].chapmax;
- }
- }
-}
-
-
-/******************************************************************************
- * VerseKey::parse - parses keytext into testament|book|chapter|verse
- *
- * RET: error status
- */
-
-char VerseKey::parse()
-{
-
-
- testament = 2;
- book = BMAX[1];
- chapter = 1;
- verse = 1;
- int booklen = 0;
-
- int error = 0;
-
- if (keytext) {
- ListKey tmpListKey = VerseKey::ParseVerseList(keytext);
- if (tmpListKey.Count()) {
- SWKey::setText((const char *)tmpListKey);
- for (int i = 1; i < 3; i++) {
- for (int j = 1; j <= BMAX[i-1]; j++) {
- int matchlen = strlen(books[i-1][j-1].name);
- if (!strncmp(keytext, books[i-1][j-1].name, matchlen)) {
- if (matchlen > booklen) {
- booklen = matchlen;
- testament = i;
- book = j;
- }
- }
- }
- }
-
- if (booklen) {
- sscanf(&keytext[booklen], "%d:%d", &chapter, &verse);
- }
- else error = 1;
- } else error = 1;
- }
- Normalize(1);
- freshtext();
-
- return (this->error) ? this->error : (this->error = error);
-}
-
-
-/******************************************************************************
- * VerseKey::freshtext - refreshes keytext based on
- * testament|book|chapter|verse
- */
-
-void VerseKey::freshtext() const
-{
- char buf[2024];
- int realtest = testament;
- int realbook = book;
-
- if (book < 1) {
- if (testament < 1)
- sprintf(buf, "[ Module Heading ]");
- else sprintf(buf, "[ Testament %d Heading ]", (int)testament);
- }
- else {
- if (realbook > BMAX[realtest-1]) {
- realbook -= BMAX[realtest-1];
- if (realtest < 2)
- realtest++;
- if (realbook > BMAX[realtest-1])
- realbook = BMAX[realtest-1];
- }
- sprintf(buf, "%s %d:%d", books[realtest-1][realbook-1].name, chapter, verse);
- }
-
- stdstr((char **)&keytext, buf);
-}
-
-
-
-/******************************************************************************
- * VerseKey::getBookAbbrev - Attempts to find a book abbreviation for a buffer
- *
- * ENT: abbr - key for which to search;
- * RET: book number or < 0 = not valid
- */
-
-int VerseKey::getBookAbbrev(const char *iabbr)
-{
- 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;
- }
- if (retVal > 0)
- break;
- }
- delete [] abbr;
- return retVal;
-}
-
-/******************************************************************************
- * VerseKey::ParseVerseList - Attempts to parse a buffer into separate
- * verse entries returned in a ListKey
- *
- * ENT: buf - buffer to parse;
- * defaultKey - if verse, chap, book, or testament is left off,
- * pull info from this key (ie. Gen 2:3; 4:5;
- * Gen would be used when parsing the 4:5 section)
- * expandRange - whether or not to expand eg. John 1:10-12 or just
- * save John 1:10
- *
- * RET: ListKey reference filled with verse entries contained in buf
- *
- * COMMENT: This code works but wreaks. Rewrite to make more maintainable.
- */
-
-ListKey VerseKey::ParseVerseList(const char *buf, const char *defaultKey, bool expandRange) {
- SWKey textkey;
-
- char book[2048];
- char number[2048];
- int tobook = 0;
- int tonumber = 0;
- int chap = -1, verse = -1;
- int bookno = 0;
- VerseKey curkey, lBound;
- curkey.setLocale(getLocale());
- lBound.setLocale(getLocale());
- int loop;
- 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) {
- case ':':
- number[tonumber] = 0;
- tonumber = 0;
- if (*number)
- chap = atoi(number);
- *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
- number[tonumber] = 0;
- tonumber = 0;
- if (*number) {
- if (chap >= 0)
- verse = atoi(number);
- else chap = atoi(number);
- }
- *number = 0;
- book[tobook] = 0;
- tobook = 0;
- bookno = -1;
- if (*book) {
- for (loop = strlen(book) - 1; loop+1; loop--) {
- if ((isdigit(book[loop])) || (book[loop] == ' ')) {
- book[loop] = 0;
- continue;
- }
- else {
- if ((SW_toupper(book[loop])=='F')&&(loop)) {
- if ((isdigit(book[loop-1])) || (book[loop-1] == ' ') || (SW_toupper(book[loop-1]) == 'F')) {
- book[loop] = 0;
- continue;
- }
- }
- }
- break;
- }
-
- 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 ((!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))) {
- char partial = 0;
- curkey.Verse(1);
- curkey.Chapter(1);
- curkey.Book(1);
-
- if (bookno < 0) {
- curkey.Testament(VerseKey(tmpListKey).Testament());
- curkey.Book(VerseKey(tmpListKey).Book());
- }
- else {
- curkey.Testament(1);
- curkey.Book(bookno);
- }
-
- if (((comma)||((verse < 0)&&(bookno < 0)))&&(!lastPartial)) {
-// if (comma) {
- curkey.Chapter(VerseKey(tmpListKey).Chapter());
- curkey.Verse(chap); // chap because this is the first number captured
- }
- else {
- if (chap >= 0) {
- curkey.Chapter(chap);
- }
- else {
- partial++;
- curkey.Chapter(1);
- }
- if (verse >= 0) {
- curkey.Verse(verse);
- }
- else {
- partial++;
- curkey.Verse(1);
- }
- }
-
- if ((*buf == '-') && (expandRange)) { // if this is a dash save lowerBound and wait for upper
- VerseKey newElement;
- 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
- if (expandRange && partial) {
- VerseKey newElement;
- newElement.LowerBound(curkey);
- if (partial > 1)
- curkey.setPosition(MAXCHAPTER);
- if (partial > 0)
- curkey = MAXVERSE;
- 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 if (expandRange) {
- VerseKey *newElement = SWDYNAMIC_CAST(VerseKey, tmpListKey.GetElement());
- if (newElement) {
- if (partial > 1)
- curkey = MAXCHAPTER;
- if (partial > 0)
- curkey = MAXVERSE;
- newElement->UpperBound(curkey);
- *newElement = TOP;
- tmpListKey.GetElement()->userData = (void *)buf;
- }
- }
- }
- lastPartial = partial;
- }
- *book = 0;
- chap = -1;
- verse = -1;
- if (*buf == ',')
- comma = 1;
- else comma = 0;
- if (*buf == '-')
- dash = 1;
- else dash = 0;
- 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
- 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)) {
- number[tonumber++] = *buf;
- }
- else {
- switch (*buf) {
- case ' ': // ignore these and don't reset number
- case 'f':
- case 'F':
- break;
- default:
- number[tonumber] = 0;
- tonumber = 0;
- break;
- }
- }
- if (chap == -1)
- book[tobook++] = *buf;
- }
- buf++;
- }
- number[tonumber] = 0;
- tonumber = 0;
- if (*number) {
- if (chap >= 0)
- verse = atoi(number);
- else chap = atoi(number);
- }
- *number = 0;
- book[tobook] = 0;
- tobook = 0;
- if (*book) {
- for (loop = strlen(book) - 1; loop+1; loop--) {
- if ((isdigit(book[loop])) || (book[loop] == ' ')) {
- book[loop] = 0;
- continue;
- }
- else {
- if ((SW_toupper(book[loop])=='F')&&(loop)) {
- if ((isdigit(book[loop-1])) || (book[loop-1] == ' ') || (SW_toupper(book[loop-1]) == 'F')) {
- book[loop] = 0;
- continue;
- }
- }
- }
- break;
- }
-
- 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 ((!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))) {
- char partial = 0;
- curkey.Verse(1);
- curkey.Chapter(1);
- curkey.Book(1);
-
- if (bookno < 0) {
- curkey.Testament(VerseKey(tmpListKey).Testament());
- curkey.Book(VerseKey(tmpListKey).Book());
- }
- else {
- curkey.Testament(1);
- curkey.Book(bookno);
- }
-
- if (((comma)||((verse < 0)&&(bookno < 0)))&&(!lastPartial)) {
-// if (comma) {
- curkey.Chapter(VerseKey(tmpListKey).Chapter());
- curkey.Verse(chap); // chap because this is the first number captured
- }
- else {
- if (chap >= 0) {
- curkey.Chapter(chap);
- }
- else {
- partial++;
- curkey.Chapter(1);
- }
- if (verse >= 0) {
- curkey.Verse(verse);
- }
- else {
- partial++;
- curkey.Verse(1);
- }
- }
-
- if ((*buf == '-') && (expandRange)) { // if this is a dash save lowerBound and wait for upper
- VerseKey newElement;
- newElement.LowerBound(curkey);
- newElement = TOP;
- tmpListKey << newElement;
- tmpListKey.GetElement()->userData = (void *)buf;
- }
- else {
- if (!dash) { // if last separator was not a dash just add
- if (expandRange && partial) {
- VerseKey newElement;
- newElement.LowerBound(curkey);
- if (partial > 1)
- curkey = MAXCHAPTER;
- if (partial > 0)
- curkey = MAXVERSE;
- 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 if (expandRange) {
- VerseKey *newElement = SWDYNAMIC_CAST(VerseKey, tmpListKey.GetElement());
- if (newElement) {
- if (partial > 1)
- curkey = MAXCHAPTER;
- if (partial > 0)
- curkey = MAXVERSE;
- newElement->UpperBound(curkey);
- *newElement = TOP;
- tmpListKey.GetElement()->userData = (void *)buf;
- }
- }
- }
- }
- *book = 0;
- tmpListKey = TOP;
- tmpListKey.Remove(); // remove defaultKey
- internalListKey = tmpListKey;
- internalListKey = TOP; // Align internalListKey to first element before passing back;
-
- return internalListKey;
-}
-
-
-/******************************************************************************
- * VerseKey::LowerBound - sets / gets the lower boundary for this key
- */
-
-VerseKey &VerseKey::LowerBound(const char *lb)
-{
- if (!lowerBound)
- initBounds();
-
- (*lowerBound) = lb;
- lowerBound->Normalize();
- lowerBound->setLocale( this->getLocale() );
- boundSet = true;
- return (*lowerBound);
-}
-
-
-/******************************************************************************
- * VerseKey::UpperBound - sets / gets the upper boundary for this key
- */
-
-VerseKey &VerseKey::UpperBound(const char *ub)
-{
- if (!upperBound)
- initBounds();
-
-// need to set upperbound parsing to resolve to max verse/chap if not specified
- (*upperBound) = ub;
- if (*upperBound < *lowerBound)
- *upperBound = *lowerBound;
- upperBound->Normalize();
- upperBound->setLocale( this->getLocale() );
-
-// until we have a proper method to resolve max verse/chap use this kludge
- int len = strlen(ub);
- bool alpha = false;
- bool versespec = false;
- bool chapspec = false;
- for (int i = 0; i < len; i++) {
- if (isalpha(ub[i]))
- alpha = true;
- if (ub[i] == ':') // if we have a : we assume verse spec
- versespec = true;
- if ((isdigit(ub[i])) && (alpha)) // if digit after alpha assume chap spec
- chapspec = true;
- }
- if (!chapspec)
- *upperBound = MAXCHAPTER;
- if (!versespec)
- *upperBound = MAXVERSE;
-
-
-// -- end kludge
- boundSet = true;
- return (*upperBound);
-}
-
-
-/******************************************************************************
- * VerseKey::LowerBound - sets / gets the lower boundary for this key
- */
-
-VerseKey &VerseKey::LowerBound() const
-{
- if (!lowerBound)
- initBounds();
-
- return (*lowerBound);
-}
-
-
-/******************************************************************************
- * VerseKey::UpperBound - sets / gets the upper boundary for this key
- */
-
-VerseKey &VerseKey::UpperBound() const
-{
- if (!upperBound)
- initBounds();
-
- return (*upperBound);
-}
-
-
-/******************************************************************************
- * VerseKey::ClearBounds - clears bounds for this VerseKey
- */
-
-void VerseKey::ClearBounds()
-{
- initBounds();
-}
-
-
-void VerseKey::initBounds() const
-{
- if (!upperBound) {
- upperBound = new VerseKey();
- upperBound->AutoNormalize(0);
- upperBound->Headings(1);
- }
- if (!lowerBound) {
- lowerBound = new VerseKey();
- lowerBound->AutoNormalize(0);
- lowerBound->Headings(1);
- }
-
- lowerBound->Testament(0);
- lowerBound->Book(0);
- lowerBound->Chapter(0);
- lowerBound->Verse(0);
-
- upperBound->Testament(2);
- upperBound->Book(BMAX[1]);
- upperBound->Chapter(books[1][BMAX[1]-1].chapmax);
- upperBound->Verse(books[1][BMAX[1]-1].versemax[upperBound->Chapter()-1]);
- boundSet = false;
-}
-
-
-/******************************************************************************
- * VerseKey::copyFrom - Equates this VerseKey to another VerseKey
- */
-
-void VerseKey::copyFrom(const VerseKey &ikey) {
- SWKey::copyFrom(ikey);
-
- parse();
-}
-
-
-/******************************************************************************
- * VerseKey::copyFrom - Equates this VerseKey to another SWKey
- */
-
-void VerseKey::copyFrom(const SWKey &ikey) {
- SWKey::copyFrom(ikey);
-
- parse();
-}
-
-
-/******************************************************************************
- * VerseKey::getText - refreshes keytext before returning if cast to
- * a (char *) is requested
- */
-
-const char *VerseKey::getText() const {
- freshtext();
- return keytext;
-}
-
-
-const char *VerseKey::getShortText() const {
- static char *stext = 0;
- char buf[2047];
- freshtext();
- if (book < 1) {
- if (testament < 1)
- sprintf(buf, "[ Module Heading ]");
- else sprintf(buf, "[ Testament %d Heading ]", (int)testament);
- }
- else {
- sprintf(buf, "%s %d:%d", books[testament-1][book-1].prefAbbrev, chapter, verse);
- }
- stdstr(&stext, buf);
- return stext;
-}
-
-
-const char *VerseKey::getBookName() const {
- return books[testament-1][book-1].name;
-}
-
-
-const char *VerseKey::getBookAbbrev() const {
- return books[testament-1][book-1].prefAbbrev;
-}
-/******************************************************************************
- * VerseKey::setPosition(SW_POSITION) - Positions this key
- *
- * ENT: p - position
- *
- * RET: *this
- */
-
-void VerseKey::setPosition(SW_POSITION p) {
- switch (p) {
- case POS_TOP:
- testament = LowerBound().Testament();
- book = LowerBound().Book();
- chapter = LowerBound().Chapter();
- verse = LowerBound().Verse();
- break;
- case POS_BOTTOM:
- testament = UpperBound().Testament();
- book = UpperBound().Book();
- chapter = UpperBound().Chapter();
- verse = UpperBound().Verse();
- break;
- case POS_MAXVERSE:
- Normalize();
- verse = books[testament-1][book-1].versemax[chapter-1];
- break;
- case POS_MAXCHAPTER:
- verse = 1;
- Normalize();
- chapter = books[testament-1][book-1].chapmax;
- break;
- }
- Normalize(1);
- Error(); // clear error from normalize
-}
-
-
-/******************************************************************************
- * VerseKey::increment - Increments key a number of verses
- *
- * ENT: step - Number of verses to jump forward
- *
- * RET: *this
- */
-
-void VerseKey::increment(int step) {
- char ierror = 0;
- Index(Index() + step);
- while ((!verse) && (!headings) && (!ierror)) {
- Index(Index() + 1);
- ierror = Error();
- }
-
- error = (ierror) ? ierror : error;
-}
-
-
-/******************************************************************************
- * VerseKey::decrement - Decrements key a number of verses
- *
- * ENT: step - Number of verses to jump backward
- *
- * RET: *this
- */
-
-void VerseKey::decrement(int step) {
- char ierror = 0;
-
- Index(Index() - step);
- while ((!verse) && (!headings) && (!ierror)) {
- Index(Index() - 1);
- ierror = Error();
- }
- if ((ierror) && (!headings))
- (*this)++;
-
- error = (ierror) ? ierror : error;
-}
-
-
-/******************************************************************************
- * VerseKey::Normalize - checks limits and normalizes if necessary (e.g.
- * Matthew 29:47 = Mark 2:2). If last verse is
- * exceeded, key is set to last Book CH:VS
- * RET: *this
- */
-
-void VerseKey::Normalize(char autocheck)
-{
- error = 0;
-
- if ((autocheck) && (!autonorm)) // only normalize if we were explicitely called or if autonorm is turned on
- return;
-
- if ((headings) && (!verse)) // this is cheeze and temporary until deciding what actions should be taken.
- return; // so headings should only be turned on when positioning with Index() or incrementors
-
- while ((testament < 3) && (testament > 0)) {
-
- if (book > BMAX[testament-1]) {
- book -= BMAX[testament-1];
- testament++;
- continue;
- }
-
- if (book < 1) {
- if (--testament > 0) {
- book += BMAX[testament-1];
- }
- continue;
- }
-
- if (chapter > books[testament-1][book-1].chapmax) {
- chapter -= books[testament-1][book-1].chapmax;
- book++;
- continue;
- }
-
- if (chapter < 1) {
- if (--book > 0) {
- chapter += books[testament-1][book-1].chapmax;
- }
- else {
- if (testament > 1) {
- chapter += books[0][BMAX[0]-1].chapmax;
- }
- }
- continue;
- }
-
- if (verse > books[testament-1][book-1].versemax[chapter-1]) { // -1 because e.g chapter 1 of Matthew is books[1][0].versemax[0]
- verse -= books[testament-1][book-1].versemax[chapter++ - 1];
- continue;
- }
-
- if (verse < 1) {
- if (--chapter > 0) {
- verse += books[testament-1][book-1].versemax[chapter-1];
- }
- else {
- if (book > 1) {
- verse += books[testament-1][book-2].versemax[books[testament-1][book-2].chapmax-1];
- }
- else {
- if (testament > 1) {
- verse += books[0][BMAX[0]-1].versemax[books[0][BMAX[0]-1].chapmax-1];
- }
- }
- }
- continue;
- }
-
- break; // If we've made it this far (all failure checks continue) we're ok
- }
-
- if (testament > 2) {
- testament = 2;
- book = BMAX[testament-1];
- chapter = books[testament-1][book-1].chapmax;
- verse = books[testament-1][book-1].versemax[chapter-1];
- error = KEYERR_OUTOFBOUNDS;
- }
-
- if (testament < 1) {
- error = ((!headings) || (testament < 0) || (book < 0)) ? KEYERR_OUTOFBOUNDS : 0;
- testament = ((headings) ? 0 : 1);
- book = ((headings) ? 0 : 1);
- chapter = ((headings) ? 0 : 1);
- verse = ((headings) ? 0 : 1);
- }
- if (_compare(UpperBound()) > 0) {
- *this = UpperBound();
- error = KEYERR_OUTOFBOUNDS;
- }
- if (_compare(LowerBound()) < 0) {
- *this = LowerBound();
- error = KEYERR_OUTOFBOUNDS;
- }
-}
-
-
-/******************************************************************************
- * VerseKey::Testament - Gets testament
- *
- * RET: value of testament
- */
-
-char VerseKey::Testament() const
-{
- return testament;
-}
-
-
-/******************************************************************************
- * VerseKey::Book - Gets book
- *
- * RET: value of book
- */
-
-char VerseKey::Book() const
-{
- return book;
-}
-
-
-/******************************************************************************
- * VerseKey::Chapter - Gets chapter
- *
- * RET: value of chapter
- */
-
-int VerseKey::Chapter() const
-{
- return chapter;
-}
-
-
-/******************************************************************************
- * VerseKey::Verse - Gets verse
- *
- * RET: value of verse
- */
-
-int VerseKey::Verse() const
-{
- return verse;
-}
-
-
-/******************************************************************************
- * VerseKey::Testament - Sets/gets testament
- *
- * ENT: itestament - value which to set testament
- * [MAXPOS(char)] - only get
- *
- * RET: if unchanged -> value of testament
- * if changed -> previous value of testament
- */
-
-char VerseKey::Testament(char itestament)
-{
- char retval = testament;
-
- if (itestament != MAXPOS(char)) {
- testament = itestament;
- Normalize(1);
- }
- return retval;
-}
-
-
-/******************************************************************************
- * VerseKey::Book - Sets/gets book
- *
- * ENT: ibook - value which to set book
- * [MAXPOS(char)] - only get
- *
- * RET: if unchanged -> value of book
- * if changed -> previous value of book
- */
-
-char VerseKey::Book(char ibook)
-{
- char retval = book;
-
- Chapter(1);
- book = ibook;
- Normalize(1);
-
- return retval;
-}
-
-
-/******************************************************************************
- * VerseKey::Chapter - Sets/gets chapter
- *
- * ENT: ichapter - value which to set chapter
- * [MAXPOS(int)] - only get
- *
- * RET: if unchanged -> value of chapter
- * if changed -> previous value of chapter
- */
-
-int VerseKey::Chapter(int ichapter)
-{
- int retval = chapter;
-
- Verse(1);
- chapter = ichapter;
- Normalize(1);
-
- return retval;
-}
-
-
-/******************************************************************************
- * VerseKey::Verse - Sets/gets verse
- *
- * ENT: iverse - value which to set verse
- * [MAXPOS(int)] - only get
- *
- * RET: if unchanged -> value of verse
- * if changed -> previous value of verse
- */
-
-int VerseKey::Verse(int iverse)
-{
- int retval = verse;
-
- verse = iverse;
- Normalize(1);
-
- return retval;
-}
-
-
-/******************************************************************************
- * VerseKey::AutoNormalize - Sets/gets flag that tells VerseKey to auto-
- * matically normalize itself when modified
- *
- * ENT: iautonorm - value which to set autonorm
- * [MAXPOS(char)] - only get
- *
- * RET: if unchanged -> value of autonorm
- * if changed -> previous value of autonorm
- */
-
-char VerseKey::AutoNormalize(char iautonorm)
-{
- char retval = autonorm;
-
- if (iautonorm != MAXPOS(char)) {
- autonorm = iautonorm;
- Normalize(1);
- }
- return retval;
-}
-
-
-/******************************************************************************
- * VerseKey::Headings - Sets/gets flag that tells VerseKey to include
- * chap/book/testmnt/module headings
- *
- * ENT: iheadings - value which to set headings
- * [MAXPOS(char)] - only get
- *
- * RET: if unchanged -> value of headings
- * if changed -> previous value of headings
- */
-
-char VerseKey::Headings(char iheadings)
-{
- char retval = headings;
-
- if (iheadings != MAXPOS(char)) {
- headings = iheadings;
- Normalize(1);
- }
- return retval;
-}
-
-
-/******************************************************************************
- * VerseKey::findindex - binary search to find the index closest, but less
- * than the given value.
- *
- * ENT: array - long * to array to search
- * size - number of elements in the array
- * value - value to find
- *
- * RET: the index into the array that is less than but closest to value
- */
-
-int VerseKey::findindex(long *array, int size, long value)
-{
- int lbound, ubound, tval;
-
- lbound = 0;
- ubound = size - 1;
- while ((ubound - lbound) > 1) {
- tval = lbound + (ubound-lbound)/2;
- if (array[tval] <= value)
- lbound = tval;
- else ubound = tval;
- }
- return (array[ubound] <= value) ? ubound : lbound;
-}
-
-
-/******************************************************************************
- * VerseKey::Index - Gets index based upon current verse
- *
- * RET: offset
- */
-
-long VerseKey::Index() const
-{
- long offset;
-
- if (!testament) { // if we want module heading
- offset = 0;
- verse = 0;
- }
- else {
- if (!book)
- chapter = 0;
- if (!chapter)
- verse = 0;
-
- offset = offsets[testament-1][0][book];
- offset = offsets[testament-1][1][(int)offset + chapter];
- if (!(offset|verse)) // if we have a testament but nothing else.
- offset = 1;
- }
- return (offset + verse);
-}
-
-
-/******************************************************************************
- * VerseKey::Index - Gets index based upon current verse
- *
- * RET: offset
- */
-
-long VerseKey::NewIndex() const
-{
- static long otMaxIndex = 32300 - 8245; // total positions - new testament positions
-// static long otMaxIndex = offsets[0][1][(int)offsets[0][0][BMAX[0]] + books[0][BMAX[0]].chapmax];
- return ((testament-1) * otMaxIndex) + Index();
-}
-
-
-/******************************************************************************
- * VerseKey::Index - Sets index based upon current verse
- *
- * ENT: iindex - value to set index to
- *
- * RET: offset
- */
-
-long VerseKey::Index(long iindex)
-{
- long offset;
-
-// This is the dirty stuff --------------------------------------------
-
- if (!testament)
- testament = 1;
-
- if (iindex < 1) { // if (-) or module heading
- if (testament < 2) {
- if (iindex < 0) {
- testament = 0; // previously we changed 0 -> 1
- error = KEYERR_OUTOFBOUNDS;
- }
- else testament = 0; // we want module heading
- }
- else {
- testament--;
- iindex = (offsets[testament-1][1][offsize[testament-1][1]-1] + books[testament-1][BMAX[testament-1]-1].versemax[books[testament-1][BMAX[testament-1]-1].chapmax-1]) + iindex; // What a doozy! ((offset of last chapter + number of verses in the last chapter) + iindex)
- }
- }
-
-// --------------------------------------------------------------------
-
-
- if (testament) {
- if ((!error) && (iindex)) {
- offset = findindex(offsets[testament-1][1], offsize[testament-1][1], iindex);
- verse = iindex - offsets[testament-1][1][offset];
- book = findindex(offsets[testament-1][0], offsize[testament-1][0], offset);
- chapter = offset - offsets[testament-1][0][VerseKey::book];
- verse = (chapter) ? verse : 0; // funny check. if we are index=1 (testmt header) all gets set to 0 exept verse. Don't know why. Fix if you figure out. Think its in the offsets table.
- if (verse) { // only check if -1 won't give negative
- if (verse > books[testament-1][book-1].versemax[chapter-1]) {
- if (testament > 1) {
- verse = books[testament-1][book-1].versemax[chapter-1];
- error = KEYERR_OUTOFBOUNDS;
- }
- else {
- testament++;
- Index(verse - books[testament-2][book-1].versemax[chapter-1]);
- }
- }
- }
- }
- }
- if (_compare(UpperBound()) > 0) {
- *this = UpperBound();
- error = KEYERR_OUTOFBOUNDS;
- }
- if (_compare(LowerBound()) < 0) {
- *this = LowerBound();
- error = KEYERR_OUTOFBOUNDS;
- }
- return Index();
-}
-
-
-/******************************************************************************
- * VerseKey::compare - Compares another SWKey object
- *
- * ENT: ikey - key to compare with this one
- *
- * RET: >0 if this versekey is greater than compare versekey
- * <0 <
- * 0 =
- */
-
-int VerseKey::compare(const SWKey &ikey)
-{
- VerseKey ivkey = (const char *)ikey;
- return _compare(ivkey);
-}
-
-
-/******************************************************************************
- * VerseKey::_compare - Compares another VerseKey object
- *
- * ENT: ikey - key to compare with this one
- *
- * RET: >0 if this versekey is greater than compare versekey
- * <0 <
- * 0 =
- */
-
-int VerseKey::_compare(const VerseKey &ivkey)
-{
- long keyval1 = 0;
- long keyval2 = 0;
-
- keyval1 += Testament() * 1000000000;
- keyval2 += ivkey.Testament() * 1000000000;
- keyval1 += Book() * 1000000;
- keyval2 += ivkey.Book() * 1000000;
- keyval1 += Chapter() * 1000;
- keyval2 += ivkey.Chapter() * 1000;
- keyval1 += Verse();
- keyval2 += ivkey.Verse();
- keyval1 -= keyval2;
- keyval1 = (keyval1) ? ((keyval1 > 0) ? 1 : -1) /*keyval1/labs(keyval1)*/:0; // -1 | 0 | 1
- 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