2434 lines · 59.7 KB · C++
RawDownload
/*----------------------------------------------------------------------------  ChucK Concurrent, On-the-fly Audio Programming Language    Compiler and Virtual Machine   Copyright (c) 2004 Ge Wang and Perry R. Cook.  All rights reserved.    http://chuck.stanford.edu/    http://chuck.cs.princeton.edu/   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., 59 Temple Place, Suite 330, Boston, MA 02111-1307  U.S.A.-----------------------------------------------------------------------------*/ //-----------------------------------------------------------------------------// file: chuck_shell.cpp// desc: chuck shell implementation//// author: Spencer Salazar (spencer@ccrma.stanford.edu)// date: Autumn 2005//-----------------------------------------------------------------------------#include "chuck_shell.h"#include "chuck_otf.h"#include "chuck_errmsg.h"#include "util_network.h"#include "util_string.h" #include <stdio.h>#include <errno.h>#include <ctype.h>#ifndef __PLATFORM_WIN32__ #include <unistd.h> #include <sys/param.h> #include <sys/types.h> #include <dirent.h>#endif using namespace std;    //-----------------------------------------------------------------------------// name: tokenize_string// desc: divides a string into space separated tokens, respecting single and//      double quotes//-----------------------------------------------------------------------------void tokenize_string( string str, vector< string > & tokens){    t_CKINT space = 1;    t_CKINT end_space = 0;    t_CKINT squote = 0;    t_CKINT dquote = 0;    t_CKINT i = 0, j = 0, len = str.size();     for( i = 0; i < len; i++ )    {        if( isspace( str[i] ) && space )        {            j++;            continue;        }         if( isspace( str[i] ) && end_space )        {            tokens.push_back( string( str, j, i - j ) );            j = i + 1;            space = 1;            end_space = 0;            continue;        }         if( str[i] == '\'' )        {            if( dquote )                continue;            if( !squote )            {                str.erase( i, 1 );                len--;                i--;                space = 0;                end_space = 0;                squote = 1;                continue;            }             else if( str[i - 1] == '\\' )            {                str.erase( i - 1, 1 );                len--;                i--;                continue;            }             else            {                str.erase( i, 1 );                len--;                i--;                squote = 0;                end_space = 1;                space = 0;                continue;            }        }         if( str[i] == '"' ) //"        {            if( squote )                continue;            if( !dquote )            {                str.erase( i, 1 );                i--;                len--;                space = 0;                end_space = 0;                dquote = 1;                continue;            }             else if( str[i - 1] == '\\' )            {                str.erase( i - 1, 1 );                len--;                i--;                continue;            }             else            {                str.erase( i, 1 );                i--;                len--;                dquote = 0;                end_space = 1;                space = 0;                continue;            }        }         if( !squote && !dquote )        {            end_space = 1;            space = 0;        }    }     if( i > j && end_space )    {        tokens.push_back( string( str, j, i - j ) );    }} //-----------------------------------------------------------------------------// name: win32_tmpnam()// desc: replacement for broken tmpnam() on Windows Vista + 7// file_path should be at least MAX_PATH characters.//-----------------------------------------------------------------------------#ifdef __PLATFORM_WIN32__ #include <windows.h> int win32_tmpnam(char *file_path){    char tmp_path[MAX_PATH];     if(GetTempPath(256, tmp_path) == 0)        return 0;     if(GetTempFileName(tmp_path, "cksh", 0, file_path) == 0)        return 0;     return 1;} #endif    //-----------------------------------------------------------------------------// name: Chuck_Shell()// desc: ...//-----------------------------------------------------------------------------Chuck_Shell::Chuck_Shell(){    ui = NULL;    process_vm = NULL;    current_vm = NULL;    initialized = FALSE;    stop = FALSE;    code_entry_active = FALSE;}    //-----------------------------------------------------------------------------// name: ~Chuck_Shell()// desc: ...//-----------------------------------------------------------------------------Chuck_Shell::~Chuck_Shell(){    vector<string>::size_type i, len = allocated_commands.size();     //iterate through commands, delete the associated heap data    for( i = 0; i != len; i++ )        SAFE_DELETE( allocated_commands[i] );     // delete ui    SAFE_DELETE( ui );     // flag    initialized = FALSE;}    //-----------------------------------------------------------------------------// name: init()// desc: ...//-----------------------------------------------------------------------------t_CKBOOL Chuck_Shell::init( Chuck_VM * vm, Chuck_Shell_UI * ui ){    // log    EM_log( CK_LOG_SYSTEM, "initializing chuck shell..." );     // check    if( initialized == TRUE )    {        EM_log( CK_LOG_WARNING, "chuck shell already initialized" );        return TRUE;    }     // ui    if( ui == NULL )    {        CK_FPRINTF_STDERR( "[chuck](via shell): NULL ui passed to Chuck_Shell::init..." );        return FALSE;    }     this->ui = ui;     process_vm = vm;     Chuck_Shell_Network_VM * cspv = new Chuck_Shell_Network_VM();    if( !cspv->init( "localhost", 8888 ) )    {        CK_FPRINTF_STDERR( "[chuck](via shell): error initializing process VM..." );        SAFE_DELETE( cspv );        return FALSE;    }     // chuck shell network VM    current_vm = cspv;    vms.push_back( current_vm->copy() );    // chuck vm    process_vm = vm;     code_entry_active = FALSE;    code = "";     // init default variables    variables["COMMAND_PROMPT"] = "chuck %> ";    variables["DEFAULT_CONTEXT"] = "shell_global";     // initialize prompt    prompt = variables["COMMAND_PROMPT"];     Command * temp;     // initialize the string -> Chuck_Shell_Command map    temp = new Command_VM();    temp->init( this );    commands["vm"] = temp;    allocated_commands.push_back( temp );     temp = new Command_VMList();    temp->init( this );    commands["vms"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Add();    temp->init( this );    commands["+"] = temp;    commands["add"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Remove();    temp->init( this );    commands["-"] = temp;    commands["remove"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Status();    temp->init( this );    commands["status"] = temp;    commands["^"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Removeall();    temp->init( this );    commands["removeall"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Removelast();    temp->init( this );    commands["--"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Replace();    temp->init( this );    commands["replace"] = temp;    commands["="] = temp;    allocated_commands.push_back( temp );     temp = new Command_Close();    temp->init( this );    commands["close"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Kill();    temp->init( this );    commands["kill"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Exit();    temp->init( this );    commands["exit"] = temp;    commands["quit"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Ls();    temp->init( this );    commands["ls"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Pwd();    temp->init( this );    commands["pwd"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Cd();    temp->init( this );    commands["cd"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Alias();    temp->init( this );    commands["alias"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Unalias();    temp->init( this );    commands["unalias"] = temp;    allocated_commands.push_back( temp );     temp = new Command_Source();    temp->init( this );    commands["source"] = temp;    commands["."] = temp;    allocated_commands.push_back( temp );     temp = new Command_Code();    temp->init( this );    commands["code"] = temp;    allocated_commands.push_back( temp );     // flag    initialized = TRUE;     return TRUE;}    //-----------------------------------------------------------------------------// name: run()// desc: ...//-----------------------------------------------------------------------------void Chuck_Shell::run(){    // log    EM_log( CK_LOG_SYSTEM, "running chuck shell..." );     // make sure    if(initialized == FALSE)    {        CK_FPRINTF_STDERR( "[chuck](via shell): shell not initialized...\n" );        return;    }     string command;    string result;     ui->next_result( "welcome to chuck shell!\n" );    // ui->next_result( "(type \"help\" for more information)\n" );     // loop    for( ; !stop; )    {        // get command        if( ui->next_command( prompt, command ) == TRUE )        {            // result.clear();            result = "";             //printf( "chuck_shell::run\n" );             // execute the command            execute( command, result );             // command.clear();            command = "";             // pass the result to the shell ui            ui->next_result( result );        }        else            // done            break;    }     // log    EM_log( CK_LOG_SYSTEM, "exiting chuck shell..." );}    //-----------------------------------------------------------------------------// name: execute// desc: ...//-----------------------------------------------------------------------------t_CKBOOL Chuck_Shell::execute( string & in, string & out ){    if( !initialized )    {        return FALSE;    }     // vector of string tokens    vector< string > vec;     // clear the response    out = "";     // first find out if this is code to run    if( !code_entry_active && in[in.find_first_not_of( " \t\v\n" )] == '{' )        start_code();     if( code_entry_active )    {        continue_code( in );         if( code_entry_active == FALSE )        {            //strip opening and closing braces            string::size_type k = code.find( "{" );            string head = string( code, 0, k );            code = string( code, k + 1, code.size() - k - 1 );             k = code.rfind( "}" );            string tail = string( code, k + 1, code.size() - k - 1 );            code = string( code, 0, k );             do_code( code, out );             tokenize_string( tail, vec );             if( vec.size() > 0 )            {                string temp = "code save " + vec[0];                execute( temp, out );            }        }         return TRUE;    }     // divide the string into white space separated substrings    tokenize_string( in, vec );     // if no tokens    if( vec.size() == 0)        return TRUE;

Lines 1–500 of 2434.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t