From 70f56fc78e949ec8a0d832626a99bda9082acafd Mon Sep 17 00:00:00 2001 From: moret Date: Wed, 9 Jul 2008 13:04:46 +0000 Subject: [PATCH] Add JackArgParser tool to build argc and argv array from a string git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2668 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackTools.cpp | 344 +++++++++++++++++++++++++----------------- common/JackTools.h | 20 +++ windows/Setup/jack.ci | 34 ++--- 3 files changed, 244 insertions(+), 154 deletions(-) diff --git a/common/JackTools.cpp b/common/JackTools.cpp index 41688d3e..e47c66bd 100644 --- a/common/JackTools.cpp +++ b/common/JackTools.cpp @@ -31,188 +31,258 @@ #include #endif -namespace Jack -{ +using namespace std; + +namespace Jack { #define DEFAULT_TMP_DIR "/tmp" -char* jack_tmpdir = (char*)DEFAULT_TMP_DIR; + char* jack_tmpdir = (char*)DEFAULT_TMP_DIR; -int JackTools::GetPID() -{ + int JackTools::GetPID() { #ifdef WIN32 - return _getpid(); + return _getpid(); #else - return getpid(); + return getpid(); #endif -} + } -int JackTools::GetUID() -{ + int JackTools::GetUID() { #ifdef WIN32 - return _getpid(); - //#error "No getuid function available" + return _getpid(); + //#error "No getuid function available" #else - return getuid(); + return getuid(); #endif -} + } -const char* JackTools::DefaultServerName() -{ - const char* server_name; - if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) - server_name = JACK_DEFAULT_SERVER_NAME; - return server_name; -} + const char* JackTools::DefaultServerName() { + const char* server_name; + if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) + server_name = JACK_DEFAULT_SERVER_NAME; + return server_name; + } -/* returns the name of the per-user subdirectory of jack_tmpdir */ + /* returns the name of the per-user subdirectory of jack_tmpdir */ #ifdef WIN32 -char* JackTools::UserDir() -{ - return ""; -} + char* JackTools::UserDir() { + return ""; + } -char* JackTools::ServerDir(const char* server_name, char* server_dir) -{ - return ""; -} + char* JackTools::ServerDir(const char* server_name, char* server_dir) { + return ""; + } -void JackTools::CleanupFiles(const char* server_name) -{} + void JackTools::CleanupFiles(const char* server_name) {} -int JackTools::GetTmpdir() -{ - return 0; -} + int JackTools::GetTmpdir() { + return 0; + } #else -char* JackTools::UserDir() -{ - static char user_dir[PATH_MAX + 1] = ""; - - /* format the path name on the first call */ - if (user_dir[0] == '\0') { - if (getenv ("JACK_PROMISCUOUS_SERVER")) { - snprintf(user_dir, sizeof(user_dir), "%s/jack", jack_tmpdir); - } else { - snprintf(user_dir, sizeof(user_dir), "%s/jack-%d", jack_tmpdir, GetUID()); + char* JackTools::UserDir() { + static char user_dir[PATH_MAX + 1] = ""; + + /* format the path name on the first call */ + if (user_dir[0] == '\0') { + if (getenv ("JACK_PROMISCUOUS_SERVER")) { + snprintf(user_dir, sizeof(user_dir), "%s/jack", jack_tmpdir); + } else { + snprintf(user_dir, sizeof(user_dir), "%s/jack-%d", jack_tmpdir, GetUID()); + } } + + return user_dir; } - return user_dir; -} + /* returns the name of the per-server subdirectory of jack_user_dir() */ + char* JackTools::ServerDir(const char* server_name, char* server_dir) { + /* format the path name into the suppled server_dir char array, + * assuming that server_dir is at least as large as PATH_MAX+1 */ -/* returns the name of the per-server subdirectory of jack_user_dir() */ -char* JackTools::ServerDir(const char* server_name, char* server_dir) -{ - /* format the path name into the suppled server_dir char array, - * assuming that server_dir is at least as large as PATH_MAX+1 */ + snprintf(server_dir, PATH_MAX + 1, "%s/%s", UserDir(), server_name); + return server_dir; + } - snprintf(server_dir, PATH_MAX + 1, "%s/%s", UserDir(), server_name); - return server_dir; -} + void JackTools::CleanupFiles(const char* server_name) { + DIR* dir; + struct dirent *dirent; + char dir_name[PATH_MAX + 1] = ""; + ServerDir(server_name, dir_name); + + /* On termination, we remove all files that jackd creates so + * subsequent attempts to start jackd will not believe that an + * instance is already running. If the server crashes or is + * terminated with SIGKILL, this is not possible. So, cleanup + * is also attempted when jackd starts. + * + * There are several tricky issues. First, the previous JACK + * server may have run for a different user ID, so its files + * may be inaccessible. This is handled by using a separate + * JACK_TMP_DIR subdirectory for each user. Second, there may + * be other servers running with different names. Each gets + * its own subdirectory within the per-user directory. The + * current process has already registered as `server_name', so + * we know there is no other server actively using that name. + */ + + /* nothing to do if the server directory does not exist */ + if ((dir = opendir(dir_name)) == NULL) { + return; + } -void JackTools::CleanupFiles(const char* server_name) -{ - DIR* dir; - struct dirent *dirent; - char dir_name[PATH_MAX + 1] = ""; - ServerDir(server_name, dir_name); - - /* On termination, we remove all files that jackd creates so - * subsequent attempts to start jackd will not believe that an - * instance is already running. If the server crashes or is - * terminated with SIGKILL, this is not possible. So, cleanup - * is also attempted when jackd starts. - * - * There are several tricky issues. First, the previous JACK - * server may have run for a different user ID, so its files - * may be inaccessible. This is handled by using a separate - * JACK_TMP_DIR subdirectory for each user. Second, there may - * be other servers running with different names. Each gets - * its own subdirectory within the per-user directory. The - * current process has already registered as `server_name', so - * we know there is no other server actively using that name. - */ - - /* nothing to do if the server directory does not exist */ - if ((dir = opendir(dir_name)) == NULL) { - return; - } - - /* unlink all the files in this directory, they are mine */ - while ((dirent = readdir(dir)) != NULL) { - - char fullpath[PATH_MAX + 1]; - - if ((strcmp(dirent->d_name, ".") == 0) || (strcmp (dirent->d_name, "..") == 0)) { - continue; + /* unlink all the files in this directory, they are mine */ + while ((dirent = readdir(dir)) != NULL) { + + char fullpath[PATH_MAX + 1]; + + if ((strcmp(dirent->d_name, ".") == 0) || (strcmp (dirent->d_name, "..") == 0)) { + continue; + } + + snprintf(fullpath, sizeof(fullpath), "%s/%s", dir_name, dirent->d_name); + + if (unlink(fullpath)) { + jack_error("cannot unlink `%s' (%s)", fullpath, strerror(errno)); + } } - snprintf(fullpath, sizeof(fullpath), "%s/%s", dir_name, dirent->d_name); + closedir(dir); - if (unlink(fullpath)) { - jack_error("cannot unlink `%s' (%s)", fullpath, strerror(errno)); + /* now, delete the per-server subdirectory, itself */ + if (rmdir(dir_name)) { + jack_error("cannot remove `%s' (%s)", dir_name, strerror(errno)); + } + + /* finally, delete the per-user subdirectory, if empty */ + if (rmdir(UserDir())) { + if (errno != ENOTEMPTY) { + jack_error("cannot remove `%s' (%s)", UserDir(), strerror(errno)); + } } } - closedir(dir); + int JackTools::GetTmpdir() { + FILE* in; + size_t len; + char buf[PATH_MAX + 2]; /* allow tmpdir to live anywhere, plus newline, plus null */ - /* now, delete the per-server subdirectory, itself */ - if (rmdir(dir_name)) { - jack_error("cannot remove `%s' (%s)", dir_name, strerror(errno)); - } + if ((in = popen("jackd -l", "r")) == NULL) { + return -1; + } - /* finally, delete the per-user subdirectory, if empty */ - if (rmdir(UserDir())) { - if (errno != ENOTEMPTY) { - jack_error("cannot remove `%s' (%s)", UserDir(), strerror(errno)); + if (fgets(buf, sizeof(buf), in) == NULL) { + fclose(in); + return -1; } - } -} -int JackTools::GetTmpdir() -{ - FILE* in; - size_t len; - char buf[PATH_MAX + 2]; /* allow tmpdir to live anywhere, plus newline, plus null */ + len = strlen(buf); - if ((in = popen("jackd -l", "r")) == NULL) { - return -1; - } + if (buf[len - 1] != '\n') { + /* didn't get a whole line */ + fclose(in); + return -1; + } + + jack_tmpdir = (char *)malloc(len); + memcpy(jack_tmpdir, buf, len - 1); + jack_tmpdir[len - 1] = '\0'; - if (fgets(buf, sizeof(buf), in) == NULL) { fclose(in); - return -1; + return 0; + } +#endif + + void JackTools::RewriteName(const char* name, char* new_name) { + size_t i; + for (i = 0; i < strlen(name); i++) { + if ((name[i] == '/') || (name[i] == '\\')) + new_name[i] = '_'; + else + new_name[i] = name[i]; + } + new_name[i] = '\0'; } - len = strlen(buf); + JackArgParser::JackArgParser(const char* arg) { + fArgc=0; + fNumArgv=0; + fArgString=string(arg); + fArgString+=" "; + const size_t arg_len=fArgString.length(); + int i=0; + size_t pos=0; + size_t start=0; + size_t copy_start=0; + size_t copy_length=0; + vector args; + + //first fill a vector with args + do { + //find the first non-space character from the actual position + start=fArgString.find_first_not_of(' ',start); + //get the next quote or space position + pos=fArgString.find_first_of(" \"",start); + //no more quotes or spaces, consider the end of the string + if (pos==string::npos) + pos=arg_len; + //if it's a double quote + if (fArgString.at(pos)=='\"') { + //first character : copy the substring + if (pos==start) { + copy_start=start+1; + pos=fArgString.find('\"',++pos); + copy_length=pos-copy_start; + start=pos+1; + } + //else there is someting before the quote, first copy that + else { + copy_start=start; + copy_length=pos-copy_start; + start=pos; + } + } + //if it's a space + if (fArgString.at(pos)==' ') { + copy_start=start; + copy_length=pos-copy_start; + start=pos+1; + } + //then push the substring to the args vector + args.push_back(fArgString.substr(copy_start,copy_length)); + } while(start(fArgv); + } } + diff --git a/common/JackTools.h b/common/JackTools.h index 6882d7bc..bf264552 100644 --- a/common/JackTools.h +++ b/common/JackTools.h @@ -32,6 +32,10 @@ #include #endif +#include +#include +#include + namespace Jack { @@ -49,6 +53,22 @@ struct JackTools static void RewriteName(const char* name, char* new_name); }; + +class JackArgParser +{ + private: + std::string fArgString; + int fNumArgv; + int fArgc; + char** fArgv; + public: + JackArgParser(const char* arg); + ~JackArgParser(); + std::string GetArgString(); + int GetNumArgv(); + int GetArgc(); + const char** GetArgv(); +}; } #endif diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index 32f31b8c..c5179c06 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -36,7 +36,7 @@ ppmdmax 1 - overnewer + over 0 1 @@ -53,8 +53,8 @@ - <_>..\Release\bin\libjackmp.ainst\libovernewer0 -<_>..\Release\bin\libjackservermp.ainst\libovernewer0 + <_>..\Release\bin\libjackmp.ainstlibovernewer0 +<_>..\Release\bin\libjackservermp.ainstlibovernewer0 <_>..\Release\bin\jack_connect.exeinstovernewer0 <_>..\Release\bin\jack_disconnect.exeinstovernewer0 <_>..\Release\bin\jack_load.exeinstovernewer0 @@ -68,20 +68,20 @@ <_>..\Release\bin\libjackservermp.dllinstovernewer0 <_>..\Release\bin\libsamplerate-0.dllinstovernewer0 <_>..\Release\bin\portaudio_x86.dllinstovernewer0 -<_>..\Release\bin\jackmp\jack_net.dllinst\jackmpovernewer0 -<_>..\Release\bin\jackmp\jack_portaudio.dllinst\jackmpovernewer0 -<_>..\Release\bin\jackmp\netmanager.dllinst\jackmpovernewer0 -<_>..\Release\bin\jackmp\audioadapter.dllinst\jackmpovernewer0 -<_>..\..\common\jack\control.hinst\includes\jackovernewer0 -<_>..\..\common\jack\intclient.hinst\includes\jackovernewer0 -<_>..\..\common\jack\jack.hinst\includes\jackovernewer0 -<_>..\..\common\jack\jslist.hinst\includes\jackovernewer0 -<_>..\..\common\jack\midiport.hinst\includes\jackovernewer0 -<_>..\..\common\jack\ringbuffer.hinst\includes\jackovernewer0 -<_>..\..\common\jack\statistics.hinst\includes\jackovernewer0 -<_>..\..\common\jack\thread.hinst\includes\jackovernewer0 -<_>..\..\common\jack\transport.hinst\includes\jackovernewer0 -<_>..\..\common\jack\types.hinst\includes\jackovernewer0 +<_>..\Release\bin\jackmp\jack_net.dllinstjackmpovernewer0 +<_>..\Release\bin\jackmp\jack_portaudio.dllinstjackmpovernewer0 +<_>..\Release\bin\jackmp\netmanager.dllinstjackmpovernewer0 +<_>..\Release\bin\jackmp\audioadapter.dllinstjackmpovernewer0 +<_>..\..\common\jack\control.hinstincludes\jackovernewer0 +<_>..\..\common\jack\intclient.hinstincludes\jackovernewer0 +<_>..\..\common\jack\jack.hinstincludes\jackovernewer0 +<_>..\..\common\jack\jslist.hinstincludes\jackovernewer0 +<_>..\..\common\jack\midiport.hinstincludes\jackovernewer0 +<_>..\..\common\jack\ringbuffer.hinstincludes\jackovernewer0 +<_>..\..\common\jack\statistics.hinstincludes\jackovernewer0 +<_>..\..\common\jack\thread.hinstincludes\jackovernewer0 +<_>..\..\common\jack\transport.hinstincludes\jackovernewer0 +<_>..\..\common\jack\types.hinstincludes\jackovernewer0 <_>.\qjackctl\mingwm10.dllinstovernewer0 <_>.\qjackctl\qjackctl.exeinstovernewer0 <_>.\qjackctl\QtCore4.dllinstovernewer0