bool SC_TerminalClient::parseOptions(int& argc, char**& argv, Options& opt) { const char* optstr = ":d:Dg:hl:m:rsu:i:av"; int c; // inhibit error reporting opterr = 0; while ((c = getopt(argc, argv, optstr)) != -1) { switch (c) { case 'd': opt.mRuntimeDir = optarg; break; case 'D': opt.mDaemon = true; break; case 'g': if (!parseMemArg(optarg, &opt.mMemGrow)) { optopt = c; goto optArgInvalid; } break; case 'h': goto help; case 'l': opt.mLibraryConfigFile = optarg; break; case 'm': if (!parseMemArg(optarg, &opt.mMemSpace)) { optopt = c; goto optArgInvalid; } break; case 'r': opt.mCallRun = true; break; case 'v': fprintf(stdout, "sclang %s\n", SC_VersionString().c_str()); quit(0); return false; break; case 's': opt.mCallStop = true; break; case 'u': if (!parsePortArg(optarg, &opt.mPort)) { optopt = c; goto optArgInvalid; } break; case '?': goto optInvalid; break; case ':': goto optArgExpected; break; case 'i': gIdeName = optarg; break; case 'a': opt.mStandalone = true; break; default: ::post("%s: unknown error (getopt)\n", getName()); quit(255); return false; } } argv += optind; argc -= optind; return true; help: printUsage(); quit(0); return false; optInvalid: ::post("%s: invalid option -%c\n", getName(), optopt); quit(1); return false; optArgExpected: ::post("%s: missing argument for option -%c\n", getName(), optopt); quit(1); return false; optArgInvalid: ::post("%s: invalid argument for option -%c -- %s\n", getName(), optopt, optarg); quit(1); return false; }
int main(int argc, char* argv[]) { setlinebuf(stdout); #ifdef _WIN32 // initialize winsock WSAData wsaData; int nCode; if ((nCode = WSAStartup(MAKEWORD(1, 1), &wsaData)) != 0) { scprintf( "WSAStartup() failed with error code %d.\n", nCode ); return 1; } #endif int udpPortNum = -1; int tcpPortNum = -1; std::string bindTo("0.0.0.0"); WorldOptions options = kDefaultWorldOptions; for (int i=1; i<argc;) { if (argv[i][0] != '-' || argv[i][1] == 0 || strchr("utBaioczblndpmwZrCNSDIOMHvVRUhPL", argv[i][1]) == 0) { scprintf("ERROR: Invalid option %s\n", argv[i]); Usage(); } int j = i; switch (argv[j][1]) { case 'u' : checkNumArgs(2); udpPortNum = atoi(argv[j+1]); break; case 't' : checkNumArgs(2); tcpPortNum = atoi(argv[j+1]); break; case 'B': checkNumArgs(2); bindTo = argv[j+1]; break; case 'a' : checkNumArgs(2); options.mNumAudioBusChannels = atoi(argv[j+1]); break; case 'i' : checkNumArgs(2); options.mNumInputBusChannels = atoi(argv[j+1]); break; case 'o' : checkNumArgs(2); options.mNumOutputBusChannels = atoi(argv[j+1]); break; case 'c' : checkNumArgs(2); options.mNumControlBusChannels = atoi(argv[j+1]); break; case 'z' : checkNumArgs(2); options.mBufLength = NEXTPOWEROFTWO(atoi(argv[j+1])); break; case 'Z' : checkNumArgs(2); options.mPreferredHardwareBufferFrameSize = NEXTPOWEROFTWO(atoi(argv[j+1])); break; case 'b' : checkNumArgs(2); options.mNumBuffers = NEXTPOWEROFTWO(atoi(argv[j+1])); break; case 'l' : checkNumArgs(2); options.mMaxLogins = NEXTPOWEROFTWO(atoi(argv[j+1])); break; case 'n' : checkNumArgs(2); options.mMaxNodes = NEXTPOWEROFTWO(atoi(argv[j+1])); break; case 'd' : checkNumArgs(2); options.mMaxGraphDefs = NEXTPOWEROFTWO(atoi(argv[j+1])); break; case 'p' : checkNumArgs(2); options.mPassword = argv[j+1]; break; case 'm' : checkNumArgs(2); options.mRealTimeMemorySize = atoi(argv[j+1]); break; case 'w' : checkNumArgs(2); options.mMaxWireBufs = atoi(argv[j+1]); break; case 'r' : checkNumArgs(2); options.mNumRGens = atoi(argv[j+1]); break; case 'S' : checkNumArgs(2); options.mPreferredSampleRate = (uint32)atof(argv[j+1]); break; case 'D' : checkNumArgs(2); options.mLoadGraphDefs = atoi(argv[j+1]); break; case 'N' : #ifdef NO_LIBSNDFILE scprintf("NRT mode not supported: scsynth compiled without libsndfile\n"); exit(0); #endif // -N cmd-filename input-filename output-filename sample-rate header-format sample-format checkNumArgs(7); options.mRealTime = false; options.mNonRealTimeCmdFilename = strcmp(argv[j+1], "_") ? argv[j+1] : 0; options.mNonRealTimeInputFilename = strcmp(argv[j+2], "_") ? argv[j+2] : 0; options.mNonRealTimeOutputFilename = argv[j+3]; options.mPreferredSampleRate = (uint32)atof(argv[j+4]); options.mNonRealTimeOutputHeaderFormat = argv[j+5]; options.mNonRealTimeOutputSampleFormat = argv[j+6]; break; #ifdef __APPLE__ case 'I' : checkNumArgs(2); options.mInputStreamsEnabled = argv[j+1]; break; case 'O' : checkNumArgs(2); options.mOutputStreamsEnabled = argv[j+1]; break; case 'M': #endif case 'H' : checkNumArgs(2); options.mInDeviceName = argv[j+1]; #ifdef __APPLE__ if (i+1>argc || argv[j+2][0]=='-') { options.mOutDeviceName = options.mInDeviceName; } else { // If there's a second argument then the user wants separate I/O devices options.mOutDeviceName = argv[j+2]; ++i; } #else options.mOutDeviceName = options.mInDeviceName; // Non-Mac platforms always use same device #endif break; case 'L' : checkNumArgs(1); #if (_POSIX_MEMLOCK - 0) >= 200112L options.mMemoryLocking = true; #else options.mMemoryLocking = false; #endif break; case 'V' : checkNumArgs(2); options.mVerbosity = atoi(argv[j+1]); break; case 'v' : scprintf("scsynth %s (%s)\n", SC_VersionString().c_str(), SC_BuildString().c_str()); exit(0); break; case 'R' : checkNumArgs(2); options.mRendezvous = atoi(argv[j+1]) > 0; break; case 'U' : checkNumArgs(2); options.mUGensPluginPath = argv[j+1]; break; case 'P' : checkNumArgs(2); options.mRestrictedPath = argv[j+1]; break; case 'C' : checkNumArgs(2); break; case 'h': default: Usage(); } } if (udpPortNum == -1 && tcpPortNum == -1 && options.mRealTime) { scprintf("ERROR: There must be a -u and/or a -t options, or -N for nonrealtime.\n"); Usage(); } if (options.mNumInputBusChannels + options.mNumOutputBusChannels > options.mNumAudioBusChannels) { scprintf("ERROR: number of audio bus channels < inputs + outputs.\n"); Usage(); } if (options.mRealTime) { int port = (udpPortNum > 0) ? udpPortNum : tcpPortNum; options.mSharedMemoryID = port; } else options.mSharedMemoryID = 0; struct World *world = World_New(&options); if (!world) return 1; if (!options.mRealTime) { #ifdef NO_LIBSNDFILE return 1; #else int exitCode = 0; try { World_NonRealTimeSynthesis(world, &options); } catch (std::exception& exc) { scprintf("%s\n", exc.what()); exitCode = 1; } return exitCode; #endif } if (udpPortNum >= 0) { if (!World_OpenUDP(world, bindTo.c_str(), udpPortNum)) { World_Cleanup(world,true); return 1; } } if (tcpPortNum >= 0) { if (!World_OpenTCP(world, bindTo.c_str(), tcpPortNum, options.mMaxLogins, 8)) { World_Cleanup(world,true); return 1; } } if(options.mVerbosity >=0){ #ifdef NDEBUG scprintf("SuperCollider 3 server ready.\n"); #else scprintf("SuperCollider 3 server ready (debug build).\n"); #endif } fflush(stdout); World_WaitForQuit(world,true); #ifdef _WIN32 // clean up winsock WSACleanup(); #endif // _WIN32 return 0; }