summaryrefslogtreecommitdiff
path: root/Ivy
diff options
context:
space:
mode:
authorfcolin2007-02-01 13:29:31 +0000
committerfcolin2007-02-01 13:29:31 +0000
commitafe2e7dfc1388cad991e8d38dda7d648c137aa52 (patch)
tree92bf63d2b2b34a805927aa294c7c51912638f66a /Ivy
parent0be65f8a110ee9bf5da9c93e0bd5b5b62b3bad0c (diff)
parent04c263c314499e38d64af9d4a1aa5e2b8d9d5ead (diff)
downloadivy-cplusplus-afe2e7dfc1388cad991e8d38dda7d648c137aa52.zip
ivy-cplusplus-afe2e7dfc1388cad991e8d38dda7d648c137aa52.tar.gz
ivy-cplusplus-afe2e7dfc1388cad991e8d38dda7d648c137aa52.tar.bz2
ivy-cplusplus-afe2e7dfc1388cad991e8d38dda7d648c137aa52.tar.xz
modif struct svnwindows@3001
Diffstat (limited to 'Ivy')
-rw-r--r--Ivy/BufferedSocket.cxx168
-rw-r--r--Ivy/BufferedSocket.h36
-rw-r--r--Ivy/DataTypes.h328
-rw-r--r--Ivy/InstIvy/InstIvy.sln42
-rw-r--r--Ivy/InstIvy/InstIvy.vdproj282
-rw-r--r--Ivy/InstIvy/InstIvy.vdproj.vspscc10
-rw-r--r--Ivy/InstIvy/InstIvy.vssscc10
-rw-r--r--Ivy/InstIvyDev/InstIvyDev.sln21
-rw-r--r--Ivy/InstIvyDev/InstIvyDev.vdproj1042
-rw-r--r--Ivy/InstIvyDev/InstIvyDev.vdproj.vspscc10
-rw-r--r--Ivy/InstallSource/InstallSource.vdproj728
-rw-r--r--Ivy/InstallSource/InstallSource.vdproj.vspscc10
-rw-r--r--Ivy/Ivy.cxx437
-rw-r--r--Ivy/Ivy.dsp196
-rw-r--r--Ivy/Ivy.h119
-rw-r--r--Ivy/Ivy.vcproj590
-rw-r--r--Ivy/Ivy.vcproj.vspscc10
-rw-r--r--Ivy/IvyApplication.cxx375
-rw-r--r--Ivy/IvyApplication.h69
-rw-r--r--Ivy/IvyBinding.cxx189
-rw-r--r--Ivy/IvyBinding.h58
-rw-r--r--Ivy/IvyCallback.h180
-rw-r--r--Ivy/IvyCbindings.cxx129
-rw-r--r--Ivy/IvyCbindings.h108
-rw-r--r--Ivy/IvyDllMain.cpp42
-rw-r--r--Ivy/IvyLib/IvyLib.vdproj264
-rw-r--r--Ivy/IvyLib/IvyLib.vdproj.vspscc10
-rw-r--r--Ivy/IvyStdAfx.cpp27
-rw-r--r--Ivy/IvyStdAfx.h91
-rw-r--r--Ivy/IvySynchroWnd.cxx243
-rw-r--r--Ivy/IvySynchroWnd.h109
-rw-r--r--Ivy/IvyWatcher.cxx124
-rw-r--r--Ivy/IvyWatcher.h34
-rw-r--r--Ivy/Regexp.cxx1758
-rw-r--r--Ivy/Regexp.h41
-rw-r--r--Ivy/ThreadedSocket.cxx547
-rw-r--r--Ivy/ThreadedSocket.h135
-rw-r--r--Ivy/intervalRegexp.c432
-rw-r--r--Ivy/intervalRegexp.h14
39 files changed, 9018 insertions, 0 deletions
diff --git a/Ivy/BufferedSocket.cxx b/Ivy/BufferedSocket.cxx
new file mode 100644
index 0000000..1a11c56
--- /dev/null
+++ b/Ivy/BufferedSocket.cxx
@@ -0,0 +1,168 @@
+// BufferedSocket.cpp: implementation of the CBufferedSocket class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "IvyStdAfx.h"
+#include "BufferedSocket.h"
+
+#define BUFFER_SIZE 4096
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CBufferedSocket::CBufferedSocket()
+{
+ separator = '\n';
+ buffer_size = BUFFER_SIZE;
+ buffer = (char*)malloc( buffer_size );
+ current_ptr = buffer;
+ connected = false;
+ InitializeCriticalSection( &m_CritSection );
+}
+
+CBufferedSocket::~CBufferedSocket()
+{
+ free( buffer );
+}
+void CBufferedSocket::Accept(CBufferedSocket& rConnectedSocket, SOCKADDR* lpSockAddr , int* lpSockAddrLen )
+{
+ CThreadedSocket::Accept(rConnectedSocket, lpSockAddr , lpSockAddrLen );
+ rConnectedSocket.connected = true;
+}
+void CBufferedSocket::OnReceive(int nErrorCode)
+{
+ char *ptr_sep;
+ char *ptr;
+ size_t nb_to_read = 0;
+ size_t nb;
+ char *tmp_buf;
+
+ SOCKADDR addr;
+ size_t len = sizeof( addr );
+
+ /* limitation taille buffer */
+ nb_to_read = buffer_size - (current_ptr - buffer );
+ if( nb_to_read == 0 )
+ {
+ buffer_size *= 2; /* twice old size */
+ tmp_buf = (char*)realloc( buffer, buffer_size );
+ if (!tmp_buf )
+ {
+ TRACE("HandleSocket Buffer Memory Alloc Error\n");
+ exit(0);
+ }
+ buffer = tmp_buf;
+ TRACE( "Buffer Limit reached realloc new size %ld\n", buffer_size );
+ nb_to_read = buffer_size - (current_ptr - buffer );
+ }
+ nb = ReceiveFrom( current_ptr, nb_to_read, &addr, &len, 0/*MSG_PARTIAL*/ );
+ ASSERT ( memchr( current_ptr, 0, nb) == NULL );
+ if ( nb == SOCKET_ERROR )
+ {
+ int err = this->GetLastError();
+ if ( err != WSAESHUTDOWN ) // shutdown by remote side ?
+ TRACE("error Receive %d socket %d\n",this->GetLastError(),m_hSocket);
+ Close();
+ return;
+ }
+ if ( nb == 0 ) // shutdown by remote side ?
+ {
+ Close();
+ return;
+ }
+
+ current_ptr += nb;
+ ptr = buffer;
+ while ((ptr_sep = (char*)memchr (ptr, separator, current_ptr - ptr )))
+ {
+ *ptr_sep = '\0';
+ //TRACE("message %s\n", ptr );
+ OnReceive( ptr );
+ ptr = ++ptr_sep;
+ //ASSERT( ptr < (buffer + buffer_size) );
+ }
+ if (ptr < current_ptr )
+ { /* recopie ligne incomplete au debut du buffer */
+ len = current_ptr - ptr;
+ memcpy (buffer, ptr, len );
+ current_ptr = buffer + len;
+ }
+ else
+ {
+ current_ptr = buffer;
+ }
+
+
+}
+
+void CBufferedSocket::OnReceive( char *line )
+{
+}
+void CBufferedSocket::SetSeparator( char sep )
+{
+ separator = sep;
+}
+void CBufferedSocket::OnSend( int nErrorCode )
+{
+ ivy::string msg;
+ bool empty;
+
+ // on essaye de garder la section critique a l'interieur de la boucle
+ // pour permettre l'entrelacement avec la partie emetrice
+ do
+ {
+ EnterCriticalSection( &m_CritSection );
+ empty = buf_out.empty();
+ if ( !empty ) msg = buf_out.front();
+ LeaveCriticalSection( &m_CritSection );
+ if ( !empty )
+ {
+// TRACE("CBufferedSocket::OnSend Sending buffer %s\n",msg.c_str());
+
+ size_t lg = msg.length();
+ size_t sent = CThreadedSocket::Send( msg.c_str(), lg );
+ if ( sent == lg )
+ { // emission correcte on enleve le msg de la file
+ EnterCriticalSection( &m_CritSection );
+ buf_out.pop_front();
+ LeaveCriticalSection( &m_CritSection );
+ }
+ else
+ { // erreur
+ int err = this->GetLastError();
+ switch ( err ){
+ case WSAEWOULDBLOCK: // si la file est pleine on sort en silence !
+ break;
+ case WSAECONNABORTED: // broken pipe on sort en silence
+ break;
+ default:
+ TRACE("CBufferedSocket::OnWakeup error %d Sending buffer %s \n",err,msg.c_str());
+ break;
+ }
+ break;
+ }
+ }
+ } while ( !empty );
+}
+
+void CBufferedSocket::OnConnect( int nErrorCode )
+{
+ connected = true;
+ StartWriter();
+// TRACE("CBufferedSocket::OnConnect buffer size %d\n",buf_out.size());
+}
+void CBufferedSocket::Send ( const char * data )
+{
+ //BOOL toBeSignaled;
+ EnterCriticalSection( &m_CritSection );
+ //toBeSignaled = buf_out.IsEmpty() && connected;
+ buf_out.push_back( ivy::string(data) );
+ LeaveCriticalSection( &m_CritSection );
+ //TRACE("CBufferedSocket::Send Adding buffer to send count %d\n",buf_out.size());
+// if ( connected )
+// {
+ bool ok = SignalWriter();
+ if ( !ok ) TRACE( "CBufferedSocket::SignalWriter Error %d\n", this->GetLastError());
+// }
+}
diff --git a/Ivy/BufferedSocket.h b/Ivy/BufferedSocket.h
new file mode 100644
index 0000000..851ead1
--- /dev/null
+++ b/Ivy/BufferedSocket.h
@@ -0,0 +1,36 @@
+// BufferedSocket.h: interface for the CBufferedSocket class.
+//
+//////////////////////////////////////////////////////////////////////
+
+
+#pragma once
+
+
+#include "ThreadedSocket.h"
+
+class CBufferedSocket : public CThreadedSocket
+{
+// DECLARE_DYNAMIC(CBufferedSocket)
+public:
+ CBufferedSocket();
+ virtual ~CBufferedSocket();
+ void OnReceive( int nErrorCode );
+ void OnSend( int nErrorCode );
+ void OnConnect(int nErrorCode);
+ virtual void OnReceive( char *line );
+ virtual void Accept(CBufferedSocket& rConnectedSocket,
+ SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL);
+ void SetSeparator( char sep );
+ void Send ( const char * data );
+protected:
+ bool connected; /* wait to be connected before sending any Data */
+ int separator;
+ /* buffer de reception de l'application */
+ long buffer_size;
+ char *buffer;
+ char *current_ptr;
+ // Buffer Emission
+ CRITICAL_SECTION m_CritSection;
+ ivy::list<ivy::string> buf_out;
+};
+
diff --git a/Ivy/DataTypes.h b/Ivy/DataTypes.h
new file mode 100644
index 0000000..8afc4ce
--- /dev/null
+++ b/Ivy/DataTypes.h
@@ -0,0 +1,328 @@
+#pragma once
+
+
+#include <string.h>
+
+namespace ivy
+{
+#ifdef WIN32
+#ifdef IVY_EXPORTS
+class _declspec(dllexport) string;
+template <class T> class _declspec(dllexport) list;
+template <class T> class _declspec(dllexport) vector;
+#else
+#pragma comment(lib,"Ivy.LIB" )
+class _declspec(dllimport) string;
+template <class T> class _declspec(dllimport) list;
+template <class T> class _declspec(dllimport) vector;
+#endif
+#endif
+
+class string {
+public:
+ static const size_t npos = size_t(-1);
+ string(size_t len = 0)
+ { ptr = allocBuffer( len ); };
+ string ( const string& s )
+ { ptr = 0; copy( s.ptr, s.size ); }
+ string( const char * s, size_t len = npos )
+ {
+ ptr = 0;
+ if ( len == npos )
+ len = strlen(s) ;
+ copy( s, len );
+ }
+
+ ~string()
+ { delete [] ptr; }
+ size_t length()
+ { return size; }
+ bool empty() const
+ { return size==0; }
+ void copy( const char * s, size_t len )
+ {
+ if ( ptr ) delete [] ptr;
+ ptr = allocBuffer( len );
+ strncpy_s( ptr, len + 1, s, len );
+ }
+ void erase(size_t start=0, size_t len = npos)
+ {
+ char *newptr;
+ size_t real_len;
+ size_t buf_size;
+ real_len = len == npos ? size - start : len;
+ if ( real_len > size ) real_len = size;
+ buf_size = size - real_len;
+ newptr = allocBuffer( buf_size );
+ strncpy_s( newptr, buf_size +1, ptr , start );
+ strncpy_s( &newptr[start], buf_size +1 - start, &ptr[start+real_len], size - start );
+ delete ptr;
+ ptr = newptr;
+ }
+ void append( const char *s , size_t len = npos )
+ {
+ insert ( size, s , len );
+ }
+ void insert(size_t index, const char * s, size_t len = npos)
+ {
+ char *newptr;
+ if ( len == npos ) len = strlen(s) ;
+ size_t buf_len = size + len;
+ newptr = allocBuffer( buf_len );
+ strncpy_s( newptr , buf_len +1, ptr, index );
+ strncpy_s( newptr+index, buf_len + 1 - index, s, len ) ;
+ strncpy_s( newptr+index+len, buf_len + 1 - index -len, &ptr[index], size - (index+len) ) ;
+ delete ptr;
+ ptr = newptr;
+ }
+ string substr( size_t start, size_t len = npos )
+ { return string ( &ptr[start], len ); }
+ size_t find_first_of( const char* strCharSet )
+ { char *fnd = strpbrk( ptr, strCharSet ); if ( fnd ) return (size_t)(fnd - ptr); else return npos; }
+ size_t rfind( char c )
+ { char *fnd = strrchr( ptr, c); if ( fnd ) return (size_t)(fnd - ptr); else return npos; }
+// friend string operator + (const string& left, const char* right);
+// friend string operator + (const char* left, const string& right);
+ friend string operator + (const string& left, const string& right)
+ {
+ string str( left.size + right.size );
+ str.append( left.ptr, left.size);
+ str.append( right.ptr, right.size);
+ return str;
+ }
+
+ void operator +=(string s)
+ {
+ append( s.ptr, s.size );
+ }
+
+ void operator +=(const char* s)
+ {
+ append( s, strlen(s) );
+ }
+
+ void operator +=(char c)
+ { append( &c, 1);}
+
+
+ string operator +(string s) const
+ { string str ( ptr, size ); str.append( s.ptr, s.size ); return str; }
+ string operator +(const char c) const
+ { string str ( ptr, size ); str.append( &c, 1); return str; }
+ string& operator=(const string& s)
+ { copy(s.ptr,s.size); return *this; }
+ string& operator=(const char* s)
+ { copy(s,strlen(s)); return *this; }
+ // Nondestructive typecast operator
+ operator const char*() const
+ { return ptr; }
+ const char *c_str() const // remove this ugly thing
+ { return ptr; }
+private:
+ char *ptr;
+ size_t size;
+ // always allocate one extra character for '\0' termination
+ char *allocBuffer(size_t len)
+ {
+ char *newptr;
+ size = len;
+ newptr = new char[len+1] ;
+ newptr[len] = '\0';
+ return newptr;
+ }
+
+};
+
+
+
+
+template <class T> class list {
+
+protected:
+ struct _Node;
+ friend struct _Node;
+ typedef struct _Node Node;
+ typedef Node* NodePtr;
+ struct _Node {
+ NodePtr next, prev;
+ T value;
+ };
+
+public:
+
+ //friend class iterator;
+ class iterator {
+ public:
+ iterator()
+ {ptr = 0;}
+ iterator(NodePtr p)
+ {ptr = p;}
+ T& operator*() const
+ {return ptr->value; }
+// T* operator->() const
+// {return &(ptr->value); }
+// T* operator->() const
+// {return (&**this); }
+ iterator& operator++()
+ {ptr = ptr->next;
+ return (*this); }
+ iterator operator++(int)
+ {iterator tmp = *this;
+ ++*this;
+ return (tmp); }
+ iterator& operator--()
+ {ptr = ptr.prev;
+ return (*this); }
+ iterator operator--(int)
+ {iterator tmp = *this;
+ --*this;
+ return (tmp); }
+ bool operator==(const iterator& p) const
+ {return (ptr == p.ptr); }
+ bool operator!=(const iterator& p) const
+ {return (ptr != p.ptr); }
+ NodePtr next() const
+ {return ptr->next; };
+ NodePtr prev() const
+ {return ptr->prev ; };
+ NodePtr node() const
+ {return (ptr); }
+ protected:
+ NodePtr ptr;
+ };
+
+ list()
+ {
+ head = new Node;
+ head->next = head->prev = head;
+ }
+ ~list()
+ {
+ clear();
+ delete head;
+ }
+ bool empty()
+ { return head->next == head ; }
+ T& front()
+ {return (*begin()); }
+ const T& front() const
+ {return (*begin()); }
+ T& back()
+ {return (*(--end())); }
+ const T& back() const
+ {return (*(--end())); }
+ iterator erase(iterator p)
+ {
+ NodePtr s = (p++).node();
+ s->prev->next = s->next;
+ s->next->prev = s->prev;
+ delete s;
+ return (p);
+ }
+
+ iterator insert(iterator p, const T& v =T())
+ {
+ NodePtr s = p.node();
+ NodePtr newnode = new Node;
+ newnode->value = v;
+ newnode->prev = s->prev;
+ newnode->next = s;
+ s->prev->next = newnode;
+ s->prev = newnode;
+ return (iterator(newnode));
+ }
+ void push_front(const T& v)
+ {insert(begin(), v); }
+ void pop_front()
+ {erase(begin()); }
+ void push_back(const T& v)
+ {insert(end(), v); }
+ void pop_back()
+ {erase(--end()); }
+ iterator erase(iterator first, iterator last)
+ {
+ while (first != last)
+ erase(first++);
+ return (first);
+ }
+ void clear()
+ {erase(begin(), end()); }
+
+ void remove( const T& data )
+ {
+ iterator last = end();
+ for (iterator iter = begin(); iter != last; )
+ if (*iter == data)
+ erase(iter++);
+ else
+ ++iter;
+ }
+ iterator begin()
+ {return (iterator(head->next)); }
+ iterator end()
+ {return (iterator(head));}
+ protected:
+ NodePtr head;
+
+};
+
+template <class T> class vector {
+public:
+
+ vector ( )
+ { data = 0; len = 0; }
+ size_t size()
+ { return len; }
+ void reserve( size_t index )
+ {
+ if ( index >= len )
+ resize( index );
+ }
+ void resize( size_t index )
+ {
+ size_t i;
+ T* newdata = new T[index];
+ for ( i = 0; i < len ; i ++ )
+ newdata[i] = data[i];
+ for ( i = len; i < index ; i ++ )
+ newdata[i] = 0;
+ if ( data ) delete [] data;
+ data = newdata;
+ len = index;
+ }
+ // Accesses indexed component of vector
+ T & operator [](size_t index )
+ {
+ // reserve( index ); // TODO or NOT check range
+ return data[index] ;
+ }
+ T & operator [](size_t index ) const
+ {
+ return data[index] ;
+ }
+ void push_back( const T& value )
+ {
+ T* newdata = new T[len+1];
+ for ( size_t i = 0; i < len ; i ++ )
+ newdata[i] = data[i];
+ newdata[len++] = value;
+ if ( data ) delete [] data;
+ data = newdata;
+ }
+ void erase( int i )
+ {
+ data[i] = 0;
+ }
+ void clear()
+ {
+ delete [] data;
+ data = 0;
+ len = 0;
+ }
+
+private:
+ T* data;
+ size_t len;
+};
+
+} \ No newline at end of file
diff --git a/Ivy/InstIvy/InstIvy.sln b/Ivy/InstIvy/InstIvy.sln
new file mode 100644
index 0000000..def9de2
--- /dev/null
+++ b/Ivy/InstIvy/InstIvy.sln
@@ -0,0 +1,42 @@
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "InstIvy", "InstIvy.vdproj", "{8826FCA8-62E5-449E-A1F5-A3203F13EF78}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ivy", "..\..\C++\Bus\Ivy\Ivy.vcproj", "{9F40EF6B-8C74-4087-9E25-32A5E7EC2128}"
+EndProject
+Global
+ GlobalSection(SourceCodeControl) = preSolution
+ SccNumberOfProjects = 3
+ SccProjectName0 = \u0022$/Bus/Install/InstIvy\u0022,\u0020CREAAAAA
+ SccLocalPath0 = .
+ SccProvider0 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe
+ CanCheckoutShared = false
+ SolutionUniqueID = {F1027A98-11B4-463A-808C-63E2AD09C2EA}
+ SccProjectUniqueName1 = InstIvy.vdproj
+ SccLocalPath1 = .
+ CanCheckoutShared = false
+ SccProjectUniqueName2 = ..\\..\\C++\\Bus\\Ivy\\Ivy.vcproj
+ SccProjectName2 = \u0022$/Bus/Ivy\u0022,\u0020QPEAAAAA
+ SccLocalPath2 = ..\\..\\C++\\Bus\\Ivy
+ CanCheckoutShared = false
+ EndGlobalSection
+ GlobalSection(SolutionConfiguration) = preSolution
+ ConfigName.0 = Debug
+ ConfigName.1 = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {8826FCA8-62E5-449E-A1F5-A3203F13EF78}.Debug.ActiveCfg = Debug
+ {8826FCA8-62E5-449E-A1F5-A3203F13EF78}.Debug.Build.0 = Debug
+ {8826FCA8-62E5-449E-A1F5-A3203F13EF78}.Release.ActiveCfg = Release
+ {8826FCA8-62E5-449E-A1F5-A3203F13EF78}.Release.Build.0 = Release
+ {9F40EF6B-8C74-4087-9E25-32A5E7EC2128}.Debug.ActiveCfg = Debug|Win32
+ {9F40EF6B-8C74-4087-9E25-32A5E7EC2128}.Debug.Build.0 = Debug|Win32
+ {9F40EF6B-8C74-4087-9E25-32A5E7EC2128}.Release.ActiveCfg = Release|Win32
+ {9F40EF6B-8C74-4087-9E25-32A5E7EC2128}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/Ivy/InstIvy/InstIvy.vdproj b/Ivy/InstIvy/InstIvy.vdproj
new file mode 100644
index 0000000..4346312
--- /dev/null
+++ b/Ivy/InstIvy/InstIvy.vdproj
@@ -0,0 +1,282 @@
+"DeployProject"
+{
+"VSVersion" = "3:700"
+"ProjectType" = "8:{5443560e-dbb4-11d2-8724-00a0c9a8b90c}"
+"IsWebType" = "8:FALSE"
+"ProjectName" = "8:InstIvy"
+"LanguageId" = "3:1036"
+"CodePage" = "3:1252"
+"UILanguageId" = "3:1036"
+"SccProjectName" = "8:\"$/Bus/Install/InstIvy\", CREAAAAA"
+"SccLocalPath" = "8:."
+"SccAuxPath" = "8:"
+"SccProvider" = "8:MSSCCI:Microsoft Visual SourceSafe"
+ "Hierarchy"
+ {
+ "Entry"
+ {
+ "MsmKey" = "8:_1C8127E2CE08470A9FB2772F59EF6C16"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:C:\\USERS\\FCOLIN\\PROGRAM FILES\\DEBUG\\IVY.DLL"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_474D2E042D971A73B3B54FD999910DF8"
+ "OwnerKey" = "8:_1C8127E2CE08470A9FB2772F59EF6C16"
+ "MsmSig" = "8:C:\\WINDOWS\\SYSTEM32\\MSVCR70D.DLL"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_6853BE42500AB02614E13C492A847CC2"
+ "OwnerKey" = "8:_1C8127E2CE08470A9FB2772F59EF6C16"
+ "MsmSig" = "8:C:\\WINDOWS\\SYSTEM32\\MSVCP70D.DLL"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_84E197CA5A09A6E635F4F2D20CB9C269"
+ "OwnerKey" = "8:_1C8127E2CE08470A9FB2772F59EF6C16"
+ "MsmSig" = "8:C:\\WINDOWS\\SYSTEM32\\WSOCK32.DLL"
+ }
+ }
+ "Configurations"
+ {
+ "Debug"
+ {
+ "DisplayName" = "8:Debug"
+ "IsDebugOnly" = "11:TRUE"
+ "IsReleaseOnly" = "11:FALSE"
+ "OutputFilename" = "8:Debug\\InstIvy.msm"
+ "PackageFilesAs" = "3:2"
+ "PackageFileSize" = "3:-2147483648"
+ "CabType" = "3:1"
+ "Compression" = "3:2"
+ "SignOutput" = "11:FALSE"
+ "CertificateFile" = "8:"
+ "PrivateKeyFile" = "8:"
+ "TimeStampServer" = "8:"
+ "InstallerBootstrapper" = "3:1"
+ }
+ "Release"
+ {
+ "DisplayName" = "8:Release"
+ "IsDebugOnly" = "11:FALSE"
+ "IsReleaseOnly" = "11:TRUE"
+ "OutputFilename" = "8:Release\\InstIvy.msm"
+ "PackageFilesAs" = "3:2"
+ "PackageFileSize" = "3:-2147483648"
+ "CabType" = "3:1"
+ "Compression" = "3:2"
+ "SignOutput" = "11:FALSE"
+ "CertificateFile" = "8:"
+ "PrivateKeyFile" = "8:"
+ "TimeStampServer" = "8:"
+ "InstallerBootstrapper" = "3:1"
+ }
+ }
+ "Deployable"
+ {
+ "CustomAction"
+ {
+ }
+ "DefaultFeature"
+ {
+ "Name" = "8:DefaultFeature"
+ "Title" = "8:"
+ "Description" = "8:"
+ }
+ "File"
+ {
+ "{54DA9790-1474-11D3-8E00-00C04F6837D0}:_474D2E042D971A73B3B54FD999910DF8"
+ {
+ "Signature" = "8:20000000a04c53fed195c101662efae5e36ac201a04c53fed195c101000000000030080000000000000000006d0073007600630072003700300064002e0064006c006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+ "SourcePath" = "8:MSVCR70D.dll"
+ "TargetName" = "8:MSVCR70D.dll"
+ "Tag" = "8:"
+ "Folder" = "8:_15DCD27905D341429030EE4BA476A488"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:TRUE"
+ "IsolateTo" = "8:"
+ }
+ "{54DA9790-1474-11D3-8E00-00C04F6837D0}:_6853BE42500AB02614E13C492A847CC2"
+ {
+ "Signature" = "8:2000000090c39d10d295c101662efae5e36ac20190c39d10d295c1010000000000400b0000000000000000006d0073007600630070003700300064002e0064006c006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+ "SourcePath" = "8:MSVCP70D.dll"
+ "TargetName" = "8:MSVCP70D.dll"
+ "Tag" = "8:"
+ "Folder" = "8:_15DCD27905D341429030EE4BA476A488"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:TRUE"
+ "IsolateTo" = "8:"
+ }
+ "{54DA9790-1474-11D3-8E00-00C04F6837D0}:_84E197CA5A09A6E635F4F2D20CB9C269"
+ {
+ "Signature" = "8:2000000000e08cf6b82fc101bec8e082ea6ac20100e08cf6b82fc10100000000005e00000000000000000000770073006f0063006b00330032002e0064006c006c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+ "SourcePath" = "8:WSOCK32.dll"
+ "TargetName" = "8:WSOCK32.dll"
+ "Tag" = "8:"
+ "Folder" = "8:_15DCD27905D341429030EE4BA476A488"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:TRUE"
+ "IsolateTo" = "8:"
+ }
+ }
+ "FileType"
+ {
+ }
+ "Folder"
+ {
+ "{777C097F-0ED8-11D3-8D6C-00A0C9CFCEE6}:_15DCD27905D341429030EE4BA476A488"
+ {
+ "Name" = "8:#1910"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:CommonFilesFolder"
+ "Folders"
+ {
+ }
+ }
+ "{2FBCB9FF-B6A1-4FA9-9C7C-D1366E178586}:_7BEBD1D67A934D228BFBAE7C11467C9A"
+ {
+ "DefaultLocation" = "8:[TARGETDIR]"
+ "DisplayName" = "8:Dossier Remplacement pour les modules"
+ "Description" = "8:"
+ "Name" = "8:Dossier Remplacement pour les modules"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:NEWRETARGETABLEPROPERTY1"
+ "Folders"
+ {
+ }
+ }
+ "{777C097F-0ED8-11D3-8D6C-00A0C9CFCEE6}:_AEEFF3D8A3364088A698304D464E078E"
+ {
+ "Name" = "8:#1914"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:SystemFolder"
+ "Folders"
+ {
+ }
+ }
+ }
+ "Shortcut"
+ {
+ }
+ "Sequences"
+ {
+ }
+ "Registry"
+ {
+ "HKLM"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKCU"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKCR"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKU"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKPU"
+ {
+ "Keys"
+ {
+ }
+ }
+ }
+ "ProjectOutput"
+ {
+ "{B1E2BB22-187D-11D3-8E02-00C04F6837D0}:_1C8127E2CE08470A9FB2772F59EF6C16"
+ {
+ "SourcePath" = "8:..\\..\\Program Files\\Debug\\Ivy.dll"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_15DCD27905D341429030EE4BA476A488"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:Built"
+ "OutputProjectCanonicalName" = "8:..\\..\\C++\\Bus\\Ivy\\Ivy.vcproj"
+ "OutputProjectGuid" = "8:{9F40EF6B-8C74-4087-9E25-32A5E7EC2128}"
+ "ShowKeyOutput" = "11:FALSE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ }
+ "Module"
+ {
+ "ModuleSignature" = "8:MergeModule.50212549D8E242BBB1C9246BFDAFADB2"
+ "Version" = "8:1.0.0.0"
+ "Title" = "8:Ivy"
+ "Subject" = "8:"
+ "Author" = "8:CENA"
+ "Keywords" = "8:"
+ "Comments" = "8:"
+ "SearchPath" = "8:"
+ "UseSystemSearchPath" = "11:TRUE"
+ }
+ "MergeModule"
+ {
+ }
+ }
+}
diff --git a/Ivy/InstIvy/InstIvy.vdproj.vspscc b/Ivy/InstIvy/InstIvy.vdproj.vspscc
new file mode 100644
index 0000000..492cf62
--- /dev/null
+++ b/Ivy/InstIvy/InstIvy.vdproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = "relative:Install\\InstIvy"
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/Ivy/InstIvy/InstIvy.vssscc b/Ivy/InstIvy/InstIvy.vssscc
new file mode 100644
index 0000000..794f014
--- /dev/null
+++ b/Ivy/InstIvy/InstIvy.vssscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/Ivy/InstIvyDev/InstIvyDev.sln b/Ivy/InstIvyDev/InstIvyDev.sln
new file mode 100644
index 0000000..79e9200
--- /dev/null
+++ b/Ivy/InstIvyDev/InstIvyDev.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "InstIvyDev", "InstIvyDev.vdproj", "{07B35ABB-D1C2-4546-8ABA-945C1E8A88FE}"
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ ConfigName.0 = Debug
+ ConfigName.1 = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {07B35ABB-D1C2-4546-8ABA-945C1E8A88FE}.Debug.ActiveCfg = Debug
+ {07B35ABB-D1C2-4546-8ABA-945C1E8A88FE}.Debug.Build.0 = Debug
+ {07B35ABB-D1C2-4546-8ABA-945C1E8A88FE}.Release.ActiveCfg = Release
+ {07B35ABB-D1C2-4546-8ABA-945C1E8A88FE}.Release.Build.0 = Release
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/Ivy/InstIvyDev/InstIvyDev.vdproj b/Ivy/InstIvyDev/InstIvyDev.vdproj
new file mode 100644
index 0000000..25df386
--- /dev/null
+++ b/Ivy/InstIvyDev/InstIvyDev.vdproj
@@ -0,0 +1,1042 @@
+"DeployProject"
+{
+"VSVersion" = "3:800"
+"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}"
+"IsWebType" = "8:FALSE"
+"ProjectName" = "8:InstallIvyDev"
+"LanguageId" = "3:1036"
+"CodePage" = "3:1252"
+"UILanguageId" = "3:1036"
+"SccProjectName" = "8:\"$/Bus/Ivy/InstIvyDev\", FUFAAAAA"
+"SccLocalPath" = "8:."
+"SccAuxPath" = "8:"
+"SccProvider" = "8:MSSCCI:Microsoft Visual SourceSafe"
+ "Hierarchy"
+ {
+ "Entry"
+ {
+ "MsmKey" = "8:_0881ABF5280948D5AA93B02FECFC3956"
+ "OwnerKey" = "8:_587183B52DD64752997FFA522BC57D0A"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_32C90C9C8FC242AE9C65DA1C92DA2700"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_587183B52DD64752997FFA522BC57D0A"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_6C5F1DCD58734C9D953B306F435ED006"
+ "OwnerKey" = "8:_7B9C5BFD7A8B4F36A616771B210FF5C8"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_6FB50FA4D8F60743C6DAA4C31583C68C"
+ "OwnerKey" = "8:_BFED66BE7DFC4FC5B625527D0526B5A5"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_7B9C5BFD7A8B4F36A616771B210FF5C8"
+ "OwnerKey" = "8:_32C90C9C8FC242AE9C65DA1C92DA2700"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_7B9C5BFD7A8B4F36A616771B210FF5C8"
+ "OwnerKey" = "8:_BFED66BE7DFC4FC5B625527D0526B5A5"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_7B9C5BFD7A8B4F36A616771B210FF5C8"
+ "OwnerKey" = "8:_587183B52DD64752997FFA522BC57D0A"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_AB55CBB0776C4E9E90F5CB636E7D660B"
+ "OwnerKey" = "8:_0881ABF5280948D5AA93B02FECFC3956"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_B656C8E7B4C5444BB7CAA2BB82B22DEB"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_BFED66BE7DFC4FC5B625527D0526B5A5"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ }
+ "Configurations"
+ {
+ "Debug"
+ {
+ "DisplayName" = "8:Debug"
+ "IsDebugOnly" = "11:TRUE"
+ "IsReleaseOnly" = "11:FALSE"
+ "OutputFilename" = "8:Debug\\InstIvyDev.msi"
+ "PackageFilesAs" = "3:2"
+ "PackageFileSize" = "3:-2147483648"
+ "CabType" = "3:1"
+ "Compression" = "3:2"
+ "SignOutput" = "11:FALSE"
+ "CertificateFile" = "8:"
+ "PrivateKeyFile" = "8:"
+ "TimeStampServer" = "8:"
+ "InstallerBootstrapper" = "3:1"
+ "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
+ {
+ "Enabled" = "11:FALSE"
+ "PromptEnabled" = "11:TRUE"
+ "PrerequisitesLocation" = "2:1"
+ "Url" = "8:"
+ "ComponentsUrl" = "8:"
+ "Items"
+ {
+ }
+ }
+ }
+ "Release"
+ {
+ "DisplayName" = "8:Release"
+ "IsDebugOnly" = "11:FALSE"
+ "IsReleaseOnly" = "11:TRUE"
+ "OutputFilename" = "8:..\\..\\..\\..\\Install\\InstIvyDev.msi"
+ "PackageFilesAs" = "3:2"
+ "PackageFileSize" = "3:-2147483648"
+ "CabType" = "3:1"
+ "Compression" = "3:2"
+ "SignOutput" = "11:FALSE"
+ "CertificateFile" = "8:"
+ "PrivateKeyFile" = "8:"
+ "TimeStampServer" = "8:"
+ "InstallerBootstrapper" = "3:1"
+ "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
+ {
+ "Enabled" = "11:FALSE"
+ "PromptEnabled" = "11:TRUE"
+ "PrerequisitesLocation" = "2:1"
+ "Url" = "8:http://www.tls.cena.fr/products/ivy/download/packages"
+ "ComponentsUrl" = "8:"
+ "Items"
+ {
+ }
+ }
+ }
+ }
+ "Deployable"
+ {
+ "CustomAction"
+ {
+ }
+ "DefaultFeature"
+ {
+ "Name" = "8:DefaultFeature"
+ "Title" = "8:"
+ "Description" = "8:"
+ }
+ "ExternalPersistence"
+ {
+ "LaunchCondition"
+ {
+ }
+ }
+ "File"
+ {
+ "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6FB50FA4D8F60743C6DAA4C31583C68C"
+ {
+ "SourcePath" = "8:WSOCK32.dll"
+ "TargetName" = "8:WSOCK32.dll"
+ "Tag" = "8:"
+ "Folder" = "8:_97BD9053CEE5430F9BC907C244C522C0"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:TRUE"
+ "IsDependency" = "11:TRUE"
+ "IsolateTo" = "8:"
+ }
+ "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B656C8E7B4C5444BB7CAA2BB82B22DEB"
+ {
+ "SourcePath" = "8:..\\..\\release\\Ivy.lib"
+ "TargetName" = "8:Ivy.lib"
+ "Tag" = "8:"
+ "Folder" = "8:_4BD06D3C92334052AE64EABA3DE642C3"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ }
+ }
+ "FileType"
+ {
+ }
+ "Folder"
+ {
+ "{3C67513D-01DD-4637-8A68-80971EB9504F}:_97BD9053CEE5430F9BC907C244C522C0"
+ {
+ "DefaultLocation" = "8:[ProgramFilesFolder][Manufacturer]\\[ProductName]"
+ "Name" = "8:#1925"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:TARGETDIR"
+ "Folders"
+ {
+ "{9EF0B969-E518-4E46-987F-47570745A589}:_4BD06D3C92334052AE64EABA3DE642C3"
+ {
+ "Name" = "8:Lib"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:_884F08395AE541928DAABB355DC3485B"
+ "Folders"
+ {
+ }
+ }
+ "{9EF0B969-E518-4E46-987F-47570745A589}:_64AFC2E36B5346C08FF007A580F68304"
+ {
+ "Name" = "8:Include"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:_631518C84C224AE680C352EB2F43713C"
+ "Folders"
+ {
+ }
+ }
+ "{9EF0B969-E518-4E46-987F-47570745A589}:_823268F0927E471C9AC8D4518AB6C2F5"
+ {
+ "Name" = "8:SrcExample"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:_D2C6F66A7FE9467184E94EAE96D06FA2"
+ "Folders"
+ {
+ }
+ }
+ "{9EF0B969-E518-4E46-987F-47570745A589}:_9CFE50635C5443E68113471C7E3235C3"
+ {
+ "Name" = "8:SrcLib"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:_A82ABE6889AF4890A9FB2AE77868B9D4"
+ "Folders"
+ {
+ }
+ }
+ "{9EF0B969-E518-4E46-987F-47570745A589}:_BE1B10BDB24D49EA8562F4B0A6596F21"
+ {
+ "Name" = "8:Bin"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:_4839FF1AF6C24020B0C868BA0C7D4D2E"
+ "Folders"
+ {
+ }
+ }
+ }
+ }
+ }
+ "LaunchCondition"
+ {
+ }
+ "Locator"
+ {
+ }
+ "MsiBootstrapper"
+ {
+ "LangId" = "3:1036"
+ }
+ "Product"
+ {
+ "Name" = "8:Microsoft Visual Studio"
+ "ProductName" = "8:InstIvyDev"
+ "ProductCode" = "8:{54EEC85D-F868-49E0-A71C-54409C92E02F}"
+ "PackageCode" = "8:{4A4A8B44-7D84-4AEB-98DA-766B603AD502}"
+ "UpgradeCode" = "8:{B61AA283-78E2-443D-A093-4D5D6C0B779A}"
+ "RestartWWWService" = "11:FALSE"
+ "RemovePreviousVersions" = "11:FALSE"
+ "DetectNewerInstalledVersion" = "11:TRUE"
+ "InstallAllUsers" = "11:FALSE"
+ "ProductVersion" = "8:1.0.0"
+ "Manufacturer" = "8:SDER PII"
+ "ARPHELPTELEPHONE" = "8:"
+ "ARPHELPLINK" = "8:http://www.tls.cena.fr/products/ivy"
+ "Title" = "8:InstIvyDev"
+ "Subject" = "8:Ivy"
+ "ARPCONTACT" = "8:SDER PII"
+ "Keywords" = "8:Ivy"
+ "ARPCOMMENTS" = "8:Ivy Sources and Lib "
+ "ARPURLINFOABOUT" = "8:"
+ "ARPPRODUCTICON" = "8:"
+ "ARPIconIndex" = "3:0"
+ "SearchPath" = "8:"
+ "UseSystemSearchPath" = "11:TRUE"
+ "TargetPlatform" = "3:0"
+ "PreBuildEvent" = "8:"
+ "PostBuildEvent" = "8:\"$(ProjectDir)..\\..\\UpdateIvyWeb.bat\" \"$(BuiltOuputPath)\""
+ "RunPostBuildEvent" = "3:0"
+ }
+ "Registry"
+ {
+ "HKLM"
+ {
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_BB28EFBCAF6D427984A8D12ADA79ED71"
+ {
+ "Name" = "8:Software"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_46BB5FEDD5E54B1DA83F1AEE69B7414D"
+ {
+ "Name" = "8:[Manufacturer]"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ }
+ "HKCU"
+ {
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_D254D89ED3C54FA68FAE6AD35F7725E3"
+ {
+ "Name" = "8:Software"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_D96808EDD7E448E3BF4976DBB5153FDA"
+ {
+ "Name" = "8:[Manufacturer]"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ }
+ "HKCR"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKU"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKPU"
+ {
+ "Keys"
+ {
+ }
+ }
+ }
+ "Sequences"
+ {
+ }
+ "Shortcut"
+ {
+ }
+ "UserInterface"
+ {
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_02EC527B9FF844D88C616726908FDF10"
+ {
+ "Name" = "8:#1902"
+ "Sequence" = "3:2"
+ "Attributes" = "3:3"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_BDEB1035C12E4BFEB8737D924C6F4156"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Finished"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_3750316B8DBF425BA6AA4348C0F1CA87"
+ {
+ "UseDynamicProperties" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim"
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_51727C53A61B4F6D901F06AED9B3C481"
+ {
+ "Name" = "8:#1901"
+ "Sequence" = "3:1"
+ "Attributes" = "3:2"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_BA05984C1F294731B5ED66914BD89A5C"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Progress"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "ShowProgress"
+ {
+ "Name" = "8:ShowProgress"
+ "DisplayName" = "8:#1009"
+ "Description" = "8:#1109"
+ "Type" = "3:5"
+ "ContextData" = "8:1;True=1;False=0"
+ "Attributes" = "3:0"
+ "Setting" = "3:0"
+ "Value" = "3:1"
+ "DefaultValue" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_6FF89DC49B8348899925787F1294FD64"
+ {
+ "Name" = "8:#1901"
+ "Sequence" = "3:2"
+ "Attributes" = "3:2"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_9F7D27549F654B418F380589DA56C3ED"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Progress"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "ShowProgress"
+ {
+ "Name" = "8:ShowProgress"
+ "DisplayName" = "8:#1009"
+ "Description" = "8:#1109"
+ "Type" = "3:5"
+ "ContextData" = "8:1;True=1;False=0"
+ "Attributes" = "3:0"
+ "Setting" = "3:0"
+ "Value" = "3:1"
+ "DefaultValue" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_8F8434AEBED14452982010E6F3848023"
+ {
+ "Name" = "8:#1900"
+ "Sequence" = "3:1"
+ "Attributes" = "3:1"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_97A4AE594BB347ECAD98AAFC6FD3B0FB"
+ {
+ "Sequence" = "3:200"
+ "DisplayName" = "8:Installation Folder"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "InstallAllUsersVisible"
+ {
+ "Name" = "8:InstallAllUsersVisible"
+ "DisplayName" = "8:#1059"
+ "Description" = "8:#1159"
+ "Type" = "3:5"
+ "ContextData" = "8:1;True=1;False=0"
+ "Attributes" = "3:0"
+ "Setting" = "3:0"
+ "Value" = "3:1"
+ "DefaultValue" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_E3B1F5B6B5FE4CE6B369C0374CA9AA75"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Welcome"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "CopyrightWarning"
+ {
+ "Name" = "8:CopyrightWarning"
+ "DisplayName" = "8:#1002"
+ "Description" = "8:#1102"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1202"
+ "DefaultValue" = "8:#1202"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "Welcome"
+ {
+ "Name" = "8:Welcome"
+ "DisplayName" = "8:#1003"
+ "Description" = "8:#1103"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1203"
+ "DefaultValue" = "8:#1203"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_EA128F65E9D44AE1B2E071C21B8C0010"
+ {
+ "Sequence" = "3:300"
+ "DisplayName" = "8:Confirm Installation"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_9AC53598B4544C15A28E2D88AD28D24E"
+ {
+ "UseDynamicProperties" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim"
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_D1645593CABE4CAF974F04BA8599A164"
+ {
+ "Name" = "8:#1900"
+ "Sequence" = "3:2"
+ "Attributes" = "3:1"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_0EE17FA1A76D4B8C86D0CA3BC7089F16"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Welcome"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "CopyrightWarning"
+ {
+ "Name" = "8:CopyrightWarning"
+ "DisplayName" = "8:#1002"
+ "Description" = "8:#1102"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1202"
+ "DefaultValue" = "8:#1202"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "Welcome"
+ {
+ "Name" = "8:Welcome"
+ "DisplayName" = "8:#1003"
+ "Description" = "8:#1103"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1203"
+ "DefaultValue" = "8:#1203"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_B8FA44662FAF40B4A23F14BBE7115F3C"
+ {
+ "Sequence" = "3:300"
+ "DisplayName" = "8:Confirm Installation"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_F1C7DEE7DB5C4556ADD1217E3B254EC3"
+ {
+ "Sequence" = "3:200"
+ "DisplayName" = "8:Installation Folder"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_FED02DC05BEC48728F86FB64CF2C5B31"
+ {
+ "Name" = "8:#1902"
+ "Sequence" = "3:1"
+ "Attributes" = "3:3"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_83F73B2D8F7E44DA9567C4497FA978AB"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Finished"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "UpdateText"
+ {
+ "Name" = "8:UpdateText"
+ "DisplayName" = "8:#1058"
+ "Description" = "8:#1158"
+ "Type" = "3:15"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1258"
+ "DefaultValue" = "8:#1258"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ }
+ "MergeModule"
+ {
+ "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_0881ABF5280948D5AA93B02FECFC3956"
+ {
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:TRUE"
+ "SourcePath" = "8:Microsoft_VC80_MFC_x86.msm"
+ "Properties"
+ {
+ }
+ "LanguageId" = "3:0"
+ "Exclude" = "11:FALSE"
+ "Folder" = "8:"
+ "Feature" = "8:"
+ "IsolateTo" = "8:"
+ }
+ "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_6C5F1DCD58734C9D953B306F435ED006"
+ {
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:TRUE"
+ "SourcePath" = "8:policy_8_0_microsoft_vc80_crt_x86.msm"
+ "Properties"
+ {
+ }
+ "LanguageId" = "3:0"
+ "Exclude" = "11:FALSE"
+ "Folder" = "8:"
+ "Feature" = "8:"
+ "IsolateTo" = "8:"
+ }
+ "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_7B9C5BFD7A8B4F36A616771B210FF5C8"
+ {
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:TRUE"
+ "SourcePath" = "8:Microsoft_VC80_CRT_x86.msm"
+ "Properties"
+ {
+ }
+ "LanguageId" = "3:0"
+ "Exclude" = "11:FALSE"
+ "Folder" = "8:"
+ "Feature" = "8:"
+ "IsolateTo" = "8:"
+ }
+ "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_AB55CBB0776C4E9E90F5CB636E7D660B"
+ {
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:TRUE"
+ "SourcePath" = "8:policy_8_0_microsoft_vc80_mfc_x86.msm"
+ "Properties"
+ {
+ }
+ "LanguageId" = "3:0"
+ "Exclude" = "11:FALSE"
+ "Folder" = "8:"
+ "Feature" = "8:"
+ "IsolateTo" = "8:"
+ }
+ }
+ "ProjectOutput"
+ {
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_0DBE25F652264D9F92A27A1581D093E3"
+ {
+ "SourcePath" = "8:"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_9CFE50635C5443E68113471C7E3235C3"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:SourceFiles"
+ "OutputProjectGuid" = "8:{9BD87B7A-517E-4900-B3EA-A358885CD876}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ "ExcludeFilter" = "8:*.vcproj"
+ "ExcludeFilter" = "8:*.res"
+ "ExcludeFilter" = "8:*.h"
+ }
+ }
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_10C831C856C745B8862A1DA57473BE41"
+ {
+ "SourcePath" = "8:"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_64AFC2E36B5346C08FF007A580F68304"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:SourceFiles"
+ "OutputProjectGuid" = "8:{9BD87B7A-517E-4900-B3EA-A358885CD876}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ "ExcludeFilter" = "8:*.vcproj"
+ "ExcludeFilter" = "8:*.cxx"
+ "ExcludeFilter" = "8:*.res"
+ "ExcludeFilter" = "8:*.cpp"
+ }
+ }
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_32C90C9C8FC242AE9C65DA1C92DA2700"
+ {
+ "SourcePath" = "8:..\\..\\release\\pcre.dll"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_BE1B10BDB24D49EA8562F4B0A6596F21"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:Built"
+ "OutputProjectGuid" = "8:{D79FC143-498E-4342-B2C7-BDAD1B8D0E6B}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_3EE353CD5A944D589E7FD68F71A9F409"
+ {
+ "SourcePath" = "8:"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_823268F0927E471C9AC8D4518AB6C2F5"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:SourceFiles"
+ "OutputProjectGuid" = "8:{B7F7F0F7-9029-4D1A-8CB4-C42DAF86A21C}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_587183B52DD64752997FFA522BC57D0A"
+ {
+ "SourcePath" = "8:c:\\users\\fcolin\\program files\\release\\IvyProbe.exe"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_BE1B10BDB24D49EA8562F4B0A6596F21"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:Built"
+ "OutputProjectGuid" = "8:{B7F7F0F7-9029-4D1A-8CB4-C42DAF86A21C}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_BFED66BE7DFC4FC5B625527D0526B5A5"
+ {
+ "SourcePath" = "8:..\\..\\release\\Ivy.dll"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_BE1B10BDB24D49EA8562F4B0A6596F21"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:Built"
+ "OutputProjectGuid" = "8:{9BD87B7A-517E-4900-B3EA-A358885CD876}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ }
+ "VJSharpPlugin"
+ {
+ }
+ }
+}
diff --git a/Ivy/InstIvyDev/InstIvyDev.vdproj.vspscc b/Ivy/InstIvyDev/InstIvyDev.vdproj.vspscc
new file mode 100644
index 0000000..587f3d9
--- /dev/null
+++ b/Ivy/InstIvyDev/InstIvyDev.vdproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/Ivy/InstallSource/InstallSource.vdproj b/Ivy/InstallSource/InstallSource.vdproj
new file mode 100644
index 0000000..72879da
--- /dev/null
+++ b/Ivy/InstallSource/InstallSource.vdproj
@@ -0,0 +1,728 @@
+"DeployProject"
+{
+"VSVersion" = "3:800"
+"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}"
+"IsWebType" = "8:FALSE"
+"ProjectName" = "8:InstallIvySources"
+"LanguageId" = "3:1036"
+"CodePage" = "3:1252"
+"UILanguageId" = "3:1036"
+"SccProjectName" = "8:SAK"
+"SccLocalPath" = "8:SAK"
+"SccAuxPath" = "8:SAK"
+"SccProvider" = "8:SAK"
+ "Hierarchy"
+ {
+ }
+ "Configurations"
+ {
+ "Debug"
+ {
+ "DisplayName" = "8:Debug"
+ "IsDebugOnly" = "11:TRUE"
+ "IsReleaseOnly" = "11:FALSE"
+ "OutputFilename" = "8:Debug\\InstallSource.msi"
+ "PackageFilesAs" = "3:2"
+ "PackageFileSize" = "3:-2147483648"
+ "CabType" = "3:1"
+ "Compression" = "3:2"
+ "SignOutput" = "11:FALSE"
+ "CertificateFile" = "8:"
+ "PrivateKeyFile" = "8:"
+ "TimeStampServer" = "8:"
+ "InstallerBootstrapper" = "3:2"
+ "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
+ {
+ "Enabled" = "11:TRUE"
+ "PromptEnabled" = "11:TRUE"
+ "PrerequisitesLocation" = "2:1"
+ "Url" = "8:"
+ "ComponentsUrl" = "8:"
+ "Items"
+ {
+ }
+ }
+ }
+ "Release"
+ {
+ "DisplayName" = "8:Release"
+ "IsDebugOnly" = "11:FALSE"
+ "IsReleaseOnly" = "11:TRUE"
+ "OutputFilename" = "8:..\\..\\..\\..\\Install\\InstallIvySources.msi"
+ "PackageFilesAs" = "3:2"
+ "PackageFileSize" = "3:-2147483648"
+ "CabType" = "3:1"
+ "Compression" = "3:2"
+ "SignOutput" = "11:FALSE"
+ "CertificateFile" = "8:"
+ "PrivateKeyFile" = "8:"
+ "TimeStampServer" = "8:"
+ "InstallerBootstrapper" = "3:1"
+ "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
+ {
+ "Enabled" = "11:FALSE"
+ "PromptEnabled" = "11:TRUE"
+ "PrerequisitesLocation" = "2:1"
+ "Url" = "8:http://www.tls.cena.fr/products/ivy/download/packages"
+ "ComponentsUrl" = "8:"
+ "Items"
+ {
+ }
+ }
+ }
+ }
+ "Deployable"
+ {
+ "CustomAction"
+ {
+ }
+ "DefaultFeature"
+ {
+ "Name" = "8:DefaultFeature"
+ "Title" = "8:"
+ "Description" = "8:"
+ }
+ "ExternalPersistence"
+ {
+ "LaunchCondition"
+ {
+ }
+ }
+ "File"
+ {
+ }
+ "FileType"
+ {
+ }
+ "Folder"
+ {
+ "{3C67513D-01DD-4637-8A68-80971EB9504F}:_B3B7EB8E946F45E1BA06E9D854393106"
+ {
+ "DefaultLocation" = "8:[ProgramFilesFolder][Manufacturer]\\[ProductName]"
+ "Name" = "8:#1925"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:TARGETDIR"
+ "Folders"
+ {
+ "{9EF0B969-E518-4E46-987F-47570745A589}:_982736CE041D479585A839B95041A4C3"
+ {
+ "Name" = "8:Ivy"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:_E96D066878304D268825DFE0DDE10D44"
+ "Folders"
+ {
+ }
+ }
+ "{9EF0B969-E518-4E46-987F-47570745A589}:_D5ABE290941D4E11A32C1B4224453B50"
+ {
+ "Name" = "8:IvyProbe"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:_D6C5E160784140D3B122D7535BF25441"
+ "Folders"
+ {
+ }
+ }
+ }
+ }
+ }
+ "LaunchCondition"
+ {
+ }
+ "Locator"
+ {
+ }
+ "MsiBootstrapper"
+ {
+ "LangId" = "3:1036"
+ }
+ "Product"
+ {
+ "Name" = "8:Microsoft Visual Studio"
+ "ProductName" = "8:IVY Sources"
+ "ProductCode" = "8:{A4D80C7C-E792-43F3-97D5-F163E43C2592}"
+ "PackageCode" = "8:{6C9A2D11-2E42-486D-84E1-C0A8A0AA3FB1}"
+ "UpgradeCode" = "8:{779E9266-AC8C-490F-8519-7B26BDA9E0F3}"
+ "RestartWWWService" = "11:FALSE"
+ "RemovePreviousVersions" = "11:TRUE"
+ "DetectNewerInstalledVersion" = "11:TRUE"
+ "InstallAllUsers" = "11:FALSE"
+ "ProductVersion" = "8:1.1.0"
+ "Manufacturer" = "8:CENA PII"
+ "ARPHELPTELEPHONE" = "8:"
+ "ARPHELPLINK" = "8:http://www.tls.cena.fr/products/ivy"
+ "Title" = "8:IVY Sources"
+ "Subject" = "8:"
+ "ARPCONTACT" = "8:CENA PII"
+ "Keywords" = "8:Ivy"
+ "ARPCOMMENTS" = "8:Source de Ivy IvyProbe "
+ "ARPURLINFOABOUT" = "8:"
+ "ARPPRODUCTICON" = "8:"
+ "ARPIconIndex" = "3:0"
+ "SearchPath" = "8:"
+ "UseSystemSearchPath" = "11:TRUE"
+ "TargetPlatform" = "3:0"
+ "PreBuildEvent" = "8:"
+ "PostBuildEvent" = "8:\"$(ProjectDir)..\\..\\UpdateIvyWeb.bat\" \"$(BuiltOuputPath)\""
+ "RunPostBuildEvent" = "3:0"
+ }
+ "Registry"
+ {
+ "HKLM"
+ {
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_53933E3AD9234F12A4873FFA9773F31B"
+ {
+ "Name" = "8:Software"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_7A4AE5DE0CDC412DB0987B541DAEEA5C"
+ {
+ "Name" = "8:[Manufacturer]"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ }
+ "HKCU"
+ {
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_44F3154318AA4F4E8261D87380278D24"
+ {
+ "Name" = "8:Software"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_9E06D03F3A794C62A13E46DD90ECF5C2"
+ {
+ "Name" = "8:[Manufacturer]"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ }
+ "HKCR"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKU"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKPU"
+ {
+ "Keys"
+ {
+ }
+ }
+ }
+ "Sequences"
+ {
+ }
+ "Shortcut"
+ {
+ }
+ "UserInterface"
+ {
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_0A813400DCAA4CA2AED300FE90057CD5"
+ {
+ "Name" = "8:#1902"
+ "Sequence" = "3:1"
+ "Attributes" = "3:3"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_D10C5ED5EBA44D81A8E5ABCD373D3DFB"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Finished"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "UpdateText"
+ {
+ "Name" = "8:UpdateText"
+ "DisplayName" = "8:#1058"
+ "Description" = "8:#1158"
+ "Type" = "3:15"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1258"
+ "DefaultValue" = "8:#1258"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_0BBD850026394B248C77CF0D6A143DCC"
+ {
+ "Name" = "8:#1901"
+ "Sequence" = "3:2"
+ "Attributes" = "3:2"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_C6C426B741844BD2B3CEDB5637FA9398"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Progress"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "ShowProgress"
+ {
+ "Name" = "8:ShowProgress"
+ "DisplayName" = "8:#1009"
+ "Description" = "8:#1109"
+ "Type" = "3:5"
+ "ContextData" = "8:1;True=1;False=0"
+ "Attributes" = "3:0"
+ "Setting" = "3:0"
+ "Value" = "3:1"
+ "DefaultValue" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_138810673D2A4B039E304596343A481D"
+ {
+ "Name" = "8:#1902"
+ "Sequence" = "3:2"
+ "Attributes" = "3:3"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_F70B3043BFCB4E2CAE3E5D5165AEF3BE"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Finished"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_14D0F4EA9F4542A9A7180215B5B185E0"
+ {
+ "UseDynamicProperties" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim"
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_A5F428FF10E64C82A99936F0EEFE6C9A"
+ {
+ "Name" = "8:#1900"
+ "Sequence" = "3:1"
+ "Attributes" = "3:1"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_BC6CF4D097A54F8796A6DC0991F61A8A"
+ {
+ "Sequence" = "3:300"
+ "DisplayName" = "8:Confirm Installation"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_C59FDD5750904CE69714920B25A7A1D5"
+ {
+ "Sequence" = "3:200"
+ "DisplayName" = "8:Installation Folder"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "InstallAllUsersVisible"
+ {
+ "Name" = "8:InstallAllUsersVisible"
+ "DisplayName" = "8:#1059"
+ "Description" = "8:#1159"
+ "Type" = "3:5"
+ "ContextData" = "8:1;True=1;False=0"
+ "Attributes" = "3:0"
+ "Setting" = "3:0"
+ "Value" = "3:1"
+ "DefaultValue" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_F3608A2FED224610A31E8BA94D72172B"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Welcome"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "CopyrightWarning"
+ {
+ "Name" = "8:CopyrightWarning"
+ "DisplayName" = "8:#1002"
+ "Description" = "8:#1102"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1202"
+ "DefaultValue" = "8:#1202"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "Welcome"
+ {
+ "Name" = "8:Welcome"
+ "DisplayName" = "8:#1003"
+ "Description" = "8:#1103"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1203"
+ "DefaultValue" = "8:#1203"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_B959F1B9EF674DF1AAAC84393D11F1F4"
+ {
+ "UseDynamicProperties" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim"
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_BF96EE5647E446EE8E09C7161F2D15C6"
+ {
+ "Name" = "8:#1900"
+ "Sequence" = "3:2"
+ "Attributes" = "3:1"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_5DD5731B72974577BB1FE53249896CE6"
+ {
+ "Sequence" = "3:300"
+ "DisplayName" = "8:Confirm Installation"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_6CF0FA0D246440D18CF8219B20779B9B"
+ {
+ "Sequence" = "3:200"
+ "DisplayName" = "8:Installation Folder"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_7232E533C8364A2481A6BF178EF00E6E"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Welcome"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "CopyrightWarning"
+ {
+ "Name" = "8:CopyrightWarning"
+ "DisplayName" = "8:#1002"
+ "Description" = "8:#1102"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1202"
+ "DefaultValue" = "8:#1202"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "Welcome"
+ {
+ "Name" = "8:Welcome"
+ "DisplayName" = "8:#1003"
+ "Description" = "8:#1103"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1203"
+ "DefaultValue" = "8:#1203"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_D683AF1F16134222A207B5C3D986AFD7"
+ {
+ "Name" = "8:#1901"
+ "Sequence" = "3:1"
+ "Attributes" = "3:2"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_6A78AB4A47D846BE8BCFE2FD4B21FED4"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Progress"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "ShowProgress"
+ {
+ "Name" = "8:ShowProgress"
+ "DisplayName" = "8:#1009"
+ "Description" = "8:#1109"
+ "Type" = "3:5"
+ "ContextData" = "8:1;True=1;False=0"
+ "Attributes" = "3:0"
+ "Setting" = "3:0"
+ "Value" = "3:1"
+ "DefaultValue" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ }
+ "MergeModule"
+ {
+ }
+ "ProjectOutput"
+ {
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_31B0D0C4AA7F433F8B505436C2D1D325"
+ {
+ "SourcePath" = "8:"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_D5ABE290941D4E11A32C1B4224453B50"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:SourceFiles"
+ "OutputProjectGuid" = "8:{B7F7F0F7-9029-4D1A-8CB4-C42DAF86A21C}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_F7CCDC767F0A43859A12C6B0D26950FD"
+ {
+ "SourcePath" = "8:"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_982736CE041D479585A839B95041A4C3"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:SourceFiles"
+ "OutputProjectGuid" = "8:{9BD87B7A-517E-4900-B3EA-A358885CD876}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ }
+ "VJSharpPlugin"
+ {
+ }
+ }
+}
diff --git a/Ivy/InstallSource/InstallSource.vdproj.vspscc b/Ivy/InstallSource/InstallSource.vdproj.vspscc
new file mode 100644
index 0000000..65fed18
--- /dev/null
+++ b/Ivy/InstallSource/InstallSource.vdproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = "relative:Ivy\\InstallSource"
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/Ivy/Ivy.cxx b/Ivy/Ivy.cxx
new file mode 100644
index 0000000..4564c6f
--- /dev/null
+++ b/Ivy/Ivy.cxx
@@ -0,0 +1,437 @@
+// Ivy.cpp: implementation of the Ivy class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "IvyStdAfx.h"
+
+#include "Ivy.h"
+
+#include "IvyWatcher.h"
+#include "IvyApplication.h"
+#include "IvySynchroWnd.h"
+#include "IvyBinding.h"
+#include "intervalRegexp.h"
+
+#define DEFAULT_ADDR "127.255.255.255"
+#define SEPARATOR ":"
+#define DEFAULT_PORT "2010"
+#define DEFAULT_DOMAIN DEFAULT_ADDR/**/SEPARATOR/**/DEFAULT_PORT
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+Ivy::~Ivy()
+{
+ // remove all app and stop watcher
+ stop();
+ regexp_out.clear();
+
+
+ if ( synchronous )
+ {
+ for ( unsigned int i = 0; i < callbacks.size(); i ++)
+ {
+ delete callbacks[i];
+ }
+ }
+ callbacks.clear();
+
+
+// if ( direct_callback ) delete direct_callback;
+// if ( application_callback ) delete application_callback;
+
+ delete watcher;
+// server->Close();
+ delete server;
+ if ( synchronous )
+ {
+ delete IvySynchronousCallback::m_synchro;
+ delete application_callback;
+ }
+}
+
+
+Ivy::Ivy(const char* name, const char * ready, IvyApplicationCallback *callback, bool Synchronous)
+{
+ InitializeCriticalSection( &m_application_cs );
+ regexp_id = 0;
+ synchronous = Synchronous;
+ if ( synchronous )
+ IvySynchronousCallback::m_synchro = new IvySynchroWnd();
+ ready_message = ready;
+ ApplicationName = name;
+
+ binding_callback = NULL;
+ application_callback = synchronous ? new IvySynchronousApplicationCallback(callback) : callback;
+ direct_callback = NULL;
+ die_callback = NULL;
+ server = new IvyApplication(this);
+ applicationPort = server->Create();
+ if ( !applicationPort )
+ {
+ TRACE( " Can't Create server %d\n", server->GetLastError( ) );
+ return;
+ }
+ ApplicationID = GenApplicationUniqueIdentifier();
+ watcher = new IvyWatcher(this);
+
+
+}
+const char *Ivy::GenApplicationUniqueIdentifier()
+{
+ static char appid[2048];
+ unsigned long curtime;
+ curtime = GetTickCount();
+ srand( curtime );
+ sprintf(appid,"%d:%lu:%d",rand(),curtime,applicationPort);
+ return appid;
+}
+
+const char * Ivy::GetDomain(const char *domainlist)
+{
+ // determine domain to use
+ // the syntax of domain is "IpBroadcastAddr1,IpBroadcastAddr2,IpBroadcastAddr2:port"
+ if ( domainlist )
+ {
+ domain = domainlist;
+ }
+ if ( domain.empty() )
+ {
+#ifndef UNDER_CE
+ size_t requiredSize;
+
+ getenv_s( &requiredSize, NULL, 0, "IVYBUS");
+
+ if ( requiredSize )
+ {
+ char *env = (char*)malloc( requiredSize * sizeof(char));
+ getenv_s( &requiredSize, env, requiredSize, "IVYBUS");
+ domain = env;
+ free( env );
+ }
+#endif
+ if ( domain.empty() )
+ domain = DEFAULT_DOMAIN;
+ }
+ // first find our UDP port
+ size_t sep_index = domain.rfind( ':' );
+ if ( sep_index == -1 )
+ {
+ domain = DEFAULT_DOMAIN;
+ TRACE(" Missing ':' in domain list using default domain %s\n", domain );
+ }
+ if ( sep_index == 0 )
+ {
+ /* missing addr using localhost */
+ domain.insert(0,DEFAULT_ADDR);
+ }
+ return domain.c_str();
+}
+
+void Ivy::start(const char *domain)
+{
+ watcher->start(domain);
+}
+void Ivy::stop()
+{
+ watcher->stop();
+
+ IvyApplicationList::iterator iter;
+ for ( iter = applications.begin() ; iter != applications.end() ; ++iter )
+ {
+ IvyApplication *app = *iter;
+ app->Close();
+ delete app;
+ }
+ applications.clear();
+}
+int Ivy::BindMsg(const char *regexp, IvyMessageCallback *cb)
+{
+ char buffer[8192];
+
+ SubstituteInterval( regexp, buffer, sizeof( buffer ) );
+ regexp_out.push_back( buffer );
+ callbacks.push_back( synchronous ? new IvySynchronousMessageCallback(cb) : cb );
+
+ /* send to already connected */
+ IvyApplicationList::iterator iter;
+ for ( iter = applications.begin() ; iter != applications.end() ; ++iter )
+ {
+ IvyApplication *app = *iter;
+ app->SendMsg(IvyApplication::AddRegexp, regexp_id, buffer );
+ }
+ return regexp_id++;
+}
+int Ivy::BindMsg( IvyMessageCallback *cb, const char *regexp, ... )
+{
+ char buffer[4096];
+ char buffer2[8192];
+ va_list args;
+
+ va_start( args, regexp ); /* Initialize variable arguments. */
+ _vsnprintf_s( buffer, sizeof(buffer), sizeof(buffer)-1, regexp, args );
+ va_end( args);
+
+ SubstituteInterval( buffer, buffer2, sizeof( buffer2 ) );
+
+ regexp_out.push_back( buffer2 );
+ callbacks.push_back( synchronous ? new IvySynchronousMessageCallback(cb) : cb );
+
+ /* send to already connected */
+ IvyApplicationList::iterator iter;
+ for ( iter = applications.begin() ; iter != applications.end() ; ++iter )
+ {
+ IvyApplication *app = *iter;
+ app->SendMsg(IvyApplication::AddRegexp, regexp_id, buffer2 );
+ }
+ return regexp_id++;
+}
+
+void Ivy::UnbindMsg(int id)
+{
+ regexp_out[ id ] = "";
+ callbacks[ id ] = NULL;
+ /* send to already connected */
+ IvyApplicationList::iterator iter;
+ for ( iter = applications.begin() ; iter != applications.end() ; ++iter )
+ {
+ IvyApplication *app = *iter;
+ app->SendMsg(IvyApplication::DelRegexp, id, "" );
+ }
+
+}
+
+void Ivy::BindDirectMsg(IvyDirectMessageCallback *callback)
+{
+direct_callback = callback;
+}
+
+unsigned int Ivy::GetApplicationPort()
+{
+ return applicationPort;
+}
+
+void Ivy::AddApplication(IvyApplication *app)
+{
+ EnterCriticalSection( &m_application_cs );
+ // Check for disconnected Application
+ IvyApplicationList::iterator iter;
+ for ( iter = applications.begin() ; iter != applications.end() ; )
+ {
+ IvyApplication *disc_app = *iter++;
+ if ( disc_app->m_hSocket == INVALID_SOCKET )
+ {
+ applications.remove( disc_app );
+ delete disc_app;
+ }
+ }
+ applications.push_back( app );
+ LeaveCriticalSection( &m_application_cs );
+ SendSubscriptions( app );
+}
+void Ivy::RemoveApplication(IvyApplication * app)
+{
+ /// OLD NOT called because of deallocation PB
+ // the real remove is done at arrival of a new Application
+ // or at the bus Stop
+ TRACE( "Ivy::RemoveApplication %lu\n", app );
+ if ( app )
+ {
+
+ EnterCriticalSection( &m_application_cs );
+ applications.remove( app );
+ LeaveCriticalSection( &m_application_cs );
+ delete app;
+ }
+}
+
+void Ivy::SendSubscriptions(IvyApplication *app)
+{
+ app->SendMsg( IvyApplication::StartRegexp, GetApplicationPort(), ApplicationName.c_str());
+ for ( unsigned int id = 0 ; id < regexp_out.size(); id++ )
+ {
+ const ivy::string& regexp = regexp_out[id];
+ if ( !regexp.empty() )
+ app->SendMsg( IvyApplication::AddRegexp, id, regexp.c_str());
+ }
+ app->SendMsg( IvyApplication::EndRegexp, 0);
+
+}
+
+
+int Ivy::SendMsg(const char * message, ... )
+{
+ int count = 0;
+ char buffer[4096];
+ va_list args;
+
+ va_start( args, message ); /* Initialize variable arguments. */
+ _vsnprintf_s( buffer, sizeof(buffer), sizeof(buffer)-1, message, args );
+ va_end( args);
+ /* send to already connected */
+ IvyApplicationList::iterator iter;
+ for ( iter = applications.begin() ; iter != applications.end() ; ++iter )
+ {
+ IvyApplication *app = *iter;
+ count += app->SendMsg( buffer );
+ }
+ return count;
+}
+void Ivy::SendDieMsg( IvyApplication *app )
+{
+ app->SendMsg( IvyApplication::Die, 0 );
+}
+IvyApplication * Ivy::GetApplication(const char *name)
+{
+ IvyApplication *app = NULL;
+ EnterCriticalSection( &m_application_cs );
+ IvyApplicationList::iterator iter;
+ for ( iter = applications.begin() ; iter != applications.end() ; )
+ {
+ IvyApplication *ap = *iter++;
+ if ( (ap->m_hSocket != INVALID_SOCKET) && ap->appname == name )
+ {
+ app = ap;
+ break; // dont return because of LeaveCriticalSection !!!
+ }
+ }
+ LeaveCriticalSection( &m_application_cs );
+ return app;
+}
+
+
+void Ivy::CallMessageCallback(IvyApplication *app, int id, int argc, const char ** argv)
+{
+ IvyMessageCallback *callback;
+ callback = callbacks[ id ];
+ if ( callback )
+ {
+ callback->OnMessage( app, argc, argv );
+ }
+}
+
+void Ivy::CallDirectMessageCallback(IvyApplication *app, int id, const char *arg)
+{
+ if ( direct_callback )
+ {
+ direct_callback->OnDirectMessage( app, id, arg );
+ }
+}
+
+bool Ivy::CallDieCallback(IvyApplication *app, int id, const char *arg)
+{
+ if ( die_callback )
+ {
+ return die_callback->OnDie( app, id, arg );
+ }
+ return TRUE;
+}
+
+void Ivy::CallApplicationConnectedCallback(IvyApplication * app)
+{
+ if ( application_callback )
+ {
+ application_callback->OnApplicationConnected( app );
+ }
+}
+void Ivy::CallApplicationDisconnectedCallback(IvyApplication * app)
+{
+ if ( application_callback )
+ {
+ application_callback->OnApplicationDisconnected( app );
+ }
+}
+void Ivy::CallBindingAddCallback(IvyApplication * app, int id, const char * regexp)
+{
+ if ( binding_callback )
+ {
+ binding_callback->OnAddBind( app, id, regexp );
+ }
+}
+void Ivy::CallBindingRemoveCallback(IvyApplication * app, int id, const char * regexp)
+{
+ if ( binding_callback )
+ {
+ binding_callback->OnRemoveBind( app, id, regexp );
+ }
+}
+void Ivy::CallBindingFilterCallback(IvyApplication * app, int id, const char * regexp)
+{
+ if ( binding_callback )
+ {
+ binding_callback->OnFilterBind( app, id, regexp );
+ }
+}
+void Ivy::SendDirectMsg(IvyApplication * app, int id, const char *message)
+{
+ app->SendMsg( IvyApplication::DirectMsg, id, message );
+}
+
+void Ivy::SetBindCallback( IvyBindingCallback* bind_callback )
+{
+ binding_callback = synchronous ? new IvySynchronousBindingCallback(bind_callback) : bind_callback;
+}
+
+void Ivy::SetFilter(int argc, const char **argv )
+{
+ IvyBinding::SetFilter(argc, argv );
+}
+
+bool Ivy::CheckConnected(IvyApplication * app)
+{
+ if (app->remoteService == 0) /* old application dont check */
+ return false;
+ /* check to see if app already connected */
+ IvyApplicationList::iterator iter;
+ for ( iter = applications.begin() ; iter != applications.end() ; ++iter )
+ {
+ IvyApplication *application = *iter;
+ if ( application != app && application->SameApplication(app))
+ return true;
+ }
+ return false;
+}
+void Ivy::SubstituteInterval (const char *src, char *dst, size_t dst_len)
+{
+
+ // pas de traitement couteux s'il n'y a rien à interpoler
+ if (strstr (src, "(?I") == NULL) {
+ strcpy (dst,src);
+ return;
+ } else {
+ char *curPos;
+ char *itvPos;
+ char *dstPos = dst;
+
+ curPos = (char *)src;
+ while ((itvPos = strstr (curPos, "(?I")) != NULL) {
+ // copie depuis la position courante jusqu'à l'intervalle
+ int lenCp, min,max;
+ char withDecimal;
+ lenCp = itvPos-curPos;
+ memcpy ( dstPos, curPos, lenCp);
+ curPos=itvPos;
+ dstPos += lenCp;
+
+ // extraction des paramètres de l'intervalle
+ sscanf (itvPos, "(?I%d#%d%c", &min, &max, &withDecimal);
+
+ // printf ("DBG> substituteInterval min=%d max=%d withDecimal=%d\n",
+ // min, max, (withDecimal != 'i'));
+
+ // generation et copie de l'intervalle
+ regexpGen (dstPos, dst_len-(dstPos-dst), min, max, (withDecimal != 'i'));
+ dstPos = dst + strlen (dst);
+
+ // consommation des caractères décrivant intervalle dans la chaine source
+ curPos = strstr (curPos, ")");
+ curPos++;
+ }
+ strncat (dstPos, curPos, dst_len-(dstPos-dst));
+ }
+
+}
+
diff --git a/Ivy/Ivy.dsp b/Ivy/Ivy.dsp
new file mode 100644
index 0000000..d36f170
--- /dev/null
+++ b/Ivy/Ivy.dsp
@@ -0,0 +1,196 @@
+# Microsoft Developer Studio Project File - Name="Ivy" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Ivy - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Ivy.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Ivy.mak" CFG="Ivy - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Ivy - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Ivy - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""$/Ivy", NBEAAAAA"
+# PROP Scc_LocalPath "."
+CPP=xicl6.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Ivy - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IVY_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IVY_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 wsock32.lib ws2_32.lib user32.lib /nologo /dll /machine:I386
+
+!ELSEIF "$(CFG)" == "Ivy - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IVY_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "IVY_EXPORTS" /D "NO_IVY_DEBUG" /FR /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40c /d "_DEBUG"
+# ADD RSC /l 0x40c /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 wsock32.lib user32.lib /nologo /dll /profile /debug /machine:I386 /out:"c:\users\fcolin\Program Files\Debug\Ivy.dll"
+
+!ENDIF
+
+# Begin Target
+
+# Name "Ivy - Win32 Release"
+# Name "Ivy - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\BufferedSocket.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\Ivy.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\IvyApplication.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\IvyCbindings.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\IvyDllMain.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\IvySynchroWnd.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\IvyWatcher.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\Regexp.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+
+!IF "$(CFG)" == "Ivy - Win32 Release"
+
+!ELSEIF "$(CFG)" == "Ivy - Win32 Debug"
+
+# ADD CPP /Yc"stdafx.h"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\ThreadedSocket.cxx
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\BufferedSocket.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DataTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Ivy.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IvyApplication.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IvyCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IvyCbindings.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IvySynchroWnd.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IvyWatcher.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Regexp.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ThreadedSocket.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/Ivy/Ivy.h b/Ivy/Ivy.h
new file mode 100644
index 0000000..cf90bdd
--- /dev/null
+++ b/Ivy/Ivy.h
@@ -0,0 +1,119 @@
+// Ivy.h: interface for the Ivy class.
+//
+//////////////////////////////////////////////////////////////////////
+
+
+#pragma once
+#pragma warning(disable: 4251)
+
+#ifdef WIN32
+#ifdef IVY_EXPORTS
+class _declspec(dllexport) IvyWatcher;
+class _declspec(dllexport) IvyApplication;
+class _declspec(dllexport) Ivy;
+class _declspec(dllexport) CThreadedSocket;
+class _declspec(dllexport) CBufferedSocket;
+#else
+#pragma comment(lib,"Ivy.LIB" )
+class _declspec(dllimport) IvyWatcher;
+class _declspec(dllimport) IvyApplication;
+class _declspec(dllimport) Ivy;
+class _declspec(dllimport) CThreadedSocket;
+class _declspec(dllimport) CBufferedSocket;
+#endif
+#endif
+
+#ifdef IVY_USE_OWN_DATATYPES
+
+#include "DataTypes.h"
+
+#else
+
+#include <string>
+#include <list>
+#include <vector>
+#include <map>
+
+namespace ivy = std;
+
+#endif
+
+#include "IvyCallback.h"
+
+
+class Ivy
+{
+ friend class IvyWatcher;
+
+ friend class IvyApplication;
+
+private:
+ int regexp_id;
+ unsigned int applicationPort;
+ void SendSubscriptions(IvyApplication *app);
+ bool synchronous; // use Window Shink to made CB mono thread like
+ IvyApplication * server;
+ IvyWatcher * watcher;
+ IvyDieCallback *die_callback;
+ IvyDirectMessageCallback *direct_callback;
+ IvyApplicationCallback *application_callback;
+ IvyBindingCallback *binding_callback;
+ /* list des adresses de broadcast */
+ ivy::string domain;
+ /* nom de l'appliction */
+ ivy::string ApplicationName;
+ /* Aplication Unique ID */
+ ivy::string ApplicationID;
+ /* liste des clients connectes */
+ CRITICAL_SECTION m_application_cs;
+ typedef ivy::list<IvyApplication*> IvyApplicationList;
+ IvyApplicationList applications;
+
+ /* liste des souscriptions locale a emettre aux autres applications */
+ ivy::vector<ivy::string> regexp_out;
+ /* liste des callbacks a appeler */
+ ivy::vector< IvyMessageCallback* > callbacks;
+
+protected:
+ void SubstituteInterval (const char *src, char *dst, size_t dst_len);
+ void AddApplication( IvyApplication *app );
+ void RemoveApplication( IvyApplication *app);
+
+ bool CheckConnected( IvyApplication *app );
+ void CallApplicationConnectedCallback( IvyApplication *app );
+ void CallApplicationDisconnectedCallback( IvyApplication *app );
+ void CallBindingAddCallback(IvyApplication * app, int id, const char * regexp);
+ void CallBindingRemoveCallback(IvyApplication * app, int id, const char * regexp);
+ void CallBindingFilterCallback(IvyApplication * app, int id, const char * regexp);
+ bool CallDieCallback( IvyApplication *app, int id, const char *arg );
+ void CallDirectMessageCallback( IvyApplication *app, int id, const char *arg );
+ void CallMessageCallback( IvyApplication *app, int id, int argc, const char **argv );
+
+ const char *GenApplicationUniqueIdentifier();
+
+ /* message a emettre sur connection nouvelle application */
+ ivy::string ready_message;
+
+public:
+
+ void SetBindCallback( IvyBindingCallback* bind_callback );
+ void SetFilter( int argc, const char **argv );
+ void SendDieMsg( IvyApplication *app );
+ IvyApplication *GetApplication(const char *name);
+ void SendDirectMsg( IvyApplication *app, int id, const char *message);
+ void BindDirectMsg( IvyDirectMessageCallback *callback );
+ int SendMsg( const char *message, ... );
+
+ const char *GetDomain(const char *domainlist);
+ unsigned int GetApplicationPort();
+ int BindMsg( const char *regexp, IvyMessageCallback *cb );
+ int BindMsg( IvyMessageCallback *cb, const char *regexp, ... );
+ void UnbindMsg( int id );
+ Ivy( const char *name, const char* ready, IvyApplicationCallback *callback, bool Synchronous = true );
+ void start(const char *domain);
+ void stop();
+ virtual ~Ivy();
+
+
+
+};
diff --git a/Ivy/Ivy.vcproj b/Ivy/Ivy.vcproj
new file mode 100644
index 0000000..f9e983a
--- /dev/null
+++ b/Ivy/Ivy.vcproj
@@ -0,0 +1,590 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="Ivy"
+ ProjectGUID="{9818D652-CC05-463E-880D-AFCA2C7BFABE}"
+ RootNamespace="Ivy"
+ SccProjectName="&quot;$/Bus/Ivy&quot;, QPEAAAAA"
+ SccLocalPath="."
+ SccProvider="MSSCCI:Microsoft Visual SourceSafe"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/Ivy.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=""
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;..\..\..\pcre-6.4&quot;"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;IVY_EXPORTS;NO_IVY_DEBUG"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="IvyStdAfx.h"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="wsock32.lib"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Copying libraries, headers &amp; dll&apos;s..."
+ CommandLine="rem copy &quot;$(TargetDir)$(TargetName).dll&quot; &quot;C:\users\fcolin\Program Files\$(OutDir)&quot;&#x0D;&#x0A;rem copy &quot;$(TargetDir)$(TargetName).lib&quot; &quot;C:\users\fcolin\Program Files\lib\$(OutDir)&quot;&#x0D;&#x0A;rem copy Ivy.h &quot;C:\users\fcolin\Program Files\Include\&quot;&#x0D;&#x0A;rem copy IvyApplication.h &quot;C:\users\fcolin\Program Files\Include\&quot;&#x0D;&#x0A;rem copy IvyCallback.h &quot;C:\users\fcolin\Program Files\Include\&quot;&#x0D;&#x0A;rem copy BufferedSocket.h &quot;C:\users\fcolin\Program Files\Include\&quot;&#x0D;&#x0A;rem copy ThreadedSocket.h &quot;C:\users\fcolin\Program Files\Include\&quot;&#x0D;&#x0A;rem copy DataTypes.h &quot;C:\users\fcolin\Program Files\Include\&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="3"
+ TypeLibraryName=".\Debug/Ivy.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=""
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;..\..\..\pcre-6.4&quot;"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;IVY_EXPORTS;NO_IVY_DEBUG"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="IvyStdAfx.h"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="wsock32.lib"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ Rules="-Microsoft.Design#CA1012;-Microsoft.Design#CA2210;-Microsoft.Design#CA1040;-Microsoft.Design#CA1005;-Microsoft.Design#CA1020;-Microsoft.Design#CA1021;-Microsoft.Design#CA1010;-Microsoft.Design#CA1011;-Microsoft.Design#CA1009;-Microsoft.Design#CA1050;-Microsoft.Design#CA1026;-Microsoft.Design#CA1019;-Microsoft.Design#CA1031;-Microsoft.Design#CA1047;-Microsoft.Design#CA1000;-Microsoft.Design#CA1048;-Microsoft.Design#CA1051;-Microsoft.Design#CA1002;-Microsoft.Design#CA1061;-Microsoft.Design#CA1006;-Microsoft.Design#CA1046;-Microsoft.Design#CA1045;-Microsoft.Design#CA1038;-Microsoft.Design#CA1008;-Microsoft.Design#CA1028;-Microsoft.Design#CA1004;-Microsoft.Design#CA1035;-Microsoft.Design#CA1063;-Microsoft.Design#CA1032;-Microsoft.Design#CA1023;-Microsoft.Design#CA1033;-Microsoft.Design#CA1039;-Microsoft.Design#CA1016;-Microsoft.Design#CA1014;-Microsoft.Design#CA1017;-Microsoft.Design#CA1018;-Microsoft.Design#CA1027;-Microsoft.Design#CA1059;-Microsoft.Design#CA1060;-Microsoft.Design#CA1034;-Microsoft.Design#CA1013;-Microsoft.Design#CA1036;-Microsoft.Design#CA1044;-Microsoft.Design#CA1041;-Microsoft.Design#CA1025;-Microsoft.Design#CA1052;-Microsoft.Design#CA1053;-Microsoft.Design#CA1057;-Microsoft.Design#CA1058;-Microsoft.Design#CA1001;-Microsoft.Design#CA1049;-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055;-Microsoft.Design#CA1030;-Microsoft.Design#CA1003;-Microsoft.Design#CA1007;-Microsoft.Design#CA1043;-Microsoft.Design#CA1024;-Microsoft.Design#CA1062;-Microsoft.Globalization#CA1301;-Microsoft.Globalization#CA1302;-Microsoft.Globalization#CA1303;-Microsoft.Globalization#CA1306;-Microsoft.Globalization#CA1304;-Microsoft.Globalization#CA1305;-Microsoft.Globalization#CA1300;-Microsoft.Mobility#CA1600;-Microsoft.Mobility#CA1601;-Microsoft.Naming#CA1718;-Microsoft.Naming#CA1720;-Microsoft.Naming#CA1700;-Microsoft.Naming#CA1712;-Microsoft.Naming#CA1713;-Microsoft.Naming#CA1709;-Microsoft.Naming#CA1708;-Microsoft.Naming#CA1715;-Microsoft.Naming#CA1710;-Microsoft.Naming#CA1707;-Microsoft.Naming#CA1722;-Microsoft.Naming#CA1711;-Microsoft.Naming#CA1716;-Microsoft.Naming#CA1705;-Microsoft.Naming#CA1725;-Microsoft.Naming#CA1719;-Microsoft.Naming#CA1721;-Microsoft.Naming#CA1706;-Microsoft.Naming#CA1724;-Microsoft.Naming#CA1726;-Microsoft.Usage#CA2209;-Microsoft.Usage#CA2236;-Microsoft.Usage#CA2227;-Microsoft.Usage#CA2213;-Microsoft.Usage#CA2216;-Microsoft.Usage#CA2215;-Microsoft.Usage#CA2214;-Microsoft.Usage#CA2222;-Microsoft.Usage#CA2202;-Microsoft.Usage#CA1806;-Microsoft.Usage#CA2217;-Microsoft.Usage#CA2212;-Microsoft.Usage#CA2219;-Microsoft.Usage#CA2201;-Microsoft.Usage#CA2228;-Microsoft.Usage#CA2221;-Microsoft.Usage#CA2220;-Microsoft.Usage#CA2240;-Microsoft.Usage#CA2229;-Microsoft.Usage#CA2238;-Microsoft.Usage#CA2207;-Microsoft.Usage#CA2208;-Microsoft.Usage#CA2235;-Microsoft.Usage#CA2237;-Microsoft.Usage#CA2232;-Microsoft.Usage#CA2223;-Microsoft.Usage#CA2211;-Microsoft.Usage#CA2233;-Microsoft.Usage#CA2225;-Microsoft.Usage#CA2226;-Microsoft.Usage#CA2231;-Microsoft.Usage#CA2224;-Microsoft.Usage#CA2218;-Microsoft.Usage#CA2234;-Microsoft.Usage#CA2241;-Microsoft.Usage#CA2239;-Microsoft.Usage#CA2200;-Microsoft.Usage#CA1801;-Microsoft.Usage#CA2205;-Microsoft.Usage#CA2230"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/Ivy.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=""
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="&quot;..\..\..\pcre-6.4&quot;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;IVY_EXPORTS"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="IvyStdAfx.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="wsock32.lib"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=""
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="3"
+ TypeLibraryName=".\Release/Ivy.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions=""
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="&quot;..\..\..\pcre-6.4&quot;"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;IVY_EXPORTS"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="IvyStdAfx.h"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="wsock32.lib"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=""
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine=""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ <ProjectReference
+ ReferencedProjectIdentifier="{D79FC143-498E-4342-B2C7-BDAD1B8D0E6B}"
+ RelativePathToProject="..\..\pcre\pcre.vcproj"
+ />
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath=".\BufferedSocket.cxx"
+ >
+ </File>
+ <File
+ RelativePath=".\intervalRegexp.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Ivy.cxx"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyApplication.cxx"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyBinding.cxx"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyCbindings.cxx"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyDllMain.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyStdAfx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\IvySynchroWnd.cxx"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyWatcher.cxx"
+ >
+ </File>
+ <File
+ RelativePath=".\Regexp.cxx"
+ >
+ </File>
+ <File
+ RelativePath=".\ThreadedSocket.cxx"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath=".\BufferedSocket.h"
+ >
+ </File>
+ <File
+ RelativePath=".\DataTypes.h"
+ >
+ </File>
+ <File
+ RelativePath=".\intervalRegexp.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Ivy.h"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyApplication.h"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyBinding.h"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyCallback.h"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyCbindings.h"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyStdAfx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\IvySynchroWnd.h"
+ >
+ </File>
+ <File
+ RelativePath=".\IvyWatcher.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Regexp.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ThreadedSocket.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Ivy/Ivy.vcproj.vspscc b/Ivy/Ivy.vcproj.vspscc
new file mode 100644
index 0000000..794f014
--- /dev/null
+++ b/Ivy/Ivy.vcproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/Ivy/IvyApplication.cxx b/Ivy/IvyApplication.cxx
new file mode 100644
index 0000000..07f37be
--- /dev/null
+++ b/Ivy/IvyApplication.cxx
@@ -0,0 +1,375 @@
+// IvyApplication.cpp : implementation file
+//
+
+#include "IvyStdAfx.h"
+
+#include "IvyApplication.h"
+#include "IvyBinding.h"
+
+
+//#define IVY_DEBUG
+
+#define ARG_START 2
+#define ARG_END 3
+
+static char * firstArg( char *s, const char separator )
+{
+ char *ptr = s;
+
+ while ( *ptr && *ptr != separator )
+ ptr++;
+ if ( *ptr == separator )
+ return ptr++ ;
+ else return NULL;
+}
+/*
+function like strok but do not eat consecutive separator
+*/
+static char * nextArg( char **s, const char separator )
+{
+ char *start = *s;
+ char *end = *s;
+
+ while ( *end && *end != separator )
+ end++;
+ if ( *end == separator ) *end++ = '\0';
+ if ( end == start ) return NULL;
+ *s = end;
+ return start;
+}
+/////////////////////////////////////////////////////////////////////////////
+// IvyApplication
+
+IvyApplication::IvyApplication(Ivy * bus)
+{
+ this->bus = bus;
+ remoteService = 0; /* unknown or unconnected application */
+ appname = "Unknown";
+ AppConnectedCallbackCalled = false;
+}
+
+IvyApplication::~IvyApplication()
+{
+// bus->RemoveApplication( this );
+ for ( Bindings::iterator iter = regexp_in.begin( ); iter != regexp_in.end( ); iter++ )
+ delete iter->second;
+ regexp_in.clear();
+ if ( m_hSocket != INVALID_SOCKET )
+ Close();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// IvyApplication member functions
+
+
+void IvyApplication::Create(const char* host, UINT & port, const char* name)
+{
+ appname = name;
+ // Exception to catch
+ CBufferedSocket::Create();
+ Connect(host, port);
+}
+
+
+
+UINT IvyApplication::Create()
+{
+ ivy::string host;
+ UINT port;
+ CBufferedSocket::Create();
+ // Max Listen Connexion
+ Listen( SOMAXCONN );
+ GetSockName( host, port );
+ TRACE(" TCP %s:%d\n", host.c_str(), port );
+#ifdef IVY_DEBUG
+ TRACE( "IvyApplication::Create server socket %d\n", m_hSocket );
+#endif
+ return port;
+}
+
+void IvyApplication::OnReceive(char * line)
+{
+ int err;
+ unsigned int id;
+ int kind_of_msg = Bye;
+ char *arg;
+ int argc = 0;
+ char *arg_ptr;
+ static const int max_subexp = 200;
+ const char *argv[max_subexp];
+
+ IvyBinding *exp;
+ int erroffset;
+ const char *errmsg;
+
+#ifdef IVY_DEBUG
+ TRACE("Receive %s\n",line);
+#endif //IVY_DEBUG
+
+ err = sscanf_s( line ,"%d %d", &kind_of_msg, &id);
+ arg = firstArg( line , ARG_START );
+ if ( (err != 2) || (arg == NULL) )
+ {
+ TRACE("Quitting bad format %s\n", line);
+ SendMsg(Error, Error, "bad format request expected 'type id ...'");
+// bus->RemoveApplication( this );
+ Close();
+ return;
+ }
+ arg++;
+ switch( kind_of_msg )
+ {
+ case Bye:
+
+#ifdef IVY_DEBUG
+ TRACE("Quitting %s\n", line);
+#endif //IVY_DEBUG
+
+// bus->RemoveApplication( this );
+ OnClose(0);
+ //Close();
+ break;
+ case Error:
+
+#ifdef IVY_DEBUG
+ TRACE("Receive error %d %s\n", id, arg);
+#endif //IVY_DEBUG
+
+ break;
+ case AddRegexp:
+
+#ifdef IVY_DEBUG
+ TRACE("Regexp id=%d exp='%s'\n", id, arg);
+#endif //IVY_DEBUG
+
+ if ( !IvyBinding::Filter( arg ) )
+ {
+#ifdef IVY_DEBUG
+ TRACE("Warning exp='%s' can't match removing from %s\n",arg,appname.c_str());
+#endif //IVY_DEBUG
+ bus->CallBindingFilterCallback( this, id, arg );
+ return;
+ }
+ exp = new IvyBinding();
+ if ( !exp->Compile(arg, &erroffset, &errmsg ) )
+ {
+ ivy::string errstr( "Error can't compile regexp '" );
+ errstr += arg;
+ errstr += "' error ";
+ errstr += errmsg;
+ SendMsg( Error, Error, errstr.c_str() );
+ TRACE("IvyApplication %s\n",errstr.c_str());
+ delete exp;
+ return;
+ }
+
+ /*if ( regexp_in.size() < (id + 1) )
+ {
+ regexp_in.resize( id + 1 );
+ regexp_str_in.resize( id + 1 );
+ }*/
+ regexp_in[ id ] = exp;
+ regexp_str_in[ id ] = arg;
+#ifdef IVY_DEBUG
+ TRACE("Adding regexp[%d]='%s' size: %d\n",id,arg,regexp_in.size());
+#endif //IVY_DEBUG
+ bus->CallBindingAddCallback( this, id, arg );
+ break;
+ case DelRegexp:
+
+#ifdef IVY_DEBUG
+ TRACE("Regexp Delete id=%d\n", id);
+#endif //IVY_DEBUG
+ if ( regexp_in[id] )
+ {
+ exp = regexp_in[ id ];
+ bus->CallBindingRemoveCallback( this, id, regexp_str_in[id].c_str() );
+
+ delete exp;
+ regexp_in[ id ] = NULL;
+ }
+ break;
+ case StartRegexp:
+
+#ifdef IVY_DEBUG
+ TRACE("Regexp Start id=%d\n", id);
+#endif //IVY_DEBUG
+
+ appname = arg;
+ /* remote socket port */
+ remoteService = id;
+ if ( bus->CheckConnected( this ) )
+ {
+ TRACE("Quitting already connected %s\n", appname.c_str());
+ SendMsg( Error, Error, "already connected" );
+// bus->RemoveApplication( this );
+ Close();
+ }
+ break;
+ case EndRegexp:
+
+#ifdef IVY_DEBUG
+ TRACE("Regexp End id=%d\n", id);
+#endif //IVY_DEBUG
+
+ bus->CallApplicationConnectedCallback( this );
+ AppConnectedCallbackCalled = true;
+ if ( !bus->ready_message.empty() )
+ SendMsg( bus->ready_message.c_str() );
+ break;
+ case Msg:
+
+#ifdef IVY_DEBUG
+ TRACE("Message id=%d msg='%s'\n", id, arg);
+#endif //IVY_DEBUG
+
+ arg_ptr = arg;
+ arg = nextArg( &arg_ptr, ARG_END);
+ while ( arg )
+ {
+ argv[argc++] = arg;
+ arg = nextArg( &arg_ptr, ARG_END );
+ }
+ bus->CallMessageCallback( this, id, argc, argv );
+ break;
+ case DirectMsg:
+
+#ifdef IVY_DEBUG
+ TRACE("Direct Message id=%d msg='%s'\n", id, arg);
+#endif //IVY_DEBUG
+
+ bus->CallDirectMessageCallback( this, id, arg );
+ break;
+ case Die:
+
+#ifdef IVY_DEBUG
+ TRACE("Die Message id=%d msg='%s'\n", id, arg);
+#endif //IVY_DEBUG
+
+ if ( bus->CallDieCallback( this, id, arg ) )
+ {
+ PostMessage( NULL, WM_CLOSE, 0, 0);
+ exit(-1);
+ }
+ break;
+ case Ping:
+#ifdef IVY_DEBUG
+ TRACE("Ping Message\n");
+#endif //IVY_DEBUG
+ this->SendMsg( Pong, 0, "beurk" );
+ break;
+
+ case Pong:
+#ifdef IVY_DEBUG
+ TRACE("Pong Message\n");
+#endif //IVY_DEBUG
+ TRACE("Receive unhandled Pong message (ivy-c++ not able to send ping)\n");
+ break;
+
+ default:
+ TRACE("Receive unhandled message %s\n", line);
+ break;
+ }
+}
+
+
+void IvyApplication::SendMsg(MsgType msg, int id, const char * arg)
+{
+ char buffer[1024];
+ if ( arg )
+ _snprintf_s( buffer, sizeof( buffer ),sizeof( buffer )-1, "%d %d%c%s\n", msg, id, ARG_START, arg );
+ else sprintf_s( buffer,sizeof( buffer ), "%d %d%c\n", msg, id, ARG_START);
+
+#ifdef IVY_DEBUG
+ TRACE("SendMsg %s\n",buffer);
+#endif //IVY_DEBUG
+ Send( buffer );
+}
+
+void IvyApplication::OnAccept(int nErrorCode)
+{
+ ivy::string remotehost;
+ UINT remoteport;
+
+ // construct a new, empty socket
+
+ IvyApplication *newapp = new IvyApplication(bus);
+
+ // accept connection
+
+ Accept( *newapp );
+ newapp->GetPeerName( remotehost, remoteport );
+ TRACE("Connexion de %s:%u\n", remotehost.c_str(), remoteport );
+ bus->AddApplication( newapp );
+}
+
+void IvyApplication::OnClose(int nErrorCode)
+{
+ ivy::string remotehost;
+ UINT remoteport;
+ GetPeerName( remotehost, remoteport );
+ TRACE("Deconnexion de %s:%u\n", remotehost.c_str(), remoteport );
+ if ( AppConnectedCallbackCalled )
+ bus->CallApplicationDisconnectedCallback( this );
+
+ for ( Bindings::iterator iter = regexp_in.begin( ); iter != regexp_in.end( ); iter++)
+ delete iter->second;
+ regexp_in.clear();
+ Close();
+ //bus->RemoveApplication( this );
+}
+
+int IvyApplication::SendMsg(const char *message)
+{
+ int count = 0;
+ IvyBinding *exp;
+
+ /* send to already connected */
+ for ( Bindings::iterator iter = regexp_in.begin( ); iter != regexp_in.end( ); iter++ )
+ {
+ exp = iter->second;
+ if ( !exp )
+ continue;
+ int match_count = exp->Exec( message );
+ if ( match_count > 0 )
+ {
+ ivy::string buffer;
+ int arglen;
+ const char *arg;
+
+ for ( int j = 1; j < match_count; j++ )
+ {
+ exp->Match(message, j, &arglen, &arg);
+ buffer += ivy::string(arg,arglen );
+ buffer += ARG_END;
+ }
+ SendMsg( Msg, iter->first, buffer.c_str() );
+ count++;
+ }
+
+ }
+ return count;
+}
+
+const char *IvyApplication::GetName(void)
+{
+return appname.c_str();
+}
+
+
+BOOL IvyApplication::SameApplication(IvyApplication * app)
+{
+ ivy::string host1;
+ UINT port1;
+ ivy::string host2;
+ UINT port2;
+ if ( (remoteService != 0) && (remoteService == app->remoteService) )
+ {
+ GetPeerName( host1, port1 );
+ app->GetPeerName( host2, port2 );
+ TRACE( "IvyApplication::SameApplication %s:%d %s:%d\n", host1.c_str(),port1, host2.c_str(),port2);
+ return ( host1 == host2 );
+ }
+ return false;
+}
diff --git a/Ivy/IvyApplication.h b/Ivy/IvyApplication.h
new file mode 100644
index 0000000..7191400
--- /dev/null
+++ b/Ivy/IvyApplication.h
@@ -0,0 +1,69 @@
+
+#pragma once
+
+// IvyApplication.h : header file
+//
+#include "BufferedSocket.h"
+#include "Ivy.h"
+#include "IvyBinding.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// IvyApplication command target
+
+class IvyApplication : public CBufferedSocket
+{
+// Attributes
+public:
+
+
+ typedef enum {
+
+ Bye, /* quit l'application ( non utilise ) */
+ AddRegexp, /* expression reguliere d'un client */
+ Msg, /* message reel */
+ Error, /* error message */
+ DelRegexp, /* Remove expression reguliere */
+ EndRegexp, /* end of the regexp list */
+ StartRegexp, /* debut des expressions */
+ DirectMsg, /* message direct a destination de l'appli */
+ Die, /* demande de terminaison de l'appli */
+ Ping, /* message de controle ivy */
+ Pong /* ivy doit renvoyer ce message à la reception d'un ping */
+
+ }MsgType;
+
+
+// Operations
+public:
+ IvyApplication(Ivy *bus);
+ virtual ~IvyApplication();
+
+// Overrides
+public:
+ BOOL SameApplication( IvyApplication *app );
+ UINT remoteService;
+ const char *GetName(void);
+ inline Ivy *GetBus(void){ return bus;};
+ int SendMsg( const char *message );
+ void SendMsg( MsgType msg, int id, const char * arg = NULL);
+ UINT Create();
+ void OnReceive( char *line );
+ void Create( const char * host, UINT &port, const char* name );
+ virtual void OnAccept(int nErrorCode);
+ virtual void OnClose(int nErrorCode);
+
+
+// Implementation
+protected:
+ ivy::string appname;
+ bool AppConnectedCallbackCalled;
+ Ivy *bus;
+ /* liste des souscriptions remote */
+ /* en clair */
+ ivy::map<int,ivy::string> regexp_str_in;
+ /* compile */
+ typedef ivy::map<int,IvyBinding *> Bindings;
+ Bindings regexp_in;
+
+ friend class Ivy;
+};
diff --git a/Ivy/IvyBinding.cxx b/Ivy/IvyBinding.cxx
new file mode 100644
index 0000000..f3000fd
--- /dev/null
+++ b/Ivy/IvyBinding.cxx
@@ -0,0 +1,189 @@
+/*
+ * Ivy, C++ interface
+ *
+ * Copyright (C) 1997-2000
+ * Centre d'Études de la Navigation Aérienne
+ *
+ * Bind syntax for extracting message comtent
+ * using regexp or other
+ *
+ * Authors: François-Régis Colin <fcolin@cena.fr>
+ *
+ * $Id: ivybind.c,v 1.9.2.7 2006/06/01 12:07:17 bustico Exp $
+ *
+ * Please refer to file version.h for the
+ * copyright notice regarding this software
+ */
+/* Module de gestion de la syntaxe des messages Ivy */
+#include "IvyStdAfx.h"
+
+#include "IvyBinding.h"
+
+static int err_offset;
+
+#ifdef USE_PCRE
+ static const char *err_buf;
+#else /* we don't USE_PCRE */
+ static char err_buf[4096];
+#endif /* USE_PCRE */
+
+/* classes de messages emis par l'application utilise pour le filtrage */
+static int messages_classes_count = 0;
+static const char **messages_classes = 0;
+/* regexp d'extraction du mot clef des regexp client pour le filtrage des regexp , ca va c'est clair ??? */
+static IvyBinding token_extract;
+
+IvyBinding::IvyBinding()
+{
+#ifdef USE_PCRE
+ regexp = NULL;
+ inspect = NULL;
+#else /* we don't USE_PCRE */
+ free( regexp );
+#endif /* USE_PCRE */
+ nb_match = 0;
+}
+IvyBinding::~IvyBinding()
+{
+#ifdef USE_PCRE
+ if (inspect!=NULL)
+ pcre_free(inspect);
+ if (regexp!=NULL)
+ pcre_free(regexp);
+#else /* we don't USE_PCRE */
+ free( regexp );
+#endif /* USE_PCRE */
+}
+bool IvyBinding::Compile( const char * expression, int *erroffset, const char **errmessage )
+{
+ bool compile = false;
+#ifdef USE_PCRE
+ regexp = pcre_compile(expression, PCRE_CASELESS, &err_buf, &err_offset, NULL);
+ if ( regexp != NULL )
+ {
+ this->inspect = pcre_study(regexp,0,&err_buf);
+ if (err_buf!=NULL)
+ {
+ printf("Error studying %s, message: %s\n",expression,err_buf);
+ }
+ compile = true;
+ }
+ else
+ {
+ *erroffset = err_offset;
+ *errmessage = err_buf;
+ printf("Error compiling '%s', %s\n", expression, err_buf);
+ }
+#else /* we don't USE_PCRE */
+ regex_t regexp;
+ int reg;
+ reg = regcomp(&regexp, expression, REGCOMP_OPT|REG_EXTENDED);
+ if ( reg == 0 )
+ {
+ this->next = NULL;
+ }
+ else
+ {
+ regerror (reg, &regexp, err_buf, sizeof(err_buf) );
+ *erroffset = err_offset;
+ *errmessage = err_buf;
+ printf("Error compiling '%s', %s\n", expression, err_buf);
+ }
+#endif /* USE_PCRE */
+ return compile;
+}
+
+
+int IvyBinding::Exec( const char * message )
+{
+#ifdef USE_PCRE
+
+ nb_match = pcre_exec(
+ regexp,
+ inspect,
+ message,
+ strlen(message),
+ 0, /* debut */
+ 0, /* no other regexp option */
+ ovector,
+ OVECSIZE);
+ if (nb_match<1) return 0; /* no match */
+#else /* we don't USE_PCRE */
+ memset( match, -1, sizeof(match )); /* work around bug !!!*/
+ nb_match = regexec (&regexp, message, MAX_MSG_FIELDS, match, 0)
+ if (nb_match == REG_NOMATCH)
+ return 0;
+ for ( index = 1; index < MAX_MSG_FIELDS; index++ )
+ {
+ if ( match[i].rm_so != -1 )
+ nb_match++;
+ }
+#endif /* USE_PCRE */
+ return nb_match;
+}
+
+void IvyBinding::Match( const char *message, int argnum, int *arglen, const char **arg)
+{
+#ifdef USE_PCRE
+
+ *arglen = ovector[2*argnum+1]- ovector[2*argnum];
+ *arg = message + ovector[2*argnum];
+#else /* we don't USE_PCRE */
+
+ regmatch_t* p;
+
+ p = &match[argnum+1];
+ if ( p->rm_so != -1 ) {
+ *arglen = p->rm_eo - p->rm_so;
+ *arg = message + p->rm_so;
+ } else { // ARG VIDE
+ *arglen = 0;
+ *arg = NULL;
+ }
+#endif /* USE_PCRE */
+
+}
+
+//filter Expression Bind
+void IvyBinding::SetFilter( int argc, const char **argv)
+{
+ const char *errbuf;
+ int erroffset;
+
+ messages_classes_count = argc;
+ messages_classes = argv;
+ /* compile the token extraction regexp */
+
+ if ( !token_extract.Compile("^\\^([a-zA-Z_0-9-]+).*", & erroffset, & errbuf) )
+ {
+ printf("Error compiling Token Extract regexp: %s\n", errbuf);
+ }
+}
+
+int IvyBinding::Filter(const char *expression)
+{
+ int i;
+ int err;
+ int regexp_ok = 1; /* accepte tout par default */
+ int tokenlen;
+ const char *token;
+
+ if ( *expression =='^' && messages_classes_count !=0 )
+ {
+ regexp_ok = 0;
+
+ /* extract token */
+ err = token_extract.Exec( expression );
+ if ( err < 1 ) return 1;
+ token_extract.Match( expression , 1, &tokenlen, &token );
+ for ( i = 0 ; i < messages_classes_count; i++ )
+ {
+ if (strncmp( messages_classes[i], token, tokenlen ) == 0) {
+ return 1; }
+ // else {
+ //printf ("DBG> %s eliminé [%s]\n", token, expression);
+ //}
+ }
+ }
+ return regexp_ok;
+}
diff --git a/Ivy/IvyBinding.h b/Ivy/IvyBinding.h
new file mode 100644
index 0000000..44a87ee
--- /dev/null
+++ b/Ivy/IvyBinding.h
@@ -0,0 +1,58 @@
+/*
+ * Ivy, C interface
+ *
+ * Copyright (C) 1997-2006
+ * Centre d'Études de la Navigation Aérienne
+ *
+ * Bind syntax for extracting message comtent
+ * using regexp or other
+ *
+ * Authors: François-Régis Colin <fcolin@cena.fr>
+ *
+ * $Id: ivybind.h,v 1.5.2.3 2006/04/21 15:51:55 fcolin Exp $
+ *
+ * Please refer to file version.h for the
+ * copyright notice regarding this software
+ */
+/* Module de gestion de la syntaxe des messages Ivy */
+#pragma once
+
+#define USE_PCRE
+
+#ifdef USE_PCRE
+#define OVECSIZE 60 /* must be multiple of 3, for regexp return */
+#include <pcre.h>
+#else /* we don't USE_PCRE */
+#define MAX_MSG_FIELDS 200
+#include "Regex.h"
+#endif /* USE_PCRE */
+
+class IvyBinding
+{
+public:
+ /* Creation, Compilation */
+ IvyBinding();
+ ~IvyBinding();
+
+ /* Mise en place des Filtrages */
+ static void SetFilter( int argc, const char ** argv );
+ static int Filter( const char *expression );
+
+ /* Creation, Compilation */
+ bool Compile( const char *expression, int *erroffset, const char **errmessage );
+ /* Execution , extraction */
+ int Exec( const char * message );
+ void Match( const char *message, int argnum, int *arglen, const char **arg );
+
+private:
+#ifdef USE_PCRE
+ pcre *regexp;
+ pcre_extra *inspect;
+ int nb_match;
+ int ovector[OVECSIZE];
+#else /* we don't USE_PCRE */
+ regex_t regexp; /* la regexp sous forme machine */
+ regmatch_t match[MAX_MSG_FIELDS+1]; /* resultat du match */
+#endif /* USE_PCRE */
+
+}; \ No newline at end of file
diff --git a/Ivy/IvyCallback.h b/Ivy/IvyCallback.h
new file mode 100644
index 0000000..ede0ef4
--- /dev/null
+++ b/Ivy/IvyCallback.h
@@ -0,0 +1,180 @@
+// IvyCallback.h : Interface for the IvyMessageCallback Class
+// : Interface for the IvyDirectMessageCallback Class
+// : Interface for the IvyApplicationCallback Class
+//
+
+
+#pragma once
+
+class IvyApplication;
+
+/* Callback for the normal bus Message */
+
+class IvyMessageCallback {
+public:
+ virtual void OnMessage (IvyApplication *app, int argc, const char **argv )=0;
+ virtual ~IvyMessageCallback()
+ {
+ }
+};
+class IvyMessageCallbackFunction: public IvyMessageCallback {
+public:
+ typedef void ( *IvyMessageCallback_fun )( IvyApplication *app, void *user_data, int argc, const char **argv );
+ IvyMessageCallback_fun MessageCb;
+ void *data;
+
+public:
+ IvyMessageCallbackFunction ( IvyMessageCallback_fun m_cb, void *udata = NULL ) : MessageCb( m_cb )
+ {
+ data = udata;
+ }
+ ~IvyMessageCallbackFunction ()
+ {
+ }
+ void OnMessage (IvyApplication *app, int argc, const char **argv)
+ {
+ (*MessageCb) (app, data, argc, argv);
+ }
+/* raccourci d'ecriture */
+#define BUS_CALLBACK( m , d ) new IvyMessageCallbackFunction( m, d )
+};
+/* template Class Callback for the normal bus Message */
+template <class T> class IvyMessageCallbackOf : public IvyMessageCallback {
+
+protected:
+ T* Object;
+ typedef void ( T::*IvyMessageCallback_fun )( IvyApplication *app, int argc, const char **argv );
+ IvyMessageCallback_fun MessageCb;
+
+public:
+ IvyMessageCallbackOf ( T* o, IvyMessageCallback_fun m_cb ) : Object (o), MessageCb( m_cb )
+ {
+ }
+ ~IvyMessageCallbackOf ()
+ {
+ }
+ void OnMessage (IvyApplication *app, int argc, const char **argv)
+ {
+ (Object->*MessageCb) (app, argc, argv);
+ }
+/* raccourci d'ecriture */
+#define BUS_CALLBACK_OF( cl, m ) new IvyMessageCallbackOf<cl>( this, &cl::m )
+};
+/* Callback for the direct Message */
+class IvyDirectMessageCallback {
+public:
+ virtual void OnDirectMessage (IvyApplication *app, int id, const char *arg ) = 0;
+};
+
+/* Application Callback */
+
+class IvyApplicationCallback {
+public:
+ virtual void OnApplicationConnected (IvyApplication *app) = 0;
+ virtual void OnApplicationDisconnected (IvyApplication *app) = 0;
+ virtual ~IvyApplicationCallback()
+ {
+ }
+};
+class IvyApplicationNullCallback : public IvyApplicationCallback {
+public:
+ virtual void OnApplicationConnected (IvyApplication *app)
+ {};
+ virtual void OnApplicationDisconnected (IvyApplication *app)
+ {};
+ virtual ~IvyApplicationNullCallback()
+ {
+ }
+};
+// Static function CB
+class IvyApplicationCallbackFunction: public IvyApplicationCallback {
+public:
+ typedef void ( *IvyApplicationCallback_fun )( IvyApplication *app );
+ IvyApplicationCallback_fun ApplicationConnectedCb;
+ IvyApplicationCallback_fun ApplicationDisconnectedCb;
+
+public:
+ IvyApplicationCallbackFunction ( IvyApplicationCallback_fun con_cb, IvyApplicationCallback_fun disc_cb)
+ : ApplicationConnectedCb( con_cb ), ApplicationDisconnectedCb( disc_cb )
+ {
+ }
+ ~IvyApplicationCallbackFunction ()
+ {
+ }
+ virtual void OnApplicationConnected (IvyApplication *app)
+ {
+ if ( ApplicationConnectedCb ) (*ApplicationConnectedCb) (app);
+ };
+ virtual void OnApplicationDisconnected (IvyApplication *app)
+ {
+ if ( ApplicationDisconnectedCb ) (*ApplicationDisconnectedCb) (app);
+ };
+
+/* raccourci d'ecriture */
+#define BUS_APPLICATION_CALLBACK( conn, disconn ) new IvyApplicationCallbackFunction( conn, disconn )
+};
+
+/* Binding Callback */
+
+class IvyBindingCallback {
+public:
+ virtual void OnAddBind (IvyApplication *app, int id, const char * regexp) = 0;
+ virtual void OnRemoveBind (IvyApplication *app, int id, const char * regexp) = 0;
+ virtual void OnFilterBind (IvyApplication *app, int id, const char * regexp) = 0;
+ virtual ~IvyBindingCallback()
+ {
+ }
+};
+class IvyBindingNullCallback : public IvyBindingCallback {
+public:
+ virtual void OnAddBind (IvyApplication *app, int id, const char * regexp)
+ {};
+ virtual void OnRemoveBind (IvyApplication *app, int id, const char * regexp)
+ {};
+ virtual void OnFilterBind (IvyApplication *app, int id, const char * regexp)
+ {};
+ virtual ~IvyBindingNullCallback()
+ {
+ }
+};
+// Static function CB
+class IvyBindingCallbackFunction: public IvyBindingCallback {
+public:
+ typedef void ( *IvyBindingCallback_fun )( IvyApplication *app, int id, const char * regexp );
+ IvyBindingCallback_fun BindingAddCb;
+ IvyBindingCallback_fun BindingRemoveCb;
+ IvyBindingCallback_fun BindingFilterCb;
+
+public:
+ IvyBindingCallbackFunction ( IvyBindingCallback_fun add_cb, IvyBindingCallback_fun remove_cb, IvyBindingCallback_fun filter_cb )
+ : BindingAddCb( add_cb ), BindingRemoveCb( remove_cb ), BindingFilterCb( filter_cb )
+ {
+ }
+ ~IvyBindingCallbackFunction ()
+ {
+ }
+ virtual void OnAddBind (IvyApplication *app, int id, const char * regexp)
+ {
+ if(BindingAddCb) (*BindingAddCb) (app, id, regexp);
+ };
+ virtual void OnRemoveBind (IvyApplication *app, int id, const char * regexp)
+ {
+ if (BindingRemoveCb) (*BindingRemoveCb) (app, id, regexp);
+ };
+ virtual void OnFilterBind (IvyApplication *app, int id, const char * regexp)
+ {
+ if(BindingFilterCb ) (*BindingFilterCb) (app, id, regexp);
+ };
+
+/* raccourci d'ecriture */
+#define BUS_BINDING_CALLBACK( add, remove, filter ) new IvyBindingCallbackFunction( add, remove, filter )
+};
+
+/* Callback for the die Message */
+class IvyDieCallback {
+public:
+ virtual bool OnDie (IvyApplication *app, int id, const char *arg ) = 0;
+ virtual ~IvyDieCallback()
+ {
+ }
+};
diff --git a/Ivy/IvyCbindings.cxx b/Ivy/IvyCbindings.cxx
new file mode 100644
index 0000000..8876bbf
--- /dev/null
+++ b/Ivy/IvyCbindings.cxx
@@ -0,0 +1,129 @@
+
+#include "IvyStdAfx.h"
+#include <stdarg.h>
+#include "Ivy.h"
+#include "IvyApplication.h"
+
+#include "IvyCbindings.h"
+
+static Ivy *bus = NULL;
+
+// application callback wrappers
+IvyCApplicationCallback app_cb = NULL;
+void * app_user_data = NULL;
+void app_conn( IvyApplication *app )
+{
+ (*app_cb)(app, app_user_data, IvyApplicationConnected );
+}
+void app_discon( IvyApplication *app )
+{
+ (*app_cb)(app, app_user_data, IvyApplicationDisconnected );
+}
+
+void IvyInit(
+ const char *AppName, /* nom de l'application */
+ const char *ready, /* ready Message peut etre NULL */
+ IvyCApplicationCallback callback, /* callback appele sur connection deconnection d'une appli */
+ void *data, /* user data passe au callback */
+ IvyCDieCallback die_callback, /* last change callback before die */
+ void *die_data ) /* user data */
+{
+ bus = new Ivy(AppName, ready, BUS_APPLICATION_CALLBACK(app_conn,app_discon) );
+}
+/* filtrage des regexps */
+void IvySetFilter( int argc, const char **argv)
+{
+ bus->SetFilter( argc, argv );
+}
+
+void IvyStart (const char* domain)
+{
+ bus->start(domain);
+}
+void IvyStop ()
+{
+ bus->stop();
+}
+
+/* query sur les applications connectees */
+const char *IvyGetApplicationName( IvyClientPtr app )
+{
+ return ((IvyApplication*)app)->GetName();
+}
+const char *IvyGetApplicationHost( IvyClientPtr app )
+{
+ ivy::string host;
+ UINT port;
+ ((IvyApplication*)app)->GetPeerName(host,port);
+ return host.c_str();
+}
+IvyClientPtr IvyGetApplication( char *name )
+{
+ return NULL;
+}
+const char *IvyGetApplicationList()
+{
+ return "Not yiet implemented";
+}
+const char **IvyGetApplicationMessages( IvyClientPtr app)
+{
+ return NULL;
+}
+
+MsgRcvPtr IvyBindMsg( IvyCMsgCallback callback, void *user_data, const char *fmt_regexp, ... )
+{
+ int count;
+ char buf_regexp[2048];
+ va_list args;
+ va_start( args, fmt_regexp );
+ _vsnprintf_s( buf_regexp, sizeof(buf_regexp), sizeof(buf_regexp)-1, fmt_regexp, args );
+ count = bus->BindMsg(buf_regexp, BUS_CALLBACK( ((IvyMessageCallbackFunction::IvyMessageCallback_fun)callback), user_data ) );
+ va_end( args );
+ return count;
+}
+void IvyUnbindMsg( MsgRcvPtr id )
+{
+ bus->UnbindMsg( id );
+}
+
+/* emission d'un message d'erreur */
+void IvySendError( IvyClientPtr app, int id, const char *fmt, ... )
+{
+ char buf[2048];
+ va_list args;
+ va_start( args, fmt );
+ _vsnprintf_s( buf, sizeof(buf), sizeof(buf)-1, fmt, args );
+ ((IvyApplication*)app)->SendMsg( IvyApplication::Error, id, buf );
+ va_end( args );
+}
+
+/* emmission d'un message die pour terminer l'application */
+void IvySendDieMsg( IvyClientPtr app )
+{
+ ((IvyApplication*)app)->SendMsg( IvyApplication::Die, 0 );
+}
+
+/* emission d'un message retourne le nb effectivement emis */
+
+int IvySendMsg( const char *fmt_message, ... )
+{
+ int count;
+ char buf[2048];
+ va_list args;
+ va_start( args, fmt_message );
+ _vsnprintf_s( buf, sizeof(buf), sizeof(buf)-1, fmt_message, args );
+ count = bus->SendMsg(buf);
+ va_end( args );
+ return count;
+}
+
+void IvyBindDirectMsg( IvyCMsgDirectCallback callback, void *user_data)
+{
+}
+void IvySendDirectMsg( IvyClientPtr app, int id, char *msg )
+{
+}
+void IvyMainLoop( void(*hook)(void) )
+{
+ Sleep( INFINITE );
+}
diff --git a/Ivy/IvyCbindings.h b/Ivy/IvyCbindings.h
new file mode 100644
index 0000000..38ccfd6
--- /dev/null
+++ b/Ivy/IvyCbindings.h
@@ -0,0 +1,108 @@
+/*
+ * Ivy, C interface
+ *
+ * Copyright (C) 1997-2000
+ * Centre d'Études de la Navigation Aérienne
+ *
+ * Main functions
+ *
+ * Authors: François-Régis Colin <fcolin@cena.dgac.fr>
+ * Stéphane Chatty <chatty@cena.dgac.fr>
+ *
+ * $Id: ivy.h,v 1.8 2000/08/07 11:29:29 sc Exp $
+ *
+ * Please refer to file version.h for the
+ * copyright notice regarding this software
+ */
+
+#ifndef IVY_C_BINDINGS_H
+#define IVY_C_BINDINGS_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WIN32
+#ifdef IVY_EXPORTS
+#define DLL_EXPORT _declspec(dllexport)
+#else
+#pragma comment(lib,"Ivy.LIB" )
+#define DLL_EXPORT /*_declspec(dllimport)*/
+#endif
+#endif
+
+
+/* numero par default du bus */
+
+#define DEFAULT_BUS 2010
+
+typedef void * Channel ;
+typedef int TimerId;
+
+typedef void * IvyClientPtr;
+
+typedef enum { IvyApplicationConnected, IvyApplicationDisconnected } IvyApplicationEvent;
+
+extern void IvyDefaultApplicationCallback( IvyClientPtr app, void *user_data, IvyApplicationEvent evt ) ;
+
+/* callback callback appele sur connexion deconnexion d'une appli */
+typedef void (*IvyCApplicationCallback)( IvyClientPtr app, void *user_data, IvyApplicationEvent evt ) ;
+
+/* callback appele sur reception de die */
+typedef void (*IvyCDieCallback)( IvyClientPtr app, void *user_data, int id ) ;
+
+/* callback appele sur reception de messages normaux */
+typedef void (*IvyCMsgCallback)( IvyClientPtr app, void *user_data, int argc, const char **argv ) ;
+
+/* callback appele sur reception de messages directs */
+typedef void (*IvyCMsgDirectCallback)( IvyClientPtr app, void *user_data, int id, char *msg ) ;
+
+/* identifiant d'une expression reguliere ( Bind/Unbind ) */
+typedef int MsgRcvPtr;
+
+/* filtrage des regexps */
+DLL_EXPORT void IvyClasses( int argc, const char **argv);
+
+DLL_EXPORT void IvyInit(
+ const char *AppName, /* nom de l'application */
+ const char *ready, /* ready Message peut etre NULL */
+ IvyCApplicationCallback callback, /* callback appele sur connection deconnection d'une appli */
+ void *data, /* user data passe au callback */
+ IvyCDieCallback die_callback, /* last change callback before die */
+ void *die_data ); /* user data */
+
+DLL_EXPORT void IvyStart (const char*);
+DLL_EXPORT void IvyStop ();
+
+/* query sur les applications connectees */
+DLL_EXPORT const char *IvyGetApplicationName( IvyClientPtr app );
+DLL_EXPORT const char *IvyGetApplicationHost( IvyClientPtr app );
+DLL_EXPORT IvyClientPtr IvyGetApplication( char *name );
+DLL_EXPORT const char *IvyGetApplicationList();
+DLL_EXPORT const char **IvyGetApplicationMessages( IvyClientPtr app); /* demande de reception d'un message */
+
+DLL_EXPORT MsgRcvPtr IvyBindMsg( IvyCMsgCallback callback, void *user_data, const char *fmt_regexp, ... ); /* avec sprintf prealable */
+DLL_EXPORT void IvyUnbindMsg( MsgRcvPtr id );
+
+/* emission d'un message d'erreur */
+DLL_EXPORT void IvySendError( IvyClientPtr app, int id, const char *fmt, ... );
+
+/* emmission d'un message die pour terminer l'application */
+DLL_EXPORT void IvySendDieMsg( IvyClientPtr app );
+
+/* emission d'un message retourne le nb effectivement emis */
+
+DLL_EXPORT int IvySendMsg( const char *fmt_message, ... ); /* avec sprintf prealable */
+
+/* Message Direct Inter-application */
+
+DLL_EXPORT void IvyBindDirectMsg( IvyCMsgDirectCallback callback, void *user_data);
+DLL_EXPORT void IvySendDirectMsg( IvyClientPtr app, int id, char *msg );
+DLL_EXPORT void IvyMainLoop( void(*hook)(void) );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Ivy/IvyDllMain.cpp b/Ivy/IvyDllMain.cpp
new file mode 100644
index 0000000..e8c13f4
--- /dev/null
+++ b/Ivy/IvyDllMain.cpp
@@ -0,0 +1,42 @@
+// libIvy.cpp : Defines the initialization routines for the DLL.
+//
+
+#include "IvyStdAfx.h"
+
+BOOL APIENTRY DllMain(HANDLE hInstance,
+ DWORD dwReason,
+ LPVOID lpReserved)
+{
+ // Remove this if you use lpReserved
+ UNREFERENCED_PARAMETER(lpReserved);
+
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ TRACE("IVY.DLL Initializing!\n");
+
+ // Extension DLL one-time initialization
+
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int err;
+
+ wVersionRequested = MAKEWORD( 2, 0 );
+
+ err = WSAStartup( wVersionRequested, &wsaData );
+ if ( err != 0 ) {
+ /* Tell the user that we could not find a usable */
+ /* WinSock DLL. */
+ return 0;
+ }
+
+
+
+ }
+ else if (dwReason == DLL_PROCESS_DETACH)
+ {
+ TRACE("IVY.DLL Terminating!\n");
+ // Terminate the library before destructors are called
+ WSACleanup();
+ }
+ return 1; // ok
+}
diff --git a/Ivy/IvyLib/IvyLib.vdproj b/Ivy/IvyLib/IvyLib.vdproj
new file mode 100644
index 0000000..e8a78e1
--- /dev/null
+++ b/Ivy/IvyLib/IvyLib.vdproj
@@ -0,0 +1,264 @@
+"DeployProject"
+{
+"VSVersion" = "3:800"
+"ProjectType" = "8:{06A35CCD-C46D-44D5-987B-CF40FF872267}"
+"IsWebType" = "8:FALSE"
+"ProjectName" = "8:InstallIvyLib"
+"LanguageId" = "3:1033"
+"CodePage" = "3:1252"
+"UILanguageId" = "3:1033"
+"SccProjectName" = "8:SAK"
+"SccLocalPath" = "8:SAK"
+"SccAuxPath" = "8:SAK"
+"SccProvider" = "8:SAK"
+ "Hierarchy"
+ {
+ "Entry"
+ {
+ "MsmKey" = "8:_66D910CBB02B47569794CF954A72E057"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_DE30DB02DD7494AFFBB32B50F67B491E"
+ "OwnerKey" = "8:_66D910CBB02B47569794CF954A72E057"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_EF9BC5D6F4274E54867D4FB7F7A33653"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ }
+ "Configurations"
+ {
+ "Debug"
+ {
+ "DisplayName" = "8:Debug"
+ "IsDebugOnly" = "11:TRUE"
+ "IsReleaseOnly" = "11:FALSE"
+ "OutputFilename" = "8:Debug\\IvyLib.msm"
+ "PackageFilesAs" = "3:2"
+ "PackageFileSize" = "3:-2147483648"
+ "CabType" = "3:1"
+ "Compression" = "3:2"
+ "SignOutput" = "11:FALSE"
+ "CertificateFile" = "8:"
+ "PrivateKeyFile" = "8:"
+ "TimeStampServer" = "8:"
+ "InstallerBootstrapper" = "3:1"
+ "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
+ {
+ "Enabled" = "11:FALSE"
+ "PromptEnabled" = "11:TRUE"
+ "PrerequisitesLocation" = "2:1"
+ "Url" = "8:"
+ "ComponentsUrl" = "8:"
+ "Items"
+ {
+ }
+ }
+ }
+ "Release"
+ {
+ "DisplayName" = "8:Release"
+ "IsDebugOnly" = "11:FALSE"
+ "IsReleaseOnly" = "11:TRUE"
+ "OutputFilename" = "8:Release\\IvyLib.msm"
+ "PackageFilesAs" = "3:2"
+ "PackageFileSize" = "3:-2147483648"
+ "CabType" = "3:1"
+ "Compression" = "3:2"
+ "SignOutput" = "11:FALSE"
+ "CertificateFile" = "8:"
+ "PrivateKeyFile" = "8:"
+ "TimeStampServer" = "8:"
+ "InstallerBootstrapper" = "3:1"
+ "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
+ {
+ "Enabled" = "11:FALSE"
+ "PromptEnabled" = "11:TRUE"
+ "PrerequisitesLocation" = "2:1"
+ "Url" = "8:"
+ "ComponentsUrl" = "8:"
+ "Items"
+ {
+ }
+ }
+ }
+ }
+ "Deployable"
+ {
+ "CustomAction"
+ {
+ }
+ "DefaultFeature"
+ {
+ "Name" = "8:DefaultFeature"
+ "Title" = "8:"
+ "Description" = "8:"
+ }
+ "File"
+ {
+ "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DE30DB02DD7494AFFBB32B50F67B491E"
+ {
+ "SourcePath" = "8:WSOCK32.dll"
+ "TargetName" = "8:WSOCK32.dll"
+ "Tag" = "8:"
+ "Folder" = "8:_E128D81775304F09A5707F244264031A"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:TRUE"
+ "IsDependency" = "11:TRUE"
+ "IsolateTo" = "8:"
+ }
+ }
+ "FileType"
+ {
+ }
+ "Folder"
+ {
+ "{F4FE1E22-A4D2-4EE8-9259-29A1CE8BB2FF}:_E128D81775304F09A5707F244264031A"
+ {
+ "DefaultLocation" = "8:[TARGETDIR]"
+ "DisplayName" = "8:Module Retargetable Folder"
+ "Description" = "8:"
+ "Name" = "8:Module Retargetable Folder"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:TRUE"
+ "Property" = "8:NEWRETARGETABLEPROPERTY1"
+ "Folders"
+ {
+ }
+ }
+ }
+ "Sequences"
+ {
+ }
+ "MergeModule"
+ {
+ }
+ "Module"
+ {
+ "ModuleSignature" = "8:MergeModule.B704211C29924E868D1D16832CA83D91"
+ "Version" = "8:1.0.0.0"
+ "Title" = "8:IvyLib"
+ "Subject" = "8:"
+ "Author" = "8:DTI/SDER"
+ "Keywords" = "8:Ivy"
+ "Comments" = "8:"
+ "SearchPath" = "8:"
+ "UseSystemSearchPath" = "11:TRUE"
+ "TargetPlatform" = "3:0"
+ "PreBuildEvent" = "8:"
+ "PostBuildEvent" = "8:\"$(ProjectDir)..\\..\\UpdateIvyWeb.bat\" \"$(BuiltOuputPath)\""
+ "RunPostBuildEvent" = "3:0"
+ }
+ "ProjectOutput"
+ {
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_66D910CBB02B47569794CF954A72E057"
+ {
+ "SourcePath" = "8:..\\..\\release\\Ivy.dll"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_E128D81775304F09A5707F244264031A"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:Built"
+ "OutputProjectGuid" = "8:{9BD87B7A-517E-4900-B3EA-A358885CD876}"
+ "ShowKeyOutput" = "11:FALSE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_EF9BC5D6F4274E54867D4FB7F7A33653"
+ {
+ "SourcePath" = "8:..\\..\\release\\pcre.dll"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_E128D81775304F09A5707F244264031A"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:Built"
+ "OutputProjectGuid" = "8:{D79FC143-498E-4342-B2C7-BDAD1B8D0E6B}"
+ "ShowKeyOutput" = "11:FALSE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ }
+ "Registry"
+ {
+ "HKLM"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKCU"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKCR"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKU"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKPU"
+ {
+ "Keys"
+ {
+ }
+ }
+ }
+ "Shortcut"
+ {
+ }
+ }
+}
diff --git a/Ivy/IvyLib/IvyLib.vdproj.vspscc b/Ivy/IvyLib/IvyLib.vdproj.vspscc
new file mode 100644
index 0000000..1cf11d0
--- /dev/null
+++ b/Ivy/IvyLib/IvyLib.vdproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = "relative:Ivy\\IvyLib"
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/Ivy/IvyStdAfx.cpp b/Ivy/IvyStdAfx.cpp
new file mode 100644
index 0000000..2fe8012
--- /dev/null
+++ b/Ivy/IvyStdAfx.cpp
@@ -0,0 +1,27 @@
+// stdafx.cpp : source file that includes just the standard includes
+// libIvy.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "IvyStdAfx.h"
+
+#include <windows.h>
+
+void DebugTrace ( const char *fmt , ... )
+{
+ char buffer[4096];
+#ifdef UNDER_CE
+ TCHAR CEBuffer[4096];
+#endif
+ va_list args;
+
+ va_start( args, fmt );
+ _vsnprintf_s( buffer, sizeof(buffer), sizeof(buffer)-1, fmt, args );
+ va_end( args );
+#ifdef UNDER_CE
+ MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, buffer, -1, CEBuffer, 4096 );
+
+ OutputDebugString( CEBuffer );
+#else
+ OutputDebugString( buffer );
+#endif
+}
diff --git a/Ivy/IvyStdAfx.h b/Ivy/IvyStdAfx.h
new file mode 100644
index 0000000..58a16bb
--- /dev/null
+++ b/Ivy/IvyStdAfx.h
@@ -0,0 +1,91 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#if defined( WIN32 ) || defined( UNDER_CE )
+#pragma warning( disable : 4786 ) // identifier was truncated to '255' characters in the debug information
+#pragma warning( disable : 4275 ) // non dll-interface class 'X' used as base for dll-interface class 'Y'
+#pragma warning( disable : 4251 ) // 'm' : class 'X' needs to have dll-interface to be used by clients of class 'Y'
+
+#endif
+#include <winsock.h>
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+//#include <assert.h>
+#ifdef _WINSOCK2API_
+// Some definition missing from winsock2
+/*
+ * Options for use with [gs]etsockopt at the IP level.
+ */
+#define IP_OPTIONS 1 /* set/get IP per-packet options */
+#define IP_MULTICAST_IF 2 /* set/get IP multicast interface */
+#define IP_MULTICAST_TTL 3 /* set/get IP multicast timetolive */
+#define IP_MULTICAST_LOOP 4 /* set/get IP multicast loopback */
+#define IP_ADD_MEMBERSHIP 5 /* add an IP group membership */
+#define IP_DROP_MEMBERSHIP 6 /* drop an IP group membership */
+#define IP_TTL 7 /* set/get IP Time To Live */
+#define IP_TOS 8 /* set/get IP Type Of Service */
+#define IP_DONTFRAGMENT 9 /* set/get IP Don't Fragment flag */
+/*
+ * Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP.
+ */
+struct ip_mreq {
+ struct in_addr imr_multiaddr; /* IP multicast address of group */
+ struct in_addr imr_interface; /* local IP address of interface */
+};
+#endif
+
+#ifndef IN_CLASSD
+#define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
+#endif
+
+#ifdef IVY_USE_OWN_DATATYPES
+
+#include "DataTypes.h"
+
+#else
+
+#include <string>
+#include <list>
+#include <vector>
+#include <map>
+
+namespace ivy = std;
+
+#endif
+
+
+#ifdef WIN32
+
+#ifndef TRACE
+void DebugTrace ( const char *fmt , ... );
+#define TRACE DebugTrace
+#endif
+
+#if defined(_WIN32_WCE)
+#undef ASSERT
+#endif // _WIN32_WCE
+
+#ifndef ASSERT
+#define ASSERT(expr) \
+ do { \
+ if (! (expr) ) \
+ {\
+ TRACE( "Assert (%s) failed in file %s at line %d\r\n", TEXT(#expr), __FILE__ , __LINE__ ); \
+ DebugBreak(); \
+ }\
+ } while (0)
+#endif
+
+#else
+#include <assert.h>
+#define TRACE printf
+#define ASSERT(expr) assert( expr )
+#endif
+
diff --git a/Ivy/IvySynchroWnd.cxx b/Ivy/IvySynchroWnd.cxx
new file mode 100644
index 0000000..2109a61
--- /dev/null
+++ b/Ivy/IvySynchroWnd.cxx
@@ -0,0 +1,243 @@
+// SynchroWnd.cpp : implementation file
+//
+
+#include "IvyStdAfx.h"
+
+
+#include "IvySynchroWnd.h"
+
+
+#define WM_IVY_CB WM_USER + 1001
+
+
+IvySynchroWnd* IvySynchronousCallback::m_synchro = NULL;
+IvySynchroWnd* IvySynchroWnd::m_synchro = NULL;
+
+/////////////////////////////////////////////////////////////////////////////
+// IvySynchroWnd
+
+IvySynchroWnd::IvySynchroWnd()
+{
+ m_hWnd = NULL;
+ m_synchro = this;
+
+ WNDCLASS wc;
+
+ // Fill in the window class structure with parameters
+ // that describe the main window.
+
+ wc.style = 0; // noredraw if size changes
+ wc.lpfnWndProc = WindowProc; // points to window procedure
+ wc.cbClsExtra = 0; // no extra class memory
+ wc.cbWndExtra = 0; // no extra window memory
+ wc.hInstance = 0; // handle to instance
+ wc.hIcon = NULL; // predefined app. icon
+ wc.hCursor = NULL; // predefined arrow
+ wc.hbrBackground = 0; // white background brush
+ wc.lpszMenuName = NULL; // no menu
+ wc.lpszClassName = TEXT("IvySynchroClass"); // name of window class
+
+ // Register the window class.
+
+ if ( ! RegisterClass(&wc) )
+ {
+ TRACE("Warning: unable to create Ivy Synchro notify window!\n");
+ //AfxThrowResourceException();
+ }
+
+ // Create the syncrho window.
+ m_hWnd = CreateWindowEx(0, TEXT("IvySynchroClass"), TEXT("Ivy Synchro Notification Sink"),
+ WS_OVERLAPPED, 0, 0, 0, 0, NULL , NULL, NULL, NULL);
+ if (!m_hWnd)
+ {
+ TRACE("Warning: unable to create Ivy Synchro notify window!\n");
+ //AfxThrowResourceException();
+ }
+ InitializeCriticalSection( &m_CritSection );
+
+}
+IvySynchroWnd::~IvySynchroWnd()
+{
+}
+
+
+LRESULT CALLBACK IvySynchroWnd::WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+ switch ( uMsg )
+ {
+ case WM_IVY_CB:
+ m_synchro->OnIvyCB( wParam, lParam );
+ break;
+ //
+ // Process other messages.
+ //
+
+ default:
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+ }
+ return 0;
+}
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// IvySynchroWnd message handlers
+
+
+LRESULT IvySynchroWnd::OnIvyCB(WPARAM wParam, LPARAM lParam)
+{
+ IvySynchronousCallbackList::iterator iter;
+ EnterCriticalSection( &m_CritSection );
+
+ for ( iter = callbacklist.begin(); iter != callbacklist.end(); )
+ {
+ IvySynchronousCallback *param = *iter++;
+ param->CallCallback();
+ delete param;
+ }
+ callbacklist.clear();
+ LeaveCriticalSection( &m_CritSection );
+ return 0L;
+}
+void IvySynchroWnd::PostIvyCB( IvySynchronousCallback *cb )
+{
+ EnterCriticalSection( &m_CritSection );
+ if ( m_synchro->callbacklist.empty() )
+ ASSERT(PostMessage(m_synchro->m_hWnd, WM_IVY_CB, 0, 0 ));
+ m_synchro->callbacklist.push_back( cb );
+ LeaveCriticalSection( &m_CritSection );
+}
+//
+//
+IvySynchronousMessageCallback::IvySynchronousMessageCallback( IvyMessageCallback *cb )
+{
+ target = cb;
+ app = 0;
+ argc = 0;
+ argv = 0;
+}
+IvySynchronousMessageCallback::~IvySynchronousMessageCallback()
+{
+ //delete target;
+ for( int i = 0; i < argc ; i++ )
+ {
+ delete argv[i];
+ }
+ if ( argv ) delete argv;
+}
+void IvySynchronousMessageCallback::OnMessage(IvyApplication *app, int argc, const char **argv )
+{
+ static int msg_count = 0;
+ // duplicate on the Message Queue
+ IvySynchronousMessageCallback *param = new IvySynchronousMessageCallback(target);
+ param->app = app;
+ param->argc = argc;
+ param->argv = new char*[argc];
+ for( int i = 0; i < argc ; i++ )
+ {
+#ifdef UNDER_CE
+ param->argv[i] = _strdup( argv[i]);
+#else
+ param->argv[i] = _strdup( argv[i]);
+#endif
+ }
+// TRACE( "IvySynchronousMessageCallback::OnMessage msg count %d\n",wParam);
+ m_synchro->PostIvyCB( param );
+
+}
+void IvySynchronousMessageCallback::CallCallback()
+{
+ target->OnMessage( app, argc, (const char **) argv );
+ for( int i = 0; i < argc ; i++ )
+ delete argv[i];
+ delete argv;
+}
+
+
+IvySynchronousApplicationCallback::IvySynchronousApplicationCallback( IvyApplicationCallback *cb )
+{
+ target = cb;
+}
+void IvySynchronousApplicationCallback::OnApplicationConnected( IvyApplication *app)
+{
+ // duplicate on the Message Queue
+ IvySynchronousApplicationCallback *param = new IvySynchronousApplicationCallback(target);
+ param->type = CONNECTED_CB;
+ param->app = app;
+ m_synchro->PostIvyCB( param );
+}
+
+void IvySynchronousApplicationCallback::OnApplicationDisconnected( IvyApplication *app)
+{
+ // duplicate on the Message Queue
+ IvySynchronousApplicationCallback *param = new IvySynchronousApplicationCallback(target);
+ param->type = DISCONNECTED_CB;
+ param->app = app;
+ m_synchro->PostIvyCB( param );
+}
+void IvySynchronousApplicationCallback::CallCallback()
+{
+ switch ( type )
+ {
+ case CONNECTED_CB:
+ target->OnApplicationConnected( app );
+ break;
+ case DISCONNECTED_CB:
+ target->OnApplicationDisconnected( app );
+ break;
+ }
+}
+
+
+IvySynchronousBindingCallback::IvySynchronousBindingCallback( IvyBindingCallback *cb )
+{
+ target = cb;
+}
+void IvySynchronousBindingCallback::OnAddBind( IvyApplication *app, int id, const char *regexp)
+{
+ // duplicate on the Message Queue
+ IvySynchronousBindingCallback *param = new IvySynchronousBindingCallback(target);
+ param->type = ADD_CB;
+ param->app = app;
+ param->id = id;
+ param->regexp = _strdup(regexp);
+ m_synchro->PostIvyCB( param );
+}
+
+void IvySynchronousBindingCallback::OnRemoveBind( IvyApplication *app, int id, const char *regexp)
+{
+ // duplicate on the Message Queue
+ IvySynchronousBindingCallback *param = new IvySynchronousBindingCallback(target);
+ param->type = REMOVE_CB;
+ param->app = app;
+ param->id = id;
+ param->regexp = _strdup(regexp);
+ m_synchro->PostIvyCB( param );
+}
+void IvySynchronousBindingCallback::OnFilterBind( IvyApplication *app, int id, const char *regexp)
+{
+ // duplicate on the Message Queue
+ IvySynchronousBindingCallback *param = new IvySynchronousBindingCallback(target);
+ param->type = FILTER_CB;
+ param->app = app;
+ param->id = id;
+ param->regexp = _strdup(regexp);
+ m_synchro->PostIvyCB( param );
+}
+void IvySynchronousBindingCallback::CallCallback()
+{
+ switch ( type )
+ {
+ case ADD_CB:
+ target->OnAddBind( app, id, regexp );
+ break;
+ case REMOVE_CB:
+ target->OnRemoveBind( app, id, regexp );
+ break;
+ case FILTER_CB:
+ target->OnFilterBind( app, id, regexp );
+ break;
+ }
+ delete regexp;
+} \ No newline at end of file
diff --git a/Ivy/IvySynchroWnd.h b/Ivy/IvySynchroWnd.h
new file mode 100644
index 0000000..ffa44ba
--- /dev/null
+++ b/Ivy/IvySynchroWnd.h
@@ -0,0 +1,109 @@
+//
+// SynchroWnd.h : header file
+//
+#pragma once
+/////////////////////////////////////////////////////////////////////////////
+// IvySynchroWnd window
+
+#include "IvyApplication.h"
+
+class IvySynchronousCallback;
+
+class IvySynchroWnd
+{
+// Construction
+public:
+ IvySynchroWnd();
+
+// Attributes
+public:
+
+
+// Operations
+public:
+ void PostIvyCB( IvySynchronousCallback *cb );
+
+// Implementation
+public:
+ virtual ~IvySynchroWnd();
+protected:
+ HWND m_hWnd;
+
+protected:
+ // Unique instance of this class
+ static IvySynchroWnd *m_synchro;
+ // Generated message map functions
+ static LRESULT CALLBACK WindowProc(
+ HWND hwnd, // handle to window
+ UINT uMsg, // message identifier
+ WPARAM wParam, // first message parameter
+ LPARAM lParam // second message parameter
+ );
+ // Buffer Emission
+ CRITICAL_SECTION m_CritSection;
+ typedef ivy::list<IvySynchronousCallback*> IvySynchronousCallbackList;
+ IvySynchronousCallbackList callbacklist;
+
+protected:
+
+ LRESULT OnIvyCB(WPARAM wParam, LPARAM lParam);
+ friend class IvySynchronousMessageCallback;
+ friend class IvySynchronousApplicationCallback;
+
+};
+class IvySynchronousCallback
+{
+protected:
+ IvyApplication *app;
+ static IvySynchroWnd *m_synchro;
+ friend class Ivy;
+public:
+ virtual void CallCallback() = 0;
+
+};
+class IvySynchronousMessageCallback: public IvySynchronousCallback, public IvyMessageCallback
+{
+public:
+ IvySynchronousMessageCallback( IvyMessageCallback *cb );
+ virtual ~IvySynchronousMessageCallback();
+ virtual void CallCallback();
+ virtual void OnMessage (IvyApplication *app, int argc, const char **argv );
+
+protected:
+ IvyMessageCallback *target;
+ int argc;
+ char **argv;
+
+ friend class IvySynchroWnd;
+};
+class IvySynchronousApplicationCallback: public IvySynchronousCallback, public IvyApplicationCallback
+{
+public:
+ IvySynchronousApplicationCallback( IvyApplicationCallback *cb );
+ virtual void CallCallback();
+ virtual void OnApplicationConnected (IvyApplication *app);
+ virtual void OnApplicationDisconnected (IvyApplication *app);
+protected:
+ IvyApplicationCallback *target;
+ typedef enum { CONNECTED_CB, DISCONNECTED_CB } CallbackType;
+ CallbackType type;
+
+ friend class IvySynchroWnd;
+};
+class IvySynchronousBindingCallback: public IvySynchronousCallback, public IvyBindingCallback
+{
+public:
+ IvySynchronousBindingCallback( IvyBindingCallback *cb );
+ virtual void CallCallback();
+ virtual void OnAddBind (IvyApplication *app, int id, const char *regexp);
+ virtual void OnRemoveBind (IvyApplication *app, int id, const char *regexp);
+ virtual void OnFilterBind (IvyApplication *app, int id, const char *regexp);
+protected:
+ IvyBindingCallback *target;
+ typedef enum { ADD_CB, REMOVE_CB, FILTER_CB } CallbackType;
+ CallbackType type;
+ int id;
+ const char *regexp;
+
+ friend class IvySynchroWnd;
+};
diff --git a/Ivy/IvyWatcher.cxx b/Ivy/IvyWatcher.cxx
new file mode 100644
index 0000000..4cbf604
--- /dev/null
+++ b/Ivy/IvyWatcher.cxx
@@ -0,0 +1,124 @@
+// IvyWatcher.cpp : implementation file
+//
+
+#include "IvyStdAfx.h"
+
+
+#include "IvyWatcher.h"
+#include "IvyApplication.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// IvyWatcher
+
+
+#define VERSION 3
+
+IvyWatcher::IvyWatcher(Ivy * bus)
+{
+ this->bus = bus;
+}
+IvyWatcher::~IvyWatcher()
+{
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// IvyWatcher member functions
+
+void IvyWatcher::OnReceive(int nErrorCode)
+{
+ size_t err;
+ int version;
+ char buffer[2048];
+ ivy::string remotehost;
+ UINT remoteport;
+ UINT serviceport;
+ char appid[2048];
+ char appname[2048];
+
+ memset( appid, 0, sizeof( appid ) );
+ memset( appname, 0, sizeof( appname ) );
+
+ err = ReceiveFrom( buffer, sizeof(buffer), remotehost, remoteport );
+ if ( err == SOCKET_ERROR )
+ {
+ TRACE("Receive Broadcast error %d\n",this->GetLastError());
+ return;
+ }
+ if ( err < 255 ) buffer[err] ='\0';
+ err = sscanf_s(buffer,"%d %u %s %[^\n]",&version, &serviceport,appid, sizeof(appid), appname,sizeof(appname));
+ if ( err < 2 )
+ {
+ /* ignore the message */
+ TRACE(" Bad Supervision message expected 'version port'\n");
+ return;
+ }
+ if ( version != VERSION )
+ {
+ /* ignore the message */
+ TRACE(" Bad Ivy verion number expected %d receive %d from %s:%d\n", VERSION,version, remotehost.c_str(), remoteport);
+ return;
+ }
+ /* check if we received our own message. SHOULD ALSO TEST THE HOST */
+ if ( strcmp( appid , bus->ApplicationID.c_str()) ==0 ) return;
+
+ /* check if we receive our own message should test also the host */
+ if ( serviceport == bus->GetApplicationPort() /*&& remotehost == "localhost"*/) return;
+ TRACE(" Broadcast de %s:%u port %u\n", remotehost.c_str(), remoteport, serviceport );
+
+ /* connect to the service and send the regexp */
+ IvyApplication *newapp = new IvyApplication(bus);
+ // exception to catch
+ newapp->Create(remotehost.c_str(), serviceport, appname );
+ // delete newapp;
+ // return;
+
+ bus->AddApplication( newapp );
+ TRACE(" Connecting to %s:%u\n", remotehost.c_str(), serviceport );
+
+}
+
+void IvyWatcher::start(const char *domainlist)
+{
+ BOOL reuse = TRUE;
+ ivy::string domain;
+ UINT port=0;
+ // determine domain to use
+ domain = bus->GetDomain( domainlist );
+
+ // first find our UDP port
+ size_t sep_index = domain.rfind( ':' );
+ if ( sep_index != -1 )
+ {
+ port = atoi ( domain.substr( sep_index +1 ).c_str() );
+ // supress port number from end of domain list
+ domain.erase( sep_index, domain.length() - sep_index );
+ }
+ // create UDP receiver
+ // catch exception !!!
+ Socket(SOCK_DGRAM);
+ SetSockOpt( SO_REUSEADDR, &reuse, sizeof(BOOL) );
+ Bind(port);
+ StartListener();
+
+ ivy::string addr;
+ char hello[2048];
+ int len = _snprintf_s( hello, sizeof(hello), sizeof(hello)-1, "%d %u %s %s\n", VERSION, bus->GetApplicationPort(), bus->ApplicationID.c_str(), bus->ApplicationName.c_str() );
+
+ // send broadcast to domain list
+ while ( !domain.empty() )
+ {
+ // find addr up to separator
+ size_t index = domain.find_first_of( ", \t" );
+ addr = domain.substr( 0, index );
+ domain.erase( 0, addr.length() +1 );
+ TRACE("Ivy Broadcasting on %s:%d\n", addr.c_str(), port );
+ AddMember( addr.c_str() );
+ SendTo( hello, len, port, addr.c_str() );
+ }
+}
+void IvyWatcher::stop()
+{
+ Close();
+}
diff --git a/Ivy/IvyWatcher.h b/Ivy/IvyWatcher.h
new file mode 100644
index 0000000..1eb0718
--- /dev/null
+++ b/Ivy/IvyWatcher.h
@@ -0,0 +1,34 @@
+
+#pragma once
+
+// IvyWatcher.h : header file
+//
+
+
+#include "ThreadedSocket.h"
+#include "Ivy.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// IvyWatcher command target
+
+class IvyWatcher : public CThreadedSocket
+{
+// Attributes
+public:
+
+// Operations
+public:
+ IvyWatcher(Ivy *bus);
+ virtual ~IvyWatcher();
+// Overrides
+public:
+ void start(const char *domain);
+ void stop();
+ virtual void OnReceive(int nErrorCode);
+
+// Implementation
+protected:
+ Ivy * bus;
+
+};
+
diff --git a/Ivy/Regexp.cxx b/Ivy/Regexp.cxx
new file mode 100644
index 0000000..4dc1823
--- /dev/null
+++ b/Ivy/Regexp.cxx
@@ -0,0 +1,1758 @@
+// Win32 porting notes.
+
+#if defined( _MBCS )
+#pragma message( __FILE__ "This code is broken under _MBCS, " \
+ "see the comments at the top of this file." )
+#endif //_MBCS
+//
+//
+// In case this isn't obvious from the later comments this is an ALTERED
+// version of the software. If you like my changes then cool, but nearly
+// all of the functionality here is derived from Henry Spencer's original
+// work.
+//
+// This code should work correctly under both _SBCS and _UNICODE, I did
+// start working on making it work with _MBCS but gave up after a while
+// since I don't need this particular port and it's not going to be as
+// straight forward as the other two.
+//
+// The problem stems from the compiled program being stored as TCHARS,
+// the individual items need to be wide enough to hold whatever character
+// is thrown at them, but currently they are accessed as an array of
+// whatever size integral type is appropriate. _MBCS would cause this
+// to be char, but at times it would need to be larger. This would
+// require making the program be an array of short with the appropriate
+// conversions used everywhere. Certainly it's doable, but it's a pain.
+// What's worse is that the current code will compile and run under _MBCS,
+// only breaking when it gets wide characters thrown against it.
+//
+// I've marked at least one bit of code with #pragma messages, I may not
+// get all of them, but they should be a start
+//
+// Guy Gascoigne - Piggford (ggp@bigfoot.com) Friday, February 27, 1998
+
+
+// regcomp and regexec -- regsub and regerror are elsewhere
+// @(#)regexp.c 1.3 of 18 April 87
+//
+// Copyright (c) 1986 by University of Toronto.
+// Written by Henry Spencer. Not derived from licensed software.
+//
+// Permission is granted to anyone to use this software for any
+// purpose on any computer system, and to redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The author is not responsible for the consequences of use of
+// this software, no matter how awful, even if they arise
+// from defects in it.
+//
+// 2. The origin of this software must not be misrepresented, either
+// by explicit claim or by omission.
+//
+// 3. Altered versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+// *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
+// *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching
+// *** as in BSD grep and ex.
+// *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
+// *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \.
+// *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods,
+// *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy.
+// *** THIS IS AN ALTERED VERSION. It was altered by Geoffrey Noer,
+// *** THIS IS AN ALTERED VERSION. It was altered by Guy Gascoigne - Piggford
+// *** guy@wyrdrune.com, on 15 March 1998, porting it to C++ and converting
+// *** it to be the engine for the Regexp class
+//
+// Beware that some of this code is subtly aware of the way operator
+// precedence is structured in regular expressions. Serious changes in
+// regular-expression syntax might require a total rethink.
+
+#include "IvyStdAfx.h"
+#include "regexp.h"
+
+// The first byte of the regexp internal "program" is actually this magic
+// number; the start node begins in the second byte.
+
+const char MAGIC = '\234';
+
+#pragma warning( disable : 4711 ) // automatic inline selected
+
+// The "internal use only" fields in regexp.h are present to pass info from
+// compile to execute that permits the execute phase to run lots faster on
+// simple cases. They are:
+//
+// regstart char that must begin a match; '\0' if none obvious
+// reganch is the match anchored (at beginning-of-line only)?
+// regmust string (pointer into program) that match must include, or NULL
+// regmlen length of regmust string
+//
+// Regstart and reganch permit very fast decisions on suitable starting
+// points for a match, cutting down the work a lot. Regmust permits fast
+// rejection of lines that cannot possibly match. The regmust tests are
+// costly enough that regcomp() supplies a regmust only if the
+// r.e. contains something potentially expensive (at present, the only
+// such thing detected is * or + at the start of the r.e., which can
+// involve a lot of backup). Regmlen is supplied because the test in
+// regexec() needs it and regcomp() is computing it anyway.
+
+// Structure for regexp "program". This is essentially a linear encoding
+// of a nondeterministic finite-state machine (aka syntax charts or
+// "railroad normal form" in parsing technology). Each node is an opcode
+// plus a "next" pointer, possibly plus an operand. "Next" pointers of
+// all nodes except BRANCH implement concatenation; a "next" pointer with
+// a BRANCH on both ends of it is connecting two alternatives. (Here we
+// have one of the subtle syntax dependencies: an individual BRANCH (as
+// opposed to a collection of them) is never concatenated with anything
+// because of operator precedence.) The operand of some types of node is
+// a literal string; for others, it is a node leading into a sub-FSM. In
+// particular, the operand of a BRANCH node is the first node of the
+// branch. (NB this is *not* a tree structure: the tail of the branch
+// connects to the thing following the set of BRANCHes.) The opcodes
+// are:
+
+enum {
+// definition number opnd? meaning
+ END = 0, // no End of program.
+ BOL = 1, // no Match beginning of line.
+ EOL = 2, // no Match end of line.
+ ANY = 3, // no Match any character.
+ ANYOF = 4, // str Match any of these.
+ ANYBUT = 5, // str Match any but one of these.
+ BRANCH = 6, // node Match this, or the next..\&.
+ BACK = 7, // no "next" ptr points backward.
+ EXACTLY = 8, // str Match this string.
+ NOTHING = 9, // no Match empty string.
+ STAR = 10, // node Match this 0 or more times.
+ PLUS = 11, // node Match this 1 or more times.
+ WORDA = 12, // no Match "" at wordchar, where prev is nonword
+ WORDZ = 13, // no Match "" at nonwordchar, where prev is word
+ OPEN = 20, // no Sub-RE starts here.
+ // OPEN+1 is number 1, etc.
+ CLOSE = 40 // no Analogous to OPEN.
+};
+
+// Opcode notes:
+//
+// BRANCH The set of branches constituting a single choice are hooked
+// together with their "next" pointers, since precedence prevents
+// anything being concatenated to any individual branch. The
+// "next" pointer of the last BRANCH in a choice points to the
+// thing following the whole choice. This is also where the
+// final "next" pointer of each individual branch points; each
+// branch starts with the operand node of a BRANCH node.
+//
+// BACK Normal "next" pointers all implicitly point forward; BACK
+// exists to make loop structures possible.
+//
+// STAR,PLUS '?', and complex '*' and '+', are implemented as circular
+// BRANCH structures using BACK. Simple cases (one character
+// per match) are implemented with STAR and PLUS for speed
+// and to minimize recursive plunges.
+//
+// OPEN,CLOSE ...are numbered at compile time.
+
+// A node is one char of opcode followed by two chars of "next" pointer.
+// "Next" pointers are stored as two 8-bit pieces, high order first. The
+// value is a positive offset from the opcode of the node containing it.
+// An operand, if any, simply follows the node. (Note that much of the
+// code generation knows about this implicit relationship.)
+//
+// Using two bytes for the "next" pointer is vast overkill for most things,
+// but allows patterns to get big without disasters.
+
+
+enum
+{
+ REGERR_SENTINEL_VALUE = 0,
+ REGERR_NULLARG = 1, REGERR_CORRUPTED, REGERR_CORRUPTION, REGERR_CORRUPTED_POINTERS,
+ REGERR_BAD_REGREPEAT, REGERR_CORRUPTED_OPCODE, REGERR_NULL_TO_REGSUB,
+ REGERR_DAMAGED_REGEXP_REGSUB, REGERR_DAMAGED_MATCH_STRING, REGERR_NULL_TO_REGCOMP,
+ REGERR_TO_BIG, REGERR_TO_MANY_PAREN, REGERR_UNTERMINATED_PAREN, REGERR_UNMATCHED_PAREN,
+ REGERR_INTERNAL_ERROR_JUNK, REGERR_OP_COULD_BE_EMPTY, REGERR_NESTED_OP, REGERR_INVALID_RANGE,
+ REGERR_UNMATCHED_BRACE, REGERR_INTERNAL_UNEXPECTED_CHAR, REGERR_OP_FOLLOWS_NOTHING,
+ REGERR_TRAILING_ESC, REGERR_INTERNAL_STRSCSPN, REGERR_NO_REGEXP
+};
+
+struct regErr
+{
+ int m_id;
+ const char * m_err;
+} errors[] = {
+ { REGERR_NULLARG, "NULL argument to regexec" },
+ { REGERR_CORRUPTED, "corrupted regexp" },
+ { REGERR_CORRUPTION, "regexp corruption" },
+ { REGERR_CORRUPTED_POINTERS, "corrupted pointers" },
+ { REGERR_BAD_REGREPEAT, "internal error: bad call of regrepeat" },
+ { REGERR_CORRUPTED_OPCODE, "corrupted opcode" },
+ { REGERR_NULL_TO_REGSUB, "NULL parm to regsub" },
+ { REGERR_DAMAGED_REGEXP_REGSUB, "damaged regexp fed to regsub" },
+ { REGERR_DAMAGED_MATCH_STRING, "damaged match string" },
+ { REGERR_NULL_TO_REGCOMP, "NULL argument to regcomp" },
+ { REGERR_TO_BIG, "regexp too big" },
+ { REGERR_TO_MANY_PAREN, "too many ()" },
+ { REGERR_UNTERMINATED_PAREN, "unterminated ()" },
+ { REGERR_UNMATCHED_PAREN, "unmatched ()" },
+ { REGERR_INTERNAL_ERROR_JUNK, "internal error: junk on end" },
+ { REGERR_OP_COULD_BE_EMPTY, "*+ operand could be empty" },
+ { REGERR_NESTED_OP, "nested *?+" },
+ { REGERR_INVALID_RANGE, "invalid [] range" },
+ { REGERR_UNMATCHED_BRACE, "unmatched []" },
+ { REGERR_INTERNAL_UNEXPECTED_CHAR, "internal error: \\0|) unexpected" },
+ { REGERR_OP_FOLLOWS_NOTHING, "?+* follows nothing" },
+ { REGERR_TRAILING_ESC, "trailing \\" },
+ { REGERR_INTERNAL_STRSCSPN, "internal error: strcspn 0" },
+ { REGERR_NO_REGEXP, "NULL regexp" },
+ { REGERR_SENTINEL_VALUE, "Unknown error" } // must be last value
+};
+
+// Flags to be passed up and down.
+
+enum {
+ HASWIDTH = 01, // Known never to match null string.
+ SIMPLE = 02, // Simple enough to be STAR/PLUS operand.
+ SPSTART = 04, // Starts with * or +.
+ WORST = 0 // Worst case.
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class CRegErrorHandler
+{
+ friend Regexp;
+ mutable ivy::string m_szError;
+ static const char * FindErr( int id );
+protected:
+ void ClearErrorString() const;
+ void regerror( const char * s ) const;
+ void regerror( int id ) const;
+public:
+ CRegErrorHandler() { }
+ CRegErrorHandler( const CRegErrorHandler & reh ) : m_szError( reh.m_szError ) {}
+
+ const ivy::string & GetErrorString() const;
+};
+
+void CRegErrorHandler::regerror( const char * s ) const
+{
+ TRACE( "regerror: %s\n", s );
+ m_szError = s;
+}
+
+void CRegErrorHandler::regerror( int id ) const
+{
+ regerror( FindErr( id ) );
+}
+
+const ivy::string & CRegErrorHandler::GetErrorString() const
+{
+ return m_szError;
+}
+
+void CRegErrorHandler::ClearErrorString() const
+{
+ m_szError.erase() ;
+}
+
+const char * CRegErrorHandler::FindErr( int id )
+{
+ struct regErr * perr;
+ for ( perr = errors; perr->m_id != REGERR_SENTINEL_VALUE; perr++ )
+ if ( perr->m_id == id )
+ return perr->m_err;
+
+ return perr->m_err; // since we've fallen off the array, perr->m_id == 0
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// All of the functions required to directly access the 'program'
+class CRegProgramAccessor : public CRegErrorHandler
+{
+public:
+ static inline char OP( char * p )
+ {
+ return (*(p));
+ }
+ static inline char * OPERAND( char * p )
+ {
+ return p + 3;
+ }
+ static inline char * regnext( char * p )
+ {
+ const short offset = *((short*)(p+1));
+
+ if (offset == 0)
+ return(NULL);
+
+ return((OP(p) == BACK) ? p-offset : p+offset);
+ }
+#ifdef _RE_DEBUG
+ char * CRegProgramAccessor::regprop( char * op );
+#endif
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+// The internal interface to the regexp, wrapping the compilation as well as the
+// execution of the regexp (matching)
+
+class regexp : public CRegProgramAccessor
+{
+ friend class CRegExecutor;
+ friend class Regexp;
+
+ int m_programSize;
+ char * startp[Regexp::NSUBEXP];
+ char * endp[Regexp::NSUBEXP];
+ char regstart; // Internal use only.
+ char reganch; // Internal use only.
+ char * regmust; // Internal use only.
+ int regmlen; // Internal use only.
+ char * program;
+
+ bool status;
+ int count; // used by Regexp to manage the reference counting of regexps
+ int numSubs;
+public:
+
+ regexp( const char * exp, bool iCase );
+ regexp( const regexp & r );
+ ~regexp();
+
+ void ignoreCase( const char * in, char * out );
+
+ bool regcomp( const char * exp );
+ bool regexec( const char * string );
+ bool Status() const { return status; }
+
+ ivy::string GetReplaceString( const char* sReplaceExp ) const;
+
+ regexp * getCopy();
+
+#ifdef _RE_DEBUG
+ void regdump();
+#endif
+
+#ifdef _DEBUG
+ ivy::string m_originalPattern;
+ ivy::string m_modifiedPattern;
+#endif
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Compile / Validate the regular expression - ADT
+
+class CRegCompilerBase : public CRegProgramAccessor
+{
+public:
+ CRegCompilerBase( const char * parse );
+
+ char * reg(int paren, int *flagp);
+protected:
+ char * regparse; // Input-scan pointer.
+ int regnpar; // () count.
+
+ char * regbranch(int *flagp);
+ char * regpiece(int *flagp);
+ char * regatom(int *flagp);
+ inline bool ISREPN( char c ) { return ((c) == '*' || (c) == '+' || (c) == '?'); }
+
+ virtual void regc(int c) = 0;
+ virtual char * regnode(int op) = 0;
+ virtual void reginsert(char op, char * opnd) = 0;
+ virtual void regtail(char * p, char * val) = 0;
+ virtual void regoptail(char * p, char * val) = 0;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// First pass over the expression, testing for validity and returning the
+// program size
+
+class CRegValidator : public CRegCompilerBase
+{
+public:
+ CRegValidator( const char * parse );
+
+ inline long Size() const { return regsize; }
+private:
+ long regsize; // Code size.
+ char regdummy[3]; // NOTHING, 0 next ptr
+protected:
+ char * regnode(int) { regsize += 3; return regdummy; }
+ void regc(int) { regsize++; }
+ void reginsert(char, char *) { regsize += 3; }
+ void regtail(char *, char *) { return; }
+ void regoptail(char *, char *) { return; }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Second pass, actually generating the program
+
+class CRegCompiler : public CRegCompilerBase
+{
+public:
+ CRegCompiler( const char * parse, char * prog );
+private:
+ char * regcode;
+protected:
+ // regc - emit (if appropriate) a byte of code
+ void regc(int b)
+ {
+ *regcode++ = (char)b;
+ }
+ char * regnode(int op);
+ void reginsert(char op, char * opnd);
+ void regtail(char * p, char * val);
+ void regoptail(char * p, char * val);
+};
+
+// regnode - emit a node
+char * CRegCompiler::regnode(int op)
+{
+ char * const ret = regcode;
+
+ char * ptr = ret;
+ *ptr++ = (char)op;
+ *ptr++ = '\0'; // Null next pointer.
+ *ptr++ = '\0';
+ regcode = ptr;
+
+ return(ret);
+}
+
+// reginsert - insert an operator in front of already-emitted operand
+//
+// Means relocating the operand.
+void CRegCompiler::reginsert(char op, char * opnd)
+{
+ char * place;
+
+ (void) memmove(opnd+3, opnd, (size_t)((regcode - opnd)*sizeof(char)));
+ regcode += 3;
+
+ place = opnd; // Op node, where operand used to be.
+ *place++ = op;
+ *place++ = '\0';
+ *place++ = '\0';
+}
+
+// regtail - set the next-pointer at the end of a node chain
+void CRegCompiler::regtail(char * p, char * val)
+{
+ char * scan;
+ char * temp;
+
+ // Find last node.
+ for (scan = p; (temp = regnext(scan)) != NULL; scan = temp)
+ continue;
+
+ *((short *)(scan+1)) = (short)((OP(scan) == BACK) ? scan - val : val - scan);
+}
+
+// regoptail - regtail on operand of first argument; nop if operandless
+void CRegCompiler::regoptail(char * p, char * val)
+{
+ // "Operandless" and "op != BRANCH" are synonymous in practice.
+ if (OP(p) == BRANCH)
+ regtail(OPERAND(p), val);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+CRegCompilerBase::CRegCompilerBase( const char * parse )
+ : regparse( (char *)parse ),
+ regnpar(1)
+{
+}
+
+CRegValidator::CRegValidator( const char * parse )
+ : CRegCompilerBase( parse ),
+ regsize(0)
+{
+ regc(MAGIC);
+ regdummy[0] = NOTHING;
+ regdummy[1] = regdummy[2] = 0;
+}
+
+CRegCompiler::CRegCompiler( const char * parse, char * prog )
+ : CRegCompilerBase( parse ),
+ regcode(prog)
+{
+ regc(MAGIC);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+regexp::regexp( const char * exp, bool iCase )
+ : regstart(0),
+ reganch(0),
+ regmust(0),
+ regmlen(0),
+ program(0),
+ m_programSize(0)
+{
+#if _DEBUG
+ m_originalPattern = exp; // keep a version of the pattern for debugging
+#endif
+
+ if ( iCase )
+ {
+ char * out = new char[(strlen( exp ) * 4) + 1];
+ ignoreCase( exp, out );
+
+#if _DEBUG
+ m_modifiedPattern = out; // and the modified version if there is one
+#endif
+ status = regcomp( out );
+ delete [] out;
+ }
+ else
+ status = regcomp( exp );
+
+ count = numSubs = 0;
+}
+
+regexp::regexp( const regexp & orig )
+ : regstart(orig.regstart),
+ reganch(orig.reganch),
+ regmlen(orig.regmlen),
+ m_programSize(orig.m_programSize),
+ numSubs(orig.numSubs),
+ regmust(0)
+{
+#if _DEBUG
+ m_originalPattern = orig.m_originalPattern;
+ m_modifiedPattern = orig.m_modifiedPattern;
+#endif
+ status = orig.status;
+ count = 0;
+ program = new char[m_programSize];
+ memcpy( program, orig.program, m_programSize * sizeof( char ) );
+ if ( orig.regmust )
+ regmust = program + ( orig.regmust - orig.program );
+
+ for ( int i = Regexp::NSUBEXP - 1; i >= 0; i--)
+ {
+ startp[i] = orig.startp[i];
+ endp[i] = orig.endp[i];
+ }
+}
+
+regexp::~regexp()
+{
+ delete [] program;
+}
+
+
+// regcomp - compile a regular expression into internal code
+//
+// We can't allocate space until we know how big the compiled form will
+// be, but we can't compile it (and thus know how big it is) until we've
+// got a place to put the code. So we cheat: we compile it twice, once
+// with code generation turned off and size counting turned on, and once
+// "for real". This also means that we don't allocate space until we are
+// sure that the thing really will compile successfully, and we never
+// have to move the code and thus invalidate pointers into it. (Note
+// that it has to be in one piece because free() must be able to free it
+// all.)
+//
+// Beware that the optimization-preparation code in here knows about some
+// of the structure of the compiled regexp.
+
+bool regexp::regcomp(const char * exp)
+{
+ char * scan;
+ int flags;
+
+ if (exp == NULL)
+ {
+ regerror( REGERR_NULL_TO_REGCOMP );
+ return NULL;
+ }
+
+ // First pass: determine size, legality.
+ CRegValidator tester( exp );
+
+ if (tester.reg(0, &flags) == NULL)
+ return false;
+
+ // Small enough for pointer-storage convention?
+ if (tester.Size() >= 0x7fffL) // Probably could be 0xffffL.
+ {
+ regerror(REGERR_TO_BIG);
+ return NULL;
+ }
+
+ m_programSize = tester.Size();
+ // Allocate space.
+ program = new char[m_programSize];
+
+ CRegCompiler comp( exp, program );
+ // Second pass: emit code.
+ if (comp.reg(0, &flags) == NULL)
+ return false;
+
+ scan = program + 1; // First BRANCH.
+ if (OP(regnext(scan)) == END)
+ { // Only one top-level choice.
+ scan = OPERAND(scan);
+
+ // Starting-point info.
+ if (OP(scan) == EXACTLY)
+ regstart = *OPERAND(scan);
+ else if (OP(scan) == BOL)
+ reganch = 1;
+
+ // If there's something expensive in the r.e., find the
+ // longest literal string that must appear and make it the
+ // regmust. Resolve ties in favor of later strings, since
+ // the regstart check works with the beginning of the r.e.
+ // and avoiding duplication strengthens checking. Not a
+ // strong reason, but sufficient in the absence of others.
+
+ if (flags&SPSTART)
+ {
+ char * longest = NULL;
+ size_t len = 0;
+
+ for (; scan != NULL; scan = regnext(scan))
+ if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len)
+ {
+ longest = OPERAND(scan);
+ len = strlen(OPERAND(scan));
+ }
+ regmust = longest;
+ regmlen = (int)len;
+ }
+ }
+
+ return true;
+}
+
+regexp * regexp::getCopy()
+{
+ return new regexp( *this );
+}
+
+// reg - regular expression, i.e. main body or parenthesized thing
+//
+// Caller must absorb opening parenthesis.
+//
+// Combining parenthesis handling with the base level of regular expression
+// is a trifle forced, but the need to tie the tails of the branches to what
+// follows makes it hard to avoid.
+
+char * CRegCompilerBase::reg( int paren, int *flagp )
+{
+ char * ret = NULL;
+ char * br;
+ char * ender;
+ int parno = 0;
+ int flags;
+
+ *flagp = HASWIDTH; // Tentatively.
+
+ if (paren)
+ {
+ // Make an OPEN node.
+ if (regnpar >= Regexp::NSUBEXP)
+ {
+ regerror(REGERR_TO_MANY_PAREN);
+ return NULL;
+ }
+ parno = regnpar;
+ regnpar++;
+ ret = regnode(OPEN+parno);
+ }
+
+ // Pick up the branches, linking them together.
+ br = regbranch(&flags);
+ if (br == NULL)
+ return(NULL);
+ if (paren)
+ regtail(ret, br); // OPEN -> first.
+ else
+ ret = br;
+ *flagp &= ~(~flags&HASWIDTH); // Clear bit if bit 0.
+ *flagp |= flags&SPSTART;
+ while (*regparse == '|')
+ {
+ regparse++;
+ br = regbranch(&flags);
+ if (br == NULL)
+ return(NULL);
+ regtail(ret, br); // BRANCH -> BRANCH.
+ *flagp &= ~(~flags&HASWIDTH);
+ *flagp |= flags&SPSTART;
+ }
+
+ // Make a closing node, and hook it on the end.
+ ender = regnode((paren) ? CLOSE+parno : END);
+ regtail(ret, ender);
+
+ // Hook the tails of the branches to the closing node.
+ for (br = ret; br != NULL; br = regnext(br))
+ regoptail(br, ender);
+
+ // Check for proper termination.
+ if (paren && *regparse++ != ')')
+ {
+ regerror( REGERR_UNTERMINATED_PAREN );
+ return NULL;
+ }
+ else if (!paren && *regparse != '\0')
+ {
+ if (*regparse == ')')
+ {
+ regerror( REGERR_UNMATCHED_PAREN );
+ return NULL;
+ }
+ else
+ {
+ regerror( REGERR_INTERNAL_ERROR_JUNK );
+ return NULL;
+ }
+ // NOTREACHED
+ }
+
+ return(ret);
+}
+
+// regbranch - one alternative of an | operator
+//
+// Implements the concatenation operator.
+
+char * CRegCompilerBase::regbranch(int *flagp)
+{
+ char * ret;
+ char * chain;
+ char * latest;
+ int flags;
+ int c;
+
+ *flagp = WORST; // Tentatively.
+
+ ret = regnode(BRANCH);
+ chain = NULL;
+ while ((c = *regparse) != '\0' && c != '|' && c != ')')
+ {
+ latest = regpiece(&flags);
+ if (latest == NULL)
+ return(NULL);
+ *flagp |= flags&HASWIDTH;
+ if (chain == NULL) // First piece.
+ *flagp |= flags&SPSTART;
+ else
+ regtail(chain, latest);
+ chain = latest;
+ }
+ if (chain == NULL) // Loop ran zero times.
+ (void) regnode(NOTHING);
+
+ return(ret);
+}
+
+// regpiece - something followed by possible [*+?]
+//
+// Note that the branching code sequences used for ? and the general cases
+// of * and + are somewhat optimized: they use the same NOTHING node as
+// both the endmarker for their branch list and the body of the last branch.
+// It might seem that this node could be dispensed with entirely, but the
+// endmarker role is not redundant.
+
+char * CRegCompilerBase::regpiece(int *flagp)
+{
+ char * ret;
+ char op;
+ char * next;
+ int flags;
+
+ ret = regatom(&flags);
+ if (ret == NULL)
+ return(NULL);
+
+ op = *regparse;
+ if (!ISREPN(op))
+ {
+ *flagp = flags;
+ return(ret);
+ }
+
+ if (!(flags&HASWIDTH) && op != '?' )
+ {
+ regerror( REGERR_OP_COULD_BE_EMPTY );
+ return NULL;
+ }
+ switch (op)
+ {
+ case '*' : *flagp = WORST|SPSTART; break;
+ case '+' : *flagp = WORST|SPSTART|HASWIDTH; break;
+ case '?' : *flagp = WORST; break;
+ }
+
+ if (op == '*' && (flags&SIMPLE))
+ reginsert(STAR, ret);
+ else if (op == '*' )
+ {
+ // Emit x* as (x&|), where & means "self".
+ reginsert(BRANCH, ret); // Either x
+ regoptail(ret, regnode(BACK)); // and loop
+ regoptail(ret, ret); // back
+ regtail(ret, regnode(BRANCH)); // or
+ regtail(ret, regnode(NOTHING)); // null.
+ }
+ else if (op == '+' && (flags&SIMPLE))
+ reginsert(PLUS, ret);
+ else if (op == '+' )
+ {
+ // Emit x+ as x(&|), where & means "self".
+ next = regnode(BRANCH); // Either
+ regtail(ret, next);
+ regtail(regnode(BACK), ret); // loop back
+ regtail(next, regnode(BRANCH)); // or
+ regtail(ret, regnode(NOTHING)); // null.
+ }
+ else if (op == '?' )
+ {
+ // Emit x? as (x|)
+ reginsert(BRANCH, ret); // Either x
+ regtail(ret, regnode(BRANCH)); // or
+ next = regnode(NOTHING); // null.
+ regtail(ret, next);
+ regoptail(ret, next);
+ }
+ regparse++;
+ if (ISREPN(*regparse))
+ {
+ regerror( REGERR_NESTED_OP );
+ return NULL;
+ }
+
+ return(ret);
+}
+
+// regatom - the lowest level
+//
+// Optimization: gobbles an entire sequence of ordinary characters so that
+// it can turn them into a single node, which is smaller to store and
+// faster to run. Backslashed characters are exceptions, each becoming a
+// separate node; the code is simpler that way and it's not worth fixing.
+
+char * CRegCompilerBase::regatom(int * flagp)
+{
+ char * ret;
+ int flags;
+
+ *flagp = WORST; // Tentatively.
+
+ switch ( *regparse++ )
+ {
+ // FIXME: these chars only have meaning at beg/end of pat?
+ case '^':
+ ret = regnode(BOL);
+ break;
+ case '$':
+ ret = regnode(EOL);
+ break;
+ case '.':
+ ret = regnode(ANY);
+ *flagp |= HASWIDTH|SIMPLE;
+ break;
+ case '[':
+ {
+ int range;
+ int rangeend;
+ int c;
+
+ if (*regparse == '^')
+ { // Complement of range.
+ ret = regnode(ANYBUT);
+ regparse++;
+ }
+ else
+ ret = regnode(ANYOF);
+ if ((c = *regparse) == ']' || c == '-')
+ {
+ regc(c);
+ regparse++;
+ }
+ while ((c = *regparse++ ) != '\0' && c != ']')
+ {
+ if (c != '-')
+ regc(c);
+ else if ((c = *regparse) == ']' || c == '\0')
+ regc('-');
+ else
+ {
+ range = (char)*(regparse-2);
+ rangeend = (char)c;
+ if (range > rangeend)
+ {
+ regerror( REGERR_INVALID_RANGE );
+ return NULL;
+ }
+ for (range++; range <= rangeend; range++)
+ regc(range);
+ regparse++;
+ }
+ }
+ regc('\0');
+ if (c != ']')
+ {
+ regerror( REGERR_UNMATCHED_BRACE );
+ return NULL;
+ }
+ *flagp |= HASWIDTH|SIMPLE;
+ break;
+ }
+ case '(':
+ ret = reg(1, &flags);
+ if (ret == NULL)
+ return(NULL);
+ *flagp |= flags&(HASWIDTH|SPSTART);
+ break;
+ case '\0':
+ case '|':
+ case ')':
+ // supposed to be caught earlier
+ regerror( REGERR_INTERNAL_UNEXPECTED_CHAR );
+ return NULL;
+ case '?':
+ case '+':
+ case '*':
+ {
+ regerror( REGERR_OP_FOLLOWS_NOTHING );
+ return NULL;
+ }
+ case '\\':
+ switch (*regparse++)
+ {
+ case '\0':
+ {
+ regerror( REGERR_TRAILING_ESC );
+ return NULL;
+ }
+ case '<':
+ ret = regnode(WORDA);
+ break;
+ case '>':
+ ret = regnode(WORDZ);
+ break;
+ /* FIXME: Someday handle \1, \2, ... */
+ default:
+ /* Handle general quoted chars in exact-match routine */
+ goto de_fault;
+ }
+ break;
+ de_fault:
+ default:
+ // Encode a string of characters to be matched exactly.
+ //
+ // This is a bit tricky due to quoted chars and due to
+ // '*', '+', and '?' taking the SINGLE char previous
+ // as their operand.
+ //
+ // On entry, the char at regparse[-1] is going to go
+ // into the string, no matter what it is. (It could be
+ // following a \ if we are entered from the '\' case.)
+ //
+ // Basic idea is to pick up a good char in ch and
+ // examine the next char. If it's *+? then we twiddle.
+ // If it's \ then we frozzle. If it's other magic char
+ // we push ch and terminate the string. If none of the
+ // above, we push ch on the string and go around again.
+ //
+ // regprev is used to remember where "the current char"
+ // starts in the string, if due to a *+? we need to back
+ // up and put the current char in a separate, 1-char, string.
+ // When regprev is NULL, ch is the only char in the
+ // string; this is used in *+? handling, and in setting
+ // flags |= SIMPLE at the end.
+ {
+ char *regprev;
+ register char ch;
+
+ regparse--; /* Look at cur char */
+ ret = regnode(EXACTLY);
+ for ( regprev = 0 ; ; ) {
+ ch = *regparse++; /* Get current char */
+ switch (*regparse) { /* look at next one */
+
+ default:
+ regc(ch); /* Add cur to string */
+ break;
+
+ case '.': case '[': case '(':
+ case ')': case '|': case '\n':
+ case '$': case '^':
+ case '\0':
+ /* FIXME, $ and ^ should not always be magic */
+ magic:
+ regc(ch); /* dump cur char */
+ goto done; /* and we are done */
+
+ case '?': case '+': case '*':
+ if (!regprev) /* If just ch in str, */
+ goto magic; /* use it */
+ /* End mult-char string one early */
+ regparse = regprev; /* Back up parse */
+ goto done;
+
+ case '\\':
+ regc(ch); /* Cur char OK */
+ switch (regparse[1]){ /* Look after \ */
+ case '\0':
+ case '<':
+ case '>':
+ /* FIXME: Someday handle \1, \2, ... */
+ goto done; /* Not quoted */
+ default:
+ /* Backup point is \, scan * point is after it. */
+ regprev = regparse;
+ regparse++;
+ continue; /* NOT break; */
+ }
+ }
+ regprev = regparse; /* Set backup point */
+ }
+ done:
+ regc('\0');
+ *flagp |= HASWIDTH;
+ if (!regprev) /* One char? */
+ *flagp |= SIMPLE;
+ }
+ break;
+ }
+
+ return(ret);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// regexec and friends
+
+// Work-variable struct for regexec().
+
+class CRegExecutor : public CRegProgramAccessor
+{
+ friend bool regexp::regexec( const char * str );
+
+ char * reginput; // string-input pointer.
+ char * regbol; // Beginning of input, for ^ check.
+ char * * regstartp; // Pointer to startp array.
+ char * * regendp; // Ditto for endp.
+
+ regexp * prog;
+public:
+ CRegExecutor( regexp * prog, char * string );
+protected:
+ bool regtry( char * string );
+ bool regmatch( char * prog );
+ size_t regrepeat( char * node );
+};
+
+CRegExecutor::CRegExecutor( regexp * p, char * string )
+ : regbol( string ),
+ regstartp( p->startp ),
+ regendp( p->endp ),
+ prog(p)
+{
+}
+
+#ifdef _RE_DEBUG
+int regnarrate = 0;
+#endif
+
+// regexec - match a regexp against a string
+
+bool regexp::regexec( const char * str )
+{
+ char * string = (char *)str; // avert const poisoning
+
+ // Be paranoid.
+ if ( string == NULL )
+ {
+ regerror( REGERR_NULLARG );
+ return false;
+ }
+
+ // Check validity of program.
+ if (*program != MAGIC)
+ {
+ regerror( REGERR_CORRUPTED );
+ return false;
+ }
+
+ // If there is a "must appear" string, look for it.
+ if ( regmust != NULL && strstr( string, regmust ) == NULL )
+ return false;
+
+ CRegExecutor executor( this, string );
+
+ // Simplest case: anchored match need be tried only once.
+ if ( reganch )
+ return( executor.regtry( string ) );
+
+ // Messy cases: unanchored match.
+ if ( regstart != '\0' )
+ {
+ // We know what char it must start with.
+ for ( char * s = string; s != NULL; s = strchr( s+1 , regstart ) )
+ if ( executor.regtry( s) )
+ return true;
+ return false;
+ }
+ else
+ {
+ // We don't -- general case.
+ for ( char * s = string; ! executor.regtry( s ); s++ )
+ if (*s == '\0')
+ return false;
+ }
+ return true;
+}
+
+// regtry - try match at specific point
+bool CRegExecutor::regtry( char * string )
+{
+ int i;
+ char * * stp;
+ char * * enp;
+
+ reginput = string;
+
+ stp = prog->startp;
+ enp = prog->endp;
+ for (i = Regexp::NSUBEXP; i > 0; i--)
+ {
+ *stp++ = NULL;
+ *enp++ = NULL;
+ }
+ if ( regmatch( prog->program + 1 ) )
+ {
+ prog->startp[0] = string;
+ prog->endp[0] = reginput;
+ return true;
+ }
+ else
+ return false;
+}
+
+// regmatch - main matching routine
+//
+// Conceptually the strategy is simple: check to see whether the current
+// node matches, call self recursively to see whether the rest matches,
+// and then act accordingly. In practice we make some effort to avoid
+// recursion, in particular by going through "ordinary" nodes (that don't
+// need to know whether the rest of the match failed) by a loop instead of
+// by recursion.
+
+bool CRegExecutor::regmatch( char * prog )
+{
+ char * scan; // Current node.
+ char * next; // Next node.
+
+#ifdef _RE_DEBUG
+ if (prog != NULL && regnarrate)
+ fprintf(stderr, "%s(\n", regprop(prog));
+#endif
+ for (scan = prog; scan != NULL; scan = next)
+ {
+#ifdef _RE_DEBUG
+ if (regnarrate)
+ fprintf(stderr, "%s...\n", regprop(scan));
+#endif
+ next = regnext(scan);
+
+ switch (OP(scan))
+ {
+ case BOL:
+ if (reginput != regbol)
+ return false;
+ break;
+ case EOL:
+ if (*reginput != '\0')
+ return false;
+ break;
+ case WORDA:
+ /* Must be looking at a letter, digit, or _ */
+ if ((!isalnum(*reginput)) && *reginput != '_')
+ return(0);
+ /* Prev must be BOL or nonword */
+ if (reginput > regbol &&
+ (isalnum(reginput[-1]) || reginput[-1] == '_'))
+ return(0);
+ break;
+ case WORDZ:
+ /* Must be looking at non letter, digit, or _ */
+ if (isalnum(*reginput) || *reginput == '_')
+ return(0);
+ /* We don't care what the previous char was */
+ break;
+ case ANY:
+ if (*reginput == '\0')
+ return false;
+ reginput++;
+ break;
+ case EXACTLY:
+ {
+ size_t len;
+ char * const opnd = OPERAND(scan);
+
+ // Inline the first character, for speed.
+ if (*opnd != *reginput)
+ return false;
+ len = strlen(opnd);
+ if (len > 1 && strncmp(opnd, reginput, len) != 0)
+ return false;
+ reginput += len;
+
+ break;
+ }
+ case ANYOF:
+ if (*reginput == '\0' ||
+ strchr(OPERAND(scan), *reginput) == NULL)
+ return false;
+ reginput++;
+ break;
+ case ANYBUT:
+ if (*reginput == '\0' ||
+ strchr(OPERAND(scan), *reginput) != NULL)
+ return false;
+ reginput++;
+ break;
+ case NOTHING:
+ break;
+ case BACK:
+ break;
+ case OPEN+1: case OPEN+2: case OPEN+3:
+ case OPEN+4: case OPEN+5: case OPEN+6:
+ case OPEN+7: case OPEN+8: case OPEN+9:
+ case OPEN+10: case OPEN+11: case OPEN+12:
+ case OPEN+13: case OPEN+14: case OPEN+15:
+ case OPEN+16: case OPEN+17: case OPEN+18:
+ case OPEN+19:
+ {
+ const int no = OP(scan) - OPEN;
+ char * const input = reginput;
+
+ if (regmatch(next))
+ {
+ // Don't set startp if some later
+ // invocation of the same parentheses
+ // already has.
+
+ if (regstartp[no] == NULL)
+ regstartp[no] = input;
+ return true;
+ }
+ else
+ return false;
+ break;
+ }
+ case CLOSE+1: case CLOSE+2: case CLOSE+3:
+ case CLOSE+4: case CLOSE+5: case CLOSE+6:
+ case CLOSE+7: case CLOSE+8: case CLOSE+9:
+ case CLOSE+10: case CLOSE+11: case CLOSE+12:
+ case CLOSE+13: case CLOSE+14: case CLOSE+15:
+ case CLOSE+16: case CLOSE+17: case CLOSE+18:
+ case CLOSE+19:
+ {
+ const int no = OP(scan) - CLOSE;
+ char * const input = reginput;
+
+ if (regmatch(next))
+ {
+ // Don't set endp if some later
+ // invocation of the same parentheses
+ // already has.
+
+ if (regendp[no] == NULL)
+ regendp[no] = input;
+ return true;
+ }
+ else
+ return false;
+ break;
+ }
+ case BRANCH:
+ {
+ char * const save = reginput;
+
+ if (OP(next) != BRANCH) // No choice.
+ next = OPERAND(scan); // Avoid recursion.
+ else
+ {
+ while (OP(scan) == BRANCH)
+ {
+ if (regmatch(OPERAND(scan)))
+ return true;
+ reginput = save;
+ scan = regnext(scan);
+ }
+ return false;
+ // NOTREACHED
+ }
+ break;
+ }
+ case STAR: case PLUS:
+ {
+ const char nextch = (OP(next) == EXACTLY) ? *OPERAND(next) : '\0';
+ size_t no;
+ char * const save = reginput;
+ const size_t min = (OP(scan) == STAR) ? 0 : 1;
+
+ for (no = regrepeat(OPERAND(scan)) + 1; no > min; no--)
+ {
+ reginput = save + no - 1;
+ // If it could work, try it.
+ if (nextch == '\0' || *reginput == nextch)
+ if (regmatch(next))
+ return true;
+ }
+ return false;
+ break;
+ }
+ case END:
+ return true; // Success!
+ break;
+ default:
+ regerror( REGERR_CORRUPTION );
+ return false;
+ break;
+ }
+ }
+
+ // We get here only if there's trouble -- normally "case END" is
+ // the terminating point.
+
+ regerror( REGERR_CORRUPTED_POINTERS );
+ return false;
+}
+
+// regrepeat - report how many times something simple would match
+
+size_t CRegExecutor::regrepeat( char * node )
+{
+ size_t count;
+ char * scan;
+ char ch;
+
+ switch (OP(node))
+ {
+ case ANY:
+ return(strlen(reginput));
+ break;
+ case EXACTLY:
+ ch = *OPERAND(node);
+ count = 0;
+ for (scan = reginput; *scan == ch; scan++)
+ count++;
+ return(count);
+ break;
+ case ANYOF:
+ return(strspn(reginput, OPERAND(node)));
+ break;
+ case ANYBUT:
+ return(strcspn(reginput, OPERAND(node)));
+ break;
+ default: // Oh dear. Called inappropriately.
+ regerror( REGERR_BAD_REGREPEAT );
+ return(0); // Best compromise.
+ break;
+ }
+ // NOTREACHED
+}
+
+#ifdef _RE_DEBUG
+
+// regdump - dump a regexp onto stdout in vaguely comprehensible form
+
+void regexp::regdump()
+{
+ char * s;
+ char op = EXACTLY; // Arbitrary non-END op.
+ char * next;
+
+ s = program + 1;
+ while (op != END)
+ { // While that wasn't END last time...
+ op = OP(s);
+ printf("%2d%s", s-program, regprop(s)); // Where, what.
+ next = regnext(s);
+ if (next == NULL) // Next ptr.
+ printf("(0)" );
+ else
+ printf("(%d)", (s-program)+(next-s));
+ s += 3;
+ if (op == ANYOF || op == ANYBUT || op == EXACTLY)
+ {
+ // Literal string, where present.
+ while (*s != '\0')
+ {
+ putchar(*s);
+ s++;
+ }
+ s++;
+ }
+ putchar('\n');
+ }
+
+ // Header fields of interest.
+ if (regstart != '\0')
+ printf("start `%c' ", regstart);
+ if (reganch)
+ printf("anchored ");
+ if (regmust != NULL)
+ printf("must have \"%s\"" , regmust);
+ printf("\n");
+}
+
+// regprop - printable representation of opcode
+
+#define OUTPUT(s) case s: p = #s; break
+char * CRegProgramAccessor::regprop( char * op )
+{
+ char * p = NULL;
+ static char buf[50];
+
+ (void) strcpy(buf, ":" );
+
+ switch (OP(op))
+ {
+ OUTPUT( BOL );
+ OUTPUT( EOL );
+ OUTPUT( ANY );
+ OUTPUT( ANYOF );
+ OUTPUT( ANYBUT );
+ OUTPUT( BRANCH );
+ OUTPUT( EXACTLY );
+ OUTPUT( NOTHING );
+ OUTPUT( BACK );
+ OUTPUT( END );
+ OUTPUT( STAR );
+ OUTPUT( PLUS );
+ OUTPUT( WORDA );
+ OUTPUT( WORDZ );
+ case OPEN+1: case OPEN+2: case OPEN+3:
+ case OPEN+4: case OPEN+5: case OPEN+6:
+ case OPEN+7: case OPEN+8: case OPEN+9:
+ case OPEN+10: case OPEN+11: case OPEN+12:
+ case OPEN+13: case OPEN+14: case OPEN+15:
+ case OPEN+16: case OPEN+17: case OPEN+18:
+ case OPEN+19:
+ sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
+ p = NULL;
+ break;
+ case CLOSE+1: case CLOSE+2: case CLOSE+3:
+ case CLOSE+4: case CLOSE+5: case CLOSE+6:
+ case CLOSE+7: case CLOSE+8: case CLOSE+9:
+ case CLOSE+10: case CLOSE+11: case CLOSE+12:
+ case CLOSE+13: case CLOSE+14: case CLOSE+15:
+ case CLOSE+16: case CLOSE+17: case CLOSE+18:
+ case CLOSE+19:
+ sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
+ p = NULL;
+ break;
+ default:
+ regerror( REGERR_CORRUPTED_OPCODE );
+ break;
+ }
+ if (p != NULL)
+ (void) strcat(buf, p);
+ return(buf);
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+Regexp::Regexp()
+ : rc(0),
+ str(0)
+{
+}
+
+Regexp::Regexp( const char * exp, bool iCase )
+ : rc( new regexp( exp, iCase ) ),
+ str( 0 )
+{
+}
+
+Regexp::Regexp( const Regexp &r )
+ : rc( r.rc ),
+ m_szError(r.m_szError),
+ str(r.str)
+{
+ if ( rc )
+ rc->count++;
+}
+
+const Regexp & Regexp::operator=( const Regexp & r )
+{
+ if ( this != &r )
+ {
+ if ( rc && rc->count-- == 0 )
+ delete rc;
+
+ rc = r.rc;
+ if ( rc )
+ rc->count++;
+
+ str = r.str;
+ m_szError = r.m_szError;
+ }
+ return *this;
+}
+
+Regexp::~Regexp()
+{
+ if ( rc && rc->count-- == 0 )
+ delete rc;
+}
+
+bool Regexp::Match( const char * s )
+{
+ ClearErrorString();
+ str = s;
+ bool ret = false;
+ if ( rc )
+ {
+ // copy on write !
+
+ if ( rc->count )
+ {
+ rc->count--;
+ rc = rc->getCopy();
+ }
+
+ ret = rc->regexec( s );
+ int i = 0;
+ if ( ret )
+ for ( i = 0; i < Regexp::NSUBEXP && rc->startp[i] ; i++ )
+ ;
+ rc->numSubs = i - 1;
+ }
+ else
+ m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+ return ret;
+}
+
+ivy::string Regexp::GetReplaceString( const char * source ) const
+{
+ ClearErrorString();
+ if ( rc )
+ return rc->GetReplaceString( source );
+ else
+ m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+ return "";
+}
+
+int Regexp::SubStrings() const
+{
+ ClearErrorString();
+ int ret = -1;
+ if ( rc )
+ ret = rc->numSubs;
+ else
+ m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+ return ret;
+}
+
+size_t Regexp::SubStart( size_t i ) const
+{
+ ClearErrorString();
+ size_t ret = -1;
+ if ( rc )
+ ret = rc->startp[safeIndex(i)] - str;
+ else
+ m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+ return ret;
+}
+
+size_t Regexp::SubLength( size_t i ) const
+{
+ ClearErrorString();
+ size_t ret = -1;
+ if ( rc )
+ {
+ i = safeIndex(i);
+ ret = rc->endp[i] - rc->startp[i];
+ }
+ else
+ m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+ return ret;
+}
+
+bool Regexp::CompiledOK() const
+{
+ return rc ? rc->Status() : false;
+}
+
+#ifdef _RE_DEBUG
+void Regexp::Dump()
+{
+ if ( rc )
+ rc->regdump();
+#if defined( _DEBUG )
+ else
+ TRACE( "No regexp to dump out\n" );
+#endif
+}
+#endif
+
+size_t Regexp::safeIndex( size_t i ) const
+{
+ return i < Regexp::NSUBEXP ? i : Regexp::NSUBEXP;
+}
+
+const ivy::string Regexp::operator[]( size_t i ) const
+{
+ ivy::string value;
+ ClearErrorString();
+ ASSERT( rc );
+ if ( rc )
+ {
+ size_t len = SubLength(i);
+ //char * szbuf = buffer.GetBufferSetLength( len );
+ //memcpy( szbuf, rc->startp[i], len * sizeof(char) );
+ //buffer.ReleaseBuffer();
+ value = ivy::string ( rc->startp[i], len );
+ }
+ else
+ {
+ m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+ }
+ return value;
+}
+
+void regexp::ignoreCase( const char * in, char * out )
+{
+ // copy in to out making every top level character a [Aa] set
+ bool inRange = false;
+ while( *in )
+ {
+ if ( *in == '[' )
+ inRange = true;
+ if ( *in == ']' )
+ inRange = false;
+ if ( ! inRange && isalpha( *in ) )
+ {
+ *out++ = '[';
+ *out++ = (char)toupper( *in );
+ *out++ = (char)tolower( *in );
+ *out++ = ']';
+ }
+ else
+ *out++ = *in;
+ in++;
+ }
+ *out = 0;
+}
+
+// GetReplaceString - Converts a replace expression to a string
+// - perform substitutions after a regexp match
+// Returns - The resultant string
+ivy::string regexp::GetReplaceString( const char* sReplaceExp ) const
+{
+ ivy::string szEmpty( "" );
+
+ char *src = (char *)sReplaceExp;
+ //char *buf;
+ char c;
+ int no;
+ size_t len;
+
+ if( sReplaceExp == NULL )
+ {
+ regerror( REGERR_NULL_TO_REGSUB );
+ return szEmpty;
+ }
+ if ( *program != MAGIC)
+ {
+ regerror( REGERR_DAMAGED_REGEXP_REGSUB );
+ return szEmpty;
+ }
+
+ // First compute the length of the string
+ size_t replacelen = 0;
+ while ((c = *src++) != '\0')
+ {
+ if (c == '&')
+ no = 0;
+ else if (c == '\\' && isdigit(*src))
+ no = *src++ - '0';
+ else
+ no = -1;
+
+ if (no < 0)
+ {
+ // Ordinary character.
+ if (c == '\\' && (*src == '\\' || *src == '&'))
+ c = *src++;
+ replacelen++;
+ }
+ else if (startp[no] != NULL && endp[no] != NULL &&
+ endp[no] > startp[no])
+ {
+ // Get tagged expression
+ len = endp[no] - startp[no];
+ replacelen += len;
+ }
+ }
+
+ ivy::string szReplace;
+
+ //buf = szReplace.GetBufferSetLength( replacelen );
+
+ // Now we can create the string
+ src = (char *)sReplaceExp;
+ while ((c = *src++) != '\0')
+ {
+ if (c == '&')
+ no = 0;
+ else if (c == '\\' && isdigit(*src))
+ no = *src++ - '0';
+ else
+ no = -1;
+
+ if (no < 0)
+ {
+ // Ordinary character.
+ if (c == '\\' && (*src == '\\' || *src == '&'))
+ c = *src++;
+ //*buf++ = c;
+ szReplace += c ;
+ }
+ else if (startp[no] != NULL && endp[no] != NULL &&
+ endp[no] > startp[no])
+ {
+ // Get tagged expression
+ len = endp[no] - startp[no];
+ //strncpy(buf, startp[no], len);
+ //buf += len;
+ szReplace.append( startp[no], len );
+// if (len != 0 && *(buf-1) == '\0' ))
+// { /* strncpy hit NUL. */
+// regerror( REGERR_DAMAGED_MATCH_STRING );
+// return szEmpty;
+// }
+ }
+ }
+
+ //szReplace.ReleaseBuffer( replacelen );
+ return szReplace;
+}
+
+ivy::string Regexp::GetErrorString() const
+{
+ // make sure that if status == 0 that we have an error string
+ //assert( ( ! CompiledOK() ) ? ( rc ? rc->GetErrorString() : m_szError).length() != 0 : 1 );
+ return rc ? rc->GetErrorString() : m_szError ;
+}
+
+void Regexp::ClearErrorString() const
+{
+ if ( rc )
+ rc->ClearErrorString();
+ m_szError.erase();
+}
+
diff --git a/Ivy/Regexp.h b/Ivy/Regexp.h
new file mode 100644
index 0000000..b41d88e
--- /dev/null
+++ b/Ivy/Regexp.h
@@ -0,0 +1,41 @@
+#pragma once
+
+class regexp;
+
+class Regexp
+{
+public:
+ enum { NSUBEXP = 40 };
+
+ Regexp();
+ Regexp( const char * exp, bool iCase = 0 );
+ Regexp( const Regexp &r );
+ ~Regexp();
+ const Regexp & operator=( const Regexp & r );
+
+ bool Match( const char * s );
+ int SubStrings() const;
+
+ const ivy::string operator[]( size_t i ) const;
+ size_t SubStart( size_t i ) const;
+ size_t SubLength( size_t i ) const;
+
+ ivy::string GetReplaceString( const char * source ) const;
+
+ ivy::string GetErrorString() const;
+ bool CompiledOK() const;
+
+#if defined( _RE_DEBUG )
+ void Dump();
+#endif
+private:
+ const char * str; /* used to return substring offsets only */
+ mutable ivy::string m_szError;
+ regexp * rc;
+
+ void ClearErrorString() const;
+ size_t safeIndex( size_t i ) const;
+
+};
+
+
diff --git a/Ivy/ThreadedSocket.cxx b/Ivy/ThreadedSocket.cxx
new file mode 100644
index 0000000..ee1e03b
--- /dev/null
+++ b/Ivy/ThreadedSocket.cxx
@@ -0,0 +1,547 @@
+// ThreadedSocket.cpp: implementation of the CThreadedSocket class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "IvyStdAfx.h"
+
+
+#include "ThreadedSocket.h"
+
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CThreadedSocket::CThreadedSocket()
+{
+
+ m_hSocket = INVALID_SOCKET;
+ h_reader = NULL;
+ h_writer = NULL;
+ reader_id = 0;
+ writer_id = 0;
+ listen_mode = false;
+ connect_pending = true;
+ send_pending = false;
+}
+
+CThreadedSocket::~CThreadedSocket()
+{
+ if (m_hSocket != INVALID_SOCKET)
+ Close();
+}
+int CThreadedSocket::Create(UINT nSocketPort, int nSocketType, const char * lpszSocketAddress)
+{
+ if ( Socket(nSocketType) < 0 )
+ return SOCKET_ERROR;
+
+ send_count = CreateSemaphore( NULL, 0, 100, NULL); // unnamed semaphore
+ if (send_count == NULL)
+ return SOCKET_ERROR;
+
+ return Bind(nSocketPort,lpszSocketAddress);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CThreadedSocket Attributes
+
+
+
+void CThreadedSocket::GetPeerName(ivy::string & rPeerAddress, UINT& rPeerPort)
+{
+ SOCKADDR_IN sockAddr;
+ memset(&sockAddr, 0, sizeof(sockAddr));
+
+ int nSockAddrLen = sizeof(sockAddr);
+ GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);
+ rPeerPort = ntohs(sockAddr.sin_port);
+ rPeerAddress = inet_ntoa(sockAddr.sin_addr);
+}
+
+void CThreadedSocket::GetSockName(ivy::string & rSocketAddress, UINT& rSocketPort)
+{
+ SOCKADDR_IN sockAddr;
+ memset(&sockAddr, 0, sizeof(sockAddr));
+
+ int nSockAddrLen = sizeof(sockAddr);
+ GetSockName((SOCKADDR*)&sockAddr, &nSockAddrLen);
+ rSocketPort = ntohs(sockAddr.sin_port);
+ rSocketAddress = inet_ntoa(sockAddr.sin_addr);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CAscynSocket Operations
+
+SOCKET CThreadedSocket::Accept(CThreadedSocket& rConnectedSocket,
+ SOCKADDR* lpSockAddr, int* lpSockAddrLen)
+{
+ ASSERT(rConnectedSocket.m_hSocket == INVALID_SOCKET);
+
+ SOCKET hTemp = accept(m_hSocket, lpSockAddr, lpSockAddrLen);
+
+ if (hTemp == INVALID_SOCKET)
+ {
+ rConnectedSocket.m_hSocket = INVALID_SOCKET;
+ return SOCKET_ERROR;
+ }
+ else
+ {
+ rConnectedSocket.m_hSocket = hTemp;
+ rConnectedSocket.send_count = CreateSemaphore( NULL, 0, 100, NULL); // unnamed semaphore
+ if (rConnectedSocket.send_count == NULL)
+ return SOCKET_ERROR;
+
+ rConnectedSocket.StartListener();
+ return hTemp;
+ }
+}
+
+int CThreadedSocket::Bind(UINT nSocketPort, const char * lpszSocketAddress)
+{
+
+ SOCKADDR_IN sockAddr;
+ memset(&sockAddr,0,sizeof(sockAddr));
+
+ sockAddr.sin_family = AF_INET;
+
+ if (lpszSocketAddress == NULL)
+ sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ else
+ {
+ DWORD lResult = inet_addr(lpszSocketAddress);
+ if (lResult == INADDR_NONE)
+ {
+ WSASetLastError(WSAEINVAL);
+ return SOCKET_ERROR;
+ }
+ sockAddr.sin_addr.s_addr = lResult;
+ }
+
+ sockAddr.sin_port = htons((u_short)nSocketPort);
+
+ return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
+}
+
+void CThreadedSocket::Close()
+{
+ long PreviousCount = 0;
+ int err;
+ DWORD currentThreadId;
+
+
+ if (m_hSocket != INVALID_SOCKET)
+ {
+ currentThreadId = GetCurrentThreadId();
+
+ //ASSERT(SOCKET_ERROR != closesocket(m_hSocket));
+ SOCKET temp = m_hSocket; // Thread ACK
+ m_hSocket = INVALID_SOCKET;
+ TRACE( "CThreadedSocket::Close (reader=0x%0lx) (writer=0x%0lx)\n", reader_id, writer_id );
+ closesocket(temp); // close silently
+
+ //if ( thread ) // On fait de l'auto delete mais dans le cas de terminaison anormale l'object reste ????!!!
+ // delete thread;
+// TRACE("CThreadedSocket waiting for thread end ...\n");
+ if ( h_reader && currentThreadId != reader_id )
+ WaitForSingleObject( h_reader, 5000 );
+ // wake up writer
+ if ( h_writer && currentThreadId != writer_id )
+ {
+ err = ReleaseSemaphore(send_count, 1, &PreviousCount);
+ WaitForSingleObject( h_writer, 5000 );
+ }
+// TRACE("CThreadedSocket all thread ended\n");
+ }
+}
+int CThreadedSocket::Listen(int nConnectionBacklog)
+{
+ int err = listen(m_hSocket, nConnectionBacklog);
+ if ( !err )
+ listen_mode = true;
+ return StartListener();
+}
+
+int CThreadedSocket::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
+{
+ int ok;
+ fd_set writefds;
+
+ FD_ZERO(&writefds);
+
+ FD_SET(m_hSocket, &writefds);
+
+ ok = connect(m_hSocket, lpSockAddr, nSockAddrLen);
+ if ( ok != 0 )
+ {
+ int err = this->GetLastError();
+ if ( err == 0 ) return err;
+ TRACE( "***************************************Error connect %d\n", err);
+ if ( err != WSAEWOULDBLOCK )
+ return -1;
+ // Wait for connection to complete
+ TRACE( "***************************************Waiting for connection to complete\n");
+ FD_SET(m_hSocket, &writefds);
+ err = select( 1, NULL, &writefds, NULL, NULL );
+ //TRACE( "Thread socket %d wait return %d\n", m_hSocket, err );
+ if ( !err )
+ connect_pending = true;
+ return err;
+ }
+ connect_pending = true;
+ return StartListener();
+}
+
+int CThreadedSocket::Connect(const char * lpszHostAddress, UINT nHostPort)
+{
+
+ ASSERT(lpszHostAddress != NULL);
+
+ SOCKADDR_IN sockAddr;
+ memset(&sockAddr,0,sizeof(sockAddr));
+
+ sockAddr.sin_family = AF_INET;
+ sockAddr.sin_addr.s_addr = inet_addr(lpszHostAddress);
+
+ if (sockAddr.sin_addr.s_addr == INADDR_NONE)
+ {
+ LPHOSTENT lphost;
+ lphost = gethostbyname(lpszHostAddress);
+ if (lphost != NULL)
+ sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
+ else
+ {
+ WSASetLastError(WSAEINVAL);
+ return SOCKET_ERROR;
+ }
+ }
+
+ sockAddr.sin_port = htons((u_short)nHostPort);
+
+ return Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
+}
+
+size_t CThreadedSocket::Receive(void* lpBuf, size_t nBufLen, int nFlags)
+{
+ int lg = recv(m_hSocket, (LPSTR)lpBuf, (int)nBufLen, nFlags);
+ return lg;
+}
+
+size_t CThreadedSocket::ReceiveFrom(void* lpBuf, size_t nBufLen, ivy::string & rSocketAddress, UINT& rSocketPort, int nFlags)
+{
+ SOCKADDR_IN sockAddr;
+
+ memset(&sockAddr, 0, sizeof(sockAddr));
+
+ size_t nSockAddrLen = sizeof(sockAddr);
+ size_t nResult = ReceiveFrom(lpBuf, nBufLen, (SOCKADDR*)&sockAddr, &nSockAddrLen, nFlags);
+ rSocketPort = ntohs(sockAddr.sin_port);
+ rSocketAddress = inet_ntoa(sockAddr.sin_addr);
+
+ return nResult;
+}
+
+size_t CThreadedSocket::Send(const void* lpBuf, size_t nBufLen, int nFlags)
+{
+ return send(m_hSocket, (LPSTR)lpBuf, (int)nBufLen, nFlags);
+}
+
+size_t CThreadedSocket::SendTo(const void* lpBuf, size_t nBufLen, UINT nHostPort, const char * lpszHostAddress, int nFlags)
+{
+ SOCKADDR_IN sockAddr;
+
+ memset(&sockAddr,0,sizeof(sockAddr));
+
+ sockAddr.sin_family = AF_INET;
+
+ if (lpszHostAddress == NULL)
+ sockAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
+ else
+ {
+ sockAddr.sin_addr.s_addr = inet_addr(lpszHostAddress);
+ if (sockAddr.sin_addr.s_addr == INADDR_NONE)
+ {
+ LPHOSTENT lphost;
+ lphost = gethostbyname(lpszHostAddress);
+ if (lphost != NULL)
+ sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
+ else
+ {
+ WSASetLastError(WSAEINVAL);
+ return SOCKET_ERROR;
+ }
+ }
+ }
+
+ sockAddr.sin_port = htons((u_short)nHostPort);
+
+ return SendTo(lpBuf, nBufLen, (SOCKADDR*)&sockAddr, sizeof(sockAddr), nFlags);
+ }
+int CThreadedSocket::AddMember( const char * lpszHostAddress )
+{
+ int multicast_ttl = 64; // region
+ struct ip_mreq imr;
+
+ TRACE("CThreadedSocket::AddMember adding %s\n", lpszHostAddress );
+ imr.imr_multiaddr.s_addr = INADDR_ANY;
+ imr.imr_interface.s_addr = INADDR_ANY;
+
+ if (lpszHostAddress )
+ {
+ imr.imr_multiaddr.s_addr = inet_addr(lpszHostAddress);
+ if (imr.imr_multiaddr.s_addr == INADDR_NONE)
+ {
+ LPHOSTENT lphost;
+ lphost = gethostbyname(lpszHostAddress);
+ if (lphost != NULL)
+ imr.imr_multiaddr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
+ else
+ {
+ WSASetLastError(WSAEINVAL);
+ return SOCKET_ERROR;
+ }
+ }
+ }
+ if ( IN_CLASSD( htonl(imr.imr_multiaddr.s_addr) ) )
+ {
+ SetSockOpt( IP_MULTICAST_TTL, &multicast_ttl, sizeof( multicast_ttl ), IPPROTO_IP );
+ SetSockOpt( IP_ADD_MEMBERSHIP, &imr, sizeof( imr ), IPPROTO_IP );
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CThreadedSocket Overridable callbacks
+void CThreadedSocket::OnReceive(int /*nErrorCode*/)
+{
+}
+
+void CThreadedSocket::OnSend(int /*nErrorCode*/)
+{
+}
+
+void CThreadedSocket::OnOutOfBandData(int /*nErrorCode*/)
+{
+}
+
+void CThreadedSocket::OnAccept(int /*nErrorCode*/)
+{
+}
+
+void CThreadedSocket::OnConnect(int /*nErrorCode*/)
+{
+}
+
+void CThreadedSocket::OnClose(int /*nErrorCode*/)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CThreadedSocket Implementation
+
+
+SOCKET CThreadedSocket::Socket(int nSocketType, int nProtocolType, int nAddressFormat)
+{
+ ASSERT(m_hSocket == INVALID_SOCKET);
+
+ m_hSocket = socket(nAddressFormat,nSocketType,nProtocolType);
+
+ return m_hSocket;
+ //return StartListener();
+}
+
+int CThreadedSocket::StartListener()
+{
+ h_reader = CreateThread(NULL,0,SocketReaderProc, this, 0, &reader_id);
+ return h_reader != NULL ? 0 : SOCKET_ERROR;
+}
+int CThreadedSocket::StartWriter()
+{
+ h_writer = CreateThread(NULL,0,SocketWriterProc, this, 0, &writer_id);
+ return h_writer != NULL ? 0 : SOCKET_ERROR;
+}
+bool CThreadedSocket::SignalWriter()
+{
+ long PreviousCount = 0;
+ BOOL err;
+ err = ReleaseSemaphore(send_count, 1, &PreviousCount);
+// TRACE("CThreadedSocket::SignalWriter() PreviousCount = %ld \n", PreviousCount );
+ return (err != 0);
+}
+
+// Implementation
+DWORD WINAPI CThreadedSocket::SocketReaderProc( LPVOID pParam )
+{
+ CThreadedSocket* pObject = (CThreadedSocket*)pParam;
+
+ if (pObject == NULL )
+ {
+ return SOCKET_ERROR; // if pObject is not valid
+ }
+
+ return pObject->SocketReader();
+}
+// Implementation
+DWORD WINAPI CThreadedSocket::SocketWriterProc( LPVOID pParam )
+{
+ CThreadedSocket* pObject = (CThreadedSocket*)pParam;
+
+ if (pObject == NULL )
+ {
+ return SOCKET_ERROR; // if pObject is not valid
+ }
+
+ return pObject->SocketWriter();
+}
+
+UINT CThreadedSocket::SocketReader( )
+{
+ int err;
+ int sock_err;
+ unsigned long readcount = 0;
+ fd_set readfds;
+ fd_set writefds;
+ fd_set exceptfds;
+
+ TRACE( "CThreadedSocket::SocketReader( START thread_id =( 0x%x) )\n",reader_id);
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptfds);
+
+ while ( m_hSocket != INVALID_SOCKET )
+ {
+ FD_SET(m_hSocket, &readfds);
+ if ( connect_pending )
+ FD_SET(m_hSocket, &writefds);
+ else
+ FD_CLR(m_hSocket, &writefds);
+ FD_SET(m_hSocket, &exceptfds);
+
+ err = select( 1, &readfds, &writefds, &exceptfds, NULL );
+ sock_err = this->GetLastError();
+
+ switch ( err )
+ {
+ case 0:
+ TRACE( "CThreadedSocket::SocketThread Unhandled Timeout Event !\n");
+ break;
+ case SOCKET_ERROR:
+
+ TRACE( "CThreadedSocket::SocketReader( select error thread_id =( 0x%x) )\n",reader_id);
+ if ( (sock_err != WSAENOTSOCK ) && ( m_hSocket != INVALID_SOCKET )) // could be Invalid if close when in select
+ Close();
+ h_reader = NULL;
+ return sock_err;
+ break;
+ default:
+
+
+ if ( FD_ISSET(m_hSocket, &readfds) )
+ {
+ readcount = 0;
+ IOCtl( FIONREAD, &readcount );
+ if ( listen_mode )
+ OnAccept( sock_err );
+ else if ( ! readcount )
+ OnClose( sock_err );
+ else OnReceive(sock_err);
+ }
+
+ if ( FD_ISSET(m_hSocket, &writefds) )
+ {
+ if ( connect_pending )
+ {
+ OnConnect( sock_err );
+ connect_pending = false;
+ }
+ }
+
+ if ( FD_ISSET(m_hSocket, &exceptfds) )
+ OnOutOfBandData( sock_err );
+
+
+ break;
+ }
+ }
+ if (m_hSocket != INVALID_SOCKET)
+ Close();
+ h_reader = NULL;
+ TRACE( "CThreadedSocket::SocketReader( END thread_id =( 0x%x) )\n",reader_id);
+
+ return 0;
+}
+
+UINT CThreadedSocket::SocketWriter( )
+{
+ int err;
+ int sock_err;
+ fd_set writefds;
+
+ TRACE( "CThreadedSocket::SocketWriter( START thread_id =( 0x%x) )\n",writer_id);
+
+ FD_ZERO(&writefds);
+
+
+ while ( m_hSocket != INVALID_SOCKET )
+ {
+ DWORD dwWaitResult;
+
+ // Wait for message to send
+
+ dwWaitResult = WaitForSingleObject( send_count, INFINITE );
+
+ switch (dwWaitResult) {
+
+ // The semaphore object was signaled.
+ case WAIT_OBJECT_0:
+ // OK to really send the message.
+ break;
+
+ // Semaphore was nonsignaled, so a time-out occurred.
+ case WAIT_TIMEOUT:
+ case WAIT_FAILED:
+ default:
+ TRACE( "CThreadedSocket::SocketWriter( WaitForSingleObject error thread_id =( %d) )\n",writer_id);
+ if (m_hSocket != INVALID_SOCKET)
+ Close();
+ h_writer = NULL;
+ return this->GetLastError();
+ break;
+ }
+ if (m_hSocket != INVALID_SOCKET)
+ {
+ FD_SET(m_hSocket, &writefds);
+
+ err = select( 1, NULL, &writefds, NULL, NULL );
+ sock_err = this->GetLastError();
+
+ switch ( err )
+ {
+ case 0:
+ TRACE( "CThreadedSocket::SocketThread Unhandled Timeout Event !\n");
+ break;
+ case SOCKET_ERROR:
+ TRACE( "CThreadedSocketException( select )\n");
+ if ( (sock_err != WSAENOTSOCK ) && ( m_hSocket != INVALID_SOCKET )) // could be Invalid if close when in select
+ Close();
+ h_reader = NULL;
+ return sock_err;
+ break;
+ default:
+
+ if ( FD_ISSET(m_hSocket, &writefds) )
+ {
+ OnSend( sock_err );
+ }
+
+ break;
+ }
+ }
+ }
+ Close();
+ h_writer = NULL;
+ TRACE( "CThreadedSocket::SocketWriter( END thread_id =( 0x%x) )\n",writer_id);
+
+ return 0;
+}
diff --git a/Ivy/ThreadedSocket.h b/Ivy/ThreadedSocket.h
new file mode 100644
index 0000000..ad33c3e
--- /dev/null
+++ b/Ivy/ThreadedSocket.h
@@ -0,0 +1,135 @@
+// ThreadedSocket.h: interface for the CThreadedSocket class.
+//
+//////////////////////////////////////////////////////////////////////
+
+
+#pragma once
+
+
+
+class CThreadedSocket
+{
+
+public:
+ CThreadedSocket();
+ virtual ~CThreadedSocket();
+// Construction
+public:
+ int Create(unsigned int nSocketPort = 0, int nSocketType=SOCK_STREAM, const char * lpszSocketAddress = 0);
+
+// Attributes
+public:
+ SOCKET m_hSocket;
+
+ inline operator SOCKET() const { return m_hSocket; };
+
+ void GetPeerName(ivy::string & rPeerAddress, unsigned int& rPeerPort);
+
+ void GetSockName(ivy::string & rSocketAddress, unsigned int& rSocketPort);
+
+// Operations
+public:
+ SOCKET Socket(int nSocketType=SOCK_STREAM, int nProtocolType = 0, int nAddressFormat = PF_INET);
+
+ int AddMember( const char * lpszHostAddress );
+
+ virtual SOCKET Accept(CThreadedSocket& rConnectedSocket,
+ SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL);
+
+ int Bind(unsigned int nSocketPort, const char * lpszSocketAddress = 0);
+
+ virtual void Close();
+
+ int Connect(const char * lpszHostAddress, unsigned int nHostPort);
+ int Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen);
+ int Listen(int nConnectionBacklog=5);
+
+ virtual size_t Receive(void* lpBuf, size_t nBufLen, int nFlags = 0);
+
+ size_t ReceiveFrom(void* lpBuf, size_t nBufLen,
+ ivy::string & rSocketAddress, unsigned int & rSocketPort, int nFlags = 0);
+
+ enum { receives = 0, sends = 1, both = 2 };
+
+ virtual size_t Send(const void* lpBuf, size_t nBufLen, int nFlags = 0);
+
+ size_t SendTo(const void* lpBuf, size_t nBufLen,
+ unsigned int nHostPort, const char * lpszHostAddress = 0, int nFlags = 0);
+
+
+inline int GetPeerName(SOCKADDR* lpSockAddr, int* lpSockAddrLen)
+ {
+ return getpeername(m_hSocket, lpSockAddr, lpSockAddrLen);
+ }
+inline int GetSockName(SOCKADDR* lpSockAddr, int* lpSockAddrLen)
+ {
+ return getsockname(m_hSocket, lpSockAddr, lpSockAddrLen);
+ }
+inline int SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel = SOL_SOCKET)
+ {
+ return setsockopt(m_hSocket, nLevel, nOptionName, (LPCSTR)lpOptionValue, nOptionLen);
+ }
+inline int GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel = SOL_SOCKET)
+ {
+ return getsockopt(m_hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen);
+ }
+
+static inline int CThreadedSocket::GetLastError()
+ { return ::WSAGetLastError(); }
+inline int Bind(const SOCKADDR* lpSockAddr, int nSockAddrLen)
+ {
+ return bind(m_hSocket, lpSockAddr, nSockAddrLen);
+ }
+
+inline int IOCtl(long lCommand, unsigned long* lpArgument)
+ {
+ return ioctlsocket(m_hSocket, lCommand, lpArgument);
+ }
+
+inline size_t ReceiveFrom(void* lpBuf, size_t nBufLen, SOCKADDR* lpSockAddr, size_t* lpSockAddrLen, int nFlags = 0)
+ {
+ int len = (int)*lpSockAddrLen; // Non conforme a Unix
+ size_t lg = recvfrom(m_hSocket, (LPSTR)lpBuf, (int)nBufLen, nFlags, lpSockAddr, &len);
+ *lpSockAddrLen = len;
+ return lg;
+ }
+inline int ShutDown(int nHow = sends)
+ {
+ return shutdown(m_hSocket,nHow);
+ }
+inline size_t SendTo(const void* lpBuf, size_t nBufLen, const SOCKADDR* lpSockAddr, size_t nSockAddrLen, int nFlags = 0)
+ {
+ return sendto(m_hSocket, (LPSTR)lpBuf, (int)nBufLen, nFlags, lpSockAddr, (int)nSockAddrLen);
+ }
+
+
+// Overridable callbacks
+protected:
+ virtual void OnReceive(int nErrorCode);
+ virtual void OnSend(int nErrorCode);
+ virtual void OnOutOfBandData(int nErrorCode);
+ virtual void OnAccept(int nErrorCode);
+ virtual void OnConnect(int nErrorCode);
+ virtual void OnClose(int nErrorCode);
+// Implementation
+ int StartListener();
+ int StartWriter();
+ bool SignalWriter();
+
+ HANDLE h_reader;
+ HANDLE h_writer;
+ unsigned long reader_id;
+ unsigned long writer_id;
+ unsigned int SocketReader(); //Receiver Thread
+ unsigned int SocketWriter(); //Sender Thread
+ bool listen_mode;
+ bool connect_pending;
+ bool send_pending;
+ HANDLE send_count;
+
+
+// wrapper for thread routine
+static DWORD WINAPI SocketReaderProc( void * pParam );
+static DWORD WINAPI SocketWriterProc( void * pParam );
+
+};
diff --git a/Ivy/intervalRegexp.c b/Ivy/intervalRegexp.c
new file mode 100644
index 0000000..6efcd72
--- /dev/null
+++ b/Ivy/intervalRegexp.c
@@ -0,0 +1,432 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "intervalRegexp.h"
+
+#ifdef __PRETTY_FUNCTION__
+#else
+#define __PRETTY_FUNCTION__ __FUNCTION__
+#endif
+
+
+#define MAXINT( a , b ) ((a) > (b) ? (a) : (b))
+#define MININT( a , b ) ((a) < (b) ? (a) : (b))
+
+#define Perr(...) (perr ( __PRETTY_FUNCTION__, __VA_ARGS__))
+#define CHECK_AND_RETURN(a) if (strlen (locBuf) <= buflen) { \
+ strcpy (a, locBuf); \
+ return success; \
+ } else { \
+ return Perr ("CHECK_AND_RETURN"); }
+
+#define EndLocBuf (&(locBuf[strlen(locBuf)]))
+#ifdef WIN32
+#define snprintf _snprintf
+#endif
+#define AddLocBuf(...) snprintf (EndLocBuf, sizeof (locBuf)-strlen(locBuf), __VA_ARGS__)
+
+typedef struct {
+ int max;
+ int rank;
+} NextMax ;
+
+
+typedef char bool;
+
+const bool success = 1;
+const bool fail = 0;
+
+
+static bool strictPosRegexpGen (char *regexp, size_t buflen, long min, long max, const char* decimalPart,
+ const char* boundDecimalPart);
+static bool genAtRank (char *regexp, size_t buflen, const char *min, const char *max, int rank);
+static bool genPreRank (char *preRank, size_t buflen, const char *min, const char *max, int rank);
+static bool genRank (char *outRank, size_t buflen, const char *min, const char *max, int rank);
+static bool genPostRank (char *postRank, size_t buflen, int rank);
+static bool substr (char *substring, size_t buflen, const char* expr, size_t pos, size_t len);
+static char* reverse (char *string);
+static char* longtoa (char *string, size_t buflen, long n);
+static NextMax nextMax (const char *min, const char *max);
+static bool perr (const char* func, const char *fmt, ...);
+
+
+
+/*
+# __ _ _ __ _____
+# / _` | | '_ \ / ____|
+# _ __ ___ | (_| | ___ __ __ | |_) | | | __ ___ _ __
+# | '__| / _ \ \__, | / _ \ \ \/ / | .__/ | | |_ | / _ \ | '_ \
+# | | | __/ __/ | | __/ > < | | | |__| | | __/ | | | |
+# |_| \___| |___/ \___| /_/\_\ |_| \_____| \___| |_| |_|
+*/
+int regexpGen (char *regexp, size_t buflen, long min, long max, int flottant)
+{
+ char *decimalPart = "";
+ char *boundDecimalPart = "";
+ char locBuf [8192] = "(?:";
+
+
+ if (flottant) {
+ decimalPart = "(?:\\.\\d+)?";
+ boundDecimalPart = "(?:\\.0+)?";
+ }
+
+ if (min > max) {
+ int nmin = max;
+ max = min;
+ min = nmin;
+ }
+
+ if (min == max) {
+ AddLocBuf ("%ld%s", min, decimalPart);
+ } else if (min < 0) {
+ if (max < 0) {
+ // reg = '\-(?:' . strictPosRegexpGen (-max, -min, decimalPart, boundDecimalPart). ')';
+ AddLocBuf ("\\-(?:");
+ if (strictPosRegexpGen (EndLocBuf, sizeof (locBuf)-strlen(locBuf), -min, -max, decimalPart,
+ boundDecimalPart) == fail) return fail;
+ AddLocBuf (")");
+ } else if (max == 0) {
+ AddLocBuf ("(?:0%s)|(?:-0%s)|-(?:", boundDecimalPart, decimalPart);
+ if (strictPosRegexpGen (EndLocBuf, sizeof (locBuf)-strlen(locBuf), 1, -min, decimalPart,
+ boundDecimalPart)== fail) return fail;
+ AddLocBuf (")");
+ } else {
+ //reg ='(?:' . regexpGen (min, 0,withDecimal) . '|' . regexpGen (0, max, withDecimal). ')' ;
+ AddLocBuf ("(?:");
+ if (regexpGen (EndLocBuf, sizeof (locBuf)-strlen(locBuf), min, 0, flottant)== fail) return fail;
+ AddLocBuf ("|");
+ if (regexpGen (EndLocBuf, sizeof (locBuf)-strlen(locBuf), 0, max, flottant)== fail) return fail;
+ AddLocBuf (")");
+ }
+ } else if (min == 0) {
+ // reg = "(?:0{decimalPart})|" . strictPosRegexpGen (1, max, decimalPart,boundDecimalPart) ;
+ AddLocBuf ("(?:0%s)|",decimalPart);
+ if (strictPosRegexpGen (EndLocBuf, sizeof (locBuf)-strlen(locBuf), 1, max, decimalPart,
+ boundDecimalPart)== fail) return fail;
+ } else {
+ if (strictPosRegexpGen (EndLocBuf, sizeof (locBuf)-strlen(locBuf), min, max, decimalPart,
+ boundDecimalPart)== fail) return fail;
+ }
+
+ AddLocBuf (")(?![\\d.])");
+ CHECK_AND_RETURN (regexp);
+}
+
+/*
+# _ _ _ _____
+# | | (_) | | | __ \
+# ___ | |_ _ __ _ ___ | |_ | |__) | ___ ___
+# / __| | __| | '__| | | / __| | __| | ___/ / _ \ / __|
+# \__ \ \ |_ | | | | | (__ \ |_ | | | (_) | \__ \
+# |___/ \__| |_| |_| \___| \__| |_| \___/ |___/
+# _____ __ _ _ __ _____
+# | __ \ / _` | | '_ \ / ____|
+# | |__) | ___ | (_| | ___ __ __ | |_) | | | __ ___ _ __
+# | _ / / _ \ \__, | / _ \ \ \/ / | .__/ | | |_ | / _ \ | '_ \
+# | | \ \ | __/ __/ | | __/ > < | | | |__| | | __/ | | | |
+# |_| \_\ \___| |___/ \___| /_/\_\ |_| \_____| \___| |_| |_|
+*/
+static bool strictPosRegexpGen (char *regexp, size_t buflen, long min, long max, const char* decimalPart,
+ const char* boundDecimalPart)
+{
+
+#define maxSubReg 64
+#define digitRegSize 128
+
+ char regList[maxSubReg][digitRegSize];
+ char locBuf[maxSubReg*digitRegSize] ;
+ size_t regIndex=0,i;
+ size_t nbRank;
+ char maxAsString[32], minAsString[32];
+ NextMax nMax;
+
+
+ if ((min <= 0) || (max <= 0)) return Perr ("min or max <= 0");
+ if (min == max) {
+ sprintf (EndLocBuf, "%ld", max);
+ } else {
+
+ max--;
+
+ nbRank = strlen (longtoa (maxAsString, sizeof (maxAsString), max));
+ do {
+ nMax = nextMax (longtoa (minAsString, sizeof (minAsString), min),
+ longtoa (maxAsString, sizeof (maxAsString), max));
+ if (genAtRank (regList[regIndex++], digitRegSize, minAsString,
+ longtoa (maxAsString, sizeof (maxAsString),
+ nMax.max), nMax.rank) == fail) return fail;
+ if (regIndex == maxSubReg) return Perr ("regIndex == maxSubReg");
+ min = nMax.max +1;
+ } while (nMax.max != max);
+
+ locBuf[0] = 0;
+ for (i=0; i<regIndex; i++) {
+ sprintf (EndLocBuf, "(?:%s%s)|", regList[i], decimalPart);
+ }
+
+ if (locBuf[strlen(locBuf)-1] == '|') {
+ locBuf[strlen(locBuf)-1] = 0;
+ }
+ max++;
+ sprintf (EndLocBuf, "|(?:%s%s)",
+ longtoa (maxAsString, sizeof (maxAsString), max), boundDecimalPart);
+ }
+
+ CHECK_AND_RETURN (regexp);
+}
+
+/*
+# _ __ __
+# | | | \/ |
+# _ __ ___ __ __ | |_ | \ / | __ _ __ __
+# | '_ \ / _ \ \ \/ / | __| | |\/| | / _` | \ \/ /
+# | | | | | __/ > < \ |_ | | | | | (_| | > <
+# |_| |_| \___| /_/\_\ \__| |_| |_| \__,_| /_/\_\
+*/
+static NextMax nextMax (const char *min, const char *max)
+{
+ NextMax nextMax ={0,0};
+ char revMin[32], revMax[32];
+ size_t nbDigitsMin, nbDigitsMax;
+ size_t rankRev=0, rankForw, rank=0;
+ int i;
+ int currMax;
+
+ nbDigitsMin = strlen (min);
+ nbDigitsMax = strlen (max);
+
+ for (i=nbDigitsMin-1; i >= 0; i--) {
+ revMin[nbDigitsMin-i-1]= min[i];
+ // printf ("DBG> nextMax revMin[%d]= %c\n", nbDigitsMin-i-1, min[i]);
+ }
+ for (i=nbDigitsMax-nbDigitsMin; i >= 0; i--) {
+ revMin[nbDigitsMax-i]= '0';
+ // printf ("DBG> nextMax revMin[%d]= %c\n", nbDigitsMax-i, '0');
+ }
+
+ for (i=nbDigitsMax-1; i >= 0; i--) {
+ revMax[nbDigitsMax-i-1]= max[i];
+ }
+ revMin[nbDigitsMax] = revMax[nbDigitsMax] = 0;
+ rankForw = nbDigitsMax -1;
+
+ // printf ("DBG> nextMax rev(%s)=%s rev(%s)=%s rankForw=%d\n", min, revMin, max, revMax, rankForw);
+
+ // en partant des unitées (digit de poids faible), premier digit de min != 0
+ while ((revMin[rankRev] == '0') && (rankRev < nbDigitsMax)) rankRev++;
+ // en partant du digit de poids fort, premier digit de max != du même digit de revMin
+ while ((revMin[rankForw] == revMax[rankForw]) && rankForw > 0) rankForw--;
+
+ if (rankForw <= rankRev) {
+ rank = rankForw;
+ revMin[rankForw]= revMax[rankForw] - (rankForw ? 1 : 0);
+ for (i=0; i<rankForw; i++) revMin[i] = '9';
+ } else {
+ rank = rankRev;
+ for (i=0; i<=rankRev; i++) revMin[i] = '9';
+ }
+
+ nextMax.max = atoi (reverse (revMin));
+ nextMax.rank = rank+1;
+
+ currMax = atoi (max);
+ if (nextMax.max > currMax) nextMax.max = currMax;
+
+ // printf ("DBG> nextMax ('%s', '%s') = %d@%d\n", min, max, nextMax.max, nextMax.rank);
+ return (nextMax);
+}
+
+
+/*
+# __ _ ____ _
+# / _` | / __ \ | |
+# | (_| | ___ _ __ / / _` | _ __ __ _ _ __ | | _
+# \__, | / _ \ | '_ \ | | (_| | | '__| / _` | | '_ \ | |/ /
+# __/ | | __/ | | | | \ \__,_| | | | (_| | | | | | | <
+# |___/ \___| |_| |_| \____/ |_| \__,_| |_| |_| |_|\_\
+*/
+static bool genAtRank (char *regexp, size_t buflen, const char *min, const char *max, int rank)
+{
+ char locBuf [512];
+
+ if (genPreRank (locBuf, sizeof (locBuf), min, max, rank) == fail) return (fail);
+ if (genRank (EndLocBuf, sizeof (locBuf)-strlen(locBuf), min, max, rank) == fail) return (fail);
+ if (genPostRank (EndLocBuf, sizeof (locBuf)-strlen(locBuf), rank) == fail) return (fail);
+
+
+ CHECK_AND_RETURN (regexp);
+}
+
+/*
+# __ _ _____ _____ _
+# / _` | | __ \ | __ \ | |
+# | (_| | ___ _ __ | |__) | _ __ ___ | |__) | __ _ _ __ | | _
+# \__, | / _ \ | '_ \ | ___/ | '__| / _ \ | _ / / _` | | '_ \ | |/ /
+# __/ | | __/ | | | | | | | | | __/ | | \ \ | (_| | | | | | | <
+# |___/ \___| |_| |_| |_| |_| \___| |_| \_\ \__,_| |_| |_| |_|\_\
+*/
+static bool genPreRank (char *preRank, size_t buflen, const char *min, const char *max, int rank)
+{
+ char locBuf [512], locBufMax[512];
+ const char *lmin, *lmax;
+ int i=0, j=0;
+
+ while (min[i] == '0') i++;
+ while (max[j] == '0') j++;
+
+ lmin = &(min[i]);
+ lmax = &(max[j]);
+
+ // printf ("DBG> genPreRank (lmin='%s'[%d], lmax='%s'[%d], rank=%d\n", lmin, (int) strlen (lmin), lmax,
+ // (int) strlen (lmax), rank);
+
+ if (substr (locBuf, sizeof (locBuf), lmin, 0, strlen (lmin) - rank) == fail) return fail;
+ if (substr (locBufMax, sizeof (locBufMax), lmax, 0, strlen (lmax) - rank) == fail) return fail;
+
+ if (strncmp (locBuf, locBufMax, MININT (sizeof (locBuf), sizeof (locBufMax))) != 0)
+ return Perr ("min=%s[%s] and max=%s[%s] should be invariants at rank %d", locBuf, min, locBufMax, max, rank);
+
+ // printf ("DBG> genPreRank ('%s', '%s', %d) = '%s'\n", min, max, rank, locBuf);
+
+ CHECK_AND_RETURN (preRank);
+}
+
+
+/*
+# __ _ _____ _
+# / _` | | __ \ | |
+# | (_| | ___ _ __ | |__) | __ _ _ __ | | _
+# \__, | / _ \ | '_ \ | _ / / _` | | '_ \ | |/ /
+# __/ | | __/ | | | | | | \ \ | (_| | | | | | | <
+# |___/ \___| |_| |_| |_| \_\ \__,_| |_| |_| |_|\_\
+*/
+static bool genRank (char *outRank, size_t buflen, const char *min, const char *max, int rank)
+{
+ char locBuf [512];
+
+ char a,b,lmin,lmax;
+ a = min[strlen(min)-rank];
+ b = max[strlen(max)-rank];
+
+ lmin = MININT (a,b);
+ lmax = MAXINT (a,b);
+
+ if ((lmin == '0') && (lmax == '9')) {
+ strcpy (locBuf, "\\d");
+ } else if (lmin == lmax) {
+ locBuf[0] = lmin;
+ locBuf[1] = 0;
+ } else if (lmax == (lmin+1)) {
+ sprintf (locBuf, "[%c%c]", lmin, lmax);
+ } else {
+ sprintf (locBuf, "[%c-%c]", lmin, lmax);
+ }
+
+ CHECK_AND_RETURN (outRank);
+}
+
+/*
+# __ _ _____ _ _____
+# / _` | | __ \ | | | __ \
+# | (_| | ___ _ __ | |__) | ___ ___ | |_ | |__) | __ _ _ __
+# \__, | / _ \ | '_ \ | ___/ / _ \ / __| | __| | _ / / _` | | '_ \
+# __/ | | __/ | | | | | | | (_) | \__ \ \ |_ | | \ \ | (_| | | | | |
+# |___/ \___| |_| |_| |_| \___/ |___/ \__| |_| \_\ \__,_| |_| |_|
+*/
+static bool genPostRank (char *postRank, size_t buflen, int rank)
+{
+ char locBuf [512];
+
+ if (rank <= 1) {
+ strcpy (locBuf, "");
+ } else if (rank == 2) {
+ sprintf (locBuf, "\\d");
+ } else {
+ sprintf (locBuf, "\\d{%d}", rank -1);
+ }
+
+ CHECK_AND_RETURN (postRank);
+}
+
+/*
+# _ _
+# | | | |
+# ___ _ _ | |__ ___ | |_ _ __
+# / __| | | | | | '_ \ / __| | __| | '__|
+# \__ \ | |_| | | |_) | \__ \ \ |_ | |
+# |___/ \__,_| |_.__/ |___/ \__| |_|
+*/
+static bool substr (char *substring, size_t buflen, const char* expr, size_t pos, size_t len)
+{
+ char locBuf [512];
+ size_t i, j=0;
+
+ len = MAXINT (0, MININT (len, strlen (expr) - pos));
+ for (i=pos; i<(pos+len); i++) {
+ locBuf[j++]= expr[i];
+ }
+ locBuf[j] = 0;
+
+ // printf ("DBG> substr ('%s', %d, %d) = '%s'\n", expr, pos, len, locBuf);
+ CHECK_AND_RETURN (substring);
+}
+
+/*
+#
+#
+# _ __ ___ __ __ ___ _ __ ___ ___
+# | '__| / _ \ \ \ / / / _ \ | '__| / __| / _ \
+# | | | __/ \ V / | __/ | | \__ \ | __/
+# |_| \___| \_/ \___| |_| |___/ \___|
+*/
+static char* reverse (char *string)
+{
+ char *locBuf ;
+ int i;
+ size_t len = strlen (string);
+
+ locBuf = malloc (len+1);
+ for (i=len-1; i >= 0; i--) {
+ locBuf[len-i-1]= string[i];
+ //printf ("DBG> reverse locBuf[%d]= %c\n",len- i-1, string[i]);
+ }
+ locBuf [len] = 0;
+
+ // printf ("DBG> reverse '%s' = '%s'\n", string, locBuf);
+ strcpy (string, locBuf);
+ free (locBuf);
+ return (string);
+}
+
+static char* longtoa (char *string, size_t buflen, long n)
+{
+ snprintf (string, buflen, "%ld", n);
+ return (string);
+}
+
+
+/*
+# _ __
+# | '_ \
+# | |_) | ___ _ __ _ __
+# | .__/ / _ \ | '__| | '__|
+# | | | __/ | | | |
+# |_| \___| |_| |_|
+*/
+static bool perr (const char* func, const char *fmt, ...)
+{
+ char err[4096], buffer[2048];
+ va_list args;
+ va_start( args, fmt );
+ vsprintf( buffer, fmt, args );
+ va_end( args );
+
+
+ sprintf (err, "Erreur %s @ %s\n", buffer, func);
+ fprintf (stderr, err);
+ return (fail);
+}
diff --git a/Ivy/intervalRegexp.h b/Ivy/intervalRegexp.h
new file mode 100644
index 0000000..c1176ff
--- /dev/null
+++ b/Ivy/intervalRegexp.h
@@ -0,0 +1,14 @@
+#ifndef INTERVALREGEXP_H
+#define INTERVALREGEXP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int regexpGen (char *regexp, size_t buflen, long min, long max, int flottant);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif