From 22c20ab6f215c0ab24702a479aa6821c25a7d058 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 5 Jul 2006 19:47:25 +0000 Subject: Merged with trunk, and a few trivial GUI updates etc. git-svn-id: svn://localhost/ardour2/branches/midi@664 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/SConscript | 4 +- libs/ardour/ardour/audiofilesource.h | 8 +- libs/ardour/ardour/coreaudio_source.h | 54 - libs/ardour/ardour/coreaudiosource.h | 61 + libs/ardour/ardour/destructive_filesource.h | 3 +- libs/ardour/ardour/diskstream.h | 9 +- libs/ardour/ardour/session.h | 30 +- libs/ardour/ardour/session_diskstream.h | 4 +- libs/ardour/ardour/sndfilesource.h | 5 +- libs/ardour/audio_diskstream.cc | 10 +- libs/ardour/audio_playlist.cc | 2 +- libs/ardour/audio_track.cc | 8 - libs/ardour/audiofilesource.cc | 54 +- libs/ardour/coreaudio_source.cc | 220 --- libs/ardour/coreaudiosource.cc | 218 +++ libs/ardour/midi_diskstream.cc | 11 +- libs/ardour/midi_track.cc | 10 +- libs/ardour/plugin.cc | 14 +- libs/ardour/session.cc | 68 +- libs/ardour/session_butler.cc | 24 +- libs/ardour/session_export.cc | 2 +- libs/ardour/session_process.cc | 12 +- libs/ardour/session_state.cc | 17 +- libs/ardour/session_time.cc | 1 - libs/ardour/session_transport.cc | 36 +- libs/ardour/sndfilesource.cc | 94 +- libs/cassowary/.cvsignore | 3 - libs/cassowary/ANNOUNCE | 37 - libs/cassowary/AUTHORS | 12 - libs/cassowary/COPYING | 340 ---- libs/cassowary/COPYING.LGPL | 444 ----- libs/cassowary/ChangeLog | 2005 -------------------- libs/cassowary/ClAbstractVariable.cc | 23 - libs/cassowary/ClBug0.cc | 102 - libs/cassowary/ClBug1.cc | 21 - libs/cassowary/ClBug2.cc | 130 -- libs/cassowary/ClConstraint.cc | 32 - libs/cassowary/ClDummyVariable.cc | 12 - libs/cassowary/ClFDBinaryOneWayConstraint.cc | 140 -- libs/cassowary/ClFDConnectorVariable.cc | 29 - libs/cassowary/ClFDSolver.cc | 364 ---- libs/cassowary/ClFDVariable.cc | 27 - libs/cassowary/ClFloatVariable.cc | 25 - libs/cassowary/ClLinearExpression.cc | 473 ----- libs/cassowary/ClReader.ll | 87 - libs/cassowary/ClReader.yy | 154 -- libs/cassowary/ClSimplexSolver.cc | 1631 ---------------- libs/cassowary/ClSlackVariable.cc | 12 - libs/cassowary/ClSolver.cc | 59 - libs/cassowary/ClStrength.cc | 52 - libs/cassowary/ClSymbolicWeight.cc | 149 -- libs/cassowary/ClTableau.cc | 297 --- libs/cassowary/ClTests.cc | 884 --------- libs/cassowary/ClVariable.cc | 21 - libs/cassowary/IMPORTANT | 26 - libs/cassowary/LICENSE | 18 - libs/cassowary/NEWS | 229 --- libs/cassowary/README | 241 --- libs/cassowary/SConscript | 32 - libs/cassowary/THANKS | 30 - libs/cassowary/cassowary-config.in | 102 - libs/cassowary/cassowary-nofd.spec2.in | 84 - libs/cassowary/cassowary.spec.in | 78 - libs/cassowary/cassowary/.cvsignore | 0 libs/cassowary/cassowary/Cassowary.h | 40 - libs/cassowary/cassowary/Cl.h | 49 - libs/cassowary/cassowary/ClAbstractVariable.h | 161 -- libs/cassowary/cassowary/ClConstraint.h | 198 -- libs/cassowary/cassowary/ClConstraintHash.h | 39 - libs/cassowary/cassowary/ClDummyVariable.h | 88 - libs/cassowary/cassowary/ClEditConstraint.h | 45 - libs/cassowary/cassowary/ClEditOrStayConstraint.h | 51 - libs/cassowary/cassowary/ClErrors.h | 179 -- .../cassowary/ClFDBinaryOneWayConstraint.h | 94 - libs/cassowary/cassowary/ClFDConnectorVariable.h | 89 - libs/cassowary/cassowary/ClFDConstraint.h | 40 - libs/cassowary/cassowary/ClFDSolver.h | 120 -- libs/cassowary/cassowary/ClFDVariable.h | 126 -- libs/cassowary/cassowary/ClFloatVariable.h | 119 -- libs/cassowary/cassowary/ClLinearConstraint.h | 61 - libs/cassowary/cassowary/ClLinearEquation.h | 74 - libs/cassowary/cassowary/ClLinearExpression.h | 298 --- libs/cassowary/cassowary/ClLinearExpression_fwd.h | 26 - libs/cassowary/cassowary/ClLinearInequality.h | 167 -- libs/cassowary/cassowary/ClObjectiveVariable.h | 63 - libs/cassowary/cassowary/ClPoint.h | 74 - libs/cassowary/cassowary/ClReader.h | 120 -- libs/cassowary/cassowary/ClSimplexSolver.h | 588 ------ libs/cassowary/cassowary/ClSlackVariable.h | 75 - libs/cassowary/cassowary/ClSolver.h | 167 -- libs/cassowary/cassowary/ClStayConstraint.h | 43 - libs/cassowary/cassowary/ClStrength.h | 91 - libs/cassowary/cassowary/ClSymbolicWeight.h | 197 -- libs/cassowary/cassowary/ClTableau.h | 230 --- libs/cassowary/cassowary/ClTypedefs.h | 48 - libs/cassowary/cassowary/ClVariable.h | 169 -- libs/cassowary/cassowary/cl_auto_ptr.h | 69 - libs/cassowary/cassowary/config-inline.h | 1 - libs/cassowary/cassowary/debug.h | 48 - libs/cassowary/cassowary/timer.h | 176 -- libs/gtkmm2ext/SConscript | 2 +- libs/libsndfile/src/sndfile.c | 4 +- libs/midi++2/SConscript | 2 +- libs/pbd/.cvsignore | 5 + libs/pbd/AUTHORS | 0 libs/pbd/COPYING | 340 ++++ libs/pbd/ChangeLog | 10 + libs/pbd/NEWS | 0 libs/pbd/README | 0 libs/pbd/SConscript | 68 + libs/pbd/base_ui.cc | 88 + libs/pbd/basename.cc | 20 + libs/pbd/convert.cc | 212 +++ libs/pbd/dmalloc.cc | 102 + libs/pbd/error.cc | 7 + libs/pbd/gettext.h | 82 + libs/pbd/i18n.h | 11 + libs/pbd/libpbd.pc.in | 11 + libs/pbd/libpbd.spec.in | 70 + libs/pbd/mountpoint.cc | 158 ++ libs/pbd/path.cc | 164 ++ libs/pbd/pathscanner.cc | 203 ++ libs/pbd/pbd/.DS_Store | Bin 0 -> 6148 bytes libs/pbd/pbd/.cvsignore | 1 + libs/pbd/pbd/abstract_ui.cc | 149 ++ libs/pbd/pbd/abstract_ui.h | 79 + libs/pbd/pbd/base_ui.h | 46 + libs/pbd/pbd/basename.h | 13 + libs/pbd/pbd/compose.h | 393 ++++ libs/pbd/pbd/convert.h | 40 + libs/pbd/pbd/error.h | 32 + libs/pbd/pbd/failed_constructor.h | 11 + libs/pbd/pbd/fastlog.h | 40 + libs/pbd/pbd/forkexec.h | 9 + libs/pbd/pbd/mathfix.h | 34 + libs/pbd/pbd/mountpoint.h | 28 + libs/pbd/pbd/path.h | 113 ++ libs/pbd/pbd/pathscanner.h | 66 + libs/pbd/pbd/pool.h | 75 + libs/pbd/pbd/pthread_utils.h | 23 + libs/pbd/pbd/receiver.h | 50 + libs/pbd/pbd/restartable_rw.h | 7 + libs/pbd/pbd/ringbuffer.h | 284 +++ libs/pbd/pbd/ringbufferNPT.h | 275 +++ libs/pbd/pbd/selectable.h | 102 + libs/pbd/pbd/stacktrace.h | 10 + libs/pbd/pbd/stl_delete.h | 89 + libs/pbd/pbd/stl_functors.h | 93 + libs/pbd/pbd/strsplit.h | 9 + libs/pbd/pbd/textreceiver.h | 44 + libs/pbd/pbd/thrown_error.h | 39 + libs/pbd/pbd/tokenizer.h | 49 + libs/pbd/pbd/touchable.h | 89 + libs/pbd/pbd/transmitter.h | 110 ++ libs/pbd/pbd/undo.h | 96 + libs/pbd/pbd/whitespace.h | 8 + libs/pbd/pbd/xml++.h | 129 ++ libs/pbd/pool.cc | 144 ++ libs/pbd/pthread_utils.cc | 133 ++ libs/pbd/receiver.cc | 58 + libs/pbd/stacktrace.cc | 42 + libs/pbd/strsplit.cc | 41 + libs/pbd/textreceiver.cc | 66 + libs/pbd/transmitter.cc | 115 ++ libs/pbd/undo.cc | 146 ++ libs/pbd/whitespace.cc | 30 + libs/pbd/xml++.cc | 422 ++++ libs/surfaces/control_protocol/SConscript | 2 +- libs/surfaces/generic_midi/SConscript | 2 +- libs/surfaces/tranzport/SConscript | 2 +- 170 files changed, 5890 insertions(+), 13114 deletions(-) delete mode 100644 libs/ardour/ardour/coreaudio_source.h create mode 100644 libs/ardour/ardour/coreaudiosource.h delete mode 100644 libs/ardour/coreaudio_source.cc create mode 100644 libs/ardour/coreaudiosource.cc delete mode 100644 libs/cassowary/.cvsignore delete mode 100644 libs/cassowary/ANNOUNCE delete mode 100644 libs/cassowary/AUTHORS delete mode 100644 libs/cassowary/COPYING delete mode 100644 libs/cassowary/COPYING.LGPL delete mode 100644 libs/cassowary/ChangeLog delete mode 100644 libs/cassowary/ClAbstractVariable.cc delete mode 100644 libs/cassowary/ClBug0.cc delete mode 100644 libs/cassowary/ClBug1.cc delete mode 100644 libs/cassowary/ClBug2.cc delete mode 100644 libs/cassowary/ClConstraint.cc delete mode 100644 libs/cassowary/ClDummyVariable.cc delete mode 100644 libs/cassowary/ClFDBinaryOneWayConstraint.cc delete mode 100644 libs/cassowary/ClFDConnectorVariable.cc delete mode 100644 libs/cassowary/ClFDSolver.cc delete mode 100644 libs/cassowary/ClFDVariable.cc delete mode 100644 libs/cassowary/ClFloatVariable.cc delete mode 100644 libs/cassowary/ClLinearExpression.cc delete mode 100644 libs/cassowary/ClReader.ll delete mode 100644 libs/cassowary/ClReader.yy delete mode 100644 libs/cassowary/ClSimplexSolver.cc delete mode 100644 libs/cassowary/ClSlackVariable.cc delete mode 100644 libs/cassowary/ClSolver.cc delete mode 100644 libs/cassowary/ClStrength.cc delete mode 100644 libs/cassowary/ClSymbolicWeight.cc delete mode 100644 libs/cassowary/ClTableau.cc delete mode 100644 libs/cassowary/ClTests.cc delete mode 100644 libs/cassowary/ClVariable.cc delete mode 100644 libs/cassowary/IMPORTANT delete mode 100644 libs/cassowary/LICENSE delete mode 100644 libs/cassowary/NEWS delete mode 100644 libs/cassowary/README delete mode 100644 libs/cassowary/SConscript delete mode 100644 libs/cassowary/THANKS delete mode 100755 libs/cassowary/cassowary-config.in delete mode 100644 libs/cassowary/cassowary-nofd.spec2.in delete mode 100644 libs/cassowary/cassowary.spec.in delete mode 100644 libs/cassowary/cassowary/.cvsignore delete mode 100644 libs/cassowary/cassowary/Cassowary.h delete mode 100644 libs/cassowary/cassowary/Cl.h delete mode 100644 libs/cassowary/cassowary/ClAbstractVariable.h delete mode 100644 libs/cassowary/cassowary/ClConstraint.h delete mode 100644 libs/cassowary/cassowary/ClConstraintHash.h delete mode 100644 libs/cassowary/cassowary/ClDummyVariable.h delete mode 100644 libs/cassowary/cassowary/ClEditConstraint.h delete mode 100644 libs/cassowary/cassowary/ClEditOrStayConstraint.h delete mode 100644 libs/cassowary/cassowary/ClErrors.h delete mode 100644 libs/cassowary/cassowary/ClFDBinaryOneWayConstraint.h delete mode 100644 libs/cassowary/cassowary/ClFDConnectorVariable.h delete mode 100644 libs/cassowary/cassowary/ClFDConstraint.h delete mode 100644 libs/cassowary/cassowary/ClFDSolver.h delete mode 100644 libs/cassowary/cassowary/ClFDVariable.h delete mode 100644 libs/cassowary/cassowary/ClFloatVariable.h delete mode 100644 libs/cassowary/cassowary/ClLinearConstraint.h delete mode 100644 libs/cassowary/cassowary/ClLinearEquation.h delete mode 100644 libs/cassowary/cassowary/ClLinearExpression.h delete mode 100644 libs/cassowary/cassowary/ClLinearExpression_fwd.h delete mode 100644 libs/cassowary/cassowary/ClLinearInequality.h delete mode 100644 libs/cassowary/cassowary/ClObjectiveVariable.h delete mode 100644 libs/cassowary/cassowary/ClPoint.h delete mode 100644 libs/cassowary/cassowary/ClReader.h delete mode 100644 libs/cassowary/cassowary/ClSimplexSolver.h delete mode 100644 libs/cassowary/cassowary/ClSlackVariable.h delete mode 100644 libs/cassowary/cassowary/ClSolver.h delete mode 100644 libs/cassowary/cassowary/ClStayConstraint.h delete mode 100644 libs/cassowary/cassowary/ClStrength.h delete mode 100644 libs/cassowary/cassowary/ClSymbolicWeight.h delete mode 100644 libs/cassowary/cassowary/ClTableau.h delete mode 100644 libs/cassowary/cassowary/ClTypedefs.h delete mode 100644 libs/cassowary/cassowary/ClVariable.h delete mode 100644 libs/cassowary/cassowary/cl_auto_ptr.h delete mode 100644 libs/cassowary/cassowary/config-inline.h delete mode 100644 libs/cassowary/cassowary/debug.h delete mode 100644 libs/cassowary/cassowary/timer.h create mode 100644 libs/pbd/.cvsignore create mode 100644 libs/pbd/AUTHORS create mode 100644 libs/pbd/COPYING create mode 100644 libs/pbd/ChangeLog create mode 100644 libs/pbd/NEWS create mode 100644 libs/pbd/README create mode 100644 libs/pbd/SConscript create mode 100644 libs/pbd/base_ui.cc create mode 100644 libs/pbd/basename.cc create mode 100644 libs/pbd/convert.cc create mode 100644 libs/pbd/dmalloc.cc create mode 100644 libs/pbd/error.cc create mode 100644 libs/pbd/gettext.h create mode 100644 libs/pbd/i18n.h create mode 100644 libs/pbd/libpbd.pc.in create mode 100644 libs/pbd/libpbd.spec.in create mode 100644 libs/pbd/mountpoint.cc create mode 100644 libs/pbd/path.cc create mode 100644 libs/pbd/pathscanner.cc create mode 100644 libs/pbd/pbd/.DS_Store create mode 100644 libs/pbd/pbd/.cvsignore create mode 100644 libs/pbd/pbd/abstract_ui.cc create mode 100644 libs/pbd/pbd/abstract_ui.h create mode 100644 libs/pbd/pbd/base_ui.h create mode 100644 libs/pbd/pbd/basename.h create mode 100644 libs/pbd/pbd/compose.h create mode 100644 libs/pbd/pbd/convert.h create mode 100644 libs/pbd/pbd/error.h create mode 100644 libs/pbd/pbd/failed_constructor.h create mode 100644 libs/pbd/pbd/fastlog.h create mode 100644 libs/pbd/pbd/forkexec.h create mode 100644 libs/pbd/pbd/mathfix.h create mode 100644 libs/pbd/pbd/mountpoint.h create mode 100644 libs/pbd/pbd/path.h create mode 100644 libs/pbd/pbd/pathscanner.h create mode 100644 libs/pbd/pbd/pool.h create mode 100644 libs/pbd/pbd/pthread_utils.h create mode 100644 libs/pbd/pbd/receiver.h create mode 100644 libs/pbd/pbd/restartable_rw.h create mode 100644 libs/pbd/pbd/ringbuffer.h create mode 100644 libs/pbd/pbd/ringbufferNPT.h create mode 100644 libs/pbd/pbd/selectable.h create mode 100644 libs/pbd/pbd/stacktrace.h create mode 100644 libs/pbd/pbd/stl_delete.h create mode 100644 libs/pbd/pbd/stl_functors.h create mode 100644 libs/pbd/pbd/strsplit.h create mode 100644 libs/pbd/pbd/textreceiver.h create mode 100644 libs/pbd/pbd/thrown_error.h create mode 100644 libs/pbd/pbd/tokenizer.h create mode 100644 libs/pbd/pbd/touchable.h create mode 100644 libs/pbd/pbd/transmitter.h create mode 100644 libs/pbd/pbd/undo.h create mode 100644 libs/pbd/pbd/whitespace.h create mode 100644 libs/pbd/pbd/xml++.h create mode 100644 libs/pbd/pool.cc create mode 100644 libs/pbd/pthread_utils.cc create mode 100644 libs/pbd/receiver.cc create mode 100644 libs/pbd/stacktrace.cc create mode 100644 libs/pbd/strsplit.cc create mode 100644 libs/pbd/textreceiver.cc create mode 100644 libs/pbd/transmitter.cc create mode 100644 libs/pbd/undo.cc create mode 100644 libs/pbd/whitespace.cc create mode 100644 libs/pbd/xml++.cc (limited to 'libs') diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index c42728f85b..c93a7c4593 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -106,7 +106,7 @@ arch_specific_objects = [ ] osc_files = [ 'osc.cc' ] vst_files = [ 'vst_plugin.cc', 'session_vst.cc' ] -coreaudio_files = [ 'coreaudio_source.cc' ] +coreaudio_files = [ 'coreaudiosource.cc' ] extra_sources = [ ] if ardour['VST']: @@ -206,7 +206,7 @@ ardour.Merge ([ libraries['lrdf'], libraries['samplerate'], libraries['sigc2'], - libraries['pbd3'], + libraries['pbd'], libraries['soundtouch'], libraries['midi++2'], libraries['glib2'], diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h index ecbac569d5..36251c07ff 100644 --- a/libs/ardour/ardour/audiofilesource.h +++ b/libs/ardour/ardour/audiofilesource.h @@ -42,7 +42,7 @@ class AudioFileSource : public AudioSource { Removable = 0x8, RemovableIfEmpty = 0x10, RemoveAtDestroy = 0x20, - BuildPeaks = 0x40 + NoPeakFile = 0x40 }; virtual ~AudioFileSource (); @@ -62,7 +62,7 @@ class AudioFileSource : public AudioSource { cannot. */ - static AudioFileSource* create (string path_plus_channel); + static AudioFileSource* create (const string& path_plus_channel, Flag flags = Flag (0)); static AudioFileSource* create (const XMLNode&); static bool get_soundfile_info (string path, SoundFileInfo& _info, string& error); @@ -97,7 +97,7 @@ class AudioFileSource : public AudioSource { static void set_search_path (string); static void set_header_position_offset (jack_nframes_t offset, bool negative); - static sigc::signal HeaderPositionOffsetChanged; + static sigc::signal HeaderPositionOffsetChanged; XMLNode& get_state (); int set_state (const XMLNode&); @@ -107,7 +107,7 @@ class AudioFileSource : public AudioSource { to cause issues. */ - void handle_header_position_change (struct tm*, time_t tnow); + void handle_header_position_change (); protected: diff --git a/libs/ardour/ardour/coreaudio_source.h b/libs/ardour/ardour/coreaudio_source.h deleted file mode 100644 index 81f1a14050..0000000000 --- a/libs/ardour/ardour/coreaudio_source.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __coreaudio_source_h__ -#define __coreaudio_source_h__ - -#include -#include - -namespace ARDOUR { - -class CoreAudioSource : public AudioFileSource { - public: - CoreAudioSource (const string& path_plus_channel, bool build_peak = true); - CoreAudioSource (const XMLNode&); - ~CoreAudioSource (); - - float sample_rate() const; - int update_header (jack_nframes_t when, struct tm&, time_t); - - protected: - jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const; - - private: - ExtAudioFileRef af; - uint16_t n_channels; - - mutable float *tmpbuf; - mutable jack_nframes_t tmpbufsize; - mutable Glib::Mutex _tmpbuf_lock; - - void init (const string &str, bool build_peak); -}; - -}; /* namespace ARDOUR */ - -#endif /* __coreaudio_source_h__ */ - diff --git a/libs/ardour/ardour/coreaudiosource.h b/libs/ardour/ardour/coreaudiosource.h new file mode 100644 index 0000000000..ba9f122fc9 --- /dev/null +++ b/libs/ardour/ardour/coreaudiosource.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2000 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __coreaudio_source_h__ +#define __coreaudio_source_h__ + +#include +#include + +namespace ARDOUR { + +class CoreAudioSource : public AudioFileSource { + public: + CoreAudioSource (const XMLNode&); + CoreAudioSource (const string& path_plus_channel, Flag); + ~CoreAudioSource (); + + float sample_rate() const; + int update_header (jack_nframes_t when, struct tm&, time_t); + + int flush_header () {return 0;}; + void set_header_timeline_position () {}; + + protected: + jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const; + + jack_nframes_t write_unlocked (Sample *dst, jack_nframes_t cnt, char * workbuf) + { return 0; } + + + private: + ExtAudioFileRef af; + uint16_t n_channels; + + mutable float *tmpbuf; + mutable jack_nframes_t tmpbufsize; + mutable Glib::Mutex _tmpbuf_lock; + + void init (const string &str); +}; + +}; /* namespace ARDOUR */ + +#endif /* __coreaudio_source_h__ */ + diff --git a/libs/ardour/ardour/destructive_filesource.h b/libs/ardour/ardour/destructive_filesource.h index c92a0762ee..2d10528ac8 100644 --- a/libs/ardour/ardour/destructive_filesource.h +++ b/libs/ardour/ardour/destructive_filesource.h @@ -32,8 +32,7 @@ namespace ARDOUR { class DestructiveFileSource : public SndFileSource { public: DestructiveFileSource (std::string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate, - Flag flags = AudioFileSource::Flag (AudioFileSource::Writable| - AudioFileSource::BuildPeaks)); + Flag flags = AudioFileSource::Flag (AudioFileSource::Writable)); DestructiveFileSource (const XMLNode&); ~DestructiveFileSource (); diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index f43e8273a7..a72289acd1 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -80,6 +80,9 @@ class Diskstream : public Stateful, public sigc::trackable void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; } uint32_t refcnt() const { return _refcnt; } + virtual float playback_buffer_load() const = 0; + virtual float capture_buffer_load() const = 0; + void set_flag (Flag f) { _flags |= f; } void unset_flag (Flag f) { _flags &= ~f; } @@ -106,6 +109,7 @@ class Diskstream : public Stateful, public sigc::trackable virtual void punch_out() {} virtual void set_speed (double); + virtual void non_realtime_set_speed () = 0; virtual Playlist *playlist () = 0; virtual int use_new_playlist () = 0; @@ -128,6 +132,9 @@ class Diskstream : public Stateful, public sigc::trackable /* Stateful */ virtual XMLNode& get_state(void) = 0; virtual int set_state(const XMLNode& node) = 0; + + // FIXME: makes sense for all diskstream types? + virtual void monitor_input (bool) {} jack_nframes_t capture_offset() const { return _capture_offset; } virtual void set_capture_offset (); @@ -166,7 +173,7 @@ class Diskstream : public Stateful, public sigc::trackable virtual void set_pending_overwrite (bool) = 0; virtual int overwrite_existing_buffers () = 0; virtual void reverse_scrub_buffer (bool to_forward) = 0; - //void set_block_size (jack_nframes_t); + virtual void set_block_size (jack_nframes_t) = 0; virtual int internal_playback_seek (jack_nframes_t distance) = 0; virtual int can_internal_playback_seek (jack_nframes_t distance) = 0; virtual int rename_write_sources () = 0; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 6284e94900..0e1b7627be 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -68,6 +68,7 @@ class AuxInput; class Source; class AudioSource; +class Diskstream; class AudioDiskstream; class AudioFileSource; class Auditioner; @@ -281,30 +282,25 @@ class Session : public sigc::trackable, public Stateful void refill_all_diskstream_buffers (); uint32_t diskstream_buffer_size() const { return dstream_buffer_size; } - /* XXX fix required here when we get new diskstream types *, but - not sure of the direction to take this in until then. - */ - - uint32_t get_next_diskstream_id() const { return n_audio_diskstreams(); } - uint32_t n_audio_diskstreams() const; + uint32_t get_next_diskstream_id() const { return n_diskstreams(); } + uint32_t n_diskstreams() const; - typedef list AudioDiskstreamList; + template void foreach_diskstream (T *obj, void (T::*func)(Diskstream&)); - Session::AudioDiskstreamList audio_disk_streams() const { + typedef list DiskstreamList; + + Session::DiskstreamList disk_streams() const { Glib::RWLock::ReaderLock lm (diskstream_lock); - return audio_diskstreams; /* XXX yes, force a copy */ + return diskstreams; /* XXX yes, force a copy */ } - void foreach_audio_diskstream (void (AudioDiskstream::*func)(void)); - template void foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&)); - typedef list RouteList; - + RouteList get_routes() const { Glib::RWLock::ReaderLock rlock (route_lock); return routes; /* XXX yes, force a copy */ } - + uint32_t nroutes() const { return routes.size(); } uint32_t ntracks () const; uint32_t nbusses () const; @@ -719,8 +715,6 @@ class Session : public sigc::trackable, public Stateful sigc::signal PlaylistAdded; sigc::signal PlaylistRemoved; - Playlist *get_playlist (string name); - uint32_t n_playlists() const; template void foreach_playlist (T *obj, void (T::*func)(Playlist *)); @@ -980,7 +974,7 @@ class Session : public sigc::trackable, public Stateful void set_frame_rate (jack_nframes_t nframes); protected: - friend class AudioDiskstream; + friend class Diskstream; void stop_butler (); void wait_till_butler_finished(); @@ -1475,7 +1469,7 @@ class Session : public sigc::trackable, public Stateful /* disk-streams */ - AudioDiskstreamList audio_diskstreams; + DiskstreamList diskstreams; mutable Glib::RWLock diskstream_lock; uint32_t dstream_buffer_size; void add_diskstream (Diskstream*); diff --git a/libs/ardour/ardour/session_diskstream.h b/libs/ardour/ardour/session_diskstream.h index 33fc5419ba..52db157f44 100644 --- a/libs/ardour/ardour/session_diskstream.h +++ b/libs/ardour/ardour/session_diskstream.h @@ -27,10 +27,10 @@ namespace ARDOUR { template void -Session::foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&)) +Session::foreach_diskstream (T *obj, void (T::*func)(Diskstream&)) { Glib::RWLock::ReaderLock lm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); i++) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); i++) { if (!(*i)->hidden()) { (obj->*func) (**i); } diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h index d146bb5793..5e3c1f621d 100644 --- a/libs/ardour/ardour/sndfilesource.h +++ b/libs/ardour/ardour/sndfilesource.h @@ -39,8 +39,7 @@ class SndFileSource : public AudioFileSource { Flag flags = AudioFileSource::Flag (AudioFileSource::Writable| AudioFileSource::Removable| AudioFileSource::RemovableIfEmpty| - AudioFileSource::CanRename| - AudioFileSource::BuildPeaks)); + AudioFileSource::CanRename)); /* constructor to be called for existing in-session files */ @@ -52,7 +51,7 @@ class SndFileSource : public AudioFileSource { int update_header (jack_nframes_t when, struct tm&, time_t); int flush_header (); - static Flag default_in_session_flags(); + void handle_smpte_offset_change (jack_nframes_t offset, bool negative); protected: void set_header_timeline_position (); diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 277fad0ae8..f24993b87b 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -55,10 +55,7 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -//sigc::signal AudioDiskstream::AudioDiskstreamCreated; sigc::signal*> AudioDiskstream::DeleteSources; -//sigc::signal AudioDiskstream::DiskOverrun; -//sigc::signal AudioDiskstream::DiskUnderrun; AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Diskstream::Flag flag) : Diskstream(sess, name, flag) @@ -295,9 +292,9 @@ AudioDiskstream::find_and_use_playlist (const string& name) Playlist* pl; AudioPlaylist* playlist; - if ((pl = _session.get_playlist (name)) == 0) { - error << string_compose(_("AudioDiskstream: Session doesn't know about a Playlist called \"%1\""), name) << endmsg; - return -1; + if ((pl = _session.playlist_by_name (name)) == 0) { + playlist = new AudioPlaylist(_session, name); + pl = playlist; } if ((playlist = dynamic_cast (pl)) == 0) { @@ -1630,6 +1627,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca srcs.push_back (s); if ((fsrc = dynamic_cast(s)) != 0) { + cerr << "updating source after capture\n"; fsrc->update_header (capture_info.front()->start, when, twhen); } diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index be5c9ab5d9..aa8940dce4 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -20,7 +20,7 @@ #include -#include +#include #include diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index 0f22ebbe44..82a2a38c2c 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -94,14 +94,6 @@ AudioTrack::~AudioTrack () } } -#if 0 -void -AudioTrack::handle_smpte_offset_change () -{ - diskstream -} -#endif - int AudioTrack::deprecated_use_diskstream_connections () { diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index 1e13a29acc..0663f5f9b1 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -42,7 +42,7 @@ // if these headers come before sigc++ is included // the parser throws ObjC++ errors. (nil is a keyword) #ifdef HAVE_COREAUDIO -#include +#include #include #include #endif // HAVE_COREAUDIO @@ -55,9 +55,9 @@ using namespace PBD; string AudioFileSource::peak_dir = ""; string AudioFileSource::search_path; -sigc::signal AudioFileSource::HeaderPositionOffsetChanged; -bool AudioFileSource::header_position_negative; -uint64_t AudioFileSource::header_position_offset; +sigc::signal AudioFileSource::HeaderPositionOffsetChanged; +bool AudioFileSource::header_position_negative; +uint64_t AudioFileSource::header_position_offset; char AudioFileSource::bwf_country_code[3] = "US"; char AudioFileSource::bwf_organization_code[4] = "LAS"; @@ -122,7 +122,6 @@ AudioFileSource::init (string pathstr, bool must_exist) next_peak_clear_should_notify = false; if (!find (pathstr, must_exist, is_new)) { - cerr << "cannot find " << pathstr << " with me = " << must_exist << endl; return -1; } @@ -211,16 +210,16 @@ AudioFileSource::create (const XMLNode& node) #ifdef HAVE_COREAUDIO AudioFileSource* -AudioFileSource::create (const string& idstr) +AudioFileSource::create (const string& idstr, Flag flags) { AudioFileSource* es = 0; try { - es = new CoreAudioSource (idstr); + es = new CoreAudioSource (idstr, flags); } catch (failed_constructor& err) { - es = new SndFileSource (idstr); + es = new SndFileSource (idstr, flags); } return es; @@ -229,9 +228,9 @@ AudioFileSource::create (const string& idstr) #else AudioFileSource* -AudioFileSource::create (string idstr) +AudioFileSource::create (const string& idstr, Flag flags) { - return new SndFileSource (idstr); + return new SndFileSource (idstr, flags); } #endif // HAVE_COREAUDIO @@ -595,32 +594,27 @@ AudioFileSource::set_search_path (string p) void AudioFileSource::set_header_position_offset (jack_nframes_t offset, bool negative) { - time_t tnow; - - time (&tnow); - header_position_offset = offset; header_position_negative = negative; - HeaderPositionOffsetChanged (localtime (&tnow), tnow); /* EMIT SIGNAL */ -} -void -AudioFileSource::set_timeline_position (jack_nframes_t pos) -{ - timeline_position = pos; + HeaderPositionOffsetChanged (); } -void -AudioFileSource::handle_header_position_change (struct tm* now, time_t tnow) +void +AudioFileSource::handle_header_position_change () { - /* don't do this if the file has never had its header flushed to disk yet */ - - if (writable() && _timestamp) { + if (writable()) { set_header_timeline_position (); flush_header (); } } +void +AudioFileSource::set_timeline_position (jack_nframes_t pos) +{ + timeline_position = pos; +} + void AudioFileSource::set_allow_remove_if_empty (bool yn) { @@ -655,8 +649,14 @@ AudioFileSource::set_name (string newname, bool destructive) bool AudioFileSource::is_empty (string path) { - /* XXX fix me */ + bool ret = false; + AudioFileSource* afs = create (path, NoPeakFile); - return false; + if (afs) { + ret = (afs->length() == 0); + delete afs; + } + + return ret; } diff --git a/libs/ardour/coreaudio_source.cc b/libs/ardour/coreaudio_source.cc deleted file mode 100644 index 1b0ee565e7..0000000000 --- a/libs/ardour/coreaudio_source.cc +++ /dev/null @@ -1,220 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include - -#include - -#include "i18n.h" - -#include - -using namespace ARDOUR; -using namespace PBD; - -CoreAudioSource::CoreAudioSource (const XMLNode& node) - : AudioFileSource (node) -{ - init (_name, true); - AudioSourceCreated (this); /* EMIT SIGNAL */ -} - -CoreAudioSource::CoreAudioSource (const string& idstr, bool build_peak) - : AudioFileSource(idstr, build_peak) -{ - init (idstr, build_peak); - - if (build_peak) { - AudioSourceCreated (this); /* EMIT SIGNAL */ - } -} - -void -CoreAudioSource::init (const string& idstr, bool build_peak) -{ - string::size_type pos; - string file; - - tmpbuf = 0; - tmpbufsize = 0; - af = 0; - OSStatus err = noErr; - - _name = idstr; - - if ((pos = idstr.find_last_of (':')) == string::npos) { - channel = 0; - file = idstr; - } else { - channel = atoi (idstr.substr (pos+1).c_str()); - file = idstr.substr (0, pos); - } - - /* note that we temporarily truncated _id at the colon */ - FSRef fsr; - err = FSPathMakeRef ((UInt8*)file.c_str(), &fsr, 0); - if (err != noErr) { - cerr << "FSPathMakeRef " << err << endl; - throw failed_constructor(); - } - - err = ExtAudioFileOpen (&fsr, &af); - if (err != noErr) { - cerr << "ExtAudioFileOpen " << err << endl; - ExtAudioFileDispose (af); - throw failed_constructor(); - } - - AudioStreamBasicDescription file_asbd; - memset(&file_asbd, 0, sizeof(AudioStreamBasicDescription)); - size_t asbd_size = sizeof(AudioStreamBasicDescription); - err = ExtAudioFileGetProperty(af, - kExtAudioFileProperty_FileDataFormat, &asbd_size, &file_asbd); - if (err != noErr) { - cerr << "ExtAudioFileGetProperty1 " << err << endl; - ExtAudioFileDispose (af); - throw failed_constructor(); - } - n_channels = file_asbd.mChannelsPerFrame; - - cerr << "number of channels: " << n_channels << endl; - - if (channel >= n_channels) { - error << string_compose(_("CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel number"), n_channels, channel) << endmsg; - ExtAudioFileDispose (af); - throw failed_constructor(); - } - - int64_t ca_frames; - size_t prop_size = sizeof(int64_t); - - err = ExtAudioFileGetProperty(af, kExtAudioFileProperty_FileLengthFrames, &prop_size, &ca_frames); - if (err != noErr) { - cerr << "ExtAudioFileGetProperty2 " << err << endl; - ExtAudioFileDispose (af); - throw failed_constructor(); - } - - _length = ca_frames; - _path = file; - - AudioStreamBasicDescription client_asbd; - memset(&client_asbd, 0, sizeof(AudioStreamBasicDescription)); - client_asbd.mSampleRate = file_asbd.mSampleRate; - client_asbd.mFormatID = kAudioFormatLinearPCM; - client_asbd.mFormatFlags = kLinearPCMFormatFlagIsFloat; - client_asbd.mBytesPerPacket = file_asbd.mChannelsPerFrame * 4; - client_asbd.mFramesPerPacket = 1; - client_asbd.mBytesPerFrame = client_asbd.mBytesPerPacket; - client_asbd.mChannelsPerFrame = file_asbd.mChannelsPerFrame; - client_asbd.mBitsPerChannel = 32; - - err = ExtAudioFileSetProperty (af, kExtAudioFileProperty_ClientDataFormat, asbd_size, &client_asbd); - if (err != noErr) { - cerr << "ExtAudioFileSetProperty3 " << err << endl; - ExtAudioFileDispose (af); - throw failed_constructor (); - } - - if (build_peak) { - if (initialize_peakfile (false, file)) { - error << "initialize peakfile failed" << endmsg; - ExtAudioFileDispose (af); - throw failed_constructor (); - } - } -} - -CoreAudioSource::~CoreAudioSource () -{ - GoingAway (this); /* EMIT SIGNAL */ - - if (af) { - ExtAudioFileDispose (af); - } - - if (tmpbuf) { - delete [] tmpbuf; - } -} - -jack_nframes_t -CoreAudioSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const -{ - OSStatus err = noErr; - - err = ExtAudioFileSeek(af, start); - if (err != noErr) { - error << string_compose(_("CoreAudioSource: could not seek to frame %1 within %2 (%3)"), start, _name.substr (1), err) << endmsg; - return 0; - } - - AudioBufferList abl; - abl.mNumberBuffers = 1; - abl.mBuffers[0].mNumberChannels = n_channels; - abl.mBuffers[0].mDataByteSize = cnt * sizeof(Sample); - abl.mBuffers[0].mData = dst; - - if (n_channels == 1) { - err = ExtAudioFileRead(af, (UInt32*) &cnt, &abl); - _read_data_count = cnt * sizeof(float); - return cnt; - } - - uint32_t real_cnt = cnt * n_channels; - - { - Glib::Mutex::Lock lm (_tmpbuf_lock); - - if (tmpbufsize < real_cnt) { - - if (tmpbuf) { - delete [] tmpbuf; - } - tmpbufsize = real_cnt; - tmpbuf = new float[tmpbufsize]; - } - - abl.mBuffers[0].mDataByteSize = real_cnt * sizeof(Sample); - abl.mBuffers[0].mData = tmpbuf; - - err = ExtAudioFileRead(af, (UInt32*) &real_cnt, &abl); - float *ptr = tmpbuf + channel; - real_cnt /= n_channels; - - /* stride through the interleaved data */ - - for (uint32_t n = 0; n < real_cnt; ++n) { - dst[n] = *ptr; - ptr += n_channels; - } - } - - _read_data_count = cnt * sizeof(float); - - return real_cnt; -} - -float -CoreAudioSource::sample_rate() const -{ - /* XXX taybin fill me in please */ - - return 44100.0f; -} diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc new file mode 100644 index 0000000000..55409a8524 --- /dev/null +++ b/libs/ardour/coreaudiosource.cc @@ -0,0 +1,218 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include + +#include "i18n.h" + +#include + +using namespace ARDOUR; +using namespace PBD; + +CoreAudioSource::CoreAudioSource (const XMLNode& node) + : AudioFileSource (node) +{ + init (_name); + + AudioSourceCreated (this); /* EMIT SIGNAL */ +} + +CoreAudioSource::CoreAudioSource (const string& idstr, Flag flags) + : AudioFileSource(idstr, flags) +{ + init (idstr); + + AudioSourceCreated (this); /* EMIT SIGNAL */ +} + +void +CoreAudioSource::init (const string& idstr) +{ + string::size_type pos; + string file; + + tmpbuf = 0; + tmpbufsize = 0; + af = 0; + OSStatus err = noErr; + + _name = idstr; + + if ((pos = idstr.find_last_of (':')) == string::npos) { + channel = 0; + file = idstr; + } else { + channel = atoi (idstr.substr (pos+1).c_str()); + file = idstr.substr (0, pos); + } + + /* note that we temporarily truncated _id at the colon */ + FSRef fsr; + err = FSPathMakeRef ((UInt8*)file.c_str(), &fsr, 0); + if (err != noErr) { + cerr << "FSPathMakeRef " << err << endl; + throw failed_constructor(); + } + + err = ExtAudioFileOpen (&fsr, &af); + if (err != noErr) { + cerr << "ExtAudioFileOpen " << err << endl; + ExtAudioFileDispose (af); + throw failed_constructor(); + } + + AudioStreamBasicDescription file_asbd; + memset(&file_asbd, 0, sizeof(AudioStreamBasicDescription)); + size_t asbd_size = sizeof(AudioStreamBasicDescription); + err = ExtAudioFileGetProperty(af, + kExtAudioFileProperty_FileDataFormat, &asbd_size, &file_asbd); + if (err != noErr) { + cerr << "ExtAudioFileGetProperty1 " << err << endl; + ExtAudioFileDispose (af); + throw failed_constructor(); + } + n_channels = file_asbd.mChannelsPerFrame; + + cerr << "number of channels: " << n_channels << endl; + + if (channel >= n_channels) { + error << string_compose(_("CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel number"), n_channels, channel) << endmsg; + ExtAudioFileDispose (af); + throw failed_constructor(); + } + + int64_t ca_frames; + size_t prop_size = sizeof(int64_t); + + err = ExtAudioFileGetProperty(af, kExtAudioFileProperty_FileLengthFrames, &prop_size, &ca_frames); + if (err != noErr) { + cerr << "ExtAudioFileGetProperty2 " << err << endl; + ExtAudioFileDispose (af); + throw failed_constructor(); + } + + _length = ca_frames; + _path = file; + + AudioStreamBasicDescription client_asbd; + memset(&client_asbd, 0, sizeof(AudioStreamBasicDescription)); + client_asbd.mSampleRate = file_asbd.mSampleRate; + client_asbd.mFormatID = kAudioFormatLinearPCM; + client_asbd.mFormatFlags = kLinearPCMFormatFlagIsFloat; + client_asbd.mBytesPerPacket = file_asbd.mChannelsPerFrame * 4; + client_asbd.mFramesPerPacket = 1; + client_asbd.mBytesPerFrame = client_asbd.mBytesPerPacket; + client_asbd.mChannelsPerFrame = file_asbd.mChannelsPerFrame; + client_asbd.mBitsPerChannel = 32; + + err = ExtAudioFileSetProperty (af, kExtAudioFileProperty_ClientDataFormat, asbd_size, &client_asbd); + if (err != noErr) { + cerr << "ExtAudioFileSetProperty3 " << err << endl; + ExtAudioFileDispose (af); + throw failed_constructor (); + } + + if (_build_peakfiles) { + if (initialize_peakfile (false, file)) { + error << "initialize peakfile failed" << endmsg; + ExtAudioFileDispose (af); + throw failed_constructor (); + } + } +} + +CoreAudioSource::~CoreAudioSource () +{ + GoingAway (this); /* EMIT SIGNAL */ + + if (af) { + ExtAudioFileDispose (af); + } + + if (tmpbuf) { + delete [] tmpbuf; + } +} + +jack_nframes_t +CoreAudioSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const +{ + OSStatus err = noErr; + + err = ExtAudioFileSeek(af, start); + if (err != noErr) { + error << string_compose(_("CoreAudioSource: could not seek to frame %1 within %2 (%3)"), start, _name.substr (1), err) << endmsg; + return 0; + } + + AudioBufferList abl; + abl.mNumberBuffers = 1; + abl.mBuffers[0].mNumberChannels = n_channels; + abl.mBuffers[0].mDataByteSize = cnt * sizeof(Sample); + abl.mBuffers[0].mData = dst; + + if (n_channels == 1) { + err = ExtAudioFileRead(af, (UInt32*) &cnt, &abl); + _read_data_count = cnt * sizeof(float); + return cnt; + } + + uint32_t real_cnt = cnt * n_channels; + + { + Glib::Mutex::Lock lm (_tmpbuf_lock); + + if (tmpbufsize < real_cnt) { + + if (tmpbuf) { + delete [] tmpbuf; + } + tmpbufsize = real_cnt; + tmpbuf = new float[tmpbufsize]; + } + + abl.mBuffers[0].mDataByteSize = real_cnt * sizeof(Sample); + abl.mBuffers[0].mData = tmpbuf; + + err = ExtAudioFileRead(af, (UInt32*) &real_cnt, &abl); + float *ptr = tmpbuf + channel; + real_cnt /= n_channels; + + /* stride through the interleaved data */ + + for (uint32_t n = 0; n < real_cnt; ++n) { + dst[n] = *ptr; + ptr += n_channels; + } + } + + _read_data_count = cnt * sizeof(float); + + return real_cnt; +} + +float +CoreAudioSource::sample_rate() const +{ + /* XXX taybin fill me in please */ + + return 44100.0f; +} diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 0af4af4f7c..fdf9092308 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -55,10 +55,7 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -//sigc::signal MidiDiskstream::MidiDiskstreamCreated; sigc::signal*> MidiDiskstream::DeleteSources; -//sigc::signal MidiDiskstream::DiskOverrun; -//sigc::signal MidiDiskstream::DiskUnderrun; MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag) : Diskstream(sess, name, flag) @@ -154,13 +151,13 @@ MidiDiskstream::find_and_use_playlist (const string& name) Playlist* pl; MidiPlaylist* playlist; - if ((pl = _session.get_playlist (name)) == 0) { - error << string_compose(_("MidiDiskstream: Session doesn't know about a Playlist called \"%1\""), name) << endmsg; - return -1; + if ((pl = _session.playlist_by_name (name)) == 0) { + playlist = new MidiPlaylist(_session, name); + pl = playlist; } if ((playlist = dynamic_cast (pl)) == 0) { - error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't an midi playlist"), name) << endmsg; + error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't a midi playlist"), name) << endmsg; return -1; } diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index d4f7be1e6f..4a9febcdca 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -186,32 +186,30 @@ MidiTrack::set_diskstream (MidiDiskstream& ds, void *src) int MidiTrack::use_diskstream (string name) { - /* MidiDiskstream *dstream; - if ((dstream = _session.diskstream_by_name (name)) == 0) { + if ((dstream = dynamic_cast(_session.diskstream_by_name (name))) == 0) { PBD::error << string_compose(_("MidiTrack: diskstream \"%1\" not known by session"), name) << endmsg; return -1; } return set_diskstream (*dstream, this); - */ + return 0; } int MidiTrack::use_diskstream (id_t id) { - /* MidiDiskstream *dstream; - if ((dstream = _session.diskstream_by_id (id)) == 0) { + if ((dstream = dynamic_cast(_session.diskstream_by_id (id))) == 0) { PBD::error << string_compose(_("MidiTrack: diskstream \"%1\" not known by session"), id) << endmsg; return -1; } return set_diskstream (*dstream, this); - */ + return 0; } diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc index 2d1f8ffcbd..9fc6c57909 100644 --- a/libs/ardour/plugin.cc +++ b/libs/ardour/plugin.cc @@ -127,10 +127,16 @@ Plugin::MIDIPortControl::set_value (float value) value = 0.0; } } else { - value = lower + (range * value); - - if (logarithmic) { - value = exp(value); + + if (!logarithmic) { + value = lower + (range * value); + } else { + float _lower = 0.0f; + if (lower > 0.0f) { + _lower = log(lower); + } + + value = exp(_lower + log(range) * value); } } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index c6c6f0444c..2fcd09a31c 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -462,10 +462,10 @@ Session::~Session () } #ifdef TRACK_DESTRUCTION - cerr << "delete audio_diskstreams\n"; + cerr << "delete diskstreams\n"; #endif /* TRACK_DESTRUCTION */ - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ) { - AudioDiskstreamList::iterator tmp; + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) { + DiskstreamList::iterator tmp; tmp = i; ++tmp; @@ -973,7 +973,7 @@ Session::set_auto_input (bool yn) The rarity and short potential lock duration makes this "OK" */ Glib::RWLock::ReaderLock dsm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->record_enabled ()) { //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl; (*i)->monitor_input (!auto_input); @@ -991,7 +991,7 @@ Session::reset_input_monitor_state () { if (transport_rolling()) { Glib::RWLock::ReaderLock dsm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->record_enabled ()) { //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl; (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input); @@ -999,7 +999,7 @@ Session::reset_input_monitor_state () } } else { Glib::RWLock::ReaderLock dsm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->record_enabled ()) { //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl; (*i)->monitor_input (Config->get_use_hardware_monitoring()); @@ -1080,7 +1080,7 @@ Session::auto_loop_changed (Location* location) } else if (seamless_loop && !loop_changing) { - // schedule a locate-roll to refill the audio_diskstreams at the + // schedule a locate-roll to refill the diskstreams at the // previous loop end loop_changing = true; @@ -1277,7 +1277,7 @@ Session::enable_record () */ Glib::RWLock::ReaderLock dsm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->record_enabled ()) { (*i)->monitor_input (true); } @@ -1316,7 +1316,7 @@ Session::disable_record (bool rt_context, bool force) */ Glib::RWLock::ReaderLock dsm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->record_enabled ()) { (*i)->monitor_input (false); } @@ -1343,7 +1343,7 @@ Session::step_back_from_record () */ Glib::RWLock::ReaderLock dsm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (auto_input && (*i)->record_enabled ()) { //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; (*i)->monitor_input (false); @@ -1512,7 +1512,7 @@ Session::set_block_size (jack_nframes_t nframes) (*i)->set_block_size (nframes); } - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { (*i)->set_block_size (nframes); } @@ -2115,21 +2115,14 @@ Session::add_route (Route* route) } void -Session::add_diskstream (Diskstream* s) +Session::add_diskstream (Diskstream* dstream) { - // FIXME: temporary. duh. - AudioDiskstream* dstream = dynamic_cast(s); - if (!dstream) { - cerr << "FIXME: Non Audio Diskstream" << endl; - return; - } - /* need to do this in case we're rolling at the time, to prevent false underruns */ dstream->non_realtime_do_refill(); { Glib::RWLock::WriterLock lm (diskstream_lock); - audio_diskstreams.push_back (dstream); + diskstreams.push_back (dstream); } /* take a reference to the diskstream, preventing it from @@ -2194,7 +2187,7 @@ Session::remove_route (Route& route) { Glib::RWLock::WriterLock lm (diskstream_lock); - audio_diskstreams.remove (ds); + diskstreams.remove (ds); } ds->unref (); @@ -2483,7 +2476,7 @@ Session::get_maximum_extent () const ensure atomicity. */ - for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { Playlist* pl = (*i)->playlist(); if ((me = pl->get_maximum_extent()) > max) { max = me; @@ -2499,7 +2492,7 @@ Session::diskstream_by_name (string name) Glib::RWLock::ReaderLock lm (diskstream_lock); // FIXME: duh - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->name() == name) { return* i; } @@ -2514,7 +2507,7 @@ Session::diskstream_by_id (id_t id) Glib::RWLock::ReaderLock lm (diskstream_lock); // FIXME: duh - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->id() == id) { return *i; } @@ -2840,7 +2833,7 @@ Session::remove_last_capture () Glib::RWLock::ReaderLock lm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { list& l = (*i)->last_capture_regions(); if (!l.empty()) { @@ -3151,18 +3144,6 @@ Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bo /* Playlist management */ -Playlist * -Session::get_playlist (string name) -{ - Playlist* ret = 0; - - if ((ret = playlist_by_name (name)) == 0) { - ret = new AudioPlaylist (*this, name); - } - - return ret; -} - Playlist * Session::playlist_by_name (string name) { @@ -3385,29 +3366,30 @@ Session::set_all_mute (bool yn) } uint32_t -Session::n_audio_diskstreams () const +Session::n_diskstreams () const { Glib::RWLock::ReaderLock lm (diskstream_lock); uint32_t n = 0; - for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (!(*i)->hidden()) { n++; } } return n; } - +/* void Session::foreach_audio_diskstream (void (AudioDiskstream::*func)(void)) { Glib::RWLock::ReaderLock lm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (!(*i)->hidden()) { ((*i)->*func)(); } } } +*/ void Session::graph_reordered () @@ -3429,7 +3411,7 @@ Session::graph_reordered () reflect any changes in latencies within the graph. */ - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { (*i)->set_capture_offset (); } } @@ -3712,7 +3694,7 @@ Session::reset_native_file_format () //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__); Glib::RWLock::ReaderLock lm2 (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { (*i)->reset_write_sources (false); } } diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc index b1451912d0..f0a2af0a83 100644 --- a/libs/ardour/session_butler.cc +++ b/libs/ardour/session_butler.cc @@ -168,7 +168,7 @@ Session::butler_thread_work () struct timeval begin, end; struct pollfd pfd[1]; bool disk_work_outstanding = false; - AudioDiskstreamList::iterator i; + DiskstreamList::iterator i; butler_mixdown_buffer = new Sample[AudioDiskstream::disk_io_frames()]; butler_gain_buffer = new gain_t[AudioDiskstream::disk_io_frames()]; @@ -239,7 +239,7 @@ Session::butler_thread_work () } } - //for (i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + //for (i = diskstreams.begin(); i != diskstreams.end(); ++i) { // cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl; //} @@ -255,15 +255,17 @@ Session::butler_thread_work () Glib::RWLock::ReaderLock dsm (diskstream_lock); - for (i = audio_diskstreams.begin(); !transport_work_requested() && butler_should_run && i != audio_diskstreams.end(); ++i) { + for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) { // cerr << "rah fondr " << (*i)->io()->name () << endl; + AudioDiskstream* ads = dynamic_cast(*i); + if (!ads) continue; // FIXME - switch ((*i)->do_refill (butler_mixdown_buffer, butler_gain_buffer, conv_buffer)) { + switch (ads->do_refill (butler_mixdown_buffer, butler_gain_buffer, conv_buffer)) { case 0: - bytes += (*i)->read_data_count(); + bytes += ads->read_data_count(); break; case 1: - bytes += (*i)->read_data_count(); + bytes += ads->read_data_count(); disk_work_outstanding = true; break; @@ -275,7 +277,7 @@ Session::butler_thread_work () } - if (i != audio_diskstreams.end()) { + if (i != diskstreams.end()) { /* we didn't get to all the streams */ disk_work_outstanding = true; } @@ -297,7 +299,7 @@ Session::butler_thread_work () compute_io = true; gettimeofday (&begin, 0); - for (i = audio_diskstreams.begin(); !transport_work_requested() && butler_should_run && i != audio_diskstreams.end(); ++i) { + for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) { // cerr << "write behind for " << (*i)->name () << endl; switch ((*i)->do_flush (conv_buffer)) { @@ -326,7 +328,7 @@ Session::butler_thread_work () request_stop (); } - if (i != audio_diskstreams.end()) { + if (i != diskstreams.end()) { /* we didn't get to all the streams */ disk_work_outstanding = true; } @@ -353,7 +355,7 @@ Session::butler_thread_work () Glib::Mutex::Lock lm (butler_request_lock); if (butler_should_run && (disk_work_outstanding || transport_work_requested())) { -// for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { +// for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { // cerr << "AFTER " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl; // } @@ -393,7 +395,7 @@ Session::overwrite_some_buffers (Diskstream* ds) } else { Glib::RWLock::ReaderLock dm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { (*i)->set_pending_overwrite (true); } } diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index ddced9cc5f..37365c8403 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -495,7 +495,7 @@ Session::prepare_to_export (AudioExportSpecification& spec) { Glib::RWLock::ReaderLock lm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)-> seek (spec.start_frame, true)) { error << string_compose (_("%1: cannot seek to %2 for export"), (*i)->name(), spec.start_frame) diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 23e7757c9d..9e3809f6b8 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -74,7 +74,7 @@ Session::process (jack_nframes_t nframes) void Session::prepare_diskstreams () { - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { (*i)->prepare (); } } @@ -151,7 +151,7 @@ Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset) call path, so make sure we release any outstanding locks here before we return failure. */ - for (AudioDiskstreamList::iterator ids = audio_diskstreams.begin(); ids != audio_diskstreams.end(); ++ids) { + for (DiskstreamList::iterator ids = diskstreams.begin(); ids != diskstreams.end(); ++ids) { (*ids)->recover (); } @@ -190,7 +190,7 @@ Session::silent_process_routes (jack_nframes_t nframes, jack_nframes_t offset) call path, so make sure we release any outstanding locks here before we return failure. */ - for (AudioDiskstreamList::iterator ids = audio_diskstreams.begin(); ids != audio_diskstreams.end(); ++ids) { + for (DiskstreamList::iterator ids = diskstreams.begin(); ids != diskstreams.end(); ++ids) { (*ids)->recover (); } @@ -209,7 +209,7 @@ Session::commit_diskstreams (jack_nframes_t nframes, bool &needs_butler) float pworst = 1.0f; float cworst = 1.0f; - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->hidden()) { continue; @@ -579,7 +579,7 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset) bool ok = true; jack_nframes_t frame_delta = slave_transport_frame - _transport_frame; - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (!(*i)->can_internal_playback_seek (frame_delta)) { ok = false; break; @@ -587,7 +587,7 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset) } if (ok) { - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { (*i)->internal_playback_seek (frame_delta); } _transport_frame += frame_delta; diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 12092b1bad..9f21eb5c4e 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -270,7 +271,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source)); Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist)); Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect)); - AudioDiskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream)); + Diskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream)); NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection)); IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers)); @@ -624,12 +625,16 @@ Session::load_diskstreams (const XMLNode& node) clist = node.children(); for (citer = clist.begin(); citer != clist.end(); ++citer) { - - AudioDiskstream* dstream; + Diskstream* dstream = NULL; try { - dstream = new AudioDiskstream (*this, **citer); - /* added automatically by AudioDiskstreamCreated handler */ + if ((*citer)->name() == "AudioDiskstream") { + dstream = new AudioDiskstream (*this, **citer); + /* added automatically by DiskstreamCreated handler */ + } else { + assert((*citer)->name() == "MidiDiskstream"); + dstream = new MidiDiskstream (*this, **citer); + } } catch (failed_constructor& err) { @@ -1380,7 +1385,7 @@ Session::state(bool full_state) { Glib::RWLock::ReaderLock dl (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (!(*i)->hidden()) { child->add_child_nocopy ((*i)->get_state()); } diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc index 0db3afcee6..494a78ae88 100644 --- a/libs/ardour/session_time.cc +++ b/libs/ardour/session_time.cc @@ -113,7 +113,6 @@ Session::set_smpte_offset_negative (bool neg) SMPTEOffsetChanged (); /* EMIT SIGNAL */ } - void Session::smpte_to_sample( SMPTE::Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const { diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index d7ab60f3fb..6a92d71d1c 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -206,7 +206,7 @@ Session::butler_transport_work () } if (post_transport_work & PostTransportInputChange) { - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { (*i)->non_realtime_input_change (); } } @@ -222,7 +222,7 @@ Session::butler_transport_work () cumulative_rf_motion = 0; reset_rf_scale (0); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (!(*i)->hidden()) { if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) { (*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed())); @@ -254,7 +254,7 @@ Session::non_realtime_set_speed () { Glib::RWLock::ReaderLock lm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { (*i)->non_realtime_set_speed (); } } @@ -264,7 +264,7 @@ Session::non_realtime_overwrite () { Glib::RWLock::ReaderLock lm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->pending_overwrite) { (*i)->overwrite_existing_buffers (); } @@ -280,7 +280,7 @@ Session::non_realtime_stop (bool abort) did_record = false; - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->get_captured_frames () != 0) { did_record = true; break; @@ -333,7 +333,7 @@ Session::non_realtime_stop (bool abort) _have_captured = true; } - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { (*i)->transport_stopped (*now, xnow, abort); } @@ -370,7 +370,7 @@ Session::non_realtime_stop (bool abort) } #endif - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (!(*i)->hidden()) { if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) { (*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed())); @@ -494,7 +494,7 @@ Session::set_auto_loop (bool yn) if (seamless_loop) { // set all diskstreams to use internal looping - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (!(*i)->hidden()) { (*i)->set_loop (loc); } @@ -502,7 +502,7 @@ Session::set_auto_loop (bool yn) } else { // set all diskstreams to NOT use internal looping - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (!(*i)->hidden()) { (*i)->set_loop (0); } @@ -532,7 +532,7 @@ Session::set_auto_loop (bool yn) clear_events (Event::AutoLoop); // set all diskstreams to NOT use internal looping - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (!(*i)->hidden()) { (*i)->set_loop (0); } @@ -653,7 +653,7 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b The rarity and short potential lock duration makes this "OK" */ Glib::RWLock::ReaderLock dsm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->record_enabled ()) { //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; (*i)->monitor_input (!auto_input); @@ -668,7 +668,7 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b The rarity and short potential lock duration makes this "OK" */ Glib::RWLock::ReaderLock dsm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->record_enabled ()) { //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl; (*i)->monitor_input (true); @@ -714,7 +714,7 @@ Session::set_transport_speed (float speed, bool abort) The rarity and short potential lock duration makes this "OK" */ Glib::RWLock::ReaderLock dsm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->record_enabled ()) { //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl; (*i)->monitor_input (true); @@ -740,7 +740,7 @@ Session::set_transport_speed (float speed, bool abort) The rarity and short potential lock duration makes this "OK" */ Glib::RWLock::ReaderLock dsm (diskstream_lock); - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (auto_input && (*i)->record_enabled ()) { //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; (*i)->monitor_input (false); @@ -791,7 +791,7 @@ Session::set_transport_speed (float speed, bool abort) _last_transport_speed = _transport_speed; _transport_speed = speed; - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->realtime_set_speed ((*i)->speed(), true)) { post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed); } @@ -881,7 +881,7 @@ Session::actually_start_transport () transport_sub_state |= PendingDeclickIn; _transport_speed = 1.0; - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { (*i)->realtime_set_speed ((*i)->speed(), true); } @@ -1014,7 +1014,7 @@ Session::set_slave_source (SlaveSource src, jack_nframes_t frame) _slave_type = src; - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if (!(*i)->hidden()) { if ((*i)->realtime_set_speed ((*i)->speed(), true)) { non_rt_required = true; @@ -1242,7 +1242,7 @@ Session::update_latency_compensation (bool with_stop, bool abort) /* reflect any changes in latencies into capture offsets */ - for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) { + for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { (*i)->set_capture_offset (); } } diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index 24a70f636b..443a24e3c2 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -55,6 +55,7 @@ SndFileSource::SndFileSource (const XMLNode& node) } SndFileSource::SndFileSource (string idstr, Flag flags) + /* files created this way are never writable or removable */ : AudioFileSource (idstr, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) { init (idstr); @@ -63,7 +64,7 @@ SndFileSource::SndFileSource (string idstr, Flag flags) throw failed_constructor (); } - if (_build_peakfiles) { + if (!(_flags & NoPeakFile) && _build_peakfiles) { if (initialize_peakfile (false, _path)) { sf_close (sf); sf = 0; @@ -170,9 +171,10 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, delete _broadcast_info; _broadcast_info = 0; } + } - if (_build_peakfiles) { + if (!(_flags & NoPeakFile) && _build_peakfiles) { if (initialize_peakfile (true, _path)) { sf_close (sf); sf = 0; @@ -180,12 +182,6 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, } } - /* since SndFileSource's constructed with this constructor can be writable, make sure we update if the header info changes */ - - if (writable()) { - HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioFileSource::handle_header_position_change)); - } - AudioSourceCreated (this); /* EMIT SIGNAL */ } @@ -235,34 +231,56 @@ SndFileSource::open () _length = _info.frames; + + _broadcast_info = (SF_BROADCAST_INFO*) calloc (1, sizeof (SF_BROADCAST_INFO)); + + /* lookup broadcast info */ + + if (sf_command (sf, SFC_GET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) { + + /* if the file has data but no broadcast info, then clearly, there is no broadcast info */ + + if (_length) { + free (_broadcast_info); + _broadcast_info = 0; + _flags = Flag (_flags & ~Broadcast); + } + + } else { + + /* XXX 64 bit alert: when JACK switches to a 64 bit frame count, this needs to use the high bits + of the time reference. + */ + + set_timeline_position (_broadcast_info->time_reference_low); + } + if (writable()) { sf_command (sf, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE); + + /* update header if header offset info changes */ + + AudioFileSource::HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioFileSource::handle_header_position_change)); } return 0; } -void -SndFileSource::close () +SndFileSource::~SndFileSource () { + GoingAway (this); /* EMIT SIGNAL */ + if (sf) { sf_close (sf); sf = 0; } -} - -SndFileSource::~SndFileSource () -{ - GoingAway (this); /* EMIT SIGNAL */ - - close (); if (interleave_buf) { delete [] interleave_buf; } if (_broadcast_info) { - delete [] _broadcast_info; + free (_broadcast_info); } } @@ -404,27 +422,38 @@ SndFileSource::write_unlocked (Sample *data, jack_nframes_t cnt, char * workbuf) int SndFileSource::update_header (jack_nframes_t when, struct tm& now, time_t tnow) { - /* allow derived classes to override how this is done */ - set_timeline_position (when); if (_flags & Broadcast) { - /* this will flush the header implicitly */ - return setup_broadcast_info (when, now, tnow); - } else { - return flush_header (); - } + if (setup_broadcast_info (when, now, tnow)) { + return -1; + } + } + + return flush_header (); } int SndFileSource::flush_header () { + if (!writable() || (sf == 0)) { + return -1; + } + return (sf_command (sf, SFC_UPDATE_HEADER_NOW, 0, 0) != SF_TRUE); } int SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t tnow) { + if (!writable()) { + return -1; + } + + if (!(_flags & Broadcast)) { + return 0; + } + /* random code is 9 digits */ int random_code = random() % 999999999; @@ -452,12 +481,10 @@ SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t set_header_timeline_position (); - /* note that libsndfile flushes the header to disk when resetting the broadcast info */ - if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) { error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg; _flags = Flag (_flags & ~Broadcast); - delete _broadcast_info; + free (_broadcast_info); _broadcast_info = 0; return -1; } @@ -470,6 +497,10 @@ SndFileSource::set_header_timeline_position () { uint64_t pos; + if (!(_flags & Broadcast)) { + return; + } + _broadcast_info->time_reference_high = 0; if (header_position_negative) { @@ -491,6 +522,13 @@ SndFileSource::set_header_timeline_position () _broadcast_info->time_reference_high = (pos >> 32); _broadcast_info->time_reference_low = (pos & 0xffffffff); + + if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) { + error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg; + _flags = Flag (_flags & ~Broadcast); + free (_broadcast_info); + _broadcast_info = 0; + } } jack_nframes_t diff --git a/libs/cassowary/.cvsignore b/libs/cassowary/.cvsignore deleted file mode 100644 index 532f703477..0000000000 --- a/libs/cassowary/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -ClReader-lex.cc -ClReader.cc -ClReader.cc.h diff --git a/libs/cassowary/ANNOUNCE b/libs/cassowary/ANNOUNCE deleted file mode 100644 index e0137fa643..0000000000 --- a/libs/cassowary/ANNOUNCE +++ /dev/null @@ -1,37 +0,0 @@ -Announcing the release of a free (for research use) constraint solver: - -Cassowary Constraint Solver for Smalltalk, C++, and Java -Version 0.60 - -Web Page: http://www.cs.washington.edu/research/constraints/cassowary -Distribution: ftp://ftp.cs.washington.edu:/pub/constraints/code/cassowary/ -Contact: cassowary@cs.washington.edu - -Greg J. Badros and -Alan Borning -University of Washington -Computer Science and Engineering -15-December-1999 - -with Constraint Drawing Applet (CDA) by Michael Noth - -Cassowary is an incremental constraint solving toolkit that efficiently -solves systems of linear equalities and inequalities. Constraints may -be either requirements or preferences. Client code specifies the -constraints to be maintained, and the solver updates the constrained -variables to have values that satisfy the constraints. - -A technical report is included in the distribution that describes the -algorithm, interface, and implementation of the Cassowary solver. -Additionally, the distribution contains toy sample applications written -in Smalltalk, C++, Java, and Python, and a more complex example Java -applet, the "Constraint Drawing Application". - -More information is available on our web page: - -http://www.cs.washington.edu/research/constraints/cassowary - -See README for more details on getting started using these packages. -See NEWS for a history of user-visible changes. -See LICENSE for legalese regarding use of this distribution. - diff --git a/libs/cassowary/AUTHORS b/libs/cassowary/AUTHORS deleted file mode 100644 index 51d8592e6f..0000000000 --- a/libs/cassowary/AUTHORS +++ /dev/null @@ -1,12 +0,0 @@ -Cassowary Constraint Solving Toolkit was -Implemented by: - -Greg J. Badros and -Alan Borning -University of Washington -Computer Science and Engineering -Seattle, WA 98195-2350 - -with Constraint Drawing Applet (CDA) by Michael Noth - -Please send bug reports to cassowary@cs.washington.edu diff --git a/libs/cassowary/COPYING b/libs/cassowary/COPYING deleted file mode 100644 index d60c31a97a..0000000000 --- a/libs/cassowary/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/libs/cassowary/COPYING.LGPL b/libs/cassowary/COPYING.LGPL deleted file mode 100644 index 5f66256a83..0000000000 --- a/libs/cassowary/COPYING.LGPL +++ /dev/null @@ -1,444 +0,0 @@ -GNU LESSER GENERAL PUBLIC LICENSE - -Version 2.1, February 1999 - -Copyright (C) 1991, 1999 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - -Preamble - -The licenses for most software are designed to take away your freedom to -share and change it. By contrast, the GNU General Public Licenses are -intended to guarantee your freedom to share and change free software--to -make sure the software is free for all its users. - -This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the Free -Software Foundation and other authors who decide to use it. You can use -it too, but we suggest you first think carefully about whether this -license or the ordinary General Public License is the better strategy to -use in any particular case, based on the explanations below. - -When we speak of free software, we are referring to freedom of use, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish); that you receive source code or can get it if -you want it; that you can change the software and use pieces of it in -new free programs; and that you are informed that you can do these -things. - -To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for you -if you distribute copies of the library or if you modify it. - -For example, if you distribute copies of the library, whether gratis or -for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide complete -object files to the recipients, so that they can relink them with the -library after making changes to the library and recompiling it. And you -must show them these terms so they know their rights. - -We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - -To protect each distributor, we want to make it very clear that there is -no warranty for the free library. Also, if the library is modified by -someone else and passed on, the recipients should know that what they -have is not the original version, so that the original author's -reputation will not be affected by problems that might be introduced by -others. - -Finally, software patents pose a constant threat to the existence of any -free program. We wish to make sure that a company cannot effectively -restrict the users of a free program by obtaining a restrictive license -from a patent holder. Therefore, we insist that any patent license -obtained for a version of the library must be consistent with the full -freedom of use specified in this license. - -Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License. This license, the GNU Lesser General Public -License, applies to certain designated libraries, and is quite different -from the ordinary General Public License. We use this license for -certain libraries in order to permit linking those libraries into -non-free programs. - -When a program is linked with a library, whether statically or using a -shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the entire -combination fits its criteria of freedom. The Lesser General Public -License permits more lax criteria for linking other code with the -library. - -We call this license the "Lesser" General Public License because it does -Less to protect the user's freedom than the ordinary General Public -License. It also provides other free software developers Less of an -advantage over competing non-free programs. These disadvantages are the -reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - -For example, on rare occasions, there may be a special need to encourage -the widest possible use of a certain library, so that it becomes a -de-facto standard. To achieve this, non-free programs must be allowed to -use the library. A more frequent case is that a free library does the -same job as widely used non-free libraries. In this case, there is -little to gain by limiting the free library to free software only, so we -use the Lesser General Public License. - -In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of free -software. For example, permission to use the GNU C Library in non-free -programs enables many more people to use the whole GNU operating system, -as well as its variant, the GNU/Linux operating system. - -Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is linked -with the Library has the freedom and the wherewithal to run that program -using a modified version of the Library. - -The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or other -authorized party saying it may be distributed under the terms of this -Lesser General Public License (also called "this License"). Each -licensee is addressed as "you". - -A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - -The "Library", below, refers to any such software library or work which -has been distributed under these terms. A "work based on the Library" -means either the Library or any derivative work under copyright law: -that is to say, a work containing the Library or a portion of it, either -verbatim or with modifications and/or translated straightforwardly into -another language. (Hereinafter, translation is included without -limitation in the term "modification".) - -"Source code" for a work means the preferred form of the work for making -modifications to it. For a library, complete source code means all the -source code for all modules it contains, plus any associated interface -definition files, plus the scripts used to control compilation and -installation of the library. - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of running -a program using the Library is not restricted, and output from such a -program is covered only if its contents constitute a work based on the -Library (independent of the use of the Library in a tool for writing -it). Whether that is true depends on what the Library does and what the -program that uses the Library does. - -1. You may copy and distribute verbatim copies of the Library's complete -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the notices -that refer to this License and to the absence of any warranty; and -distribute a copy of this License along with the Library. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Library or any portion of -it, thus forming a work based on the Library, and copy and distribute -such modifications or work under the terms of Section 1 above, provided -that you also meet all of these conditions: - - a) The modified work must itself be a software library. b) You - must cause the files modified to carry prominent notices stating - that you changed the files and the date of any change. c) You - must cause the whole of the work to be licensed at no charge to - all third parties under the terms of this License. d) If a - facility in the modified Library refers to a function or a table - of data to be supplied by an application program that uses the - facility, other than as an argument passed when the facility is - invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - - These requirements apply to the modified work as a whole. If - identifiable sections of that work are not derived from the - Library, and can be reasonably considered independent and - separate works in themselves, then this License, and its terms, - do not apply to those sections when you distribute them as - separate works. But when you distribute the same sections as part - of a whole which is a work based on the Library, the distribution - of the whole must be on the terms of this License, whose - permissions for other licensees extend to the entire whole, and - thus to each and every part regardless of who wrote it. - - Thus, it is not the intent of this section to claim rights or - contest your rights to work written entirely by you; rather, the - intent is to exercise the right to control the distribution of - derivative or collective works based on the Library. - - In addition, mere aggregation of another work not based on the - Library with the Library (or with a work based on the Library) on - a volume of a storage or distribution medium does not bring the - other work under the scope of this License. - -3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so that -they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in these -notices. - -Once this change is made in a given copy, it is irreversible for that -copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - -This option is useful when you wish to copy part of the code of the -Library into a program that is not a library. - -4. You may copy and distribute the Library (or a portion or derivative -of it, under Section 2) in object code or executable form under the -terms of Sections 1 and 2 above provided that you accompany it with the -complete corresponding machine-readable source code, which must be -distributed under the terms of Sections 1 and 2 above on a medium -customarily used for software interchange. - -If distribution of object code is made by offering access to copy from a -designated place, then offering equivalent access to copy the source -code from the same place satisfies the requirement to distribute the -source code, even though third parties are not compelled to copy the -source along with the object code. - -5. A program that contains no derivative of any portion of the Library, -but is designed to work with the Library by being compiled or linked -with it, is called a "work that uses the Library". Such a work, in -isolation, is not a derivative work of the Library, and therefore falls -outside the scope of this License. - -However, linking a "work that uses the Library" with the Library creates -an executable that is a derivative of the Library (because it contains -portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. Section 6 -states terms for distribution of such executables. - -When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is -not. Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - -If such an object file uses only numerical parameters, data structure -layouts and accessors, and small macros and small inline functions (ten -lines or less in length), then the use of the object file is -unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - -Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section -6. Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - -6. As an exception to the Sections above, you may also combine or link a -"work that uses the Library" with the Library to produce a work -containing portions of the Library, and distribute that work under terms -of your choice, provided that the terms permit modification of the work -for the customer's own use and reverse engineering for debugging such -modifications. - -You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work during -execution displays copyright notices, you must include the copyright -notice for the Library among them, as well as a reference directing the -user to the copy of this License. Also, you must do one of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in - the Library will not necessarily be able to recompile the - application to use the modified definitions.) b) Use a suitable - shared library mechanism for linking with the Library. A suitable - mechanism is one that (1) uses at run time a copy of the library - already present on the user's computer system, rather than - copying library functions into the executable, and (2) will - operate properly with a modified version of the library, if the - user installs one, as long as the modified version is - interface-compatible with the version that the work was made - with. c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials specified - in Subsection 6a, above, for a charge no more than the cost of - performing this distribution. d) If distribution of the work is - made by offering access to copy from a designated place, offer - equivalent access to copy the above specified materials from the - same place. e) Verify that the user has already received a copy - of these materials or that you have already sent this user a - copy. - -For an executable, the required form of the "work that uses the Library" -must include any data and utility programs needed for reproducing the -executable from it. However, as a special exception, the materials to be -distributed need not include anything that is normally distributed (in -either source or binary form) with the major components (compiler, -kernel, and so on) of the operating system on which the executable runs, -unless that component itself accompanies the executable. - -It may happen that this requirement contradicts the license restrictions -of other proprietary libraries that do not normally accompany the -operating system. Such a contradiction means you cannot use both them -and the Library together in an executable that you distribute. - -7. You may place library facilities that are a work based on the Library -side-by-side in a single library together with other library facilities -not covered by this License, and distribute such a combined library, -provided that the separate distribution of the work based on the Library -and of the other library facilities is otherwise permitted, and provided -that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. b) Give prominent notice with the combined - library of the fact that part of it is a work based on the - Library, and explaining where to find the accompanying uncombined - form of the same work. - -8. You may not copy, modify, sublicense, link with, or distribute the -Library except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense, link with, or distribute the -Library is void, and will automatically terminate your rights under this -License. However, parties who have received copies, or rights, from you -under this License will not have their licenses terminated so long as -such parties remain in full compliance. - -9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and all -its terms and conditions for copying, distributing or modifying the -Library or works based on it. - -10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted -herein. You are not responsible for enforcing compliance by third -parties with this License. - -11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot distribute -so as to satisfy simultaneously your obligations under this License and -any other pertinent obligations, then as a consequence you may not -distribute the Library at all. For example, if a patent license would -not permit royalty-free redistribution of the Library by all those who -receive copies directly or indirectly through you, then the only way you -could satisfy both it and this License would be to refrain entirely from -distribution of the Library. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply, and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is implemented -by public license practices. Many people have made generous -contributions to the wide range of software distributed through that -system in reliance on consistent application of that system; it is up to -the author/donor to decide if he or she is willing to distribute -software through any other system and a licensee cannot impose that -choice. - -This section is intended to make thoroughly clear what is believed to be -a consequence of the rest of this License. - -12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may -add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among countries -not thus excluded. In such case, this License incorporates the -limitation as if written in the body of this License. - -13. The Free Software Foundation may publish revised and/or new versions -of the Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a license -version number, you may choose any version ever published by the Free -Software Foundation. - -14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free Software -Foundation; we sometimes make exceptions for this. Our decision will be -guided by the two goals of preserving the free status of all derivatives -of our free software and of promoting the sharing and reuse of software -generally. - -NO WARRANTY - -15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER -EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE -ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH -YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL -NECESSARY SERVICING, REPAIR OR CORRECTION. - -16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR -DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL -DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY -(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED -INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF -THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR -OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -END OF TERMS AND CONDITIONS diff --git a/libs/cassowary/ChangeLog b/libs/cassowary/ChangeLog deleted file mode 100644 index 11b4762616..0000000000 --- a/libs/cassowary/ChangeLog +++ /dev/null @@ -1,2005 +0,0 @@ -Tue May 17 16:24:00 2005 Taybin Rutkin - * Moved cassowary from autotools to scons. - -Fri Mar 18 15:41:00 2005 Taybin Rutkin - * Removed ClSet.h, ClMap.h. - * ClReader.l includes ClReader.cc.h instead of ClReader.hh. The - difference between yacc and bison. - * Various changes to fix compliation. - -Wed Jan 29 21:36:15 2003 Taybin Rutkin - * Updated to work with g++ 3.x compilers. - * More direct use of STL. - * Removed C wrappers - -Sun Mar 12 13:40:44 2000 Greg J. Badros - - * guile/cassowary_scm.cc: Give docstrings as arguments - - * guile/cl-snarf.h: Added docstring as an argument to CL_PROC to - be like the revised Scwm documentation extraction system. - -Sat Feb 12 20:34:55 2000 Greg J. Badros - - * Makefile.am: Added GTL.h.patch to EXTRA_DIST - -Sat Feb 12 20:31:47 2000 Greg J. Badros - - * c++/ClSimplexSolver.cc, c++/ClSimplexSolver.h: Drop - ExternalResetStayConstants, make ResetStayConstants() public. - Test _fResetStayConstantsAutomatically before doing so in - Resolve(). Use _fAutosolve instead of _fOptimizeAutomatically. - Drop DisplayObjective (wasn't defined anyway). Drop field - _fOptimizeAutomatically (use _fAutosolve from parent, instead). - - * guile/cassowary_scm.hpp, guile/cassowary_scm.cc: Drop extra - include of guile/gh.h - - * guile/cassowary_scm.cc: Added `cl-set-auto-solve!', - `cl-set-auto-reset-stay-constants!' - -Sat Jan 29 17:45:32 2000 Greg J. Badros - - * configure.in (CASSOWARY_VERSION): Bump to 0.55. - -Sat Jan 29 17:43:05 2000 Greg J. Badros - - * c++/ClSimplexSolver.cc (Resolve): Do not comment out - "ResetStayConstants()" as Beurivé had done. This was resulting in - quirky behaviour whereby the windows were "rubber-banding" back to - where they were at the start of an interaction (e.g., if I push a - window out of the way to the left with another window, as I move - the pushing window back to the right, the other window comes back - to the right with the pushing window). Maybe that's desirable - behaviour in some instances, but it's not the behaviour we - document and sure feels weird to me. - -Sat Jan 29 17:38:43 2000 Greg J. Badros - - * java/sym.java, java/parser.java, java/Yylex.java: Added -- these - are created by JavaCUP which I don't want to be necessary for - building. - -Mon Jan 24 09:34:20 2000 Greg J. Badros - - * c++/ClSymbolicWeight.h: Set SymbolicWeight multiplier to - 1000000, not 10000 (A.Beurivé) - - * c++/ClSimplexSolver.h, c++/ClSimplexSolver.cc: Added - ChangeStrength, ChangeStrengthAndWeight, ChangeWeight, - DisplayObjective, ExternalResetStayConstants fns. - (RemoveConstraintInternal) Avoid picking the objective row when - removing a constraint. (Optimize) Pick any negative row to avoid - unending pivots [I think this is a work-around to avoid having to - implement Bland's anti-cycling rule... maybe I should just do - that, though]. (A.Beurivé) - -Thu Dec 16 11:12:34 1999 Greg J. Badros - - * configure.in: Version bumped to 0.54a - -Thu Dec 16 11:10:42 1999 Greg J. Badros - - * java/Makefile.am: Force prefix ordering in SUBDIRS so that "." - dir gets built before the demos subdirectory. - - * smalltalk/Makefile.am: Fix .dat file -- thanks Alan! - -Wed Dec 15 19:31:48 1999 Greg J. Badros - - * java/README: More notes re: security problems w/ Java 2. - - * java/cda/Makefile.am: Added run target to ease running it. - - * Makefile.am (EXTRA_DIST): Added c++/{config.h.in,stamp-h.in} - - * java/cda/Makefile.am (EXTRA_DIST): Clean up install of .gif - files. - - * java/Makefile.am (EXTRA_DIST): Added ClReader.{cup,lex} - - * c++/Makefile.am: Do not make symlink to cassowary; let - configure.in do that. - -Wed Dec 15 18:13:14 1999 Greg J. Badros - - * java/Makefile.am: Put SUBDIRS demo cda back in since they - compile now. - - * scripts/recreate-symlinks: Update with links to ../../EDU from - demo directories for Java code. Use ln -sf, not just ln -s, to avoid - warnings. - - * Makefile.am (EXTRA_DIST): Include scripts/recreate-symlinks - - * configure.in: Run recreate-symlinks script. - -Wed Dec 15 18:07:27 1999 Greg J. Badros - - * java/cda/Makefile.am: Put Constraint/*, Main/* files into the - distribution and build with them. - - * java/demos/*.java: Move everything into the - EDU.Washington.grad.gjb.cassowary_demos package. - - * java/cda/classes/run.html, java/demos/quaddemo.htm: Fix nl - convention, name class explicitly w/ package in front, w/o - trailing .class. - - * java/cda/**: Move everything into the - EDU.Washington.grad.noth.cda package. - -Wed Dec 15 17:21:08 1999 Greg J. Badros - - * java/Makefile.am: Build java parser. - - * java/ClParseTest.java: Added. - - * GTL.h.patch: Added -- need by gcc-2.95 when compiling GTL-0.3.1 - - * java/README: Mention java parser. - - * java/ClReader.lex, java/ClReader.cup: Cleanup, guard debug messages. - -Tue Dec 14 11:15:01 1999 Greg J. Badros - - * configure.in: Fix -fpermissive test to not check "cc" as well as - $CC. Eliminate the --enable-permissive flag since it is no longer - necessary. - -Mon Dec 13 15:56:19 1999 Greg J. Badros - - * java/Yylex.java: Added, from Will Portnoy. - - * java/ClReader.cup, java/ClReader.lex: Latest version from Will, - cleaned up line breaks, set a tab-width for Emacs. - -Mon Dec 13 15:55:59 1999 Greg J. Badros - - * c++/Makefile.am: Remove ClReader.cc -- why did I add this - before? - -Fri Dec 10 13:29:00 1999 Greg J. Badros - - * java/ClSimplexSolver.java (addLowerBound, addUpperBound): Fix - these two functions to call addConstraint before returning. - Thanks Stephen Allain for catching this! Updated exception specs - for those methods and for addBounds. - -Tue Dec 7 08:42:34 1999 Greg J. Badros - - * smalltalk/A991206.dat: New image from Alan. Include correct - version of code for "ClSimplexSolver removeConstraint:" to fix bug - when deleting constraints with weights other than 1. Also - disallow invalid comparisons between symbolic weights and floats. - Replace expressions "x clApprox: 0.0" with "x clApproxZero", which - works correctly for both symbolic weights and floats. - - * smalltalk/*.st: Added from Alan. - -Mon Nov 29 16:23:06 1999 - - * configure.in: Bump to version 0.54, added -lGTL to GTL_LIB even - when no --with-gtl option is given. No longer create README from - README.in. Added --enable-static-library option, off by default. - - * c++/Makefile.am (sources): Added ClReader.cc - - * cassowary.spec.in, cassowary-both.spec.in: No longer need the - --enable-guile-build option; it's the default now. - -Mon Nov 29 10:52:49 1999 Greg J. Badros - - * c++/Makefile.am: Added use of AM_CONDITIONAL - CL_BUILD_STATIC_LIBRARY; only buile libcassowary.a if that option - was selected. - - * guile/Makefile.am (libconstraints_la_LIBADD): Added @GTL_LIB@ to - make the guile library work with the FD-enabled version of the library. - -Sat Nov 27 16:11:10 1999 Greg J. Badros - - * configure.in: Invert sense of --enable-guile-build and call it - --disable-guile-build; build guile wrapper automatically if - guile-config works. - -Sat Nov 27 15:20:03 1999 Greg J. Badros - - * configure.in: Use an AM_CONDITIONAL for CL_BUILD_FD_SOLVER, not - an AC_DEFINE. Also, remove duplicate AC_SUBST of GTL_LIB, and fix - AM_CONDITIONAL of CL_BUILD_TESTS. - -Sat Nov 27 15:19:20 1999 Greg J. Badros - - * c++/Makefile.am: Try separating out FD stuff better, and use - CL_BUILD_FD_SOLVER AM_CONDITIONAL to control dependence on that - code. - - * c++/config.h.in: Drop CL_BUILD_FD_SOLVER; it's now an - AM_CONDITIONAL instead of a define. - -Wed Nov 24 15:40:27 1999 Greg J. Badros - - * c++/ClSimplexSolver.cc: Fix typo in a throw message. - - * c++/ClLinearInequality.h: Throw an editmisuse when a - ClLinearInequality is created w/o an inequality operator. - -Tue Nov 23 16:54:05 1999 Greg J. Badros - - * configure.in: Use guile's pkglibdir, not pkgdatadir, for - choosing cassoguiledir. - -Tue Nov 16 17:35:54 1999 Greg J. Badros - - * java/ClReader.lex, java/ClReader.cup: Added -- code by Will - Portnoy for adding a parser to the Java implementation. Untested, - and an early version that he emailed me. - -Tue Nov 16 17:34:00 1999 Greg J. Badros - - * java/ClTestColumns.java, java/ClTests.java: Put in the cassowary - package, instead of importing cassowary.*; jikes needed this - (discovered during testing of java-ml work). - -Sat Nov 13 11:43:48 1999 Greg J. Badros - - * java/Timer.java (Timer): Remove return type from Timer() - constructor (jikes caught the bug when I used this as a test case - for my java-ml work). - -Sun Oct 24 13:17:14 1999 Greg J. Badros - - * configure.in: Updated version to 0.53, generate - smalltalk/Makefile from Makefile.am. - - * NEWS: Updated for 0.53 release. - - * Makefile.am: Added smalltalk directory to SUBDIRS. - -Sat Oct 23 14:34:27 1999 Greg J. Badros - - * COPYING.GPL: Added - - * LICENSE: Added Scwm exception - - -Sat Oct 23 14:33:48 1999 Greg J. Badros - - * c++/Makefile.am: Make cassowary/ directory symlink as needed. - -Sun Oct 3 16:50:43 1999 Greg J. Badros - - * c++/ClSimplexSolver.cc: Use clvNil some places instead of NULL. - This is important for newer, pickier gcc-2.95.x. Thanks Alexandre - Duret-Lutz for the patch! - -Thu Sep 30 08:17:16 1999 Greg J. Badros - - * c++/ClFDSolver.cc: Added missing #include -- Thanks - Harry Hochheiser for bug report. - -Sun Sep 26 13:43:12 1999 Greg J. Badros - - * c++/Makefile.am (libcassowary_la_LDFLAGS): Added -version-info - flag to make libcassowary.so.0.0.1, instead of .0.0.0 - -Sun Sep 26 13:15:32 1999 Greg J. Badros - - * README, ANNOUNCE: Removed - - * README.in, ANNOUNCE.in: Added - - * configure.in: Create README, ANNOUNCE, bump to 0.52post - -Sat Sep 25 16:02:22 1999 Greg J. Badros - - * cassowary.spec.in, configure.in: Update to version 0.52. - -Fri Sep 24 18:51:42 1999 Greg J. Badros - - * configure.in: Remove first of redundant checks for HAVE_SCM_MAKE_SMOB_TYPE_MFPE. - -Mon Sep 20 13:36:45 1999 Greg J. Badros - - * guile/cassowary_scm.cc: Fix `cl-int-value' to use gh_int2scm - instead of gh_double2scm - -Sun Sep 19 14:45:59 1999 Greg J. Badros - - * c++/ClSimplexSolver.h, c++/ClSimplexSolver.cc: Replace - _editVarMap with _editInfoList, a list. Make ClEditInfo class - contain the variable since its no longer stored as values in a - hash where the key is the variable. Drop the index from - ClEditInfo. Rename ClVarToEditInfoMap to ClEditInfoList. - -Sun Sep 19 14:44:00 1999 Greg J. Badros - - * c++/ClTests.cc (multiedit2): Added this new test to check nested - edits that share an existing variable better. This tests the fix - for the ScwmButtons auto-orientation seg-fault bug in Scwm. - - * c++/ClBug0.cc: Added comment re: new bug fix. - -Sat Sep 18 22:31:54 1999 Greg J. Badros - - * configure.in: Added GUILE_LIBS setting. - - * cassowary.spec.in: Use fake_root_for_install to get the - cassowary guile library in proper place. - - * autogen.sh: Only create symlink if not already created. - - * acconfig.h, c++/config.h.in: Added HAVE_SCM_MAKE_SMOB_TYPE_MFPE - - * README: Added note re: enable-permissive - - * guile/cassowary_scm.cc: Use new-style (guile-1.3.2 or better) - SMOBs conditioning on HAVE_SCM_MAKE_SMOB_TYPE_MFPE. - -Wed Sep 8 20:03:25 1999 Greg J. Badros - - * cassowary.spec.in: Bump to release 8 - - * cassowary-nofd.spec2.in: Bump to release 2. - -Wed Sep 8 19:43:53 1999 Greg J. Badros - - * c++/Makefile.am: Drop building of config-inline.h -- let - configure handle that-- this was causing a double-build - (!!!ugh!!!) of Cassowary when building from RPMs, e.g. - - * GTL.spec.in: Use install-strip target. - -Tue Sep 7 23:34:49 1999 Greg J. Badros - - * configure.in, Makefile.am: use cassowary-nofd.spec2.in - - * cassowary-nofd.spec2.in: Renamed from cassowary-nofd.spec.in, - since having two *.spec files in the top level upsets rpm (it cats - them together and then gets confused by the double .spec file). - - * cassowary-both.spec.in: Added-- rpm doesn't support two %build - tags (one for a subpackage), but if it did, this is what the - corresponding .spec file might look like. - -Tue Sep 7 23:02:26 1999 Greg J. Badros - - * Makefile.am: Added cassowary-nofd.spec to EXTRA_DIST, - bin_SCRIPTS = cassowary-config. Added dist-nofd target, and - supporting targets. - - * cassowary.spec.in: Bump to 7, provide virtual package, install - %{prefix}/bin/* (for cassowary-config script). - - * configure.in: Added CASSOWARY_VERSION variable, create - cassowary-config, cassowary-nofd.spec - - * cassowary-config.in, cassowary-nofd.spec.in: Added - -Mon Sep 6 21:40:58 1999 - - * cassowary.spec.in: Use install-strip target to remove debug - symbols and save disk space. Remove %{prefix}/doc/* from the - %files list as they are in the %doc listing already. - -Mon Sep 6 12:25:14 1999 Greg J. Badros - - * cassowary.spec.in: Use --host=alpha-linux on that platform - (using an %ifarch). Bump to release 6. - - * GTL.spec.in: Fix the ./configure line for alpha platform (was - missing "--" before the "prefix" option). Bump to release 2. - - * c++/ClSymbolicWeight.h, c++/ClSymbolicWeight.cc: Use int, not - unsigned, to remove ambiguity in ClSymbolicWeight constructor. - -Sat Sep 4 15:17:13 1999 Greg J. Badros - - * acconfig.h: Added NO_CC_PERMISSIVE flag. - - * autogen.sh: Added #!/bin/sh - to top. - - * configure.in: Test for g++/gcc -fpermissive flag. Hopefully - this will let it get used only where it is accepted. Some better - guile tests, too. - - * cassowary.spec.in: Use --enable-permissive flag, bump from - release 3 to 5. - -Sat Sep 4 14:44:14 1999 Greg J. Badros - - * c++/Makefile.am, guile/Makefile.am: Added CPPEXTRAFLAGS to - AM_CPPFLAGS. - - * guile/Makefile.am: Guard lib_LIBRARIES with HAVE_GUILE test so - that guile stuff is only built when GUILE is desired and we have - the libraries installed. - -Tue Aug 31 22:16:04 1999 Greg J. Badros - - * java/demos/Makefile.am, java/cda/Makefile.am, java/Makefile.am - (install-javaJAVA): Do not try to install .class files if no - HAVE_JAVA - -Tue Aug 31 21:30:24 1999 Greg J. Badros - - * cassowary.spec.in: Do not use --disable-java-build, since that - still invokes the rule which is not what I want. - - * java/demos/Makefile.am, java/cda/Makefile.am: Added bogus - classjava.stamp rule when no HAVE_JAVA to work around getting an - error when trying to run javac with no source files. - - * configure.in: Fix some HAVE_JAVA bugs. Still not perfect, but better. - -Tue Aug 31 17:07:31 1999 Greg J. Badros - - * java/demos/Makefile.am, java/cda/Makefile.am, java/Makefile.am: - Added EXTRA_DIST. - -Tue Aug 31 16:27:41 1999 Greg J. Badros - - * configure.in (HAVA_JAVA): AC_OUTPUT the java/*/Makefiles. - - * cassowary.spec.in: Use --disable-java-build ./configure option. - Bump to release 3. - - * Makefile.am: Do not conditionally do directories-- that is - really broken with automake/rpm building. - -Tue Aug 31 16:20:45 1999 Greg J. Badros - - * java/demos/Makefile.am, java/cda/Makefile.am, java/Makefile.am - (java_JAVA): Guard with if HAVE_JAVE. - -Mon Aug 30 12:03:26 1999 Greg J. Badros - - * cassowary.spec.in: Bump to release 2 - - * configure.in: Drop the java/* wrappers/* from AC_OUTPUT macro-- - this breaks java builds but make the Cassowary RPM build more - cleanly. I'm going to start making a separate cassowary-java - distribution unless I can figure out how to make automake and Java - co-exist more happily. - -Mon Aug 30 12:00:39 1999 Greg J. Badros - - * c++/ClAbstractVariable.h: #include "cl_auto_ptr.h" and use - cl_auto_ptr, not auto_ptr. - -Mon Aug 30 10:06:50 1999 Greg J. Badros - - * c++/cl_auto_ptr.h: Change the conditional inclusion sandwich to - CL_AUTO_PTR_H. Added "#define cl_auto_ptr auto_ptr" for MSVC. - -Thu Aug 26 22:42:50 1999 Greg J. Badros - - * cassowary.spec.in: Require guile 1.3.2, to be safe. Require GTL - >= 0.3.1, not gtl >= 0.3.1 (note capitalization) - -Thu Aug 26 14:12:42 1999 Greg J. Badros - - * c++/ClFDSolver.h, c++/ClCTest.c, c++/ClC.h, c++/ClC.cc, - c++/Cassowary.h, c++/ClConstraint.h: Use LONG_MIN, not MINLONG and - #include not since the latter is deprecated - (and does not work in VC++). - - * THANKS: Thank Pengling He for his VC++ bug report re: values.h - -Thu Aug 26 14:08:46 1999 Greg J. Badros - - * configure.in (GUILE_PKGDATA_DIR): Set cassoguiledir variable, - and use ${prefix} prefix of GUILE_PKGDATA_DIR to be sure that rpm - building succeeds (was failing because it was trying to write to - an absolute location that guile told it to use, instead of using - the prefix of $RPM_BUILD_ROOT). - - * c++/Makefile.am: Fix lex/yacc building dependencies. - - * guile/Makefile.am (cassoguile_LTLIBRARIES): Do not set - cassoguiledir here-- do it in configure.in instead. - -Thu Aug 26 11:02:36 1999 Greg J. Badros - - * guile/Makefile.am (EXTRA_DIST), docs/Makefile.am: Added docs to - EXTRA_DIST. - - * c++/Makefile.am: Added ClReader.l, ClReader.y to EXTRA_DIST, - remove ClReader.cc from sources. Added timer.h to - pkginclude_HEADERS. - - * Makefile.am: Update EXTRA_DIST - -Thu Aug 26 08:45:08 1999 Greg J. Badros - - * configure.in: Write cassowary.spec, GTL.spec. Bump version to - 0.51. - - * autogen.sh: Run configure, not config.status - - * VERSION, README, NEWS, ANNOUNCE: Bump to 0.51, add date, notes. - - * Makefile.am: Drop Java, Python to make easier to package. Added - EXTRA_DIST to include some doc files and the cassowary.spec file. - -Wed Aug 25 22:54:18 1999 Greg J. Badros - - * c++/Makefile.am (pkginclude_HEADERS): cl_auto_ptr.h now, not auto_ptr.h - -Mon Aug 23 21:26:31 1999 Greg J. Badros - - * ltmain.sh, ltconfig, libtool, configure: Removed -- these are - autogenerated by autogen.sh - -Mon Aug 23 21:23:53 1999 Greg J. Badros - - * c++/ClSimplexSolver.cc: Use cl_auto_ptr, not auto_ptr. - - * c++/ClAbstractVariable.h: #include , not "auto_ptr.h" - - * c++/cl_auto_ptr.h: Added -- renamed from auto_ptr.h since that - was causing some difficulties due to the standard C++ auto_ptr template. - -Mon Jul 26 10:19:35 1999 Greg Badros - - * c++/Makefile.am (libcassowary_la_SOURCES): Remove redundant - listing of ClFD* files from this target. - -Mon Jul 26 09:41:09 1999 Greg Badros - - * c++/Cl.h: Include ClConstraint.h, since cnLT, etc., need to be - defined for ClReader.y - -Mon Jul 26 09:22:11 1999 Greg Badros - - * acconfig.h, configure.in: Use CL_ prefix for BUILD_FD_SOLVER and - HAVE_GTL. - -Mon Jul 26 09:17:56 1999 Greg Badros - - * c++/config.h.in,c++/ClC.h,c++/ClC.cc,c++/Cl.h: Use CL_ prefix on - BUILD_FD_SOLVER and HAVE_GTL so that the config-inline.h gets the - right definitions. - - * c++/Makefile.am: Expanded out the sources_for_fd_solver since - the _OBJECTS make variable doesn't get expanded properly if this - step is deferred until later. This breaks builds w/o FD solver, - but I have to get Amaya working ASAP. - -Mon Jul 19 17:08:03 1999 Greg Badros - - * c++/ClSymbolicWeight.h: Increase multiplier to 10000 for - AsDouble-- works around the bug in resizing Scwm windows because - the medium stay constraints on width and height are too strong for - the strong edit constraint. - -Sun Jul 11 19:37:39 1999 Greg Badros - - * c++/ClLinearExpression.h: Remove "class" from a typedef - ClMap. Thanks Alexandre 'Pollux' Duret-Lutz - for testing against a more recent egcs (gcc-2.95) that caught this - problem. - - * configure.in: Improve checks for guile so that it uses --prefix - and --exec-prefix to --guile-prefix and --guile-exec-prefix - -Sat Jul 10 19:21:34 1999 Greg Badros - - * autogen.sh: rm libtool stuff just in case. - - * README: Updated version number, notes about building it and - needing GTL for fd solver. - - * configure.in: Added --enable-cxx-tests, --enable-fd-solver, - --with-gtl; switch --disable-java-build to --enable-java-build - - * acconfig.h, c++/config.h.in: Added HAVE_GTL, BUILD_FD_SOLVER options. - - * c++/Makefile.am: Make only the library and ClTests get built by - default (other binary test programs are each big when build -g, - and aren't useful to the end user). Use @SOURCES_FOR_FD_SOLVER@ - to permit a version of the toolkit to be build without the finite - domain subsolver. - - * c++/ClC.h, c++/ClC.cc, c++/Cl.h: Add #ifdefs for no fd subsolver. - -Fri May 7 17:02:09 1999 Greg J Badros - - * c++/ClC.cc (CL_ClvLookup): Return NULL if varmap is NULL instead - of asserting it is non-NULL - -Thu May 6 19:02:38 1999 Greg J Badros - - * c++/ClFDTests.cc: Added return type to connect1. - - * c++/ClFDSolver.cc: Return *this where missing. - - * c++/ClFDConnectorVariable.h: Reorder mem vars to match - initialization order in ctr. - - * c++/ClC.h, c++/ClC.cc: Added CL_ClvIsFD. - -Sun May 2 10:42:00 1999 Greg J Badros - - * c++/ClReader.l: Permit "_" in identifiers (needed for env - variable precondition variables). - - * c++/ClLinearInequality.h: Honour _fStrictInequality flag when - testing FIsSatisfied(). - - * c++/ClLinearConstraint.h: Added missing "void" return type for - ChangeConstant. - -Fri Apr 30 09:45:51 1999 Greg J Badros - - * c++/ClFDConnectorVariable.cc, c++/ClFDConnectorVariable.h: - Added -- support connecting the FD solver to the simplex solver - via a variable in the FD region that gets its value "copied" to a - analogous variable in the Simplex region. - - * Makefile.am: Added ClFDConnectorVariable.[ch] files. - - * c++/ClLinearConstraint.h: Added ChangeConstant() - - * c++/ClFloatVariable.h, c++/ClFDVariable.h, - c++/ClFloatVariable.cc, c++/ClFDVariable.cc, - c++/ClAbstractVariable.h: Move _pv, SetPv(), Pv() from - ClFloatVariable, ClFDVariable, into common parent - ClAbstractVariable. Drop ClFloatVariable::SetName(). - - * c++/ClFDTests.cc: Added connect1 test to test - ClFDConnectorVariable - - * c++/ClFDSolver.cc: Use 1 + value-rhs for errors to ensure that - strict inequalities behave reasonably. - -Thu Apr 29 19:29:34 1999 Greg J Badros - - * c++/ClVariable.h: Register variable in the dictionary when - initialized from a ClFDVariable*. Added const ClAbstractVariable - *operator() const. - - * c++/ClSolver.h, c++/ClSimplexSolver.h: Added _fAutosolve, - _pfnChangeClvCallback; added default ctr to initialize. Added - SolveNoException(); Moved SetAutosolve(), FIsAutosolving(), - SetChangeClvCallback() from ClSimplexSolver up to here. - - * c++/ClSolver.cc: Added PrintTo for list, operator<< - for same. - - * c++/ClSimplexSolver.cc: Test constraint with - FIsOkayForSimplexSolver() before trying to add it (avoids adding - FD constraints to the simplex solver). - s/_fOptimizeAutomatically/_fAutosolve/g - - * c++/ClParseTest.cc: Use FCanConvertCn() before trying to. - - * c++/ClFDVariable.h: Make PlfdnDomain() const and return const. - - * c++/ClFDVariable.cc: PrintOn now displays value (duh!) - - * c++/ClFDTests.cc: Use new ListPushOnto() instead of a bunch of - push_back. Added simple2, simple3. - - * c++/ClFDSolver.h, c++/ClFDSolver.cc: Added ChangeClv(), - AddConstraintInternal(), RemoveConstraintInternal(), - ListPushOnto(), fDebugFDSolve var, more debugging code. - - * c++/ClConstraint.h, c++/ClFDConstraint.h: Added - FIsOkayForSimplexSolver() returning false for FDCns, true in the - base class. - - * c++/ClFDBinaryOneWayConstraint.h, - c++/ClFDBinaryOneWayConstraint.cc: Make ctr take ClConstraint - instead of ClLinearConstraint. Added EnsurePreconditionsForCn(), - FCanConvertCn(). Throw better exceptions instead of - ExCLEditMisue-- use new ExCLTooDifficultSpecial. - - * c++/ClCTest.c: Use CL_ClvPrint instead of coding by hand. - Added CL_CldvNew() call. - - * c++/ClC.cc, c++/ClC.h: Added FDN_EOL defn, typedefs for Number, - FDNumber, CL_CldvNew(), CL_FDCanConvertCn(), CL_FDCnFromCn(), - CL_ClvPrint(). Use CL_Solver for PfnChangeClvCallback, not CL_SimplexSolver. - - * c++/ClAbstractVariable.h: Throw instead of assert(false) in base - class IsPivotable(), IsRestricted(). - -Wed Apr 28 19:38:46 1999 Greg J Badros - - * c++/ClC.cc: Added CL_FDSolverNew() - -Wed Apr 28 19:10:32 1999 Greg J Badros - - * c++/Makefile.am (INCLUDES): Include @GUILE_INCLUDES@ -- actually - done to get cassowary libraries (GJB:FIXME::) - -Wed Apr 28 18:49:51 1999 Greg J Badros - - * c++/Makefile.am: Added ClCTest to the _PROGRAMS, and use - -lstdc++ on them - - * c++/ClSolver.h: Expose Resolve() in base-class interface, along - with <<, and PrintOn. - - * c++/ClSolver.cc: Added << operator. - - * c++/ClC.h, c++/ClC.cc, c++/ClTest.c: Fixed bugs, use - CL_Solver... instead of CL_SimplexSolver... where appropriate. - -Wed Apr 28 17:15:47 1999 Greg J Badros - - * c++/ClSymbolicWeight.h: Make CLevels unsigned, not int, and - require all 3 args to the 3 double ctr to remove ambiguity. - - * c++/ClSimplexSolver.h: Check constraint before adding and throw - an error if the constraint is no good for the SimplexSolver. - - * c++/ClParseTest.cc: Don't assume a failed add is due to an - inconsistent system-- could be wrong kind of constraint was read - in. - - * c++/ClLinearInequality.h: Store the strictness of the - inequality, since other solvers may be able to use strict ones. - - * c++/ClFDSolver.cc: Fine-tune the exception objects thrown... use - the richer hierarchy. - - * c++/ClFDBinaryOneWayConstraint.c, - c++/ClFDBinaryOneWayConstraint.h: Added IsStrictInequality(), get - the direction of the inequality correct. - - * c++/ClErrors.h: Richer hierarchy of exceptions to cope with - solver limitations. - - * c++/ClConstraint.h: Added IsStrictInequality(); have - ReadOnlyVars return a const ClVarSet&, not value. - -Wed Apr 28 12:20:47 1999 Greg J Badros - - * c++/Makefile.am: Added ClFDBinaryOneWayConstraint.cc. - - * c++/ClReader.y, c++/ClReader.l: Added tokens GT, LT, and handle - them (for >, <, resp). - - * c++/ClParseTest.cc: try converting to a FD constraint, and show - what that object is. - - * c++/ClFDBinaryOneWayConstraint.h: Added ctr from a - ClLinearConstraint. Added IsInequality(). - -Wed Apr 28 12:08:16 1999 Greg J Badros - - * c++/ro-test.in: Added for testing below. - - * c++/ClFDBinaryOneWayConstraint.cc: Added -- so far just a ctr - from a ClLinearConstraint object (since the parser hands me a - constraint object that is a ClLinearConstraint object). - -Tue Apr 27 20:35:23 1999 Greg J Badros - - * c++/ClSymbolicWeight.h, c++/ClSymbolicWeight.cc: Drop default - ctr, and give default arg value to CLevels of 3. Added operator*. - - * c++/ClFDTests.cc: Better test. - - * c++/ClFDSolver.h, c++/ClFDSolver.cc: Use SymbolicWeights for - errors, so hierarchy is handled (i.e., strengths on constraints - are honoured). - - * c++/ClFDConstraint.h: Added ctr with strength, weight. - - * c++/ClFDBinaryOneWayConstraint.h: Added strength, weight - arguments to ctr. - - * c++/ClConstraint.h: Added symbolicWeight() accessor. - -Tue Apr 27 15:04:34 1999 Greg J Badros - - * c++/ClFDSolver.cc (RemoveConstraint): Fix some bugs-- handle nil - read-only variable properly, and clean up _mapVarToNode when - erasing nodes. - -Tue Apr 27 10:40:58 1999 Greg J Badros - - * c++/ClSolver.cc: Added -- wrote PrintTo, << basic impls, and - simple AddConstraint. - - * c++/QocaBench.cc, c++/ClTests.cc, c++/ClSubgraphTest.cc, - ClLeakTest.cc, ClC.cc: Use Solve(), not solve() - - * c++/ClVariable.h: Added DesiredValue, PlfdnDomain base-class - accessors, handle clvNil in PrintOn. - - * c++/Makefile.am: Added ClSolver.cc, link with -lGTL, added - missing and new .cc, .h files. - - * c++/ClTypedefs.h: added ClVarToConstraintSetMap. - - * c++/ClSolver.h: Added AddConstraint{,NoException}, - RemoveConstraint{,NoException}, Solver here to the abstract - interface, also the prototypes for the PrintTo and << on the - ClTypedefs.h types. - - * c++/ClSimplexSolver.h, c++/ClSimplexSolver.cc: Solve(), not - solve(), move some protos in abstract base class ClSolver. - - * c++/ClLinearInequality.h: Use ClCnRelation, not - ClInequalityOperator. - - * c++/ClFDVariable.h, c++/ClFDVariable.cc: More accessors, - settors, comment-out non-initial-domain ctr. - - * c++/ClFDTests.cc: Test more. - - * c++/ClFDSolver.h, c++/ClFDSolver.cc: Almost complete, but - largely untested implementation. - - * c++/ClFDBinaryOneWayConstraint.h: Added ctrs, setters, getters. - - * c++/ClErrors.h: Fixed throw message for ExCLConstraintNotFound - to not refer to the tableau. - - * c++/ClConstraint.h: Added ClCnRelation (was ClInequalityOperator - in c++/ClLinearInequality.h) and wrote StrCnRelation for printing - it. - - * c++/Cl.h: include ClFDSolver.h - - * c++/Cassowary.h : include values.h, def FDN_NOTSET (FIXME: drop this?) - -Sun Apr 25 18:55:26 1999 Greg J Badros - - * c++/Makefile.am: Added ClFDBinaryOneWayConstraint.h, - ClFDConstraint.h to pkginclude_HEADERS. - - * c++/ClSimplexSolver.h, c++/ClSimplexSolver.cc: Added optional - strength argument to AddPointStays, AddPointStay fns. - - * c++/ClFDVariable.h: Set _plfdnInitialDomain to avoid a warning - for now. - - * c++/ClFDBinaryOneWayConstraint.h: Added return xo to PrintOn. - - * c++/ClConstraint.h: Fix order of initializers. - - * c++/ClC.h, c++/ClC.cc: Document return value for - CL_VarMapDelete, and do proper return. - - * configure.in: Added --enable-cflags, --enable-cxxflags, - --enable-cppextraflags. Not tested yet. - -Sun Apr 25 11:46:28 1999 Greg J Badros - - * configure.in: Bump version to .50, for FD features. - -Sun Apr 25 11:37:52 1999 Greg J Badros - - * c++/Makefile.am: Comment out the Bug sources/builds, add the FD - sources. - - * c++/ClSimplexSolver.h: Inherit from ClSolver, too. Move SetPv, - Pv() out into ClSolver base class. - - * c++/ClSimplexSolver.cc, c++/Cl.h: Make szCassowaryVersion a const char *. - - * c++/ClReadery.y, c++/ClReader.l, c++/ClReader.h: Support "?" - read-only annotations, and use Constraint::AddROVars() to track - the ro vars of a constraint expression. - - * c++/ClParseTest.cc: Show whether the constraint is added - successfully or if it is inconsistent. - - * c++/ClLinearConstraint.h: Fix BUG-- super should be - ClConstraint, not ClLinearConstraint. - - * c++/ClFDVariable.cc: Use <, > to delimit FD vars, not [, ]. - - * c++/ClConstraint.h, c++/ClConstraint.cc: Added AddROVars, - FIsReadOnlyVar, ReadOnlyVars. - -Thu Apr 22 20:18:31 1999 Greg J Badros - - * c++/ClVariable.h: Added ClVariable ctr that takes a - ClFDVariable*, this ambiguates returning NULL as a ClVariable, so - may not be a good idea, but it does make it less confusing than - having another overloaded version of ClVariable's ctr. Added - IsFloatVariable, IsFDVariable fwding fns. - - * c++/ClSimplexSolver.cc: Disambiguate uses of NULL to be - (ClFloatVariable *)NULL. - - * c++/ClFloatVariable.h: Added IsFloatVariable() to return true - - * c++/ClC.h, c++/ClC.cc: Added CL_ClvLookupTrim for removing ws - around the var name. - - * c++/ClAbstractVariable.h: Make IsPivotable, IsRestricted both - assert false instead of being pure virtual -- they only need to be - overridden if we want to permit them to be called. Added - IsFloatVariable(), IsFDVariable() both returning false in this - base class. - - * c++/Cassowary.h: Added FDNumber typedef to be a long. - - * c++/Makefile.am: Added ClFDVariable.{cc,h} - - * c++/ClFDVariable.cc, c++/ClFDVariable.h: Added, copied from - ClFloatVariable and modified slightly. - -Tue Apr 20 10:18:32 1999 Greg J Badros - - * smalltalk/README: Note that smalltalk implementation is now in - the public domain. - - * README: Update to version 0.43, note about smalltalk - implementation being in public domain. - - * LICENSE: Note about not applying to smalltalk implementation - - * ANNOUNCE: Update date to today. - - * *: Changed copyright to be "Greg J. Badros and Alan Borning" - instead of "Alan Borning and Greg J. Badros". Okayed by Alan -- - to hopefully encourage more people to write me with their - questions/problems rather than Alan. - -Mon Apr 19 13:45:35 1999 Greg J Badros - - * cassowary.spec: Added --with-guile-prefix - -Mon Apr 19 13:02:46 1999 Greg J Badros - - * c++/ClReader.l: Be a bit more careful about end of string - handling in YY_INPUT-- only return result = 1 if we read a - non-null character. Call yy_flush_buffer() before throw-ing an - error, so that we start anew the next time we are asked to return - tokens for the parser. - - * c++/ClC.h, c++/ClC.cc: Added CL_SimplexSolverAddStay. (Fix typo - in .cc) - -Fri Apr 16 16:36:24 1999 Greg J Badros - - * c++/ClTests.cc, c++/ClSimplexSolver.h, c++/ClSimplexSolver.cc, : Use "RemoveConstraintNoException", not - "removeConstraintNoException" (fix initial caps.) - - * c++/ClReader.y: Start looking for a constraint, turn on verbose - warnings and DEBUG option (still need to set cldebug = 1 in - debugger) - - * c++/ClReader.h: In operator() for the lookup proc, Return - &clvNil() if _pmapVars is still NULL - - * c++/ClC.h, c++/ClC.cc: Added CL_VariableName(..), CL_VarMapDelete(..), - CL_RemoveConstraint(..) - - -Wed Apr 14 16:56:05 1999 Greg J Badros - - * configure.in: Bump to .43. - - * c++/ClC.cc (CL_VarMapDelete, CL_VariableName): Added new functions. - - * cassowary.spec: Added, for building rpms - - * c++/gdbinit-cassowary: Added a bunch of guile debugging macros. - - * c++/Makefile.am: Added ClC.cc to libcassowary_a_SOURCES - - * c++/ClReader.y: Turn off parser debugging messages by default - - * c++/ClC.h, c++/ClC.cc: Added CL_ConstraintPrint, CL_FIsSatisfied - protos - -Wed Mar 31 17:23:18 1999 Greg J Badros - - * wrappers/Makefile.in: Rename PYTHON_HEADERS to PYTHON_HEADER_DIR - so it does not get treated specially by automake (?). - - * configure.in: Bump to .42. Added --disable-cpp-build, - --disable-java-build, and disable Python/Guile builds - automatically if directories cannot be found. Drop the - cassowary from c++/cassowary/config.h -- just use c++/config.h - - * autogen.sh: do not fail if config.status is not -x. - - * Makefile.am: Honour the HAVE_foo flags so that not all subdirs - have to be built. - -Mon Mar 29 21:01:21 1999 Greg J Badros - - * ltconfig, ltmain.sh: Added -- so libtool isn't broken in - distributions. - -Mon Mar 29 20:59:17 1999 Greg J Badros - - * configure.in: Try to undo a bash-ism. Untested on a vendor sh, - but still works with bash. - -Sat Mar 20 19:19:37 1999 Greg J Badros - - * Release v0.41. - -Sat Mar 20 19:19:13 1999 Greg J Badros - - * Added config.sub and config.guess to the repo -- they were - symlinks before which broke the distribution. - -Thu Mar 18 15:20:51 1999 Greg J Badros - - * Release v0.4. - -Thu Mar 18 14:44:39 1999 Greg J Badros - - * configure.in: Do not let config-inline.h get overwritten if it - is unchanged. Add some extra messages to tell status of - config-inline.h - -Thu Mar 18 12:59:02 1999 Greg J Badros - - * README, configure.in, wrappers/Makefile.in: Added - --with-python-headers configure option. - -Thu Mar 18 12:48:55 1999 Greg J Badros - - * README: Added notes about what to do when a subdir build fails, - suggest -k by default. - - * guile/Makefile.am (test): Added this target for easier way to - run cltests.scm. - - * guile/README: Updated with notes about how to run cltests.scm. - - * java/Makefile.in: Fix tests build rule. - -Thu Mar 18 11:42:49 1999 Greg J Badros - - * configure.in: Create config-inline.h at end of script. - - * c++/Makefile.am: Do not have rule for building config-inline.h; - let configure script do that. - -Thu Mar 18 11:05:27 1999 Greg J Badros - - * c++/*.h: Use #include config-inline.h incantation so that header - files don't include config.h (since they may be included by - another package that has its own config.h) - - * c++/*.cc: Use #include config.h as these are build-time-only - used and can thus rely on the full configure details. - -Thu Mar 18 10:57:08 1999 Greg J Badros - - * guile/cassowary_scm.hpp: Use #include config-inline.h - incantation. - - * guile/cassowary_scm.h: Drop including config.h; it's not - needed. - - * guile/cassowary_scm.cc: Use cassowary/config.h, not config.h - -Thu Mar 18 10:29:40 1999 Greg J Badros - - * c++/Makefile.am: Install config-inline.h, not config.h, and - build config-inline.h by grepping for #define CL_ in config.h. - This works around the problem caused by Scwm including Cassowary - header files which then included cassowary's config.h and - conflicted with Scwm's config.h. - -Thu Mar 18 10:11:40 1999 Greg J Badros - - * c++/test-*.cc: Only #include "Cl.h" - -Thu Mar 18 09:50:45 1999 Greg J Badros - - * wrappers/Makefile.in (clean): use rm -f so we don't get a - warning if file is missing. - -Thu Mar 18 09:49:35 1999 Greg J Badros - - * java/Makefile.in: Use JAVA_CLASS_PATH configure variable. Fix - install target to echo a message about the install happening - during the build. - -Wed Mar 17 18:54:16 1999 Greg J Badros - - * c++/Makefile.am: Use libtool, and added lib_LTLIBRARIES. Put - benchmarks, bugs, and test programs all under $libdir/cassowary. - Drop cassoincludedir, as that's just pkginclude, and use - include_HEADERS for Cl.h and ClC.h, the main top-level includes. - Also install config.h. - - * c++/Cassowary.h: #undef PACKAGE, VERSION before #including - cassowary/config.h as a cheezy workaround. (Switched from "" to - <>, and ../ to cassowary/ also). - -Wed Mar 17 18:50:49 1999 Greg J Badros - - * configure.in: Put config.h in c++/cassowary so cassowary must do - #include so there is no filename conflict - with other packages including cassowary header files (e.g., - Scwm). Added AM_PROG_LIBTOOL call. Set GUILE variables outside - of the guile-prefix ACE_ARG_PATH macro, and set GUILE_PKGDATA_DIR - use guile-config to find out where we should install the .so file. - -Wed Mar 17 18:43:08 1999 Greg J Badros - - * guile/Makefile.am: Updated to build using libtool, and to - install header files. Changes name to libconstraints.* so that - the guile module name (cassowary constraints) works out, and set - it to install in the right place. - -Wed Mar 17 18:39:13 1999 Greg J Badros - - * guile/cltests.scm: Added #! lines, change name of module to - (cassowary constraints), remove redundant `use-modules' call. - - * guile/cassowary_scm.hpp: #include - cassowary/ClLinearExpression_fwd.h, not ClLinearExpression_fwd.h - - * guile/cassowary_scm.cc: Change name of module to (cassowary - constraints). Make the init_cassowary_scm fn static. - -Wed Mar 17 07:39:10 1999 Greg J Badros - - * c++/Cassowary.h, c++/ClSimplexSolver.cc: Switch back to - including config.h (now ../config.h) from Cassowary.h, instead of - from ClSimplexSolver.cc. - -Tue Mar 16 19:56:02 1999 Greg J Badros - - * acconfig.h: Fix missing comment closer */ - - * c++/Makefile.am: Added AM_CPPFLAGS = $(CPPEXTRAFLAGS) - - * configure.in: Use config.h, not c++/config.h, and permit - --enable-warnings option to turn on compile-time warnings (uses - AM_CPPFLAGS in Makefile.am) - -Tue Mar 16 19:26:23 1999 Greg J Badros - - * configure.in, acconfig.h: Better autoconf support, including - several --enable options. Added acconfig.h to support autoheader - doing the right thing in making config.h.in. - -Tue Mar 16 19:22:50 1999 Greg J Badros - - * c++/ClSimplexSolver.cc, c++/Cassowary.h: Include "config.h" from - here, not from Cassowary.h (still not right-- problem is scwm gets - the wrong config.h. Maybe config.h should be in ..? - -Tue Mar 16 19:21:06 1999 Greg J Badros - - * java/README: Added note about common error when CLASSPATH is wrong. - -Tue Mar 16 15:51:15 1999 Greg J Badros - - * c++/Cassowary.h: #include "config.h" - - * c++/ClSimplexSolver.cc: Use VERSION to init szCassowaryVersion. - -Tue Mar 16 12:44:33 1999 Greg J Badros - - * c++/**: Updated function names to always start with an uppercase - letter (follows C++ conventions, and brings API of Cassowary and - QOCA closer together). Used scripts/convert-ids to do the - conversion, along with scripts/ids-to-upper as the list of - conversions to do. - -Wed Mar 10 15:28:33 1999 Greg J Badros - - * Release v0.32. - -Wed Mar 10 11:36:37 1999 Greg J Badros - - * **/Makefile: Removed, since these are now generated by - autoconf from Makefile.in (which itself is generated by - automake from Makefile.am [only for some directories]) - - * configure.in: - - * c++/ClBug2.cc: Added to demonstrate a bug that Anthony Beurivé - reported. - - * c++/ClSimplexSolver.cc: Fix above-mentioned bug by changing the - coefficient of the added in removeConstraintInternal. - - * c++/ClReader.l: Reset the lexer on failed id lookup. - - * c++/ClC.cc, c++/ClC.h: Added VarMap access functionality, make - CL_ParseConstraint catch exceptions and return NULL on error - parsing. - - * c++/config.h.in, c++/stamp-h.in: Added, for automake/autoconf - support. - - * c++/Makefile.am: Improve installation support, updated for - ClBug2 - - * guile/Makefile.am: Build .x using guile-snarf - - * c++/Makefile.linux: Updated for ClBug2 - - * c++/demos/DraggableBox.h: Do not return references to - ClVariable-s -- just return by value since they are a handle - class. - - * guile/Makefile.am: changed name of library to - libcassowaryguile.a from libconstraints.a - - * java/CL.h: Added a String description argument to assert() to - permit easier tracking of failures. - - * java/ClSimplexSolver.java: Fix bug that Emmanuel Pietriga - reported -- use peek() to get at top element of _stkCedns stack - when removing edit variables in removeEditVarsTo(). Added - descriptions to assert()s and to throwing of ExCLInternalError. - Have the addBounds, addUpperBound, addLowerBound functions - propagate out ExCLInternalError-s instead of catching them and - printing an error message. Added messages to all assertions. - - * java/ClLinearExpression.java: Added description to throwing of - ExCLInternalError. - - * java/ClLinearInequality.java: Added description to throwing of - ExCLInternalError. - - * java/ExCLInternalError.java: Require description of the error in - constructor. - - * java/QuadDemo.java: Use System.err when printing errors, and - print the description of the exception. - - * smalltalk/ClKernel.app: Fix bug with not using the weight of a - constraint as the negating coefficient when removing a constraint. - -Mon Mar 8 16:40:17 1999 Greg J Badros - - * Added autoconf and partial automake support. Added numerous - Makefile.am's, renamed old Makefiles to Makefile.linux (and copied - to Makefile.in when I did not write a Makefile.am). Added - configure.in. - - * guile/cassowary_scm.cc: Use ClReader.h, not creader.h (I renamed - the file) - -Fri Mar 5 16:24:05 1999 Greg J Badros - - * c++/Makefile, c++/Cl.h: Fix for renaming of creader.* -> - ClReader.*; make C libraries as part of lib, shared_lib rules. - - * c++/ClReader.*: Added, renamed from creader.h, creader.y, - creader.l - - * c++/ClTableau.h, c++/ClTableau.cc: Added - printExternalVariablesTo() fn. - - * c++/ClSimplexSolver.cc: printExternalVariablesTo in - printInternalInfo. - - * c++/ClParseTest.cc: DO not include ClReader.h-- Cl.h includes it - - * c++/ClCTest.c: Make more like a browser-related test, use new - CL_TableauPrintExternalVariables() - - * c++/ClC.h, ClC.cc: Added CL_Tableau, - CL_TableauPrintExternalVariables. Use "ends" to terminate - strstreams. Make Strong Stays use medium strength stays. Make - CL_ParseConstraint call ClsFromSz instead of parsing the char * - itself. - -Thu Mar 4 19:08:23 1999 Greg J Badros - - * c++/ClVariable.h: Add assert(pclv) before dereferencing through - ClVariable's pclv member. - - * c++/Makefile: Added DYNLINK = yes/no variable for controlling - dynamic linking more easily. - - * c++/ClSimplexSolver.h: Changed PfnChangeClvCallback to take a - ClVariable * instead of a ClVariable. This make it easier for the - C interface since it has "CLV" as a "ClVariable *" and cannot - reason about ClVariable-s because it doesn't see the struct defn. - - * c++/ClC.cc, c++/ClC.h: Added CL_SimplexSolverSetEditedValue, - CL_SimplexSolverPrint, CL_SimplexSolverSetChangeClvCallback, - CL_VariableSetPv, CL_VariablePv. - - * c++/ClCTest.cc: Test CL_SimplexSolverSetEditedValue, CL_SimplexSolverPrint. - -Wed Mar 3 17:37:17 1999 Greg J Badros - - * c++/ClSimplexSolver.h (UpdateExternalVariables): Added this - function to provide a publicly available way to get at setExternalVariables() - - * c++/ClCTest.c, c++/ClC.h, c++/ClC.cc: Added for the beginnings - of a rudimentary C interface to the c++ library. - - * c++/Makefile: Updated to build ClCTest, libccassowary.so (the C - interface to Cassowary [for Amaya, initially]) - -Mon Mar 1 Greg J Badros - - * Release v0.31 - -Mon Mar 1 15:11:52 1999 Greg J Badros - - * c++/ClVariable.h: Added explict copy ctr. - - * c++/ClEditConstraint.h, c++/ClStayConstraint.h: Changed output - format so parentheses started by super:: call to ClConstraint.h - are closed properly. - - * c++/ClSimplexSolver.h, c++/ClSimplexSolver.cc: Undo removing a - pass by reference of ClVariable when used as an output argument. - Added printing for ClEditInfo class instancesm, - ClVarToEditInfoMap. - -Mon Mar 1 13:46:48 1999 Greg J Badros - - * README: Updated for version 0.31. - - * c++/Makefile: Added QocaBench.o to TEST_OBJS, comment out - CL_USE_HASH_MAP_AND_SET by default. - - * c++/ClTestColumns.cc: Allocate constraint objects on heap, not - as temporaries on local stack - - * c++/ClStayConstraint.h, c++/ClSimplexSolver.h, - c++/ClSimplexSolver.cc, c++/ClPoint.h, c++/ClLinearInequality.h, - c++/ClEditOrStayConstraint.h, c++/ClEditConstraint.h: Pass and - return ClVariable-s by value, not by reference. (Fixes bug in - QocaBench from re-use of a ClVariable object with the underlying - pointer different. - - * c++/Cl.h: include creader.h - - * c++/README: Fix spelling of deprecated, URL for WxWindows. - - * c++/test-ClConstraint.cc: Comment out unused variables - -Mon Mar 1 12:53:02 1999 Greg J Badros - - * c++/qdemos/QuadDemoWindow.cc: Allocate constraint objects on - heap, not as temporaries on local stack. - -Fri Feb 26 09:16:31 1999 Greg J Badros - - * wrappers/cassowary.i: Use .c_str() off of exception descriptions - to get the char * (description() now returns a string) - -Fri Feb 26 09:11:17 1999 Greg J Badros - - * c++/ClConstraint.h: Added FIsInSolver() - - * guile/cassowary_scm.cc: Wrap cl-constraint-is-in-solver? - -Thu Feb 25 18:58:55 1999 Greg J Badros - - * guile/cltests.scm: Added (use-modules..) invocation to get the - dynamically-loaded module so that it can be tested outside of - scwm. Updated to reflect changed behaviour in cl-add-stay. Added - some test code for make-cl-constraint-from-string. - - * guile/cassowary_scm.hpp: Added ScmMakeClConstraint(..) to - abstract out setting "answer" for the (now) two ClConstraint ctrs. - - * guile/cassowary_scm.cc: Added make-cl-constraint-from-string for - interfacing to the parser. Wrap - cl-constraint-change-{strength,weight}!. Make dynamically loadable - module! Fix BUG: was returning SCM_UNDEFINED instead of - SCM_UNSPECIFIED. - - * guile/Makefile: Build libconstraints.so, and necessary directory - structure if neeeded. - - -Thu Feb 25 18:41:34 1999 Greg J Badros - - * c++/ClSimplexSolver.h, c++/ClSimplexSolver.cc: Make constraints - get told when they're added/removed from a solver. This means - that constraints are no longer const params to add/remove - Constraint functions, and also that removeConstraint needs an - internal version that doesn't do the counting (since - removeConstraint can get called from addConstraint to clean up - after a failed addition). - - * c++/ClSimplexSolver.cc: Clean up uses of ClConstraint &cn -- - prefer ClConstraint *pcn even internally. - - * c++/ClConstraint.h: Added ChangeStrength(..), ChangeWeight(..) - and _times_added memvar along w/ private (for friend - ClSimplexSolver) addedTo(..) and removedFrom(..) functions. Only - permit strength/weight changing if constraint is in no solvers - presently. - - * c++/ClConstraint.cc: Output _times_added memvar in printOn(...) - -Thu Feb 25 15:58:27 1999 Greg J Badros - - * c++/ClErrors.h: Added parse error classes, and have description - return a "string" instead of a "char *" - - * c++/creader.y: Use exception ExCLParseErrorMisc in clerror, Use - ClVarLookupFunction instead of mapVars and fAutoCreate - - * c++/creader.l: Use ClVarLookupFunction instead of doing it - inline with mapVars and fAutoCreate; throw exceptions on errors. - - * c++/creader.h: Added ClVarLookupFunction and ClVarLookupInMap - and use them when parsing. - - * c++/Makefile: Added some dependencies for proper building of - .l,.y files - - * c++/ClSimplexSolver.cc: Descend VarInVarSet from - unary_function<..,..> - - * c++/ClParseTest.cc: Catch parse errors and display the message. - Use ClVarLookupInMap class - -Thu Feb 25 12:09:48 1999 Greg J Badros - - * c++/ClSimplexSolver.cc: Simplify removeConstraint to not use - references. - - * c++/ClSimplexSolver.h: Updated a comment - - * c++/ClTests.cc: Use addEditVar, beginEdit, and endEdit, instead - of building EditConstraints directly. - -Tue Feb 23 18:48:21 1999 Greg J Badros - - * c++/creader.y, c++/creader.h: Remove old crummy lexer. Added - fAutoCreate flag to PcnParseConstraint to allow parsing with - automatic introduction of newly-referenced variables. - - * c++/creader.l: Fixed bugs in missing tokens "|", "(", ")", and - permit "==" as a synonym for "=". Honour the _fAutoCreate flag by - introducing variables when needed. - - * c++/ClTests.cc: Display version id string at startup. - - * c++/ClSimplexSolver.cc, c++/Cl.h: Added szCassowaryVersion id - string. - - * c++/ClParseTest.cc: Test auto-addition of variable (fAutoCreate - = true) - -Tue Feb 23 18:12:23 1999 Greg J Badros - - * c++/Makefile: Build libcassowary.{a,so} by default, not - libcassowary-notrace.{a,so}. Remove special rule for building - ClParseTest; list creader-lex.o, creader.o in OBJS and have them - be a part of the library. - - * c++/ClVariable.h, c++/ClVariable.cc: Rename pmapSzPclv to - pmapStrPclv. Make it a map from "const string" not "string". - Make setName erase the old mapping, and add the new mapping. - - * c++/ClParseTest.cc: Accept "-" option to mean "rename x to foo" - for testing the setName change above. - - * c++/ClFloatVariable.cc: Do not output warning msg in setName -- - instead, do the right thing in ClVariable.h - -Tue Feb 23 08:55:28 1999 Greg J Badros - - * c++/Makefile: Fix build rules for bison/flex parser so - dependencies are correct. Added new targets, all-notests, - all-tests, make 'lib' the default target, and all really build - everything. - - * c++/creader.h, c++/creader.l, c++/creader.y: Take address of - ClVariable-s from the map's values (cannot use ClVariable in the - union directly because union members cannot have constructors). - #include ClVariable.h instead of fwd decl of ClVariable so that we - get the StringToVarMap typedef, too. - -Mon Feb 22 16:33:16 1999 Greg J Badros - - * c++/Makefile: Use CL_LIBRARY, not LIB_FILE, throughout. Use - flags for maximum performance. - - * c++/ClVariable.h, c++/ClConstraintHash.h, c++/Cassowary.h: - Divide pointer address by CL_PTR_HASH_DIVISOR in hash functions - - * c++/ClTests.cc: Added CL_SHOW_CNS_IN_BENCHMARK guard protecting - new displaying of constraints and listing of inconsistent constraints. - -Mon Feb 22 12:18:53 1999 Greg J Badros - - * c++/ClTests.cc (inconsistent3): Drop extra redundant - inconsistency for pedagogical reasons. Use simpler pointer-based - addConstraint in benchmark test - - * c++/ClSimplexSolver.h: Added addConstraintNoException, - removeConstraintNoException taking ClConstraint &'s -- deprecated. - Added CL_NO_DEPRECATED guard for turning off availability of - deprecated functions. - -Mon Feb 22 11:12:35 1999 Greg J Badros - - * c++/ClSimplexSolver.h: Added deprecated - FIsConstraintSatisfied(Constraint &) - - * guile/cassowary_scm.cc: Use ClConstraintToVarMap for return - value of ConstraintMap(). Pass Constraint *'s instead of &'s. - Use new name printOnVerbose instead of printDebugInfo. - -Fri Feb 19 Greg J Badros - - * Release v0.3. - -Fri Feb 19 18:00:49 1999 Greg J Badros - - * c++/ClTests.cc: Updated to fix below interface. - - * c++/ClSimplexSolver.cc, c++/ClSimplexSolver.h: make - addConstraint, addConstraintNoException, removeConstraint, - removeConstraintNoException take ClConstraint *'s instead of - ClConstraint &'s. Clarifies the mental model, and simplifies the - syntax. Old style is still accepted, but is deprecated. - -Fri Feb 19 17:41:45 1999 Greg J Badros - - * c++/ClFloatVariable.cc, c++/ClFloatVariable.h: Added -- moved - here from ClVariable.h, and renamed from class ClVariableRep since - they not what ClVariable wraps (ClVariable wraps - ClAbstractVariable) - - * c++/ClAbstractVariable.h: Fatten interface to include set_value, - change_value, setPv, and Pv. - - * c++/ClVariable.h, c++/ClVariable.cc: Move ClVariableRep into - ClFloatVariable.{h,cc}, and use pclv-> for - set_value, change_value, SetPv, and Pv since ClAbstractVariable - now has a fat interface and we do not need to do the dynamic - down-casting. - - * c++/Makefile: Added new files to build rules. - -Fri Feb 19 17:08:29 1999 Greg J Badros - - * c++/debug.h, c++/ClTableau.h: Move operator<< out into ClTableau.h - - * c++/ClVariable.h, c++/ClVariable.cc: Move some inline functions - into .cc so that the hash function can go in the .h file (some stl - dependency issue, it seems). - - * c++/ClErrors.h, c++/ClTypedefs.h: Move typedef for - ClConstraintSet from ClErrors.h into ClTypedefs.h, and have former - include the latter. - - * c++/Cassowary.h: #include ClConstraintHash.h - - * c++/ClConstraintHash.h: Added. The hash function needs to - appear before any typedef that uses a hash_map or hash_set, so - this file is included by Cassowary.h - -Fri Feb 19 08:45:24 1999 Greg J Badros - - * c++/ClSubgraphTest.cc: Fix some bugs just from not testing - completely. - - * c++/*: Fix bugs from not-updated-code hidden by #ifdefs. Builds - w/ all compile-options except -DCL_USE_HASH_MAP_AND_SET. Drop - some gratuitous appearances of ClAbstractVariable - -Thu Feb 18 18:53:56 1999 Greg J Badros - - * c++/ClLinearExpression.cc: Use clvNill when returning a - ClVariable instead of NULL - - * c++/ClVariable.h, c++/ClVariable.cc: operators ==, !=, < all should use the - contained pointers address, not value. Also define global clvNil, - isNil(). - - * c++/ClTests.cc: BUGFIX: #if 0 removed from adding stays in - simple1 test - - * c++/ClSimplexSolver.h: Use ClVariable-s internally for - ClObjectiveVariable-s. - - * c++/ClSimplexSolver.cc: Use ClVariable-s internally for - ClObjectiveVariable-s and replace ClAbstractVariable - *p{entryVar,exitVar} with ClVariable-s. (Use clvNil and isNil() - to test for not yet set). - -Thu Feb 18 Greg J Badros - - * c++/*: First compilable and almost working version with - ClVariable as a handle to ClVariableRep. Major simplifications - throughout. - -Thu Feb 18 14:22:14 1999 Greg J Badros - - * c++/Makefile: Split out the options into += lists so they can be - flipped independently more easily. - - * c++/ClSimplexSolver.cc, c++/ClSimplexSolver.h: Added output - operation for ClConstraintToVarSetMap; use fFoundErrorVar flag to - simplify some redundant tests in removeConstraint -- no longer use - errorVarsCopy. - - * c++/CLVariable.h: Fix a comment's example. - - * c++/ClTypedefs.h: Use set always for ClTableauVarSet (Steve - Wolfman notes that it's faster as a set than as a hash_set). - - * c++/debug.h: Add CtrTracer, DtrTracer fns that do nothing when - not CL_TRACE - - * c++/ClConstraint.h: Invoke CtrTracer, DtrTracer in ctr, dtr for - finding memory problem - - * c++/ClTests.cc: Fix some long-time bugs in the use of ctrs that - build temporary objects whose lifetime was expected to be longer - than it was. - - * c++/*: Invert sense of CL_NO_TRACE to CL_TRACE - -Wed Feb 17 12:10:28 1999 Greg J Badros - - * c++/ClTypedefs.h: Added -- factored out useful typedefs from - ClSimplexSolver.h, ClTableau.h and put them in this file. - - * c++/ClTableau.h, c++/ClSimplexSolver.h, c++/debug.h: Use - ClTypedefs.h. Drop gdb_print (it uses printOn and printTo, now). - Renamed printDebugInfo to printOnVerbose (for generalized gdb - interface) - - * c++/ClSimplexSolver.cc: Fix two bugs where I was modifying data - structures indirectly while iterating over them. Remove a delete - that was premature to fix another bug in optimized builds. - - * c++/ClLinearExpression.h, c++/ClConstraint.h, - c++/ClAbstractVariable.h: Drop gdb_print(). - - * c++/ClSymbolicWeight.h: Use Number instead of double more consistently. - -Tue Feb 16 15:04:06 1999 Greg J Badros - - * c++/Cassowary.h,ClAbstractVariable.h,ClMap.h,ClSet.h,Makefile: Use - CL_USE_HASH_MAP_AND_SET, not USE_HASH_MAP_AND_SET. - - * c++/Cl.h: #undef CL_TRACE_VERBOSE ifdef CL_NO_IO - -Tue Feb 16 14:55:12 1999 Greg J Badros - - * java/ClVariable.java: Add setVarMap(..), getVarMap() for - maintaining symbol table of ClVariables. Added - setAttachedObject(..), getAttachedObject() for hanging something - off of a variable. - - * java/ClConstraint.java: Added setAttachedObject(..), - getAttachedObject() for hanging something off of a constraint. - - * java/ClTests.java: Added inconsistent3() and multiedit() tests - - * java/ClSimplexSolver.java: Manage multiple (nested) edits - properly. Provide access to the _markerVars var through - getConstraintMap() accessor. Deprecate resolve(Vector) fn. - -Tue Feb 16 14:29:46 1999 Greg J Badros - - * README: Updated reference to swig web site. - -Tue Feb 16 12:45:04 1999 Greg J Badros - - * java/ClSimplexSolver.java, java/ClEditInfo.java, java/Makefile: - Fixed Michael Kaufmann's bug. (See Feb 15 note for C++ version - two entries below.) - - * java/*.java: Updated copyright to include 1999. - -Tue Feb 16 10:51:01 1999 Greg J Badros - - * c++/*: Added CL_FIND_LEAK guard and ctr/ctr counters for - tracking various variable kinds. - -Mon Feb 15 18:38:06 1999 Greg J Badros - - * c++/ClAbstractVariable.{cc,h}, ClSlackVariable.{cc,h}, - ClDummyVariable.{cc,h}: Add counters to ctr/dtr for leakage detection. - - * c++/ClSimplexSolver.{cc,h}: Replace ClConstraintAndIndex with - ClEditInfo, and remove ugliness of parallel vectors for edit - constraints. Drop _editPlusErrorVars, _editMinusErrorVars, - _prevEditConstants, and bundle them all up in the value end of the - map attached to _editVarMap. This fixes a bug reported in the - Java version by Michael Kaufmann long ago, and generally cleans - code up a bit. The resolve(vector) function is - deprecated, and now implemented in terms of the indices stored in - the new ClEditInfo class. - - * c++/*: Updated copyright to include 1999. - -1999-02-15 Greg J Badros - - * c++/ClVariable.{cc,h}, c++/ClAbstractVariable.h: Added - SetVarMap(..), VarMap(), and make variables given names get their - names mapped to the objects in the var map (for access when - parsing constraints as strings). Make setName() virtual so - ClVariable can override it. - -1999-02-12 Greg J Badros - - * c++/creader.{y,h}: New version from Steve Wolfman, slightly - updated for cleaner integration. Pass in a map instead of an array of ClVariable; improve error handling a - bit. - - * c++/debug.h: Use ClMap, ClSet - - * c++/{ClMap.h,ClSet.h}: Added, for optionally using hash_map, - hash_set instead of map, set. - - * c++/ClSimplexSolver.{cc,h}: Added Steve Wolfman's explanation - support (added back map for marker->constraint, _fExplainFailure - var + getter & settor). Use ClMap, ClSet. Cleaned up some cerr - output, and use DEBUG_FAILURES cpp symbol to guard some output. - - * c++/Cassowary.h: Added operator() for hash<..> to support - hashing things used as keys in hash_map/hash_set - - * c++/ClErrors.h: Added ExCLRequiredFailureWithExplanation class - for explanation support. - - * c++/{ClLinearExpression.h,ClTableau.h}: Use ClMap, not map. Use - ClSet, not set. - - * c++/ClSymbolicWeight.h: Return a symbolic weight even when - assert(false) to avoid compiler warning. - -1999-02-11 Greg J Badros - - * guile/cassowary_scm.cc: Use cl-snarf.h, not scwm-snarf.h. Use - CL_PROC to denote primitives, not SCWM_PROC. Use - CL_VAR_INIT_PERMANENT macro for variables, and document them (the - strength objects only, for now). Fix the default strength of - cl-add-editvar to Strong, not Weak, and update docs (was cut&paste - error from the cl-add-stay primitive). Thanks Anthony Beurivé for - noticing this bug, too! - -Sat Jan 30 Greg Badros - - * Release v0.23. - -Sat Jan 30 13:16:31 1999 Greg Badros - - * c++/ClSimplexSolver.cc: Fixed bug in removing a stay - constraint. Was editing a vector in place while iterating over - it. Now I use remove_if and erase. Thanks to Anthony Beurivé for - noticing the bug. - - * c++/ClBug1.cc: Added -- bug report from Anthony Beurivé. - -Sat Jan 23 Greg Badros - - * Release v0.22. - -Sat Jan 23 16:46:27 1999 Greg Badros - - * guile/cassowary_scm.cc: Replace iarg uses with literal argument - index numbers. Use const_cast to avoid warnings when calling - ScmMakeClStrength on clsWeak,clsMedium,clsStrong,clsRequired objects - -Sat Jan 23 15:30:16 1999 Greg Badros - - * c++/ClSimplexSolver.cc: Added some comments, some explanations - when exceptions are thrown, and some minor cleanups, bug-fixes - - * c++/ClTests.cc: Added inconsistent3() test, and run it. - - * c++/ClStrength.h: Added _pv memvar, and setPv(), Pv() -- needed - for tracking ClStrengths in guile - - * guile/cassowary_scm.cc: Replace all iarg uses with the literal - number. Point ClStrength objects at their scheme-level object - using their new _pv field. Protect ClStrength objects properly. - -Sat Sep 19 17:08:21 1998 Greg Badros - - * c++/Makefile (CPPFLAGS): Added USE_GC, commented out, and added - OTHER_LIBS variable for linking with the gc library - -Sat Sep 19 17:01:16 1998 Greg Badros - - * c++/ClTableau.h: Added AssertValid() for testing integrity of - Tableau - - * c++/ClSymbolicWeight.h, c++/ClStrength.h, c++/ClSlackVariable.h, - c++/ClLinearExpression.h, c++/ClErrors.h, c++/ClDummyVariable.h, - c++/ClConstraint.h, c++/ClAbstractVariable.h: Descend objects - from "gc" class conditioned on USE_GC* pp macros - - * c++/Cassowary.h: Conditionally include gc_cpp.h ifdef USE_GC; - added NEWVAR and DELVAR macros for outputting debug information at - new/delete sites - - * c++/ClSimplexSolver.h: Call AssertValid before solving - - * c++/ClSimplexSolver.cc: Remove memory leak of the artificial - objective variable - - * c++/ClLinearExpression.h: Fix gdb_print to have a newline - - * c++/ClLeakTest: Added leakTest2 which more obviously leaks, and - use GC_gcollect() to force a collect - -Tue Sep 15 16:36:20 1998 Greg Badros - - * c++/ClTableau.h, ClTableau.cc: Handle removing vars from _columns more - carefully, and add gdb_print(), virtual destructor - - * c++/ClLinearExpression.h, c++/ClConstraint.h, - c++/ClAbstractVariable.h: Added gdb_print() - -Tue Sep 14 Greg Badros - - * Release v0.21. - -Wed Sep 9 09:46:35 1998 Greg Badros - - * c++/ClLinearExpression.h, c++/ClLinearExpression.cc: added uses - of 'typename' keyword as needed by egcs-1.1b's -pedantic (and the - C++ FDIS) - -Sun Sep 6 13:19:01 1998 Greg Badros - - * c++/ClSimplexSolver.h: Added _pv field, and Pv() setPv() getter - and setter - - * guile/cassowary_scm.cc: Use solver's _pv field to point - ClSimplexSolver back at the scheme object that wraps it - -Fri Sep 4 18:52:50 1998 Greg Badros - - * guile/cassowary_scm.hpp, guile/cassowary_scm.cc: Added PvFromScm - and ScmFromPv to hide the reinterpret casts used to store a scheme - object as the void * Pv() attached to a cassowary object. Attach - the scheme-level cl-variable to a ClVariable object. Added - `clv-attach!' and `clv-attached-object' to manipulate the attached - object (often better to use scheme level properties, though) - -Fri Sep 4 18:51:30 1998 Greg Badros - - * guile/Makefile: Use "perl" from path to run extract docs instead - of relying on #! line, and generate the -procedures.txt file as - well as the .sgml file - -Wed Sep 2 17:08:14 1998 Greg Badros - - * guile/cassowary_scm.cc, guile/cassowary_scm.hpp: Added - ClStayConstraint wrapper. Make cl-add-stay, cl-add-editvar take a - list of variables instead of a varargs last argument and instead - add two optional arguments STRENGTH and FACTOR (thus those - primitives remain backward compatible as long as only one variable - was given). - -Wed Sep 2 13:55:37 1998 Greg Badros - - * ClSimplexSolver.h: Added weight option to addEditVar and use it - - * ClLinearExpression.h: Added PconstClAbstractVariable, use it; - use ClVarToCoeffMap in coefficientFor. - -Thu Aug 6 20:56:45 1998 Greg Badros - - * Release v0.2. - -Thu Aug 6 20:41:40 1998 Greg Badros - - * ClTests.cc: Added multiedit() test for testing nested - beginEdit-s - - * ClSimplexSolver.h, ClSimplexSolver.cc: Support nested - beginEdit-s -- use removeEditVarsTo(n), and rewrite - removeAllEditVars in terms of the former; Use FIsSatisfied on - constraint and compare with testing internally for - FIsConstraintSatisfied() -- untested. - - * ClLinearInequality.h, ClLinearEquation.h, ClConstraint.h: Added - virtual FIsSatisfied - - * ClLinearExpression.h, ClLinearExpression.cc: Added evaluate() - - * ClAbstractVariable.h: Return 0 for value(), and make it a - virtual function. - -Wed Aug 5 16:10:56 1998 Greg Badros - - * ClStrength.h: Have ClStrength::symbolicWeight return a const - ref, instead of by value, make clsXXX const refs. - - * ClSimplexSolver.cc, ClLinearInequality.cc, ClLinearEquation.cc, - ClLinearConstraint.cc: Take ClStrengths by const refs - -Tue Aug 4 15:22:08 1998 Greg Badros - - * guile/cassowary_scm.cc, cassowary_scm.hpp: Move all inline - functions into .hpp file. Added cl-is-constraint-satisfied? - - * ClTableau.h: Added a rowExpression() const memfn, for - FIsConstraintSatisfied() - - * ClSimplexSolver.h, ClSimplexSolver.cc: Added (probably broken) - FIsConstraintSatisfied(cn) memfn -- needs testing - -Sun Aug 2 16:49:34 1998 Greg Badros - - * ClSimplexSolver.h: Added ConstraintMap() accessor to - _markerVars, for cl-constraint-list guile primitive - - * ClConstraint.h: Added setPv(), Pv(), and _pv field to a - constraint, for attaching extra information. - -Thu Jul 30 19:15:40 1998 Greg Badros - - * ClTests.cc: Added simple2, to test new EditMisuse exception on - editing a variable that is nowhere in the solver. - - * ClTableau.h, ClTableau.cc: Be more careful about inserting into - _externalParametricVars; add FIsBasicVar to assist that care. - - * ClSimplexSolver.cc, ClSimplexSolver.h: Added pfnCnSatCallback -- - does nothing for now; throw an ExCLEditMisuse exception if an - edit constraint is added on a variable that is not in the tableau - (needs at least a stay constraint in the solver); replace some - calls to rowExpression with FIsBasicVar when the latter is the - intent. - -Thu Jul 21 Greg Badros - - * ClVariable.h, ClVariable.cc: Added _pv field, settor and gettor. - - -ABOVE CHANGES ONLY IN C++ IMPLEMENTATION AND ITS WRAPPERS - -Fri Jul 17 19:24:54 1998 Greg Badros - - * ClVariable.h, .java: Added change_value memfn, and make it virtual - instead of setValue -- thus subclasses can specialize behaviour - when the variable gets set by the solver. - - * ClSimplexSolver.h, .java: Use change_value for setEditedValue if - the variable is not in the tableau; call resolve() before - removeAllEditVars in endEdit - - * ClSimplexSolver.cc, .java (setExternalVariables): Use change_value - instead of set_value when so subclasses can override and notice a - changed variable - -Thu Jul 16 19:49:45 1998 Greg Badros - - * Added setEditedValue(), FContainsVariable(), and addVar() to c++ - and Java implementations - - * Fixed bug in C++ and Java in solvers lacking stay constraints - that was due to not-updating the external parametric variables - set. - -Fri Jul 10 09:00:15 1998 Greg Badros - - * Fixed bug whereby a dummy variable was being pivoted into the - basis because pexpr->anyVariable() didn't guarantee the variable - it returned was a pivotable variable -- now it's called - anyPivotableVariable(), and does the right thing. - - * Fixed bug whereby column mappings that had no rows remained in - the list of columns -- now erase the column key when its value is - the empty set - - * Fixed bug whereby constraints that threw required failure - exceptions remained in the tableau (a removeConstraint on a - constraint that failed to be added used to succeed, now it does - not) - -Monday Jun 29 16:50:00 1998 Greg Badros - - * Release Cassowary v0.1 --- see local/POST-ANNOUNCE-TO for - list of places where it was announced - diff --git a/libs/cassowary/ClAbstractVariable.cc b/libs/cassowary/ClAbstractVariable.cc deleted file mode 100644 index b5502d4fbb..0000000000 --- a/libs/cassowary/ClAbstractVariable.cc +++ /dev/null @@ -1,23 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClAbstractVariable.cc - -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -long ClAbstractVariable::iVariableNumber = 0; -#ifdef CL_FIND_LEAK -long ClAbstractVariable::cAbstractVariables = 0; -#endif - diff --git a/libs/cassowary/ClBug0.cc b/libs/cassowary/ClBug0.cc deleted file mode 100644 index 09ca1826cb..0000000000 --- a/libs/cassowary/ClBug0.cc +++ /dev/null @@ -1,102 +0,0 @@ -// $Id$ - -#include - -/* This bug fixed --02/15/99 gjb - Replaced the parallel vectors for edit constraints - (the errorPlus..., errorMinus..., prevEditConstants vectors) - with a ClEditInfo class that is the Value of the _editVarMap map. - - Later I realized that I need to go to a _editVars list so that - multiple edits on the same variable that nest are handled properly. - --09/19/99 gjb -*/ - -int main() -{ - ClSimplexSolver solver; - - ClVariable x("x",7); - ClVariable y("y",8); - ClVariable z("z",9); - - solver - .AddStay(x) - .AddStay(y) - .AddStay(z); - - try { - solver.AddEditVar(x); - solver.AddEditVar(y); - solver.AddEditVar(z); - solver.BeginEdit(); - - solver.SuggestValue(x,1); - solver.SuggestValue(z,2); - - solver.RemoveEditVar(y); - - solver.SuggestValue(x,3); - solver.SuggestValue(z,4); - - solver.EndEdit(); - - } catch (ExCLError &e) { - cerr << e.description() << endl; - } - - cout << x << endl << y << endl << z < - To: - Subject: bugreport - Date: Thu, 1 Oct 1998 11:40:55 +0200 - Message-Id: <000001bded1f$973a2060$230e1fac@itc_mk.sbcs.swissbank.com> - Mime-Version: 1.0 - Content-Type: text/plain; - charset="iso-8859-1" - Content-Transfer-Encoding: 7bit - X-Priority: 3 (Normal) - X-Msmail-Priority: Normal - X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 - Importance: Normal - X-Mimeole: Produced By Microsoft MimeOLE V4.72.2106.4 - - Dear Mr Noth, - - I am currently working with the Java implementation of Cassowary and found - the following bug: - - If I Add several editConstraints, remove some of them again later and - perform a 'ClSimplexSolver.SuggestValue()', the indices of - 'ClConstraintAndIndex' in the variable 'cai' are sometimes wrong (see - ClSimplexSolver.SuggestValue(ClVariable v, double x), the 3rd line). This is - because if you remove an element from a 'java.util.Vector', and the element - is somewhere in the middle of the Vector, the indices of the Vector change. - (see java.util.Vector.removeElementAt(int index): - - public final synchronized void removeElementAt(int index) { - if (index >= elementCount) { - throw new ArrayIndexOutOfBoundsException(index + " >= " + - elementCount); - } - else if (index < 0) { - throw new ArrayIndexOutOfBoundsException(index); - } - int j = elementCount - index - 1; - if (j > 0) { - System.arraycopy(elementData, index + 1, elementData, index, j); - } - elementCount--; - elementData[elementCount] = null; /* to let gc do its work */ - } - - - My workaround now is, that everytime when I remove an EditVariable from the - Solver, I have to remove all the EditVariables and Add then the ones again, - that I do not want to remove. - -#endif diff --git a/libs/cassowary/ClBug1.cc b/libs/cassowary/ClBug1.cc deleted file mode 100644 index e7543757e3..0000000000 --- a/libs/cassowary/ClBug1.cc +++ /dev/null @@ -1,21 +0,0 @@ -#include - -int main() -{ - ClVariable *var = new ClVariable(); - ClSimplexSolver *solver = new ClSimplexSolver(); - ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),1.0); - - cout << *solver; - solver->AddConstraint(*stcn); - cout << *solver; - solver->RemoveConstraint(*stcn); - cout << *solver; -} -/* -The result is a segmentation fault when the constraint is removed. I -don't understand why. - -Anthony Beurive'" -*/ - diff --git a/libs/cassowary/ClBug2.cc b/libs/cassowary/ClBug2.cc deleted file mode 100644 index 3a1e424259..0000000000 --- a/libs/cassowary/ClBug2.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* $Id$ - -From: "Anthony Beurive'" -Subject: cassowary -To: gjb@cs.washington.edu -Date: Tue, 9 Mar 1999 12:42:24 +0100 (CET) - -I believe there's a bug in cassowary. It seems to be related to the -previous one I encountered a while ago, concerning the removal of -constraints. - -The three following examples may help you to track the bug, I hope. - --------------------------------------------------------------------------------- -#include "Cl.h" - -void main() -{ - ClSimplexSolver *solver = new ClSimplexSolver(); - ClVariable *var = new ClVariable(); - ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),1.0); - - solver->AddConstraint(*stcn); - cout << *solver; - solver->RemoveConstraint(*stcn); - cout << *solver; -} --------------------------------------------------------------------------------- -This works fine. - - -Now, the factor of the stay constraint is changed. --------------------------------------------------------------------------------- -#include "Cl.h" - -void main() -{ - ClSimplexSolver *solver = new ClSimplexSolver(); - ClVariable *var = new ClVariable(); - ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),2.0); - - solver->AddConstraint(*stcn); - cout << *solver; - solver->RemoveConstraint(*stcn); - cout << *solver; -} --------------------------------------------------------------------------------- -The result is: -test2: ClSimplexSolver.cc:1199: void ClSimplexSolver::Optimize(class ClVariable): Assertion \ -`pzRow != __null' failed. -Aborted - - -Now, the solver is created after the variable. --------------------------------------------------------------------------------- -#include "Cl.h" - -void main() -{ - ClVariable *var = new ClVariable(); - ClSimplexSolver *solver = new ClSimplexSolver(); - ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),2.0); - - solver->AddConstraint(*stcn); - cout << *solver; - solver->RemoveConstraint(*stcn); - cout << *solver; -} --------------------------------------------------------------------------------- -This works again. - - -Can you reproduce the same results? Maybe the cause is my c++ -compiler (egcs-2.90.29 980515 (egcs-1.0.3 release)). I don't know. - -*/ - -#include - -void foo1() -{ - ClSimplexSolver *solver = new ClSimplexSolver(); - ClVariable *var = new ClVariable(); - ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),1.0); - - solver->AddConstraint(*stcn); - cout << *solver; - solver->RemoveConstraint(*stcn); - cout << *solver; -} - - -void foo2() -{ - ClSimplexSolver *solver = new ClSimplexSolver(); - ClVariable *var = new ClVariable(); - ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),2.0); - - solver->AddConstraint(*stcn); - cout << *solver; - solver->RemoveConstraint(*stcn); - cout << *solver; -} - - -void foo3() -{ - ClVariable *var = new ClVariable(); - ClSimplexSolver *solver = new ClSimplexSolver(); - ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),2.0); - - solver->AddConstraint(*stcn); - cout << *solver; - solver->RemoveConstraint(*stcn); - cout << *solver; -} - - -int main() -{ - cerr << "Test1: " << endl; - foo1(); - - cerr << "\nTest2: " << endl; - foo2(); - - cerr << "\nTest3: " << endl; - foo3(); - -} diff --git a/libs/cassowary/ClConstraint.cc b/libs/cassowary/ClConstraint.cc deleted file mode 100644 index 1bc6be91b3..0000000000 --- a/libs/cassowary/ClConstraint.cc +++ /dev/null @@ -1,32 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClConstraint.cc - -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -#ifndef CL_NO_IO -#include // for VarSet printing - -ostream & -ClConstraint::PrintOn(ostream &xo) const -{ - // Note that the trailing "= 0)" or ">= 0)" is missing, as derived classes will - // print the right thing after calling this function - xo << strength() << " w{" << weight() << "} ta{" - << _times_added << "} RO" << _readOnlyVars << " " << "(" << Expression(); - return xo; -} - -#endif diff --git a/libs/cassowary/ClDummyVariable.cc b/libs/cassowary/ClDummyVariable.cc deleted file mode 100644 index e1e9b39c0c..0000000000 --- a/libs/cassowary/ClDummyVariable.cc +++ /dev/null @@ -1,12 +0,0 @@ -// $Id$ - -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -#ifdef CL_FIND_LEAK -long ClDummyVariable::cDummyVariables = 0; -#endif diff --git a/libs/cassowary/ClFDBinaryOneWayConstraint.cc b/libs/cassowary/ClFDBinaryOneWayConstraint.cc deleted file mode 100644 index e7bf7f1089..0000000000 --- a/libs/cassowary/ClFDBinaryOneWayConstraint.cc +++ /dev/null @@ -1,140 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClFDBinaryOneWayConstraint.cc - - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -#include -#include -#include -#include - - -void -ClFDBinaryOneWayConstraint::EnsurePreconditionsForCn(const ClConstraint &cn) -{ - ClVarSet setRO = cn.ReadOnlyVars(); - if (setRO.size() > 1) - throw ExCLTooDifficultSpecial("Only 0 or 1 read only variables are allowed"); - const ClLinearExpression &expr = cn.Expression(); - const ClVarToNumberMap &terms = expr.Terms(); - if (terms.size() > 2) - throw ExCLTooDifficultSpecial("Cannot have more than 2 variables"); - if (terms.size() == 0) - throw ExCLTooDifficultSpecial("Must have at least 1 variable"); - if (terms.size() == 2 && setRO.size() == 0) - throw ExCLTooDifficultSpecial("Both variables cannot be read-write, one must be read-only"); - if (terms.size() == 1 && setRO.size() == 1) - throw ExCLTooDifficultSpecial("Single read-only variable in LinearConstraint -- must not be read-only."); - ClVariable clv = (*terms.begin()).first; - /* GJB:FIXME:: iterate over all the variables */ - if (!clv->IsFDVariable()) { - throw ExCLTooDifficultSpecial("FD constraint contains non-FD variables"); - } -} - -bool -ClFDBinaryOneWayConstraint::FCanConvertCn(const ClConstraint &cn) -{ - try { - EnsurePreconditionsForCn(cn); - return true; - } catch (...) { - return false; - } -} - - -ClFDBinaryOneWayConstraint::ClFDBinaryOneWayConstraint(const ClConstraint &cn) - :ClFDConstraint(cn.strength(), cn.weight()) -{ - EnsurePreconditionsForCn(cn); - list l; - /* GJB:FIXME:: varargs inteface, with sentinel as first arg? */ - l.push_back(9); - l.push_back(10); - l.push_back(12); - l.push_back(14); - l.push_back(20); - - ClVarSet setRO = cn.ReadOnlyVars(); - - ClVariable clvRO = clvNil; - ClVariable clvROLinear = clvNil; - Number coeffRO = 0; - - ClVariable clvRW = clvNil; - Number coeffRW = 0; - - if (setRO.size() == 1) { - const ClVariable &clv = *(setRO.begin()); - if (clv->IsFDVariable()) - clvRO = clv; - else - clvRO = new ClFDVariable(clv.Name(),clv.IntValue(),l); - clvROLinear = clv; - } - const ClLinearExpression &expr = cn.Expression(); - const ClVarToNumberMap &terms = expr.Terms(); - - for (ClVarToNumberMap::const_iterator it = terms.begin(); - it != terms.end(); - ++it) { - ClVariable clv = (*it).first; - if (clv == clvROLinear) { - coeffRO = (*it).second; - } else { - if (clv->IsFDVariable()) - clvRW = clv; - else - clvRW = new ClFDVariable(clv.Name(),clv.Value(),l); - coeffRW = (*it).second; - } - } - assert(!clvRW.IsNil()); - if (coeffRW == 0) { - throw ExCLTooDifficultSpecial("RW variable's coefficient must be non-zero"); - } - - bool fInequality = cn.IsInequality(); - bool fStrictInequality = cn.IsStrictInequality(); - double rhs_constant = expr.Constant(); - - // now we have: - // coeffRW * clvRW + coeffRO * clvRO rhs_constant - // where is >= if fInequality, or = if !fInequality - // - // need: - // clvRW coefficient * clvRO + constant - // - // so: - // coefficient = -coeffRO/coeffRW - // constant = rhs_constant/coeffRW - - if (fStrictInequality) - _rel = cnGT; - else if (fInequality) - _rel = cnGEQ; - else - _rel = cnEQ; - - if (coeffRW < 0) - _rel = ReverseInequality(_rel); - - _coefficient = -coeffRO/coeffRW; - _constant = -rhs_constant/coeffRW; - _vRW = clvRW; - _vRO = clvRO; - return; -} diff --git a/libs/cassowary/ClFDConnectorVariable.cc b/libs/cassowary/ClFDConnectorVariable.cc deleted file mode 100644 index e6618eb9d4..0000000000 --- a/libs/cassowary/ClFDConnectorVariable.cc +++ /dev/null @@ -1,29 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClFDConnectorVariable.cc - -#include -#include // for list printing - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -// Use < > for ClFDConnector-s, instead of [ ] -#ifndef CL_NO_IO -ostream &ClFDConnectorVariable::PrintOn(ostream &xo) const -{ - xo << "<" << Name() << "=" << Value() - << "{" << _clvFloat << "}" - << ":" << *PlfdnDomain() << ">"; - return xo; -} -#endif diff --git a/libs/cassowary/ClFDSolver.cc b/libs/cassowary/ClFDSolver.cc deleted file mode 100644 index 7f2d199869..0000000000 --- a/libs/cassowary/ClFDSolver.cc +++ /dev/null @@ -1,364 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClFDSolver.cc - - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int fDebugFDSolve; - -ClFDSolver & -ClFDSolver::AddConstraint(ClConstraint *const pcn) -{ - AddConstraintInternal(pcn); - if (_fAutosolve) Solve(); - return *this; -} - -ClFDSolver & -ClFDSolver::RemoveConstraint(ClConstraint *const pcn) -{ - RemoveConstraintInternal(pcn); - if (_fAutosolve) Solve(); - return *this; -} - -ClFDSolver & -ClFDSolver::AddConstraintInternal(ClConstraint *const pcn) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << *pcn << ")" << endl; -#endif - - ClFDBinaryOneWayConstraint *const pcnfd = - dynamic_cast(pcn); - if (!pcnfd) { - throw ExCLTooDifficultSpecial("Can only add ClFDBinaryOneWayConstraint-s to ClFDSolvers"); - } - ClVariable rw = pcnfd->ClvRW(); - ClVariable ro = pcnfd->ClvRO(); - if (!rw.IsFDVariable()) { - throw ExCLTooDifficultSpecial("RW variable must be an FDVariable"); - } - if (!(ro.IsNil() || ro.IsFDVariable())) { - throw ExCLTooDifficultSpecial("RO variable must be an FDVariable or clvNil"); - } - // add the constraint to our set of cns - _setCns.insert(pcn); - // and add the constraint to the cns that affect var rw - assert(!rw.IsNil()); - _mapClvToCns[rw].insert(pcn); - - - node nRw = GetVarNode(rw); - if (!ro.IsNil()) { - node nRo = GetVarNode(ro); - edge e = G.new_edge(nRo, nRw); - - _mapCnToEdge[pcn] = e; - - if (!G.is_acyclic()) { - /* there is a cycle... give up after cleaning up */ - RemoveConstraint(pcn); - throw ExCLCycleNotAllowed(); - } - } - return *this; -} - -ClFDSolver & -ClFDSolver::RemoveConstraintInternal(ClConstraint *const pcn) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << *pcn << ")" << endl; -#endif - - ClFDBinaryOneWayConstraint *const pcnfd = - dynamic_cast(pcn); - - if (!pcnfd) { - throw ExCLInternalError("Could not downcast to a ClFDBinaryOneWayConstraint"); - } - - ClConstraintSet::iterator itCn = _setCns.find(pcnfd); - if (itCn == _setCns.end()) { - throw ExCLConstraintNotFound(); - } - _setCns.erase(itCn); - - ClVariable rw = pcnfd->ClvRW(); - ClVariable ro = pcnfd->ClvRO(); - ClConstraintSet &_cnsAffectingRW = _mapClvToCns[rw]; - ClConstraintSet::iterator it = _cnsAffectingRW.find(pcnfd); - if (it == _cnsAffectingRW.end()) { - throw ExCLInternalError("Cannot find pcnfd"); - } - _cnsAffectingRW.erase(it); - - if (!ro.IsNil()) { - edge e = _mapCnToEdge[pcn]; - G.del_edge(e); - _mapCnToEdge.erase(pcn); - - if (_mapVarToNode.find(ro) != _mapVarToNode.end() && - _mapVarToNode[ro].degree() == 0) { - G.del_node(_mapVarToNode[ro]); - _mapVarToNode.erase(ro); - } - } - if (_mapVarToNode.find(rw) != _mapVarToNode.end() && - _mapVarToNode[rw].degree() == 0) { - G.del_node(_mapVarToNode[rw]); - _mapVarToNode.erase(rw); - } - if (_mapClvToCns[rw].size() == 0) { - _mapClvToCns.erase(rw); - } - - return *this; -} - -ClFDSolver & -ClFDSolver::Solve() -{ - topsort t; - t.run(G); - topsort::topsort_iterator it = t.top_order_begin(); - topsort::topsort_iterator end = t.top_order_end(); - ClSymbolicWeight errorTotal; - ResetSetFlagsOnVariables(); - for (; it != end; ++it) { - ClVariable clv = nodeToVar[*it]; - ClFDVariable *pcldv = dynamic_cast(clv.get_pclv()); -#ifndef NO_FDSOLVE_DEBUG - if (fDebugFDSolve) { - if (!clv.IsNil()) cout << "node " << (*it) << " is " << clv << endl; - cerr << "Set from: " << endl; - for (ClConstraintSet::iterator itCns = _mapClvToCns[clv].begin(); - itCns != _mapClvToCns[clv].end(); - ++itCns) { - const ClConstraint *pcn = *itCns; - cerr << *pcn << endl; - } - cerr << endl; - } -#endif - pair p = ComputeBest(pcldv); - ClSymbolicWeight e = p.first; - FDNumber v = p.second; - if (v == FDN_NOTSET) - throw ExCLRequiredFailure(); - pcldv->ChangeValue(v); - pcldv->SetFIsSet(true); - errorTotal += e; - } - return *this; -} - -/* return the best (lowest) incremental error and the value - at which that error occurs */ -pair -ClFDSolver::ComputeBest(ClFDVariable *pcldv) -{ - assert(pcldv); - // assert(!pcldv->FIsSet()); //GJB:FIXME:: - ClSymbolicWeight minError = ClsRequired().symbolicWeight(); - FDNumber bestValue = FDN_NOTSET; - // ClVariable clv(pcldv); - // for each domain value - for (list::const_iterator itVal= pcldv->PlfdnDomain()->begin(); - itVal != pcldv->PlfdnDomain()->end(); - ++itVal) { - FDNumber value = *itVal; - ClSymbolicWeight error; - const ClConstraintSet &setCns = _mapClvToCns[pcldv]; - // for each constraint affecting *pcldv - for (ClConstraintSet::const_iterator itCn = setCns.begin(); - itCn != setCns.end(); - ++itCn) { - const ClConstraint *pcn = *itCn; - ClSymbolicWeight e = ErrorForClvAtValSubjectToCn(pcldv,value,*pcn); - error += e; - } - // now error is the total error for binding clv <- value - if (error < minError) { - minError = error; - bestValue = value; - } - } - // now minError is the lowest error we can get for clv - // and it occurs binding clv <- bestValue - if (bestValue == FDN_NOTSET) - throw ExCLRequiredFailure(); - return pair(minError,bestValue); -} - -ClSymbolicWeight -ClFDSolver::ErrorForClvAtValSubjectToCn(ClFDVariable *pcldv,FDNumber value,const ClConstraint &cn) -{ - const ClFDBinaryOneWayConstraint *pcnFd = dynamic_cast(&cn); - if (!pcnFd) throw ExCLInternalError("Not a binary FD constraint."); - ClCnRelation rel = pcnFd->Relation(); - double m = pcnFd->Coefficient(); - double b = pcnFd->Constant(); - ClVariable rw = pcnFd->ClvRW(); - ClVariable ro = pcnFd->ClvRO(); - assert(rw.get_pclv() == pcldv); - double e; - double x = ro.IsNil()? 0 : ro.Value(); - // return the error in satisfying: - // value REL m*x + b - double rhs = m*x + b; - switch (rel) { - case cnLEQ: - if (value <= rhs) e = 0; - else e = 1 + value-rhs; - break; - case cnLT: - if (value < rhs) e = 0; - else e = 1 + value-rhs; - break; - case cnGEQ: - if (value >= rhs) e = 0; - else e = 1+ rhs-value; - break; - case cnGT: - if (value > rhs) e = 0; - else e = 1 + rhs-value; - break; - case cnEQ: - if (value == rhs) e = 0; - else e = 1 + fabs(rhs-value); - break; - case cnNEQ: - if (value != rhs) e = 0; - else e = 1; /* GJB:FIXME:: what makes sense here? */ - break; - default: - e = 0; /* quiet warning */ - assert(false); - } - - ClSymbolicWeight err; - if (cn.IsRequired() && e > 0) - err = ClsRequired().symbolicWeight(); - else - err = cn.symbolicWeight() * (e*cn._weight); -#ifndef NO_FDSOLVE_DEBUG - if (fDebugFDSolve) { - cerr << "Error at " << value << " = " << err << endl; - } -#endif - return err; -} - - -ClFDSolver & -ClFDSolver::ShowSolve() -{ - topsort t; - t.run(G); - topsort::topsort_iterator it = t.top_order_begin(); - topsort::topsort_iterator end = t.top_order_end(); - for (; it != end; ++it) { - ClVariable clv = nodeToVar[*it]; - if (!clv.IsNil()) cout << "Node " << (*it) << " is " << clv << endl; - cout << "Set from: " << endl; - for (ClConstraintSet::iterator itCns = _mapClvToCns[clv].begin(); - itCns != _mapClvToCns[clv].end(); - ++itCns) { - const ClConstraint *pcn = *itCns; - cout << *pcn << endl; - } - cout << endl; - } - return *this; -} - - -/* Turn all FDVariable FIsSet() flags to false */ -void -ClFDSolver::ResetSetFlagsOnVariables() -{ - for (ClVarToConstraintSetMap::iterator it = _mapClvToCns.begin(); - it != _mapClvToCns.end(); - ++it) { - ClVariable clv = (*it).first; - ClFDVariable *pcldv = dynamic_cast(clv.get_pclv()); - assert(pcldv); - pcldv->SetFIsSet(false); - } -} - - -ostream & -ClFDSolver::PrintOn(ostream &xo) const -{ - xo << "FDSolver: " - << _setCns - << "Graph nodes, edges = " << G.number_of_nodes() << ", " << G.number_of_edges() - << endl; - return xo; -} - -ostream & -ClFDSolver::PrintInternalInfo(ostream &xo) const -{ return xo; } - - -ostream &operator<<(ostream &xo, const ClFDSolver &clfds) -{ return clfds.PrintOn(xo); } - - -//// protected member functions - -/* Create node for v in G, if necessary, - otherwise return the node we already created. */ -node -ClFDSolver::GetVarNode(ClVariable v) -{ - ClMap::iterator it = _mapVarToNode.find(v); - if (it == _mapVarToNode.end()) { - node n = G.new_node(); - _mapVarToNode[v] = n; - nodeToVar[n] = v; - return n; - } else { - return (*it).second; - } -} - - -void -ListPushOnto(list *pl, ...) -{ - va_list ap; - va_start(ap, pl); - FDNumber n; - while ( (n = va_arg(ap, FDNumber)) != FDN_EOL) { - pl->push_back(n); - } - va_end(ap); -} diff --git a/libs/cassowary/ClFDVariable.cc b/libs/cassowary/ClFDVariable.cc deleted file mode 100644 index 5ab9d518b1..0000000000 --- a/libs/cassowary/ClFDVariable.cc +++ /dev/null @@ -1,27 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClFDVariable.cc - -#include -#include // for list printing - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -// Use < > for ClFDVariable-s, instead of [ ] -#ifndef CL_NO_IO -ostream &ClFDVariable::PrintOn(ostream &xo) const -{ - xo << "<" << Name() << "=" << Value() << ":" << *PlfdnDomain() << ">"; - return xo; -} -#endif diff --git a/libs/cassowary/ClFloatVariable.cc b/libs/cassowary/ClFloatVariable.cc deleted file mode 100644 index a3096e4b08..0000000000 --- a/libs/cassowary/ClFloatVariable.cc +++ /dev/null @@ -1,25 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClFloatVariable.cc - -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -#ifndef CL_NO_IO -ostream &ClFloatVariable::PrintOn(ostream &xo) const -{ - xo << "[" << Name() << ":" << _value << "]"; - return xo; -} -#endif diff --git a/libs/cassowary/ClLinearExpression.cc b/libs/cassowary/ClLinearExpression.cc deleted file mode 100644 index 72383ffec1..0000000000 --- a/libs/cassowary/ClLinearExpression.cc +++ /dev/null @@ -1,473 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClLinearExpression.cc - -using namespace std; - -#include -#include /// needed only to instantiate with T=ClSymbolicWeight -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -template -ClGenericLinearExpression::ClGenericLinearExpression(T num) : - _constant(num) -{ } - -// Convert from ClVariable to a ClLinearExpression -// this replaces ClVariable::asLinearExpression -template -ClGenericLinearExpression::ClGenericLinearExpression(ClVariable clv, T value, - T Constant) : - _constant(Constant) -{ - _terms[clv] = value; -} - -template -ClGenericLinearExpression::~ClGenericLinearExpression() -{ } - -#ifndef CL_NO_IO -template -ostream & -ClGenericLinearExpression::PrintOn(ostream &xo) const -{ - typename ClVarToCoeffMap::const_iterator i = _terms.begin(); - - if (!ClApprox(_constant,0.0) || i == _terms.end()) - { - xo << _constant; - } - else - { - if (i == _terms.end()) - return xo; - xo << (*i).second << "*" << (*i).first; - ++i; - } - for ( ; i != _terms.end(); ++i) - { - xo << " + " << (*i).second << "*" << (*i).first; - } - return xo; -} -#endif - - - -// Destructively multiply self by x. -// (private memfn) -template -ClGenericLinearExpression & -ClGenericLinearExpression::MultiplyMe(T x) -{ - _constant *= x; - - typename ClVarToCoeffMap::const_iterator i = _terms.begin(); - for ( ; i != _terms.end(); ++i) - { - _terms[(*i).first] = (*i).second * x; - } - return *this; -} - -// Return a new linear expression formed by multiplying self by x. -// (Note that this result must be linear.) -template -ClGenericLinearExpression -ClGenericLinearExpression::Times(Number x) const -{ - ClGenericLinearExpression result = *this; - return result.MultiplyMe(x); -} - -// Return a new linear expression formed by multiplying self by x. -// (Note that this result must be linear.) -// The above function optimizes the specific case of multiplying -// by a Constant, here is the more general case -template -ClGenericLinearExpression -ClGenericLinearExpression::Times(const ClGenericLinearExpression &expr) const -{ - if (IsConstant()) - { - return expr.Times(_constant); - } - else if (!expr.IsConstant()) - { - // neither are constants, so we'd introduce non-linearity - throw ExCLNonlinearExpression(); - } - return Times(expr._constant); -} - - -// Return a new linear expression formed by adding x to self. -template -ClGenericLinearExpression -ClGenericLinearExpression::Plus(const ClGenericLinearExpression &expr) const -{ - ClGenericLinearExpression result = *this; - result.AddExpression(expr,1.0); - return result; -} - -// Return a new linear expression formed by subtracting x from self. -template -ClGenericLinearExpression -ClGenericLinearExpression::Minus(const ClGenericLinearExpression &expr) const -{ - ClGenericLinearExpression result = *this; - result.AddExpression(expr,-1.0); - return result; -} - -// Return a new linear expression formed by dividing self by x. -// (Note that this result must be linear.) -template -ClGenericLinearExpression -ClGenericLinearExpression::Divide(Number x) const -{ - if (ClApprox(x,0.0)) - { - throw ExCLNonlinearExpression(); - } - return Times(1.0/x); -} - -// Return a new linear expression formed by dividing self by x. -// (Note that this result must be linear.) -template -ClGenericLinearExpression -ClGenericLinearExpression::Divide(const ClGenericLinearExpression &expr) const -{ - if (!expr.IsConstant()) - { - throw ExCLNonlinearExpression(); - } - return Divide(expr._constant); -} - - -// Return a new linear expression (expr/this). Since the result -// must be linear, this is permissible only if 'this' is a Constant. -template -ClGenericLinearExpression -ClGenericLinearExpression::DivFrom(const ClGenericLinearExpression &expr) const -{ - if (!IsConstant() || ClApprox(_constant,0.0)) - { - throw ExCLNonlinearExpression(); - } - return expr.Divide(_constant); -} - -// Add n*expr to this expression for another expression expr. -template -ClGenericLinearExpression & -ClGenericLinearExpression::AddExpression(const ClGenericLinearExpression &expr, Number n) -{ - IncrementConstant(expr.Constant()*n); - - typename ClVarToCoeffMap::const_iterator i = expr._terms.begin(); - for ( ; i != expr._terms.end(); ++i) - { - AddVariable((*i).first, (*i).second * n); - } - return *this; -} - -// Add n*expr to this expression for another expression expr. -// Notify the solver if a variable is added or deleted from this -// expression. -template -ClGenericLinearExpression & -ClGenericLinearExpression::AddExpression(const ClGenericLinearExpression &expr, Number n, - ClVariable subject, - ClTableau &solver) -{ - IncrementConstant(expr.Constant() * n); - - typename ClVarToCoeffMap::const_iterator i = expr._terms.begin(); - for ( ; i != expr._terms.end(); ++i) - { - AddVariable((*i).first, (*i).second * n, subject, solver); - } - return *this; -} - -// Add a term c*v to this expression. If the expression already -// contains a term involving v, Add c to the existing coefficient. -// If the new coefficient is approximately 0, delete v. -template -ClGenericLinearExpression & -ClGenericLinearExpression::AddVariable(ClVariable v, T c) -{ // body largely duplicated below -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << v << ", " << c << ")" << endl; -#endif - typename ClVarToCoeffMap::iterator i = _terms.find(v); - if (i != _terms.end()) - { - // expression already contains that variable, so Add to it - T new_coefficient = 0; - new_coefficient = (*i).second + c; - if (ClApprox(new_coefficient,0.0)) - { - // new coefficient is Zero, so erase it - _terms.erase(i); - } - else - { - (*i).second = new_coefficient; - } - } - else // expression did not contain that variable - { - if (!ClApprox(c,0.0)) - { - _terms[v] = c; - } - } - return *this; -} - -// Add a term c*v to this expression. If the expression already -// contains a term involving v, Add c to the existing coefficient. -// If the new coefficient is approximately 0, delete v. Notify the -// solver if v appears or disappears from this expression. -template -ClGenericLinearExpression & -ClGenericLinearExpression::AddVariable(ClVariable v, T c, - ClVariable subject, - ClTableau &solver) -{ // body largely duplicated above -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << v << ", " << c << ", " << subject << ", ...)" << endl; -#endif - typename ClVarToCoeffMap::iterator i = _terms.find(v); - if (i != _terms.end()) - { - // expression already contains that variable, so Add to it - T new_coefficient = (*i).second + c; - if (ClApprox(new_coefficient,0.0)) - { - // new coefficient is Zero, so erase it - solver.NoteRemovedVariable((*i).first,subject); - _terms.erase(i); - } - else - { - (*i).second = new_coefficient; - } - } - else // expression did not contain that variable - { - if (!ClApprox(c,0.0)) - { - _terms[v] = c; - solver.NoteAddedVariable(v,subject); - } - } -#ifdef CL_TRACE - cerr << "Now *this == " << *this << endl; -#endif - return *this; -} - -// Return a variable in this expression. (It is an error if this -// expression is Constant -- signal ExCLInternalError in that case). -template -ClVariable -ClGenericLinearExpression::AnyPivotableVariable() const -{ - if (IsConstant()) - { - throw ExCLInternalError("(ExCLInternalError) No pivotable variables in Constant expression"); - } - typename ClVarToCoeffMap::const_iterator i = _terms.begin(); - for ( ; i != _terms.end(); ++i) - { - ClVariable v = (*i).first; - if (v.IsPivotable()) - return v; - } - return clvNil; -} - -// Replace var with a symbolic expression expr that is equal to it. -// If a variable has been added to this expression that wasn't there -// before, or if a variable has been dropped from this expression -// because it now has a coefficient of 0, inform the solver. -// PRECONDITIONS: -// var occurs with a non-Zero coefficient in this expression. -template -void -ClGenericLinearExpression::SubstituteOut(ClVariable var, - const ClGenericLinearExpression &expr, - ClVariable subject, - ClTableau &solver) -{ -#ifdef CL_TRACE - cerr << "* ClGenericLinearExpression::"; - Tracer TRACER(__FUNCTION__); - cerr << "(" << var << ", " << expr << ", " << subject << ", " - << solver << ")" << endl; - cerr << "*this == " << *this << endl; -#endif - - typename ClVarToCoeffMap::iterator pv = _terms.find(var); - -#ifndef NDEBUG - if (pv == _terms.end()) - { -#ifndef CL_NO_IO - cerr << "SubstituteOut: pv != _terms.end()" << endl; - cerr << "(" << var << ", " << expr << ", " << subject << ", " - << ")" << endl; - cerr << "*this == " << *this << endl; -#endif - throw "SubstituteOut: pv != _terms.end()"; - } -#endif - assert(pv != _terms.end()); - // FIXGJB: this got thrown! assert(!ClApprox((*pv).second,0.0)); - - T multiplier = (*pv).second; - _terms.erase(pv); - IncrementConstant(multiplier * expr._constant); - typename ClVarToCoeffMap::const_iterator i = expr._terms.begin(); - for ( ; i != expr._terms.end(); ++i) - { - ClVariable v = (*i).first; - T c = (*i).second; - typename ClVarToCoeffMap::iterator poc = _terms.find(v); - if (poc != _terms.end()) - { // if oldCoeff is not nil -#ifdef CL_TRACE - cerr << "Considering (*poc) == " << (*poc).second << "*" << (*poc).first << endl; -#endif - // found it, so new coefficient is old one Plus what is in *i - T newCoeff = (*poc).second + (multiplier*c); - if (ClApprox(newCoeff,0.0)) - { - solver.NoteRemovedVariable((*poc).first,subject); - _terms.erase(poc); - } - else - { - (*poc).second = newCoeff; - } - } - else - { // did not have that variable already (oldCoeff == nil) -#ifdef CL_TRACE - cerr << "Adding (*i) == " << (*i).second << "*" << (*i).first << endl; -#endif - _terms[v] = multiplier * c; - solver.NoteAddedVariable(v,subject); - } - } -#ifdef CL_TRACE - cerr << "Now (*this) is " << *this << endl; -#endif -} - -// This linear expression currently represents the equation -// oldSubject=self. Destructively modify it so that it represents -// the equation NewSubject=self. -// -// Precondition: NewSubject currently has a nonzero coefficient in -// this expression. -// -// NOTES -// Suppose this expression is c + a*NewSubject + a1*v1 + ... + an*vn. -// -// Then the current equation is -// oldSubject = c + a*NewSubject + a1*v1 + ... + an*vn. -// The new equation will be -// NewSubject = -c/a + oldSubject/a - (a1/a)*v1 - ... - (an/a)*vn. -// Note that the term involving NewSubject has been dropped. -// -// Basically, we consider the expression to be an equation with oldSubject -// equal to the expression, then Resolve the equation for NewSubject, -// and destructively make the expression what NewSubject is then equal to -template -void -ClGenericLinearExpression::ChangeSubject(ClVariable old_subject, - ClVariable new_subject) -{ - _terms[old_subject] = NewSubject(new_subject); -} - -inline double ReciprocalOf(double n) -{ return 1.0/n; } - -// This linear expression currently represents the equation self=0. Destructively modify it so -// that subject=self represents an equivalent equation. -// -// Precondition: subject must be one of the variables in this expression. -// NOTES -// Suppose this expression is -// c + a*subject + a1*v1 + ... + an*vn -// representing -// c + a*subject + a1*v1 + ... + an*vn = 0 -// The modified expression will be -// subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn -// representing -// subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn = 0 -// -// Note that the term involving subject has been dropped. -// -// Returns the reciprocal, so that NewSubject can be used by ChangeSubject -template -T -ClGenericLinearExpression::NewSubject(ClVariable subject) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << subject << ")" << endl; -#endif - typename ClVarToCoeffMap::iterator pnewSubject = _terms.find(subject); - assert(pnewSubject != _terms.end()); - // assert(!ClApprox((*pnewSubject).second,0.0)); - T reciprocal = ReciprocalOf((*pnewSubject).second); - _terms.erase(pnewSubject); - MultiplyMe(-reciprocal); - return reciprocal; -} - -template -T -ClGenericLinearExpression::Evaluate() const -{ - T answer = _constant; - typename ClVarToCoeffMap::const_iterator i = _terms.begin(); - - for ( ; i != _terms.end(); ++i) - { - ClVariable v = (*i).first; - answer += (*i).second * v.Value(); - } - return answer; -} - - -template class ClGenericLinearExpression; -// template class ClGenericLinearExpression; diff --git a/libs/cassowary/ClReader.ll b/libs/cassowary/ClReader.ll deleted file mode 100644 index 77fa13a5a1..0000000000 --- a/libs/cassowary/ClReader.ll +++ /dev/null @@ -1,87 +0,0 @@ -/* $Id$ - Cassowary Incremental Constraint Solver - Original Smalltalk Implementation by Alan Borning - This C++ Implementation by Greg J. Badros, - http://www.cs.washington.edu/homes/gjb - (C) 1998, 1999 Greg J. Badros and Alan Borning - See ../LICENSE for legal details regarding this software - - ClReader.l - Scanner for constraint parsing. - By Greg J. Badros - */ - -%{ -/* Get the token numbers that bison created for us - (uses the -d option of bison) */ - -#include -#include "ClReader.cc.h" - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -/* global variable for the istream we are reading from; - gets set by PcnParseConstraint */ -istream *pxi_lexer; - -/* Pass in an extra variable (ClParseData *) to cllex so that - it can look up variable names */ -#define YY_DECL int cllex(YYSTYPE *lvalp, void *YYLEX_PARAM) - -/* Make lexer reader from the global variable */ -#define YY_INPUT(buf,result,max_size) \ - do { if (pxi_lexer->get(buf[0]) && buf[0] > 0) result = 1; \ - else result = YY_NULL; } while (0) - -%} - -%option noyywrap - -DIGIT [0-9] -ALPHA [A-Za-z] -ALPHANUM [A-Za-z0-9] -ID_OK_PUNC [-_\[\]] -RO_ANNOTATION "?" -ID {ALPHA}({ALPHANUM}|{ID_OK_PUNC})*({RO_ANNOTATION})? -NUMID "{"{DIGIT}+"}" -ws [ \t\n]+ - -%% -{ws} /* skip whitespace */ -\n|";" { return 0; } -">=" { return GEQ; } -">" { return GT; } -"<=" { return LEQ; } -"<" { return LT; } -"==" { return '='; } -"="|"-"|"+"|"*"|"/"|"("|")" { return yytext[0]; } - -{DIGIT}+("."{DIGIT}*)? | -"."{DIGIT}+ { lvalp->num = strtod(yytext,0); return NUM; } - -{ID} { /* Lookup the variable name */ - ClParseData *pclpd = ((ClParseData *) YYLEX_PARAM); - int cch = strlen(yytext); - ClVariable *pclv = NULL; - bool fReadOnly = false; - if (yytext[cch-1] == '?') { - yytext[cch-1] = '\0'; - fReadOnly = true; - } - const string str = string(yytext); - pclv = pclpd->_lookup_func(str); - if (!pclv->IsNil()) { - lvalp->pclv = pclv; - return fReadOnly?RO_VAR:VAR; - } else { - pxi_lexer = NULL; - yy_flush_buffer(YY_CURRENT_BUFFER); - throw ExCLParseErrorBadIdentifier(str); - return 0; - } - } - -. { pxi_lexer = NULL; throw ExCLParseErrorMisc("Unrecognized character"); } - diff --git a/libs/cassowary/ClReader.yy b/libs/cassowary/ClReader.yy deleted file mode 100644 index f9f0dca43e..0000000000 --- a/libs/cassowary/ClReader.yy +++ /dev/null @@ -1,154 +0,0 @@ -/* - $Id$ - - Cassowary Incremental Constraint Solver - Original Smalltalk Implementation by Alan Borning - This C++ Implementation by Greg J. Badros, - http://www.cs.washington.edu/homes/gjb - (C) 1998, 1999 Greg J. Badros and Alan Borning - See ../LICENSE for legal details regarding this software - - ClReader.y - Original implementation contributed by Steve Wolfman - Subsequently largely revised by Greg J. Badros - - Supports parsing of read-only variables in constraints via "?" suffix - annotations on variables. If a variable is followed by "?" in any of - its occurrences in the constraint, that variable is deemed read-only - and entered into the constraint object as such. E.g., - - x = 2*y? - - is a one-way constraint that sets x from y's value. - - x = y + y? - and - x = y? + y - - are identical one-way constraints with y read-only. One would prefer - to have it written like so: - - x = y? + y? - - but it need not be, and no warning or error is raised. -*/ - - -%{ - /* C Declarations */ - -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -#ifdef USE_CRUMMY_LEXER -string current; /* Global to help in debugging/error messages */ -#endif - -/* Get yyparse, yylex to have an extra argument (type void *) */ -#define YYPARSE_PARAM cl_parse_data -#define YYLEX_PARAM cl_parse_data -#ifndef YYERROR_VERBOSE -#define YYERROR_VERBOSE -#endif -#define YYDEBUG 1 - -%} - - -/* Bison Declarations */ - -%pure_parser - -%union { - double num; - const ClVariable *pclv; - ClLinearExpression *pcle; - ClConstraint *pcn; -} - -%{ -int yylex(YYSTYPE *lvalp, void *YYLEX_PARAM); -void yyerror(const char *sz); -%} - -%start constraint - -%token NUM -%token VAR -%token RO_VAR - -%token GEQ -%token GT -%token LEQ -%token LT - -%type expr -%type constraint equation inequality - -%left '-' '+' -%left '*' '/' -%left NEG - -%% -/* Grammar Rules */ - -constraint: equation { $$ = $1; ((ClParseData*)YYPARSE_PARAM)->_pcn = $1; } - | inequality { $$ = $1; ((ClParseData*)YYPARSE_PARAM)->_pcn = $1; } -; - -equation: expr '=' expr { $$ = new ClLinearEquation(*$1, *$3); } -; - -inequality: expr GEQ expr { $$ = new ClLinearInequality(*$1, cnGEQ, *$3); } - | expr LEQ expr { $$ = new ClLinearInequality(*$1, cnLEQ, *$3); } - | expr LT expr { $$ = new ClLinearInequality(*$1, cnLT, *$3); } - | expr GT expr { $$ = new ClLinearInequality(*$1, cnGT, *$3); } -; - -expr: NUM { $$ = new ClLinearExpression($1); } - | VAR { $$ = new ClLinearExpression(*$1); } - | RO_VAR { $$ = new ClLinearExpression(*$1); - ((ClParseData*)YYPARSE_PARAM)->_readOnlyVarsSoFar.insert(*$1); } - | expr '+' expr { $$ = new ClLinearExpression(*$1 + *$3); } - | expr '-' expr { $$ = new ClLinearExpression(*$1 - *$3); } - | expr '*' expr { $$ = new ClLinearExpression(*$1 * *$3); } - | expr '/' expr { $$ = new ClLinearExpression(*$1 / *$3); } - | '-' expr %prec NEG { $$ = new ClLinearExpression(-1 * *$2); } - | '(' expr ')' { $$ = $2; } -; - -%% - -void clerror(const char *sz) -{ - throw ExCLParseErrorMisc(sz); -} - -extern istream *pxi_lexer; - -// xi is the stream from which to read the constraint. -// aVars is an array of variables large enough to account for -// each one that might be mentioned in a constraint -ClConstraint *PcnParseConstraint(istream &xi, const ClVarLookupFunction &lookup_func, - const ClStrength &strength) -{ - ClParseData cl_parse_data(xi, lookup_func); - pxi_lexer = ξ - if (yyparse(&cl_parse_data) == 0) { // success -#ifdef DEBUG_PARSER - cerr << *cl_parse_data.Pcn() << endl; -#endif - cl_parse_data.Pcn()->ChangeStrength(strength); - cl_parse_data.Pcn()->AddROVars(cl_parse_data._readOnlyVarsSoFar); - return cl_parse_data.Pcn(); - } - else { // failed - return 0; - } -} diff --git a/libs/cassowary/ClSimplexSolver.cc b/libs/cassowary/ClSimplexSolver.cc deleted file mode 100644 index 32ea59df74..0000000000 --- a/libs/cassowary/ClSimplexSolver.cc +++ /dev/null @@ -1,1631 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClSimplexSolver.cc - -using namespace std; - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -// Need to delete all expressions -// and all slack and dummy variables -// See NewExpression -- all allocation is done in there -ClSimplexSolver::~ClSimplexSolver() -{ -#ifdef CL_SOLVER_STATS - cerr << "_slackCounter == " << _slackCounter - << "\n_artificialCounter == " << _artificialCounter - << "\n_dummyCounter == " << _dummyCounter << endl; - cerr << "stayMinusErrorVars " << _stayMinusErrorVars.size() << ", " - << "stayPlusErrorVars " << _stayPlusErrorVars.size() << ", " - << "errorVars " << _errorVars.size() << ", " - << "markerVars " << _markerVars.size() << endl; -#endif - // Cannot print *this here, since local ClVariable-s may have been - // destructed already -} - -// Add the constraint cn to the tableau -ClSimplexSolver & -ClSimplexSolver::AddConstraint(ClConstraint *const pcn) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << *pcn << ")" << endl; -#endif - - if (!pcn->FIsOkayForSimplexSolver()) { - throw ExCLTooDifficultSpecial("SimplexSolver cannot handle this constraint object"); - } - - if (pcn->IsStrictInequality()) { - // cannot handle strict inequalities - throw ExCLStrictInequalityNotAllowed(); - } - - if (pcn->ReadOnlyVars().size() > 0) { - // cannot handle read-only vars - throw ExCLReadOnlyNotAllowed(); - } - - if (pcn->IsEditConstraint()) - { - ClEditConstraint *pcnEdit = dynamic_cast(pcn); - const ClVariable &v = pcnEdit->variable(); - if (!v.IsExternal() || - (!FIsBasicVar(v) && !ColumnsHasKey(v))) - { - // we could try to make this case work, - // but it'd be unnecessarily inefficient -- - // and probably easier for the client application - // to deal with - throw ExCLEditMisuse("(ExCLEditMisuse) Edit constraint on variable not in tableau."); - } - ClEditInfo *pcei = PEditInfoFromClv(v); - if (pcei) - { - // we need to only add a partial _editInfoList entry for this - // edit constraint since the variable is already being edited. - // otherwise a more complete entry is added later in this function - _editInfoList.push_back(new ClEditInfo(v, NULL, clvNil, clvNil, 0)); - return *this; - } - } - - ClVariable clvEplus, clvEminus; - Number prevEConstant; - ClLinearExpression *pexpr = NewExpression(pcn, /* output to: */ - clvEplus,clvEminus, - prevEConstant); - bool fAddedOkDirectly = false; - - try - { - // If possible Add expr directly to the appropriate tableau by - // choosing a subject for expr (a variable to become basic) from - // among the current variables in expr. If this doesn't work use an - // artificial variable. After adding expr re-Optimize. - fAddedOkDirectly = TryAddingDirectly(*pexpr); - } - catch (ExCLRequiredFailure &error) - { -#ifdef CL_TRACE - cerr << "could not Add directly -- caught ExCLRequiredFailure error" << endl; -#endif - RemoveConstraintInternal(pcn); - throw; - } - - if (!fAddedOkDirectly) - { // could not Add directly - ExCLRequiredFailureWithExplanation e; - if (!AddWithArtificialVariable(*pexpr, e)) - { -#ifdef CL_DEBUG_FAILURES - cerr << "Failed solve! Could not Add constraint.\n" - << *this << endl; -#endif - RemoveConstraintInternal(pcn); - if (FIsExplaining()) - throw e; - else - throw ExCLRequiredFailure(); - } - } - - _fNeedsSolving = true; - - if (pcn->IsEditConstraint()) - { - ClEditConstraint *pcnEdit = dynamic_cast(pcn); - ClVariable clv = pcnEdit->variable(); - _editInfoList.push_back(new ClEditInfo(clv, pcnEdit, clvEplus, clvEminus, - prevEConstant)); - } - - if (_fAutosolve) - { - Optimize(_objective); - SetExternalVariables(); - } - - pcn->addedTo(*this); - return *this; -} - -// Add weak stays to the x and y parts of each point. These have -// increasing weights so that the solver will try to satisfy the x -// and y stays on the same point, rather than the x stay on one and -// the y stay on another. -ClSimplexSolver & -ClSimplexSolver::AddPointStays(const vector &listOfPoints, - const ClStrength &strength) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); -#endif - - vector::const_iterator it = listOfPoints.begin(); - double weight = 1.0; - static const double multiplier = 2.0; - for ( ; it != listOfPoints.end(); ++it ) - { - AddPointStay((*it)->X(),(*it)->Y(),strength,weight); - weight *= multiplier; - } - return *this; -} - -ClSimplexSolver & -ClSimplexSolver::AddPointStay(const ClPoint &clp, const ClStrength &strength, double weight) -{ - AddPointStay(clp.X(),clp.Y(),strength,weight); - return *this; -} - - -ClSimplexSolver & -ClSimplexSolver::RemoveEditVarsTo(unsigned int n) -{ - queue qclv; - ClVarSet sclvStillEditing; // Set of edit variables that we need to *not* remove -#ifdef DEBUG_NESTED_EDITS - cerr << __FUNCTION__ << " " << n << endl; -#endif - unsigned int i = 0; - for ( ClEditInfoList::const_iterator it = _editInfoList.begin(); - (it != _editInfoList.end() && _editInfoList.size() != static_cast(n)); - ++it, ++i ) - { - const ClEditInfo *pcei = (*it); - assert(pcei); -#ifdef DEBUG_NESTED_EDITS - cerr << __FUNCTION__ << "Checking " << pcei->_clv - << ", index = " << i << endl; -#endif - if (i >= n) - qclv.push(pcei->_clv); - else - sclvStillEditing.insert(pcei->_clv); - } - while (!qclv.empty()) - { - ClVariable clv = qclv.front(); - // only remove the variable if it's not in the set of variable - // from a previous nested outer edit - // e.g., if I do: - // Edit x,y - // Edit w,h,x,y - // EndEdit - // The end edit needs to only get rid of the edits on w,h - // not the ones on x,y - if (sclvStillEditing.find(clv) == sclvStillEditing.end()) - { -#ifdef DEBUG_NESTED_EDITS - cerr << __FUNCTION__ << ": Removing " << clv << endl; -#endif - RemoveEditVar(clv); - } -#ifdef DEBUG_NESTED_EDITS - else - { - cerr << __FUNCTION__ << ": Not removing " << clv << endl; - } -#endif - qclv.pop(); - } - while (_editInfoList.size() > n) { - _editInfoList.pop_back(); - } - - return *this; -} - - -/* A predicate used for remove_if */ -class VarInVarSet : public unary_function { -public: - VarInVarSet(const ClVarSet &clvset) : - _set(clvset), - _setEnd(clvset.end()) - { } - - bool operator ()(ClVariable clv) const { - return (_set.find(clv) != _setEnd); - } - -private: - const ClVarSet &_set; - const ClVarSet::iterator _setEnd; -}; - - - -// Remove the constraint cn from the tableau -// Also remove any error variable associated with cn -ClSimplexSolver & -ClSimplexSolver::RemoveConstraintInternal(const ClConstraint *const pcn) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << *pcn << ")" << endl; -#endif - - // We are about to remove a constraint. There may be some stay - // constraints that were unsatisfied previously -- if we just - // removed the constraint these could come into play. Instead, - // Reset all of the stays so that things should stay where they are - // at the moment. - _fNeedsSolving = true; - - ResetStayConstants(); - - // remove any error variables from the objective function - ClLinearExpression *pzRow = RowExpression(_objective); - -#ifdef CL_TRACE - cerr << _errorVars << endl << endl; -#endif - - ClConstraintToVarSetMap::iterator - it_eVars = _errorVars.find(pcn); - bool fFoundErrorVar = (it_eVars != _errorVars.end()); - - if (fFoundErrorVar) - { - ClVarSet &eVars = (*it_eVars).second; - ClVarSet::iterator it = eVars.begin(); - for ( ; it != eVars.end(); ++it ) - { - const ClLinearExpression *pexpr = RowExpression(*it); - if (pexpr == NULL ) - { - pzRow->AddVariable(*it,-pcn->weight() * pcn->strength().symbolicWeight().AsDouble(), - _objective,*this); - } - else - { // the error variable was in the basis - pzRow->AddExpression(*pexpr,-pcn->weight() * pcn->strength().symbolicWeight().AsDouble(), - _objective,*this); - } - } - } - - ClConstraintToVarMap::iterator - it_marker = _markerVars.find(pcn); - if (it_marker == _markerVars.end()) - { // could not find the constraint - throw ExCLConstraintNotFound(); - } - // try to make the marker variable basic if it isn't already - const ClVariable marker = (*it_marker).second; - _markerVars.erase(it_marker); - _constraintsMarked.erase(marker); -#ifdef CL_TRACE - cerr << "Looking to remove var " << marker << endl; -#endif - if (!FIsBasicVar(marker)) - { // not in the basis, so need to do some work - // first choose which variable to move out of the basis - // only consider restricted basic variables - ClVarSet &col = _columns[marker]; - ClVarSet::iterator it_col = col.begin(); -#ifdef CL_TRACE - cerr << "Must Pivot -- columns are " << col << endl; -#endif - - ClVariable exitVar = clvNil; - bool fExitVarSet = false; - double minRatio = 0.0; - for ( ; it_col != col.end(); ++it_col) - { - const ClVariable &v = *it_col; - if (v.IsRestricted() ) - { - const ClLinearExpression *pexpr = RowExpression(v); - assert(pexpr != NULL ); - Number coeff = pexpr->CoefficientFor(marker); -#ifdef CL_TRACE - cerr << "Marker " << marker << "'s coefficient in " << *pexpr << " is " - << coeff << endl; -#endif - // only consider negative coefficients - if (coeff < 0.0) - { - Number r = - pexpr->Constant() / coeff; - if (!fExitVarSet || r < minRatio) - { - minRatio = r; - exitVar = v; - fExitVarSet = true; - } - } - } - } - // if we didn't set exitvar above, then either the marker - // variable has a positive coefficient in all equations, or it - // only occurs in equations for unrestricted variables. If it - // does occur in an equation for a restricted variable, pick the - // equation that gives the smallest ratio. (The row with the - // marker variable will become infeasible, but all the other rows - // will still be feasible; and we will be dropping the row with - // the marker variable. In effect we are removing the - // non-negativity restriction on the marker variable.) - if (!fExitVarSet) - { -#ifdef CL_TRACE - cerr << "exitVar did not get set" << endl; -#endif - it_col = col.begin(); - for ( ; it_col != col.end(); ++it_col) - { - ClVariable v = *it_col; - if (v.IsRestricted() ) - { - const ClLinearExpression *pexpr = RowExpression(v); - assert(pexpr != NULL); - Number coeff = pexpr->CoefficientFor(marker); - Number r = pexpr->Constant() / coeff; - if (!fExitVarSet || r < minRatio) - { - minRatio = r; - exitVar = v; - fExitVarSet = true; - } - } - } - } - - if (!fExitVarSet) - { // exitVar is still nil - // If col is empty, then exitVar doesn't occur in any equations, - // so just remove it. Otherwise pick an exit var from among the - // unrestricted variables whose equation involves the marker var - if (col.size() == 0) - { - RemoveColumn(marker); - } - else - { - // A. Beurive' Tue Sep 14 18:26:05 CEST 1999 - // Don't pick the objective, or it will be removed! - it_col = col.begin(); - for ( ; it_col != col.end(); ++it_col) - { - ClVariable v = *it_col; - if (v != _objective) - { - exitVar = v; - fExitVarSet = true; - break; - } - } - assert(fExitVarSet == true); - } - } - - if (fExitVarSet) - { - Pivot(marker,exitVar); - } - } - - if (FIsBasicVar(marker)) - { - ClLinearExpression *pexpr = RemoveRow(marker); -#ifdef CL_TRACE - cerr << "delete@ " << pexpr << endl; -#endif - delete pexpr; - } - - // Delete any error variables. If cn is an inequality, it also - // contains a slack variable; but we use that as the marker variable - // and so it has been deleted when we removed its row. - if (fFoundErrorVar) - { - ClVarSet &eVars = (*it_eVars).second; - ClVarSet::iterator it = eVars.begin(); - for ( ; it != eVars.end(); ++it ) - { - ClVariable v = (*it); - if (v != marker) - { - RemoveColumn(v); - } - } - } - - if (pcn->isStayConstraint()) - { - // iterate over the stay{Plus,Minus}ErrorVars and remove those - // variables v in those vectors that are also in set eVars - if (fFoundErrorVar) - { - ClVarSet &eVars = (*it_eVars).second; - _stayPlusErrorVars - .erase(remove_if(_stayPlusErrorVars.begin(),_stayPlusErrorVars.end(), - VarInVarSet(eVars)), - _stayPlusErrorVars.end()); - _stayMinusErrorVars - .erase(remove_if(_stayMinusErrorVars.begin(),_stayMinusErrorVars.end(), - VarInVarSet(eVars)), - _stayMinusErrorVars.end()); - } - } - else if (pcn->IsEditConstraint()) - { - const ClEditConstraint *pcnEdit = dynamic_cast(pcn); - const ClVariable clv = pcnEdit->variable(); - ClEditInfo *pcei = PEditInfoFromClv(clv); - assert(pcei); - ClVariable clvEditMinus = pcei->_clvEditMinus; - RemoveColumn(clvEditMinus); // clvEditPlus is a marker var and gets removed later - delete pcei; - _editInfoList.remove(pcei); - } - - if (fFoundErrorVar) - { - // This code is not needed since the variables are deleted - // when they are removed from the row -- - // leaving it in results in double deletions - // delete the constraint's error variables - // ClVarSet &evars_set = (*it_eVars).second; - // ClVarSet::const_iterator it_set = evars_set.begin(); - // for ( ; it_set != evars_set.end(); ++it_set) - // { - // delete *it_set; - // } - _errorVars.erase((*it_eVars).first); - } - - if (_fAutosolve) - { - Optimize(_objective); - SetExternalVariables(); - } - - return *this; -} - - -// Re-initialize this solver from the original constraints, thus -// getting rid of any accumulated numerical problems. (Actually, -// Alan hasn't observed any such problems yet, but here's the method -// anyway.) -void -ClSimplexSolver::Reset() -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "()" << endl; -#endif - // FIXGJB -- can postpone writing this for a while - // gotta be careful, though, as it's a likely place for - // a memory leak to sneak in - assert(false); -} - - -// Re-solve the cuurent collection of constraints, given the new -// values for the edit variables that have already been -// suggested (see SuggestValue() method) -void -ClSimplexSolver::Resolve() -{ // CODE DUPLICATED ABOVE -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); -#endif - DualOptimize(); - SetExternalVariables(); - _infeasibleRows.clear(); - if (_fResetStayConstantsAutomatically) - ResetStayConstants(); -} - -ClSimplexSolver & -ClSimplexSolver::SuggestValue(ClVariable v, Number x) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); -#endif - ClEditInfo *pcei = PEditInfoFromClv(v); - if (NULL == pcei) - { -#ifndef CL_NO_IO - std::stringstream ss; - ss << "SuggestValue for variable " << v << ", but var is not an edit variable" << ends; - throw ExCLEditMisuse(ss.str().c_str()); -#else - throw ExCLEditMisuse(v.Name().c_str()); -#endif - } - ClVariable clvEditPlus = pcei->_clvEditPlus; - ClVariable clvEditMinus = pcei->_clvEditMinus; - Number delta = x - pcei->_prevEditConstant; - pcei->_prevEditConstant = x; - DeltaEditConstant(delta,clvEditPlus,clvEditMinus); - return *this; -} - -// Re-solve the cuurent collection of constraints, given the new -// values for the edit variables that have already been -// suggested (see SuggestValue() method) -// This is not guaranteed to work if you remove an edit constraint -// from the middle of the edit constraints you added -// (e.g., edit A, edit B, edit C, remove B -> this will fail!) -// DEPRECATED -void -ClSimplexSolver::Resolve(const vector &newEditConstants) -{ - ClEditInfoList::iterator it = _editInfoList.begin(); - unsigned int i = 0; - for (; i < newEditConstants.size() && it != _editInfoList.end(); ++it, ++i) - { - ClEditInfo *pcei = (*it); - SuggestValue(pcei->_clv,newEditConstants[i]); - } - Resolve(); -} - - -//// protected - -// Add the constraint expr=0 to the inequality tableau using an -// artificial variable. To do this, create an artificial variable -// av and Add av=expr to the inequality tableau, then make av be 0. -// (Raise an exception if we can't attain av=0 -- and prepare explanation) -bool -ClSimplexSolver::AddWithArtificialVariable(ClLinearExpression &expr, - ExCLRequiredFailureWithExplanation &e) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << expr << ")" << endl; -#endif - - // Allocate the objects on the heap because the objects - // will remain in the tableau if we throw an exception, - // and that will result in the destructor cleaning up - // after us - ClSlackVariable *pav = new ClSlackVariable(++_artificialCounter,"a"); - ClObjectiveVariable *paz = new ClObjectiveVariable("az"); - ClLinearExpression *pazRow = new ClLinearExpression(expr); - // the artificial objective is av, which we know is equal to expr - // (which contains only parametric variables) - -#ifdef CL_FIND_LEAK - cerr << "aC = " << _artificialCounter - << "\nDeletes = " << _cArtificialVarsDeleted << endl; -#endif -#ifdef CL_TRACE - cerr << __FUNCTION__ << " before addRow-s:\n" - << (*this) << endl; -#endif - - // the artificial objective is av, which we know is equal to expr - // (which contains only parametric variables) - - // objective is treated as a row in the tableau, - // so do the substitution for its value (we are minimizing - // the artificial variable) - // this row will be removed from the tableau after optimizing - addRow(*paz,*pazRow); - - // now Add the normal row to the tableau -- when artifical - // variable is minimized to 0 (if possible) - // this row remains in the tableau to maintain the constraint - // we are trying to Add - addRow(*pav,expr); - -#ifdef CL_TRACE - cerr << __FUNCTION__ << " after addRow-s:\n" - << (*this) << endl; -#endif - - // try to Optimize az to 0 - // note we are *not* optimizing the real objective, but optimizing - // the artificial objective to see if the error in the constraint - // we are adding can be set to 0 - Optimize(*paz); - - // Careful, we want to get the Expression that is in - // the tableau, not the one we initialized it with! - ClLinearExpression *pazTableauRow = RowExpression(*paz); -#ifdef CL_TRACE - cerr << "pazTableauRow->Constant() == " << pazTableauRow->Constant() << endl; -#endif - - // Check that we were able to make the objective value 0 - // If not, the original constraint was not satisfiable - if (!ClApprox(pazTableauRow->Constant(),0.0)) - { - BuildExplanation(e, paz, pazTableauRow); - // remove the artificial objective row that we just - // added temporarily - delete RemoveRow(*paz); - // and delete the artificial objective variable that we also added above - delete paz; - return false; - } - - // see if av is a basic variable - const ClLinearExpression *pe = RowExpression(*pav); - if (pe != NULL) - { - // FIXGJB: do we ever even get here? - // Find another variable in this row and Pivot, so that av becomes parametric - // If there isn't another variable in the row then - // the tableau contains the equation av = 0 -- just delete av's row - if (pe->IsConstant()) - { - // FIXGJB: do we ever get here? - assert(ClApprox(pe->Constant(),0.0)); - delete RemoveRow(*pav); - // remove the temporary objective function - // FIXGJB may need this too: delete RemoveRow(*paz); - delete pav; -#ifdef CL_FIND_LEAK - ++_cArtificialVarsDeleted; -#endif - return true; - } - ClVariable entryVar = pe->AnyPivotableVariable(); - if (entryVar.IsNil()) - { - BuildExplanation(e, *pav, pe); - return false; /* required failure */ - } - Pivot(entryVar, *pav); - } - // now av should be parametric - assert(RowExpression(*pav) == NULL); - RemoveColumn(*pav); - delete pav; -#ifdef CL_FIND_LEAK - ++_cArtificialVarsDeleted; -#endif - // remove the temporary objective function - delete RemoveRow(*paz); - delete paz; - return true; -} - - -// Using the given equation (av = cle) build an explanation which -// implicates all constraints used to construct the equation. That -// is, everything for which the variables in the equation are markers. -void ClSimplexSolver::BuildExplanation(ExCLRequiredFailureWithExplanation &e, - ClVariable av, - const ClLinearExpression *pcle) -{ - ClVarToConstraintMap::iterator it_cn; - it_cn = _constraintsMarked.find(av); - if (it_cn != _constraintsMarked.end()) - { - e.AddConstraint((*it_cn).second); - } - - assert(pcle != NULL); - - const ClVarToNumberMap & terms = pcle->Terms(); - ClVarToNumberMap::const_iterator it_term; - for (it_term = terms.begin(); it_term != terms.end(); it_term++) - { - it_cn = _constraintsMarked.find((*it_term).first); - if (it_cn != _constraintsMarked.end()) - { - e.AddConstraint((*it_cn).second); - } - } -} - - - -// We are trying to Add the constraint expr=0 to the appropriate -// tableau. Try to Add expr directly to the tableaus without -// creating an artificial variable. Return true if successful and -// false if not. -bool -ClSimplexSolver::TryAddingDirectly(ClLinearExpression &expr) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << expr << ")" << endl; -#endif - ClVariable subject = ChooseSubject(expr); - if (subject.get_pclv() == NULL ) - { -#ifdef CL_TRACE - cerr << "- returning false" << endl; -#endif - return false; - } - expr.NewSubject(subject); - if (ColumnsHasKey(subject)) - { - SubstituteOut(subject,expr); - } - addRow(subject,expr); -#ifdef CL_TRACE - cerr << "- returning true" << endl; -#endif - return true; // successfully added directly -} - - -// We are trying to Add the constraint expr=0 to the tableaux. Try -// to choose a subject (a variable to become basic) from among the -// current variables in expr. If expr contains any unrestricted -// variables, then we must choose an unrestricted variable as the -// subject. Also, if the subject is new to the solver we won't have -// to do any substitutions, so we prefer new variables to ones that -// are currently noted as parametric. If expr contains only -// restricted variables, if there is a restricted variable with a -// negative coefficient that is new to the solver we can make that -// the subject. Otherwise we can't find a subject, so return nil. -// (In this last case we have to Add an artificial variable and use -// that variable as the subject -- this is done outside this method -// though.) -// -// Note: in checking for variables that are new to the solver, we -// ignore whether a variable occurs in the objective function, since -// new slack variables are added to the objective function by -// 'NewExpression:', which is called before this method. -ClVariable -ClSimplexSolver::ChooseSubject(ClLinearExpression &expr) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << expr << ")" << endl; -#endif - ClVariable subject(clvNil); // the current best subject, if any - - // true iff we have found a subject that is an unrestricted variable - bool foundUnrestricted = false; - - // true iff we have found a restricted variable that is new to the - // solver (except for being in the obj. function) and that has a - // negative coefficient - bool foundNewRestricted = false; - - const ClVarToNumberMap &terms = expr.Terms(); - ClVarToNumberMap::const_iterator it = terms.begin(); - for ( ; it != terms.end(); ++it ) - { - ClVariable v = (*it).first; - Number c = (*it).second; - - if (foundUnrestricted) - { - // We have already found an unrestricted variable. The only - // time we will want to use v instead of the current choice - // 'subject' is if v is unrestricted and new to the solver and - // 'subject' isn't new. If this is the case just pick v - // immediately and return. - if (!v.IsRestricted()) - { - if (!ColumnsHasKey(v)) - return v; - } - } - else - { // we haven't found an restricted variable yet - if (v.IsRestricted()) - { - // v is restricted. If we have already found a suitable - // restricted variable just stick with that. Otherwise, if v - // is new to the solver and has a negative coefficient pick - // it. Regarding being new to the solver -- if the variable - // occurs only in the objective function we regard it as being - // new to the solver, since error variables are added to the - // objective function when we make the Expression. We also - // never pick a dummy variable here. - if (!foundNewRestricted && !v.IsDummy() && c < 0.0) - { - const ClTableauColumnsMap &col = Columns(); - ClTableauColumnsMap::const_iterator it_col = col.find(v); - if (it_col == col.end() || - ( col.size() == 1 && ColumnsHasKey(_objective) ) ) - { - subject = v; - foundNewRestricted = true; - } - } - } - else - { - // v is unrestricted. - // If v is also new to the solver just pick it now - subject = v; - foundUnrestricted = true; - } - } - } - if (!subject.IsNil()) - return subject; - - // subject is nil. - // Make one last check -- if all of the variables in expr are dummy - // variables, then we can pick a dummy variable as the subject - Number coeff = 0; - it = terms.begin(); - for ( ; it != terms.end(); ++it ) - { - ClVariable v = (*it).first; - Number c = (*it).second; - if (!v.IsDummy()) - return clvNil; // nope, no luck - // if v is new to the solver, tentatively make it the subject - if (!ColumnsHasKey(v)) - { - subject = v; - coeff = c; - } - } - - // If we get this far, all of the variables in the Expression should - // be dummy variables. If the Constant is nonzero we are trying to - // Add an unsatisfiable required constraint. (Remember that dummy - // variables must take on a value of 0.) Otherwise, if the Constant - // is Zero, multiply by -1 if necessary to make the coefficient for - // the subject negative." - if (!ClApprox(expr.Constant(),0.0)) - { -#ifdef CL_DEBUG_FAILURES - cerr << "required failure in choose subject:\n" - << *this << endl; -#endif - if (FIsExplaining()) - { - ExCLRequiredFailureWithExplanation e; - BuildExplanation(e, clvNil, &expr); - throw e; - } - else - throw ExCLRequiredFailure(); - } - if (coeff > 0.0) - { - expr.MultiplyMe(-1); - } - return subject; -} - -// Each of the non-required edits will be represented by an equation -// of the form -// v = c + eplus - eminus -// where v is the variable with the edit, c is the previous edit -// value, and eplus and eminus are slack variables that hold the -// error in satisfying the edit constraint. We are about to change -// something, and we want to fix the constants in the equations -// representing the edit constraints. If one of eplus and eminus is -// basic, the other must occur only in the Expression for that basic -// error variable. (They can't both be basic.) Fix the Constant in -// this Expression. Otherwise they are both nonbasic. Find all of -// the expressions in which they occur, and fix the constants in -// those. See the UIST paper for details. -// (This comment was for resetEditConstants(), but that is now -// gone since it was part of the screwey vector-based interface -// to resolveing. --02/15/99 gjb) -void -ClSimplexSolver::DeltaEditConstant(Number delta, - ClVariable plusErrorVar, - ClVariable minusErrorVar) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << delta << ", " << plusErrorVar << ", " << minusErrorVar << ")" << endl; -#endif - // first check if the plusErrorVar is basic - ClLinearExpression *pexprPlus = RowExpression(plusErrorVar); - if (pexprPlus != NULL ) - { - pexprPlus->IncrementConstant(delta); - // error variables are always restricted - // so the row is infeasible if the Constant is negative - if (pexprPlus->Constant() < 0.0) - { - _infeasibleRows.insert(plusErrorVar); - } - return; - } - // check if minusErrorVar is basic - ClLinearExpression *pexprMinus = RowExpression(minusErrorVar); - if (pexprMinus != NULL) - { - pexprMinus->IncrementConstant(-delta); - if (pexprMinus->Constant() < 0.0) - { - _infeasibleRows.insert(minusErrorVar); - } - return; - } - // Neither is basic. So they must both be nonbasic, and will both - // occur in exactly the same expressions. Find all the expressions - // in which they occur by finding the column for the minusErrorVar - // (it doesn't matter whether we look for that one or for - // plusErrorVar). Fix the constants in these expressions. - ClVarSet &columnVars = _columns[minusErrorVar]; - ClVarSet::iterator it = columnVars.begin(); - for (; it != columnVars.end(); ++it) - { - ClVariable basicVar = *it; - ClLinearExpression *pexpr = RowExpression(basicVar); - assert(pexpr != NULL ); - double c = pexpr->CoefficientFor(minusErrorVar); - pexpr->IncrementConstant(c*delta); - if (basicVar.IsRestricted() && pexpr->Constant() < 0.0) - { - _infeasibleRows.insert(basicVar); - } - } -} - -// We have set new values for the constants in the edit constraints. -// Re-Optimize using the dual simplex algorithm. -void -ClSimplexSolver::DualOptimize() -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "()" << endl; -#endif - const ClLinearExpression *pzRow = RowExpression(_objective); - // need to handle infeasible rows - while (!_infeasibleRows.empty()) - { - ClVarSet::iterator it_exitVar = _infeasibleRows.begin(); - ClVariable exitVar = *it_exitVar; - _infeasibleRows.erase(it_exitVar); - ClVariable entryVar; - // exitVar might have become basic after some other pivoting - // so allow for the case of its not being there any longer - ClLinearExpression *pexpr = RowExpression(exitVar); - if (pexpr != NULL ) - { - // make sure the row is still not feasible - if (pexpr->Constant() < 0.0) - { - double ratio = DBL_MAX; - double r; - ClVarToNumberMap &terms = pexpr->Terms(); - ClVarToNumberMap::iterator it = terms.begin(); - for ( ; it != terms.end(); ++it ) - { - ClVariable v = (*it).first; - Number c = (*it).second; - if (c > 0.0 && v.IsPivotable()) - { - Number zc = pzRow->CoefficientFor(v); - r = zc/c; // FIXGJB r:= zc/c or Zero, as ClSymbolicWeight-s - if (r < ratio) - { - entryVar = v; - ratio = r; - } - } - } - if (ratio == DBL_MAX) - { - stringstream ss; - ss << "ratio == nil (DBL_MAX)" << ends; - throw ExCLInternalError(ss.str().c_str()); - } - Pivot(entryVar,exitVar); - } - } - } -} - -// Make a new linear Expression representing the constraint cn, -// replacing any basic variables with their defining expressions. -// Normalize if necessary so that the Constant is non-negative. If -// the constraint is non-required give its error variables an -// appropriate weight in the objective function. -ClLinearExpression * -ClSimplexSolver::NewExpression(const ClConstraint *pcn, - /* output to */ - ClVariable &clvEplus, - ClVariable &clvEminus, - Number &prevEConstant) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << *pcn << ")" << endl; - cerr << "cn.IsInequality() == " << pcn->IsInequality() << endl; - cerr << "cn.IsRequired() == " << pcn->IsRequired() << endl; -#endif - const ClLinearExpression &cnExpr = pcn->Expression(); - cl_auto_ptr pexpr ( new ClLinearExpression(cnExpr.Constant()) ); - cl_auto_ptr pslackVar; - cl_auto_ptr pdummyVar; - cl_auto_ptr peminus(0); - cl_auto_ptr peplus(0); - const ClVarToNumberMap &cnTerms = cnExpr.Terms(); - ClVarToNumberMap::const_iterator it = cnTerms.begin(); - for ( ; it != cnTerms.end(); ++it) - { - ClVariable v = (*it).first; - Number c = (*it).second; - const ClLinearExpression *pe = RowExpression(v); - if (pe == NULL) - { - pexpr->AddVariable(v,c); - } - else - { - pexpr->AddExpression(*pe,c); - } - } - - // Add slack and error variables as needed - if (pcn->IsInequality()) - { - // cn is an inequality, so Add a slack variable. The original - // constraint is expr>=0, so that the resulting equality is - // expr-slackVar=0. If cn is also non-required Add a negative - // error variable, giving - // expr-slackVar = -errorVar, in other words - // expr-slackVar+errorVar=0. - // Since both of these variables are newly created we can just Add - // them to the Expression (they can't be basic). - ++_slackCounter; - ReinitializeAutoPtr(pslackVar,new ClSlackVariable (_slackCounter, "s")); - pexpr->setVariable(*pslackVar,-1); - // index the constraint under its slack variable and vice-versa - _markerVars[pcn] = pslackVar.get(); - _constraintsMarked[pslackVar.get()] = pcn; - - if (!pcn->IsRequired()) - { - ++_slackCounter; - ReinitializeAutoPtr(peminus,new ClSlackVariable (_slackCounter, "em")); - pexpr->setVariable(*peminus,1.0); - // Add emnius to the objective function with the appropriate weight - ClLinearExpression *pzRow = RowExpression(_objective); - // FIXGJB: pzRow->AddVariable(eminus,pcn->strength().symbolicWeight() * pcn->weight()); - ClSymbolicWeight sw = pcn->strength().symbolicWeight().Times(pcn->weight()); - pzRow->setVariable(*peminus,sw.AsDouble()); - _errorVars[pcn].insert(peminus.get()); - NoteAddedVariable(*peminus,_objective); - } - } - else - { // cn is an equality - if (pcn->IsRequired()) - { - // Add a dummy variable to the Expression to serve as a marker - // for this constraint. The dummy variable is never allowed to - // enter the basis when pivoting. - ++_dummyCounter; - ReinitializeAutoPtr(pdummyVar,new ClDummyVariable (_dummyCounter, "d")); - pexpr->setVariable(*pdummyVar,1.0); - _markerVars[pcn] = pdummyVar.get(); - _constraintsMarked[pdummyVar.get()] = pcn; -#ifdef CL_TRACE - cerr << "Adding dummyVar == d" << _dummyCounter << endl; -#endif - } - else - { - // cn is a non-required equality. Add a positive and a negative - // error variable, making the resulting constraint - // expr = eplus - eminus, - // in other words: expr-eplus+eminus=0 - ++_slackCounter; - ReinitializeAutoPtr(peplus,new ClSlackVariable (_slackCounter, "ep")); - ReinitializeAutoPtr(peminus,new ClSlackVariable (_slackCounter, "em")); - - pexpr->setVariable(*peplus,-1.0); - pexpr->setVariable(*peminus,1.0); - // index the constraint under one of the error variables - _markerVars[pcn] = peplus.get(); - _constraintsMarked[peplus.get()] = pcn; - - ClLinearExpression *pzRow = RowExpression(_objective); - // FIXGJB: pzRow->AddVariable(eplus,pcn->strength().symbolicWeight() * pcn->weight()); - ClSymbolicWeight sw = pcn->strength().symbolicWeight().Times(pcn->weight()); - double swCoeff = sw.AsDouble(); -#ifdef CL_TRACE - if (swCoeff == 0) - { - cerr << "sw == " << sw << endl - << "cn == " << *pcn << endl; - cerr << "adding " << *peplus << " and " << *peminus - << " with swCoeff == " << swCoeff << endl; - } -#endif - pzRow->setVariable(*peplus,swCoeff); - NoteAddedVariable(*peplus,_objective); - // FIXGJB: pzRow->AddVariable(eminus,pcn->strength().symbolicWeight() * pcn->weight()); - pzRow->setVariable(*peminus,swCoeff); - NoteAddedVariable(*peminus,_objective); - _errorVars[pcn].insert(peminus.get()); - _errorVars[pcn].insert(peplus.get()); - if (pcn->isStayConstraint()) - { - _stayPlusErrorVars.push_back(peplus.get()); - _stayMinusErrorVars.push_back(peminus.get()); - } - else if (pcn->IsEditConstraint()) - { - clvEplus = peplus.get(); - clvEminus = peminus.get(); - prevEConstant = cnExpr.Constant(); - } - } - } - - // the Constant in the Expression should be non-negative. - // If necessary normalize the Expression by multiplying by -1 - if (pexpr->Constant() < 0) - { -#ifdef CL_TRACE - cerr << "NewExpression's Constant is " << pexpr->Constant() << ", < 0, so flipping" << endl; -#endif - pexpr->MultiplyMe(-1); - } -#ifdef CL_TRACE - cerr << "- returning " << *pexpr << endl; -#endif - // Terrible Name -- release() does *not* delete the object, - // only makes sure that the destructor won't delete the object - // (it releases the cl_auto_ptr from the responsibility of deleting the object) - pslackVar.release(); - pdummyVar.release(); - peminus.release(); - peplus.release(); - return pexpr.release(); -} - -// Minimize the value of the objective. (The tableau should already -// be feasible.) -void -ClSimplexSolver::Optimize(ClVariable zVar) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << zVar << ")\n" - << *this << endl; -#endif - ClLinearExpression *pzRow = RowExpression(zVar); - assert(pzRow != NULL); - ClVariable entryVar = clvNil; - ClVariable exitVar = clvNil; - while (true) - { - Number objectiveCoeff = 0; - // Find the most negative coefficient in the objective function - // (ignoring the non-pivotable dummy variables). If all - // coefficients are positive we're done - ClVarToNumberMap &terms = pzRow->Terms(); - ClVarToNumberMap::iterator it = terms.begin(); - for (; it != terms.end(); ++it) - { - ClVariable v = (*it).first; - Number c = (*it).second; - if (v.IsPivotable() && c < objectiveCoeff) - { - objectiveCoeff = c; - entryVar = v; - // A. Beurive' Tue Jul 13 23:03:05 CEST 1999 Why the most - // negative? I encountered unending cycles of pivots! - break; - } - } - // if all coefficients were positive (or if the objective - // function has no pivotable variables) - // we are at an optimum - if (objectiveCoeff >= -_epsilon) - return; -#ifdef CL_TRACE - cerr << "entryVar == " << entryVar << ", " - << "objectiveCoeff == " << objectiveCoeff - << endl; -#endif - - // choose which variable to move out of the basis - // Only consider pivotable basic variables - // (i.e. restricted, non-dummy variables) - double minRatio = DBL_MAX; - ClVarSet &columnVars = _columns[entryVar]; - ClVarSet::iterator it_rowvars = columnVars.begin(); - Number r = 0.0; - for (; it_rowvars != columnVars.end(); ++it_rowvars) - { - ClVariable v = *it_rowvars; -#ifdef CL_TRACE - cerr << "Checking " << v << endl; -#endif - if (v.IsPivotable()) - { - const ClLinearExpression *pexpr = RowExpression(v); - Number coeff = pexpr->CoefficientFor(entryVar); - // only consider negative coefficients - if (coeff < 0.0) - { - r = - pexpr->Constant() / coeff; - if (r < minRatio) - { -#ifdef CL_TRACE - cerr << "New minRatio == " << r << endl; -#endif - minRatio = r; - exitVar = v; - } - } - } - } - // If minRatio is still nil at this point, it means that the - // objective function is unbounded, i.e. it can become - // arbitrarily negative. This should never happen in this - // application. - if (minRatio == DBL_MAX) - { - stringstream ss; - ss << "objective function is unbounded!" << ends; - throw ExCLInternalError(ss.str().c_str()); - } - Pivot(entryVar, exitVar); -#ifdef CL_TRACE - cerr << "After Optimize:\n" - << *this << endl; -#endif - } -} - -// Do a Pivot. Move entryVar into the basis (i.e. make it a basic variable), -// and move exitVar out of the basis (i.e., make it a parametric variable) -void -ClSimplexSolver::Pivot(ClVariable entryVar, ClVariable exitVar) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << entryVar << ", " << exitVar << ")" << endl; -#endif - - // the entryVar might be non-pivotable if we're doing a RemoveConstraint -- - // otherwise it should be a pivotable variable -- enforced at call sites, - // hopefully - - // expr is the Expression for the exit variable (about to leave the basis) -- - // so that the old tableau includes the equation: - // exitVar = expr - ClLinearExpression *pexpr = RemoveRow(exitVar); - - // Compute an Expression for the entry variable. Since expr has - // been deleted from the tableau we can destructively modify it to - // build this Expression. - pexpr->ChangeSubject(exitVar,entryVar); - SubstituteOut(entryVar,*pexpr); - - if (entryVar.IsExternal()) - { - // entry var is no longer a parametric variable since we're moving - // it into the basis - _externalParametricVars.erase(entryVar); - } - addRow(entryVar,*pexpr); -} - - - -// Each of the non-required stays will be represented by an equation -// of the form -// v = c + eplus - eminus -// where v is the variable with the stay, c is the previous value of -// v, and eplus and eminus are slack variables that hold the error -// in satisfying the stay constraint. We are about to change -// something, and we want to fix the constants in the equations -// representing the stays. If both eplus and eminus are nonbasic -// they have value 0 in the current solution, meaning the previous -// stay was exactly satisfied. In this case nothing needs to be -// changed. Otherwise one of them is basic, and the other must -// occur only in the Expression for that basic error variable. -// Reset the Constant in this Expression to 0. -void -ClSimplexSolver::ResetStayConstants() -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "()" << endl; -#endif - ClVarVector::const_iterator - itStayPlusErrorVars = _stayPlusErrorVars.begin(); - ClVarVector::const_iterator - itStayMinusErrorVars = _stayMinusErrorVars.begin(); - - for ( ; itStayPlusErrorVars != _stayPlusErrorVars.end(); - ++itStayPlusErrorVars, ++itStayMinusErrorVars ) - { - ClLinearExpression *pexpr = RowExpression(*itStayPlusErrorVars); - if (pexpr == NULL ) - { - pexpr = RowExpression(*itStayMinusErrorVars); - } - if (pexpr != NULL) - { - pexpr->Set_constant(0.0); - } - } -} - -// Set the external variables known to this solver to their appropriate values. -// Set each external basic variable to its value, and set each -// external parametric variable to 0. (It isn't clear that we will -// ever have external parametric variables -- every external -// variable should either have a stay on it, or have an equation -// that defines it in terms of other external variables that do have -// stays. For the moment I'll put this in though.) Variables that -// are internal to the solver don't actually store values -- their -// values are just implicit in the tableu -- so we don't need to set -// them." -void -ClSimplexSolver::SetExternalVariables() -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "()\n" - << *this << endl; -#endif - - // FIXGJB -- oughta check some invariants here - - // Set external parametric variables first - // in case I've screwed up - ClVarSet::iterator itParVars = _externalParametricVars.begin(); - for ( ; itParVars != _externalParametricVars.end(); ++itParVars ) - { - ClVariable v = *itParVars; -#ifndef NDEBUG - // defensively skip it if it is basic -- ChangeValue is virtual - // so don't want to call it twice; this should never - // happen - if (FIsBasicVar(v)) - { -#ifndef CL_NO_IO - // WARNING - cerr << __FUNCTION__ << "Error: variable " << v - << " in _externalParametricVars is basic" << endl; - cerr << "Row is: " << *RowExpression(v) << endl; -#endif - continue; - } -#endif - ChangeClv(v,0.0); - } - - // Only iterate over the rows w/ external variables - ClVarSet::iterator itRowVars = _externalRows.begin(); - for ( ; itRowVars != _externalRows.end() ; ++itRowVars ) - { - ClVariable v = *itRowVars; - ClLinearExpression *pexpr = RowExpression(v); - ChangeClv(v,pexpr->Constant()); - } - - _fNeedsSolving = false; - if (_pfnResolveCallback) - _pfnResolveCallback(this); -} - -#ifndef CL_NO_IO -ostream & -PrintTo(ostream &xo, const ClVarVector &varlist) -{ - ClVarVector::const_iterator it = varlist.begin(); - xo << varlist.size() << ":" << "[ "; - if (it != varlist.end()) - { - xo << *it; - ++it; - } - for (; it != varlist.end(); ++it) - { - xo << ", " << *it; - } - xo << " ]"; - return xo; -} - -ostream &operator<<(ostream &xo, const ClVarVector &varlist) -{ return PrintTo(xo,varlist); } - - -ostream & -PrintTo(ostream &xo, const ClConstraintToVarSetMap &mapCnToVarSet) -{ - ClConstraintToVarSetMap::const_iterator it = mapCnToVarSet.begin(); - for ( ; it != mapCnToVarSet.end(); ++it) { - const ClConstraint *pcn = (*it).first; - const ClVarSet &set = (*it).second; - xo << "CN: " << pcn << *pcn << ":: " << set << endl; - } - return xo; -} - -ostream &operator <<(ostream &xo, const ClConstraintToVarSetMap &mapCnToVarSet) -{ return PrintTo(xo,mapCnToVarSet); } - - - -ostream & -ClSimplexSolver::PrintOn(ostream &xo) const -{ - ClTableau::PrintOn(xo); - - xo << "_stayPlusErrorVars: " - << _stayPlusErrorVars << endl; - xo << "_stayMinusErrorVars: " - << _stayMinusErrorVars << endl; - xo << "_editInfoList:\n" - << _editInfoList << endl; - return xo; -} - - -ostream & -ClSimplexSolver::PrintInternalInfo(ostream &xo) const -{ - ClTableau::PrintInternalInfo(xo); - xo << "; edvars: " << _editInfoList.size(); - xo << endl; - printExternalVariablesTo(xo); - return xo; -} - -ostream &operator<<(ostream &xo, const ClSimplexSolver &clss) -{ - return clss.PrintOn(xo); -} - -#endif - -bool -ClSimplexSolver::FIsConstraintSatisfied(const ClConstraint *const pcn) const -{ - ClConstraintToVarMap::const_iterator it_marker = _markerVars.find(pcn); - if (it_marker == _markerVars.end()) - { // could not find the constraint - throw ExCLConstraintNotFound(); - } - -#ifndef CL_NO_IO - bool fCnsays = pcn->FIsSatisfied(); -#endif - - ClConstraintToVarSetMap::const_iterator it_eVars = _errorVars.find(pcn); - - if (it_eVars != _errorVars.end()) - { - const ClVarSet &eVars = (*it_eVars).second; - ClVarSet::const_iterator it = eVars.begin(); - for ( ; it != eVars.end(); ++it ) - { - const ClLinearExpression *pexpr = RowExpression(*it); - if (pexpr != NULL && !ClApprox(pexpr->Constant(),0.0)) - { -#ifndef CL_NO_IO - if (fCnsays) - cerr << __FUNCTION__ << ": constraint says satisfiable, but solver does not" << endl; -#endif - return false; - } - } - } - -#ifndef CL_NO_IO - if (!fCnsays) - cerr << __FUNCTION__ << ": solver says satisfiable, but constraint does not" << endl; -#endif - return true; -} - - - -#ifndef CL_NO_ID - -ostream &PrintTo(ostream &xo, const ClSimplexSolver::ClEditInfoList &listPEditInfo) -{ - ClSimplexSolver::ClEditInfoList::const_iterator it = listPEditInfo.begin(); - for ( ; it != listPEditInfo.end(); ++it) { - const ClSimplexSolver::ClEditInfo *pcei = (*it); - xo << *pcei << endl; - } - return xo; -} - - -ostream &operator<<(ostream &xo, const ClSimplexSolver::ClEditInfoList &listPEditInfo) -{ return PrintTo(xo,listPEditInfo); } - -#endif - -// A. Beurive' Tue Jul 6 17:03:32 CEST 1999 -void -ClSimplexSolver::ChangeStrengthAndWeight(ClConstraint *pcn, const ClStrength &strength, double weight) -{ - ClConstraintToVarSetMap::iterator it_eVars = _errorVars.find(pcn); - // Only for constraints that already have error variables (i.e. non-required constraints) - assert(it_eVars != _errorVars.end()); - - ClLinearExpression *pzRow = RowExpression(_objective); - - Number old_coeff = pcn->weight() * pcn->strength().symbolicWeight().AsDouble(); - pcn->setStrength(strength); - pcn->setWeight(weight); - Number new_coeff = pcn->weight() * pcn->strength().symbolicWeight().AsDouble(); - - if (new_coeff != old_coeff) - { -#ifdef CL_TRACE - cerr << "Changing strength and/or weight for constraint: " << endl << *pcn << endl; - cerr << "Updating objective row from:" << endl << *pzRow << endl; -#endif - ClVarSet &eVars = (*it_eVars).second; - ClVarSet::iterator it = eVars.begin(); - for ( ; it != eVars.end(); ++it ) - { - const ClLinearExpression *pexpr = RowExpression(*it); - if (pexpr == NULL ) - { - pzRow->AddVariable(*it,-old_coeff,_objective,*this); - pzRow->AddVariable(*it,new_coeff,_objective,*this); - } - else - { - pzRow->AddExpression(*pexpr,-old_coeff,_objective,*this); - pzRow->AddExpression(*pexpr,new_coeff,_objective,*this); - } - } -#ifdef CL_TRACE - cerr << "to: " << endl << *pzRow << endl; -#endif - - if (_fAutosolve) - { - Optimize(_objective); - SetExternalVariables(); - } - } -} - -// A. Beurive' Tue Jul 6 17:03:42 CEST 1999 -void -ClSimplexSolver::ChangeStrength(ClConstraint *pcn, const ClStrength &strength) -{ - ChangeStrengthAndWeight(pcn,strength,pcn->weight()); -} - -// A. Beurive' Tue Jul 6 17:03:42 CEST 1999 -void -ClSimplexSolver::ChangeWeight(ClConstraint *pcn, double weight) -{ - ChangeStrengthAndWeight(pcn,pcn->strength(),weight); -} diff --git a/libs/cassowary/ClSlackVariable.cc b/libs/cassowary/ClSlackVariable.cc deleted file mode 100644 index eaf0432eb0..0000000000 --- a/libs/cassowary/ClSlackVariable.cc +++ /dev/null @@ -1,12 +0,0 @@ -// $Id$ - -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -#ifdef CL_FIND_LEAK -long ClSlackVariable::cSlackVariables = 0; -#endif diff --git a/libs/cassowary/ClSolver.cc b/libs/cassowary/ClSolver.cc deleted file mode 100644 index 18b0b7f9cc..0000000000 --- a/libs/cassowary/ClSolver.cc +++ /dev/null @@ -1,59 +0,0 @@ -// $Id$ - -using namespace std; - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -#include -#include -#include -#include -#include - - -ClSolver & -ClSolver::AddConstraint(ClConstraint *const ) -{ - return *this; -} - - -ostream & -PrintTo(ostream &xo, const ClConstraintSet &setCn) -{ - ClConstraintSet::const_iterator it = setCn.begin(); - for (; it != setCn.end(); ++it) { - const ClConstraint *pcn = *it; - xo << *pcn << endl; - } - return xo; -} - -ostream & -PrintTo(ostream &xo, const list &listFDN) -{ - list::const_iterator it = listFDN.begin(); - for (; it != listFDN.end(); ) { - FDNumber n = *it; - xo << n; - ++it; - if (it != listFDN.end()) - xo << ","; - } - return xo; -} - - -ostream &operator<<(ostream &xo, const ClConstraintSet &setCn) -{ return PrintTo(xo,setCn); } - - -ostream &operator<<(ostream &xo, const ClSolver &solver) -{ return solver.PrintOn(xo); } - -ostream &operator<<(ostream &xo, const list &listFDN) -{ return PrintTo(xo,listFDN); } - diff --git a/libs/cassowary/ClStrength.cc b/libs/cassowary/ClStrength.cc deleted file mode 100644 index 0629d4afff..0000000000 --- a/libs/cassowary/ClStrength.cc +++ /dev/null @@ -1,52 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClStrength.cc - -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -// Use the singleton pattern for the strength objects -const ClStrength &ClsRequired() -{ - // required is distinct by equality to this static object, - // but I still use an especially high symbolic weight, just in case - // FIXGJB: hack? - static ClStrength required_strength("", 1000, 1000, 1000); - return required_strength; -} - -const ClStrength &ClsStrong() -{ - static ClStrength strong_strength("strong", 1.0, 0.0, 0.0); - return strong_strength; -} - -const ClStrength &ClsMedium() -{ - static ClStrength medium_strength("medium", 0.0, 1.0, 0.0); - return medium_strength; -} - - -const ClStrength &ClsWeak() -{ - static ClStrength weak_strength("weak", 0.0, 0.0, 1.0); - return weak_strength; -} - -// special case for when nLevels = 3, should assert nLevels() == 3 -ClStrength::ClStrength(const string &Name, double w1, double w2, double w3) : - _name(Name), _symbolicWeight(w1, w2, w3) -{ -} diff --git a/libs/cassowary/ClSymbolicWeight.cc b/libs/cassowary/ClSymbolicWeight.cc deleted file mode 100644 index 9dddaa5949..0000000000 --- a/libs/cassowary/ClSymbolicWeight.cc +++ /dev/null @@ -1,149 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClSymbolicWeight.cc - -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -// Help g++ out, tell it to instantiate this -//template vector &vector::operator =(const vector &); - -ClSymbolicWeight::ClSymbolicWeight(unsigned int CLevels, double value) : - _values(CLevels, value) -{ - assert(_values.size() == CLevels); -} - -ClSymbolicWeight::ClSymbolicWeight(double w1, double w2, double w3) -{ - _values.push_back(w1); - _values.push_back(w2); - _values.push_back(w3); - assert(_values.size() == 3); -} - -ClSymbolicWeight::ClSymbolicWeight(const vector &weights) : - _values(weights) -{ } - -ClSymbolicWeight & -ClSymbolicWeight::Zero() -{ - static ClSymbolicWeight Zero(0.0, 0.0, 0.0); - return Zero; -} - - -ClSymbolicWeight & -ClSymbolicWeight::negated() -{ - vector::iterator it = _values.begin(); - for (; it != _values.end(); ++it) - { - *it = -*it; - } - return *this; -} - -ClSymbolicWeight & -ClSymbolicWeight::MultiplyMe(Number n) -{ - vector::iterator it = _values.begin(); - for (; it != _values.end(); ++it) - { - *it *= n; - } - return *this; -} - - -ClSymbolicWeight -ClSymbolicWeight::DivideBy(Number n) const -{ - assert(n!=0); - ClSymbolicWeight clsw(0); - vector::const_iterator i = _values.begin(); - for (; i != _values.end(); ++i) - { - clsw.push_back(*i / n); - } - return clsw; -} - -ClSymbolicWeight & -ClSymbolicWeight::addtoMe(const ClSymbolicWeight &cl) -{ - assert(cl.CLevels() == CLevels()); - - vector::iterator i1 = _values.begin(); - vector::const_iterator i2 = cl._values.begin(); - for (; i1 != _values.end(); ++i1, ++i2) - { - *i1 += *i2; - } - return *this; -} - -ClSymbolicWeight -ClSymbolicWeight::Subtract(const ClSymbolicWeight &cl) const -{ - assert(cl.CLevels() == CLevels()); - - ClSymbolicWeight clsw(0); - vector::const_iterator i1 = _values.begin(); - vector::const_iterator i2 = cl._values.begin(); - for (; i1 != _values.end(); ++i1, ++i2) - { - clsw.push_back(*i1 - *i2); - } - return clsw; -} - - -bool -ClSymbolicWeight::lessThan(const ClSymbolicWeight &cl) const -{ - return _values < cl._values; -} - -bool -ClSymbolicWeight::lessThanOrEqual(const ClSymbolicWeight &cl) const -{ - return _values <= cl._values; -} - -bool -ClSymbolicWeight::equal(const ClSymbolicWeight &cl) const -{ - return _values == cl._values; -} - -bool -ClSymbolicWeight::greaterThan(const ClSymbolicWeight &cl) const -{ - return _values > cl._values; -} - -bool -ClSymbolicWeight::greaterThanOrEqual(const ClSymbolicWeight &cl) const -{ - return _values >= cl._values; -} - -bool -ClSymbolicWeight::isNegative() const -{ - return _values < Zero()._values; -} diff --git a/libs/cassowary/ClTableau.cc b/libs/cassowary/ClTableau.cc deleted file mode 100644 index 85ac841725..0000000000 --- a/libs/cassowary/ClTableau.cc +++ /dev/null @@ -1,297 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClTableau.cc - -using namespace std; - -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - - -// delete the linear expressions -// let ClSimplexSolver worry about deleting the variables -ClTableau::~ClTableau() -{ - ClTableauRowsMap::iterator it = _rows.begin(); - for (; it != _rows.end(); ++it) - { - // free the ClLinearExpression that we new-ed -#ifdef CL_TRACE - cerr << "Deleting row delete@ " << ((*it).second) << endl; -#endif - delete (*it).second; - } -} - -#ifndef CL_NO_IO -// Some extra debugging info -ostream & -ClTableau::PrintInternalInfo(ostream &xo) const -{ - xo << "ncns:" << _rows.size() -1 - << "; cols:" << _columns.size() - << "; infrows:" << _infeasibleRows.size() - << "; ebvars:" << _externalRows.size() - << "; epvars:" << _externalParametricVars.size(); - return xo; -} - - -ostream & -ClTableau::printExternalVariablesTo(ostream &xo) const -{ - xo << "Parametric: "; - ClVarSet::iterator itParVars = _externalParametricVars.begin(); - for ( ; itParVars != _externalParametricVars.end(); ++itParVars ) { - ClVariable v = *itParVars; - xo << v << " "; - } - xo << "\nBasic: "; - ClVarSet::iterator itRowVars = _externalRows.begin(); - for ( ; itRowVars != _externalRows.end() ; ++itRowVars ) { - ClVariable v = *itRowVars; - xo << v << " "; - } - return xo << endl; -} - -#endif - - -// Add v, update column cross indices -// v becomes a basic variable -// expr is now owned by ClTableau class, -// and ClTableauis responsible for deleting it -// (also, expr better be allocated on the heap!) -void -ClTableau::addRow(ClVariable var, const ClLinearExpression &expr) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << var << ", " << expr << ")" << endl; -#endif - _rows[var] = const_cast(&expr); - ClVarToNumberMap::const_iterator it = expr.Terms().begin(); - // for each variable in expr, Add var to the set of rows which have that variable - // in their Expression - for (; it != expr.Terms().end(); ++it) - { - ClVariable v = (*it).first; - _columns[v].insert(var); - if (v.IsExternal() && !FIsBasicVar(v)) - { - _externalParametricVars.insert(v); - } - } - if (var.IsExternal()) - { - _externalRows.insert(var); - } -#ifdef CL_TRACE - cerr << *this << endl; -#endif -} - -// Remove var from the tableau -- remove the column cross indices for var -// and remove var from every Expression in rows in which v occurs -// Remove the parametric variable var, updating the appropriate column and row entries. -// (Renamed from Smalltalk implementation's `removeParametricVar') -ClVariable -ClTableau::RemoveColumn(ClVariable var) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << var << ")" << endl; -#endif - ClTableauColumnsMap::iterator it_var = _columns.find(var); - if (it_var == _columns.end()) - return var; // nothing to do - - ClVarSet &varset = (*it_var).second; - // remove the rows with the variables in varset - ClVarSet::iterator it = varset.begin(); - for (; it != varset.end(); ++it) - { - ClVariable v = (*it); - ClVarToNumberMap &Terms = _rows[v]->Terms(); - Terms.erase(Terms.find(var)); - } - if (var.IsExternal()) - { - _externalRows.erase(var); - _externalParametricVars.erase(var); - } - _columns.erase(it_var); - return var; -} - -// Remove the basic variable v from the tableau row v=expr -// Then update column cross indices -ClLinearExpression * -ClTableau::RemoveRow(ClVariable var) -{ -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - cerr << "(" << var << ")" << endl; -#endif - ClTableauRowsMap::iterator it = _rows.find(var); - assert(it != _rows.end()); - ClLinearExpression *pexpr = (*it).second; - ClVarToNumberMap &Terms = pexpr->Terms(); - ClVarToNumberMap::iterator it_term = Terms.begin(); - for (; it_term != Terms.end(); ++it_term) - { - ClVariable v = (*it_term).first; - _columns[v].erase(var); - if (_columns[v].size() == 0) - { - _columns.erase(v); - _externalParametricVars.erase(v); - } - } - - _infeasibleRows.erase(var); - - if (var.IsExternal()) - { - _externalRows.erase(var); - _externalParametricVars.erase(var); - } - - _rows.erase(it); -#ifdef CL_TRACE - cerr << "- returning " << *pexpr << endl; -#endif - return pexpr; -} - -// Replace all occurrences of oldVar with expr, and update column cross indices -// oldVar should now be a basic variable -// Uses the Columns data structure and calls SubstituteOut on each -// row that has oldVar in it -// oldVar is leaving the basis, and becoming parametric -void -ClTableau::SubstituteOut(ClVariable oldVar, const ClLinearExpression &expr) -{ -#ifdef CL_TRACE - cerr << "* ClTableau::"; - Tracer TRACER(__FUNCTION__); - cerr << "(" << oldVar << ", " << expr << ")" << endl; - cerr << (*this) << endl; -#endif - - ClTableauColumnsMap::iterator it_oldVar = _columns.find(oldVar); - if (it_oldVar == _columns.end()) - return; - - ClVarSet &varset = (*it_oldVar).second; - ClVarSet::iterator it = varset.begin(); - for (; it != varset.end(); ++it) - { - ClVariable v = (*it); - ClLinearExpression *prow = _rows[v]; - prow->SubstituteOut(oldVar,expr,v,*this); - if (v.IsRestricted() && prow->Constant() < 0.0) - { - _infeasibleRows.insert(v); - } - } - _columns.erase(it_oldVar); - if (oldVar.IsExternal()) - { - if (_columns[oldVar].size() > 0) - { - _externalRows.insert(oldVar); - } - _externalParametricVars.erase(oldVar); - } -} - - -#ifndef CL_NO_IO - -ostream & -PrintTo(ostream &xo, const ClVarSet & varset) -{ - ClVarSet::const_iterator it = varset.begin(); - xo << "{ "; - if (it != varset.end()) - { - xo << *it; - ++it; - } - for (; it != varset.end(); ++it) - { - xo << ", " << *it; - } - xo << " }"; - return xo; -} - -ostream &operator<<(ostream &xo, const ClVarSet & varset) -{ return PrintTo(xo,varset); } - -ostream & -PrintTo(ostream &xo, const ClTableauColumnsMap & varmap) -{ - ClTableauColumnsMap::const_iterator it = varmap.begin(); - for (; it != varmap.end(); ++it) - { - xo << (*it).first << " -> " << (*it).second << endl; - } - return xo; -} - -ostream &operator<<(ostream &xo, const ClTableauColumnsMap & varmap) -{ return PrintTo(xo,varmap); } - -ostream & -PrintTo(ostream &xo, const ClTableauRowsMap & rows) -{ - ClTableauRowsMap::const_iterator it = rows.begin(); - for (; it != rows.end(); ++it) - { - ClVariable v = it->first; - const ClLinearExpression *pe = it->second; - xo << v << " <-=-> "; - if (pe) xo << *pe; else xo << "NilExpr"; - xo << endl; - } - return xo; -} - -ostream &operator<<(ostream &xo, const ClTableauRowsMap & rows) -{ return PrintTo(xo,rows); } - -ostream & -ClTableau::PrintOn(ostream &xo) const -{ - xo << "Tableau:\n" - << _rows << endl; - xo << "Columns:\n" - << _columns << endl; - xo << "Infeasible rows: " - << _infeasibleRows << endl; - xo << "External basic variables: " - << _externalRows << endl; - xo << "External parametric variables: " - << _externalParametricVars << endl; - return xo; -} - -ostream &operator<<(ostream &xo, const ClTableau &clt) -{ return clt.PrintOn(xo); } - -#endif diff --git a/libs/cassowary/ClTests.cc b/libs/cassowary/ClTests.cc deleted file mode 100644 index 606d6f3e44..0000000000 --- a/libs/cassowary/ClTests.cc +++ /dev/null @@ -1,884 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClTests.cc - -#include -#include -#include -#include -#include - -inline -double UniformRandom() -{ return double(rand())/RAND_MAX; } - - -bool -simple1() -{ - try - { - bool fOkResult = true; - ClVariable x(167); - ClVariable y(2); - ClSimplexSolver solver; - - ClLinearEquation eq(x,y+0.0); - solver.AddStay(x); - solver.AddStay(y); - solver.AddConstraint(eq); - cout << "x = " << x.Value() << endl - << "y = " << y.Value() << endl; - fOkResult = (x.Value() == y.Value()); - return fOkResult; - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(false); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } -} - - -/* Add an edit variable to an empty solver */ -bool -simple2() -{ - try - { - ClVariable x(167); - ClSimplexSolver solver; - - solver.AddEditVar(x); - solver.BeginEdit(); - solver.SuggestValue(x,100); - solver.EndEdit(); - - cout << "x = " << x.Value() << endl; - } - catch (ExCLEditMisuse &error) - { - cout << "Success: got the exception" << endl; - return true; - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(false); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } - cerr << "Should have gotten an exception!" << endl; - return false; -} - - -bool -justStay1() -{ - try - { - bool fOkResult = true; - ClVariable x(5); - ClVariable y(10); - ClSimplexSolver solver; - -#if 0 - solver.AddPointStay(x,y,1); -#else - solver.AddStay(x); - solver.AddStay(y); -#endif - fOkResult = fOkResult && ClApprox(x,5); - fOkResult = fOkResult && ClApprox(y,10); - cout << "x == " << x.Value() << endl; - cout << "y == " << y.Value() << endl; - - return(fOkResult); - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(false); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } -} - - - -bool -addDelete1() -{ - try - { - bool fOkResult = true; - ClVariable x("x"); - ClSimplexSolver solver; - - solver.AddConstraint(new ClLinearEquation( x, 100, ClsWeak() )); - - ClLinearInequality c10(x,cnLEQ,10.0); - ClLinearInequality c20(x,cnLEQ,20.0); - solver - .AddConstraint(c10) - .AddConstraint(c20); - - fOkResult = fOkResult && ClApprox(x,10.0); - cout << "x == " << x.Value() << endl; - - cout << endl << solver << endl; - - solver.RemoveConstraint(c10); - - cout << endl << solver << endl; - - fOkResult = fOkResult && ClApprox(x,20.0); - cout << "x == " << x.Value() << endl; - - solver.RemoveConstraint(c20); - fOkResult = fOkResult && ClApprox(x,100.0); - cout << "x == " << x.Value() << endl; - - ClLinearInequality c10again(x,cnLEQ,10.0); - - solver - .AddConstraint(c10) - .AddConstraint(c10again); - - fOkResult = fOkResult && ClApprox(x,10.0); - cout << "x == " << x.Value() << endl; - - solver.RemoveConstraint(c10); - fOkResult = fOkResult && ClApprox(x,10.0); - cout << "x == " << x.Value() << endl; - - solver.RemoveConstraint(c10again); - fOkResult = fOkResult && ClApprox(x,100.0); - cout << "x == " << x.Value() << endl; - - return(fOkResult); - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(false); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } -} - -bool -addDelete2() -{ - try - { - bool fOkResult = true; - ClVariable x("x"); - ClVariable y("y"); - ClSimplexSolver solver; - - solver - .AddConstraint(new ClLinearEquation(x, 100.0, ClsWeak())) - .AddConstraint(new ClLinearEquation(y, 120.0, ClsStrong())); - - ClLinearInequality c10(x,cnLEQ,10.0); - ClLinearInequality c20(x,cnLEQ,20.0); - - solver - .AddConstraint(c10) - .AddConstraint(c20); - fOkResult = fOkResult && ClApprox(x,10.0) && ClApprox(y,120.0); - cout << "x == " << x.Value() << ", y == " << y.Value() << endl; - - solver.RemoveConstraint(c10); - fOkResult = fOkResult && ClApprox(x,20.0) && ClApprox(y,120.0); - cout << "x == " << x.Value() << ", y == " << y.Value() << endl; - - ClLinearEquation cxy( 2*x, y); - solver.AddConstraint(cxy); - fOkResult = fOkResult && ClApprox(x,20.0) && ClApprox(y,40.0); - cout << "x == " << x.Value() << ", y == " << y.Value() << endl; - - solver.RemoveConstraint(c20); - fOkResult = fOkResult && ClApprox(x,60.0) && ClApprox(y,120.0); - cout << "x == " << x.Value() << ", y == " << y.Value() << endl; - - solver.RemoveConstraint(cxy); - fOkResult = fOkResult && ClApprox(x,100.0) && ClApprox(y,120.0); - cout << "x == " << x.Value() << ", y == " << y.Value() << endl; - - - return(fOkResult); - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(false); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } -} - -bool -casso1() -{ - try - { - bool fOkResult = true; - ClVariable x("x"); - ClVariable y("y"); - ClSimplexSolver solver; - - solver - .AddConstraint(new ClLinearInequality(x,cnLEQ,y)) - .AddConstraint(new ClLinearEquation(y, x+3.0)) - .AddConstraint(new ClLinearEquation(x,10.0,ClsWeak())) - .AddConstraint(new ClLinearEquation(y,10.0,ClsWeak())) - ; - - fOkResult = fOkResult && - ( ClApprox(x,10.0) && ClApprox(y,13.0) || - ClApprox(x,7.0) && ClApprox(y,10.0) ); - - cout << "x == " << x.Value() << ", y == " << y.Value() << endl; - - return(fOkResult); - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(false); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } -} - -bool -inconsistent1() -{ - ClSimplexSolver solver; - ClVariable x("x"); - ClLinearEquation eq1(x,10.0); - ClLinearEquation eq2(x,5.0); - try - { - - solver.AddConstraint( eq1 ); - solver.AddConstraint( eq2 ); - - // no exception, we failed! - return(false); - } - catch (ExCLRequiredFailure) - { - // we want this exception to get thrown - cout << "Success -- got the exception" << endl; - // solver.RemoveConstraint(eq2); this would throw a constraint not found exception - // cout << solver << endl; - return(true); - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(false); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } -} - -bool -inconsistent2() -{ - try - { - ClVariable x("x"); - ClSimplexSolver solver; - - solver - .AddConstraint(new ClLinearInequality(x,cnGEQ,10.0)) - .AddConstraint(new ClLinearInequality(x,cnLEQ, 5.0)); - - // no exception, we failed! - return(false); - } - catch (ExCLRequiredFailure &) - { - // we want this exception to get thrown - cout << "Success -- got the exception" << endl; - // cout << solver << endl; - return(true); - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(false); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } -} - -bool -inconsistent3() -{ - try - { - ClVariable w("w"); - ClVariable x("x"); - ClVariable y("y"); - ClVariable z("z"); - ClSimplexSolver solver; - - solver - .AddConstraint(new ClLinearInequality(w,cnGEQ,10.0)) - .AddConstraint(new ClLinearInequality(x,cnGEQ,w)) - .AddConstraint(new ClLinearInequality(y,cnGEQ,x)) - .AddConstraint(new ClLinearInequality(z,cnGEQ,y)) - .AddConstraint(new ClLinearInequality(z,cnLEQ,4.0)); - - // no exception, we failed! - return(false); - } - catch (ExCLRequiredFailure &) - { - // we want this exception to get thrown - cout << "Success -- got the exception" << endl; - // cout << solver << endl; - return(true); - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(false); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } -} - - -bool -multiedit() -{ - try - { - bool fOkResult = true; - - ClVariable x("x",0); - ClVariable y("y",0); - ClVariable w("w",0); - ClVariable h("h",0); - ClSimplexSolver solver; - - solver - .AddStay(x) - .AddStay(y) - .AddStay(w) - .AddStay(h); - - solver - .AddEditVar(x) - .AddEditVar(y) - .BeginEdit(); - - solver - .SuggestValue(x,10) - .SuggestValue(y,20) - .Resolve(); - - cout << "x = " << x.Value() << "; y = " << y.Value() << endl - << "w = " << w.Value() << "; h = " << h.Value() << endl; - - fOkResult = fOkResult && - ClApprox(x,10) && ClApprox(y,20) && ClApprox(w,0) && ClApprox(h,0); - - solver - .AddEditVar(w) - .AddEditVar(h) - .BeginEdit(); - - solver - .SuggestValue(w,30) - .SuggestValue(h,40) - .EndEdit(); - - cout << "x = " << x.Value() << "; y = " << y.Value() << endl - << "w = " << w.Value() << "; h = " << h.Value() << endl; - - fOkResult = fOkResult && - ClApprox(x,10) && ClApprox(y,20) && ClApprox(w,30) && ClApprox(h,40); - - solver - .SuggestValue(x,50) - .SuggestValue(y,60) - .EndEdit(); - - cout << "x = " << x.Value() << "; y = " << y.Value() << endl - << "w = " << w.Value() << "; h = " << h.Value() << endl; - - fOkResult = fOkResult && - ClApprox(x,50) && ClApprox(y,60) && ClApprox(w,30) && ClApprox(h,40); - - return fOkResult; - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(false); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } - cerr << "Should have gotten an exception!" << endl; - return false; -} - - -bool -multiedit2() -{ - try - { - bool fOkResult = true; - - ClVariable x("x",0); - ClVariable y("y",0); - ClVariable w("w",0); - ClVariable h("h",0); - ClSimplexSolver solver; - - solver - .AddStay(x) - .AddStay(y) - .AddStay(w) - .AddStay(h); - - solver - .AddEditVar(x) - .AddEditVar(y) - .BeginEdit(); - - solver - .SuggestValue(x,10) - .SuggestValue(y,20) - .Resolve(); - - cout << "x = " << x.Value() << "; y = " << y.Value() << endl - << "w = " << w.Value() << "; h = " << h.Value() << endl; - - fOkResult = fOkResult && - ClApprox(x,10) && ClApprox(y,20) && ClApprox(w,0) && ClApprox(h,0); - - solver - .AddEditVar(x) - .AddEditVar(y) - .AddEditVar(w) - .AddEditVar(h) - .BeginEdit(); - - solver - .SuggestValue(w,30) - .SuggestValue(h,40) - .EndEdit(); - - cout << "x = " << x.Value() << "; y = " << y.Value() << endl - << "w = " << w.Value() << "; h = " << h.Value() << endl; - - fOkResult = fOkResult && - ClApprox(x,10) && ClApprox(y,20) && ClApprox(w,30) && ClApprox(h,40); - - solver - .SuggestValue(x,50) - .SuggestValue(y,60) - .EndEdit(); - - cout << "x = " << x.Value() << "; y = " << y.Value() << endl - << "w = " << w.Value() << "; h = " << h.Value() << endl; - - fOkResult = fOkResult && - ClApprox(x,50) && ClApprox(y,60) && ClApprox(w,30) && ClApprox(h,40); - - return fOkResult; - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(false); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } - cerr << "Should have gotten an exception!" << endl; - return false; -} - - -// From a bug report from Steve Wolfman on his -// SAT project using "blackbox" -bool -blackboxsat() -{ - try - { - ClSimplexSolver solver; - - ClVariable r1("r1"); - ClVariable r2("r2"); - ClVariable r3("r3"); - ClVariable r4("r4"); - ClVariable r5("r5"); - ClVariable r6("r6"); - ClVariable r7("r7"); - ClVariable r8("r8"); - - ClConstraint *rgpcn[30]; - for (int i=0; i> szCmd; - if (!cin) - break; - if (szCmd[0] == '#') - { - cin.getline(szCmd,900); - continue; - } - if (strcasecmp(szCmd,"Add") == 0) - { - cin >> i; - cout << "eq" << i << ": " << solver.AddConstraintNoException(rgpcn[i]) - << "\t" << *(rgpcn[i]) << endl; - cout << r1 << " = " << r1.Value() << endl; - } - else if (strcasecmp(szCmd,"del") == 0) - { - cin >> i; - cout << "REMeq" << i << ": " << solver.RemoveConstraintNoException(rgpcn[i]) - << "\t" << *(rgpcn[i]) << endl; - cout << r1 << " = " << r1.Value() << endl; - } - else if (strcasecmp(szCmd,"dump") == 0) - { - cout << solver << endl; - } - else if (strcasecmp(szCmd,"val") == 0) - { - cout << r1 << " = " << r1.Value() << endl; - } - else if (strcasecmp(szCmd,"solve") == 0) - { - cout << solver.Solve() << endl; - } - else if (strcasecmp(szCmd,"autosolve") == 0) - { - solver.SetAutosolve(true); - } - else if (strcasecmp(szCmd,"noautosolve") == 0) - { - solver.SetAutosolve(true); - } - } - - cout << r1 << " = " << r1.Value() << endl - << r2 << " = " << r2.Value() << endl - << r3 << " = " << r3.Value() << endl - << r4 << " = " << r4.Value() << endl - << r5 << " = " << r5.Value() << endl - << r6 << " = " << r6.Value() << endl - << r7 << " = " << r7.Value() << endl - << r8 << " = " << r8.Value() << endl; - - return false; - } - catch (ExCLError &error) - { - cerr << "Exception! " << error.description() << endl; - return(true); - } - catch (...) - { - cerr << "Unknown exception" << endl; - return(false); - } -} - -typedef ClVariable *PClVariable; - -bool -addDel(const int nCns = 900, const int nVars = 900, const int nResolves = 10000) -//addDel(int nCns = 300, int nVars = 300, int nResolves = 1000) -//addDel(int nCns = 30, int nVars = 30, int nResolves = 100) -{ - Timer timer; - // FIXGJB: from where did .12 come? - static const double ineqProb = 0.12; - static const int maxVars = 3; - - cout << "starting timing test. nCns = " << nCns - << ", nVars = " << nVars << ", nResolves = " << nResolves << endl; - - timer.Start(); - ClSimplexSolver solver; - solver.SetAutosolve(false); - - ClVariable **rgpclv = new PClVariable[nVars]; - for (int i = 0; i < nVars; i++) - { - rgpclv[i] = new ClVariable(i,"x"); - solver.AddStay(*rgpclv[i]); - } - - ClConstraint **rgpcns = new PClConstraint[nCns]; - int nvs = 0; - int k; - int j; - double coeff; - for (j = 0; j < nCns; j++) - { - // number of variables in this constraint - nvs = int(UniformRandom()*maxVars) + 1; - ClLinearExpression expr = UniformRandom()*20.0 - 10.0; - for (k = 0; k < nvs; k++) - { - coeff = UniformRandom()*10 - 5; - expr.AddExpression(*(rgpclv[int(UniformRandom()*nVars)]) * coeff); - } - if (UniformRandom() < ineqProb) - { - rgpcns[j] = new ClLinearInequality(expr); - } - else - { - rgpcns[j] = new ClLinearEquation(expr); - } -#ifdef CL_SHOW_CNS_IN_BENCHMARK - cout << "Cn[" << j << "]: " << *rgpcns[j] << endl; -#endif - } - - cout << "done building data structures" << endl; - cout << "time = " << timer.ElapsedTime() << "\n" << endl; - timer.Start(); - int cExceptions = 0; -#ifdef CL_SHOW_CNS_IN_BENCHMARK - cout << "Exceptions on: "; -#endif - for (j = 0; j < nCns; j++) - { - // Add the constraint -- if it's incompatible, just ignore it - try - { - solver.AddConstraint(rgpcns[j]); - } - catch (ExCLRequiredFailure &) - { - cExceptions++; - rgpcns[j] = NULL; -#ifdef CL_SHOW_CNS_IN_BENCHMARK - cout << j << " "; -#endif - } - } -#ifdef CL_SHOW_CNS_IN_BENCHMARK - cout << "\n" << endl; -#endif - solver.Solve(); - cout << "done adding constraints [" << cExceptions << " exceptions]" << endl; - cout << "time = " << timer.ElapsedTime() << "\n" << endl; - cout << "time per cn = " << timer.ElapsedTime()/nCns << "\n" << endl; - cout << "time per actual cn = " << timer.ElapsedTime()/(nCns - cExceptions) << "\n" <Value()*1.001) - .SuggestValue(e2,e2->Value()*1.001) - .Resolve(); - } - solver.EndEdit(); - // cout << "run time: " << - - cout << "done resolves -- now removing constraints" << endl; - cout << "time = " << timer.ElapsedTime() << "\n" < 1) - cns = atoi(argv[1]); - - if (argc > 2) - vars = atoi(argv[2]); - - if (argc > 3) - resolves = atoi(argv[3]); - - if (cns > 0) - { - cout << "addDel" << ":" << endl; - fResult = addDel(cns,vars,resolves); fAllOkResult &= fResult; - if (!fResult) cout << "Failed!" << endl; - } - -#undef RUN_TEST - -#ifdef CL_FIND_LEAK - cout << "ClAbstractVariables: " << ClAbstractVariable::cAbstractVariables - << "\nClDummyVariables: " << ClDummyVariable::cDummyVariables - << "\nClSlackVariables: " << ClSlackVariable::cSlackVariables - << endl; -#endif - - - return (fAllOkResult? 0 : 255); - - } - catch (...) - { - cerr << "exception!" << endl; - } -} diff --git a/libs/cassowary/ClVariable.cc b/libs/cassowary/ClVariable.cc deleted file mode 100644 index 2a136c1096..0000000000 --- a/libs/cassowary/ClVariable.cc +++ /dev/null @@ -1,21 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClVariable.cc - -#include - -#ifdef HAVE_CONFIG_H -#include -#define CONFIG_H_INCLUDED -#endif - -StringToVarMap *ClVariable::pmapStrPclv = NULL; -ClVariable clvNil(static_cast(0)); - diff --git a/libs/cassowary/IMPORTANT b/libs/cassowary/IMPORTANT deleted file mode 100644 index 1edaabfa01..0000000000 --- a/libs/cassowary/IMPORTANT +++ /dev/null @@ -1,26 +0,0 @@ -Cassowary/C++ needs to be compiled using a modern C++ compiler. -At one time or another, it has compiled using: - o egcs-1.0.1, egcs-1.0.3, egcs-1.1b, gcc-2.8.1, gcc-2.95.2 - o Visual C++ 5.0 - -Cassowary/Java was developed using Sun's JDK-1.1.3, ported to Linux -More recent versions should work fine, and it has been tested -with JDK-1.2pre2. - -The included Makefiles depend upon features of GNU Make. See: - -ftp://ftp.gnu.org/pub/gnu/ - -for a version that you can build. - - -To build the c++/qdemos/QuadDemo application, you'll need TrollTech's Qt -widget set for X11, available from: - -http://www.troll.no/dl/qtfree-dl.html - - -See also the Scwm (Scheme Constraints Window Manager) web page for a use -of Cassowary in a substantial application: - -http://scwm.mit.edu/scwm/ diff --git a/libs/cassowary/LICENSE b/libs/cassowary/LICENSE deleted file mode 100644 index 21ecedf70d..0000000000 --- a/libs/cassowary/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -Cassowary Constraint Solving Toolkit -Copyright (C) 1998-200 Greg J. Badros - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -See COPYING.LGPL diff --git a/libs/cassowary/NEWS b/libs/cassowary/NEWS deleted file mode 100644 index 0f950dacef..0000000000 --- a/libs/cassowary/NEWS +++ /dev/null @@ -1,229 +0,0 @@ -Cassowary NEWS -- history of user-visible changes. -*- text -*- - -Cassowary Constraint Solving Toolkit was -Implemented by: - -Greg J. Badros and -Alan Borning -University of Washington -Computer Science and Engineering -Seattle, WA 98195-2350 - -with Constraint Drawing Applet (CDA) by Michael Noth - -12-March-2000: Version 0.60 released. -* Changed license to LGPL!!! -* Added SetAutoResetStayConstants(), FIsAutoResetStayConstants(), make ResetStayConstants() public - -29-Jan-2000: Version 0.55 released. -* Some bug fixes -* Added ClSimplexSolver::{ChangeStrength,ChangeStrengthAndWeight,ChangeWeight, - DisplayObjective,ExternalResetStayConstants} fns - From A. Beurivé. - -16-Dec-1999: Version 0.54a released. -* Include correct version of OTI Smalltalk .dat file - (the source in the *.app files was right, the .dat file was old) -* Fix java build bug - -15-Dec-1999: Version 0.54 released. -* Bug fixes -* auto-configuration improvements -* Support Java 2 (jdk-1.2) -* Improved ease of building Java demos -* Build guile wrapper as long as guile-config works, use new --disable-guile-build to force off -* Alpha-version of Java constraint parser contributed by Will Portnoy - -24-October-1999: Version 0.53 released. -* Bug fixes -* License exception for linking with Scwm. - -25-September-1999: Version 0.52 released. -* Bug fix for nested edits where a later edit includes an already-being-edited variable - -14-September-1999: Version 0.51 released. -* Minor bug fixes -* Much better packaging, RPMs, etc. more forced reliance on GTL - -26-August-1999: Version 0.51 pre-releases begin - -12-July-1999: Version 0.50 released. -* Made only C++ version build by default, --enable-java-build is needed to turn java on -* Added restricted finite domain solver -** needs --with-gtl configure option, and libGTL.{a,so*} to be installed -* Added ClSolver base class, and use its type for pointers in callbacks - -14-Apr-1999: Version 0.43 released. -* DEBUG_PARSE turned off by default -* Added cassowary.spec for RPM building - -31-Mar-1999: Version 0.42 released. -* Fixed autoconf bugs (.41 was a buggy release) -* Added --disable-cpp-build,--disable-java-build, and disable Python/Guile builds -automatically if directories cannot be found - -20-Mar-1999: Version 0.41 released. -* Fixed bug in autoconf support -- config.sub, config.guess to the -distribution so configure should actually work (they were symlinks -before, in error). - -18-Mar-1999: Version 0.4 released. - -18-Mar-1999: Changes since Cassowary v0.32 (for release v0.4) -* MUCH improved autoconf/automake support including numerous configure -options, added libtool support. -* Renamed many identifiers in the public API; this will break old code -using Cassowary. See the scripts/convert-ids script for help converting -your code (beware false positives; i.e., improper or unnecessary -changes). - - -10-Mar-1999: Changes since Cassowary v0.31 (for release v0.32) -* Added automake/autoconf support. Old Makefiles are now -Makefile.linux. This is not yet fully tested or correct, but I need to -make a release now for the bug fixes. Consider compiling with "make -f -Makefile.linux all" if you have problems running autoconf and/or -automake. - -* Changes to C++ -** Bug fix for problem Anthony Beurivé noticed regarding removing non-1 -weight stay constraints. -** Minor bug fix for parser. Also renamed the creader files to ClReader. - -* Changes to Java -** Bug fix for problem Emmanuel Pietriga reported regarding edit -constraints. -** Improved debugging support a bit by adding descriptions to -ExCLInternalError-s and assert()s - -* Changes to guile wrapper -** changed name of library to libcassowaryguile.a from libconstraints.a - - -1-Mar-1999: Changes since Cassowary v0.3 (for release v0.31) -* Changes to C++ -** Some bug fixes -- pass ClVariable-s around by value instead of const -& since they are now a handle class. -** Changed output format for ClEditConstraint, ClStayConstraint instances -** Use a function-object for controlling lookup/creation of variables in PcnParseConstraint -** Fix bugs in creader.y parser (did not accept parens or division -before). Introduced "==" as a a synonym for "=" -** Added szCassowaryVersion id string as a public char *. -** Added ChangeStrength, ChangeWeight to ClConstraint's public -interface, and have it valid only when the constraint is not in a solver -** Added ClConstraint::FIsInSolver() - -* Changes to Guile wrapper -** Fix bugs -** Wrap parsing functionality, including a lambda for lookup/creation of -variables -** Build a dynamically-loadable guile module, update cltests.scm to use it - - -23-Feb-1999: Version 0.3 released. - -19-Feb-1999, Changes since Cassowary v0.23 (for release v0.3) - -* Changes to Java and C++ -** Bug fix for Michael Kaufmann's report (see ChangeLog for details) -** resolve(Vector..) procedure is now depracated; preferred interface is -suggestValue(...) calls followed by resolve() (the one taking no -arguments). -** Added ClVariable::SetVarMap(..), ClVariable::VarMap() to permit -ClVariable ctr to save the mapping between given name and actual object -in a symbol table (used for parsing ascii expressions in C++ version) - -* Changes to just C++ implementation -** Use ClVariable as a handle class to a ClAbstractVariable-- old -ClVariable is now a ClFloatVariable. SetChangeClvCallback now takes a -function that takes a ClVariable handle, not a pointer. -** Passing ClConstraints's by const & is now deprecated -- pass by -pointer to the ClConstraint object -** Added creader.y, creader.l and function PcnParseConstraint(..) for -creating a constraint from an ASCII string. -** Added CL_NO_IO compile-time option to C++ version for preventing need -to link with the stream library (is not complete) -** Added CL_FIND_LEAK compile-time option for counting ctrs/dtr -invocations -** Added CL_USE_HASH_MAP compile-time option to permit using the GNU -hash_map class instead of the standard STL map (which is a sorted -associative container whose performance for lookups is logarithmic -rather than constant time). Still does not work for me --02/16/99 gjb. - -* Changes to just Java implementation (updated to match changes to C++ -version for .2) -** Added {get,set}AttachedObject for ClVariable, ClConstant -** Permit access to ClSimplexSolver.ConstraintMap() -** Permit nested beginEdit()s and handle them correctly - -* Miscellaneous changes -** Updated copyright to include 1999 -** Fixed wrappers/Makefile for building Python wrapper -** Reference Anthony Beurivé's STk wrapper -** Fix Scwm URL - - -30-Jan-1999, Changes since Cassowary v0.22 (for release v0.23) -* Bug fix (see ChangeLog for details) - - -23-Jan-1999, Changes since Cassowary v0.21 (for release v0.22) -* Minor code cleanup, additions of comments. - - -14-Sep-98, Changes since Cassowary v0.2 (for release v0.21) - -* Make compile cleanly using egcs-1.1b -- use typename, and drop - unused templated instantiation - -* Improved guile interface: add a void pointer to the solver objects, - and let the guile wrapper use it to keep a pointer to the scheme-level - object; also added clv-attach! and clv-attached-object for attaching - an object to a cl-variable (somewhat redundant with guile's - object properties) - -* Wrap ClStayConstraints so they can be managed explicitly - -* cl-add-stay, cl-add-editvar now take strength and factor arguments, - instead of a list of cl-vars - -* Added weight option to addEditVar - - -6-Aug-98, Changes since Cassowary v0.1 (for release v0.2): - -* Changes to the distribution for release v0.2 - -** added guile/scheme wrapper of C++ version - -** mention SCWM in README - -** mention non-maintenance of Smalltalk implementation unless we have users - -* Changes to the C++ and Java implementations - -** Fixed several bugs -- dummy variables were wrongly being pivoted into - the basis, and constraints that threw required failure exceptions - were mistakenly remaining in the tableau (now trying to remove an - exception that was not added because of a required-failure exception - will correctly throw a ConstraintNotFound exception); more -- see ChangeLog - -** Added a virtual change_value function to permit applications to watch - for changes made to external variables. - -* Changes to only the C++ version (Java version will catch up in 0.3) - -** Added new test cases to ClTests, fixed bugs in ClTestColumns - -** Added _pv (void *) field hanging off of ClConstraint and ClVariable - for associating arbitrary structs with those (needed by SCWM) - -** Permit nested beginEdit()s, and do the right thing upon calling - endEdit() -- i.e., not all the edit variables are removed, only the - nested ones - -** Permit access to ClSimplexSolver::ConstraintMap() (used by - guile-wrapper to efficiently get at a list of constraints in the - solver) - -** Added ExCLEditMisuse exception diff --git a/libs/cassowary/README b/libs/cassowary/README deleted file mode 100644 index 16ed492b8e..0000000000 --- a/libs/cassowary/README +++ /dev/null @@ -1,241 +0,0 @@ -Cassowary Constraint Solving Toolkit for C++, Java, and Smalltalk -Version 0.60 - -Web Page: http://www.cs.washington.edu/research/constraints/cassowary -Contact: cassowary@cs.washington.edu - -Greg J. Badros and -Alan Borning -University of Washington -Computer Science and Engineering -Seattle, WA 98195-2350 -12-March-2000 - -with Constraint Drawing Applet (CDA) by Michael Noth - -See ANNOUNCE for a brief description and announcement of this distribution. -See NEWS for a history of user-visible changes. -See ChangeLog for a detailed listing of the changes to each source file. -See LICENSE for legalese regarding use of this distribution. - -The Smalltalk implementation is in the public domain -- see smalltalk/README. - -Please send bug reports to cassowary@cs.washington.edu - -Also, send mail to cassowary@cs.washington.edu if you would like to be -informed about bug fixes, feature enhancements, etc. Let us know what -implementation(s) you are using, too. - ------------------------------------------------------------------- - -HOW TO GET STARTED - -The Cassowary library uses GNU autoconf to permit easy building on -various platforms. You should be able to do: - -./configure -make - -and everything will work. A more complex, but realistic example is: - -./configure --with-prefix=/usr/contrib \ - --with-guile-prefix=/usr/contrib \ - --with-python-headers=/usr/include/python1.5 \ - --enable-java-build \ - --with-gtl=/usr/contrib \ - --with-java-class-path=/usr/contrib/share/java/site \ - --enable-warnings -make -k - -Be sure to give the extra --enable-permissive flag to configure if -you are building with gcc-2.95 or more recent. - -As yet another data point, I build Cassowary with: - -./configure --with-guile-exec-prefix=/uns/bin \ - --with-guile-prefix=/uns/share --prefix=/uns/share \ - --exec-prefix=/uns --enable-maintainer-mode - -See the file "INSTALL" for more details about -autoconf support and the options that the "configure" takes. You can -also do "./configure --help" for the list of the options that configure -accepts. - -If the make in any of the subdirectories fails, you can turn on the "-k" -option to make, or just do make in the subdirectories that you want -build. E.g., if you do not have the JDK installed, the Java version of -Cassowary might not compile; if you still want the guile version, just -"cd guile; make -k". - -Be sure that configure detects the validity of using the "-fpermissive" -flag of more recent g++/egcs compilers to work around some -const-discrepancies between the const-challenged guile header files and -Cassowary's more const-correct usage. You should get a message like: - - checking whether gcc understands -fpermissive option... yes - -when running configure if you're using, e.g., gcc-2.95 or later. - -You need to apply GTL.h.patch to the installed GTL.h header file for -Cassowary to compile with recent versions of egcs/gcc (e.g., gcc-2.95). - -Also, you may need to change libguile/gsubr.h from: - - extern SCM scm_make_gsubr SCM_P ((char *name, int req, int opt, - int rst, SCM (*fcn)())); - to - - extern SCM scm_make_gsubr SCM_P ((char *name, int req, int opt, - int rst, void*)); - -or patch guile's snarf.h to insert the appropriate case at each call to -SCM_PROC and SCM_PROC1. (Thanks to Alexandre Duret-Lutz for the above -information about more recent g++/egcs compilers). - -Note that the generated Makefiles depend upon features of GNU Make. See: - -ftp://ftp.gnu.org/pub/gnu/ - -for a version of make that you can build first to then build Cassowary. - -Example applications exist in subdirectories of the top-level -implementation subdirectories (e.g., c++/qdemos contains demos for C++ -that use the Qt Widget toolkit). - -Please send mail to cassowary@cs.washington.edu if you are using this -toolkit so we know how to reach you for bug fixes, updates, etc. - ------------------------------------------------------------------- - -WHAT THE DISTRIBUTION CONTAINS - -This distribution contains 3 implementations of the Cassowary constraint -solving toolkit: - -o C++ -o Java -o Smalltalk - -For each implementation language, there is at least one example program; -for some there are many. - -There is a wrapping of the C++ solver in Guile-Scheme -- see the guile/ -subdirectory. Also, Anthony Beurivé has wrapped Cassowary for -STk/Scheme. His code is available at: - - http://dept-info.labri.u-bordeaux.fr/~beurive/Code - -and the STk Scheme system is available at: - - http://kaolin.unice.fr/STk/ - -There is also a SWIG-generated wrapper of the C++ library making the -solver available from the Python language. - -A technical report describing the solver, its interface, and its -implementation is in cassowary-tr.ps (pdf version in cassowary-tr.pdf). -This paper is required reading if you intend to use the solver in your -own project(s). - -See also the Scwm (Scheme Constraints Window Manager) web page: - -http://scwm.mit.edu/scwm/ - -Scwm, also by Greg Badros (and Maciej Stachowiak), is the most -substantial application using this toolkit that we are aware of. - ------------------------------------------------------------------- - -VARIOUS IMPLEMENTATION NOTES - -Cassowary/C++ needs to be compiled using a modern C++ compiler. -At one time or another, it has compiled using: - o egcs-1.0.1 - o egcs-1.0.3a - o egcs-1.1b - o egcs-1.1.1 - o gcc-2.8.1 (needs libstdc++-2.8.x, too) - o Visual C++ 5.0 (not tried recently) - -In particular, Cassowary will *not* build with gcc-2.7.x.x! - -See c++/README for more details about building the C++ version. - -The C++ implementation of the toolkit also has an optional finite domain -subsolver. You need to build and install the GTL -- the Graph Template -Library -- and use the "--with-gtl=DIR" configure option for the finite -domain subsolver to be built. GTL is available from: - -http://www.fmi.uni-passau.de/Graphlet/GTL/ - -Cassowary was tested against GTL-0.3.1; it may work with later -versions, but I have not tried it. You need to apply GTL.h.patch to -the installed GTL.h header file for Cassowary to compile with recent -versions of egcs/gcc (e.g., gcc-2.95). - -Cassowary/Java was developed using Sun's JDK-1.1.x, ported to Linux -More recent versions should work fine. - -See java/README for more details about building the Java version. - - -Cassowary/Smalltalk was written under OTI Smalltalk-- other versions of -smalltalk will likely require (possibly significant) changes. - -See smalltalk/README for more details about the Smalltalk version. - -See guile/README for details about the Guile Scheme wrapper of the C++ -implementation, and for a pointer to SCWM, the Scheme Constraints Window -Manager which uses Cassowary. - -The Python bindings (by Tessa Lau) bindings for the Cassowary library -are in the wrappers/ subdirectory. SWIG was used in wrapping the -library. These bindings may no longer work, and are provided only for -your hacking pleasure (please send back useful patches if you do get the -code working). - -For more information about SWIG, see: - -http://www.swig.org/ - - -For more information about the Python language, see: - -http://www.python.org/ - - -For more information about the Guile-Scheme language, see: - -http://www.red-bean.com/guile/ -http://www.fsf.org/software/guile/guile.html - - ------------------------------------------------------------------- - -DEMONSTRATION APPLICATION - -A standard demonstration application is included for each implementation -of the Cassowary solver. The application builds a quadrilateral and -connects the neighboring midpoints of each of the outer edges to form an -interior quadrilateral which is provably a parallelogram. The -constraint solver manages the constraints to keep the outer -quadrilateral inside the window, keep the midpoints properly positioned, -and keep the outer quadrilateral from turning "inside out." - -The user is able to select points (draggable boxes) and move them around -within the window (both midpoints and endpoints can be selected, of -course). The solver updates the figure, and redraws. - - ------------------------------------------------------------------- - -FUNDING ACKNOWLEDGEMENTS - -This work has been funded in part by the National Science Foundation under -Grants IRI-9302249 and CCR-9402551, by Object Technology International, and -by a Fulbright Award from the Australian-American Educational -Foundation. - -Additionally, Greg Badros is supported by a National Science Foundation -Graduate Research Fellowship. Parts of this material are based upon -work supported under that fellowship. diff --git a/libs/cassowary/SConscript b/libs/cassowary/SConscript deleted file mode 100644 index 86222085f5..0000000000 --- a/libs/cassowary/SConscript +++ /dev/null @@ -1,32 +0,0 @@ -# -*- python -*- -Import('env libraries') - -cassowary = env.Copy(YACCFLAGS="-d") - -domain = 'libcassowary' -cassowary.Append(DOMAIN=domain,MAJOR=0,MINOR=60,MICRO=3) - -cassowary_files = Split(""" -ClAbstractVariable.cc -ClConstraint.cc -ClLinearExpression.cc -ClSolver.cc -ClSimplexSolver.cc -ClStrength.cc -ClSymbolicWeight.cc -ClTableau.cc -ClVariable.cc -ClFloatVariable.cc -ClSlackVariable.cc -ClDummyVariable.cc -ClReader.cc -ClReader-lex.cc -""") - -cassowary.Append(CCFLAGS="-D_REENTRANT") - -cassowary.CXXFile(target = ['ClReader.cc', 'ClReader.cc.h'], source = 'ClReader.yy') -cassowary.CXXFile(target = 'ClReader-lex.cc', source = 'ClReader.ll') - -libcassowary = cassowary.SharedLibrary('cassowary', cassowary_files) -Default(libcassowary) diff --git a/libs/cassowary/THANKS b/libs/cassowary/THANKS deleted file mode 100644 index 11918b3d52..0000000000 --- a/libs/cassowary/THANKS +++ /dev/null @@ -1,30 +0,0 @@ -Cassowary Constraint Solving Toolkit was -Implemented by: - -Greg J. Badros and -Alan Borning -University of Washington -Computer Science and Engineering -Seattle, WA 98195-2350 - -with Constraint Drawing Applet (CDA) by Michael Noth - -Please send bug reports to cassowary@cs.washington.edu - - -Bug reports, helpful testing, and/or code from: - -Spencer Allain -Anthony Beurivé -Robert Chassell -Alexandre 'Pollux' Duret-Lutz -Michael Kaufmann -Brian Grant -Pengling He -Tessa Lau -John MacPhail -Larry Melia -Michael Noth -Emmanuel Pietriga -Will Portnoy -Steve Wolfman diff --git a/libs/cassowary/cassowary-config.in b/libs/cassowary/cassowary-config.in deleted file mode 100755 index ac1b3ac8ce..0000000000 --- a/libs/cassowary/cassowary-config.in +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/sh -# Modified from gtk-config -# --09/07/99 gjb - -# gotten from LDADD in c++/Makefile.am -cassowary_gtllibs="@GTL_LIB@" -cassowary_libs="-L@prefix@/lib $cassowary_gtllibs" -cassowary_cflags="@GUILE_INCLUDES@ @GTL_INCLUDES@" - -prefix=@prefix@ -exec_prefix=@exec_prefix@ -exec_prefix_set=no - -usage() -{ - cat <&2 -fi - -while test $# -gt 0; do - case "$1" in - -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - case $1 in - --prefix=*) - prefix=$optarg - if test $exec_prefix_set = no ; then - exec_prefix=$optarg - fi - ;; - --prefix) - echo_prefix=yes - ;; - --exec-prefix=*) - exec_prefix=$optarg - exec_prefix_set=yes - ;; - --exec-prefix) - echo_exec_prefix=yes - ;; - --version) - echo @CASSOWARY_VERSION@ - ;; - --cflags) - echo_cflags=yes - ;; - --libs) - echo_libs=yes - ;; - --gtllibs) - echo_gtllibs=yes - ;; - *) - usage 1 1>&2 - ;; - esac - shift -done - -if test "$echo_prefix" = "yes"; then - echo $prefix -fi - -if test "$echo_exec_prefix" = "yes"; then - echo $exec_prefix -fi - - -if test "$echo_cflags" = "yes"; then - if test @includedir@ != /usr/include ; then - includes=-I@includedir@ - for i in $cassowary_cflags ; do - if test $i = -I@includedir@ ; then - includes="" - fi - done - fi - echo $includes $cassowary_cflags -fi - -if test "$echo_libs" = "yes"; then - echo -L@libdir@ -lcassowary -lstdc++ $cassowary_libs -fi - -if test "$echo_gtllibs" = "yes"; then - echo $cassowary_gtllibs -fi diff --git a/libs/cassowary/cassowary-nofd.spec2.in b/libs/cassowary/cassowary-nofd.spec2.in deleted file mode 100644 index ee951bb446..0000000000 --- a/libs/cassowary/cassowary-nofd.spec2.in +++ /dev/null @@ -1,84 +0,0 @@ -# Note that this is NOT a relocatable package -%define ver @VERSION@ -%define rel 2 -%define prefix /usr - -Name: cassowary-nofd -Summary: A Linear Arithmetic Constraint Solving Library. -Version: %ver -Release: %rel -# This source just has a different top-level directory name -Source: http://www.cs.washington.edu/research/constraints/cassowary/cassowary-nofd-%ver.tar.gz -Group: Development/Libraries -BuildRoot: /tmp/cassowary-%ver-build -Copyright: Copyright (C) 1998,1999 Greg J. Badros -Packager: Greg J. Badros -URL: http://www.cs.washington.edu/research/constraints/cassowary -Requires: guile >= 1.3.2 -Provides: cassowary-constraint-solver - -%description - -Cassowary is an advanced incremental constraint solving toolkit that -efficiently solves systems of linear equalities and inequalities. -Constraints may be either requirements or preferences. Client code -specifies the constraints to be maintained, and the solver updates the -constrained variables to have values that satisfy the constraints. - -This package lacks the finite domain subsolver. The cassowary RPM -contains that solver as well, but also requires the GTL (Graph -Template Library) package. - - -%changelog -* Tue Sep 7 1999 Greg J. Badros -- Rework spec file. - -* Wed Apr 14 1999 Greg J. Badros - -- Initial release of this package. - -%prep - -%setup - -%build -ln -sf . ./c++/cassowary - -%ifarch alpha -./configure --host=alpha-linux --prefix=%prefix --enable-guile-build --enable-fsstd --enable-permissive -%else -./configure --prefix=%prefix --enable-guile-build --enable-fsstd --enable-permissive -%endif - -make - -%install -make prefix=$RPM_BUILD_ROOT%{prefix} install-strip - -%clean -rm -rf $RPM_BUILD_ROOT - -%post - -%postun - -%files -%defattr(-, root, root) - -%{prefix}/bin/* -%{prefix}/lib/* -%{prefix}/include/* - -%doc ANNOUNCE AUTHORS COPYING IMPORTANT INSTALL LICENSE NEWS README THANKS -%doc ChangeLog docs/cassowary-tr.pdf docs/cassowary-tr.ps.gz -%doc guile/cassowary_scm-procedures.txt guile/cassowary_scm-variables.txt -%doc guile/cassowary_scm.sgml diff --git a/libs/cassowary/cassowary.spec.in b/libs/cassowary/cassowary.spec.in deleted file mode 100644 index 2b7c23a8e5..0000000000 --- a/libs/cassowary/cassowary.spec.in +++ /dev/null @@ -1,78 +0,0 @@ -# Note that this is NOT a relocatable package -%define ver @VERSION@ -%define rel 1 -%define prefix /usr - -Name: cassowary -Summary: A Linear Arithmetic Constraint Solving Library. -Version: %ver -Release: %rel -Source: http://www.cs.washington.edu/research/constraints/cassowary/cassowary-%ver.tar.gz -Group: Development/Libraries -BuildRoot: /tmp/cassowary-%ver-build -Copyright: Copyright (C) 1998,1999 Greg J. Badros -Packager: Greg J. Badros -URL: http://www.cs.washington.edu/research/constraints/cassowary -Requires: guile >= 1.3.4 -Requires: GTL >= 0.3.1 -Provides: cassowary-constraint-solver - -%description - -Cassowary is an advanced incremental constraint solving toolkit that -efficiently solves systems of linear equalities and inequalities. -Constraints may be either requirements or preferences. Client code -specifies the constraints to be maintained, and the solver updates the -constrained variables to have values that satisfy the constraints. - -%changelog -* Tue Sep 7 1999 Greg J. Badros -- Rework spec file. - -* Wed Apr 14 1999 Greg J. Badros - -- Initial release of this package. - -%prep - -%setup - -%build -ln -sf . ./c++/cassowary - -%ifarch alpha -fake_root_for_install=$RPM_BUILD_ROOT ./configure --host=alpha-linux --prefix=%prefix --with-gtl=%prefix --enable-fd-solver --enable-fsstd --enable-permissive -%else -fake_root_for_install=$RPM_BUILD_ROOT ./configure --prefix=%prefix --with-gtl=%prefix --enable-fd-solver --enable-fsstd --enable-permissive -%endif - -make - -%install -make prefix=$RPM_BUILD_ROOT%{prefix} fake_root_for_install=$RPM_BUILD_ROOT install-strip - -%clean -rm -rf $RPM_BUILD_ROOT - -%post - -%postun - -%files -%defattr(-, root, root) - -%{prefix}/bin/* -%{prefix}/lib/* -%{prefix}/include/* - -%doc ANNOUNCE AUTHORS COPYING IMPORTANT INSTALL LICENSE NEWS README THANKS -%doc ChangeLog docs/cassowary-tr.pdf docs/cassowary-tr.ps.gz -%doc guile/cassowary_scm-procedures.txt guile/cassowary_scm-variables.txt -%doc guile/cassowary_scm.sgml diff --git a/libs/cassowary/cassowary/.cvsignore b/libs/cassowary/cassowary/.cvsignore deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/libs/cassowary/cassowary/Cassowary.h b/libs/cassowary/cassowary/Cassowary.h deleted file mode 100644 index 8413f321f9..0000000000 --- a/libs/cassowary/cassowary/Cassowary.h +++ /dev/null @@ -1,40 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// Cassowary.h - -#ifndef Cassowary_H -#define Cassowary_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) - #include - #define CONFIG_INLINE_H_INCLUDED -#endif - -#ifndef CL_PTR_HASH_DIVISOR - #define CL_PTR_HASH_DIVISOR 4 -#endif - -#include "ClConstraintHash.h" -#include - -#include -#include -#include - -typedef double Number; - -typedef long FDNumber; - -enum { FDN_NOTSET = LONG_MIN }; - -#define NEWVAR(x) do { cerr << "line " << __LINE__ << ": new " << x << endl; } while (0) -#define DELVAR(x) do { cerr << "line " << __LINE__ << ": del " << x << endl; } while (0) - -#endif // Cassowary_H diff --git a/libs/cassowary/cassowary/Cl.h b/libs/cassowary/cassowary/Cl.h deleted file mode 100644 index 6c2604da6f..0000000000 --- a/libs/cassowary/cassowary/Cl.h +++ /dev/null @@ -1,49 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// Cl.h -// This is the top level include file for external clients - -#ifndef CL_H -#define CL_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#ifdef CL_NO_IO -#undef CL_TRACE -#undef CL_SOLVER_STATS -#undef CL_DEBUG_FAILURES -#undef CL_TRACE_VERBOSE -#endif - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "cassowary/ClVariable.h" -#include "cassowary/ClSimplexSolver.h" -#include "cassowary/ClLinearEquation.h" -#include "cassowary/ClLinearInequality.h" -#include "cassowary/ClErrors.h" -#include "cassowary/ClEditConstraint.h" -#include "cassowary/ClStayConstraint.h" -#include "cassowary/ClReader.h" -#include "cassowary/ClConstraint.h" -#if defined(CL_HAVE_GTL) && defined(CL_BUILD_FD_SOLVER) -#include "cassowary/ClFDBinaryOneWayConstraint.h" -#include "cassowary/ClFDSolver.h" -#endif - -extern const char *szCassowaryVersion; - -#endif diff --git a/libs/cassowary/cassowary/ClAbstractVariable.h b/libs/cassowary/cassowary/ClAbstractVariable.h deleted file mode 100644 index 08ade9ec98..0000000000 --- a/libs/cassowary/cassowary/ClAbstractVariable.h +++ /dev/null @@ -1,161 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClAbstractVariable.h - -#ifndef ClAbstractVariable_H -#define ClAbstractVariable_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include /* for sprintf */ -#include "Cassowary.h" -#include "ClErrors.h" -#include -#include -#include -#include "cl_auto_ptr.h" - -using std::string; -using std::ostream; - -class ClAbstractVariable { -public: - ClAbstractVariable(string Name = "") : - _name(Name), _pv(0) - { - ++iVariableNumber; -#ifdef CL_FIND_LEAK - ++cAbstractVariables; -#endif - if (Name.length() == 0) - { - char sz[16]; - sprintf(sz,"v%ld",iVariableNumber); - _name = string(sz); - } - } - - ClAbstractVariable(long varnumber, char *prefix) : - _pv(0) - { - cl_auto_ptr pch (new char[16+strlen(prefix)]); - iVariableNumber++; -#ifdef CL_FIND_LEAK - ++cAbstractVariables; -#endif - sprintf(pch.get(),"%s%ld",prefix,varnumber); - _name = string(pch.get()); - } - - virtual ~ClAbstractVariable() -#ifdef CL_FIND_LEAK - { --cAbstractVariables; } - - static long cAbstractVariables; -#else - { } -#endif - - // Return the Name of the variable - string Name() const - { return _name; } - - // Set the Name of the variable - virtual void SetName(string const &Name) - { _name = Name; } - - // Return true iff this variable is a ClFloatVariable - virtual bool IsFloatVariable() const - { return false; } - - // Return true iff this variable is a ClFDVariable - virtual bool IsFDVariable() const - { return false; } - - // Return true if this a dummy variable (used as a marker variable - // for required equality constraints). Such variables aren't - // allowed to enter the basis when pivoting. - virtual bool IsDummy() const - { return false; } - - // Return true if this a variable known outside the solver. - // (We need to give such variables a Value after solving is complete.) - virtual bool IsExternal() const - { return false; } - - // Return true if we can Pivot on this variable. - virtual bool IsPivotable() const - { throw ExCLTooDifficultSpecial("Variable not usable inside SimplexSolver"); return false; } - - // Return true if this is a restricted (or slack) variable. Such - // variables are constrained to be non-negative and occur only - // internally to the simplex solver. - virtual bool IsRestricted() const - { throw ExCLTooDifficultSpecial("Variable not usable inside SimplexSolver"); return false; } - -#ifndef CL_NO_IO - // Prints a semi-descriptive representation to the stream, using the - // Name if there is one, and otherwise the hash number of this - // object. - // EXAMPLES - // x[10.0] -- w/ Name - // x[0.0,100] -- w/ Name, bounds but no Value yet - // CV#345(10.0) -- w/o Name - virtual ostream &PrintOn(ostream &xo) const = 0; - - friend ostream& operator<<(ostream &xos, const ClAbstractVariable &clv) - { clv.PrintOn(xos); return xos; } - -#endif // CL_NO_IO - - friend bool operator<(const ClAbstractVariable &cl1, const ClAbstractVariable &cl2) - { return &cl1 < &cl2; } - - friend bool operator==(const ClAbstractVariable &cl1, const ClAbstractVariable &cl2) - { - return &cl1 == &cl2; - } - - friend bool operator!=(const ClAbstractVariable &cl1, const ClAbstractVariable &cl2) - { - return !(cl1 == cl2); - } - - virtual Number Value() const { return 0; } - virtual int IntValue() const { return 0; } - - virtual void SetValue(Number) - { assert(false); } - - virtual void ChangeValue(Number) - { assert(false); } - - void SetPv(void *pv) - { _pv = pv; } - - void *Pv() const - { return _pv; } - -private: - string _name; - - static long iVariableNumber; - - // C-style extension mechanism so I - // don't have to wrap ScwmClVariables separately - void *_pv; -}; - -typedef ClAbstractVariable *PClAbstractVariable; - -#endif diff --git a/libs/cassowary/cassowary/ClConstraint.h b/libs/cassowary/cassowary/ClConstraint.h deleted file mode 100644 index 0b670e6c07..0000000000 --- a/libs/cassowary/cassowary/ClConstraint.h +++ /dev/null @@ -1,198 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClConstraint.h - -#ifndef ClConstraint_H -#define ClConstraint_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "debug.h" - -#include "Cassowary.h" -#include "ClLinearExpression.h" -#include "ClStrength.h" -#include - -using std::string; - -class ClSimplexSolver; -class ClFDSolver; -class ClBlueSolver; - -// enum setup so additive inverse flips the direction of the inequality -enum ClCnRelation {cnEQ = 0, cnNEQ = 100, cnLEQ = 2, cnGEQ = -2, cnLT = 3, cnGT = -3 }; - -inline enum ClCnRelation -ReverseInequality(enum ClCnRelation c) -{ - if (c != cnNEQ) - c = (enum ClCnRelation) (- int(c)); - return c; -} - -inline string -StrCnRelation(enum ClCnRelation rel) { - switch (rel) { - case cnEQ: return "="; - case cnNEQ: return "=/="; - case cnLEQ: return "<="; - case cnGEQ: return ">="; - case cnLT: return "<"; - case cnGT: return ">"; - default: assert(false); - } -} - - - -class ClConstraint { -public: - - ClConstraint(const ClStrength &strength = ClsRequired(), double weight = 1.0 ) : - _strength(strength), - _readOnlyVars(), - _weight(weight), - _pv(0), - _times_added(0) - { - CtrTracer(__FUNCTION__,this); - } - - virtual ~ClConstraint() - { - DtrTracer(__FUNCTION__,this); - } - - // Return my linear Expression. (For linear equations, this - // constraint represents Expression=0; for linear inequalities it - // represents Expression>=0.) - virtual ClLinearExpression Expression() const - { assert(false); } - - // Returns true if this is an edit constraint - virtual bool IsEditConstraint() const - { return false; } - - // Return true if this is an inequality constraint and - // false if it is an equality constraint. The default is - // that it is not. - virtual bool IsInequality() const - { return false; } - - virtual bool IsStrictInequality() const - { return false; } - - virtual bool IsRequired() const - { return _strength.IsRequired(); } - - virtual bool isStayConstraint() const - { return false; } - - virtual const ClStrength &strength() const - { return _strength; } - - virtual double weight() const - { return _weight; } - -#ifndef CL_NO_IO - virtual ostream &PrintOn(ostream &xo) const = 0; - - friend ostream& operator<<(ostream &xos, const ClConstraint &constraint) - { constraint.PrintOn(xos); return xos; } - -#endif - - - void SetPv(void *pv) - { _pv = pv; } - - void *Pv() const - { return _pv; } - - virtual bool FIsSatisfied() const { return false; } - - virtual bool FIsInSolver() const { return _times_added != 0; } - - virtual bool FIsOkayForSimplexSolver() const { return true; } - - void ChangeStrength( const ClStrength &strength) - { - if (_times_added == 0) { - setStrength(strength); - } else { - throw ExCLTooDifficult(); - } - } - - void ChangeWeight( double weight ) - { - if (_times_added == 0) { - setWeight(weight); - } else { - throw ExCLTooDifficult(); - } - } - - bool FIsReadOnlyVar(ClVariable v) const { - return !(_readOnlyVars.find(v) == _readOnlyVars.end()); - } - - const ClVarSet &ReadOnlyVars() const { - return _readOnlyVars; - } - - ClConstraint &AddROVars(const ClVarSet &setClv) { - for ( ClVarSet::const_iterator it = setClv.begin(); - it != setClv.end(); ++it) { - _readOnlyVars.insert(*it); - } - return *this; - } - - friend class ClSimplexSolver; - friend class ClFDSolver; - friend class ClBlueSolver; -private: - - ClSymbolicWeight symbolicWeight() const { - return _strength.symbolicWeight(); - } - - void addedTo(const ClSimplexSolver &) - { ++_times_added; } - - void removedFrom(const ClSimplexSolver &) - { --_times_added; } - - void setStrength( const ClStrength &strength ) - { _strength = strength; } - - void setWeight( double weight ) - { _weight = weight; } - - /// instance variables - ClStrength _strength; - - ClVarSet _readOnlyVars; - - double _weight; - - void *_pv; - - int _times_added; -}; - -typedef ClConstraint* PClConstraint; - -#endif diff --git a/libs/cassowary/cassowary/ClConstraintHash.h b/libs/cassowary/cassowary/ClConstraintHash.h deleted file mode 100644 index 9d51fad311..0000000000 --- a/libs/cassowary/cassowary/ClConstraintHash.h +++ /dev/null @@ -1,39 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClHash.h - -#ifndef CL_HASH_H__ -#define CL_HASH_H__ - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#ifdef CL_USE_HASH_MAP_AND_SET - -#include - -class ClConstraint; - -struct hash { - size_t operator()(const ClConstraint * const p) const - { return size_t((unsigned long)p/CL_PTR_HASH_DIVISOR); } -}; - -struct hash { - size_t operator()(ClConstraint * const p) const - { return size_t((unsigned long)p/CL_PTR_HASH_DIVISOR); } -}; - -#endif // CL_USE_HASH_MAP_AND_SET - - -#endif diff --git a/libs/cassowary/cassowary/ClDummyVariable.h b/libs/cassowary/cassowary/ClDummyVariable.h deleted file mode 100644 index ad959a6d20..0000000000 --- a/libs/cassowary/cassowary/ClDummyVariable.h +++ /dev/null @@ -1,88 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClDummyVariable.h - -#ifndef ClDummyVariable_H -#define ClDummyVariable_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClAbstractVariable.h" - -class ClTableau; -class ClSimplexSolver; - -class ClDummyVariable : public ClAbstractVariable { - -public: - -#ifdef CL_FIND_LEAK - ~ClDummyVariable() { --cDummyVariables; }; - - static long cDummyVariables; - -#endif - -protected: - friend class ClTableau; - friend class ClSimplexSolver; - - ClDummyVariable(string Name = "") : - ClAbstractVariable(Name) - { -#ifdef CL_FIND_LEAK - ++cDummyVariables; -#endif - } - - ClDummyVariable(long number, char *prefix) : - ClAbstractVariable(number,prefix) - { -#ifdef CL_FIND_LEAK - ++cDummyVariables; -#endif - } - -#ifndef CL_NO_IO - virtual ostream &PrintOn(ostream &xo) const - { - xo << "[" << Name() << ":dummy]"; - return xo; - } -#endif - - // Return true if this a dummy variable (used as a marker variable - // for required equality constraints). Such variables aren't - // allowed to enter the basis when pivoting. - virtual bool IsDummy() const - { return true; } - - // Return true if this a variable known outside the solver. - // (We need to give such variables a Value after solving is complete.) - virtual bool IsExternal() const - { return false; } - - // Return true if we can Pivot on this variable. - virtual bool IsPivotable() const - { return false; } - - // Return true if this is a restricted (or slack) variable. Such - // variables are constrained to be non-negative and occur only - // internally to the simplex solver. - virtual bool IsRestricted() const - { return true; } - -}; - -#endif diff --git a/libs/cassowary/cassowary/ClEditConstraint.h b/libs/cassowary/cassowary/ClEditConstraint.h deleted file mode 100644 index 4bd91e2ca2..0000000000 --- a/libs/cassowary/cassowary/ClEditConstraint.h +++ /dev/null @@ -1,45 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClEditConstraint.h - -#ifndef ClEditConstraint_H -#define ClEditConstraint_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClEditOrStayConstraint.h" - -class ClEditConstraint : public ClEditOrStayConstraint { - typedef ClEditOrStayConstraint super; - public: - - ClEditConstraint(const ClVariable var, - const ClStrength &strength = ClsStrong(), double weight = 1.0 ) : - ClEditOrStayConstraint(var,strength,weight) - { } - - // Returns true if this is an edit constraint - virtual bool IsEditConstraint() const - { return true; } - -#ifndef CL_NO_IO - virtual ostream &PrintOn(ostream &xo) const - { super::PrintOn(xo); return xo << "= edit)"; } -#endif - - private: - -}; - -#endif diff --git a/libs/cassowary/cassowary/ClEditOrStayConstraint.h b/libs/cassowary/cassowary/ClEditOrStayConstraint.h deleted file mode 100644 index 79b6761b69..0000000000 --- a/libs/cassowary/cassowary/ClEditOrStayConstraint.h +++ /dev/null @@ -1,51 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClEditOrStayConstraint.h - -#ifndef ClEditOrStayConstraint_H -#define ClEditOrStayConstraint_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "ClConstraint.h" -#include "ClLinearExpression.h" - -class ClVariable; - -class ClEditOrStayConstraint : public ClConstraint { - public: - - ClEditOrStayConstraint(const ClVariable var, - const ClStrength &strength = ClsRequired(), double weight = 1.0 ) : - ClConstraint(strength,weight), - _variable(var) - { } - - const ClVariable variable() const - { return _variable; } - - ClLinearExpression Expression() const - { return ClLinearExpression(_variable,-1,_variable.Value()); } - - private: - - void setVariable( const ClVariable v) - { _variable = v; } - - /// instance variables - ClVariable _variable; - - -}; - -#endif diff --git a/libs/cassowary/cassowary/ClErrors.h b/libs/cassowary/cassowary/ClErrors.h deleted file mode 100644 index 867c578dbc..0000000000 --- a/libs/cassowary/cassowary/ClErrors.h +++ /dev/null @@ -1,179 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClErrors.h - -#ifndef ClErrors_H -#define ClErrors_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClTypedefs.h" -#include -#include - -using std::string; -using std::exception; - -class ExCLError : public exception { - public: - ExCLError() : _msg(0) { } - virtual ~ExCLError() throw() {} - virtual string description() const - { return "(ExCLError) An error has occured in CL"; } - protected: - char *_msg; -}; - -class ExCLInternalError : public ExCLError { - public: - ExCLInternalError(const char *sz) - { _msg = strdup(sz); } - virtual string description() const - { - if (_msg) return _msg; - else return "(ExCLInternalError) An internal error has occurred"; - } -}; - -class ExCLBadResolve : public ExCLError { - public: - ExCLBadResolve(const char *sz) - { _msg = strdup(sz); } - virtual string description() const - { - if (_msg) return _msg; - else return "(ExCLBadResolve) Number of resolve values did not match number of edit vars"; - } -}; - -class ExCLEditMisuse : public ExCLError { - public: - ExCLEditMisuse(const char *sz) - { _msg = strdup(sz); } - virtual string description() const - { - if (_msg) return _msg; - return "(ExCLEditMisuse) Edit protocol usage violation"; - } -}; - -class ExCLTooDifficult : public ExCLError { - public: - virtual string description() const - { return "(ExCLTooDifficult) The constraints are too difficult to solve"; } -}; - -class ExCLTooDifficultSpecial : public ExCLTooDifficult { - public: - ExCLTooDifficultSpecial(const char *sz) - { _msg = strdup(sz); } - virtual string description() const - { - if (_msg) return _msg; - else return "(ExCLTooDifficultSpecial) Solver requirements are not satisfied"; - } -}; - -class ExCLReadOnlyNotAllowed : public ExCLTooDifficult { - public: - virtual string description() const - { return "(ExCLReadOnlyNotAllowed) The read-only annotation is not permitted by the solver"; } -}; - -class ExCLCycleNotAllowed : public ExCLTooDifficult { - public: - virtual string description() const - { return "(ExCLCycleNotAllowed) A cyclic constraint graph is not permitted by the solver"; } -}; - -class ExCLStrictInequalityNotAllowed : public ExCLTooDifficult { - public: - virtual string description() const - { return "(ExCLStrictInequalityNotAllowed) The strict inequality is not permitted by the solver"; } -}; - -class ExCLRequiredFailure : public ExCLError { - public: - virtual ~ExCLRequiredFailure() throw() {} - virtual string description() const - { return "(ExCLRequiredFailure) A required constraint cannot be satisfied"; } -}; - -class ExCLNotEnoughStays : public ExCLError { - public: - virtual string description() const - { return "(ExCLNotEnoughStays) There are not enough stays to give specific values to every variable"; } -}; - -class ExCLNonlinearExpression : public ExCLError { - public: - virtual string description() const - { return "(ExCLNonlinearExpression) The resulting expression would be nonlinear"; } -}; - -class ExCLConstraintNotFound : public ExCLError { - public: - virtual string description() const - { return "(ExCLConstraintNotFound) Tried to remove a constraint that was never added"; } -}; - -class ExCLParseError : public ExCLError { - public: - virtual ~ExCLParseError() throw() {} - virtual string description() const - { return "(ExCLParseError)"; } -}; - -class ExCLParseErrorMisc : public ExCLParseError { - public: - ExCLParseErrorMisc(const string &s) - : _msg("(ExCLParseError) ") - { _msg += s; } - virtual ~ExCLParseErrorMisc() throw() {} - virtual string description() const - { return _msg; } - private: - string _msg; -}; - -class ExCLParseErrorBadIdentifier : public ExCLParseError { - public: - ExCLParseErrorBadIdentifier(const string &id) - : _msg("(ExCLParseErrorBadIdentifier) Did not recognize identifier '") - { - _msg += id; - _msg += "'"; - } - virtual ~ExCLParseErrorBadIdentifier() throw() {} - virtual string description() const - { return _msg; } - private: - string _msg; -}; - -class ExCLRequiredFailureWithExplanation : public ExCLRequiredFailure -{ -public: - virtual ~ExCLRequiredFailureWithExplanation() throw() {} - virtual string description() const - { return "(ExCLRequiredFailureWithExplanation) A required constraint cannot be satisfied"; } - virtual void AddConstraint(const ClConstraint *cnExpl) - { _explanation.insert(cnExpl); } - virtual const ClConstraintSet & explanation() const - { return _explanation; } -protected: - ClConstraintSet _explanation; -}; - -#endif // ClErrors_H diff --git a/libs/cassowary/cassowary/ClFDBinaryOneWayConstraint.h b/libs/cassowary/cassowary/ClFDBinaryOneWayConstraint.h deleted file mode 100644 index a779ec1f91..0000000000 --- a/libs/cassowary/cassowary/ClFDBinaryOneWayConstraint.h +++ /dev/null @@ -1,94 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClFDBinaryOneWayConstraint.h - -#ifndef ClFDBinaryOneWayConstraint_H -#define ClFDBinaryOneWayConstraint_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClFDConstraint.h" - -class ClLinearConstraint; - -// Just a node in the class hierarchy for now -class ClFDBinaryOneWayConstraint : public ClFDConstraint { - private: typedef ClFDConstraint super; - - public: - - ClFDBinaryOneWayConstraint(ClVariable vRW, enum ClCnRelation rel, ClVariable vRO, - double coefficient = 1.0, double constant = 0.0, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) - : ClFDConstraint(strength,weight), _vRW(vRW), _rel(rel), _vRO(vRO), - _coefficient(coefficient), _constant(constant) - { } - - ClFDBinaryOneWayConstraint(ClVariable vRW, enum ClCnRelation rel, double constant, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) - : ClFDConstraint(strength,weight), _vRW(vRW), _rel(rel), _vRO(clvNil), - _coefficient(0), _constant(constant) - { } - - ClFDBinaryOneWayConstraint(const ClConstraint &cn); - - static void EnsurePreconditionsForCn(const ClConstraint &cn); - - static bool FCanConvertCn(const ClConstraint &cn); - -#ifndef CL_NO_IO - virtual ostream &PrintOn(ostream &xo) const - { - xo << "FDCn: " << _vRW << " " << StrCnRelation(_rel) << " "; - if (_coefficient != 0) { - if (_coefficient != 1) xo << _coefficient << "*"; - if (_vRO != clvNil) xo << _vRO; - } - if (_constant != 0) xo << " + " << _constant; - return xo; - } - - friend ostream& operator<<(ostream &xos, const ClFDBinaryOneWayConstraint &constraint) - { return constraint.PrintOn(xos); } - -#endif - - ClVariable ClvRW() const - { return _vRW; } - ClVariable ClvRO() const - { return _vRO; } - enum ClCnRelation Relation() const - { return _rel; } - double Coefficient() const - { return _coefficient; } - double Constant() const - { return _constant; } - - bool IsInequality() const - { return (_rel != cnEQ && _rel != cnNEQ); } - - bool IsStrictInequality() const - { return (_rel == cnGT || _rel == cnLT); } - - protected: - ClVariable _vRW; - enum ClCnRelation _rel; - ClVariable _vRO; - double _coefficient; - double _constant; -}; - -#endif diff --git a/libs/cassowary/cassowary/ClFDConnectorVariable.h b/libs/cassowary/cassowary/ClFDConnectorVariable.h deleted file mode 100644 index 4ae38ae42e..0000000000 --- a/libs/cassowary/cassowary/ClFDConnectorVariable.h +++ /dev/null @@ -1,89 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClFDConnectorVariable.h - -#ifndef ClFDConnectorVariable_H -#define ClFDConnectorVariable_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include -#include -#include -#include -#include "Cassowary.h" -#include "ClVariable.h" -#include "ClFDVariable.h" -#include "ClLinearEquation.h" -#include "ClSimplexSolver.h" - -/* Creates a new variable in the FD region - that sets clvFloat in solver (simplex region) - when it changes */ -class ClFDConnectorVariable : public ClFDVariable { -public: - typedef ClFDVariable super; - - ClFDConnectorVariable(string name, FDNumber Value, const list &initial_domain, - ClSimplexSolver &solver, ClVariable clvFloat) : - ClFDVariable(name,Value,initial_domain), - _solver(solver), - _clvFloat(clvFloat), - _pcnRequiredLink(new ClLinearEquation(clvFloat,Value)) - { solver.AddConstraint(_pcnRequiredLink); } - -#ifndef CL_NO_IO - // Prints a semi-descriptive representation to the stream, using the - // name if there is one, and otherwise the hash number of this - // object. - // EXAMPLE - // [x:10.0] -- name = "x", Value = 10.0 - virtual ostream &PrintOn(ostream &xo) const; -#endif - - // permit overriding in subclasses in case something needs to be - // done when the Value is changed by the solver - // may be called when the Value hasn't actually changed -- just - // means the solver is setting the external variable - virtual void ChangeValue(FDNumber Value) - { - if (_value != Value) { - _value = Value; - cerr << "Updating " << _clvFloat << " now!" << endl; - _solver.RemoveConstraint(_pcnRequiredLink); - _pcnRequiredLink->ChangeConstant(_value); - _solver.AddConstraint(_pcnRequiredLink); - } - } - -private: - - // similar to SetValue -- see caveat above -- made private for now - // since it's probably the wrong thing and is too easy to invoke - FDNumber operator=(FDNumber Value) - { _value = Value; return Value; } - - // Copy constructor left undefined since we want to - // outlaw passing by Value! Will get a link error if you - // try to use within ClFDConnectorVariable.c, compile-time error everywhere else - ClFDConnectorVariable(const ClFDConnectorVariable &); - - ClSimplexSolver &_solver; - - ClVariable _clvFloat; - - ClLinearEquation *_pcnRequiredLink; - -}; - -#endif diff --git a/libs/cassowary/cassowary/ClFDConstraint.h b/libs/cassowary/cassowary/ClFDConstraint.h deleted file mode 100644 index 2cf9776449..0000000000 --- a/libs/cassowary/cassowary/ClFDConstraint.h +++ /dev/null @@ -1,40 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClFDConstraint.h - -#ifndef ClFDConstraint_H -#define ClFDConstraint_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClConstraint.h" - - -// Just a node in the class hierarchy for now -class ClFDConstraint : public ClConstraint { - private: typedef ClConstraint super; - - public: - // Constructor - ClFDConstraint(const ClStrength &strength = ClsRequired(), - double weight = 1.0) - : ClConstraint(strength, weight) { } - - virtual bool FIsOkayForSimplexSolver() const { return false; } - - protected: - -}; - -#endif diff --git a/libs/cassowary/cassowary/ClFDSolver.h b/libs/cassowary/cassowary/ClFDSolver.h deleted file mode 100644 index 2fbb637764..0000000000 --- a/libs/cassowary/cassowary/ClFDSolver.h +++ /dev/null @@ -1,120 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClSolver.h - -#ifndef ClFDSolver_H -#define ClFDSolver_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClSolver.h" -#include "ClVariable.h" -#include "ClErrors.h" -#include "ClTypedefs.h" -#include "ClSymbolicWeight.h" -#include -#include - -using std::map; - -class ClVariable; -class ClFDBinaryOneWayConstraint; - -// ClFDSolver is a concrete class -// implementing a very restricted (for now --04/23/99 gjb) -// finite-domain constraint solving algorithm -class ClFDSolver: public ClSolver { - public: - ClFDSolver() - : _setCns(), _mapClvToCns(), G(), nodeToVar(G) - { G.make_directed(); } - - virtual ~ClFDSolver() - { } - - virtual ClFDSolver &AddConstraint(ClConstraint *const pcn); - - virtual ClFDSolver &RemoveConstraint(ClConstraint *const pcn); - - virtual ClFDSolver &Solve(); - - virtual ClFDSolver &ShowSolve(); - - void ChangeClv(ClVariable clv, FDNumber n) { - clv.ChangeValue(n); - if (_pfnChangeClvCallback) { - _pfnChangeClvCallback(&clv,this); - } - } - - -#ifndef CL_NO_IO - ostream &PrintOn(ostream &xo) const; - - ostream &PrintInternalInfo(ostream &xo) const; - - ostream &PrintOnVerbose(ostream &xo) const - { PrintOn(xo); PrintInternalInfo(xo); xo << endl; return xo; } - - friend ostream &operator<<(ostream &xo, const ClFDSolver &solver); - -#endif - - protected: - - virtual ClFDSolver &AddConstraintInternal(ClConstraint *const pcn); - - virtual ClFDSolver &RemoveConstraintInternal(ClConstraint *const pcn); - - /* Create node for v in G, if necessary, - otherwise return the node we already created. */ - node GetVarNode(ClVariable v); - - /* return the best (lowest) incremental error and the value - at which that error occurs */ - pair ComputeBest(ClFDVariable *pcldv); - - ClSymbolicWeight ErrorForClvAtValSubjectToCn(ClFDVariable *pcldv, - FDNumber value,const ClConstraint &cn); - - /* Turn all FDVariable FIsSet() flags to false */ - void ResetSetFlagsOnVariables(); - - /* all the constraints in the solver */ - ClConstraintSet _setCns; - - /* _mapClvToCns maps variable to the constraints in which - it is rw (it omits where it is ro) */ - ClVarToConstraintSetMap _mapClvToCns; - - /* track what edges correspond to which constraints - so we can update the constraint graph when - removing a constraint */ - map _mapCnToEdge; - - /* track what nodes correspond to which variables */ - map _mapVarToNode; - - /* directed graph that mirrors the structure of - the relations of the added constraints */ - graph G; - - node_map nodeToVar; -}; - -#define FDN_EOL LONG_MIN - -void ListPushOnto(list *pl, ...); - -#endif diff --git a/libs/cassowary/cassowary/ClFDVariable.h b/libs/cassowary/cassowary/ClFDVariable.h deleted file mode 100644 index 326b339459..0000000000 --- a/libs/cassowary/cassowary/ClFDVariable.h +++ /dev/null @@ -1,126 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClFDVariable.h - -#ifndef ClFDVariable_H -#define ClFDVariable_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include -#include -#include -#include -#include "Cassowary.h" -#include "ClAbstractVariable.h" - -using std::map; -using std::list; -using std::string; - -class ClFDVariable : public ClAbstractVariable { -public: - typedef ClAbstractVariable super; - -#if 0 /* GJB:FIXME:: */ - ClFDVariable(string name, FDNumber Value) : - ClAbstractVariable(name), - _value(Value), - _fSet(true), - _desired_value(Value), - _plfdnInitialDomain(0) - { } -#endif - - ClFDVariable(string name, FDNumber Value, const list &initial_domain) : - ClAbstractVariable(name), - _value(Value), - _fSet(true), - _desired_value(Value), - _plfdnInitialDomain(new list()) - { - *_plfdnInitialDomain = initial_domain; - } - - virtual bool IsFDVariable() const - { return true; } - - // Return true if this a variable known outside the solver. - // (We need to give such variables a Value after solving is complete.) - virtual bool IsExternal() const - { return true; } - -#ifndef CL_NO_IO - // Prints a semi-descriptive representation to the stream, using the - // name if there is one, and otherwise the hash number of this - // object. - // EXAMPLE - // [x:10.0] -- name = "x", Value = 10.0 - virtual ostream &PrintOn(ostream &xo) const; -#endif - - // Return the current Value I hold. - Number Value() const - { return _value; } - - // Round the Value to an integer and return it - int IntValue() const - { return _value; } - - // change the Value held -- should *not* use this if the variable is - // in a solver -- instead use AddEditVar() and SuggestValue() interface - void SetValue(FDNumber Value) - { _value = Value; } - - // permit overriding in subclasses in case something needs to be - // done when the Value is changed by the solver - // may be called when the Value hasn't actually changed -- just - // means the solver is setting the external variable - virtual void ChangeValue(FDNumber Value) - { _value = Value; } - - virtual bool FIsSet() - { return _fSet; } - - virtual void SetFIsSet(bool f) - { _fSet = f; } - - virtual FDNumber DesiredValue() const - { return _desired_value; } - - virtual const list *PlfdnDomain() const - { return _plfdnInitialDomain; } - -protected: - - // similar to SetValue -- see caveat above -- made private for now - // since it's probably the wrong thing and is too easy to invoke - FDNumber operator=(FDNumber Value) - { _value = Value; return Value; } - - // Copy constructor left undefined since we want to - // outlaw passing by Value! Will get a link error if you - // try to use within ClFDVariable.c, compile-time error everywhere else - ClFDVariable(const ClFDVariable &); - - FDNumber _value; - - // has the _value been set? Used during solves. - bool _fSet; - - FDNumber _desired_value; - - list *_plfdnInitialDomain; -}; - -#endif diff --git a/libs/cassowary/cassowary/ClFloatVariable.h b/libs/cassowary/cassowary/ClFloatVariable.h deleted file mode 100644 index 4e58036ab7..0000000000 --- a/libs/cassowary/cassowary/ClFloatVariable.h +++ /dev/null @@ -1,119 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClFloatVariable.h - -#ifndef ClFloatVariable_H -#define ClFloatVariable_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include -#include -#include -#include "Cassowary.h" -#include "ClAbstractVariable.h" - -using std::map; -using std::string; - -class ClFloatVariable : public ClAbstractVariable { -public: - typedef ClAbstractVariable super; - - ClFloatVariable(string name, Number Value = 0.0) : - ClAbstractVariable(name), - _value(Value) - { } - - ClFloatVariable(Number Value = 0.0) : - ClAbstractVariable(""), - _value(Value) - { } - - ClFloatVariable(long number, char *prefix, Number Value = 0.0) : - ClAbstractVariable(number,prefix), - _value(Value) - { } - - virtual bool IsFloatVariable() const - { return true; } - - // Return true if this a dummy variable (used as a marker variable - // for required equality constraints). Such variables aren't - // allowed to enter the basis when pivoting. - virtual bool IsDummy() const - { return false; } - - // Return true if this a variable known outside the solver. - // (We need to give such variables a Value after solving is complete.) - virtual bool IsExternal() const - { return true; } - - // Return true if we can Pivot on this variable. - virtual bool IsPivotable() const - { return false; } - - // Return true if this is a restricted (or slack) variable. Such - // variables are constrained to be non-negative and occur only - // internally to the simplex solver. - virtual bool IsRestricted() const - { return false; } - -#ifndef CL_NO_IO - // Prints a semi-descriptive representation to the stream, using the - // name if there is one, and otherwise the hash number of this - // object. - // EXAMPLE - // [x:10.0] -- name = "x", Value = 10.0 - virtual ostream &PrintOn(ostream &xo) const; -#endif - - // Return the current Value I hold. - Number Value() const - { return _value; } - - // Round the Value to an integer and return it - int IntValue() const - { return int(_value + 0.5); } - - // change the Value held -- should *not* use this if the variable is - // in a solver -- instead use AddEditVar() and SuggestValue() interface - void SetValue(Number Value) - { _value = Value; } - - // permit overriding in subclasses in case something needs to be - // done when the Value is changed by the solver - // may be called when the Value hasn't actually changed -- just - // means the solver is setting the external variable - virtual void ChangeValue(Number Value) - { _value = Value; } - -private: - - // similar to SetValue -- see caveat above -- made private for now - // since it's probably the wrong thing and is too easy to invoke - Number operator=(Number Value) - { _value = Value; return Value; } - - // Copy constructor left undefined since we want to - // outlaw passing by Value! Will get a link error if you - // try to use within ClFloatVariable.c, compile-time error everywhere else - ClFloatVariable(const ClFloatVariable &); - - Number _value; - -}; - - - -#endif diff --git a/libs/cassowary/cassowary/ClLinearConstraint.h b/libs/cassowary/cassowary/ClLinearConstraint.h deleted file mode 100644 index d657d1d73e..0000000000 --- a/libs/cassowary/cassowary/ClLinearConstraint.h +++ /dev/null @@ -1,61 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClLinearConstraint.h - -#ifndef ClLinearConstraint_H -#define ClLinearConstraint_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClConstraint.h" -#include "ClLinearExpression.h" - - -// Add the ClLinearExpression member variable needed for both -// ClLinearEquation and ClLinearInequality -class ClLinearConstraint : public ClConstraint { - private: typedef ClConstraint super; - - public: - - // Constructor - ClLinearConstraint(const ClLinearExpression &cle, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) : - ClConstraint(strength, weight), - _expression(cle) - { } - - virtual ~ClLinearConstraint() {} - - // Return my linear Expression. (For linear equations, this - // constraint represents Expression=0; for linear inequalities it - // represents Expression>=0.) - ClLinearExpression Expression() const - { return _expression; } - - // do not do this if *this is inside a solver - void ChangeConstant(Number constant) - { _expression.Set_constant(constant); } - - protected: - - ClLinearExpression _expression; - - virtual void setExpression( const ClLinearExpression &expr) - { _expression = expr; } - -}; - -#endif diff --git a/libs/cassowary/cassowary/ClLinearEquation.h b/libs/cassowary/cassowary/ClLinearEquation.h deleted file mode 100644 index a02b51d70b..0000000000 --- a/libs/cassowary/cassowary/ClLinearEquation.h +++ /dev/null @@ -1,74 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClLinearEquation.h - -#ifndef ClLinearEquation_H -#define ClLinearEquation_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClLinearConstraint.h" -#include "ClLinearExpression.h" - -class ClStrength; -class ClVariable; - -class ClLinearEquation : public ClLinearConstraint { - private: typedef ClLinearConstraint super; - - public: - //// Constructors - - // ClLinearEquation(expr,...) is expr == 0 - ClLinearEquation(const ClLinearExpression &cle, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) : - ClLinearConstraint(cle,strength, weight) - { } - - // ClLinearEquation(var,expr,...) is var == expr - ClLinearEquation(ClVariable clv, - const ClLinearExpression &cle, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) : - ClLinearConstraint(cle,strength,weight) - { _expression.AddVariable(clv,-1.0); } - - // ClLinearEquation(expr,var,...) is var == expr - ClLinearEquation(const ClLinearExpression &cle, - ClVariable clv, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) : - ClLinearConstraint(cle,strength,weight) - { _expression.AddVariable(clv,-1.0); } - - // ClLinearEquation(expr,expr,...) is expr == expr - ClLinearEquation(const ClLinearExpression &cle1, - const ClLinearExpression &cle2, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) : - ClLinearConstraint(cle1,strength,weight) - { _expression.AddExpression(cle2,-1.0); } - -#ifndef CL_NO_IO - virtual ostream &PrintOn(ostream &xo) const - { super::PrintOn(xo); xo << " = 0 )"; return xo; } -#endif - - virtual bool FIsSatisfied() const - { return (_expression.Evaluate() == 0); } - -}; - -#endif diff --git a/libs/cassowary/cassowary/ClLinearExpression.h b/libs/cassowary/cassowary/ClLinearExpression.h deleted file mode 100644 index 0a1df9c243..0000000000 --- a/libs/cassowary/cassowary/ClLinearExpression.h +++ /dev/null @@ -1,298 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClLinearExpression.h - -#ifndef ClLinearExpression_H -#define ClLinearExpression_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "debug.h" -#include "ClVariable.h" -#include "ClLinearExpression_fwd.h" - -class ClSimplexSolver; -class ClTableau; -class ClSymbolicWeight; - -ClLinearExpression &cleNil(); - -template -class ClGenericLinearExpression { - public: - typedef std::map ClVarToCoeffMap; - - // convert Number-s into ClLinearExpression-s - ClGenericLinearExpression(T num = 0.0); - - // Convert from ClVariable to a ClLinearExpression - // this replaces ClVariable::asLinearExpression - ClGenericLinearExpression(ClVariable clv, T value = 1.0, T constant = 0.0); - - // copy ctr - ClGenericLinearExpression(const ClGenericLinearExpression &expr) : - _constant(expr._constant), - _terms(expr._terms) - { } - - virtual ~ClGenericLinearExpression(); - - // Return a new linear expression formed by multiplying self by x. - // (Note that this result must be linear.) - ClGenericLinearExpression Times(Number x) const; - - // Return a new linear expression formed by multiplying self by x. - // (Note that this result must be linear.) - ClGenericLinearExpression Times(const ClGenericLinearExpression &expr) const; - - // Return a new linear expression formed by adding x to self. - ClGenericLinearExpression Plus(const ClGenericLinearExpression &expr) const; - - // Return a new linear expression formed by subtracting x from self. - ClGenericLinearExpression Minus(const ClGenericLinearExpression &expr) const; - - // Return a new linear expression formed by dividing self by x. - // (Note that this result must be linear.) - ClGenericLinearExpression Divide(Number x) const; - - - - // Return a new linear expression formed by multiplying self by x. - // (Note that this result must be linear.) - ClGenericLinearExpression *P_times(Number x) const - { return new ClGenericLinearExpression(Times(x)); } - - // Return a new linear expression formed by adding x to self. - ClGenericLinearExpression *P_plus(const ClGenericLinearExpression &expr) const - { return new ClGenericLinearExpression(Plus(expr)); } - - // Return a new linear expression formed by subtracting x from self. - ClGenericLinearExpression *P_minus(const ClGenericLinearExpression &expr) const - { return new ClGenericLinearExpression(Minus(expr)); } - - // Return a new linear expression formed by dividing self by x. - // (Note that this result must be linear.) - ClGenericLinearExpression *P_divide(Number x) const - { return new ClGenericLinearExpression(Divide(x)); } - - // Return a new linear expression formed by dividing self by x. - // (Note that this result must be linear.) - ClGenericLinearExpression Divide(const ClGenericLinearExpression &expr) const; - - // Return a new linear expression (aNumber/this). Since the result - // must be linear, this is permissible only if 'this' is a constant. - ClGenericLinearExpression DivFrom(const ClGenericLinearExpression &expr) const; - - // Return a new linear expression (aNumber-this). - ClGenericLinearExpression SubtractFrom(const ClGenericLinearExpression &expr) const - { return expr.Minus(*this); } - - // Add n*expr to this expression from another expression expr. - ClGenericLinearExpression &AddExpression(const ClGenericLinearExpression &expr, - Number n = 1.0); - - // Add n*expr to this expression from another expression expr. - // Notify the solver if a variable is added or deleted from this - // expression. - ClGenericLinearExpression &AddExpression(const ClGenericLinearExpression &expr, Number n, - ClVariable subject, - ClTableau &solver); - - // Add a term c*v to this expression. If the expression already - // contains a term involving v, Add c to the existing coefficient. - // If the new coefficient is approximately 0, delete v. - ClGenericLinearExpression &AddVariable(ClVariable v, T c = 1.0); - - // Add a term c*v to this expression. If the expression already - // contains a term involving v, Add c to the existing coefficient. - // If the new coefficient is approximately 0, delete v. - ClGenericLinearExpression &setVariable(ClVariable v, T c) - {assert(c != 0.0); _terms[v] = c; return *this; } - - // Add a term c*v to this expression. If the expression already - // contains a term involving v, Add c to the existing coefficient. - // If the new coefficient is approximately 0, delete v. Notify the - // solver if v appears or disappears from this expression. - ClGenericLinearExpression &AddVariable(ClVariable v, T c, - ClVariable subject, - ClTableau &solver); - - // Return a pivotable variable in this expression. (It is an error - // if this expression is constant -- signal ExCLInternalError in - // that case). Return NULL if no pivotable variables - ClVariable AnyPivotableVariable() const; - - // Replace var with a symbolic expression expr that is equal to it. - // If a variable has been added to this expression that wasn't there - // before, or if a variable has been dropped from this expression - // because it now has a coefficient of 0, inform the solver. - // PRECONDITIONS: - // var occurs with a non-Zero coefficient in this expression. - void SubstituteOut(ClVariable v, - const ClGenericLinearExpression &expr, - ClVariable subject, - ClTableau &solver); - - // This linear expression currently represents the equation - // oldSubject=self. Destructively modify it so that it represents - // the equation NewSubject=self. - // - // Precondition: NewSubject currently has a nonzero coefficient in - // this expression. - // - // NOTES - // Suppose this expression is c + a*NewSubject + a1*v1 + ... + an*vn. - // - // Then the current equation is - // oldSubject = c + a*NewSubject + a1*v1 + ... + an*vn. - // The new equation will be - // NewSubject = -c/a + oldSubject/a - (a1/a)*v1 - ... - (an/a)*vn. - // Note that the term involving NewSubject has been dropped. - void ChangeSubject(ClVariable old_subject, - ClVariable new_subject); - - // This linear expression currently represents the equation self=0. Destructively modify it so - // that subject=self represents an equivalent equation. - // - // Precondition: subject must be one of the variables in this expression. - // NOTES - // Suppose this expression is - // c + a*subject + a1*v1 + ... + an*vn - // representing - // c + a*subject + a1*v1 + ... + an*vn = 0 - // The modified expression will be - // subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn - // representing - // subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn - // - // Note that the term involving subject has been dropped. - // Returns the reciprocal, so ChangeSubject can use it, too - T NewSubject(ClVariable subject); - - // Return the value of the linear expression - // given the current assignments of values to contained variables - T Evaluate() const; - - // Return the coefficient corresponding to variable var, i.e., - // the 'ci' corresponding to the 'vi' that var is: - // v1*c1 + v2*c2 + .. + vn*cn + c - T CoefficientFor(ClVariable var) const - { - typename ClVarToCoeffMap::const_iterator it = _terms.find(var); - if (it != _terms.end()) - return (*it).second; - return 0.0; - } - - T Constant() const - { return _constant; } - - void Set_constant(T c) - { _constant = c; } - - const ClVarToCoeffMap &Terms() const - { return _terms; } - - ClVarToCoeffMap &Terms() - { return _terms; } - - void IncrementConstant(T c) - { _constant += c; } - - bool IsConstant() const - { return _terms.size() == 0; } - -#ifndef CL_NO_IO - virtual ostream &PrintOn(ostream &xo) const; - - friend ostream &operator<<(ostream &xo,const ClGenericLinearExpression &cle) - { return cle.PrintOn(xo); } -#endif - - friend ClGenericLinearExpression operator+(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return e1.Plus(e2); } - - friend ClGenericLinearExpression operator-(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return e1.Minus(e2); } - - friend ClGenericLinearExpression operator*(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return e1.Times(e2); } - - - friend ClGenericLinearExpression operator/(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return e1.Divide(e2); } - - // FIXGJB -- this may be wrong -- should test underlying expression for equality - friend bool operator==(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return &e1 == &e2; } - - /// Named versions of the operator functions for ease of - /// wrapping, or expressing using prefix notation - - friend ClGenericLinearExpression Plus(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return e1.Plus(e2); } - - friend ClGenericLinearExpression Minus(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return e1.Minus(e2); } - - friend ClGenericLinearExpression Times(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return e1.Times(e2); } - - - friend ClGenericLinearExpression *Divide(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return new ClGenericLinearExpression(e1.Divide(e2)); } - - friend ClGenericLinearExpression *p_Plus(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return new ClGenericLinearExpression(e1.Plus(e2)); } - - friend ClGenericLinearExpression *p_Minus(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return new ClGenericLinearExpression(e1.Minus(e2)); } - - friend ClGenericLinearExpression *p_Times(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return new ClGenericLinearExpression(e1.Times(e2)); } - - friend ClGenericLinearExpression *p_Divide(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return new ClGenericLinearExpression(e1.Divide(e2)); } - - - // FIXGJB -- this may be wrong -- should test underlying expression for equality - friend bool FEquals(const ClGenericLinearExpression &e1, - const ClGenericLinearExpression &e2) - { return &e1 == &e2; } - - ClGenericLinearExpression &MultiplyMe(T x); - - private: - - T _constant; - ClVarToCoeffMap _terms; - -}; - -typedef ClGenericLinearExpression::ClVarToCoeffMap ClVarToNumberMap; - -#endif diff --git a/libs/cassowary/cassowary/ClLinearExpression_fwd.h b/libs/cassowary/cassowary/ClLinearExpression_fwd.h deleted file mode 100644 index 99b48557ec..0000000000 --- a/libs/cassowary/cassowary/ClLinearExpression_fwd.h +++ /dev/null @@ -1,26 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClLinearExpression.h - -#ifndef ClLinearExpression_fwd_H -#define ClLinearExpression_fwd_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" - -template class ClGenericLinearExpression; -typedef ClGenericLinearExpression ClLinearExpression; -typedef ClLinearExpression* PClLinearExpression; - -#endif diff --git a/libs/cassowary/cassowary/ClLinearInequality.h b/libs/cassowary/cassowary/ClLinearInequality.h deleted file mode 100644 index 017c4b819e..0000000000 --- a/libs/cassowary/cassowary/ClLinearInequality.h +++ /dev/null @@ -1,167 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClLinearInequality.h - -#ifndef ClLinearInequality_H -#define ClLinearInequality_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "ClConstraint.h" -#include "ClLinearConstraint.h" - -class ClVariable; - -class ClLinearInequality : public ClLinearConstraint { - private: typedef ClLinearConstraint super; - - public: - //// Constructors - // ClLinearInequality(expr,...) is expr >= 0 - ClLinearInequality(const ClLinearExpression &cle, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) : - ClLinearConstraint(cle,strength, weight), - _fStrictInequality(false) - { } - - // ClLinearInequality(var,OP,expr) is var >= expr - ClLinearInequality(const ClVariable clv, - enum ClCnRelation op, - const ClLinearExpression &cle, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) : - ClLinearConstraint( cle, strength, weight), - _fStrictInequality(false) - { - if (op == cnGEQ || op == cnGT) - { - _expression.MultiplyMe(-1.0); - _expression.AddVariable(clv,1.0); - } - else if (op == cnLEQ || op == cnGEQ) - { - _expression.AddVariable(clv,-1.0); - } - else - { - throw ExCLEditMisuse("Cannot use that operator for ClLinearInequality objects"); - } - if (op == cnLT || op == cnGT) { - _fStrictInequality = true; - } - } - -#ifdef FIXGJB_AMBIGUOUS - // ClLinearInequality(expr,OP,var) is var ?<>? expr - ClLinearInequality(const ClLinearExpression &cle, - enum ClCnRelation op, - const ClVariable clv, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) : - ClLinearConstraint( cle, strength, weight), - _fStrictInequality(false) - { - if (op == cnLEQ || op == cnLT) - { - _expression.MultiplyMe(-1.0); - _expression.AddVariable(clv,1.0); - } - else if (op == cnGEQ || op == cnGT) - { - _expression.AddVariable(clv,-1.0); - } - if (op == cnLT || op == cnGT) { - _fStrictInequality = true; - } - } -#endif - - // ClLinearInequality(expr,OP,expr) is expr >= expr - ClLinearInequality(const ClLinearExpression &cle1, - enum ClCnRelation op, - const ClLinearExpression &cle2, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) : - ClLinearConstraint( cle2, strength, weight), - _fStrictInequality(false) - { - if (op == cnGEQ || op == cnGT) - { - _expression.MultiplyMe(-1.0); - _expression.AddExpression(cle1); - } - else if (op == cnLEQ || op == cnLT) - { - _expression.AddExpression(cle1,-1.0); - } - if (op == cnLT || op == cnGT) { - _fStrictInequality = true; - } - } - -#ifdef FIXGJB_AMBIGUOUS - // ClLinearInequality(var,OP,var) is var ?<>? var - ClLinearInequality(const ClVariable clv1, - enum ClCnRelation op, - const ClVariable clv2, - const ClStrength &strength = ClsRequired(), - double weight = 1.0) : - ClLinearConstraint( clv2, strength, weight), - _fStrictInequality(false) - { - if (op == cnGEQ || op == cnGT) - { - _expression.MultiplyMe(-1.0); - _expression.AddVariable(clv1,1.0); - } - else if (op == cnLEQ || op == cnLT) - { - _expression.AddVariable(clv1,-1.0); - } - if (op == cnLT || op == cnGT) { - _fStrictInequality = true; - } - } -#endif - - - // Return true if this is an inequality constraint and - // false if it is an equality constraint. The default is - // that it is not. - virtual bool IsInequality() const - { return true; } - - virtual bool IsStrictInequality() const - { return _fStrictInequality; } - -#ifndef CL_NO_IO - virtual ostream &PrintOn(ostream &xo) const - { super::PrintOn(xo); xo << " >= 0 )"; return xo; } -#endif - - virtual bool FIsSatisfied() const - { - Number v = _expression.Evaluate(); - if (_fStrictInequality) - return (v > 0); - else - return (v >= 0); - } - - private: - - bool _fStrictInequality; -}; - -#endif diff --git a/libs/cassowary/cassowary/ClObjectiveVariable.h b/libs/cassowary/cassowary/ClObjectiveVariable.h deleted file mode 100644 index 664e2d65a4..0000000000 --- a/libs/cassowary/cassowary/ClObjectiveVariable.h +++ /dev/null @@ -1,63 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClObjectiveVariable.h - -#ifndef ClObjectiveVariable_H -#define ClObjectiveVariable_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClAbstractVariable.h" - -class ClTableau; -class ClSimplexSolver; - -class ClObjectiveVariable : public ClAbstractVariable { -protected: - friend class ClTableau; - friend class ClSimplexSolver; - - ClObjectiveVariable(string name = "") : - ClAbstractVariable(name) - { } - - ClObjectiveVariable(long number, char *prefix) : - ClAbstractVariable(number,prefix) - { } - -#ifndef CL_NO_IO - virtual ostream &PrintOn(ostream &xo) const - { - xo << "[" << Name() << ":obj]"; - return xo; - } -#endif - - // We don't need to give such variables a Value after solving is complete. - virtual bool IsExternal() const - { return false; } - - // Return true if we can Pivot on this variable. - virtual bool IsPivotable() const - { return false; } - - // Return true if this is a restricted (or slack) variable. Such - // variables are constrained to be non-negative and occur only - // internally to the simplex solver. - virtual bool IsRestricted() const - { return false; } - -}; - -#endif diff --git a/libs/cassowary/cassowary/ClPoint.h b/libs/cassowary/cassowary/ClPoint.h deleted file mode 100644 index 15139aa73b..0000000000 --- a/libs/cassowary/cassowary/ClPoint.h +++ /dev/null @@ -1,74 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClPoint.h - -#ifndef ClPoint_H -#define ClPoint_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClVariable.h" - -// ClPoint is just a convenience class for pairs of -// ClVariables -- often useful for coordinate pairs in 2-space -class ClPoint { - public: - ClPoint(Number x, Number y) - : _clv_x(x), _clv_y(y) - { } - - ClPoint() - { } - - ClVariable X() - { return _clv_x; } - - ClVariable Y() - { return _clv_y; } - - const ClVariable X() const - { return _clv_x; } - - const ClVariable Y() const - { return _clv_y; } - - void SetXY(Number x, Number y) - { _clv_x.SetValue(x); _clv_y.SetValue(y); } - - Number Xvalue() const - { return X().Value(); } - - Number Yvalue() const - { return Y().Value(); } - - private: - ClVariable _clv_x; - ClVariable _clv_y; - -#ifndef CL_NO_IO - friend ostream &operator<<(ostream &xo, const ClPoint &clp); -#endif - -}; - -#ifndef CL_NO_IO -inline ostream & -operator<<(ostream &xo, const ClPoint &clp) -{ - xo << "(" << clp._clv_x << ", " << clp._clv_y << ")"; - return xo; -} -#endif - -#endif diff --git a/libs/cassowary/cassowary/ClReader.h b/libs/cassowary/cassowary/ClReader.h deleted file mode 100644 index 4eef907759..0000000000 --- a/libs/cassowary/cassowary/ClReader.h +++ /dev/null @@ -1,120 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClReader.h -// Original implementation contributed by Steve Wolfman -// Subsequently largely revised by Greg J. Badros - -#ifndef CREADER_H -#define CREADER_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include -#include -#include -#include -#include "ClErrors.h" -#include "ClVariable.h" -#include "ClStrength.h" -#include "ClLinearExpression_fwd.h" - -using std::string; -using std::istream; - -class ClConstraint; - -class ClVarLookupFunction : public std::unary_function { -public: - virtual ~ClVarLookupFunction () {}; - virtual ClVariable *operator()(const string &) const { return &clvNil; } -}; - - -// Attempts to read a constraint of input stream in -// Returns constraint (freshly allocated, client responsibility to deallocate) -// if succesful. Otherwise, returns 0. -ClConstraint *PcnParseConstraint(istream &xi, const ClVarLookupFunction &lookup_func, - const ClStrength &strength = ClsRequired()); - -class ClVarLookupInMap : public ClVarLookupFunction { -public: - ClVarLookupInMap(StringToVarMap *pmapVars, bool fAutoCreate) - : _pmapVars(pmapVars), _fAutoCreate(fAutoCreate) { } - - virtual ~ClVarLookupInMap () {}; - - ClVariable *operator()(const string &str) const - { - if (!_pmapVars) - return &clvNil; - StringToVarMap &_mapVars = *_pmapVars; - StringToVarMap::iterator it = _mapVars.find(str); - if (it != _mapVars.end()) { - return &it->second; - } else if (_fAutoCreate) { - // save the old symbol table, if any - StringToVarMap *pmapOld = ClVariable::VarMap(); - // and set it to this one temporarily - ClVariable::SetVarMap(&_mapVars); - ClVariable *pclv = new ClVariable(str); - // now switch it back - ClVariable::SetVarMap(pmapOld); - return pclv; - } else { - return &clvNil; - } - } -private: - StringToVarMap *_pmapVars; - bool _fAutoCreate; -}; - - -/* the "yyerror" function */ -void clerror(const char *sz); - -struct ClParseData { - ClParseData(istream &xi, const ClVarLookupFunction &lookup_func) - : _xi(xi), _lookup_func(lookup_func) { } - - ClConstraint *Pcn() { return _pcn; } - - ClVarSet _readOnlyVarsSoFar; - - istream & _xi; - ClConstraint * _pcn; - const ClVarLookupFunction &_lookup_func; -}; - - -inline -const ClStrength -&ClsFromSz(const char *sz) -{ - const ClStrength *pcls = &ClsRequired(); - double n1, n2, n3; - if (strcmp("required",sz) == 0) - ; /* initialized to ClsRequired, above */ - else if (strcasecmp("strong",sz) == 0) { pcls = &ClsStrong(); } - else if (strcasecmp("medium",sz) == 0) { pcls = &ClsMedium(); } - else if (strcasecmp("weak",sz) == 0) { pcls = &ClsWeak(); } - else if (sscanf(sz,"(%lf,%lf,%lf)",&n1,&n2,&n3) == 3) { - pcls = new ClStrength("parsed",n1,n2,n3); - } else { - throw ExCLParseErrorMisc("Error parsing strength"); - } - return *pcls; -} - - -#endif diff --git a/libs/cassowary/cassowary/ClSimplexSolver.h b/libs/cassowary/cassowary/ClSimplexSolver.h deleted file mode 100644 index c187992728..0000000000 --- a/libs/cassowary/cassowary/ClSimplexSolver.h +++ /dev/null @@ -1,588 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClSimplexSolver.h - -#ifndef ClSimplexSolver_H -#define ClSimplexSolver_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include -#include -#include -#include "Cassowary.h" -#include "ClSolver.h" -#include "ClTableau.h" -#include "ClLinearInequality.h" -#include "ClStrength.h" -#include "ClStayConstraint.h" -#include "ClEditConstraint.h" -#include "ClSlackVariable.h" -#include "ClObjectiveVariable.h" -#include "ClErrors.h" -#include "ClTypedefs.h" - -using std::list; -using std::stack; -using std::ostream; - -class ClVariable; -class ClPoint; -class ExCLRequiredFailureWithExplanation; - - -// ClSimplexSolver encapsulates the solving behaviour -// of the cassowary algorithm -class ClSimplexSolver : public ClSolver, public ClTableau { - protected: - class ClEditInfo; - typedef list ClEditInfoList; - - ClEditInfo *PEditInfoFromClv(ClVariable clv) { - ClEditInfoList::iterator it = _editInfoList.begin(); - for (; it != _editInfoList.end(); ++it) { - ClEditInfo *pei = (*it); - if (pei->_clv == clv) - return pei; - } - return 0; - } - - public: - - // Constructor - ClSimplexSolver() : - ClSolver(), - _objective(ClVariable(new ClObjectiveVariable("Z"))), - _slackCounter(0), - _artificialCounter(0), -#ifdef CL_FIND_LEAK - _cArtificialVarsDeleted(0), -#endif - _dummyCounter(0), - _epsilon(1e-8), - _fResetStayConstantsAutomatically(true), - _fNeedsSolving(false), - _fExplainFailure(false), - _pfnResolveCallback(0), - _pfnCnSatCallback(0) - { - _rows[_objective] = new ClLinearExpression(); - // start out with no edit variables - _stkCedcns.push(0); -#ifdef CL_TRACE - std::cerr << "objective row new@ " << _rows[_objective] << std::endl; -#endif - } - - virtual ~ClSimplexSolver(); - - // Add constraints so that lower<=var<=upper. (nil means no bound.) - ClSimplexSolver &AddLowerBound(ClVariable v, Number lower) - { - ClLinearInequality *pcn = new ClLinearInequality(ClLinearExpression(v - lower)); - return AddConstraint(pcn); - } - ClSimplexSolver &AddUpperBound(ClVariable v, Number upper) - { - ClLinearInequality *pcn = new ClLinearInequality(ClLinearExpression(upper - v)); - return AddConstraint(pcn); - } - ClSimplexSolver &AddBounds(ClVariable v, Number lower, Number upper) - { AddLowerBound(v,lower); AddUpperBound(v,upper); return *this; } - - // Add the constraint cn to the tableau - ClSimplexSolver &AddConstraint(ClConstraint *const pcn); - -#ifndef CL_NO_DEPRECATED - // Deprecated! --02/19/99 gjb - ClSimplexSolver &AddConstraint(ClConstraint &cn) - { return AddConstraint(&cn); } -#endif - - // Add an edit constraint for "v" with given strength - ClSimplexSolver &AddEditVar(const ClVariable v, const ClStrength &strength = ClsStrong(), - double weight = 1.0 ) - { - ClEditConstraint *pedit = new ClEditConstraint(v, strength, weight); - return AddConstraint(pedit); - } - - ClSimplexSolver &RemoveEditVar(ClVariable v) - { - ClEditInfo *pcei = PEditInfoFromClv(v); - if (!pcei) { - throw ExCLEditMisuse("Removing edit variable that was not found"); - } - ClConstraint *pcnEdit = pcei->_pconstraint; - RemoveConstraint(pcnEdit); - delete pcnEdit; - return *this; - } - - // BeginEdit() should be called before sending - // Resolve() messages, after adding the appropriate edit variables - ClSimplexSolver &BeginEdit() - { - if (_editInfoList.size() == 0) { - throw ExCLEditMisuse("BeginEdit called, but no edit variable"); - } - // may later want to do more in here - _infeasibleRows.clear(); - ResetStayConstants(); - _stkCedcns.push(_editInfoList.size()); - return *this; - } - - // EndEdit should be called after editing has finished - // for now, it just removes edit variables added from before the last BeginEdit - ClSimplexSolver &EndEdit() - { - if (_editInfoList.size() == 0) - throw ExCLEditMisuse("EndEdit called but no edit variables"); - Resolve(); - _stkCedcns.pop(); - RemoveEditVarsTo(_stkCedcns.top()); - // may later want to do more in here - return *this; - } - - // RemoveAllEditVars() just eliminates all the edit constraints - // that were added - ClSimplexSolver &RemoveAllEditVars() { RemoveEditVarsTo(0); return *this; } - - // remove the last added edit vars to leave only n edit vars left - ClSimplexSolver &RemoveEditVarsTo(unsigned int n); - - int numEditVars() const - { return _editInfoList.size(); } - - // Add weak stays to the x and y parts of each point. These have - // increasing weights so that the solver will try to satisfy the x - // and y stays on the same point, rather than the x stay on one and - // the y stay on another. - ClSimplexSolver &AddPointStays(const vector &listOfPoints, - const ClStrength &strength = ClsWeak()); - - ClSimplexSolver &AddPointStay(const ClVariable vx, const ClVariable vy, - const ClStrength &strength = ClsWeak(), - double weight = 1.0) - { AddStay(vx,strength,weight); AddStay(vy,strength,weight); return *this; } - - ClSimplexSolver &AddPointStay(const ClPoint &clp, - const ClStrength &strength = ClsWeak(), - double weight = 1.0); - - - // Add a stay of the given strength (default to weak) of v to the tableau - ClSimplexSolver &AddStay(const ClVariable v, - const ClStrength &strength = ClsWeak(), double weight = 1.0 ) - { - ClStayConstraint *pcn = new ClStayConstraint(v,strength,weight); - return AddConstraint(pcn); - } - - // Remove the constraint cn from the tableau - // Also remove any error variable associated with cn - ClSimplexSolver &RemoveConstraint(ClConstraint *const pcn) - { RemoveConstraintInternal(pcn); pcn->removedFrom(*this); return *this; } - -#ifndef CL_NO_DEPRECATED - // Deprecated! --02/19/99 gjb - ClSimplexSolver &RemoveConstraint(ClConstraint &cn) - { return RemoveConstraint(&cn); } -#endif - - - // Re-initialize this solver from the original constraints, thus - // getting rid of any accumulated numerical problems. (Actually, we - // haven't definitely observed any such problems yet) - void Reset(); - - // Re-solve the current collection of constraints, given the new - // values for the edit variables that have already been - // suggested (see SuggestValue() method) - // This is not guaranteed to work if you remove an edit constraint - // from the middle of the edit constraints you added - // (e.g., edit A, edit B, edit C, remove B -> this will fail!) - // DEPRECATED - void Resolve(); - - // Re-solve the current collection of constraints for new values for - // the constants of the edit variables. - // This is implemented in terms of SuggestValue-s, and is - // less efficient than that more natural interface - void Resolve(const vector &newEditConstants); - - // Convenience function for Resolve-s of two variables - void Resolve(Number x, Number y) - { - vector vals; - vals.push_back(x); - vals.push_back(y); - Resolve(vals); - } - - // Suggest a new value for an edit variable - // the variable needs to be added as an edit variable - // and BeginEdit() needs to be called before this is called. - // The tableau will not be solved completely until - // after Resolve() has been called - ClSimplexSolver &SuggestValue(ClVariable v, Number x); - - // Set and check whether or not the solver will attempt to compile - // an explanation of failure when a required constraint conflicts - // with another required constraint - ClSimplexSolver &SetExplaining(bool f) - { _fExplainFailure = f; return *this; } - - bool FIsExplaining() const - { return _fExplainFailure; } - - // If autosolving has been turned off, client code needs - // to explicitly call solve() before accessing variables - // values - ClSimplexSolver &Solve() - { -#ifdef CL_SOLVER_CHECK_INTEGRITY - AssertValid(); -#endif - if (_fNeedsSolving) - { - Optimize(_objective); - SetExternalVariables(); -#ifdef CL_TRACE_VERBOSE - std::cerr << "Manual solve actually solving." << std::endl; -#endif - } - return *this; - } - - ClSimplexSolver &SetEditedValue(ClVariable v, double n) - { - if (!FContainsVariable(v)) - { - ChangeClv(v,n); - return *this; - } - - if (!ClApprox(n, v.Value())) - { - AddEditVar(v); - BeginEdit(); - SuggestValue(v,n); - EndEdit(); - } - return *this; - } - - // Solver contains the variable if it's in either the columns - // list or the rows list - bool FContainsVariable(const ClVariable v) - { return ColumnsHasKey(v) || RowExpression(v); } - - ClSimplexSolver &AddVar(const ClVariable v) - { if (!FContainsVariable(v)) - { - AddStay(v); -#ifdef CL_TRACE - std::cerr << "added initial stay on " << v << std::endl; -#endif - } - return *this; } - - typedef void (*PfnResolveCallback)(ClSimplexSolver *psolver); - - void SetResolveCallback(PfnResolveCallback pfn) - { _pfnResolveCallback = pfn; } - - typedef void (*PfnCnSatCallback)(ClSimplexSolver *psolver, - ClConstraint *pcn, bool fSatisfied); - - void SetCnSatCallback(PfnCnSatCallback pfn) - { _pfnCnSatCallback = pfn; } - -#ifndef CL_NO_IO - friend ostream &operator<<(ostream &xo, const ClSimplexSolver &tableau); - - ostream &PrintOn(ostream &xo) const; - - ostream &PrintInternalInfo(ostream &xo) const; - - ostream &PrintOnVerbose(ostream &xo) const - { PrintOn(xo); PrintInternalInfo(xo); xo << std::endl; return xo; } - -#endif - - const ClConstraintToVarMap &ConstraintMap() const - { return _markerVars; } - - const ClVarToConstraintMap &MarkerMap() const - { return _constraintsMarked; } - - bool FIsConstraintSatisfied(const ClConstraint *const pcn) const; - - // DEPRECATED - bool FIsConstraintSatisfied(const ClConstraint &pcn) const - { return FIsConstraintSatisfied(&pcn); } - - // re-set all the external variables to their current values - // most importantly, this re-calls all the ChangeClv callbacks - // (which might be used to copy the ClVariable's value to another - // variable) - void UpdateExternalVariables() - { SetExternalVariables(); } - - // A. Beurive' Tue Jul 6 17:05:39 CEST 1999 - void ChangeStrengthAndWeight(ClConstraint *pcn, const ClStrength &strength, double weight); - void ChangeStrength(ClConstraint *pcn, const ClStrength &strength); - void ChangeWeight(ClConstraint *pcn, double weight); - // void DisplayObjective(); - - // Each of the non-required stays will be represented by an equation - // of the form - // v = c + eplus - eminus - // where v is the variable with the stay, c is the previous value of - // v, and eplus and eminus are slack variables that hold the error - // in satisfying the stay constraint. We are about to change - // something, and we want to fix the constants in the equations - // representing the stays. If both eplus and eminus are nonbasic - // they have value 0 in the current solution, meaning the previous - // stay was exactly satisfied. In this case nothing needs to be - // changed. Otherwise one of them is basic, and the other must - // occur only in the Expression for that basic error variable. - // Reset the Constant in this Expression to 0. - void ResetStayConstants(); - - ClSimplexSolver &SetAutoResetStayConstants(bool f) - { _fResetStayConstantsAutomatically = f; if (f) ResetStayConstants(); return *this; } - - bool FIsAutoResetStayConstants() const - { return _fResetStayConstantsAutomatically; } - - protected: - - // ClEditInfo is a privately-used class - // that just wraps a constraint, its positive and negative - // error variables, and its prior edit Constant. - // It is used as values in _editInfoList, and replaces - // the parallel vectors of error variables and previous edit - // constants from the smalltalk version of the code. - class ClEditInfo { - friend class ClSimplexSolver; - public: - - // These instances own none of the pointers; - // the tableau row (the Expression) owns the peplus, peminus, - // and AddEditVar/RemoveEditVar pair or the client code owns - // the constraint object - ClEditInfo(ClVariable clv, - ClEditConstraint *pconstraint, - ClVariable eplus, ClVariable eminus, - Number prevEditConstant) - :_clv(clv), - _pconstraint(pconstraint), - _clvEditPlus(eplus), _clvEditMinus(eminus), - _prevEditConstant(prevEditConstant) - { } - - ~ClEditInfo() - { } - - ostream &PrintOn(ostream &xo) const - { xo << _clv << " -> [" << _clvEditPlus << ", " << _clvEditMinus << "](" - << _prevEditConstant << ")@" << " -- " - << *_pconstraint; - return xo; } - - friend ostream &operator<<(ostream &xo, const ClEditInfo &cei) - { return cei.PrintOn(xo); } - - private: - ClVariable _clv; - ClConstraint *_pconstraint; - ClVariable _clvEditPlus; - ClVariable _clvEditMinus; - Number _prevEditConstant; - }; - - // Add the constraint expr=0 to the inequality tableau using an - // artificial variable. To do this, create an artificial variable - // av and Add av=expr to the inequality tableau, then make av be 0. - // (Raise an exception if we can't attain av=0.) - // (Raise an exception if we can't attain av=0.) If the Add fails, - // prepare an explanation in e that describes why it failed (note - // that an empty explanation is considered to mean the explanation - // encompasses all active constraints. - bool AddWithArtificialVariable(ClLinearExpression &pexpr, - ExCLRequiredFailureWithExplanation &e); - - // Using the given equation (av = cle) build an explanation which - // implicates all constraints used to construct the equation. That - // is, everything for which the variables in the equation are markers. - // Thanks to Steve Wolfman for the implementation of the explanation feature - void BuildExplanation(ExCLRequiredFailureWithExplanation & e, - ClVariable av, - const ClLinearExpression * pcle); - - // We are trying to Add the constraint expr=0 to the appropriate - // tableau. Try to Add expr directly to the tableax without - // creating an artificial variable. Return true if successful and - // false if not. - bool TryAddingDirectly(ClLinearExpression &pexpr); - - // We are trying to Add the constraint expr=0 to the tableaux. Try - // to choose a subject (a variable to become basic) from among the - // current variables in expr. If expr contains any unrestricted - // variables, then we must choose an unrestricted variable as the - // subject. Also, if the subject is new to the solver we won't have - // to do any substitutions, so we prefer new variables to ones that - // are currently noted as parametric. If expr contains only - // restricted variables, if there is a restricted variable with a - // negative coefficient that is new to the solver we can make that - // the subject. Otherwise we can't find a subject, so return nil. - // (In this last case we have to Add an artificial variable and use - // that variable as the subject -- this is done outside this method - // though.) - // - // Note: in checking for variables that are new to the solver, we - // ignore whether a variable occurs in the objective function, since - // new slack variables are added to the objective function by - // 'NewExpression:', which is called before this method. - ClVariable ChooseSubject(ClLinearExpression &pexpr); - - // Each of the non-required edits will be represented by an equation - // of the form - // v = c + eplus - eminus - // where v is the variable with the edit, c is the previous edit - // value, and eplus and eminus are slack variables that hold the - // error in satisfying the edit constraint. We are about to change - // something, and we want to fix the constants in the equations - // representing the edit constraints. If one of eplus and eminus is - // basic, the other must occur only in the Expression for that basic - // error variable. (They can't both be basic.) Fix the Constant in - // this Expression. Otherwise they are both nonbasic. Find all of - // the expressions in which they occur, and fix the constants in - // those. See the UIST paper for details. - // (This comment was for resetEditConstants(), but that is now - // gone since it was part of the screwey vector-based interface - // to resolveing. --02/15/99 gjb) - void DeltaEditConstant(Number delta, ClVariable pv1, ClVariable pv2); - - // We have set new values for the constants in the edit constraints. - // Re-Optimize using the dual simplex algorithm. - void DualOptimize(); - - // Make a new linear Expression representing the constraint cn, - // replacing any basic variables with their defining expressions. - // Normalize if necessary so that the Constant is non-negative. If - // the constraint is non-required give its error variables an - // appropriate weight in the objective function. - ClLinearExpression *NewExpression(const ClConstraint *pcn, - /* output to */ - ClVariable &clvEplus, - ClVariable &clvEminus, - Number &prevEConstant); - - // Minimize the value of the objective. (The tableau should already - // be feasible.) - void Optimize(ClVariable zVar); - - // Do a Pivot. Move entryVar into the basis (i.e. make it a basic variable), - // and move exitVar out of the basis (i.e., make it a parametric variable) - void Pivot(ClVariable entryVar, ClVariable exitVar); - - // Set the external variables known to this solver to their appropriate values. - // Set each external basic variable to its value, and set each - // external parametric variable to 0. (It isn't clear that we will - // ever have external parametric variables -- every external - // variable should either have a stay on it, or have an equation - // that defines it in terms of other external variables that do have - // stays. For the moment I'll put this in though.) Variables that - // are internal to the solver don't actually store values -- their - // values are just implicit in the tableu -- so we don't need to set - // them. - void SetExternalVariables(); - - // this gets called by RemoveConstraint and by AddConstraint when the - // contraint we're trying to Add is inconsistent - ClSimplexSolver &RemoveConstraintInternal(const ClConstraint *const pcn); - - void ChangeClv(ClVariable clv, Number n) { - clv.ChangeValue(n); - if (_pfnChangeClvCallback) - _pfnChangeClvCallback(&clv,this); - } - - /// instance variables - - // the arrays of positive and negative error vars for the stay constraints - // (need both positive and negative since they have only non-negative values) - ClVarVector _stayMinusErrorVars; - ClVarVector _stayPlusErrorVars; - - // give error variables for a non required constraint, - // maps to ClSlackVariable-s - ClConstraintToVarSetMap _errorVars; - - // Return a lookup table giving the marker variable for each - // constraint (used when deleting a constraint). - ClConstraintToVarMap _markerVars; - - // Reverse of the above-- a lookup table giving the constraint - // for each marker variable (used when building failure explanations) - ClVarToConstraintMap _constraintsMarked; - - ClVariable _objective; - - // Map edit variables to their constraints, errors, and prior - // values - ClEditInfoList _editInfoList; - - int _slackCounter; - int _artificialCounter; -#ifdef CL_FIND_LEAK - int _cArtificialVarsDeleted; -#endif - int _dummyCounter; - const double _epsilon; - - bool _fResetStayConstantsAutomatically; - bool _fNeedsSolving; - bool _fExplainFailure; - - PfnResolveCallback _pfnResolveCallback; - PfnCnSatCallback _pfnCnSatCallback; - - // C-style extension mechanism so I - // don't have to wrap ScwmClSolver separately - void *_pv; - - // a stack of the number of edit constraints - // that existed at the prior BeginEdit. - // an EndEdit needs to pop off the top value, - // then remove constraints to get down - // to the # of constraints as in _stkCedcns.top() - stack _stkCedcns; - - -#ifndef CL_NO_IO - -friend ostream &PrintTo(ostream &xo, const ClSimplexSolver::ClEditInfoList &listPEditInfo); -friend ostream &operator<<(ostream &xo, const ClSimplexSolver::ClEditInfoList &listPEditInfo); - -#endif - -}; - -#endif // ClSimplexSolver_H diff --git a/libs/cassowary/cassowary/ClSlackVariable.h b/libs/cassowary/cassowary/ClSlackVariable.h deleted file mode 100644 index ca116702e9..0000000000 --- a/libs/cassowary/cassowary/ClSlackVariable.h +++ /dev/null @@ -1,75 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClSlackVariable.h - -#ifndef ClSlackVariable_H -#define ClSlackVariable_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClAbstractVariable.h" - -class ClTableau; -class ClSimplexSolver; - - -class ClSlackVariable : public ClAbstractVariable { -public: -#ifdef CL_FIND_LEAK - ~ClSlackVariable() { --cSlackVariables; }; - - static long cSlackVariables; -#endif - -protected: - friend class ClTableau; - friend class ClSimplexSolver; - - ClSlackVariable(string Name = "") : - ClAbstractVariable(Name) - { -#ifdef CL_FIND_LEAK - ++cSlackVariables; -#endif - } - - ClSlackVariable(long number, char *prefix) : - ClAbstractVariable(number,prefix) - { -#ifdef CL_FIND_LEAK - ++cSlackVariables; -#endif - } - -#ifndef CL_NO_IO - virtual ostream &PrintOn(ostream &xo) const - { - xo << "[" << Name() << ":slack]"; - return xo; - } -#endif - - virtual bool IsExternal() const - { return false; } - - virtual bool IsPivotable() const - { return true; } - - virtual bool IsRestricted() const - { return true; } - -}; - - -#endif diff --git a/libs/cassowary/cassowary/ClSolver.h b/libs/cassowary/cassowary/ClSolver.h deleted file mode 100644 index 16e798d491..0000000000 --- a/libs/cassowary/cassowary/ClSolver.h +++ /dev/null @@ -1,167 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClSolver.h - -#ifndef ClSolver_H -#define ClSolver_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClErrors.h" -#include "ClTypedefs.h" -#include -#include - -using std::list; -using std::ostream; - -class ClVariable; - -// ClSolver is an abstract base class -class ClSolver { - public: - - ClSolver() : _pv(0), _fAutosolve(true), _pfnChangeClvCallback(0) { } - - virtual ~ClSolver() - { } - - // Add the constraint cn to the solver - virtual ClSolver &AddConstraint(ClConstraint *const pcn) = 0; - - // Remove the constraint cn from the solver - virtual ClSolver &RemoveConstraint(ClConstraint *const pcn) = 0; - - // Same as above, but returns false if the constraint cannot be solved - // (i.e., the resulting system would be unsatisfiable) - // The above function "AddConstraint" throws an exception in that case - // which may be inconvenient - virtual bool AddConstraintNoException(ClConstraint *const pcn) - { - try { - AddConstraint(pcn); - return true; - } - catch (const ExCLRequiredFailure &e) - { return false; } - catch (const ExCLTooDifficult &e) - { return false; } - } - -#ifndef CL_NO_DEPRECATED - // Deprecated --02/22/99 gjb - bool AddConstraintNoException(ClConstraint &cn) - { return AddConstraintNoException(&cn); } -#endif - - virtual bool RemoveConstraintNoException(ClConstraint *const pcn) - { - try { - RemoveConstraint(pcn); - return true; - } - catch (const ExCLConstraintNotFound &e) - { return false; } - } - -#ifndef CL_NO_DEPRECATED - // Deprecated --02/22/99 gjb - bool RemoveConstraintNoException(ClConstraint &cn) - { return RemoveConstraintNoException(&cn); } -#endif - - - virtual ClSolver &Solve() - { assert(false); return *this; } - - virtual bool SolveNoException() - { - try { - Solve(); - return true; - } - catch (const ExCLTooDifficult &e) - { return false; } - catch (const ExCLRequiredFailure &e) - { return false; } - } - - - virtual void Resolve() - { assert(false); } - - void SetPv(void *pv) - { _pv = pv; } - - void *Pv() const - { return _pv; } - - typedef void (*PfnChangeClvCallback)(ClVariable *pclv, ClSolver *psolver); - - void SetChangeClvCallback(PfnChangeClvCallback pfn) - { _pfnChangeClvCallback = pfn; } - - // Control whether optimization and setting of external variables - // is done automatically or not. By default it is done - // automatically and solve() never needs to be explicitly - // called by client code; if SetAutosolve is put to false, - // then solve() needs to be invoked explicitly before using - // variables' values - // (Turning off autosolve while adding lots and lots of - // constraints [ala the addDel test in ClTests] saved - // about 20% in runtime, from 68sec to 54sec for 900 constraints, - // with 126 failed adds) - ClSolver &SetAutosolve(bool f) - { _fAutosolve = f; if (f) Solve(); return *this; } - - // Tell whether we are autosolving - bool FIsAutosolving() const - { return _fAutosolve; } - - -#ifndef CL_NO_IO - friend ostream &operator<<(ostream &xo, const ClSolver &solver); - - virtual ostream &PrintOn(ostream &xo) const = 0; - -#endif - - protected: - - // C-style extension mechanism so I - // don't have to wrap ScwmClSolver separately - void *_pv; - - bool _fAutosolve; - - PfnChangeClvCallback _pfnChangeClvCallback; -}; - - -#ifndef CL_NO_IO -ostream &PrintTo(ostream &xo, const ClVarVector &varlist); -ostream &operator<<(ostream &xo, const ClVarVector &varlist); - -ostream &PrintTo(ostream &xo, const ClConstraintToVarSetMap &mapCnToVarSet); -ostream &operator<<(ostream &xo, const ClConstraintToVarSetMap &mapCnToVarSet); - -ostream &PrintTo(ostream &xo, const ClConstraintSet &setCn); -ostream &operator<<(ostream &xo, const ClConstraintSet &setCn); - -ostream &PrintTo(ostream &xo, const list &listFDN); -ostream &operator<<(ostream &xo, const list &listFDN); - -#endif - -#endif diff --git a/libs/cassowary/cassowary/ClStayConstraint.h b/libs/cassowary/cassowary/ClStayConstraint.h deleted file mode 100644 index f009731b09..0000000000 --- a/libs/cassowary/cassowary/ClStayConstraint.h +++ /dev/null @@ -1,43 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClStayConstraint.h - -#ifndef ClStayConstraint_H -#define ClStayConstraint_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClEditOrStayConstraint.h" - -class ClStayConstraint : public ClEditOrStayConstraint { - typedef ClEditOrStayConstraint super; - public: - - ClStayConstraint(const ClVariable var, - const ClStrength &strength = ClsWeak(), double weight = 1.0 ) : - ClEditOrStayConstraint(var,strength,weight) - { } - - virtual bool isStayConstraint() const - { return true; } - -#ifndef CL_NO_IO - virtual ostream &PrintOn(ostream &xo) const - { super::PrintOn(xo); return xo << " STAY)"; } -#endif - - private: -}; - -#endif diff --git a/libs/cassowary/cassowary/ClStrength.h b/libs/cassowary/cassowary/ClStrength.h deleted file mode 100644 index 644c04cb5f..0000000000 --- a/libs/cassowary/cassowary/ClStrength.h +++ /dev/null @@ -1,91 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClStrength.h - -#ifndef ClStrength_H -#define ClStrength_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include - -#include "Cassowary.h" -#include "ClSymbolicWeight.h" - -using std::string; - -class ClStrength; - -const ClStrength &ClsRequired(); -const ClStrength &ClsStrong(); -const ClStrength &ClsMedium(); -const ClStrength &ClsWeak(); - -class ClStrength { - public: - - ClStrength(const string &Name, const ClSymbolicWeight &symbolicWeight) : - _name(Name), _symbolicWeight(symbolicWeight) - { } - - // special case for when nLevels = 3, should assert nLevels() == 3 - ClStrength(const string &Name, double w1, double w2, double w3); - - virtual ~ClStrength() - { } - - virtual bool IsRequired() const - { return (_symbolicWeight == ClsRequired()._symbolicWeight); } - -#ifndef CL_NO_IO - virtual ostream &PrintOn(ostream &xo) const - { - xo << Name(); - if (!IsRequired()) - xo << ":" << symbolicWeight(); - return xo; - } - - friend ostream& operator<<(ostream &xos, const ClStrength &Cls) - { Cls.PrintOn(xos); return xos; } - -#endif - - virtual const ClSymbolicWeight &symbolicWeight() const - { return _symbolicWeight; } - - void SetPv(void *pv) - { _pv = pv; } - - void *Pv() const - { return _pv; } - - private: - string Name() const - { return _name; } - - void SetName(string Name) - { _name = Name; } - - void SetSymbolicWeight(const ClSymbolicWeight &symbolicWeight) - { _symbolicWeight = symbolicWeight; } - - // instance variables - string _name; - ClSymbolicWeight _symbolicWeight; - - void *_pv; - -}; - -#endif diff --git a/libs/cassowary/cassowary/ClSymbolicWeight.h b/libs/cassowary/cassowary/ClSymbolicWeight.h deleted file mode 100644 index 1c0339c887..0000000000 --- a/libs/cassowary/cassowary/ClSymbolicWeight.h +++ /dev/null @@ -1,197 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClSymbolicWeight.h - -#ifndef ClSymbolicWeight_H -#define ClSymbolicWeight_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClErrors.h" -#include -#include - -using std::vector; -using std::ostream; - -class ClSymbolicWeight { - public: - ClSymbolicWeight(unsigned int CLevels = 3, Number value = 0.0); - - ClSymbolicWeight(Number w1, Number w2, Number w3); - - ClSymbolicWeight(const vector &weights); - - static ClSymbolicWeight &Zero(); - - ClSymbolicWeight &negated(); - - ClSymbolicWeight &MultiplyMe(Number n); - - ClSymbolicWeight Times(Number n) const - { ClSymbolicWeight cl = *this; cl.MultiplyMe(n); return cl; } - - ClSymbolicWeight DivideBy(Number n) const; - - ClSymbolicWeight &addtoMe(const ClSymbolicWeight &cl); - - ClSymbolicWeight Add(const ClSymbolicWeight &cl) const - { ClSymbolicWeight clRet = *this; clRet.addtoMe(cl); return clRet; } - - ClSymbolicWeight Subtract(const ClSymbolicWeight &cl) const; - - ClSymbolicWeight operator*(const Number &n) const - { return Times(n); } - - ClSymbolicWeight operator/(const Number &n) const - { return DivideBy(n); } - - // FIXGJB: can we express this statically? - ClSymbolicWeight operator*(ClSymbolicWeight &w) const - { throw ExCLInternalError("Multiplication of symbolic weights encountered"); - return w; } - ClSymbolicWeight &operator*=(ClSymbolicWeight &w) - { throw ExCLInternalError("Multiplicative assignment of symbolic weights encountered"); - return w; } - - // FIXGJB: can we express this statically? - ClSymbolicWeight operator-() const - { throw ExCLInternalError("Can not negate a symbolic weight"); - return ClSymbolicWeight::Zero(); } - - friend ClSymbolicWeight ReciprocalOf(const ClSymbolicWeight &); - - ClSymbolicWeight &operator*=(const Number &n) - { return MultiplyMe(n); } - - ClSymbolicWeight operator+(const ClSymbolicWeight &cl) const - { return Add(cl); } - - ClSymbolicWeight operator+=(const ClSymbolicWeight &cl) - { return addtoMe(cl); } - - ClSymbolicWeight operator*(const Number &n) - { ClSymbolicWeight answer(*this); - answer *= n; - return answer; } - - bool lessThan(const ClSymbolicWeight &cl) const; - bool lessThanOrEqual(const ClSymbolicWeight &cl) const; - bool equal(const ClSymbolicWeight &cl) const; - bool greaterThan(const ClSymbolicWeight &cl) const; - bool greaterThanOrEqual(const ClSymbolicWeight &cl) const; - bool isNegative() const; - - friend bool operator==(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2) - { return cl1.equal(cl2); } - - friend bool operator!=(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2) - { return !(cl1 == cl2); } - - friend bool operator<(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2) - { return cl1.lessThan(cl2); } - - friend bool operator>(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2) - { return (cl2 < cl1); } - - // function.h provides operator>, >=, <= from operator< - - double AsDouble() const - { - vector::const_reverse_iterator i = _values.rbegin(); - Number sum = 0; - Number factor = 1; - // A. Beurive' Wed Jul 7 11:07:47 CEST 1999 - Number multiplier = 1000000; - for ( ; i != _values.rend(); ++i) - { - sum += *i * factor; - factor *= multiplier; - } - return sum; - } - -#ifndef CL_NO_IO - ostream &PrintOn(ostream &xo) const - { - vector::const_iterator i = _values.begin(); - if (i == _values.end()) - return xo; - - xo << *i; - for (++i; i != _values.end(); ++i) - { - xo << "," << *i; - } - return xo; - } - - // FIXGJB: use a template function to generate these automatically - friend ostream& operator<<(ostream &xos, const ClSymbolicWeight &clsw) - { clsw.PrintOn(xos); return xos; } -#endif - - int CLevels() const - { return _values.size(); } - - friend bool ClApprox(const ClSymbolicWeight &cl, Number n); - friend bool ClApprox(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2); - - private: - vector _values; - - void push_back(Number d) - { _values.push_back(d); } - -}; - -inline bool ClApprox(const ClSymbolicWeight &cl, Number n) -{ - vector::const_iterator it = cl._values.begin(); - if (!ClApprox(*it,n)) - return false; - - ++it; - for (; it != cl._values.end(); ++it) - { - if (!ClApprox(*it,0)) - return false; - } - - return true; -} - -inline bool ClApprox(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2) -{ - vector::const_iterator it1 = cl1._values.begin(); - vector::const_iterator it2 = cl2._values.begin(); - - for (; it1 != cl1._values.end() && it2 != cl2._values.end(); - ++it1, ++it2) - { - if (!ClApprox(*it1,*it2)) - return false; - } - - if (it1 == cl1._values.end() && it2 == cl2._values.end()) - return true; - - return false; -} - -inline ClSymbolicWeight ReciprocalOf(const ClSymbolicWeight &) -{ throw(ExCLInternalError("Cannot take ReciprocalOf symbolic weight")); - return ClSymbolicWeight::Zero(); } - -#endif diff --git a/libs/cassowary/cassowary/ClTableau.h b/libs/cassowary/cassowary/ClTableau.h deleted file mode 100644 index 117ed0fb9d..0000000000 --- a/libs/cassowary/cassowary/ClTableau.h +++ /dev/null @@ -1,230 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClTableau.h - -#ifndef ClTableau_H -#define ClTableau_H - -#include - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "Cassowary.h" -#include "ClLinearExpression.h" -#include "ClVariable.h" -#include "ClTypedefs.h" - - -#ifndef CL_NO_IO -class ClTableau; - -ostream &operator<<(ostream &xo, const ClTableau &clt); - -ostream &operator<<(ostream &xo, const ClVarSet &varset); - -ostream &operator<<(ostream &xo, const ClTableauColumnsMap &varmap); - -ostream &operator<<(ostream &xo, const ClTableauRowsMap &rows); - -ostream &operator<<(ostream &xo, const ClVarVector &varlist); -#endif // CL_NO_IO - -class ClTableau { - - public: - // No public constructor, since this does nothing but support - // an ADT for the ClSimplexSolver - - // Variable v has been removed from an Expression. If the - // Expression is in a tableau the corresponding basic variable is - // subject (or if subject is nil then it's in the objective function). - // Update the column cross-indices. - void NoteRemovedVariable(ClVariable v, ClVariable subject) - { -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - std::cerr << "(" << v << ", " << subject << ")" << std::endl; -#endif - ClVarSet &column = _columns[v]; - ClVarSet::const_iterator it = column.find(subject); - assert(it != column.end()); - column.erase(it); -#ifdef CL_TRACE_VERBOSE - std::cerr << "v = " << v << " and Columns[v].size() = " - << column.size() << std::endl; -#endif - if (column.size() == 0) - { - _columns.erase(v); - _externalRows.erase(v); - _externalParametricVars.erase(v); - } - } - - // v has been added to the linear Expression for subject - // update column cross indices - void NoteAddedVariable(ClVariable v, ClVariable subject) - { -#ifdef CL_TRACE - Tracer TRACER(__FUNCTION__); - std::cerr << "(" << v << ", " << subject << ")" << std::endl; -#endif - _columns[v].insert(subject); - if (v.IsExternal() && !FIsBasicVar(v)) - { - _externalParametricVars.insert(v); - } - } - -#ifndef CL_NO_IO - std::ostream &PrintOn(ostream &xo) const; - - ostream &PrintInternalInfo(ostream &xo) const; - - ostream &printExternalVariablesTo(ostream &xo) const; - -#endif - - // Check integrity of the tableau - // not complete, yet, but a start, at least - // Guard calls to AssertValid with CL_SOLVER_CHECK_INTEGRITY, - // since this is expensive - virtual void AssertValid() const { -#ifndef NDEBUG - // all external basic variables are in _externalRows - // and all external parametric variables are in _externalParametricVars - ClTableauRowsMap::const_iterator itRow = _rows.begin(); - for (; itRow != _rows.end(); ++itRow) - { - const ClVariable clv = (*itRow).first; - if (clv.IsExternal()) - { - if (_externalRows.find(clv) == _externalRows.end()) - { -#ifndef CL_NO_IO - std::cerr << "External basic variable " << clv - << " is not in _externalRows" << std::endl; -#endif - } - } - const ClLinearExpression *pcle = RowExpression(clv); - assert(pcle); - ClVarToNumberMap::const_iterator it = pcle->Terms().begin(); - for (; it != pcle->Terms().end(); ++it) - { - ClVariable clv = (*it).first; - if (clv.IsExternal()) - { - if (_externalParametricVars.find(clv) == _externalParametricVars.end()) - { -#ifndef CL_NO_IO - std::cerr << "External parametric variable " << clv - << " is not in _externalParametricVars" << std::endl; -#endif - } - } - } - } -#endif /* !NDEBUG */ - } - - - protected: - // Constructor -- want to start with empty objects so not much to do - ClTableau() - { } - - virtual ~ClTableau(); - - // Add v=expr to the tableau, update column cross indices - // v becomes a basic variable - // expr is now owned by ClTableau class, - // and ClTableauis responsible for deleting it - // (also, expr better be allocated on the heap!) - void addRow(ClVariable v, const ClLinearExpression &expr); - - // Remove v from the tableau -- remove the column cross indices for v - // and remove v from every Expression in rows in which v occurs - // returns a pointer to the variable (since we often want to delete - // the variable) - ClVariable RemoveColumn(ClVariable v); - - // Remove the basic variable v from the tableau row v=expr - // Then update column cross indices - // Probably want to call delete on the ClLinearExpression * returned - // unless you're adding that same Expression back into the - // tableau - ClLinearExpression *RemoveRow(ClVariable v); - - // Replace all occurrences of oldVar with expr, and update column cross indices - // oldVar should now be a basic variable - void SubstituteOut(ClVariable oldVar, const ClLinearExpression &expr); - - ClTableauColumnsMap Columns() - { return _columns; } - - ClTableauRowsMap Rows() - { return _rows; } - - // return true iff the variable subject is in the Columns keys - bool ColumnsHasKey(ClVariable subject) const - { - ClTableauColumnsMap::const_iterator i = _columns.find(subject); - return (i != _columns.end()); - } - - const ClLinearExpression *RowExpression(ClVariable v) const - { - ClTableauRowsMap::const_iterator i = _rows.find(v); - if (i != _rows.end()) - return (*i).second; - else - return 0; - } - - ClLinearExpression *RowExpression(ClVariable v) - { - const ClTableau *pthis = const_cast(this); - return const_cast(pthis->RowExpression(v)); - } - - - bool FIsBasicVar(ClVariable v) - { return RowExpression(v) != 0; } - - // private: FIXGJB: can I improve the encapsulation? - - // _columns is a mapping from variables which occur in expressions to the - // set of basic variables whose expressions contain them - // i.e., it's a mapping from variables in expressions (a column) to the - // set of rows that contain them - ClTableauColumnsMap _columns; - - // _rows maps basic variables to the expressions for that row in the tableau - ClTableauRowsMap _rows; - - // the collection of basic variables that have infeasible rows - // (used when reoptimizing) - ClVarSet _infeasibleRows; - - // the set of rows where the basic variable is external - // this was added to the C++ version to reduce time in SetExternalVariables() - ClVarSet _externalRows; - - // the set of external variables which are parametric - // this was added to the C++ version to reduce time in SetExternalVariables() - ClVarSet _externalParametricVars; - -}; - -#endif diff --git a/libs/cassowary/cassowary/ClTypedefs.h b/libs/cassowary/cassowary/ClTypedefs.h deleted file mode 100644 index 74b625a72b..0000000000 --- a/libs/cassowary/cassowary/ClTypedefs.h +++ /dev/null @@ -1,48 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClTypedefs.h - -#ifndef CL_TYPEDEFS_H__ -#define CL_TYPEDEFS_H__ - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include "ClLinearExpression_fwd.h" -#include -#include -#include - -using std::set; -using std::map; -using std::vector; - -class ClVariable; -class ClConstraint; -class ClEditInfo; - -typedef set ClVarSet; -typedef map ClTableauColumnsMap; -typedef map ClTableauRowsMap; - -// For Solver -typedef map ClConstraintToVarSetMap; -typedef map ClConstraintToVarMap; -typedef map ClVarToConstraintMap; -typedef vector ClVarVector; - -typedef set ClConstraintSet; - -// For FDSolver -typedef map ClVarToConstraintSetMap; - -#endif diff --git a/libs/cassowary/cassowary/ClVariable.h b/libs/cassowary/cassowary/ClVariable.h deleted file mode 100644 index b046247c67..0000000000 --- a/libs/cassowary/cassowary/ClVariable.h +++ /dev/null @@ -1,169 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// ClVariable.h -// A handle on ClAbstractVariable-s - -#ifndef ClVariable_H -#define ClVariable_H - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include -#include -#include -#include "Cassowary.h" -#include "ClFloatVariable.h" -#include "ClFDVariable.h" - -using std::map; -using std::string; - -class ClVariable; -typedef map StringToVarMap; - - -class ClVariable { - ClAbstractVariable *pclv; -public: - // converters from raw ClAbstractVariable - ClVariable(ClAbstractVariable *pclv_) : pclv(pclv_) { } - ClVariable(ClAbstractVariable &clv_) : pclv(&clv_) { } - - // Copy ctr - ClVariable(const ClVariable &clv_) : pclv(clv_.pclv) { } - - /// These ctrs build ClFloatVariable-s - ClVariable(string name, Number Value = 0.0) - : pclv(new ClFloatVariable(name,Value)) - { if (pmapStrPclv) { (*pmapStrPclv)[name] = *this; } } - ClVariable(Number Value = 0.0) - : pclv(new ClFloatVariable(Value)) { } - ClVariable(long number, char *prefix, Number Value = 0.0) - : pclv(new ClFloatVariable(number,prefix,Value)) { } - - // This one builds a ClFDVariable - ClVariable(ClFDVariable *pcfv) - : pclv(pcfv) - { if (pmapStrPclv) { (*pmapStrPclv)[pcfv->Name()] = *this; } } - - // Destructor - virtual ~ClVariable() {}; - - /// permit ClVariables to be used as pointers to pclvs - ClAbstractVariable *operator->() { return pclv; } - const ClAbstractVariable *operator->() const { return pclv; } - - /// and also forward the function calls along - - - bool IsFloatVariable() const { assert(pclv); return pclv->IsFloatVariable(); } - bool IsFDVariable() const { assert(pclv); return pclv->IsFDVariable(); } - bool IsDummy() const { assert(pclv); return pclv->IsDummy(); } - bool IsExternal() const { assert(pclv); return pclv->IsExternal(); } - bool IsPivotable() const { assert(pclv); return pclv->IsPivotable(); } - bool IsRestricted() const { assert(pclv); return pclv->IsRestricted(); } - - string Name() const { assert(pclv); return pclv->Name(); } - - Number Value() const { assert(pclv); return pclv->Value(); } - int IntValue() const { assert(pclv); return pclv->IntValue(); } - void SetValue(Number Value) - { assert(pclv); pclv->SetValue(Value); } - void ChangeValue(Number Value) - { assert(pclv); pclv->ChangeValue(Value); } - void SetPv(void *pv) - { assert(pclv); pclv->SetPv(pv); } - void *Pv() const - { assert(pclv); return pclv->Pv(); } - - void SetName(string const &nm) { - assert(pclv); - if (pmapStrPclv) { - pmapStrPclv->erase(Name()); - (*pmapStrPclv)[nm] = *this; - } - pclv->SetName(nm); - } - - ClAbstractVariable *get_pclv() const { return pclv; } - bool IsNil() const { return pclv == 0; } - - virtual FDNumber DesiredValue() const - { assert(false); } - - virtual list *PlfdnDomain() - { assert(false); return 0; } - - static void SetVarMap(StringToVarMap *pmap) { pmapStrPclv = pmap; } - static StringToVarMap *VarMap() { return pmapStrPclv; } - static StringToVarMap *pmapStrPclv; -#ifndef CL_NO_IO - ostream &PrintOn(ostream &xo) const - { - if (pclv) return pclv->PrintOn(xo); /* return xo << "@" << pclv << endl; */ - return xo << "clvNil"; - } -#endif - - friend bool operator<(ClVariable cl1, ClVariable cl2) - { return cl1.pclv < cl2.pclv; } - - friend bool operator==(ClVariable cl1, ClVariable cl2) - { return cl1.pclv == cl2.pclv; } - - friend bool operator!=(ClVariable cl1, ClVariable cl2) - { return !(cl1 == cl2); } - -}; - -#ifndef CL_NO_IO -inline ostream &operator<<(ostream &xo, const ClVariable &clv) -{ return clv.PrintOn(xo); } -#endif - -#ifdef CL_USE_HASH_MAP_AND_SET -struct hash { - size_t operator()(const ClVariable & v) const - { return size_t((unsigned long)v.get_pclv()/CL_PTR_HASH_DIVISOR); } -}; -#endif - - -#include - -// Compare two double-s approximately, since equality is no good -inline bool ClApprox(double a, double b) -{ - const double epsilon = 1.0e-8; - if (a > b) { - return (a - b) < epsilon; - } else { - return (b - a) < epsilon; - } -} - -// Can remove these if I decide to -// autoconvert from ClVariable-s to double-s -inline bool ClApprox(ClVariable clv, double b) -{ - return ClApprox(clv->Value(),b); -} - -inline bool ClApprox(double a, ClVariable clv) -{ - return ClApprox(a,clv->Value()); -} - -extern ClVariable clvNil; - -#endif diff --git a/libs/cassowary/cassowary/cl_auto_ptr.h b/libs/cassowary/cassowary/cl_auto_ptr.h deleted file mode 100644 index 3c37429676..0000000000 --- a/libs/cassowary/cassowary/cl_auto_ptr.h +++ /dev/null @@ -1,69 +0,0 @@ -// $Id$ -// See http://cseng.aw.com/bookdetail.qry?ISBN=0-201-63371-X&ptype=634 -// auto_ptr from More Effective C++ an earlier appendix (works w/ egcs) - - -#ifndef CL_AUTO_PTR_H -#define CL_AUTO_PTR_H - -#ifdef _MSC_VER -#include -template -void ReinitializeAutoPtr(auto_ptr &apref, T *pt) -{ - auto_ptr ap(pt); - apref = ap; -} -#define cl_auto_ptr auto_ptr -#else -// FIXGJB: This implementation for egcs is buggy -- be careful -// and replace ASAP -template -class cl_auto_ptr { - public: - explicit cl_auto_ptr(T *p = 0): pointee(p) {} - - template - cl_auto_ptr(cl_auto_ptr& rhs): pointee(rhs.release()) {} - - ~cl_auto_ptr() { delete pointee; } - - template - cl_auto_ptr& operator=(cl_auto_ptr& rhs) - { - if (this != &rhs) reset(rhs.release()); - return *this; - } - - T& operator*() const { return *pointee; } - - T* operator->() const { return pointee; } - - T* get() const { return pointee; } - - T* release() - { - T *oldPointee = pointee; - pointee = 0; - return oldPointee; - } - - // protected: - // This is non-standard - void reset(T *p = 0) { delete pointee; pointee = p; } - - private: - T *pointee; -}; - -template -void ReinitializeAutoPtr(cl_auto_ptr &apref, T *pt) -{ - apref.reset(pt); -} - - -#endif - - -#endif diff --git a/libs/cassowary/cassowary/config-inline.h b/libs/cassowary/cassowary/config-inline.h deleted file mode 100644 index 8b13789179..0000000000 --- a/libs/cassowary/cassowary/config-inline.h +++ /dev/null @@ -1 +0,0 @@ - diff --git a/libs/cassowary/cassowary/debug.h b/libs/cassowary/cassowary/debug.h deleted file mode 100644 index aa0499c641..0000000000 --- a/libs/cassowary/cassowary/debug.h +++ /dev/null @@ -1,48 +0,0 @@ -// $Id$ -// -// Cassowary Incremental Constraint Solver -// Original Smalltalk Implementation by Alan Borning -// This C++ Implementation by Greg J. Badros, -// http://www.cs.washington.edu/homes/gjb -// (C) 1998, 1999 Greg J. Badros and Alan Borning -// See ../LICENSE for legal details regarding this software -// -// debug.h - -#ifndef CASSOWARY_DEBUG_H_ -#define CASSOWARY_DEBUG_H_ - -#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED) -#include -#define CONFIG_INLINE_H_INCLUDED -#endif - -#include -#include "Cassowary.h" - -#ifdef CL_TRACE -class Tracer { - public: - Tracer(const char *const sz) : sz_(sz) { cerr << "* " << sz; } - ~Tracer() { cerr << "x " << sz_ << " exited." << endl; } - private: - const char *const sz_; -}; - -inline void CtrTracer(const char *const sz, const void *pv) -{ cerr << "@+ " << sz << " ctrnew@ " << pv << endl; } - -inline void DtrTracer(const char *const sz, const void *pv) -{ cerr << "@- " << sz << " dtrnew@ " << pv << endl; } - -#else -class Tracer { - public: - Tracer(const char *const) { } -}; - -inline void CtrTracer(const char *const, const void *) { } -inline void DtrTracer(const char *const, const void *) { } -#endif // CL_TRACE - -#endif diff --git a/libs/cassowary/cassowary/timer.h b/libs/cassowary/cassowary/timer.h deleted file mode 100644 index 6bad1a6fef..0000000000 --- a/libs/cassowary/cassowary/timer.h +++ /dev/null @@ -1,176 +0,0 @@ -/* $Id$ */ -#ifndef _TIMER_H_ -#define _TIMER_H_ - -// Programmer: John P. Russo -// -------------------------- -// John Russo has given permission to any of my students to use his -// "timer" class. -// -// Please give full credit to him any time you wish to use this class. -// Hossein Hakimzadeh 11/5/96 - -/************************** timer.cpp ********************************** - - A simple example that shows how C++ classes can be used to implement - a "Timer" object, which mimics the familiar actions of a stopwatch. - - The code relies heavily on the clock() function defined in the time - library. The clock() function returns the number of "ticks" that have - elapsed since a program starts. The size of a "tick" is compiler - dependent, but for PC compilers is about 1/18 second. - - The problem with the clock function is that it is not convenient to - use for typical timing operations. The timer class, defined below, by - contrast, shows that an object-oriented approach to modules can - provide tools that are natural and easy to use. - -= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ -#include - -class Timer -{ - //==================== public section ================================ - - // The functions and/or data in the public section of a class are - // accessible to anyone who uses the Timer class. - -public: - Timer(); // Constructor, used to declare Timer objects - void Start(); // Starts a timer object - void Stop(); // Stop a timer object - void Reset(); // Reset timer object - int IsRunning(); // Is the timer object running? - double ElapsedTime(); // How much time has been recorded? - double Resolution(); // Shortest measurable amount of time - - //-------------------- private section ------------------------------- - - // The functions and/or data in the private section of a class are NOT - // accessible to those who use the Timer class. They are accessible by - // member functions of the class. This allows access to the data to be - // carefully controlled. - -private: - long StartReading; // Number of ticks when timer object last started. - long ElapsedTicks; // Number of ticks on timer object. - int TimerIsRunning; // 1 if and only if timer object is running. - double TicksPerSecond() // This inline function is used to convert -// {return 18.206481;} // "ticks" (returned by clock() ) to seconds. - {return CLOCKS_PER_SEC;} // "ticks" (returned by clock() ) to seconds. - // In most UNIX systems this is 1000000 -}; - -/**************************** Start ************************************ - - If the declaration "Timer StopWatch;" has been made, the the call, - "StopWatch.Start();" is like push the start button of a real stopwatch. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ -void Timer::Start() -{ - TimerIsRunning = 1; // Stopwatch is now running - StartReading = clock(); // Look at internal clock and remember reading -} - -/**************************** Stop ************************************ - - Looks at the PC's internal clock and computes the number of ticks that - have elapsed since the timer was started. - - Note that if a timer is not reset, it can be used to time several events - and return the elapsed time for the enter set of events. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ -void Timer::Stop() -{ - TimerIsRunning = 0; // Stop timer object. - ElapsedTicks += clock() - StartReading; // Add elapsed time to the -} // previous time. - -/**************************** Reset ************************************ - - Clears a Timer of previous elapsed times, so that a new event can be - timed. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ -void Timer::Reset() -{ - TimerIsRunning = 0; // Start not yet called. - ElapsedTicks = 0; // No time on timer object yet. -} - -/************************** IsRunning ************************************ - - The data member, "TimerIsRunning" is used to keep track of whether a - timer is active, i.e. whether an event is being timed. While we want - those using the timer class to know when a timer is active, we do NOT - want them to directly access the TimerIsRunning variable. We solve this - problem, by making TimerIsRunning private and providing the public - "access function" below. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ -int Timer::IsRunning() -{ - return TimerIsRunning; -} - -/************************* ElapsedTime *********************************** - - This function allows a client to determine the amount of time that has - elapsed on a timer object. Note that there are two possibilities: - - 1) A timer object has been started and stopped. We can detect this - case, because the variable "TimerIsRunning" is false. - - 2) A timer object is "running", i.e. is still in the process of timing - an event. It is not expected that this case will occur as frequently - as case 1). - - In either case, this function converts ticks to seconds. Note that - since the function TicksPerSecond() returns a value of type double, - an implicit type conversion takes place before doing the division - required in either case. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ -double Timer::ElapsedTime() -{ - if ( !TimerIsRunning ) // Normal case - return ElapsedTicks/TicksPerSecond(); - - else - return (ElapsedTicks + clock() - StartReading)/TicksPerSecond(); -} - -/************************** Resolution *********************************** - - Althould we have no way of knowing how accurate the internal clock is, - we can predict its resolution, which is the shortest event that can be - measured by the clock. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ -double Timer::Resolution() -{ - return 1/TicksPerSecond(); // Note 1 is coverted to 1.0 before division -} - -/******************** Timer (constructor) ******************************* - - A "constructor" is a special class member function, one which has the - same name as the class. The "default constructor" is a constructor that - has no parameters. A constructor is called automatically when an - instance of a class is declared. For example, the constructor defined - below is called when the declaration "Timer T;" is executed. - - If the programmer does not write a default constructor, then the - compiler will generate one automatically. However, by writing the - constructor below, we provide automatic initialization of timer objects. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ -Timer::Timer() -{ - TimerIsRunning = 0; // Start not yet called. - ElapsedTicks = 0; // No time on timer object yet. -} - -#endif /* _TIMER_H_ */ diff --git a/libs/gtkmm2ext/SConscript b/libs/gtkmm2ext/SConscript index b70aea3d40..5d8489f103 100644 --- a/libs/gtkmm2ext/SConscript +++ b/libs/gtkmm2ext/SConscript @@ -9,7 +9,7 @@ Import('env final_prefix install_prefix libraries i18n') gtkmm2ext = env.Copy() gtkmm2ext.Merge ([ libraries['sigc2'], - libraries['pbd3'], + libraries['pbd'], libraries['midi++2'], libraries['gtk2'], libraries['glibmm2'], diff --git a/libs/libsndfile/src/sndfile.c b/libs/libsndfile/src/sndfile.c index b627c88ffe..47b74cfd7f 100644 --- a/libs/libsndfile/src/sndfile.c +++ b/libs/libsndfile/src/sndfile.c @@ -1087,7 +1087,7 @@ sf_command (SNDFILE *sndfile, int command, void *data, int datasize) broadcast_info_copy (psf->broadcast_info, data) ; broadcast_add_coding_history (psf->broadcast_info, psf->sf.channels, psf->sf.samplerate) ; - if (psf->write_header) + if (psf->auto_header && psf->write_header) psf->write_header (psf, SF_TRUE) ; return SF_TRUE ; @@ -1210,7 +1210,7 @@ sf_seek (SNDFILE *sndfile, sf_count_t offset, int whence) if (psf->error) return PSF_SEEK_ERROR ; -#ifdef ECDL_ORIGINAL# +#ifdef ECDL_ORIGINAL if (seek_from_start < 0 || seek_from_start > psf->sf.frames) { psf->error = SFE_BAD_SEEK ; return PSF_SEEK_ERROR ; diff --git a/libs/midi++2/SConscript b/libs/midi++2/SConscript index f396dba09e..e0df59c7da 100644 --- a/libs/midi++2/SConscript +++ b/libs/midi++2/SConscript @@ -7,7 +7,7 @@ import glob Import('env libraries install_prefix') midi2 = env.Copy() -midi2.Merge([ libraries['sigc2'], libraries['xml'], libraries['glib2'], libraries['pbd3'] ]) +midi2.Merge([ libraries['sigc2'], libraries['xml'], libraries['glib2'], libraries['pbd'] ]) domain = 'midipp' diff --git a/libs/pbd/.cvsignore b/libs/pbd/.cvsignore new file mode 100644 index 0000000000..e9a15e81e9 --- /dev/null +++ b/libs/pbd/.cvsignore @@ -0,0 +1,5 @@ +libpbd.pc +libpbd.spec +version.cc +*.os +*.dylib diff --git a/libs/pbd/AUTHORS b/libs/pbd/AUTHORS new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/pbd/COPYING b/libs/pbd/COPYING new file mode 100644 index 0000000000..d60c31a97a --- /dev/null +++ b/libs/pbd/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libs/pbd/ChangeLog b/libs/pbd/ChangeLog new file mode 100644 index 0000000000..59e92915ba --- /dev/null +++ b/libs/pbd/ChangeLog @@ -0,0 +1,10 @@ +2005-12-02 Taybin Rutkin + * libpbd now allocates warning, info, error, and fatal itself. + * Incremented version to 3.1. + +2005-04-01 Taybin Rutkin + * Updated to support sigc++-2.0. + * Incremented version to 3.0.0. + +2004-08-04 Taybin Rutkin + * Added support for gcc-3.4 diff --git a/libs/pbd/NEWS b/libs/pbd/NEWS new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/pbd/README b/libs/pbd/README new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/pbd/SConscript b/libs/pbd/SConscript new file mode 100644 index 0000000000..a9166d9505 --- /dev/null +++ b/libs/pbd/SConscript @@ -0,0 +1,68 @@ +# -*- python -*- + +import os +import os.path +import glob + +Import('env libraries i18n install_prefix') + +pbd = env.Copy() + +domain = 'libpbd' + +pbd.Append(DOMAIN=domain,MAJOR=4,MINOR=1,MICRO=0) +pbd.Append(CXXFLAGS="-DPACKAGE=\\\"" + domain + "\\\"") +pbd.Append(CXXFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE") +pbd.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED") +pbd.Append(PACKAGE=domain) +pbd.Append(POTFILE=domain + '.pot') + +pbd_files = Split(""" +basename.cc +base_ui.cc +convert.cc +dmalloc.cc +error.cc +mountpoint.cc +path.cc +pathscanner.cc +pool.cc +pthread_utils.cc +receiver.cc +stacktrace.cc +strsplit.cc +textreceiver.cc +transmitter.cc +undo.cc +version.cc +whitespace.cc +xml++.cc +""") + +conf = Configure(pbd) +if conf.CheckFunc('getmntent'): + conf.env.Append(CCFLAGS="-DHAVE_GETMNTENT") +if conf.CheckCHeader('execinfo.h'): + conf.env.Append(CXXFLAGS="-DHAVE_EXECINFO") +pbd = conf.Finish() + +pbd.Merge ([ libraries['sigc2'], libraries['xml'], libraries['glibmm2'], libraries['glib2'] ]) + +pbd.VersionBuild(['version.cc','pbd/version.h'], 'SConscript') + +libpbd = pbd.SharedLibrary('pbd', pbd_files) +Default(libpbd) + +mount_env = Environment(CCFLAGS='-DTEST_MOUNTPOINT -Ilibs/pbd') +mount_env.Program('mountpoint', 'mountpoint.cc') + +if env['NLS']: + i18n (pbd, pbd_files, env) + +env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libpbd)) + +env.Alias('tarball', env.Distribute (env['DISTTREE'], + [ 'SConscript', 'i18n.h', 'gettext.h', 'pbd/abstract_ui.cc' ] + + pbd_files + + glob.glob('po/*.po') + + glob.glob('pbd/*.h'))) diff --git a/libs/pbd/base_ui.cc b/libs/pbd/base_ui.cc new file mode 100644 index 0000000000..d3c8d5e4c7 --- /dev/null +++ b/libs/pbd/base_ui.cc @@ -0,0 +1,88 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "i18n.h" + +using namespace std; +using namespace PBD; + +uint32_t BaseUI::rt_bit = 1; +BaseUI::RequestType BaseUI::CallSlot = BaseUI::new_request_type(); + +BaseUI::BaseUI (string str, bool with_signal_pipe) + : _name (str) +{ + /* odd pseudo-singleton semantics */ + + base_ui_instance = this; + + signal_pipe[0] = -1; + signal_pipe[1] = -1; + + if (with_signal_pipe) { + if (setup_signal_pipe ()) { + throw failed_constructor (); + } + } +} + +BaseUI::~BaseUI() +{ + if (signal_pipe[0] >= 0) { + close (signal_pipe[0]); + } + + if (signal_pipe[1] >= 0) { + close (signal_pipe[1]); + } +} + +BaseUI::RequestType +BaseUI::new_request_type () +{ + RequestType rt; + + /* XXX catch out-of-range */ + + rt = RequestType (rt_bit); + rt_bit <<= 1; + + return rt; +} + +int +BaseUI::setup_signal_pipe () +{ + /* setup the pipe that other threads send us notifications/requests + through. + */ + + if (pipe (signal_pipe)) { + error << string_compose (_("%1-UI: cannot create error signal pipe (%2)"), _name, std::strerror (errno)) + << endmsg; + + return -1; + } + + if (fcntl (signal_pipe[0], F_SETFL, O_NONBLOCK)) { + error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal read pipe (%2)"), _name, std::strerror (errno)) + << endmsg; + return -1; + } + + if (fcntl (signal_pipe[1], F_SETFL, O_NONBLOCK)) { + error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal write pipe (%2)"), _name, std::strerror (errno)) + << endmsg; + return -1; + } + + return 0; +} + diff --git a/libs/pbd/basename.cc b/libs/pbd/basename.cc new file mode 100644 index 0000000000..a51e393b78 --- /dev/null +++ b/libs/pbd/basename.cc @@ -0,0 +1,20 @@ +#include +#include +#include + + +// implement this using Glib::path_get_basename +std::string +PBD::basename_nosuffix (const std::string& str) +{ + std::string::size_type slash = str.find_last_of ('/'); + std::string noslash; + + if (slash == std::string::npos) { + noslash = str; + } else { + noslash = str.substr (slash+1); + } + + return noslash.substr (0, noslash.find_last_of ('.')); +} diff --git a/libs/pbd/convert.cc b/libs/pbd/convert.cc new file mode 100644 index 0000000000..60d39c91e2 --- /dev/null +++ b/libs/pbd/convert.cc @@ -0,0 +1,212 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include + +#include "pbd/convert.h" + +#include "i18n.h" + +using std::string; +using std::vector; + +namespace PBD { + +string +short_version (string orig, string::size_type target_length) +{ + /* this tries to create a recognizable abbreviation + of "orig" by removing characters until we meet + a certain target length. + + note that we deliberately leave digits in the result + without modification. + */ + + + string::size_type pos; + + /* remove white-space and punctuation, starting at end */ + + while (orig.length() > target_length) { + if ((pos = orig.find_last_of (_("\"\n\t ,<.>/?:;'[{}]~`!@#$%^&*()_-+="))) == string::npos) { + break; + } + orig.replace (pos, 1, ""); + } + + /* remove lower-case vowels, starting at end */ + + while (orig.length() > target_length) { + if ((pos = orig.find_last_of (_("aeiou"))) == string::npos) { + break; + } + orig.replace (pos, 1, ""); + } + + /* remove upper-case vowels, starting at end */ + + while (orig.length() > target_length) { + if ((pos = orig.find_last_of (_("AEIOU"))) == string::npos) { + break; + } + orig.replace (pos, 1, ""); + } + + /* remove lower-case consonants, starting at end */ + + while (orig.length() > target_length) { + if ((pos = orig.find_last_of (_("bcdfghjklmnpqrtvwxyz"))) == string::npos) { + break; + } + orig.replace (pos, 1, ""); + } + + /* remove upper-case consonants, starting at end */ + + while (orig.length() > target_length) { + if ((pos = orig.find_last_of (_("BCDFGHJKLMNPQRTVWXYZ"))) == string::npos) { + break; + } + orig.replace (pos, 1, ""); + } + + /* whatever the length is now, use it */ + + return orig; +} + +int +atoi (const string& s) +{ + return std::atoi (s.c_str()); +} + +double +atof (const string& s) +{ + return std::atof (s.c_str()); +} + +vector +internationalize (const char **array) +{ + vector v; + + for (uint32_t i = 0; array[i]; ++i) { + v.push_back (_(array[i])); + } + + return v; +} + +static int32_t +int_from_hex (char hic, char loc) +{ + int hi; /* hi byte */ + int lo; /* low byte */ + + hi = (int) hic; + + if( ('0'<=hi) && (hi<='9') ) { + hi -= '0'; + } else if( ('a'<= hi) && (hi<= 'f') ) { + hi -= ('a'-10); + } else if( ('A'<=hi) && (hi<='F') ) { + hi -= ('A'-10); + } + + lo = (int) loc; + + if( ('0'<=lo) && (lo<='9') ) { + lo -= '0'; + } else if( ('a'<=lo) && (lo<='f') ) { + lo -= ('a'-10); + } else if( ('A'<=lo) && (lo<='F') ) { + lo -= ('A'-10); + } + + return lo + (16 * hi); +} + +void +url_decode (string& url) +{ + string::iterator last; + string::iterator next; + + for (string::iterator i = url.begin(); i != url.end(); ++i) { + if ((*i) == '+') { + *i = ' '; + } + } + + if (url.length() <= 3) { + return; + } + + last = url.end(); + + --last; /* points at last char */ + --last; /* points at last char - 1 */ + + for (string::iterator i = url.begin(); i != last; ) { + + if (*i == '%') { + + next = i; + + url.erase (i); + + i = next; + ++next; + + if (isxdigit (*i) && isxdigit (*next)) { + /* replace first digit with char */ + *i = int_from_hex (*i,*next); + ++i; /* points at 2nd of 2 digits */ + url.erase (i); + } + } else { + ++i; + } + } +} + +string +length2string (const int32_t frames, const float sample_rate) +{ + int secs = (int) (frames / sample_rate); + int hrs = secs / 3600; + secs -= (hrs * 3600); + int mins = secs / 60; + secs -= (mins * 60); + + int total_secs = (hrs * 3600) + (mins * 60) + secs; + int frames_remaining = (int) floor (frames - (total_secs * sample_rate)); + float fractional_secs = (float) frames_remaining / sample_rate; + + char duration_str[32]; + sprintf (duration_str, "%02d:%02d:%05.2f", hrs, mins, (float) secs + fractional_secs); + + return duration_str; +} + +} // namespace PBD diff --git a/libs/pbd/dmalloc.cc b/libs/pbd/dmalloc.cc new file mode 100644 index 0000000000..0e730946c8 --- /dev/null +++ b/libs/pbd/dmalloc.cc @@ -0,0 +1,102 @@ +/* + * file that facilitates C++ program debugging. + * + * Copyright 1995 by Gray Watson + * + * This file is part of the dmalloc package. + * + * Permission to use, copy, modify, and distribute this software for any + * NON-COMMERCIAL purpose and without fee is hereby granted, provided + * that the above copyright notice and this permission notice appear + * in all copies, and that the name of Gray Watson not be used in + * advertising or publicity pertaining to distribution of the document + * or software without specific, written prior permission. + * + * Please see the PERMISSIONS file or contact the author for information + * about commercial licenses. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be contacted via http://www.letters.com/~gray/ + * + * $Id$ + */ + +/* + * This file is used to effectively redirect new to the more familiar + * malloc and delete to the more familiar free so they can be debugged + * with the debug malloc library.. They also give the known error + * behavior, too. + * + * Compile and link this in with the C++ program you want to debug. + * + * NOTE: I am not a C++ hacker so feedback in the form of other hints + * and ideas for C++ users would be much appreciated. + */ + +#ifdef DEBUG_MALLOC + +extern "C" { +#include +#include +#include "/usr/local/src/dmalloc-4.1.2/return.h" +} + +/* + * An overload function for the C++ new. + */ +void * +operator new(size_t size) +{ + char *file; + GET_RET_ADDR(file); + + /* handle correct C++ semantics for an alloc of size 0 */ + + if (size == 0) size = 1; + + return _malloc_leap(file, 0, size); +} + +/* + * An overload function for the C++ new[]. + */ +void * +operator new[](size_t size) +{ + char *file; + GET_RET_ADDR(file); + + /* handle correct C++ semantics for an alloc of size 0 */ + + if (size == 0) size = 1; + + return _malloc_leap(file, 0, size); +} + +/* + * An overload function for the C++ delete. + */ +void +operator delete(void *pnt) +{ + char *file; + GET_RET_ADDR(file); + _free_leap(file, 0, pnt); +} + +/* + * An overload function for the C++ delete[]. Thanks to Jens Krinke + * + */ +void +operator delete[](void *pnt) +{ + char *file; + GET_RET_ADDR(file); + _free_leap(file, 0, pnt); +} + +#endif diff --git a/libs/pbd/error.cc b/libs/pbd/error.cc new file mode 100644 index 0000000000..a6f8fb7f8f --- /dev/null +++ b/libs/pbd/error.cc @@ -0,0 +1,7 @@ +#include + +Transmitter PBD::error (Transmitter::Error); +Transmitter PBD::info (Transmitter::Info); +Transmitter PBD::fatal (Transmitter::Fatal); +Transmitter PBD::warning (Transmitter::Warning); + diff --git a/libs/pbd/gettext.h b/libs/pbd/gettext.h new file mode 100644 index 0000000000..339c74ffe7 --- /dev/null +++ b/libs/pbd/gettext.h @@ -0,0 +1,82 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include + +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of a NOP. We don't include + as well because people using "gettext.h" will not include , + and also including would fail on SunOS 4, whereas + is OK. */ +#if defined(__sun) +# include +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ + +/* other headers may have included libintl.h */ + +# undef gettext +# undef dgettext +# undef dcgettext +# undef ngettext +# undef dngettext +# undef dcngettext +# undef textdomain +# undef bindtextdomain +# undef bind_textdomain_codeset + +# define gettext(Msgid) ((const char *) (Msgid)) +# define dgettext(Domainname, Msgid) ((const char *) (Msgid)) +# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define textdomain(Domainname) ((const char *) (Domainname)) +# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) +# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) + +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +#endif /* _LIBGETTEXT_H */ diff --git a/libs/pbd/i18n.h b/libs/pbd/i18n.h new file mode 100644 index 0000000000..7c79d2eb53 --- /dev/null +++ b/libs/pbd/i18n.h @@ -0,0 +1,11 @@ +#ifndef __i18n_h__ +#define __i18n_h__ + +#include +#include "gettext.h" + +#define _(Text) dgettext (PACKAGE, Text) +#define N_(Text) gettext_noop (Text) +#define X_(Text) (Text) + +#endif // __i18n_h__ diff --git a/libs/pbd/libpbd.pc.in b/libs/pbd/libpbd.pc.in new file mode 100644 index 0000000000..14d0208845 --- /dev/null +++ b/libs/pbd/libpbd.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/pbd + +Name: libpbd +Version: @VERSION@ +Description: libpbd, a library of useful, generic C++ objects +Requires: +Libs: -L${libdir} -lpbd @NON_PKG_LIBS@ +Cflags: -I${includedir} @NON_PKG_CFLAGS@ diff --git a/libs/pbd/libpbd.spec.in b/libs/pbd/libpbd.spec.in new file mode 100644 index 0000000000..d50622d638 --- /dev/null +++ b/libs/pbd/libpbd.spec.in @@ -0,0 +1,70 @@ +Summary: A general purpose programming library +%define lib_name pbd +Name: lib%{lib_name} +Version: @VERSION@ +Release: 2 +Copyright: GPL +Source: . +Url: http://www.quasimodo.org +Vendor: Paul Davis +Packager: jfm3 +Group: System Environment/Libraries +Prefix: %{_prefix} +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +%description + +This library implements a number of programming utilities used by Paul +Davis (formerly Paul Barton-Davis, hence the name). It is used in +some of his Open Source software projects. See +http://ardour.sf.net/ for examples. + +%prep +%setup -q + +%build +CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure $ARCH_FLAGS --prefix=%{prefix} +make + +%install +rm -rf $RPM_BUILD_ROOT +install -d -m 755 $RPM_BUILD_ROOT%{prefix}/{{include,lib}/%{lib_name}} +make install INSTALL="%(which install) -p" prefix=$RPM_BUILD_ROOT%{prefix} + +%post +/sbin/ldconfig + +%postun +/sbin/ldconfig + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%doc README AUTHORS NEWS COPYING* +%{prefix}/lib/libpbd.so* + +%package devel +Summary: A general purpose programming library -- developer version. +Group: System Environment/Libraries + +%description devel + +This library implements a number of programming utilities used by Paul +Davis (formerly Paul Barton-Davis, hence the name). It is used in +some of his Open Source software projects. See +http://ardour.sf.net/ for examples. + +This package holds static libraries and headers needed by developers +who wish to use libpbd in their programs. + +%files devel +%defattr(-,root,root) +%{prefix}/include/pbd/* +%{prefix}/lib/libpbd.a +%{prefix}/lib/libpbd.la +%{prefix}/bin/pbd-config +%{prefix}/share/aclocal/pbd.m4 +%{prefix}/share/aclocal/unique_args.m4 + diff --git a/libs/pbd/mountpoint.cc b/libs/pbd/mountpoint.cc new file mode 100644 index 0000000000..c1bcb375f3 --- /dev/null +++ b/libs/pbd/mountpoint.cc @@ -0,0 +1,158 @@ +/* + Copyright (C) 2002 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include +#include +#include + +#include + +using std::string; + +#if HAVE_GETMNTENT +#include + +struct mntent_sorter { + bool operator() (const mntent *a, const mntent *b) { + return strcmp (a->mnt_dir, b->mnt_dir); + } +}; + +string +mountpoint (string path) +{ + FILE *mntf; + mntent *mnt; + unsigned int maxmatch = 0; + unsigned int matchlen; + const char *cpath = path.c_str(); + char best[PATH_MAX+1]; + + if ((mntf = setmntent ("/etc/mtab", "r")) == 0) { + return ""; + } + + best[0] = '\0'; + + while ((mnt = getmntent (mntf))) { + unsigned int n; + + n = 0; + matchlen = 0; + + /* note: strcmp's semantics are not + strict enough to use for this. + */ + + while (cpath[n] && mnt->mnt_dir[n]) { + if (cpath[n] != mnt->mnt_dir[n]) { + break; + } + matchlen++; + n++; + } + + if (cpath[matchlen] == '\0') { + + endmntent (mntf); + return mnt->mnt_dir; + + } else { + + if (matchlen > maxmatch) { + snprintf (best, sizeof(best), "%s", mnt->mnt_dir); + maxmatch = matchlen; + } + } + } + + endmntent (mntf); + + return best; +} + +#else // !HAVE_GETMNTENT + +#include +#include +#include + +string +mountpoint (string path) +{ + struct statfs *mntbufp = 0; + int count; + unsigned int maxmatch = 0; + unsigned int matchlen; + const char *cpath = path.c_str(); + char best[PATH_MAX+1]; + + if ((count = getmntinfo(&mntbufp, MNT_NOWAIT)) == 0) { + free(mntbufp); + return "\0"; + } + + best[0] = '\0'; + + for (int i = 0; i < count; ++i) { + unsigned int n = 0; + matchlen = 0; + + /* note: strcmp's semantics are not + strict enough to use for this. + */ + + while (cpath[n] && mntbufp[i].f_mntonname[n]) { + if (cpath[n] != mntbufp[i].f_mntonname[n]) { + break; + } + matchlen++; + n++; + } + + if (cpath[matchlen] == '\0') { + snprintf(best, sizeof(best), "%s", mntbufp[i].f_mntonname); + free(mntbufp); + return best; + + } else { + + if (matchlen > maxmatch) { + snprintf (best, sizeof(best), "%s", mntbufp[i].f_mntonname); + maxmatch = matchlen; + } + } + } + + free(mntbufp); + + return best; +} +#endif // HAVE_GETMNTENT + +#ifdef TEST_MOUNTPOINT + +main (int argc, char *argv[]) +{ + printf ("mp of %s = %s\n", argv[1], mountpoint (argv[1]).c_str()); + exit (0); +} + +#endif // TEST_MOUNTPOINT diff --git a/libs/pbd/path.cc b/libs/pbd/path.cc new file mode 100644 index 0000000000..80f916c9ae --- /dev/null +++ b/libs/pbd/path.cc @@ -0,0 +1,164 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include + +#include +#include + +#include +#include + +namespace PBD { + +Path::Path () +{ + +} + +Path::Path (const string& path) +{ + vector tmp; + + if(!tokenize ( path, string(":;"), std::back_inserter (tmp))) { + g_warning ("%s : %s\n", G_STRLOC, G_STRFUNC); + return; + } + + add_readable_directories (tmp); +} + +Path::Path (const vector& paths) +{ + add_readable_directories (paths); +} + +Path::Path (const Path& other) + : m_dirs(other.m_dirs) +{ + +} + +bool +Path::readable_directory (const string& directory_path) +{ + if (g_access (directory_path.c_str(), R_OK) == 0) { + if (Glib::file_test(directory_path, Glib::FILE_TEST_IS_DIR)) { + return true; + } else { + g_warning (" %s : Path exists but is not a directory\n", G_STRLOC); + } + } else { + g_warning ("%s : %s : %s\n", G_STRLOC, directory_path.c_str(), g_strerror(errno)); + } + return false; +} + +void +Path::add_readable_directory (const string& directory_path) +{ + if(readable_directory(directory_path)) { + m_dirs.push_back(directory_path); + } +} + +void +Path::add_readable_directories (const vector& paths) +{ + for(vector::const_iterator i = paths.begin(); i != paths.end(); ++i) { + add_readable_directory (*i); + } +} + +const string +Path::path_string() const +{ + string path; + + for (vector::const_iterator i = m_dirs.begin(); i != m_dirs.end(); ++i) { + path += (*i); + path += G_SEARCHPATH_SEPARATOR; + } + + g_message ("%s : %s", G_STRLOC, path.c_str()); + + return path.substr (0, path.length() - 1); // drop final colon +} + +const Path& +Path::operator= (const Path& path) +{ + m_dirs = path.m_dirs; + return *this; +} + +const Path& +Path::operator+= (const string& directory_path) +{ + add_readable_directory (directory_path); + return *this; +} + +const Path +operator+ (const Path& lhs_path, const Path& rhs_path) +{ + Path tmp_path(lhs_path); // does this do what I think it does. + // concatenate paths into new Path + tmp_path.m_dirs.insert(tmp_path.m_dirs.end(), rhs_path.m_dirs.begin(), rhs_path.m_dirs.end()); + return tmp_path; +} + +Path& +Path::add_subdirectory_to_path (const string& subdir) +{ + vector tmp; + string directory_path; + + for (vector::iterator i = m_dirs.begin(); i != m_dirs.end(); ++i) { + directory_path = Glib::build_filename (*i, subdir); + if(readable_directory(directory_path)) { + tmp.push_back(directory_path); + } + } + m_dirs = tmp; + return *this; +} + +bool +find_file_in_path (const Path& path, const string& filename, string& resulting_path) +{ + for (vector::const_iterator i = path.dirs().begin(); i != path.dirs().end(); ++i) { + resulting_path = Glib::build_filename ((*i), filename); + if (g_access (resulting_path.c_str(), R_OK) == 0) { + g_message ("File %s found in Path : %s\n", resulting_path.c_str(), + path.path_string().c_str()); + return true; + } + } + + g_warning ("%s : Could not locate file %s in path %s\n", G_STRLOC, filename.c_str(), + path.path_string().c_str()); + + return false; +} + +} // namespace PBD + diff --git a/libs/pbd/pathscanner.cc b/libs/pbd/pathscanner.cc new file mode 100644 index 0000000000..2af227a3a0 --- /dev/null +++ b/libs/pbd/pathscanner.cc @@ -0,0 +1,203 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include +#include +#include +#include + +#include +#include +#include + +using namespace PBD; + +vector * +PathScanner::operator() (const string &dirpath, const string ®exp, + bool match_fullpath, bool return_fullpath, + long limit) + +{ + int err; + char msg[256]; + + if ((err = regcomp (&compiled_pattern, regexp.c_str(), + REG_EXTENDED|REG_NOSUB))) { + + regerror (err, &compiled_pattern, + msg, sizeof (msg)); + + error << "Cannot compile soundfile regexp for use (" + << msg + << ")" + << endmsg; + + return 0; + } + + return run_scan (dirpath, &PathScanner::regexp_filter, + (bool (*)(const string &, void *)) 0, + 0, + match_fullpath, + return_fullpath, + limit); +} + +vector * +PathScanner::run_scan (const string &dirpath, + bool (PathScanner::*memberfilter)(const string &), + bool (*filter)(const string &, void *), + void *arg, + bool match_fullpath, bool return_fullpath, + long limit) + +{ + vector *result = 0; + DIR *dir; + struct dirent *finfo; + char *pathcopy = strdup (dirpath.c_str()); + char *thisdir; + char fullpath[PATH_MAX+1]; + string search_str; + string *newstr; + long nfound = 0; + + if ((thisdir = strtok (pathcopy, ":")) == 0 || + strlen (thisdir) == 0) { + free (pathcopy); + return 0; + } + + result = new vector; + + do { + + if ((dir = opendir (thisdir)) == 0) { + continue; + } + + while ((finfo = readdir (dir)) != 0) { + + snprintf (fullpath, sizeof(fullpath), "%s/%s", + thisdir, finfo->d_name); + + if (match_fullpath) { + search_str = fullpath; + } else { + search_str = finfo->d_name; + } + + /* handle either type of function ptr */ + + if (memberfilter) { + if (!(this->*memberfilter)(search_str)) { + continue; + } + } else { + if (!filter(search_str, arg)) { + continue; + } + } + + if (return_fullpath) { + newstr = new string (fullpath); + } else { + newstr = new string (finfo->d_name); + } + + result->push_back (newstr); + nfound++; + } + + closedir (dir); + + } while ((limit < 0 || (nfound < limit)) && (thisdir = strtok (0, ":"))); + + free (pathcopy); + return result; +} + +string * +PathScanner::find_first (const string &dirpath, + const string ®exp, + bool match_fullpath, + bool return_fullpath) +{ + vector *res; + string *ret; + int err; + char msg[256]; + + if ((err = regcomp (&compiled_pattern, regexp.c_str(), + REG_EXTENDED|REG_NOSUB))) { + + regerror (err, &compiled_pattern, + msg, sizeof (msg)); + + error << "Cannot compile soundfile regexp for use (" << msg << ")" << endmsg; + + + return 0; + } + + res = run_scan (dirpath, + &PathScanner::regexp_filter, + (bool (*)(const string &, void *)) 0, + 0, + match_fullpath, + return_fullpath, + 1); + + if (res->size() == 0) { + ret = 0; + } else { + ret = res->front(); + } + vector_delete (res); + delete res; + return ret; +} + +string * +PathScanner::find_first (const string &dirpath, + bool (*filter)(const string &, void *), + void *arg, + bool match_fullpath, + bool return_fullpath) +{ + vector *res; + string *ret; + + res = run_scan (dirpath, + (bool (PathScanner::*)(const string &)) 0, + filter, + 0, + match_fullpath, + return_fullpath, 1); + + if (res->size() == 0) { + ret = 0; + } else { + ret = res->front(); + } + vector_delete (res); + delete res; + return ret; +} diff --git a/libs/pbd/pbd/.DS_Store b/libs/pbd/pbd/.DS_Store new file mode 100644 index 0000000000..5008ddfcf5 Binary files /dev/null and b/libs/pbd/pbd/.DS_Store differ diff --git a/libs/pbd/pbd/.cvsignore b/libs/pbd/pbd/.cvsignore new file mode 100644 index 0000000000..67020331ba --- /dev/null +++ b/libs/pbd/pbd/.cvsignore @@ -0,0 +1 @@ +version.h diff --git a/libs/pbd/pbd/abstract_ui.cc b/libs/pbd/pbd/abstract_ui.cc new file mode 100644 index 0000000000..0e34787a2d --- /dev/null +++ b/libs/pbd/pbd/abstract_ui.cc @@ -0,0 +1,149 @@ +#include + +#include +#include +#include + +template +AbstractUI::AbstractUI (string name, bool with_signal_pipes) + : BaseUI (name, with_signal_pipes) +{ + if (pthread_key_create (&thread_request_buffer_key, 0)) { + cerr << _("cannot create thread request buffer key") << endl; + throw failed_constructor(); + } + + PBD::ThreadCreated.connect (mem_fun (*this, &AbstractUI::register_thread)); + PBD::ThreadCreatedWithRequestSize.connect (mem_fun (*this, &AbstractUI::register_thread_with_request_count)); +} + +template void +AbstractUI::register_thread (pthread_t thread_id, string name) +{ + register_thread_with_request_count (thread_id, name, 256); +} + +template void +AbstractUI::register_thread_with_request_count (pthread_t thread_id, string thread_name, uint32_t num_requests) +{ + RequestBuffer* b = new RequestBuffer (num_requests); + + { + Glib::Mutex::Lock lm (request_buffer_map_lock); + request_buffers[thread_id] = b; + } + + pthread_setspecific (thread_request_buffer_key, b); +} + +template RequestObject* +AbstractUI::get_request (RequestType rt) +{ + RequestBuffer* rbuf = static_cast(pthread_getspecific (thread_request_buffer_key)); + + if (rbuf == 0) { + /* Cannot happen, but if it does we can't use the error reporting mechanism */ + cerr << _("programming error: ") + << string_compose (X_("no %1-UI request buffer found for thread %2"), name(), pthread_name()) + << endl; + abort (); + } + + RequestBufferVector vec; + + rbuf->get_write_vector (&vec); + + if (vec.len[0] == 0) { + if (vec.len[1] == 0) { + cerr << string_compose (X_("no space in %1-UI request buffer for thread %2"), name(), pthread_name()) + << endl; + return 0; + } else { + vec.buf[1]->type = rt; + return vec.buf[1]; + } + } else { + vec.buf[0]->type = rt; + return vec.buf[0]; + } +} + +template void +AbstractUI::handle_ui_requests () +{ + RequestBufferMapIterator i; + + request_buffer_map_lock.lock (); + + for (i = request_buffers.begin(); i != request_buffers.end(); ++i) { + + RequestBufferVector vec; + + while (true) { + + /* we must process requests 1 by 1 because + the request may run a recursive main + event loop that will itself call + handle_ui_requests. when we return + from the request handler, we cannot + expect that the state of queued requests + is even remotely consistent with + the condition before we called it. + */ + + i->second->get_read_vector (&vec); + + if (vec.len[0] == 0) { + break; + } else { + /* request_factory/copy constructor does a deep + copy of the Request object, + unlike Ringbuffer::read() + */ + + RequestObject req (*vec.buf[0]); + i->second->increment_read_ptr (1); + request_buffer_map_lock.unlock (); + do_request (&req); + request_buffer_map_lock.lock (); + } + } + } + + request_buffer_map_lock.unlock (); +} + +template void +AbstractUI::send_request (RequestObject *req) +{ + if (base_instance() == 0) { + return; /* XXX is this the right thing to do ? */ + } + + if (caller_is_ui_thread()) { + // cerr << "GUI thread sent request " << req << " type = " << req->type << endl; + do_request (req); + } else { + RequestBuffer* rbuf = static_cast (pthread_getspecific (thread_request_buffer_key)); + + if (rbuf == 0) { + /* can't use the error system to report this, because this + thread isn't registered! + */ + cerr << _("programming error: ") + << string_compose (X_("AbstractUI::send_request() called from %1, but no request buffer exists for that thread"), pthread_name()) + << endl; + abort (); + } + + // cerr << "thread " << pthread_self() << " sent request " << req << " type = " << req->type << endl; + + rbuf->increment_write_ptr (1); + + if (signal_pipe[1] >= 0) { + const char c = 0; + write (signal_pipe[1], &c, 1); + } + } +} + diff --git a/libs/pbd/pbd/abstract_ui.h b/libs/pbd/pbd/abstract_ui.h new file mode 100644 index 0000000000..f80db7bf1a --- /dev/null +++ b/libs/pbd/pbd/abstract_ui.h @@ -0,0 +1,79 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __pbd_abstract_ui_h__ +#define __pbd_abstract_ui_h__ + +#include +#include +#include + +#include + +#include + +#include +#include +#include + +class Touchable; + +template +class AbstractUI : public BaseUI +{ + public: + AbstractUI (std::string name, bool with_signal_pipe); + virtual ~AbstractUI() {} + + virtual bool caller_is_ui_thread() = 0; + + void call_slot (sigc::slot el_slot) { + RequestObject *req = get_request (BaseUI::CallSlot); + + if (req == 0) { + return; + } + + req->slot = el_slot; + send_request (req); + } + + void register_thread (pthread_t, std::string); + void register_thread_with_request_count (pthread_t, std::string, uint32_t num_requests); + + protected: + typedef RingBufferNPT RequestBuffer; + typedef typename RequestBuffer::rw_vector RequestBufferVector; + typedef typename std::map::iterator RequestBufferMapIterator; + + Glib::Mutex request_buffer_map_lock; + typedef std::map RequestBufferMap; + RequestBufferMap request_buffers; + pthread_key_t thread_request_buffer_key; + RequestObject* get_request (RequestType); + void handle_ui_requests (); + void send_request (RequestObject *); + + virtual void do_request (RequestObject *) = 0; +}; + +#endif /* __pbd_abstract_ui_h__ */ + + diff --git a/libs/pbd/pbd/base_ui.h b/libs/pbd/pbd/base_ui.h new file mode 100644 index 0000000000..b4570f8707 --- /dev/null +++ b/libs/pbd/pbd/base_ui.h @@ -0,0 +1,46 @@ +#ifndef __pbd_base_ui_h__ +#define __pbd_base_ui_h__ + +#include +#include + +#include +#include + +class BaseUI : virtual public sigc::trackable { + public: + BaseUI (std::string name, bool with_signal_pipes); + virtual ~BaseUI(); + + BaseUI* base_instance() { return base_ui_instance; } + + std::string name() const { return _name; } + + bool ok() const { return _ok; } + + enum RequestType { + range_guarantee = ~0 + }; + + struct BaseRequestObject { + RequestType type; + sigc::slot the_slot; + }; + + static RequestType new_request_type(); + static RequestType CallSlot; + + protected: + int signal_pipe[2]; + bool _ok; + + private: + std::string _name; + BaseUI* base_ui_instance; + + static uint32_t rt_bit; + + int setup_signal_pipe (); +}; + +#endif /* __pbd_base_ui_h__ */ diff --git a/libs/pbd/pbd/basename.h b/libs/pbd/pbd/basename.h new file mode 100644 index 0000000000..35aebe166c --- /dev/null +++ b/libs/pbd/pbd/basename.h @@ -0,0 +1,13 @@ +#ifndef __stupid_basename_h__ +#define __stupid_basename_h__ + +#include + +namespace PBD +{ + +extern std::string basename_nosuffix (const std::string&); + +}; + +#endif // __stupid_basename_h__ diff --git a/libs/pbd/pbd/compose.h b/libs/pbd/pbd/compose.h new file mode 100644 index 0000000000..0df9519aaf --- /dev/null +++ b/libs/pbd/pbd/compose.h @@ -0,0 +1,393 @@ +/* Defines String::compose(fmt, arg...) for easy, i18n-friendly + * composition of strings. + * + * Version 1.0. + * + * Copyright (c) 2002 Ole Laursen . + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +// +// Basic usage is like +// +// std::cout << String::compose("This is a %1x%2 matrix.", rows, cols); +// +// See http://www.cs.auc.dk/~olau/compose/ or the included README.compose for +// more details. +// + +#ifndef STRING_COMPOSE_H +#define STRING_COMPOSE_H + +#include +#include +#include +#include // for multimap + +namespace StringPrivate +{ + // the actual composition class - using string::compose is cleaner, so we + // hide it here + class Composition + { + public: + // initialize and prepare format string on the form "text %1 text %2 etc." + explicit Composition(std::string fmt); + + // supply an replacement argument starting from %1 + template + Composition &arg(const T &obj); + + // compose and return string + std::string str() const; + + private: + std::ostringstream os; + int arg_no; + + // we store the output as a list - when the output string is requested, the + // list is concatenated to a string; this way we can keep iterators into + // the list instead of into a string where they're possibly invalidated on + // inserting a specification string + typedef std::list output_list; + output_list output; + + // the initial parse of the format string fills in the specification map + // with positions for each of the various %?s + typedef std::multimap specification_map; + specification_map specs; + }; + + // helper for converting spec string numbers + inline int char_to_int(char c) + { + switch (c) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + default: return -1000; + } + } + + inline bool is_number(int n) + { + switch (n) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return true; + + default: + return false; + } + } + + + // implementation of class Composition + template + inline Composition &Composition::arg(const T &obj) + { + os << obj; + + std::string rep = os.str(); + + if (!rep.empty()) { // manipulators don't produce output + for (specification_map::const_iterator i = specs.lower_bound(arg_no), + end = specs.upper_bound(arg_no); i != end; ++i) { + output_list::iterator pos = i->second; + ++pos; + + output.insert(pos, rep); + } + + os.str(std::string()); + //os.clear(); + ++arg_no; + } + + return *this; + } + + inline Composition::Composition(std::string fmt) + : arg_no(1) + { + std::string::size_type b = 0, i = 0; + + // fill in output with the strings between the %1 %2 %3 etc. and + // fill in specs with the positions + while (i < fmt.length()) { + if (fmt[i] == '%' && i + 1 < fmt.length()) { + if (fmt[i + 1] == '%') { // catch %% + fmt.replace(i, 2, "%"); + ++i; + } + else if (is_number(fmt[i + 1])) { // aha! a spec! + // save string + output.push_back(fmt.substr(b, i - b)); + + int n = 1; // number of digits + int spec_no = 0; + + do { + spec_no += char_to_int(fmt[i + n]); + spec_no *= 10; + ++n; + } while (i + n < fmt.length() && is_number(fmt[i + n])); + + spec_no /= 10; + output_list::iterator pos = output.end(); + --pos; // safe since we have just inserted a string> + + specs.insert(specification_map::value_type(spec_no, pos)); + + // jump over spec string + i += n; + b = i; + } + else + ++i; + } + else + ++i; + } + + if (i - b > 0) // add the rest of the string + output.push_back(fmt.substr(b, i - b)); + } + + inline std::string Composition::str() const + { + // assemble string + std::string str; + + for (output_list::const_iterator i = output.begin(), end = output.end(); + i != end; ++i) + str += *i; + + return str; + } +} + +// now for the real thing(s) +//namespace PBD +//{ + // a series of functions which accept a format string on the form "text %1 + // more %2 less %3" and a number of templated parameters and spits out the + // composited string + template + inline std::string string_compose(const std::string &fmt, const T1 &o1) + { + StringPrivate::Composition c(fmt); + c.arg(o1); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4, const T5 &o5) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4, const T5 &o5, const T6 &o6) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4, const T5 &o5, const T6 &o6, + const T7 &o7) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4, const T5 &o5, const T6 &o6, + const T7 &o7, const T8 &o8) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4, const T5 &o5, const T6 &o6, + const T7 &o7, const T8 &o8, const T9 &o9) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4, const T5 &o5, const T6 &o6, + const T7 &o7, const T8 &o8, const T9 &o9, + const T10 &o10) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9) + .arg(o10); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4, const T5 &o5, const T6 &o6, + const T7 &o7, const T8 &o8, const T9 &o9, + const T10 &o10, const T11 &o11) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9) + .arg(o10).arg(o11); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4, const T5 &o5, const T6 &o6, + const T7 &o7, const T8 &o8, const T9 &o9, + const T10 &o10, const T11 &o11, const T12 &o12) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9) + .arg(o10).arg(o11).arg(o12); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4, const T5 &o5, const T6 &o6, + const T7 &o7, const T8 &o8, const T9 &o9, + const T10 &o10, const T11 &o11, const T12 &o12, + const T13 &o13) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9) + .arg(o10).arg(o11).arg(o12).arg(o13); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4, const T5 &o5, const T6 &o6, + const T7 &o7, const T8 &o8, const T9 &o9, + const T10 &o10, const T11 &o11, const T12 &o12, + const T13 &o13, const T14 &o14) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9) + .arg(o10).arg(o11).arg(o12).arg(o13).arg(o14); + return c.str(); + } + + template + inline std::string string_compose(const std::string &fmt, + const T1 &o1, const T2 &o2, const T3 &o3, + const T4 &o4, const T5 &o5, const T6 &o6, + const T7 &o7, const T8 &o8, const T9 &o9, + const T10 &o10, const T11 &o11, const T12 &o12, + const T13 &o13, const T14 &o14, const T15 &o15) + { + StringPrivate::Composition c(fmt); + c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9) + .arg(o10).arg(o11).arg(o12).arg(o13).arg(o14).arg(o15); + return c.str(); + } +//} + + +#endif // STRING_COMPOSE_H diff --git a/libs/pbd/pbd/convert.h b/libs/pbd/pbd/convert.h new file mode 100644 index 0000000000..12e63ba6fc --- /dev/null +++ b/libs/pbd/pbd/convert.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2002 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __pbd_convert_h__ +#define __pbd_convert_h__ + +#include +#include + +namespace PBD { + +std::string short_version (std::string, std::string::size_type target_length); + +int atoi (const std::string&); +double atof (const std::string&); +void url_decode (std::string&); + +std::string length2string (const int32_t frames, const float sample_rate); + +std::vector internationalize (const char **); + +} //namespace PBD + +#endif /* __pbd_convert_h__ */ diff --git a/libs/pbd/pbd/error.h b/libs/pbd/pbd/error.h new file mode 100644 index 0000000000..4136f02ee2 --- /dev/null +++ b/libs/pbd/pbd/error.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 1998-2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ +#ifndef __libpbd_error_h__ +#define __libpbd_error_h__ + +#include "transmitter.h" + +namespace PBD { + extern Transmitter error; + extern Transmitter info; + extern Transmitter warning; + extern Transmitter fatal; +} + +#endif // __libpbd_error_h__ diff --git a/libs/pbd/pbd/failed_constructor.h b/libs/pbd/pbd/failed_constructor.h new file mode 100644 index 0000000000..62eb6c0d71 --- /dev/null +++ b/libs/pbd/pbd/failed_constructor.h @@ -0,0 +1,11 @@ +#ifndef __pbd_failed_constructor_h__ +#define __pbd_failed_constructor_h__ + +#include + +class failed_constructor : public std::exception { + public: + virtual const char *what() const throw() { return "failed constructor"; } +}; + +#endif /* __pbd_failed_constructor_h__ */ diff --git a/libs/pbd/pbd/fastlog.h b/libs/pbd/pbd/fastlog.h new file mode 100644 index 0000000000..4269705a44 --- /dev/null +++ b/libs/pbd/pbd/fastlog.h @@ -0,0 +1,40 @@ +/* Copyright unknown. Code by Laurent de Soras . + */ + +#ifndef __pbd_fastlog_h__ +#define __pbd_fastlog_h__ + +#include /* for HUGE_VAL */ + +static inline float fast_log2 (float val) +{ + /* don't use reinterpret_cast<> because that prevents this + from being used by pure C code (for example, GnomeCanvasItems) + */ + union {float f; int i;} t; + t.f = val; + int * const exp_ptr = &t.i; + int x = *exp_ptr; + const int log_2 = ((x >> 23) & 255) - 128; + x &= ~(255 << 23); + x += 127 << 23; + *exp_ptr = x; + + val = ((-1.0f/3) * t.f + 2) * t.f - 2.0f/3; + + return (val + log_2); +} + +static inline float fast_log (const float val) +{ + return (fast_log2 (val) * 0.69314718f); +} + +static inline float fast_log10 (const float val) +{ + return fast_log2(val) / 3.312500f; +} + +static inline float minus_infinity() { return -HUGE_VAL; } + +#endif /* __pbd_fastlog_h__ */ diff --git a/libs/pbd/pbd/forkexec.h b/libs/pbd/pbd/forkexec.h new file mode 100644 index 0000000000..2af3711390 --- /dev/null +++ b/libs/pbd/pbd/forkexec.h @@ -0,0 +1,9 @@ +#ifndef __forkexec_h__ +#define __forkexec_h__ + +#include + +pid_t forkexec(char **argv, char **envp, int outpipe[2], int inpipe[2]); +pid_t forkexec_cmd(char *cmd, char **envp, int outpipe[2], int inpipe[2]); + +#endif // __forkexec_h__ diff --git a/libs/pbd/pbd/mathfix.h b/libs/pbd/pbd/mathfix.h new file mode 100644 index 0000000000..f0dc7e491e --- /dev/null +++ b/libs/pbd/pbd/mathfix.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2005 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __pbd_mathfix_h__ +#define __pbd_mathfix_h__ + +/* this is necessary to support older releases of OSX where + they moved around some of the standard math functions +*/ + +#ifdef __APPLE__ +#define powf pow +#define sqrtf sqrt +#endif + + +#endif diff --git a/libs/pbd/pbd/mountpoint.h b/libs/pbd/pbd/mountpoint.h new file mode 100644 index 0000000000..86ccc58190 --- /dev/null +++ b/libs/pbd/pbd/mountpoint.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __pbd_mountpoint_h__ +#define __pbd_mountpoint_h__ + +#include + +std::string mountpoint (std::string path); + +#endif // __pbd_mountpoint_h__ diff --git a/libs/pbd/pbd/path.h b/libs/pbd/pbd/path.h new file mode 100644 index 0000000000..0b77a7c237 --- /dev/null +++ b/libs/pbd/pbd/path.h @@ -0,0 +1,113 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef PBD_PATH +#define PBD_PATH + +#include +#include + +namespace PBD { + +using std::string; +using std::vector; + +/** + The Path class is a helper class for getting a vector of absolute + paths contained in a path string where a path string contains + absolute directory paths separated by a colon(:) or a semi-colon(;) + on windows. + */ +class Path { +public: + + /** + Create an empty Path. + */ + Path (); + + /** + Initialize Path from a string, each absolute path contained + in the "path" will be accessed to ensure it exists and is + readable. + \param path A path string. + */ + Path (const string& path); + + /** + Initialize Path from a vector of path strings, each absolute + path contained in paths will be accessed to ensure it + exists and is readable. + \param path A path string. + */ + Path (const vector& paths); + + Path(const Path& path); + + /** + Indicate whether there are any directories in m_dirs, if Path is + initialized with an empty string as the result of for instance + calling Glib::getenv where the environment variable doesn't + exist or if none of the directories in the path string are + accessible then false is returned. + + \return true if there are any paths in m_paths. + */ + //operator bool () const { return !m_dirs.empty(); } + + /** + \return vector containing the absolute paths to the directories + contained + */ + operator const vector& () const { return m_dirs; } + + /** + \return vector containing the absolute paths to the directories + contained + */ + const vector& dirs () const { return m_dirs; } + + const string path_string() const; + + const Path& operator= (const Path& path); + + const Path& operator+= (const string& directory_path); + + Path& add_subdirectory_to_path (const string& subdirectory); + +protected: + + friend const Path operator+ (const Path&, const Path&); + + bool readable_directory (const string& directory_path); + + void add_readable_directory (const string& directory_path); + + void add_readable_directories (const vector& paths); + + vector m_dirs; + +}; + +bool find_file_in_path (const Path& path, const string& filename, string& resulting_path_to_file); + +} // namespace PBD + +#endif // PBD_PATH + + diff --git a/libs/pbd/pbd/pathscanner.h b/libs/pbd/pbd/pathscanner.h new file mode 100644 index 0000000000..346e7858c4 --- /dev/null +++ b/libs/pbd/pbd/pathscanner.h @@ -0,0 +1,66 @@ +#ifndef __libmisc_pathscanner_h__ +#define __libmisc_pathscanner_h__ + +#include +#include +#include + +using std::string; +using std::vector; + +class PathScanner + +{ + public: + vector *operator() (const string &dirpath, + bool (*filter)(const string &, void *arg), + void *arg, + bool match_fullpath = true, + bool return_fullpath = true, + long limit = -1) { + return run_scan (dirpath, + (bool (PathScanner::*)(const string &)) 0, + filter, + arg, + match_fullpath, + return_fullpath, + limit); + } + + vector *operator() (const string &dirpath, + const string ®exp, + bool match_fullpath = true, + bool return_fullpath = true, + long limit = -1); + + + string *find_first (const string &dirpath, + const string ®exp, + bool match_fullpath = true, + bool return_fullpath = true); + + string *find_first (const string &dirpath, + bool (*filter)(const string &, void *), + void *arg, + bool match_fullpath = true, + bool return_fullpath = true); + + private: + regex_t compiled_pattern; + + bool regexp_filter (const string &str) { + return regexec (&compiled_pattern, str.c_str(), 0, 0, 0) == 0; + } + + vector *run_scan (const string &dirpath, + bool (PathScanner::*mfilter) (const string &), + bool (*filter)(const string &, void *), + void *arg, + bool match_fullpath, + bool return_fullpath, + long limit); + + +}; + +#endif // __libmisc_pathscanner_h__ diff --git a/libs/pbd/pbd/pool.h b/libs/pbd/pbd/pool.h new file mode 100644 index 0000000000..f8e19e72fb --- /dev/null +++ b/libs/pbd/pbd/pool.h @@ -0,0 +1,75 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __qm_pool_h__ +#define __qm_pool_h__ + +#include +#include + +#include + +#include + +class Pool +{ + public: + Pool (std::string name, unsigned long item_size, unsigned long nitems); + virtual ~Pool (); + + virtual void *alloc (); + virtual void release (void *); + + std::string name() const { return _name; } + + private: + RingBuffer* free_list; + std::string _name; + void *block; +}; + +class SingleAllocMultiReleasePool : public Pool +{ + public: + SingleAllocMultiReleasePool (std::string name, unsigned long item_size, unsigned long nitems); + ~SingleAllocMultiReleasePool (); + + virtual void *alloc (); + virtual void release (void *); + + private: + Glib::Mutex* m_lock; +}; + + +class MultiAllocSingleReleasePool : public Pool +{ + public: + MultiAllocSingleReleasePool (std::string name, unsigned long item_size, unsigned long nitems); + ~MultiAllocSingleReleasePool (); + + virtual void *alloc (); + virtual void release (void *); + + private: + Glib::Mutex* m_lock; +}; + +#endif // __qm_pool_h__ diff --git a/libs/pbd/pbd/pthread_utils.h b/libs/pbd/pbd/pthread_utils.h new file mode 100644 index 0000000000..482b5b54cf --- /dev/null +++ b/libs/pbd/pbd/pthread_utils.h @@ -0,0 +1,23 @@ +#ifndef __pbd_pthread_utils__ +#define __pbd_pthread_utils__ + +#include +#include +#include +#include + +#include + +int pthread_create_and_store (std::string name, pthread_t *thread, pthread_attr_t *attr, void * (*start_routine)(void *), void * arg); +void pthread_cancel_one (pthread_t thread); +void pthread_kill_all (int signum); +void pthread_cancel_all (); +void pthread_exit_pbd (void* status); +std::string pthread_name (); + +namespace PBD { + extern sigc::signal ThreadCreated; + extern sigc::signal ThreadCreatedWithRequestSize; +} + +#endif /* __pbd_pthread_utils__ */ diff --git a/libs/pbd/pbd/receiver.h b/libs/pbd/pbd/receiver.h new file mode 100644 index 0000000000..5ce238df63 --- /dev/null +++ b/libs/pbd/pbd/receiver.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __libmisc_receiver_h__ +#define __libmisc_receiver_h__ + +#include + +#include + +#include "transmitter.h" + +using std::vector; + +class strstream; + +class Receiver : virtual public sigc::trackable +{ + public: + Receiver (); + virtual ~Receiver (); + + void listen_to (Transmitter &); + void hangup (); + + protected: + virtual void receive (Transmitter::Channel, const char *) = 0; + + private: + vector connections; +}; + +#endif // __libmisc_receiver_h__ diff --git a/libs/pbd/pbd/restartable_rw.h b/libs/pbd/pbd/restartable_rw.h new file mode 100644 index 0000000000..ee84e4e295 --- /dev/null +++ b/libs/pbd/pbd/restartable_rw.h @@ -0,0 +1,7 @@ +#ifndef __libmisc_restartable_rw__h__ +#define __libmisc_restartable_rw__h__ + +extern int restartable_write (int fd, unsigned char *buf, size_t cnt); +extern int restartable_read (int fd, unsigned char *buf, size_t cnt); + +#endif // __libmisc_restartable_rw__h__ diff --git a/libs/pbd/pbd/ringbuffer.h b/libs/pbd/pbd/ringbuffer.h new file mode 100644 index 0000000000..1d9c9b04e3 --- /dev/null +++ b/libs/pbd/pbd/ringbuffer.h @@ -0,0 +1,284 @@ +/* + Copyright (C) 2000 Paul Davis & Benno Senoner + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef ringbuffer_h +#define ringbuffer_h + +//#include + +#include + +template +class RingBuffer +{ + public: + RingBuffer (size_t sz) { + size_t power_of_two; + + for (power_of_two = 1; 1U< r) { + return ((r - w + size) & size_mask) - 1; + } else if (w < r) { + return (r - w) - 1; + } else { + return size - 1; + } + } + + size_t read_space () { + size_t w, r; + + w = g_atomic_int_get (&write_ptr); + r = g_atomic_int_get (&read_ptr); + + if (w > r) { + return w - r; + } else { + return (w - r + size) & size_mask; + } + } + + T *buffer () { return buf; } + size_t get_write_ptr () const { return g_atomic_int_get (&write_ptr); } + size_t get_read_ptr () const { return g_atomic_int_get (&read_ptr); } + size_t bufsize () const { return size; } + + protected: + T *buf; + size_t size; + mutable gint write_ptr; + mutable gint read_ptr; + size_t size_mask; +}; + +template size_t +RingBuffer::read (T *dest, size_t cnt) +{ + size_t free_cnt; + size_t cnt2; + size_t to_read; + size_t n1, n2; + size_t priv_read_ptr; + + priv_read_ptr=g_atomic_int_get(&read_ptr); + + if ((free_cnt = read_space ()) == 0) { + return 0; + } + + to_read = cnt > free_cnt ? free_cnt : cnt; + + cnt2 = priv_read_ptr + to_read; + + if (cnt2 > size) { + n1 = size - priv_read_ptr; + n2 = cnt2 & size_mask; + } else { + n1 = to_read; + n2 = 0; + } + + memcpy (dest, &buf[priv_read_ptr], n1 * sizeof (T)); + priv_read_ptr = (priv_read_ptr + n1) & size_mask; + + if (n2) { + memcpy (dest+n1, buf, n2 * sizeof (T)); + priv_read_ptr = n2; + } + + g_atomic_int_set(&read_ptr, priv_read_ptr); + return to_read; +} + +template size_t +RingBuffer::write (T *src, size_t cnt) + +{ + size_t free_cnt; + size_t cnt2; + size_t to_write; + size_t n1, n2; + size_t priv_write_ptr; + + priv_write_ptr=g_atomic_int_get(&write_ptr); + + if ((free_cnt = write_space ()) == 0) { + return 0; + } + + to_write = cnt > free_cnt ? free_cnt : cnt; + + cnt2 = priv_write_ptr + to_write; + + if (cnt2 > size) { + n1 = size - priv_write_ptr; + n2 = cnt2 & size_mask; + } else { + n1 = to_write; + n2 = 0; + } + + memcpy (&buf[priv_write_ptr], src, n1 * sizeof (T)); + priv_write_ptr = (priv_write_ptr + n1) & size_mask; + + if (n2) { + memcpy (buf, src+n1, n2 * sizeof (T)); + priv_write_ptr = n2; + } + + g_atomic_int_set(&write_ptr, priv_write_ptr); + return to_write; +} + +template void +RingBuffer::get_read_vector (RingBuffer::rw_vector *vec) + +{ + size_t free_cnt; + size_t cnt2; + size_t w, r; + + w = g_atomic_int_get (&write_ptr); + r = g_atomic_int_get (&read_ptr); + + if (w > r) { + free_cnt = w - r; + } else { + free_cnt = (w - r + size) & size_mask; + } + + cnt2 = r + free_cnt; + + if (cnt2 > size) { + /* Two part vector: the rest of the buffer after the + current write ptr, plus some from the start of + the buffer. + */ + + vec->buf[0] = &buf[r]; + vec->len[0] = size - r; + vec->buf[1] = buf; + vec->len[1] = cnt2 & size_mask; + + } else { + + /* Single part vector: just the rest of the buffer */ + + vec->buf[0] = &buf[r]; + vec->len[0] = free_cnt; + vec->len[1] = 0; + } +} + +template void +RingBuffer::get_write_vector (RingBuffer::rw_vector *vec) + +{ + size_t free_cnt; + size_t cnt2; + size_t w, r; + + w = g_atomic_int_get (&write_ptr); + r = g_atomic_int_get (&read_ptr); + + if (w > r) { + free_cnt = ((r - w + size) & size_mask) - 1; + } else if (w < r) { + free_cnt = (r - w) - 1; + } else { + free_cnt = size - 1; + } + + cnt2 = w + free_cnt; + + if (cnt2 > size) { + + /* Two part vector: the rest of the buffer after the + current write ptr, plus some from the start of + the buffer. + */ + + vec->buf[0] = &buf[w]; + vec->len[0] = size - w; + vec->buf[1] = buf; + vec->len[1] = cnt2 & size_mask; + } else { + vec->buf[0] = &buf[w]; + vec->len[0] = free_cnt; + vec->len[1] = 0; + } +} + + +#endif /* __ringbuffer_h__ */ diff --git a/libs/pbd/pbd/ringbufferNPT.h b/libs/pbd/pbd/ringbufferNPT.h new file mode 100644 index 0000000000..fee2efce3d --- /dev/null +++ b/libs/pbd/pbd/ringbufferNPT.h @@ -0,0 +1,275 @@ +/* + Copyright (C) 2000 Paul Davis & Benno Senoner + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef ringbuffer_npt_h +#define ringbuffer_npt_h + +//#include + +#include + +/* ringbuffer class where the element size is not required to be a power of two */ + +template +class RingBufferNPT +{ + public: + RingBufferNPT (size_t sz) { + size = sz; + buf = new T[size]; + reset (); + + }; + + virtual ~RingBufferNPT() { + delete [] buf; + } + + void reset () { + /* !!! NOT THREAD SAFE !!! */ + g_atomic_int_set (&write_ptr, 0); + g_atomic_int_set (&read_ptr, 0); + } + + void set (size_t r, size_t w) { + /* !!! NOT THREAD SAFE !!! */ + g_atomic_int_set (&write_ptr, w); + g_atomic_int_set (&read_ptr, r); + } + + size_t read (T *dest, size_t cnt); + size_t write (T *src, size_t cnt); + + struct rw_vector { + T *buf[2]; + size_t len[2]; + }; + + void get_read_vector (rw_vector *); + void get_write_vector (rw_vector *); + + void decrement_read_ptr (size_t cnt) { + g_atomic_int_set (&read_ptr, (g_atomic_int_get(&read_ptr) - cnt) % size); + } + + void increment_read_ptr (size_t cnt) { + g_atomic_int_set (&read_ptr, (g_atomic_int_get(&read_ptr) + cnt) % size); + } + + void increment_write_ptr (size_t cnt) { + g_atomic_int_set (&write_ptr, (g_atomic_int_get(&write_ptr) + cnt) % size); + } + + size_t write_space () { + size_t w, r; + + w = g_atomic_int_get (&write_ptr); + r = g_atomic_int_get (&read_ptr); + + if (w > r) { + return ((r - w + size) % size) - 1; + } else if (w < r) { + return (r - w) - 1; + } else { + return size - 1; + } + } + + size_t read_space () { + size_t w, r; + + w = g_atomic_int_get (&write_ptr); + r = g_atomic_int_get (&read_ptr); + + if (w > r) { + return w - r; + } else { + return (w - r + size) % size; + } + } + + T *buffer () { return buf; } + size_t get_write_ptr () const { return g_atomic_int_get (&write_ptr); } + size_t get_read_ptr () const { return g_atomic_int_get (&read_ptr); } + size_t bufsize () const { return size; } + + protected: + T *buf; + size_t size; + mutable gint write_ptr; + mutable gint read_ptr; +}; + +template size_t +RingBufferNPT::read (T *dest, size_t cnt) +{ + size_t free_cnt; + size_t cnt2; + size_t to_read; + size_t n1, n2; + size_t priv_read_ptr; + + priv_read_ptr=g_atomic_int_get(&read_ptr); + + if ((free_cnt = read_space ()) == 0) { + return 0; + } + + to_read = cnt > free_cnt ? free_cnt : cnt; + + cnt2 = priv_read_ptr + to_read; + + if (cnt2 > size) { + n1 = size - priv_read_ptr; + n2 = cnt2 % size; + } else { + n1 = to_read; + n2 = 0; + } + + memcpy (dest, &buf[priv_read_ptr], n1 * sizeof (T)); + priv_read_ptr = (priv_read_ptr + n1) % size; + + if (n2) { + memcpy (dest+n1, buf, n2 * sizeof (T)); + priv_read_ptr = n2; + } + + g_atomic_int_set(&read_ptr, priv_read_ptr); + return to_read; +} + +template size_t +RingBufferNPT::write (T *src, size_t cnt) +{ + size_t free_cnt; + size_t cnt2; + size_t to_write; + size_t n1, n2; + size_t priv_write_ptr; + + priv_write_ptr=g_atomic_int_get(&write_ptr); + + if ((free_cnt = write_space ()) == 0) { + return 0; + } + + to_write = cnt > free_cnt ? free_cnt : cnt; + + cnt2 = priv_write_ptr + to_write; + + if (cnt2 > size) { + n1 = size - priv_write_ptr; + n2 = cnt2 % size; + } else { + n1 = to_write; + n2 = 0; + } + + memcpy (&buf[priv_write_ptr], src, n1 * sizeof (T)); + priv_write_ptr = (priv_write_ptr + n1) % size; + + if (n2) { + memcpy (buf, src+n1, n2 * sizeof (T)); + priv_write_ptr = n2; + } + + g_atomic_int_set(&write_ptr, priv_write_ptr); + return to_write; +} + +template void +RingBufferNPT::get_read_vector (RingBufferNPT::rw_vector *vec) +{ + size_t free_cnt; + size_t cnt2; + size_t w, r; + + w = g_atomic_int_get (&write_ptr); + r = g_atomic_int_get (&read_ptr); + + if (w > r) { + free_cnt = w - r; + } else { + free_cnt = (w - r + size) % size; + } + + cnt2 = r + free_cnt; + + if (cnt2 > size) { + /* Two part vector: the rest of the buffer after the + current write ptr, plus some from the start of + the buffer. + */ + + vec->buf[0] = &buf[r]; + vec->len[0] = size - r; + vec->buf[1] = buf; + vec->len[1] = cnt2 % size; + + } else { + + /* Single part vector: just the rest of the buffer */ + + vec->buf[0] = &buf[r]; + vec->len[0] = free_cnt; + vec->len[1] = 0; + } +} + +template void +RingBufferNPT::get_write_vector (RingBufferNPT::rw_vector *vec) +{ + size_t free_cnt; + size_t cnt2; + size_t w, r; + + w = g_atomic_int_get (&write_ptr); + r = g_atomic_int_get (&read_ptr); + + if (w > r) { + free_cnt = ((r - w + size) % size) - 1; + } else if (w < r) { + free_cnt = (r - w) - 1; + } else { + free_cnt = size - 1; + } + + cnt2 = w + free_cnt; + + if (cnt2 > size) { + + /* Two part vector: the rest of the buffer after the + current write ptr, plus some from the start of + the buffer. + */ + + vec->buf[0] = &buf[w]; + vec->len[0] = size - w; + vec->buf[1] = buf; + vec->len[1] = cnt2 % size; + } else { + vec->buf[0] = &buf[w]; + vec->len[0] = free_cnt; + vec->len[1] = 0; + } +} + +#endif /* __ringbuffer_npt_h__ */ diff --git a/libs/pbd/pbd/selectable.h b/libs/pbd/pbd/selectable.h new file mode 100644 index 0000000000..470bc3cfcc --- /dev/null +++ b/libs/pbd/pbd/selectable.h @@ -0,0 +1,102 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __selectable_h__ +#define __selectable_h__ + +#include +#include +#include + +#include + +#include + +namespace Select { + enum Condition { + Readable = 0x1, + Writable = 0x2, + Exception = 0x4 + }; + +class Selectable : public sigc::trackable + +{ + public: + Selectable (int fd); + Selectable (const std::string &, int flags, int mode = 0); + Selectable (FILE *); + ~Selectable (); + + sigc::signal readable; + sigc::signal writable; + sigc::signal exceptioned; + + int fd() { return _fd; } + bool ok() { return _ok; } + + protected: + void selected (unsigned int condition); + int condition; + int _fd; + + friend class Selector; + + private: + enum { + fromFD, + fromPath, + fromFILE + }; + + bool _ok; + int _type; + std::string path; +}; + +class Selector { + private: + int post_select (fd_set *, fd_set *, fd_set *); + int _max_fd; + + typedef std::list Selectables; + Selectables selectables; + pthread_mutex_t list_lock; + + static bool use_list_lock; + + public: + Selector (); + + void multithreaded (bool yn) { + use_list_lock = yn; + } + + void add (int condition, Selectable *s); + void remove (Selectable *); + int select (unsigned long usecs); +}; + + + +} /* namespace */ + + +#endif // __selectable_h__ diff --git a/libs/pbd/pbd/stacktrace.h b/libs/pbd/pbd/stacktrace.h new file mode 100644 index 0000000000..d7278bd35a --- /dev/null +++ b/libs/pbd/pbd/stacktrace.h @@ -0,0 +1,10 @@ +#ifndef __libpbd_stacktrace_h__ +#define __libpbd_stacktrace_h__ + +#include + +namespace PBD { + void stacktrace (std::ostream& out); +} + +#endif /* __libpbd_stacktrace_h__ */ diff --git a/libs/pbd/pbd/stl_delete.h b/libs/pbd/pbd/stl_delete.h new file mode 100644 index 0000000000..6e5bfa0734 --- /dev/null +++ b/libs/pbd/pbd/stl_delete.h @@ -0,0 +1,89 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __libmisc_stl_delete_h__ +#define __libmisc_stl_delete_h__ + +/* To actually use any of these deletion functions, you need to + first include the revelant container type header. +*/ +#if defined(_CPP_VECTOR) || defined(_GLIBCXX_VECTOR) || defined(__SGI_STL_VECTOR) +template void vector_delete (std::vector *vec) +{ + typename std::vector::iterator i; + + for (i = vec->begin(); i != vec->end(); i++) { + delete *i; + } + vec->clear (); +} +#endif // _CPP_VECTOR || _GLIBCXX_VECTOR || __SGI_STL_VECTOR + +#if defined(_CPP_MAP) || defined(_GLIBCXX_MAP) || defined(__SGI_STL_MAP) +template void map_delete (std::map *m) +{ + typename std::map::iterator i; + + for (i = m->begin(); i != m->end(); i++) { + delete (*i).second; + } + m->clear (); +} +#endif // _CPP_MAP || _GLIBCXX_MAP || __SGI_STL_MAP + +#if defined(_CPP_LIST) || defined(_GLIBCXX_LIST) || defined(__SGI_STL_LIST) +template void list_delete (std::list *l) +{ + typename std::list::iterator i; + + for (i = l->begin(); i != l->end(); i++) { + delete (*i); + } + + l->clear (); +} +#endif // _CPP_LIST || _GLIBCXX_LIST || __SGI_STL_LIST + +#if defined(_CPP_SLIST) || defined(_GLIBCXX_SLIST) || defined(__SGI_STL_SLIST) +template void slist_delete (std::slist *l) +{ + typename std::slist::iterator i; + + for (i = l->begin(); i != l->end(); i++) { + delete (*i); + } + + l->clear (); +} +#endif // _CPP_SLIST || _GLIBCXX_SLIST || __SGI_STL_SLIST + +#if defined(_CPP_SET) || defined(_GLIBCXX_SET) || defined(__SGI_STL_SET) +template void set_delete (std::set *sset) +{ + typename std::set::iterator i; + + for (i = sset->begin(); i != sset->end(); i++) { + delete *i; + } + sset->erase (sset->begin(), sset->end()); +} +#endif // _CPP_SET || _GLIBCXX_SET || __SGI_STL_SET + +#endif // __libmisc_stl_delete_h__ diff --git a/libs/pbd/pbd/stl_functors.h b/libs/pbd/pbd/stl_functors.h new file mode 100644 index 0000000000..4a96e91a28 --- /dev/null +++ b/libs/pbd/pbd/stl_functors.h @@ -0,0 +1,93 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __stl_functors_h__ +#define __stl_functors_h__ + +#include + +#ifndef LESS_STRING_P +struct less { + bool operator()(std::string *s1, std::string *s2) const { + return *s1 < *s2; + } +}; +#define LESS_STRING_P +#endif // LESS_STRING_P + +#ifndef LESS_CONST_STRING_P +struct less { + bool operator()(const std::string *s1, const std::string *s2) const { + return *s1 < *s2; + } +}; +#define LESS_CONST_STRING_P +#endif // LESS_CONST_STRING_P + +#ifndef LESS_CONST_CHAR_P +struct less +{ + bool operator()(const char* s1, const char* s2) const { + return strcmp(s1, s2) < 0; + } +}; +#define LESS_CONST_CHAR_P +#endif // LESS_CONST_CHAR_P + +#ifndef LESS_CONST_FLOAT_P +struct less +{ + bool operator()(const float *n1, const float *n2) const { + return *n1 < *n2; + } +}; +#define LESS_CONST_FLOAT_P +#endif // LESS_CONST_FLOAT_P + +#ifndef EQUAL_TO_CONST_CHAR_P +struct equal_to +{ + bool operator()(const char *s1, const char *s2) const { + return strcmp (s1, s2) == 0; + } +}; +#define EQUAL_TO_CONST_CHAR_P +#endif // EQUAL_TO_CONST_CHAR_P + +#ifndef EQUAL_TO_STRING_P +struct equal_to +{ + bool operator()(const std::string *s1, const std::string *s2) const { + return *s1 == *s2; + } +}; +#define EQUAL_TO_STRING_P +#endif // EQUAL_TO_STRING_P + +#ifndef LESS_CONST_STRING_R +struct less { + bool operator() (const std::string &s1, const std::string &s2) { + return s1 < s2; + } +}; +#define LESS_CONST_STRING_R +#endif // EQUAL_TO_STRING_P + +#endif // __stl_functors_h__ diff --git a/libs/pbd/pbd/strsplit.h b/libs/pbd/pbd/strsplit.h new file mode 100644 index 0000000000..e55ad1c825 --- /dev/null +++ b/libs/pbd/pbd/strsplit.h @@ -0,0 +1,9 @@ +#ifndef __pbd_strplit_h__ +#define __pbd_strplit_h__ + +#include +#include + +extern void split (std::string, std::vector&, char); + +#endif // __pbd_strplit_h__ diff --git a/libs/pbd/pbd/textreceiver.h b/libs/pbd/pbd/textreceiver.h new file mode 100644 index 0000000000..b8bfe5bc78 --- /dev/null +++ b/libs/pbd/pbd/textreceiver.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __libmisc_textreceiver_h__ +#define __libmisc_textreceiver_h__ + +#include + +#include "receiver.h" + +using std::string; +using std::cout; +using std::endl; + +class TextReceiver : public Receiver +{ + public: + TextReceiver (const string &n); + + protected: + void receive (Transmitter::Channel, const char *); + + private: + string name; +}; + +#endif //__libmisc_textreceiver_h__ diff --git a/libs/pbd/pbd/thrown_error.h b/libs/pbd/pbd/thrown_error.h new file mode 100644 index 0000000000..83cf8acfac --- /dev/null +++ b/libs/pbd/pbd/thrown_error.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ +#ifndef __qm_thrown_error_h__ +#define __qm_thrown_error_h__ + +#include "transmitter.h" + +#define SAFE_THROW(T) \ + T *sent = new T; \ + (*sent) << rdbuf(); \ + throw sent + +class ThrownError : public Transmitter { + public: + ThrownError () : Transmitter (Transmitter::Throw) {} + protected: + virtual void deliver () = 0; +}; + +#endif // __qm_thrown_error_h__ + + diff --git a/libs/pbd/pbd/tokenizer.h b/libs/pbd/pbd/tokenizer.h new file mode 100644 index 0000000000..a976b79341 --- /dev/null +++ b/libs/pbd/pbd/tokenizer.h @@ -0,0 +1,49 @@ +#ifndef PBD_TOKENIZER +#define PBD_TOKENIZER + +#include +#include + +namespace PBD { + +/** + Tokenize string, this should work for standard + strings aswell as Glib::ustring. This is a bit of a hack, + there are much better string tokenizing patterns out there. +*/ +template +unsigned int +tokenize(const StringType& str, + const StringType& delims, + Iter it) +{ + typename StringType::size_type start_pos = 0; + typename StringType::size_type end_pos = 0; + unsigned int token_count = 0; + + do { + start_pos = str.find_first_not_of(delims, start_pos); + end_pos = str.find_first_of(delims, start_pos); + if (start_pos != end_pos) { + if (end_pos == str.npos) { + end_pos = str.length(); + } + *it++ = str.substr(start_pos, end_pos - start_pos); + ++token_count; + start_pos = str.find_first_not_of(delims, end_pos + 1); + } + } while (start_pos != str.npos); + + if (start_pos != str.npos) { + *it++ = str.substr(start_pos, str.length() - start_pos); + ++token_count; + } + + return token_count; +} + +} // namespace PBD + +#endif // PBD_TOKENIZER + + diff --git a/libs/pbd/pbd/touchable.h b/libs/pbd/pbd/touchable.h new file mode 100644 index 0000000000..0298574dfa --- /dev/null +++ b/libs/pbd/pbd/touchable.h @@ -0,0 +1,89 @@ +/* + Copyright (C) 1999 Paul Barton-Davis + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __pbd_touchable_h__ +#define __pbd_touchable_h__ + +class Touchable +{ + public: + Touchable() : _delete_after_touch (false) {} + virtual ~Touchable() {} + + void set_delete_after_touch (bool yn) { _delete_after_touch = yn; } + bool delete_after_touch() const { return _delete_after_touch; } + + virtual void touch () = 0; + + protected: + bool _delete_after_touch; +}; + +template +class DynamicTouchable : public Touchable +{ + public: + DynamicTouchable (T& t, void (T::*m)(void)) + : object (t), method (m) { set_delete_after_touch (true); } + + void touch () { + (object.*method)(); + } + + protected: + T& object; + void (T::*method)(void); +}; + +template +class DynamicTouchable1 : public Touchable +{ + public: + DynamicTouchable1 (T1& t, void (T1::*m)(T2), T2 a) + : object (t), method (m), arg (a) { set_delete_after_touch (true); } + + void touch () { + (object.*method)(arg); + } + + protected: + T1& object; + void (T1::*method)(T2); + T2 arg; +}; + +template +class DynamicTouchable2 : public Touchable +{ + public: + DynamicTouchable2 (T1& t, void (T1::*m)(T2, T3), T2 a1, T3 a2) + : object (t), method (m), arg1 (a1), arg2 (a2) { set_delete_after_touch (true); } + + void touch () { + (object.*method)(arg1, arg2); + } + + protected: + T1& object; + void (T1::*method)(T2,T3); + T2 arg1; + T3 arg2; +}; + +#endif // __pbd_touchable_h__ diff --git a/libs/pbd/pbd/transmitter.h b/libs/pbd/pbd/transmitter.h new file mode 100644 index 0000000000..357cb9965f --- /dev/null +++ b/libs/pbd/pbd/transmitter.h @@ -0,0 +1,110 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __libmisc_transmitter_h__ +#define __libmisc_transmitter_h__ + +#include +#include + +#include + +using std::cout; +using std::cerr; +using std::endl; + +class Transmitter : public std::stringstream + +{ + public: + enum Channel { + Info, + Error, + Warning, + Fatal, + Throw + }; + + Transmitter (Channel); + + sigc::signal &sender() { + return *send; + } + + bool does_not_return (); + + protected: + virtual void deliver (); + friend std::ostream& endmsg (std::ostream &); + + private: + Channel channel; + sigc::signal *send; + + sigc::signal info; + sigc::signal warning; + sigc::signal error; + sigc::signal fatal; +}; + +/* for EGCS 2.91.66, if this function is not compiled within the same + compilation unit as the one where a ThrownError is thrown, then + nothing will catch the error. This is a pretty small function, so + inlining it here seems like a reasonable workaround. +*/ + +inline std::ostream & +endmsg (std::ostream &ostr) + +{ + Transmitter *t; + + /* There is a serious bug in the Cygnus/GCC libstdc++ library: + cout is not actually an ostream, but a trick was played + to make the compiler think that it is. This will cause + the dynamic_cast<> to fail with SEGV. So, first check to + see if ostr == cout, and handle it specially. + */ + + if (&ostr == &cout) { + cout << endl; + return ostr; + } else if (&ostr == &cerr) { + cerr << endl; + return ostr; + } + + if ((t = dynamic_cast (&ostr)) != 0) { + t->deliver (); + } else { + /* hmm. not a Transmitter, so just put a newline on + it and assume that that will be enough. + */ + + ostr << endl; + } + + return ostr; +} + + +extern "C" { void pbd_c_error (const char *); } + +#endif // __libmisc_transmitter_h__ diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h new file mode 100644 index 0000000000..f067635ed3 --- /dev/null +++ b/libs/pbd/pbd/undo.h @@ -0,0 +1,96 @@ +/* + Copyright (C) 2002 Brett Viren & Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __lib_pbd_undo_h__ +#define __lib_pbd_undo_h__ + +#include +#include +#include +#include + +using std::string; +using std::list; + +typedef sigc::slot UndoAction; + +class UndoCommand +{ + public: + UndoCommand (); + UndoCommand (const UndoCommand&); + UndoCommand& operator= (const UndoCommand&); + + void clear (); + + void add_undo (const UndoAction&); + void add_redo (const UndoAction&); + void add_redo_no_execute (const UndoAction&); + + void undo(); + void redo(); + + void set_name (const string& str) { + _name = str; + } + const string& name() const { return _name; } + + void set_timestamp (struct timeval &t) { + _timestamp = t; + } + + const struct timeval& timestamp() const { + return _timestamp; + } + + private: + list redo_actions; + list undo_actions; + struct timeval _timestamp; + string _name; +}; + +class UndoHistory +{ + public: + UndoHistory() {} + ~UndoHistory() {} + + void add (UndoCommand uc); + void undo (unsigned int n); + void redo (unsigned int n); + + unsigned long undo_depth() const { return UndoList.size(); } + unsigned long redo_depth() const { return RedoList.size(); } + + string next_undo() const { return (UndoList.empty() ? string("") : UndoList.back().name()); } + string next_redo() const { return (RedoList.empty() ? string("") : RedoList.back().name()); } + + void clear (); + void clear_undo (); + void clear_redo (); + + private: + list UndoList; + list RedoList; +}; + + +#endif /* __lib_pbd_undo_h__ */ diff --git a/libs/pbd/pbd/whitespace.h b/libs/pbd/pbd/whitespace.h new file mode 100644 index 0000000000..6620a8fb50 --- /dev/null +++ b/libs/pbd/pbd/whitespace.h @@ -0,0 +1,8 @@ +#ifndef __pbd_whitespace_h__ +#define __pbd_whitespace_h__ + +#include + +extern void strip_whitespace_edges (std::string& str); + +#endif // __pbd_whitespace_h__ diff --git a/libs/pbd/pbd/xml++.h b/libs/pbd/pbd/xml++.h new file mode 100644 index 0000000000..afb896e1d5 --- /dev/null +++ b/libs/pbd/pbd/xml++.h @@ -0,0 +1,129 @@ +/* xml++.h + * libxml++ and this file are copyright (C) 2000 by Ari Johnson, and + * are covered by the GNU Lesser General Public License, which should be + * included with libxml++ as the file COPYING. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#ifndef __XML_H +#define __XML_H + +using std::string; +using std::map; +using std::list; + +class XMLTree; +class XMLNode; +class XMLProperty; + +typedef list XMLNodeList; +typedef XMLNodeList::iterator XMLNodeIterator; +typedef XMLNodeList::const_iterator XMLNodeConstIterator; +typedef list XMLPropertyList; +typedef XMLPropertyList::iterator XMLPropertyIterator; +typedef XMLPropertyList::const_iterator XMLPropertyConstIterator; +typedef map XMLPropertyMap; + +class XMLTree { +private: + string _filename; + XMLNode *_root; + int _compression; + bool _initialized; + +public: + XMLTree(); + XMLTree(const string &fn); + XMLTree(const XMLTree *); + ~XMLTree(); + + bool initialized() const { return _initialized; }; + XMLNode *root() const { return _root; }; + XMLNode *set_root(XMLNode *n) { _initialized = true; return _root = n; }; + + const string & filename() const { return _filename; }; + const string & set_filename(const string &fn) { return _filename = fn; }; + + int compression() const { return _compression; }; + int set_compression(int); + + bool read(); + bool read(const string &fn) { set_filename(fn); return read(); }; + bool read_buffer(const string &); + + bool write() const; + bool write(const string &fn) { set_filename(fn); return write(); }; + + void debug (FILE*) const; + + const string & write_buffer() const; +}; + +class XMLNode { +private: + bool _initialized; + string _name; + bool _is_content; + string _content; + XMLNodeList _children; + XMLPropertyList _proplist; + XMLPropertyMap _propmap; + +public: + XMLNode(const string &); + XMLNode(const string &, const string &); + XMLNode(const XMLNode&); + ~XMLNode(); + + bool initialized() const { return _initialized; }; + const string name() const { return _name; }; + + bool is_content() const { return _is_content; }; + const string & content() const { return _content; }; + const string & set_content(const string &); + XMLNode *add_content(const string & = string()); + + const XMLNodeList & children(const string & = string()) const; + XMLNode *add_child(const char *); + XMLNode *add_child_copy(const XMLNode&); + void add_child_nocopy (XMLNode&); + + const XMLPropertyList & properties() const { return _proplist; }; + XMLProperty *property(const char * ); + const XMLProperty *property(const char * n) const + { return ((XMLNode *) this)->property(n); }; + XMLProperty *add_property(const char *, const string &); + XMLProperty *add_property(const char *, const char * = ""); + + void remove_property(const string &); + + /** Remove all nodes with the name passed to remove_nodes */ + void remove_nodes(const string &); + /** Remove and delete all nodes with the name passed to remove_nodes */ + void remove_nodes_and_delete(const string &); +}; + +class XMLProperty { +private: + string _name; + string _value; + +public: + XMLProperty(const string &n, const string &v = string()); + ~XMLProperty(); + + const string & name() const { return _name; }; + const string & value() const { return _value; }; + const string & set_value(const string &v) { return _value = v; }; +}; + +#endif /* __XML_H */ + diff --git a/libs/pbd/pool.cc b/libs/pbd/pool.cc new file mode 100644 index 0000000000..089766482d --- /dev/null +++ b/libs/pbd/pool.cc @@ -0,0 +1,144 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include +#include + +#include +#include + +using namespace std; +using namespace PBD; + +Pool::Pool (string n, unsigned long item_size, unsigned long nitems) +{ + _name = n; + + free_list = new RingBuffer (nitems); + + /* since some overloaded ::operator new() might use this, + its important that we use a "lower level" allocator to + get more space. + */ + + block = malloc (nitems * item_size); + + void **ptrlist = (void **) malloc (sizeof (void *) * nitems); + + for (unsigned long i = 0; i < nitems; i++) { + ptrlist[i] = static_cast (static_cast(block) + (i * item_size)); + } + + free_list->write (ptrlist, nitems); + + free (ptrlist); +} + +Pool::~Pool () +{ + free (block); +} + +void * +Pool::alloc () +{ + void *ptr; + +// cerr << _name << " pool " << " alloc, thread = " << pthread_name() << " space = " << free_list->read_space() << endl; + + if (free_list->read (&ptr, 1) < 1) { + fatal << "CRITICAL: " << _name << " POOL OUT OF MEMORY - RECOMPILE WITH LARGER SIZE!!" << endmsg; + /*NOTREACHED*/ + return 0; + } else { + return ptr; + } +}; + +void +Pool::release (void *ptr) +{ + free_list->write (&ptr, 1); +// cerr << _name << ": release, now has " << free_list->read_space() << endl; +} + +/*---------------------------------------------*/ + +MultiAllocSingleReleasePool::MultiAllocSingleReleasePool (string n, unsigned long isize, unsigned long nitems) + : Pool (n, isize, nitems), + m_lock(0) +{ +} + +MultiAllocSingleReleasePool::~MultiAllocSingleReleasePool () +{ + if(m_lock) delete m_lock; +} + +SingleAllocMultiReleasePool::SingleAllocMultiReleasePool (string n, unsigned long isize, unsigned long nitems) + : Pool (n, isize, nitems), + m_lock(0) +{ +} + +SingleAllocMultiReleasePool::~SingleAllocMultiReleasePool () +{ + if(m_lock) delete m_lock; +} + +void* +MultiAllocSingleReleasePool::alloc () +{ + void *ptr; + if(!m_lock) { + m_lock = new Glib::Mutex(); + // umm, I'm not sure that this doesn't also allocate memory. + if(!m_lock) error << "cannot create Glib::Mutex in pool.cc" << endmsg; + } + + Glib::Mutex::Lock guard(*m_lock); + ptr = Pool::alloc (); + return ptr; +} + +void +MultiAllocSingleReleasePool::release (void* ptr) +{ + Pool::release (ptr); +} + +void* +SingleAllocMultiReleasePool::alloc () +{ + return Pool::alloc (); +} + +void +SingleAllocMultiReleasePool::release (void* ptr) +{ + if(!m_lock) { + m_lock = new Glib::Mutex(); + // umm, I'm not sure that this doesn't also allocate memory. + if(!m_lock) error << "cannot create Glib::Mutex in pool.cc" << endmsg; + } + Glib::Mutex::Lock guard(*m_lock); + Pool::release (ptr); +} + diff --git a/libs/pbd/pthread_utils.cc b/libs/pbd/pthread_utils.cc new file mode 100644 index 0000000000..db242cea7b --- /dev/null +++ b/libs/pbd/pthread_utils.cc @@ -0,0 +1,133 @@ +/* + Copyright (C) 2002 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include +#include +#include +#include + +#include + +using namespace std; + +typedef std::map ThreadMap; +static ThreadMap all_threads; +static pthread_mutex_t thread_map_lock = PTHREAD_MUTEX_INITIALIZER; + +namespace PBD { + sigc::signal ThreadCreated; + sigc::signal ThreadCreatedWithRequestSize; +} + +using namespace PBD; + +int +pthread_create_and_store (string name, pthread_t *thread, pthread_attr_t *attr, void * (*start_routine)(void *), void * arg) +{ + int ret; + + if ((ret = pthread_create (thread, attr, start_routine, arg)) == 0) { + std::pair newpair; + newpair.first = name; + newpair.second = *thread; + + pthread_mutex_lock (&thread_map_lock); + all_threads.insert (newpair); + + pthread_mutex_unlock (&thread_map_lock); + } + + return ret; +} + +string +pthread_name () +{ + pthread_t self = pthread_self(); + string str; + + pthread_mutex_lock (&thread_map_lock); + for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { + if (i->second == self) { + str = i->first; + pthread_mutex_unlock (&thread_map_lock); + return str; + } + } + pthread_mutex_unlock (&thread_map_lock); + return "unknown"; +} + +void +pthread_kill_all (int signum) +{ + pthread_mutex_lock (&thread_map_lock); + for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { + if (i->second != pthread_self()) { + pthread_kill (i->second, signum); + } + } + all_threads.clear(); + pthread_mutex_unlock (&thread_map_lock); +} + +void +pthread_cancel_all () +{ + pthread_mutex_lock (&thread_map_lock); + for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { + if (i->second != pthread_self()) { + pthread_cancel (i->second); + } + } + all_threads.clear(); + pthread_mutex_unlock (&thread_map_lock); +} + +void +pthread_cancel_one (pthread_t thread) +{ + pthread_mutex_lock (&thread_map_lock); + for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { + if (i->second == thread) { + all_threads.erase (i); + break; + } + } + + pthread_cancel (thread); + pthread_mutex_unlock (&thread_map_lock); +} + +void +pthread_exit_pbd (void* status) +{ + pthread_t thread = pthread_self(); + + pthread_mutex_lock (&thread_map_lock); + for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { + if (i->second == thread) { + all_threads.erase (i); + break; + } + } + pthread_mutex_unlock (&thread_map_lock); + pthread_exit (status); +} diff --git a/libs/pbd/receiver.cc b/libs/pbd/receiver.cc new file mode 100644 index 0000000000..5e7c10de70 --- /dev/null +++ b/libs/pbd/receiver.cc @@ -0,0 +1,58 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include + +#include +#include + +using namespace sigc; + +Receiver::Receiver () {} + +Receiver::~Receiver () + +{ + hangup (); +} + +void +Receiver::hangup () +{ + vector::iterator i; + + for (i = connections.begin(); i != connections.end (); i++) { + (*i)->disconnect (); + delete *i; + } + + connections.erase (connections.begin(), connections.end()); +} + +void +Receiver::listen_to (Transmitter &transmitter) + +{ + sigc::connection *c = new sigc::connection; + + (*c) = transmitter.sender().connect(mem_fun(*this, &Receiver::receive)); + + connections.push_back (c); +} diff --git a/libs/pbd/stacktrace.cc b/libs/pbd/stacktrace.cc new file mode 100644 index 0000000000..1e7dfa08e9 --- /dev/null +++ b/libs/pbd/stacktrace.cc @@ -0,0 +1,42 @@ +#include +#include + +/* Obtain a backtrace and print it to stdout. */ + +#ifdef HAVE_EXECINFO + +#include +#include + +void +PBD::stacktrace (std::ostream& out) +{ + void *array[200]; + size_t size; + char **strings; + size_t i; + + size = backtrace (array, 200); + strings = backtrace_symbols (array, size); + + if (strings) { + + printf ("Obtained %zd stack frames.\n", size); + + for (i = 0; i < size; i++) { + out << strings[i] << std::endl; + } + + free (strings); + } +} + +#else + +void +PBD::stacktrace (std::ostream& out) +{ + out << "stack tracing is not enabled on this platform" << std::endl; +} + +#endif /* HAVE_EXECINFO */ diff --git a/libs/pbd/strsplit.cc b/libs/pbd/strsplit.cc new file mode 100644 index 0000000000..7f29a77887 --- /dev/null +++ b/libs/pbd/strsplit.cc @@ -0,0 +1,41 @@ +#include + +using namespace std; + +void +split (string str, vector& result, char splitchar) +{ + string::size_type pos; + string remaining; + string::size_type len = str.length(); + int cnt; + + cnt = 0; + + if (str.empty()) { + return; + } + + for (string::size_type n = 0; n < len; ++n) { + if (str[n] == splitchar) { + cnt++; + } + } + + if (cnt == 0) { + result.push_back (str); + return; + } + + remaining = str; + + while ((pos = remaining.find_first_of (':')) != string::npos) { + result.push_back (remaining.substr (0, pos)); + remaining = remaining.substr (pos+1); + } + + if (remaining.length()) { + + result.push_back (remaining); + } +} diff --git a/libs/pbd/textreceiver.cc b/libs/pbd/textreceiver.cc new file mode 100644 index 0000000000..43620e9830 --- /dev/null +++ b/libs/pbd/textreceiver.cc @@ -0,0 +1,66 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include +#include + +#include + +TextReceiver::TextReceiver (const string &n) + +{ + name = n; +} + +void +TextReceiver::receive (Transmitter::Channel chn, const char *str) + +{ + const char *prefix = ""; + + switch (chn) { + case Transmitter::Error: + prefix = ": [ERROR]: "; + break; + case Transmitter::Info: + prefix = ": [INFO]: "; + break; + case Transmitter::Warning: + prefix = ": [WARNING]: "; + break; + case Transmitter::Fatal: + prefix = ": [FATAL]: "; + break; + case Transmitter::Throw: + /* this isn't supposed to happen */ + abort (); + } + + /* note: iostreams are already thread-safe: no external + lock required. + */ + + cout << name << prefix << str << endl; + + if (chn == Transmitter::Fatal) { + exit (9); + } +} + diff --git a/libs/pbd/transmitter.cc b/libs/pbd/transmitter.cc new file mode 100644 index 0000000000..876a9d86e5 --- /dev/null +++ b/libs/pbd/transmitter.cc @@ -0,0 +1,115 @@ +/* + Copyright (C) 1998-99 Paul Barton-Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include +#include +#include +#include + +#include +#include + +using std::string; +using std::ios; + +Transmitter::Transmitter (Channel c) +{ + channel = c; + switch (c) { + case Error: + send = &error; + break; + case Warning: + send = &warning; + break; + case Info: + send = &info; + break; + case Fatal: + send = &fatal; + break; + case Throw: + /* we should never call Transmitter::deliver + for thrown messages (because its overridden in the + class heirarchy). force a segv if we do. + */ + send = 0; + break; + } +} + +void +Transmitter::deliver () + +{ + string foo; + + /* NOTE: this is just a default action for a Transmitter or a + derived class. Any class can override this to produce some + other action when deliver() is called. + */ + + *this << '\0'; + + /* send the SigC++ signal */ + + foo = str(); + (*send) (channel, foo.c_str()); + + /* XXX when or how can we delete this ? */ + // delete foo; + + /* return to a pristine state */ + + clear (); + seekp (0, ios::beg); + seekg (0, ios::beg); + + /* do the right thing if this should not return */ + + if (does_not_return()) { + sigset_t mask; + + sigemptyset (&mask); + sigsuspend (&mask); + /*NOTREACHED*/ + exit (1); + } +} + +bool +Transmitter::does_not_return () + +{ + if (channel == Fatal || channel == Throw) { + return true; + } else { + return false; + } +} + + +extern "C" { + void pbd_c_error (const char *str) + + { + PBD::error << str << endmsg; + } +} diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc new file mode 100644 index 0000000000..f2f11b1c5c --- /dev/null +++ b/libs/pbd/undo.cc @@ -0,0 +1,146 @@ +/* + Copyright (C) 2001 Brett Viren & Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include + +#include + +using namespace std; +using namespace sigc; + +UndoCommand::UndoCommand () +{ +} + +UndoCommand::UndoCommand (const UndoCommand& rhs) +{ + _name = rhs._name; + clear (); + undo_actions.insert(undo_actions.end(),rhs.undo_actions.begin(),rhs.undo_actions.end()); + redo_actions.insert(redo_actions.end(),rhs.redo_actions.begin(),rhs.redo_actions.end()); +} + +UndoCommand& +UndoCommand::operator= (const UndoCommand& rhs) +{ + if (this == &rhs) return *this; + _name = rhs._name; + clear (); + undo_actions.insert(undo_actions.end(),rhs.undo_actions.begin(),rhs.undo_actions.end()); + redo_actions.insert(redo_actions.end(),rhs.redo_actions.begin(),rhs.redo_actions.end()); + return *this; +} + +void +UndoCommand::add_undo (const UndoAction& action) +{ + undo_actions.push_back (action); +} + +void +UndoCommand::add_redo (const UndoAction& action) +{ + redo_actions.push_back (action); + redo_actions.back()(); // operator() +} + +void +UndoCommand::add_redo_no_execute (const UndoAction& action) +{ + redo_actions.push_back (action); +} + +void +UndoCommand::clear () +{ + undo_actions.clear (); + redo_actions.clear (); +} + +void +UndoCommand::undo () +{ + cerr << "Undo " << _name << endl; + for (list::reverse_iterator i = undo_actions.rbegin(); i != undo_actions.rend(); ++i) { + (*i)(); + } +} + +void +UndoCommand::redo () +{ + cerr << "Redo " << _name << endl; + for (list::iterator i = redo_actions.begin(); i != redo_actions.end(); ++i) { + (*i)(); + } +} + +void +UndoHistory::add (UndoCommand uc) +{ + UndoList.push_back (uc); +} + +void +UndoHistory::undo (unsigned int n) +{ + while (n--) { + if (UndoList.size() == 0) { + return; + } + UndoCommand uc = UndoList.back (); + UndoList.pop_back (); + uc.undo (); + RedoList.push_back (uc); + } +} + +void +UndoHistory::redo (unsigned int n) +{ + while (n--) { + if (RedoList.size() == 0) { + return; + } + UndoCommand cmd = RedoList.back (); + RedoList.pop_back (); + cmd.redo (); + UndoList.push_back (cmd); + } +} + +void +UndoHistory::clear_redo () +{ + RedoList.clear (); +} + +void +UndoHistory::clear_undo () +{ + UndoList.clear (); +} + +void +UndoHistory::clear () +{ + RedoList.clear (); + UndoList.clear (); +} diff --git a/libs/pbd/whitespace.cc b/libs/pbd/whitespace.cc new file mode 100644 index 0000000000..7f74940457 --- /dev/null +++ b/libs/pbd/whitespace.cc @@ -0,0 +1,30 @@ +#include + +using namespace std; + +void +strip_whitespace_edges (string& str) +{ + string::size_type i; + string::size_type len; + string::size_type s; + + len = str.length(); + + for (i = 0; i < len; ++i) { + if (isgraph (str[i])) { + break; + } + } + + s = i; + + for (i = len - 1; i >= 0; --i) { + if (isgraph (str[i])) { + break; + } + } + + str = str.substr (s, (i - s) + 1); +} + diff --git a/libs/pbd/xml++.cc b/libs/pbd/xml++.cc new file mode 100644 index 0000000000..e496d8b2fd --- /dev/null +++ b/libs/pbd/xml++.cc @@ -0,0 +1,422 @@ +/* xml++.cc + * libxml++ and this file are copyright (C) 2000 by Ari Johnson, and + * are covered by the GNU Lesser General Public License, which should be + * included with libxml++ as the file COPYING. + */ + +#include +#include + +static XMLNode *readnode(xmlNodePtr); +static void writenode(xmlDocPtr, XMLNode *, xmlNodePtr, int); + +XMLTree::XMLTree() + : _filename(), + _root(), + _compression(0), + _initialized(false) +{ +} + +XMLTree::XMLTree(const string &fn) + : _filename(fn), + _root(0), + _compression(0), + _initialized(false) +{ + read(); +} + +XMLTree::XMLTree(const XMLTree * from) +{ + _filename = from->filename(); + _root = new XMLNode(*from->root()); + _compression = from->compression(); + _initialized = true; +} + +XMLTree::~XMLTree() +{ + if (_initialized && _root) + delete _root; +} + +int +XMLTree::set_compression(int c) +{ + if (c > 9) + c = 9; + + if (c < 0) + c = 0; + + _compression = c; + + return _compression; +} + +bool +XMLTree::read(void) +{ + xmlDocPtr doc; + + if (_root) { + delete _root; + _root = 0; + } + + xmlKeepBlanksDefault(0); + + doc = xmlParseFile(_filename.c_str()); + if (!doc) { + _initialized = false; + return false; + } + + _root = readnode(xmlDocGetRootElement(doc)); + xmlFreeDoc(doc); + _initialized = true; + + return true; +} + +bool +XMLTree::read_buffer(const string & buffer) +{ + xmlDocPtr doc; + + _filename = ""; + + if (_root) { + delete _root; + _root = 0; + } + + doc = xmlParseMemory((char *) buffer.c_str(), buffer.length()); + if (!doc) { + _initialized = false; + return false; + } + + _root = readnode(xmlDocGetRootElement(doc)); + xmlFreeDoc(doc); + _initialized = true; + + return true; +} + +bool +XMLTree::write(void) const +{ + xmlDocPtr doc; + XMLNodeList children; + int result; + + xmlKeepBlanksDefault(0); + doc = xmlNewDoc((xmlChar *) "1.0"); + xmlSetDocCompressMode(doc, _compression); + writenode(doc, _root, doc->children, 1); + result = xmlSaveFormatFile(_filename.c_str(), doc, 1); + xmlFreeDoc(doc); + + if (result == -1) + return false; + + return true; +} + +void +XMLTree::debug(FILE* out) const +{ + xmlDocPtr doc; + XMLNodeList children; + + xmlKeepBlanksDefault(0); + doc = xmlNewDoc((xmlChar *) "1.0"); + xmlSetDocCompressMode(doc, _compression); + writenode(doc, _root, doc->children, 1); + xmlDebugDumpDocument (out, doc); + xmlFreeDoc(doc); +} + +const string & +XMLTree::write_buffer(void) const +{ + static string retval; + char *ptr; + int len; + xmlDocPtr doc; + XMLNodeList children; + + xmlKeepBlanksDefault(0); + doc = xmlNewDoc((xmlChar *) "1.0"); + xmlSetDocCompressMode(doc, _compression); + writenode(doc, _root, doc->children, 1); + xmlDocDumpMemory(doc, (xmlChar **) & ptr, &len); + xmlFreeDoc(doc); + + retval = ptr; + + free(ptr); + + return retval; +} + +XMLNode::XMLNode(const string & n) + : _name(n), _is_content(false), _content(string()) +{ + + if (_name.empty()) + _initialized = false; + else + _initialized = true; +} + +XMLNode::XMLNode(const string & n, const string & c) + :_name(string()), _is_content(true), _content(c) +{ + _initialized = true; +} + +XMLNode::XMLNode(const XMLNode& from) + : _initialized(false) +{ + XMLPropertyList props; + XMLPropertyIterator curprop; + XMLNodeList nodes; + XMLNodeIterator curnode; + + _name = from.name(); + set_content(from.content()); + + props = from.properties(); + for (curprop = props.begin(); curprop != props.end(); curprop++) + add_property((*curprop)->name().c_str(), (*curprop)->value()); + + nodes = from.children(); + for (curnode = nodes.begin(); curnode != nodes.end(); curnode++) + add_child_copy(**curnode); +} + +XMLNode::~XMLNode() +{ + XMLNodeIterator curchild; + XMLPropertyIterator curprop; + + for (curchild = _children.begin(); curchild != _children.end(); + curchild++) + delete *curchild; + + for (curprop = _proplist.begin(); curprop != _proplist.end(); + curprop++) + delete *curprop; +} + +const string & +XMLNode::set_content(const string & c) +{ + if (c.empty()) + _is_content = false; + else + _is_content = true; + + _content = c; + + return _content; +} + +const XMLNodeList & +XMLNode::children(const string & n) const +{ + static XMLNodeList retval; + XMLNodeConstIterator cur; + + if (n.length() == 0) + return _children; + + retval.erase(retval.begin(), retval.end()); + + for (cur = _children.begin(); cur != _children.end(); cur++) + if ((*cur)->name() == n) + retval.insert(retval.end(), *cur); + + return retval; +} + +XMLNode * +XMLNode::add_child(const char * n) +{ + return add_child_copy(XMLNode (n)); +} + +void +XMLNode::add_child_nocopy (XMLNode& n) +{ + _children.insert(_children.end(), &n); +} + +XMLNode * +XMLNode::add_child_copy(const XMLNode& n) +{ + XMLNode *copy = new XMLNode (n); + _children.insert(_children.end(), copy); + return copy; +} + +XMLNode * +XMLNode::add_content(const string & c) +{ + return add_child_copy(XMLNode (string(), c)); +} + +XMLProperty * +XMLNode::property(const char * n) +{ + string ns(n); + if (_propmap.find(ns) == _propmap.end()) + return 0; + return _propmap[ns]; +} + +XMLProperty * +XMLNode::add_property(const char * n, const string & v) +{ + string ns(n); + if(_propmap.find(ns) != _propmap.end()){ + remove_property(ns); + } + + XMLProperty *tmp = new XMLProperty(ns, v); + + if (!tmp) + return 0; + + _propmap[tmp->name()] = tmp; + _proplist.insert(_proplist.end(), tmp); + + return tmp; +} + +XMLProperty * +XMLNode::add_property(const char * n, const char * v) +{ + string vs(v); + return add_property(n, vs); +} + +void +XMLNode::remove_property(const string & n) +{ + if (_propmap.find(n) != _propmap.end()) { + _proplist.remove(_propmap[n]); + _propmap.erase(n); + } +} + +void +XMLNode::remove_nodes(const string & n) +{ + XMLNodeIterator i = _children.begin(); + XMLNodeIterator tmp; + + while (i != _children.end()) { + tmp = i; + ++tmp; + if ((*i)->name() == n) { + _children.erase (i); + } + i = tmp; + } +} + +void +XMLNode::remove_nodes_and_delete(const string & n) +{ + XMLNodeIterator i = _children.begin(); + XMLNodeIterator tmp; + + while (i != _children.end()) { + tmp = i; + ++tmp; + if ((*i)->name() == n) { + delete *i; + _children.erase (i); + } + i = tmp; + } +} + +XMLProperty::XMLProperty(const string &n, const string &v) + : _name(n), + _value(v) +{ +} + +XMLProperty::~XMLProperty() +{ +} + +static XMLNode * +readnode(xmlNodePtr node) +{ + string name, content; + xmlNodePtr child; + XMLNode *tmp; + xmlAttrPtr attr; + + if (node->name) + name = (char *) node->name; + + tmp = new XMLNode(name); + + for (attr = node->properties; attr; attr = attr->next) { + content = ""; + if (attr->children) + content = (char *) attr->children->content; + tmp->add_property((char *) attr->name, content); + } + + if (node->content) + tmp->set_content((char *) node->content); + else + tmp->set_content(string()); + + for (child = node->children; child; child = child->next) + tmp->add_child_nocopy (*readnode(child)); + + return tmp; +} + +static void +writenode(xmlDocPtr doc, XMLNode * n, xmlNodePtr p, int root = + 0) +{ + XMLPropertyList props; + XMLPropertyIterator curprop; + XMLNodeList children; + XMLNodeIterator curchild; + xmlNodePtr node; + + if (root) + node = doc->children = + xmlNewDocNode(doc, 0, (xmlChar *) n->name().c_str(), 0); + + else + node = xmlNewChild(p, 0, (xmlChar *) n->name().c_str(), 0); + + if (n->is_content()) { + node->type = XML_TEXT_NODE; + xmlNodeSetContentLen(node, (const xmlChar *) n->content().c_str(), + n->content().length()); + } + + props = n->properties(); + for (curprop = props.begin(); curprop != props.end(); curprop++) + xmlSetProp(node, (xmlChar *) (*curprop)->name().c_str(), + (xmlChar *) (*curprop)->value().c_str()); + + children = n->children(); + for (curchild = children.begin(); curchild != children.end(); + curchild++) + writenode(doc, *curchild, node); +} diff --git a/libs/surfaces/control_protocol/SConscript b/libs/surfaces/control_protocol/SConscript index f8a7d574f5..ce59b1c67c 100644 --- a/libs/surfaces/control_protocol/SConscript +++ b/libs/surfaces/control_protocol/SConscript @@ -34,7 +34,7 @@ cp.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"") cp.Merge ([ libraries['ardour'], libraries['sigc2'], - libraries['pbd3'], + libraries['pbd'], libraries['midi++2'], libraries['xml'], libraries['usb'], diff --git a/libs/surfaces/generic_midi/SConscript b/libs/surfaces/generic_midi/SConscript index 1760eb24e9..213a81a99d 100644 --- a/libs/surfaces/generic_midi/SConscript +++ b/libs/surfaces/generic_midi/SConscript @@ -34,7 +34,7 @@ genericmidi.Merge ([ libraries['ardour'], libraries['ardour_cp'], libraries['midi++2'], - libraries['pbd3'], + libraries['pbd'], libraries['sigc2'], libraries['usb'], libraries['xml'], diff --git a/libs/surfaces/tranzport/SConscript b/libs/surfaces/tranzport/SConscript index 8f3568aa8f..3f9cc5cc15 100644 --- a/libs/surfaces/tranzport/SConscript +++ b/libs/surfaces/tranzport/SConscript @@ -34,7 +34,7 @@ tranzport.Merge ([ libraries['ardour'], libraries['ardour_cp'], libraries['sigc2'], - libraries['pbd3'], + libraries['pbd'], libraries['midi++2'], libraries['xml'], libraries['usb'], -- cgit v1.2.3