-/************************************************************************
- ************************************************************************
- FAUST compiler
- Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
- ---------------------------------------------------------------------
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ************************************************************************
- ************************************************************************/
-
-#include "preprocess.hh"
-
-
-
-
-/****************************************************************
- Parser variables
-*****************************************************************/
-
-
-int yyparse();
-
-int yyerr;
-extern int yydebug;
-extern FILE* yyin;
-Tree gResult;
-Tree gResult2;
-
-SourceReader gReader;
-
-map<Tree, set<Tree> > gMetaDataSet;
-extern vector<Tree> gDocVector;
-extern string gDocLang;
-
-
-/****************************************************************
- Command line tools and arguments
-*****************************************************************/
-
-//-- globals
-string gFaustSuperSuperDirectory;
-string gFaustSuperDirectory;
-string gFaustDirectory;
-string gMasterDocument;
-string gMasterDirectory;
-string gMasterName;
-string gDocName;
-Tree gExpandedDefList;
-
-//-- command line arguments
-
-bool gHelpSwitch = false;
-bool gVersionSwitch = false;
-bool gDetailsSwitch = false;
-bool gDrawSignals = false;
-bool gShadowBlur = false; // note: svg2pdf doesn't like the blur filter
-bool gGraphSwitch = false;
-bool gDrawPSSwitch = false;
-bool gDrawSVGSwitch = false;
-bool gPrintXMLSwitch = false;
-bool gPrintDocSwitch = false;
-bool gLatexDocSwitch = true; // Only LaTeX outformat is handled for the moment.
-bool gStripDocSwitch = false; // Strip <mdoc> content from doc listings.
-int gBalancedSwitch = 0;
-int gFoldThreshold = 25;
-int gMaxNameSize = 40;
-bool gSimpleNames = false;
-bool gSimplifyDiagrams = false;
-bool gLessTempSwitch = false;
-int gMaxCopyDelay = 16;
-string gArchFile;
-string gOutputFile;
-list<string> gInputFiles;
-
-bool gPatternEvalMode = false;
-
-bool gVectorSwitch = false;
-bool gDeepFirstSwitch= false;
-int gVecSize = 32;
-int gVectorLoopVariant = 0;
-
-bool gOpenMPSwitch = false;
-bool gOpenMPLoop = false;
-bool gSchedulerSwitch = false;
-bool gGroupTaskSwitch= false;
-
-bool gUIMacroSwitch = false;
-bool gDumpNorm = false;
-
-int gTimeout = 120; // time out to abort compiler (in seconds)
-
-int gFloatSize = 1;
-
-bool gPrintFileListSwitch = false;
-
-string gClassName = "mydsp";
-
-//-- command line tools
-
-static bool isCmd(const char* cmd, const char* kw1)
-{
- return (strcmp(cmd, kw1) == 0);
-}
-
-static bool isCmd(const char* cmd, const char* kw1, const char* kw2)
-{
- return (strcmp(cmd, kw1) == 0) || (strcmp(cmd, kw2) == 0);
-}
-
-bool process_cmdline(int argc, char* argv[])
-{
- int i=1; int err=0;
-
- while (i<argc) {
-
- if (isCmd(argv[i], "-h", "--help")) {
- gHelpSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-v", "--version")) {
- gVersionSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-d", "--details")) {
- gDetailsSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-a", "--architecture")) {
- gArchFile = argv[i+1];
- i += 2;
-
- } else if (isCmd(argv[i], "-o")) {
- gOutputFile = argv[i+1];
- i += 2;
-
- } else if (isCmd(argv[i], "-ps", "--postscript")) {
- gDrawPSSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-xml", "--xml")) {
- gPrintXMLSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-tg", "--task-graph")) {
- gGraphSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-sg", "--signal-graph")) {
- gDrawSignals = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-blur", "--shadow-blur")) {
- gShadowBlur = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-svg", "--svg")) {
- gDrawSVGSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-f", "--fold")) {
- gFoldThreshold = atoi(argv[i+1]);
- i += 2;
-
- } else if (isCmd(argv[i], "-mns", "--max-name-size")) {
- gMaxNameSize = atoi(argv[i+1]);
- i += 2;
-
- } else if (isCmd(argv[i], "-sn", "--simple-names")) {
- gSimpleNames = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-lb", "--left-balanced")) {
- gBalancedSwitch = 0;
- i += 1;
-
- } else if (isCmd(argv[i], "-mb", "--mid-balanced")) {
- gBalancedSwitch = 1;
- i += 1;
-
- } else if (isCmd(argv[i], "-rb", "--right-balanced")) {
- gBalancedSwitch = 2;
- i += 1;
-
- } else if (isCmd(argv[i], "-lt", "--less-temporaries")) {
- gLessTempSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-mcd", "--max-copy-delay")) {
- gMaxCopyDelay = atoi(argv[i+1]);
- i += 2;
-
- } else if (isCmd(argv[i], "-sd", "--simplify-diagrams")) {
- gSimplifyDiagrams = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-vec", "--vectorize")) {
- gVectorSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-dfs", "--deepFirstScheduling")) {
- gDeepFirstSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-vs", "--vec-size")) {
- gVecSize = atoi(argv[i+1]);
- i += 2;
-
- } else if (isCmd(argv[i], "-lv", "--loop-variant")) {
- gVectorLoopVariant = atoi(argv[i+1]);
- i += 2;
-
- } else if (isCmd(argv[i], "-omp", "--openMP")) {
- gOpenMPSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-pl", "--par-loop")) {
- gOpenMPLoop = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-sch", "--scheduler")) {
- gSchedulerSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-g", "--groupTasks")) {
- gGroupTaskSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-uim", "--user-interface-macros")) {
- gUIMacroSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-t", "--timeout")) {
- gTimeout = atoi(argv[i+1]);
- i += 2;
-
- // double float options
- } else if (isCmd(argv[i], "-single", "--single-precision-floats")) {
- gFloatSize = 1;
- i += 1;
-
- } else if (isCmd(argv[i], "-double", "--double-precision-floats")) {
- gFloatSize = 2;
- i += 1;
-
- } else if (isCmd(argv[i], "-quad", "--quad-precision-floats")) {
- gFloatSize = 3;
- i += 1;
-
- } else if (isCmd(argv[i], "-mdoc", "--mathdoc")) {
- gPrintDocSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-mdlang", "--mathdoc-lang")) {
- gDocLang = argv[i+1];
- i += 2;
-
- } else if (isCmd(argv[i], "-stripmdoc", "--strip-mdoc-tags")) {
- gStripDocSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-flist", "--file-list")) {
- gPrintFileListSwitch = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-norm", "--normalized-form")) {
- gDumpNorm = true;
- i += 1;
-
- } else if (isCmd(argv[i], "-cn", "--class-name")) {
- gClassName = argv[i+1];
- i += 2;
-
- } else if (argv[i][0] != '-') {
- if (check_file(argv[i])) {
- gInputFiles.push_back(argv[i]);
- }
- i++;
-
- } else {
- cerr << "faust: unrecognized option \"" << argv[i] <<"\"" << endl;
- i++;
- err++;
- }
- }
-
- // adjust related options
- if (gOpenMPSwitch || gSchedulerSwitch) gVectorSwitch = true;
-
- return err == 0;
-}
-
-
-
-/****************************************************************
- Help and Version information
-*****************************************************************/
-
-
-
-void printversion()
-{
- cout << "FAUST, DSP to C++ compiler, Version " << FAUSTVERSION << "\n";
- cout << "Copyright (C) 2002-2012, GRAME - Centre National de Creation Musicale. All rights reserved. \n\n";
-}
-
-
-void printhelp()
-{
- printversion();
- cout << "usage: faust [options] file1 [file2 ...]\n";
- cout << "\twhere options represent zero or more compiler options \n\tand fileN represents a faust source file (.dsp extension).\n";
-
- cout << "\noptions :\n";
- cout << "---------\n";
-
- cout << "-h \t\tprint this --help message\n";
- cout << "-v \t\tprint compiler --version information\n";
- cout << "-d \t\tprint compilation --details\n";
- cout << "-tg \t\tprint the internal --task-graph in dot format file\n";
- cout << "-sg \t\tprint the internal --signal-graph in dot format file\n";
- cout << "-ps \t\tprint block-diagram --postscript file\n";
- cout << "-svg \tprint block-diagram --svg file\n";
- cout << "-mdoc \tprint --mathdoc of a Faust program in LaTeX format in a -mdoc directory\n";
- cout << "-mdlang <l>\t\tload --mathdoc-lang <l> if translation file exists (<l> = en, fr, ...)\n";
- cout << "-stripdoc \t\tapply --strip-mdoc-tags when printing Faust -mdoc listings\n";
- cout << "-sd \t\ttry to further --simplify-diagrams before drawing them\n";
- cout << "-f <n> \t\t--fold <n> threshold during block-diagram generation (default 25 elements) \n";
- cout << "-mns <n> \t--max-name-size <n> threshold during block-diagram generation (default 40 char)\n";
- cout << "-sn \t\tuse --simple-names (without arguments) during block-diagram generation\n";
- cout << "-xml \t\tgenerate an --xml description file\n";
- cout << "-blur \t\tadd a --shadow-blur to SVG boxes\n";
- cout << "-lb \t\tgenerate --left-balanced expressions\n";
- cout << "-mb \t\tgenerate --mid-balanced expressions (default)\n";
- cout << "-rb \t\tgenerate --right-balanced expressions\n";
- cout << "-lt \t\tgenerate --less-temporaries in compiling delays\n";
- cout << "-mcd <n> \t--max-copy-delay <n> threshold between copy and ring buffer implementation (default 16 samples)\n";
- cout << "-a <file> \tC++ architecture file\n";
- cout << "-cn <name> \t--class-name <name> specify the name of the dsp class to be used instead of mydsp \n";
- cout << "-t <sec> \t--timeout <sec>, abort compilation after <sec> seconds (default 120)\n";
- cout << "-o <file> \tC++ output file\n";
- cout << "-vec \t--vectorize generate easier to vectorize code\n";
- cout << "-vs <n> \t--vec-size <n> size of the vector (default 32 samples)\n";
- cout << "-lv <n> \t--loop-variant [0:fastest (default), 1:simple] \n";
- cout << "-omp \t--openMP generate OpenMP pragmas, activates --vectorize option\n";
- cout << "-pl \t--par-loop generate parallel loops in --openMP mode\n";
- cout << "-sch \t--scheduler generate tasks and use a Work Stealing scheduler, activates --vectorize option\n";
- cout << "-dfs \t--deepFirstScheduling schedule vector loops in deep first order\n";
- cout << "-g \t\t--groupTasks group single-threaded sequential tasks together when -omp or -sch is used\n";
- cout << "-uim \t--user-interface-macros add user interface macro definitions in the C++ code\n";
- cout << "-single \tuse --single-precision-floats for internal computations (default)\n";
- cout << "-double \tuse --double-precision-floats for internal computations\n";
- cout << "-quad \t\tuse --quad-precision-floats for internal computations\n";
- cout << "-flist \t\tuse --file-list used to eval process\n";
- cout << "-norm \t\t--normalized-form prints signals in normalized form and exits\n";
-
- cout << "\nexample :\n";
- cout << "---------\n";
-
- cout << "faust -a jack-gtk.cpp -o myfx.cpp myfx.dsp\n";
-}
-
-
-void printheader(ostream& dst)
-{
- // defines the metadata we want to print as comments at the begin of in the C++ file
- set<Tree> selectedKeys;
- selectedKeys.insert(tree("name"));
- selectedKeys.insert(tree("author"));
- selectedKeys.insert(tree("copyright"));
- selectedKeys.insert(tree("license"));
- selectedKeys.insert(tree("version"));
-
- dst << "//-----------------------------------------------------" << endl;
- for (map<Tree, set<Tree> >::iterator i = gMetaDataSet.begin(); i != gMetaDataSet.end(); i++) {
- if (selectedKeys.count(i->first)) {
- dst << "// " << *(i->first);
- const char* sep = ": ";
- for (set<Tree>::iterator j = i->second.begin(); j != i->second.end(); ++j) {
- dst << sep << **j;
- sep = ", ";
- }
- dst << endl;
- }
- }
-
- dst << "//" << endl;
- dst << "// Code generated with Faust " << FAUSTVERSION << " (http://faust.grame.fr)" << endl;
- dst << "//-----------------------------------------------------" << endl;
-}
-
-
-
-
-/****************************************************************
- MAIN
-*****************************************************************/
-
-
-
-/**
- * transform a filename "faust/example/noise.dsp" into
- * the corresponding fx name "noise"
- */
-static string fxname(const string& filename)
-{
- // determine position right after the last '/' or 0
- unsigned int p1 = 0;
- for (unsigned int i=0; i<filename.size(); i++) {
- if (filename[i] == '/') { p1 = i+1; }
- }
-
- // determine position of the last '.'
- unsigned int p2 = filename.size();
- for (unsigned int i=p1; i<filename.size(); i++) {
- if (filename[i] == '.') { p2 = i; }
- }
-
- return filename.substr(p1, p2-p1);
-}
-
-
-static void initFaustDirectories()
-{
- char s[1024];
- getFaustPathname(s, 1024);
-
- gFaustDirectory = filedirname(s);
- gFaustSuperDirectory = filedirname(gFaustDirectory);
- gFaustSuperSuperDirectory = filedirname(gFaustSuperDirectory);
- if (gInputFiles.empty()) {
- gMasterDocument = "Unknown";
- gMasterDirectory = ".";
- gMasterName = "faustfx";
- gDocName = "faustdoc";
- } else {
- gMasterDocument = *gInputFiles.begin();
- gMasterDirectory = filedirname(gMasterDocument);
- gMasterName = fxname(gMasterDocument);
- gDocName = fxname(gMasterDocument);
- }
-}
-
-char* preProcess (char* file_route)
-{
-
- /****************************************************************
- 1 - process command line
- *****************************************************************/
- int argc = 3;
- char* argv[3];
- argv[0] = "faust";
- argv[1] = "-d";
- argv[2] = file_route;
-
- process_cmdline(argc, argv);
-
- if (gHelpSwitch) { printhelp(); exit(0); }
- if (gVersionSwitch) { printversion(); exit(0); }
-
- initFaustDirectories();
-#ifndef WIN32
- alarm(gTimeout);
-#endif
-
-
- /****************************************************************
- 2 - parse source files
- *****************************************************************/
-
- startTiming("parser");
-
-
- list<string>::iterator s;
- gResult2 = nil;
- yyerr = 0;
-
- if (gInputFiles.begin() == gInputFiles.end()) {
- cerr << "ERROR: no files specified;" << endl;
- cerr << "interpreter <program.dsp> [input.wav]." << endl;
- exit(1);
- }
- for (s = gInputFiles.begin(); s != gInputFiles.end(); s++) {
- if (s == gInputFiles.begin()) gMasterDocument = *s;
- gResult2 = cons(importFile(tree(s->c_str())), gResult2);
- }
- if (yyerr > 0) {
- //fprintf(stderr, "Erreur de parsing 2, count = %d \n", yyerr);
- exit(1);
- }
- gExpandedDefList = gReader.expandlist(gResult2);
-
- endTiming("parser");
-
- /****************************************************************
- 3 - evaluate 'process' definition
- *****************************************************************/
-
- startTiming("evaluation");
-
- Tree process = evalprocess(gExpandedDefList);
-
- if (gErrorCount > 0) {
- // cerr << "Total of " << gErrorCount << " errors during evaluation of : process = " << boxpp(process) << ";\n";
- cerr << "Total of " << gErrorCount << " errors during the compilation of " << gMasterDocument << ";\n";
- exit(1);
- }
-
- endTiming("evaluation");
-
- ostringstream result_stream;
- result_stream << boxpp(process);
- string result_string = result_stream.str();
- char* result_char = new char [result_string.length()+1];
- strcpy(result_char, result_string.c_str());;
-
- //cout << result_string.length() << endl;
- //cout << result_char << endl;
-
- // Karim Barkati: printing globals value
- //list<string> faustGlobals = {
- //cout << "gFaustSuperSuperDirectory = " << gFaustSuperSuperDirectory << endl;
- //cout << "gFaustSuperDirectory = " << gFaustSuperDirectory << endl;
- //cout << "gFaustDirectory = " << gFaustDirectory << endl;
- //cout << "gMasterDocument = " << gMasterDocument << endl;
- //cout << "gMasterDirectory = " << gMasterDirectory << endl;
- //cout << "gMasterName = " << gMasterName << endl;
-
- return result_char;
-}