[cfe-commits] Possible contribution
Amer Agovic
agov0001 at umn.edu
Thu Oct 28 10:10:16 PDT 2010
Hi Clang Team,
I came across your project recently and found it very interesting.
Downloaded 2.8 and compiled it on Win32 using MinGW32 (TDM 4.5.0)
sitting in a non-standard location (c:/projects/bin/mingw).
Compile worked nicely and LLVM and CLANG work. However simple clang++ -v
tt.cpp shows that my CPATH env var is not added (for c or c++) and the
search dirs it uses are based on MinGW being in c:/mingw. After closer
inspection I have notice that for many targets hard coded paths are used
and I might have a better solution. If you agree please consider these
suggestions.
I would like to submit following code for possible consideration. If you
find it useful (and I think it is) please show me how to commit or one
of you can commit.
Please consider making following changes:
In file InitHeaderSearch.cpp
Change existing method: AddDefaultCIncludePaths
To this:
case llvm::Triple::MinGW64:
case llvm::Triple::MinGW32:
{
std::string base=GetMinGWBase();
AddPath(base+"/include", System, true, false, false);
}
break;
Change existing method:AddDefaultCPlusPlusIncludePaths(
to this:
case llvm::Triple::MinGW32:
{
std::string base=GetMinGWBase();
// Try gcc 4.5.0
AddMinGWCPlusPlusIncludePaths(base+"/lib/gcc", "mingw32", "4.5.0");
// Try gcc 4.4.0
AddMinGWCPlusPlusIncludePaths(base+"/lib/gcc", "mingw32", "4.4.0");
// Try gcc 4.3.0
AddMinGWCPlusPlusIncludePaths(base+"/lib/gcc", "mingw32", "4.3.0");
}
break;
Add following two methods in the same file:
/** Finds full path that contains provided substring within a
collection of paths.
* You can supply any Env var that holds path collections and extract
paths from it
* that match a partial string. The path returned is only up to the
part so even if a path
* is mentioned that is used for BIN folder you get the actual base path.
* Search is case insensitive and should work for Win and Unix paths.
If Mac and other
* platforms fail then what we consider path and name separators needs
to be generalized.
* Finds the first occurance of provided parial string.
* Path separators used: :;"'
* Name separators used: /\
* @param body string with collection of paths
* @param part partial string known to be present in our desired path base
* @return path base from last path separator until the first path
separator after part
*/
std::string FindPathBase(const std::string &body,const std::string &part){
// convert to lower case for case insesitive search
std::string lbody=body;
std::transform(lbody.begin(), lbody.end(), lbody.begin(),
(int(*)(int)) std::tolower);
std::string lpart=part;
std::transform(lpart.begin(), lpart.end(), lpart.begin(),
(int(*)(int)) std::tolower);
std::string ret="";
// locate first occurance
int plen=lpart.length();
int blen=lbody.length();
int state=-1; // when it reaches plen we got a match
int index=0;
for(;index<blen && state<(plen-1);index++){
char cl=lbody[index];
char cr=lpart[state+1];
if(cl=='\\') cl='/'; //translate name separator
if(cr=='\\') cr='/';
if(cl==cr){
state++; // advance fsm state
}else{
state=-1;// reset fsm state
}
}
if(state!=(plen-1)) return ret; // no luck
// index points to first occurance
// now we find teh start and end of the path
int end=index;
int begin=end-plen;
// look for end
while(end<blen){
char c=lbody[end];
// we try to sense a path or name delimiter and break there
if(c=='/' || c=='\\' || c==':' || c==';' || c=='"' || c=='\'')
break;
end++;
}
// look for begin
while(begin>0){
char c=lbody[begin-1];
// we try to sense a path separator
if((c==':' && lbody[begin]!='\\') || c==';' || c=='"' ||
c=='\'') break;
begin--;
}
// should have being and end with blen that contains part
ret=body.substr(begin,end-begin);
return ret;
}
/// Returns the base or root folder of MinGW
std::string GetMinGWBase(){
const char * path=getenv("PATH");
return FindPathBase(path,"/mingw");
}
More information about the cfe-commits
mailing list