From a197cd7925c5a9a996d00c5eaddc8b09dfb154e4 Mon Sep 17 00:00:00 2001 From: AquariusPower Date: Fri, 5 Jun 2020 01:13:20 -0300 Subject: [PATCH 1/5] NOT WORKING HERE: auto store item in container (some code is missing to copy from SomeFixes1234 ...) --- Main/Include/game.h | 2 ++ Main/Include/ivandef.h | 1 + Main/Source/cmdcraft.cpp | 22 ++++++++++++++-- Main/Source/command.cpp | 5 +++- Main/Source/game.cpp | 57 ++++++++++++++++++++++++++++++++++++++++ Main/Source/iconf.cpp | 7 ++++- Main/Source/item.cpp | 2 +- 7 files changed, 91 insertions(+), 5 deletions(-) diff --git a/Main/Include/game.h b/Main/Include/game.h index 2c04481bf..3c19168b5 100644 --- a/Main/Include/game.h +++ b/Main/Include/game.h @@ -181,6 +181,8 @@ class game static void UpdateSRegionsXBRZ(bool bIsXBRZScale); static void RegionSilhouetteEnable(bool b); static void RegionListItemEnable(bool b); + static cchar* StoreMatchNameKey(item* it,bool bUnarticled=false); + static void AutoStoreItemInContainer(item* itToStore,character* C); static void UpdatePosAroundForXBRZ(v2 ScreenPos); static void SRegionAroundDisable(); static void SRegionAroundAllow(); diff --git a/Main/Include/ivandef.h b/Main/Include/ivandef.h index a06028c4a..165f31f2d 100644 --- a/Main/Include/ivandef.h +++ b/Main/Include/ivandef.h @@ -240,6 +240,7 @@ const name##prototype name::ProtoType #define INDEFINE_BIT 4 #define INDEFINITE 6 #define STRIPPED 8 +#define UNLABELED 16 #define TRANSPARENT_COLOR 0xF81F // pink diff --git a/Main/Source/cmdcraft.cpp b/Main/Source/cmdcraft.cpp index fb7416243..c7babcc98 100644 --- a/Main/Source/cmdcraft.cpp +++ b/Main/Source/cmdcraft.cpp @@ -98,10 +98,25 @@ bool craftcore::EmptyContentsIfPossible(recipedata& rpd,item* itContainer, bool return bEmptied; } +/** + * Why this is important? + * + * Because if the item remain on slot, and 1 turn has not passed, + * what may happpen on crafting code in case user gives up on crafting action, + * it will provide inconsistent inventory contents (something that was sent to hell + * but is still on inventory as the turn has not passed to properly send it to hell). + * + * If all the above is correctly understood as "it is how thing work", + * then crafting should be fixed to always pass one turn even if user giveup? + * But that doesnt looks good, giveup = cancel, should not pass a turn at all. + * + * This shall be used for anything related to crafting until something better is coded. + */ void craftcore::SendToHellSafely(item* it) { it->RemoveFromSlot(); //just in case to prevent problems later... like crashing elsewhere!!! - it->SendToHell(); DBG3("SentToHell",it,it->GetID());//,lumpAtInv,lumpAtInv->GetID()); + it->SendToHell(); //DBG3("SentToHell",it,it->GetID());//,lumpAtInv,lumpAtInv->GetID()); + DBGITEM(it,"SentToHell:Safely"); // **rit=NULL; } @@ -1902,7 +1917,10 @@ struct srpInspect : public recipe{ //TODO this is instantaneous, should take tim material* matM = it0->GetMainMaterial(); material* matS = it0->GetSecondaryMaterial(); festring fs; - fs<GetName(DEFINITE)<<" is made of "; + fs << it0->GetName(DEFINITE) + << " (" << game::StoreMatchNameKey(it0) << " or " //used by auto-store items on containers, so here is the place to determine it's value + << game::StoreMatchNameKey(it0,true) << ")" + << " is made of "; if(matM)fs<GetName(UNARTICLED); if(matS){ if(matM)fs<<" and "; //actually, there is only 2nd material if there is main but anyway... diff --git a/Main/Source/command.cpp b/Main/Source/command.cpp index 276c65a97..c07e8c310 100644 --- a/Main/Source/command.cpp +++ b/Main/Source/command.cpp @@ -680,6 +680,8 @@ truth commandsystem::PickUp(character* Char) if(game::IsAutoPickupMatch(PileVector[0][c]->GetName(DEFINITE))){ PileVector[0][c]->ClearTag('d'); //intentionally drop tag dismissed for autopickup regex match } + + game::AutoStoreItemInContainer(PileVector[0][c],Char); } ADD_MESSAGE("%s picked up.", PileVector[0][0]->GetName(INDEFINITE, Amount).CStr()); @@ -1139,7 +1141,8 @@ truth commandsystem::WhatToEngrave(character* Char,bool bEngraveMapNote,v2 v2Eng break; festring What = ToAddLabel[0]->GetLabel(); - if(game::StringQuestion(What, CONST_S("What would you like to inscribe on this item?"), WHITE, 0, 20, true) == NORMAL_EXIT) + int iMaxChars=150; // item labels can contain user custom hints to let the algorithm use these to perform automatic actions + if(game::StringQuestion(What, CONST_S("What would you like to inscribe on this item?"), WHITE, 0, iMaxChars, true) == NORMAL_EXIT) for(int i=0;iSetLabel(What); } diff --git a/Main/Source/game.cpp b/Main/Source/game.cpp index 0fc6aa59e..9f68acab9 100644 --- a/Main/Source/game.cpp +++ b/Main/Source/game.cpp @@ -1323,6 +1323,62 @@ int game::RotateMapNotes() return iMapNotesRotation; } +/** + * + * @param it + * @param bUnarticled if false is GetNameSingular() + * @return + */ +cchar* game::StoreMatchNameKey(item* it,bool bUnarticled) +{ + static festring fsRet,fsSpace=" ",fsEmpty=""; + static cchar* cToken="+"; + + fsRet=""; + fsRet<GetName(UNARTICLED|UNLABELED); + else + fsRet<GetNameSingular()<IsPlayer()) + return; + + static itemvector vit;vit.clear(); + C->GetStack()->FillItemVector(vit); + static festring fsMatchGeneric,fsMatchPrecise; + fsMatchGeneric=StoreMatchNameKey(itToStore); + fsMatchPrecise=StoreMatchNameKey(itToStore,true); + DBG2(fsMatchGeneric.CStr(),fsMatchPrecise.CStr()); + for(int i=0;i(vit[i]); + if(itc){ + long lRemainingVol = itc->GetStorageVolume() - itc->GetContained()->GetVolume(); + DBG3(lRemainingVol,itToStore->GetVolume(),itc->GetLabel().CStr()); + if(lRemainingVolGetVolume()) + continue; + + if( + itc->GetLabel().Find(fsMatchGeneric)!=festring::NPos || + itc->GetLabel().Find(fsMatchPrecise)!=festring::NPos + ){ + itToStore->RemoveFromSlot(); + itc->GetContained()->AddItem(itToStore); + ADD_MESSAGE("%s was safely stored in %s",itToStore->GetName(DEFINITE).CStr(),itc->GetName(DEFINITE).CStr()); + break; + } + } + } +} + std::vector afsAutoPickupMatch; pcre *reAutoPickup=NULL; void game::UpdateAutoPickUpMatching() //simple matching syntax @@ -1397,6 +1453,7 @@ int game::CheckAutoPickup(square* sqr) if(b){ it->MoveTo(PLAYER->GetStack()); ADD_MESSAGE("%s picked up.", it->GetName(INDEFINITE).CStr()); + AutoStoreItemInContainer(it,PLAYER); iTot++; } } diff --git a/Main/Source/iconf.cpp b/Main/Source/iconf.cpp index 7df4c94a5..bde7e92cc 100644 --- a/Main/Source/iconf.cpp +++ b/Main/Source/iconf.cpp @@ -51,7 +51,12 @@ stringoption ivanconfig::SelectedBkgColor("SelectedBkgColor", &SelectedBkgColorChanger); stringoption ivanconfig::AutoPickUpMatching("AutoPickUpMatching", "Auto pick up regex", - "Automatically pick up items according to a regular expression. To disable something, you can invalidate it with '_' without removing it from the expression (eg. '_dagger'). To disable everything at once, begin this config option with '!'. Due to current constraints on length of options, editing is easier to do externally for now.", //TODO if multiline text editing is implemented, remove the last help statement. + "Automatically pick up items according to a regular expression.\n" + " To disable something, you can invalidate it with '_' without removing it from the expression (eg. '_dagger').\n" + " To disable everything at once, begin this config option with '!'.\n" + " Containers inscribed with eg. '+key+ring+scroll' will auto store such items,\n" + " and you can determine what to inscribe by craft/inspecting the items.\n" + " Due to current constraints on length of options, editing is easier to do externally for now.", //TODO if multiline text editing is implemented, remove the last help statement. "!((book|can|dagger|grenade|horn of|kiwi|key|ring|scroll|wand|whistle)|^(?:(?!(broken|empty)).)*(bottle|vial)|sol stone)", &configsystem::NormalStringDisplayer, &AutoPickUpMatchingChangeInterface, diff --git a/Main/Source/item.cpp b/Main/Source/item.cpp index e2fa013cb..972be7a5d 100644 --- a/Main/Source/item.cpp +++ b/Main/Source/item.cpp @@ -530,7 +530,7 @@ void item::AddName(festring& Name, int Case) const { object::AddName(Name,Case); - if(label.GetSize()) + if(!(Case&UNLABELED) && label.GetSize()) Name << " inscribed " << label; } From 8159c3b50d841349fa604afc2cbdf8206c500c10 Mon Sep 17 00:00:00 2001 From: AquariusPower Date: Sun, 7 Jun 2020 22:08:58 -0300 Subject: [PATCH 2/5] auto store item in container is working! uses pcre regex (pcre compile code unified at festring); works for normal pickup and auto-pickup; Inscribe containers with a valid regex for it to work! --- FeLib/Include/festring.h | 2 ++ FeLib/Source/festring.cpp | 51 ++++++++++++++++++++++++-- Main/Include/game.h | 2 +- Main/Include/miscitem.h | 5 +++ Main/Source/game.cpp | 76 ++++++++++++--------------------------- Main/Source/iconf.cpp | 2 +- Main/Source/miscitem.cpp | 57 ++++++++++++++++++++++------- 7 files changed, 126 insertions(+), 69 deletions(-) diff --git a/FeLib/Include/festring.h b/FeLib/Include/festring.h index 3c1af2a54..5b4d93895 100644 --- a/FeLib/Include/festring.h +++ b/FeLib/Include/festring.h @@ -15,6 +15,7 @@ #include #include +#include #include "felibdef.h" @@ -119,6 +120,7 @@ class festring void ExtractWord(festring&); long GetCheckSum() const; void EnsureOwnsData(bool = false); + static pcre* CompilePCRE(pcre *pcreExistingRegexWorker, cfestring &fsPattern, festring *pfsErrorMsg=NULL); private: static void InstallIntegerMap(); static void DeInstallIntegerMap(); diff --git a/FeLib/Source/festring.cpp b/FeLib/Source/festring.cpp index 6d26138ce..ba7ee6495 100644 --- a/FeLib/Source/festring.cpp +++ b/FeLib/Source/festring.cpp @@ -13,6 +13,7 @@ #include #include #include + #include "festring.h" #include "allocate.h" #include "error.h" @@ -713,8 +714,13 @@ festring::sizetype festring::IgnoreCaseFind(cfestring& Where, return NPos; } -/* Replaces all occurances of What in Where after Begin with With */ - +/** + * Replaces all occurances of What in Where after Begin with With + * @param Where + * @param What + * @param With + * @param Begin + */ void festring::SearchAndReplace(festring& Where, cfestring& What, cfestring& With, sizetype Begin) { @@ -907,3 +913,44 @@ void festring::EnsureOwnsData(bool Unique) CreateOwnData(Data, Size); } } + +/** + * + * @param pcreExistingRegexWorker it has to be freed if was already set + * @param fsPattern + * @param bWarnOnError + * @return + */ +pcre* festring::CompilePCRE(pcre *pcreExistingRegexWorker, cfestring &fsPattern, festring *pfsErrorMsg) +{ + if(pcreExistingRegexWorker) + pcre_free(pcreExistingRegexWorker); + + if(fsPattern.IsEmpty()) + return NULL; + + const char *errMsg; + int iErrOffset; + pcreExistingRegexWorker = pcre_compile( + fsPattern.CStr(), + 0, // no options + &errMsg, &iErrOffset, + 0 // default char tables + ); + + if (!pcreExistingRegexWorker){ + festring fsErr; + fsErr<<"Regex validation failed, if ignored will just not work at all.\n" + <) diff --git a/Main/Source/game.cpp b/Main/Source/game.cpp index 9f68acab9..dfc66379d 100644 --- a/Main/Source/game.cpp +++ b/Main/Source/game.cpp @@ -1353,10 +1353,6 @@ void game::AutoStoreItemInContainer(item* itToStore,character* C) static itemvector vit;vit.clear(); C->GetStack()->FillItemVector(vit); - static festring fsMatchGeneric,fsMatchPrecise; - fsMatchGeneric=StoreMatchNameKey(itToStore); - fsMatchPrecise=StoreMatchNameKey(itToStore,true); - DBG2(fsMatchGeneric.CStr(),fsMatchPrecise.CStr()); for(int i=0;i(vit[i]); @@ -1366,10 +1362,7 @@ void game::AutoStoreItemInContainer(item* itToStore,character* C) if(lRemainingVolGetVolume()) continue; - if( - itc->GetLabel().Find(fsMatchGeneric)!=festring::NPos || - itc->GetLabel().Find(fsMatchPrecise)!=festring::NPos - ){ + if(itc->IsAutoStoreMatch(itToStore->GetName(DEFINITE))){ itToStore->RemoveFromSlot(); itc->GetContained()->AddItem(itToStore); ADD_MESSAGE("%s was safely stored in %s",itToStore->GetName(DEFINITE).CStr(),itc->GetName(DEFINITE).CStr()); @@ -1379,40 +1372,21 @@ void game::AutoStoreItemInContainer(item* itToStore,character* C) } } -std::vector afsAutoPickupMatch; pcre *reAutoPickup=NULL; -void game::UpdateAutoPickUpMatching() //simple matching syntax +void game::UpdateAutoPickUpRegex() { - afsAutoPickupMatch.clear(); - - bool bSimple=false; - if(bSimple){ //TODO just drop the simple code? or start the string with something to let it be used instead of regex? tho is cool to let ppl learn regex :) - if(ivanconfig::GetAutoPickUpMatching().GetSize()==0 || ivanconfig::GetAutoPickUpMatching()[0]=='!')return; - - std::stringstream ss(ivanconfig::GetAutoPickUpMatching().CStr()); - std::string match; - while(std::getline(ss,match,'|')) - afsAutoPickupMatch.push_back(festring(match.c_str())); - }else{ - //TODO test regex about: ignoring broken lanterns and bottles, ignore sticks on fire but pickup scrolls on fire - // static bool bDummyInit = [](){reAutoPickup=NULL;return true;}(); - const char *errMsg; - int iErrOffset; - if(reAutoPickup)pcre_free(reAutoPickup); - reAutoPickup = pcre_compile( - ivanconfig::GetAutoPickUpMatching().CStr(), //pattern - 0, //no options - &errMsg, &iErrOffset, - 0); // default char tables - if (!reAutoPickup){ - std::vector afsFullProblems; - afsFullProblems.push_back(festring(errMsg)); - afsFullProblems.push_back(festring()+"offset:"+iErrOffset); - bool bDummy = iosystem::AlertConfirmMsg("regex validation failed, if ignored will just not work at all",afsFullProblems,false); - } + //TODO test regex about: ignoring broken lanterns and bottles, ignore sticks on fire but pickup scrolls on fire + festring fsErr; + reAutoPickup = festring::CompilePCRE(reAutoPickup,ivanconfig::GetAutoPickUpMatching(),&fsErr); + if(!fsErr.IsEmpty()){ + std::vector afsFullProblems; + afsFullProblems.push_back(fsErr); + bool bDummy = iosystem::AlertConfirmMsg("Failed updating auto-pickup regex.",afsFullProblems,false); } } bool game::IsAutoPickupMatch(cfestring fsName) { + if(!reAutoPickup) + return false; return pcre_exec(reAutoPickup, 0, fsName.CStr(), fsName.GetSize(), 0, 0, NULL, 0) >= 0; } int game::CheckAutoPickup(square* sqr) @@ -1425,30 +1399,26 @@ int game::CheckAutoPickup(square* sqr) lsquare* lsqr = (lsquare*)sqr; - static bool bDummyInit = [](){UpdateAutoPickUpMatching();return true;}(); + static bool bDummyInit = [](){UpdateAutoPickUpRegex();return true;}(); itemvector iv; lsqr->GetStack()->FillItemVector(iv); int iTot=0; for(int i=0;iGetRoom() && it->GetRoom()->GetMaster())continue; //not from owned rooms - if(it->GetSpoilLevel()>0)continue; + if(it->GetSpoilLevel()>0)continue; //just a guess no one auto-wants it + bool b=false; if(!b && ivanconfig::IsAutoPickupThrownItems() && it->HasTag('t') )b=true; //was thrown - if(!b && !it->HasTag('d')){ - if(reAutoPickup!=NULL){ - if(IsAutoPickupMatch(it->GetName(DEFINITE))){ - b=true; - } - } - } - if(!b){ //TODO use player's perception, in case of a stack of items, to allow random pickup based on item volume (size) where smaller = harder like tiny rings, to compensate for the easiness of not losing a round having to pick up the item interactively - for(int i=0;iGetNameSingular().Find(afsAutoPickupMatch[i].CStr(),0) != festring::NPos){ - b=true; - break; //each simple match loop - } - } + if(!b && !it->HasTag('d')){ //was NOT intentionally dropped (dropping adds such tag) + /** + * TODO ? + * Use player's perception, in case of a stack of items, + * to allow random pickup based on item volume (size) where smaller = harder like tiny rings, + * to compensate for the easiness of not losing a round having to pick up the item interactively. + * But it may just be annnoying... + */ + b = IsAutoPickupMatch(it->GetName(DEFINITE)); } if(b){ it->MoveTo(PLAYER->GetStack()); diff --git a/Main/Source/iconf.cpp b/Main/Source/iconf.cpp index bde7e92cc..5d1c6b052 100644 --- a/Main/Source/iconf.cpp +++ b/Main/Source/iconf.cpp @@ -850,7 +850,7 @@ void ivanconfig::AutoPickUpMatchingChanger(stringoption* O, cfestring& What) if(O!=NULL){ O->Value.Empty(); O->Value<TakeSomethingFrom(Opener, GetName(DEFINITE)); + Success = Stk->TakeSomethingFrom(Opener, fsName); break; case 'p': case 'P': - Success = GetContained()->PutSomethingIn(Opener, GetName(DEFINITE), GetStorageVolume(), GetID()); + Success = Stk->PutSomethingIn(Opener, fsName, volume, ID); break; default: return false; @@ -1404,10 +1400,23 @@ truth itemcontainer::Open(character* Opener) if(Success) Opener->DexterityAction(Opener->OpenMultiplier() * 5); - + return Success; } +/* Returns true if container opens fine else false */ + +truth itemcontainer::Open(character* Opener) +{ + if(IsLocked()) + { + ADD_MESSAGE("%s seems to be locked.", CHAR_NAME(DEFINITE)); + return false; + } + + return OpenGeneric(Opener,GetContained(),GetName(DEFINITE),GetStorageVolume(),ID); +} + void itemcontainer::Save(outputfile& SaveFile) const { lockableitem::Save(SaveFile); @@ -1769,9 +1778,33 @@ materialcontainer::materialcontainer(const materialcontainer& MC) : mybase(MC) itemcontainer::itemcontainer(const itemcontainer& Container) : mybase(Container) { Contained = new stack(0, this, HIDDEN); + pcreAutoStoreRegex = festring::CompilePCRE(NULL,Container.GetLabel()); + bLazyInitPcre=true; + CalculateAll(); } +void itemcontainer::SetLabel(cfestring& What) +{ + item::SetLabel(What); + pcreAutoStoreRegex = festring::CompilePCRE(pcreAutoStoreRegex,GetLabel()); +} + +truth itemcontainer::IsAutoStoreMatch(cfestring fs) { + if(bLazyInitPcre){ + if(!pcreAutoStoreRegex && !GetLabel().IsEmpty()){ + pcreAutoStoreRegex = festring::CompilePCRE(pcreAutoStoreRegex,GetLabel()); + DBGEXEC( if(!pcreAutoStoreRegex){ DBG2("InvalidRegex",GetLabel().CStr()); } ); + } + bLazyInitPcre=false; + } + + if(!pcreAutoStoreRegex) + return false; + + return pcre_exec(pcreAutoStoreRegex, 0, fs.CStr(), fs.GetSize(), 0, 0, NULL, 0) >= 0; +} + oillamp::oillamp(const oillamp& Lamp) : mybase(Lamp), InhabitedByGenie(false) { } From 809cbe53d2895784b9e9846a196f84662cc9d300 Mon Sep 17 00:00:00 2001 From: AquariusPower Date: Sun, 7 Jun 2020 22:16:12 -0300 Subject: [PATCH 3/5] missing #include --- FeLib/Source/festring.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/FeLib/Source/festring.cpp b/FeLib/Source/festring.cpp index ba7ee6495..2c7fb31a2 100644 --- a/FeLib/Source/festring.cpp +++ b/FeLib/Source/festring.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include "festring.h" #include "allocate.h" From d59e52123c70f8c784667aa350a371004ba6b5e1 Mon Sep 17 00:00:00 2001 From: AquariusPower Date: Sun, 7 Jun 2020 22:36:50 -0300 Subject: [PATCH 4/5] commented helpful output as travis-ci wont compile it even with: #include --- FeLib/Source/festring.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FeLib/Source/festring.cpp b/FeLib/Source/festring.cpp index 2c7fb31a2..bece51dc3 100644 --- a/FeLib/Source/festring.cpp +++ b/FeLib/Source/festring.cpp @@ -946,8 +946,7 @@ pcre* festring::CompilePCRE(pcre *pcreExistingRegexWorker, cfestring &fsPattern, <<"offset:"< Date: Sun, 7 Jun 2020 23:00:28 -0300 Subject: [PATCH 5/5] pcre for igor and mihail --- igor/CMakeLists.txt | 18 ++++++++++++++++-- mihail/CMakeLists.txt | 18 ++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/igor/CMakeLists.txt b/igor/CMakeLists.txt index b1c0b73bb..810a277ab 100644 --- a/igor/CMakeLists.txt +++ b/igor/CMakeLists.txt @@ -1,5 +1,19 @@ set(IGOR_VERSION 1.203) +include(FindPkgConfig) +if(PKG_CONFIG_FOUND) + pkg_check_modules(PCRE libpcre) + set(PCRE_LIBRARIES ${PCRE_LDFLAGS}) +endif() +if(NOT PCRE_FOUND) + if(MSVC) + find_path(PCRE_INCLUDE_DIR NAMES pcre.h) + find_library(PCRE_LIBRARY pcre) + endif() + find_package(PCRE REQUIRED) + add_definitions(${PCRE_DEFINITIONS}) +endif() + add_executable(igor EXCLUDE_FROM_ALL Source/igor.cpp) -target_include_directories(igor PUBLIC ../Felib/Include) -target_link_libraries(igor FeLib xbrzscale) +target_include_directories(igor PUBLIC ../Felib/Include ${PCRE_INCLUDE_DIRS}) +target_link_libraries(igor FeLib xbrzscale ${PCRE_LIBRARIES}) diff --git a/mihail/CMakeLists.txt b/mihail/CMakeLists.txt index e7c952b1e..c037ff7c6 100644 --- a/mihail/CMakeLists.txt +++ b/mihail/CMakeLists.txt @@ -1,5 +1,19 @@ set(MIHAIL_VERSION 0.91) +include(FindPkgConfig) +if(PKG_CONFIG_FOUND) + pkg_check_modules(PCRE libpcre) + set(PCRE_LIBRARIES ${PCRE_LDFLAGS}) +endif() +if(NOT PCRE_FOUND) + if(MSVC) + find_path(PCRE_INCLUDE_DIR NAMES pcre.h) + find_library(PCRE_LIBRARY pcre) + endif() + find_package(PCRE REQUIRED) + add_definitions(${PCRE_DEFINITIONS}) +endif() + add_executable(mihail EXCLUDE_FROM_ALL Source/mihail.cpp) -target_include_directories(mihail PUBLIC ../Felib/Include) -target_link_libraries(mihail FeLib xbrzscale) +target_include_directories(mihail PUBLIC ../Felib/Include ${PCRE_INCLUDE_DIRS}) +target_link_libraries(mihail FeLib xbrzscale ${PCRE_LIBRARIES})