FAUST compiler  0.9.9.6b8
main.cpp
Go to the documentation of this file.
1 /************************************************************************
2  ************************************************************************
3  FAUST compiler
4  Copyright (C) 2003-2012 GRAME, Centre National de Creation Musicale
5  ---------------------------------------------------------------------
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  ************************************************************************
20  ************************************************************************/
21 #define FAUSTVERSION "0.9.67"
22 
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <assert.h>
27 #include <limits.h>
28 
29 #ifndef WIN32
30 #include <unistd.h>
31 #include <sys/time.h>
32 #include "libgen.h"
33 #endif
34 
35 #include "compatibility.hh"
36 #include "signals.hh"
37 #include "sigtype.hh"
38 #include "sigtyperules.hh"
39 #include "sigprint.hh"
40 #include "simplify.hh"
41 #include "privatise.hh"
42 
43 #include "compile_scal.hh"
44 #include "compile_vect.hh"
45 #include "compile_sched.hh"
46 
47 #include "propagate.hh"
48 #include "errormsg.hh"
49 #include "ppbox.hh"
50 #include "enrobage.hh"
51 #include "eval.hh"
52 #include "description.hh"
53 #include "floats.hh"
54 #include "doc.hh"
55 
56 #include <map>
57 #include <string>
58 #include <vector>
59 #include <list>
60 #include <iostream>
61 #include <fstream>
62 #include <sstream>
63 
64 #include "sourcereader.hh"
65 
66 
67 // construction des representations graphiques
68 
69 #include "schema.h"
70 #include "drawschema.hh"
71 #include "timing.hh"
72 
73 using namespace std ;
74 
75 
76 /****************************************************************
77  Parser variables
78 *****************************************************************/
79 
80 
81 int yyparse();
82 
83 int yyerr;
84 extern int yydebug;
85 extern FILE* yyin;
88 
90 
91 map<Tree, set<Tree> > gMetaDataSet;
92 extern vector<Tree> gDocVector;
93 extern string gDocLang;
95 
96 /****************************************************************
97  Command line tools and arguments
98 *****************************************************************/
99 
100 //-- globals
106 string gMasterName;
107 string gDocName;
109 
110 //-- command line arguments
111 
112 bool gHelpSwitch = false;
113 bool gVersionSwitch = false;
114 bool gDetailsSwitch = false;
115 bool gTimingSwitch = false;
116 bool gDrawSignals = false;
117 bool gShadowBlur = false; // note: svg2pdf doesn't like the blur filter
118 bool gGraphSwitch = false;
119 bool gDrawPSSwitch = false;
120 bool gDrawSVGSwitch = false;
121 bool gPrintXMLSwitch = false;
122 bool gPrintDocSwitch = false;
123 bool gLatexDocSwitch = true; // Only LaTeX outformat is handled for the moment.
124 bool gStripDocSwitch = false; // Strip <mdoc> content from doc listings.
126 int gFoldThreshold = 25;
127 int gMaxNameSize = 40;
128 bool gSimpleNames = false;
129 bool gSimplifyDiagrams = false;
130 bool gLessTempSwitch = false;
131 int gMaxCopyDelay = 16;
132 string gArchFile;
133 string gOutputFile;
134 list<string> gInputFiles;
135 
136 bool gPatternEvalMode = false;
137 
138 bool gVectorSwitch = false;
139 bool gDeepFirstSwitch= false;
140 int gVecSize = 32;
142 
143 bool gOpenMPSwitch = false;
144 bool gOpenMPLoop = false;
145 bool gSchedulerSwitch = false;
146 bool gGroupTaskSwitch= false;
147 
148 bool gUIMacroSwitch = false;
149 bool gDumpNorm = false;
150 
151 int gTimeout = 120; // time out to abort compiler (in seconds)
152 
153 int gFloatSize = 1;
154 
155 bool gPrintFileListSwitch = false;
156 bool gInlineArchSwitch = false;
157 
158 string gClassName = "mydsp";
159 bool gExportDSP = false;
160 
161 list<string> gImportDirList; // dir list enrobage.cpp/fopensearch() searches for imports, etc.
162 string gOutputDir; // output directory for additionnal generated ressources : -SVG, XML...etc...
163 bool gInPlace = false; // add cache to input for correct in-place computations
164 
165 //-- command line tools
166 
167 static bool isCmd(const char* cmd, const char* kw1)
168 {
169  return (strcmp(cmd, kw1) == 0);
170 }
171 
172 static bool isCmd(const char* cmd, const char* kw1, const char* kw2)
173 {
174  return (strcmp(cmd, kw1) == 0) || (strcmp(cmd, kw2) == 0);
175 }
176 
177 string makeDrawPath()
178 {
179  if (gOutputDir != "") {
180  return gOutputDir + "/" + gMasterName + ".dsp";
181  } else {
182  return gMasterDocument;
183  }
184 }
185 
186 static string makeDrawPathNoExt()
187 {
188  if (gOutputDir != "") {
189  return gOutputDir + "/" + gMasterName;
190  } else if (gMasterDocument.length() >= 4 && gMasterDocument.substr(gMasterDocument.length() - 4) == ".dsp") {
191  return gMasterDocument.substr(0, gMasterDocument.length() - 4);
192  } else {
193  return gMasterDocument;
194  }
195 }
196 
197 bool process_cmdline(int argc, char* argv[])
198 {
199  int i=1; int err=0;
200 
201  while (i<argc) {
202 
203  if (isCmd(argv[i], "-h", "--help")) {
204  gHelpSwitch = true;
205  i += 1;
206 
207  } else if (isCmd(argv[i], "-v", "--version")) {
208  gVersionSwitch = true;
209  i += 1;
210 
211  } else if (isCmd(argv[i], "-d", "--details")) {
212  gDetailsSwitch = true;
213  i += 1;
214 
215  } else if (isCmd(argv[i], "-a", "--architecture")) {
216  gArchFile = argv[i+1];
217  i += 2;
218 
219  } else if (isCmd(argv[i], "-o")) {
220  gOutputFile = argv[i+1];
221  i += 2;
222 
223  } else if (isCmd(argv[i], "-ps", "--postscript")) {
224  gDrawPSSwitch = true;
225  i += 1;
226 
227  } else if (isCmd(argv[i], "-xml", "--xml")) {
228  gPrintXMLSwitch = true;
229  i += 1;
230 
231  } else if (isCmd(argv[i], "-tg", "--task-graph")) {
232  gGraphSwitch = true;
233  i += 1;
234 
235  } else if (isCmd(argv[i], "-sg", "--signal-graph")) {
236  gDrawSignals = true;
237  i += 1;
238 
239  } else if (isCmd(argv[i], "-blur", "--shadow-blur")) {
240  gShadowBlur = true;
241  i += 1;
242 
243  } else if (isCmd(argv[i], "-svg", "--svg")) {
244  gDrawSVGSwitch = true;
245  i += 1;
246 
247  } else if (isCmd(argv[i], "-f", "--fold")) {
248  gFoldThreshold = atoi(argv[i+1]);
249  i += 2;
250 
251  } else if (isCmd(argv[i], "-mns", "--max-name-size")) {
252  gMaxNameSize = atoi(argv[i+1]);
253  i += 2;
254 
255  } else if (isCmd(argv[i], "-sn", "--simple-names")) {
256  gSimpleNames = true;
257  i += 1;
258 
259  } else if (isCmd(argv[i], "-lb", "--left-balanced")) {
260  gBalancedSwitch = 0;
261  i += 1;
262 
263  } else if (isCmd(argv[i], "-mb", "--mid-balanced")) {
264  gBalancedSwitch = 1;
265  i += 1;
266 
267  } else if (isCmd(argv[i], "-rb", "--right-balanced")) {
268  gBalancedSwitch = 2;
269  i += 1;
270 
271  } else if (isCmd(argv[i], "-lt", "--less-temporaries")) {
272  gLessTempSwitch = true;
273  i += 1;
274 
275  } else if (isCmd(argv[i], "-mcd", "--max-copy-delay")) {
276  gMaxCopyDelay = atoi(argv[i+1]);
277  i += 2;
278 
279  } else if (isCmd(argv[i], "-sd", "--simplify-diagrams")) {
280  gSimplifyDiagrams = true;
281  i += 1;
282 
283  } else if (isCmd(argv[i], "-vec", "--vectorize")) {
284  gVectorSwitch = true;
285  i += 1;
286 
287  } else if (isCmd(argv[i], "-dfs", "--deepFirstScheduling")) {
288  gDeepFirstSwitch = true;
289  i += 1;
290 
291  } else if (isCmd(argv[i], "-vs", "--vec-size")) {
292  gVecSize = atoi(argv[i+1]);
293  i += 2;
294 
295  } else if (isCmd(argv[i], "-lv", "--loop-variant")) {
296  gVectorLoopVariant = atoi(argv[i+1]);
297  i += 2;
298 
299  } else if (isCmd(argv[i], "-omp", "--openMP")) {
300  gOpenMPSwitch = true;
301  i += 1;
302 
303  } else if (isCmd(argv[i], "-pl", "--par-loop")) {
304  gOpenMPLoop = true;
305  i += 1;
306 
307  } else if (isCmd(argv[i], "-sch", "--scheduler")) {
308  gSchedulerSwitch = true;
309  i += 1;
310 
311  } else if (isCmd(argv[i], "-g", "--groupTasks")) {
312  gGroupTaskSwitch = true;
313  i += 1;
314 
315  } else if (isCmd(argv[i], "-uim", "--user-interface-macros")) {
316  gUIMacroSwitch = true;
317  i += 1;
318 
319  } else if (isCmd(argv[i], "-t", "--timeout")) {
320  gTimeout = atoi(argv[i+1]);
321  i += 2;
322 
323  } else if (isCmd(argv[i], "-time", "--compilation-time")) {
324  gTimingSwitch = true;
325  i += 1;
326 
327  // double float options
328  } else if (isCmd(argv[i], "-single", "--single-precision-floats")) {
329  gFloatSize = 1;
330  i += 1;
331 
332  } else if (isCmd(argv[i], "-double", "--double-precision-floats")) {
333  gFloatSize = 2;
334  i += 1;
335 
336  } else if (isCmd(argv[i], "-quad", "--quad-precision-floats")) {
337  gFloatSize = 3;
338  i += 1;
339 
340  } else if (isCmd(argv[i], "-mdoc", "--mathdoc")) {
341  gPrintDocSwitch = true;
342  i += 1;
343 
344  } else if (isCmd(argv[i], "-mdlang", "--mathdoc-lang")) {
345  gDocLang = argv[i+1];
346  i += 2;
347 
348  } else if (isCmd(argv[i], "-stripmdoc", "--strip-mdoc-tags")) {
349  gStripDocSwitch = true;
350  i += 1;
351 
352  } else if (isCmd(argv[i], "-flist", "--file-list")) {
353  gPrintFileListSwitch = true;
354  i += 1;
355 
356  } else if (isCmd(argv[i], "-norm", "--normalized-form")) {
357  gDumpNorm = true;
358  i += 1;
359 
360  } else if (isCmd(argv[i], "-cn", "--class-name")) {
361  gClassName = argv[i+1];
362  i += 2;
363 
364  } else if (isCmd(argv[i], "-i", "--inline-architecture-files")) {
365  gInlineArchSwitch = true;
366  i += 1;
367 
368  } else if (isCmd(argv[i], "-e", "--export-dsp")) {
369  gExportDSP = true;
370  i += 1;
371 
372  } else if (isCmd(argv[i], "-I", "--import-dir")) {
373 
374  char temp[PATH_MAX+1];
375  char* path = realpath(argv[i+1], temp);
376  if (path == 0) {
377  std::cerr << "ERROR : invalid directory path " << argv[i+1] << std::endl;
378  exit(-1);
379  } else {
380  gImportDirList.push_back(path);
381  i += 2;
382  }
383  } else if (isCmd(argv[i], "-O", "--output-dir")) {
384 
385  char temp[PATH_MAX+1];
386  char* path = realpath(argv[i+1], temp);
387  if (path == 0) {
388  std::cerr << "ERROR : invalid directory path " << argv[i+1] << std::endl;
389  exit(-1);
390  } else {
391  gOutputDir = path;
392  i += 2;
393  }
394 
395  } else if (isCmd(argv[i], "-inpl", "--in-place")) {
396  gInPlace = true;
397  i += 1;
398 
399  } else if (argv[i][0] != '-') {
400  const char* url = argv[i];
401  if (check_url(url)) {
402  gInputFiles.push_back(url);
403  }
404  i++;
405 
406  } else {
407  std::cerr << "faust: unrecognized option \"" << argv[i] <<"\"" << endl;
408  i++;
409  err++;
410  }
411  }
412 
413  // adjust related options
415 
416  if (gInPlace && gVectorSwitch) {
417  std::cerr << "ERROR : 'in-place' option can only be used in scalar mode" << endl;
418  exit(-1);
419  }
420 
421  return err == 0;
422 }
423 
424 
425 
426 /****************************************************************
427  Help and Version information
428 *****************************************************************/
429 
430 
431 
433 {
434  cout << "FAUST, DSP to C++ compiler, Version " << FAUSTVERSION << "\n";
435  cout << "Copyright (C) 2002-2014, GRAME - Centre National de Creation Musicale. All rights reserved. \n\n";
436 }
437 
438 
439 void printhelp()
440 {
441  printversion();
442  cout << "usage: faust [options] file1 [file2 ...]\n";
443  cout << "\twhere options represent zero or more compiler options \n\tand fileN represents a faust source file (.dsp extension).\n";
444 
445  cout << "\noptions :\n";
446  cout << "---------\n";
447 
448  cout << "-h \t\tprint this --help message\n";
449  cout << "-v \t\tprint compiler --version information\n";
450  cout << "-d \t\tprint compilation --details\n";
451  cout << "-tg \t\tprint the internal --task-graph in dot format file\n";
452  cout << "-sg \t\tprint the internal --signal-graph in dot format file\n";
453  cout << "-ps \t\tprint block-diagram --postscript file\n";
454  cout << "-svg \t\tprint block-diagram --svg file\n";
455  cout << "-mdoc \t\tprint --mathdoc of a Faust program in LaTeX format in a -mdoc directory\n";
456  cout << "-mdlang <l> \tload --mathdoc-lang <l> if translation file exists (<l> = en, fr, ...)\n";
457  cout << "-stripdoc \tapply --strip-mdoc-tags when printing Faust -mdoc listings\n";
458  cout << "-sd \t\ttry to further --simplify-diagrams before drawing them\n";
459  cout << "-f <n> \t\t--fold <n> threshold during block-diagram generation (default 25 elements) \n";
460  cout << "-mns <n> \t--max-name-size <n> threshold during block-diagram generation (default 40 char)\n";
461  cout << "-sn \t\tuse --simple-names (without arguments) during block-diagram generation\n";
462  cout << "-xml \t\tgenerate an --xml description file\n";
463  cout << "-blur \t\tadd a --shadow-blur to SVG boxes\n";
464  cout << "-lb \t\tgenerate --left-balanced expressions\n";
465  cout << "-mb \t\tgenerate --mid-balanced expressions (default)\n";
466  cout << "-rb \t\tgenerate --right-balanced expressions\n";
467  cout << "-lt \t\tgenerate --less-temporaries in compiling delays\n";
468  cout << "-mcd <n> \t--max-copy-delay <n> threshold between copy and ring buffer implementation (default 16 samples)\n";
469  cout << "-a <file> \tC++ architecture file\n";
470  cout << "-i \t\t--inline-architecture-files \n";
471  cout << "-cn <name> \t--class-name <name> specify the name of the dsp class to be used instead of mydsp \n";
472  cout << "-t <sec> \t--timeout <sec>, abort compilation after <sec> seconds (default 120)\n";
473  cout << "-time \t\t--compilation-time, flag to display compilation phases timing information\n";
474  cout << "-o <file> \tC++ output file\n";
475  cout << "-vec \t--vectorize generate easier to vectorize code\n";
476  cout << "-vs <n> \t--vec-size <n> size of the vector (default 32 samples)\n";
477  cout << "-lv <n> \t--loop-variant [0:fastest (default), 1:simple] \n";
478  cout << "-omp \t--openMP generate OpenMP pragmas, activates --vectorize option\n";
479  cout << "-pl \t--par-loop generate parallel loops in --openMP mode\n";
480  cout << "-sch \t--scheduler generate tasks and use a Work Stealing scheduler, activates --vectorize option\n";
481  cout << "-dfs \t--deepFirstScheduling schedule vector loops in deep first order\n";
482  cout << "-g \t\t--groupTasks group single-threaded sequential tasks together when -omp or -sch is used\n";
483  cout << "-uim \t--user-interface-macros add user interface macro definitions in the C++ code\n";
484  cout << "-single \tuse --single-precision-floats for internal computations (default)\n";
485  cout << "-double \tuse --double-precision-floats for internal computations\n";
486  cout << "-quad \t\tuse --quad-precision-floats for internal computations\n";
487  cout << "-flist \t\tuse --file-list used to eval process\n";
488  cout << "-norm \t\t--normalized-form prints signals in normalized form and exits\n";
489  cout << "-I <dir> \t--import-dir <dir> add the directory <dir> to the import search path\n";
490  cout << "-O <dir> \t--output-dir <dir> specify the relative directory of the generated C++ output, and the output directory of additional generated files (SVG, XML...)\n";
491  cout << "-e \t--export-dsp export expanded DSP (all included libraries) \n";
492  cout << "-inpl \t--in-place generates code working when input and output buffers are the same (in scalar mode only) \n";
493  cout << "\nexample :\n";
494  cout << "---------\n";
495 
496  cout << "faust -a jack-gtk.cpp -o myfx.cpp myfx.dsp\n";
497 }
498 
499 
500 void printheader(ostream& dst)
501 {
502  // defines the metadata we want to print as comments at the begin of in the C++ file
503  set<Tree> selectedKeys;
504  selectedKeys.insert(tree("name"));
505  selectedKeys.insert(tree("author"));
506  selectedKeys.insert(tree("copyright"));
507  selectedKeys.insert(tree("license"));
508  selectedKeys.insert(tree("version"));
509 
510  dst << "//-----------------------------------------------------" << endl;
511  for (map<Tree, set<Tree> >::iterator i = gMetaDataSet.begin(); i != gMetaDataSet.end(); i++) {
512  if (selectedKeys.count(i->first)) {
513  dst << "// " << *(i->first);
514  const char* sep = ": ";
515  for (set<Tree>::iterator j = i->second.begin(); j != i->second.end(); ++j) {
516  dst << sep << **j;
517  sep = ", ";
518  }
519  dst << endl;
520  }
521  }
522 
523  dst << "//" << endl;
524  dst << "// Code generated with Faust " << FAUSTVERSION << " (http://faust.grame.fr)" << endl;
525  dst << "//-----------------------------------------------------" << endl;
526 }
527 
528 
529 
530 
531 /****************************************************************
532  MAIN
533 *****************************************************************/
534 
535 
536 
541 static string fxname(const string& filename)
542 {
543  // determine position right after the last '/' or 0
544  unsigned int p1 = 0;
545  for (unsigned int i=0; i<filename.size(); i++) {
546  if (filename[i] == '/') { p1 = i+1; }
547  }
548 
549  // determine position of the last '.'
550  unsigned int p2 = (int)filename.size();
551  for (unsigned int i=p1; i<filename.size(); i++) {
552  if (filename[i] == '.') { p2 = i; }
553  }
554 
555  return filename.substr(p1, p2-p1);
556 }
557 
558 
559 static void initFaustDirectories()
560 {
561  char s[1024];
562  getFaustPathname(s, 1024);
563 
567  if (gInputFiles.empty()) {
568  gMasterDocument = "Unknown";
569  gMasterDirectory = ".";
570  gMasterName = "faustfx";
571  gDocName = "faustdoc";
572  } else {
573  gMasterDocument = *gInputFiles.begin();
577  }
578 }
579 
580 
581 
582 int main (int argc, char* argv[])
583 {
584 
585  /****************************************************************
586  1 - process command line
587  *****************************************************************/
588 
589  process_cmdline(argc, argv);
590 
591  if (gHelpSwitch) { printhelp(); exit(0); }
592  if (gVersionSwitch) { printversion(); exit(0); }
593 
595  alarm(gTimeout);
596 
597 
598  /****************************************************************
599  2 - parse source files
600  *****************************************************************/
601 
602  startTiming("parser");
603 
604  list<string>::iterator s;
605  gResult2 = nil;
606  yyerr = 0;
607 
608  if (gInputFiles.begin() == gInputFiles.end()) {
609  exit(1);
610  }
611  for (s = gInputFiles.begin(); s != gInputFiles.end(); s++) {
612  if (s == gInputFiles.begin()) {
613  gMasterDocument = *s;
614  }
615  gResult2 = cons(importFile(tree(s->c_str())), gResult2);
616  }
617  if (yyerr > 0) {
618  cerr << "ERROR : paorsing count = " << yyerr << endl;
619  exit(1);
620  }
622 
623  endTiming("parser");
624 
625  /****************************************************************
626  3 - evaluate 'process' definition
627  *****************************************************************/
628 
629  startTiming("evaluation");
630 
631 
632  Tree process = evalprocess(gExpandedDefList);
633 
634  if (gErrorCount > 0) {
635  // cerr << "Total of " << gErrorCount << " errors during evaluation of : process = " << boxpp(process) << ";\n";
636  cerr << "Total of " << gErrorCount << " errors during the compilation of " << gMasterDocument << ";\n";
637  exit(1);
638  }
639 
640 
641  if (gDetailsSwitch) { cerr << "process = " << boxpp(process) << ";\n"; }
642 
643  if (gDrawPSSwitch || gDrawSVGSwitch) {
644  string projname = makeDrawPathNoExt();
645  if (gDrawPSSwitch) { drawSchema( process, subst("$0-ps", projname).c_str(), "ps" ); }
646  if (gDrawSVGSwitch) { drawSchema( process, subst("$0-svg", projname).c_str(), "svg" ); }
647  }
648 
649  int numInputs, numOutputs;
650  if (!getBoxType(process, &numInputs, &numOutputs)) {
651  cerr << "ERROR during the evaluation of process : "
652  << boxpp(process) << endl;
653  exit(1);
654  }
655 
656  if (gDetailsSwitch) {
657  cerr <<"process has " << numInputs <<" inputs, and " << numOutputs <<" outputs" << endl;
658  }
659 
660  endTiming("evaluation");
661 
662  if (gExportDSP) {
663  ofstream xout(subst("$0_exp.dsp", makeDrawPathNoExt()).c_str());
664  xout << "process = " << boxpp(process) << ";" << endl;
665  return 0;
666  }
667 
668  /****************************************************************
669  3.5 - output file list is needed
670  *****************************************************************/
671  if (gPrintFileListSwitch) {
672  cout << "******* ";
673  // print the pathnames of the files used to evaluate process
674  vector<string> pathnames = gReader.listSrcFiles();
675  for (unsigned int i=0; i< pathnames.size(); i++) cout << pathnames[i] << ' ';
676  cout << endl;
677 
678  }
679 
680 
681  /****************************************************************
682  4 - compute output signals of 'process'
683  *****************************************************************/
684 
685  startTiming("propagation");
686 
687 
688  Tree lsignals = boxPropagateSig(nil, process , makeSigInputList(numInputs) );
689  if (gDetailsSwitch) { cerr << "output signals are : " << endl; printSignal(lsignals, stderr); }
690 
691  endTiming("propagation");
692 
693 
694  /****************************************************************
695  5 - translate output signals into C++ code
696  *****************************************************************/
697 
698  startTiming("compilation");
699 
700  Compiler* C;
701  if (gSchedulerSwitch) C = new SchedulerCompiler(gClassName, "dsp", numInputs, numOutputs);
702  else if (gVectorSwitch) C = new VectorCompiler(gClassName, "dsp", numInputs, numOutputs);
703  else C = new ScalarCompiler(gClassName, "dsp", numInputs, numOutputs);
704 
707 
708  C->compileMultiSignal(lsignals);
709 
710  endTiming("compilation");
711 
712  /****************************************************************
713  6 - generate XML description (if required)
714  *****************************************************************/
715 
716  if (gPrintXMLSwitch) {
717  Description* D = C->getDescription(); assert(D);
718  ofstream xout(subst("$0.xml", makeDrawPath()).c_str());
719 
720  if(gMetaDataSet.count(tree("name"))>0) D->name(tree2str(*(gMetaDataSet[tree("name")].begin())));
721  if(gMetaDataSet.count(tree("author"))>0) D->author(tree2str(*(gMetaDataSet[tree("author")].begin())));
722  if(gMetaDataSet.count(tree("copyright"))>0) D->copyright(tree2str(*(gMetaDataSet[tree("copyright")].begin())));
723  if(gMetaDataSet.count(tree("license"))>0) D->license(tree2str(*(gMetaDataSet[tree("license")].begin())));
724  if(gMetaDataSet.count(tree("version"))>0) D->version(tree2str(*(gMetaDataSet[tree("version")].begin())));
725 
726  D->className(gClassName);
727  D->inputs(C->getClass()->inputs());
728  D->outputs(C->getClass()->outputs());
729 
730  D->print(0, xout);
731  }
732 
733 
734  /****************************************************************
735  7 - generate documentation from Faust comments (if required)
736  *****************************************************************/
737 
738 
739  if (gPrintDocSwitch) {
740  if (gLatexDocSwitch) {
741  printDoc(subst("$0-mdoc", makeDrawPathNoExt()).c_str(), "tex", FAUSTVERSION);
742  }
743  }
744 
745 
746 
747 
748  /****************************************************************
749  8 - generate output file
750  *****************************************************************/
751 
752  ostream* dst;
753  istream* enrobage;
754  //istream* intrinsic;
755 
756  if (gOutputFile != "") {
757  string outpath = (gOutputDir != "") ? (gOutputDir + "/" + gOutputFile) : gOutputFile;
758  dst = new ofstream(outpath.c_str());
759  } else {
760  dst = &cout;
761  }
762 
763  if (gArchFile != "") {
764  if ( (enrobage = open_arch_stream(gArchFile.c_str())) ) {
765  printheader(*dst);
766  C->getClass()->printLibrary(*dst);
767  C->getClass()->printIncludeFile(*dst);
768  C->getClass()->printAdditionalCode(*dst);
769 
770  streamCopyUntil(*enrobage, *dst, "<<includeIntrinsic>>");
771 
772 // if ( gVectorSwitch && (intrinsic = open_arch_stream("intrinsic.hh")) ) {
773 // streamCopyUntilEnd(*intrinsic, *dst);
774 // }
775 
776  if (gSchedulerSwitch) {
777  istream* scheduler_include = open_arch_stream("scheduler.cpp");
778  if (scheduler_include) {
779  streamCopy(*scheduler_include, *dst);
780  } else {
781  cerr << "ERROR : can't include \"scheduler.cpp\", file not found" << endl;
782  exit(1);
783  }
784  }
785 
786  streamCopyUntil(*enrobage, *dst, "<<includeclass>>");
787  printfloatdef(*dst);
788 
789  C->getClass()->println(0,*dst);
790  streamCopyUntilEnd(*enrobage, *dst);
791  } else {
792  cerr << "ERROR : can't open architecture file " << gArchFile << endl;
793  return 1;
794  }
795  } else {
796  printheader(*dst);
797  printfloatdef(*dst);
798  C->getClass()->printLibrary(*dst);
799  C->getClass()->printIncludeFile(*dst);
800  C->getClass()->printAdditionalCode(*dst);
801  C->getClass()->println(0,*dst);
802  }
803 
804 
805  /****************************************************************
806  9 - generate the task graph file in dot format
807  *****************************************************************/
808 
809  if (gGraphSwitch) {
810  ofstream dotfile(subst("$0.dot", makeDrawPath()).c_str());
811  C->getClass()->printGraphDotFormat(dotfile);
812  }
813 
814  delete C;
815  return 0;
816 }
Description * name(const string &s)
Definition: description.hh:58
int yyerr
Definition: main.cpp:83
Tree gExpandedDefList
Definition: main.cpp:108
bool gInlineArchSwitch
Definition: main.cpp:156
bool gGroupTaskSwitch
Definition: main.cpp:146
tvec gWaveForm
Definition: main.cpp:94
Description * className(const string &s)
Definition: description.hh:64
virtual void compileMultiSignal(Tree lsig)=0
Compile a list of FAUST signals into a scalar C++ class.
Definition: compile_scal.hh:40
int outputs()
Definition: klass.hh:210
Description * author(const string &s)
Definition: description.hh:59
int gVecSize
Definition: main.cpp:140
static string fxname(const string &filename)
transform a filename "faust/example/noise.dsp" into the corresponding fx name "noise" ...
Definition: main.cpp:541
SourceReader gReader
Definition: main.cpp:89
Description * copyright(const string &s)
Definition: description.hh:60
string gFaustSuperSuperDirectory
Definition: main.cpp:101
virtual void printAdditionalCode(ostream &fout)
Print additional functions required by the generated code.
Definition: klass.cpp:217
bool gExportDSP
Definition: main.cpp:159
void drawSchema(Tree bd, const char *projname, const char *dev)
The entry point to generate from a block diagram as a set of svg files stored in the directory "
Definition: drawschema.cpp:161
void printfloatdef(std::ostream &fout)
Definition: floats.cpp:52
Tree cons(Tree a, Tree b)
Definition: list.hh:124
Compile a list of FAUST signals into a vector C++ class.
Definition: compile_vect.hh:39
virtual void println(int n, ostream &fout)
Print a full C++ class corresponding to a Faust dsp.
Definition: klass.cpp:737
void endTiming(const char *msg)
Definition: timing.cpp:43
bool gPrintXMLSwitch
Definition: main.cpp:121
FILE * yyin
Definition: faustlexer.cpp:351
void streamCopyUntil(istream &src, ostream &dst, const string &until)
Copy src to dst until specific line.
Definition: enrobage.cpp:183
bool gLatexDocSwitch
Definition: main.cpp:123
bool gDetailsSwitch
Definition: main.cpp:114
int gMaxCopyDelay
Definition: main.cpp:131
bool gDrawSVGSwitch
Definition: main.cpp:120
vector< Tree > tvec
Definition: tree.hh:90
bool gPrintDocSwitch
Definition: main.cpp:122
bool gSimpleNames
Definition: main.cpp:128
A CTree = (Node x [CTree]) is a Node associated with a list of subtrees called branches.
Definition: tree.hh:109
ifstream * open_arch_stream(const char *filename)
Try to open an architecture file searching in various directories.
Definition: enrobage.cpp:220
int gBalancedSwitch
Definition: main.cpp:125
string gFaustDirectory
Definition: main.cpp:103
bool gOpenMPSwitch
Definition: main.cpp:143
string gOutputDir
Definition: main.cpp:162
list< string > gImportDirList
Definition: main.cpp:161
map< Tree, set< Tree > > gMetaDataSet
Definition: main.cpp:91
string gDocLang
Definition: doc.cpp:118
Interface of the block diagram evaluator.
string gMasterDocument
Definition: main.cpp:104
int gVectorLoopVariant
Definition: main.cpp:141
virtual void printGraphDotFormat(ostream &fout)
Print the loop graph in dot format.
Definition: klass.cpp:522
string makeDrawPath()
Definition: main.cpp:177
void streamCopyUntilEnd(istream &src, ostream &dst)
Copy src to dst until end.
Definition: enrobage.cpp:207
vector< Tree > gDocVector
Contains parsed trees: DOCTXT, DOCEQN, DOCDGM.
Definition: doc.cpp:109
bool gDrawSignals
Definition: main.cpp:116
void getFaustPathname(char *str, unsigned int size)
string gDocName
Contains the filename for out documentation.
Definition: main.cpp:107
void print(int n, ostream &fout)
Tree boxPropagateSig(Tree path, Tree box, const siglist &lsig)
Top level propagate a list of signals into a block diagram.
Definition: propagate.cpp:501
bool gTimingSwitch
Definition: main.cpp:115
Tree evalprocess(Tree eqlist)
Eval "process" from a list of definitions.
Definition: eval.cpp:100
int gFloatSize
Definition: main.cpp:153
vector< string > listSrcFiles()
Return a vector of pathnames representing the list of all the source files that have been required to...
void setDescription(Description *descr)
Definition: compile.hh:69
string subst(const string &model, const vector< string > &args)
Text substitution.
Definition: Text.cpp:47
Tree gResult2
Definition: main.cpp:87
virtual void printIncludeFile(ostream &fout)
Print the required include files.
Definition: klass.cpp:199
bool gPatternEvalMode
Definition: main.cpp:136
int gMaxNameSize
Definition: main.cpp:127
void startTiming(const char *msg)
Definition: timing.cpp:34
void printSignal(Tree sig, FILE *out, int prec)
Definition: sigprint.cpp:85
bool check_url(const char *filename)
Check if an URL exists.
Definition: enrobage.cpp:296
bool gVersionSwitch
Definition: main.cpp:113
bool gShadowBlur
Definition: main.cpp:117
string gMasterName
Definition: main.cpp:106
string gMasterDirectory
Definition: main.cpp:105
void streamCopy(istream &src, ostream &dst)
Copy src to dst.
Definition: enrobage.cpp:199
Tree importFile(Tree filename)
Definition: boxes.cpp:300
Tree expandlist(Tree ldef)
Return the list of definitions where all imports have been expanded.
Description * inputs(int n)
Definition: description.hh:65
static bool isCmd(const char *cmd, const char *kw1)
Definition: main.cpp:167
Description * outputs(int n)
Definition: description.hh:66
Description * license(const string &s)
Definition: description.hh:61
int yydebug
int gErrorCount
Definition: errormsg.cpp:31
bool gDrawPSSwitch
Definition: main.cpp:119
bool gDumpNorm
Definition: main.cpp:149
siglist makeSigInputList(int n)
Fabrique une liste de n entrées.
Definition: propagate.cpp:96
list< string > gInputFiles
Definition: main.cpp:134
bool gOpenMPLoop
Definition: main.cpp:144
bool gPrintFileListSwitch
Definition: main.cpp:155
bool gInPlace
Definition: main.cpp:163
void printhelp()
Definition: main.cpp:439
int yyparse()
Tree tree(const Node &n)
Definition: tree.hh:186
Description * version(const string &s)
Definition: description.hh:62
string filedirname(const string &name)
returns a string containing the dirname of name If no dirname, returns "."
Definition: enrobage.cpp:568
bool gDeepFirstSwitch
Definition: main.cpp:139
Description * getDescription()
Definition: compile.hh:70
static string makeDrawPathNoExt()
Definition: main.cpp:186
bool gSchedulerSwitch
Definition: main.cpp:145
int gTimeout
Definition: main.cpp:151
void printversion()
Definition: main.cpp:432
string gOutputFile
Definition: main.cpp:133
bool gStripDocSwitch
Definition: main.cpp:124
bool gGraphSwitch
Definition: main.cpp:118
Definition: ppbox.hh:58
bool gUIMacroSwitch
Definition: main.cpp:148
bool gHelpSwitch
Definition: main.cpp:112
bool gSimplifyDiagrams
Definition: main.cpp:129
Tree nil
Definition: list.cpp:116
void printheader(ostream &dst)
Definition: main.cpp:500
string gClassName
Definition: main.cpp:158
string gArchFile
Definition: main.cpp:132
Tree gResult
Definition: main.cpp:86
int gFoldThreshold
Definition: main.cpp:126
static void initFaustDirectories()
Definition: main.cpp:559
string gFaustSuperDirectory
Definition: main.cpp:102
API to the typing system of signals.
Compile a list of FAUST signals into a vector C++ class.
int main(int argc, char *argv[])
Definition: main.cpp:582
virtual void printLibrary(ostream &fout)
Print the required C++ libraries as comments in source code.
Definition: klass.cpp:182
int inputs()
Definition: klass.hh:209
void printDoc(const char *projname, const char *docdev, const char *faustversion)
The entry point to generate faust doc files.
Definition: doc.cpp:224
const char * tree2str(Tree t)
if t has a node of type symbol, return its name otherwise error
Definition: tree.cpp:278
#define FAUSTVERSION
Definition: main.cpp:21
Klass * getClass()
Definition: compile.hh:67
bool getBoxType(Tree box, int *inum, int *onum)
Return the type (number of inputs and outputs) of a box or false if undefined.
Definition: boxtype.cpp:63
bool process_cmdline(int argc, char *argv[])
Definition: main.cpp:197
bool gVectorSwitch
Definition: main.cpp:138
bool gLessTempSwitch
Definition: main.cpp:130