diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index e1dc376c..731efba7 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -239,7 +239,7 @@ extern "C" LIB_EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread); LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread); -#ifndef WIN32 +#ifndef _WIN32 LIB_EXPORT void jack_set_thread_creator(jack_thread_creator_t jtc); #endif LIB_EXPORT char * jack_get_internal_client_name(jack_client_t *client, @@ -267,15 +267,6 @@ extern "C" LIB_EXPORT void jack_session_commands_free(jack_session_command_t *cmds); LIB_EXPORT int jack_client_has_session_callback(jack_client_t *client, const char* client_name); - LIB_EXPORT jack_uuid_t jack_client_uuid_generate(); - LIB_EXPORT jack_uuid_t jack_port_uuid_generate(uint32_t port_id); - LIB_EXPORT uint32_t jack_uuid_to_index(jack_uuid_t); - LIB_EXPORT int jack_uuid_compare(jack_uuid_t, jack_uuid_t); - LIB_EXPORT void jack_uuid_copy(jack_uuid_t* dst, jack_uuid_t src); - LIB_EXPORT void jack_uuid_clear(jack_uuid_t*); - LIB_EXPORT int jack_uuid_parse(const char* buf, jack_uuid_t*); - LIB_EXPORT void jack_uuid_unparse(jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]); - LIB_EXPORT int jack_uuid_empty(jack_uuid_t); #ifdef __cplusplus } @@ -1768,7 +1759,7 @@ LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread return JackThread::KillImp(thread); } -#ifndef WIN32 +#ifndef _WIN32 LIB_EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc) { if (jtc == NULL) { @@ -2073,7 +2064,7 @@ LIB_EXPORT int jack_client_has_session_callback(jack_client_t* ext_client, const } } -LIB_EXPORT jack_uuid_t jack_client_uuid_generate() +jack_uuid_t jack_client_uuid_generate() { static uint32_t uuid_cnt = 0; jack_uuid_t uuid = 0x2; /* JackUUIDClient */; @@ -2081,19 +2072,19 @@ LIB_EXPORT jack_uuid_t jack_client_uuid_generate() return uuid; } -LIB_EXPORT jack_uuid_t jack_port_uuid_generate(uint32_t port_id) +jack_uuid_t jack_port_uuid_generate(uint32_t port_id) { jack_uuid_t uuid = 0x1; /* JackUUIDPort */ uuid = (uuid << 32) | (port_id + 1); return uuid; } -LIB_EXPORT uint32_t jack_uuid_to_index(jack_uuid_t u) +uint32_t jack_uuid_to_index(jack_uuid_t u) { return (u & 0xffff) - 1; } -LIB_EXPORT int jack_uuid_compare(jack_uuid_t a, jack_uuid_t b) +int jack_uuid_compare(jack_uuid_t a, jack_uuid_t b) { if (a == b) { return 0; @@ -2106,17 +2097,17 @@ LIB_EXPORT int jack_uuid_compare(jack_uuid_t a, jack_uuid_t b) return 1; } -LIB_EXPORT void jack_uuid_copy(jack_uuid_t* dst, jack_uuid_t src) +void jack_uuid_copy(jack_uuid_t* dst, jack_uuid_t src) { *dst = src; } -LIB_EXPORT void jack_uuid_clear(jack_uuid_t* u) +void jack_uuid_clear(jack_uuid_t* u) { *u = JACK_UUID_EMPTY_INITIALIZER; } -LIB_EXPORT int jack_uuid_parse(const char* b, jack_uuid_t* u) +int jack_uuid_parse(const char* b, jack_uuid_t* u) { if (sscanf (b, "%" PRIu64, u) == 1) { @@ -2131,12 +2122,12 @@ LIB_EXPORT int jack_uuid_parse(const char* b, jack_uuid_t* u) return -1; } -LIB_EXPORT void jack_uuid_unparse(jack_uuid_t u, char b[JACK_UUID_STRING_SIZE]) +void jack_uuid_unparse(jack_uuid_t u, char b[JACK_UUID_STRING_SIZE]) { snprintf (b, JACK_UUID_STRING_SIZE, "%" PRIu64, u); } -LIB_EXPORT int jack_uuid_empty(jack_uuid_t u) +int jack_uuid_empty(jack_uuid_t u) { return u == JACK_UUID_EMPTY_INITIALIZER; } diff --git a/common/JackActivationCount.cpp b/common/JackActivationCount.cpp index b7bde1f0..397d3278 100644 --- a/common/JackActivationCount.cpp +++ b/common/JackActivationCount.cpp @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +#include "systemdeps.h" #include "JackAtomic.h" #include "JackActivationCount.h" #include "JackConstants.h" diff --git a/common/JackAtomic.h b/common/JackAtomic.h index 481e17f3..82a633ef 100644 --- a/common/JackAtomic.h +++ b/common/JackAtomic.h @@ -21,7 +21,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define __JackAtomic__ #include "JackTypes.h" + +#ifndef _MSC_VER #include "JackAtomic_os.h" +#define COMPARE_EXCHANGE(ADDRESS, NEW, EXPECTED) CAS(EXPECTED, NEW, ADDRESS) static inline long INC_ATOMIC(volatile SInt32* val) { @@ -41,6 +44,20 @@ static inline long DEC_ATOMIC(volatile SInt32* val) return actual; } -#endif +#else + +#include "atomic_msvc.h" +using namespace atomic::msvc; + +static inline long INC_ATOMIC(volatile SInt32* val) { + return interlocked::increment(val); +} +static inline long DEC_ATOMIC(volatile SInt32* val) { + return interlocked::decrement(val); +} + +#endif // _MSC_VER + +#endif diff --git a/common/JackAtomicArrayState.h b/common/JackAtomicArrayState.h index 7113da5c..760bdf0c 100644 --- a/common/JackAtomicArrayState.h +++ b/common/JackAtomicArrayState.h @@ -21,6 +21,9 @@ #define __JackAtomicArrayState__ #include "JackAtomic.h" +#ifdef _MSC_VER +#include "JackAtomic_os.h" +#endif #include "JackCompilerDeps.h" #include // for memcpy @@ -138,7 +141,7 @@ class JackAtomicArrayState next_index = SwapIndex1(fCounter, state); need_copy = (GetIndex1(new_val, state) == 0); // Written = false, switch just occured SetIndex1(new_val, state, 0); // Written = false, invalidate state - } while (!CAS(Counter1(old_val), Counter1(new_val), (UInt32*)&fCounter)); + } while (!COMPARE_EXCHANGE((UInt32*)&fCounter, Counter1(new_val), Counter1(old_val))); if (need_copy) memcpy(&fState[next_index], &fState[cur_index], sizeof(T)); return next_index; @@ -152,7 +155,7 @@ class JackAtomicArrayState old_val = fCounter; new_val = old_val; SetIndex1(new_val, state, 1); // Written = true, state becomes "switchable" - } while (!CAS(Counter1(old_val), Counter1(new_val), (UInt32*)&fCounter)); + } while (!COMPARE_EXCHANGE((UInt32*)&fCounter, Counter1(new_val), Counter1(old_val))); } public: @@ -199,7 +202,7 @@ class JackAtomicArrayState SetIndex1(new_val, state, 0); // Invalidate the state "state" IncIndex1(new_val, 3); // Inc switch } - } while (!CAS(Counter1(old_val), Counter1(new_val), (UInt32*)&fCounter)); + } while (!COMPARE_EXCHANGE((UInt32*)&fCounter, Counter1(new_val), Counter1(old_val))); return &fState[GetIndex1(fCounter, 0)]; // Read the counter again } @@ -219,7 +222,7 @@ class JackAtomicArrayState SetIndex1(new_val, state, 0); // Invalidate the state "state" IncIndex1(new_val, 3); // Inc switch } - } while (!CAS(Counter1(old_val), Counter1(new_val), (UInt32*)&fCounter)); + } while (!COMPARE_EXCHANGE((UInt32*)&fCounter, Counter1(new_val), Counter1(old_val))); return &fState[GetIndex1(fCounter, 0)]; // Read the counter again } diff --git a/common/JackAtomicState.h b/common/JackAtomicState.h index 6f90d66a..8a2cee0c 100644 --- a/common/JackAtomicState.h +++ b/common/JackAtomicState.h @@ -21,9 +21,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define __JackAtomicState__ #include "JackAtomic.h" +#ifdef _MSC_VER +#include "JackAtomic_os.h" +#endif #include "JackCompilerDeps.h" #include // for memcpy + namespace Jack { @@ -110,7 +114,7 @@ class JackAtomicState next_index = NextArrayIndex(new_val); need_copy = (CurIndex(new_val) == NextIndex(new_val)); NextIndex(new_val) = CurIndex(new_val); // Invalidate next index - } while (!CAS(Counter(old_val), Counter(new_val), (UInt32*)&fCounter)); + } while (!COMPARE_EXCHANGE((UInt32*)&fCounter, Counter(new_val), Counter(old_val))); if (need_copy) memcpy(&fState[next_index], &fState[cur_index], sizeof(T)); return next_index; @@ -124,7 +128,7 @@ class JackAtomicState old_val = fCounter; new_val = old_val; NextIndex(new_val)++; // Set next index - } while (!CAS(Counter(old_val), Counter(new_val), (UInt32*)&fCounter)); + } while (!COMPARE_EXCHANGE((UInt32*)&fCounter, Counter(new_val), Counter(old_val))); } public: @@ -165,7 +169,7 @@ class JackAtomicState old_val = fCounter; new_val = old_val; CurIndex(new_val) = NextIndex(new_val); // Prepare switch - } while (!CAS(Counter(old_val), Counter(new_val), (UInt32*)&fCounter)); + } while (!COMPARE_EXCHANGE((UInt32*)&fCounter, Counter(new_val), Counter(old_val))); return &fState[CurArrayIndex(fCounter)]; // Read the counter again } @@ -181,7 +185,7 @@ class JackAtomicState new_val = old_val; *result = (CurIndex(new_val) != NextIndex(new_val)); CurIndex(new_val) = NextIndex(new_val); // Prepare switch - } while (!CAS(Counter(old_val), Counter(new_val), (UInt32*)&fCounter)); + } while (!COMPARE_EXCHANGE((UInt32*)&fCounter, Counter(new_val), Counter(old_val))); return &fState[CurArrayIndex(fCounter)]; // Read the counter again } diff --git a/common/JackAudioAdapterFactory.cpp b/common/JackAudioAdapterFactory.cpp index 9ceeee04..5e4bb6fd 100644 --- a/common/JackAudioAdapterFactory.cpp +++ b/common/JackAudioAdapterFactory.cpp @@ -40,7 +40,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define JackPlatformAdapter JackOSSAdapter #endif -#ifdef WIN32 +#ifdef _WIN32 #include "JackPortAudioAdapter.h" #define JackPlatformAdapter JackPortAudioAdapter #endif diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 11abb4e6..2d32a2d3 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -20,7 +20,7 @@ */ -#ifndef WIN32 +#ifndef _WIN32 #include #include #include @@ -534,7 +534,7 @@ jackctl_server_free_parameters( } } -#ifdef WIN32 +#ifdef _WIN32 struct jackctl_sigmask { diff --git a/common/JackDebugClient.cpp b/common/JackDebugClient.cpp index a7d11f9e..b1aa2e93 100644 --- a/common/JackDebugClient.cpp +++ b/common/JackDebugClient.cpp @@ -116,7 +116,7 @@ int JackDebugClient::Close() void JackDebugClient::CheckClient(const char* function_name) const { -#ifdef WIN32 +#ifdef _WIN32 *fStream << "CheckClient : " << function_name << ", calling thread : " << GetCurrentThread() << endl; #else *fStream << "CheckClient : " << function_name << ", calling thread : " << pthread_self() << endl; diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp index 4ce81661..1c9f7d53 100644 --- a/common/JackDriverLoader.cpp +++ b/common/JackDriverLoader.cpp @@ -28,11 +28,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include -#ifndef WIN32 +#ifndef _WIN32 #include #endif -#ifdef WIN32 +#ifdef _MSC_VER +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + +#ifdef _WIN32 static char* locate_dll_driver_dir() { @@ -48,7 +53,7 @@ static char* locate_dll_driver_dir() *p = 0; } jack_info("Drivers/internals found in : %s", driver_dir_storage); - strcat(driver_dir_storage, "/"); + strcat(driver_dir_storage, "\\"); strcat(driver_dir_storage, ADDON_DIR); return strdup(driver_dir_storage); } else { @@ -186,7 +191,8 @@ int jack_parse_driver_params(jack_driver_desc_t* desc, int argc, char* argv[], J /* create the params */ optind = 0; opterr = 0; - while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) { + + while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) { if (opt == ':' || opt == '?') { if (opt == ':') { @@ -318,8 +324,9 @@ SERVER_EXPORT int jackctl_driver_params_parse(jackctl_driver *driver_ptr, int ar /* create the params */ optind = 0; - opterr = 0; - while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) { + opterr = 0; + + while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) { if (opt == ':' || opt == '?') { if (opt == ':') { @@ -417,10 +424,15 @@ static void* check_symbol(const char* sofile, const char* symbol, const char* dr void* dlhandle; void* res = NULL; char filename[1024]; + +#ifdef _WIN32 + sprintf(filename, "%s\\%s", driver_dir, sofile); +#else sprintf(filename, "%s/%s", driver_dir, sofile); +#endif if ((dlhandle = LoadDriverModule(filename)) == NULL) { -#ifdef WIN32 +#ifdef _WIN32 jack_error ("Could not open component .dll '%s': %ld", filename, GetLastError()); #else jack_error ("Could not open component .so '%s': %s", filename, dlerror()); @@ -479,7 +491,7 @@ error: return descriptor; } -#ifdef WIN32 +#ifdef _WIN32 JSList * jack_drivers_load(JSList * drivers) { @@ -608,7 +620,7 @@ JSList* jack_drivers_load (JSList * drivers) #endif -#ifdef WIN32 +#ifdef _WIN32 JSList* jack_internals_load(JSList * internals) { @@ -734,7 +746,7 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver Jack::JackSynchro* synchro, const JSList* params) { -#ifdef WIN32 +#ifdef _WIN32 int errstr; #else const char* errstr; @@ -743,7 +755,7 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver fHandle = LoadDriverModule (driver_desc->file); if (fHandle == NULL) { -#ifdef WIN32 +#ifdef _WIN32 if ((errstr = GetLastError ()) != 0) { jack_error ("Can't load \"%s\": %ld", driver_desc->file, errstr); #else @@ -759,7 +771,7 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver fInitialize = (driverInitialize)GetDriverProc(fHandle, "driver_initialize"); -#ifdef WIN32 +#ifdef _WIN32 if ((fInitialize == NULL) && (errstr = GetLastError ()) != 0) { #else if ((fInitialize == NULL) && (errstr = dlerror ()) != 0) { diff --git a/common/JackDriverLoader.h b/common/JackDriverLoader.h index 1562f76e..5545f7cd 100644 --- a/common/JackDriverLoader.h +++ b/common/JackDriverLoader.h @@ -31,6 +31,7 @@ JSList* jack_internals_load(JSList* internals); void jack_free_driver_params(JSList * param_ptr); void jack_print_driver_options(jack_driver_desc_t* desc, FILE* file); + // External control.h API extern "C" SERVER_EXPORT int jackctl_driver_params_parse(jackctl_driver * driver, int argc, char* argv[]); diff --git a/common/JackDummyDriver.cpp b/common/JackDummyDriver.cpp index 4dc81608..5c29c58f 100644 --- a/common/JackDummyDriver.cpp +++ b/common/JackDummyDriver.cpp @@ -23,7 +23,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackThreadedDriver.h" #include "JackCompilerDeps.h" #include +#ifdef _WIN32 +#include "JackWinThread.h" +#else #include +#endif #include diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index be87c977..0b6d250b 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -43,7 +43,7 @@ JackEngine::JackEngine(JackGraphManager* manager, char self_connect_mode) : JackLockAble(control->fServerName), fSignal(control->fServerName), - fMetadata(NULL) // FIXME use control->fServerName? + fMetadata(NULL) // FIXME use control->fServerName? { fGraphManager = manager; fSynchroTable = table; @@ -774,6 +774,7 @@ int JackEngine::ClientCloseAux(int refnum, bool wait) NotifyRemoveClient(client->GetClientControl()->fName, refnum); fMetadata.RemoveProperties(NULL, uuid); + /* have to do the notification ourselves, since the client argument to fMetadata->RemoveProperties() was NULL */ diff --git a/common/JackEngine.h b/common/JackEngine.h index 8b5136c9..1a3e3ece 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -23,6 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackConstants.h" #include "JackGraphManager.h" #include "JackSynchro.h" +#include "JackMetadata.h" #include "JackMutex.h" #include "JackTransportEngine.h" #include "JackPlatformPlug.h" @@ -55,7 +56,6 @@ class SERVER_EXPORT JackEngine : public JackLockAble JackServerNotifyChannel fChannel; /*! To communicate between the RT thread and server */ JackProcessSync fSignal; jack_time_t fLastSwitchUsecs; - JackMetadata fMetadata; int fSessionPendingReplies; detail::JackChannelTransactionInterface* fSessionTransaction; @@ -163,10 +163,12 @@ class SERVER_EXPORT JackEngine : public JackLockAble int GetClientNameForUUID(const char *uuid, char *name_res); int ReserveClientName(const char *name, const char *uuid); int ClientHasSessionCallback(const char *name); + + // fMetadata needs to be public for JackNetManager.cpp to refernce to it + JackMetadata fMetadata; }; } // end of namespace #endif - diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index 21ae3599..1c9cd1a3 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -105,7 +105,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem fSavedRealTime = false; fServerPriority = priority; - #ifdef WIN32 + #ifdef _WIN32 fClientPriority = (rt) ? priority - 3 : 0; #else fClientPriority = (rt) ? priority - 5 : 0; diff --git a/common/JackFrameTimer.cpp b/common/JackFrameTimer.cpp index 56cbb6ec..7488e5c2 100644 --- a/common/JackFrameTimer.cpp +++ b/common/JackFrameTimer.cpp @@ -26,9 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -#if defined(WIN32) && !defined(__MINGW32__) +#ifdef _MSC_VER /* missing on Windows : see http://bugs.mysql.com/bug.php?id=15936 */ -inline double rint(double nr) +static double rint(double nr) { double f = floor(nr); double c = ceil(nr); @@ -118,7 +118,7 @@ void JackFrameTimer::IncFrameTime(jack_nframes_t buffer_size, jack_time_t callba InitFrameTimeAux(callback_usecs, period_usecs); fFirstWakeUp = false; } - + IncFrameTimeAux(buffer_size, callback_usecs, period_usecs); } @@ -157,35 +157,35 @@ void JackFrameTimer::InitFrameTimeAux(jack_time_t callback_usecs, jack_time_t pe /* There seems to be no significant difference between the two conditions OR-ed above. Incrementing the - frame_time after an xrun shouldn't harm, as there + frame_time after an xrun shouldn't harm, as there will be a discontinuity anyway. So the two are combined in this version. - FA 16/03/2012 + FA 16/03/2012 */ /* Since the DLL *will* be run, next_wakeup should be the current wakeup time *without* adding the period time, as if it were computed in the previous period. - FA 16/03/2012 + FA 16/03/2012 */ /* Added initialisation of timer->period_usecs, required - due to the modified implementation of the DLL itself. + due to the modified implementation of the DLL itself. OTOH, this should maybe not be repeated after e.g. freewheeling or an xrun, as the current value would be more accurate than the nominal one. But it doesn't really harm either. Implementing this would require a new flag - in the engine structure, to be used after freewheeling + in the engine structure, to be used after freewheeling or an xrun instead of first_wakeup. I don't know if this can be done without breaking compatibility, so I did not add this FA 13/02/2012 */ - /* Added initialisation of timer->filter_omega. This makes + /* Added initialisation of timer->filter_omega. This makes the DLL bandwidth independent of the actual period time. The bandwidth is now 1/8 Hz in all cases. The value of timer->filter_omega is 2 * pi * BW * Tperiod. FA 13/02/2012 */ - + JackTimer* timer = WriteNextStateStart(); timer->fPeriodUsecs = (float)period_usecs; timer->fCurrentCallback = callback_usecs; @@ -198,11 +198,11 @@ void JackFrameTimer::InitFrameTimeAux(jack_time_t callback_usecs, jack_time_t pe void JackFrameTimer::IncFrameTimeAux(jack_nframes_t buffer_size, jack_time_t callback_usecs, jack_time_t period_usecs) { JackTimer* timer = WriteNextStateStart(); - + /* Modified implementation (the actual result is the same). 'fSecondOrderIntegrator' is renamed to 'fPeriodUsecs' - and now represents the DLL's best estimate of the + and now represents the DLL's best estimate of the period time in microseconds (before it was a scaled version of the difference w.r.t. the nominal value). This allows this value to be made available to clients @@ -220,19 +220,18 @@ void JackFrameTimer::IncFrameTimeAux(jack_nframes_t buffer_size, jack_time_t cal FA 13/02/2012 */ - + float delta = (float)((int64_t)callback_usecs - (int64_t)timer->fNextWakeUp); delta *= timer->fFilterOmega; timer->fCurrentWakeup = timer->fNextWakeUp; timer->fCurrentCallback = callback_usecs; timer->fFrames += buffer_size; - timer->fPeriodUsecs += timer->fFilterOmega * delta; + timer->fPeriodUsecs += timer->fFilterOmega * delta; timer->fNextWakeUp += (int64_t)floorf(timer->fPeriodUsecs + 1.41f * delta + 0.5f); timer->fInitialized = true; - + WriteNextStateStop(); TrySwitchState(); // always succeed since there is only one writer } } // end of namespace - diff --git a/common/JackGlobals.cpp b/common/JackGlobals.cpp index 1047d169..a4bb4d2c 100644 --- a/common/JackGlobals.cpp +++ b/common/JackGlobals.cpp @@ -38,7 +38,7 @@ JackMutex* JackGlobals::fSynchroMutex = new JackMutex(); volatile bool JackGlobals::fServerRunning = false; JackClient* JackGlobals::fClientTable[CLIENT_NUM] = {}; -#ifndef WIN32 +#ifndef _WIN32 jack_thread_creator_t JackGlobals::fJackThreadCreator = pthread_create; #endif diff --git a/common/JackGlobals.h b/common/JackGlobals.h index 5d7c2421..f0a59d19 100644 --- a/common/JackGlobals.h +++ b/common/JackGlobals.h @@ -45,7 +45,7 @@ struct JackGlobals { static volatile bool fServerRunning; static JackClient* fClientTable[CLIENT_NUM]; static bool fVerbose; -#ifndef WIN32 +#ifndef _WIN32 static jack_thread_creator_t fJackThreadCreator; #endif diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index 4d5061b5..94c152e6 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -24,7 +24,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include +#ifdef _WIN32 +#include +#else #include +#endif namespace Jack { @@ -811,6 +815,7 @@ void JackGraphManager::GetPortsAux(const char** matching_ports, const char* port memset(matching_ports, 0, sizeof(char*) * fPortMax); int match_cnt = 0; + #ifndef _WIN32 regex_t port_regex, type_regex; if (port_name_pattern && port_name_pattern[0]) { @@ -825,6 +830,16 @@ void JackGraphManager::GetPortsAux(const char** matching_ports, const char* port return; } } + #define PORT_REGEX_MATCHES regexec(&port_regex, port->GetName(), 0, NULL, 0) + #define TYPE_REGEX_MATCHES regexec(&type_regex, port->GetType(), 0, NULL, 0) + #else + std::regex port_regex(&port_name_pattern[0]); + std::regex type_regex(&type_name_pattern[0]); + std::cmatch port_regex_match; + std::cmatch type_regex_match; + #define PORT_REGEX_MATCHES regex_match(port->GetName(), port_regex_match, port_regex) + #define TYPE_REGEX_MATCHES regex_match(port->GetType(), type_regex_match, type_regex) + #endif for (unsigned int i = 0; i < fPortMax; i++) { bool matching = true; @@ -839,12 +854,12 @@ void JackGraphManager::GetPortsAux(const char** matching_ports, const char* port } if (matching && port_name_pattern && port_name_pattern[0]) { - if (regexec(&port_regex, port->GetName(), 0, NULL, 0)) { + if (PORT_REGEX_MATCHES) { matching = false; } } if (matching && type_name_pattern && type_name_pattern[0]) { - if (regexec(&type_regex, port->GetType(), 0, NULL, 0)) { + if (TYPE_REGEX_MATCHES) { matching = false; } } @@ -856,13 +871,14 @@ void JackGraphManager::GetPortsAux(const char** matching_ports, const char* port } matching_ports[match_cnt] = 0; - +#ifndef _WIN32 if (port_name_pattern && port_name_pattern[0]) { regfree(&port_regex); } if (type_name_pattern && type_name_pattern[0]) { regfree(&type_regex); } +#endif } // Client @@ -910,5 +926,3 @@ void JackGraphManager::Restore(JackConnectionManager* src) } } // end of namespace - - diff --git a/common/JackLibClient.h b/common/JackLibClient.h index 9fe5d783..cac0bd06 100644 --- a/common/JackLibClient.h +++ b/common/JackLibClient.h @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackClient.h" #include "JackShmMem.h" #include "JackClientControl.h" +#include "JackCompilerDeps.h" #include "JackEngineControl.h" namespace Jack @@ -32,7 +33,7 @@ namespace Jack \brief Client on the library side. */ -class JackLibClient : public JackClient +class LIB_EXPORT JackLibClient : public JackClient { private: diff --git a/common/JackLibGlobals.h b/common/JackLibGlobals.h index 16d93fde..7365af9a 100644 --- a/common/JackLibGlobals.h +++ b/common/JackLibGlobals.h @@ -32,7 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include -#ifdef WIN32 +#ifdef _WIN32 #ifdef __MINGW32__ #include typedef _sigset_t sigset_t; @@ -73,7 +73,7 @@ struct JackLibGlobals fMetadata = new JackMetadata(NULL); // Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. - #ifdef WIN32 + #ifdef _WIN32 // TODO #else sigset_t signals; @@ -94,7 +94,7 @@ struct JackLibGlobals delete fMetadata; // Restore old signal mask - #ifdef WIN32 + #ifdef _WIN32 // TODO #else sigprocmask(SIG_BLOCK, &fProcessSignals, 0); diff --git a/common/JackMessageBuffer.cpp b/common/JackMessageBuffer.cpp index 207e5d7f..42f7cb72 100644 --- a/common/JackMessageBuffer.cpp +++ b/common/JackMessageBuffer.cpp @@ -169,7 +169,7 @@ int JackMessageBuffer::SetInitCallback(JackThreadInitCallback callback, void *ar fInitArg = arg; fInit = callback; - #ifndef WIN32 + #ifndef _WIN32 // wake msg buffer thread fGuard.Signal(); // wait for it to be done diff --git a/common/JackMidiBufferReadQueue.cpp b/common/JackMidiBufferReadQueue.cpp index 67d79b1f..21b26100 100644 --- a/common/JackMidiBufferReadQueue.cpp +++ b/common/JackMidiBufferReadQueue.cpp @@ -45,7 +45,7 @@ JackMidiBufferReadQueue::DequeueEvent() } void -JackMidiBufferReadQueue::ResetMidiBuffer(JackMidiBuffer *buffer) +Jack::JackMidiBufferReadQueue::ResetMidiBuffer(JackMidiBuffer *buffer) { event_count = 0; index = 0; diff --git a/common/JackMidiBufferReadQueue.h b/common/JackMidiBufferReadQueue.h index 84337e42..3fd78d5a 100644 --- a/common/JackMidiBufferReadQueue.h +++ b/common/JackMidiBufferReadQueue.h @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define __JackMidiBufferReadQueue__ #include "JackMidiReadQueue.h" +#include "JackMidiPort.h" namespace Jack { diff --git a/common/JackMidiBufferWriteQueue.cpp b/common/JackMidiBufferWriteQueue.cpp index 82788155..563511c3 100644 --- a/common/JackMidiBufferWriteQueue.cpp +++ b/common/JackMidiBufferWriteQueue.cpp @@ -47,7 +47,7 @@ JackMidiBufferWriteQueue::EnqueueEvent(jack_nframes_t time, size_t size, } void -JackMidiBufferWriteQueue::ResetMidiBuffer(JackMidiBuffer *buffer, +Jack::JackMidiBufferWriteQueue::ResetMidiBuffer(JackMidiBuffer *buffer, jack_nframes_t frames) { if (! buffer) { diff --git a/common/JackMidiPort.cpp b/common/JackMidiPort.cpp index 8731f1e1..7968fc7b 100644 --- a/common/JackMidiPort.cpp +++ b/common/JackMidiPort.cpp @@ -100,7 +100,7 @@ static void MidiBufferMixdown(void* mixbuffer, void** src_buffers, int src_count } mix->Reset(nframes); - uint32_t mix_index[src_count]; + uint32_t* mix_index = new uint32_t[src_count]; int event_count = 0; for (int i = 0; i < src_count; ++i) { JackMidiBuffer* buf = static_cast(src_buffers[i]); diff --git a/common/JackMidiRawOutputWriteQueue.cpp b/common/JackMidiRawOutputWriteQueue.cpp index b81ea0c0..5cd84c3b 100644 --- a/common/JackMidiRawOutputWriteQueue.cpp +++ b/common/JackMidiRawOutputWriteQueue.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackError.h" #include "JackMidiRawOutputWriteQueue.h" +#include "JackMidiSendQueue.h" #include "JackMidiUtil.h" using Jack::JackMidiRawOutputWriteQueue; @@ -29,7 +30,7 @@ using Jack::JackMidiRawOutputWriteQueue; #define STILL_TIME(c, b) ((! (b)) || ((c) < (b))) JackMidiRawOutputWriteQueue:: -JackMidiRawOutputWriteQueue(JackMidiSendQueue *send_queue, size_t non_rt_size, +JackMidiRawOutputWriteQueue(Jack::JackMidiSendQueue *send_queue, size_t non_rt_size, size_t max_non_rt_messages, size_t max_rt_messages) { non_rt_queue = new JackMidiAsyncQueue(non_rt_size, max_non_rt_messages); diff --git a/common/JackMidiRawOutputWriteQueue.h b/common/JackMidiRawOutputWriteQueue.h index 967591bf..bad774bf 100644 --- a/common/JackMidiRawOutputWriteQueue.h +++ b/common/JackMidiRawOutputWriteQueue.h @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define __JackMidiRawOutputWriteQueue__ #include "JackMidiAsyncQueue.h" +#include "JackMidiPort.h" #include "JackMidiSendQueue.h" namespace Jack { diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index c05979b0..4a3a4355 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -173,18 +173,18 @@ namespace Jack public: - JackNetMasterInterface() - : JackNetInterface(), - fRunning(false), - fCurrentCycleOffset(0), - fMaxCycleOffset(0), + JackNetMasterInterface() + : JackNetInterface(), + fRunning(false), + fCurrentCycleOffset(0), + fMaxCycleOffset(0), fSynched(false) {} JackNetMasterInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip) - : JackNetInterface(params, socket, multicast_ip), - fRunning(false), - fCurrentCycleOffset(0), - fMaxCycleOffset(0), + : JackNetInterface(params, socket, multicast_ip), + fRunning(false), + fCurrentCycleOffset(0), + fMaxCycleOffset(0), fSynched(false) {} @@ -201,8 +201,6 @@ namespace Jack protected: - static uint fSlaveCounter; - bool Init(); bool InitConnection(int time_out_sec); bool InitRendering(); @@ -230,6 +228,8 @@ namespace Jack void InitAPI(); + static uint fSlaveCounter; + public: JackNetSlaveInterface() : JackNetInterface() @@ -241,14 +241,16 @@ namespace Jack { InitAPI(); } - + #ifndef _MSC_VER + // FIXME: window static reference to fSlaveCounter not working while linking virtual ~JackNetSlaveInterface() { // close Socket API with the last slave - if (--fSlaveCounter == 0) { + if ( --fSlaveCounter == 0) { SocketAPIEnd(); } } + #endif }; } diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index 250c1237..f9f31da7 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -21,8 +21,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackServerGlobals.h" #include "JackLockedEngine.h" #include "thread.h" +#ifdef _WIN32 +#include "JackMetadata.h" +#include "JackWinNamedPipe.h" +#include "JackNetInterface.h" +#endif -using namespace std; namespace Jack { diff --git a/common/JackNetManager.h b/common/JackNetManager.h index 80a66070..e25fc60b 100644 --- a/common/JackNetManager.h +++ b/common/JackNetManager.h @@ -20,7 +20,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JACKNETMANAGER_H__ #define __JACKNETMANAGER_H__ +#include "JackCompilerDeps.h" #include "JackNetInterface.h" +#include "JackServer.h" #include "jack.h" #include #include @@ -35,7 +37,7 @@ namespace Jack typedef std::list > connections_list_t; - class JackNetMaster : public JackNetMasterInterface + class SERVER_EXPORT JackNetMaster : public JackNetMasterInterface { friend class JackNetMasterManager; @@ -75,7 +77,6 @@ namespace Jack void EncodeTransportData(); void DecodeTransportData(); - int Process(); void TimebaseCallback(jack_position_t* pos); void ConnectPorts(); void ConnectCallback(jack_port_id_t a, jack_port_id_t b, int connect); @@ -89,6 +90,8 @@ namespace Jack ~JackNetMaster(); bool IsSlaveReadyToRoll(); + + int Process(); }; typedef std::list master_list_t; diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index 3985e475..ad81f595 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -58,7 +58,7 @@ JackNetOneDriver::JackNetOneDriver(const char* name, const char* alias, JackLock { jack_log("JackNetOneDriver::JackNetOneDriver port %d", port); -#ifdef WIN32 +#ifdef _WIN32 WSADATA wsa; WSAStartup(MAKEWORD(2, 0), &wsa); #endif diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index c21e5fca..5c011ec3 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -1346,7 +1346,7 @@ namespace Jack SERVER_EXPORT int SocketAPIInit() { -#ifdef WIN32 +#ifdef _WIN32 WORD wVersionRequested = MAKEWORD(2, 2); WSADATA wsaData; @@ -1366,7 +1366,7 @@ namespace Jack SERVER_EXPORT int SocketAPIEnd() { -#ifdef WIN32 +#ifdef _WIN32 return WSACleanup(); #endif return 0; diff --git a/common/JackNetTool.h b/common/JackNetTool.h index b22061c3..14379a59 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -21,7 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackTools.h" #include "types.h" #include "transport.h" -#ifndef WIN32 +#ifndef _WIN32 #include #endif #include diff --git a/common/JackProfiler.cpp b/common/JackProfiler.cpp index 54b8091f..c40a1f98 100644 --- a/common/JackProfiler.cpp +++ b/common/JackProfiler.cpp @@ -21,13 +21,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackEngineControl.h" #include "JackLockedEngine.h" #include "JackArgParser.h" +#ifdef _WIN32 +#include "JackWinNamedPipe.h" +#include "JackWinNamedPipeServerChannel.h" +#endif #include #include namespace Jack { - JackProfilerClient::JackProfilerClient(jack_client_t* client, const char* name) + SERVER_EXPORT JackProfilerClient::JackProfilerClient(jack_client_t* client, const char* name) :fClient(client) { char port_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; @@ -40,7 +44,7 @@ namespace Jack fDurationPort = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); } - JackProfilerClient::~JackProfilerClient() + SERVER_EXPORT JackProfilerClient::~JackProfilerClient() { jack_port_unregister(fClient, fSchedulingPort); jack_port_unregister(fClient, fDurationPort); @@ -202,7 +206,7 @@ extern "C" using namespace Jack; - static Jack::JackProfiler* profiler = NULL; + static JackProfiler* profiler = NULL; SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() { @@ -229,7 +233,7 @@ extern "C" jack_log("Loading profiler"); try { - profiler = new Jack::JackProfiler(jack_client, params); + profiler = new JackProfiler(jack_client, params); assert(profiler); return 0; } catch (...) { @@ -244,7 +248,7 @@ extern "C" int res = 1; jack_driver_desc_t* desc = jack_get_descriptor(); - Jack::JackArgParser parser ( load_init ); + JackArgParser parser ( load_init ); if ( parser.GetArgc() > 0 ) parse_params = parser.ParseParams ( desc, ¶ms ); @@ -257,7 +261,7 @@ extern "C" SERVER_EXPORT void jack_finish(void* arg) { - Jack::JackProfiler* profiler = static_cast(arg); + JackProfiler* profiler = static_cast(arg); if (profiler) { jack_log("Unloading profiler"); diff --git a/common/JackProfiler.h b/common/JackProfiler.h index 6ce93921..4723cf4a 100644 --- a/common/JackProfiler.h +++ b/common/JackProfiler.h @@ -22,7 +22,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackConstants.h" #include "JackPlatformPlug.h" +#include "JackCompilerDeps.h" #include "jack.h" +#include "JackServer.h" #include "jslist.h" #include #include @@ -34,7 +36,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -struct JackProfilerClient { +struct SERVER_EXPORT JackProfilerClient { int fRefNum; jack_client_t* fClient; diff --git a/common/JackProxyDriver.cpp b/common/JackProxyDriver.cpp index 43910776..0869f82a 100644 --- a/common/JackProxyDriver.cpp +++ b/common/JackProxyDriver.cpp @@ -543,7 +543,7 @@ namespace Jack const char* default_client_name = getenv("JACK_PROXY_CLIENT_NAME"); strcpy(client_name, (default_client_name) ? default_client_name : DEFAULT_CLIENT_NAME); -#ifdef WIN32 +#ifdef _WIN32 const char* username = getenv("USERNAME"); #else const char* username = getenv("LOGNAME"); diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index 16688411..75c09ca8 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -314,7 +314,7 @@ bool JackServerGlobals::Init() goto error; } -#ifndef WIN32 +#ifndef _WIN32 if (server_name == NULL) { server_name = (char*)JackTools::DefaultServerName(); } @@ -416,5 +416,3 @@ void JackServerGlobals::Destroy() } } // end of namespace - - diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index beb1880f..88f33943 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -29,7 +29,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -class JackClient; +class SERVER_EXPORT JackClient; /*! \brief Global server static structure: singleton kind of pattern. diff --git a/common/JackTimedDriver.cpp b/common/JackTimedDriver.cpp index 7fccfd01..758c7f4d 100644 --- a/common/JackTimedDriver.cpp +++ b/common/JackTimedDriver.cpp @@ -23,7 +23,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackTime.h" #include "JackCompilerDeps.h" #include +#ifndef _MSC_VER #include +#endif #include namespace Jack diff --git a/common/JackTools.cpp b/common/JackTools.cpp index f5be038e..26b1c5e4 100644 --- a/common/JackTools.cpp +++ b/common/JackTools.cpp @@ -26,7 +26,8 @@ #include #include -#ifdef WIN32 +#ifdef _WIN32 +#include #include #endif @@ -37,7 +38,7 @@ namespace Jack { void JackTools::KillServer() { - #ifdef WIN32 + #ifdef _WIN32 raise(SIGINT); #else kill(GetPID(), SIGINT); @@ -46,7 +47,7 @@ namespace Jack { int JackTools::MkDir(const char* path) { -#ifdef WIN32 +#ifdef _WIN32 return CreateDirectory(path, NULL) == 0; #else return mkdir(path, 0777) != 0; @@ -58,7 +59,7 @@ namespace Jack { int JackTools::GetPID() { -#ifdef WIN32 +#ifdef _WIN32 return _getpid(); #else return getpid(); @@ -67,7 +68,7 @@ namespace Jack { int JackTools::GetUID() { -#ifdef WIN32 +#ifdef _WIN32 return _getpid(); //#error "No getuid function available" #else @@ -85,7 +86,7 @@ namespace Jack { } /* returns the name of the per-user subdirectory of jack_tmpdir */ -#ifdef WIN32 +#ifdef _WIN32 char* JackTools::UserDir() { @@ -235,7 +236,7 @@ namespace Jack { new_name[i] = '\0'; } -#ifdef WIN32 +#ifdef _WIN32 void BuildClientPath(char* path_to_so, int path_len, const char* so_name) { diff --git a/common/JackTools.h b/common/JackTools.h index d7a2ab49..9008e2bb 100644 --- a/common/JackTools.h +++ b/common/JackTools.h @@ -20,7 +20,7 @@ #ifndef __JackTools__ #define __JackTools__ -#ifdef WIN32 +#ifdef _WIN32 #include #define DIR_SEPARATOR '\\' #else diff --git a/common/JackWeakAPI.c b/common/JackWeakAPI.c index 7fcacd72..b25d084c 100644 --- a/common/JackWeakAPI.c +++ b/common/JackWeakAPI.c @@ -24,7 +24,7 @@ #include #include #include -#ifndef WIN32 +#ifndef _WIN32 #include #endif #include @@ -39,12 +39,12 @@ typedef void *(*thread_routine)(void*); static int libjack_is_present = 0; // public symbol, similar to what relaytool does. -#ifdef WIN32 +#ifdef _WIN32 static HMODULE libjack_handle = 0; #else static void *libjack_handle = 0; #endif -#ifndef WIN32 +#ifndef _WIN32 static void __attribute__((constructor)) tryload_libjack() #else void tryload_libjack() @@ -60,7 +60,7 @@ void tryload_libjack() if (!libjack_handle) { fprintf(stderr, "dlopen error : %s \n", dlerror()); } - #elif defined(WIN32) + #elifdef _WIN32 #ifdef _WIN64 libjack_handle = LoadLibrary("libjack64.dll"); #else @@ -80,13 +80,13 @@ void *load_jack_function(const char *fn_name) fprintf (stderr, "libjack not found, so do not try to load %s ffs !\n", fn_name); return 0; } -#ifdef WIN32 +#ifdef _WIN32 fn = (void*)GetProcAddress(libjack_handle, fn_name); #else fn = dlsym(libjack_handle, fn_name); #endif if (!fn) { -#ifdef WIN32 +#ifdef _WIN32 char* lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf,0,NULL ); fprintf(stderr, "could not GetProcAddress( %s ), %s \n", fn_name, lpMsgBuf); @@ -280,7 +280,7 @@ DECL_FUNCTION(int, jack_drop_real_time_scheduling, (jack_native_thread_t thread) DECL_FUNCTION(int, jack_client_stop_thread, (jack_client_t* client, jack_native_thread_t thread), (client, thread)); DECL_FUNCTION(int, jack_client_kill_thread, (jack_client_t* client, jack_native_thread_t thread), (client, thread)); -#ifndef WIN32 +#ifndef _WIN32 DECL_VOID_FUNCTION(jack_set_thread_creator, (jack_thread_creator_t jtc), (jtc)); #endif DECL_FUNCTION(char *, jack_get_internal_client_name, (jack_client_t *client, jack_intclient_t intclient), (client, intclient)); diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index e0b70c94..e7c3298c 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -48,6 +48,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #endif +#ifdef _WIN32 +#include "getopt.h" +#endif + /* This is a simple port of the old jackdmp.cpp file to use the new jack2 control API. Available options for the server are "hard-coded" in the source. A much better approach would be to use the control API to: diff --git a/common/jack/jack.h b/common/jack/jack.h index 05ef7959..5ad2d67f 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -337,9 +337,9 @@ int jack_set_thread_init_callback (jack_client_t *client, * passed to this function will not be called, and the one passed to * jack_on_info_shutdown() will. * - * NOTE: application should typically signal another thread to correctly - * finish cleanup, that is by calling "jack_client_close" - * (since "jack_client_close" cannot be called directly in the context + * NOTE: application should typically signal another thread to correctly + * finish cleanup, that is by calling "jack_client_close" + * (since "jack_client_close" cannot be called directly in the context * of the thread that calls the shutdown callback). */ void jack_on_shutdown (jack_client_t *client, @@ -367,9 +367,9 @@ void jack_on_shutdown (jack_client_t *client, * in case of a client thread shutdown, the callback passed to * jack_on_info_shutdown() will be called. * - * NOTE: application should typically signal another thread to correctly - * finish cleanup, that is by calling "jack_client_close" - * (since "jack_client_close" cannot be called directly in the context + * NOTE: application should typically signal another thread to correctly + * finish cleanup, that is by calling "jack_client_close" + * (since "jack_client_close" cannot be called directly in the context * of the thread that calls the shutdown callback). */ void jack_on_info_shutdown (jack_client_t *client, @@ -1360,14 +1360,14 @@ jack_nframes_t jack_last_frame_time (const jack_client_t *client) JACK_OPTIONAL_ * microseconds. * * NOTES: - * + * * Because of the types used, all the returned values except period_usecs * are unsigned. In computations mapping between frames and microseconds * *signed* differences are required. The easiest way is to compute those * separately and assign them to the appropriate signed variables, * int32_t for frames and int64_t for usecs. See the implementation of * jack_frames_to_time() and Jack_time_to_frames() for an example. - * + * * Unless there was an xrun, skipped cycles, or the current cycle is the * first after freewheeling or starting Jack, the value of current_usecs * will always be the value of next_usecs of the previous cycle. @@ -1386,7 +1386,7 @@ int jack_get_cycle_times(const jack_client_t *client, jack_time_t *current_usecs, jack_time_t *next_usecs, float *period_usecs) JACK_OPTIONAL_WEAK_EXPORT; - + /** * @return the estimated time in microseconds of the specified frame time */ @@ -1420,8 +1420,9 @@ jack_time_t jack_get_time(void) JACK_OPTIONAL_WEAK_EXPORT; * * @param msg error message text (no newline at end). */ + #ifndef _MSC_VER extern void (*jack_error_callback)(const char *msg) JACK_OPTIONAL_WEAK_EXPORT; - +#endif /** * Set the @ref jack_error_callback for error message display. * Set it to NULL to restore default_jack_error_callback function. @@ -1439,7 +1440,9 @@ void jack_set_error_function (void (*func)(const char *)) JACK_OPTIONAL_WEAK_EXP * * @param msg info message text (no newline at end). */ + #ifndef _MSC_VER extern void (*jack_info_callback)(const char *msg) JACK_OPTIONAL_WEAK_EXPORT; +#endif /** * Set the @ref jack_info_callback for info message display. diff --git a/common/jack/systemdeps.h b/common/jack/systemdeps.h index 2244c6e7..7462e21c 100644 --- a/common/jack/systemdeps.h +++ b/common/jack/systemdeps.h @@ -26,7 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. /* POST_PACKED_STRUCTURE needs to be a macro which expands into a compiler directive. The directive must tell the compiler to arrange the preceding structure - declaration so that it is packed on byte-boundaries rather + declaration so that it is packed on byte-boundaries rather than use the natural alignment of the processor and/or compiler. */ @@ -35,7 +35,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define POST_PACKED_STRUCTURE __attribute__((__packed__)) #else - + #ifdef _MSC_VER #define PRE_PACKED_STRUCTURE1 __pragma(pack(push,1)) #define PRE_PACKED_STRUCTURE PRE_PACKED_STRUCTURE1 @@ -60,27 +60,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(GNU_WIN32) - #ifdef __MINGW32__ - # include // mingw gives warning if we include windows.h before winsock2.h - #endif - + #include + #include #include #ifdef _MSC_VER /* Microsoft compiler */ #define __inline__ inline - #if (!defined(int8_t) && !defined(_STDINT_H)) - #define __int8_t_defined - typedef char int8_t; - typedef unsigned char uint8_t; - typedef short int16_t; - typedef unsigned short uint16_t; - typedef long int32_t; - typedef unsigned long uint32_t; - typedef LONGLONG int64_t; - typedef ULONGLONG uint64_t; - #endif #elif __MINGW32__ /* MINGW */ - #include #include #else /* other compilers ...*/ #include diff --git a/common/jack/uuid.h b/common/jack/uuid.h index faa354b5..ee999095 100644 --- a/common/jack/uuid.h +++ b/common/jack/uuid.h @@ -30,6 +30,7 @@ extern "C" { #define JACK_UUID_STRING_SIZE (JACK_UUID_SIZE+1) /* includes trailing null */ #define JACK_UUID_EMPTY_INITIALIZER 0 + extern jack_uuid_t jack_client_uuid_generate (); extern jack_uuid_t jack_port_uuid_generate (uint32_t port_id); @@ -42,6 +43,7 @@ extern int jack_uuid_parse (const char *buf, jack_uuid_t*); extern void jack_uuid_unparse (jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]); extern int jack_uuid_empty (jack_uuid_t); + #ifdef __cplusplus } /* namespace */ #endif diff --git a/common/netjack.c b/common/netjack.c index a77c6ad7..ce658384 100644 --- a/common/netjack.c +++ b/common/netjack.c @@ -30,7 +30,6 @@ $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ #include #include #include -#include #include #include #include @@ -40,11 +39,11 @@ $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ #include -#ifdef WIN32 -#include +#ifdef _WIN32 #include #define socklen_t int #else +#include #include #include #endif @@ -663,7 +662,7 @@ netjack_startup( netjack_driver_state_t *netj ) struct sockaddr_in address; // Now open the socket, and wait for the first packet to arrive... netj->sockfd = socket (AF_INET, SOCK_DGRAM, 0); -#ifdef WIN32 +#ifdef _WIN32 if (netj->sockfd == INVALID_SOCKET) #else if (netj->sockfd == -1) @@ -681,7 +680,7 @@ netjack_startup( netjack_driver_state_t *netj ) } netj->outsockfd = socket (AF_INET, SOCK_DGRAM, 0); -#ifdef WIN32 +#ifdef _WIN32 if (netj->outsockfd == INVALID_SOCKET) #else if (netj->outsockfd == -1) @@ -693,7 +692,7 @@ netjack_startup( netjack_driver_state_t *netj ) netj->srcaddress_valid = 0; if (netj->use_autoconfig) { jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header)); -#ifdef WIN32 +#ifdef _WIN32 int address_size = sizeof( struct sockaddr_in ); #else socklen_t address_size = sizeof (struct sockaddr_in); @@ -707,7 +706,7 @@ netjack_startup( netjack_driver_state_t *netj ) return -1; } first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size); -#ifdef WIN32 +#ifdef _WIN32 if( first_pack_len == -1 ) { first_pack_len = sizeof(jacknet_packet_header); break; diff --git a/common/netjack.h b/common/netjack.h index b21f5bde..bebc863c 100644 --- a/common/netjack.h +++ b/common/netjack.h @@ -21,7 +21,9 @@ #ifndef __NETJACK_H__ #define __NETJACK_H__ +#ifndef _MSC_VER #include +#endif #include #include diff --git a/common/netjack_packet.c b/common/netjack_packet.c index e6a88e9b..8d974ab9 100644 --- a/common/netjack_packet.c +++ b/common/netjack_packet.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -52,12 +51,12 @@ #include -#ifdef WIN32 -#include +#ifdef _WIN32 #include #define socklen_t int #else #include +#include #include #include #endif @@ -350,7 +349,7 @@ cache_packet_is_complete (cache_packet *pack) return 1; } -#ifndef WIN32 +#ifndef _WIN32 // new poll using nanoseconds resolution and // not waiting forever. int @@ -512,7 +511,7 @@ packet_cache_drain_socket( packet_cache *pcache, int sockfd ) jack_nframes_t framecnt; cache_packet *cpack; struct sockaddr_in sender_address; -#ifdef WIN32 +#ifdef _WIN32 int senderlen = sizeof( struct sockaddr_in ); u_long parm = 1; ioctlsocket( sockfd, FIONBIO, &parm ); @@ -520,7 +519,7 @@ packet_cache_drain_socket( packet_cache *pcache, int sockfd ) unsigned int senderlen = sizeof( struct sockaddr_in ); #endif while (1) { -#ifdef WIN32 +#ifdef _WIN32 rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, 0, (struct sockaddr*) &sender_address, &senderlen); #else diff --git a/common/promiscuous.c b/common/promiscuous.c index c6fed3c6..c92bc300 100644 --- a/common/promiscuous.c +++ b/common/promiscuous.c @@ -17,7 +17,7 @@ */ -#ifndef WIN32 +#ifndef _WIN32 #include #include #include @@ -35,7 +35,7 @@ int jack_group2gid(const char* group) { -#ifdef WIN32 +#ifdef _WIN32 return -1; #else size_t buflen; @@ -74,7 +74,7 @@ jack_group2gid(const char* group) #endif } -#ifndef WIN32 +#ifndef _WIN32 int jack_promiscuous_perms(int fd, const char* path, gid_t gid) { diff --git a/common/ringbuffer.c b/common/ringbuffer.c index 9de844f6..7edbe118 100644 --- a/common/ringbuffer.c +++ b/common/ringbuffer.c @@ -58,8 +58,6 @@ LIB_EXPORT void jack_ringbuffer_reset(jack_ringbuffer_t *rb); LIB_EXPORT void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz); LIB_EXPORT size_t jack_ringbuffer_write(jack_ringbuffer_t *rb, const char *src, size_t cnt); -void jack_ringbuffer_write_advance(jack_ringbuffer_t *rb, size_t cnt); -size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb); /* Create a new ringbuffer to hold at least `sz' bytes of data. The actual buffer size is rounded up to the next power of two. */ diff --git a/common/shm.c b/common/shm.c index c8d6c273..c08e6d17 100644 --- a/common/shm.c +++ b/common/shm.c @@ -14,7 +14,7 @@ /* Copyright (C) 2001-2003 Paul Davis Copyright (C) 2005-2012 Grame - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or @@ -32,12 +32,14 @@ */ #include "JackConstants.h" - -#ifdef WIN32 +#ifdef _WIN32 +#define _WINSOCKAPI_ +#include #include #include +#include +#include #else - #include #include #include @@ -47,31 +49,41 @@ #include #include #include -#include #include #include #include +#include #include #include "promiscuous.h" - #endif #include "shm.h" #include "JackError.h" -static int GetUID() +#ifdef _WIN32 +static char* GetUID() { -#ifdef WIN32 - return _getpid(); - //#error "No getuid function available" + #if defined(__HAVE_USERENV_H) + char username[UNLEN+1]; + DWORD username_len = UNLEN+1; + return GetUserName(username, &username_len); + #else + char* username = getenv("USERNAME"); + return username; + #endif +} #else - return geteuid(); -#endif +static char* GetUID() +{ + char buffer [256]; + int n, a=5, b=3; + return sprintf(buffer, "%d", geteuid()); } +#endif static int GetPID() { -#ifdef WIN32 +#ifdef _WIN32 return _getpid(); #else return getpid(); @@ -80,7 +92,7 @@ static int GetPID() #ifdef USE_POSIX_SHM static jack_shmtype_t jack_shmtype = shm_POSIX; -#elif WIN32 +#elif defined(_WIN32) static jack_shmtype_t jack_shmtype = shm_WIN32; #else static jack_shmtype_t jack_shmtype = shm_SYSV; @@ -105,10 +117,10 @@ static void jack_remove_shm (jack_shm_id_t *id); /* per-process global data for the SHM interfaces */ static jack_shm_id_t registry_id; /* SHM id for the registry */ -#ifdef WIN32 +#ifdef _WIN32 static jack_shm_info_t registry_info = {/* SHM info for the registry */ JACK_SHM_NULL_INDEX, - NULL + 0 }; #else static jack_shm_info_t registry_info = { /* SHM info for the registry */ @@ -144,7 +156,7 @@ static char jack_shm_server_prefix[JACK_SERVER_NAME_SIZE+1] = ""; static int semid = -1; -#ifdef WIN32 +#ifdef _WIN32 #include #include @@ -317,16 +329,8 @@ jack_shm_validate_registry () static void jack_set_server_prefix (const char *server_name) { -#ifdef WIN32 - char buffer[UNLEN+1]={0}; - DWORD len = UNLEN+1; - GetUserName(buffer, &len); - snprintf (jack_shm_server_prefix, sizeof (jack_shm_server_prefix), - "jack-%s:%s:", buffer, server_name); -#else - snprintf (jack_shm_server_prefix, sizeof (jack_shm_server_prefix), - "jack-%d:%s:", GetUID(), server_name); -#endif + snprintf (jack_shm_server_prefix, sizeof (jack_shm_server_prefix), + "jack-%s:%s:", GetUID(), server_name); } /* gain server addressability to shared memory registration segment @@ -517,7 +521,7 @@ jack_register_server (const char *server_name, int new_registry) } /* see if server still exists */ - #ifdef WIN32 + #ifdef _WIN32 if (check_process_running(jack_shm_header->server[i].pid)) { res = EEXIST; /* other server running */ goto unlock; @@ -612,7 +616,7 @@ jack_cleanup_shm () } else { /* see if allocator still exists */ - #ifdef WIN32 + #ifdef _WIN32 //jack_info("TODO: kill API not available !!"); #else if (kill (r->allocator, 0)) { @@ -742,7 +746,7 @@ jack_access_registry (jack_shm_info_t *ri) jack_shm_header = ri->ptr.attached_at; jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1); - close (shm_fd); + close (shm_fd); return 0; } @@ -801,7 +805,7 @@ jack_create_registry (jack_shm_info_t *ri) /* initialize registry contents */ jack_shm_init_registry (); - close (shm_fd); + close (shm_fd); return 0; } @@ -858,7 +862,7 @@ jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) * registry index for uniqueness and ignore the shm_name * parameter. Bah! */ - snprintf (name, sizeof (name), "/jack-%d-%d", GetUID(), registry->index); + snprintf (name, sizeof (name), "/jack-%s-%d", GetUID(), registry->index); if (strlen (name) >= sizeof (registry->id)) { jack_error ("shm segment name too long %s", name); @@ -948,7 +952,7 @@ jack_attach_shm_read (jack_shm_info_t* si) return 0; } -#elif WIN32 +#elif _WIN32 static int jack_access_registry (jack_shm_info_t *ri) @@ -1058,7 +1062,7 @@ jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) goto unlock; } - snprintf (name, sizeof (name), "jack-%d-%d", GetUID(), registry->index); + snprintf (name, sizeof (name), "jack-%s-%d", GetUID(), registry->index); if (strlen (name) >= sizeof (registry->id)) { jack_error ("shm segment name too long %s", name); @@ -1307,4 +1311,3 @@ jack_attach_shm_read (jack_shm_info_t* si) } #endif /* !USE_POSIX_SHM */ - diff --git a/common/shm.h b/common/shm.h index e9b4403e..fb400312 100644 --- a/common/shm.h +++ b/common/shm.h @@ -71,7 +71,7 @@ extern "C" typedef char shm_name_t[SHM_NAME_MAX]; typedef shm_name_t jack_shm_id_t; -#elif WIN32 +#elif defined(_WIN32) #define NAME_MAX 255 #ifndef SHM_NAME_MAX #define SHM_NAME_MAX NAME_MAX diff --git a/common/wscript b/common/wscript index afc251a2..22fb3fe5 100644 --- a/common/wscript +++ b/common/wscript @@ -9,13 +9,11 @@ def configure(conf): conf.env['BUILD_ADAPTER'] = conf.env['SAMPLERATE'] if conf.env['IS_WINDOWS']: - try: - conf.check(function_name='regcomp', header_name='regex.h', lib='regex', uselib_store='REGEX', define_name='HAVE_REGEX_H') - except: - conf.check(function_name='regcomp', header_name='regex.h', lib='tre', uselib_store='REGEX', define_name='HAVE_REGEX_H') conf.check(function_name='htons', header_name='winsock2.h', lib='ws2_32', uselib_store='WS2_32', define_name='HAVE_WINSOCK2_H') conf.check(function_name='timeGetDevCaps', header_name=['windows.h', 'mmsystem.h'], lib='winmm', uselib_store='WINMM', define_name='HAVE_MMSYSTEM_H') conf.check(function_name='EnumProcesses', header_name=['windows.h', 'psapi.h'], lib='psapi', uselib_store='PSAPI', define_name='HAVE_PSAPI_H') + conf.check(function_name='UserEnv', header_name=['windows.h'], lib='UserEnv', uselib_store='USERENV', define_name='HAVE_USERENV_H') + conf.check(function_name='SHGetFolderPathA', lib='shell32', header_name=['Shlobj.h'], uselib_store='SHELL32', define_name='HAVE_SHELLOBJ_H') def create_jack_process_obj(bld, target, sources, uselib = None, framework = None): process = bld(features = ['cxx', 'cxxshlib']) @@ -31,6 +29,8 @@ def create_jack_process_obj(bld, target, sources, uselib = None, framework = Non if bld.env['IS_SUN']: env_includes = ['../solaris', '../posix', '../solaris/oss'] if bld.env['IS_WINDOWS']: + if conf.env['CC_NAME'] == 'msvc': + driver.env.append_unique('LDFLAGS', ['/DLL', "common\\build", '/MT']) env_includes = ['../windows', '../windows/portaudio'] process.includes = ['.'] + env_includes + ['jack', '..'] process.name = target @@ -74,7 +74,10 @@ def build(bld): includes.append('..') else: includes.append('../..') - uselib = ['PTHREAD', 'CELT', 'OPUS', 'DB'] + if bld.env['IS_WINDOWS']: + uselib = ['CELT', 'OPUS', 'DB'] + else: + uselib = ['PTHREAD', 'CELT', 'OPUS', 'DB'] if bld.env['IS_LINUX']: common_libsources += [ @@ -125,6 +128,7 @@ def build(bld): if bld.env['IS_WINDOWS']: common_libsources += [ + 'JackDebugClient.cpp', '../windows/JackWinMutex.cpp', '../windows/JackWinProcessSync.cpp', '../windows/JackWinSemaphore.cpp', @@ -132,7 +136,7 @@ def build(bld): '../windows/JackWinTime.c', ] includes = ['../windows' ] + includes - uselib.append('REGEX') + uselib.append('SHELL32') uselib.append('WS2_32') uselib.append('PSAPI') uselib.append('WINMM') @@ -143,8 +147,11 @@ def build(bld): clientlib.defines = 'HAVE_CONFIG_H' clientlib.use = uselib if bld.env['IS_WINDOWS']: - clientlib.env['cxxshlib_PATTERN'] = 'lib%s.dll' - clientlib.install_path = '${BINDIR}' + if bld.env['IS_WIN64']: + clientlib.env['cxxshlib_PATTERN'] = 'lib%s64.dll' + else: + clientlib.env['cxxshlib_PATTERN'] = 'lib%s.dll' + clientlib.install_path = '${BINDIR}' else: clientlib.install_path = '${LIBDIR}' if bld.env['AUTOSTART_METHOD'] == 'dbus': @@ -279,6 +286,7 @@ def build(bld): if bld.env['IS_WINDOWS']: serverlib.source += [ + '../windows/getopt.c', '../windows/JackMMCSS.cpp', '../windows/JackWinNamedPipe.cpp', '../windows/JackWinNamedPipeServerChannel.cpp', @@ -309,9 +317,13 @@ def build(bld): netlib.target = 'jacknet' netlib.use = ['SAMPLERATE', 'CELT', 'OPUS', 'PTHREAD'] if bld.env['IS_WINDOWS']: - netlib.env['cxxshlib_PATTERN'] = 'lib%s.dll' - netlib.install_path = '${BINDIR}' - netlib.use += ['WS2_32', 'WINMM'] + if bld.env['IS_WIN64']: + clientlib.env['cxxshlib_PATTERN'] = 'lib%s64.dll' + else: + clientlib.env['cxxshlib_PATTERN'] = 'lib%s.dll' + netlib.env['cxxshlib_PATTERN'] = 'lib%s.dll' + netlib.install_path = '${BINDIR}' + netlib.use += ['WS2_32', 'WINMM'] elif bld.env['IS_MACOSX']: netlib.install_path = '${LIBDIR}' else: @@ -346,9 +358,10 @@ def build(bld): netlib.vnum = bld.env['JACK_API_VERSION'] - create_jack_process_obj(bld, 'netmanager', 'JackNetManager.cpp', serverlib) - - create_jack_process_obj(bld, 'profiler', 'JackProfiler.cpp', serverlib) + # FIXME: Doesn't link JackServerGlobals::fInstance (help wanted) + if not bld.env['IS_WINDOWS']: + create_jack_process_obj(bld, 'netmanager', 'JackNetManager.cpp', serverlib) + create_jack_process_obj(bld, 'profiler', 'JackProfiler.cpp', serverlib) net_adapter_sources = [ 'JackResampler.cpp', @@ -400,7 +413,6 @@ def build(bld): process = create_jack_process_obj(bld, 'audioadapter', audio_adapter_sources, serverlib) process.use += ['SAMPLERATE', 'PORTAUDIO'] - bld.install_files('${PREFIX}/include/jack', bld.path.ant_glob('jack/*.h')) # process jack.pc.in -> jack.pc diff --git a/windows/JackAtomic_os.h b/windows/JackAtomic_os.h index 2de2aa43..9b5eac7a 100644 --- a/windows/JackAtomic_os.h +++ b/windows/JackAtomic_os.h @@ -22,7 +22,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackTypes.h" -#ifndef __MINGW32__ +#ifdef _MSC_VER +#define COMPARE_EXCHANGE(ADDRESS, NEW, EXPECTED) atomic::msvc::interlocked::compare_exchange(ADDRESS, NEW, EXPECTED) +#endif + +#ifdef __MINGW32__ #ifdef __SMP__ # define LOCK lock #else @@ -36,24 +40,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //---------------------------------------------------------------- // CAS functions //---------------------------------------------------------------- -inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void * addr) -{ - register char c; - __asm { - push ebx - push esi - mov esi, addr - mov eax, value - mov ebx, newvalue - LOCK cmpxchg dword ptr [esi], ebx - sete c - pop esi - pop ebx - } - return c; -} - -#else #define LOCK "lock ; " @@ -70,7 +56,6 @@ static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* ad return ret; } -#endif +#endif // __MINGW32__ #endif - diff --git a/windows/JackNetWinSocket.h b/windows/JackNetWinSocket.h index 153f65bb..4e392fd9 100644 --- a/windows/JackNetWinSocket.h +++ b/windows/JackNetWinSocket.h @@ -21,9 +21,9 @@ #define __JackNetWinSocket__ #include "JackNetSocket.h" -#ifdef __MINGW32__ #include #include +#ifdef __MINGW32__ #include #endif @@ -112,4 +112,3 @@ namespace Jack } #endif - diff --git a/windows/JackRouter/JackRouter.cpp b/windows/JackRouter/JackRouter.cpp index ff51b680..0513efb6 100644 --- a/windows/JackRouter/JackRouter.cpp +++ b/windows/JackRouter/JackRouter.cpp @@ -22,7 +22,7 @@ */ -#ifdef WIN32 +#ifdef _WIN32 #pragma warning (disable : 4786) #endif @@ -56,8 +56,7 @@ static const double twoRaisedTo32Reciprocal = 1. / twoRaisedTo32; //------------------------------------------------------------------------------------------ // on windows, we do the COM stuff. -#if WINDOWS -#include "windows.h" +#if _WIN32 #include "mmsystem.h" #ifdef _WIN64 #define JACK_ROUTER "JackRouter.dll" diff --git a/windows/JackRouter/profport.cpp b/windows/JackRouter/profport.cpp index ffc68b28..4334faee 100644 --- a/windows/JackRouter/profport.cpp +++ b/windows/JackRouter/profport.cpp @@ -286,7 +286,7 @@ int write_private_profile_int(char *section, return write_private_profile_string (section,entry, buffer, file_name); } -#endif // #ifndef WIN32 +#endif // #ifndef _WIN32 /************************************************************************** diff --git a/windows/JackRouter/profport.h b/windows/JackRouter/profport.h index 2f717177..76f8b27a 100644 --- a/windows/JackRouter/profport.h +++ b/windows/JackRouter/profport.h @@ -15,7 +15,7 @@ extern "C" { #endif -#ifdef WIN32 +#ifdef _WIN32 #include "Windows.h" #define get_private_profile_int GetPrivateProfileInt #define get_private_profile_string GetPrivateProfileString diff --git a/windows/JackSystemDeps_os.h b/windows/JackSystemDeps_os.h index 60718519..fb03c096 100644 --- a/windows/JackSystemDeps_os.h +++ b/windows/JackSystemDeps_os.h @@ -28,7 +28,9 @@ #define PATH_MAX 512 #endif +#ifndef UINT32_MAX #define UINT32_MAX 4294967295U +#endif #define DRIVER_HANDLE HINSTANCE #define LoadDriverModule(name) LoadLibrary((name)) diff --git a/windows/JackWinNamedPipe.cpp b/windows/JackWinNamedPipe.cpp index de12c112..106f745a 100644 --- a/windows/JackWinNamedPipe.cpp +++ b/windows/JackWinNamedPipe.cpp @@ -17,7 +17,6 @@ */ - #include "JackWinNamedPipe.h" #include "JackError.h" #include @@ -52,6 +51,16 @@ int JackWinNamedPipeAux::WriteAux(void* data, int len) } } +int JackWinNamedPipe::Read(void* data, int len) +{ + return JackWinNamedPipeAux::ReadAux(data, len); +} + +int JackWinNamedPipe::Write(void* data, int len) +{ + return JackWinNamedPipeAux::WriteAux(data, len); +} + /* See : http://answers.google.com/answers/threadview?id=430173 diff --git a/windows/JackWinNamedPipe.h b/windows/JackWinNamedPipe.h index 01e971a4..cd1b74a4 100644 --- a/windows/JackWinNamedPipe.h +++ b/windows/JackWinNamedPipe.h @@ -23,22 +23,20 @@ #include +#include "JackCompilerDeps_os.h" #include "JackChannel.h" namespace Jack { -class JackWinNamedPipeAux +class SERVER_EXPORT JackWinNamedPipeAux { protected: HANDLE fNamedPipe; char fName[256]; - - int ReadAux(void* data, int len); - int WriteAux(void* data, int len); - + public: JackWinNamedPipeAux(): fNamedPipe(INVALID_HANDLE_VALUE) @@ -47,11 +45,15 @@ class JackWinNamedPipeAux {} virtual ~JackWinNamedPipeAux() {} + + int ReadAux(void* data, int len); + + int WriteAux(void* data, int len); }; -class JackWinNamedPipe : public JackWinNamedPipeAux, public detail::JackChannelTransactionInterface +class SERVER_EXPORT JackWinNamedPipe : public JackWinNamedPipeAux, public detail::JackChannelTransactionInterface { public: @@ -63,21 +65,15 @@ class JackWinNamedPipe : public JackWinNamedPipeAux, public detail::JackChannelT virtual ~JackWinNamedPipe() {} - virtual int Read(void* data, int len) - { - return ReadAux(data, len); - } - virtual int Write(void* data, int len) - { - return WriteAux(data, len); - } + int Read(void* data, int len); + int Write(void* data, int len); }; /*! \brief Client named pipe. */ -class JackWinNamedPipeClient : public JackWinNamedPipeAux, public detail::JackClientRequestInterface +class SERVER_EXPORT JackWinNamedPipeClient : public JackWinNamedPipeAux, public detail::JackClientRequestInterface { protected: @@ -115,7 +111,7 @@ class JackWinNamedPipeClient : public JackWinNamedPipeAux, public detail::JackCl virtual void SetNonBlocking(bool onoff); }; -class JackWinAsyncNamedPipeClient : public JackWinNamedPipeClient +class SERVER_EXPORT JackWinAsyncNamedPipeClient : public JackWinNamedPipeClient { enum kIOState {kIdle = 0, kConnecting, kReading, kWriting}; @@ -156,7 +152,7 @@ class JackWinAsyncNamedPipeClient : public JackWinNamedPipeClient \brief Server named pipe. */ -class JackWinNamedPipeServer : public JackWinNamedPipe +class SERVER_EXPORT JackWinNamedPipeServer : public JackWinNamedPipe { private: @@ -180,7 +176,7 @@ class JackWinNamedPipeServer : public JackWinNamedPipe \brief Server async named pipe. */ -class JackWinAsyncNamedPipeServer : public JackWinNamedPipeServer +class SERVER_EXPORT JackWinAsyncNamedPipeServer : public JackWinNamedPipeServer { private: diff --git a/windows/JackWinNamedPipeServerChannel.h b/windows/JackWinNamedPipeServerChannel.h index e625565f..c10db0f0 100644 --- a/windows/JackWinNamedPipeServerChannel.h +++ b/windows/JackWinNamedPipeServerChannel.h @@ -20,6 +20,7 @@ #ifndef __JackWinNamedPipeServerChannel__ #define __JackWinNamedPipeServerChannel__ +#include "JackCompilerDeps_os.h" #include "JackWinNamedPipe.h" #include "JackPlatformPlug.h" #include "JackConstants.h" @@ -31,7 +32,7 @@ namespace Jack class JackServer; -class JackClientPipeThread : public JackRunnableInterface, public JackClientHandlerInterface +class SERVER_EXPORT JackClientPipeThread : public JackRunnableInterface, public JackClientHandlerInterface { private: @@ -72,7 +73,7 @@ class JackClientPipeThread : public JackRunnableInterface, public JackClientHand \brief JackServerChannel using pipe. */ -class JackWinNamedPipeServerChannel : public JackRunnableInterface +class SERVER_EXPORT JackWinNamedPipeServerChannel : public JackRunnableInterface { private: diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index d586f964..ad8ea632 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -122,6 +122,11 @@ int JackWinThread::StartImp(jack_native_thread_t* thread, int priority, int real return 0; } +int JackWinThread::StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) +{ + return JackWinThread::StartImp(thread, priority, realtime, (ThreadCallback) start_routine, arg); +} + // voir http://www.microsoft.com/belux/msdn/nl/community/columns/ldoc/multithread1.mspx int JackWinThread::Kill() @@ -176,14 +181,32 @@ int JackWinThread::StopImp(jack_native_thread_t thread) } } +int JackWinThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraintt) +{ + jack_log("JackWinThread::AcquireRealTimeImp priority = %d", priority); + + if (priority >= (BASE_REALTIME_PRIORITY - 1) && MMCSSAcquireRealTime(thread, priority) == 0) { + jack_log("MMCSS API used to acquire RT for thread"); + return 0; + } else { + jack_log("MMCSS API not used..."); + if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) { + return 0; + } else { + jack_error("Cannot set thread priority = %d", GetLastError()); + return -1; + } + } +} + int JackWinThread::AcquireRealTime() { - return (fThread != (HANDLE)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; + return (fThread != (HANDLE)NULL) ? JackWinThread::AcquireRealTimeImp(fThread, fPriority, NULL, NULL, NULL) : -1; } int JackWinThread::AcquireSelfRealTime() { - return AcquireRealTimeImp(GetCurrentThread(), fPriority); + return JackWinThread::AcquireRealTimeImp(GetCurrentThread(), fPriority, NULL, NULL, NULL); } int JackWinThread::AcquireRealTime(int priority) @@ -198,24 +221,6 @@ int JackWinThread::AcquireSelfRealTime(int priority) return AcquireSelfRealTime(); } -int JackWinThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority) -{ - jack_log("JackWinThread::AcquireRealTimeImp priority = %d", priority); - - if (priority >= (BASE_REALTIME_PRIORITY - 1) && MMCSSAcquireRealTime(thread, priority) == 0) { - jack_log("MMCSS API used to acquire RT for thread"); - return 0; - } else { - jack_log("MMCSS API not used..."); - if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) { - return 0; - } else { - jack_error("Cannot set thread priority = %d", GetLastError()); - return -1; - } - } -} - int JackWinThread::DropRealTime() { return (fThread != (HANDLE)NULL) ? DropRealTimeImp(fThread) : -1; diff --git a/windows/JackWinThread.h b/windows/JackWinThread.h index 106e9963..809940dc 100644 --- a/windows/JackWinThread.h +++ b/windows/JackWinThread.h @@ -68,16 +68,10 @@ class SERVER_EXPORT JackWinThread : public JackMMCSS, public detail::JackThreadI jack_native_thread_t GetThreadID(); bool IsThread(); - static int AcquireRealTimeImp(jack_native_thread_t thread, int priority); - static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) - { - return JackWinThread::AcquireRealTimeImp(thread, priority); - } + static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint); + static int DropRealTimeImp(jack_native_thread_t thread); - static int StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) - { - return JackWinThread::StartImp(thread, priority, realtime, (ThreadCallback) start_routine, arg); - } + static int StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); static int StartImp(jack_native_thread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg); static int StopImp(jack_native_thread_t thread); static int KillImp(jack_native_thread_t thread); diff --git a/windows/atomic_msvc.h b/windows/atomic_msvc.h new file mode 100644 index 00000000..935a5e58 --- /dev/null +++ b/windows/atomic_msvc.h @@ -0,0 +1,240 @@ +// Author: mbitsnbites +// https://github.com/mbitsnbites/atomic +//----------------------------------------------------------------------------- +// This is free and unencumbered software released into the public domain. +// +// Anyone is free to copy, modify, publish, use, compile, sell, or distribute +// this software, either in source code form or as a compiled binary, for any +// purpose, commercial or non-commercial, and by any means. +// +// In jurisdictions that recognize copyright laws, the author or authors of +// this software dedicate any and all copyright interest in the software to the +// public domain. We make this dedication for the benefit of the public at +// large and to the detriment of our heirs and successors. We intend this +// dedication to be an overt act of relinquishment in perpetuity of all present +// and future rights to this software under copyright law. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// For more information, please refer to +//----------------------------------------------------------------------------- + +#ifndef ATOMIC_ATOMIC_MSVC_H_ +#define ATOMIC_ATOMIC_MSVC_H_ + +// Define which functions we need (don't include ). +extern "C" { +short _InterlockedIncrement16(short volatile*); +long _InterlockedIncrement(long volatile*); +__int64 _InterlockedIncrement64(__int64 volatile*); + +short _InterlockedDecrement16(short volatile*); +long _InterlockedDecrement(long volatile*); +__int64 _InterlockedDecrement64(__int64 volatile*); + +char _InterlockedExchange8(char volatile*, char); +short _InterlockedExchange16(short volatile*, short); +long __cdecl _InterlockedExchange(long volatile*, long); +__int64 _InterlockedExchange64(__int64 volatile*, __int64); + +char _InterlockedCompareExchange8(char volatile*, char, char); +short _InterlockedCompareExchange16(short volatile*, short, short); +long __cdecl _InterlockedCompareExchange(long volatile*, long, long); +__int64 _InterlockedCompareExchange64(__int64 volatile*, __int64, __int64); +}; + +// Define which functions we want to use as inline intriniscs. +#pragma intrinsic(_InterlockedIncrement) +#pragma intrinsic(_InterlockedIncrement16) + +#pragma intrinsic(_InterlockedDecrement) +#pragma intrinsic(_InterlockedDecrement16) + +#pragma intrinsic(_InterlockedCompareExchange) +#pragma intrinsic(_InterlockedCompareExchange8) +#pragma intrinsic(_InterlockedCompareExchange16) + +#pragma intrinsic(_InterlockedExchange) +#pragma intrinsic(_InterlockedExchange8) +#pragma intrinsic(_InterlockedExchange16) + +#if defined(_M_X64) +#pragma intrinsic(_InterlockedIncrement64) +#pragma intrinsic(_InterlockedDecrement64) +#pragma intrinsic(_InterlockedCompareExchange64) +#pragma intrinsic(_InterlockedExchange64) +#endif // _M_X64 + +namespace atomic { +namespace msvc { +template +struct interlocked { +}; + +template +struct interlocked { + static inline T increment(T volatile* x) { + // There's no _InterlockedIncrement8(). + char old_val, new_val; + do { + old_val = static_cast(*x); + new_val = old_val + static_cast(1); + } while (_InterlockedCompareExchange8(reinterpret_cast(x), + new_val, + old_val) != old_val); + return static_cast(new_val); + } + + static inline T decrement(T volatile* x) { + // There's no _InterlockedDecrement8(). + char old_val, new_val; + do { + old_val = static_cast(*x); + new_val = old_val - static_cast(1); + } while (_InterlockedCompareExchange8(reinterpret_cast(x), + new_val, + old_val) != old_val); + return static_cast(new_val); + } + + static inline T compare_exchange(T volatile* x, + const T new_val, + const T expected_val) { + return static_cast( + _InterlockedCompareExchange8(reinterpret_cast(x), + static_cast(new_val), + static_cast(expected_val))); + } + + static inline T exchange(T volatile* x, const T new_val) { + return static_cast(_InterlockedExchange8( + reinterpret_cast(x), static_cast(new_val))); + } +}; + +template +struct interlocked { + static inline T increment(T volatile* x) { + return static_cast( + _InterlockedIncrement16(reinterpret_cast(x))); + } + + static inline T decrement(T volatile* x) { + return static_cast( + _InterlockedDecrement16(reinterpret_cast(x))); + } + + static inline T compare_exchange(T volatile* x, + const T new_val, + const T expected_val) { + return static_cast( + _InterlockedCompareExchange16(reinterpret_cast(x), + static_cast(new_val), + static_cast(expected_val))); + } + + static inline T exchange(T volatile* x, const T new_val) { + return static_cast( + _InterlockedExchange16(reinterpret_cast(x), + static_cast(new_val))); + } +}; + +template +struct interlocked { + static inline T increment(T volatile* x) { + return static_cast( + _InterlockedIncrement(reinterpret_cast(x))); + } + + static inline T decrement(T volatile* x) { + return static_cast( + _InterlockedDecrement(reinterpret_cast(x))); + } + + static inline T compare_exchange(T volatile* x, + const T new_val, + const T expected_val) { + return static_cast( + _InterlockedCompareExchange(reinterpret_cast(x), + static_cast(new_val), + static_cast(expected_val))); + } + + static inline T exchange(T volatile* x, const T new_val) { + return static_cast(_InterlockedExchange( + reinterpret_cast(x), static_cast(new_val))); + } +}; + +template +struct interlocked { + static inline T increment(T volatile* x) { +#if defined(_M_X64) + return static_cast( + _InterlockedIncrement64(reinterpret_cast(x))); +#else + // There's no _InterlockedIncrement64() for 32-bit x86. + __int64 old_val, new_val; + do { + old_val = static_cast<__int64>(*x); + new_val = old_val + static_cast<__int64>(1); + } while (_InterlockedCompareExchange64( + reinterpret_cast(x), new_val, old_val) != + old_val); + return static_cast(new_val); +#endif // _M_X64 + } + + static inline T decrement(T volatile* x) { +#if defined(_M_X64) + return static_cast( + _InterlockedDecrement64(reinterpret_cast(x))); +#else + // There's no _InterlockedDecrement64() for 32-bit x86. + __int64 old_val, new_val; + do { + old_val = static_cast<__int64>(*x); + new_val = old_val - static_cast<__int64>(1); + } while (_InterlockedCompareExchange64( + reinterpret_cast(x), new_val, old_val) != + old_val); + return static_cast(new_val); +#endif // _M_X64 + } + + static inline T compare_exchange(T volatile* x, + const T new_val, + const T expected_val) { + return static_cast(_InterlockedCompareExchange64( + reinterpret_cast(x), + static_cast(new_val), + static_cast(expected_val))); + } + + static inline T exchange(T volatile* x, const T new_val) { +#if defined(_M_X64) + return static_cast( + _InterlockedExchange64(reinterpret_cast(x), + static_cast(new_val))); +#else + // There's no _InterlockedExchange64 for 32-bit x86. + __int64 old_val; + do { + old_val = static_cast<__int64>(*x); + } while (_InterlockedCompareExchange64( + reinterpret_cast(x), new_val, old_val) != + old_val); + return static_cast(old_val); +#endif // _M_X64 + } +}; +} // namespace msvc +} // namespace atomic + +#endif // ATOMIC_ATOMIC_MSVC_H_ diff --git a/windows/getopt.c b/windows/getopt.c index ca5cb5ce..400c41e7 100644 --- a/windows/getopt.c +++ b/windows/getopt.c @@ -1,1047 +1,615 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to drepper@gnu.org - before changing it! - - Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 - Free Software Foundation, Inc. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* This tells Alpha OSF/1 not to define a getopt prototype in . - Ditto for AIX 3.2 and . */ -#ifndef _NO_PROTO -# define _NO_PROTO -#endif - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#if !defined __STDC__ || !__STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -# ifndef const -# define const -# endif -#endif - +/** + * DISCLAIMER + * This file is part of the mingw-w64 runtime package. + * + * The mingw-w64 runtime package and its code is distributed in the hope that it + * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR + * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to + * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + /* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma warning(disable:4996) + + +#include +#include +#include +#include +#include #include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#define GETOPT_INTERFACE_VERSION 2 -#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 -# include -# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION -# define ELIDE_CODE -# endif -#endif - -#ifndef ELIDE_CODE - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -# include -# include -#endif /* GNU C library. */ - -#ifdef VMS -# include -# if HAVE_STRING_H - 0 -# include -# endif -#endif - -#ifndef _ -/* This is for other GNU distributions with internationalized messages. - When compiling libc, the _ macro is predefined. */ -# ifdef HAVE_LIBINTL_H -# include -# define _(msgid) gettext (msgid) -# else -# define _(msgid) (msgid) -# endif -#endif - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - +#include #include "getopt.h" -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* 1003.2 says this must be 1 before any call. */ -int optind = 1; - -/* Formerly, initialization of getopt depended on optind==0, which - causes problems with re-calling getopt as programs generally don't - know that. */ - -int __getopt_initialized; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int optopt = '?'; +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +#undef optreset /* see getopt.h */ +#define optreset __mingw_optreset +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ -/* Describe how to deal with options that follow non-option ARGV-elements. +#define PRINT_ERROR ((opterr) && (*options != ':')) - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return -1 with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -/* Value of POSIXLY_CORRECT environment variable. */ -static char *posixly_correct; - -#ifdef __GNU_LIBRARY__ -/* We want to avoid inclusion of string.h with non-GNU libraries - because there are many ways it can cause trouble. - On some systems, it contains special magic macros that don't work - in GCC. */ -# include -# define my_index strchr +#ifndef __CYGWIN__ +#define __progname __argv[0] #else - -#include - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -#ifndef getenv -extern char *getenv (); +extern char __declspec(dllimport) *__progname; #endif -static char * -my_index (str, chr) - const char *str; - int chr; -{ - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; -} - -/* If using GCC, we can safely declare strlen this way. - If not using GCC, it is ok not to declare it. */ -#ifdef __GNUC__ -/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. - That was relevant to code that was here before. */ -# if (!defined __STDC__ || !__STDC__) && !defined strlen -/* gcc with -traditional declares the built-in strlen to return int, - and has done so at least since version 2.4.5. -- rms. */ -extern int strlen (const char *); -# endif /* not __STDC__ */ -#endif /* __GNUC__ */ - -#endif /* not __GNU_LIBRARY__ */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; +#ifdef __CYGWIN__ +static char EMSG[] = ""; +#else +#define EMSG "" +#endif -#ifdef _LIBC -/* Bash 2.0 gives us an environment variable containing flags - indicating ARGV elements that should not be considered arguments. */ +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); -/* Defined in getopt_init.c */ -extern char *__getopt_nonoption_flags; +static char *place = EMSG; /* option letter processing */ -static int nonoption_flags_max_len; -static int nonoption_flags_len; +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ -static int original_argc; -static char *const *original_argv; +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; -/* Make sure the environment variable bash 2.0 puts in the environment - is valid for the getopt call we must make sure that the ARGV passed - to getopt is that one passed to the process. */ static void -__attribute__ ((unused)) -store_args_and_env (int argc, char *const *argv) +_vwarnx(const char *fmt,va_list ap) { - /* XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ - original_argc = argc; - original_argv = argv; + (void)fprintf(stderr,"%s: ",__progname); + if (fmt != NULL) + (void)vfprintf(stderr,fmt,ap); + (void)fprintf(stderr,"\n"); } -# ifdef text_set_element -text_set_element (__libc_subinit, store_args_and_env); -# endif /* text_set_element */ - -# define SWAP_FLAGS(ch1, ch2) \ - if (nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ - } -#else /* !_LIBC */ -# define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -#if defined __STDC__ && __STDC__ -static void exchange (char **); -#endif static void -exchange (argv) - char **argv; +warnx(const char *fmt,...) { - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ - -#ifdef _LIBC - /* First make sure the handling of the `__getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc (top + 1); - if (new_str == NULL) - nonoption_flags_len = nonoption_flags_max_len = 0; - else - { - memset (__mempcpy (new_str, __getopt_nonoption_flags, - nonoption_flags_max_len), - '\0', top + 1 - nonoption_flags_max_len); - nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; - } - } -#endif - - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; + va_list ap; + va_start(ap,fmt); + _vwarnx(fmt,ap); + va_end(ap); +} - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; } - } - - /* Update records for the slots the non-options now occupy. */ - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; + return (b); } -/* Initialize the internal data when the first call is made. */ - -#if defined __STDC__ && __STDC__ -static const char *_getopt_initialize (int, char *const *, const char *); -#endif -static const char * -_getopt_initialize (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) { - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - first_nonopt = last_nonopt = optind; - - nextchar = NULL; - - posixly_correct = getenv ("POSIXLY_CORRECT"); - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (posixly_correct != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - -#ifdef _LIBC - if (posixly_correct == NULL - && argc == original_argc && argv == original_argv) - { - if (nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = nonoption_flags_max_len = strlen (orig_str); - if (nonoption_flags_max_len < argc) - nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - nonoption_flags_max_len = -1; - else - memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), - '\0', nonoption_flags_max_len - len); - } + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } } - nonoption_flags_len = nonoption_flags_max_len; - } - else - nonoption_flags_len = 0; -#endif - - return optstring; } - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns -1. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the BSD getopt] + */ int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; +getopt(int nargc, char * const *nargv, const char *options) { - optarg = NULL; - if (optind == 0 || !__getopt_initialized) - { - if (optind == 0) - optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring); - __getopt_initialized = 1; - } + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#ifdef _LIBC -# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ - || (optind < nonoption_flags_len \ - && __getopt_nonoption_flags[optind] == '1')) -#else -# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +//extern int getopt(int nargc, char * const *nargv, const char *options); + +#ifdef _BSD_SOURCE +/* + * BSD adds the non-standard `optreset' feature, for reinitialisation + * of `getopt' parsing. We support this feature, for applications which + * proclaim their BSD heritage, before including this header; however, + * to maintain portability, developers are advised to avoid it. + */ +# define optreset __mingw_optreset +extern int optreset; +#endif +#ifdef __cplusplus +} +#endif +/* + * POSIX requires the `getopt' API to be specified in `unistd.h'; + * thus, `unistd.h' includes this header. However, we do not want + * to expose the `getopt_long' or `getopt_long_only' APIs, when + * included in this manner. Thus, close the standard __GETOPT_H__ + * declarations block, and open an additional __GETOPT_LONG_H__ + * specific block, only when *not* __UNISTD_H_SOURCED__, in which + * to declare the extended API. + */ + +#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) +#define __GETOPT_LONG_H__ + +#ifdef __cplusplus +extern "C" { #endif - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (last_nonopt > optind) - last_nonopt = optind; - if (first_nonopt > optind) - first_nonopt = optind; - - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc && NONOPTION_P) - optind++; - last_nonopt = optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return -1; +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too) +{ + char *current_argv, *has_equal; + size_t current_argv_len; + int i, ambiguous, match; + +#define IDENTICAL_INTERPRETATION(_x, _y) \ + (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \ + long_options[(_x)].flag == long_options[(_y)].flag && \ + long_options[(_x)].val == long_options[(_y)].val) + + current_argv = place; + match = -1; + ambiguous = 0; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + ambiguous = 0; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* partial match */ + match = i; + else if (!IDENTICAL_INTERPRETATION(i, match)) + ambiguous = 1; } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if (NONOPTION_P) - { - if (ordering == REQUIRE_ORDER) - return -1; - optarg = argv[optind++]; - return 1; + if (ambiguous) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return (BADCH); } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) - == (unsigned int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - optopt = 0; - return '?'; + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return (BADCH); } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +#undef IDENTICAL_INTERPRETATION +} - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - _("%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - _("%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[optind - 1][0], pfound->name); - } - - nextchar += strlen (nextchar); - - optopt = pfound->val; - return '?'; +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + char *oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; + + if (options == NULL) + return (-1); + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + * + * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or + * optreset != 0 for GNU compatibility. + */ + if (posixly_correct == -1 || optreset != 0) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + if (*options == '+' || *options == '-') + options++; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; } - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - optopt = 0; - return '?'; + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too); + if (optchar != -1) { + place = EMSG; + return (optchar); + } } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: illegal option -- %c\n"), - argv[0], c); - else - fprintf (stderr, _("%s: invalid option -- %c\n"), - argv[0], c); - } - optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; + if ((optchar = (int)*place++) == (int)':' || + (optchar == (int)'-' && *place != '\0') || + (oli = (char*)strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, + idx, 0); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - fprintf (stderr, _("\ -%s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); - - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); } +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) { - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -#endif /* Not ELIDE_CODE. */ - -#ifdef TEST -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ int -main (argc, argv) - int argc; - char **argv; +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) { - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == -1) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } +//extern int getopt_long(int nargc, char * const *nargv, const char *options, +// const struct option *long_options, int *idx); +//extern int getopt_long_only(int nargc, char * const *nargv, const char *options, +// const struct option *long_options, int *idx); +/* + * Previous MinGW implementation had... + */ +#ifndef HAVE_DECL_GETOPT +/* + * ...for the long form API only; keep this for compatibility. + */ +# define HAVE_DECL_GETOPT 1 +#endif - exit (0); -} -#endif /* TEST */ +#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */ \ No newline at end of file diff --git a/windows/getopt.h b/windows/getopt.h index b65740db..a3439199 100644 --- a/windows/getopt.h +++ b/windows/getopt.h @@ -1,172 +1,45 @@ -/* Declarations for getopt. - Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. - This file is part of the GNU C Library. +#ifndef _GETOPT_H_ +#define _GETOPT_H_ - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. +#include "JackCompilerDeps.h" - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef _GETOPT_H - -#ifndef __need_getopt -# define _GETOPT_H 1 -#endif - -#ifdef __cplusplus -extern "C" +struct option /* specification for a long form option... */ { -#endif - - /* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - - extern char *optarg; - - /* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - - extern int optind; - - /* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - - extern int opterr; + const char *name; /* option name, without leading hyphens */ + int has_arg; /* does it take an argument? */ + int *flag; /* where to save its status, or NULL */ + int val; /* its associated status value */ +}; - /* Set to an option character which was unrecognized. */ - - extern int optopt; - -#ifndef __need_getopt - /* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - - struct option { -# if defined __STDC__ && __STDC__ - const char *name; -# else - - char *name; -# endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; - }; - - /* Names for the values of the `has_arg' field of `struct option'. */ - -# define no_argument 0 -# define required_argument 1 -# define optional_argument 2 -#endif /* need getopt */ - - - /* Get definitions and prototypes for functions to process the - arguments in ARGV (ARGC of them, minus the program name) for - options given in OPTS. - - Return the option character from OPTS just read. Return -1 when - there are no more options. For unrecognized options, or options - missing arguments, `optopt' is set to the option letter, and '?' is - returned. - - The OPTS string is a list of characters which are recognized option - letters, optionally followed by colons, specifying that that letter - takes an argument, to be placed in `optarg'. - - If a letter in OPTS is followed by two colons, its argument is - optional. This behavior is specific to the GNU `getopt'. - - The argument `--' causes premature termination of argument - scanning, explicitly telling `getopt' that there are no more - options. - - If OPTS begins with `--', then non-option arguments are treated as - arguments to the option '\0'. This behavior is specific to the GNU - `getopt'. */ +enum /* permitted values for its `has_arg' field... */ +{ + no_argument = 0, /* option never takes an argument */ + required_argument, /* option always requires an argument */ + optional_argument /* option may take an argument */ +}; -#if defined __STDC__ && __STDC__ -# ifdef __GNU_LIBRARY__ - /* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ - extern int getopt (int __argc, char *const *__argv, const char *__shortopts); -# else /* not __GNU_LIBRARY__ */ - extern int getopt (); -# endif /* __GNU_LIBRARY__ */ +#ifdef __cplusplus +extern "C" { +#endif -# ifndef __need_getopt +extern char *optarg; /* argument associated with option */ +SERVER_EXPORT extern int optind; /* index into parent argv vector */ +SERVER_EXPORT extern int optopt; +SERVER_EXPORT extern int opterr; - extern int getopt_long (int argc, char ** argv, const char * shortopts, - const struct option * longopts, int * longind); +SERVER_EXPORT extern int getopt(int nargc, char * const *nargv, const char *options); - extern int getopt_long_only (int __argc, char *const *__argv, - const char *__shortopts, - const struct option *__longopts, int *__longind); +SERVER_EXPORT extern int getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx); - /* Internal only. Users should not call this directly. */ - extern int _getopt_internal (int __argc, char *const *__argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only); -# endif -#else /* not __STDC__ */ - extern int getopt (); -# ifndef __need_getopt - extern int getopt_long (); - extern int getopt_long_only (); +SERVER_EXPORT extern int getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx); - extern int _getopt_internal (); -# endif -#endif /* __STDC__ */ +SERVER_EXPORT extern int getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx); -#ifdef __cplusplus +#ifdef __cplusplus } #endif -/* Make sure we later can get all the definitions and declarations. */ -#undef __need_getopt - -#endif /* getopt.h */ +#endif \ No newline at end of file diff --git a/windows/getopt1.c b/windows/getopt1.c deleted file mode 100644 index 00c3071c..00000000 --- a/windows/getopt1.c +++ /dev/null @@ -1,188 +0,0 @@ -/* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "getopt.h" - -#if !defined __STDC__ || !__STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -#ifndef const -#define const -#endif -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#define GETOPT_INTERFACE_VERSION 2 -#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 -#include -#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION -#define ELIDE_CODE -#endif -#endif - -#ifndef ELIDE_CODE - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#endif - -#ifndef NULL -#define NULL 0 -#endif - -int -getopt_long (argc, argv, options, long_options, opt_index) - int argc; - char **argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); -} - -/* Like getopt_long, but '-' as well as '--' can indicate a long option. - If an option that starts with '-' (not '--') doesn't match a long option, - but does match a short option, it is parsed as a short option - instead. */ - -int -getopt_long_only (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); -} - - -#endif /* Not ELIDE_CODE. */ - -#ifdef TEST - -#include - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == -1) - break; - - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case 'd': - printf ("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/windows/jack_audioadapter.cbp b/windows/jack_audioadapter.cbp deleted file mode 100644 index 50862351..00000000 --- a/windows/jack_audioadapter.cbp +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - diff --git a/windows/jack_connect.cbp b/windows/jack_connect.cbp deleted file mode 100644 index 39fdcb27..00000000 --- a/windows/jack_connect.cbp +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - diff --git a/windows/jack_disconnect.cbp b/windows/jack_disconnect.cbp deleted file mode 100644 index ae62e7fd..00000000 --- a/windows/jack_disconnect.cbp +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - diff --git a/windows/jack_dummy.cbp b/windows/jack_dummy.cbp deleted file mode 100644 index 28342652..00000000 --- a/windows/jack_dummy.cbp +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - diff --git a/windows/jack_latent_client.cbp b/windows/jack_latent_client.cbp deleted file mode 100644 index 1f7e55cb..00000000 --- a/windows/jack_latent_client.cbp +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - diff --git a/windows/jack_load.cbp b/windows/jack_load.cbp deleted file mode 100644 index 43d6e59c..00000000 --- a/windows/jack_load.cbp +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - diff --git a/windows/jack_loopback.cbp b/windows/jack_loopback.cbp deleted file mode 100644 index b797daf9..00000000 --- a/windows/jack_loopback.cbp +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - diff --git a/windows/jack_lsp.cbp b/windows/jack_lsp.cbp deleted file mode 100644 index 5e49b84a..00000000 --- a/windows/jack_lsp.cbp +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - diff --git a/windows/jack_metro.cbp b/windows/jack_metro.cbp deleted file mode 100644 index 04358069..00000000 --- a/windows/jack_metro.cbp +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - diff --git a/windows/jack_midi_dump.cbp b/windows/jack_midi_dump.cbp deleted file mode 100644 index ac5332ab..00000000 --- a/windows/jack_midi_dump.cbp +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - diff --git a/windows/jack_midi_latency_test.cbp b/windows/jack_midi_latency_test.cbp deleted file mode 100644 index eb62a96b..00000000 --- a/windows/jack_midi_latency_test.cbp +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - diff --git a/windows/jack_netadapter.cbp b/windows/jack_netadapter.cbp deleted file mode 100644 index b41b31ec..00000000 --- a/windows/jack_netadapter.cbp +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - diff --git a/windows/jack_netdriver.cbp b/windows/jack_netdriver.cbp deleted file mode 100644 index b3d0c0bc..00000000 --- a/windows/jack_netdriver.cbp +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - diff --git a/windows/jack_netmanager.cbp b/windows/jack_netmanager.cbp deleted file mode 100644 index 4be11f28..00000000 --- a/windows/jack_netmanager.cbp +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - diff --git a/windows/jack_netonedriver.cbp b/windows/jack_netonedriver.cbp deleted file mode 100644 index 0a4e7186..00000000 --- a/windows/jack_netonedriver.cbp +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - diff --git a/windows/jack_netsource.cbp b/windows/jack_netsource.cbp deleted file mode 100644 index 30203452..00000000 --- a/windows/jack_netsource.cbp +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - diff --git a/windows/jack_portaudio.cbp b/windows/jack_portaudio.cbp deleted file mode 100644 index 43664996..00000000 --- a/windows/jack_portaudio.cbp +++ /dev/null @@ -1,241 +0,0 @@ - - - - - - diff --git a/windows/jack_test.cbp b/windows/jack_test.cbp deleted file mode 100644 index 8b301f62..00000000 --- a/windows/jack_test.cbp +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - diff --git a/windows/jack_unload.cbp b/windows/jack_unload.cbp deleted file mode 100644 index 454e08d0..00000000 --- a/windows/jack_unload.cbp +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - diff --git a/windows/jack_winmme.cbp b/windows/jack_winmme.cbp deleted file mode 100644 index 91fa8e04..00000000 --- a/windows/jack_winmme.cbp +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - diff --git a/windows/jackd.cbp b/windows/jackd.cbp deleted file mode 100644 index 71bc5985..00000000 --- a/windows/jackd.cbp +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - diff --git a/windows/jackd.workspace b/windows/jackd.workspace deleted file mode 100644 index dc5bb4c0..00000000 --- a/windows/jackd.workspace +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/windows/libjack.cbp b/windows/libjack.cbp deleted file mode 100644 index 874f214e..00000000 --- a/windows/libjack.cbp +++ /dev/null @@ -1,403 +0,0 @@ - - - - - - diff --git a/windows/libjacknet.cbp b/windows/libjacknet.cbp deleted file mode 100644 index a988450e..00000000 --- a/windows/libjacknet.cbp +++ /dev/null @@ -1,254 +0,0 @@ - - - - - - diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp deleted file mode 100644 index bd7f5708..00000000 --- a/windows/libjackserver.cbp +++ /dev/null @@ -1,381 +0,0 @@ - - - - - - diff --git a/windows/multiple_metro.cbp b/windows/multiple_metro.cbp deleted file mode 100644 index 697bd95b..00000000 --- a/windows/multiple_metro.cbp +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index ad56efd6..6b78d666 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -26,406 +26,405 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. using Jack::JackWinMMEDriver; -JackWinMMEDriver::JackWinMMEDriver(const char *name, const char *alias, - JackLockedEngine *engine, - JackSynchro *table): - JackMidiDriver(name, alias, engine, table) -{ - input_ports = 0; - output_ports = 0; - period = 0; +namespace Jack { + + JackWinMMEDriver::JackWinMMEDriver(char *name, char *alias, JackLockedEngine *engine, JackSynchro *table): JackMidiDriver(name, alias, engine, table) + { + input_ports = 0; + output_ports = 0; + period = 0; + } + + JackWinMMEDriver::~JackWinMMEDriver() + {} + + int + JackWinMMEDriver::Attach() + { + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + jack_port_id_t index; + jack_nframes_t latency = buffer_size; + jack_latency_range_t latency_range; + const char *name; + JackPort *port; + latency_range.max = latency + + ((jack_nframes_t) std::ceil((period / 1000.0) * + fEngineControl->fSampleRate)); + latency_range.min = latency; + + jack_log("JackWinMMEDriver::Attach - fCaptureChannels %d", fCaptureChannels); + jack_log("JackWinMMEDriver::Attach - fPlaybackChannels %d", fPlaybackChannels); + + // Inputs + for (int i = 0; i < fCaptureChannels; i++) { + JackWinMMEInputPort *input_port = input_ports[i]; + name = input_port->GetName(); + if (fEngine->PortRegister(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + CaptureDriverFlags, buffer_size, &index) < 0) { + jack_error("JackWinMMEDriver::Attach - cannot register input port " + "with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; + } + port = fGraphManager->GetPort(index); + port->SetAlias(input_port->GetAlias()); + port->SetLatencyRange(JackCaptureLatency, &latency_range); + fCapturePortList[i] = index; + } + + if (! fEngineControl->fSyncMode) { + latency += buffer_size; + latency_range.max = latency; + latency_range.min = latency; + } + + // Outputs + for (int i = 0; i < fPlaybackChannels; i++) { + JackWinMMEOutputPort *output_port = output_ports[i]; + name = output_port->GetName(); + if (fEngine->PortRegister(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + PlaybackDriverFlags, buffer_size, &index) < 0) { + jack_error("JackWinMMEDriver::Attach - cannot register output " + "port with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; + } + port = fGraphManager->GetPort(index); + port->SetAlias(output_port->GetAlias()); + port->SetLatencyRange(JackPlaybackLatency, &latency_range); + fPlaybackPortList[i] = index; + } + + return 0; + } + + int + JackWinMMEDriver::Close() + { + // Generic MIDI driver close + int result = JackMidiDriver::Close(); + + if (input_ports) { + for (int i = 0; i < fCaptureChannels; i++) { + delete input_ports[i]; + } + delete[] input_ports; + input_ports = 0; + } + if (output_ports) { + for (int i = 0; i < fPlaybackChannels; i++) { + delete output_ports[i]; + } + delete[] output_ports; + output_ports = 0; + } + if (period) { + if (timeEndPeriod(period) != TIMERR_NOERROR) { + jack_error("JackWinMMEDriver::Close - failed to unset timer " + "resolution."); + result = -1; + } + } + return result; + } + + int + JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, + int out_channels, bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) + { + const char *client_name = fClientControl.fName; + int input_count = 0; + int output_count = 0; + int num_potential_inputs = midiInGetNumDevs(); + int num_potential_outputs = midiOutGetNumDevs(); + + jack_log("JackWinMMEDriver::Open - num_potential_inputs %d", num_potential_inputs); + jack_log("JackWinMMEDriver::Open - num_potential_outputs %d", num_potential_outputs); + + period = 0; + TIMECAPS caps; + if (timeGetDevCaps(&caps, sizeof(TIMECAPS)) != TIMERR_NOERROR) { + jack_error("JackWinMMEDriver::Open - could not get timer device " + "capabilities. Continuing anyway ..."); + } else { + period = caps.wPeriodMin; + if (timeBeginPeriod(period) != TIMERR_NOERROR) { + jack_error("JackWinMMEDriver::Open - could not set minimum timer " + "resolution. Continuing anyway ..."); + period = 0; + } else { + jack_log("JackWinMMEDriver::Open - multimedia timer resolution " + "set to %d milliseconds.", period); + } + } + + if (num_potential_inputs) { + try { + input_ports = new JackWinMMEInputPort *[num_potential_inputs]; + } catch (std::exception& e) { + jack_error("JackWinMMEDriver::Open - while creating input port " + "array: %s", e.what()); + goto unset_timer_resolution; + } + for (int i = 0; i < num_potential_inputs; i++) { + try { + input_ports[input_count] = + new JackWinMMEInputPort(fAliasName, client_name, + capture_driver_name, i); + } catch (std::exception& e) { + jack_error("JackWinMMEDriver::Open - while creating input " + "port: %s", e.what()); + continue; + } + input_count++; + } + } + if (num_potential_outputs) { + try { + output_ports = new JackWinMMEOutputPort *[num_potential_outputs]; + } catch (std::exception& e) { + jack_error("JackWinMMEDriver::Open - while creating output port " + "array: %s", e.what()); + goto destroy_input_ports; + } + for (int i = 0; i < num_potential_outputs; i++) { + try { + output_ports[output_count] = + new JackWinMMEOutputPort(fAliasName, client_name, + playback_driver_name, i); + } catch (std::exception& e) { + jack_error("JackWinMMEDriver::Open - while creating output " + "port: %s", e.what()); + continue; + } + output_count++; + } + } + + jack_log("JackWinMMEDriver::Open - input_count %d", input_count); + jack_log("JackWinMMEDriver::Open - output_count %d", output_count); + + if (! (input_count || output_count)) { + jack_error("JackWinMMEDriver::Open - no WinMME inputs or outputs " + "allocated."); + } else if (! JackMidiDriver::Open(capturing, playing, input_count, + output_count, monitor, + capture_driver_name, + playback_driver_name, capture_latency, + playback_latency)) { + return 0; + } + + if (output_ports) { + for (int i = 0; i < output_count; i++) { + delete output_ports[i]; + } + delete[] output_ports; + output_ports = 0; + } + destroy_input_ports: + if (input_ports) { + for (int i = 0; i < input_count; i++) { + delete input_ports[i]; + } + delete[] input_ports; + input_ports = 0; + } + unset_timer_resolution: + if (period) { + if (timeEndPeriod(period) != TIMERR_NOERROR) { + jack_error("JackWinMMEDriver::Open - failed to unset timer " + "resolution."); + } + } + return -1; + } + + int + JackWinMMEDriver::Read() + { + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + for (int i = 0; i < fCaptureChannels; i++) { + input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); + } + + return 0; + } + + int + JackWinMMEDriver::Write() + { + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + for (int i = 0; i < fPlaybackChannels; i++) { + output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); + } + + return 0; + } + + int + JackWinMMEDriver::Start() + { + jack_log("JackWinMMEDriver::Start - Starting driver."); + + JackMidiDriver::Start(); + + int input_count = 0; + int output_count = 0; + + jack_log("JackWinMMEDriver::Start - Enabling input ports."); + + for (; input_count < fCaptureChannels; input_count++) { + if (input_ports[input_count]->Start() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to enable input " + "port."); + goto stop_input_ports; + } + } + + jack_log("JackWinMMEDriver::Start - Enabling output ports."); + + for (; output_count < fPlaybackChannels; output_count++) { + if (output_ports[output_count]->Start() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to enable output " + "port."); + goto stop_output_ports; + } + } + + jack_log("JackWinMMEDriver::Start - Driver started."); + return 0; + + stop_output_ports: + for (int i = 0; i < output_count; i++) { + if (output_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to disable output " + "port."); + } + } + stop_input_ports: + for (int i = 0; i < input_count; i++) { + if (input_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to disable input " + "port."); + } + } + + return -1; + } + + int + JackWinMMEDriver::Stop() + { + int result = 0; + + JackMidiDriver::Stop(); + + jack_log("JackWinMMEDriver::Stop - disabling input ports."); + + for (int i = 0; i < fCaptureChannels; i++) { + if (input_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Stop - Failed to disable input " + "port."); + result = -1; + } + } + + jack_log("JackWinMMEDriver::Stop - disabling output ports."); + + for (int i = 0; i < fPlaybackChannels; i++) { + if (output_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Stop - Failed to disable output " + "port."); + result = -1; + } + } + + return result; + } + + #ifdef __cplusplus + extern "C" + { + #endif + + // singleton kind of driver + static Jack::JackWinMMEDriver* driver = NULL; + + SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() + { + return jack_driver_descriptor_construct("winmme", JackDriverSlave, "WinMME API based MIDI backend", NULL); + } + + SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) + { + /* + unsigned int capture_ports = 2; + unsigned int playback_ports = 2; + unsigned long wait_time = 0; + const JSList * node; + const jack_driver_param_t * param; + bool monitor = false; + + for (node = params; node; node = jack_slist_next (node)) { + param = (const jack_driver_param_t *) node->data; + + switch (param->character) { + + case 'C': + capture_ports = param->value.ui; + break; + + case 'P': + playback_ports = param->value.ui; + break; + + case 'r': + sample_rate = param->value.ui; + break; + + case 'p': + period_size = param->value.ui; + break; + + case 'w': + wait_time = param->value.ui; + break; + + case 'm': + monitor = param->value.i; + break; + } + } + */ + + // singleton kind of driver + if (!driver) { + driver = new Jack::JackWinMMEDriver("system_midi", "winmme", engine, table); + if (driver->Open(1, 1, 0, 0, false, "in", "out", 0, 0) == 0) { + return driver; + } else { + delete driver; + return NULL; + } + } else { + jack_info("JackWinMMEDriver already allocated, cannot be loaded twice"); + return NULL; + } + + } + + #ifdef __cplusplus + } + #endif } -JackWinMMEDriver::~JackWinMMEDriver() -{} - -int -JackWinMMEDriver::Attach() -{ - jack_nframes_t buffer_size = fEngineControl->fBufferSize; - jack_port_id_t index; - jack_nframes_t latency = buffer_size; - jack_latency_range_t latency_range; - const char *name; - JackPort *port; - latency_range.max = latency + - ((jack_nframes_t) std::ceil((period / 1000.0) * - fEngineControl->fSampleRate)); - latency_range.min = latency; - - jack_log("JackWinMMEDriver::Attach - fCaptureChannels %d", fCaptureChannels); - jack_log("JackWinMMEDriver::Attach - fPlaybackChannels %d", fPlaybackChannels); - - // Inputs - for (int i = 0; i < fCaptureChannels; i++) { - JackWinMMEInputPort *input_port = input_ports[i]; - name = input_port->GetName(); - if (fEngine->PortRegister(fClientControl.fRefNum, name, - JACK_DEFAULT_MIDI_TYPE, - CaptureDriverFlags, buffer_size, &index) < 0) { - jack_error("JackWinMMEDriver::Attach - cannot register input port " - "with name '%s'.", name); - // X: Do we need to deallocate ports? - return -1; - } - port = fGraphManager->GetPort(index); - port->SetAlias(input_port->GetAlias()); - port->SetLatencyRange(JackCaptureLatency, &latency_range); - fCapturePortList[i] = index; - } - - if (! fEngineControl->fSyncMode) { - latency += buffer_size; - latency_range.max = latency; - latency_range.min = latency; - } - - // Outputs - for (int i = 0; i < fPlaybackChannels; i++) { - JackWinMMEOutputPort *output_port = output_ports[i]; - name = output_port->GetName(); - if (fEngine->PortRegister(fClientControl.fRefNum, name, - JACK_DEFAULT_MIDI_TYPE, - PlaybackDriverFlags, buffer_size, &index) < 0) { - jack_error("JackWinMMEDriver::Attach - cannot register output " - "port with name '%s'.", name); - // X: Do we need to deallocate ports? - return -1; - } - port = fGraphManager->GetPort(index); - port->SetAlias(output_port->GetAlias()); - port->SetLatencyRange(JackPlaybackLatency, &latency_range); - fPlaybackPortList[i] = index; - } - - return 0; -} - -int -JackWinMMEDriver::Close() -{ - // Generic MIDI driver close - int result = JackMidiDriver::Close(); - - if (input_ports) { - for (int i = 0; i < fCaptureChannels; i++) { - delete input_ports[i]; - } - delete[] input_ports; - input_ports = 0; - } - if (output_ports) { - for (int i = 0; i < fPlaybackChannels; i++) { - delete output_ports[i]; - } - delete[] output_ports; - output_ports = 0; - } - if (period) { - if (timeEndPeriod(period) != TIMERR_NOERROR) { - jack_error("JackWinMMEDriver::Close - failed to unset timer " - "resolution."); - result = -1; - } - } - return result; -} - -int -JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, - int out_channels, bool monitor, - const char* capture_driver_name, - const char* playback_driver_name, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency) -{ - const char *client_name = fClientControl.fName; - int input_count = 0; - int output_count = 0; - int num_potential_inputs = midiInGetNumDevs(); - int num_potential_outputs = midiOutGetNumDevs(); - - jack_log("JackWinMMEDriver::Open - num_potential_inputs %d", num_potential_inputs); - jack_log("JackWinMMEDriver::Open - num_potential_outputs %d", num_potential_outputs); - - period = 0; - TIMECAPS caps; - if (timeGetDevCaps(&caps, sizeof(TIMECAPS)) != TIMERR_NOERROR) { - jack_error("JackWinMMEDriver::Open - could not get timer device " - "capabilities. Continuing anyway ..."); - } else { - period = caps.wPeriodMin; - if (timeBeginPeriod(period) != TIMERR_NOERROR) { - jack_error("JackWinMMEDriver::Open - could not set minimum timer " - "resolution. Continuing anyway ..."); - period = 0; - } else { - jack_log("JackWinMMEDriver::Open - multimedia timer resolution " - "set to %d milliseconds.", period); - } - } - - if (num_potential_inputs) { - try { - input_ports = new JackWinMMEInputPort *[num_potential_inputs]; - } catch (std::exception& e) { - jack_error("JackWinMMEDriver::Open - while creating input port " - "array: %s", e.what()); - goto unset_timer_resolution; - } - for (int i = 0; i < num_potential_inputs; i++) { - try { - input_ports[input_count] = - new JackWinMMEInputPort(fAliasName, client_name, - capture_driver_name, i); - } catch (std::exception& e) { - jack_error("JackWinMMEDriver::Open - while creating input " - "port: %s", e.what()); - continue; - } - input_count++; - } - } - if (num_potential_outputs) { - try { - output_ports = new JackWinMMEOutputPort *[num_potential_outputs]; - } catch (std::exception& e) { - jack_error("JackWinMMEDriver::Open - while creating output port " - "array: %s", e.what()); - goto destroy_input_ports; - } - for (int i = 0; i < num_potential_outputs; i++) { - try { - output_ports[output_count] = - new JackWinMMEOutputPort(fAliasName, client_name, - playback_driver_name, i); - } catch (std::exception& e) { - jack_error("JackWinMMEDriver::Open - while creating output " - "port: %s", e.what()); - continue; - } - output_count++; - } - } - - jack_log("JackWinMMEDriver::Open - input_count %d", input_count); - jack_log("JackWinMMEDriver::Open - output_count %d", output_count); - - if (! (input_count || output_count)) { - jack_error("JackWinMMEDriver::Open - no WinMME inputs or outputs " - "allocated."); - } else if (! JackMidiDriver::Open(capturing, playing, input_count, - output_count, monitor, - capture_driver_name, - playback_driver_name, capture_latency, - playback_latency)) { - return 0; - } - - if (output_ports) { - for (int i = 0; i < output_count; i++) { - delete output_ports[i]; - } - delete[] output_ports; - output_ports = 0; - } - destroy_input_ports: - if (input_ports) { - for (int i = 0; i < input_count; i++) { - delete input_ports[i]; - } - delete[] input_ports; - input_ports = 0; - } - unset_timer_resolution: - if (period) { - if (timeEndPeriod(period) != TIMERR_NOERROR) { - jack_error("JackWinMMEDriver::Open - failed to unset timer " - "resolution."); - } - } - return -1; -} - -int -JackWinMMEDriver::Read() -{ - jack_nframes_t buffer_size = fEngineControl->fBufferSize; - for (int i = 0; i < fCaptureChannels; i++) { - input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); - } - - return 0; -} - -int -JackWinMMEDriver::Write() -{ - jack_nframes_t buffer_size = fEngineControl->fBufferSize; - for (int i = 0; i < fPlaybackChannels; i++) { - output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); - } - - return 0; -} - -int -JackWinMMEDriver::Start() -{ - jack_log("JackWinMMEDriver::Start - Starting driver."); - - JackMidiDriver::Start(); - - int input_count = 0; - int output_count = 0; - - jack_log("JackWinMMEDriver::Start - Enabling input ports."); - - for (; input_count < fCaptureChannels; input_count++) { - if (input_ports[input_count]->Start() < 0) { - jack_error("JackWinMMEDriver::Start - Failed to enable input " - "port."); - goto stop_input_ports; - } - } - - jack_log("JackWinMMEDriver::Start - Enabling output ports."); - - for (; output_count < fPlaybackChannels; output_count++) { - if (output_ports[output_count]->Start() < 0) { - jack_error("JackWinMMEDriver::Start - Failed to enable output " - "port."); - goto stop_output_ports; - } - } - - jack_log("JackWinMMEDriver::Start - Driver started."); - return 0; - - stop_output_ports: - for (int i = 0; i < output_count; i++) { - if (output_ports[i]->Stop() < 0) { - jack_error("JackWinMMEDriver::Start - Failed to disable output " - "port."); - } - } - stop_input_ports: - for (int i = 0; i < input_count; i++) { - if (input_ports[i]->Stop() < 0) { - jack_error("JackWinMMEDriver::Start - Failed to disable input " - "port."); - } - } - - return -1; -} - -int -JackWinMMEDriver::Stop() -{ - int result = 0; - - JackMidiDriver::Stop(); - - jack_log("JackWinMMEDriver::Stop - disabling input ports."); - - for (int i = 0; i < fCaptureChannels; i++) { - if (input_ports[i]->Stop() < 0) { - jack_error("JackWinMMEDriver::Stop - Failed to disable input " - "port."); - result = -1; - } - } - - jack_log("JackWinMMEDriver::Stop - disabling output ports."); - - for (int i = 0; i < fPlaybackChannels; i++) { - if (output_ports[i]->Stop() < 0) { - jack_error("JackWinMMEDriver::Stop - Failed to disable output " - "port."); - result = -1; - } - } - - return result; -} - -#ifdef __cplusplus -extern "C" -{ -#endif - - // singleton kind of driver - static Jack::JackWinMMEDriver* driver = NULL; - - SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() - { - return jack_driver_descriptor_construct("winmme", JackDriverSlave, "WinMME API based MIDI backend", NULL); - } - - SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) - { - /* - unsigned int capture_ports = 2; - unsigned int playback_ports = 2; - unsigned long wait_time = 0; - const JSList * node; - const jack_driver_param_t * param; - bool monitor = false; - - for (node = params; node; node = jack_slist_next (node)) { - param = (const jack_driver_param_t *) node->data; - - switch (param->character) { - - case 'C': - capture_ports = param->value.ui; - break; - - case 'P': - playback_ports = param->value.ui; - break; - - case 'r': - sample_rate = param->value.ui; - break; - - case 'p': - period_size = param->value.ui; - break; - - case 'w': - wait_time = param->value.ui; - break; - - case 'm': - monitor = param->value.i; - break; - } - } - */ - - // singleton kind of driver - if (!driver) { - driver = new Jack::JackWinMMEDriver("system_midi", "winmme", engine, table); - if (driver->Open(1, 1, 0, 0, false, "in", "out", 0, 0) == 0) { - return driver; - } else { - delete driver; - return NULL; - } - } else { - jack_info("JackWinMMEDriver already allocated, cannot be loaded twice"); - return NULL; - } - - } - -#ifdef __cplusplus -} -#endif - - /* jack_connect system:midi_capture_1 system_midi:playback_1 jack_connect system:midi_capture_1 system_midi:playback_2 @@ -442,4 +441,3 @@ jack_connect system_midi:capture_2 system:midi_playback_1 jack_connect system_midi:capture_1 system_midi:playback_1 */ - diff --git a/windows/winmme/JackWinMMEDriver.h b/windows/winmme/JackWinMMEDriver.h index 3bcdb7e6..b69dbb73 100644 --- a/windows/winmme/JackWinMMEDriver.h +++ b/windows/winmme/JackWinMMEDriver.h @@ -37,8 +37,7 @@ namespace Jack { public: - JackWinMMEDriver(const char* name, const char* alias, - JackLockedEngine* engine, JackSynchro* table); + JackWinMMEDriver(char* name, char* alias, JackLockedEngine* engine, JackSynchro* table); ~JackWinMMEDriver(); diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index c1d3fa15..5ccfb0a9 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackError.h" #include "JackTime.h" #include "JackMidiUtil.h" +#include "JackMidiPort.h" #include "JackWinMMEInputPort.h" #include "JackMidiWriteQueue.h" @@ -176,7 +177,7 @@ JackWinMMEInputPort::GetInErrorString(MMRESULT error, LPTSTR text) } void -JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, +JackWinMMEInputPort::ProcessJack(Jack::JackMidiBuffer *port_buffer, jack_nframes_t frames) { write_queue->ResetMidiBuffer(port_buffer, frames); diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 20452d7e..3a2eac2b 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include "JackMidiUtil.h" +#include "JackMidiPort.h" #include "JackTime.h" #include "JackWinMMEOutputPort.h" #include "JackGlobals.h" @@ -285,7 +286,7 @@ JackWinMMEOutputPort::Init() } void -JackWinMMEOutputPort::ProcessJack(JackMidiBuffer *port_buffer, +JackWinMMEOutputPort::ProcessJack(Jack::JackMidiBuffer *port_buffer, jack_nframes_t frames) { read_queue->ResetMidiBuffer(port_buffer); diff --git a/wscript b/wscript index f73a16d6..2fa9c9c4 100644 --- a/wscript +++ b/wscript @@ -116,10 +116,6 @@ def options(opt): help='Enable Portaudio driver', conf_dest='BUILD_DRIVER_PORTAUDIO') portaudio.check(header_name='windows.h') # only build portaudio on windows - portaudio.check_cfg( - package='portaudio-2.0 >= 19', - uselib_store='PORTAUDIO', - args='--cflags --libs') winmme = opt.add_auto_option( 'winmme', help='Enable WinMME driver', @@ -209,12 +205,19 @@ def configure(conf): detect_platform(conf) if conf.env['IS_WINDOWS']: - conf.env.append_unique('CCDEFINES', '_POSIX') - conf.env.append_unique('CXXDEFINES', '_POSIX') - - conf.env.append_unique('CXXFLAGS', '-Wall') - conf.env.append_unique('CXXFLAGS', '-std=gnu++11') - conf.env.append_unique('CFLAGS', '-Wall') + if conf.env['CC_NAME'] == 'msvc': + conf.env.append_unique('CXXFLAGS', '/MT') # static linking + conf.env.append_unique('CXXFLAGS', '/std:c++14') + conf.env.append_unique('CXXFLAGS', '/EHsc') + conf.env.append_unique('CXXFLAGS', '/D_WINSOCKAPI_=1') # https://stackoverflow.com/a/1517198 + conf.env.append_unique('LIBPATH', os.getcwd() + '\\windows\\lib') + else: + conf.env.append_unique('CCDEFINES', '_POSIX') + conf.env.append_unique('CXXDEFINES', '_POSIX') + else: + conf.env.append_unique('CXXFLAGS', '-Wall') + conf.env.append_unique('CXXFLAGS', '-std=gnu++11') + conf.env.append_unique('CFLAGS', '-Wall') if conf.env['IS_MACOSX']: conf.check(lib='aften', uselib='AFTEN', define_name='AFTEN') @@ -276,14 +279,17 @@ def configure(conf): conf.recurse('example-clients') # test for the availability of ucontext, and how it should be used - for t in ['gp_regs', 'uc_regs', 'mc_gregs', 'gregs']: - fragment = '#include \n' - fragment += 'int main() { ucontext_t *ucontext; return (int) ucontext->uc_mcontext.%s[0]; }' % t - confvar = 'HAVE_UCONTEXT_%s' % t.upper() - conf.check_cc(fragment=fragment, define_name=confvar, mandatory=False, - msg='Checking for ucontext->uc_mcontext.%s' % t) - if conf.is_defined(confvar): - conf.define('HAVE_UCONTEXT', 1) + if conf.env['IS_WINDOWS']: + conf.define('HAVE_UCONTEXT', 0) + else: + for t in ['gp_regs', 'uc_regs', 'mc_gregs', 'gregs']: + fragment = '#include \n' + fragment += 'int main() { ucontext_t *ucontext; return (int) ucontext->uc_mcontext.%s[0]; }' % t + confvar = 'HAVE_UCONTEXT_%s' % t.upper() + conf.check_cc(fragment=fragment, define_name=confvar, mandatory=False, + msg='Checking for ucontext->uc_mcontext.%s' % t) + if conf.is_defined(confvar): + conf.define('HAVE_UCONTEXT', 1) fragment = '#include \n' fragment += 'int main() { return NGREG; }' @@ -508,6 +514,10 @@ def build_jackd(bld): jackd.use += ['DL', 'PTHREAD'] jackd.framework = ['CoreFoundation'] + if bld.env['IS_WINDOWS']: + jackd.source += ['windows/getopt.c'] + jackd.env.append_unique('LDFLAGS', ['/ENTRY:mainCRTStartup', '/SubSystem:console']) + if bld.env['IS_SUN']: jackd.use += ['DL', 'PTHREAD'] @@ -515,9 +525,14 @@ def build_jackd(bld): return jackd +def removekey(d, key): + r = dict(d) + del r[key] + return r + # FIXME: Is SERVER_SIDE needed? def create_driver_obj(bld, **kw): - if bld.env['IS_MACOSX'] or bld.env['IS_WINDOWS']: + if bld.env['IS_MACOSX']: # On MacOSX this is necessary. # I do not know if this is necessary on Windows. # Note added on 2015-12-13 by karllinden. @@ -526,6 +541,11 @@ def create_driver_obj(bld, **kw): else: kw['use'] = ['serverlib'] + win_dll = [] + if 'win_dll' in kw: + win_dll = kw['win_dll'] + kw = removekey(kw, 'win_dll') + driver = bld( features = ['c', 'cxx', 'cshlib', 'cxxshlib'], defines = ['HAVE_CONFIG_H', 'SERVER_SIDE'], @@ -534,7 +554,12 @@ def create_driver_obj(bld, **kw): **kw) if bld.env['IS_WINDOWS']: - driver.env['cxxshlib_PATTERN'] = 'jack_%s.dll' + for dll in win_dll: + driver.env.append_unique('LDFLAGS', ['/DLL', dll]) + if bld.env['IS_WIN64']: + driver.env['cxxshlib_PATTERN'] = 'jack_%s64.dll' + else: + driver.env['cxxshlib_PATTERN'] = 'jack_%s.dll' else: driver.env['cxxshlib_PATTERN'] = 'jack_%s.so' @@ -645,28 +670,33 @@ def build_drivers(bld): create_driver_obj( bld, target = 'dummy', - source = dummy_src) + source = dummy_src, + win_dll = ['common\\jackserver.lib']) create_driver_obj( bld, target = 'loopback', - source = loopback_src) + source = loopback_src, + win_dll = ['common\\jackserver.lib']) create_driver_obj( bld, target = 'net', - source = net_src) + source = net_src, + win_dll = ['common\\jackserver.lib']) create_driver_obj( bld, target = 'netone', source = netone_src, - use = ['SAMPLERATE', 'CELT']) + use = ['SAMPLERATE', 'CELT'], + win_dll = ['common\\jackserver.lib', 'Ws2_32.lib']) create_driver_obj( bld, target = 'proxy', - source = proxy_src) + source = proxy_src, + win_dll = ['common\\jackserver.lib']) # Create hardware driver objects. Lexically sorted after the conditional, # e.g. BUILD_DRIVER_ALSA. @@ -701,14 +731,16 @@ def build_drivers(bld): bld, target = 'portaudio', source = portaudio_src, - use = ['PORTAUDIO']) + use = ['PORTAUDIO'], + win_dll = ['common\\jackserver.lib', os.getenv('PORTAUDIO_LIBRARY') or 'libportaudio64.lib']) if bld.env['BUILD_DRIVER_WINMME']: create_driver_obj( bld, target = 'winmme', source = winmme_src, - use = ['WINMME']) + use = ['WINMME'], + win_dll = ['common\\jackserver.lib', 'Winmm.lib']) if bld.env['IS_MACOSX']: create_driver_obj( @@ -773,7 +805,8 @@ def build(bld): build_drivers(bld) - bld.recurse('example-clients') + if not bld.env['IS_WINDOWS']: + bld.recurse('example-clients') if bld.env['IS_LINUX']: bld.recurse('man') bld.recurse('systemd')