Browse Source

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
tags/1.90
moret 17 years ago
parent
commit
70f56fc78e
3 changed files with 244 additions and 154 deletions
  1. +207
    -137
      common/JackTools.cpp
  2. +20
    -0
      common/JackTools.h
  3. +17
    -17
      windows/Setup/jack.ci

+ 207
- 137
common/JackTools.cpp View File

@@ -31,188 +31,258 @@
#include <process.h>
#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<string> 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<arg_len);

//and then duplicate args into the argv array
fNumArgv=args.size();
fArgv=new char* [fNumArgv];
for (i=0; i<fNumArgv; i++) {
fArgv[i]=new char[args[i].length()];
fill_n(fArgv[i],args[i].length()+1,0);
args[i].copy(fArgv[i],args[i].length());
}
for (i=0; i<fNumArgv; i++)
if (fArgv[i][0]=='-')
fArgc++;
}

if (buf[len - 1] != '\n') {
/* didn't get a whole line */
fclose(in);
return -1;
JackArgParser::~JackArgParser() {
delete[] fArgv;
}

jack_tmpdir = (char *)malloc(len);
memcpy(jack_tmpdir, buf, len - 1);
jack_tmpdir[len - 1] = '\0';
string JackArgParser::GetArgString() {
return fArgString;
}

fclose(in);
return 0;
}
#endif
int JackArgParser::GetNumArgv() {
return fNumArgv;
}

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];
int JackArgParser::GetArgc() {
return fArgc;
}
new_name[i] = '\0';
}

const char** JackArgParser::GetArgv() {
return const_cast<const char**>(fArgv);
}
}


+ 20
- 0
common/JackTools.h View File

@@ -32,6 +32,10 @@
#include <sys/syslimits.h>
#endif

#include <string>
#include <algorithm>
#include <vector>

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

+ 17
- 17
windows/Setup/jack.ci View File

@@ -36,7 +36,7 @@
<comptype> ppmdmax</>
<solid> 1</>
<srcfolder> </>
<ifexist> overnewer</>
<ifexist> over</>
<runafter> </>
<runconfirm> 0</>
<uninclude> 1</>
@@ -53,8 +53,8 @@
<bgfoot> </>
<bgback> </>
<files listview >
<_><src>..\Release\bin\libjackmp.a</><dest>inst</><custom>\lib</><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\libjackservermp.a</><dest>inst</><custom>\lib</><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\libjackmp.a</><dest>inst</><custom>lib</><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\libjackservermp.a</><dest>inst</><custom>lib</><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\jack_connect.exe</><dest>inst</><custom></><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\jack_disconnect.exe</><dest>inst</><custom></><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\jack_load.exe</><dest>inst</><custom></><ifexist>overnewer</><recurs>0</></>
@@ -68,20 +68,20 @@
<_><src>..\Release\bin\libjackservermp.dll</><dest>inst</><custom></><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\libsamplerate-0.dll</><dest>inst</><custom></><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\portaudio_x86.dll</><dest>inst</><custom></><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\jackmp\jack_net.dll</><dest>inst</><custom>\jackmp</><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\jackmp\jack_portaudio.dll</><dest>inst</><custom>\jackmp</><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\jackmp\netmanager.dll</><dest>inst</><custom>\jackmp</><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\jackmp\audioadapter.dll</><dest>inst</><custom>\jackmp</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\control.h</><dest>inst</><custom>\includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\intclient.h</><dest>inst</><custom>\includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\jack.h</><dest>inst</><custom>\includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\jslist.h</><dest>inst</><custom>\includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\midiport.h</><dest>inst</><custom>\includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\ringbuffer.h</><dest>inst</><custom>\includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\statistics.h</><dest>inst</><custom>\includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\thread.h</><dest>inst</><custom>\includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\transport.h</><dest>inst</><custom>\includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\types.h</><dest>inst</><custom>\includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\jackmp\jack_net.dll</><dest>inst</><custom>jackmp</><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\jackmp\jack_portaudio.dll</><dest>inst</><custom>jackmp</><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\jackmp\netmanager.dll</><dest>inst</><custom>jackmp</><ifexist>overnewer</><recurs>0</></>
<_><src>..\Release\bin\jackmp\audioadapter.dll</><dest>inst</><custom>jackmp</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\control.h</><dest>inst</><custom>includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\intclient.h</><dest>inst</><custom>includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\jack.h</><dest>inst</><custom>includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\jslist.h</><dest>inst</><custom>includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\midiport.h</><dest>inst</><custom>includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\ringbuffer.h</><dest>inst</><custom>includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\statistics.h</><dest>inst</><custom>includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\thread.h</><dest>inst</><custom>includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\transport.h</><dest>inst</><custom>includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>..\..\common\jack\types.h</><dest>inst</><custom>includes\jack</><ifexist>overnewer</><recurs>0</></>
<_><src>.\qjackctl\mingwm10.dll</><dest>inst</><custom></><ifexist>overnewer</><recurs>0</></>
<_><src>.\qjackctl\qjackctl.exe</><dest>inst</><custom></><ifexist>overnewer</><recurs>0</></>
<_><src>.\qjackctl\QtCore4.dll</><dest>inst</><custom></><ifexist>overnewer</><recurs>0</></>


Loading…
Cancel
Save