42 #if defined(USECXX11REGEX)
45 #define REG_ICASE std::regex::icase
47 #elif defined(USEICUREGEX)
48 #include <unicode/regex.h>
50 #define REG_ICASE UREGEX_CASE_INSENSITIVE
58 #elif defined USELUCENE
67 using namespace lucene::index;
68 using namespace lucene::analysis;
69 using namespace lucene::util;
70 using namespace lucene::store;
71 using namespace lucene::document;
72 using namespace lucene::queryParser;
73 using namespace lucene::search;
113 this->encoding = encoding;
114 this->direction = direction;
115 this->markup = markup;
117 disp = (idisp) ? idisp : &rawdisp;
118 stdstr(&modname, imodname);
119 stdstr(&moddesc, imoddesc);
120 stdstr(&modtype, imodtype);
121 stdstr(&modlang, imodlang);
127 skipConsecutiveLinks =
true;
148 if (!key->isPersist())
152 stripFilters->clear();
154 renderFilters->clear();
155 optionFilters->clear();
156 encodingFilters->clear();
157 entryAttributes.clear();
161 delete renderFilters;
162 delete optionFilters;
163 delete encodingFilters;
190 if (!retval) retval = key->popError();
273 disp->display(*
this);
302 if (!key->isPersist())
310 else key = (
SWKey *)ikey;
329 char saveError = key->popError();
357 error = key->popError();
371 error = key->popError();
397 ListKey &
SWModule::search(
const char *istr,
int searchType,
int flags,
SWKey *scope,
bool *justCheckIfSupported,
void (*percent)(
char,
void *),
void *percentUserData) {
401 bool includeComponents =
false;
409 if ((flags & SEARCHFLAG_STRICTBOUNDARIES) && (searchType == SEARCHTYPE_MULTIWORD || searchType > 0)) {
411 flags ^= SEARCHFLAG_STRICTBOUNDARIES;
415 SWBuf target = getConfigEntry(
"AbsoluteDataPath");
419 #if defined USEXAPIAN
421 #elif defined USELUCENE
424 if (justCheckIfSupported) {
425 *justCheckIfSupported = (searchType >= SEARCHTYPE_ENTRYATTR);
426 #if defined USEXAPIAN
428 *justCheckIfSupported =
true;
430 #elif defined USELUCENE
431 if ((searchType == SEARCHTYPE_EXTERNAL) && (IndexReader::indexExists(target.
c_str()))) {
432 *justCheckIfSupported =
true;
439 SWKey *searchKey = 0;
440 SWKey *resultKey = createKey();
441 SWKey *lastKey = createKey();
446 std::locale oldLocale;
447 std::locale::global(std::locale(
"en_US.UTF-8"));
450 #elif defined(USEICUREGEX)
451 icu::RegexMatcher *matcher = 0;
457 vector<SWBuf> window;
459 terminateSearch =
false;
461 bool savePEA = isProcessEntryAttributes();
464 bool specialStrips = (getConfigEntry(
"LocalStripFilter")
465 || (getConfig().has(
"GlobalOptionFilter",
"UTF8GreekAccents"))
466 || (getConfig().has(
"GlobalOptionFilter",
"UTF8HebrewPoints"))
467 || (getConfig().has(
"GlobalOptionFilter",
"UTF8ArabicPoints"))
468 || (strchr(istr,
'<')));
470 setProcessEntryAttributes(searchType == SEARCHTYPE_ENTRYATTR);
473 if (!key->isPersist()) {
474 saveKey = createKey();
479 searchKey = (scope)?scope->
clone():(key->isPersist())?key->
clone():0;
485 (*percent)(perc, percentUserData);
488 long highIndex = key->getIndex();
492 if (searchType >= 0) {
494 preg = std::regex((
SWBuf(
".*")+istr+
".*").c_str(), std::regex_constants::extended | searchType | flags);
495 #elif defined(USEICUREGEX)
496 UErrorCode status = U_ZERO_ERROR;
497 matcher =
new icu::RegexMatcher(istr, searchType | flags, status);
498 if (U_FAILURE(status)) {
505 int err = regcomp(&preg, istr, flags);
513 (*percent)(++perc, percentUserData);
516 #if defined USEXAPIAN || defined USELUCENE
517 (*percent)(10, percentUserData);
518 if (searchType == SEARCHTYPE_EXTERNAL) {
519 #if defined USEXAPIAN
521 Xapian::Database database(target.
c_str());
522 Xapian::QueryParser queryParser;
523 queryParser.set_default_op(Xapian::Query::OP_AND);
525 queryParser.set_stemmer(Xapian::Stem(getLanguage()));
527 queryParser.set_stemming_strategy(queryParser.STEM_SOME);
528 queryParser.add_prefix(
"content",
"C");
529 queryParser.add_prefix(
"lemma",
"L");
530 queryParser.add_prefix(
"morph",
"M");
531 queryParser.add_prefix(
"prox",
"P");
532 queryParser.add_prefix(
"proxlem",
"PL");
533 queryParser.add_prefix(
"proxmorph",
"PM");
535 #elif defined USELUCENE
537 lucene::index::IndexReader *ir = 0;
538 lucene::search::IndexSearcher *is = 0;
542 ir = IndexReader::open(target);
543 is =
new IndexSearcher(ir);
544 const TCHAR *stopWords[] = { 0 };
545 standard::StandardAnalyzer analyzer(stopWords);
549 #if defined USEXAPIAN
550 Xapian::Query q = queryParser.parse_query(istr);
551 Xapian::Enquire enquire = Xapian::Enquire(database);
552 #elif defined USELUCENE
553 q = QueryParser::parse((
wchar_t *)
utf8ToWChar(istr).getRawData(), _T(
"content"), &analyzer);
555 (*percent)(20, percentUserData);
558 #if defined USEXAPIAN
559 enquire.set_query(q);
560 Xapian::MSet h = enquire.get_mset(0, 99999);
561 #elif defined USELUCENE
564 (*percent)(80, percentUserData);
567 bool checkBounds = getKey()->isBoundSet();
568 #if defined USEXAPIAN
569 Xapian::MSetIterator i;
570 for (i = h.begin(); i != h.end(); ++i) {
572 SW_u64 score = i.get_percent();
573 Xapian::Document doc = i.get_document();
574 *resultKey = doc.get_data().c_str();
575 #elif defined USELUCENE
576 for (
unsigned long i = 0; i < (
unsigned long)h->length(); i++) {
577 Document &doc = h->doc(i);
585 *getKey() = *resultKey;
586 if (*getKey() != *resultKey) {
590 listKey << *resultKey;
591 listKey.getElement()->
userData = score;
593 (*percent)(98, percentUserData);
596 #if defined USEXAPIAN
597 #elif defined USELUCENE
602 #if defined USEXAPIAN
603 #elif defined USELUCENE
616 switch (searchType) {
618 case SEARCHTYPE_PHRASE:
623 case SEARCHTYPE_MULTIWORD:
629 words.push_back(term);
632 words.push_back(word);
634 if ((flags & REG_ICASE) == REG_ICASE) {
635 for (
unsigned int i = 0; i < words.size(); i++) {
642 case SEARCHTYPE_ENTRYATTR:
647 words.push_back(term);
650 words.push_back(word);
652 if ((words.size()>2) && words[2].endsWith(
".")) {
653 includeComponents =
true;
662 (*percent)(perc, percentUserData);
665 while ((searchType != SEARCHTYPE_EXTERNAL) && !popError() && !terminateSearch) {
666 long mindex = key->getIndex();
667 float per = (float)mindex / highIndex;
670 char newperc = (char)per;
671 if (newperc > perc) {
673 (*percent)(perc, percentUserData);
675 else if (newperc < perc) {
677 "Serious error: new percentage complete is less than previous value\nindex: %d\nhighIndex: %d\nnewperc == %d%% is smaller than\nperc == %d%%",
678 key->getIndex(), highIndex, (int)newperc, (
int )perc);
682 if (searchType >= 0) {
683 SWBuf textBuf = stripText();
686 #elif defined(USEICUREGEX)
687 icu::UnicodeString stringToTest = textBuf.
c_str();
688 matcher->reset(stringToTest);
690 if (matcher->find()) {
692 if (!regexec(&preg, textBuf, 0, 0, 0)) {
694 *resultKey = *getKey();
696 listKey << *resultKey;
700 else if (std::regex_match(
std::string((lastBuf +
' ' + textBuf).c_str()), preg)) {
701 #elif defined(USEICUREGEX)
703 stringToTest = (lastBuf +
' ' + textBuf).c_str();
704 matcher->reset(stringToTest);
706 if (matcher->find()) {
708 else if (!regexec(&preg, lastBuf +
' ' + textBuf, 0, 0, 0)) {
713 *resultKey = *getKey();
718 *resultKey = *lastKey;
721 listKey << *resultKey;
722 lastBuf = (windowSize > 1) ? textBuf.
c_str() :
"";
725 lastBuf = (windowSize > 1) ? textBuf.
c_str() :
"";
727 #if defined(USEICUREGEX)
734 switch (searchType) {
736 case SEARCHTYPE_PHRASE: {
737 textBuf = stripText();
741 *resultKey = *getKey();
743 listKey << *resultKey;
748 case SEARCHTYPE_MULTIWORD: {
751 unsigned int foundWords = 0;
752 textBuf = getRawEntry();
772 if (stripped||specialStrips||multiVerse) {
773 testBuf = multiVerse ? lastBuf +
' ' + textBuf : textBuf;
774 if (stripped) testBuf = stripText(testBuf);
780 for (
unsigned int i = 0; i < words.size(); i++) {
781 sres = strstr(testBuf.
size() ? testBuf.
c_str() : textBuf.
c_str(), words[i].c_str());
789 }
while ( (stripped < 2) && (foundWords == words.size()));
791 }
while ((windowSize > 1) && (multiVerse < 2) && (stripped != 2 || foundWords != words.size()));
793 if ((stripped == 2) && (foundWords == words.size())) {
796 *resultKey = (multiVerse > 1 && !vkCheck) ? *lastKey : *getKey();
797 if (multiVerse > 1 && vkCheck) {
804 listKey << *resultKey;
808 if (multiVerse == 2) {
813 lastBuf = (windowSize > 1) ? textBuf.
c_str() :
"";
818 case SEARCHTYPE_ENTRYATTR: {
821 AttributeTypeList::iterator i1Start, i1End;
822 AttributeList::iterator i2Start, i2End;
823 AttributeValue::iterator i3Start, i3End;
825 if ((words.size()) && (words[0].
length())) {
827 for (i1Start = entryAttribs.begin(); i1Start != entryAttribs.end(); ++i1Start) {
830 i1Start = entryAttribs.find(words[0]);
832 if (i1End != entryAttribs.end()) {
837 i1Start = entryAttribs.begin();
838 i1End = entryAttribs.end();
840 for (;i1Start != i1End; i1Start++) {
841 if ((words.size()>1) && (words[1].
length())) {
842 i2Start = i1Start->second.find(words[1]);
844 if (i2End != i1Start->second.end())
848 i2Start = i1Start->second.begin();
849 i2End = i1Start->second.end();
851 for (;i2Start != i2End; i2Start++) {
852 if ((words.size()>2) && (words[2].
length()) && (!includeComponents)) {
853 i3Start = i2Start->second.find(words[2]);
855 if (i3End != i2Start->second.end())
859 i3Start = i2Start->second.begin();
860 i3End = i2Start->second.end();
862 for (;i3Start != i3End; i3Start++) {
863 if ((words.size()>3) && (words[3].
length())) {
864 if (includeComponents) {
869 if (key != words[2])
continue;
871 if (flags & SEARCHFLAG_MATCHWHOLEENTRY) {
873 sres = (found) ? i3Start->second.c_str() : 0;
876 sres = ((flags &
REG_ICASE) ==
REG_ICASE) ?
stristr(i3Start->second.c_str(), words[3]) : strstr(i3Start->second.c_str(), words[3]);
879 *resultKey = *getKey();
881 listKey << *resultKey;
886 if (i3Start != i3End)
889 if (i2Start != i2End)
899 for (AttributeList::iterator it = words.begin(); it != words.end(); it++) {
900 int parts = atoi(it->second[
"PartCount"]);
903 for (
int i = 1; i <= parts; i++) {
906 AttributeValue::iterator li = it->second.find(key);
907 if (li != it->second.end()) {
908 if (i > 1) lemma +=
" ";
910 AttributeValue::iterator lci = it->second.find(key);
911 if (lci != it->second.end()) {
912 lemma += lci->second +
":";
917 li = it->second.find(key);
919 if (i == 1 && parts != 1 && li == it->second.end()) {
920 li = it->second.find(
"Morph");
922 if (li != it->second.end()) {
923 if (i > 1) morph +=
" ";
925 AttributeValue::iterator lci = it->second.find(key);
927 if (i == 1 && parts != 1 && lci == it->second.end()) {
928 lci = it->second.find(
"MorphClass");
930 if (lci != it->second.end()) {
931 morph += lci->second +
":";
937 while (window.size() < (unsigned)flags) {
944 *lastKey = *getKey();
950 if (searchType >= 0) {
952 std::locale::global(oldLocale);
953 #elif defined(USEICUREGEX)
971 setProcessEntryAttributes(savePEA);
974 (*percent)(100, percentUserData);
992 local = renderText(buf, len,
false);
993 return local.
c_str();
1003 FilterList::const_iterator first = getRenderFilters().begin();
1004 if (first != getRenderFilters().end()) {
1005 return (*first)->getHeader();
1018 return renderText((
const char *)0);
1039 bool savePEA = isProcessEntryAttributes();
1041 entryAttributes.clear();
1044 setProcessEntryAttributes(
false);
1051 SWBuf &tmpbuf = (buf) ? local : getRawEntryBuf();
1053 static const char *null =
"";
1056 unsigned long size = (len < 0) ? ((getEntrySize()<0) ? strlen(tmpbuf) : getEntrySize()) : len;
1058 key = this->getKey();
1060 optionFilter(tmpbuf, key);
1063 renderFilter(tmpbuf, key);
1064 encodingFilter(tmpbuf, key);
1066 else stripFilter(tmpbuf, key);
1073 setProcessEntryAttributes(savePEA);
1091 if (!key->isPersist()) {
1092 saveKey = createKey();
1099 retVal = renderText();
1122 if (!key->isPersist()) {
1123 saveKey = createKey();
1130 retVal = stripText();
1151 switch (bibFormat) {
1160 ConfigEntMap::iterator it = config->find(key);
1161 return (it != config->end()) ? it->second.c_str() : 0;
1166 this->config = config;
1180 SWBuf target = getConfigEntry(
"AbsoluteDataPath");
1195 #if defined USELUCENE || defined USEXAPIAN
1196 SWBuf target = getConfigEntry(
"AbsoluteDataPath");
1200 #if defined USEXAPIAN
1202 #elif defined USELUCENE
1203 const int MAX_CONV_SIZE = 1024 * 1024;
1207 if (status)
return -1;
1210 SWKey *searchKey = 0;
1217 for (OptionFilterList::iterator filter = optionFilters->begin(); filter != optionFilters->end(); filter++) {
1218 filterSettings.push_back((*filter)->getOptionValue());
1219 (*filter)->setOptionValue(*((*filter)->getOptionValues().begin()));
1221 if ( (!strcmp(
"Greek Accents", (*filter)->getOptionName())) ||
1222 (!strcmp(
"Hebrew Vowel Points", (*filter)->getOptionName())) ||
1223 (!strcmp(
"Arabic Vowel Points", (*filter)->getOptionName()))
1225 (*filter)->setOptionValue(
"Off");
1235 if (!key->isPersist()) {
1236 saveKey = createKey();
1241 searchKey = (key->isPersist())?key->
clone():0;
1247 bool includeKeyInSearch = getConfig().has(
"SearchOption",
"IncludeKeyInSearch");
1250 #if defined USEXAPIAN
1251 Xapian::WritableDatabase database(target.
c_str(), Xapian::DB_CREATE_OR_OPEN);
1252 Xapian::TermGenerator termGenerator;
1254 termGenerator.set_stemmer(Xapian::Stem(getLanguage()));
1257 #elif defined USELUCENE
1258 RAMDirectory *ramDir = 0;
1259 IndexWriter *coreWriter = 0;
1260 IndexWriter *fsWriter = 0;
1263 const TCHAR *stopWords[] = { 0 };
1264 standard::StandardAnalyzer *an =
new standard::StandardAnalyzer(stopWords);
1266 ramDir =
new RAMDirectory();
1267 coreWriter =
new IndexWriter(ramDir, an,
true);
1268 coreWriter->setMaxFieldLength(MAX_CONV_SIZE);
1285 long highIndex = key->getIndex();
1289 bool savePEA = isProcessEntryAttributes();
1290 setProcessEntryAttributes(
true);
1302 char err = popError();
1304 long mindex = key->getIndex();
1311 float per = (float)mindex / highIndex;
1313 per *= 93; per += 5;
1314 char newperc = (char)per;
1315 if (newperc > perc) {
1317 (*percent)(perc, percentUserData);
1321 const char *content = stripText();
1326 #if defined USEXAPIAN
1327 Xapian::Document doc;
1328 termGenerator.set_document(doc);
1329 #elif defined USELUCENE
1330 Document *doc =
new Document();
1334 if (content && *content) {
1339 AttributeTypeList::iterator words;
1340 AttributeList::iterator word;
1341 AttributeValue::iterator strongVal;
1342 AttributeValue::iterator morphVal;
1346 words = getEntryAttributes().find(
"Word");
1347 if (words != getEntryAttributes().end()) {
1348 for (word = words->second.begin();word != words->second.end(); word++) {
1349 int partCount = atoi(word->second[
"PartCount"]);
1350 if (!partCount) partCount = 1;
1351 for (
int i = 0; i < partCount; i++) {
1352 SWBuf tmp =
"Lemma";
1354 strongVal = word->second.find(tmp);
1355 if (strongVal != word->second.end()) {
1357 if (strongVal->second ==
"G3588") {
1358 if (word->second.find(
"Text") == word->second.end())
1361 strong.
append(strongVal->second);
1362 morph.
append(strongVal->second);
1364 SWBuf tmp =
"Morph";
1366 morphVal = word->second.find(tmp);
1367 if (morphVal != word->second.end()) {
1368 morph.
append(morphVal->second);
1377 #if defined USEXAPIAN
1378 doc.set_data(keyText.
c_str());
1379 #elif defined USELUCENE
1380 doc->add(*_CLNEW Field(_T(
"key"), (
wchar_t *)
utf8ToWChar(keyText).getRawData(), Field::STORE_YES | Field::INDEX_UNTOKENIZED));
1383 if (includeKeyInSearch) {
1387 content = c.
c_str();
1390 #if defined USEXAPIAN
1391 termGenerator.index_text(content);
1392 termGenerator.index_text(content, 1,
"C");
1393 #elif defined USELUCENE
1394 doc->add(*_CLNEW Field(_T(
"content"), (
wchar_t *)
utf8ToWChar(content).getRawData(), Field::STORE_NO | Field::INDEX_TOKENIZED));
1397 if (strong.
length() > 0) {
1398 #if defined USEXAPIAN
1399 termGenerator.index_text(strong.
c_str(), 1,
"L");
1400 termGenerator.index_text(morph.
c_str(), 1,
"M");
1401 #elif defined USELUCENE
1402 doc->add(*_CLNEW Field(_T(
"lemma"), (
wchar_t *)
utf8ToWChar(strong).getRawData(), Field::STORE_NO | Field::INDEX_TOKENIZED));
1403 doc->add(*_CLNEW Field(_T(
"morph"), (
wchar_t *)
utf8ToWChar(morph).getRawData(), Field::STORE_NO | Field::INDEX_TOKENIZED));
1415 *chapMax = *vkcheck;
1420 while ((!err) && (*vkcheck <= *chapMax)) {
1424 content = stripText();
1425 if (content && *content) {
1429 AttributeTypeList::iterator words;
1430 AttributeList::iterator word;
1431 AttributeValue::iterator strongVal;
1432 AttributeValue::iterator morphVal;
1434 words = getEntryAttributes().find(
"Word");
1435 if (words != getEntryAttributes().end()) {
1436 for (word = words->second.begin();word != words->second.end(); word++) {
1437 int partCount = atoi(word->second[
"PartCount"]);
1438 if (!partCount) partCount = 1;
1439 for (
int i = 0; i < partCount; i++) {
1440 SWBuf tmp =
"Lemma";
1442 strongVal = word->second.find(tmp);
1443 if (strongVal != word->second.end()) {
1445 if (strongVal->second ==
"G3588") {
1446 if (word->second.find(
"Text") == word->second.end())
1449 strong.
append(strongVal->second);
1450 morph.
append(strongVal->second);
1452 SWBuf tmp =
"Morph";
1454 morphVal = word->second.find(tmp);
1455 if (morphVal != word->second.end()) {
1456 morph.
append(morphVal->second);
1489 content = stripText();
1490 if (content && *content) {
1494 AttributeTypeList::iterator words;
1495 AttributeList::iterator word;
1496 AttributeValue::iterator strongVal;
1497 AttributeValue::iterator morphVal;
1499 words = getEntryAttributes().find(
"Word");
1500 if (words != getEntryAttributes().end()) {
1501 for (word = words->second.begin();word != words->second.end(); word++) {
1502 int partCount = atoi(word->second[
"PartCount"]);
1503 if (!partCount) partCount = 1;
1504 for (
int i = 0; i < partCount; i++) {
1505 SWBuf tmp =
"Lemma";
1507 strongVal = word->second.find(tmp);
1508 if (strongVal != word->second.end()) {
1510 if (strongVal->second ==
"G3588") {
1511 if (word->second.find(
"Text") == word->second.end())
1514 strong.
append(strongVal->second);
1515 morph.
append(strongVal->second);
1517 SWBuf tmp =
"Morph";
1519 morphVal = word->second.find(tmp);
1520 if (morphVal != word->second.end()) {
1521 morph.
append(morphVal->second);
1547 if (proxBuf.
length() > 0) {
1549 #if defined USEXAPIAN
1550 termGenerator.index_text(proxBuf.
c_str(), 1,
"P");
1551 #elif defined USELUCENE
1552 doc->add(*_CLNEW Field(_T(
"prox"), (
wchar_t *)
utf8ToWChar(proxBuf).getRawData(), Field::STORE_NO | Field::INDEX_TOKENIZED));
1556 if (proxLem.
length() > 0) {
1557 #if defined USEXAPIAN
1558 termGenerator.index_text(proxLem.
c_str(), 1,
"PL");
1559 termGenerator.index_text(proxMorph.
c_str(), 1,
"PM");
1560 #elif defined USELUCENE
1561 doc->add(*_CLNEW Field(_T(
"proxlem"), (
wchar_t *)
utf8ToWChar(proxLem).getRawData(), Field::STORE_NO | Field::INDEX_TOKENIZED) );
1562 doc->add(*_CLNEW Field(_T(
"proxmorph"), (
wchar_t *)
utf8ToWChar(proxMorph).getRawData(), Field::STORE_NO | Field::INDEX_TOKENIZED) );
1569 #if defined USEXAPIAN
1572 doc.add_boolean_term(idTerm.
c_str());
1573 database.replace_document(idTerm.
c_str(), doc);
1574 #elif defined USELUCENE
1575 coreWriter->addDocument(doc);
1578 #if defined USEXAPIAN
1579 #elif defined USELUCENE
1589 #if defined USEXAPIAN
1590 #elif defined USELUCENE
1591 coreWriter->close();
1594 d = FSDirectory::getDirectory(target.
c_str());
1596 if (IndexReader::indexExists(target.
c_str())) {
1598 d = FSDirectory::getDirectory(target.
c_str(),
false);
1600 if (IndexReader::isLocked(d)) {
1601 IndexReader::unlock(d);
1603 fsWriter =
new IndexWriter( d, an,
false);
1607 d = FSDirectory::getDirectory(target.
c_str(),
true);
1609 fsWriter =
new IndexWriter(d, an,
true);
1612 Directory *dirs[] = { ramDir, 0 };
1614 lucene::util::ConstValueArray< lucene::store::Directory *>dirsa(dirs, 1);
1615 fsWriter->addIndexes(dirsa);
1617 fsWriter->addIndexes(dirs);
1638 setProcessEntryAttributes(savePEA);
1641 StringList::iterator origVal = filterSettings.begin();
1642 for (OptionFilterList::iterator filter = optionFilters->begin(); filter != optionFilters->end(); filter++) {
1643 (*filter)->setOptionValue(*origVal++);
1658 OptionFilterList::iterator it;
1659 for (it = filters->begin(); it != filters->end(); it++) {
1660 (*it)->processText(buf, key,
this);
1670 FilterList::iterator it;
1671 for (it = filters->begin(); it != filters->end(); it++) {
1672 (*it)->processText(buf, key,
this);
1696 unsigned int to, from;
1697 char space = 0, cr = 0, realdata = 0, nlcnt = 0;
1699 for (to = from = 0; rawBuf[from]; from++) {
1700 switch (rawBuf[from]) {
1704 space = (cr) ? 0 : 1;
1727 if (rawBuf[from] !=
' ') {
1733 rawBuf[to++] = rawBuf[from];
1739 if ((rawBuf[to] == 10) || (rawBuf[to] ==
' '))
const char * getName() const
#define SWORD_NAMESPACE_START
SWBuf & appendFormatted(const char *format,...)
virtual SWKey * clone() const
static int removeDir(const char *targetDir)
unsigned long length() const
virtual bool hasSearchFramework()
static signed char createModule(const char *path)
static void prepText(SWBuf &buf)
const char * getType() const
static signed char existsDir(const char *ipath, const char *idirName=0)
virtual signed char createSearchFramework(void(*percent)(char, void *)=&nullPercent, void *percentUserData=0)
virtual SWBuf getBibliography(unsigned char bibFormat=BIB_BIBTEX) const
virtual void deleteSearchFramework()
virtual const char * getConfigEntry(const char *key) const
static SWLog * getSystemLog()
virtual void setPosition(SW_POSITION pos)
std::map< SWBuf, AttributeList, std::less< SWBuf > > AttributeTypeList
SWBuf wcharToUTF8(const wchar_t *buf)
static StdOutDisplay rawdisp
virtual void setEntry(const char *inbuf, long len=-1)
std::list< SWOptionFilter * > OptionFilterList
virtual SWKey * getKey() const
virtual char setKey(const SWKey *ikey)
virtual char getDirection() const
SWBuf utf8ToWChar(const char *buf)
bool endsWith(const SWBuf &postfix) const
int stricmp(const char *s1, const char *s2)
virtual signed char createSearchFramework(void(*percent)(char, void *)=&nullPercent, void *percentUserData=0)
virtual bool previousSibling()
virtual SWKey * clone() const
void setLowerBound(const VerseKey &lb)
virtual void clearBounds() const
virtual bool nextSibling()
void setPersist(bool ipersist)
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
virtual void linkEntry(const SWKey *sourceKey)
virtual const char * getRenderHeader() const
static const signed int SEARCHTYPE_MULTIWORD
virtual void deleteSearchFramework()
const char * stristr(const char *s1, const char *s2)
const char * c_str() const
std::list< SWBuf > StringList
SWBuf & append(const char *str, long max=-1)
SWModule(const char *imodname=0, const char *imoddesc=0, SWDisplay *idisp=0, const char *imodtype=0, SWTextEncoding encoding=ENC_UNKNOWN, SWTextDirection dir=DIRECTION_LTR, SWTextMarkup markup=FMT_UNKNOWN, const char *modlang=0)
virtual bool hasSearchFramework()
std::list< SWFilter * > FilterList
static const signed int SEARCHTYPE_REGEX
static const signed int SEARCHTYPE_EXTERNAL
virtual int getVerse() const
virtual void decrement(int steps=1)
virtual const char * getOSISRef() const
virtual void increment(int steps=1)
virtual void filterBuffer(OptionFilterList *filters, SWBuf &buf, const SWKey *key) const
#define SWDYNAMIC_CAST(className, object)
void setUpperBound(const VerseKey &ub)
virtual bool hasChildren()
static int createParent(const char *pName)
unsigned long size() const
const char * stripPrefix(char separator, bool endOfStringAsSeparator=false)
virtual ListKey & search(const char *istr, int searchType=0, int flags=0, SWKey *scope=0, bool *justCheckIfSupported=0, void(*percent)(char, void *)=&nullPercent, void *percentUserData=0)
const char * getDescription() const
unsigned long long SW_u64
virtual void setConfig(ConfigEntMap *config)
SWORD_NAMESPACE_START typedef multimapwithdefault< SWBuf, SWBuf, std::less< SWBuf > > ConfigEntMap
virtual const char * stripText(const char *buf=0, int len=-1)
virtual void setDisplay(SWDisplay *idisp)
void logError(const char *fmt,...) const
static const signed int SEARCHFLAG_MATCHWHOLEENTRY
virtual SWDisplay * getDisplay() const
#define SWORD_NAMESPACE_END
virtual char getError() const
virtual SWKey * createKey() const
SWBuf & setFormatted(const char *format,...)
std::map< SWBuf, AttributeValue, std::less< SWBuf > > AttributeList
virtual bool firstChild()
void setSize(unsigned long len)
static const signed int SEARCHTYPE_PHRASE
static FileMgr * getSystemFileMgr()
static const signed int SEARCHTYPE_ENTRYATTR
static const signed int SEARCHFLAG_STRICTBOUNDARIES