--- /dev/null
+/************************************************************************
+ ************************************************************************
+ 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;
+}