// // This program is and should be standalone so that : // UNIX> c++ obuild_platform.cxx // DOS> cl.exe obuild_platform.cxx // builds at first shoot. // // Applying : // OS> obuild_platform // prints on stdout the string : // --. // For example : // Darwin-i386-gcc_401 // // It can be used too with : // OS> obuild_platform // In this case it prints on stdout "yes" or "no" // according the results of the evaluation of the expression // by using the local kind of os, processor. // The syntax of the expression is : // // not // [and,or] // With primary being : // // for which is compared to the os, or : // [os,processor][=,!=] // For example : // Darwin // not Darwin // not os=UNIX // os=UNIX and processor!=intel // // Then, for example on a MacIntel : // MacIntel> obuild_platform 'Darwin and processor=intel' // prints yes, and on a Windows : // DOS> obuild_platform 'os=UNIX' // prints no // // In case of errors, some message is expected on stderr // and the program exits with EXIT_FAILURE (1), else // it exists with EXIT_SUCCESS (0). // // If possible, below get_[os,proc,compiler]() are before // any include to be sure that ifdef things come only // from the compiler... char* get_os() { #if defined(__APPLE__) static char os[] = {"Darwin"}; #elif defined(_WIN32) static char os[] = {"Windows_NT"}; #elif defined(__linux) static char os[] = {"Linux"}; #elif defined(__alpha) static char os[] = {"OSF1"}; #elif defined(__CYGWIN__) static char os[] = {"CYGWIN"}; #else static char os[] = {"unknown"}; #endif return os; } char* get_proc() { // should be consistent with is_proc() #if defined(__GNUC__) #if defined(__ppc__) static char proc[] = {"ppc"}; #elif defined(__ppc64__) static char proc[] = {"ppc64"}; #elif defined(__i386__) static char proc[] = {"i386"}; #elif defined(__x86_64__) static char proc[] = {"x86_64"}; #elif defined(__ia64__) static char proc[] = {"ia64"}; #else static char proc[] = {"unknown"}; #endif #elif defined(_MSC_VER) #if defined(_M_IX86) static char proc[] = {"ix86"}; #elif defined(_M_X64) static char proc[] = {"x64"}; #else static char proc[] = {"unknown"}; #endif #elif defined(__alpha) static char proc[] = {"alpha"}; #else static char proc[] = {"unknown"}; #endif return proc; } #if defined(__GNUC__) || defined(_MSC_VER) #include #endif char* get_compiler() { #if defined(__GNUC__) static char compiler[128]; ::sprintf(compiler,"gcc_%d%d%d",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__); #elif defined(_MSC_VER) static char compiler[128]; //::sprintf(compiler,"cl_%d_mfc_%d",_MSC_VER,_MFC_VER); ::sprintf(compiler,"cl_%d",_MSC_VER); #elif defined(__alpha) static char compiler[] = {"cxx"}; #else static char compiler[] = {"unknown"}; #endif return compiler; } #include #include #include #include #include //memcpy // From Lib : static std::vector Lib_smanip_words(const std::string&, const std::string&, bool = false); ////////////////////////////////////////////////////////////////////////////// static bool is_os( const std::string& aString ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { if(aString=="Windows_NT") { return true; } else if(aString=="Linux") { return true; } else if(aString=="Darwin") { return true; } else if(aString=="SunOS") { return true; } else if(aString=="OSF1") { return true; } else if(aString=="CYGWIN") { return true; } else if(aString=="UNIX") { return true; } else if(aString=="Linux_m32") { // used on a Linux 64 bits machine to cross build // for a 32 bits machine. It is used in the templates/tools.obuild file. // To work with Linux_m32 someone has to set the environment // variable OBUILD_PLATFORM_OS to Linux_m32 by hand since // we can't self detect with a CPP macro in get_os() that someone // wants to cross compile for a 32 bits machine. return true; } else { ::fprintf(stderr,"obuild_platform : unknown operating system \"%s\".\n", aString.c_str()); return false; } } ////////////////////////////////////////////////////////////////////////////// static bool is_proc( const std::string& aString ) ////////////////////////////////////////////////////////////////////////////// // should be consistent with get_proc() //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { if(aString=="ppc") { return true; } else if(aString=="ppc64") { return true; } else if(aString=="i386") { return true; } else if(aString=="x86_64") { return true; } else if(aString=="ia64") { return true; } else if(aString=="ix86") { return true; } else if(aString=="x64") { return true; } else if(aString=="alpha") { return true; } else if(aString=="m32") { return true; } else { ::fprintf(stderr,"obuild_platform : unknown processor \"%s\".\n", aString.c_str()); return false; } } ////////////////////////////////////////////////////////////////////////////// static bool is_UNIX( const std::string& aString ,bool& aResult ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { if(!is_os(aString)) { aResult = false; return false; } if(aString=="Windows_NT") { aResult = false; } else { aResult = true; } return true; } ////////////////////////////////////////////////////////////////////////////// static bool check_os( const std::string& a_os //a_os comes from get_os. ,const std::string& aString //aString from os= ,bool& aResult ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { if(aString=="UNIX") { return is_UNIX(a_os,aResult); } else if((aString=="Linux")&&(a_os=="Linux_m32")) { //Linux_m32 is a Linux. aResult = true; return true; } else if(!is_os(aString)){ return false; } else { aResult = (aString==a_os); return true; } } ////////////////////////////////////////////////////////////////////////////// static bool check_proc( const std::string& a_proc //a_proc comes from get_proc. ,const std::string& aString //aString from processor= ,bool& aResult ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { if(!is_proc(a_proc)) return false; if(aString=="intel") { //Darwin to test a MacIntel. if(a_proc=="i386") { aResult = true; } else { aResult = false; } } else if(aString=="powerpc") { if(a_proc=="ppc") { aResult = true; } else if(a_proc=="ppc64") { aResult = true; } else { aResult = false; } } else if(aString=="64_bits") { if(a_proc=="ppc64") { aResult = true; } else if(a_proc=="x86_64") { aResult = true; } else if(a_proc=="ia64") { aResult = true; } else if(a_proc=="x64") { aResult = true; } else { aResult = false; } } else { if(!is_proc(aString)) return false; aResult = (aString==a_proc); } return true; } ////////////////////////////////////////////////////////////////////////////// static bool evaluate_primary( const std::string& a_os ,const std::string& a_proc ,const std::string& aString ,bool& aResult ) ////////////////////////////////////////////////////////////////////////////// // aString is : // and then string is compared to the os. // or : // [os,processor][=,!=] //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { std::string::size_type pos_neq = aString.rfind("!="); std::string::size_type pos_eq = aString.find('='); std::string left,right; if(pos_neq!=std::string::npos) { left = aString.substr(0,pos_neq); right = aString.substr(pos_neq+2,aString.size()-(pos_neq+2)); if(left=="os") { if(a_os=="unknown") { ::fprintf(stderr, "obuild_platform : unknown operating system \"%s\".\n", a_os.c_str()); aResult = false; return false; } bool result; if(!check_os(a_os,right,result)) { aResult = false; return false; } aResult = (result?false:true); return true; } else if (left=="processor") { if(a_proc=="*") { //Used in obuild::Builder::build_on_platform. aResult = true; return true; } if(a_proc=="unknown") { ::fprintf(stderr,"obuild_platform : unknown processor \"%s\".\n", a_proc.c_str()); aResult = false; return false; } bool result; if(!check_proc(a_proc,right,result)){ aResult = false; return false; } aResult = (result?false:true); return true; } else { ::fprintf(stderr, "obuild_platform : unknown keyword \"%s\". os or processor expected.\n", left.c_str()); aResult = false; return false; } } else if(pos_eq!=std::string::npos) { left = aString.substr(0,pos_eq); right = aString.substr(pos_eq+1,aString.size()-(pos_eq+1)); if(left=="os") { if(a_os=="unknown") { ::fprintf(stderr, "obuild_platform : unknown operating system \"%s\".\n", a_os.c_str()); aResult = false; return false; } return check_os(a_os,right,aResult); } else if (left=="processor") { if(a_proc=="*") { //Used in obuild::Builder::build_on_platform. aResult = true; return true; } if(a_proc=="unknown") { ::fprintf(stderr,"obuild_platform : unknown processor \"%s\".\n", a_proc.c_str()); aResult = false; return false; } return check_proc(a_proc,right,aResult); } else { ::fprintf(stderr, "obuild_platform : unknown keyword \"%s\". os or processor expected.\n", left.c_str()); aResult = false; return false; } } else { if(a_os=="unknown") { ::fprintf(stderr,"obuild_platform : unknown operating system \"%s\".\n", a_os.c_str()); aResult = false; return false; } return check_os(a_os,aString,aResult); } } ////////////////////////////////////////////////////////////////////////////// static bool evaluate_ternary( const std::string& a_os ,const std::string& a_proc ,const std::string& a_left ,const std::string& a_op ,const std::string& a_right ,bool& aResult ) ////////////////////////////////////////////////////////////////////////////// // [and,or] //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { if(a_op=="and") { bool res_left; if(!evaluate_primary(a_os,a_proc,a_left,res_left)) { aResult = false; return false; } bool res_right; if(!evaluate_primary(a_os,a_proc,a_right,res_right)) { aResult = false; return false; } aResult = res_left && res_right; return true; } else if(a_op=="or") { bool res_left; if(!evaluate_primary(a_os,a_proc,a_left,res_left)) { aResult = false; return false; } bool res_right; if(!evaluate_primary(a_os,a_proc,a_right,res_right)) { aResult = false; return false; } aResult = res_left || res_right; return true; } else { ::fprintf(stderr, "obuild_platform : unknown keyword \"%s\". and or or expected.\n", a_op.c_str()); aResult = false; return false; } } ////////////////////////////////////////////////////////////////////////////// static bool evaluate_expression_old( const std::string& a_os ,const std::string& a_proc ,const std::string& aString ,bool& aResult ) ////////////////////////////////////////////////////////////////////////////// // aString is : // // not (for backward compatibility) // or : // [and,or] //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { std::vector words = Lib_smanip_words(aString," "); if(words.size()==1) { return evaluate_primary(a_os,a_proc,words[0],aResult); } else if( (words.size()==2) && (words[0]=="not") ) { // For backward compatibility : bool result; if(!evaluate_primary(a_os,a_proc,words[1],result)) { aResult = false; return false; } aResult = (result?false:true); return true; } else if(words.size()==3) { return evaluate_ternary(a_os,a_proc,words[0],words[1],words[2],aResult); } else { ::fprintf (stderr,"obuild_platform : only one or three words today supported.\n"); aResult = false; return false; } } static bool evaluate_expression( const std::string& a_os ,const std::string& a_proc ,const std::string& aString ,bool& aResult ); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// int main(int aArgc,char** aArgv) { // aArgs[0] : program name. // aArgs[1] : an expression to be evaluated according // the local kind of os, processor, compiler. std::vector args; {for(int index=0;index 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.empty()) return words; std::string::size_type lim = (aTakeEmpty?0:1); if(aLimiter.empty()) { 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; } ////////////////////////////////////////////////////////////////////////////// /// from Lib/Parser ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //#include #ifndef Lib_Parser_h #define Lib_Parser_h namespace Lib { class IResult { public: virtual ~IResult(){} virtual void* cast_head() const = 0; }; class IParser { public: virtual ~IParser(){} public: typedef unsigned int Length; public: virtual bool primary(const char* b,Length l, IResult& res) const = 0; virtual bool unary(const char* o,Length lo, const IResult& r, IResult& res) const = 0; virtual bool binary(const IResult& l, const char* o,Length lo, const IResult& r, IResult& res) const = 0; virtual bool evaluate(const char* b,Length l,IResult& res) const = 0; virtual IResult* create_result() const = 0; }; class BaseParser : public virtual IParser { public: virtual ~BaseParser(){} public: virtual bool evaluate(const char* b,Length l,IResult& res) const; }; } #endif //#include // this : //#include ////////////////////////////////////////////////////////////////////////////// bool Lib::BaseParser::evaluate( const char* a_b ,Length a_l ,IResult& aResult ) const ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { if(a_l==0) return false; Length count = 0; bool find_sep = false; const char* p_b = a_b; for(Length pos=0;pos(this); } public: bool m_bool; }; class BoolParser : public Lib::BaseParser { public: BoolParser(const std::string& a_os,const std::string& a_proc) :m_os(a_os),m_proc(a_proc){} virtual ~BoolParser(){} public: virtual Lib::IResult* create_result() const { return new BoolResult;} virtual bool primary(const char* b,L_t l, Lib::IResult& a_res) const { if(l==0) return false; BoolResult* res = Lib_CastHead(a_res,BoolResult); if(!res) return false; std::string s(l,' '); ::memcpy((char*)s.c_str(),b,l); return evaluate_primary(m_os,m_proc,s,res->m_bool); } virtual bool unary(const char* o,L_t lo, const Lib::IResult& r, Lib::IResult& a_res) const { BoolResult* sr = Lib_CastHead(r,BoolResult); if(!sr) return false; BoolResult* res = Lib_CastHead(a_res,BoolResult); if(!res) return false; /* if(eq(o,lo,"not",3)) { res->m_bool = (sr->m_bool?false:true); } else { return false; } return true; */ return false; } virtual bool binary(const Lib::IResult& l, const char* o,L_t lo, const Lib::IResult& r, Lib::IResult& a_res) const { BoolResult* sl = Lib_CastHead(l,BoolResult); if(!sl) return false; BoolResult* sr = Lib_CastHead(r,BoolResult); if(!sr) return false; BoolResult* res = Lib_CastHead(a_res,BoolResult); if(!res) return false; if(eq(o,lo,"and",3)) { res->m_bool = sl->m_bool && sr->m_bool; } else if(eq(o,lo,"or",2)) { res->m_bool = sl->m_bool || sr->m_bool; } else { return false; } return true; } private: static bool eq(const char* b1,L_t l1, const char* b2,L_t l2) { if(l1!=l2) return false; for(L_t i=0;i