/[svn]/linuxsampler/trunk/src/ls_instr_script.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/ls_instr_script.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2588 by schoenebeck, Sun Jun 1 14:44:38 2014 UTC revision 3308 by schoenebeck, Sat Jul 15 01:14:20 2017 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 Christian Schoenebeck   * Copyright (c) 2014-2016 Christian Schoenebeck
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# Line 10  Line 10 
10  #include "common/global.h"  #include "common/global.h"
11  #include "scriptvm/ScriptVM.h"  #include "scriptvm/ScriptVM.h"
12  #include "shell/CFmt.h"  #include "shell/CFmt.h"
13    #include "engines/common/InstrumentScriptVM.h"
14    #include "engines/gig/InstrumentScriptVM.h"
15    #include <iostream>
16    #include <fstream>
17    
18  /*  /*
19    This command line tool is currently merely for development and testing    This command line tool is currently merely for development and testing
20    purposes, regarding the real-time instrument script feature of the sampler.    purposes, regarding the real-time instrument script feature of the sampler.
21    You can use this command line application like this:    You can use this command line application like this:
22    
23    ls_instr_script < src/scriptvm/examples/helloworld.txt    ls_instr_script core < src/scriptvm/examples/helloworld.txt
24    
25    Which will peform 3 things:    Which will peform 3 things:
26    
# Line 28  Line 32 
32   */   */
33    
34  using namespace LinuxSampler;  using namespace LinuxSampler;
35    using namespace std;
36    
37  int main() {  static void printUsage() {
38      ScriptVM vm;      cout << "ls_instr_script - Parse real-time instrument script from stdin." << endl;
39      VMParserContext* parserContext = vm.loadScript(&std::cin);      cout << endl;
40        cout << "Usage: ls_instr_script ENGINE [OPTIONS]" << endl;
41        cout << endl;
42        cout << "    ENGINE\n";
43        cout << "        Either \"core\", \"gig\", \"sf2\" or \"sfz\"." << endl;
44        cout << endl;
45        cout << "    OPTIONS" << endl;
46        cout << "        --file FILE | -f FILE" << endl;
47        cout << "            Read from this file instead from stdin." << endl;
48        cout << endl;
49        cout << "        --syntax | -s" << endl;
50        cout << "            Prints the script to stdout with colored syntax highlighting" << endl;
51        cout << "            and exits immediately." << endl;
52        cout << endl;
53        cout << "        --debug-syntax | -ds" << endl;
54        cout << "            Prints a debugging representation (of the syntax" << endl;
55        cout << "            highlighting backend) of the parsed script to stdout and exits" << endl;
56        cout << "            immediately." << endl;
57        cout << endl;
58        cout << "        --auto-suspend" << endl;
59        cout << "            In contrast to the real sampler, this command line program " << endl;
60        cout << "            disables automatic suspension by the VM by default to ease " << endl;
61        cout << "            i.e. bench marking tasks and the like. By providing this " << endl;
62        cout << "            argument auto suspension will be enabled." << endl;
63        cout << endl;
64        cout << "If you pass \"core\" as argument, only the core language built-in" << endl;
65        cout << "variables and functions are available. However in this particular" << endl;
66        cout << "mode the program will not just parse the given script, but also" << endl;
67        cout << "execute the event handlers. All other arguments for ENGINE provide" << endl;
68        cout << "the sampler engine / sampler format specific additional built-in" << endl;
69        cout << "variables and functions, however they wil not be executed by this" << endl;
70        cout << "program." << endl;
71        cout << endl;
72    }
73    
74    static void printCodeWithSyntaxHighlighting(ScriptVM* vm);
75    static void dumpSyntaxHighlighting(ScriptVM* vm);
76    static String readTxtFromFile(String path);
77    
78    int main(int argc, char *argv[]) {
79        if (argc < 2) {
80            printUsage();
81            return -1;
82        }
83        String engine = argv[1];
84        String path;
85        bool runScript = false;
86    
87        ScriptVM* vm;
88        if (engine == "core") {
89            vm = new ScriptVM;
90            runScript = true;
91        } else if (engine == "sf2" || engine == "sfz") {
92            vm = new InstrumentScriptVM;
93        } else if (engine == "gig") {
94            vm = new gig::InstrumentScriptVM;
95        } else {
96            std::cerr << "Unknown ENGINE '" << engine << "'\n\n";
97            printUsage();
98            return -1;
99        }
100        vm->setAutoSuspendEnabled(false);
101    
102        // validate & parse arguments provided to this program
103        for (int iArg = 2; iArg < argc; ++iArg) {
104            const string opt = argv[iArg];
105            if (opt == "--") { // common for all command line tools: separator between initial option arguments and i.e. subsequent file arguments
106                iArg++;
107                break;
108            }
109            if (opt.substr(0, 1) != "-") break;
110    
111            if (opt == "-s" || opt == "--syntax") {
112                printCodeWithSyntaxHighlighting(vm);
113                return 0;
114            } else if (opt == "-ds" || opt == "--debug-syntax") {
115                dumpSyntaxHighlighting(vm);
116                return 0;
117            } else if (opt == "--auto-suspend") {
118                vm->setAutoSuspendEnabled(true);
119            } else if (opt == "-f" || opt == "--file") {
120                if (++iArg < argc)
121                    path = argv[iArg];
122            } else {
123                cerr << "Unknown option '" << opt << "'" << endl;
124                cerr << endl;
125                printUsage();
126                return -1;
127            }
128        }
129    
130        VMParserContext* parserContext;
131        if (path.empty())
132            parserContext = vm->loadScript(&std::cin);
133        else {
134            String txt = readTxtFromFile(path);
135            parserContext = vm->loadScript(txt);
136        }
137    
138      std::vector<ParserIssue> errors = parserContext->errors();      std::vector<ParserIssue> errors = parserContext->errors();
139      std::vector<ParserIssue> warnings = parserContext->warnings();      std::vector<ParserIssue> warnings = parserContext->warnings();
# Line 42  int main() { Line 144  int main() {
144      } else if (!errors.empty()) {      } else if (!errors.empty()) {
145          CFmt fmt; fmt.red();          CFmt fmt; fmt.red();
146          printf("EOF. Script parse completed with issues (%d errors, %d warnings):\n",          printf("EOF. Script parse completed with issues (%d errors, %d warnings):\n",
147                 errors.size(), warnings.size());                 int(errors.size()), int(warnings.size()));
148      } else {      } else {
149          CFmt fmt; fmt.yellow();          CFmt fmt; fmt.yellow();
150          printf("EOF. Script parse completed with issues (%d errors, %d warnings):\n",          printf("EOF. Script parse completed with issues (%d errors, %d warnings):\n",
151                 errors.size(), warnings.size());                 int(errors.size()), int(warnings.size()));
152      }      }
153      for (int i = 0; i < issues.size(); ++i) {      for (int i = 0; i < issues.size(); ++i) {
154          CFmt fmt;          CFmt fmt;
# Line 56  int main() { Line 158  int main() {
158      }      }
159    
160      printf("[Dumping parsed VM tree]\n");      printf("[Dumping parsed VM tree]\n");
161      vm.dumpParsedScript(parserContext);      vm->dumpParsedScript(parserContext);
162      printf("[End of parsed VM tree]\n");      printf("[End of parsed VM tree]\n");
163    
164      if (!errors.empty()) {      if (!errors.empty()) {
# Line 64  int main() { Line 166  int main() {
166          return -1;          return -1;
167      }      }
168    
169        if (!runScript) {
170            return 0;
171        }
172    
173      if (!parserContext->eventHandler(0)) {      if (!parserContext->eventHandler(0)) {
174          printf("No event handler exists. So nothing to execute.\n");          printf("No event handler exists. So nothing to execute.\n");
175          if (parserContext) delete parserContext;          if (parserContext) delete parserContext;
# Line 71  int main() { Line 177  int main() {
177      }      }
178    
179      printf("Preparing execution of script.\n");      printf("Preparing execution of script.\n");
180      VMExecContext* execContext = vm.createExecContext(parserContext);      VMExecContext* execContext = vm->createExecContext(parserContext);
181      for (int i = 0; parserContext->eventHandler(i); ++i) {      for (int i = 0; parserContext->eventHandler(i); ++i) {
182          VMEventHandler* handler = parserContext->eventHandler(i);          VMEventHandler* handler = parserContext->eventHandler(i);
183          printf("[Running event handler '%s']\n", handler->eventHandlerName().c_str());          printf("[Running event handler '%s']\n", handler->eventHandlerName().c_str());
184          VMExecStatus_t result = vm.exec(parserContext, execContext, handler);          VMExecStatus_t result = vm->exec(parserContext, execContext, handler);
185          CFmt fmt;          CFmt fmt;
186          if (result & VM_EXEC_ERROR) {          if (result & VM_EXEC_ERROR) {
187              fmt.red();              fmt.red();
# Line 95  int main() { Line 201  int main() {
201              printf("[Event handler '%s' finished with UNKNOWN status]\n", handler->eventHandlerName().c_str());              printf("[Event handler '%s' finished with UNKNOWN status]\n", handler->eventHandlerName().c_str());
202          }          }
203      }      }
204    
205      if (parserContext) delete parserContext;      if (parserContext) delete parserContext;
206      if (execContext) delete execContext;      if (execContext) delete execContext;
207        if (vm) delete vm;
208    
209      return 0;      return 0;
210  }  }
211    
212    static void printCodeWithSyntaxHighlighting(ScriptVM* vm) {
213        vector<VMSourceToken> tokens = vm->syntaxHighlighting(&std::cin);
214    
215        for (int i = 0; i < tokens.size(); ++i) {
216            const VMSourceToken& token = tokens[i];
217    
218            CFmt fmt;
219            if (token.isKeyword()) {
220                fmt.bold();
221            } else if (token.isVariableName()) {
222                fmt.magenta();
223            } else if (token.isIdentifier()) {
224                if (token.isEventHandlerName()) {
225                    fmt.bold();
226                    fmt.cyan();
227                } else { // a function ...
228                    fmt.cyan();
229                }
230            } else if (token.isNumberLiteral()) {
231                fmt.yellow();
232            } else if (token.isStringLiteral()) {
233                fmt.red();
234            } else if (token.isComment()) {
235                fmt.blue();
236            } else if (token.isPreprocessor()) {
237                fmt.green();
238            } else if (token.isNewLine()) {
239            }
240    
241            printf("%s", token.text().c_str());
242            fflush(stdout);
243        }
244    }
245    
246    static void dumpSyntaxHighlighting(ScriptVM* vm) {
247        vector<VMSourceToken> tokens = vm->syntaxHighlighting(&std::cin);
248    
249        for (int i = 0; i < tokens.size(); ++i) {
250            const VMSourceToken& token = tokens[i];
251            const char* type = "OTHER";
252            if (token.isKeyword()) {
253                type = "KEYWORD";
254            } else if (token.isVariableName()) {
255                type = "VARIABLE";
256            } else if (token.isIdentifier()) {
257                if (token.isEventHandlerName()) {
258                    type = "HANDLER_NAME";
259                } else { // a function ...
260                    type = "FUNCTION";
261                }
262            } else if (token.isNumberLiteral()) {
263                type = "NUMBER";
264            } else if (token.isStringLiteral()) {
265                type = "STRING";
266            } else if (token.isComment()) {
267                type = "COMMENT";
268            } else if (token.isPreprocessor()) {
269                type = "PREPROC";
270            } else if (token.isNewLine()) {
271                type = "NL";
272            }
273            printf("L%d,C%d: %s \"%s\"\n", token.firstLine(), token.firstColumn(), type, token.text().c_str());
274        }
275    }
276    
277    static String readTxtFromFile(String path) {
278        std::ifstream f(path.c_str(), std::ifstream::in);
279        String s;
280        s += (char) f.get();
281        while (f.good()) {
282            char c = f.get();
283            if (c == EOF) break;
284            s += c;
285        }
286        f.close();
287        return s;
288    }

Legend:
Removed from v.2588  
changed lines
  Added in v.3308

  ViewVC Help
Powered by ViewVC