void SC_TerminalClient::initInput() { #ifndef _WIN32 if( pipe( mInputCtlPipe ) == -1 ) { postfl("Error creating pipe for input thread control:\n%s\n", strerror(errno)); quit(1); } #else mQuitInputEvent = CreateEvent( NULL, false, false, NULL ); if( mQuitInputEvent == NULL ) { postfl("Error creating event for input thread control.\n"); quit(1); } #endif #ifdef HAVE_READLINE if (strcmp(gIdeName, "none") == 0) { // Other clients (emacs, vim, ...) won't want to interact through rl mUseReadline = true; return; } #endif #ifndef _WIN32 if( fcntl( STDIN_FD, F_SETFL, O_NONBLOCK ) == -1 ) { postfl("Error setting up non-blocking pipe reading:\n%s\n", strerror(errno)); quit(1); } #endif // !_WIN32 }
void SC_TerminalClient::endInput() { // NOTE: On Windows, there is no way to safely interrupt // the pipe-reading thread. So just quit and let it die. #ifdef _WIN32 if (mUseReadline) { #endif // wake up the input thread in case it is waiting // for input to be processed lockInput(); mInputShouldBeRunning = false; pthread_cond_signal( &mInputCond ); unlockInput(); #ifndef _WIN32 char c = 'q'; ssize_t bytes = write( mInputCtlPipe[1], &c, 1 ); if( bytes < 1 ) postfl("WARNING: could not send quit command to input thread.\n"); #else SetEvent( mQuitInputEvent ); #endif postfl("main: waiting for input thread to join...\n"); pthread_join( mInputThread, NULL ); #ifdef _WIN32 } // if (mUseReadline) #endif postfl("main: quitting...\n"); }
void *SC_TerminalClient::readlineFunc( void *arg ) { readlineInit(); SC_TerminalClient *client = static_cast<SC_TerminalClient*>(arg); fd_set fds; FD_ZERO(&fds); while(true) { FD_SET(STDIN_FD, &fds); FD_SET(client->mInputCtlPipe[0], &fds); if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0 ) { if( errno == EINTR ) continue; postfl("readline: select() error:\n%s\n", strerror(errno)); client->onQuit(1); break; } if( FD_ISSET(client->mInputCtlPipe[0], &fds) ) { postfl("readline: quit requested\n"); break; } if( FD_ISSET(STDIN_FD, &fds) ) { rl_callback_read_char(); } } postfl("readline: stopped.\n"); return NULL; }
void *SC_TerminalClient::readlineFunc( void *arg ) { readlineInit(); SC_TerminalClient *client = static_cast<SC_TerminalClient*>(arg); HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); HANDLE hnds[] = { client->mQuitInputEvent, hStdIn }; bool shouldRun = true; while (shouldRun) { DWORD result = WaitForMultipleObjects( 2, hnds, false, INFINITE ); if( result == WAIT_FAILED ) { postfl("readline: wait error.\n"); client->onQuit(1); break; } int hIndex = result - WAIT_OBJECT_0; if( hIndex == 0 ) { postfl("readline: quit requested.\n"); break; } if( hIndex == 1 ) { rl_callback_read_char(); } } postfl("readline: stopped.\n"); return NULL; }
SC_DLLEXPORT_C void runLibrary(PyrSymbol* selector) { VMGlobals *g = gMainVMGlobals; g->canCallOS = true; try { if (compiledOK) { ++g->sp; SetObject(g->sp, g->process); runInterpreter(g, selector, 1); } else { postfl("Library has not been compiled successfully.\n"); } } catch (std::exception &ex) { PyrMethod *meth = g->method; if (meth) { int ip = slotRawInt8Array(&meth->code) ? g->ip - slotRawInt8Array(&meth->code)->b : -1; post("caught exception in runLibrary %s:%s %3d\n", slotRawSymbol(&slotRawClass(&meth->ownerclass)->name)->name, slotRawSymbol(&meth->name)->name, ip ); dumpByteCodes(meth); } else { post("caught exception in runLibrary\n"); } error(ex.what()); } catch (...) { postfl("DANGER: OUT of MEMORY. Operation failed.\n"); } g->canCallOS = false; }
int prConnectSharedMem(VMGlobals *g, int numArgsPushed) { #if !defined(SC_IPHONE) PyrSlot *a = g->sp - 1; PyrSlot *b = g->sp; assert(IsObj(a)); PyrObject * self = slotRawObject(a); int portNumber = slotRawInt(b); int ptrIndex = 0; int finalizerIndex = 1; try { server_shared_memory_client * client = new server_shared_memory_client(portNumber); SetPtr(self->slots + ptrIndex, client); InstallFinalizer(g, self, finalizerIndex, disconnectSharedMem); postfl("Shared memory server interface initialized\n"); } catch (std::exception & e) { postfl("Cannot connect to shared memory: %s\n", e.what()); return errFailed; } #else postfl("Warning: Shared memory server interface disabled on iphone\n"); #endif return errNone; }
void SC_TerminalClient::onInputRead(const boost::system::error_code &error, std::size_t bytes_transferred) { if (error == boost::asio::error::operation_aborted) { postfl("SCLang Input: Quit requested\n"); return; } if (error == boost::asio::error::eof) { postfl("SCLang Input: EOF. Will quit.\n"); onQuit(0); return; } if (error) { postfl("SCLang Input: %s.\n", error.message().c_str()); onQuit(1); return; } if (!error) { #if HAVE_READLINE if (mUseReadline) { rl_callback_read_char(); startInputRead(); return; } #endif pushCmdLine( inputBuffer.data(), bytes_transferred ); } }
void SC_TerminalClient::endInput() { mInputService.stop(); postfl("main: waiting for input thread to join...\n"); mInputThread.join(); postfl("main: quitting...\n"); }
void init_OSC(int port) { postfl("init_OSC\n"); try { gUDPport = new SC_UdpInPort(port); } catch (...) { postfl("No networking."); } }
SC_DLLEXPORT_C bool compileLibrary() { //printf("->compileLibrary\n"); shutdownLibrary(); pthread_mutex_lock (&gLangMutex); gNumCompiledFiles = 0; compiledOK = false; // FIXME: the library config should have been initialized earlier! if (!gLibraryConfig) SC_LanguageConfig::readDefaultLibraryConfig(); compileStartTime = elapsedTime(); totalByteCodes = 0; #ifdef NDEBUG postfl("compiling class library...\n"); #else postfl("compiling class library (debug build)...\n"); #endif bool res = passOne(); if (res) { postfl("\tpass 1 done\n"); if (!compileErrors) { buildDepTree(); traverseFullDepTree(); traverseFullDepTree2(); flushPostBuf(); if (!compileErrors && gShowWarnings) { SymbolTable* symbolTable = gMainVMGlobals->symbolTable; symbolTable->CheckSymbols(); } } pyr_pool_compile->FreeAll(); flushPostBuf(); compileSucceeded(); } else { compiledOK = false; } pthread_mutex_unlock (&gLangMutex); //printf("<-compileLibrary\n"); return compiledOK; }
SC_DLLEXPORT_C bool compileLibrary(bool standalone) { //printf("->compileLibrary\n"); shutdownLibrary(); gLangMutex.lock(); gNumCompiledFiles = 0; compiledOK = false; SC_LanguageConfig::readLibraryConfig(standalone); compileStartTime = elapsedRealTime(); totalByteCodes = 0; #ifdef NDEBUG postfl("compiling class library...\n"); #else postfl("compiling class library (debug build)...\n"); #endif bool res = passOne(); if (res) { postfl("\tpass 1 done\n"); if (!compileErrors) { buildDepTree(); traverseFullDepTree(); traverseFullDepTree2(); flushPostBuf(); if (!compileErrors && gShowWarnings) { SymbolTable* symbolTable = gMainVMGlobals->symbolTable; symbolTable->CheckSymbols(); } } pyr_pool_compile->FreeAll(); flushPostBuf(); compileSucceeded(); } else { compiledOK = false; } gLangMutex.unlock(); //printf("<-compileLibrary\n"); return compiledOK; }
void SC_TerminalClient::readlineCmdLine( char *cmdLine ) { SC_TerminalClient *client = static_cast<SC_TerminalClient*>(instance()); if( cmdLine == NULL ) { postfl("\nExiting sclang (ctrl-D)\n"); client->onQuit(0); return; } if(*cmdLine!=0){ // If line wasn't empty, store it so that uparrow retrieves it add_history(cmdLine); int len = (int)strlen(cmdLine); client->lockInput(); client->mInputBuf.append(cmdLine, len); client->mInputBuf.append(kInterpretPrintCmdLine); client->sendSignal(sig_input); // Wait for input to be processed, // so that its output is displayed before readline prompt. if (client->mInputShouldBeRunning) pthread_cond_wait( &client->mInputCond, &client->mInputMutex ); client->unlockInput(); } }
void SC_HID_APIManager::handleElement( int joy_idx, struct hid_device_element * ele, std::atomic<bool> const & shouldBeRunning ){ int status = lockLanguageOrQuit(shouldBeRunning); if (status == EINTR) return; if (status) { postfl("error when locking language (%d)\n", status); return; } if (compiledOK) { VMGlobals* g = gMainVMGlobals; g->canCallOS = false; ++g->sp; SetObject(g->sp, s_hidapi->u.classobj ); // set the class HID_API ++g->sp; SetInt(g->sp, joy_idx ); ++g->sp; SetInt(g->sp, ele->index ); ++g->sp; SetInt(g->sp, ele->usage_page ); ++g->sp; SetInt(g->sp, ele->usage ); ++g->sp; SetInt(g->sp, ele->value ); ++g->sp; SetFloat(g->sp, hid_element_map_logical( ele ) ); ++g->sp; SetFloat(g->sp, hid_element_map_physical( ele ) ); ++g->sp; SetInt(g->sp, ele->array_value ); runInterpreter(g, s_hidElementData, 9 ); g->canCallOS = false; } gLangMutex.unlock(); }
int ScIDE_Send(struct VMGlobals *g, int numArgsPushed) { if (!gIpcClient) { error("ScIDE not connected\n"); return errFailed; } if( !gMainVMGlobals->canCallOS ) { error("You can not use ScIDE:prSend functionality in the current thread.\nTry scheduling on AppClock instead.\n"); return errFailed; } PyrSlot * idSlot = g->sp - 1; char id[255]; if (slotStrVal( idSlot, id, 255 )) return errWrongType; PyrSlot * argSlot = g->sp; try { YAMLSerializer serializer(argSlot); sendSelectorAndData(gIpcClient->mSocket, QString(id), QString::fromUtf8(serializer.data())); } catch (std::exception const & e) { postfl("Exception during ScIDE_Send: %s\n", e.what()); return errFailed; } return errNone; }
int ScIDE_Send(struct VMGlobals *g, int numArgsPushed) { if (!gIpcClient) { error("ScIDE not connected\n"); return errFailed; } PyrSlot * idSlot = g->sp - 1; char id[255]; if (slotStrVal( idSlot, id, 255 )) return errWrongType; PyrSlot * argSlot = g->sp; try { YAMLSerializer serializer(argSlot); QDataStream stream(gIpcClient->mSocket); stream.setVersion(QDataStream::Qt_4_6); stream << QString(id); stream << QString::fromUtf8(serializer.data()); } catch (std::exception const & e) { postfl("Exception during ScIDE_Send: %s\n", e.what()); return errFailed; } return errNone; }
void SC_LanguageClient::initRuntime(const Options& opt) { // start virtual machine if (!mHiddenClient->mRunning) { #ifdef __linux__ using DirName = SC_Filesystem::DirName; namespace bfs = boost::filesystem; bfs::path deprecatedSupportDirectory = SC_Filesystem::instance().getDirectory(DirName::UserHome); deprecatedSupportDirectory /= "share/SuperCollider"; if (bfs::exists(deprecatedSupportDirectory)) { bfs::path supportDirectory = SC_Filesystem::instance().getDirectory(DirName::UserAppSupport); postfl("WARNING: Deprecated support directory detected: %s\n" "Extensions and other contents in this directory will not be available until you move them to the new support directory:\n" "%s\n" "Quarks will need to be reinstalled due to broken symbolic links.\n\n", deprecatedSupportDirectory.string().c_str(), // we can safely convert to c_str here because the POSIX filesystem uses UTF-8 supportDirectory.string().c_str()); } #endif mHiddenClient->mRunning = true; if (opt.mRuntimeDir) { int err = chdir(opt.mRuntimeDir); if (err) error("Cannot change to runtime directory: %s", strerror(errno)); } pyr_init_mem_pools(opt.mMemSpace, opt.mMemGrow); init_OSC(opt.mPort); schedInit(); onInitRuntime(); } }
ClassDependancy* newClassDependancy(PyrSymbol *className, PyrSymbol *superClassName, PyrSymbol *fileSym, int startPos, int endPos, int lineOffset) { ClassDependancy* classdep; //post("classdep '%s' '%s' '%s' %d %d\n", className->name, superClassName->name, // fileSym->name, className, superClassName); // pyrmalloc: // lifetime: kill after compile. numClassDeps++; if (className->classdep) { error("duplicate Class found: '%s' \n", className->name); post("%s\n",className->classdep->fileSym->name); postfl("%s\n\n",fileSym->name); return className->classdep; } classdep = (ClassDependancy*)pyr_pool_compile->Alloc(sizeof(ClassDependancy)); MEMFAIL(text); classdep->className = className; classdep->superClassName = superClassName; classdep->fileSym = fileSym; classdep->superClassDep = NULL; classdep->next = NULL; classdep->subclasses = NULL; classdep->startPos = startPos; classdep->endPos = endPos; classdep->lineOffset = lineOffset; className->classdep = classdep; return classdep; }
void interpretCmdLine(const char *textbuf, int textlen, char *methodname) { PyrString *string; if (compiledOK) { PyrSlot slot; string = newPyrStringN(gMainVMGlobals->gc, textlen, 0, false); memcpy(string->s, textbuf, textlen); SetObject(&slotRawInterpreter(&gMainVMGlobals->process->interpreter)->cmdLine, string); gMainVMGlobals->gc->GCWrite(slotRawObject(&gMainVMGlobals->process->interpreter), string); SetObject(&slot, gMainVMGlobals->process); //#if __profile__ // ProfilerInit(collectSummary, microsecondsTimeBase, 500, 100); //#endif slotCopy((++gMainVMGlobals->sp), &slot); runInterpreter(gMainVMGlobals, getsym(methodname), 1); //#if __profile__ // ProfilerDump("\pErase2.prof"); // ProfilerTerm(); //#endif } else { postfl("Library has not been compiled successfully.\n"); } }
void compileClass(PyrSymbol *fileSym, int startPos, int endPos, int lineOffset) { //fprintf(stderr, "compileClass: %d\n", fileSym->u.index); gCompilingFileSym = fileSym; gCompilingVMGlobals = 0; gRootParseNode = NULL; initParserPool(); if (startLexer(fileSym, startPos, endPos, lineOffset)) { //postfl("->Parsing %s\n", fileSym->name); fflush(stdout); parseFailed = yyparse(); //postfl("<-Parsing %s %d\n", fileSym->name, parseFailed); fflush(stdout); //post("parseFailed %d\n", parseFailed); fflush(stdout); if (!parseFailed && gRootParseNode) { //postfl("Compiling nodes %p\n", gRootParseNode);fflush(stdout); compilingCmdLine = false; compileNodeList(gRootParseNode, true); //postfl("done compiling\n");fflush(stdout); } else { compileErrors++; char extPath[MAXPATHLEN]; asRelativePath(fileSym->name, extPath); error("file '%s' parse failed\n", extPath); postfl("error parsing\n"); } finiLexer(); } else { error("file '%s' open failed\n", fileSym->name); } freeParserPool(); }
void fatalerror(const char*str) { fputs(str, stderr); postfl(str); throw std::runtime_error(str); //exit(-1); }
void SC_LanguageClient::initRuntime(const Options& opt) { // start virtual machine if (!mHiddenClient->mRunning) { #ifdef __linux__ char deprecatedSupportDirectory[PATH_MAX]; sc_GetUserHomeDirectory(deprecatedSupportDirectory, PATH_MAX); sc_AppendToPath(deprecatedSupportDirectory, PATH_MAX, "share/SuperCollider"); if (sc_DirectoryExists(deprecatedSupportDirectory)) { char supportDirectory[PATH_MAX]; sc_GetUserAppSupportDirectory(supportDirectory, PATH_MAX); postfl("WARNING: Deprecated support directory detected: %s\n" "Extensions and other contents in this directory will not be available until you move them to the new support directory:\n" "%s\n" "Quarks will need to be reinstalled due to broken symbolic links.\n\n", deprecatedSupportDirectory, supportDirectory); } #endif mHiddenClient->mRunning = true; if (opt.mRuntimeDir) { int err = chdir(opt.mRuntimeDir); if (err) error("Cannot change to runtime directory: %s", strerror(errno)); } pyr_init_mem_pools(opt.mMemSpace, opt.mMemGrow); init_OSC(opt.mPort); schedInit(); onInitRuntime(); } }
void SC_TerminalClient::onQuit( int exitCode ) { lockSignal(); postfl("main: quit request %i\n", exitCode); quit( exitCode ); mCond.notify_one(); unlockSignal(); }
void SC_TerminalClient::onQuit( int exitCode ) { lockSignal(); postfl("main: quit request %i\n", exitCode); quit( exitCode ); pthread_cond_signal( &mCond ); unlockSignal(); }
void closeAllCustomPorts() { // close all custom sockets if(gCustomUdpPorts.empty()) postfl("empty\n"); for(int i=0; i<gCustomUdpPorts.size(); i++){ delete gCustomUdpPorts[i]; } gCustomUdpPorts.clear(); }
void cleanup_OSC() { postfl( "cleaning up OSC\n"); stopAsioThread(); #ifdef _WIN32 WSACleanup(); #endif }
void init_OSC(int port) { postfl("init_OSC\n"); #ifdef _WIN32 WSAData wsaData; int nCode; if ((nCode = WSAStartup(MAKEWORD(1, 1), &wsaData)) != 0) { error( "sclang: init_OSC: WSAStartup() failed with error code %d.\n", nCode ); } #endif startAsioThread(); try { gUDPport = new SC_UdpInPort(port); } catch (std::exception const & e) { postfl("No networking: %s", e.what()); } }
int processchar(int c) { PyrSlot slot; PyrSlotNode *node; #if DEBUGLEX if (gDebugLexer) postfl("processhex: '%c'\n",c); #endif SetChar(&slot, c); node = newPyrSlotNode(&slot); zzval = (long)node; return ASCII; }
int processint(char *s) { PyrSlot slot; PyrSlotNode *node; #if DEBUGLEX if (gDebugLexer) postfl("processint: '%s'\n",s); #endif SetInt(&slot, atoi(s)); node = newPyrSlotNode(&slot); zzval = (long)node; return INTEGER; }
int processfloatradix(char *s, int n, int radix) { PyrSlot slot; PyrSlotNode *node; #if DEBUGLEX if (gDebugLexer) postfl("processfloatradix: '%s'\n",s); #endif SetFloat(&slot, sc_strtof(s, n, radix)); node = newPyrSlotNode(&slot); zzval = (long)node; return INTEGER; }
int processstring(char *s) { PyrSlot slot; PyrSlotNode *node; PyrString *string; #if DEBUGLEX if (gDebugLexer) postfl("processstring: '%s'\n",s); #endif int flags = compilingCmdLine ? obj_immutable : obj_permanent | obj_immutable; string = newPyrString(gMainVMGlobals->gc, s+1, flags, false); SetObject(&slot, string); node = newPyrSlotNode(&slot); zzval = (long)node; return STRING; }