/[svn]/linuxsampler/trunk/src/shell/lscp.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/shell/lscp.cpp

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

revision 2533 by schoenebeck, Wed Mar 5 17:29:15 2014 UTC revision 2534 by schoenebeck, Sun Mar 9 21:34:03 2014 UTC
# Line 39  static int g_linesActive = 0; Line 39  static int g_linesActive = 0;
39  static const String g_prompt = "lscp=# ";  static const String g_prompt = "lscp=# ";
40  static std::vector<String> g_commandHistory;  static std::vector<String> g_commandHistory;
41  static int g_commandHistoryIndex = -1;  static int g_commandHistoryIndex = -1;
42    static String g_doc;
43    
44  static void printUsage() {  static void printUsage() {
45      cout << "lscp - The LinuxSampler Control Protocol (LSCP) Shell." << endl;      cout << "lscp - The LinuxSampler Control Protocol (LSCP) Shell." << endl;
# Line 51  static void printUsage() { Line 52  static void printUsage() {
52      cout << endl;      cout << endl;
53      cout << "   --no-auto-correct  Don't perform auto correction of obvious syntax errors." << endl;      cout << "   --no-auto-correct  Don't perform auto correction of obvious syntax errors." << endl;
54      cout << endl;      cout << endl;
55        cout << "   --no-doc  Don't show LSCP reference documentation on screen." << endl;
56        cout << endl;
57  }  }
58    
59  static void printWelcome() {  static void printWelcome() {
# Line 131  static void storeCommandInHistory(const Line 134  static void storeCommandInHistory(const
134          g_commandHistory.push_back(sCommand);          g_commandHistory.push_back(sCommand);
135  }  }
136    
137    /// Splits the given string into individual lines for the given screen resolution.
138    static std::vector<String> splitForScreen(const String& s, int cols, int rows) {
139        std::vector<String> lines;
140        if (rows <= 0 || cols <= 0) return lines;
141        String line;
142        for (int i = 0; i < s.size(); ++i) {
143            char c = s[i];
144            if (c == '\r') continue;
145            if (c == '\n') {
146                lines.push_back(line);
147                if (lines.size() >= rows) return lines;
148                line.clear();
149                continue;
150            }
151            line += c;
152            if (line.size() >= cols) {
153                lines.push_back(line);
154                if (lines.size() >= rows) return lines;
155                line.clear();
156            }
157        }
158        return lines;
159    }
160    
161    /**
162     * Will be called whenever the LSCP documentation reference to be shown, has
163     * been changed. This call will accordingly update the screen with the new
164     * documentation text received from LSCP server.
165     */
166    static void updateDoc() {
167        const int vOffset = 2;
168    
169        CCursor originalCursor = CCursor::now();
170        CCursor cursor = originalCursor;
171        cursor.toColumn(0).down(vOffset);
172    
173        // wipe out current documentation off screen
174        cursor.clearVerticalToBottom();
175    
176        if (g_doc.empty()) {
177            // restore original cursor position
178            cursor.up(vOffset).toColumn(originalCursor.column());
179            return;
180        }
181    
182        // get screen size (in characters)
183        const int cols = TerminalCtrl::columns();
184        const int rows = TerminalCtrl::rows();
185    
186        // convert the string block into individual lines according to screen resolution
187        std::vector<String> lines = splitForScreen(g_doc, cols - 1, rows);
188    
189        // print lines onto screen
190        for (int row = 0; row < lines.size(); ++row)
191            std::cout << lines[row] << std::endl;
192    
193        // restore original cursor position
194        cursor.up(vOffset + lines.size()).toColumn(originalCursor.column());
195    }
196    
197  /**  /**
198   * This LSCP shell application is designed as thin client. That means the heavy   * This LSCP shell application is designed as thin client. That means the heavy
199   * LSCP grammar evaluation tasks are peformed by the LSCP server and the shell   * LSCP grammar evaluation tasks are peformed by the LSCP server and the shell
# Line 195  int main(int argc, char *argv[]) { Line 258  int main(int argc, char *argv[]) {
258      String host = LSCP_DEFAULT_HOST;      String host = LSCP_DEFAULT_HOST;
259      int port    = LSCP_DEFAULT_PORT;      int port    = LSCP_DEFAULT_PORT;
260      bool autoCorrect = true;      bool autoCorrect = true;
261        bool showDoc = true;
262    
263      // parse command line arguments      // parse command line arguments
264      for (int i = 0; i < argc; ++i) {      for (int i = 0; i < argc; ++i) {
# Line 217  int main(int argc, char *argv[]) { Line 281  int main(int argc, char *argv[]) {
281              }              }
282          } else if (s == "--no-auto-correct") {          } else if (s == "--no-auto-correct") {
283              autoCorrect = false;              autoCorrect = false;
284            } else if (s == "--no-doc") {
285                showDoc = false;
286          } else if (s[0] == '-') { // invalid / unknown command line argument ...          } else if (s[0] == '-') { // invalid / unknown command line argument ...
287              printUsage();              printUsage();
288              return -1;              return -1;
# Line 226  int main(int argc, char *argv[]) { Line 292  int main(int argc, char *argv[]) {
292      // try to connect to the sampler's LSCP server and start a thread for      // try to connect to the sampler's LSCP server and start a thread for
293      // receiving incoming network data from the sampler's LSCP server      // receiving incoming network data from the sampler's LSCP server
294      g_client = new LSCPClient;      g_client = new LSCPClient;
     g_client->setCallback(onLSCPClientNewInputAvailable);  
295      g_client->setErrorCallback(onLSCPClientErrorOccured);      g_client->setErrorCallback(onLSCPClientErrorOccured);
296      if (!g_client->connect(host, port)) return -1;      if (!g_client->connect(host, port)) return -1;
297        g_client->sendCommandSync(
298            (showDoc) ? "SET SHELL DOC 1" : "SET SHELL DOC 0"
299        );
300      String sResponse = g_client->sendCommandSync(      String sResponse = g_client->sendCommandSync(
301          (autoCorrect) ? "SET SHELL AUTO_CORRECT 1" : "SET SHELL AUTO_CORRECT 0"          (autoCorrect) ? "SET SHELL AUTO_CORRECT 1" : "SET SHELL AUTO_CORRECT 0"
302      );      );
# Line 237  int main(int argc, char *argv[]) { Line 305  int main(int argc, char *argv[]) {
305          cerr << "Error: sampler too old, it does not support shell instructions\n";          cerr << "Error: sampler too old, it does not support shell instructions\n";
306          return -1;          return -1;
307      }      }
308            g_client->setCallback(onLSCPClientNewInputAvailable);
309    
310      printWelcome();      printWelcome();
311      printPrompt();      printPrompt();
312    
# Line 365  int main(int argc, char *argv[]) { Line 434  int main(int argc, char *argv[]) {
434                      if (p.linesAdvanced()) cursor.up(p.linesAdvanced());                      if (p.linesAdvanced()) cursor.up(p.linesAdvanced());
435                      cursor.toColumn(cursorColumn + promptOffset());                      cursor.toColumn(cursorColumn + promptOffset());
436                  }                  }
437                } else if (line.substr(0,4) == "SHD:") { // new LSCP doc reference section received ...
438                    int code = LSCP_SHD_NO_MATCH;
439                    int res = sscanf(line.c_str(), "SHD:%d", &code);
440                    g_doc.clear();
441                    if (code == LSCP_SHD_MATCH) {
442                        while (true) { // multi-line response expected (terminated by dot line) ...
443                           if (line.substr(0, 1) == ".") break;
444                           if (!g_client->lineAvailable()) break;
445                           line = *g_client->popLine();
446                           g_doc += line;
447                        }
448                    }
449                    updateDoc();
450              } else if (line.substr(0,2) == "OK") { // single-line response expected ...              } else if (line.substr(0,2) == "OK") { // single-line response expected ...
451                  cout << endl << flush;                  cout << endl << flush;
452    
453                    // wipe out potential current documentation off screen
454                    CCursor cursor = CCursor::now();
455                    cursor.clearVerticalToBottom();
456    
457                  CFmt cfmt;                  CFmt cfmt;
458                  cfmt.green();                  cfmt.green();
459                  cout << line.substr(0,2) << flush;                  cout << line.substr(0,2) << flush;
# Line 375  int main(int argc, char *argv[]) { Line 462  int main(int argc, char *argv[]) {
462                  printPrompt();                  printPrompt();
463              } else if (line.substr(0,3) == "WRN") { // single-line response expected ...              } else if (line.substr(0,3) == "WRN") { // single-line response expected ...
464                  cout << endl << flush;                  cout << endl << flush;
465    
466                    // wipe out potential current documentation off screen
467                    CCursor cursor = CCursor::now();
468                    cursor.clearVerticalToBottom();
469    
470                  CFmt cfmt;                  CFmt cfmt;
471                  cfmt.yellow();                  cfmt.yellow();
472                  cout << line.substr(0,3) << flush;                  cout << line.substr(0,3) << flush;
# Line 383  int main(int argc, char *argv[]) { Line 475  int main(int argc, char *argv[]) {
475                  printPrompt();                  printPrompt();
476              } else if (line.substr(0,3) == "ERR") { // single-line response expected ...              } else if (line.substr(0,3) == "ERR") { // single-line response expected ...
477                  cout << endl << flush;                  cout << endl << flush;
478    
479                    // wipe out potential current documentation off screen
480                    CCursor cursor = CCursor::now();
481                    cursor.clearVerticalToBottom();
482    
483                  CFmt cfmt;                  CFmt cfmt;
484                  cfmt.bold().red();                  cfmt.bold().red();
485                  cout << line.substr(0,3) << flush;                  cout << line.substr(0,3) << flush;
# Line 391  int main(int argc, char *argv[]) { Line 488  int main(int argc, char *argv[]) {
488                  printPrompt();                  printPrompt();
489              } else if (g_client->multiLine()) { // multi-line response expected ...              } else if (g_client->multiLine()) { // multi-line response expected ...
490                  cout << endl << flush;                  cout << endl << flush;
491    
492                    // wipe out potential current documentation off screen
493                    CCursor cursor = CCursor::now();
494                    cursor.clearVerticalToBottom();
495    
496                  while (true) {                                    while (true) {                  
497                     cout << line << endl << flush;                     cout << line << endl << flush;
498                     if (line.substr(0, 1) == ".") break;                     if (line.substr(0, 1) == ".") break;
# Line 399  int main(int argc, char *argv[]) { Line 501  int main(int argc, char *argv[]) {
501                  }                  }
502                  printPrompt();                  printPrompt();
503              } else {              } else {
504                  cout << endl << line << endl << flush;                  cout << endl << flush;
505    
506                    // wipe out potential current documentation off screen
507                    CCursor cursor = CCursor::now();
508                    cursor.clearVerticalToBottom();
509    
510                    cout << line << endl << flush;
511                  printPrompt();                  printPrompt();
512              }              }
513          }          }

Legend:
Removed from v.2533  
changed lines
  Added in v.2534

  ViewVC Help
Powered by ViewVC