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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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 );
	}
}
예제 #8
0
void SC_TerminalClient::endInput()
{
	mInputService.stop();
	postfl("main: waiting for input thread to join...\n");
	mInputThread.join();
	postfl("main: quitting...\n");
}
예제 #9
0
파일: OSCData.cpp 프로젝트: scztt/sc-debug
void init_OSC(int port)
{
    postfl("init_OSC\n");
    try {
        gUDPport = new SC_UdpInPort(port);
    } catch (...) {
        postfl("No networking.");
    }
}
예제 #10
0
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;
}
예제 #11
0
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();
	}
}
예제 #13
0
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();
}
예제 #14
0
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;
}
예제 #15
0
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;
}
예제 #16
0
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();
	}
}
예제 #17
0
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;
}
예제 #18
0
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");
	}
}
예제 #19
0
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();
}
예제 #20
0
파일: GC.cpp 프로젝트: ASauer/supercollider
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();
	}
}
예제 #22
0
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();
}
예제 #24
0
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();
}
예제 #25
0
void cleanup_OSC()
{
	postfl( "cleaning up OSC\n");

	stopAsioThread();

#ifdef _WIN32
	WSACleanup();
#endif
}
예제 #26
0
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());
	}
}
예제 #27
0
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;
}
예제 #28
0
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;
}
예제 #29
0
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;
}
예제 #30
0
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;
}