summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog116
-rw-r--r--debian/compat1
-rw-r--r--debian/control28
-rw-r--r--debian/dirs7
-rw-r--r--debian/ivy-c-dev.dirs2
-rw-r--r--debian/ivy-c-dev.files9
-rw-r--r--debian/ivy-c-dev.install8
-rw-r--r--debian/ivy-c.dirs3
-rw-r--r--debian/ivy-c.install4
-rwxr-xr-xdebian/rules124
-rw-r--r--debian/substvars1
-rw-r--r--doc/ChangeLog1256
-rw-r--r--doc/ivy-c-functions.164
-rw-r--r--doc/ivy-c.110
-rw-r--r--doc/ivy-c.sgml114
-rw-r--r--examples/gtkIvyButton.c6
-rw-r--r--examples/motifButtonIvy.c4
-rw-r--r--examples/testUnbind.c11
-rw-r--r--redhat/changelog105
-rw-r--r--redhat/files15
-rw-r--r--redhat/rules21
-rw-r--r--redhat/rules-devel17
-rw-r--r--src/Makefile193
-rwxr-xr-xsrc/Makefile.mingw2
-rwxr-xr-xsrc/Makefile.win3249
-rwxr-xr-xsrc/hash.c665
-rwxr-xr-xsrc/hash.h29
-rw-r--r--src/intervalRegexp.c432
-rw-r--r--src/intervalRegexp.h14
-rw-r--r--src/ivy.c1045
-rw-r--r--src/ivy.h71
-rwxr-xr-xsrc/ivyargument.c180
-rwxr-xr-xsrc/ivyargument.h35
-rw-r--r--src/ivybind.c249
-rw-r--r--src/ivybind.h22
-rw-r--r--src/ivybuffer.c82
-rw-r--r--src/ivybuffer.h39
-rw-r--r--src/ivychannel.h19
-rw-r--r--src/ivydebug.h30
-rw-r--r--src/ivyglibloop.c26
-rw-r--r--src/ivyglibloop.h3
-rwxr-xr-xsrc/ivyglutloop.c28
-rwxr-xr-xsrc/ivyglutloop.h6
-rw-r--r--src/ivyloop.c66
-rw-r--r--src/ivyloop.h37
-rwxr-xr-xsrc/ivyperf.c71
-rw-r--r--src/ivyprobe.c333
-rw-r--r--src/ivysocket.c408
-rw-r--r--src/ivysocket.h31
-rwxr-xr-xsrc/ivytcl.c21
-rwxr-xr-xsrc/ivytcl.h6
-rw-r--r--src/ivyxtloop.c29
-rw-r--r--src/ivyxtloop.h8
-rw-r--r--src/libIvy.def28
-rw-r--r--src/list.h42
-rw-r--r--src/timer.c35
-rw-r--r--src/timer.h2
-rw-r--r--src/version.h8
58 files changed, 3495 insertions, 2775 deletions
diff --git a/debian/changelog b/debian/changelog
index 32cbc1b..9430f61 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,10 +1,122 @@
+ivy-c (3.9.1-2) unstable; urgency=low
+
+ * Update package for Debian Etch
+
+ -- Olivier Fourdan <fourdan@false> Fri, 12 Jan 2007 14:35:44 +0100
+
+ivy-c (3.9.1-1) unstable; urgency=low
+
+ * Build Debian Package with Alex's latest changes, implementing numerical
+ interval support within the regular expression definition.
+
+ -- Olivier Fourdan <fourdan@lerak.tls.cena.fr> Wed, 20 Sep 2006 17:42:42 +0200
+
+ivy-c (3.9.0-2) unstable; urgency=low
+
+ * Build Debian Package with Alex's latest changes, implementing ping/pong
+ messages, and documentation update.
+
+ -- Olivier Fourdan <fourdan@lerak.tls.cena.fr> Mon, 21 Aug 2006 10:11:47 +0200
+
+ivy-c (3.9.0-1) unstable; urgency=low
+
+ * Correction d'un petit pb dans la generation de l'appID ( signe - )
+ * Ajout test de controle des argument de IvySendMsg.
+ * Correction d'un BUG dans IvyGetMessages ( si nb > 200 ) ajout d'un
+ argument -f a ivyprobe pour passer des regexps dans un fichier.
+ * Ajout d'un warning si la variable IVY_DEBUG_FILTER est postionne et que le
+ message n'est pas emit , on controle la table des filtres ajout d'un flag
+ -c a ivyprobe pour la gestion des filtres de regexps.
+ * Modification API Hook sur IvyMainLoop.
+ * Mise en conformite avec prototype.
+ * Modification de l'emplacement du calcul du timer (juste avant le select )
+ la fonction TimerScan ne s'occupe que des callback la fonction
+ TimerGetSmallestTimeout recalcul le timeout en reprenant l'heure courante.
+
+ -- Olivier Fourdan <fourdan@lerak.tls.cena.fr> Tue, 4 Jul 2006 16:03:58 +0200
+
+ivy-c (3.8.1-1) unstable; urgency=low
+
+ * Bug fix in IvyBinding filtering with PCRE (bustico)
+ * Bug fix in IvyBinding when not using PCRE (fcolin)
+
+ -- Olivier Fourdan <fourdan@lerak.tls.cena.fr> Thu, 1 Jun 2006 14:27:08 +0200
+
+ivy-c (3.8-2) unstable; urgency=low
+
+ * Include deps patch from Yannick.
+
+ -- Olivier Fourdan <fourdan@lerak.tls.cena.fr> Tue, 30 May 2006 15:30:08 +0200
+
+ivy-c (3.8-1) unstable; urgency=low
+
+ * suppression warning format
+ * portage WIN32 random => rand
+ * modification du protocol Ivy UDP : ajout de appid et appname dans
+ le mesage Hello
+ * rework the Makefile for cleaner installation
+ * redo the debian packaging administration files for better lib/dev
+ files splitting
+ * move the Ivy header files to a new Ivy/ subdir to avoid conflicts
+ with other existing system headers (beware, that *will* break
+ existing code that needs to look in the the new path for headers
+ inclusion)
+ * correction Bug regexp encore
+ * correction Bug introduit lors de la separation ivybind ( regexp sans
+ argument )
+ * rendu compatible avec la version 3.7 a un seul parametre sur la mainloop
+ * adaptation pour linux 64 bits
+ * cleanup sur channel et main loop
+ * ajout de getopt pour la compile sur Windows
+ * suppression de l'indirection sur les fonction channel et renomage
+ * separation regexp en module ( bug arg num edbute a 1 )
+ * Separation du code Regexp dans un module
+ * portage WIN32 ( pb sur macro debug )
+ * ivy bind pour isolation code regexp
+ * gestion de buffer a taille variable pour eliminer les pbs de taille static
+ dans le code
+ * Macro de debug afin d'eviter de truffer le code de #ifdef DEBUG #endif
+ * cleanup DEBUG code
+ * correction bug sur filtrage regexp
+ * correction Filtred Binding + test avec ivyperf
+ * add indication on regexp filtering when classes are used call
+ BindingCallback
+ * add doc printf for commande bincall in ivyprobe
+ * correction de probleme potentiel en multithread ( Ada rejeu ) ajout d'un
+ warning en cas de client bloquant si la varaiable d'env IVY_DEBUG_SEND est
+ positionne
+ * changement version suite a modif ( hook unhook ) et test sur blocage a
+ l'emission
+ * retour au protocol V3
+ * correction bug malloc free
+ * memory leak malloc/free cleanup
+ * Implementation binding simple sans regexp
+ * uniformisation variable message d'erreur
+ * remplacement argc argv par IvyArgument
+ * compile sur Windows les fichiers getopt sont necessaires uniquement sur
+ Windows( WIN32 ) compilateur VStudio
+ * gestion argument Ivy
+ * socket Buffered output
+ * separation du code regexp dans un module a part en vue de l'implementation
+ des bindings simple!
+ * fichiers d'export pour Windows
+ * pb de compile avec DEBUG
+ * portages des modifications sur windows
+ * un test de performance d'ivy a lancer en deux exemplaires donne le temps
+ de roundtrip d'un ping pong
+ * elimination des tailles de buffer par utilisation de realloc la plupart
+ des fonctions utilisent un pointeur static pour eviter de multiple
+ malloc/free ce qui veut dire que IvyC n'est pas reentrant !!!!
+
+ -- Olivier Fourdan <fourdan@lerak.tls.cena.fr> Wed, 17 May 2006 15:09:07 +0200
+
ivy-c (3.7) unstable; urgency=low
- * no more libgtkivy, replaced by libgivy (thx Alexandre Bustico <bustico@cena.fr>)
+ * no more libgtkivy, replaced by libgivy (thx Alexandre Bustico <bustico@cena.fr>)
* Add new callback to treat binding events on ivy bus (Guillaume Vidon <vidon@cena.fr>)
* Add Option to ivyprobe to test new callback on binding events
- --
+ -- Guillaume Vidon <vidon@cena.fr> Fri, 24 Feb 2005 16:16:39 +0100
ivy-c (3.6) unstable; urgency=low
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..b8626c4
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+4
diff --git a/debian/control b/debian/control
index 7f3e616..1325974 100644
--- a/debian/control
+++ b/debian/control
@@ -1,26 +1,28 @@
Source: ivy-c
-Section: devel
Priority: extra
-Maintainer: Yannick Jestin <jestin@cena.fr>
-Standards-Version: 3.1.1.1
+Section: devel
+Maintainer: Alexandre Bustico <alexandre.bustico@cena.fr>
+Build-Depends: debhelper (>> 4.0.0), libc6-dev, xlibs-dev | libx11-dev | xorg-dev, tcl8.4-dev, libgtk1.2-dev, libglib2.0-dev, libpcre3-dev
+Standards-Version: 3.6.1
-Package: ivy-c
+Package: ivy-c-dev
+Section: libdevel
Architecture: any
-Depends: ${shlibs:Depends}
-Build-Depends: debhelper, libc6-dev, xlibs-dev, tcl8.4-dev, libgtk1.2-dev, libpcre3-dev
+Depends: ivy-c (= ${Source-Version}), libc6-dev, xlibs-dev | libx11-dev | xorg-dev, libgtk1.2-dev, libglib2.0-dev
Suggests: tclsh, wish
-Conflicts: ivy-tcl
-Description: Ivy software bus. runtime Package
+Description: Ivy software bus. development Package
+ This package is needed for compiling applications using ivy-c.
Ivy is mostly a communication convention between processes, implemented
- through a collection of libraries in several languages and for several platforms:
+ through a collection of libraries in several languages and for several platforms,
from C to Perl, from Macintosh or WindowsNT to Linux or Unix.
-Package: ivy-c-dev
+Package: ivy-c
+Section: libs
Architecture: any
-Depends: ivy-c (>= 3.2-3), libc6-dev, xlibs-dev, libgtk1.2-dev
+Depends: ${shlibs:Depends}
Suggests: tclsh, wish
-Description: Ivy software bus. development Package
- This package is needed for compiling applications using ivy-c.
+Conflicts: ivy-tcl
+Description: Ivy software bus. runtime Package
Ivy is mostly a communication convention between processes, implemented
through a collection of libraries in several languages and for several platforms:
from C to Perl, from Macintosh or WindowsNT to Linux or Unix.
diff --git a/debian/dirs b/debian/dirs
index e09a7e3..6593239 100644
--- a/debian/dirs
+++ b/debian/dirs
@@ -1,7 +1,4 @@
-usr/man/man1
+usr/X11R6/lib
usr/lib
usr/bin
-usr/X11R6/lib
-usr/X11R6/bin
-usr/include
-usr/man/man3
+usr/man/man1
diff --git a/debian/ivy-c-dev.dirs b/debian/ivy-c-dev.dirs
new file mode 100644
index 0000000..db43e9f
--- /dev/null
+++ b/debian/ivy-c-dev.dirs
@@ -0,0 +1,2 @@
+usr/include/Ivy
+usr/lib
diff --git a/debian/ivy-c-dev.files b/debian/ivy-c-dev.files
deleted file mode 100644
index 73fa322..0000000
--- a/debian/ivy-c-dev.files
+++ /dev/null
@@ -1,9 +0,0 @@
-usr/include
-usr/lib/libivy.a
-usr/lib/libivy.so
-usr/lib/libgivy.a
-usr/lib/libgivy.so
-usr/lib/libtclivy.a
-usr/lib/libtclivy.so
-usr/X11R6/lib/libxtivy.a
-usr/X11R6/lib/libxtivy.so
diff --git a/debian/ivy-c-dev.install b/debian/ivy-c-dev.install
new file mode 100644
index 0000000..d73b978
--- /dev/null
+++ b/debian/ivy-c-dev.install
@@ -0,0 +1,8 @@
+usr/lib/*.so
+usr/lib/*.a
+usr/lib/*.la
+usr/X11R6/lib/*.so
+usr/X11R6/lib/*.a
+usr/X11R6/lib/*.la
+usr/include/Ivy/*.h
+usr/lib/pkgconfig/*
diff --git a/debian/ivy-c.dirs b/debian/ivy-c.dirs
new file mode 100644
index 0000000..d0ebc38
--- /dev/null
+++ b/debian/ivy-c.dirs
@@ -0,0 +1,3 @@
+usr/lib
+usr/bin
+usr/man/man1
diff --git a/debian/ivy-c.install b/debian/ivy-c.install
new file mode 100644
index 0000000..38010b3
--- /dev/null
+++ b/debian/ivy-c.install
@@ -0,0 +1,4 @@
+usr/X11R6/lib/*.so.*
+usr/lib/*.so.*
+usr/bin/*
+usr/man/man1/*
diff --git a/debian/rules b/debian/rules
index e78e6a8..ccdbd89 100755
--- a/debian/rules
+++ b/debian/rules
@@ -2,77 +2,69 @@
# Made with the aid of debmake, by Christoph Lameter,
# based on the sample debian/rules file for GNU hello by Ian Jackson.
+# Uncomment this to turn on verbose mode.
+export DH_VERBOSE=1
+
SED_COMMAND='s/.*(\([^)]*\)).*/\1/p'
MAJOR := $(shell sed -n $(SED_COMMAND) debian/changelog | head -1 | sed -n 's/\([0-9]*\)\..*/\1/p')
MINOR := $(shell sed -n $(SED_COMMAND) debian/changelog | head -1 | sed -n 's/[0-9]*\.\([0-9\.]*\).*/\1/p')
-package=ivy-c
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ # Add here commands to configure the package.
+ touch configure-stamp
-build:
- $(checkdir)
- cd src && make all MAJOR=$(MAJOR) MINOR=$(MINOR) TCLINC=$(-I/usr/include/tcl8.3/) TCLLIB=$(-ltcl8.3) CFLAGS="-g -fPIC -D_REENTRANT"
- touch build
+build: build-stamp
+build-stamp: configure-stamp
+ dh_testdir
+ cd src && $(MAKE) all MAJOR=$(MAJOR) MINOR=$(MINOR) TCLINC=$(-I/usr/include/tcl8.4/) TCLLIB=$(-ltcl8.4) CFLAGS="-g -fPIC -D_REENTRANT"
+ touch build-stamp
clean:
- $(checkdir)
- -rm -f build
- -rm -rf debian/tmp debian/*~ debian/copyright `find debian/* -type d ! -name CVS` debian/files* core
- -rm -f debian/*substvars
- cd src && make clean
-
-binary-indep: checkroot build
- $(checkdir)
-# There are no architecture-independent files to be uploaded
-# generated by this package. If there were any they would be
-# made here.
-
-binary-arch: checkroot build
- $(checkdir)
- -rm -rf debian/tmp `find debian/* -type d ! -name CVS`
- install -d debian/tmp
- cd debian/tmp && install -d `cat ../dirs`
-
- cd src && make installlibs PREFIX=`pwd`/../debian/tmp MAJOR=$(MAJOR) MINOR=$(MINOR)
- cd src && make installbins PREFIX=`pwd`/../debian/tmp
- cd src && make installdocs PREFIX=`pwd`/../debian/tmp
-
- -rm debian/tmp/usr/include/list.h # it's yet in utils-c-dev
- -cp src/version.h debian/copyright
- #dh_strip debian/tmp/usr/lib/libivy.so.$(MAJOR).$(MINOR)
- strip debian/tmp/usr/lib/libivy.so.$(MAJOR).$(MINOR)
- #dh_strip debian/tmp/usr/lib/libtclivy.so.$(MAJOR).$(MINOR)
- strip debian/tmp/usr/lib/libtclivy.so.$(MAJOR).$(MINOR)
- #dh_strip debian/tmp/usr/X11R6/lib/libxtivy.so.$(MAJOR).$(MINOR)
- strip debian/tmp/usr/X11R6/lib/libxtivy.so.$(MAJOR).$(MINOR)
-
- dh_link usr/lib/libivy.so.$(MAJOR).$(MINOR) usr/lib/libivy.so.$(MAJOR)
- dh_link usr/lib/libgivy.so.$(MAJOR).$(MINOR) usr/lib/libgivy.so.$(MAJOR)
- dh_link usr/lib/libtclivy.so.$(MAJOR).$(MINOR) usr/lib/libtclivy.so.$(MAJOR)
- dh_link usr/X11R6/lib/libxtivy.so.$(MAJOR).$(MINOR) usr/X11R6/lib/libxtivy.so.$(MAJOR)
- dh_link usr/lib/libivy.so.$(MAJOR).$(MINOR) usr/lib/libivy.so
- dh_link usr/lib/libgivy.so.$(MAJOR).$(MINOR) usr/lib/libgivy.so
- dh_link usr/lib/libtclivy.so.$(MAJOR).$(MINOR) usr/lib/libtclivy.so
- dh_link usr/X11R6/lib/libxtivy.so.$(MAJOR).$(MINOR) usr/X11R6/lib/libxtivy.so
-
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+ cd src && $(MAKE) clean
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+ cd src && $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp PREFIX=/usr
+
+binary-indep: build install
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs
+ dh_installdocs
+ dh_installexamples
+ dh_install --source=$(CURDIR)/debian/tmp
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+ dh_strip
+ dh_compress
dh_fixperms
-
- debstd doc/man-ivy-c.html doc/ivy-c-*.html
-
- -rmdir debian/tmp/usr/include
-
- dpkg-gencontrol -p$(package) -isp
- dpkg --build debian/tmp ..
-
-define checkdir
- test -f debian/rules
-endef
-
-# Below here is fairly generic really
-
-binary: binary-indep binary-arch
-
-checkroot:
- $(checkdir)
- test root = "`whoami`"
-
-.PHONY: binary binary-arch binary-indep clean checkroot
+# dh_perl
+# dh_python
+# dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/debian/substvars b/debian/substvars
new file mode 100644
index 0000000..dc83102
--- /dev/null
+++ b/debian/substvars
@@ -0,0 +1 @@
+shlibs:Depends=libc6 (>= 2.3.2.ds1-21), libglib2.0-0 (>= 2.6.0), libice6, libpcre3 (>= 4.5), libsm6, libx11-6, libxt6
diff --git a/doc/ChangeLog b/doc/ChangeLog
index ddcf56a..114f7aa 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,40 +1,1240 @@
-ivy-c (3.1)
+2006-05-19 12:35 fcolin
- * src/Makefile : Ajout de liens pour les libs paratagées
- * Ajout du majeur et du mineur
- * Making ivyprobe ivy-3.0 compliant
- * Bug correction which appears at ivy closing
-
- --
+ * ivy-c/src/ivy.c: suppression warning format
-ivy-c (3.0)
+2006-05-19 12:33 fcolin
- * new api : see documentation
- * src/Makefile : updates
- * src/ivy.c
- * - bug correction when broadcast socket can't be opened
- * src/ivychannel.c :
- * - bug correction when handling expceptions on channels
- * Clean headers
- * testivy -> ivyprobe
+ * ivy-c/src/ivy.c: portage WIN32 random => rand
- --
+2006-05-19 11:45 fcolin
-ivy-c (1.2)
+ * ivy-c/src/ivy.c: modification du protocol Ivy UDP : ajout de
+ appid et appname dans le mesage Hello
- * Mise au propre
- * Ajout du mecanisme de choix des adresses de broadcast
+2006-05-18 14:05 fourdan
- --
+ * ivy-c/debian/changelog: Update debian changelog accordingly
-ivy-c (1.1)
+2006-05-18 13:20 fourdan
- * Suppression du header list.h qui est aussi défini dans utils-c.
- * Ajout du soname à la bibliothèque dynamique.
-
- --
+ * ivy-c/doc/ChangeLog: Update ChangeLog
-ivy-c (1.1)
+2006-05-18 13:18 fourdan
- * Initial Release.
+ * ivy-c/: debian/compat, debian/control, debian/dirs,
+ debian/ivy-c-dev.dirs, debian/ivy-c-dev.files,
+ debian/ivy-c-dev.install, debian/ivy-c.dirs,
+ debian/ivy-c.install, debian/rules, debian/substvars,
+ examples/Makefile, examples/Test.tcl, examples/button.tk,
+ examples/gtkIvyButton.c, examples/motifButtonIvy.c,
+ examples/testUnbind.c, examples/unBind.tcl, src/Makefile: Rework
+ the Makefile for cleaner installation, redo the debian packaging
+ administration files for better lib/dev files splitting, move the
+ Ivy header files to a new Ivy/ subdir to avoid conflicts with
+ other existing system headers (beware, that *will* break existing
+ code that needs to look in the the new path for headers
+ inclusion)
+
+2006-05-17 15:31 fourdan
+
+ * ivy-c/: debian/README, debian/changelog, debian/control,
+ debian/dirs, debian/ivy-c-dev.files, debian/rules, doc/BUGS,
+ doc/ChangeLog, doc/NEWS, doc/README, doc/TODO,
+ doc/ivy-c-functions.1, doc/ivy-c.1, doc/ivy-c.sgml,
+ doc/ivyprobe.1: Put back the missing bits which were lost when
+ the branch protocol_v3 was created, prepare a new debian package
+
+2006-05-11 19:20 fcolin
+
+ * ivy-c/src/ivybind.c: correction BUg regexp encore
+
+2006-05-11 18:42 fcolin
+
+ * ivy-c/src/: ivy.c, ivybind.c: correction Bug introduit lors de la
+ separation ivybind ( regexp sans argument )
+
+2006-05-11 18:13 fcolin
+
+ * ivy-c/src/ivyloop.c: rendu compatible avec la version 3.7 a un
+ suel parametre sur la mainloop
+
+2006-05-11 18:06 bustico
+
+ * ivy-c/src/Makefile:
+ adaptation pour linux 64 bits
+
+2006-04-21 18:34 fcolin
+
+ * ivy-c/src/: ivy.c, ivychannel.h, ivyglibloop.c, ivyglibloop.h,
+ ivyglutloop.c, ivyglutloop.h, ivyloop.c, ivyprobe.c, ivytcl.c,
+ ivyxtloop.c, ivyxtloop.h: cleanup sur channel et main loop
+
+2006-04-21 17:54 fcolin
+
+ * ivy-c/src/: getopt.c, getopt.h: ajout de getopt pour la compile
+ sur Windows
+
+2006-04-21 17:51 fcolin
+
+ * ivy-c/src/: Makefile.win32, ivy.c, ivybind.c, ivybind.h,
+ ivychannel.h, ivyloop.c, ivyloop.h, ivyprobe.c, ivysocket.c,
+ libIvy.def: suppression de l'indirection sur les fonction channel
+ et renomage !
+
+2006-04-21 14:49 fcolin
+
+ * ivy-c/src/: Makefile, Makefile.win32, ivy.c, ivybind.c,
+ ivyperf.c: separation regexp en module ( bug arg num edbute a 1 )
+
+2006-04-21 14:13 fcolin
+
+ * ivy-c/src/: ivy.c, ivy.h, ivybind.c, ivybind.h: Separation du
+ code Regexp dans un module
+
+2006-04-21 11:49 fcolin
+
+ * ivy-c/src/ivydebug.h: et aussi pour la version sans le DEBUG
+
+2006-04-21 11:38 fcolin
+
+ * ivy-c/src/ivydebug.h: portage WIN32 ( pb sur macro debug )
+
+2006-04-21 10:44 fcolin
+
+ * ivy-c/src/: ivybind.c, ivybind.h: ivy bind pour isolation code
+ regexp
+
+2006-04-21 10:41 fcolin
+
+ * ivy-c/src/: Makefile, Makefile.mingw, Makefile.win32, ivy.c,
+ ivybuffer.c, ivybuffer.h, ivydebug.h, ivyperf.c, ivyprobe.c,
+ ivysocket.c, ivytcl.c: dos2unix -U
+
+2006-04-21 10:37 fcolin
+
+ * ivy-c/src/: ivy.h, ivybuffer.c, ivybuffer.h, ivychannel.h,
+ ivydebug.h, ivyglibloop.c, ivyglibloop.h, ivyglutloop.c,
+ ivyglutloop.h, ivyloop.c, ivyloop.h, ivyperf.c, ivyprobe.c,
+ ivysocket.c, ivysocket.h, ivytcl.c, ivytcl.h, ivyxtloop.c,
+ ivyxtloop.h, list.h, timer.c, timer.h, version.h: dos2unix
+ grrr!!!
+
+2006-04-21 10:31 fcolin
+
+ * ivy-c/src/: ivy.h, ivybuffer.c, ivybuffer.h, ivychannel.h,
+ ivydebug.h, ivyglibloop.c, ivyglibloop.h, ivyglutloop.c,
+ ivyglutloop.h, ivyloop.c, ivyloop.h, ivyperf.c, ivyprobe.c,
+ ivysocket.c, ivysocket.h, ivytcl.c, ivytcl.h, ivyxtloop.c,
+ ivyxtloop.h, list.h, timer.c, timer.h, version.h: dos2unix
+
+2006-04-21 10:27 fcolin
+
+ * ivy-c/src/: Makefile, Makefile.mingw, Makefile.win32, ivytcl.c,
+ libIvy.def: dos2unix
+
+2006-04-20 17:58 fcolin
+
+ * ivy-c/src/: ivybuffer.c, ivybuffer.h: gestion de buffer a taille
+ variable pour eliminer les pbs de taille static dans le code
+
+2006-04-20 17:55 fcolin
+
+ * ivy-c/src/ivydebug.h: Macro de debug afin d'eviter de truffer le
+ code de #ifdef DEBUG #endif
+
+2006-04-20 17:51 fcolin
+
+ * ivy-c/src/: Makefile, Makefile.win32, ivy.c, ivy.h,
+ ivyglibloop.c, ivyglutloop.c, ivyperf.c, ivyprobe.c, ivysocket.c,
+ ivyxtloop.c: cleanup DEBUG code
+
+2006-04-20 10:54 fcolin
+
+ * ivy-c/src/ivy.c: correction bug sur filtrage regexp
+
+2006-04-19 18:53 fcolin
+
+ * ivy-c/src/: ivy.c, ivyperf.c: correction Filtred Binding + test
+ avec ivyperf
+
+2006-04-19 18:30 fcolin
+
+ * ivy-c/src/: ivy.c, ivy.h: Add indication on regexp filtering when
+ classes are used call BindingCallback
+
+2006-04-19 12:07 fcolin
+
+ * ivy-c/src/ivyprobe.c: add doc printf for commande bincall in
+ ivyprobe
+
+2006-04-19 10:28 fcolin
+
+ * ivy-c/src/: Makefile, Makefile.win32, ivy.c, ivy.h, ivyloop.c,
+ ivyloop.h, ivyperf.c, ivyprobe.c, ivysocket.c, ivysocket.h,
+ list.h, timer.c: correction de probleme potentiel en multithread
+ ( Ada rejeu ) ajout d'un warning en cas de client bloquant si la
+ varaiable d'env IVY_DEBUG_SEND est positionne
+
+2006-04-18 14:24 fcolin
+
+ * ivy-c/src/version.h: changement version suite a modif ( hook
+ unhook ) et test sur blocage a l'emission
+
+2006-04-18 13:51 fcolin
+
+ * ivy-c/src/: ivy.c, Makefile, Makefile.win32: retour au protocol
+ V3
+
+2006-01-10 14:51 fcolin
+
+ * ivy-c/src/: ivyargument.h, ivybind.h: modif nom fichier en
+ minuscule
+
+2005-08-19 15:44 fcolin
+
+ * ivy-c/src/: ivy.c, ivybind.c, ivysocket.c: correction bug malloc
+ free
+
+2005-08-18 09:36 fcolin
+
+ * ivy-c/src/: Makefile.win32, ivy.c, ivyargument.c, ivybind.c,
+ ivyloop.c, ivyperf.c, ivyprobe.c, ivysocket.c, list.h, timer.c:
+ memory leak malloc/free cleanup
+
+2005-08-12 16:56 fcolin
+
+ * ivy-c/src/: ivy.c, ivy.h, ivybind.c, ivybind.h, ivyprobe.c,
+ libIvy.def: Implementation binding simple sans regexp
+
+2005-08-10 17:36 fcolin
+
+ * ivy-c/src/ivybind.c: uniformisation variable message d'erreur
+
+2005-08-10 17:35 fcolin
+
+ * ivy-c/src/ivyperf.c: bug recuperation arguments
+
+2005-08-10 11:52 fcolin
+
+ * ivy-c/src/: Makefile.win32, hash.c, ivy.c, ivy.h, ivyargument.c,
+ ivyargument.h, ivybind.c, ivybind.h, ivychannel.h, ivyglibloop.c,
+ ivyglutloop.c, ivyloop.c, ivyperf.c, ivyprobe.c, ivysocket.c,
+ ivysocket.h, ivytcl.c, ivyxtloop.c, libIvy.def, list.h:
+ remplacement argc argv par IvyArgument
+
+2005-07-27 16:44 fcolin
+
+ * ivy-c/src/ivy.c: remove 'next' unused field in MsgRcv struct
+ because of hash table
+
+2005-07-27 16:40 fcolin
+
+ * ivy-c/src/: hash.c, hash.h: hash table to store regexp
+
+2005-07-27 16:39 fcolin
+
+ * ivy-c/src/: Makefile, Makefile.win32, ivy.c, ivyprobe.c: use hash
+ table to store msg callback and regexp
+
+2005-07-26 19:08 fcolin
+
+ * ivy-c/src/: Makefile.win32, ivychannel.h, ivyglibloop.c,
+ ivyglutloop.c, ivyloop.c, ivyprobe.c, ivysocket.c, ivysocket.h,
+ ivyxtloop.c: Compile Windows remove HANDLE macro conflict make
+ ivyprobe like Unix version with stdin thread reading
+
+2005-07-26 16:05 fcolin
+
+ * ivy-c/src/: Makefile.win32, ivy.c, ivyargument.c, ivyprobe.c,
+ ivysocket.c: compile Windows
+
+2005-07-26 10:47 fcolin
+
+ * ivy-c/src/: Makefile.win32, getopt.c, getopt.h, ivy.c, ivybind.c,
+ ivyprobe.c: compile sur Windows les fichiers getopt sont
+ necessaires uniquement sur Windows( WIN32 ) compilateur VStudio
+
+2005-07-25 16:28 fcolin
+
+ * ivy-c/src/: ivy.c, ivy.h, ivyargument.c, ivybind.c, ivybind.h,
+ ivysocket.c, ivysocket.h: gestion argument Ivy
+
+2005-07-22 16:21 fcolin
+
+ * ivy-c/src/: ivyargument.c, ivyargument.h: gestion argument des
+ messages sous forme de Tree
+
+2005-07-22 16:20 fcolin
+
+ * ivy-c/src/: Makefile, ivy.c, ivybind.c, ivysocket.c, ivysocket.h:
+ socket Buffered output
+
+2005-07-19 18:23 fcolin
+
+ * ivy-c/src/: Makefile, ivy.c: remove old CODE
+
+2005-07-19 15:15 fcolin
+
+ * ivy-c/src/: Makefile, ivy.c, ivysocket.c: binary protocol
+
+2005-07-13 13:27 fcolin
+
+ * ivy-c/src/: ivy.c, ivysocket.c, ivysocket.h: menage dans
+ ivysocket
+
+2005-07-12 17:53 fcolin
+
+ * ivy-c/src/: ivy.c, ivysocket.c, ivysocket.h: suppression du
+ terminateur dans le code socket en vu d'une transmission binaire
+
+2005-06-13 13:19 fcolin
+
+ * ivy-c/src/: ivy.c, ivysocket.c, ivysocket.h: Ajout keepalive sur
+ les sockets
+
+2005-06-03 18:49 fcolin
+
+ * ivy-c/src/Makefile: case Sensitive NO
+
+2005-06-03 18:43 fcolin
+
+ * ivy-c/src/: Makefile, ivy.c, ivybind.c, ivybind.h: separation du
+ code regexp dans un module a part en vue de l'implementation des
+ bindings simple!
+
+2005-06-02 17:22 fcolin
+
+ * ivy-c/src/: ivy.c, ivy.h, ivyprobe.c: modify callback of binding
+ id is private part of implementation not exported to API !
+
+2005-06-02 16:22 fcolin
+
+ * ivy-c/src/: ivy.c, ivy.h, ivyprobe.c: gestion de la priorité
+ entre application
+
+2005-06-01 15:47 fcolin
+
+ * ivy-c/src/: ivy.c, ivyprobe.c: Protocol revision and empty args
+ bug corrected
+
+2005-05-30 19:07 fcolin
+
+ * ivy-c/src/: ivy.c, ivy.h, ivysocket.c, ivysocket.h: changement de
+ protocle un seul separateur ajout de l'application ID
+
+2005-05-26 17:41 fcolin
+
+ * ivy-c/src/Makefile: [no log message]
+
+2005-05-26 17:40 fcolin
+
+ * ivy-c/src/ivy.c: correction printf
+
+2005-05-26 16:37 fcolin
+
+ * ivy-c/src/: Makefile, Makefile.win32, ivy.c, ivy.h, ivychannel.h,
+ ivyglibloop.c, ivyglibloop.h, ivyglutloop.c, ivyglutloop.h,
+ ivyloop.c, ivyloop.h, ivyprobe.c, ivysocket.c, ivysocket.h,
+ ivytcl.c, ivytcl.h, ivyxtloop.c, ivyxtloop.h, list.h, timer.c,
+ timer.h, version.h: passage du separateur de message a \0
+ suppression des fonctions IvyChannel dynamique on se repose sur
+ le linker modif des adresses mails
+
+2005-05-23 15:52 fcolin
+
+ * ivy-c/src/libIvy.def: fichiers d'export pour Windows
+
+2005-05-23 13:05 fcolin
+
+ * ivy-c/src/ivy.c: pb de compile avec DEBUG
+
+2005-05-20 17:29 fcolin
+
+ * ivy-c/src/: Makefile.win32, ivy.c, ivysocket.c, ivysocket.h:
+ portages des modifications sur windows
+
+2005-05-20 14:53 fcolin
+
+ * ivy-c/src/ivyperf.c: un test de performance d'ivy a lancer en
+ deux exemplaires donne le temps de roundtrip d'un ping pong
+
+2005-05-20 14:48 fcolin
+
+ * ivy-c/src/: Makefile, ivy.c, ivysocket.c, ivysocket.h, version.h:
+ elimination des tailles de buffer par utilisation de realloc la
+ plupart des fonctions utilisent un pointeur static pour eviter de
+ multiple malloc/free ce qui veut dire que IvyC n'est pas
+ reentrant !!!!
+
+2005-02-24 17:33 vidon
+
+ * ivy-c/src/ivyprobe.c: Fix bugs with LF
+
+2005-02-24 16:17 vidon
+
+ * ivy-c/src/ivyprobe.c: Add functions to test binding events
+
+2005-02-24 16:16 vidon
+
+ * ivy-c/debian/changelog: Add comments about bindings events for
+ next release 3.7
+
+2005-02-24 16:15 vidon
+
+ * ivy-c/src/: ivy.c, ivy.h: Add functions to manipulate binding
+ events
+
+2004-11-03 16:45 fcolin
+
+ * ivy-c/src/ivy.c: added comment on check connected function
+
+2004-09-07 15:40 bustico
+
+ * ivy-c/src/: Makefile, ivy.c: permit case sensisite/insensitive
+ choice for pcre and gnu regexp at Makefile level
+
+2004-09-07 13:13 bustico
+
+ * ivy-c/src/Makefile: pcre and libpcre dependance added no more
+ reference at libgtkivy and relative tools : /ivygtkprobe
+
+2004-09-03 11:48 bustico
+
+ * ivy-c/src/Makefile:
+ redhat files have been updated to permit an automatised packaging
+ of ivy-c with the rpmize tool
+
+ Makefile has been improved : automatic detection of tcl version,
+ and installliblinks target has been fixed
+
+2004-09-01 17:54 drouin
+
+ * ivy-c/: examples/Makefile, examples/gtkIvyButton.c,
+ examples/motifButtonIvy.c, src/Makefile, src/ivy.c,
+ src/ivyglibloop.c, src/ivyglibloop.h, src/ivygtkloop.c,
+ src/ivygtkloop.h, src/ivyprobe.c, src/ivysocket.c, src/ivytcl.c,
+ src/list.h: replaced the gtk mainloop with a glib one. added
+ -Wall compile directive . fixed some warnings
+
+2004-07-23 17:14 jestin
+
+ * ivy-c/src/: Makefile, version.h: ce Makefile tient compte des
+ PCRE ( perl compatible regular expressions ), et peut permettre
+ de fabriquer ivy sous solaris et osx , moyennant une édition.
+
+2004-07-23 17:13 jestin
+
+ * ivy-c/examples/: Makefile, unBind.tcl: Makefile ne fait pas
+ encore partie du paquet unbind est un script tcl pour montrer
+ comment on se désabonne. Les exemples auraient dû être dans
+ ivy-c-dev, ainsi que la doc html, n'est-ce pas ?
+
+2004-07-23 17:13 jestin
+
+ * ivy-c/debian/: control, rules: bon, c'est un pataquès incroyable,
+ ivy-c et ivy-c-dev sont construit différemment. Si il y a un
+ empaqueteur debian motivé, qu'il se présente ...
+
+2004-07-23 15:25 jestin
+
+ * ivy-c/debian/control: problematic dependancies in control file
+ ... tcl8.3-dev is not really generic
+
+2004-07-23 15:25 jestin
+
+ * ivy-c/src/: Makefile, ivyprobe.c: now uses USE_PCRE_REGEXP in
+ ivyprobe (xtprobe ... gtkprobe ...) when binding a pattern
+
+2004-06-25 20:27 jestin
+
+ * ivy-c/src/: Makefile, Makefile.mingw, Makefile.osx,
+ Makefile.solaris, Test.tcl, ivy.c, ivyprobe.c, ivysocket.c,
+ ivytcl.c, version.h: le Makefile peut être utilisé sur Solaris,
+ OSX et Linux. Par dégaut, c'est pour linux.
+
+ ivy.c corrige un unbindmsg
+
+ ivyprobe: -n pour le nom de l'agent, -v pour la version de la lib
+
+ ivytcl: plein de problèmes réglés, d'autres introduits, notamment
+ pour la gestion de la boucle d'évéenents sous windows ...
+
+ Test.tcl déplacé dans les exemples
+
+2004-06-25 20:26 jestin
+
+ * ivy-c/examples/: Makefile, Test.tcl, button.tk, gtkIvyButton.c,
+ motifButtonIvy.c, testUnbind.c, unBind.tcl: j'ajoute des exemples
+ de code dans le CVS. il faudra les intégrer à la doc...
+
+2004-06-25 20:26 jestin
+
+ * ivy-c/debian/: changelog, control, rules: problem dh_strip de la
+ lib
+
+2004-03-24 11:15 fcolin
+
+ * ivy-c/src/: Makefile, ivysocket.c: correction fonction WIN32 non
+ encadrée WIN32
+
+2004-03-24 11:10 fcolin
+
+ * ivy-c/src/: Makefile.mingw, ivyloop.c, ivysocket.c, ivytcl.c: Pb
+ de mainloop TCL sous windows
+
+2004-03-23 16:53 fcolin
+
+ * ivy-c/src/ivytcl.c: [no log message]
+
+2004-03-12 10:40 fcolin
+
+ * ivy-c/src/Makefile.mingw: ajout des -l qui vont bien pour compile
+ sous MinGW reste a eliminer les parties qui ne sont pas
+ compilable sous MINGW
+
+2004-03-12 10:37 fcolin
+
+ * ivy-c/src/: Test.tcl, ivyloop.c, ivyprobe.c, ivysocket.c,
+ ivytcl.c: compile avec MINGW sous WIN32
+
+2004-01-20 14:40 fcolin
+
+ * ivy-c/src/ivyprobe.c:
+ pour la compilation sous INTERIX ( Windows SFU 3.5) avec gcc
+
+2004-01-20 14:39 fcolin
+
+ * ivy-c/src/ivysocket.h:
+ pour la compilation sous INTERIX ( Windows SFU 3.5) avec gcc
+
+2003-10-09 13:48 jestin
+
+ * ivy-c/src/: Makefile, Makefile.osx, ivysocket.c: Modified
+ makefiles to allow compilation on OSX
+
+2003-09-18 18:03 fcolin
+
+ * ivy-c/src/Test.tcl: mise a jour avec la modif de passage
+ arguments dans le C
+
+2003-09-18 18:02 fcolin
+
+ * ivy-c/src/ivytcl.c: modif callback argument ( c'etait tres
+ merdique avant ) pas de possibilite de mettre des blancs dans les
+ arguments
+
+2003-09-18 15:44 fcolin
+
+ * ivy-c/src/ivytcl.h: pas besoin de include X11/Intyrinsics !!!(
+ portage win pb )
+
+2003-09-18 15:43 fcolin
+
+ * ivy-c/src/ivytcl.c: modif passage tcl 8.4 ( const sur argv )
+
+2003-05-20 15:33 fcolin
+
+ * ivy-c/src/ivy.c: modif pour compile MinGW les includes sys/socket
+ n'ont rien a faire la ils sont dans ivysocket.h
+
+2003-05-20 15:25 fcolin
+
+ * ivy-c/src/ivysocket.h: modif pour compilation avec MinGW
+
+2003-03-18 15:35 buisson
+
+ * ivy-c/src/Makefile.solaris: Change version number from 3.4 to
+ 3.5.
+
+2003-03-17 18:13 jestin
+
+ * ivy-c/src/: Makefile, ivyprobe.c: Makefile changed ... once
+ again. We need a configure ?
+
+2003-03-17 18:10 jestin
+
+ * ivy-c/debian/changelog: 2 bugfixes
+
+2003-03-10 16:58 buisson
+
+ * ivy-c/src/Makefile.solaris: removing binaries.
+
+2003-03-10 11:41 buisson
+
+ * ivy-c/src/Makefile.solaris: This makefile should run on solaris.
+ makefile -f Makefile.solaris
+
+2002-12-16 15:51 fcolin
+
+ * ivy-c/src/: ivy.c, ivyglutloop.c, ivygtkloop.c, ivysocket.c,
+ list.h: passage en GCC 3.2
+
+2002-12-11 16:29 jestin
+
+ * ivy-c/doc/ivy-c.sgml: Adding examples for Xt/Motif, Tcl/Tk and
+ GTK in the documentation
+
+2002-09-24 13:35 buisson
+
+ * ivy-c/src/Makefile.osx: New Makefile for os X, compatible with
+ Mac OS X 10.2
+
+2002-06-25 13:27 mertz
+
+ * ivy-c/debian/: changelog, control, rules: - prise en compte d'une
+ modif dans e MakeFile pour les lib/include tcl - ajout de
+ dépendances Build-depends
+
+2002-06-25 12:14 chatty
+
+ * ivy-c/src/: Makefile, ivy.c: Modified Makefile to allow for
+ compatibity between install patterns of Tcl In ivy.c, restored
+ DEFAULT_DOMAIN to original value (not a string)
+
+2002-06-21 15:02 buisson
+
+ * ivy-c/src/Makefile.osx: refining symbolic links building (-fh
+ option)
+
+2002-06-21 15:00 buisson
+
+ * ivy-c/src/ivy.c: Line 110, 114, 118 : add "void" to *expr Line
+ 205 : cast argument to int for osx compatibility with int_64
+
+2002-06-20 14:07 mertz
+
+ * ivy-c/debian/changelog: Correction de typos
+
+2002-06-20 14:02 mertz
+
+ * ivy-c/src/Makefile: Makefile plus portable
+
+2002-06-20 14:02 mertz
+
+ * ivy-c/debian/: changelog, control: [no log message]
+
+2002-04-04 17:05 buisson
+
+ * ivy-c/src/Makefile.osx: Add new Makefile for mac osx platform
+
+2002-04-04 10:55 fcolin
+
+ * ivy-c/src/: ivy.c, timer.c: remove Timer struct def , and ## in
+ ivy.c
+
+2002-04-04 10:50 fcolin
+
+ * ivy-c/src/: ivy.c, ivyloop.c, ivysocket.c, list.h, timer.c:
+ replace LIST_ IVY_LIST_ collision macro
+
+2001-10-23 17:20 fcolin
+
+ * ivy-c/src/ivysocket.h: [no log message]
+
+2001-10-08 11:41 fcolin
+
+ * ivy-c/src/ivy.c: correction bug du a l'utilisation de strtok pour
+ decortiquer les arguments recu pb en cas d'arg vide !!! ([0-9]*)
+
+2001-01-17 13:55 fcolin
+
+ * ivy-c/src/ivy.c: correction bug sur SUN_OS inet_ntoa
+
+2000-12-22 10:47 sc
+
+ * ivy-c/src/Makefile: Commented out install of ivyglutprobe, which
+ apparently is not ready
+
+2000-12-21 10:51 fcolin
+
+ * ivy-c/src/Makefile: maj gtk et comment Glut ( waiting for
+ modified glut )
+
+2000-12-21 10:45 fcolin
+
+ * ivy-c/src/ivy.c: broadcast printf in number dot notation
+
+2000-12-20 17:47 fcolin
+
+ * ivy-c/src/: ivy.c, ivyprobe.c, ivysocket.c: multicast and glut
+ eventloop support
+
+2000-12-20 17:43 fcolin
+
+ * ivy-c/src/Makefile: add targets for the glut eventloop
+
+2000-12-20 17:26 fcolin
+
+ * ivy-c/src/: ivyglutloop.c, ivyglutloop.h: suppression des \r en
+ fin de ligne (windows)
+
+2000-12-20 17:23 fcolin
+
+ * ivy-c/src/ivysocket.h: ajout de SocketAddMember pour le
+ multicast.
+
+2000-12-20 16:58 fcolin
+
+ * ivy-c/src/: ivyglutloop.c, ivyglutloop.h: initial version for the
+ glut eventloop
+
+2000-12-19 17:19 mertz
+
+ * ivy-c/src/ivyprobe.c: ajout d'une ligne dans l'aide des
+ commandes: .help
+
+2000-12-12 16:17 chatty
+
+ * ivy-c/doc/ivy-c.sgml: Slight fix in example code
+
+2000-08-07 13:29 sc
+
+ * ivy-c/src/: Makefile, ivy.c, ivy.h, ivychannel.h, ivygtkloop.c,
+ ivygtkloop.h, ivyloop.c, ivyloop.h, ivyprobe.c, ivysocket.c,
+ ivysocket.h, ivytcl.c, ivytcl.h, ivyxtloop.c, ivyxtloop.h,
+ list.h, timer.c, timer.h, version.h: Fixed headers
+
+2000-08-07 13:29 sc
+
+ * ivy-c/doc/: ivy-c.sgml, ivyprobe.1: Documentation improvements
+
+2000-07-26 11:44 chatty
+
+ * ivy-c/doc/: ivy-c-1.html, ivy-c-2.html, ivy-c-3.html,
+ ivy-c-4.html, ivy-c-5.html, ivy-c-6.html, ivy-c.html,
+ man-ivy-c.html: Removed documentation files that were generated
+ from other files
+
+2000-03-13 15:54 mertz
+
+ * ivy-c/: debian/changelog, debian/control, src/Makefile: bad
+ version dependency of ivy-c-dev corrected the ivygtkprobe
+ executable is added to the package
+
+2000-03-10 17:41 mertz
+
+ * ivy-c/: debian/changelog, debian/rules, src/Makefile,
+ src/ivytcl.c, src/version.h: html docs are re-included in
+ /usr/share/doc libtclivy works again... (didn't work anymore due
+ to library rename)
+
+2000-02-22 19:36 mertz
+
+ * ivy-c/: debian/control, src/version.h: maj licence LGPL et
+ description
+
+2000-02-22 19:06 mertz
+
+ * ivy-c/debian/: control, copyright: maj copyright et descriptif
+
+2000-01-21 16:52 mertz
+
+ * ivy-c/: debian/changelog, debian/control, debian/copyright,
+ debian/dirs, debian/ivy-c-dev.files, debian/rules, src/Makefile:
+ This branch is similar to debian_version_3_2_1, but correspond to
+ package working for a slink. It is also upward compatible from
+ debian_version_3_1_4
+
+2000-01-19 20:32 bothorel
+
+ * ivy-c/src/ivyprobe.c: original file from FRC
+
+2000-01-19 20:30 bothorel
+
+ * ivy-c/src/ivyprobe.c: adding an empty file
+
+2000-01-19 20:07 bothorel
+
+ * ivy-c/src/: ivygtkloop.c, ivygtkloop.h, ivyprobe.c: [no log
+ message]
+
+2000-01-19 19:58 bothorel
+
+ * ivy-c/src/: Makefile, ivygtkloop.c: Ajout lib GTK
+
+2000-01-19 18:19 damiano
+
+ * ivy-c/debian/rules: a typo correction
+
+2000-01-19 18:11 damiano
+
+ * ivy-c/src/Makefile: split of target install into specific ones.
+ change name of ivy tcl library from ivytcl.* to libtclivy.* add
+ generation of libtclivy.a
+
+2000-01-19 18:09 damiano
+
+ * ivy-c/debian/: changelog, control, copyright, dirs,
+ ivy-c-dev.files, rules: New Makefile => new version add
+ dependancy to tcl in control add libtcl.so and libtcl.a in
+ ivy-c-dev.files Massive changes to match potato debian policy in
+ rules remove of /usr/doc in dirs remove of debian/copyright. A
+ copy of src/version.h to debian/copyright is done at build
+ time
+
+2000-01-14 16:13 jestin
+
+ * ivy-c/src/list.h: Bon, je le remet, on m'a expliqué pourquoi
+ c'est pas super d'enlever list.h. A suivre ?
+
+2000-01-14 15:59 jestin
+
+ * ivy-c/debian/changelog: [no log message]
+
+2000-01-14 15:57 jestin
+
+ * ivy-c/: debian/changelog, debian/control, src/list.h: J'enlève
+ list.h, qui est fourni par utils-c-dev, et qui entre en conflit
+ avec icelui. Du coup, hop ! Dépendance.
+
+2000-01-06 16:00 mertz
+
+ * ivy-c/debian/: changelog, control: resolve a conflict between
+ ivy-c and ivy-c-dev due to a wrong version number in control file
+
+2000-01-06 15:52 mertz
+
+ * ivy-c/debian/rules: appel de make clean pour la regle clean
+
+1999-11-10 15:14 fcolin
+
+ * ivy-c/src/ivy.c: modif pour chaine vide dans le domain traite de
+ la meme maniere que NULL
+
+1999-05-03 11:27 lecoanet
+
+ * ivy-c/debian/: changelog, control, rules: Ajout d'une règle
+ interdisant la cohabitation avec ivy-tcl
+
+1999-04-30 17:40 fcolin
+
+ * ivy-c/src/: ivy.c, ivytcl.c: [no log message]
+
+1999-04-28 13:20 lecoanet
+
+ * ivy-c/src/Makefile: Ajout de l'installation de ivytcl.so
+
+1999-04-28 13:19 lecoanet
+
+ * ivy-c/debian/dirs: Corrections pour permettre la compil à Athis
+
+1999-04-27 17:10 fcolin
+
+ * ivy-c/src/Test.tcl: [no log message]
+
+1999-04-27 17:08 fcolin
+
+ * ivy-c/src/: Makefile, ivytcl.h: ivytcl.h
+
+1999-04-27 16:58 fcolin
+
+ * ivy-c/src/ivytcl.c: Interface Ivy TCL
+
+1999-04-13 16:55 damiano
+
+ * ivy-c/debian/rules: Correcting bug regarding cvs tag
+
+1999-04-13 16:47 damiano
+
+ * ivy-c/src/Makefile: Changing MINOR to match version 3.1
+
+1999-04-13 16:38 damiano
+
+ * ivy-c/debian/: changelog, control, rules: Changing debian files
+ for version 3.1
+
+1999-04-13 16:37 damiano
+
+ * ivy-c/doc/: BUGS, ChangeLog, NEWS, README, TODO: Adding doc files
+
+1999-04-13 11:24 jacomi
+
+ * ivy-c/src/Makefile: doc files added to ivy-c package
+
+1999-04-13 11:02 jacomi
+
+ * ivy-c/doc/: ivy-c-1.html, ivy-c-2.html, ivy-c-3.html,
+ ivy-c-6.html: doc updated
+
+1999-04-12 19:29 jacomi
+
+ * ivy-c/doc/: ivy-c.htm, man-ivy-c.html: [no log message]
+
+1999-04-12 19:18 jacomi
+
+ * ivy-c/doc/: ivy-c-1.html, ivy-c-2.html, ivy-c-3.html,
+ ivy-c-4.html, ivy-c-5.html, ivy-c-6.html, ivy-c.html: doc updated
+
+1999-04-12 14:28 chatty
+
+ * ivy-c/doc/ivy-c.sgml:
+
+ Added complements (the guide is still incomplete).
+
+1999-04-02 09:10 sc
+
+ * ivy-c/doc/ivy-c.sgml:
+
+ Created the Ivy C library guide.
+
+1999-03-30 14:59 jacomi
+
+ * ivy-c/doc/: ivy-c-functions.1, ivy-c.1, ivy-c.htm: [no log
+ message]
+
+1999-03-26 16:50 fcolin
+
+ * ivy-c/src/ivysocket.c: correction d'un bug a la fermeture de Ivy
+ :wq
+
+1999-03-18 12:33 jacomi
+
+ * ivy-c/doc/: ivy-c.1, ivy-c.htm: [no log message]
+
+1999-03-17 20:11 jacomi
+
+ * ivy-c/doc/: ivy-c.1, ivy-c.htm, ivyprobe.1: first draft for man
+ pages on ivy-c
+
+1999-03-03 16:47 damiano
+
+ * ivy-c/debian/rules: check cvs tag in debian/rules
+
+1999-02-20 17:07 sc
+
+ * ivy-c/src/Makefile: Aded links for shared libs Added minor and
+ major number
+
+1999-02-19 10:53 sc
+
+ * ivy-c/src/ivyprobe.c:
+
+ Result of merge (two attempts to make ivyprobe ivy-3.0-compliant)
+
+1999-02-19 10:44 damiano
+
+ * ivy-c/: debian/changelog, debian/rules, src/Makefile, src/ivy.c,
+ src/ivyprobe.c: L'argument bus est retiré de IvyInit (ivy.c,
+ ivy.h, ivyprobe.c) La variable DefaultIvyBus est maintenant de la
+ forme "<domain>:<port>" (ivy.c) Les fichiers debian/* ont été
+ corrigés pour le paquetage 3.0 (tag V3_0)
+
+1999-02-19 09:47 sc
+
+ * ivy-c/src/ivy.c:
+
+ Default broadcast network is now 127
+
+1999-02-17 12:28 damiano
+
+ * ivy-c/src/: ivy.c, ivy.h: remove argument bus from function
+ IvyInit
+
+1999-02-10 10:29 damiano
+
+ * ivy-c/debian/rules: Mise a jour rules. DESTDIR => PREFIX
+
+1999-02-09 23:54 sc
+
+ * ivy-c/src/ivysocket.c: Clean up
+
+1999-02-09 23:52 sc
+
+ * ivy-c/src/ivyprobe.c:
+
+ Just some clean up
+
+1999-02-09 23:51 sc
+
+ * ivy-c/src/ivyloop.c:
+
+ A bit of clean up Corrected bug in handling exceptions on
+ channels.
+
+1999-02-05 20:03 sc
+
+ * ivy-c/src/: ivy.c, ivysocket.c:
+
+ Corrected bug when broadcast socket can't be opened.
+
+1999-01-29 15:46 jacomi
+
+ * ivy-c/src/Makefile: Makefile updated
+
+1999-01-28 16:24 jacomi
+
+ * ivy-c/src/list.h: useful file
+
+1999-01-28 16:14 jacomi
+
+ * ivy-c/src/ivyloop.c: c++ comment removed
+
+1999-01-27 16:28 jacomi
+
+ * ivy-c/src/: Makefile, version.h: version and makefile updated
+
+1999-01-26 14:12 jacomi
+
+ * ivy-c/src/Makefile: update of directory redhat and makefile
+
+1999-01-26 09:53 sc
+
+ * ivy-c/src/: ivy.c, ivy.h, ivychannel.h, ivyloop.h, ivyprobe.c,
+ ivysocket.c, ivysocket.h, ivyxtloop.c, ivyxtloop.h:
+
+ A bit of clean up in headers Changes in IvyStart and IvyInit: -
+ expanded parsing of IvyStart argument to bus addresses like
+ 123.123,123.122:2019 - socket for receiving broadcast handshakes
+ is now in IvyStart (we thus lose the ability to have "passive"
+ agents (agents that listen but don't say hello))
+
+1999-01-26 09:53 sc
+
+ * ivy-c/src/: Makefile, ivyloop.c: A bit of clean up in headers
+ Changes in IvyStart and IvyInit: - expanded parsing of IvyStart
+ argument to bus addresses like 123.123,123.122:2019 - socket for
+ receiving broadcast handshakes is now in IvyStart (we thus lose
+ the ability to have "passive" agents (agents that listen but
+ don't say hello))
+
+1999-01-20 16:55 jacomi
+
+ * ivy-c/src/: Makefile, ivy.c, ivy.h, ivychannel.h, ivyloop.c,
+ ivyloop.h, ivyprobe.c, ivysocket.c, ivysocket.h, ivyxtloop.c,
+ ivyxtloop.h: headers
+
+1999-01-12 12:19 chatty
+
+ * ivy-c/src/ivysocket.c: Just a bit of cleaning up tabulations.
+
+1999-01-12 12:18 chatty
+
+ * ivy-c/src/ivy.c: Limited calls to SocketGetRemote in
+ BroadcastReceive to the strict minimum, because it calls
+ gethostbyaddr and may sometimes get stuck.
+
+1999-01-12 12:17 chatty
+
+ * ivy-c/src/Makefile: Added -Wall
+
+1999-01-11 12:38 sc
+
+ * ivy-c/src/ivyxtloop.c: Added stub for IvyStop. Someday, we'll
+ have to call the appropriate Xt function
+
+1999-01-11 12:36 sc
+
+ * ivy-c/src/ivyprobe.c: IvyChannelStop -> IvyStop
+
+1999-01-11 12:36 sc
+
+ * ivy-c/src/: ivyloop.c, ivyloop.h: IvyChannelStop -> IvyStop moved
+ declaration to ivy.h
+
+1999-01-11 12:35 sc
+
+ * ivy-c/src/ivy.h: Added declaration of IvyStop Updated declaration
+ of IvyStart
+
+1999-01-11 12:34 sc
+
+ * ivy-c/src/Makefile:
+
+ Added executables to clean up list Added a bunch of libs for
+ ivyxtprobe
+
+1999-01-08 11:39 chatty
+
+ * ivy-c/src/: Makefile, ivyprobe.c, testivy.c:
+
+ testivy -> ivyprobe
+
+1999-01-08 11:32 chatty
+
+ * ivy-c/src/: ivyloop.c, ivyloop.h, ivysocket.c, ivyxtloop.c:
+
+ Bus -> Ivy Simplified management of different versions of channel
+ management. SetChannelManagement has disappeared.
+
+1999-01-08 11:32 chatty
+
+ * ivy-c/src/: ivychannel.h, ivysocket.h, ivyxtloop.h: Bus -> Ivy
+ Simplified management of different versions of channel
+ management. SetChannelManagement has disappeared.
+
+1999-01-08 11:31 chatty
+
+ * ivy-c/src/ivy.h:
+
+ Bus -> Ivy Added domains argument to IvyStart
+
+1999-01-08 11:30 chatty
+
+ * ivy-c/src/ivy.c:
+ Bus -> Ivy Added domains argument to IvyStart
+
+1999-01-08 11:28 chatty
+
+ * ivy-c/src/: timer.c, timer.h:
+
+ Just updated copyright
+
+1999-01-06 15:15 jacomi
+
+ * ivy-c/src/Makefile: V1_3
+
+1998-12-28 16:55 damiano
+
+ * ivy-c/: debian/rules, src/Makefile: Correction de debian/rules
+
+1998-12-28 16:48 damiano
+
+ * ivy-c/: debian/changelog, debian/rules, src/Makefile: Correction
+ de debian/rules et src/Makefile
+
+1998-12-28 13:35 damiano
+
+ * ivy-c/: debian/rules, src/Makefile: Correction sur debian/rules
+ et src/Makefile
+
+1998-12-22 18:24 damiano
+
+ * ivy-c/debian/rules: Erreur dans le fichier rules
+
+1998-12-22 18:18 damiano
+
+ * ivy-c/: debian/changelog, debian/control, debian/rules,
+ src/Makefile: Debianisation des sources de la version de Stéphane
+ C
+
+1998-12-22 13:49 chatty
+
+ * ivy-c/src/ivy.c:
+
+ Corrected bogus call to SocketGetRemote in ClientDelete
+
+1998-12-22 11:17 chatty
+
+ * ivy-c/src/testivy.c:
+
+ Mise au propre Amelioration des messages Remplacement de gets par
+ fgets
+
+1998-12-22 11:16 chatty
+
+ * ivy-c/src/ivy.c:
+
+ Mise au propre Ajout du mecanisme de choix des adresses de
+ broadcast
+
+1998-12-22 11:15 chatty
+
+ * ivy-c/src/: ivy.h, ivychannel.h, ivyloop.h, ivysocket.h,
+ ivyxtloop.h, timer.h, ivyloop.c, ivysocket.c, ivyxtloop.c,
+ timer.c:
+
+ Mise au propre
+
+1998-12-22 11:15 chatty
+
+ * ivy-c/src/Makefile:
+
+ Mise au propre Correction de la regle des lib
+
+1998-12-11 18:24 lecoanet
+
+ * ivy-c/: debian/README, debian/changelog, debian/control,
+ debian/copyright, debian/dirs, debian/ivy-c-dev.files,
+ debian/rules, src/Makefile, src/ivy.c, src/list.h: Modification
+ pour debianisation
+
+1998-10-20 16:28 jacomi
+
+ * ivy-c/src/ivy.c: safety rule added
+
+1998-10-20 13:31 fcolin
+
+ * ivy-c/src/ivysocket.c: correction bus buscleanup et fermeture bus
+
+1998-10-20 13:31 fcolin
+
+ * ivy-c/src/ivysocket.h: correction bus sur buscleanup gestion
+ liste et fermeture serveur
+
+1998-10-07 12:22 jacomi
+
+ * ivy-c/src/ivy.c: nouvelle adresse reseau ajoutee
+
+1998-09-18 11:33 jacomi
+
+ * ivy-c/src/Makefile: [no log message]
+
+1998-09-14 14:10 jacomi
+
+ * ivy-c/src/Makefile: librairies dynamiques ajoutees
+
+1998-09-03 10:18 jacomi
+
+ * ivy-c/src/ivychannel.h: [no log message]
+
+1998-08-12 12:23 jacomi
+
+ * ivy-c/src/: Makefile, bus.c, bus.h, buschannel.h, busloop.c,
+ busloop.h, bussocket.c, bussocket.h, busxtloop.c, busxtloop.h,
+ ivy.c, ivy.h, ivyloop.c, ivyloop.h, ivysocket.c, ivysocket.h,
+ ivyxtloop.c, ivyxtloop.h, testbus.c, testivy.c: version relookee
+ en ivy
+
+1998-08-03 15:48 fcolin
+
+ * ivy-c/src/: busxtloop.c, busxtloop.h: quelque Prototype oublie
+
+1998-08-03 15:04 fcolin
+
+ * ivy-c/src/: buschannel.h, busloop.c, busloop.h, busxtloop.c,
+ busxtloop.h: Ajout des fonctions pour permettre la gestion par
+ des boucles autres que XT et Interne( select ) buschannel.h :
+ Interface avec gestion MainLoop busloop.[ch] : Implementation
+ MainLoop par select busxtloop.[ch] : Implementation MainLoop par
+ Appel Xt
+
+1998-08-03 14:58 fcolin
+
+ * ivy-c/src/: Makefile, bus.c, bus.h, bussocket.c, bussocket.h,
+ testbus.c: eclatement de bussocket pour permettre la creation de
+ mainloop externe autre que XT et Interne buschannel.h devient
+ l'interface avec la gestion MainLoop busxtloop.[ch] MainLoop
+ Style XT busloop.[ch] MainLoop Interne basee sur select
+
+1998-06-16 11:26 fcolin
+
+ * ivy-c/src/: Makefile, bus.c, bussocket.h, testbus.c, timer.c:
+ Modif timer.c
+
+1998-04-15 11:47 damiano
+
+ * ivy-c/src/: Makefile, bus.c, bussocket.c, bussocket.h, socket.c,
+ socket.h, testbus.c: Rename des fichiers socket en bussocket, et
+ modifs des sources et du Makefile en consequence
+
+1998-04-09 15:54 damiano
+
+ * ivy-c/: Makefile, bus.c, bus.h, list.h, socket.c, socket.h,
+ testbus.c, timer.c, timer.h, src/Makefile, src/bus.c, src/bus.h,
+ src/list.h, src/socket.c, src/socket.h, src/testbus.c,
+ src/timer.c, src/timer.h: Move des fichiers dans src
+
+1998-03-25 17:51 jacomi
+
+ * ivy-c/testbus.c: Upgrade FRC
+
+1998-03-05 18:31 ihm
+
+ * ivy-c/: Makefile, bus.c, bus.h, list.h, socket.c, socket.h,
+ testbus.c, timer.c, timer.h: Initial revision
+
+1998-03-05 18:31 ihm
+
+ * ivy-c/: Makefile, bus.c, bus.h, list.h, socket.c, socket.h,
+ testbus.c, timer.c, timer.h: Source BUS_C
diff --git a/doc/ivy-c-functions.1 b/doc/ivy-c-functions.1
index 4912340..d54bb77 100644
--- a/doc/ivy-c-functions.1
+++ b/doc/ivy-c-functions.1
@@ -1,7 +1,7 @@
'\"
'\" Ivy, C interface \- library managing connexions to a software bus
'\"
-'\" Copyright (C) 1997-1999
+'\" Copyright (C) 1997-2006
'\" Centre d'Études de la Navigation Aérienne
'\"
'\" See the file "license.terms" for information on usage and redistribution
@@ -42,16 +42,15 @@
'\" # BS - start boxed text
'\" # ^y = starting y location
'\" # ^b = 1
-.TH Ivy-c-3.0 1 3.0 "Ivy-c-3.0 Library Functions"
+.TH Ivy-c-3.9 1 3.9 "Ivy-c-3.9 Library Functions"
.SH NAME
IvyInit, IvyStart, IvyStop, IvyBindMsg, IvyUnbindMsg, IvyBindDirectMsg,
IvySendMsg, IvySendDirectMsg, IvySendDieMsg, IvySendError, IvyGetApplicationName,
IvyGetApplicationHost, IvyGetApplication, IvyGetApplicationList,
-IvyGetApplicationMessages, IvyDefaultApplicationCallback, IvyClasses,
-IvyChannelInit, IvyChannelSetUp, IvyMainLoop, IvyChannelClose,
-IvyChannelDelete, IvyChannelHandleRead,
-IvyChannelHandleExcpt, IvyXtChannelInit, IvyXtChannelSetUp
-IvyXtChannelClose, IvyXtHandleChannelRead, IvyXtHandleChannelDelete,
+IvyGetApplicationMessages, IvyDefaultApplicationCallback, IvySetFilter, IvySetBindCallback,
+IvyChannelInit, IvyChannelStop, IvyChannelAdd, IvyChannelRemove, IvyMainLoop,
+IvyChannelDelete, IvyChannelHandleRead, IvyChannelHandleExcpt,
+IvySetBeforeSelectHook, IvySetAfterSelectHook,
IvyXtChannelAppContext,
.SH SYNOPSIS
useful set of library functions for communicating between different
@@ -105,22 +104,19 @@ char**
char*
\fBIvyDefaultApplicationCallback(\fIapp, user_data, Event\fB)\fR
char*
-\fBIvyClasses(\fIargc, argv\fB)\fR
+\fBIvySetFilter(\fIargc, argv\fB)\fR
.sp
void
\fBIvyChannelInit(\fIvoid\fB)\fR
.sp
Channel
-\fBIvyChannelSetUp(\fIfd, data, handle_delete, handle_read\fB)\fR
+\fBIvyChannelAdd(\fIfd, data, handle_delete, handle_read\fB)\fR
.sp
void
-\fBIvyMainLoop(\fIhook\fB)\fR
+\fBIvyChannelRemove(\fIchannel\fB)\fR
.sp
void
-\fBIvyChannelClose(\fIchannel\fB)\fR
-.sp
-static void
-\fBIvyChannelDelete(\fIchannel\fB)\fR
+\fBIvyMainLoop()\fR
.sp
static void
\fBIvyChannelHandleRead(\fIcurrent\fB)\fR
@@ -128,23 +124,8 @@ static void
static void
\fBIvyChannelHandleExcpt(\fIcurrent\fB)\fR
.sp
-static void
-\fBIvyXtChannelInit(\fIvoid\fB)\fR
-.sp
-static void
-\fBIvyXtChannelSetUp(\fIfd, data, handle_delete, handle_read\fB)\fR
-.sp
-void
-\fBIvyXtChannelClose(\fIchannel\fB)\fR
-.sp
-static void
-\fBIvyXtHandleChannelRead(\fIclosure, source, id\fB)\fR
-.sp
-static void
-\fBIvyXtHandleChannelDelete(\fIclosure, source, id\fB)\fR
-.sp
void
-\fBIvyChannelAppContext(\fIcntx\fB)\fR
+\fBIvyXtChannelAppContext(\fIcntx\fB)\fR
.SH ARGUMENTS
Only main functions are detailed in this section
.SH
@@ -191,6 +172,13 @@ Message binding
In this example the function \fBStartTimeCallback\fR will be called
each time the string \fBCLOCK Start time=(.*)\fR will be emitted on
the bus.
+There is a special syntax for specifying numeric interval, in this case
+the interval is locally transformed in a pcre regexp.
+syntax is \fB(?Imin#max[fi])\fR. min and max are the bounds,
+by default the regexp match decimal number, but if max bound is
+followed by 'i', the regexp match only integers ex : \fB(?I-10#20), (?I20#25i)\fR
+Note that due to the regexp generator limitation (which will perhaps be raised eventually)
+the bounds are always integers.
.SH
\fBIvyUnbindMsg\fR:
Message unbinding
@@ -204,14 +192,14 @@ String to be sent on the bus
.SH Example:
\fBIvySendMsg ("SECTOR:%s.AIRCRAFT:%s Entered", sectorname, pln->indicatif);\fR
.SH
-\fBIvyChannelSetUp\fR:
+\fBIvyChannelAdd\fR:
.AP HANDLE fd in
.AP void *data in
.AP ChannelHandleDelete handle_delete in
.AP ChannelHandleRead handle_read in
.AP Channel out out
.SH Example:
-\fBIvyChannelSetUp (0, NULL, NULL, HandleStdin);\fR:
+\fBIvyChannelAdd (0, NULL, NULL, HandleStdin);\fR:
.VE
.BE
.SH DESCRIPTION
@@ -245,11 +233,11 @@ Connection of the application \fBIVYPROBE\fR on a given bus
NULL,
NULL);
/* keyboard's inputs management */
- IvyChannelSetUp(0, NULL, NULL, HandleStdin);
+ IvyChannelAdd(0, NULL, NULL, HandleStdin);
/* starting the connection */
IvyStart (bus);
/* Main loop */
- IvyMainLoop(0);
+ IvyMainLoop();
};
.DE
@@ -268,13 +256,13 @@ error messages displayed
.SH BUGS
none reported yet!
.SH AUTHORS
-Francois-Regis Colin <fcolin@cenatoulouse.dgac.fr>
-Stephane Chatty <chatty@cenatoulouse.dgac.fr>
+Francois-Regis Colin
+Stephane Chatty
.SH SEE ALSO
ivyprobe (1)
.sp
-For further details, please refer to the Ivy html page at http://www.cenatls.cena.dgac.fr/pii/produits/Ivy.html
+For further details, please refer to the Ivy html page at http://www.tls.cena.fr/pii/produits/Ivy.html
.SH NOTES
In case of any comment or bug report on this library, please contact
-fcolin@cenatoulouse.dgac.fr, chatty@cenatoulouse.dgac.fr, jacomi@cenatoulouse.dgac.fr
+ivy@tls.cena.fr
diff --git a/doc/ivy-c.1 b/doc/ivy-c.1
index 14aed08..c67e96e 100644
--- a/doc/ivy-c.1
+++ b/doc/ivy-c.1
@@ -42,7 +42,7 @@
'\" # BS - start boxed text
'\" # ^y = starting y location
'\" # ^b = 1
-.TH Ivy-c-3.0 1 3.0 "Ivy-c-3.0 Interface"
+.TH Ivy-c-3.9 1 3.9 "Ivy-c-3.9 Interface"
.SH NAME
ivy-c - a software bus library
.SH SYNOPSIS
@@ -82,15 +82,15 @@ error messages displayed
none reported yet!
.SH AUTHORS
.nf
-Francois-Regis Colin <fcolin@cenatoulouse.dgac.fr>
+Francois-Regis Colin
.nf
-Stephane Chatty <chatty@cenatoulouse.dgac.fr>
+Stephane Chatty
.SH SEE ALSO
ivyprobe (1)
ivy-c-functions (1)
.sp
-For further details, please refer to the Ivy html page at http://www.cenatls.cena.dgac.fr/pii/produits/Ivy.html
+For further details, please refer to the Ivy html page at http:// www.tls.cena.fr/pii/produits/Ivy.html
.SH NOTES
In case of any comment or bug report on this library, please contact
-fcolin@cenatoulouse.dgac.fr, chatty@cenatoulouse.dgac.fr, jacomi@cenatoulouse.dgac.fr
+ivy@tls.cena.fr
diff --git a/doc/ivy-c.sgml b/doc/ivy-c.sgml
index bd0be09..578ef61 100644
--- a/doc/ivy-c.sgml
+++ b/doc/ivy-c.sgml
@@ -6,7 +6,7 @@
SGML source file
- Authors: Stéphane Chatty <chatty@cena.dgac.fr>
+ Authors: Stéphane Chatty <chatty@cena.fr>
$Id$
@@ -37,17 +37,17 @@
<affiliation><address><email>jestin@cena.fr</email></address></affiliation>
</author>
</authorgroup>
-<date>December 11, 2002</date>
+<date>November 09, 2006</date>
<copyright>
-<year>1998-2006</year>
+<year>1998-2002</year>
<holder>Centre d'Études de la Navigation Aérienne</holder>
</copyright>
<abstract>
<para>
This document is a programmer's guide that describes how to use the Ivy C
-library to connect applications to an Ivy bus. This guide describes version 3.8
+library to connect applications to an Ivy bus. This guide describes version 3.9
of the library.
</para>
</abstract>
@@ -90,7 +90,7 @@ library, please refer to <citetitle>The Ivy sofware bus: a white
paper</citetitle>. If you want more details about the internals of Ivy, have a
look at <citetitle>The Ivy architecture and protocol</citetitle>. And finally,
if you are more interested in other languages, refer to other guides such as
-<citetitle>The Ivy Java library guide</citetitle>. All those documents should be
+<citetitle>The Ivy Perl library guide</citetitle>. All those documents should be
available from the Ivy Web site at <ulink URL="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</ulink>.
</para>
</sect1>
@@ -108,7 +108,7 @@ Ivy bus. This guide is here to help you do that.
</para>
<para>
-The Ivy C library is known to compile and work in Win32, Linux, and MacOSX
+The Ivy C library is known to compile and work in WindowsNT and Linux
environments. It should be easy to use on most Posix environments.
</para>
@@ -125,8 +125,8 @@ is maintained by a group at CENA (Toulouse, France)
You can get the latest versions of the Ivy C library from CENA
(<ulink URL="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</ulink>). Depending on whether you
use a supported binary distribution, you can retrieve binary RPM or
-Debian packages for Linux. Do not forget to get the development package as well as the
-run-time package, or retrieve the source files and compile them.
+Debian packages for Linux (do not forget to get the development package as well as the
+run-time package), or retrieve the source files and compile them.
</para>
</sect2>
@@ -151,8 +151,8 @@ Here is the code of "hellotranslater.c":
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;getopt.h&gt;
-#include &lt;Ivy/ivy.h&gt;
-#include &lt;Ivy/ivyloop.h&gt;
+#include &lt;ivy.h&gt;
+#include &lt;ivyloop.h&gt;
/* callback associated to "Hello" messages */
void HelloCallback (IvyClientPtr app, void *data, int argc, char **argv)
@@ -195,7 +195,7 @@ main (int argc, char**argv)
IvyBindMsg (ByeCallback, 0, "^Bye$");
/* main loop */
- IvyMainLoop (0,0);
+ IvyMainLoop();
}
</programlisting>
@@ -308,15 +308,14 @@ environment variable is not defined, the default value
<parameter>"127:2010"</parameter> is used.
<programlisting>
-void IvyMainLoop (void (*beforehook) (void),void (*afterhook) (void));
+void IvyMainLoop ();
</programlisting>
makes your application enter the main loop in which it will handle asynchronous
communications and signals. This is the default Ivy main loop, based on the
<function>select</function> POSIX system call.
-If non-null, <parameter>beforehook</parameter> is called every time the main loop is
-about to enter <function>select</function>, and can be used (with care!) to
-extend the main loop. <parameter>afterhook</parameter> is called each time the
-main loop exits <function>select</function>.
+You can interact with the mainloop using hook before and after <function>select</function>
+ use the <function>IvySetBeforeSelectHook</function> and <function>IvySetAfterSelectHook</function>
+
<programlisting>
void IvyStop ();
@@ -347,9 +346,7 @@ sends a message on the bus. This function has exactly the same behaviour as
<title>Subscribing to messages</title>
<para>
Subscribing to messages consists in binding a callback function to a message
-pattern. Patterns are described by regular expressions with captures. Since
-the 3.6 library, we use <ulink url="http://www.pcre.org/">Perl Compatible Regular
-Expression</ulink>. When a
+pattern. Patterns are described by regular expressions with captures. When a
message matching the regular expression is detected on the bus, the callback
function is called. The captures (ie the bits of the message that match the
parts of regular expression delimited by brackets) are passed to the callback
@@ -367,6 +364,13 @@ binds callback function <function>cb</function> to the regular expression specif
<parameter>regex_format</parameter> and the optional following arguments. <parameter>regex_format</parameter> and
the following arguments are handled as in <function>printf</function>. The return
value is an identifier that can be used later for cancelling the subscription.
+There is a special syntax for specifying numeric interval, in this case
+the interval is locally transformed in a pcre regexp.
+syntax is (?Imin#max[fi]). min and max are the bounds,
+by default the regexp match decimal number, but if max bound is
+followed by 'i', the regexp match only integers ex : (?I-10#20), (?I20#25i)
+Note that due to the regexp generator limitation (which will perhaps be raised eventually)
+the bounds are always integers.
<programlisting>
void IvyUnbindMsg (MsgRcvPtr id);
@@ -400,10 +404,7 @@ typedef void (*MsgCallback)(IvyClientPtr app, void *data, int argc, char **argv)
<sect2>
<title>Direct messages</title>
<para>
-There are cases when we don't want to send messages to every other subscribee
-on the bus. Direct messages allow peer to peer communication, and thus kind of
-break the software bus metaphor. We strongly discourage you to use them, and
-thus won't provide handy documentation.
+[to be written]
</para>
</sect2>
@@ -422,9 +423,9 @@ another library.
<title>Channels</title>
<para>
You can get a channel to be managed from the Ivy main loop by using functions
-<function>IvyChannelSetUp</function> and <function>IvyChannelClose</function>.
+<function>IvyChannelAdd</function> and <function>IvyChannelRemove</function>.
<programlisting>
-Channel IvyChannelSetUp (HANDLE fd,
+Channel IvyChannelAdd (HANDLE fd,
void* data,
ChannelHandleDelete handle_delete,
ChannelHandleRead handle_read);
@@ -434,7 +435,7 @@ descriptor <parameter>fd</parameter>, and function <parameter>handle_delete</par
closed, and
<programlisting>
-void IvyChannelClose (Channel ch);
+void IvyChannelRemove (Channel ch);
</programlisting>
terminates the management of channel <parameter>ch</parameter>.
</para>
@@ -535,7 +536,7 @@ following ones:
<listitem><para>IvyXtChannelAppContect(app_context) with an existing Xt
context</para>
<listitem><para>You can add channels to be handled by Ivy, for instance,
- stdin, with the IvyXtChannelSetUp function
+ stdin, with the IvyChannelAdd function
<listitem><para>IvyInit(char *name,char *readyMessage,IvyApplicationCallback
cb,void *cbUserData,IvyDieCallback dieCb,void *dieCbUserdata)</para>
<listitem><para>IvyBindMsg() for the behavior</para>
@@ -593,11 +594,21 @@ int main(int argc,char *argv[]){
<sect2>
<title>Using Ivy with Tcl/Tk</title>
-<para>
+<para>Just load the libtclivy.so package, and use the following commands
+<programlisting>
+#!/usr/bin/tclsh
+Ivy::init $name $hellomessge connectproc dieproc
+Ivy::start $domain
+Ivy::bind $regexp ballback
+Ivy::applist
+Ivy::send $message
+Ivy::applist
+mainloop
+</programlisting>
A full example in Tcl/Tk is provided here:
<programlisting>
#!/usr/bin/wish
-load libtclivy.so.3
+load libtclivy.so.3.4
proc connect {args} { }
proc send { } {
global tosend
@@ -618,12 +629,12 @@ pack .send
</sect2>
<sect2>
-<title>Using Ivy with Gtk/Gdk</title>
+<title>Using Ivy with Gtk</title>
<para>There is little to do to make your gtk applications Ivy aware: just add
the following lines into your code:
<programlisting>
-#include &lt;Ivy/ivy.h&gt;
-#include &lt;Ivy/ivyglibloop.h&gt;
+#include &lt;ivy.h&gt;
+#include &lt;ivygtkloop.h&gt;
...
IvyInit ("IvyGtkButton", "IvyGtkButton READY",NULL,NULL,NULL,NULL);
IvyBindMsg(textCallback,&amp;tosend,"^Ivy Button text=(.*)");
@@ -632,12 +643,12 @@ IvyStart (bus);
</para>
<para>A full example: gtkIvyButton.c is provided below, compile it with the
-appropriate flags for your gtk distribution ( `pkg-config --cflags --libs
-gtk+-x11-2.0 `) and -lglibivy .
+-lgtkivy flag. The other flags depend on your system installation ( replace
+pkg-config with gtk-config for older gnome1 libs)
<programlisting>
#include &lt;gtk/gtk.h&gt;
-#include &lt;Ivy/ivy.h&gt;
-#include &lt;Ivy/ivyglibloop.h&gt;
+#include &lt;ivy.h&gt;
+#include &lt;ivygtkloop.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
@@ -679,18 +690,21 @@ int main( int argc, char *argv[] ) {
<title>Functions to be provided</title>
<para>
You can decide to use the main loop from another toolkit than the X Toolkit
-or the Tk toolkit. If you do that, you'll have to define three functions that
-Ivy will use to get its own channels managed by the other toolkit. The three
-following global variables should be defined:
+or the Tk toolkit. If you do that, you'll have to define four functions that
+Ivy will use to get its own channels managed by the other toolkit.
+you should link ivy with your new module insted of the ivy(xxx)loop module.
+These functions are declared in ivychannel.h:
<programlisting>
-ChannelInit channel_init;
-ChannelSetUp channel_setup;
-ChannelClose channel_close;
+IvyChannelInit
+IvyChannelStop
+IvyChannelAdd
+IvyChannelRemove
</programlisting>
They should point to functions that respectively:
<itemizedlist>
<listitem><para> make the necessary global initializations before entering the main loop</para>
+<listitem><para> make the necessary global finalizations before exiting the main loop</para>
<listitem><para> initialize a channel and ensure that it is managed by the main loop</para>
<listitem><para> close a channel</para>
</itemizedlist>
@@ -700,13 +714,21 @@ The types <type>ChannelInit</type>, <type>ChannelSetUp</type> and <type>ChannelC
as follows:
<programlisting>
-typedef void (*ChannelInit)(void);
-typedef Channel (*ChannelSetUp)(
+extern void IvyChannelInit(void);
+
+extern void IvyChannelStop (void);
+
+/* function called by Ivy to set callback on the sockets */
+extern Channel IvyChannelAdd(
HANDLE fd,
void *data,
ChannelHandleDelete handle_delete,
- ChannelHandleRead handle_read);
-typedef void (*ChannelClose)( Channel channel );
+ ChannelHandleRead handle_read
+);
+
+/* function called by Ivy to remove callback on the sockets */
+extern void IvyChannelRemove( Channel channel );
+
</programlisting>
</para>
</sect3>
diff --git a/examples/gtkIvyButton.c b/examples/gtkIvyButton.c
index aba5ea7..e4c7a1a 100644
--- a/examples/gtkIvyButton.c
+++ b/examples/gtkIvyButton.c
@@ -1,8 +1,8 @@
-#include <gtk/gtk.h>
-#include <ivy.h>
-#include <ivyglibloop.h>
#include <stdio.h>
#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <Ivy/ivy.h>
+#include <Ivy/ivyglibloop.h>
diff --git a/examples/motifButtonIvy.c b/examples/motifButtonIvy.c
index 084359f..cebc292 100644
--- a/examples/motifButtonIvy.c
+++ b/examples/motifButtonIvy.c
@@ -2,8 +2,8 @@
#include <stdio.h>
#include <strings.h>
#include <Xm/PushB.h>
-#include <ivy.h>
-#include <ivyxtloop.h>
+#include <Ivy/ivy.h>
+#include <Ivy/ivyxtloop.h>
void myMotifCallback(Widget w,XtPointer client_d,XtPointer call_d){
// sends the string on the bus
diff --git a/examples/testUnbind.c b/examples/testUnbind.c
index 16a4a8a..2cc7fdd 100644
--- a/examples/testUnbind.c
+++ b/examples/testUnbind.c
@@ -13,8 +13,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <ivyloop.h>
-#include <ivy.h>
+#include <Ivy/ivyloop.h>
+#include <Ivy/ivy.h>
+#include <Ivy/version.h>
#define REGEXP "^ub"
void Callback (IvyClientPtr app, void *user_data, int argc, char *argv[]) {
@@ -30,6 +31,10 @@ int main(int argc, char *argv[]) {
ptr=IvyBindMsg(Callback,&ptr,REGEXP);
printf("bound to %s\n",REGEXP);
IvyStart(NULL);
- IvyMainLoop(0);
+#if (IVYMAJOR_VERSION == 3) && (IVYMINOR_VERSION < 9)
+ IvyMainLoop(NULL, NULL);
+#else
+ IvyMainLoop();
+#endif
return 0;
}
diff --git a/redhat/changelog b/redhat/changelog
deleted file mode 100644
index 72bccd0..0000000
--- a/redhat/changelog
+++ /dev/null
@@ -1,105 +0,0 @@
-$Version = "3.7";
-$Release = 0;
-
-$ChangeLog = ' * Sat Feb 20 1999 Stéphane Chatty <chatty@cenatoulouse.dgac.fr>
-- Generation of ivy-c-3.0-2
-- New version 3.0, with new syntax for bus specification.
-
- * Sat Feb 20 1999 Stéphane Chatty <chatty@cenatoulouse.dgac.fr>
-- Generation of ivy-c-3.0-3
-- New Makefile with major and minor numbers
-
- * Sat Feb 20 1999 Stéphane Chatty <chatty@cenatoulouse.dgac.fr>
-- Generation of ivy-c-3.0-4
-- First attempt to fix dependencies
-
- * Sat Feb 20 1999 Stéphane Chatty <chatty@cenatoulouse.dgac.fr>
-- Generation of ivy-c-3.0-5
-- Fixed Makefile: added links for shared libs
-
- * Tue Apr 13 1999 Michelle Jacomi <jacomi@cenatoulouse.dgac.fr>
-- Generation of ivy-c-3.0-8
-- doc files added to ivy-c package
-
- * Mon Mar 13 2000 Stéphane Chatty <chatty@cena.fr>
-- Generation of ivy-c-3.2-1
-- First package with new version of rpmize. This is ivy-c 3.2
-
- * Tue Jul 4 2000 Stéphane Chatty <chatty@cena.fr>
-- Generation of version 3.2-2
-- First packages made with rpmize 3.1
-- Separation between ivy-c and ivy-c-devel
-
- * Wed Jul 12 2000 Stéphane Chatty <chatty@cena.fr>
-- Generation of version 3.2-3
-- The ivyprobe man page is now part of the main package
-- The URL has been fixed
-
- * Mon Aug 7 2000 Stéphane Chatty <chatty@cena.fr>
-- Generation of version 3.2-4
-- Just an upgrade of the documentation and fixes in the copyright headers
-
- * Tue Dec 12 2000 Stéphane Chatty <chatty@cena.fr>
-- Generation of version 3.2-5
-- Small fix in doc
-
- * Fri Dec 22 2000 Stéphane Chatty <chatty@cena.fr>
-- Generation of version 3.3-1
-- Additions by F.R.Colin
-
- * Tue Jun 25 2002 Stéphane Chatty <chatty@cena.fr>
-- Generation of version 3.4-1
-- * support of multicast, with IP adresses between 224.0.0.0 and 239.255.255.255
-- (i.e. no support for named group), by frc
-- * correction of message parsing in some strange but correct messages, by frc
-- e.g. with a regexp like "foo(.*) (.*)" and a message like "foo1 2", the receiver
-- will receive two values \'1\' and \'2\'
-- * upgrade of the documentation and fixes in the copyright headers, by sc
-- * miminal support of glut toolkit, by frc. However, there is currently no
-- libglutivy in the bin package due to some glut loop limitation.
-
-
-
- * Thu, 24 Jun 2004 Yannick Jestin <jestin@cena.fr>
-- Generation of version 3.6
-- * now uses PCRE ( Perl Compatible Regular Expressions ). Please use -livy -lpcre
-- now when compiling. See http://www.pcre.org or man pcre for more details
-- * tclivy.c : many bugfixes to support spaces in parameters captured by
-- regexp
-- * added an example directory, with gtk motif and tk bindings
-- * fixed a nasty bug in the IvyUnbindMsg, where new client still were sent a
-- binding to the unbound regexps
-- * added a help message for ivyprobe, when called with -? or with unknown
-- command line switches
-- * added a -n switch to ivyprobe to change the name of the ivyprobe
-- * added a -v switch to ivyprobe to check the ivy-c version
-- * Makefile merges solaris, linux, and OSX versions. edit before compiling...
-
- * Thu Sep 2 2004 Alexandre Bustico <bustico@cena.fr>
-- Generation of version 3.6-1
-- updates redhat files to coorect rules file for rpmize
-
- * Tue Sep 7 2004 Alexandre Bustico <bustico@cena.fr>
-- Generation of version 3.6-1
-- update rules file
-
- * Tue Sep 7 2004 Alexandre Bustico <bustico@cena.fr>
-- Generation of version 3.6-1
-
- * Tue Sep 7 2004 Alexandre Bustico <bustico@cena.fr>
-- Generation of version 3.6-1
-- no more libgtkivy, replaced by libgivy, changing redhat/files rules to take change
-
- * Tue Sep 7 2004 Alexandre Bustico <bustico@cena.fr>
-- Generation of version 3.6-1
-
- * Tue Sep 7 2004 Alexandre Bustico <bustico@cena.fr>
-- Generation of version 3.6-1
-
- * Tue Sep 7 2004 Alexandre Bustico <bustico@cena.fr>
-- Generation of version 3.6-2
-
- * Thu Fev 24 2005 Guillaume Vidon <vidon@cena.fr>
-- Generation of version 3.7
-
-';
diff --git a/redhat/files b/redhat/files
deleted file mode 100644
index 3c3fca5..0000000
--- a/redhat/files
+++ /dev/null
@@ -1,15 +0,0 @@
-/usr/bin/ivyprobe
-/usr/lib/libgivy.so
-/usr/lib/libgivy.so.3
-/usr/lib/libgivy.so.3.6
-/usr/lib/libivy.so
-/usr/lib/libivy.so.3
-/usr/lib/libivy.so.3.6
-/usr/lib/libtclivy.so
-/usr/lib/libtclivy.so.3.6
-/usr/man/man1/ivyprobe.1
-/usr/X11R6/bin/ivygtkprobe
-/usr/X11R6/bin/ivyxtprobe
-/usr/X11R6/lib/libxtivy.so
-/usr/X11R6/lib/libxtivy.so.3
-/usr/X11R6/lib/libxtivy.so.3.6
diff --git a/redhat/rules b/redhat/rules
deleted file mode 100644
index d5d7603..0000000
--- a/redhat/rules
+++ /dev/null
@@ -1,21 +0,0 @@
-$Summary = "Ivy, C interface";
-$Name = "ivy-c";
-$Copyright = "CENA";
-$Vendor = "Centre d'Etudes de la Navigation Aerienne";
-$Distribution = "Toccata";
-$Group = "System Environment/Libraries";
-$Url = "http://www.tls.cena.fr/products/ivy";
-$BuildArchitectures = "i586";
-$Description = "This is the C library that implements the
-connection to the Ivy software bus developed at CENA";
-$Requires = "ivy-c = \%{version}-\%{release} " .
- "glibc libpcre libgtk+1.2 libglib2 libxfree86 tcl" ;
-
-
-$FindFiles = "(find \$RPM_BUILD_ROOT -type f -print ; find \$RPM_BUILD_ROOT -type l -print) | sed \"s\@^\$RPM_BUILD_ROOT\@\@g\" | sort | join redhat/files - ";
-
-$Install = "rm -Rf \$RPM_BUILD_ROOT
-cd src
-make PREFIX=\$RPM_BUILD_ROOT install
-cd ..
-(find \$RPM_BUILD_ROOT -type f -print; find \$RPM_BUILD_ROOT -type l -print) | sed \"s\@^\$RPM_BUILD_ROOT\@\@g\" | grep -v perllocal.pod | grep -v .packlist > $Name-\%{version}-filelist";
diff --git a/redhat/rules-devel b/redhat/rules-devel
deleted file mode 100644
index 04bfa0e..0000000
--- a/redhat/rules-devel
+++ /dev/null
@@ -1,17 +0,0 @@
-$Summary = "Ivy, development files for the C interface";
-$Name = "ivy-c-devel";
-$Copyright = "CENA";
-$Vendor = "Centre d'Etudes de la Navigation Aerienne";
-$Distribution = "Toccata";
-$Group = "Development/Libraries";
-$Url = "http://www.tls.cena.fr/divisions/PII/";
-$BuildArchitectures = "i586";
-$Requires = "ivy-c = \%{version}-\%{release} " .
- "glibc-devel libpcre0-devel libgtk+1.2-devel libglib2-devel libxfree86-devel tcl-devel" ;
-
-undef $FindFiles;
-undef $Install ;
-
-$Description = "This contains the headers and static libraries necessary for
-developping and debugging applications that use the Ivy C library.";
-
diff --git a/src/Makefile b/src/Makefile
index b4f90ef..26789d0 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -4,11 +4,11 @@
# Copyright (C) 1997-2002
# Centre d'Études de la Navigation Aérienne
#
-# Makefile
+# Makefile
#
# Authors: François-Régis Colin <fcolin@cena.fr>
-# Stéphane Chatty <chatty@cena.fr>
-# Yannick Jestin <jestin@cena.fr>
+# Stéphane Chatty <chatty@cena.fr>
+# Yannick Jestin <jestin@cena.fr>
#
# Please refer to file version.h for the
# copyright notice regarding this software
@@ -16,11 +16,25 @@
# change this in version.h too !!!!
-MAJOR=4
-MINOR=0
+MAJOR=3
+MINOR=9
-XTINC = -I/usr/X11R6/include
-XTLIB = -L/usr/X11R6/lib -lXt -lX11 -lSM -lICE
+PERHAPS64 := $(shell uname -m | perl -ne "print /64/ ? '64' : '';")
+LIB = /lib$(PERHAPS64)
+ifeq ($(PERHAPS64), "64")
+ FPIC=
+else
+ FPIC=-fPIC
+endif
+
+ifndef PREFIX
+ PREFIX=/usr/local
+endif
+
+X11_PREFIX = /usr
+
+XTINC = -I$(X11_PREFIX)/include
+XTLIB = -L$(X11_PREFIX)$(LIB) -lXt -lX11 -lSM -lICE
GLIBINC = `pkg-config --cflags glib-2.0`
GLIBLIB = `pkg-config --libs glib-2.0`
GLUTINC = -I/usr/include -I.
@@ -30,19 +44,22 @@ GLUTLIB = -L. -lglut -lGLU -lGL -lX11 -lXmu
#TCLVERS = `perl -e '@_=sort map (m|/usr/lib/libtcl(\d\.\d)\.so|, glob ("/usr/lib/libtcl*")); print pop @_'`
TCLVERS:= $(shell perl -e '@_=sort map (m|/usr/lib/libtcl(\d\.\d)\.so|, glob ("/usr/lib/libtcl*")); print pop @_')
ifndef TCLVERS
+TCLVERS:= $(shell perl -e '@_=sort map (m|/usr/lib64/libtcl(\d\.\d)\.so|, glob ("/usr/lib64/libtcl*")); print pop @_')
+endif
+ifndef TCLVERS
TCLVERS=8.3
endif
-TCLINCL = -I/usr/include/tcl$(TCLVERS)
+TCLINCL = -I/usr/include/tcl$(TCLVERS)
TCLLIB = -ltcl$(TCLVERS)
#TCLINCL = -I/usr/include/tcl8.4
#TCLLIB = -ltcl8.4
# use these if you want to use Aqua Tcl on macOSX
-#TCLINC = -I/Library/Frameworks/Tcl.framework/Headers
+#TCLINC = -I/Library/Frameworks/Tcl.framework/Headers
#TCLLIB = -framework Tcl
PCREINC = `pcre-config --cflags`
PCRELIB = `pcre-config --libs`
-CASESENSITIVE = "no"
+CASESENSITIVE = "yes"
ifeq ($(CASESENSITIVE), "no")
PCRE_OPT=PCRE_CASELESS
REGCOMP_OPT=REG_ICASE
@@ -61,22 +78,24 @@ CC=gcc
LIBTOOL=ar q # linux and solaris
#LIBTOOL=libtool -static -o
-#REGEXP = -DGNU_REGEXP -DREGCOMP_OPT=$(REGCOMP_OPT) # deprecated !
+#REGEXP = -DGNU_REGEXP -DREGCOMP_OPT=$(REGCOMP_OPT) # deprecated !
REGEXP= -DUSE_PCRE_REGEX -DPCRE_OPT=$(PCRE_OPT)
# on activeTCL , set #define CHANNEL to null, and add ivyloop.o in the ivytcl target,
# see below
CHANNEL = -DTCL_CHANNEL_INTEGRATION
-CFLAGS = -g -Wall #-DDEBUG
-
-COMOBJ = hash.o ivysocket.o ivybind.o ivyargument.o ivy.o
-OBJ = $(COMOBJ) ivyloop.o timer.o
-XTOBJ = $(COMOBJ) ivyxtloop.o
-GLIBOBJ = $(COMOBJ) ivyglibloop.o
-GLUTOBJ = $(COMOBJ) ivyglutloop.o
-TCLOBJ = $(COMOBJ) ivytcl.o timer.o
+CFLAGS = -g -Wall $(FPIC)
+
+
+OBJ = ivyloop.o timer.o ivysocket.o ivy.o ivybuffer.o ivybind.o intervalRegexp.o
+GOBJ = ivyloop.o timer.o ivysocket.o givy.o ivybuffer.o ivybind.o intervalRegexp.o
+XTOBJ = ivyxtloop.o ivysocket.o ivy.o ivybuffer.o ivybind.o intervalRegexp.o
+GLIBOBJ = ivyglibloop.o ivysocket.o ivy.o ivybuffer.o ivybind.o intervalRegexp.o
+GLUTOBJ = ivyglutloop.o ivysocket.o ivy.o ivybuffer.o ivybind.o intervalRegexp.o
+TCLOBJ = ivytcl.o timer.o ivysocket.o givy.o ivybuffer.o ivybind.o intervalRegexp.o
+
# WINDOWS add ivyloop.o if TCL_CHANNEL_INTEGRATION is not set
TARGETS = ivyprobe ivyperf ivyglibprobe ivyxtprobe
-TARGETLIBS=libivy.so.$(MAJOR).$(MINOR) libxtivy.so.$(MAJOR).$(MINOR) libglibivy.so.$(MAJOR).$(MINOR) libtclivy.so.$(MAJOR).$(MINOR)
+TARGETLIBS=libivy.so.$(MAJOR).$(MINOR) libgivy.so.$(MAJOR).$(MINOR) libxtivy.so.$(MAJOR).$(MINOR) libglibivy.so.$(MAJOR).$(MINOR) libtclivy.so.$(MAJOR).$(MINOR)
# not yet need Modified Glut ivyglutprobe
.c.o:
@@ -84,7 +103,7 @@ TARGETLIBS=libivy.so.$(MAJOR).$(MINOR) libxtivy.so.$(MAJOR).$(MINOR) libglibivy.
all: static-libs commands shared-libs
-static-libs: libivy.a libxtivy.a libglibivy.a libtclivy.a
+static-libs: libivy.a libgivy.a libxtivy.a libglibivy.a libtclivy.a
# not yet need Modified Glut libglutivy.a
shared-libs: $(TARGETLIBS)
@@ -92,17 +111,15 @@ shared-libs: $(TARGETLIBS)
commands: $(TARGETS)
-ivytcl.o: ivytcl.c
- $(CC) -c $(CFLAGS) $(TCLINCL) $(CHANNEL) ivytcl.c
-
-ivy.o: ivy.c
- $(CC) -c $(CFLAGS) ivy.c
-
ivybind.o: ivybind.c
$(CC) -c $(CFLAGS) $(REGEXP) $(PCREINC) ivybind.c
-ivyargument.o: ivyargument.c
- $(CC) -c $(CFLAGS) $(REGEXP) $(PCREINC) ivyargument.c
+
+ivytcl.o: ivytcl.c
+ $(CC) -c $(CFLAGS) $(TCLINCL) $(CHANNEL) ivytcl.c
+
+givy.o: ivy.c
+ $(CC) -c $(CFLAGS) -DDEBUG -o givy.o ivy.c
ivyglutloop.o: ivyglutloop.c ivyglutloop.h
$(CC) -c $(CFLAGS) $(GLUTINC) ivyglutloop.c
@@ -115,13 +132,10 @@ ivyprobe: ivyprobe.o libivy.a
ivyprobe.o : ivyprobe.c
$(CC) $(CFLAGS) $(REGEXP) -c ivyprobe.c -o $@
-
+
ivyperf: ivyperf.o libivy.a
$(CC) $(CFLAGS) -o $@ ivyperf.o -L. -livy $(PCRELIB) $(EXTRALIB)
-ivyperf.o : ivyperf.c
- $(CC) $(CFLAGS) $(REGEXP) -c ivyperf.c -o $@
-
ivyxtprobe.o : ivyprobe.c
$(CC) $(CFLAGS) $(REGEXP) -DXTMAINLOOP -c ivyprobe.c -o $@ $(XTINC)
@@ -144,6 +158,10 @@ libivy.a: $(OBJ)
rm -f $@
$(LIBTOOL) $@ $(OBJ)
+libgivy.a: $(GOBJ)
+ rm -f $@
+ $(LIBTOOL) $@ $(GOBJ)
+
libxtivy.a: $(XTOBJ)
rm -f $@
$(LIBTOOL) $@ $(XTOBJ)
@@ -166,6 +184,11 @@ libivy.so.$(MAJOR).$(MINOR): $(OBJ)
# $(CC) -G -Wl,-h,libivy.so.$(MAJOR) -o $@ $(OBJ) #solaris
# libtool -dynamic -o $@ $(OBJ) $(PCRELIB) -lc
+libgivy.so.$(MAJOR).$(MINOR): $(GOBJ)
+ $(CC) -shared -Wl,-soname,libgivy.so.$(MAJOR) -o $@ $(GOBJ) $(PCRELIB)
+# $(CC) -G -Wl,-h,libgivy.so.$(MAJOR) -o $@ $(GOBJ) #solaris
+# libtool -dynamic -o $@ $(GOBJ) $(PCRELIB) -lc
+
libxtivy.so.$(MAJOR).$(MINOR): $(XTOBJ)
$(CC) -shared -Wl,-soname,libxtivy.so.$(MAJOR) -o $@ $(XTOBJ) $(XTLIB) $(PCRELIB)
# $(CC) -G -Wl,-h,libxtivy.so.$(MAJOR) -o $@ $(XTOBJ) $(XTLIB) #solaris
@@ -190,55 +213,73 @@ clean:
-rm -f $(TARGETS) $(TARGETLIBS) *.o *.a *.so *.so.* *~
installlibs: static-libs shared-libs
- test -d $(PREFIX)/usr/lib || mkdirhier $(PREFIX)/usr/lib
- test -d $(PREFIX)/usr/X11R6/lib || mkdirhier $(PREFIX)/usr/X11R6/lib
- test -d $(PREFIX)/usr/include || mkdirhier $(PREFIX)/usr/include
- install -m644 libivy.a $(PREFIX)/usr/lib
- install -m644 libxtivy.a $(PREFIX)/usr/X11R6/lib
- install -m644 libtclivy.a $(PREFIX)/usr/lib
- install -m644 libglibivy.a $(PREFIX)/usr/lib
-
- install -m644 libivy.so.$(MAJOR).$(MINOR) $(PREFIX)/usr/lib
- install -m644 libxtivy.so.$(MAJOR).$(MINOR) $(PREFIX)/usr/X11R6/lib
- install -m644 libtclivy.so.$(MAJOR).$(MINOR) $(PREFIX)/usr/lib
- install -m644 libglibivy.so.$(MAJOR).$(MINOR) $(PREFIX)/usr/lib
-
- install -m644 *.h $(PREFIX)/usr/include
+ test -d $(DESTDIR)$(PREFIX)$(LIB) || mkdirhier $(DESTDIR)$(PREFIX)$(LIB)
+ test -d $(DESTDIR)$(X11_PREFIX)$(LIB) || mkdirhier $(DESTDIR)$(X11_PREFIX)$(LIB)
+
+ install -m644 libivy.a $(DESTDIR)$(PREFIX)$(LIB)
+ install -m644 libgivy.a $(DESTDIR)$(PREFIX)$(LIB)
+ install -m644 libxtivy.a $(DESTDIR)$(X11_PREFIX)$(LIB)
+ install -m644 libtclivy.a $(DESTDIR)$(PREFIX)$(LIB)
+ install -m644 libglibivy.a $(DESTDIR)$(PREFIX)$(LIB)
+
+ install -m644 libivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(PREFIX)$(LIB)
+ install -m644 libgivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(PREFIX)$(LIB)
+ install -m644 libxtivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(X11_PREFIX)$(LIB)
+ install -m644 libtclivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(PREFIX)$(LIB)
+ install -m644 libglibivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(PREFIX)$(LIB)
+
+includes:
+ test -d $(DESTDIR)$(PREFIX)/include/Ivy || mkdirhier $(DESTDIR)$(PREFIX)/include/Ivy
+ install -m644 ivy.h $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 ivybind.h $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 ivybuffer.h $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 ivychannel.h $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 ivydebug.h $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 ivyglibloop.h $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 ivyglutloop.h* $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 ivyloop.h $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 ivysocket.h $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 ivytcl.h* $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 ivyxtloop.h $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 list.h $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 timer.h $(DESTDIR)$(PREFIX)/include/Ivy/
+ install -m644 version.h $(DESTDIR)$(PREFIX)/include/Ivy/
installliblinks: installlibs
- ln -fs /usr/lib/libivy.so.$(MAJOR).$(MINOR) $(PREFIX)/usr/lib/libivy.so
- ln -fs /usr/lib/libivy.so.$(MAJOR).$(MINOR) $(PREFIX)/usr/lib/libivy.so.$(MAJOR)
- ln -fs /usr/X11R6/lib/libxtivy.so.$(MAJOR).$(MINOR) $(PREFIX)/usr/X11R6/lib/libxtivy.so
- ln -fs /usr/X11R6/lib/libxtivy.so.$(MAJOR).$(MINOR) $(PREFIX)/usr/X11R6/lib/libxtivy.so.$(MAJOR)
- ln -fs /usr/lib/libtclivy.so.$(MAJOR).$(MINOR) $(PREFIX)/usr/lib/libtclivy.so
- ln -fs /usr/lib/libtclivy.so.$(MAJOR).$(MINOR) $(PREFIX)/usr/lib/libtclivy.so.$(MAJOR)
+ ln -fs $(PREFIX)$(LIB)/libivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(PREFIX)$(LIB)/libivy.so
+ ln -fs $(PREFIX)$(LIB)/libivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(PREFIX)$(LIB)/libivy.so.$(MAJOR)
+ ln -fs $(PREFIX)$(LIB)/libgivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(PREFIX)$(LIB)/libgivy.so
+ ln -fs $(PREFIX)$(LIB)/libgivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(PREFIX)$(LIB)/libgivy.so.$(MAJOR)
+ ln -fs $(X11_PREFIX)$(LIB)/libxtivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(X11_PREFIX)$(LIB)/libxtivy.so
+ ln -fs $(X11_PREFIX)$(LIB)/libxtivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(X11_PREFIX)$(LIB)/libxtivy.so.$(MAJOR)
+ ln -fs $(PREFIX)$(LIB)/libtclivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(PREFIX)$(LIB)/libtclivy.so
+ ln -fs $(PREFIX)$(LIB)/libtclivy.so.$(MAJOR).$(MINOR) $(DESTDIR)$(PREFIX)$(LIB)/libtclivy.so.$(MAJOR)
installbins: commands
- test -d $(PREFIX)/usr/bin || mkdirhier $(PREFIX)/usr/bin
- test -d $(PREFIX)/usr/X11R6/bin || mkdirhier $(PREFIX)/usr/X11R6/bin
- install -m755 ivyprobe $(PREFIX)/usr/bin
- #install -m755 ivyxtprobe $(PREFIX)/usr/X11R6/bin
- #install -m755 ivyglibprobe $(PREFIX)/usr/bin
- #install -m755 ivyglutprobe $(PREFIX)/usr/X11R6/bin
+ test -d $(DESTDIR)$(PREFIX)/bin || mkdirhier $(DESTDIR)$(PREFIX)/bin
+ install -m755 ivyprobe $(DESTDIR)$(PREFIX)/bin
+ #install -m755 ivyxtprobe $(DESTDIR)$(PREFIX)/bin
+ #install -m755 ivyglibprobe $(DESTDIR)$(PREFIX)/bin
+ #install -m755 ivyglutprobe $(DESTDIR)$(PREFIX)/bin
installdocs:
- test -d $(PREFIX)/usr/share/doc/ivy-c || mkdirhier $(PREFIX)/usr/share/doc/ivy-c
- for f in `find ../doc/*.html -type f -maxdepth 1`; do \
- install -m 644 $$f $(PREFIX)/usr/share/doc/ivy-c; \
- done
- test -d $(PREFIX)/usr/man/man1 || mkdirhier $(PREFIX)/usr/man/man1
- for f in `find ../doc/*.1 -type f -maxdepth 1`; do \
- install -m 644 $$f $(PREFIX)/usr/man/man1; \
- done
- test -d $(PREFIX)/usr/share/doc/ivy-c/examples || mkdirhier $(PREFIX)/usr/share/doc/ivy-c/examples
- install -m 644 version.h $(PREFIX)/usr/share/doc/ivy-c/copyright
- install -m 644 ../examples/motifButtonIvy.c $(PREFIX)/usr/share/doc/ivy-c/examples
- install -m 644 ../examples/testUnbind.c $(PREFIX)/usr/share/doc/ivy-c/examples
- install -m 766 ../examples/Test.tcl $(PREFIX)/usr/share/doc/ivy-c/examples
- install -m 766 ../examples/button.tk $(PREFIX)/usr/share/doc/ivy-c/examples
- install -m 766 ../examples/unBind.tcl $(PREFIX)/usr/share/doc/ivy-c/examples
-
-install: installlibs installbins installliblinks installdocs
+ test -d $(DESTDIR)$(PREFIX)/share/doc/ivy-c || mkdirhier $(DESTDIR)$(PREFIX)/share/doc/ivy-c
+ for f in `find ../doc/*.html -type f -maxdepth 1`; do \
+ install -m 644 $$f $(DESTDIR)$(PREFIX)/share/doc/ivy-c; \
+ done
+ test -d $(DESTDIR)$(PREFIX)/man/man1 || mkdirhier $(DESTDIR)$(PREFIX)/man/man1
+ for f in `find ../doc/*.1 -type f -maxdepth 1`; do \
+ install -m 644 $$f $(DESTDIR)$(PREFIX)/man/man1; \
+ done
+ test -d $(DESTDIR)$(PREFIX)/share/doc/ivy-c/examples || mkdirhier $(DESTDIR)$(PREFIX)/share/doc/ivy-c/examples
+ install -m 644 version.h $(DESTDIR)$(PREFIX)/share/doc/ivy-c/copyright
+ install -m 644 ../examples/motifButtonIvy.c $(DESTDIR)$(PREFIX)/share/doc/ivy-c/examples
+ install -m 644 ../examples/testUnbind.c $(DESTDIR)$(PREFIX)/share/doc/ivy-c/examples
+ install -m 766 ../examples/Test.tcl $(DESTDIR)$(PREFIX)/share/doc/ivy-c/examples
+ install -m 766 ../examples/button.tk $(DESTDIR)$(PREFIX)/share/doc/ivy-c/examples
+ install -m 766 ../examples/unBind.tcl $(DESTDIR)$(PREFIX)/share/doc/ivy-c/examples
+
+install: installlibs installbins installliblinks installdocs includes
rpm::
/usr/bin/rpmize
diff --git a/src/Makefile.mingw b/src/Makefile.mingw
index 6c98e87..3bac78f 100755
--- a/src/Makefile.mingw
+++ b/src/Makefile.mingw
@@ -17,7 +17,7 @@
MAJOR=3
-MINOR=6
+MINOR=9
RM=del
#RM=rm -f
XTINC =
diff --git a/src/Makefile.win32 b/src/Makefile.win32
index 6e7e43c..8bcdb97 100755
--- a/src/Makefile.win32
+++ b/src/Makefile.win32
@@ -16,11 +16,14 @@
# change this in version.h too !!!!
-MAJOR=4
-MINOR=0
+MAJOR=3
+MINOR=9
-PCREINC = -I "C:\Program Files\GnuWin32\include" #`pcre-config --cflags`
-PCRELIB = "C:\Program Files\GnuWin32\lib\libpcre.lib" #`pcre-config --libs`
+PCREINC = -I "C:\Documents and Settings\fcolin\My Documents\Visual Studio 2005\Projects\pcre-6.4\\"
+PCRELIB = Debug\pcre.lib
+
+#PCREINC = -I "C:\Program Files\GnuWin32\include" #`pcre-config --cflags`
+#PCRELIB = "C:\Program Files\GnuWin32\lib\libpcre.lib" #`pcre-config --libs`
PCRE_OPT = PCRE_CASELESS
REGCOMP_OPT = REG_ICASE
@@ -34,61 +37,57 @@ PCREOBJ =
#CC=gcc
#CFLAGS = -g -Wall
-CFLAGS = -DWIN32 -D_CRTDBG_MAP_ALLOC -nologo -GS -Zi -MDd #-DDEBUG
+CFLAGS = /W3 /DWIN32 /D_CRT_SECURE_NO_DEPRECATE /nologo
#LIBTOOL=ar q # linux and solaris
#LIBTOOL=libtool -static -o
-LIBTOOL=lib -nologo /out:
+LIBTOOL=lib /nologo /out:
#REGEXP = -DGNU_REGEXP -DREGCOMP_OPT=$(REGCOMP_OPT) # deprecated !
-REGEXP= -DUSE_PCRE_REGEX -DPCRE_OPT=$(PCRE_OPT)
+REGEXP= /DUSE_PCRE_REGEX /DPCRE_OPT=$(PCRE_OPT)
# on activeTCL , set #define CHANNEL to null, and add ivyloop.obj in the ivytcl target,
# see below
CHANNEL = -DTCL_CHANNEL_INTEGRATION
-
-OBJ = hash.obj ivyloop.obj timer.obj ivysocket.obj ivy.obj ivybind.obj ivyargument.obj
+OBJ = intervalRegexp.obj ivyloop.obj timer.obj ivysocket.obj ivy.obj ivybuffer.obj ivybind.obj getopt.obj
# WINDOWS add ivyloop.obj if TCL_CHANNEL_INTEGRATION is not set
TARGETS = ivyprobe.exe ivyperf.exe
-TARGETLIBS=ivy.dll
+TARGETLIBS=libivy.dll
.c.obj:
- $(CC) $(CFLAGS) -c $*.c
+ $(CC) $(CFLAGS) /c $*.c
all: static-libs commands shared-libs
-static-libs: ivy-static.lib
+static-libs: libivy.lib
shared-libs: $(TARGETLIBS)
commands: $(TARGETS)
ivybind.obj: ivybind.c
- $(CC) -c $(CFLAGS) $(REGEXP) $(PCREINC) ivybind.c
+ $(CC) $(CFLAGS) $(REGEXP) $(PCREINC) /c ivybind.c
-ivyprobe.exe: ivyprobe.obj getopt.obj ivy.dll
- $(CC) $(CFLAGS) -o $@ ivyprobe.obj getopt.obj ivy.lib wsock32.lib $(PCRELIB)
+ivyprobe.exe: ivyprobe.obj libivy.lib
+ $(CC) $(CFLAGS) /Fe$@ ivyprobe.obj libivy.lib wsock32.lib $(PCRELIB)
ivyprobe.obj : ivyprobe.c
- $(CC) -c $(CFLAGS) $(REGEXP) $(PCREINC) ivyprobe.c
+ $(CC) $(CFLAGS) $(REGEXP) $(PCREINC) /c ivyprobe.c
-ivyperf.exe: ivyperf.obj getopt.obj ivy.dll
- $(CC) $(CFLAGS) -o $@ ivyperf.obj getopt.obj ivy.lib wsock32.lib $(PCRELIB)
-
-ivyperf.obj : ivyperf.c
- $(CC) -c $(CFLAGS) $(REGEXP) $(PCREINC) ivyperf.c
+ivyperf.exe: ivyperf.obj libivy.lib
+ $(CC) $(CFLAGS) /Fe$@ ivyperf.obj libivy.lib wsock32.lib $(PCRELIB)
-ivy-static.lib: $(OBJ)
+libivy.lib: $(OBJ)
del /f $@
$(LIBTOOL)$@ $(OBJ)
-ivy.dll: $(OBJ)
- $(CC) -nologo /LD -o $@ $(OBJ) wsock32.lib $(PCRELIB) /link /debug /def:libIvy.def /version:$(MAJOR).$(MINOR)
+libivy.dll: $(OBJ)
+ $(CC) /dll /out: $@ $(OBJ) $(PCRELIB)
clean:
- -del /f $(TARGETS) $(TARGETLIBS) *.obj *.a *.dll *.lib *.pdb *~
+ -del /f $(TARGETS) $(TARGETLIBS) *.obj *.lib *.dll *~
diff --git a/src/hash.c b/src/hash.c
deleted file mode 100755
index a8076ae..0000000
--- a/src/hash.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/************************************************************************
- hash.c - This module maintains a hash table of key/value pairs.
- Keys can be strings of any size, or numbers up to size
- unsigned long (HASHKEYTYPE).
- Values should be a pointer to some data you wish to store.
- See hash_usage() for an example of use.
- ************************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <time.h>
-#include <stdarg.h>
-
-#include "hash.h"
-
-// Enums
-typedef enum {FindEmpty = 0, FindExisting = 1} enumFind;
-
-// Structs
-struct ROW
-{
- HASHKEYTYPE Key;
- int Type;
- void * Data;
-};
-
-struct HASHTABLE_T
-{
- int KeyIsString;
- unsigned long MaxLoad;
- unsigned long MaxRows;
- unsigned long ItemCount;
- struct ROW *Rows;
-};
-
-// Function prototypes
-static void hash_expand(HASHTABLE OldTable);
-
-// Current module name (used by error processing)
-static char *module = "hash";
-
-// Error list
-static const char *ERR_MUST_CREATE_HASH_TABLE_FIRST = "You must create the hash table before using it!";
-static const char *ERR_NOT_STRING_TABLE = "Not a string hash table!";
-
-// Deleted entry indicator
-static const int Empty = 0x00000000;
-static const int InUse = 0x11111111;
-static const int Deleted = 0xffffffff;
-
-// Expand the table when the usage exceeds this amount (80%)
-static double LoadFactor = 0.8;
-
-
-/************************************************************************
- ExitEarly - Quit the program early
- ************************************************************************/
-static void ExitEarly(const char *strModule, const char *strFunction, const char *errmsg, ...)
-{
- va_list args;
- fprintf(stderr, "Error in module %s, function %s: ", strModule, strFunction);
- va_start(args, errmsg);
- vfprintf(stderr, errmsg, args);
- va_end(args);
- exit(1);
-}
-
-/************************************************************************
- hash1 - Calculate a hash value for the desired key
- ************************************************************************/
-static HASHKEYTYPE hash1(HASHKEYTYPE Key, BOOL KeyIsString)
-{
-
- if (!KeyIsString)
- {
- return Key;
- }
- else
- {
- unsigned char *s = (unsigned char *)Key;
- HASHKEYTYPE h = 0;
- while (*s)
- h = h * 31UL + *s++;
- return h ;
- }
-}
-
-/************************************************************************
- hash2 - Calculate a secondary hash value for the desired key
- ************************************************************************/
-static HASHKEYTYPE hash2(HASHKEYTYPE Key, BOOL KeyIsString)
-{
- return hash1(Key, KeyIsString) >> 3;
-}
-
-/************************************************************************
- NextPrime - Return the next prime number past a certain number.
- ************************************************************************/
-static unsigned long NextPrime(unsigned long NumberDesired)
-{
- unsigned long i;
- unsigned long HalfwayPoint;
- int IsDivisible ;
-
- do
- {
- NumberDesired++;
- IsDivisible = FALSE;
- HalfwayPoint = NumberDesired / 2;
- for (i = 2; i <= HalfwayPoint; i++)
- {
- if (NumberDesired % i == 0)
- {
- IsDivisible = TRUE;
- break;
- }
- }
- } while (IsDivisible);
-
- return NumberDesired;
-
-};
-
-/************************************************************************
- hash_create - Create a new hash table
- ************************************************************************/
-HASHTABLE hash_create(unsigned long InitialSize, BOOL KeyIsString)
-{
- HASHTABLE table;
-
- // Allocate space for the hash table.
- table = malloc(sizeof(*table));
- memset( table, 0, sizeof(*table) );
-
- // Minimum size of hash table is 8.
- if (InitialSize < 8 )
- InitialSize = 8;
-
- // Allocate it large enough so that it's not more than 80% full.
- InitialSize = (unsigned long)(InitialSize * 1.25);
-
- // Allocate space for the rows in the hash table
- InitialSize = NextPrime(InitialSize);
- table->MaxLoad = (unsigned long)(InitialSize * LoadFactor);
- table->MaxRows = InitialSize;
- table->Rows = malloc(InitialSize * sizeof(struct ROW));
- table->KeyIsString = KeyIsString;
-
- memset( table->Rows, 0, InitialSize * sizeof(struct ROW) );
-
-
- return table;
-
-}
-
-
-/************************************************************************
- hash_destroy - Destroy a hash table.
- ************************************************************************/
-HASHTABLE hash_destroy(HASHTABLE table)
-{
- char *function = "hash_destroy";
-
- // Make sure the table is valid
- if (table == NULL)
- ExitEarly(module, function, ERR_MUST_CREATE_HASH_TABLE_FIRST);
-
- // Free the rows in the table
- free(table->Rows);
-
- // Free the table itself
- free(table);
-
- // Return NULL
- return NULL;
-}
-
-
-/************************************************************************
- FindSlot - Find a slot in the hash table, either empty or existing.
- ************************************************************************/
-static int FindSlot(HASHTABLE table, HASHKEYTYPE Key, int FindMethod, HASHKEYTYPE *Slot)
-{
- char *function = "FindSlot";
- HASHKEYTYPE hash = 0;
- unsigned long i;
- HASHKEYTYPE AddlAmt = 0;
-
- // Hash the key.
- hash = (HASHKEYTYPE)(hash1(Key, table->KeyIsString) % table->MaxRows);
-
- // Perform the lookup a maximum of MaxRows times.
- for (i = 0; i < table->MaxRows; i++)
- {
- // Are we supposed to find an empty slot or look for an existing key?
- if (FindMethod == FindExisting)
- {
- // Look for an existing key
- if (table->Rows[hash].Type == Empty)
- {
- // Couldn't find the key
- return FALSE;
- }
- else if (table->Rows[hash].Type == InUse &&
- ( (table->KeyIsString && strcmp((char *)table->Rows[hash].Key, (char *)Key) == 0) ||
- (!table->KeyIsString && table->Rows[hash].Key == Key) ) )
-
- {
- // Found the key
- *Slot = hash;
- return TRUE;
- }
- }
- else
- {
- // Look for an empty slot to insert the new key into
- if (table->Rows[hash].Type != InUse)
- {
- // Found a spot
- *Slot = hash;
- return TRUE;
- }
- else if ( (table->KeyIsString && strcmp((char *)table->Rows[hash].Key, (char *)Key) == 0) ||
- (!table->KeyIsString && table->Rows[hash].Key == Key) )
- {
- // Key already exists!
- return FALSE;
- }
- }
-
- // Rehash the hash and try again.
- if (AddlAmt == 0)
- AddlAmt = (HASHKEYTYPE)(hash2(Key, table->KeyIsString) % (table->MaxRows >> 3) + 1);
- hash = (hash + AddlAmt) % table->MaxRows;
-
- }
-
- // Searched the whole table unsuccessfully! :-O
- // Should never hit this point, because the table expands when it gets too full.
- ExitEarly(module, function, "Findslot failed!");
- return FALSE;
-}
-
-
-/************************************************************************
- hash_add - Add an item to a hash table.
- ************************************************************************/
-BOOL hash_add(HASHTABLE table, HASHKEYTYPE Key, const void *Data)
-{
- char *function = "hash_add";
- HASHKEYTYPE position;
-
- if (table == NULL)
- ExitEarly(module, function, ERR_MUST_CREATE_HASH_TABLE_FIRST);
-
- // Do not let the table become overloaded
- if (table->ItemCount > table->MaxLoad)
- hash_expand(table);
-
- // Search for an empty slot
- if (FindSlot(table, Key, FindEmpty, &position))
- {
- // Insert the data into the table.
- table->Rows[position].Key = Key;
- table->Rows[position].Type = InUse;
- table->Rows[position].Data = (void *)Data;
- table->ItemCount++;
- return TRUE;
- }
- else
- {
- // The entry already exists!
- return FALSE;
- }
-}
-
-
-/************************************************************************
- hash_addstring - Add an string to a hash table.
- ************************************************************************/
-BOOL hash_addstring(HASHTABLE table, char * Key, const void * Data)
-{
- char *function = "hash_addstring";
-
- if (table == NULL)
- ExitEarly(module, function, ERR_MUST_CREATE_HASH_TABLE_FIRST);
- if (table->KeyIsString == FALSE)
- ExitEarly(module, function, ERR_NOT_STRING_TABLE);
- return hash_add(table, (HASHKEYTYPE)Key, Data);
-}
-
-/************************************************************************
- hash_remove - Remove an item from a hash table.
- ************************************************************************/
-void *hash_remove(HASHTABLE table, HASHKEYTYPE Key)
-{
- char *function = "hash_remove";
- void *Data;
- unsigned int position;
-
- if (table == NULL)
- ExitEarly(module, function, ERR_MUST_CREATE_HASH_TABLE_FIRST);
-
- if (FindSlot(table, Key, FindExisting, &position))
- {
- // Found the item, now mark it as deleted.
- Data = table->Rows[position].Data;
- table->Rows[position].Key = 0;
- table->Rows[position].Type = Deleted;
- table->Rows[position].Data = 0;
- table->ItemCount--;
- return Data;
- }
- else
- {
- // Couldn't find the item to remove it.
- return NULL;
- }
-}
-
-/************************************************************************
- hash_lookup - Lookup an item from a hash table.
- ************************************************************************/
-void *hash_lookup(HASHTABLE table, HASHKEYTYPE Key)
-{
- char *function = "hash_lookup";
- HASHKEYTYPE position;
-
- if (table == NULL)
- ExitEarly(module, function, ERR_MUST_CREATE_HASH_TABLE_FIRST);
-
- if (FindSlot(table, Key, FindExisting, &position))
- return table->Rows[position].Data;
- else
- return NULL;
-}
-
-/************************************************************************
- hash_exists - Returns whether or not a key exists in the table.
- ************************************************************************/
-BOOL hash_exists(HASHTABLE table, HASHKEYTYPE Key)
-{
- char *function = "hash_lookup";
- HASHKEYTYPE position;
-
- if (table == NULL)
- ExitEarly(module, function, ERR_MUST_CREATE_HASH_TABLE_FIRST);
-
- if (FindSlot(table, Key, FindExisting, &position))
- return TRUE;
- else
- return FALSE;
-}
-
-/************************************************************************
- hash_count - Return a count of all items in the hash table
- ************************************************************************/
-extern size_t hash_count(HASHTABLE table)
-{
- char *function = "hash_count";
- if (table == NULL)
- ExitEarly(module, function, ERR_MUST_CREATE_HASH_TABLE_FIRST);
-
- return table->ItemCount;
-}
-
-/************************************************************************
- hash_expand - Expand the hash table to accommodate more entries.
- ************************************************************************/
-static void hash_expand(HASHTABLE OldTable)
-{
- HASHTABLE NewTable;
- unsigned long i;
-
- // Create a new temporary table
- NewTable = hash_create(OldTable->MaxRows * 2, OldTable->KeyIsString);
-
- // Add the data from the old table into the new table
- for (i = 0; i < OldTable->MaxRows; i++)
- {
- if (OldTable->Rows[i].Type == InUse)
- hash_add(NewTable, OldTable->Rows[i].Key, OldTable->Rows[i].Data);
- }
-
- // Free the old table rows
- free(OldTable->Rows);
-
- // Overlay the old table values with the temporary table values.
- OldTable->MaxRows = NewTable->MaxRows;
- OldTable->MaxLoad = NewTable->MaxLoad;
- OldTable->ItemCount = NewTable->ItemCount;
- OldTable->Rows = NewTable->Rows;
-
- // Destroy the temporary table
- NewTable->Rows = NULL;
- free(NewTable);
-}
-
-/************************************************************************
- hash_search - Search for an item in the hashtable.
- ************************************************************************/
-extern void *hash_search(HASHTABLE table, BOOL (*Search)(HASHKEYTYPE key, void *, va_list), ...)
-{
- va_list args;
- unsigned int i;
- void *p = NULL;
-
- va_start(args, Search);
- for (i = 0; i < table->MaxRows; i++)
- {
- if (table->Rows[i].Type != Deleted &&
- table->Rows[i].Type != Empty)
- {
- if (Search(table->Rows[i].Key, table->Rows[i].Data, args) != FALSE)
- {
- p = table->Rows[i].Data;
- break;
- }
- }
- }
- va_end(args);
- return p;
-}
-
-/************************************************************************
- hash_searchwithvalist - Search for an item in the hashtable.
- A va_list has already been passed in, no need to extract one.
- ************************************************************************/
-extern void *hash_searchwithvalist(HASHTABLE table, BOOL (*Search)(HASHKEYTYPE key, void *, va_list), va_list args)
-{
- unsigned int i;
- void *p = NULL;
-
- for (i = 0; i < table->MaxRows; i++)
- {
- if (table->Rows[i].Type != Deleted &&
- table->Rows[i].Type != Empty)
- {
- if (Search(table->Rows[i].Key, table->Rows[i].Data, args) != FALSE)
- {
- p = table->Rows[i].Data;
- break;
- }
- }
- }
- return p;
-}
-
-/************************************************************************
- * hash_usage - Example of how to use this module.
- ************************************************************************/
-struct person_t
-{
- int ID;
- char Name[32];
- int Age;
-};
-
-extern void hash_usage(void)
-{
- void *table;
- struct person_t *p;
- struct person_t *lookup;
- char *StringKey = "Lloyd";
- int NumberKey = 1234567;
-
- // Create some data to store
- p = malloc(sizeof(*p));
- memset ( p, 0 ,sizeof( *p));
- p->ID = NumberKey;
- p->Age = 20;
- sprintf(p->Name, StringKey);
-
- // Numeric hash example
-
- // Create the hash table
- table = hash_create(10, FALSE);
-
- // Add a key/value pair to the table
- if (hash_add(table, p->ID, p) == FALSE)
- printf("Entry already exists!");
-
- // Lookup a key/value pair in the table
- if ((lookup = hash_lookup(table, NumberKey)) == FALSE)
- printf("Entry not found!");
- else
- printf("Person found by ID: %d. Name is: %s\n", lookup->ID, lookup->Name);
-
- // Remove a key/value pair from the table
- if ((lookup = hash_remove(table, NumberKey)) == FALSE)
- printf("Entry not found!");
- else
- // you COULD free lookup here, but we're not done with it.
- ;
-
- // Free the table.
- table = hash_destroy(table);
-
-
- // String hash example
-
- // Create the hash table
- table = hash_create(10, TRUE);
-
- // Add a key/value pair to the table
- if (hash_add(table, (HASHKEYTYPE)p->Name, p) == FALSE)
- printf("Entry already exists!");
-
- // Lookup a key/value pair in the table
- if ((lookup = hash_lookup(table, (HASHKEYTYPE)StringKey)) == FALSE)
- printf("Entry not found!");
- else
- printf("Person found by name: %s. ID is: %d\n", lookup->Name, lookup->ID);
-
- // Remove a key/value pair from the table
- if ((lookup = hash_remove(table, (HASHKEYTYPE)StringKey)) == FALSE)
- printf("Entry not found!");
- else
- free(lookup);
-
- // Free the table.
- table = hash_destroy(table);
-}
-
-/************************************************************************
- hash_test - Test the hash table.
- ************************************************************************/
-static BOOL Search(HASHKEYTYPE key, void *p, va_list args)
-{
- char *s = p;
- char *find = va_arg(args, char *);
- if (strcmp(s, find) == 0)
- return TRUE;
- else
- return FALSE;
-}
-
-static BOOL Iterate(HASHKEYTYPE key, void *p, va_list args)
-{
- // Just iterate a counter.
- unsigned int *i = va_arg(args, unsigned int *);
- *i = *i + 1;
- // Return false to keep searching.
- return FALSE;
-}
-
-extern BOOL hash_test(void)
-{
- HASHTABLE table;
- HASHTABLE strings;
- int i;
- int max = 1000000;
- clock_t start;
- char **s;
- char temp[80];
- char *fmt = "\t%-8s %4d milliseconds, %8d per second.\n";
- unsigned int ctr = 0;
-
- // Logical tests
- table = hash_create(8, FALSE);
- if (hash_add(table, 0, &table) == FALSE) return FALSE;
- if (hash_add(table, 1, &table) == FALSE) return FALSE;
- if (hash_add(table, 0xffffffff, &table) == FALSE) return FALSE;
-
- strings = hash_create(8, TRUE);
- if (hash_add(strings, (HASHKEYTYPE)"test1", &strings) == FALSE) return FALSE;
- if (hash_add(strings, (HASHKEYTYPE)"test2", &strings) == FALSE) return FALSE;
- if (hash_add(strings, (HASHKEYTYPE)"test3", &strings) == FALSE) return FALSE;
-
- if (hash_lookup(table, 0) != &table) return FALSE;
- if (hash_lookup(table, 1) != &table) return FALSE;
- if (hash_lookup(table, 0xffffffff) != &table) return FALSE;
-
- if (hash_lookup(strings, (HASHKEYTYPE)"test1") != &strings) return FALSE;
- if (hash_lookup(strings, (HASHKEYTYPE)"test2") != &strings) return FALSE;
- if (hash_lookup(strings, (HASHKEYTYPE)"test3") != &strings) return FALSE;
-
- if (hash_remove(strings, (HASHKEYTYPE)"test1") != &strings) return FALSE;
- if (hash_lookup(strings, (HASHKEYTYPE)"test1") != FALSE) return FALSE;
-
- if (hash_destroy(table) != NULL) return FALSE;
- if (hash_destroy(strings) != NULL) return FALSE;
-
-
- // Stress tests for numbers
- printf("HASH Numeric Tests for %d items\n", max);
- table = hash_create(max, FALSE);
-
- start = clock();
- for (i = 0; i < max; i++)
- hash_add(table, i, &table);
- printf(fmt, "Adds:", clock() - start, (max * CLOCKS_PER_SEC)/(clock() - start));
-
- start = clock();
- for (i = 0; i < max; i++)
- if (hash_lookup(table, i) != &table)
- break;
- printf(fmt, "Lookups:", clock() - start, (max * CLOCKS_PER_SEC)/(clock() - start));
-
- start = clock();
- for (i = 0; i < max; i++)
- if (hash_remove(table, i) != &table)
- break;
- printf(fmt, "Deletes:", clock() - start, (max * CLOCKS_PER_SEC)/(clock() - start));
- if (hash_count(table) != 0)
- return FALSE;
- table = hash_destroy(table);
-
- // Stress tests for strings
- printf("HASH strings Tests for %d items\n", max);
- table = hash_create(max, TRUE);
- s = malloc(sizeof(*s) * max);
- memset ( s, 0 ,sizeof( *s)*max);
-
- for (i = 0; i < max; i++)
- {
- sprintf(temp, "Item %d", i);
- s[i] = strdup(temp);
- }
-
- start = clock();
- for (i = 0; i < max; i++)
- hash_add(table, (HASHKEYTYPE)s[i], s[i]);
- printf(fmt, "Adds:", clock() - start, (max * CLOCKS_PER_SEC)/(clock() - start));
-
- start = clock();
- for (i = 0; i < max; i++)
- if (hash_lookup(table, (HASHKEYTYPE)s[i]) != s[i])
- break;
- printf(fmt, "Lookups:", clock() - start, (max * CLOCKS_PER_SEC)/(clock() - start));
-
- // Test searching
- if (hash_search(table, Search, "Item 271") != s[271])
- return FALSE;
- if (hash_search(table, Search, "Not Found") != FALSE)
- return FALSE;
-
- // Test iterating
- ctr = 0;
- start = clock();
- hash_search(table, Iterate, &ctr);
- printf(fmt, "Iterate:", clock() - start, (max * CLOCKS_PER_SEC)/(clock() - start));
- printf("\t\t(Ctr is %u)\n", ctr);
-
- // Test deleting
- start = clock();
- for (i = 0; i < max; i++)
- if (hash_remove(table, (HASHKEYTYPE)s[i]) != s[i])
- break;
- printf(fmt, "Deletes:", clock() - start, (max * CLOCKS_PER_SEC)/(clock() - start));
- if (hash_count(table) != 0)
- return FALSE;
- table = hash_destroy(table);
-
- // Free the test strings
- for (i = 0; i < max; i++)
- free(s[i]);
-
-
- return TRUE;
-}
-
-
diff --git a/src/hash.h b/src/hash.h
deleted file mode 100755
index 4ea7731..0000000
--- a/src/hash.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/************************************************************************
- hash.h
- ************************************************************************/
-#ifndef HASH_H
-#define HASH_H
-
-
-typedef unsigned int HASHKEYTYPE;
-typedef struct HASHTABLE_T *HASHTABLE;
-typedef int BOOL;
-
-#define FALSE 0
-#define TRUE 1
-
-extern void hash_usage (void);
-extern BOOL hash_test (void);
-extern HASHTABLE hash_create (unsigned long InitialSize, BOOL KeyIsString);
-extern HASHTABLE hash_destroy (HASHTABLE table);
-extern BOOL hash_add (HASHTABLE table, HASHKEYTYPE Key, const void *Data);
-extern BOOL hash_addstring (HASHTABLE table, char * Key, const void * Data);
-extern void * hash_remove (HASHTABLE table, HASHKEYTYPE Key);
-extern void * hash_lookup (HASHTABLE table, HASHKEYTYPE Key);
-extern size_t hash_count (HASHTABLE table);
-extern void * hash_search (HASHTABLE table, BOOL (*Search)(HASHKEYTYPE key, void *, va_list), ...);
-extern void * hash_searchwithvalist(HASHTABLE table, BOOL (*Search)(HASHKEYTYPE key, void *, va_list), va_list args);
-extern BOOL hash_exists (HASHTABLE table, HASHKEYTYPE Key);
-
-
-#endif
diff --git a/src/intervalRegexp.c b/src/intervalRegexp.c
new file mode 100644
index 0000000..0132fce
--- /dev/null
+++ b/src/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/src/intervalRegexp.h b/src/intervalRegexp.h
new file mode 100644
index 0000000..a5ca2e3
--- /dev/null
+++ b/src/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
diff --git a/src/ivy.c b/src/ivy.c
index 63de4b4..5231f0d 100644
--- a/src/ivy.c
+++ b/src/ivy.c
@@ -7,8 +7,7 @@
*
* Main functions
*
- * Authors: Francois-Regis Colin <fcolin@cena.fr>
- * Stephane Chatty <chatty@cena.fr>
+ * Authors: Francois-Regis Colin,Stephane Chatty
*
* $Id$
*
@@ -16,31 +15,37 @@
* copyright notice regarding this software
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <fcntl.h>
+#include <stdlib.h>
#ifdef WIN32
-#include <crtdbg.h>
#include <windows.h>
#else
-#include <arpa/inet.h>
#include <sys/time.h>
-#include <unistd.h>
-#include <netdb.h>
+#include <arpa/inet.h>
#endif
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <fcntl.h>
+
+#include "intervalRegexp.h"
#include "ivychannel.h"
-#include "ivybind.h"
#include "ivysocket.h"
#include "list.h"
-#include "hash.h"
+#include "ivybuffer.h"
+#include "ivydebug.h"
+#include "ivybind.h"
#include "ivy.h"
-#define VERSION 4
+#define VERSION 3
+
+#define MAX_MATCHING_ARGS 40
+
+#define ARG_START "\002"
+#define ARG_END "\003"
+
#define DEFAULT_DOMAIN 127.255.255.255
/* stringification et concatenation du domaine et du port en 2 temps :
@@ -50,37 +55,28 @@
#define GenerateIvyBus(domain,bus) str(domain)":"str(bus)
static char* DefaultIvyBus = GenerateIvyBus(DEFAULT_DOMAIN,DEFAULT_BUS);
-/* syntaxe des messages */
-#define MSGTYPE 0
-#define MSGID 1
-#define ARG_0 2
-
typedef enum {
- Bye, /* l'application emettrice se termine */
- AddRegexp, /* expression reguliere d'un client */
- Msg, /* message reel */
- Error, /* error message */
- DelRegexp, /* Remove expression reguliere */
- EndRegexp, /* end of the regexp list */
+ Bye, /* l'application emettrice se termine */
+ 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 = 9, /* checks the presence of the other */
- Pong = 10, /* checks the presence of the other */
- AddBinding = 11, /* other methods for binding message based on hash table */
- DelBinding = 12, /* other methods for binding message based on hash table */
- ApplicationId = 13, /* on start send my ID and priority */
-
+ 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;
typedef struct _msg_snd *MsgSndPtr;
struct _msg_rcv { /* requete d'emission d'un client */
- IvyBindingType type;
+ MsgRcvPtr next;
int id;
- char *regexp; /* regexp du message a recevoir */
- MsgCallback callback; /* callback a declanche a la reception */
+ const char *regexp; /* regexp du message a recevoir */
+ MsgCallback callback; /* callback a declanche a la reception */
void *user_data; /* stokage d'info client */
};
@@ -88,7 +84,7 @@ struct _msg_snd { /* requete de reception d'un client */
MsgSndPtr next;
int id;
char *str_regexp; /* la regexp sous forme inhumaine */
- IvyBinding bind;
+ IvyBinding binding; /* la regexp sous forme machine */
};
struct _clnt_lst {
@@ -96,11 +92,12 @@ struct _clnt_lst {
Client client; /* la socket client */
MsgSndPtr msg_send; /* liste des requetes recues */
char *app_name; /* nom de l'application */
- char *app_id; /* identificateur unique de l'application (time-ip-port) */
- int priority; /* client priority */
unsigned short app_port; /* port de l'application */
};
+/* flag pour le debug en cas de Filter de regexp */
+int debug_filter = 0;
+
/* server pour la socket application */
static Server server;
@@ -114,17 +111,19 @@ static unsigned short SupervisionPort;
static Client broadcast;
static const char *ApplicationName = 0;
+static const char *ApplicationID = 0;
+
/* callback appele sur reception d'un message direct */
static MsgDirectCallback direct_callback = 0;
static void *direct_user_data = 0;
/* callback appele sur changement d'etat d'application */
-static IvyApplicationCallback application_callback = 0;
+static IvyApplicationCallback application_callback;
static void *application_user_data = 0;
/* callback appele sur ajout suppression de regexp */
-static IvyBindCallback application_bind_callback = 0;
+static IvyBindCallback application_bind_callback;
static void *application_bind_data = 0;
/* callback appele sur demande de terminaison d'application */
@@ -132,241 +131,114 @@ static IvyDieCallback application_die_callback;
static void *application_die_user_data = 0;
/* liste des messages a recevoir */
-//static MsgRcvPtr msg_recv = 0;
-static HASHTABLE msg_recv= NULL;
-
+static MsgRcvPtr msg_recv = 0;
/* liste des clients connectes */
static IvyClientPtr clients = 0;
static const char *ready_message = 0;
+static void substituteInterval (IvyBuffer *src);
-static char *applicationUniqueId = 0;
-static int applicationPriority = DEFAULT_PRIORITY;
-
-/* get Current Time in milliseconds */
-static long currentTime()
-{
- unsigned long current;
-#ifdef WIN32
- current = GetTickCount();
-#else
- struct timeval stamp;
- gettimeofday( &stamp, NULL );
- current = stamp.tv_sec * 1000 + stamp.tv_usec/1000;
-#endif
- return current;
-}
-
-
-// fonction de formtage a la printf d'un buffer avec reallocation dynamique
-#define MESSAGE_SIZE 4096 /* taille buffer initiale on multiple pas deux a chaque realloc */
-
-static int make_message(char ** buffer, int *size, int offset, const char *fmt, va_list ap)
-{
- /* Guess we need no more than BUFFER_INIT_SIZE bytes. */
- long n;
- if ( *size == 0 || *buffer == NULL )
- {
- *size = MESSAGE_SIZE;
- *buffer = malloc (MESSAGE_SIZE);
- if ( *buffer == NULL )
- return -1;
- }
- while (1) {
- /* Try to print in the allocated space. */
-#ifdef WIN32
- n = _vsnprintf (*buffer + offset, *size - offset, fmt, ap);
-#else
- n = vsnprintf (*buffer + offset, *size - offset, fmt, ap);
-#endif
- /* If that worked, return the string size. */
- if (n > -1 && n < *size)
- return n;
- /* Else try again with more space. */
- if (n > -1) /* glibc 2.1 */
- *size = n+1; /* precisely what is needed */
- else /* glibc 2.0 */
- *size *= 2; /* twice the old size */
- if ((*buffer = realloc (*buffer, *size)) == NULL)
- return -1;
- }
-}
-
-static char *DupArg( int len, void *s)
-{
- char *ptr;
- ptr = malloc( len+1 );
- if (!ptr )
- {
- fprintf(stderr,"DupArg Buffer Memory Alloc Error\n");
- exit(-1);
- }
- memcpy( ptr, s, len );
- ptr[len] = '\0';
- return ptr;
-}
-/* returns < 0 if *p sorts lower than *q */
-static int keycmp (IvyClientPtr p, IvyClientPtr q)
-{
- return p->priority - q->priority;
-}
-
-/* merge 2 lists under dummy head item */
-static IvyClientPtr lmerge (IvyClientPtr p, IvyClientPtr q)
-{
- IvyClientPtr r;
- struct _clnt_lst head;
-
- for ( r = &head; p && q; )
- {
- if ( keycmp(p, q) < 0 )
- {
- r = r->next = p;
- p = p->next;
- }
- else
- {
- r = r->next = q;
- q = q->next;
- }
- }
- r->next = (p ? p : q);
- return head.next;
-}
-
-/* split list into 2 parts, sort each recursively, merge */
-static IvyClientPtr lsort (IvyClientPtr p)
-{
- IvyClientPtr q, r;
-
- if ( p )
- {
- q = p;
- for ( r = q->next; r && (r = r->next) != NULL; r = r->next )
- q = q->next;
- r = q->next;
- q->next = NULL;
- if ( r )
- p = lmerge(lsort(r), lsort(p));
- }
- return p;
-}
-
-
-static void SortClients()
-{
- // sort client list again priority!
- lsort( clients );
-}
-static void MsgSendTo( Client client, MsgType msgtype, int id, int len_arg, const void *arg )
+/*
+ * function like strok but do not eat consecutive separator
+ * */
+static char * nextArg( char *s, const char *separator )
{
- unsigned short header[3];
-
-#ifdef DEBUG
- printf( "Sending message type=%d id=%d '%.*s'\n",msgtype,id,len_arg,(char*)arg);
-#endif
- header[0] = htons( (unsigned short)msgtype );
- header[1] = htons( (unsigned short)id );
- header[2] = htons( (unsigned short)len_arg );
- SocketSend( client, (char *)header, sizeof(header) );
- if ( len_arg )
+ static char *start = NULL;
+ static char *end = NULL;
+ if ( s )
{
- SocketSend( client, arg, len_arg );
+ end = s;
}
- SocketFlush( client );
-}
-
-static int MsgSendCallTo (Client client, const char *message, MsgSndPtr msg )
-{
- void * buffer = NULL;
- int buf_len = 0;
- int len;
- IvyArgument args;
-
-
- int rc = IvyBindingExec( msg->bind, message );
-
- if (rc<1) return 0; /* no match */
-#ifdef DEBUG
- printf( "Sending message id=%d '%s'\n",msg->id,message);
-#endif
- // il faut essayer d'envoyer le message en une seule fois sur la socket
- // pour eviter au maximun de passer dans le select plusieur fois par message du protocole Ivy
- // pour eviter la latence ( PB de perfo detecte par ivyperf ping roudtrip )
+ start = end;
-#ifdef DEBUG
- printf( "Send matching args count %d\n",rc);
-#endif
- args = IvyBindingMatch( msg->bind, message );
- /* serialize into buffer */
- len = IvyArgumentSerialize(args, &buf_len, &buffer, 0);
-
- MsgSendTo( client, Msg, msg->id, len, buffer );
- IvyArgumentFree( args ); /* TODO supress malloc /free */
- free( buffer );
- return 1;
+ while ( *end && *end != *separator )
+ end++;
+ if ( *end == *separator ) *end++ = '\0';
+ if ( end == start ) return NULL;
+ return start;
}
-static BOOL RemoveBinding(HASHKEYTYPE key, void *data, va_list args)
+static int MsgSendTo( Client client, MsgType msgtype, int id, const char *message )
{
- MsgRcvPtr msg = (MsgRcvPtr)data;
- free( msg->regexp );
- free ( msg );
- return FALSE; /* iter throught all hash table */
+ return SocketSend( client, "%d %d" ARG_START "%s\n", msgtype, id, message);
}
+
static void IvyCleanup()
{
IvyClientPtr clnt,next;
- MsgSndPtr msg,msg_next;
+
/* destruction des connexions clients */
IVY_LIST_EACH_SAFE( clients, clnt, next )
{
/* on dit au revoir */
- MsgSendTo( clnt->client, Bye, 0, 0, "" );
+ MsgSendTo( clnt->client, Bye, 0, "" );
SocketClose( clnt->client );
- IVY_LIST_EACH_SAFE( clnt->msg_send, msg, msg_next )
- {
- free( msg->str_regexp );
- IvyBindingFree( msg->bind );
- }
IVY_LIST_EMPTY( clnt->msg_send );
}
IVY_LIST_EMPTY( clients );
- /* destruction de mes bindings */
- hash_search( msg_recv, RemoveBinding);
- hash_destroy( msg_recv );
- free( applicationUniqueId );
+
/* destruction des sockets serveur et supervision */
SocketServerClose( server );
SocketClose( broadcast );
}
-static int ClientCall (IvyClientPtr clnt, const char *message)
+static int MsgCall (const char *message, MsgSndPtr msg, IvyClientPtr client)
+{
+ int waiting = 0;
+ static IvyBuffer buffer = { NULL, 0, 0 }; /* Use satic mem to eliminate multiple call to malloc /free */
+ int err;
+ int index;
+ int arglen;
+ const char *arg;
+
+ int rc= IvyBindingExec( msg->binding, message );
+
+ if (rc<1) return 0; /* no match */
+
+ TRACE( "Sending message id=%d '%s'\n",msg->id,message);
+
+ buffer.offset = 0;
+ // il faut essayer d'envoyer le message en une seule fois sur la socket
+ // pour eviter au maximun de passer dans le select plusieur fois par message du protocole Ivy
+ // pour eviter la latence ( PB de perfo detecte par ivyperf ping roudtrip )
+ err = make_message_var( &buffer, "%d %d" ARG_START ,Msg, msg->id);
+
+ TRACE( "Send matching args count %d\n",rc);
+
+ for( index=1; index < rc ; index++ )
+ {
+ IvyBindingMatch( msg->binding, message, index, &arglen, & arg );
+ err = make_message_var( &buffer, "%.*s" ARG_END , arglen, arg );
+ }
+ err = make_message_var( &buffer, "\n");
+ waiting = SocketSendRaw(client->client, buffer.data , buffer.offset);
+ if ( waiting )
+ fprintf(stderr, "Ivy: Slow client : %s\n", client->app_name );
+ return 1;
+}
+
+
+static int
+ClientCall (IvyClientPtr clnt, const char *message)
{
MsgSndPtr msg;
int match_count = 0;
- /* for simple binding message syntax msg arg1=val1 arg2=val2 ... argn=valn */
- IvyBindingParseMessage( message );
/* recherche dans la liste des requetes recues de ce client */
IVY_LIST_EACH (clnt->msg_send, msg) {
- match_count+= MsgSendCallTo (clnt->client, message, msg );
+ match_count+= MsgCall (message, msg, clnt);
}
return match_count;
}
-
static int CheckConnected( IvyClientPtr clnt )
{
IvyClientPtr client;
struct in_addr *addr1;
struct in_addr *addr2;
- /* TODO check multiple instance of the same application name */
-
if ( clnt->app_port == 0 ) /* Old Ivy Protocol Dont check */
return 0;
/* recherche dans la liste des clients de la presence de clnt */
- /* TODO check based on appid not on the copule host:port */
IVY_LIST_EACH( clients, client )
{
/* client different mais port identique */
@@ -378,193 +250,140 @@ static int CheckConnected( IvyClientPtr clnt )
if ( addr1->s_addr == addr2->s_addr )
return 1;
}
+ /* client different mais applicationID identique */
+ /* TODO est-ce utile ??? verif dans UDP
+ if ( (client != clnt) && (clnt->app_id == client->app_id) )
+ {
+ return 1;
+ }
+ */
}
return 0;
}
-static char* Receive( Client client, void *data, char *message, unsigned int len )
+static void Receive( Client client, void *data, char *line )
{
IvyClientPtr clnt;
- int id;
- unsigned short len_args;
+ int err,id;
MsgSndPtr snd;
MsgRcvPtr rcv;
- IvyArgument arguments;
+ int argc = 0;
+ char *argv[MAX_MATCHING_ARGS];
+ char *arg;
int kind_of_msg = Bye;
IvyBinding bind;
- char *ptr_end;
- void *args =NULL;
- char *str_regexp;
- int adv_buffer;
-
- ptr_end = message;
-
- if ( len < 6 ) return NULL; /* incomplete message */
- kind_of_msg = ntohs( *((unsigned short *) ptr_end)++ );
- id = ntohs( *((unsigned short *) ptr_end)++ );
- len_args = ntohs( *((unsigned short *) ptr_end)++ );
-
- if ( len_args )
- {
- if ( len < (6 + len_args) ) return NULL; /* incomplete message */
- args = ptr_end;
- ptr_end += len_args;
- }
-#ifdef DEBUG
- printf("Receive Message type=%d id=%d arg=%.*s\n", kind_of_msg, id, len_args, (char*)args);
-#endif //DEBUG
+ const char *errbuf;
+ int erroffset;
+ err = sscanf( line ,"%d %d", &kind_of_msg, &id );
+ arg = strstr( line , ARG_START );
+ if ( (err != 2) || (arg == 0) )
+ {
+ printf("Quitting bad format %s\n", line);
+ MsgSendTo( client, Error, Error, "bad format request expected 'type id ...'" );
+ MsgSendTo( client, Bye, 0, "" );
+ SocketClose( client );
+ return;
+ }
+ arg++;
clnt = (IvyClientPtr)data;
switch( kind_of_msg )
{
case Bye:
-#ifdef DEBUG
- printf("Quitting Bye %.*s\n", len_args, (char*)args);
-#endif //DEBUG
+ TRACE("Quitting %s\n", line);
SocketClose( client );
break;
case Error:
- /*TODO Callback */
- fprintf (stderr, "Received error %d %.*s from %s\n", id, len_args, (char*)args, clnt->app_name);
+ printf ("Received error %d %s\n", id, arg);
break;
case AddRegexp:
-#ifdef DEBUG
- printf("AddRegexp id=%d exp='%.*s'\n", id, len_args, (char*)args);
-#endif //DEBUG
- if ( !IvyBindingFilter( IvyBindRegexp, len_args, args ) )
- {
-#ifdef DEBUG
- printf("Warning: regexp '%.*s' illegal, removing from %s\n",len_args,(char*)args,ApplicationName);
-#endif //DEBUG
- return ptr_end;
- }
- str_regexp = DupArg( len_args, args );
-
- bind = IvyBindingCompile( IvyBindRegexp, str_regexp );
- if ( bind != NULL )
- {
- IVY_LIST_ADD( clnt->msg_send, snd )
- if ( snd )
- {
- snd->id = id;
- snd->str_regexp = str_regexp; /* should be Freeed on remove */
- snd->bind = bind;
- if ( application_bind_callback )
- {
- (*application_bind_callback)( clnt, application_bind_data, IvyAddBind, snd->str_regexp );
- }
- }
- }
- else
- {
- int offset;
- const char *errbuf;
- IvyBindingGetCompileError( &offset, &errbuf );
- MsgSendTo( client, Error, offset, strlen(errbuf), errbuf );
- free( str_regexp ); /* not used so Free it */
- }
-
- break;
- case DelRegexp:
-#ifdef DEBUG
- printf("DelRegexp id=%d\n", id);
-#endif //DEBUG
- IVY_LIST_ITER( clnt->msg_send, snd, ( id != snd->id ));
- if ( snd )
+ TRACE("Regexp id=%d exp='%s'\n", id, arg);
+
+ if ( !IvyBindingFilter( arg ) )
{
- if ( application_bind_callback )
- {
- (*application_bind_callback)( clnt, application_bind_data, IvyRemoveBind, snd->str_regexp );
- }
- free( snd->str_regexp );
- IvyBindingFree( snd->bind );
- IVY_LIST_REMOVE( clnt->msg_send, snd );
- }
- break;
- case AddBinding:
+ TRACE("Warning: regexp '%s' illegal, removing from %s\n",arg,ApplicationName);
-#ifdef DEBUG
- printf("AddBinding id=%d exp='%.*s'\n", id, len_args, (char*)args);
-#endif //DEBUG
- if ( !IvyBindingFilter( IvyBindSimple, len_args, args ) )
- {
-#ifdef DEBUG
- printf("Warning: regexp '%.*s' illegal, removing from %s\n",len_args,(char*)args,ApplicationName);
-#endif //DEBUG
- return ptr_end;
- }
- str_regexp = DupArg( len_args, args );
-
- bind = IvyBindingCompile( IvyBindSimple, str_regexp );
- if ( bind != NULL )
- {
- IVY_LIST_ADD( clnt->msg_send, snd )
- if ( snd )
- {
- snd->id = id;
- snd->str_regexp = str_regexp;
- snd->bind = bind;
- if ( application_bind_callback )
+ if ( application_bind_callback )
{
- (*application_bind_callback)( clnt, application_bind_data, IvyAddBind, snd->str_regexp );
+ (*application_bind_callback)( clnt, application_bind_data, id, arg, IvyFilterBind );
}
- }
+ return;
}
- else
+
+ bind = IvyBindingCompile( arg, & erroffset, & errbuf );
+ if ( bind != NULL )
{
- int offset;
- const char *errbuf;
- IvyBindingGetCompileError( &offset, &errbuf );
- MsgSendTo( client, Error, offset, strlen(errbuf), errbuf );
- free( str_regexp );
+ // On teste si c'est un change regexp : changement de regexp d'une id existante
+ IVY_LIST_ITER( clnt->msg_send, snd, ( id != snd->id ));
+ if ( snd ) {
+ free (snd->str_regexp);
+ snd->str_regexp = strdup( arg );
+ snd->binding = bind;
+ if ( application_bind_callback )
+ {
+ (*application_bind_callback)( clnt, application_bind_data, id, snd->str_regexp, IvyChangeBind );
+ }
+ } else {
+ IVY_LIST_ADD_START( clnt->msg_send, snd )
+ snd->id = id;
+ snd->str_regexp = strdup( arg );
+ snd->binding = bind;
+ if ( application_bind_callback )
+ {
+ (*application_bind_callback)( clnt, application_bind_data, id, snd->str_regexp, IvyAddBind );
+ }
+ IVY_LIST_ADD_END( clnt->msg_send, snd )
+
+ }
}
-
+ else
+ {
+ printf("Error compiling '%s', %s\n", arg, errbuf);
+ MsgSendTo( client, Error, erroffset, errbuf );
+ }
+
break;
- case DelBinding:
-#ifdef DEBUG
- printf("DelBinding id=%d\n", id);
-#endif //DEBUG
+ case DelRegexp:
+
+ TRACE("Regexp Delete id=%d\n", id);
IVY_LIST_ITER( clnt->msg_send, snd, ( id != snd->id ));
if ( snd )
{
if ( application_bind_callback )
{
- (*application_bind_callback)( clnt, application_bind_data, IvyRemoveBind, snd->str_regexp );
+ (*application_bind_callback)( clnt, application_bind_data, id, snd->str_regexp, IvyRemoveBind );
}
- free( snd->str_regexp );
- IvyBindingFree( snd->bind );
-
+ IvyBindingFree( snd->binding );
IVY_LIST_REMOVE( clnt->msg_send, snd );
}
break;
case StartRegexp:
-#ifdef DEBUG
- printf("Regexp Start id=%d Application='%.*s'\n", id, len_args, (char*)args);
-#endif //DEBUG
- clnt->app_name = DupArg( len_args, args );
+
+ TRACE("Regexp Start id=%d Application='%s'\n", id, arg);
+
+ clnt->app_name = strdup( arg );
clnt->app_port = id;
if ( CheckConnected( clnt ) )
{
-#ifdef DEBUG
- printf("Quitting already connected %.*s\n", len_args, (char*)args);
-#endif //DEBUG
+
+ TRACE("Quitting already connected %s\n", line);
+
IvySendError( clnt, 0, "Application already connected" );
SocketClose( client );
}
break;
case EndRegexp:
-#ifdef DEBUG
- printf("Regexp End id=%d\n", id);
-#endif //DEBUG
+ TRACE("Regexp End id=%d\n", id);
+
if ( application_callback )
{
(*application_callback)( clnt, application_user_data, IvyApplicationConnected );
@@ -574,94 +393,85 @@ static char* Receive( Client client, void *data, char *message, unsigned int len
int count;
count = ClientCall( clnt, ready_message );
-#ifdef DEBUG
- printf(" Sendind ready message %d\n", count);
-#endif //DEBUG
-
+ TRACE(" Sendind ready message %d\n", count);
}
break;
case Msg:
-#ifdef DEBUG
- printf("Message id=%d msg='%.*s'\n", id, len_args, (char*)args);
-#endif //DEBUG
- rcv = hash_lookup( msg_recv, id );
- if ( rcv && rcv->callback )
+ TRACE("Message id=%d msg='%s'\n", id, arg);
+
+ IVY_LIST_EACH( msg_recv, rcv )
+ {
+ if ( id == rcv->id )
{
- arguments = IvyArgumentDeserialize( len_args, args, &adv_buffer );
-
-#ifdef DEBUG
- printf("Calling id=%d for %s\n", id, rcv->regexp);
-#endif
- (*rcv->callback)( clnt, rcv->user_data, arguments );
- IvyArgumentFree( arguments ); /* TODO evy , suppress malloc/free on each callback */
- return ptr_end;
+ arg = nextArg( arg, ARG_END);
+ while ( arg )
+ {
+ argv[argc++] = arg;
+ arg = nextArg( 0, ARG_END );
+ }
+ TRACE("Calling id=%d argc=%d for %s\n", id, argc,rcv->regexp);
+ if ( rcv->callback ) (*rcv->callback)( clnt, rcv->user_data, argc, argv );
+ return;
}
- else
- printf("Callback Message id=%d not found!!!'\n", id);
+ }
+ printf("Callback Message id=%d not found!!!'\n", id);
break;
case DirectMsg:
-#ifdef DEBUG
- printf("Direct Message id=%d msg='%.*s'\n", id, len_args, (char*)args);
-#endif //DEBUG
+ TRACE("Direct Message id=%d msg='%s'\n", id, arg);
if ( direct_callback)
- (*direct_callback)( clnt, direct_user_data, id, len_args, args );
+ (*direct_callback)( clnt, direct_user_data, id, arg );
break;
case Die:
-#ifdef DEBUG
- printf("Die Message\n");
-#endif //DEBUG
+ TRACE("Die Message\n");
if ( application_die_callback)
(*application_die_callback)( clnt, application_die_user_data, id );
IvyCleanup();
exit(0);
break;
- case ApplicationId:
-#ifdef DEBUG
- printf("ApplicationId priority=%d appid='%.*s'\n", id, len_args, (char*)args);
-#endif //DEBUG
- clnt->app_id = DupArg( len_args, args );
- if ( id != clnt->priority )
- {
- clnt->priority = id;
- SortClients();
- }
+
+ case Ping:
+
+ TRACE("Ping Message\n");
+ MsgSendTo( client, Pong, id, "" );
+ break;
+
+ case Pong:
+
+ TRACE("Pong Message\n");
+ printf("Receive unhandled Pong message (ivy-c not able to send ping)\n");
break;
+
default:
- printf("Receive unhandled message %d\n", kind_of_msg);
+ printf("Receive unhandled message %s\n", line);
break;
}
- return ptr_end;
-}
-static BOOL SendRegexp(HASHKEYTYPE key, void *data, va_list args)
-{
- Client client = va_arg( args, Client);
- MsgRcvPtr msg = (MsgRcvPtr)data;
- MsgSendTo( client, msg->type == IvyBindRegexp ? AddRegexp : AddBinding, msg->id, strlen(msg->regexp), msg->regexp);
- return FALSE; /* iter throught all hash table */
+
}
-static IvyClientPtr SendService( Client client )
+
+static IvyClientPtr SendService( Client client, const char *appname )
{
IvyClientPtr clnt;
- IVY_LIST_ADD( clients, clnt )
- if ( clnt )
- {
- SocketKeepAlive ( client, 1 );
+ MsgRcvPtr msg;
+ IVY_LIST_ADD_START( clients, clnt )
+
clnt->msg_send = 0;
clnt->client = client;
- clnt->app_name = strdup("Unknown");
+ clnt->app_name = strdup(appname);
clnt->app_port = 0;
- clnt->priority = DEFAULT_PRIORITY;
- MsgSendTo( client, ApplicationId, applicationPriority, strlen(applicationUniqueId), applicationUniqueId );
- MsgSendTo( client, StartRegexp, ApplicationPort, strlen(ApplicationName), ApplicationName );
- hash_search( msg_recv, SendRegexp, client);
- MsgSendTo( client, EndRegexp, 0, 0,"");
- }
+ MsgSendTo( client, StartRegexp, ApplicationPort, ApplicationName);
+ IVY_LIST_EACH(msg_recv, msg )
+ {
+ MsgSendTo( client, AddRegexp,msg->id,msg->regexp);
+ }
+ MsgSendTo( client, EndRegexp, 0, "");
+
+ IVY_LIST_ADD_END( clients, clnt )
return clnt;
}
@@ -682,14 +492,13 @@ static void ClientDelete( Client client, void *data )
#ifdef DEBUG
/* probably bogus call, but this is for debug only anyway */
SocketGetRemoteHost( client, &remotehost, &remoteport );
- printf("Deconnexion de %s:%hu\n", remotehost, remoteport );
+ TRACE("Deconnexion de %s:%hu\n", remotehost, remoteport );
#endif //DEBUG
if ( clnt->app_name ) free( clnt->app_name );
- if ( clnt->app_id ) free( clnt->app_id );
IVY_LIST_EACH( clnt->msg_send, msg)
{
- IvyBindingFree( msg->bind );
+ /*regfree(msg->regexp);*/
free( msg->str_regexp);
}
IVY_LIST_EMPTY( clnt->msg_send );
@@ -703,69 +512,36 @@ static void *ClientCreate( Client client )
char *remotehost;
unsigned short remoteport;
SocketGetRemoteHost( client, &remotehost, &remoteport );
- printf("Connexion de %s:%hu\n", remotehost, remoteport );
+ TRACE("Connexion de %s:%hu\n", remotehost, remoteport );
#endif //DEBUG
- return SendService (client);
-}
-/* Hello packet Send */
-static void IvySendHello(unsigned long mask)
-{
- char *packet;
- char *ptr;
- int lenAppId;
- int lenAppName;
- int len;
- lenAppId = strlen( applicationUniqueId );
- lenAppName = strlen( ApplicationName );
- len = 4*sizeof(unsigned short) + lenAppId + lenAppName;
- packet = malloc( len );
- ptr = packet;
- *((unsigned short *) ptr)++ = htons( VERSION );
- *((unsigned short *) ptr)++ = htons( ApplicationPort );
- *((unsigned short *) ptr)++ = htons( lenAppId );
- strncpy( ptr, applicationUniqueId , lenAppId);
- ptr += lenAppId;
- *((unsigned short *) ptr)++ = htons( lenAppName );
- strncpy( ptr, ApplicationName , lenAppName);
-
- SocketSendBroadcast(broadcast, mask, SupervisionPort, packet,len );
- free( packet );
+
+ return SendService (client, "Unknown");
}
-/* Hello packet Receive */
-static char* BroadcastReceive( Client client, void *data, char *message, unsigned int len)
+
+static void BroadcastReceive( Client client, void *data, char *line )
{
Client app;
- unsigned short version;
+ int err;
+ int version;
unsigned short serviceport;
- char appname[1024];
- char appid[1024];
- unsigned short len_appid;
- unsigned short len_appname;
+ char appid[2048];
+ char appname[2048];
#ifdef DEBUG
unsigned short remoteport;
char *remotehost = 0;
#endif
-
- char *ptr_end;
- ptr_end = message;
-
- if ( len < 6 ) return NULL; /* incomplete message */
-
- version = ntohs( *((unsigned short *) ptr_end)++ );
- serviceport = ntohs( *((unsigned short *) ptr_end)++ );
- len_appid = ntohs( *((unsigned short *) ptr_end)++ );
- if ( len < (6 +len_appid) ) return NULL; /* incomplete message */
-
- strncpy( appid , ptr_end, len_appid );
- appid[ len_appid ] = '\0';
- ptr_end += len_appid;
- len_appname = ntohs( *((unsigned short *) ptr_end)++ );
- if ( len < (6 +len_appid + len_appname) ) return NULL; /* incomplete message */
-
- strncpy( appname , ptr_end, len_appname );
- appname[ len_appname ] = '\0';
- ptr_end += len_appname;
-
+ memset( appid, 0, sizeof( appid ) );
+ memset( appname, 0, sizeof( appname ) );
+ err = sscanf (line,"%d %hu %s %[^\n]", &version, &serviceport, appid, appname);
+ if ( err < 2 ) {
+ /* ignore the message */
+ unsigned short remoteport;
+ char *remotehost;
+ SocketGetRemoteHost (client, &remotehost, &remoteport );
+ printf (" Bad supervision message, expected 'version port' from %s:%d\n",
+ remotehost, remoteport);
+ return;
+ }
if ( version != VERSION ) {
/* ignore the message */
unsigned short remoteport;
@@ -773,116 +549,82 @@ static char* BroadcastReceive( Client client, void *data, char *message, unsigne
SocketGetRemoteHost (client, &remotehost, &remoteport );
fprintf (stderr, "Bad Ivy version, expected %d and got %d from %s:%d\n",
VERSION, version, remotehost, remoteport);
- return ptr_end;
+ return;
}
- /* check if we received our own message */
- if (strcmp( appid,applicationUniqueId )== 0)
- return ptr_end;
+ /* check if we received our own message. SHOULD ALSO TEST THE HOST */
+ if ( strcmp( appid , ApplicationID) ==0 ) return;
+ if (serviceport == ApplicationPort) return;
#ifdef DEBUG
SocketGetRemoteHost (client, &remotehost, &remoteport );
- printf(" Broadcast de %s:%hu port %hu %s %s\n", remotehost, remoteport, serviceport, appname, appid );
+ TRACE(" Broadcast de %s:%hu port %hu\n", remotehost, remoteport, serviceport );
#endif //DEBUG
- /* check if already the same name on the bus */
- if ( strcmp( appname,ApplicationName )== 0)
- {
- /* TODO rize some callback ? */
- fprintf(stderr,"!!! Warning a another instance of %s is arriving on the Bus !!!\n", ApplicationName );
- }
/* connect to the service and send the regexp */
app = SocketConnectAddr(SocketGetRemoteAddr(client), serviceport, 0, Receive, ClientDelete );
if (app) {
IvyClientPtr clnt;
- clnt = SendService( app );
+ clnt = SendService( app, appname );
SocketSetData( app, clnt);
}
- return ptr_end;
+}
+static unsigned long currentTime()
+{
+#define MILLISEC 1000
+ unsigned long current;
+#ifdef WIN32
+ current = GetTickCount();
+#else
+ struct timeval stamp;
+ gettimeofday( &stamp, NULL );
+ current = stamp.tv_sec * MILLISEC + stamp.tv_usec/MILLISEC;
+#endif
+ return current;
}
+static const char * GenApplicationUniqueIdentifier()
+{
+ static char appid[2048];
+ unsigned long curtime;
+ curtime = currentTime();
+ srand( curtime );
+ sprintf(appid,"%d:%lu:%d",rand(),curtime,ApplicationPort);
+ return appid;
+}
void IvyInit (const char *appname, const char *ready,
IvyApplicationCallback callback, void *data,
IvyDieCallback die_callback, void *die_data
)
{
- char hostname[1024];
- struct hostent *host;
- IvyChannelInit();
+ SocketInit();
- msg_recv = hash_create( 1024, FALSE );
- if ( ! msg_recv )
- {
- fprintf(stderr,"IvyInit can't create Binding hash Table\n");
- exit(-1);
- }
ApplicationName = appname;
application_callback = callback;
application_user_data = data;
application_die_callback = die_callback;
application_die_user_data = die_data;
ready_message = ready;
- /*
- * Initialize TCP port
- */
- server = SocketServer (ANYPORT, ClientCreate, ClientDelete, Receive);
- ApplicationPort = SocketServerGetPort (server);
- /* get Host Ip address */
- if ( gethostname(hostname,sizeof(hostname)) < 0 )
- {
- perror("gethostname");
- exit(-1);
- }
- host = gethostbyname( hostname );
- if ( ! host )
- {
- perror("gethostbyname");
- exit(-1);
- }
- /* generate application UniqueID (timeStamp-Ipaddress-port*/
- /* TODO bug if multiple interface */
- applicationUniqueId = malloc(1024);
- sprintf( applicationUniqueId , "%lu-%u%u%u%u-%d",
- currentTime(),
- (unsigned char)host->h_addr[0],
- (unsigned char)host->h_addr[1],
- (unsigned char)host->h_addr[2],
- (unsigned char)host->h_addr[3],
- ApplicationPort);
-
}
-void IvyStop()
+void IvySetBindCallback( IvyBindCallback bind_callback, void *bind_data )
{
- IvyCleanup();
- IvyChannelStop();
+ application_bind_callback=bind_callback;
+ application_bind_data=bind_data;
}
-void IvySetApplicationPriority( int priority )
+void IvySetFilter( int argc, const char **argv)
{
- int len;
- IvyClientPtr clnt;
- applicationPriority = priority;
- if ( clients )
- {
- /* Send to already connected clients */
- len = strlen(applicationUniqueId);
- IVY_LIST_EACH (clients, clnt ) {
- MsgSendTo( clnt->client, ApplicationId, applicationPriority, len, applicationUniqueId);
- }
- }
-}
+ IvyBindingSetFilter( argc, argv );
+ if ( getenv( "IVY_DEBUG_FILTER" )) debug_filter = 1;
-void IvySetBindCallback(IvyBindCallback bind_callback, void *bind_data)
-{
- application_bind_callback=bind_callback;
- application_bind_data=bind_data;
}
-void IvySetMyMessagesStart( int argc, const char **argv)
+void IvyStop (void)
{
- IvyBindingSetFilter( argc, argv );
+ IvyChannelStop();
}
+
void IvyStart (const char* bus)
{
@@ -898,6 +640,13 @@ void IvyStart (const char* bus)
/*
+ * Initialize TCP port
+ */
+ server = SocketServer (ANYPORT, ClientCreate, ClientDelete, Receive);
+ ApplicationPort = SocketServerGetPort (server);
+ ApplicationID = GenApplicationUniqueIdentifier();
+
+ /*
* Find network list as well as broadcast port
* (we accept things like 123.231,123.123:2000 or 123.231 or :2000),
* Initialize UDP port
@@ -956,7 +705,7 @@ void IvyStart (const char* bus)
if ( IN_MULTICAST( mask ) )
SocketAddMember (broadcast , mask );
- IvySendHello( mask );
+ SocketSendBroadcast (broadcast, mask, SupervisionPort, "%d %hu %s %s\n", VERSION, ApplicationPort, ApplicationID, ApplicationName);
numelem = 0;
mask = 0xffffffff;
}
@@ -986,123 +735,117 @@ void IvyStart (const char* bus)
++p;
}
-#ifdef DEBUG
- fprintf (stderr,"Listening on TCP:%hu\n",ApplicationPort);
-#endif
+ TRACE ("Listening on TCP:%hu\n",ApplicationPort);
}
/* desabonnements */
-void IvyUnbindMsg (MsgRcvPtr msg)
+void
+IvyUnbindMsg (MsgRcvPtr msg)
{
IvyClientPtr clnt;
/* Send to already connected clients */
IVY_LIST_EACH (clients, clnt ) {
- MsgSendTo( clnt->client, DelRegexp,msg->id, 0, "");
+ MsgSendTo( clnt->client, DelRegexp,msg->id, "");
}
- hash_remove( msg_recv, msg->id );
+ IVY_LIST_REMOVE( msg_recv, msg );
}
/* demande de reception d'un message */
-static MsgRcvPtr IvyBind ( IvyBindingType typ, MsgCallback callback, void *user_data, const char *fmt_regex, va_list ap )
+
+MsgRcvPtr
+IvyBindMsg (MsgCallback callback, void *user_data, const char *fmt_regex, ... )
{
- char *buffer = NULL;
- int size = 0;
+ static IvyBuffer buffer = { NULL, 0, 0};
+ va_list ap;
static int recv_id = 0;
IvyClientPtr clnt;
MsgRcvPtr msg;
- int len;
- int MsgType = typ == IvyBindRegexp ? AddRegexp : AddBinding;
- make_message( &buffer, &size, 0, fmt_regex, ap );
-
+ va_start (ap, fmt_regex );
+ buffer.offset = 0;
+ make_message( &buffer, fmt_regex, ap );
+ va_end (ap );
+
+ substituteInterval (&buffer);
+
/* add Msg to the query list */
- msg = malloc(sizeof(struct _msg_rcv));
- if (msg) {
- msg->type = typ;
+ IVY_LIST_ADD_START( msg_recv, msg )
msg->id = recv_id++;
- msg->regexp = buffer;
+ msg->regexp = strdup(buffer.data);
msg->callback = callback;
msg->user_data = user_data;
- if ( !hash_add(msg_recv, msg->id, msg) )
- {
- perror("IvyBindMsg can't hash_add Entry already exists!");
- exit(-1);
- }
- }
- else
- {
- perror("IvyBindMsg can't allocate Binding");
- free ( buffer );
- exit(-1);
- }
- len = strlen(msg->regexp);
+ IVY_LIST_ADD_END( msg_recv, msg )
/* Send to already connected clients */
/* recherche dans la liste des requetes recues de mes clients */
IVY_LIST_EACH( clients, clnt ) {
- MsgSendTo( clnt->client, MsgType,msg->id, len, msg->regexp);
+ MsgSendTo( clnt->client, AddRegexp,msg->id,msg->regexp);
}
return msg;
}
-
-MsgRcvPtr IvyBindMsg (MsgCallback callback, void *user_data, const char *fmt_regex, ... )
+/* changement de regexp d'un bind existant precedement fait avec IvyBindMsg */
+MsgRcvPtr
+IvyChangeMsg (MsgRcvPtr msg, const char *fmt_regex, ... )
{
+ static IvyBuffer buffer = { NULL, 0, 0};
va_list ap;
- MsgRcvPtr msg;
+ IvyClientPtr clnt;
va_start (ap, fmt_regex );
- msg = IvyBind ( IvyBindRegexp, callback, user_data, fmt_regex, ap );
+ buffer.offset = 0;
+ make_message( &buffer, fmt_regex, ap );
va_end (ap );
- return msg;
-
-}
-MsgRcvPtr IvyBindSimpleMsg( MsgCallback callback, void *user_data, const char *fmt_regex, ... )
-{
- va_list ap;
- MsgRcvPtr msg;
+ substituteInterval (&buffer);
- va_start (ap, fmt_regex );
- msg = IvyBind ( IvyBindSimple, callback, user_data, fmt_regex, ap );
- va_end (ap );
- return msg;
+ /* change Msg in the query list */
+ msg->regexp = strdup(buffer.data);
+ /* Send to already connected clients */
+ /* recherche dans la liste des requetes recues de mes clients */
+ IVY_LIST_EACH( clients, clnt ) {
+ MsgSendTo( clnt->client, AddRegexp,msg->id,msg->regexp);
+ }
+ return msg;
}
+/* emmission d'un message avec formatage a la printf */
int IvySendMsg(const char *fmt, ...)
{
IvyClientPtr clnt;
int match_count = 0;
- char *buffer = NULL; /* Use satic mem to eliminate multiple call to malloc /free */
- int size = 0; /* donc non reentrant !!!! */
+ static IvyBuffer buffer = { NULL, 0, 0}; /* Use satic mem to eliminate multiple call to malloc /free */
va_list ap;
+ if( fmt == 0 || strlen(fmt) == 0 ) return 0;
va_start( ap, fmt );
- make_message( &buffer, &size, 0, fmt, ap );
+ buffer.offset = 0;
+ make_message( &buffer, fmt, ap );
va_end ( ap );
/* recherche dans la liste des requetes recues de mes clients */
IVY_LIST_EACH (clients, clnt) {
- match_count += ClientCall (clnt, buffer);
+ match_count += ClientCall (clnt, buffer.data);
+ }
+ TRACE_IF( match_count == 0, "Warning no recipient for %s\n",buffer.data);
+ /* si le message n'est pas emit et qu'il y a des filtres alors WARNING */
+ if ( match_count == 0 && debug_filter )
+ {
+ IvyBindindFilterCheck( buffer.data );
}
-#ifdef DEBUG
- if ( match_count == 0 ) printf( "Warning no recipient for %s\n",buffer);
-#endif
- free(buffer);
return match_count;
}
void IvySendError( IvyClientPtr app, int id, const char *fmt, ... )
{
- char *buffer = NULL; /* Use satic mem to eliminate multiple call to malloc /free */
- int size = 0; /* donc non reentrant !!!! */
+ static IvyBuffer buffer = { NULL, 0, 0}; /* Use satic mem to eliminate multiple call to malloc /free */
va_list ap;
va_start( ap, fmt );
- make_message( &buffer, &size, 0, fmt, ap );
+ buffer.offset = 0;
+ make_message( &buffer, fmt, ap );
va_end ( ap );
- MsgSendTo( app->client, Error, id, strlen(buffer), buffer);
- free(buffer);
+ MsgSendTo( app->client, Error, id, buffer.data);
}
void IvyBindDirectMsg( MsgDirectCallback callback, void *user_data)
@@ -1111,14 +854,14 @@ void IvyBindDirectMsg( MsgDirectCallback callback, void *user_data)
direct_user_data = user_data;
}
-void IvySendDirectMsg( IvyClientPtr app, int id, int len, void *msg )
+void IvySendDirectMsg( IvyClientPtr app, int id, char *msg )
{
- MsgSendTo( app->client, DirectMsg, id, len, msg);
+ MsgSendTo( app->client, DirectMsg, id, msg);
}
void IvySendDieMsg( IvyClientPtr app )
{
- MsgSendTo( app->client, Die, 0, 0, "" );
+ MsgSendTo( app->client, Die, 0, "" );
}
char *IvyGetApplicationName( IvyClientPtr app )
@@ -1134,12 +877,7 @@ char *IvyGetApplicationHost( IvyClientPtr app )
return SocketGetPeerHost (app->client );
else return 0;
}
-char *IvyGetApplicationId( IvyClientPtr app )
-{
- if ( app && app->app_id )
- return app->app_id;
- else return 0;
-}
+
void IvyDefaultApplicationCallback( IvyClientPtr app, void *user_data, IvyApplicationEvent event)
{
switch ( event ) {
@@ -1154,14 +892,21 @@ void IvyDefaultApplicationCallback( IvyClientPtr app, void *user_data, IvyApplic
break;
}
}
-void IvyDefaultBindCallback( IvyClientPtr app, void *user_data, IvyBindEvent event, char* regexp )
+void IvyDefaultBindCallback( IvyClientPtr app, void *user_data, int id, char* regexp, IvyBindEvent event)
{
switch ( event ) {
case IvyAddBind:
- printf("Application: %s on %s add regexp %s\n", IvyGetApplicationName( app ), IvyGetApplicationHost(app), regexp);
+ printf("Application: %s on %s add regexp %d : %s\n", IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp);
break;
case IvyRemoveBind:
- printf("Application: %s on %s remove regexp %s\n", IvyGetApplicationName( app ), IvyGetApplicationHost(app), regexp);
+ printf("Application: %s on %s remove regexp %d :%s\n", IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp);
+ break;
+ case IvyFilterBind:
+ printf("Application: %s on %s as been filtred regexp %d :%s\n", IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp);
+ break;
+ case IvyChangeBind:
+ printf("Application: %s on %s change regexp %d : %s\n", IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp);
+ break;
break;
default:
printf("Application: %s unkown event %d\n",IvyGetApplicationName( app ), event);
@@ -1176,22 +921,23 @@ IvyClientPtr IvyGetApplication( char *name )
return app;
}
-char **IvyGetApplicationList()
+char *IvyGetApplicationList(const char *sep)
{
- static char* applist[500];
+ static char applist[4096]; /* TODO remove that ugly Thing */
IvyClientPtr app;
- int appCount= 0;
- memset( applist, 0 , sizeof( applist ));
+ applist[0] = '\0';
IVY_LIST_EACH( clients, app )
{
- applist[appCount++]= app->app_name;
+ strcat( applist, app->app_name );
+ strcat( applist, sep );
}
return applist;
}
char **IvyGetApplicationMessages( IvyClientPtr app )
{
- static char *messagelist[200];
+#define MAX_REGEXP 4096
+ static char *messagelist[MAX_REGEXP+1];/* TODO remove that ugly Thing */
MsgSndPtr msg;
int msgCount= 0;
memset( messagelist, 0 , sizeof( messagelist ));
@@ -1199,6 +945,53 @@ char **IvyGetApplicationMessages( IvyClientPtr app )
IVY_LIST_EACH( app->msg_send, msg )
{
messagelist[msgCount++]= msg->str_regexp;
+ if ( msgCount >= MAX_REGEXP )
+ {
+ fprintf(stderr,"Too Much expression(%d) for buffer\n",msgCount);
+ break;
+ }
}
return messagelist;
}
+
+static void substituteInterval (IvyBuffer *src)
+{
+ // pas de traitement couteux s'il n'y a rien à interpoler
+ if (strstr (src->data, "(?I") == NULL) {
+ return;
+ } else {
+ char *curPos;
+ char *itvPos;
+ IvyBuffer dst = {NULL, 0, 0};
+ dst.size = 8192;
+ dst.data = malloc (dst.size);
+
+ curPos = src->data;
+ while ((itvPos = strstr (curPos, "(?I")) != NULL) {
+ // copie depuis la position courante jusqu'à l'intervalle
+ int lenCp, min,max;
+ char withDecimal;
+ lenCp = itvPos-curPos;
+ memcpy (&(dst.data[dst.offset]), curPos, lenCp);
+ curPos=itvPos;
+ dst.offset += 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 (&(dst.data[dst.offset]), dst.size-dst.offset, min, max, (withDecimal != 'i'));
+ dst.offset = strlen (dst.data);
+
+ // consommation des caractères décrivant intervalle dans la chaine source
+ curPos = strstr (curPos, ")");
+ curPos++;
+ }
+ strncat (dst.data, curPos, dst.size-dst.offset);
+ free (src->data);
+ src->data = dst.data;
+ }
+}
diff --git a/src/ivy.h b/src/ivy.h
index 889e86b..0ee4542 100644
--- a/src/ivy.h
+++ b/src/ivy.h
@@ -1,6 +1,4 @@
-
/*
- * \ingroup Ivy
* Ivy, C interface
*
* Copyright (C) 1997-2000
@@ -8,17 +6,13 @@
*
* Main functions
*
- * \author Authors: François-Régis Colin <fcolin@cena.fr>
- * Stéphane Chatty <chatty@cena.fr>
+ * Authors: François-Régis Colin <fcolin@cena.dgac.fr>
+ * Stéphane Chatty <chatty@cena.dgac.fr>
*
* $Id$
*
* Please refer to file version.h for the
* copyright notice regarding this software
- * \todo
- * many things TODO
- * \bug
- * many introduced
*/
#ifndef IVY_H
@@ -28,86 +22,67 @@
extern "C" {
#endif
-#include "IvyArgument.h"
-
/* numero par default du bus */
#define DEFAULT_BUS 2010
-#define DEFAULT_PRIORITY 100;
typedef struct _clnt_lst *IvyClientPtr;
typedef enum { IvyApplicationConnected, IvyApplicationDisconnected } IvyApplicationEvent;
-typedef enum { IvyAddBind, IvyRemoveBind } IvyBindEvent;
+typedef enum { IvyAddBind, IvyRemoveBind, IvyFilterBind, IvyChangeBind } IvyBindEvent;
extern void IvyDefaultApplicationCallback( IvyClientPtr app, void *user_data, IvyApplicationEvent event ) ;
-extern void IvyDefaultBindCallback( IvyClientPtr app, void *user_data, IvyBindEvent event, char* regexp ) ;
+extern void IvyDefaultBindCallback( IvyClientPtr app, void *user_data, int id, char* regexp, IvyBindEvent event ) ;
/* callback callback appele sur connexion deconnexion d'une appli */
typedef void (*IvyApplicationCallback)( IvyClientPtr app, void *user_data, IvyApplicationEvent event ) ;
/* callback callback appele sur ajout ou suppression d'un bind */
-typedef void (*IvyBindCallback)( IvyClientPtr app, void *user_data, IvyBindEvent event, char* regexp ) ;
+typedef void (*IvyBindCallback)( IvyClientPtr app, void *user_data, int id, char* regexp, IvyBindEvent event ) ;
/* callback appele sur reception de die */
typedef void (*IvyDieCallback)( IvyClientPtr app, void *user_data, int id ) ;
/* callback appele sur reception de messages normaux */
-typedef void (*MsgCallback)( IvyClientPtr app, void *user_data, IvyArgument args ) ;
+typedef void (*MsgCallback)( IvyClientPtr app, void *user_data, int argc, char **argv ) ;
/* callback appele sur reception de messages directs */
-typedef void (*MsgDirectCallback)( IvyClientPtr app, void *user_data, int id, int len, void *msg ) ;
+typedef void (*MsgDirectCallback)( IvyClientPtr app, void *user_data, int id, char *msg ) ;
/* identifiant d'une expression reguliere ( Bind/Unbind ) */
typedef struct _msg_rcv *MsgRcvPtr;
/* filtrage des regexps */
-void IvySetMyMessagesStart( int argc, const char **argv);
+void IvySetFilter( int argc, const char **argv);
-/**
- *
- * \param AppName
- * \param ready
- * \param callback
- * \param data
- * \param die_callback
- * \param die_data
- */
void IvyInit(
- const char * AppName, /* nom de l'application */
- const char * ready, /* ready Message peut etre NULL */
+ const char *AppName, /* nom de l'application */
+ const char *ready, /* ready Message peut etre NULL */
IvyApplicationCallback callback, /* callback appele sur connection deconnection d'une appli */
- void * data, /* user data passe au callback */
+ void *data, /* user data passe au callback */
IvyDieCallback die_callback, /* last change callback before die */
- void * die_data /* user data */
+ void *die_data /* user data */
);
+
+void IvySetBindCallback(
+ IvyBindCallback bind_callback,
+ void *bind_data );
-/**
- *
- * \param priority prioritie de traitement des clients
- */
-void IvySetApplicationPriority( int priority );
-void IvySetBindCallback( IvyBindCallback bind_callback, void *bind_data );
-/**
- *
- * \param bus
- */
-void IvyStart (const char* bus);
+void IvyStart (const char*);
void IvyStop ();
/* query sur les applications connectees */
char *IvyGetApplicationName( IvyClientPtr app );
char *IvyGetApplicationHost( IvyClientPtr app );
-char *IvyGetApplicationId( IvyClientPtr app );
IvyClientPtr IvyGetApplication( char *name );
-char ** IvyGetApplicationList();
+char *IvyGetApplicationList(const char *sep);
char **IvyGetApplicationMessages( IvyClientPtr app); /* demande de reception d'un message */
MsgRcvPtr IvyBindMsg( MsgCallback callback, void *user_data, const char *fmt_regexp, ... ); /* avec sprintf prealable */
-void IvyUnbindMsg( MsgRcvPtr id );
+MsgRcvPtr IvyChangeMsg (MsgRcvPtr msg, const char *fmt_regex, ... ); /* avec sprintf prealable */
-MsgRcvPtr IvyBindSimpleMsg( MsgCallback callback, void *user_data, const char *fmt_regexp, ... ); /* avec sprintf prealable */
+void IvyUnbindMsg( MsgRcvPtr id );
/* emission d'un message d'erreur */
void IvySendError( IvyClientPtr app, int id, const char *fmt, ... );
@@ -122,11 +97,7 @@ int IvySendMsg( const char *fmt_message, ... ); /* avec sprintf prealable */
/* Message Direct Inter-application */
void IvyBindDirectMsg( MsgDirectCallback callback, void *user_data);
-void IvySendDirectMsg( IvyClientPtr app, int id, int len, void *msg );
-
-/* boucle principale d'Ivy */
-/* use of internal MainLoop or XtMainLoop, or other MainLoop integration */
-extern void IvyMainLoop(void(*hook)(void));
+void IvySendDirectMsg( IvyClientPtr app, int id, char *msg );
#ifdef __cplusplus
}
diff --git a/src/ivyargument.c b/src/ivyargument.c
deleted file mode 100755
index 5d398d9..0000000
--- a/src/ivyargument.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Ivy, C interface
- *
- * Copyright (C) 1997-2000
- * Centre d'Études de la Navigation Aérienne
- *
- * Argument message comtent
- *
- * Authors: François-Régis Colin <fcolin@cena.fr>
- *
- * $Id$
- *
- * Please refer to file version.h for the
- * copyright notice regarding this software
- */
-/* Module de gestion de la syntaxe des messages Ivy */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <time.h>
-#include <stdlib.h>
-#include <memory.h>
-#include <string.h>
-
-#ifdef WIN32
-#include <crtdbg.h>
-#include <windows.h>
-#else
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <netdb.h>
-#endif
-
-
-#include "list.h"
-#include "ivyargument.h"
-
-
-
-struct _argument {
- /* childrens */
- struct _argument *next;
- struct _argument *childrens;
- /* arg value */
- int value_len;
- const void *value;
- };
-
-IvyArgument IvyArgumentNew( int len, const void * value )
-{
- IvyArgument arg = malloc( sizeof( *arg ) );
- arg->value_len = len;
- arg->value = value;
- arg->next = 0;
- arg->childrens = 0;
- return arg;
-}
-void IvyArgumentFree( IvyArgument arg )
-{
- IvyArgument p;
- IvyArgument psuiv;
- IVY_LIST_EACH_SAFE( arg->childrens, p, psuiv )
- {
- IvyArgumentFree(p);
- }
- free( arg );
-}
-void IvyArgumentGetValue( IvyArgument arg, int * len, const void **val )
-{
- *len = arg->value_len;
- *val = arg->value;
-}
-IvyArgument IvyArgumentGetChildrens( IvyArgument arg )
-{
- return arg->childrens;
-}
-IvyArgument IvyArgumentGetNextChild( IvyArgument arg )
-{
- return arg->next;
-}
-IvyArgument IvyAddChildValue( IvyArgument arg, int childvaluelen, const void* childvalue )
-{
- /* ADD Child to the beginning of the list */
- IvyArgument child;
- IVY_LIST_ADD( arg->childrens, child )
- if ( child )
- {
- child->value_len = childvaluelen;
- child->value = childvalue;
- }
- return child;
-}
-void IvyAddChild( IvyArgument arg, IvyArgument child )
-{
- /* ADD Child to the beginning of the list */
- child->next = arg->childrens;
- arg->childrens = child;
-}
-int IvyArgumentGetChildCount( IvyArgument arg )
-{
- IvyArgument p;
- int count = 0;
- IVY_LIST_EACH( arg->childrens, p )
- {
- count++;
- }
- return count;
-}
-IvyArgument IvyArgumentDeserialize( int buf_len, void* buffer, int * buf_adv )
-{
- int i;
- void *ptr_end = buffer;
- int adv;
- unsigned short value_len;
- unsigned short nbchild;
- IvyArgument arg;
- IvyArgument child;
-
- adv = 0;
- arg = IvyArgumentNew( 0, 0);
- /* reading value */
- value_len = ntohs( *((unsigned short *) ptr_end)++ );
- if ( value_len )
- {
- arg->value_len = value_len;
- arg->value = ptr_end;
- ((unsigned char *)ptr_end) += value_len;
- }
- /* reading child */
- nbchild = ntohs( *((unsigned short *) ptr_end)++ );
-
- if ( nbchild )
- {
- for ( i= 0; i < nbchild; i++ )
- {
- child = IvyArgumentDeserialize( buf_len - ((unsigned char *)ptr_end - (unsigned char *)buffer) , ptr_end, &adv );
- IvyAddChild( arg, child );
- ((unsigned char *)ptr_end) += adv;
- }
- }
- *buf_adv += (unsigned char *)ptr_end - (unsigned char *)buffer;
-#ifdef DEBUG
- printf( "IvyArgumentDeserialize value='%.*s' nbchild=%d size=%d\n",arg->value_len, (char*)arg->value, nbchild, *buf_adv);
-#endif
- return arg;
-}
-int IvyArgumentSerialize(IvyArgument arg, int *buf_len, void **buffer, int offset)
-{
- int nb_child;
- IvyArgument child;
- void *ptr;
-
- /* check buffer space */
- if ( (*buf_len - offset) < (2 * sizeof( unsigned short ) + arg->value_len) )
- {
- *buf_len += 4096;
- *buffer = realloc( *buffer, *buf_len );
- }
- ptr = (unsigned char*)(*buffer) + offset;
- /* writing value */
- *((unsigned short*)ptr)++ = htons( (unsigned short)arg->value_len );
- if ( arg->value_len )
- {
- memcpy( ptr, arg->value, arg->value_len );
- (unsigned char*)ptr += arg->value_len;
- }
- /* writing child */
- nb_child = IvyArgumentGetChildCount( arg );
- *((unsigned short*)ptr)++ = htons( (unsigned short)nb_child );
- IVY_LIST_EACH ( arg->childrens, child )
- {
- (unsigned char*)ptr += IvyArgumentSerialize( child, buf_len, buffer, (unsigned char*)ptr - (unsigned char*)*buffer );
- }
-#ifdef DEBUG
- printf( "IvyArgumentSerialize value='%.*s' nbchild=%d buff size=%d\n",arg->value_len, (char*)arg->value, nb_child, (unsigned char*)ptr - (unsigned char*)*buffer - offset);
-#endif
- return (unsigned char*)ptr - (unsigned char*)*buffer - offset;
-}
-
diff --git a/src/ivyargument.h b/src/ivyargument.h
deleted file mode 100755
index 0176f21..0000000
--- a/src/ivyargument.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Ivy, C interface
- *
- * Copyright (C) 1997-2005
- * Centre d'Études de la Navigation Aérienne
- *
- * Argument message comtent
- *
- * Authors: François-Régis Colin <fcolin@cena.fr>
- *
- * $Id$
- *
- * Please refer to file version.h for the
- * copyright notice regarding this software
- */
-#ifndef IVY_ARGUMENT_H
-#define IVY_ARGUMENT_H
-/* Module de gestion de la syntaxe des messages Ivy */
-
-typedef struct _argument *IvyArgument;
-
-IvyArgument IvyArgumentNew( int len, const void * value );
-void IvyArgumentFree( IvyArgument arg );
-int IvyArgumentGetChildCount( IvyArgument arg );
-void IvyArgumentGetValue( IvyArgument arg, int * len, const void **val );
-IvyArgument IvyArgumentGetChildrens( IvyArgument arg );
-IvyArgument IvyArgumentGetNextChild( IvyArgument arg );
-void IvyAddChild( IvyArgument arg, IvyArgument child );
-IvyArgument IvyAddChildValue( IvyArgument arg, int childvaluelen, const void* childvalue );
-
-IvyArgument IvyArgumentDeserialize( int buf_len, void* buffer, int * buf_adv);
-int IvyArgumentSerialize(IvyArgument arg, int *buf_len, void **buffer, int offset);
-
-#endif
-
diff --git a/src/ivybind.c b/src/ivybind.c
index 237ee78..c506ab3 100644
--- a/src/ivybind.c
+++ b/src/ivybind.c
@@ -31,78 +31,41 @@
#ifdef USE_PCRE_REGEX
#define OVECSIZE 60 /* must be multiple of 3, for regexp return */
#include <pcre.h>
-#else
+#else /* we don't USE_PCRE_REGEX */
#define MAX_MSG_FIELDS 200
#include <regex.h>
-#endif
+#endif /* USE_PCRE_REGEX */
#include "list.h"
-#include "hash.h"
#include "ivybind.h"
static int err_offset;
#ifdef USE_PCRE_REGEX
static const char *err_buf;
-#else
+#else /* we don't USE_PCRE_REGEX */
static char err_buf[4096];
-#endif
+#endif /* USE_PCRE_REGEX */
struct _binding {
- IvyBindingType type;
- const char *msgname; /* msg tag name first word of message */
- char **msgargs; /* list of msg argument name */
- IvyArgument args; /* result */
#ifdef USE_PCRE_REGEX
pcre *regexp;
pcre_extra *inspect;
int nb_match;
int ovector[OVECSIZE];
-#else
+#else /* we don't USE_PCRE_REGEX */
regex_t regexp; /* la regexp sous forme machine */
regmatch_t match[MAX_MSG_FIELDS+1]; /* resultat du match */
-#endif
+#endif /* USE_PCRE_REGEX */
};
-
/* 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;
-
-/* stokage du message parse avant l'execution des regles de binding simple */
-static char *current_msg = NULL;
-static char *msgtag;
-static HASHTABLE msg_args_values = NULL;
-
-static IvyBinding IvyBindingCompileSimple( IvyBindingType typ, const char * expression )
-{
- int nb_arg= 0;
- char *argname;
- char **argv;
- char *expr;
- IvyBinding bind=0;
-
- expr = strdup( expression ); //Allocate a new buffer of separated token
- /* count nb args */
- argname = expr;
- while ( *argname )
- {
- if ( *argname++ == ' ' ) nb_arg++;
- }
-
- bind = (IvyBinding)malloc( sizeof( struct _binding ));
- memset( bind, 0, sizeof(*bind ) );
- bind->type = IvyBindSimple;
- bind->msgname = strtok( expr, " ");
- bind->msgargs = malloc ( sizeof( char* ) * ( nb_arg + 1) );
- argv = bind->msgargs;
- while ( (argname = strtok( NULL, " ")) )
- *argv++ = argname;
- *argv++ = argname; /* end with NULL */
- return bind;
-}
-static IvyBinding IvyBindingCompileRegexp( IvyBindingType typ, const char * expression )
+IvyBinding IvyBindingCompile( const char * expression, int *erroffset, const char **errmessage )
{
IvyBinding bind=0;
#ifdef USE_PCRE_REGEX
@@ -111,9 +74,13 @@ static IvyBinding IvyBindingCompileRegexp( IvyBindingType typ, const char * expr
if ( regexp != NULL )
{
bind = (IvyBinding)malloc( sizeof( struct _binding ));
+ if ( ! bind )
+ {
+ perror( "IvyBindingCompile malloc error: ");
+ exit(-1);
+ }
memset( bind, 0, sizeof(*bind ) );
bind->regexp = regexp;
- bind->type = IvyBindRegexp;
bind->inspect = pcre_study(regexp,0,&err_buf);
if (err_buf!=NULL)
{
@@ -122,9 +89,11 @@ static IvyBinding IvyBindingCompileRegexp( IvyBindingType typ, const char * expr
}
else
{
+ *erroffset = err_offset;
+ *errmessage = err_buf;
printf("Error compiling '%s', %s\n", expression, err_buf);
}
-#else
+#else /* we don't USE_PCRE_REGEX */
regex_t regexp;
int reg;
reg = regcomp(&regexp, expression, REGCOMP_OPT|REG_EXTENDED);
@@ -138,38 +107,26 @@ static IvyBinding IvyBindingCompileRegexp( IvyBindingType typ, const char * expr
else
{
regerror (reg, &regexp, err_buf, sizeof(err_buf) );
- err_offset = 0; // TODO unkown offset error
+ *erroffset = err_offset;
+ *errmessage = err_buf;
printf("Error compiling '%s', %s\n", expression, err_buf);
}
-#endif
+#endif /* USE_PCRE_REGEX */
return bind;
}
-IvyBinding IvyBindingCompile( IvyBindingType typ, const char * expression )
-{
- if ( typ == IvyBindRegexp )
- return IvyBindingCompileRegexp( typ, expression);
- else
- return IvyBindingCompileSimple( typ, expression);
-}
-void IvyBindingGetCompileError( int *offset, const char **errmessage )
-{
- *offset = err_offset;
- *errmessage = err_buf;
-}
+
void IvyBindingFree( IvyBinding bind )
{
#ifdef USE_PCRE_REGEX
- if (bind->inspect!=NULL) pcre_free(bind->inspect);
+ if (bind->inspect!=NULL)
+ pcre_free(bind->inspect);
pcre_free(bind->regexp);
-#else
-#endif
- if (bind->msgname)
- free ( bind->msgname );
- if (bind->msgargs)
- free ( bind->msgargs );
+#else /* we don't USE_PCRE_REGEX */
+ free( bind->regexp );
+#endif /* USE_PCRE_REGEX */
free ( bind );
}
-int IvyBindingExecRegexp( IvyBinding bind, const char * message )
+int IvyBindingExec( IvyBinding bind, const char * message )
{
int nb_match = 0;
#ifdef USE_PCRE_REGEX
@@ -185,9 +142,7 @@ int IvyBindingExecRegexp( IvyBinding bind, const char * message )
OVECSIZE);
if (nb_match<1) return 0; /* no match */
bind->nb_match = nb_match;
- nb_match--; // firts arg wall string ???
-
-#else
+#else /* we don't USE_PCRE_REGEX */
memset( bind->match, -1, sizeof(bind->match )); /* work around bug !!!*/
nb_match = regexec (&bind->regexp, message, MAX_MSG_FIELDS, bind->match, 0)
if (nb_match == REG_NOMATCH)
@@ -197,126 +152,90 @@ int IvyBindingExecRegexp( IvyBinding bind, const char * message )
if ( bind->match[i].rm_so != -1 )
nb_match++;
}
-#endif
+#endif /* USE_PCRE_REGEX */
return nb_match;
}
-int IvyBindingExecSimple( IvyBinding bind, const char * message )
-{
- char **msg_args;
- if ( strcmp( bind->msgname, msgtag ) != 0 )
- return 0;
- msg_args = bind->msgargs;
- bind->args = IvyArgumentNew( 0,NULL );
- while( *msg_args )
- {
- char *value;
- value = hash_lookup(msg_args_values, (HASHKEYTYPE)*msg_args++);
- if ( !value ) value = ""; /* TODO should we report matching ??? */
- IvyAddChildValue( bind->args, strlen( value ), value);
- }
- return 1;
-}
-int IvyBindingExec( IvyBinding bind, const char * message )
-{
- if ( bind->type == IvyBindRegexp )
- return IvyBindingExecRegexp( bind, message);
- else
- return IvyBindingExecSimple( bind, message);
-}
-static IvyArgument IvyBindingMatchSimple( IvyBinding bind, const char *message)
-{
- return bind->args;
-}
-static IvyArgument IvyBindingMatchRegexp( IvyBinding bind, const char *message)
+
+void IvyBindingMatch( IvyBinding bind, const char *message, int argnum, int *arglen, const char **arg)
{
- int index=1;// firts arg wall string ???
- int arglen;
- const void* arg;
- IvyArgument args;
- args = IvyArgumentNew( 0,NULL );
-
#ifdef USE_PCRE_REGEX
- while ( index<bind->nb_match ) {
- arglen = bind->ovector[2*index+1]- bind->ovector[2*index];
- arg = message + bind->ovector[2*index];
- index++;
+
+ *arglen = bind->ovector[2*argnum+1]- bind->ovector[2*argnum];
+ *arg = message + bind->ovector[2*argnum];
#else /* we don't USE_PCRE_REGEX */
- for ( index = 1; index < MAX_MSG_FIELDS; index++ )
- {
+
regmatch_t* p;
- p = &bind->match[index];
+ p = &bind->match[argnum];
if ( p->rm_so != -1 ) {
- arglen = p->rm_eo - p->rm_so;
- arg = message + p->rm_so;
+ *arglen = p->rm_eo - p->rm_so;
+ *arg = message + p->rm_so;
} else { // ARG VIDE
- arglen = 0;
- arg = NULL;
- }
-#endif // USE_PCRE_REGEX
- IvyAddChildValue( args, arglen, arg );
+ *arglen = 0;
+ *arg = NULL;
}
- return args;
-}
-IvyArgument IvyBindingMatch( IvyBinding bind, const char *message)
-{
- if ( bind->type == IvyBindRegexp )
- return IvyBindingMatchRegexp( bind, message);
- else
- return IvyBindingMatchSimple( bind, message);
+#endif /* USE_PCRE_REGEX */
+
}
//filter Expression Bind
+int IvyBindingGetFilterCount()
+{
+return messages_classes_count;
+}
void IvyBindingSetFilter( int argc, const char **argv)
{
+ const char *errbuf;
+ int erroffset;
+
messages_classes_count = argc;
messages_classes = argv;
-}
-void IvyBindingParseMessage( const char *msg )
-{
- char *arg;
- if ( current_msg ) free( current_msg );
- if ( msg_args_values ) hash_destroy( msg_args_values );
- current_msg = strdup( msg );
- msg_args_values = hash_create( 256, TRUE );
- msgtag = strtok( current_msg, " " );
- while( (arg = strtok( NULL, " =" )) )
+ /* compile the token extraction regexp */
+
+ token_extract = IvyBindingCompile("^\\^([a-zA-Z_0-9-]+).*", & erroffset, & errbuf);
+ if ( !token_extract )
{
- char *val = strtok( NULL, " =");
- if ( arg && val )
- hash_addstring( msg_args_values, arg, val );
+ printf("Error compiling Token Extract regexp: %s\n", errbuf);
}
}
-int IvyBindingFilter(IvyBindingType typ, int len, const char *exp)
+
+int IvyBindingFilter(const char *expression)
{
- /* TODO check args limits !!!*/
int i;
- /* accepte tout par default */
- int regexp_ok = 1;
- // TODO simplify test 3 conditions
- if ( typ == IvyBindRegexp )
- {
- if ( *exp =='^' && messages_classes_count !=0 )
+ 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 = IvyBindingExec( token_extract, expression );
+ if ( err < 1 ) return 1;
+ IvyBindingMatch( token_extract, expression , 1, &tokenlen, &token );
for ( i = 0 ; i < messages_classes_count; i++ )
{
- if (strncmp( messages_classes[i], exp+1, strlen( messages_classes[i] )) == 0)
- return 1;
+ if (strncmp( messages_classes[i], token, tokenlen ) == 0) {
+ return 1; }
+ // else {
+ //printf ("DBG> %s eliminé [%s]\n", token, expression);
+ //}
}
}
- }
- else
- {
- if ( messages_classes_count !=0 )
+ return regexp_ok;
+}
+/* recherche si le message commence par un mot clef de la table */
+void IvyBindindFilterCheck( const char *message )
+{
+ int i;
+ for ( i = 0 ; i < messages_classes_count; i++ )
{
- regexp_ok = 0;
- for ( i = 0 ; i < messages_classes_count; i++ )
+ if (strcmp( messages_classes[i], message ) == 0)
{
- if (strncmp( messages_classes[i], exp, strlen( messages_classes[i] )) == 0)
- return 1;
- }
- }
+ return;
+ }
}
- return regexp_ok;
-} \ No newline at end of file
+ fprintf(stderr,"*** WARNING *** message '%s' not sent due to missing keyword in filter table!!!\n", message );
+}
diff --git a/src/ivybind.h b/src/ivybind.h
index 9846d3f..adfc340 100644
--- a/src/ivybind.h
+++ b/src/ivybind.h
@@ -1,7 +1,7 @@
/*
* Ivy, C interface
*
- * Copyright (C) 1997-2000
+ * Copyright (C) 1997-2006
* Centre d'Études de la Navigation Aérienne
*
* Bind syntax for extracting message comtent
@@ -14,18 +14,22 @@
* Please refer to file version.h for the
* copyright notice regarding this software
*/
-#include "ivyargument.h"
-
/* Module de gestion de la syntaxe des messages Ivy */
typedef struct _binding *IvyBinding;
-typedef enum { IvyBindRegexp, IvyBindSimple } IvyBindingType;
-void IvyBindingParseMessage( const char *msg );
+/* Mise en place des Filtrages */
+int IvyBindingGetFilterCount();
void IvyBindingSetFilter( int argc, const char ** argv );
-int IvyBindingFilter( IvyBindingType typ, int len, const char *exp );
-IvyBinding IvyBindingCompile( IvyBindingType typ, const char * expression );
-void IvyBindingGetCompileError( int *erroffset, const char **errmessage );
+int IvyBindingFilter( const char *expression );
+void IvyBindindFilterCheck( const char *message );
+
+/* Creation, Compilation */
+IvyBinding IvyBindingCompile( const char *expression, int *erroffset, const char **errmessage );
void IvyBindingFree( IvyBinding bind );
+
+/* Execution , extraction */
int IvyBindingExec( IvyBinding bind, const char * message );
-IvyArgument IvyBindingMatch( IvyBinding bind, const char *message );
+/* Get Argument */
+void IvyBindingMatch( IvyBinding bind, const char *message, int argnum, int *arglen, const char **arg );
+
diff --git a/src/ivybuffer.c b/src/ivybuffer.c
new file mode 100644
index 0000000..0d85d98
--- /dev/null
+++ b/src/ivybuffer.c
@@ -0,0 +1,82 @@
+/*
+ * Ivy, C interface
+ *
+ * Copyright 1997-2000
+ * Centre d'Etudes de la Navigation Aerienne
+ *
+ * Sockets
+ *
+ * Authors: Francois-Regis Colin <fcolin@cena.fr>
+ *
+ * $Id$
+ *
+ * Please refer to file version.h for the
+ * copyright notice regarding this software
+ */
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "ivybuffer.h"
+
+#define BUFFER_SIZE 4096 /* taille buffer initiale on multiple par deux a chaque realloc */
+
+// fonction de formtage a la printf d'un buffer avec reallocation dynamique
+int make_message(IvyBuffer* buffer, const char *fmt, va_list ap)
+{
+ /* Guess we need no more than BUFFER_INIT_SIZE bytes. */
+ int n;
+ if ( buffer->size == 0 || buffer->data == NULL )
+ {
+ buffer->size = BUFFER_SIZE;
+ buffer->offset = 0;
+ buffer->data = malloc (BUFFER_SIZE);
+ if ( buffer->data == NULL )
+ {
+ perror(" Ivy make message MALLOC error: " );
+ return -1;
+ }
+ }
+ while (1) {
+ /* Try to print in the allocated space. */
+#ifdef WIN32
+ n = _vsnprintf (buffer->data + buffer->offset, buffer->size - buffer->offset, fmt, ap);
+#else
+ n = vsnprintf (buffer->data + buffer->offset, buffer->size - buffer->offset, fmt, ap);
+#endif
+ /* If that worked, return the string size. */
+ if (n > -1 && n < buffer->size)
+ {
+ buffer->offset += n;
+ return n;
+ }
+ /* Else try again with more space. */
+ if (n > -1) /* glibc 2.1 */
+ buffer->size = n+1; /* precisely what is needed */
+ else /* glibc 2.0 */
+ buffer->size *= 2; /* twice the old size */
+ if ((buffer->data = realloc (buffer->data, buffer->size)) == NULL)
+ {
+ perror(" Ivy make message REALLOC error: " );
+ return -1;
+ }
+ }
+}
+int make_message_var(IvyBuffer* buffer, const char *fmt, ... )
+{
+ va_list ap;
+ int len;
+ va_start (ap, fmt );
+ len = make_message (buffer, fmt, ap );
+ va_end (ap );
+ return len;
+}
+
+
+
diff --git a/src/ivybuffer.h b/src/ivybuffer.h
new file mode 100644
index 0000000..86c5474
--- /dev/null
+++ b/src/ivybuffer.h
@@ -0,0 +1,39 @@
+/*
+ * Ivy, C interface
+ *
+ * Copyright 1997-2000
+ * Centre d'Etudes de la Navigation Aerienne
+ *
+ * Sockets
+ *
+ * Authors: Francois-Regis Colin <fcolin@cena.dgac.fr>
+ *
+ * $Id$
+ *
+ * Please refer to file version.h for the
+ * copyright notice regarding this software
+ */
+
+#ifndef IVYBUFFER_H
+#define IVYBUFFER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+typedef struct {
+ char * data;
+ int size;
+ int offset;
+ } IvyBuffer;
+/* utility fonction do make vsprintf without buffer limit */
+extern int make_message(IvyBuffer * buffer, const char *fmt, va_list ap);
+extern int make_message_var(IvyBuffer* buffer, const char *fmt, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/ivychannel.h b/src/ivychannel.h
index ff9974d..ce6ecd3 100644
--- a/src/ivychannel.h
+++ b/src/ivychannel.h
@@ -6,7 +6,7 @@
*
* Basic I/O handling
*
- * Authors: François-Régis Colin <fcolin@cena.fr>
+ * Authors: François-Régis Colin <fcolin@cena.dgac.fr>
*
* $Id$
*
@@ -25,33 +25,34 @@ extern "C" {
#ifdef WIN32
#include <windows.h>
-#define IVY_HANDLE SOCKET
+#define HANDLE SOCKET
#else
-#define IVY_HANDLE int
+#define HANDLE int
#endif
typedef struct _channel *Channel;
/* callback declenche par la gestion de boucle sur evenement exception sur le canal */
typedef void (*ChannelHandleDelete)( void *data );
/* callback declenche par la gestion de boucle sur donnees pretes sur le canal */
-typedef void (*ChannelHandleRead)( Channel channel, IVY_HANDLE fd, void *data);
+typedef void (*ChannelHandleRead)( Channel channel, HANDLE fd, void *data);
/* fonction appele par le bus pour initialisation */
extern void IvyChannelInit(void);
-/* fonction appele par le bus pour terminaison */
-extern void IvyChannelStop(void);
-
+
+extern void IvyChannelStop (void);
+
/* fonction appele par le bus pour mise en place des callback sur le canal */
extern Channel IvyChannelAdd(
- IVY_HANDLE fd,
+ HANDLE fd,
void *data,
ChannelHandleDelete handle_delete,
ChannelHandleRead handle_read
);
-/* fonction appele par le bus pour fermeture du canal */
+/* fonction appele par le bus pour suppression des callback sur le canal */
extern void IvyChannelRemove( Channel channel );
+
#ifdef __cplusplus
}
#endif
diff --git a/src/ivydebug.h b/src/ivydebug.h
new file mode 100644
index 0000000..ee73f0e
--- /dev/null
+++ b/src/ivydebug.h
@@ -0,0 +1,30 @@
+#ifndef IVY_DEBUG_H
+#define IVY_DEBUG_H
+
+#ifdef WIN32
+#ifdef DEBUG
+#define TRACE(format,...) \
+ fprintf (stderr, format , __VA_ARGS__ )
+
+#define TRACE_IF( cond, format, ...) \
+ if ( cond ) fprintf (stderr, format , __VA_ARGS__ )
+
+#else
+#define TRACE(format, ...) /**/
+#define TRACE_IF( cond, format, ...) /**/
+#endif
+#else
+#ifdef DEBUG
+#define TRACE(format, args...) \
+ fprintf (stderr, format , ## args)
+
+#define TRACE_IF( cond, format, args...) \
+ if ( cond ) fprintf (stderr, format , ## args)
+
+#else
+#define TRACE(format, args...) /**/
+#define TRACE_IF( cond, format, args...) /**/
+#endif
+#endif
+
+#endif
diff --git a/src/ivyglibloop.c b/src/ivyglibloop.c
index e1944dd..c4976b1 100644
--- a/src/ivyglibloop.c
+++ b/src/ivyglibloop.c
@@ -26,7 +26,8 @@
#endif
#include <glib.h>
-
+#include "ivydebug.h"
+#include "ivychannel.h"
#include "ivyglibloop.h"
struct _channel {
@@ -58,13 +59,9 @@ void IvyChannelInit(void) {
channel_initialized = 1;
}
-void IvyChannelStop( )
-{
- channel_initialized = 0;
-}
-Channel IvyChannelAdd(IVY_HANDLE fd, void *data,
+Channel IvyChannelAdd(HANDLE fd, void *data,
ChannelHandleDelete handle_delete,
ChannelHandleRead handle_read
) {
@@ -95,14 +92,13 @@ void IvyChannelRemove( Channel channel ) {
g_source_remove( channel->id_read );
g_source_remove( channel->id_delete );
}
+
static gboolean IvyGlibHandleChannelRead(GIOChannel *source,
GIOCondition condition,
gpointer data) {
Channel channel = (Channel)data;
-#ifdef DEBUG
- printf("Handle Channel read %d\n",source );
-#endif
+ TRACE("Handle Channel read %d\n",source );
(*channel->handle_read)(channel, g_io_channel_unix_get_fd(source), channel->data);
return TRUE;
}
@@ -111,15 +107,15 @@ static gboolean IvyGlibHandleChannelDelete(GIOChannel *source,
GIOCondition condition,
gpointer data) {
Channel channel = (Channel)data;
-#ifdef DEBUG
- printf("Handle Channel delete %d\n",source );
-#endif
+ TRACE("Handle Channel delete %d\n",source );
(*channel->handle_delete)(channel->data);
return TRUE;
}
-void IvyMainLoop(void(*hook)(void))
+
+void
+IvyChannelStop ()
{
- GMainLoop *ml = g_main_loop_new(NULL, FALSE);
- g_main_loop_run(ml);
+ /* To be implemented */
}
+
diff --git a/src/ivyglibloop.h b/src/ivyglibloop.h
index f5026aa..e06a923 100644
--- a/src/ivyglibloop.h
+++ b/src/ivyglibloop.h
@@ -21,8 +21,7 @@
extern "C" {
#endif
-#include "ivychannel.h"
-
+/* Nothnig special */
#ifdef __cplusplus
}
#endif
diff --git a/src/ivyglutloop.c b/src/ivyglutloop.c
index 3dea326..b383d8f 100755
--- a/src/ivyglutloop.c
+++ b/src/ivyglutloop.c
@@ -6,8 +6,8 @@
*
* Main loop based on GLUT ( OpenGL ) Toolkit
*
- * Authors: François-Régis Colin <colin@cena.fr>
- * Stéphane Chatty <chatty@cena.fr>
+ * Authors: François-Régis Colin <colin@cenatoulouse.dgac.fr>
+ * Stéphane Chatty <chatty@cenatoulouse.dgac.fr>
*
* $Id$
*
@@ -39,6 +39,7 @@
#include <GL/glut.h>
+#include "ivydebug.h"
#include "ivychannel.h"
#include "ivyglutloop.h"
@@ -53,8 +54,6 @@ struct _channel {
static int channel_initialized = 0;
-
-
void IvyChannelInit(void)
{
@@ -66,10 +65,7 @@ void IvyChannelInit(void)
#endif
channel_initialized = 1;
}
-void IvyChannelStop(void)
-{
- channel_initialized = 0;
-}
+
void IvyChannelRemove( Channel channel )
{
@@ -83,22 +79,18 @@ void IvyChannelRemove( Channel channel )
static void IvyGlutHandleChannelRead( int source, GLUTInputId id, void *data )
{
Channel channel = (Channel)data;
-#ifdef DEBUG
- printf("Handle Channel read %d\n",source );
-#endif
+ TRACE("Handle Channel read %d\n",source );
(*channel->handle_read)(channel,source,channel->data);
}
static void IvyGlutHandleChannelDelete( int source, GLUTInputId id, void *data )
{
Channel channel = (Channel)data;
-#ifdef DEBUG
- printf("Handle Channel delete %d\n",source );
-#endif
+ TRACE("Handle Channel delete %d\n",source );
(*channel->handle_delete)(channel->data);
}
-Channel IvyChannelAdd(IVY_HANDLE fd, void *data,
+Channel IvyChannelAdd(HANDLE fd, void *data,
ChannelHandleDelete handle_delete,
ChannelHandleRead handle_read
)
@@ -122,8 +114,10 @@ Channel IvyChannelAdd(IVY_HANDLE fd, void *data,
return channel;
}
-extern void IvyMainLoop(void(*hook)(void))
+
+void
+IvyChannelStop ()
{
- glutMainLoop();
+ /* To be implemented */
}
diff --git a/src/ivyglutloop.h b/src/ivyglutloop.h
index 53437d6..9374390 100755
--- a/src/ivyglutloop.h
+++ b/src/ivyglutloop.h
@@ -6,8 +6,8 @@
*
* Main loop based on GLUT ( OpenGL ) Toolkit
*
- * Authors: François-Régis Colin <colin@cena.fr>
- * Stéphane Chatty <chatty@cena.fr>
+ * Authors: François-Régis Colin <colin@cenatoulouse.dgac.fr>
+ * Stéphane Chatty <chatty@cenatoulouse.dgac.fr>
*
* $Id$
*
@@ -24,8 +24,8 @@ extern "C" {
#include <GL/Glut.h>
+/* general Handle */
-#include "ivychannel.h"
#ifdef __cplusplus
}
diff --git a/src/ivyloop.c b/src/ivyloop.c
index ab50f75..3d1008c 100644
--- a/src/ivyloop.c
+++ b/src/ivyloop.c
@@ -6,8 +6,8 @@
*
* Main loop based on select
*
- * Authors: François-Régis Colin <fcolin@cena.fr>
- * Stéphane Chatty <chatty@cena.fr>
+ * Authors: François-Régis Colin <fcolin@cena.dgac.fr>
+ * Stéphane Chatty <chatty@cena.dgac.fr>
*
* $Id$
*
@@ -15,17 +15,16 @@
* copyright notice regarding this software
*/
-
+#ifdef WIN32
+#include <windows.h>
+#endif
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
-#ifdef WIN32
-#include <crtdbg.h>
-#include <windows.h>
-#else
+#ifndef WIN32
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
@@ -43,14 +42,13 @@
struct _channel {
Channel next;
- IVY_HANDLE fd;
+ HANDLE fd;
void *data;
int tobedeleted;
ChannelHandleDelete handle_delete;
ChannelHandleRead handle_read;
};
-
static Channel channels_list = NULL;
static int channel_initialized = 0;
@@ -58,6 +56,13 @@ static int channel_initialized = 0;
static fd_set open_fds;
static int MainLoop = 1;
+/* Hook callback & data */
+static IvyHookPtr BeforeSelect = NULL;
+static IvyHookPtr AfterSelect = NULL;
+
+static void *BeforeSelectData = NULL;
+static void *AfterSelectData = NULL;
+
#ifdef WIN32
WSADATA WsaData;
#endif
@@ -89,24 +94,21 @@ ChannelDefferedDelete ()
}
}
-Channel IvyChannelAdd (IVY_HANDLE fd, void *data,
+Channel IvyChannelAdd (HANDLE fd, void *data,
ChannelHandleDelete handle_delete,
ChannelHandleRead handle_read
)
{
Channel channel;
- IVY_LIST_ADD (channels_list, channel);
- if (!channel) {
- fprintf(stderr,"NOK Memory Alloc Error\n");
- exit(0);
- }
+ IVY_LIST_ADD_START (channels_list, channel)
channel->fd = fd;
channel->tobedeleted = 0;
channel->handle_delete = handle_delete;
channel->handle_read = handle_read;
channel->data = data;
-
+ IVY_LIST_ADD_END (channels_list, channel)
+
FD_SET (channel->fd, &open_fds);
return channel;
@@ -132,7 +134,7 @@ IvyChannelHandleExcpt (fd_set *current)
if (FD_ISSET (channel->fd, current)) {
if (channel->handle_delete)
(*channel->handle_delete)(channel->data);
-/* IvyChannelRemove (channel); */
+/* IvyChannelClose (channel); */
}
}
}
@@ -161,10 +163,9 @@ void IvyChannelInit (void)
void IvyChannelStop (void)
{
MainLoop = 0;
- ChannelDefferedDelete(); /* this will force select to exit on multithread */
}
-void IvyMainLoop(void(*hook)(void))
+void IvyMainLoop(void)
{
fd_set rdset;
@@ -172,23 +173,29 @@ void IvyMainLoop(void(*hook)(void))
int ready;
while (MainLoop) {
+
ChannelDefferedDelete();
- if (hook) (*hook)();
+
+ if (BeforeSelect)
+ (*BeforeSelect)(BeforeSelectData);
rdset = open_fds;
exset = open_fds;
ready = select(64, &rdset, 0, &exset, TimerGetSmallestTimeout());
+
+ if (AfterSelect)
+ (*AfterSelect)(AfterSelectData);
+
if (ready < 0 && (errno != EINTR)) {
fprintf (stderr, "select error %d\n",errno);
perror("select");
return;
}
- TimerScan();
- if ( MainLoop && ready > 0) {
+ TimerScan(); /* should be spliited in two part ( next timeout & callbacks */
+ if (ready > 0) {
IvyChannelHandleExcpt(&exset);
IvyChannelHandleRead(&rdset);
- continue;
}
- }
+ }
}
void IvyIdle()
@@ -216,3 +223,14 @@ void IvyIdle()
}
+
+void IvySetBeforeSelectHook(IvyHookPtr before, void *data )
+{
+ BeforeSelect = before;
+ BeforeSelectData = data;
+}
+void IvySetAfterSelectHook(IvyHookPtr after, void *data )
+{
+ AfterSelect = after;
+ AfterSelectData = data;
+}
diff --git a/src/ivyloop.h b/src/ivyloop.h
index 1d0b623..f272212 100644
--- a/src/ivyloop.h
+++ b/src/ivyloop.h
@@ -6,8 +6,8 @@
*
* Main loop handling around select
*
- * Authors: François-Régis Colin <fcolin@cena.fr>
- * Stéphane Chatty <chatty@cena.fr>
+ * Authors: François-Régis Colin <fcolin@cena.dgac.fr>
+ * Stéphane Chatty <chatty@cena.dgac.fr>
*
* $Id$
*
@@ -25,10 +25,39 @@ extern "C" {
#include "ivychannel.h"
+/* general Handle */
-extern void IvyMainLoop(void(*hook)(void) );
-extern void IvyIdle();
+#define ANYPORT 0
+#ifdef WIN32
+#include <windows.h>
+#define HANDLE SOCKET
+#else
+#define HANDLE int
+#endif
+
+/*
+Boucle principale d'IVY baseé sur un select
+les fonctions hook et unhook encradre le select
+de la maniere suivante:
+
+ BeforeSelect est appeler avant l'appel system select
+ AfterSelect est appeler avent l'appel system select
+ ces function peuvent utilisées pour depose un verrou dans le cas
+ d'utilisation de la mainloop Ivy dans une thread separe
+
+ BeforeSelect ==> on libere l'acces avant la mise en attente sur le select
+ AfterSelect == > on verrouille l'acces en sortie du select
+
+ !!!! Attention donc l'appel des callbacks ivy se fait avec l'acces verrouille !
+*/
+
+extern void IvyMainLoop(void);
+
+typedef void ( *IvyHookPtr) ( void *data );
+
+extern void IvySetBeforeSelectHook(IvyHookPtr before, void *data );
+extern void IvySetAfterSelectHook(IvyHookPtr after, void *data );
#ifdef __cplusplus
}
diff --git a/src/ivyperf.c b/src/ivyperf.c
index f8e9250..07453e3 100755
--- a/src/ivyperf.c
+++ b/src/ivyperf.c
@@ -39,6 +39,9 @@ extern int optind;
#include "ivyloop.h"
#define MILLISEC 1000.0
+const char *mymessages[] = { "IvyPerf", "ping", "pong" };
+static double origin = 0;
+
static double currentTime()
{
double current;
@@ -52,64 +55,62 @@ static double currentTime()
return current;
}
-void Reply (IvyClientPtr app, void *user_data, IvyArgument args)
+void Reply (IvyClientPtr app, void *user_data, int argc, char *argv[])
{
- IvyArgument arg;
- int len;
- const void* val;
- arg = IvyArgumentGetChildrens( args );
- IvyArgumentGetValue( arg , &len, &val);
- IvySendMsg ("pong ts=%.*s tr=%f", len, (char*)val, currentTime());
+ IvySendMsg ("pong ts=%s tr=%f", *argv, currentTime()- origin);
}
-void Pong (IvyClientPtr app, void *user_data, IvyArgument args)
+void Pong (IvyClientPtr app, void *user_data, int argc, char *argv[])
{
- double current, ts, tr, roundtrip1, roundtrip2, roundtrip3;
- IvyArgument arg;
- int len;
- const void* val;
- /* TODO bug atof non limite a la longeur de la valeur !!!*/
-
- current = currentTime();
- arg = IvyArgumentGetChildrens( args );
- IvyArgumentGetValue( arg , &len, &val);
- ts = atof( (char*)val );
- arg = IvyArgumentGetNextChild( arg );
- IvyArgumentGetValue( arg , &len, &val);
- tr = atof( (char*)val );
- roundtrip1 = tr-ts;
- roundtrip2 = current - tr;
- roundtrip3 = current - ts;
+ double current = currentTime() - origin ;
+ double ts = atof( *argv++ );
+ double tr = atof( *argv++ );
+ double roundtrip1 = tr-ts;
+ double roundtrip2 = current - tr;
+ double roundtrip3 = current - ts;
fprintf(stderr,"roundtrip %f %f %f \n", roundtrip1, roundtrip2, roundtrip3 );
}
void TimerCall(TimerId id, void *user_data, unsigned long delta)
{
- int count = IvySendMsg ("ping ts=%f", currentTime() );
+ int count = IvySendMsg ("ping ts=%f", currentTime() - origin );
if ( count == 0 ) fprintf(stderr, "." );
}
+void binCB( IvyClientPtr app, void *user_data, int id, char* regexp, IvyBindEvent event )
+{
+ char *app_name = IvyGetApplicationName( app );
+ switch ( event )
+ {
+ case IvyAddBind:
+ printf("Application:%s bind '%s' ADDED\n", app_name, regexp );
+ break;
+ case IvyRemoveBind:
+ printf("Application:%s bind '%s' REMOVED\n", app_name, regexp );
+ break;
+ case IvyFilterBind:
+ printf("Application:%s bind '%s' FILTRED\n", app_name, regexp );
+ break;
+ }
+}
int main(int argc, char *argv[])
{
-
+ long time=200;
/* Mainloop management */
+ if ( argc > 1 ) time = atol( argv[1] );
IvyInit ("IvyPerf", "IvyPerf ready", NULL,NULL,NULL,NULL);
-
-#ifdef USE_REGEXP
+ IvySetFilter( sizeof( mymessages )/ sizeof( char *),mymessages );
+ IvySetBindCallback( binCB, 0 ),
IvyBindMsg (Reply, NULL, "^ping ts=(.*)");
IvyBindMsg (Pong, NULL, "^pong ts=(.*) tr=(.*)");
-#else
- IvyBindSimpleMsg (Reply, NULL, "ping ts");
- IvyBindSimpleMsg (Pong, NULL, "pong ts tr");
-#endif
-
+ origin = currentTime();
IvyStart (0);
- TimerRepeatAfter (TIMER_LOOP, 200, TimerCall, (void*)1);
+ TimerRepeatAfter (TIMER_LOOP, time, TimerCall, (void*)1);
- IvyMainLoop (0);
+ IvyMainLoop ();
return 0;
}
diff --git a/src/ivyprobe.c b/src/ivyprobe.c
index dc134a0..b6d9607 100644
--- a/src/ivyprobe.c
+++ b/src/ivyprobe.c
@@ -34,109 +34,96 @@
#include <string.h>
#ifdef WIN32
#include <windows.h>
+#include "getopt.h"
#ifdef __MINGW32__
+#include <regex.h>
#include <getopt.h>
+#endif
#else
-#include "getopt.h"
-#endif // __MINGW32__
-#else // WIN32
#include <sys/time.h>
#include <unistd.h>
#ifdef __INTERIX
extern char *optarg;
extern int optind;
-#endif // __INTERIX
-#endif // WIN32
-
-#ifdef USE_PCRE_REGEX
-#define OVECSIZE 60 /* must be multiple of 3, for regexp return */
-#include <pcre.h>
-#else
-#include <regex.h>
#endif
-#include "ivychannel.h"
+#endif
+#ifdef XTMAINLOOP
+#include "ivyxtloop.h"
+#endif
+#ifdef GLIBMAINLOOP
+#include <glib.h>
+#include "ivyglibloop.h"
+#endif
+#ifdef GLUTMAINLOOP
+#include "ivyglutloop.h"
+#endif
+#ifdef IVYMAINLOOP
+#include "ivyloop.h"
+#endif
#include "ivysocket.h"
+#include "ivychannel.h"
+#include "ivybind.h" /* to test regexp before passing to BinMsg */
#include "ivy.h"
#include "timer.h"
#ifdef XTMAINLOOP
-#include "ivyxtloop.h"
#include <X11/Intrinsic.h>
XtAppContext cntx;
-
#endif
int app_count = 0;
int wait_count = 0;
int fbindcallback = 0;
+int filter_count = 0;
+const char *filter[4096];
+char *classes;
-void DirectCallback(IvyClientPtr app, void *user_data, int id, int len, void *msg )
+void DirectCallback(IvyClientPtr app, void *user_data, int id, char *msg )
{
- printf("%s sent a direct message, id=%d, message=%.*s\n",
- IvyGetApplicationName(app),id,len,(char*)msg);
+ printf("%s sent a direct message, id=%d, message=%s\n",
+ IvyGetApplicationName(app),id,msg);
}
-void BindCallback(IvyClientPtr app, void *user_data, IvyBindEvent event, char *regexp )
-{
- char *sevent;
- sevent= event==IvyAddBind ? "added" :"removed";
-
- printf("%s has modified his binding, regexp=%s is %s\n",
- IvyGetApplicationName(app),regexp,sevent);
-}
-void Callback (IvyClientPtr app, void *user_data, IvyArgument args)
+void Callback (IvyClientPtr app, void *user_data, int argc, char *argv[])
{
- IvyArgument arg;
- int len;
- const void* value;
- printf ("%s sent:",IvyGetApplicationName(app));
- arg = IvyArgumentGetChildrens ( args ) ;
- while( arg )
- {
- IvyArgumentGetValue( arg, &len, &value );
- printf(" '%.*s'",len, (char*)value );
- arg = IvyArgumentGetNextChild( arg );
- }
+ int i;
+ printf ("%s sent ",IvyGetApplicationName(app));
+ for (i = 0; i < argc; i++)
+ printf(" '%s'",argv[i]);
printf("\n");
}
char * Chop(char *arg)
{
- int len;
+ size_t len;
if (arg==NULL) return arg;
len=strlen(arg)-1;
if ((*(arg+len))=='\n') *(arg+len)=0;
return arg;
}
-void HandleStdin (Channel channel, IVY_HANDLE fd, void *data)
-
+void HandleStdin (Channel channel, HANDLE fd, void *data)
{
char buf[4096];
char *line;
char *cmd;
char *arg;
- char *choparg;
- char **applist;
int id;
IvyClientPtr app;
int err;
line = fgets(buf, 4096, stdin);
if (!line) {
-#ifdef WIN32
-#else
+
IvyChannelRemove (channel);
-#endif
IvyStop();
return;
-
}
if (*line == '.') {
cmd = strtok (line, ".: \n");
if (strcmp (cmd, "die") == 0) {
- arg = strtok (NULL, "\n"); /* no space separator appname can containt space*/
+ arg = strtok (NULL, " \n");
if (arg) {
app = IvyGetApplication (arg);
if (app)
@@ -145,50 +132,34 @@ void HandleStdin (Channel channel, IVY_HANDLE fd, void *data)
}
} else if (strcmp(cmd, "dieall-yes-i-am-sure") == 0) {
- applist = IvyGetApplicationList();
- while (*applist) {
- app = IvyGetApplication (*applist);
+ arg = IvyGetApplicationList("#");
+ arg = strtok (arg, "#");
+ while (arg) {
+ app = IvyGetApplication (arg);
if (app)
IvySendDieMsg (app);
else
- printf ("No Application %s!!!\n",*applist);
- applist++;
+ printf ("No Application %s!!!\n",arg);
+ arg = strtok (NULL, " ");
}
} else if (strcmp(cmd, "bind") == 0) {
arg = strtok (NULL, "'");
+ Chop(arg);
if (arg) {
-#ifdef USE_PCRE_REGEX
- pcre *regexp;
+ IvyBinding bind;
const char *errbuf;
int erroffset;
- Chop(arg);
- regexp = pcre_compile(arg, 0,&errbuf,&erroffset,NULL);
- if (regexp==NULL) {
- printf("Error compiling '%s', %s, not bound\n", arg, errbuf);
-#else
- regex_t reg;
- int err;
- Chop(arg);
- if (err=regcomp(&reg,arg,REG_ICASE|REG_EXTENDED)!=0) {
- char errbuf[4096];
- regerror (err, &reg, errbuf, 4096);
- printf("Error compiling '%s', %s, not bound\n", arg, errbuf);
-
-#endif
+ bind = IvyBindingCompile(arg, & erroffset, & errbuf);
+ if (bind==NULL) {
+ printf("Error compiling '%s', %s, not bound\n", arg, errbuf);
} else {
- IvyBindMsg (Callback, NULL, Chop(arg));
+ IvyBindingFree( bind );
+ IvyBindMsg (Callback, NULL, arg);
}
}
- }
- else if (strcmp(cmd, "bindsimple") == 0) {
- arg = strtok (NULL, "'");
- if (arg) {
- IvyBindSimpleMsg (Callback, NULL, Chop(arg));
- }
- }
- else if (strcmp(cmd, "where") == 0) {
+ } else if (strcmp(cmd, "where") == 0) {
arg = strtok (NULL, " \n");
if (arg) {
app = IvyGetApplication (arg);
@@ -199,103 +170,54 @@ void HandleStdin (Channel channel, IVY_HANDLE fd, void *data)
} else if (strcmp(cmd, "direct") == 0) {
arg = strtok (NULL, " \n");
if (arg) {
- choparg = Chop(arg);
app = IvyGetApplication (arg);
if (app) {
arg = strtok (NULL, " ");
id = atoi (arg) ;
arg = strtok (NULL, "'");
- IvySendDirectMsg (app, id, strlen(choparg), choparg);
+ IvySendDirectMsg (app, id, Chop(arg));
} else
printf ("No Application %s!!!\n",arg);
}
} else if (strcmp(cmd, "who") == 0) {
- applist = IvyGetApplicationList();
- while (*applist) {
- printf ("Application '%s'\n",*applist);
- applist++;
- }
+ printf("Apps: %s\n", IvyGetApplicationList(","));
} else if (strcmp(cmd, "help") == 0) {
fprintf(stderr,"Commands list:\n");
- printf(" .help - this help\n");
- printf(" .quit - terminate this application\n");
- printf(" .die appname - send die msg to appname\n");
- printf(" .dieall-yes-i-am-sure - send die msg to all applis\n");
- printf(" .direct appname id 'arg' - send direct msg to appname\n");
- printf(" .where appname - on which host is appname\n");
- printf(" .bind 'regexp' - add a msg to receive using regexp\n");
- printf(" .bindsimple 'expr' - add a msg to receive using simple msg format tag param param\n");
- printf(" .bindcall - toogle callback to binding\n");
- printf(" .who - who is on the bus\n");
- } else if (strcmp(cmd, "bindcall") == 0) {
+ printf(" .help - this help\n");
+ printf(" .quit - terminate this application\n");
+ printf(" .die appname - send die msg to appname\n");
+ printf(" .dieall-yes-i-am-sure - send die msg to all applis\n");
+ printf(" .direct appname id 'arg' - send direct msg to appname\n");
+ printf(" .where appname - on which host is appname\n");
+ printf(" .bind 'regexp' - add a msg to receive\n");
+ printf(" .showbind - show bindings \n");
+
+ printf(" .who - who is on the bus\n");
+ } else if (strcmp(cmd, "showbind") == 0) {
if (!fbindcallback) {
- IvySetBindCallback(BindCallback, NULL);
+ IvySetBindCallback(IvyDefaultBindCallback, NULL);
fbindcallback=1;
} else {
- IvySetBindCallback(NULL, NULL);
+ IvySetBindCallback(NULL, NULL);
fbindcallback=0;
}
} else if (strcmp(cmd, "quit") == 0) {
- IvyStop(); /* this wil exit MainLoop */
- //exit(0);
-#ifdef WIN32
- ExitThread( 0 ); /* exit STDin handle thread */
-#endif
+ exit(0);
}
} else {
cmd = strtok (buf, "\n");
- if ( cmd )
- {
err = IvySendMsg (cmd);
printf("-> Sent to %d peer%s\n", err, err == 1 ? "" : "s");
- }
}
}
-#ifdef WIN32
-DWORD WINAPI HandleStdinThread( LPVOID lpParam )
-{
- while( 1 )
- HandleStdin( 0,0,0);
-}
-void CreateStdinThread()
-{
- DWORD dwThreadId, dwThrdParam = 1;
- HANDLE hThread;
-
- hThread = CreateThread(
- NULL, // default security attributes
- 0, // use default stack size
- HandleStdinThread, // thread function
- &dwThrdParam, // argument to thread function
- 0, // use default creation flags
- &dwThreadId); // returns the thread identifier
-
- // Check the return value for success.
-
- if (hThread == NULL)
- {
- printf( "CreateThread failed (%d)\n", GetLastError() );
- }
-}
-#endif
-void StartHandleStdin()
-{
-#ifdef WIN32
- /* Stdin not compatible with select , select only accept socket */
- /* use Thread to Read StdIn */
- CreateStdinThread();
-#else
- IvyChannelAdd (0, NULL, NULL, HandleStdin);
-#endif
-}
void ApplicationCallback (IvyClientPtr app, void *user_data, IvyApplicationEvent event)
{
char *appname;
char *host;
- char **msgList;
+/* char **msgList;*/
appname = IvyGetApplicationName (app);
host = IvyGetApplicationHost (app);
switch (event) {
@@ -304,12 +226,17 @@ void ApplicationCallback (IvyClientPtr app, void *user_data, IvyApplicationEvent
app_count++;
printf("%s connected from %s\n", appname, host);
/* printf("Application(%s): Begin Messages\n", appname);*/
+/* double usage with -s flag remove it
msgList = IvyGetApplicationMessages (app);
while (*msgList )
printf("%s subscribes to '%s'\n",appname,*msgList++);
+*/
/* printf("Application(%s): End Messages\n",appname);*/
+#ifndef WIN32
+/* Stdin not compatible with select , select only accept socket */
if (app_count == wait_count)
- StartHandleStdin();
+ IvyChannelAdd (0, NULL, NULL, HandleStdin);
+#endif
break;
case IvyApplicationDisconnected:
@@ -322,13 +249,40 @@ void ApplicationCallback (IvyClientPtr app, void *user_data, IvyApplicationEvent
break;
}
}
+void IvyPrintBindCallback( IvyClientPtr app, void *user_data, int id, char* regexp, IvyBindEvent event)
+{
+ switch ( event ) {
+ case IvyAddBind:
+ if ( fbindcallback )
+ printf("Application: %s on %s add regexp %d : %s\n",
+ IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp);
+ break;
+ case IvyRemoveBind:
+ if ( fbindcallback )
+ printf("Application: %s on %s remove regexp %d :%s\n",
+ IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp);
+ break;
+ case IvyFilterBind:
+ printf("Application: %s on %s as been filtred regexp %d :%s\n",
+ IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp);
+ break;
+ case IvyChangeBind:
+ if ( fbindcallback )
+ printf("Application: %s on %s change regexp %d : %s\n",
+ IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp);
+ break;
+ default:
+ printf("Application: %s unkown event %d\n",IvyGetApplicationName( app ), event);
+ break;
+ }
+}
-#ifndef XTMAINLOOP
+#ifdef IVYMAINLOOP
void TimerCall(TimerId id, void *user_data, unsigned long delta)
{
- printf("Timer callback: %d delta %lu ms\n", (int)user_data, delta);
- IvySendMsg ("TEST TIMER %d", (int)user_data);
+ printf("Timer callback: %ld delta %lu ms\n", (long)user_data, delta);
+ IvySendMsg ("TEST TIMER %d", (long)user_data);
/*if ((int)user_data == 5) TimerModify (id, 2000);*/
}
#endif
@@ -341,18 +295,62 @@ display(void)
}
#endif
+void BindMsgOfFile( const char * regex_file )
+{
+ char line[4096];
+ size_t size;
+ FILE* file;
+ file = fopen( regex_file, "r" );
+ if ( !file ) {
+ perror( "Regexp file open ");
+ return;
+ }
+ while( !feof( file ) )
+ {
+ if ( fgets( line, sizeof(line), file ) )
+ {
+ size = strlen(line);
+ if ( size > 1 )
+ {
+ line[size-1] = '\0'; /* supress \n */
+ IvyBindMsg (Callback, NULL, line);
+ }
+ }
+ }
+}
+void BuildFilterRegexp()
+{
+ char *word=strtok( classes, "," );
+ while ( word != NULL && (filter_count < 4096 ))
+ {
+ filter[filter_count++] = word;
+ word = strtok( NULL, ",");
+ }
+ if ( filter_count )
+ IvySetFilter( filter_count, filter );
+}
int main(int argc, char *argv[])
{
int c;
int timer_test = 0;
char busbuf [1024] = "";
const char* bus = 0;
+ const char* regex_file = 0;
char agentnamebuf [1024] = "";
const char* agentname = DEFAULT_IVYPROBE_NAME;
char agentready [1024] = "";
const char* helpmsg =
- "[options] [regexps]\n\t-b bus\tdefines the Ivy bus to which to connect to, defaults to 127:2010\n\t-t\ttriggers the timer test\n\t-n name\tchanges the name of the agent, defaults to IVYPROBE\n\t-v\tprints the ivy relase number\n\nregexp is a Perl5 compatible regular expression (see ivyprobe(1) and pcrepattern(3) for more info\nuse .help within ivyprobe\n\t-s bindcall\tactive the interception of regexp's subscribing or unscribing\n";
- while ((c = getopt(argc, argv, "vn:d:b:w:t:s")) != EOF)
+ "[options] [regexps]\n\t-b bus\tdefines the Ivy bus to which to connect to, defaults to 127:2010\n"
+ "\t-t\ttriggers the timer test\n"
+ "\t-n name\tchanges the name of the agent, defaults to IVYPROBE\n"
+ "\t-v\tprints the ivy relase number\n\n"
+ "regexp is a Perl5 compatible regular expression (see ivyprobe(1) and pcrepattern(3) for more info\n"
+ "use .help within ivyprobe\n"
+ "\t-s bindcall\tactive the interception of regexp's subscribing or unscribing\n"
+ "\t-f regexfile\tread list of regexp's from file one by line\n"
+ "\t-c msg1,msg2,msg3,...\tfilter the regexp's not beginning with words\n"
+ ;
+ while ((c = getopt(argc, argv, "vn:d:b:w:t:sf:c:")) != EOF)
switch (c) {
case 'b':
strcpy (busbuf, optarg);
@@ -361,6 +359,9 @@ int main(int argc, char *argv[])
case 'w':
wait_count = atoi(optarg) ;
break;
+ case 'f':
+ regex_file = optarg ;
+ break;
case 'n':
strcpy(agentnamebuf, optarg);
agentname=agentnamebuf;
@@ -371,9 +372,11 @@ int main(int argc, char *argv[])
timer_test = 1;
break;
case 's':
- IvySetBindCallback(BindCallback, NULL);
fbindcallback=1;
break;
+ case 'c':
+ classes= strdup(optarg);
+ break;
default:
printf("usage: %s %s",argv[0],helpmsg);
exit(1);
@@ -393,13 +396,21 @@ int main(int argc, char *argv[])
glutDisplayFunc(display);
#endif
IvyInit (agentname, agentready, ApplicationCallback,NULL,NULL,NULL);
- IvySetApplicationPriority( 0 ); /* lower priority */
+ IvySetBindCallback(IvyPrintBindCallback, NULL);
+
IvyBindDirectMsg( DirectCallback,NULL);
+ if ( classes )
+ BuildFilterRegexp();
+ if ( regex_file )
+ BindMsgOfFile( regex_file );
for (; optind < argc; optind++)
IvyBindMsg (Callback, NULL, argv[optind]);
if (wait_count == 0)
- StartHandleStdin();
+#ifndef WIN32
+/* Stdin not compatible with select , select only accept socket */
+ IvyChannelAdd (0, NULL, NULL, HandleStdin);
+#endif
IvyStart (bus);
@@ -413,11 +424,19 @@ int main(int argc, char *argv[])
#ifdef XTMAINLOOP
XtAppMainLoop (cntx);
#endif
+#ifdef GLIBMAINLOOP
+ {
+ GMainLoop *ml = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(ml);
+ }
+#endif
+#ifdef GLUTMAINLOOP
+ glutMainLoop();
+#endif
- IvyMainLoop (0);
- #ifdef _CRTDBG_MAP_ALLOC
- _CrtDumpMemoryLeaks();
- #endif
-
+#ifdef IVYMAINLOOP
+ IvyMainLoop ();
+#endif
return 0;
}
+
diff --git a/src/ivysocket.c b/src/ivysocket.c
index 9ff66a0..b31ab4a 100644
--- a/src/ivysocket.c
+++ b/src/ivysocket.c
@@ -14,15 +14,16 @@
* copyright notice regarding this software
*/
-
+#ifdef WIN32
+#include <windows.h>
+#endif
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
+
#ifdef WIN32
-#include <crtdbg.h>
-#include <windows.h>
#define close closesocket
/*#define perror (a ) printf(a" error=%d\n",WSAGetLastError());*/
#else
@@ -39,46 +40,54 @@
#include "list.h"
#include "ivychannel.h"
#include "ivysocket.h"
+#include "ivyloop.h"
+#include "ivybuffer.h"
+#include "ivydebug.h"
#define BUFFER_SIZE 4096 /* taille buffer initiale on multiple pas deux a chaque realloc */
struct _server {
Server next;
- IVY_HANDLE fd;
+ HANDLE fd;
Channel channel;
unsigned short port;
- SocketCreate create;
- SocketDelete handle_delete;
+ void *(*create)(Client client);
+ void (*handle_delete)(Client client, void *data);
SocketInterpretation interpretation;
};
struct _client {
Client next;
- IVY_HANDLE fd;
+ HANDLE fd;
Channel channel;
unsigned short port;
struct sockaddr_in from;
SocketInterpretation interpretation;
- SocketDelete handle_delete;
- /* input buffer */
- int in_buffer_size;
- char *in_buffer; /* dynamicaly reallocated */
- char *in_ptr;
- /* output buffer */
- int out_buffer_size;
- char *out_buffer; /* dynamicaly reallocated */
- char *out_ptr;
-
+ void (*handle_delete)(Client client, void *data);
+ char terminator; /* character delimiter of the message */
+ /* Buffer de reception */
+ long buffer_size;
+ char *buffer; /* dynamicaly reallocated */
+ char *ptr;
+ /* user data */
void *data;
};
static Server servers_list = NULL;
static Client clients_list = NULL;
+static int debug_send = 0;
+
#ifdef WIN32
WSADATA WsaData;
#endif
+void SocketInit()
+{
+ if ( getenv( "IVY_DEBUG_SEND" )) debug_send = 1;
+ IvyChannelInit();
+}
+
static void DeleteSocket(void *data)
{
Client client = (Client )data;
@@ -86,8 +95,6 @@ static void DeleteSocket(void *data)
(*client->handle_delete) (client, client->data );
shutdown (client->fd, 2 );
close (client->fd );
- free( client->in_buffer );
- free( client->out_buffer );
IVY_LIST_REMOVE (clients_list, client );
}
@@ -96,136 +103,116 @@ static void DeleteServerSocket(void *data)
Server server = (Server )data;
#ifdef BUGGY_END
if (server->handle_delete )
- (*server->handle_delete) (server->channel, NULL );
+ (*server->handle_delete) (server, NULL );
#endif
shutdown (server->fd, 2 );
close (server->fd );
IVY_LIST_REMOVE (servers_list, server);
}
-static void HandleSocket (Channel channel, IVY_HANDLE fd, void *data)
+static void HandleSocket (Channel channel, HANDLE fd, void *data)
{
Client client = (Client)data;
char *ptr;
- char *ptr_end;
+ char *ptr_nl;
long nb_to_read = 0;
long nb;
socklen_t len;
/* limitation taille buffer */
- nb_to_read = client->in_buffer_size - (client->in_ptr - client->in_buffer );
+ nb_to_read = client->buffer_size - (client->ptr - client->buffer );
if (nb_to_read == 0 ) {
- client->in_buffer_size *= 2; /* twice old size */
- client->in_buffer = realloc( client->in_buffer, client->in_buffer_size );
- if (!client->in_buffer )
+ client->buffer_size *= 2; /* twice old size */
+ client->buffer = realloc( client->buffer, client->buffer_size );
+ if (!client->buffer )
{
fprintf(stderr,"HandleSocket Buffer Memory Alloc Error\n");
exit(0);
}
- fprintf(stderr, "Buffer Limit reached realloc new size %d\n", client->in_buffer_size );
- nb_to_read = client->in_buffer_size - (client->in_ptr - client->in_buffer );
+ fprintf(stderr, "Buffer Limit reached realloc new size %ld\n", client->buffer_size );
+ nb_to_read = client->buffer_size - (client->ptr - client->buffer );
}
len = sizeof (client->from );
- nb = recvfrom (fd, client->in_ptr, nb_to_read,0,(struct sockaddr *)&client->from,
+ nb = recvfrom (fd, client->ptr, nb_to_read,0,(struct sockaddr *)&client->from,
&len);
if (nb < 0) {
perror(" Read Socket ");
- IvyChannelRemove(client->channel );
+ IvyChannelRemove (client->channel );
return;
}
if (nb == 0 ) {
- IvyChannelRemove(client->channel );
- return;
- }
- client->in_ptr += nb;
- if (! client->interpretation )
- {
- client->in_ptr = client->in_buffer;
- fprintf (stderr,"Socket No interpretation function ??? skipping data\n");
+ IvyChannelRemove (client->channel );
return;
}
- ptr = client->in_buffer;
-
- while ( (client->in_ptr > ptr )&&(ptr_end = (*client->interpretation) (client, client->data, ptr, client->in_ptr - ptr )))
+ client->ptr += nb;
+ ptr = client->buffer;
+ while ((ptr_nl = memchr (ptr, client->terminator, client->ptr - ptr )))
{
- ptr = ptr_end;
+ *ptr_nl ='\0';
+ if (client->interpretation )
+ (*client->interpretation) (client, client->data, ptr );
+ else fprintf (stderr,"Socket No interpretation function ???\n");
+ ptr = ++ptr_nl;
}
- if (ptr < client->in_ptr )
- { /* recopie message incomplet au debut du buffer */
- len = client->in_ptr - ptr;
- memcpy (client->in_buffer, ptr, len );
- client->in_ptr = client->in_buffer + len;
+ if (ptr < client->ptr )
+ { /* recopie ligne incomplete au debut du buffer */
+ len = client->ptr - ptr;
+ memcpy (client->buffer, ptr, len );
+ client->ptr = client->buffer + len;
}
else
{
- client->in_ptr = client->in_buffer;
+ client->ptr = client->buffer;
}
}
-static Client CreateClient(int handle)
-{
- Client client;
- IVY_LIST_ADD (clients_list, client );
- if (!client )
- {
- fprintf(stderr,"NOK Memory Alloc Error\n");
- close ( handle );
- exit(-1);
- }
- client->in_buffer_size = BUFFER_SIZE;
- client->in_buffer = malloc( client->in_buffer_size );
- if (!client->in_buffer )
- {
- fprintf(stderr,"HandleSocket Buffer Memory Alloc Error\n");
- exit(-1);
- }
- client->in_ptr = client->in_buffer;
- client->out_buffer_size = BUFFER_SIZE;
- client->out_buffer = malloc( client->out_buffer_size );
- if (!client->in_buffer )
- {
- fprintf(stderr,"HandleSocket Buffer Memory Alloc Error\n");
- exit(-1);
- }
- client->out_ptr = client->out_buffer;
- client->fd = handle;
- client->channel = IvyChannelAdd (client->fd, client, DeleteSocket, HandleSocket );
- return client;
-}
-
-static void HandleServer(Channel channel, IVY_HANDLE fd, void *data)
+static void HandleServer(Channel channel, HANDLE fd, void *data)
{
Server server = (Server ) data;
Client client;
- IVY_HANDLE ns;
+ HANDLE ns;
socklen_t addrlen;
struct sockaddr_in remote2;
-#ifdef DEBUG
- printf( "Accepting Connection...\n");
-#endif //DEBUG
+
+ TRACE( "Accepting Connection...\n");
+
addrlen = sizeof (remote2 );
if ((ns = accept (fd, (struct sockaddr *)&remote2, &addrlen)) <0)
{
perror ("*** accept ***");
return;
};
-#ifdef DEBUG
- printf( "Accepting Connection ret\n");
-#endif //DEBUG
- client = CreateClient(ns);
+
+ TRACE( "Accepting Connection ret\n");
+
+ IVY_LIST_ADD_START (clients_list, client );
+
+ client->buffer_size = BUFFER_SIZE;
+ client->buffer = malloc( client->buffer_size );
+ if (!client->buffer )
+ {
+ fprintf(stderr,"HandleSocket Buffer Memory Alloc Error\n");
+ exit(0);
+ }
+ client->terminator = '\n';
client->from = remote2;
+ client->fd = ns;
+ client->channel = IvyChannelAdd (ns, client, DeleteSocket, HandleSocket );
client->interpretation = server->interpretation;
+ client->ptr = client->buffer;
client->handle_delete = server->handle_delete;
client->data = (*server->create) (client );
-}
+ IVY_LIST_ADD_END (clients_list, client );
+
+}
Server SocketServer(unsigned short port,
- SocketCreate create,
- SocketDelete handle_delete,
- SocketInterpretation interpretation )
+ void*(*create)(Client client),
+ void(*handle_delete)(Client client, void *data),
+ void(*interpretation) (Client client, void *data, char *ligne))
{
Server server;
- IVY_HANDLE fd;
+ HANDLE fd;
int one=1;
struct sockaddr_in local;
socklen_t addrlen;
@@ -278,18 +265,15 @@ Server SocketServer(unsigned short port,
};
- IVY_LIST_ADD (servers_list, server );
- if (!server )
- {
- fprintf(stderr,"NOK Memory Alloc Error\n");
- exit(0);
- }
+ IVY_LIST_ADD_START (servers_list, server );
server->fd = fd;
- server->channel = IvyChannelAdd(fd, server, DeleteServerSocket, HandleServer );
+ server->channel = IvyChannelAdd (fd, server, DeleteServerSocket, HandleServer );
server->create = create;
server->handle_delete = handle_delete;
server->interpretation = interpretation;
server->port = ntohs(local.sin_port);
+ IVY_LIST_ADD_END (servers_list, server );
+
return server;
}
@@ -302,8 +286,7 @@ void SocketServerClose (Server server )
{
if (!server)
return;
- IvyChannelRemove( server->channel );
- IVY_LIST_REMOVE (servers_list, server );
+ IvyChannelRemove (server->channel );
}
char *SocketGetPeerHost (Client client )
@@ -348,44 +331,89 @@ void SocketClose (Client client )
if (client)
IvyChannelRemove (client->channel );
}
+
+int SocketSendRaw (Client client, char *buffer, int len )
+{
+ int err;
+ int waiting= 0;
+
+ if (!client)
+ return waiting;
+
+ if ( debug_send )
+ {
+ /* try to determine if we are going to block */
+ fd_set wrset;
+ int ready;
+ struct timeval timeout;
+ timeout.tv_usec = 0;
+ timeout.tv_sec = 0;
+ FD_ZERO(&wrset);
+ FD_SET( client->fd, &wrset );
+ ready = select(client->fd+1, 0, &wrset, 0, &timeout);
+ //fprintf(stderr,"Ivy: select ready=%d fd=%d\n",ready,FD_ISSET( client->fd, &wrset ) );
+ if(ready < 0) {
+ perror("Ivy: SocketSendRaw select");
+ }
+ if ( !FD_ISSET( client->fd, &wrset ) )
+ {
+ fprintf(stderr,"Ivy: Client Queue Full Waiting..........");
+ waiting = 1;
+ }
+
+ }
+
+ err = send (client->fd, buffer, len, 0 );
+ if (err != len )
+ perror ("*** send ***");
+ if ( debug_send && waiting )
+ {
+ fprintf(stderr,"... OK\n");
+ }
+ return waiting;
+}
+
void SocketSetData (Client client, void *data )
{
if (client)
client->data = data;
}
-void *SocketGetData (Client client )
-{
- return client ? client->data : 0;
-}
-void SocketSend(Client client, const char *buffer, int len )
+int SocketSend (Client client, char *fmt, ... )
{
- unsigned long usedspace;
+ int waiting = 0;
+ static IvyBuffer buffer = {NULL, 0, 0 }; /* Use satic mem to eliminate multiple call to malloc /free */
+ va_list ap;
+ int len;
if (!client)
- return;
- usedspace = client->out_ptr - client->out_buffer;
- if ( len >= client->out_buffer_size - usedspace )
- {
- /* not enought space */
- client->out_buffer_size += len - usedspace +1;
- client->out_buffer = realloc (client->out_buffer, client->out_buffer_size);
- }
- memcpy ( client->out_ptr, buffer, len );
- client->out_ptr += len;
+ return waiting;
+ va_start (ap, fmt );
+ buffer.offset = 0;
+ len = make_message (&buffer, fmt, ap );
+ waiting = SocketSendRaw (client, buffer.data, len );
+ va_end (ap );
+ return waiting;
}
-void SocketFlush (Client client)
+void *SocketGetData (Client client )
{
- int err;
- unsigned long len;
+ return client ? client->data : 0;
+}
- if (!client)
- return;
- len = client->out_ptr - client->out_buffer;
- err = send (client->fd, client->out_buffer, len, 0 );
- if (err != len )
- perror ("*** send ***");
- client->out_ptr = client->out_buffer;
+void SocketBroadcast ( char *fmt, ... )
+{
+ Client client;
+ static IvyBuffer buffer = {NULL, 0, 0 }; /* Use satic mem to eliminate multiple call to malloc /free */
+ va_list ap;
+ int len;
+
+ va_start (ap, fmt );
+ len = make_message (&buffer, fmt, ap );
+ va_end (ap );
+ IVY_LIST_EACH (clients_list, client )
+ {
+ SocketSendRaw (client, buffer.data, len );
+ }
}
/*
@@ -394,7 +422,7 @@ Ouverture d'un canal TCP/IP en mode client
Client SocketConnect (char * host, unsigned short port,
void *data,
SocketInterpretation interpretation,
- SocketDelete handle_delete
+ void (*handle_delete)(Client client, void *data)
)
{
struct hostent *rhost;
@@ -409,10 +437,10 @@ Client SocketConnect (char * host, unsigned short port,
Client SocketConnectAddr (struct in_addr * addr, unsigned short port,
void *data,
SocketInterpretation interpretation,
- SocketDelete handle_delete
+ void (*handle_delete)(Client client, void *data)
)
{
- IVY_HANDLE handle;
+ HANDLE handle;
Client client;
struct sockaddr_in remote;
@@ -430,25 +458,91 @@ Client SocketConnectAddr (struct in_addr * addr, unsigned short port,
return NULL;
};
- client = CreateClient(handle);
+ IVY_LIST_ADD_START(clients_list, client );
+
+ client->buffer_size = BUFFER_SIZE;
+ client->buffer = malloc( client->buffer_size );
+ if (!client->buffer )
+ {
+ fprintf(stderr,"HandleSocket Buffer Memory Alloc Error\n");
+ exit(0);
+ }
+ client->terminator = '\n';
+ client->fd = handle;
+ client->channel = IvyChannelAdd (handle, client, DeleteSocket, HandleSocket );
client->interpretation = interpretation;
- client->handle_delete = handle_delete;
+ client->ptr = client->buffer;
client->data = data;
+ client->handle_delete = handle_delete;
client->from.sin_family = AF_INET;
client->from.sin_addr = *addr;
client->from.sin_port = htons (port);
+ IVY_LIST_ADD_END(clients_list, client );
+
return client;
}
+// TODO factoriser avec HandleRead !!!!
+int SocketWaitForReply (Client client, char *buffer, int size, int delai)
+{
+ fd_set rdset;
+ struct timeval timeout;
+ struct timeval *timeoutptr = &timeout;
+ int ready;
+ char *ptr;
+ char *ptr_nl;
+ long nb_to_read = 0;
+ long nb;
+ HANDLE fd;
+
+ fd = client->fd;
+ ptr = buffer;
+ timeout.tv_sec = delai;
+ timeout.tv_usec = 0;
+ do {
+ /* limitation taille buffer */
+ nb_to_read = size - (ptr - buffer );
+ if (nb_to_read == 0 )
+ {
+ fprintf(stderr, "Erreur message trop long sans LF\n");
+ ptr = buffer;
+ return -1;
+ }
+ FD_ZERO (&rdset );
+ FD_SET (fd, &rdset );
+ ready = select(fd+1, &rdset, 0, 0, timeoutptr);
+ if (ready < 0 )
+ {
+ perror("select");
+ return -1;
+ }
+ if (ready == 0 )
+ {
+ return -2;
+ }
+ if ((nb = recv (fd , ptr, nb_to_read, 0 )) < 0)
+ {
+ perror(" Read Socket ");
+ return -1;
+ }
+ if (nb == 0 )
+ return 0;
+
+ ptr += nb;
+ *ptr = '\0';
+ ptr_nl = strchr (buffer, client->terminator );
+ } while (!ptr_nl );
+ *ptr_nl = '\0';
+ return (ptr_nl - buffer);
+}
/* Socket UDP */
-Client SocketBroadcastCreate (
- unsigned short port,
+Client SocketBroadcastCreate (unsigned short port,
void *data,
SocketInterpretation interpretation
)
{
- IVY_HANDLE handle;
+ HANDLE handle;
Client client;
struct sockaddr_in local;
int on = 1;
@@ -489,43 +583,51 @@ Client SocketBroadcastCreate (
return NULL;
};
- client = CreateClient(handle);
+ IVY_LIST_ADD_START(clients_list, client );
+
+ client->buffer_size = BUFFER_SIZE;
+ client->buffer = malloc( client->buffer_size );
+ if (!client->buffer )
+ {
+ perror("HandleSocket Buffer Memory Alloc Error: ");
+ exit(0);
+ }
+ client->terminator = '\n';
+ client->fd = handle;
+ client->channel = IvyChannelAdd (handle, client, DeleteSocket, HandleSocket );
client->interpretation = interpretation;
+ client->ptr = client->buffer;
client->data = data;
+ IVY_LIST_ADD_END(clients_list, client );
+
return client;
}
-void SocketSendBroadcast(Client client, unsigned long host, unsigned short port, char *buffer, int len )
+void SocketSendBroadcast (Client client, unsigned long host, unsigned short port, char *fmt, ... )
{
struct sockaddr_in remote;
- int err;
+ static IvyBuffer buffer = { NULL, 0, 0 }; /* Use satic mem to eliminate multiple call to malloc /free */
+ va_list ap;
+ int err,len;
if (!client)
return;
+ va_start (ap, fmt );
+ buffer.offset = 0;
+ len = make_message (&buffer, fmt, ap );
/* Send UDP packet to the dest */
remote.sin_family = AF_INET;
remote.sin_addr.s_addr = htonl (host );
remote.sin_port = htons(port);
err = sendto (client->fd,
- buffer, len,0,
+ buffer.data, len,0,
(struct sockaddr *)&remote,sizeof(remote));
if (err != len) {
perror ("*** send ***");
- }
-}
-void SocketKeepAlive( Client client,int keepalive )
-{
- int alive = keepalive;
- if (setsockopt(client->fd,SOL_SOCKET,SO_KEEPALIVE,(char*)&alive,sizeof(alive)) < 0)
- {
-#ifdef WIN32
- fprintf(stderr," setsockopt %d\n",WSAGetLastError());
-#endif
- perror ("*** set socket option SO_KEEPALIVE ***");
- exit(0);
- }
+ } va_end (ap );
}
+
/* Socket Multicast */
int SocketAddMember(Client client, unsigned long host )
diff --git a/src/ivysocket.h b/src/ivysocket.h
index b491f0f..c656312 100644
--- a/src/ivysocket.h
+++ b/src/ivysocket.h
@@ -6,7 +6,7 @@
*
* Sockets
*
- * Authors: Francois-Regis Colin <fcolin@cena.fr>
+ * Authors: Francois-Regis Colin <fcolin@cena.dgac.fr>
*
* $Id$
*
@@ -32,11 +32,13 @@ extern "C" {
#ifdef __MINGW32__
#include <ws2tcpip.h>
#endif
+#define HANDLE SOCKET
#define socklen_t int
#ifndef IN_MULTICAST
#define IN_MULTICAST(i) (((long)(i) & 0xf0000000) == 0xe0000000)
#endif
#else
+#define HANDLE int
#include <netinet/in.h>
#endif
#ifdef __INTERIX
@@ -44,40 +46,43 @@ extern "C" {
#endif
/* General Init */
+extern void SocketInit();
+
/* Forward def */
typedef struct _client *Client;
-typedef char* (*SocketInterpretation) (Client client, void *data, char *ligne, unsigned int len);
-typedef void* (*SocketCreate) (Client client);
-typedef void (*SocketDelete) (Client client, void *data);
+typedef void (*SocketInterpretation) (Client client, void *data, char *ligne);
/* Server Part */
typedef struct _server *Server;
extern Server SocketServer(unsigned short port,
- SocketCreate create,
- SocketDelete handle_delete,
+ void*(*create)(Client client),
+ void(*handle_delete)(Client client, void *data),
SocketInterpretation interpretation);
extern unsigned short SocketServerGetPort( Server server );
extern void SocketServerClose( Server server );
/* Client Part */
-extern void SocketKeepAlive( Client client,int keepalive );
+
extern void SocketClose( Client client );
-extern void SocketSend( Client client, const char *buffer, int len );
-extern void SocketFlush (Client client);
+extern int SocketSend( Client client, char *fmt, ... );
+extern int SocketSendRaw( Client client, char *buffer, int len );
extern char *SocketGetPeerHost( Client client );
extern void SocketSetData( Client client, void *data );
extern void *SocketGetData( Client client );
+extern void SocketBroadcast( char *fmt, ... );
extern Client SocketConnect( char * host, unsigned short port,
void *data,
SocketInterpretation interpretation,
- SocketDelete handle_delete
- );
+ void (*handle_delete)(Client client, void *data)
+ );
extern Client SocketConnectAddr( struct in_addr * addr, unsigned short port,
void *data,
SocketInterpretation interpretation,
- SocketDelete handle_delete
+ void (*handle_delete)(Client client, void *data)
);
+extern int SocketWaitForReply( Client client, char *buffer, int size, int delai);
+
/* Socket UDP */
/* Creation d'une socket en mode non connecte */
/* et ecoute des messages */
@@ -93,7 +98,7 @@ extern int SocketAddMember( Client client, unsigned long host );
extern struct in_addr * SocketGetRemoteAddr( Client client );
extern void SocketGetRemoteHost (Client client, char **host, unsigned short *port );
/* emmission d'un broadcast UDP */
-extern void SocketSendBroadcast( Client client, unsigned long host, unsigned short port, char *buffer, int len );
+extern void SocketSendBroadcast( Client client, unsigned long host, unsigned short port, char *fmt, ... );
#ifdef __cplusplus
}
diff --git a/src/ivytcl.c b/src/ivytcl.c
index 6c82e54..a43821a 100755
--- a/src/ivytcl.c
+++ b/src/ivytcl.c
@@ -6,7 +6,7 @@
*
* Main loop based on Tcl
*
- * Authors: François-Régis Colin <fcolin@cena.fr>
+ * Authors: François-Régis Colin <fcolin@cena.dgac.fr>
*
* $Id$
*
@@ -29,6 +29,7 @@
#include "ivytcl.h"
#include "ivysocket.h"
+#include "ivychannel.h"
#include "ivy.h"
#include "timer.h"
@@ -38,7 +39,6 @@
// mais il y a des problemes sur les socket server
// Il n'y a pas de Tcl_MakeTCPserver
-
struct _channel {
HANDLE fd;
void *data;
@@ -75,15 +75,6 @@ void IvyChannelInit(void)
#endif
channel_initialized = 1;
}
-void IvyChannelStop(void)
-{
- channel_initialized = 0;
-
-#ifndef TCL_CHANNEL_INTEGRATION
- Tcl_CancelIdleCall(IvyIdleProc,0);
-#endif
-
-}
static void
IvyHandleFd(ClientData cd,
int mask)
@@ -143,6 +134,14 @@ void IvyIdleProc(ClientData clientData)
}
#endif
+void
+IvyChannelStop ()
+{
+ /* To be implemented */
+#ifndef TCL_CHANNEL_INTEGRATION
+ Tcl_CancelIdleCall(IvyIdleProc,0);
+#endif
+}
/* Code from PLC */
#define INTEGER_SPACE 30
diff --git a/src/ivytcl.h b/src/ivytcl.h
index 99c05d7..c482a60 100755
--- a/src/ivytcl.h
+++ b/src/ivytcl.h
@@ -6,7 +6,7 @@
*
* Main loop based on Tcl
*
- * Authors: François-Régis Colin <fcolin@cena.fr>
+ * Authors: François-Régis Colin <fcolin@cena.dgac.fr>
*
* $Id$
*
@@ -21,10 +21,6 @@
extern "C" {
#endif
-
-#include "ivychannel.h"
-
-
#ifdef __cplusplus
}
#endif
diff --git a/src/ivyxtloop.c b/src/ivyxtloop.c
index 6a451a1..6613307 100644
--- a/src/ivyxtloop.c
+++ b/src/ivyxtloop.c
@@ -6,8 +6,8 @@
*
* Main loop based on the X Toolkit
*
- * Authors: François-Régis Colin <fcolin@cena.fr>
- * Stéphane Chatty <chatty@cena.fr>
+ * Authors: François-Régis Colin <fcolin@cena.dgac.fr>
+ * Stéphane Chatty <chatty@cena.dgac.fr>
*
* $Id$
*
@@ -39,6 +39,7 @@
#include <X11/Intrinsic.h>
+#include "ivydebug.h"
#include "ivychannel.h"
#include "ivyxtloop.h"
@@ -83,25 +84,19 @@ void IvyChannelRemove( Channel channel )
XtRemoveInput( channel->id_read );
XtRemoveInput( channel->id_delete );
}
-void IvyChannelStop()
-{
-}
+
static void IvyXtHandleChannelRead( XtPointer closure, int* source, XtInputId* id )
{
Channel channel = (Channel)closure;
-#ifdef DEBUG
- printf("Handle Channel read %d\n",*source );
-#endif
+ TRACE("Handle Channel read %d\n",*source );
(*channel->handle_read)(channel,*source,channel->data);
}
static void IvyXtHandleChannelDelete( XtPointer closure, int* source, XtInputId* id )
{
Channel channel = (Channel)closure;
-#ifdef DEBUG
- printf("Handle Channel delete %d\n",*source );
-#endif
+ TRACE("Handle Channel delete %d\n",*source );
(*channel->handle_delete)(channel->data);
}
@@ -111,7 +106,7 @@ void IvyXtChannelAppContext( XtAppContext cntx )
app = cntx;
}
-Channel IvyChannelAdd(IVY_HANDLE fd, void *data,
+Channel IvyChannelAdd(HANDLE fd, void *data,
ChannelHandleDelete handle_delete,
ChannelHandleRead handle_read
)
@@ -134,7 +129,11 @@ Channel IvyChannelAdd(IVY_HANDLE fd, void *data,
return channel;
}
-void IvyMainLoop(void(*hook)(void))
+
+
+void
+IvyChannelStop ()
{
- XtAppMainLoop (app);
-} \ No newline at end of file
+ /* To be implemented */
+}
+
diff --git a/src/ivyxtloop.h b/src/ivyxtloop.h
index 162f398..0087274 100644
--- a/src/ivyxtloop.h
+++ b/src/ivyxtloop.h
@@ -6,8 +6,8 @@
*
* Main loop based on the X Toolkit
*
- * Authors: François-Régis Colin <colin@cena.fr>
- * Stéphane Chatty <chatty@cena.fr>
+ * Authors: François-Régis Colin <colin@cena.dgac.fr>
+ * Stéphane Chatty <chatty@cena.dgac.fr>
*
* $Id$
*
@@ -24,10 +24,6 @@ extern "C" {
#include <X11/Intrinsic.h>
-#include "ivychannel.h"
-
-
-
extern void IvyXtChannelAppContext( XtAppContext cntx );
#ifdef __cplusplus
diff --git a/src/libIvy.def b/src/libIvy.def
index 4f7e3ba..df671c7 100644
--- a/src/libIvy.def
+++ b/src/libIvy.def
@@ -3,7 +3,9 @@ LIBRARY Ivy
EXPORTS
IvyDefaultApplicationCallback
-IvySetMyMessagesStart
+IvyDefaultBindCallback
+
+IvySetFilter
IvyInit
IvyStart
IvyStop
@@ -15,32 +17,24 @@ IvyGetApplication
IvyGetApplicationList
IvyGetApplicationMessages
IvyBindMsg
-IvyBindSimpleMsg
IvyUnbindMsg
IvySendError
IvySendDieMsg
IvySendMsg
-IvySetApplicationPriority
-IvySetBindCallback
+
IvyBindDirectMsg
IvySendDirectMsg
-
-IvyArgumentNew
-IvyArgumentFree
-IvyArgumentGetValue
-IvyArgumentGetChildrens
-IvyArgumentGetNextChild
-IvyAddChild
-IvyAddChildValue
-
-
+IvySetBeforeSelectHook
+IvySetAfterSelectHook
IvyMainLoop
IvyChannelInit
IvyChannelRemove
IvyChannelAdd
-TimerRepeatAfter
-TimerModify
-TimerRemove
+IvyBindingCompile
+IvyBindingFree
+
+IvyBindingExec
+IvyBindingMatch
diff --git a/src/list.h b/src/list.h
index ff01f13..968f619 100644
--- a/src/list.h
+++ b/src/list.h
@@ -6,22 +6,18 @@
*
* Simple lists in C
*
- * Authors: François-Régis Colin <fcolin@cena.fr>
+ * Authors: François-Régis Colin <fcolin@cena.dgac.fr>
*
* $Id$
*
* Please refer to file version.h for the
* copyright notice regarding this software
*/
-#ifdef WIN32
-#define TYPEOF(p) void*
-#else
-#if (__GNUC__ >= 2)
+#if (__GNUC__ >= 3)
#define TYPEOF(p) typeof (p)
#else
#define TYPEOF(p) void *
#endif
-#endif
#define IVY_LIST_ITER( list, p, cond ) \
p = list; \
@@ -54,36 +50,30 @@
}\
} \
}
-
-#define IVY_LIST_ADD(list, p ) \
+/*
+on place le code d'initialisation de l'objet entre START et END
+pour eviter de chainer un objet non initialise
+*/
+#define IVY_LIST_ADD_START(list, p ) \
if ((p = (TYPEOF(p)) (malloc( sizeof( *p ))))) \
{ \
- memset( p, 0 , sizeof( *p ));\
- p->next = list; \
- list = p; \
- }
+ memset( p, 0 , sizeof( *p ));
#define IVY_LIST_ADD_END(list, p ) \
- if ((p = (TYPEOF(p)) (malloc( sizeof( *p ))))) \
- { \
- TYPEOF(p) list_end; \
- memset( p, 0 , sizeof( *p ));\
- p->next = 0; \
- if ( list ) \
- {\
- list_end = list; \
- while ( list_end && list_end->next ) \
- list_end = list_end->next;\
- list_end->next = p; \
+ p->next = list; \
+ list = p; \
} \
- else list = p; \
+ else \
+ { \
+ perror( "IVY LIST ADD malloc" ); \
+ exit(0); \
}
#define IVY_LIST_EACH( list, p ) \
for ( p = list ; p ; p = p -> next )
-#define IVY_LIST_EACH_SAFE( list, p, p_next )\
-for ( p = list ; (p_next = p ? p->next: p ),p ; p = p_next )
+#define IVY_LIST_EACH_SAFE( list, p, next )\
+for ( p = list ; (next = p ? p->next: p ),p ; p = next )
#define IVY_LIST_EMPTY( list ) \
{ \
diff --git a/src/timer.c b/src/timer.c
index 7efb3ce..4e38c52 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -6,7 +6,7 @@
*
* Timers used in select based main loop
*
- * Authors: François-Régis Colin <fcolin@cena.fr>
+ * Authors: François-Régis Colin <fcolin@cena.dgac.fr>
*
* $Id$
*
@@ -15,20 +15,16 @@
*/
/* Module de gestion des timers autour d'un select */
-
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include <stdlib.h>
#include <memory.h>
-
#ifdef WIN32
-#include <crtdbg.h>
#include <windows.h>
#else
#include <sys/time.h>
#endif
-
#include "list.h"
#include "timer.h"
@@ -107,18 +103,16 @@ TimerId TimerRepeatAfter( int count, long time, TimerCb cb, void *user_data )
/* si y a rien a faire et ben on fait rien */
if ( cb == NULL ) return NULL;
- IVY_LIST_ADD( timers, timer )
- if ( timer )
- {
- timer->repeat = count;
- timer->callback = cb;
- timer->user_data = user_data;
- stamp = currentTime();
- timer->period = time;
- timer->when = stamp + time;
- if ( (timer->when < nextTimeout) || (timeoutptr == NULL))
- SetNewTimeout( stamp, timer->when );
- }
+ IVY_LIST_ADD_START( timers, timer )
+ timer->repeat = count;
+ timer->callback = cb;
+ timer->user_data = user_data;
+ stamp = currentTime();
+ timer->period = time;
+ timer->when = stamp + time;
+ if ( (timer->when < nextTimeout) || (timeoutptr == NULL))
+ SetNewTimeout( stamp, timer->when );
+ IVY_LIST_ADD_END( timers, timer )
return timer;
}
void TimerRemove( TimerId timer )
@@ -143,6 +137,10 @@ void TimerModify( TimerId timer, long time )
struct timeval *TimerGetSmallestTimeout()
{
+ unsigned long stamp;
+ /* recalcul du prochain timeout */
+ stamp = currentTime();
+ AdjTimeout( stamp );
return timeoutptr;
}
@@ -174,6 +172,5 @@ void TimerScan()
}
}
}
- /* recalcul du prochain timeout */
- AdjTimeout( stamp );
+
}
diff --git a/src/timer.h b/src/timer.h
index c62b505..f8f21a5 100644
--- a/src/timer.h
+++ b/src/timer.h
@@ -6,7 +6,7 @@
*
* Timers for select-based main loop
*
- * Authors: François-Régis Colin <fcolin@cena.fr>
+ * Authors: François-Régis Colin <fcolin@cena.dgac.fr>
*
* $Id$
*
diff --git a/src/version.h b/src/version.h
index 072a2fb..42d32fd 100644
--- a/src/version.h
+++ b/src/version.h
@@ -4,8 +4,8 @@
* Copyright (C) 1997-2004
* Centre d'Études de la Navigation Aérienne
*
- * Authors: François-Régis Colin <colin@cena.fr>
- * Stéphane Chatty <chatty@cena.fr>
+ * Authors: François-Régis Colin <colin@cena.dgac.fr>
+ * Stéphane Chatty <chatty@cena.dgac.fr>
* Yannick Jestin <jestin@cena.fr>
*
* $Id$
@@ -25,5 +25,5 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
-#define IVYMAJOR_VERSION 4
-#define IVYMINOR_VERSION 0
+#define IVYMAJOR_VERSION 3
+#define IVYMINOR_VERSION 9