FAUST compiler  0.9.9.6b8
main.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 #define FAUSTVERSION "0.9.46"
00022 
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <assert.h>
00026 
00027 #ifndef WIN32
00028 #include <sys/time.h>
00029 #include "libgen.h"
00030 #endif
00031 
00032 #include "compatibility.hh"
00033 #include "signals.hh"
00034 #include "sigtype.hh"
00035 #include "sigtyperules.hh"
00036 #include "sigprint.hh"
00037 #include "simplify.hh"
00038 #include "privatise.hh"
00039 
00040 #include "compile_scal.hh"
00041 #include "compile_vect.hh"
00042 #include "compile_sched.hh"
00043 
00044 #include "propagate.hh"
00045 #include "errormsg.hh"
00046 #include "ppbox.hh"
00047 #include "enrobage.hh"
00048 #include "eval.hh"
00049 #include "description.hh"
00050 #include "floats.hh"
00051 #include "doc.hh"
00052 
00053 #include <map>
00054 #include <string>
00055 #include <vector>
00056 #include <iostream>
00057 #include <fstream>
00058 #include <sstream>
00059 
00060 #ifndef WIN32
00061 #include <unistd.h>
00062 #endif
00063 
00064 #include "sourcereader.hh"
00065 
00066 
00067 // construction des representations graphiques
00068 
00069 #include "schema.h"
00070 #include "drawschema.hh"
00071 #include "timing.hh"
00072 
00073 using namespace std ;
00074 
00075 
00076 /****************************************************************
00077                         Parser variables
00078 *****************************************************************/
00079 
00080 
00081 int yyparse();
00082 
00083 int             yyerr;
00084 extern int      yydebug;
00085 extern FILE*    yyin;
00086 Tree            gResult;
00087 Tree            gResult2;
00088 
00089 SourceReader    gReader;
00090 
00091 map<Tree, set<Tree> > gMetaDataSet;
00092 extern vector<Tree> gDocVector;
00093 extern string gDocLang;
00094 
00095 
00096 /****************************************************************
00097                 Command line tools and arguments
00098 *****************************************************************/
00099 
00100 //-- globals
00101 string          gFaustSuperSuperDirectory;
00102 string          gFaustSuperDirectory;
00103 string          gFaustDirectory;
00104 string          gMasterDocument;
00105 string          gMasterDirectory;
00106 string          gMasterName;
00107 string          gDocName;
00108 Tree            gExpandedDefList;
00109 
00110 //-- command line arguments
00111 
00112 bool            gHelpSwitch     = false;
00113 bool            gVersionSwitch  = false;
00114 bool            gDetailsSwitch  = false;
00115 bool            gDrawSignals    = false;
00116 bool            gShadowBlur     = false;    // note: svg2pdf doesn't like the blur filter
00117 bool            gGraphSwitch    = false;
00118 bool            gDrawPSSwitch   = false;
00119 bool            gDrawSVGSwitch  = false;
00120 bool            gPrintXMLSwitch = false;
00121 bool            gPrintDocSwitch = false;
00122 bool            gLatexDocSwitch = true;     // Only LaTeX outformat is handled for the moment.
00123 bool            gStripDocSwitch = false;    // Strip <mdoc> content from doc listings.
00124 int             gBalancedSwitch = 0;
00125 int             gFoldThreshold  = 25;
00126 int             gMaxNameSize    = 40;
00127 bool            gSimpleNames    = false;
00128 bool            gSimplifyDiagrams = false;
00129 bool            gLessTempSwitch = false;
00130 int             gMaxCopyDelay   = 16;
00131 string          gArchFile;
00132 string          gOutputFile;
00133 list<string>    gInputFiles;
00134 
00135 bool            gPatternEvalMode = false;
00136 
00137 bool            gVectorSwitch   = false;
00138 bool            gDeepFirstSwitch= false;
00139 int             gVecSize        = 32;
00140 int             gVectorLoopVariant = 0;
00141 
00142 bool            gOpenMPSwitch   = false;
00143 bool            gOpenMPLoop     = false;
00144 bool            gSchedulerSwitch   = false;
00145 bool            gGroupTaskSwitch= false;
00146 
00147 bool            gUIMacroSwitch  = false;
00148 bool            gDumpNorm       = false;
00149 
00150 int             gTimeout        = 600;            // time out to abort compiler (in seconds)
00151 
00152 int             gFloatSize = 1;
00153 
00154 bool            gPrintFileListSwitch = false;
00155 
00156 string          gClassName      = "mydsp";
00157 
00158 //-- command line tools
00159 
00160 static bool isCmd(const char* cmd, const char* kw1)
00161 {
00162     return  (strcmp(cmd, kw1) == 0);
00163 }
00164 
00165 static bool isCmd(const char* cmd, const char* kw1, const char* kw2)
00166 {
00167     return  (strcmp(cmd, kw1) == 0) || (strcmp(cmd, kw2) == 0);
00168 }
00169 
00170 bool process_cmdline(int argc, char* argv[])
00171 {
00172     int i=1; int err=0;
00173 
00174     while (i<argc) {
00175 
00176         if        (isCmd(argv[i], "-h", "--help")) {
00177             gHelpSwitch = true;
00178             i += 1;
00179 
00180         } else if (isCmd(argv[i], "-v", "--version")) {
00181             gVersionSwitch = true;
00182             i += 1;
00183 
00184         } else if (isCmd(argv[i], "-d", "--details")) {
00185             gDetailsSwitch = true;
00186             i += 1;
00187 
00188         } else if (isCmd(argv[i], "-a", "--architecture")) {
00189             gArchFile = argv[i+1];
00190             i += 2;
00191 
00192         } else if (isCmd(argv[i], "-o")) {
00193             gOutputFile = argv[i+1];
00194             i += 2;
00195 
00196         } else if (isCmd(argv[i], "-ps", "--postscript")) {
00197             gDrawPSSwitch = true;
00198             i += 1;
00199 
00200         } else if (isCmd(argv[i], "-xml", "--xml")) {
00201             gPrintXMLSwitch = true;
00202             i += 1;
00203 
00204         } else if (isCmd(argv[i], "-tg", "--task-graph")) {
00205             gGraphSwitch = true;
00206             i += 1;
00207 
00208         } else if (isCmd(argv[i], "-sg", "--signal-graph")) {
00209             gDrawSignals = true;
00210             i += 1;
00211 
00212         } else if (isCmd(argv[i], "-blur", "--shadow-blur")) {
00213             gShadowBlur = true;
00214             i += 1;
00215 
00216         } else if (isCmd(argv[i], "-svg", "--svg")) {
00217             gDrawSVGSwitch = true;
00218             i += 1;
00219 
00220         } else if (isCmd(argv[i], "-f", "--fold")) {
00221             gFoldThreshold = atoi(argv[i+1]);
00222             i += 2;
00223 
00224         } else if (isCmd(argv[i], "-mns", "--max-name-size")) {
00225             gMaxNameSize = atoi(argv[i+1]);
00226             i += 2;
00227 
00228         } else if (isCmd(argv[i], "-sn", "--simple-names")) {
00229             gSimpleNames = true;
00230             i += 1;
00231 
00232         } else if (isCmd(argv[i], "-lb", "--left-balanced")) {
00233             gBalancedSwitch = 0;
00234             i += 1;
00235 
00236         } else if (isCmd(argv[i], "-mb", "--mid-balanced")) {
00237             gBalancedSwitch = 1;
00238             i += 1;
00239 
00240         } else if (isCmd(argv[i], "-rb", "--right-balanced")) {
00241             gBalancedSwitch = 2;
00242             i += 1;
00243 
00244         } else if (isCmd(argv[i], "-lt", "--less-temporaries")) {
00245             gLessTempSwitch = true;
00246             i += 1;
00247 
00248         } else if (isCmd(argv[i], "-mcd", "--max-copy-delay")) {
00249             gMaxCopyDelay = atoi(argv[i+1]);
00250             i += 2;
00251 
00252         } else if (isCmd(argv[i], "-sd", "--simplify-diagrams")) {
00253             gSimplifyDiagrams = true;
00254             i += 1;
00255 
00256         } else if (isCmd(argv[i], "-vec", "--vectorize")) {
00257             gVectorSwitch = true;
00258             i += 1;
00259 
00260         } else if (isCmd(argv[i], "-dfs", "--deepFirstScheduling")) {
00261             gDeepFirstSwitch = true;
00262             i += 1;
00263 
00264         } else if (isCmd(argv[i], "-vs", "--vec-size")) {
00265             gVecSize = atoi(argv[i+1]);
00266             i += 2;
00267 
00268         } else if (isCmd(argv[i], "-lv", "--loop-variant")) {
00269             gVectorLoopVariant = atoi(argv[i+1]);
00270             i += 2;
00271 
00272         } else if (isCmd(argv[i], "-omp", "--openMP")) {
00273             gOpenMPSwitch = true;
00274             i += 1;
00275 
00276         } else if (isCmd(argv[i], "-pl", "--par-loop")) {
00277             gOpenMPLoop = true;
00278             i += 1;
00279 
00280         } else if (isCmd(argv[i], "-sch", "--scheduler")) {
00281             gSchedulerSwitch = true;
00282             i += 1;
00283 
00284         } else if (isCmd(argv[i], "-g", "--groupTasks")) {
00285             gGroupTaskSwitch = true;
00286             i += 1;
00287 
00288         } else if (isCmd(argv[i], "-uim", "--user-interface-macros")) {
00289             gUIMacroSwitch = true;
00290             i += 1;
00291 
00292         } else if (isCmd(argv[i], "-t", "--timeout")) {
00293             gTimeout = atoi(argv[i+1]);
00294             i += 2;
00295 
00296         // double float options
00297         } else if (isCmd(argv[i], "-single", "--single-precision-floats")) {
00298             gFloatSize = 1;
00299             i += 1;
00300 
00301         } else if (isCmd(argv[i], "-double", "--double-precision-floats")) {
00302             gFloatSize = 2;
00303             i += 1;
00304 
00305         } else if (isCmd(argv[i], "-quad", "--quad-precision-floats")) {
00306             gFloatSize = 3;
00307             i += 1;
00308             
00309         } else if (isCmd(argv[i], "-mdoc", "--mathdoc")) {
00310             gPrintDocSwitch = true;
00311             i += 1;
00312             
00313         } else if (isCmd(argv[i], "-mdlang", "--mathdoc-lang")) {
00314             gDocLang = argv[i+1];
00315             i += 2;
00316             
00317         } else if (isCmd(argv[i], "-stripmdoc", "--strip-mdoc-tags")) {
00318             gStripDocSwitch = true;
00319             i += 1;
00320             
00321         } else if (isCmd(argv[i], "-flist", "--file-list")) {
00322             gPrintFileListSwitch = true;
00323             i += 1;
00324 
00325         } else if (isCmd(argv[i], "-norm", "--normalized-form")) {
00326             gDumpNorm = true;
00327             i += 1;
00328 
00329         } else if (isCmd(argv[i], "-cn", "--class-name")) {
00330             gClassName = argv[i+1];
00331             i += 2;
00332 
00333         } else if (argv[i][0] != '-') {
00334             if (check_file(argv[i])) {
00335                 gInputFiles.push_back(argv[i]);
00336             }
00337             i++;
00338 
00339         } else {
00340             cerr << "faust: unrecognized option \"" << argv[i] <<"\"" << endl;
00341             i++;
00342             err++;
00343         }
00344     }
00345 
00346     // adjust related options
00347     if (gOpenMPSwitch || gSchedulerSwitch) gVectorSwitch = true;
00348 
00349     return err == 0;
00350 }
00351 
00352 
00353 
00354 /****************************************************************
00355                      Help and Version information
00356 *****************************************************************/
00357 
00358 
00359 
00360 void printversion()
00361 {
00362     cout << "FAUST, DSP to C++ compiler, Version " << FAUSTVERSION << "\n";
00363     cout << "Copyright (C) 2002-2012, GRAME - Centre National de Creation Musicale. All rights reserved. \n\n";
00364 }
00365 
00366 
00367 void printhelp()
00368 {
00369     printversion();
00370     cout << "usage: faust [options] file1 [file2 ...]\n";
00371     cout << "\twhere options represent zero or more compiler options \n\tand fileN represents a faust source file (.dsp extension).\n";
00372 
00373     cout << "\noptions :\n";
00374     cout << "---------\n";
00375 
00376     cout << "-h \t\tprint this --help message\n";
00377     cout << "-v \t\tprint compiler --version information\n";
00378     cout << "-d \t\tprint compilation --details\n";
00379     cout << "-tg \t\tprint the internal --task-graph in dot format file\n";
00380     cout << "-sg \t\tprint the internal --signal-graph in dot format file\n";
00381     cout << "-ps \t\tprint block-diagram --postscript file\n";
00382     cout << "-svg \tprint block-diagram --svg file\n";
00383     cout << "-mdoc \tprint --mathdoc of a Faust program in LaTeX format in a -mdoc directory\n";
00384     cout << "-mdlang <l>\t\tload --mathdoc-lang <l> if translation file exists (<l> = en, fr, ...)\n";
00385     cout << "-stripdoc \t\tapply --strip-mdoc-tags when printing Faust -mdoc listings\n";
00386     cout << "-sd \t\ttry to further --simplify-diagrams before drawing them\n";
00387     cout << "-f <n> \t\t--fold <n> threshold during block-diagram generation (default 25 elements) \n";
00388     cout << "-mns <n> \t--max-name-size <n> threshold during block-diagram generation (default 40 char)\n";
00389     cout << "-sn \t\tuse --simple-names (without arguments) during block-diagram generation\n";
00390     cout << "-xml \t\tgenerate an --xml description file\n";
00391     cout << "-blur \t\tadd a --shadow-blur to SVG boxes\n";
00392     cout << "-lb \t\tgenerate --left-balanced expressions\n";
00393     cout << "-mb \t\tgenerate --mid-balanced expressions (default)\n";
00394     cout << "-rb \t\tgenerate --right-balanced expressions\n";
00395     cout << "-lt \t\tgenerate --less-temporaries in compiling delays\n";
00396     cout << "-mcd <n> \t--max-copy-delay <n> threshold between copy and ring buffer implementation (default 16 samples)\n";
00397     cout << "-a <file> \tC++ architecture file\n";
00398     cout << "-cn <name> \t--class-name <name> specify the name of the dsp class to be used instead of mydsp \n";
00399     cout << "-o <file> \tC++ output file\n";
00400     cout << "-vec    \t--vectorize generate easier to vectorize code\n";
00401     cout << "-vs <n> \t--vec-size <n> size of the vector (default 32 samples)\n";
00402     cout << "-lv <n> \t--loop-variant [0:fastest (default), 1:simple] \n";
00403     cout << "-omp    \t--openMP generate OpenMP pragmas, activates --vectorize option\n";
00404     cout << "-pl     \t--par-loop generate parallel loops in --openMP mode\n";
00405     cout << "-sch    \t--scheduler generate tasks and use a Work Stealing scheduler, activates --vectorize option\n";
00406     cout << "-dfs    \t--deepFirstScheduling schedule vector loops in deep first order\n";
00407     cout << "-g    \t\t--groupTasks group single-threaded sequential tasks together when -omp or -sch is used\n";
00408     cout << "-uim    \t--user-interface-macros add user interface macro definitions in the C++ code\n";
00409     cout << "-single \tuse --single-precision-floats for internal computations (default)\n";
00410     cout << "-double \tuse --double-precision-floats for internal computations\n";
00411     cout << "-quad \t\tuse --quad-precision-floats for internal computations\n";
00412     cout << "-flist \t\tuse --file-list used to eval process\n";
00413     cout << "-norm \t\t--normalized-form prints signals in normalized form and exits\n";
00414 
00415     cout << "\nexample :\n";
00416     cout << "---------\n";
00417 
00418     cout << "faust -a jack-gtk.cpp -o myfx.cpp myfx.dsp\n";
00419 }
00420 
00421 
00422 void printheader(ostream& dst)
00423 {
00424     // defines the metadata we want to print as comments at the begin of in the C++ file
00425     set<Tree> selectedKeys;
00426     selectedKeys.insert(tree("name"));
00427     selectedKeys.insert(tree("author"));
00428     selectedKeys.insert(tree("copyright"));
00429     selectedKeys.insert(tree("license"));
00430     selectedKeys.insert(tree("version"));
00431 
00432     dst << "//-----------------------------------------------------" << endl;
00433     for (map<Tree, set<Tree> >::iterator i = gMetaDataSet.begin(); i != gMetaDataSet.end(); i++) {
00434         if (selectedKeys.count(i->first)) {
00435             dst << "// " << *(i->first);
00436             const char* sep = ": ";
00437             for (set<Tree>::iterator j = i->second.begin(); j != i->second.end(); ++j) {
00438                 dst << sep << **j;
00439                 sep = ", ";
00440             }
00441             dst << endl;
00442         }
00443     }
00444 
00445     dst << "//" << endl;
00446     dst << "// Code generated with Faust " << FAUSTVERSION << " (http://faust.grame.fr)" << endl;
00447     dst << "//-----------------------------------------------------" << endl;
00448 }
00449 
00450 
00451 
00452 
00453 /****************************************************************
00454                                 MAIN
00455 *****************************************************************/
00456 
00457 
00458 
00463 static string fxname(const string& filename)
00464 {
00465     // determine position right after the last '/' or 0
00466     unsigned int p1 = 0;
00467     for (unsigned int i=0; i<filename.size(); i++) {
00468         if (filename[i] == '/')  { p1 = i+1; }
00469     }
00470     
00471     // determine position of the last '.'
00472     unsigned int p2 = filename.size();
00473     for (unsigned int i=p1; i<filename.size(); i++) {
00474         if (filename[i] == '.')  { p2 = i; }
00475     }
00476 
00477     return filename.substr(p1, p2-p1);
00478 }
00479 
00480 
00481 static void initFaustDirectories()
00482 {
00483     char s[1024];
00484     getFaustPathname(s, 1024);
00485 
00486     gFaustDirectory = filedirname(s);
00487     gFaustSuperDirectory = filedirname(gFaustDirectory);
00488     gFaustSuperSuperDirectory = filedirname(gFaustSuperDirectory);
00489     if (gInputFiles.empty()) {
00490         gMasterDocument = "Unknown";
00491         gMasterDirectory = ".";
00492         gMasterName = "faustfx";
00493         gDocName = "faustdoc";
00494     } else {
00495         gMasterDocument = *gInputFiles.begin();
00496         gMasterDirectory = filedirname(gMasterDocument);
00497         gMasterName = fxname(gMasterDocument);
00498         gDocName = fxname(gMasterDocument);
00499     }
00500 }
00501 
00502 
00503 
00504 int main (int argc, char* argv[])
00505 {
00506 
00507     /****************************************************************
00508      1 - process command line
00509     *****************************************************************/
00510 
00511     process_cmdline(argc, argv);
00512 
00513     if (gHelpSwitch)        { printhelp(); exit(0); }
00514     if (gVersionSwitch)     { printversion(); exit(0); }
00515 
00516     initFaustDirectories();
00517 #ifndef WIN32
00518     alarm(gTimeout);
00519 #endif
00520 
00521 
00522     /****************************************************************
00523      2 - parse source files
00524     *****************************************************************/
00525 
00526     startTiming("parser");
00527 
00528     
00529     list<string>::iterator s;
00530     gResult2 = nil;
00531     yyerr = 0;
00532 
00533     if (gInputFiles.begin() == gInputFiles.end()) {
00534         cerr << "ERROR: no files specified; for help type \"faust --help\"" << endl;
00535         exit(1);
00536     }
00537     for (s = gInputFiles.begin(); s != gInputFiles.end(); s++) {
00538         if (s == gInputFiles.begin()) gMasterDocument = *s;
00539         gResult2 = cons(importFile(tree(s->c_str())), gResult2);
00540     }
00541     if (yyerr > 0) {
00542         //fprintf(stderr, "Erreur de parsing 2, count = %d \n", yyerr);
00543         exit(1);
00544     }
00545     gExpandedDefList = gReader.expandlist(gResult2);
00546 
00547     endTiming("parser");
00548     
00549     /****************************************************************
00550      3 - evaluate 'process' definition
00551     *****************************************************************/
00552     
00553     startTiming("evaluation");
00554 
00555 
00556     Tree process = evalprocess(gExpandedDefList);
00557 
00558     if (gErrorCount > 0) {
00559        // cerr << "Total of " << gErrorCount << " errors during evaluation of : process = " << boxpp(process) << ";\n";
00560         cerr << "Total of " << gErrorCount << " errors during the compilation of  " << gMasterDocument << ";\n";
00561         exit(1);
00562     }
00563 
00564 
00565     if (gDetailsSwitch) { cerr << "process = " << boxpp(process) << ";\n"; }
00566 
00567     if (gDrawPSSwitch || gDrawSVGSwitch) {
00568         string projname = gMasterDocument;
00569         if( gMasterDocument.substr(gMasterDocument.length()-4) == ".dsp" ) {
00570             projname = gMasterDocument.substr(0, gMasterDocument.length()-4); 
00571         }
00572         if (gDrawPSSwitch)  { drawSchema( process, subst("$0-ps",  projname).c_str(), "ps" ); }
00573         if (gDrawSVGSwitch) { drawSchema( process, subst("$0-svg", projname).c_str(), "svg" ); }
00574     }
00575 
00576     int numInputs, numOutputs;
00577     if (!getBoxType(process, &numInputs, &numOutputs)) {
00578         cerr << "ERROR during the evaluation of  process : "
00579              << boxpp(process) << endl;
00580         exit(1);
00581     }
00582 
00583     if (gDetailsSwitch) {
00584         cerr <<"process has " << numInputs <<" inputs, and " << numOutputs <<" outputs" << endl;
00585     }
00586     
00587     endTiming("evaluation");
00588 
00589 
00590     /****************************************************************
00591      3.5 - output file list is needed
00592     *****************************************************************/
00593     if (gPrintFileListSwitch) {
00594         cout << "******* ";
00595         // print the pathnames of the files used to evaluate process
00596         vector<string> pathnames = gReader.listSrcFiles();
00597         for (unsigned int i=0; i< pathnames.size(); i++) cout << pathnames[i] << ' ';
00598         cout << endl;
00599 
00600     }
00601     
00602 
00603     /****************************************************************
00604      4 - compute output signals of 'process'
00605     *****************************************************************/
00606     
00607     startTiming("propagation");
00608 
00609 
00610     Tree lsignals = boxPropagateSig(nil, process , makeSigInputList(numInputs) );
00611     if (gDetailsSwitch) { cerr << "output signals are : " << endl;  printSignal(lsignals, stderr); }
00612 
00613     endTiming("propagation");
00614 
00615 
00616     /****************************************************************
00617      5 - translate output signals into C++ code
00618     *****************************************************************/
00619 
00620     startTiming("compilation");
00621 
00622     Compiler* C;
00623     if (gSchedulerSwitch)   C = new SchedulerCompiler(gClassName, "dsp", numInputs, numOutputs);
00624     else if (gVectorSwitch) C = new VectorCompiler(gClassName, "dsp", numInputs, numOutputs);
00625     else                    C = new ScalarCompiler(gClassName, "dsp", numInputs, numOutputs);
00626 
00627     if (gPrintXMLSwitch) C->setDescription(new Description());
00628     if (gPrintDocSwitch) C->setDescription(new Description());
00629 
00630     C->compileMultiSignal(lsignals);
00631 
00632     endTiming("compilation");
00633 
00634     /****************************************************************
00635      6 - generate XML description (if required)
00636     *****************************************************************/
00637 
00638     if (gPrintXMLSwitch) {
00639         Description*    D = C->getDescription(); assert(D);
00640         //ostream*      xout = new ofstream(subst("$0.xml", gMasterDocument).c_str());
00641         ofstream        xout(subst("$0.xml", gMasterDocument).c_str());
00642 
00643         if(gMetaDataSet.count(tree("name"))>0)          D->name(tree2str(*(gMetaDataSet[tree("name")].begin())));
00644         if(gMetaDataSet.count(tree("author"))>0)        D->author(tree2str(*(gMetaDataSet[tree("author")].begin())));
00645         if(gMetaDataSet.count(tree("copyright"))>0)     D->copyright(tree2str(*(gMetaDataSet[tree("copyright")].begin())));
00646         if(gMetaDataSet.count(tree("license"))>0)       D->license(tree2str(*(gMetaDataSet[tree("license")].begin())));
00647         if(gMetaDataSet.count(tree("version"))>0)       D->version(tree2str(*(gMetaDataSet[tree("version")].begin())));
00648 
00649         D->inputs(C->getClass()->inputs());
00650         D->outputs(C->getClass()->outputs());
00651 
00652         D->print(0, xout);
00653     }
00654 
00655 
00656     /****************************************************************
00657      7 - generate documentation from Faust comments (if required)
00658     *****************************************************************/
00659 
00660 
00661     if (gPrintDocSwitch) {
00662         if (gLatexDocSwitch) {
00663             string projname = gMasterDocument;
00664             if( gMasterDocument.substr(gMasterDocument.length()-4) == ".dsp" ) {
00665                 projname = gMasterDocument.substr(0, gMasterDocument.length()-4); }
00666             printDoc( subst("$0-mdoc", projname).c_str(), "tex", FAUSTVERSION );
00667         }
00668     }
00669 
00670 
00671 
00672 
00673     /****************************************************************
00674      8 - generate output file
00675     *****************************************************************/
00676 
00677     ostream* dst;
00678     istream* enrobage;
00679     //istream* intrinsic;
00680 
00681     if (gOutputFile != "") {
00682         dst = new ofstream(gOutputFile.c_str());
00683     } else {
00684         dst = &cout;
00685     }
00686 
00687     if (gArchFile != "") {
00688         if ( (enrobage = open_arch_stream(gArchFile.c_str())) ) {
00689             printheader(*dst);
00690             C->getClass()->printLibrary(*dst);
00691             C->getClass()->printIncludeFile(*dst);
00692             C->getClass()->printAdditionalCode(*dst);
00693 
00694             streamCopyUntil(*enrobage, *dst, "<<includeIntrinsic>>");
00695 
00696 //          if ( gVectorSwitch && (intrinsic = open_arch_stream("intrinsic.hh")) ) {
00697 //              streamCopyUntilEnd(*intrinsic, *dst);
00698 //          }
00699             
00700             if (gSchedulerSwitch) {
00701                 istream* scheduler_include = open_arch_stream("scheduler.h");
00702                 if (scheduler_include) {
00703                     streamCopy(*scheduler_include, *dst);
00704                 }
00705             }
00706             
00707             streamCopyUntil(*enrobage, *dst, "<<includeclass>>");
00708             printfloatdef(*dst);
00709             
00710             C->getClass()->println(0,*dst);
00711             streamCopyUntilEnd(*enrobage, *dst);
00712         } else {
00713             cerr << "ERROR : can't open architecture file " << gArchFile << endl;
00714             return 1;
00715         }
00716     } else {
00717         printheader(*dst);
00718         printfloatdef(*dst);
00719         C->getClass()->printLibrary(*dst);
00720         C->getClass()->printIncludeFile(*dst);
00721         C->getClass()->printAdditionalCode(*dst);
00722         C->getClass()->println(0,*dst);
00723     }
00724 
00725 
00726     /****************************************************************
00727      9 - generate the task graph file in dot format
00728     *****************************************************************/
00729 
00730     if (gGraphSwitch) {
00731         ofstream dotfile(subst("$0.dot", gMasterDocument).c_str());
00732         C->getClass()->printGraphDotFormat(dotfile);
00733     }
00734 
00735 
00736 
00737     
00738     delete C;
00739     return 0;
00740 }