FAUST compiler  0.9.9.6b8
enrobage.cpp
Go to the documentation of this file.
00001 /************************************************************************
00002  ************************************************************************
00003     FAUST compiler
00004     Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
00005     ---------------------------------------------------------------------
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  ************************************************************************
00020  ************************************************************************/
00021  
00022  
00023  
00024 #include "enrobage.hh"
00025 #include <vector>
00026 #include <string>
00027 #include <limits.h>
00028 #include <stdlib.h>
00029 #include "compatibility.hh"
00030 #include <climits>
00031 
00032 extern string gFaustSuperSuperDirectory;
00033 extern string gFaustSuperDirectory;
00034 extern string gFaustDirectory;
00035 extern string gMasterDirectory;
00036 extern string gClassName;
00037 
00038 //----------------------------------------------------------------
00039 
00040 
00044 static bool isBlank(const string& s) {
00045     for (size_t i=0; i<s.size(); i++) {
00046         if (s[i] != ' ' && s[i] != '\t') return false;
00047     }
00048     return true;
00049 }
00050 
00051 
00056 static string& replaceOccurences(string& str, const string& oldstr, const string& newstr)
00057 {
00058     string::size_type l1 = oldstr.length();
00059     string::size_type l2 = newstr.length();
00060 
00061     string::size_type pos = str.find(oldstr);
00062     while ( pos != string::npos) {
00063         str.replace(pos, l1, newstr);
00064         pos = str.find(oldstr, pos + l2);
00065     }
00066     return str;
00067 }
00068 
00069 
00074 static string& replaceClassName(string& str)
00075 {
00076     return replaceOccurences(str, "mydsp", gClassName);
00077 }
00078 
00079 
00086 void streamCopyLicense(istream& src, ostream& dst, const string& exceptiontag)
00087 {
00088     string          s;
00089     vector<string>  H;
00090 
00091     // skip blank lines
00092     while (getline(src,s) && isBlank(s)) dst << s << endl;
00093 
00094     // first non blank should start a comment
00095     if (s.find("/*")==string::npos) { dst << s << endl; return; }
00096 
00097     // copy the header into H
00098     bool remove = false;
00099     H.push_back(s);
00100 
00101     while (getline(src,s) && s.find("*/")==string::npos) {
00102         H.push_back(s);
00103         if (s.find(exceptiontag) != string::npos) remove=true;
00104     }
00105 
00106     // copy the header unless explicitely granted to remove it
00107     if (!remove) {
00108         // copy the header
00109         for (unsigned int i=0; i<H.size(); i++) {
00110             dst << H[i] << endl;
00111         }
00112         dst << s << endl;
00113     }
00114 }
00115 
00116 
00120 void streamCopyUntil(istream& src, ostream& dst, const string& until)
00121 {
00122     string  s;
00123     while ( getline(src,s) && (s != until) ) dst << replaceClassName(s) << endl;
00124 }
00125 
00129 void streamCopy(istream& src, ostream& dst)
00130 { 
00131     string  s;
00132     while ( getline(src,s)) dst << replaceClassName(s) << endl;
00133 }
00134 
00138 void streamCopyUntilEnd(istream& src, ostream& dst)
00139 { 
00140     string  s;
00141     while ( getline(src,s) ) dst << replaceClassName(s) << endl;
00142 }
00143 
00144 
00148 ifstream* open_arch_stream(const char* filename)
00149 {
00150     char    buffer[FAUST_PATH_MAX];
00151     char*   old = getcwd (buffer, FAUST_PATH_MAX);
00152     int     err;
00153 
00154     {
00155         ifstream* f = new ifstream();
00156         f->open(filename, ifstream::in); if (f->is_open()) return f; else delete f;
00157     }
00158     char *envpath = getenv("FAUST_LIB_PATH");
00159     if (envpath!=NULL) {
00160         if (chdir(envpath)==0) {
00161             ifstream* f = new ifstream();
00162             f->open(filename, ifstream::in);
00163             if (f->is_open()) return f; else delete f;
00164         }
00165     }
00166     err = chdir(old);
00167     if ( (chdir(gFaustDirectory.c_str())==0) && (chdir("architecture")==0) ) {
00168         //cout << "enrobage.cpp : 'architecture' directory found in gFaustDirectory" << endl;
00169         ifstream* f = new ifstream();
00170         f->open(filename, ifstream::in);
00171         if (f->good()) return f; else delete f;
00172     }
00173     err = chdir(old);
00174     if ((chdir(gFaustSuperDirectory.c_str())==0) && (chdir("architecture")==0) ) {
00175         //cout << "enrobage.cpp : 'architecture' directory found in gFaustSuperDirectory" << endl;
00176         ifstream* f = new ifstream();
00177         f->open(filename, ifstream::in);
00178         if (f->good()) return f; else delete f;
00179     }
00180     err = chdir(old);
00181     if ((chdir(gFaustSuperSuperDirectory.c_str())==0) && (chdir("architecture")==0) ) {
00182         //cout << "enrobage.cpp : 'architecture' directory found in gFaustSuperSuperDirectory" << endl;
00183         ifstream* f = new ifstream();
00184         f->open(filename, ifstream::in);
00185         if (f->good()) return f; else delete f;
00186     }
00187 #ifdef INSTALL_PREFIX
00188     err = chdir(old);
00189     if (chdir(INSTALL_PREFIX "/lib/faust")==0) {
00190         ifstream* f = new ifstream();
00191         f->open(filename); 
00192         if (f->good()) return f; else delete f;
00193     }
00194 #endif
00195     err = chdir(old);
00196     if (chdir("/usr/local/lib/faust")==0) {
00197         ifstream* f = new ifstream();
00198         f->open(filename); 
00199         if (f->good()) return f; else delete f;
00200     }
00201     err = chdir(old);
00202     if (chdir("/usr/lib/faust")==0) {
00203         ifstream* f = new ifstream();
00204         f->open(filename); 
00205         if (f->good()) return f; else delete f;
00206     }
00207     
00208     return 0;
00209 }
00210 
00211 
00212 
00213 /*---------------------------------------------*/
00214 
00220 bool check_file(const char* filename)
00221 {
00222     FILE* f = fopen(filename, "r");
00223     
00224     if (f == NULL) {
00225         fprintf(stderr, "faust: "); perror(filename);
00226     } else {
00227         fclose(f);
00228     }
00229     return f != NULL;
00230 }
00231         
00232 
00237 static FILE* fopenat(string& fullpath, const char* dir, const char* filename)
00238 {
00239     int         err; 
00240     char        olddirbuffer[FAUST_PATH_MAX];
00241     char        newdirbuffer[FAUST_PATH_MAX];
00242     
00243     char*       olddir = getcwd (olddirbuffer, FAUST_PATH_MAX);
00244 
00245     if (chdir(dir) == 0) {           
00246         FILE* f = fopen(filename, "r");
00247         fullpath = getcwd (newdirbuffer, FAUST_PATH_MAX);
00248         fullpath += '/';
00249         fullpath += filename;
00250         err = chdir(olddir);
00251         return f;
00252     }
00253     err = chdir(olddir);
00254     return 0;
00255 }
00256 
00261 static FILE* fopenat(string& fullpath, const string& dir, const char* filename)
00262 {
00263     return fopenat(fullpath, dir.c_str(), filename);
00264 }
00265 
00270 static FILE* fopenat(string& fullpath, const string& dir, const char* path, const char* filename)
00271 {
00272     int         err;
00273     char        olddirbuffer[FAUST_PATH_MAX];
00274     char        newdirbuffer[FAUST_PATH_MAX];
00275     
00276     char*       olddir = getcwd (olddirbuffer, FAUST_PATH_MAX);
00277     if (chdir(dir.c_str()) == 0) {
00278         if (chdir(path) == 0) {            
00279             FILE* f = fopen(filename, "r");
00280             fullpath = getcwd (newdirbuffer, FAUST_PATH_MAX);
00281             fullpath += '/';
00282             fullpath += filename;
00283             err = chdir(olddir);
00284             return f;
00285         }
00286     }
00287     err = chdir(olddir);
00288     return 0;
00289 }
00290 
00291 
00292 
00296 static bool isAbsolutePathname(const string& filename)
00297 {
00298     //test windows absolute pathname "x:xxxxxx"
00299     if (filename.size()>1 && filename[1] == ':') return true;
00300 
00301     // test unix absolute pathname "/xxxxxx"
00302     if (filename.size()>0 && filename[0] == '/') return true;
00303 
00304     return false;
00305 }
00306 
00307 
00312 static void buildFullPathname(string& fullpath, const char* filename)
00313 {
00314     char    old[FAUST_PATH_MAX];
00315 
00316     if (isAbsolutePathname(filename)) {
00317         fullpath = filename;
00318     } else {
00319         fullpath = getcwd (old, FAUST_PATH_MAX);
00320         fullpath += '/';
00321         fullpath += filename;
00322     }
00323 }
00324 
00330 #ifdef WIN32
00331 FILE* fopensearch(const char* filename, string& fullpath)
00332 {   
00333     FILE* f;
00334     char* envpath;
00335 
00336     if ((f = fopen(filename, "r"))) { 
00337         buildFullPathname(fullpath, filename); 
00338         return f;
00339     }
00340     if ((f = fopenat(fullpath, gMasterDirectory, filename))) { 
00341         return f;
00342     }
00343     if ((envpath = getenv("FAUST_LIB_PATH")) && (f = fopenat(fullpath, envpath, filename))) {
00344         return f;
00345     }
00346     if ((f = fopenat(fullpath, gFaustDirectory, "architecture", filename))) { 
00347         return f;
00348     }
00349     if ((f = fopenat(fullpath, gFaustSuperDirectory, "architecture", filename))) { 
00350         return f;
00351     }
00352     if ((f = fopenat(fullpath, gFaustSuperSuperDirectory, "architecture", filename))) { 
00353         return f;
00354     }
00355     return 0;
00356 }
00357 #else
00358 FILE* fopensearch(const char* filename, string& fullpath)
00359 {   
00360     FILE* f;
00361     char* envpath;
00362 
00363     if ((f = fopen(filename, "r"))) { 
00364         buildFullPathname(fullpath, filename); 
00365         return f;
00366     }
00367     if ((f = fopenat(fullpath, gMasterDirectory, filename))) { 
00368         return f;
00369     }
00370     if ((envpath = getenv("FAUST_LIB_PATH")) && (f = fopenat(fullpath, envpath, filename))) {
00371         return f;
00372     }
00373     if ((f = fopenat(fullpath, gFaustDirectory, "architecture", filename))) { 
00374         return f;
00375     }
00376     if ((f = fopenat(fullpath, gFaustSuperDirectory, "architecture", filename))) { 
00377         return f;
00378     }
00379     if ((f = fopenat(fullpath, gFaustSuperSuperDirectory, "architecture", filename))) { 
00380         return f;
00381     }
00382 #ifdef INSTALL_PREFIX
00383     if ((f = fopenat(fullpath, INSTALL_PREFIX "/lib/faust", filename))) { 
00384         return f;
00385     }
00386 #endif
00387     if ((f = fopenat(fullpath, "/usr/local/lib/faust", filename))) { 
00388         return f;
00389     }
00390     if ((f = fopenat(fullpath, "/usr/lib/faust", filename))) { 
00391         return f;
00392     }
00393     return 0;
00394 }
00395 #endif
00396 
00397 
00405 #ifndef DIR_SEPARATOR
00406 #define DIR_SEPARATOR '/'
00407 #endif
00408 
00409 #ifdef WIN32
00410 #define HAVE_DOS_BASED_FILE_SYSTEM
00411 #ifndef DIR_SEPARATOR_2 
00412 #define DIR_SEPARATOR_2 '\\'
00413 #endif
00414 #endif
00415 
00416 /* Define IS_DIR_SEPARATOR.  */
00417 #ifndef DIR_SEPARATOR_2
00418 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
00419 #else /* DIR_SEPARATOR_2 */
00420 # define IS_DIR_SEPARATOR(ch) \
00421 (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
00422 #endif /* DIR_SEPARATOR_2 */
00423 
00424 
00428 const char* filebasename(const char* name)
00429 {
00430 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
00431     /* Skip over the disk name in MSDOS pathnames. */
00432     if (isalpha(name[0]) && name[1] == ':') 
00433         name += 2;
00434 #endif
00435 
00436     const char* base;
00437     for (base = name; *name; name++)
00438     {
00439         if (IS_DIR_SEPARATOR (*name))
00440         {
00441             base = name + 1;
00442         }
00443     }
00444     return base;
00445 }
00446 
00447 
00452 string filedirname(const string& name)
00453 {
00454     const char*         base = filebasename(name.c_str());
00455     const unsigned int  size = base-name.c_str();
00456     string              dirname;
00457 
00458     if (size==0) {
00459         dirname += '.';
00460 
00461     } else if (size==1) {
00462         dirname += name[0];
00463 
00464     } else {
00465         for (unsigned int i=0; i<size-1; i++) {
00466             dirname += name[i];
00467         }
00468     }
00469     return dirname;
00470 }