// // This program is and should be standalone so that : // UNIX> c++ obuild_find.cxx // DOS> cl.exe obuild_find.cxx // builds at first shoot. // #include #include #include // From Lib : static bool Lib_System_getenv(const std::string&,std::string&); static std::string Lib_System_pathSeparator(); static std::string Lib_System_fileSeparator(); static std::vector Lib_smanip_words(const std::string&, const std::string&, bool = false); static bool Lib_smanip_match(const std::string&,const std::string&); static bool Lib_smanip_printf(std::string&,int,const char*,...); static bool Lib_dirmanip_entries(const std::string&, std::vector&,bool = true); static bool Lib_dirmanip_isAnEntry(const std::string&,const std::string&, bool&); static bool Lib_dirmanip_find(const std::vector& aPaths, const std::string& aPackage, const std::string& aVersion, std::string& aPath, std::string& aError); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// int main( int aArgc ,char** aArgv ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { std::vector args; {for(int index=0;index/obuild\n\ /usr/project2/pack2//obuild\n\ someone set the OBUILD_PATH variable under a csh flavoured\n\ shell with :\n\ csh> setenv OBUILD_PATH \"/work/project1:/usr/project2\"\n\ and under a sh flavoured shell with :\n\ sh> OBUILD_PATH=\"/work/project1:/usr/project2\"\n\ sh> export OBUILD_PATH\n\ Under DOS :\n\ DOS> SET OBUILD_PATH=C:\\work\\project1;D:\\usr\\project2\"\n\ \n\ "); printf("\n"); return EXIT_FAILURE; } std::string sep = Lib_System_pathSeparator(); std::vector paths = Lib_smanip_words(opath,sep); std::string path,serr; std::string dir; if(!Lib_dirmanip_find(paths,pack,vers,dir,serr)) { fprintf(stderr,"%s\n",serr.c_str()); printf("\n"); return EXIT_FAILURE; } if(dir=="") { printf("\n"); return EXIT_FAILURE; //Not found. } printf("%s\n",dir.c_str()); return EXIT_SUCCESS; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// bool Lib_System_getenv( const std::string& aString ,std::string& aValue ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { const char* env = ::getenv(aString.c_str()); if(env) { aValue = std::string(env?env:""); return true; } else { aValue = ""; return false; } } ////////////////////////////////////////////////////////////////////////////// std::string Lib_System_fileSeparator( ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { #ifdef WIN32 return "\\"; #else return "/"; #endif } ////////////////////////////////////////////////////////////////////////////// std::string Lib_System_pathSeparator( ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { #ifdef WIN32 return ";"; #else return ":"; #endif } ////////////////////////////////////////////////////////////////////////////// #include /* strcpy */ #include /* malloc,free */ #define Lib_strdup(str) ((str) != NULL ? (::strcpy((char*)::malloc((unsigned)::strlen(str) + 1), str)) : (char*)NULL) #define Lib_strdel(str) {if((str)!=NULL) {::free(str);str=NULL;}} ////////////////////////////////////////////////////////////////////////////// bool Lib_smanip_match( const std::string& aString ,const std::string& aPattern ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { int lpattern = aPattern.length(); int lstring = aString.length(); if ((lpattern==0)&&(lstring==0)) return true; if ((lpattern==0)&&(lstring!=0)) return true; if ((lpattern!=0)&&(lstring==0)) return false; // pattern is * : if(aPattern=="*") return true; int wcount = 0; int count; for(count=0;count=wmax) { words = (char**)::realloc(words,(wmax+PACKET) * sizeof(char*)); if(words==NULL) { Lib_strdel(s); return false; } wmax += PACKET; } words[wnumber] = token; wnumber++; } token = pos + 1; } else { // last word : if(*token!='\0') { if(wnumber>=wmax) { words = (char**)::realloc(words,(wmax+PACKET) * sizeof(char*)); if(words==NULL) { Lib_strdel(s); return false; } wmax += PACKET; } words[wnumber] = token; wnumber++; } break; } } // check that at least one word is not empty : bool ok = false; for(count=0;count0) { char* pos; if(count==0) { if(aPattern[0]!='*') { // Begin of pattern (words[0]) and aString must match : if(::strncmp(token,words[count],lword)!=0) { match = false; // Different. break; } token = token + lword; continue; } } pos = ::strstr (token,words[count]); if(!pos) { match = false; break; } if((count==(wnumber-1)) && (aPattern[lpattern-1]!='*') ) { // Last word : if(::strcmp(aString.c_str()+lstring-lword,words[count])!=0) match = false; // Compare last word and end of aString. break; } else { token = pos + lword; } } } Lib_strdel(s); if(words) ::free(words); return match; } ////////////////////////////////////////////////////////////////////////////// std::vector Lib_smanip_words( const std::string& aString ,const std::string& aLimiter ,bool aTakeEmpty // false ) ////////////////////////////////////////////////////////////////////////////// // If aLimiter is for exa "|" and for "xxx||xxx" : // - aTakeEmpty false : {"xxx","xxx"} will be created (and NOT {"xxx","","xxx"}). // - aTakeEmpty true : {"xxx","","xxx"} will be created. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { std::vector words; if(aString=="") return words; std::string::size_type lim = (aTakeEmpty?0:1); if(aLimiter=="") { words.push_back(aString); } else { std::string::size_type l = aString.length(); std::string::size_type llimiter = aLimiter.length(); std::string::size_type pos = 0; while(1) { std::string::size_type index = aString.find(aLimiter,pos); if(index==std::string::npos){ // Last word. if((l-pos)>=lim) words.push_back(aString.substr(pos,l-pos)); break; } else { // abcxxxef // 0 3 67 if((index-pos)>=lim) words.push_back(aString.substr(pos,index-pos)); pos = index + llimiter; } } } return words; } #include ////////////////////////////////////////////////////////////////////////////// bool Lib_smanip_printf( std::string& aString ,int aLength ,const char* aFormat ,... ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { aString = ""; if(aLength<0) return false; if(!aFormat) return false; char* s = new char[aLength+1]; if(!s) return false; s[aLength] = '\0'; va_list args; va_start (args,aFormat); vsprintf (s,aFormat,args); va_end (args); if(s[aLength]!='\0') { delete [] s; return false; } aString = s; delete [] s; return true; } #ifdef WIN32 #include #include #else //UNIX #include #if defined(_POSIX_SOURCE) #define REAL_DIR_ENTRY(dp) 1 #else #define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) #endif #include #endif #include ////////////////////////////////////////////////////////////////////////////// bool Lib_dirmanip_entries( const std::string& aPath ,std::vector& aList ,bool aFullPath ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { aList.clear(); struct stat finfo; if (::stat(aPath.c_str(),&finfo) < 0) return false; #ifdef WIN32 if (!(finfo.st_mode & S_IFDIR)) return false; std::string entry = aPath; if (!(entry[entry.size()] == '/' || entry[entry.size()] == '\\' )) entry += "\\"; entry += "*"; WIN32_FIND_DATA findFileData; HANDLE dir = ::FindFirstFile(entry.c_str(),&findFileData); if(dir == INVALID_HANDLE_VALUE) return false; // Get file names : for (;;) { if(!::FindNextFile(dir,&findFileData)) break; std::string name = (const char*)findFileData.cFileName; if(aFullPath) aList.push_back(aPath+"\\"+name); else aList.push_back(name); } ::FindClose(dir); #else if (!S_ISDIR(finfo.st_mode)) return false; DIR* dir = ::opendir(aPath.c_str()); if(!dir) return false; // Get file names : for (;;) { struct dirent* dp = ::readdir(dir); //struct direct* dp; if (dp==NULL) break; if (REAL_DIR_ENTRY(dp)) { std::string name = dp->d_name; // Be sure we can work on the file : std::string fname = aPath+"/"+name; if (::stat(fname.c_str(),&finfo) < 0) continue; if(aFullPath) aList.push_back(fname); else aList.push_back(name); } } ::closedir(dir); #endif return true; } ////////////////////////////////////////////////////////////////////////////// bool Lib_dirmanip_isAnEntry( const std::string& aPath ,const std::string& aName ,bool& aFound ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { aFound = false; struct stat finfo; if (::stat(aPath.c_str(),&finfo) < 0) return false; #ifdef WIN32 if (!(finfo.st_mode & S_IFDIR)) return false; std::string entry = aPath; if (!(entry[entry.size()] == '/' || entry[entry.size()] == '\\' )) entry += "\\"; entry += "*"; WIN32_FIND_DATA findFileData; HANDLE dir = ::FindFirstFile(entry.c_str(),&findFileData); if(dir == INVALID_HANDLE_VALUE) return false; // Get file names : for (;;) { if(!::FindNextFile(dir,&findFileData)) break; std::string name = (const char*)findFileData.cFileName; if(name==aName) { aFound = true; ::FindClose(dir); return true; } } ::FindClose(dir); #else if (!S_ISDIR(finfo.st_mode)) return false; DIR* dir = ::opendir(aPath.c_str()); if(!dir) return false; // Get file names : for (;;) { struct dirent* dp = ::readdir(dir); //struct direct* dp; if (dp==NULL) break; if (REAL_DIR_ENTRY(dp)) { std::string name = dp->d_name; if(name==aName) { aFound = true; ::closedir(dir); return true; } } } ::closedir(dir); #endif return true; } ////////////////////////////////////////////////////////////////////////////// bool Lib_dirmanip_find( const std::vector& aPaths ,const std::string& aPackage ,const std::string& aVersion ,std::string& aPath ,std::string& aError ) ////////////////////////////////////////////////////////////////////////////// // aVersion could be empty and can contain woldcards. // The list of paths is searched first to last. // return true and aPath="" mean not found. // return false : something went wrong in directory manipulation. // aError contains then an error message. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { if(aPackage=="") { aError = "Lib::dirmanip::find : empty package name."; return false; } std::string sep = Lib_System_fileSeparator(); std::string::size_type star = aVersion.find('*'); bool vers_wildcard = (star==std::string::npos?false:true); unsigned int pathn = aPaths.size(); //fprintf(stderr,"obuild_find : number of path %d\n",pathn); for(unsigned int pathi=0;pathi files; if(Lib_dirmanip_entries(dir,files,false)) { unsigned int number = files.size(); for(unsigned int index=0;index