Compare commits

..

209 Commits

Author SHA1 Message Date
curt
1818102ffe Updated ... 2002-09-07 01:33:17 +00:00
curt
406d6dd6fc Getting ready for 0.2.0 stable release. 2002-09-07 01:25:02 +00:00
curt
c8ef854f01 Fixes to allow MingW compilation. 2002-09-06 20:05:40 +00:00
curt
87dcaf5a00 Fixes to better support the native irix compilers. 2002-09-06 15:30:11 +00:00
curt
c3bdd0e537 Automake version check is only done in autogen.sh and not in configure. 2002-09-03 21:44:44 +00:00
curt
c23fd6e66f Fix a typo in acinclude.m4 2002-09-03 02:52:39 +00:00
curt
e809eee896 Additional configure changes. 2002-09-02 22:18:31 +00:00
curt
c44ef2126c Tweaks for next prerelease. 2002-09-02 04:08:01 +00:00
curt
e2bfb5633b Minor tweaks. 2002-09-02 03:43:05 +00:00
curt
064ee8ba8f Make sure interpreters/ gets included with "make dist" 2002-09-02 03:41:39 +00:00
curt
a5c130446e Preparation for next pre-release. 2002-08-31 18:39:07 +00:00
curt
4162817c0b More clean ups. 2002-08-31 13:18:49 +00:00
curt
81cab6e089 Additional build system tweaks, regenerated the .dsp/.dsw's. 2002-08-30 15:03:30 +00:00
curt
d78204d147 Several fixes and tweaks. 2002-08-29 14:00:35 +00:00
curt
d8b523d067 Attempting more fixes to our autoconf/make scripts. 2002-08-28 14:08:12 +00:00
curt
c4cfad6069 Additional tweaks that got lost somehow. 2002-08-27 21:48:51 +00:00
curt
5bddb88ce2 Ooops, minor typo fixed. 2002-08-27 21:45:48 +00:00
curt
8c4ee69aeb Modernize the autoconf scripts a bit. 2002-08-27 21:44:39 +00:00
curt
b3a533f8ce Add #ifdef'd out support for plibs cheesy lens flare object. 2002-08-27 21:43:35 +00:00
curt
a885314a39 Tidy up the autoconf/automake configuration a bit.
- Removed some old cruft.

- Removed some support for older versions of automake which technically was
  correct, but caused the newer automakes to squawk warnings during an
  initial sanity check (which isn't done very intelligently.)

  NOTE: this fix is technically not correct for older version of automake.
  These older version use the variable "INCLUDES" internally and could have
  them already set to an important value.  That is why we were appending
  our values to them.  However, newer versions of automake don't set this
  value themselves so it is an error to append to a non-existant variable.
  We seem to "get away" with overwriting the value on older versions of
  automake, but if you have problems, consider upgrading to at least
  automake-1.5.
2002-08-25 17:31:47 +00:00
curt
0567a76445 It probably is better not to hide warning messages. Removed spaces from
AC_DEFINE( SYMBOL ) -> AC_DEFINE(SYMBOL)
2002-08-24 18:21:49 +00:00
curt
d6dc2d6eab Brandon Bergren:
2. I changed Simgear's autogen.sh so it is quieter, and errors out if
autoheader or autoconf fails.  It puts all error output in autogen.err, and
deletes it if nothing errored out.  The patch is in (sg.autogen.sh.patch.gz)
This patch applies to flightgear, too.  If someone doesn't like what I did
here, please speak up!  I really believe that this patch will help cause
less confusion among people new to compiling flightgear.
2002-08-24 03:54:45 +00:00
curt
b75a694682 Bernie Bright:
Here are some changes that gave me a significant frame rate increase of about 10 fps with random objects disabled.  The interesting thing is that these changes aren't in the main loop but are in tile loader.  My guess is that I've reduced the memory footprint just enough to reduce CPU cache misses, though I have no hard evidence of this.

Initially I modified all SGBinObject member functions to pass/return by reference instead of by-value.  This gives little or no speed up but allows for some optimizations in fgBinObjLoad().  It is these changes that reduce the number of memory allocations.  Needless copying of vectors, and vectors of vectors, can be very memory intensive, especially if they are large.

Anyway I would be interested to see if you get similar results.  I would emphasize that the frame rate increase only occurs with random objects disabled.  I lose about 10-15 fps on my GF2MX 32MB with random objects, probably a fill-rate limitation or texture memory thing.
2002-08-23 17:52:10 +00:00
david
2e7e9b73a0 Change from Norman Vine to add new random-number algorithm. 2002-08-05 18:43:28 +00:00
david
7a11523692 Random-number seed patch from Erik Hofman. 2002-07-31 17:14:29 +00:00
curt
f85a9866fe Remove efence support in favor of valgrind. 2002-07-30 14:10:08 +00:00
david
9b05c27938 Remove ECMAScript interpreter from the default build for now. It can
still be built from inside the directory.
2002-07-30 11:58:34 +00:00
david
fd96729362 Patch from Cameron Moore:
* Fixed (un)signed comparison
2002-07-18 20:30:18 +00:00
david
c57cc096f8 Patch from Cameron Moore:
* Rearranged member initializers to shut gcc -Wall up
2002-07-18 20:30:02 +00:00
david
c8efd0a465 Added JavaScript interpreter, repackaged by Tony Peden. It's not tied
into anything yet, but it builds OK inside SimGear.
2002-07-18 20:27:46 +00:00
david
db60139845 Downgrade cloud-base alert to a debug warning. 2002-07-18 20:23:30 +00:00
david
cadefd323a Quick fix for bug reported by Julian Foad, where the simplify flag was
not honoured after the first call.  This isn't all that efficient, and
the return type probably should change to string eventually, but this
fix avoids changing the headers for now.
2002-07-18 20:04:50 +00:00
david
baab88f42a Fix deletes in destructor. 2002-07-06 15:00:37 +00:00
david
767b74dd35 Added new getDisplayName method that gets the name with its index.
Suggested by Julian Foad.
2002-07-06 14:58:38 +00:00
david
90e8287f43 Made SGPropertyNode::getPath extremely efficient: it now caches its
result, so after the first call for any node, it simply tests and
returns a pointer.  This also fixes the problem of buffer conflicts
with make_string.

Added SGPropertyNode::hasChild(const char * name, int index = 0) to
provide a syntactically-cleaner way to test for the existence of a
child node, i.e.

  for (int i = 0; i < 9; i++) {
    if (node->hasChild("foo", i))
      foo[i] = node->getChild("foo", i)->getDoubleValue();
  }
2002-07-06 13:19:02 +00:00
david
d8b7e5b8fd Added simgear_config.h.in 2002-07-06 12:06:40 +00:00
curt
7769447283 Fixed a couple minor compiler warnings. 2002-07-03 17:35:49 +00:00
david
d6a790cf13 MSVC++ bug work-around from Frederic Bouvier. 2002-07-03 02:06:23 +00:00
curt
033c66363d Fixes for IA-64 with Intel compiler. 2002-07-02 18:44:20 +00:00
david
3ff1789963 Fixed an MSVC compilation problem reported by Frederic Bouvier. 2002-06-28 17:02:42 +00:00
david
9737c0c4dd Fixed bug reported by Julian Foad:
While investigating, I found that SGPropertyNode::getPath returns a
(char *) pointer to the character data of a string on its stack,
i.e. to undefined memory after it returns.  I remember someone was
changing strings to char* for efficiency.  Perhaps this bug was
introduced then.  I'll include a patch for it with my eventual patch
for the above, unless someone beats me to it.  I don't think it
affects any existing callers: they all want a string anyway.
2002-06-28 16:56:14 +00:00
david
b201383a80 Patch from Julian Foad:
Initialise a "possibly uninitialised" variable (which was already
functionally correct).

[Note from DPM: this patch will be blown away if we ever update to a
newer version of Expat.]
2002-06-28 15:55:11 +00:00
david
2253b82304 Patch from Julian Foad:
Remove a hack that originally worked around a buffer overflow
elsewhere in the file.  The buffer overflow was fixed long ago, but
the hack was not removed.
2002-06-28 15:54:34 +00:00
david
2581446d85 Patch from Julian Foad:
Remove trailing comma (unportable).
2002-06-28 15:54:15 +00:00
david
a6291b286c Patch from Julian Foad:
Remove unused static function (warning because it cannot possibly be used).
2002-06-28 15:53:58 +00:00
david
96a396bfcb Patch from Julian Foad:
This file should be removed from CVS because it is generated by
autogen.sh.
2002-06-28 15:53:31 +00:00
david
0833a11686 Significant improvements to the change-listener support. There are
now three different change events, and the listener base class removes
itself from the parent in the destructor.
2002-06-18 21:17:42 +00:00
david
9c7f7f3d32 Added a ptr() method to SGPropertyNode_ptr to get the raw pointer.
Added the SGPropertyChangeListener interface and addChangeListener and
firePropertyChange methods.
2002-06-18 01:26:09 +00:00
david
7847fe8074 Patch from Melchior Franz:
layer_span used uninitialized in SGCloudLayer::rebuild (line 162, 170, etc.)
2002-06-07 17:39:38 +00:00
david
c57d25ac51 Be more conservative and reuse SSG objects. 2002-06-05 19:12:50 +00:00
david
1341b5b9f8 Try to avoid some memory leaks. 2002-06-05 15:43:04 +00:00
curt
fb54e9e103 Include the autogen.sh script in the distribution. 2002-05-23 13:46:19 +00:00
david
3a835dde7d Skip drawing clear cloud layers. 2002-05-17 16:53:19 +00:00
curt
128a4a36ca Bernie Bright:
I've defined snprintf as _snprintf in compiler.h for MSVC and MINGW
targets and removed duplicate definitions from FG sources.
2002-05-17 14:38:03 +00:00
david
255bb6dd07 Preparation for making dynamic cloud layers -- moved cloud state out
of sky.[ch]xx and into cloud.[ch]xx, and added setters for modifying
the state of an existing layer.
2002-05-16 23:16:39 +00:00
curt
786b1e3a30 Removed SG_STATIC_CONST define. 2002-05-16 02:44:35 +00:00
curt
d5f38a558e Minor tweaks. 2002-05-16 02:30:06 +00:00
curt
ce5d4b7db8 Erik Hofman:
Some small patches to make the code Irix/Muli platform compatible and
one small fix to make it plib-1.4.2 compatible also.
2002-05-15 19:21:54 +00:00
curt
8c0b36fe9e Added SG_COMPILER macro. This is a string that identifies the build
compiler and version.  It might be useful to display it during program
startup.
2002-05-14 18:59:03 +00:00
david
c7e6459c64 Modified to work with the new SGPropertyNode_ptr class. 2002-05-10 22:58:03 +00:00
david
86e31e696d Patch from Frederic Bouvier:
I have modified the SGPropertyNode interface to support node removal
and address the issues you mention yesterday.

I added the SGPropertyNode_ptr class that is a smart pointer that
increment and decrement a counter in SGPropertyNode. The _children
vector is changed to a vector<SGPropertyNode_ptr> in order for the
node to hold a reference to its children. I also added a
_removedChildren vector of the same type. When removeChild is called
with the keep parameter set to true, the reference is removed from
_children and inserted in _removedChildren, and the attribute REMOVED
is set. When getChild is called with create set to true, the _children
vector is searched, then the _removedChildren and then a new node is
created. If a resurrected node is returned, the REMOVED bit is cleared.
The static const int LAST_USED_ATTRIBUTE is also added.

The footprint of this patch is light. SGPropertyNode is one int
longer in size, SGPropertyNode_ptr is one pointer large without
virtual functions. Some functions can be inlined if your current
policy change.

The FlightGear patch is to take account the change in the getChildren
function that now returns a vector<SGPropertyNode_ptr>. If the
removeChild functionnality is to be added in FlightGear, all those
SGPropertyNode * floating around should be changed to
SGPropertyNode_ptr.
2002-05-10 22:57:36 +00:00
david
be0b1bb994 Mac OS X fixes from Jonathan Polley. 2002-05-10 21:33:12 +00:00
david
03e74bfeb4 Ignore binaries. 2002-05-10 21:31:55 +00:00
david
972223cd50 Eliminate an unsigned-int comparison warning. 2002-05-10 21:31:15 +00:00
curt
761b7b9354 Bernie Bright:
Here's a first cut at SGSocket reimplemented using plib.net.  I've
maintained the same TCP server behaviour, that is only one client
connection at a time.  I don't think it is possible within the current
framework to handle simultaneous clients.

I've also added two simple test programs, tcp_client and tcp_server.
2002-05-10 13:53:22 +00:00
curt
6a3d1895d9 Bernie Bright:
Here is a total rewrite of the strutils package.  I've reimplemented the
trimleft(), trimright() and trim() functions as lstrip(), rstrip() and
strip() respectively.  Additionally I've added a split() function that
behaves like its perl/python equivalent.  Just the thing for splitting
comma separated option strings or space separated telnet commands and
arguments.  I've also enclosed the whole thing in a namespace
simgear::strutils.  Since I seem to be the only one who uses these
functions, SimGear and FlightGear compile without change.

PS It is no coincidence that the new function names bear an uncanny
resemblance to the python functions of the same name.
2002-05-10 13:32:44 +00:00
curt
d1178a26ce Updated MSVC project files. 2002-05-10 13:31:44 +00:00
curt
8ffdfa3cb1 Make the skydome interface a little more flexible so we can scale the dome
for other applications.
2002-04-27 03:19:45 +00:00
david
384e56b9b4 Patches from Erik Hoffman:
Tbis is a first patch in a series to clean up SimGear by removing
warning messages. Most of them are straight forwared, but in pops.hxx
the compile complaints about "type qualifier is meaningless on return
type". I think it's up to you to decide if you want that part applied.
2002-04-25 15:09:10 +00:00
david
d198e962b0 Patch from Melchior Franz:
From the cosmetics department ...
2002-04-25 14:56:03 +00:00
david
0136fdadbb Patch from Melchior Franz:
magvar and magdip are used before their initialization
2002-04-25 14:55:40 +00:00
curt
c616568830 Make sure README.MSVC goes in the distribution. 2002-04-23 01:56:51 +00:00
curt
995d2c1ede Make sure zlib.dsp goes in the distribution. 2002-04-23 01:55:48 +00:00
curt
051a5e9a38 Updated am2dsp.cfg file for creating MSVC project files.
New README.MSVC.
New src-libs/zlib.dsp for building zlib.
2002-04-22 20:37:31 +00:00
curt
60d89097de Bump up version number, remove boost from src-libs/Makefile.am 2002-04-20 22:03:35 +00:00
curt
6c35255549 Updated for 0.0.18. 2002-04-20 21:06:05 +00:00
curt
c985d8846d tweak. 2002-04-20 20:53:54 +00:00
curt
9a8ab26381 Removed boost dependency. Maybe we'll try again later. 2002-04-12 01:35:09 +00:00
david
711622fd5b Patch from Frederic Bouvier:
A const char * is not supposed to change and cannot be deleted. So
here is a patch that remove unnecessary const from props.hxx and
props.cxx. There also is the addition of a friend directive because
nested classes do not receive special privileges and cannot access
private members of the outer class.
2002-04-07 21:28:43 +00:00
david
96474823b5 Implemented a very simple hash-table cache for property lookup using
relative paths.
2002-04-06 21:47:22 +00:00
curt
bbf4b54613 Initial revision. 2002-04-03 21:22:52 +00:00
curt
9795c5dd6b Added src-libs subdirectory for keeping source code to extra libs. These
are things that are needed, but that many systems already have packages
available to install, and many users may have versions of these already
installed to support other projects.  So rather than build and install by
default with the main SimGear build/install, these are kept separate so that
those users that don't have them already installed can build and install
them separately.
2002-04-03 21:21:29 +00:00
curt
addcace80d Added a very crude/simple initial README.Install. 2002-04-03 21:18:13 +00:00
curt
77e43a5fa8 - Added src-libs/boost.tar.gz and README.boost. This is in anticipation
of actually using them in the flightgear event manager.
- Now that we have several add on libs we are bundling with simgear (but
  not automatically built as part of the simgear build) I have moved them
  to their own subdirectory (src-libs).
2002-04-03 21:05:51 +00:00
curt
b751188e56 string == "" -> string.empty() conversion. 2002-04-03 02:34:20 +00:00
curt
1ad9a15864 Updated to the latest metakit release. This fixes a few bugs that could
possibly affect some users.  For details, see the metakit changelog at
the metakit home page: ttp://www.equi4.com/metakit/
2002-03-28 02:21:00 +00:00
david
d0d7878e0a Patch from Melchior Franz:
This module works mostly with char* and allocates memory with
strdup ... delete doesn't go well with malloc(). The transition
to string only would be nice, but some class interfaces return
char*, so it was more natural to just drop the deletes.
2002-03-27 11:42:09 +00:00
david
be5d365348 Patch from Melchior Franz:
Here is a patch that fixes a little problem in dome.cxx: The fog_color
is created in a sgVec3 (227) but then handed over to ::repaint(), which
expects a sgVec4 (282). Then (343) center_color (although defined as
sgVec4) is only initialized with 3 values, but later (441) assigned to
'slot' via sgCopyVec4.
2002-03-25 19:56:48 +00:00
david
a8e0002a64 Patch from Melchior Franz:
at several places material was copied to "buffer" using strncpy
without adding a closing '\0'. This again lead to access to non
initialized memory and potentially (and actually at least in one
case) to feeding garbage to atof(). In case the following garbage
happened to start with digits, we would get funny time
values.  :-)
   I just added the obligatory "buffer[n] = 0", which doesn't
really look professional now. Maybe we should use the string
class or define a helper function that strncopies =and= adds
a trailing zero?
   The last hunk fixes another buglet, that wasn't dangerous
at all, but caused an error message. The loop that should cut
the string at hash marks ('#') did neither stop at such, nor at
string ends. It always scanned the whole 256 character long
buffer and accessed uninitialized memory. valgrind doesn't
like that. I dropped the 256 counter, because fgets =does=
add the closing zero. It is safe to scan until we either
get the zero or the hash mark.
2002-03-25 19:50:32 +00:00
david
bf75cf7225 Removed an unnecessary string allocation during copying. 2002-03-22 15:02:50 +00:00
david
c024b680bc Removed commented-out dead code. 2002-03-22 13:18:49 +00:00
david
c896475765 More rearrangement of headers. Replaced delete with delete[] where
appropriate.
2002-03-22 12:45:11 +00:00
david
101fdb3598 Moved up #include <algorithm> 2002-03-22 12:38:34 +00:00
david
b13505afdf Fix segfault when deleting a node with a string value. 2002-03-21 15:19:26 +00:00
david
9d96b171a0 Patch from Frederic Bouvier:
deletion of a const char * is not allowed with MSVC 6. I had to cast to char
*
to avoid compile errors.
2002-03-20 21:44:38 +00:00
david
8b5a0cde69 Patch from Tony Peden to remove unused variable and eliminate compiler
warning.
2002-03-20 21:31:53 +00:00
david
bed7593cdd Moved includes higher to make sure that std::sort is known. 2002-03-20 13:43:23 +00:00
david
9fed946567 Include <algorithm> and <stdio.hxx> to fix compilation errors on some
platforms (I should have done this anyway).
2002-03-19 18:17:36 +00:00
david
4d0bc0ae39 Major property-manager rewrite, using const char * throughout
interface instead of string.  This will result in a lot more
efficiency later, once I add in a simple hash table for caching
lookups, since it will avoid creating a lot of temporary string
objects.  The major considerations for users will be that they cannot
use

  node->getName() == "foo";

any more, and will have to use c_str() when setting a string value
from a C++ string.
2002-03-19 16:07:47 +00:00
david
f9824aa7de Removed SGRawValueInternal class (it's now handled directly by
SGPropertyNode) and updated some out-of-date documentation comments.
2002-03-18 14:55:59 +00:00
david
4d2522964a Some code fixes to keep untying clean with new optimizations. 2002-03-18 14:55:15 +00:00
david
dbe4a59b8e Code cleanup and minor speed improvements. For the record, accessing
an internally-managed property is nearly twice as fast as accessing
one tied to methods.
2002-03-18 03:21:18 +00:00
david
918f8a3ed4 Patches from Tony Peden to separate property XML I/O operations into a
separate header file.  This change will help integrate properties into
JSBSim.
2002-03-15 23:16:46 +00:00
curt
f645596606 Fixed an 'elstupido' bug.
Cleaned out some old #ifdef'd out code.
2002-03-13 05:01:51 +00:00
curt
d778dd081d Added some increased functionality in support of the binary file format
additions.
2002-03-13 05:00:55 +00:00
curt
f6ed02c3fb zlib-1.1.3 had a potential security flaw which is fixed by zlib-1.1.4:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


Zlib Advisory 2002-03-11
zlib Compression Library Corrupts malloc Data Structures via Double Free

   Original release date: March 11, 2002
   Last revised: March 11, 2002
   Source: This advisory is based on a CERT advisory written
           by Jeffrey P. Lanza  http://www.kb.cert.org/vuls/id/368819

Systems Affected

     * Any software that is linked against zlib 1.1.3 or earlier
     * Any data compression library derived from zlib 1.1.3 or earlier

Overview

   There is a vulnerability in the zlib shared library that may introduce
   vulnerabilities   into   any   program   that   includes   zlib.  This
   vulnerability has been assigned a CVE name of CAN-2002-0059
   http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2002-0059

I. Description

   There  is  a  vulnerability in the decompression algorithm used by the
   popular  zlib  compression  library.  If an attacker is able to pass a
   specially-crafted  block of invalid compressed data to a program  that
   includes zlib,  the program's  attempt to decompress  the crafted data
   can cause the  zlib  routines to corrupt the internal data  structures
   maintained by malloc.

   The  vulnerability  results  from  a  programming  error  that  causes
   segments of dynamically allocated memory to be released more than once
   (aka.   "double-freed").  Specifically,  when  inftrees.c:huft_build()
   encounters  the  crafted data, it returns an unexpected Z_MEM_ERROR to
   inftrees.c:inflate_trees_dynamic().  When a subsequent call is made to
   infblock.c:inflate_blocks(), the inflate_blocks function tries to free
   an internal data structure a second time.

   Because  this  vulnerability interferes with the proper allocation and
   de-allocation of dynamic memory, it may be possible for an attacker to
   influence  the  operation  of  programs  that  include  zlib.  In most
   circumstances,  this influence will be limited to denial of service or
   information  leakage, but it is theoretically possible for an attacker
   to  insert  arbitrary  code into a running program. This code would be
   executed with the permissions of the vulnerable program.

II. Impact

   This vulnerability may introduce vulnerabilities into any program that
   includes  the  affected library. Depending upon how and where the zlib
   routines   are   called   from   the   given  program,  the  resulting
   vulnerability may have one or more of the following impacts: denial of
   service, information leakage, or execution of arbitrary code.

III. Solution

Upgrade your version of zlib

   The  maintainers  of  zlib have released version 1.1.4 to address this
   vulnerability.  Any software that is linked against or derived from an
   earlier  version  of  zlib  should be upgraded immediately. The latest
   version of zlib is available at http://www.zlib.org

   The md5 sums of the source archives are:
       abc405d0bdd3ee22782d7aa20e440f08  zlib-1.1.4.tar.gz
       ea16358be41384870acbdc372f9db152  zlib-1.1.4.tar.bz2

IV. Acknowledgments

Thanks to Owen Taylor and Mark Cox of Redhat, Inc. for the
reporting and research of this vulnerability.


This document is available from
http://www.gzip.org/zlib/advisory-2002-03-11.txt

The public PGP key of zlib author Jean-loup Gailly is available from
http://www.gzip.org/zlib/jloup.asc

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE8jSR02aJ9JQGWcacRAuDEAKCWdrRkWeJV9lYU5z8NN56s3m8eKACglR4m
42KDUGHuftBkwACTMCnZLEo=
=3yLS
-----END PGP SIGNATURE-----
2002-03-11 23:03:19 +00:00
curt
7fa5dd7a35 Added a warning message if the file is not found. 2002-03-11 21:47:09 +00:00
curt
a3186af099 Additions to the binary file format to make it *much* more flexible.
For each major primative type: points, triangles, fans, and strips, you
can specify an index list of vertices, normals, colors, and texture
coordinates.  You can skip any of these you like to save on space.

Note that the work for this has only been done in the file format reader
and writer.  The FlightGear loader for instance still needs to have
support for this built in.

This is is one more small step towards runway lighting.
2002-03-10 22:49:01 +00:00
david
a2d95ac742 Patch from Martin Dressler to ensure that values as well as children
get written with write-all.
2002-03-09 11:14:29 +00:00
david
10715bbea7 Modified to add an optional parameter to writeProperties to allow
*all* properties to be written, rather than just the ones flagged as
archivable.  Tony Peden requested this feature to make it easier for
people to document properties.
2002-03-03 21:22:24 +00:00
david
89fcb12556 Cleanups from Petru Paler:
It's basically a couple unused variables, an explicit cast, some unused
functions removed or commented out, and a whole bunch of pragmas
removed.
2002-03-02 23:37:04 +00:00
david
cc3d7ddee5 Minor changes to path caching. 2002-02-28 14:37:00 +00:00
curt
cc01f99acb Added support for points objects. 2002-02-27 23:08:45 +00:00
curt
62b75190bb Might as well bump up the version number. 2002-02-26 23:55:54 +00:00
curt
520124c1be Add initial support for per vertex or per object colors. 2002-02-26 20:05:20 +00:00
curt
e251bfcbaf Extended .btg format to support a 'points' primitive. 2002-02-26 19:47:06 +00:00
david
aef809348f IMPORTANT: backwards-incompatible change to properties.
The useDefault argument for the SGPropertyNode::tie(...) methods will
invoke the setter only when there is already a property value defined;
previously, the setter was always invoked, with a default value if
necessary.
2002-02-19 15:20:02 +00:00
curt
2d4a8774b8 Updated version number. 2002-02-15 17:27:50 +00:00
curt
b55c8fd828 Removed duplicate message. 2002-02-15 17:22:53 +00:00
curt
dfff091b5f Updated ... 2002-02-15 17:13:12 +00:00
curt
47eb7efafa Added README's to distribution. 2002-02-14 21:35:32 +00:00
curt
b2a7fff26e Explicitely reset the glBlendFunc() after drawing the moon for the Voodoo2
linux driver since it seems to have a bug in glPopAttrib().
2002-02-14 14:21:48 +00:00
curt
5f70123723 0.7.9pre2 changes. 2002-02-13 15:10:06 +00:00
david
dd629da8d3 Replaced some cout's with SG_LOG (fixes namespace problem with
ANSI-conformant compilers).
2002-02-13 12:14:01 +00:00
curt
74f7d52d95 Fixed a problem that could lead to a 'near infinite' loop if bogus input
values are provided.
2002-02-12 15:21:14 +00:00
curt
7a65a990ba Decouple sg_time code from the current time(NULL), i.e. you can run the
time calculations for an alternate calendar time (i.e. if the application
is being driven from an external source of data.)

Fix a bug in sg_binobj.cxx which disrupted the 'broken down time' globally
for the entire application.
2002-02-11 22:27:27 +00:00
curt
fe0076e291 Updated with 0.0.17 changes. 2002-02-10 04:10:00 +00:00
curt
1a8bc06cc6 FreeBSD fix: strnstr() is already defined. 2002-02-10 03:28:57 +00:00
curt
8c41081a5c This code had been written to assume current clock time. Added options
to allow specifying an alternate clock time.
2002-02-10 03:16:03 +00:00
curt
5b40eed554 Fixes a config problem that could lead to a bogus build for people with
voodoo cards.
2002-02-07 22:37:09 +00:00
curt
b1c4d34eef Fix for FreeBSD. 2002-02-06 01:04:38 +00:00
curt
0152b607f8 Tweaks ... 2002-02-05 21:36:09 +00:00
curt
ab6e72047b oops, minor tweaks. 2002-02-04 22:48:30 +00:00
curt
15399bfe95 Various mingwin patches contributed by Norman Vine. 2002-02-04 22:38:23 +00:00
curt
0ff748987b Pass strings by const reference instead of by value,
Made fix_path() a private member function, SGPath::fix(),
Added bool SGPath::exists(),
Added an assignment operator that acts like SGPath::append().
2002-02-04 20:23:41 +00:00
curt
58e0e7736b Removed some depricated irix support that is now handled elsewhere. 2002-02-01 20:18:47 +00:00
david
2d1b2ca938 Minor fixes from Cameron Moore. 2002-01-30 15:09:56 +00:00
curt
9a4152eb2d Fixes to make telnet interface work more than 1x. 2002-01-28 21:48:00 +00:00
curt
6ab443545f Further autogen.sh fixes to handle more cases. 2002-01-19 13:45:06 +00:00
curt
98a9b4a10c Minor clean ups. 2002-01-19 13:37:22 +00:00
david
a6251606dd Added some new functionality to the property manager:
1. Nodes cache previous relative paths so that they do not have to
parse the paths each time.

2. There are new getNode() methods that include indices, so that users
do not have to sprintf to a buffer to iterate through indexed nodes.
2002-01-19 03:06:22 +00:00
curt
c3b21e143c Fixed typos ... 2002-01-17 16:58:18 +00:00
curt
b496593883 Updated to automatically handle newer versions of automake.
Does some IRIX specific fixups.
2002-01-17 15:21:49 +00:00
curt
4ef4b019ca Added conditional support for Norman's jpegfactory code (requires libjpeg
to be already installed.)
2002-01-16 21:13:27 +00:00
curt
a8021531ab Initial revision of jpegfactory code for generating jpeg format screen dumps. 2002-01-16 21:11:00 +00:00
david
93fd948978 Added aclocal.m4 2002-01-16 00:04:16 +00:00
curt
a1b3740dc6 A few changes from Norman Vine to support mingwin. 2002-01-15 22:28:21 +00:00
curt
40920457cb Initial revision. 2001-12-29 03:35:31 +00:00
curt
5039c84fd0 Removed metakit and zlib from the configure/build process. The
developer will need to build and install these separately if they
don't have packages already installed by their system.  See
README.metakit and README.zlib for more details.

As a convenience, pristine tarballs of the metakit and zlib source
code trees are included with the simgear distribution (and cvs.)
2001-12-29 00:38:04 +00:00
curt
220a43bf46 Removed metakit and zlib from the configure/build process. The
developer will need to build and install these separately if they don't
have packages already installed by their system.  See README.metakit and
README.zlib for more details.

As a convenience, pristine tarballs of the metakit and zlib source code
trees are included with the simgear distribution (and cvs.)
2001-12-29 00:35:34 +00:00
curt
45d3e19c38 Small tweaks to class initialization. 2001-12-28 23:37:34 +00:00
curt
5bab565cfe Updates to build system to better support automake-1.5
- automake-1.4 sets default values for INCLUDES which we can't
  overwrite.
- automake-1.5 renames this to DEFAULT_INCLUDES and leaves INCLUDES
  open for the developer to use.

Thus for automake-1.4 we are forced to 'append' to INCLUDES and in
automake-1.5 we can just set the value to whatever we like.
Unfortunately, the behaviors of the two versions are mutually
incompatible.

The solution I am committing now works for both versions but
automake-1.5 generates a lot of spurious warning messages that are
annoying, but not fatal.
2001-12-28 21:27:19 +00:00
curt
319a4282c8 Test commit. 2001-12-17 16:52:20 +00:00
david
c6aa8bc8e9 Fixed Makefile.am to install easyxml.hxx in the simgear/xml rather
than simgear/.
2001-12-16 20:59:16 +00:00
david
6f1bfa202e -Added .cvsignore files to clean up CVS messages 2001-12-12 02:44:37 +00:00
david
6fa9f86d1c Added trace attributes to properties:
TRACE_READ - log a message whenever the property is read.

TRACE_WRITE - log a message whenever the property is written.

The second one works only when the property value is changed through
the property manager; tied variables and accessors are not polled for
value changes because of the performance hit.

These methods end up invoking private methods
SGPropertyNode::trace_read and SGPropertyNode::trace_write.  By
setting breakpoints on these methods inside a debugger, it is possible
to debug property access and find what parts of a program are reading
or writing specific property values by doing a backtrace.

In the XML property files, users can use the attributes 'trace-read'
and 'trace-write' to control tracing; the value should be 'y' to
enable tracing or 'n' to disable it (the default).
2001-12-12 02:28:28 +00:00
david
019a9527d2 Added Curt to empty Authors file as CVS test. 2001-12-11 22:23:25 +00:00
curt
d100ca485f Doh! fixed a typo ... 2001-12-10 00:24:51 +00:00
curt
35ab6900ee [Hopefully] fix a line ending problem that surfaces in MSVC. 2001-12-09 03:54:46 +00:00
curt
c8570302f5 Removed this autogenerated file from CVS. 2001-12-06 22:53:29 +00:00
curt
74f10486bc In certain degenerate situations on the FlightGear side when the flight
model math blows up, the lat/lon could be nan.  Thus updateLocal() could
potentially called with nan arguments if FlightGear is reiniting from a
blown up state.  This is a bug in FlightGear, but I've added a simple
check to catch this so updateLocal() is robust if called under these
circumstances.
2001-12-05 22:31:03 +00:00
curt
2b12425a62 Christian M. says it's bad to chain one constructor call from another.
I can't find anything that addresses this in Stroustrup, but I also don't
see them doing this in any of their examples.  So I have rewritten this
instance to use default arguments to accomplish the same thing.  I imagine
there are other instances of this same sort of thing in other classes to
be fixed at a later date.
2001-11-27 03:17:43 +00:00
curt
c600aad7a7 Bernie Bright: support for Intel C++ under Linux. 2001-11-21 21:31:40 +00:00
curt
67b2f0a977 - changed getAttribute to avoid MSVC compiler warning 2001-11-20 20:57:07 +00:00
curt
70c6b48a07 - implemented set/get_log_classes and set/get_log_priority 2001-11-20 20:56:53 +00:00
curt
76084f8538 Oops, typo ... 2001-11-12 18:20:32 +00:00
curt
64c408d2b7 Updated RPM make rule as per Ross Golder. 2001-11-12 17:37:24 +00:00
curt
73b050ae34 Mixed a makefile typo. 2001-11-12 15:27:32 +00:00
curt
59991393ca plib/net based udp client/server sockets. 2001-11-12 04:47:58 +00:00
curt
69b2717b62 One more tiny Irix tweak. 2001-10-24 20:01:15 +00:00
curt
f2a323e048 Misc Irix tweaks. 2001-10-24 19:59:05 +00:00
curt
7d07e6ea51 Misc MSVC tweaks. 2001-10-24 19:05:16 +00:00
curt
7c846972bf Macintosh OSX changes. 2001-10-23 20:22:12 +00:00
curt
4f76c258af MSVC tweaks. 2001-08-13 17:14:21 +00:00
curt
eca2afb982 Various changes for MingWin32 support. 2001-08-02 22:56:33 +00:00
curt
9ff6934c83 Various MSVC fixes. 2001-07-30 20:34:20 +00:00
curt
e04839765d Updates for irix to disable various warnings and define
__STL_FUNCTION_TMPL_PARTIAL_ORDER
2001-07-30 20:05:27 +00:00
curt
d0c655109f Oops, missing a trainling backslash after exception.hxx 2001-07-28 04:00:10 +00:00
curt
b28b55abb1 - removed declaration of sg_xml_exception (use sg_io_exception) 2001-07-24 21:41:33 +00:00
curt
c3a0db1aba - make sure file is closed when an exception passes through 2001-07-24 21:41:19 +00:00
curt
5e929d7d01 - remove dependencies on sg_throwable::clone 2001-07-24 21:41:06 +00:00
curt
17f113f8cd - remove clone methods for exceptions (SGI/Irix compiler bugs)
- added declaration for sg_throwable::getFormattedMessage
- added declaration for sg_io_exception::getFormattedMessage
- added #ifdef wrapper
2001-07-24 21:40:57 +00:00
curt
445cd4ccda - remove clone method declarations (SGI/Irix compiler bugs)
- added default implementation for sg_throwable::getFormattedMessage
  (returns sg_throwable::getMessage by default)
- removed unneeded newline in sg_location::asString
2001-07-24 21:40:46 +00:00
curt
55845bbbb9 Added exceptions.[ch]xx 2001-07-19 02:34:43 +00:00
curt
1976481ba2 - added sg_xml_exception class
- changed return type of readXML from bool to void (uses an exception
  to report problems now)
- removed XMLVisitor::error callback
- declared new readXML function that uses a path rather than a stream
- modified existing readXML function to take an optional path parameter
2001-07-19 02:34:18 +00:00
curt
5f17edbc72 - implemented sg_xml_exception class
- implemented new readXML function with path instead of stream
- modified existing readXML function to use optional path parameter
- modified readXML to throw exceptions rather than returning a bool
  value on error
2001-07-19 02:33:58 +00:00
curt
6f7fe4b481 - modified both readProperties functions to return void, and modified
file-name variant to invoke new readXML function
- readProperties and writeProperties will now throw exceptions if there
  are file I/O problems
- replace error messages with exceptions
- tunnel sg_io_exception through from nested property read, since
  the C-based Expat code cannot handle exceptions
2001-07-19 02:33:38 +00:00
curt
66ebe6e690 - changed return type of both readProperties functions to void
- changed return type of both writeProperties functions to void
2001-07-19 02:33:18 +00:00
curt
a9cd67e0ce - new file: implementation of SimGear general exception classes 2001-07-19 02:33:00 +00:00
curt
994a470fbf Prepairing for 0.0.17 2001-07-13 14:58:14 +00:00
curt
0ce0684dae Added a missing include for memcpy() 2001-07-13 03:36:50 +00:00
curt
377eb4782a Updated for 0.0.16 2001-07-13 03:36:29 +00:00
curt
f1a79e6b9f - changed default value of "archive" attribute from "y" to "n"
- modified to write out non-archivable parents if they have an
  archivable descendant (i.e. archive="n" no longer kills a whole
  subbranch); this makes sense now that archive defaults to "n".
- don't save the flags -- let the program handle them itself
- produce slightly less verbose output; omit n="0" in elements
2001-07-12 21:09:12 +00:00
curt
007a1e4659 - changed the default value of the archive flag to false; it must now
be set explicitly for a value to be saved
2001-07-12 21:08:58 +00:00
curt
fcb873b6dd - added virtual destructor to XMLVisitor to make sure derived classes
get a virtual destructor automatically.
2001-07-11 16:02:26 +00:00
curt
a66d1ad855 Check for valid hostname lookup in sg_socket.cxx. 2001-07-10 14:13:51 +00:00
curt
76a5950f19 Add a separate function to just return modified julian date. 2001-07-03 14:39:05 +00:00
curt
b7a91bdb03 Various tweaks for Irix. 2001-07-02 20:51:32 +00:00
curt
e4bbc5c50b Fix a potential array under/over run bug. 2001-06-30 02:01:22 +00:00
curt
b481ccd749 Tweaks to track changes in property manager. 2001-06-28 21:54:02 +00:00
curt
e7b9e55599 - removed all reference to SGValue
- renamed UNKNOWN to UNSPECIED and setUnknownValue to
  setUnspecifiedValue
- modified routines to use 'read', 'write', and 'archive' attribute
  for access-mode attributes (only if non-default; they all default to
  'y')
- modified write routine to honour ARCHIVE attribute (won't write
  subtree if ARCHIVE is not set)
2001-06-28 21:53:46 +00:00
curt
05eaa7135f - made getValue methods protected, so that they won't be invoked outside
the class
- renamed UNKNOWN to UNSPECIED and setUnknownValue to
  setUnspecifiedValue
- added access-mode attributes
- added methods for setting and querying access-mode attributes
2001-06-28 21:53:34 +00:00
curt
d063b319e8 - attempting to tie an aliased node now fails; the node must be
unaliased first
- renamed UNKNOWN to UNSPECIED and setUnknownValue to
  setUnspecifiedValue
- modified get*Value and set*Value methods to respect READ and WRITE
  attributes
2001-06-28 21:53:24 +00:00
curt
be4fd56660 - added SGCommandState class so that commands can compile and save
copies of their arguments
- modified prototype for command functions -- they now take a pointer
  to a pointer of an SGCommandState object (which they will normally
  subclass) so that they can cache state between invocations
- commented out convenience execute methods until they're actually
  needed
2001-06-28 21:53:10 +00:00
curt
a406a3c00b - added implementation of SGCommandState
- removed commented-out convenience execute methods
2001-06-28 21:53:01 +00:00
curt
c7295da5eb Fixed a type conversion bug that could trip up some of the pickier compilers
out there.
2001-06-27 02:48:01 +00:00
curt
505f561e1c Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for
rendering ultra high res "tiled" screen shots.
2001-06-26 15:19:39 +00:00
curt
7bd8477fa1 Tweaks. 2001-06-20 18:35:42 +00:00
curt
36ef15940e Changes for 0.7.8 2001-06-20 18:12:18 +00:00
176 changed files with 20166 additions and 4606 deletions

8
.cvsignore Normal file
View File

@@ -0,0 +1,8 @@
Makefile
Makefile.in
SimGear.spec
aclocal.m4
config.cache
config.log
config.status
configure

View File

@@ -0,0 +1 @@
Curtis Olsen and others.

View File

@@ -22,7 +22,7 @@ PROJECT_NAME = SimGear
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 0.0.15
PROJECT_NUMBER = 0.0.19pre2
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.

View File

@@ -1,105 +1,21 @@
EXTRA_DIST = mksymlinks.sh acsite.m4 acconfig.h SimGear.dsp SimGear.dsw
EXTRA_DIST = \
acinclude.m4 \
autogen.sh \
mksymlinks.sh \
README.MSVC \
README.metakit \
README.zlib \
SimGear.dsp \
SimGear.dsw
SUBDIRS = simgear
#
# Additional all, clean, and distclean rules for additional packages.
# We can't just include the additional package dirs in SUBDIRS (which
# would be nice because there are then problems with make dist
#
all:
@list='@subdirs@'; \
target=`echo $@`; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done
install:
@list='@subdirs@'; \
target=`echo $@`; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done
clean:
@list='@subdirs@'; \
target=`echo $@`; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done
distclean:
@list='@subdirs@'; \
target=`echo $@`; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done
#
# distclean the associated packages and include them in the dist
#
SUBDIRS = src-libs simgear
dist-hook:
(cd $(top_srcdir); \
$(HOME)/projects/FlightGear-0.7/admin/am2dsp.pl --lib)
pwd
echo "copying simgear/metar"
(cd $(top_srcdir); tar cf - simgear/metar) | (cd $(distdir); tar xvf -)
echo "other stuff"
@list='@subdirs@'; \
target=distclean; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) echo "distclean error ignored...";; *k*) fail=yes;; *) echo "distclean error ignored...";; esac; \
done
(cd $(top_srcdir); tar cf - simgear/metakit) | \
(cd $(distdir); tar xvf -)
(cd $(top_srcdir); $(HOME)/projects/FlightGear-0.7/admin/am2dsp.pl)
#
# Rule to build RPM distribution package
#
rpm: dist
cp $(PACKAGE)-$(VERSION).tar.gz /usr/src/packages/SOURCES
rpm -ba @PACKAGE@.spec
rpm -ta $(PACKAGE)-$(VERSION).tar.gz

122
NEWS
View File

@@ -1,5 +1,116 @@
New in 0.2.0
* September 6, 2002
* Modernized the autoconf/make scripts, plus lots of tweaks and enhancements.
* Removed efence support (in favor of valgrind.)
* Added a javascript interpreter.
* SGSocket reimplimented on top of plib/net libs.
* Added a new random number generation algorithm.
* Total rewrite of the strutils package.
* Patch for the random number seed.
* IA-64 w/ Intel compiler fixes.
* MSVC/MINGW fixes.
* Mac OS X fixes.
* Irix fixes.
* Code clean ups to remove warning messages.
* Optimizations in sg_binobj to reduce the amout of memory copying
needed when loading a binobj format file.
* Fixed a couple places where variables could be used before they were
initialized.
* Various property manager fixes and improvements.
* Fixes to cloud layer management code.
* Made the sky dome more flexible to facilitate use in other applications.
New in 0.0.18
* April 20, 2002
* Created a src/libs subdirectory for several packages that need to be
installed by the user but are used by many other packages and may already
be installed. So we just bundle the source separately as a convenience
if the user needs to build and install these.
* Upgrade to zlib-1.1.4 (security fix)
* Upgrade to metakit-2.4.2-32.tar.gz (latest upstream release)
* Added support for point objects in the scenery file format.
* Additions to the binary file format to make it *much* more flexible.
For each major primative type: points, triangles, fans, and strips, you
can specify an index list of vertices, normals, colors, and texture
coordinates. You can skip any of these you like to save on space.
* Added support for new file features in the binary -> ascii scenery file
decoder.
* Various code clean ups.
* Separate XML I/O operations into a separate header file.
* Major property manager rewrite, then lots of followup cleaning and
improvements.
New in 0.0.17 (final)
* February 16, 2002
* Explicitely reset the glBlendFunc() after drawing the moon for the
Voodoo2 linux driver since it seems to have a bug in glPopAttrib().
New in 0.0.17pre2
* February 13, 2002
* Replaced some cout's with SG_LOG's
New in 0.0.17pre1
* February 12, 2002
* Removed metakit and zlib from build process. Tarballs are still included
for those who's systems don't provide these packages.
* MSVC fixes.
* IRIX fixes.
* Mingwin fixes.
* Mac OS X fixes.
* FreeBSD fixes.
* Added support for Intel's C++ compiler under Linux.
* Attempt to build in support for various non-compatible automake/autoconf
versions.
* Fix for a problem that could lead to a bogus build for people with voodoo
cards.
* Added Norman's jpegfactory code which can create jpeg format screen shots
of a live running application.
* implemented set/get_log_classes and set/get_log_priority.
* Socket library improvements.
* Added a C++ exception abstraction.
* Property manager fixes and improvements including node path caching
and debug tracing of property reads/writes.
* Updates/fixes to xml handling.
New in 0.0.16
* July 12, 2001
* Various changes to the property manager implimentation to better support
dumping out the desired portions of the property tree to file.
* Don't compile the metakit demos by default (causes problems for Irix)'
* Other various tweaks for Irix.
* Added a virtual destructor to XMLVisitor to fix a warning message.
* Check for valid hostname lookup in sg_socket.cxx
* Add a function to return modified julian date without creating an
entire SGTime class. This avoids an extraneous warning about not
being able to find a timezone.
* Created a mailing list for cvs commit messages.
* Fixed a potential array under/over run bug in interpolator.cxx
* Removed all references to SGValue from the property manager. Added
support for an "archive" bit in the property manager to control
which values get written out.
* Added SGCommandState class so that commands can compile and save
copies of their arguments for efficiency if they are called multiple
times.
* Added Brian Baul's "tr" tiled rendering low level support library.
This along with some higher level code in flightgear allows us to do
ultra-hires tiled screen dumps suitable for large format printers.
(Norman Vine)
New in 0.0.15
* June 22, 2001
* June 20, 2001
* Various bug fixes, tweaks, and optimizations.
* Added a command manager (analogous to the property manager)
* Better Irix Mips support.
@@ -26,6 +137,7 @@ New in 0.0.15
* Fixed some critical null pointer bugs in property manager.
* Magnetic variation can now be fetched for any arbitrary location.
New in 0.0.14
* December 14, 2000
* Added a module to manage waypoints and routes, calculate bearing and
@@ -47,6 +159,7 @@ New in 0.0.14
* MacOS tweaks.
* FreeBSD tweaks.
New in 0.0.13
* September 14, 2000
* Added support for reading and writing xml files (easyxml)
@@ -57,6 +170,7 @@ New in 0.0.13
* MacOS tweaks.
* MSVC tweaks.
New in 0.0.12
* July 19, 2000
* Converted project license from GPL to LGPL.
@@ -66,6 +180,7 @@ New in 0.0.12
* Added a property manager (registry)
* Some documentation added.
New in 0.0.11
* July 3, 2000
* Replaced gdbm with metakit
@@ -74,6 +189,7 @@ New in 0.0.11
* MSVC5 fixes
* Math/bucket/tiling tweaks from Norman Vine
New in 0.0.7
* March 29, 2000
* Added support for RedHat package building contributed by Habibie
@@ -86,18 +202,22 @@ New in 0.0.7
* Optimizations and bullet proofing of magnetic variation code by Norman
Vine and Ed Williams
New in 0.0.6
* March 27, 2000
* Added Nima World Magnetic Model 2000 contributed by Ed Williams
* Fixes for MSVC++
New in 0.0.5
* March 17, 2000
* Restructured directory layout to facilitate windows/mac IDE builds.
New in 0.0.4
* Removed mat3.h and friends (we now use plib's sg lib for these sorts of
things.)
New in 0.0.3
* Release that conincides with FlightGear-0.7.2

4
README
View File

@@ -1,3 +1 @@
MSVC5 users:
Copy simgear/config.h.vc5 to simgear/config.h before building.
[ Nothing here at this time. ]

24
README.MSVC Normal file
View File

@@ -0,0 +1,24 @@
This document describes how to build SimGear using the supplied workspace and
project files.
Unpack the SimGear source file into your work directory. This creates a new
subdirectory called SimGear-X.Y.Z. Rename this to SimGear. Before we can
build SimGear you must unpack and build the third party libraries metakit and
zlib. Sources for these are included in the SimGear/src-libs directory.
Unpack these into the top level SimGear directory. At this point your
directory structure should look something like this:
<work_dir>/
SimGear/
metakit-x.y.z/
simgear/
src-libs/
zlib-x.y.z/
Now open the SimGear workspace. This workspace file contains projects for
building metakit(mklib), SimGear and zlib. Select each project as the active
project and build all. Order is unimportant since there are no dependencies
between the projects.
The workspace and project files are generated by a perl script with extra
input from the am2dsp.cfg file.

View File

@@ -1,6 +1,23 @@
With the author's permission, SimGear now bundles MetaKit.
For your convenience (and with the author's permission) a copy of the
MetaKit source is bundled with SimGear in $(top_srcdir)/src-libs/.
You must have metakit installed before you can build SimGear.
Important build note:
- Most linux distributions have a metakit package. For linux
developers, we recommend ysou install your distributions package
rather than building from source.
- For developers on most other platforms, you will have to build
metakit from source and install it yourself. For your convenience a
tar ball of the metakit source is included with the simgear source
distribution. Untar the metakit source, and follow the included
build and installation instructions.
Once metakit is installed you can return to configuring and building
Simgear.
=============================================================================
Potentially important build note:
Later on when you are linking programs with -lmk4 (i.e. FlightGear or one
of it's associated programs) if you come across an error similar to the

16
README.plib Normal file
View File

@@ -0,0 +1,16 @@
[This file is mirrored in both the FlightGear and SimGear packages.]
You *must* have plib version 1.6.0 or later installed on your system
to build FlightGear!" Flight Gear is no longer compatible with the
earlier versions of the library.
You can get the latest version of plib from:
http://plib.sourceforge.net
Build notes:
You should be able to just run "./configure" to configure the package
and use all of plib's defaults. Then run "make" followed by "make
install". By default, plib installs itself into /usr so if you don't
like this, be sure to specify an alternate prefix such as --prefix=/usr/local

173
README.zlib Normal file
View File

@@ -0,0 +1,173 @@
For your convenience and allowed by zlib's license terms:
http://www.gzip.org/zlib/zlib_license.html a copy of the zlib source
is bundled with SimGear in $(top_srcdir)/src-libs/. You must have
zlib installed before you can build SimGear.
- Most linux distributions have a zlib package. For linux
developers, we recommend ysou install your distributions package
rather than building from source.
- Cygwin installs zlib automatically.
- For developers on most other platforms, you will have to build
zlib from source and install it yourself. For your convenience a
tar ball of the zlib source is included with the simgear source
distribution. Untar the zlib source, and follow the included
build and installation instructions.
Once zlib is installed you can return to configuring and building
Simgear.
We now send you to the official zlib README ...
=============================================================================
zlib 1.1.4 is a general purpose data compression library. All the code
is thread safe. The data format used by the zlib library
is described by RFCs (Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
format) and rfc1952.txt (gzip format). These documents are also available in
other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
All functions of the compression library are documented in the file zlib.h
(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
example of the library is given in the file example.c which also tests that
the library is working correctly. Another example is given in the file
minigzip.c. The compression library itself is composed of all source files
except example.c and minigzip.c.
To compile all files and run the test program, follow the instructions
given at the top of Makefile. In short "make test; make install"
should work for most machines. For Unix: "./configure; make test; make install"
For MSDOS, use one of the special makefiles such as Makefile.msc.
For VMS, use Make_vms.com or descrip.mms.
Questions about zlib should be sent to <zlib@gzip.org>, or to
Gilles Vollant <info@winimage.com> for the Windows DLL version.
The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
Before reporting a problem, please check this site to verify that
you have the latest version of zlib; otherwise get the latest version and
check whether the problem still exists or not.
PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
before asking for help.
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of Dr. Dobb's Journal; a copy of the article is available in
http://dogma.net/markn/articles/zlibtool/zlibtool.htm
The changes made in version 1.1.4 are documented in the file ChangeLog.
The only changes made since 1.1.3 are bug corrections:
- ZFREE was repeated on same allocation on some error conditions.
This creates a security problem described in
http://www.zlib.org/advisory-2002-03-11.txt
- Returned incorrect error (Z_MEM_ERROR) on some invalid data
- Avoid accesses before window for invalid distances with inflate window
less than 32K.
- force windowBits > 8 to avoid a bug in the encoder for a window size
of 256 bytes. (A complete fix will be available in 1.1.5).
The beta version 1.1.5beta includes many more changes. A new official
version 1.1.5 will be released as soon as extensive testing has been
completed on it.
Unsupported third party contributions are provided in directory "contrib".
A Java implementation of zlib is available in the Java Development Kit
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
See the zlib home page http://www.zlib.org for details.
A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
is in the CPAN (Comprehensive Perl Archive Network) sites
http://www.cpan.org/modules/by-module/Compress/
A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
is available in Python 1.5 and later versions, see
http://www.python.org/doc/lib/module-zlib.html
A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
An experimental package to read and write files in .zip format,
written on top of zlib by Gilles Vollant <info@winimage.com>, is
available at http://www.winimage.com/zLibDll/unzip.html
and also in the contrib/minizip directory of zlib.
Notes for some targets:
- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
The zlib DLL support was initially done by Alessandro Iacopetti and is
now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
home page at http://www.winimage.com/zLibDll
From Visual Basic, you can call the DLL functions which do not take
a structure as argument: compress, uncompress and all gz* functions.
See contrib/visual-basic.txt for more information, or get
http://www.tcfb.com/dowseware/cmp-z-it.zip
- For 64-bit Irix, deflate.c must be compiled without any optimization.
With -O, one libpng test fails. The test works in 32 bit mode (with
the -n32 compiler flag). The compiler bug has been reported to SGI.
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
it works when compiled with cc.
- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
is necessary to get gzprintf working correctly. This is done by configure.
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
with other compilers. Use "make test" to check your compiler.
- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
- For Turbo C the small model is supported only with reduced performance to
avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
Per Harald Myrvang <perm@stud.cs.uit.no>
Acknowledgments:
The deflate format used by zlib was defined by Phil Katz. The deflate
and zlib specifications were written by L. Peter Deutsch. Thanks to all the
people who reported problems and suggested various improvements in zlib;
they are too numerous to cite here.
Copyright notice:
(C) 1995-2002 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
If you use the zlib library in a product, we would appreciate *not*
receiving lengthy legal documents to sign. The sources are provided
for free but without warranty of any kind. The library has been
entirely written by Jean-loup Gailly and Mark Adler; it does not
include third-party code.
If you redistribute modified sources, we would appreciate that you include
in the file ChangeLog history information documenting your changes.

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,30 @@ Package=<4>
###############################################################################
Project: "mklib"=".\SimGear\metakit-2.4.3\win\msvc60\mklib.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "zlib"=".\SimGear\zlib.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>

View File

@@ -1,333 +0,0 @@
/* acconfig.h
This file is in the public domain.
Descriptive text for the C preprocessor macros that
the distributed Autoconf macros can define.
No software package will use all of them; autoheader copies the ones
your configure.in uses into your configuration header file templates.
The entries are in sort -df order: alphabetical, case insensitive,
ignoring punctuation (such as underscores). Although this order
can split up related entries, it makes it easier to check whether
a given entry is in the file.
Leave the following blank line there!! Autoheader needs it. */
/* Define if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
#ifndef _ALL_SOURCE
#undef _ALL_SOURCE
#endif
/* Define if using alloca.c. */
#undef C_ALLOCA
/* Define if type char is unsigned and you are not using gcc. */
#ifndef __CHAR_UNSIGNED__
#undef __CHAR_UNSIGNED__
#endif
/* Define if the closedir function returns void instead of int. */
#undef CLOSEDIR_VOID
/* Define to empty if the keyword does not work. */
#undef const
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
This function is required for alloca.c support on those systems. */
#undef CRAY_STACKSEG_END
/* Define for DGUX with <sys/dg_sys_info.h>. */
#undef DGUX
/* Define if you have <dirent.h>. */
#undef DIRENT
/* Define to enable audio support */
#undef ENABLE_AUDIO_SUPPORT
/* Define to enable GLUT joystick support (limited to 3 axes) */
#undef ENABLE_GLUT_JOYSTICK
/* Define to enable plib joystick support (recommended) */
#undef ENABLE_PLIB_JOYSTICK
/* Define to eliminate all trace of debugging messages such as for a
release build */
#undef FG_NDEBUG
/* Define to include Oliver's networking support */
#undef FG_NETWORK_OLK
/* Define to avoid Christian's new weather code */
#undef FG_OLD_WEATHER
/* Define if we are building FGFS (should always be defined) */
#undef FGFS
/* Define to enable 3dfx/glide render in a window hack under unix.
This probably won't work under windows. */
#undef XMESA
#undef FX
/* Define to the type of elements in the array set by `getgroups'.
Usually this is either `int' or `gid_t'. */
#undef GETGROUPS_T
/* Define if the `getloadavg' function needs to be run setuid or setgid. */
#undef GETLOADAVG_PRIVILEGED
/* Define if the `getpgrp' function takes no argument. */
#undef GETPGRP_VOID
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
/* Define if you have alloca, as a function or macro. */
#undef HAVE_ALLOCA
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
#undef HAVE_ALLOCA_H
/* Define if you external variables daylight. */
#undef HAVE_DAYLIGHT
/* Define if you don't have vprintf but do have _doprnt. */
#undef HAVE_DOPRNT
/* Define if your system has a working fnmatch function. */
#undef HAVE_FNMATCH
/* Define if your system has its own `getloadavg' function. */
#undef HAVE_GETLOADAVG
/* Define if you have getrusage() */
#undef HAVE_GETRUSAGE
/* Define if you have the getmntent function. */
#undef HAVE_GETMNTENT
/* Define if you have the gpc library and headers installed. */
#undef HAVE_GPC_H
/* Define if the `long double' type works. */
#undef HAVE_LONG_DOUBLE
/* Define if you support file names longer than 14 characters. */
#undef HAVE_LONG_FILE_NAMES
/* Define if you have a working `mmap' system call. */
#undef HAVE_MMAP
/* Define if system calls automatically restart after interruption
by a signal. */
#undef HAVE_RESTARTABLE_SYSCALLS
/* Define if you have rint() which rounds to closest int but returns
result as a double data type. */
#undef HAVE_RINT
/* Define if your struct stat has st_blksize. */
#undef HAVE_ST_BLKSIZE
/* Define if your struct stat has st_blocks. */
#undef HAVE_ST_BLOCKS
/* Define if you have the strcoll function and it is properly defined. */
#undef HAVE_STRCOLL
/* Define if your struct stat has st_rdev. */
#undef HAVE_ST_RDEV
/* Define if you have the stdint.h include. */
#undef HAVE_STDINT_H
/* Define if you have the strftime function. */
#undef HAVE_STRFTIME
/* Define if you have <sys/param.h> */
#undef HAVE_SYS_PARAM_H
/* Define if you have <sys/stat.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_STAT_H
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define if you have timegm() */
#undef HAVE_TIMEGM
/* Define if you external variables timezone. */
#undef HAVE_TIMEZONE
/* Define if your struct tm has tm_zone. */
#undef HAVE_TM_ZONE
/* Define if you don't have tm_zone but do have the external array
tzname. */
#undef HAVE_TZNAME
/* Define if you have <unistd.h>. */
#undef HAVE_UNISTD_H
/* Define if utime(file, NULL) sets file's timestamp to the present. */
#undef HAVE_UTIME_NULL
/* Define if you have <vfork.h>. */
#undef HAVE_VFORK_H
/* Define if you have the vprintf function. */
#undef HAVE_VPRINTF
/* Define if you have the wait3 system call. */
#undef HAVE_WAIT3
/* Define if you have gdbm installed system wide. */
/* #undef HAVE_GDBM */
/* Define if you have zlib installed system wide. */
#undef HAVE_ZLIB
/* Define as __inline if that's what the C compiler calls it. */
#undef inline
/* Define if int is 16 bits instead of 32. */
#undef INT_16_BITS
/* Define if long int is 64 bits. */
#undef LONG_64_BITS
/* Define if major, minor, and makedev are declared in <mkdev.h>. */
#undef MAJOR_IN_MKDEV
/* Define if major, minor, and makedev are declared in <sysmacros.h>. */
#undef MAJOR_IN_SYSMACROS
/* Define if on MINIX. */
#undef _MINIX
/* Define to `int' if <sys/types.h> doesn't define. */
#undef mode_t
/* Define if you don't have <dirent.h>, but have <ndir.h>. */
#undef NDIR
/* Define if you have <memory.h>, and <string.h> doesn't declare the
mem* functions. */
#undef NEED_MEMORY_H
/* Define if your struct nlist has an n_un member. */
#undef NLIST_NAME_UNION
/* Define if you have <nlist.h>. */
#undef NLIST_STRUCT
/* Define if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O
/* Define to `long' if <sys/types.h> doesn't define. */
#undef off_t
/* Define to package name */
#undef PACKAGE
/* Define to `int' if <sys/types.h> doesn't define. */
#undef pid_t
/* Define if the system does not provide POSIX.1 features except
with this defined. */
#undef _POSIX_1_SOURCE
/* Define if you need to in order for stat and other things to work. */
#undef _POSIX_SOURCE
/* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE
/* Define if the `setpgrp' function takes no argument. */
#undef SETPGRP_VOID
/* Define if the setvbuf function takes the buffering type as its second
argument and the buffer pointer as the third, as on System V
before release 3. */
#undef SETVBUF_REVERSED
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#undef size_t
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown
*/
#undef STACK_DIRECTION
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
#undef STAT_MACROS_BROKEN
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define on System V Release 4. */
#undef SVR4
/* Define if you don't have <dirent.h>, but have <sys/dir.h>. */
#undef SYSDIR
/* Define if you don't have <dirent.h>, but have <sys/ndir.h>. */
#undef SYSNDIR
/* Define if `sys_siglist' is declared by <signal.h>. */
#undef SYS_SIGLIST_DECLARED
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define if your <sys/time.h> declares struct tm. */
#undef TM_IN_SYS_TIME
/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t
/* Define for Encore UMAX. */
#undef UMAX
/* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
instead of <sys/cpustats.h>. */
#undef UMAX4_3
/* Define if you do not have <strings.h>, index, bzero, etc.. */
#undef USG
/* Define to version number */
#undef VERSION
/* Define vfork as fork if vfork does not work. */
#undef vfork
/* Define if the closedir function returns void instead of int. */
#undef VOID_CLOSEDIR
/* Define if compiling on a Winbloze (95, NT, etc.) platform */
#undef WIN32
/* Define if your processor stores words with the most significant
byte first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define if the X Window System is missing or not being used. */
#undef X_DISPLAY_MISSING
/* Define if lex declares yytext as a char * by default, not a char[]. */
#undef YYTEXT_POINTER
/* Leave that blank line there!! Autoheader needs it.
If you're adding to this file, keep in mind:
The entries are in sort -df order: alphabetical, case insensitive,
ignoring punctuation (such as underscores). */

View File

@@ -102,7 +102,7 @@ for exdir in $exdirs ; do
mylibdir="${exdir}/lib${subexdir}"
wi_EXTRA_LDIR($mylibdir)
progdir="${exdir}/bin${subexdirr}"
progdir="${exdir}/bin${subexdir}"
wi_EXTRA_PDIR($progdir)
fi
done

140
aclocal.m4 vendored
View File

@@ -1,140 +0,0 @@
dnl aclocal.m4 generated automatically by aclocal 1.4
dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
dnl PARTICULAR PURPOSE.
# Do all the work for Automake. This macro actually does too much --
# some checks are only needed if your package does certain things.
# But this isn't really a big deal.
# serial 1
dnl Usage:
dnl AM_INIT_AUTOMAKE(package,version, [no-define])
AC_DEFUN(AM_INIT_AUTOMAKE,
[AC_REQUIRE([AC_PROG_INSTALL])
PACKAGE=[$1]
AC_SUBST(PACKAGE)
VERSION=[$2]
AC_SUBST(VERSION)
dnl test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
ifelse([$3],,
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
AC_REQUIRE([AM_SANITY_CHECK])
AC_REQUIRE([AC_ARG_PROGRAM])
dnl FIXME This is truly gross.
missing_dir=`cd $ac_aux_dir && pwd`
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
AC_REQUIRE([AC_PROG_MAKE_SET])])
#
# Check to make sure that the build environment is sane.
#
AC_DEFUN(AM_SANITY_CHECK,
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftestfile
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
if test "[$]*" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftestfile`
fi
if test "[$]*" != "X $srcdir/configure conftestfile" \
&& test "[$]*" != "X conftestfile $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "[$]2" = conftestfile
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
rm -f conftest*
AC_MSG_RESULT(yes)])
dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
dnl The program must properly implement --version.
AC_DEFUN(AM_MISSING_PROG,
[AC_MSG_CHECKING(for working $2)
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
if ($2 --version) < /dev/null > /dev/null 2>&1; then
$1=$2
AC_MSG_RESULT(found)
else
$1="$3/missing $2"
AC_MSG_RESULT(missing)
fi
AC_SUBST($1)])
# Define a conditional.
AC_DEFUN(AM_CONDITIONAL,
[AC_SUBST($1_TRUE)
AC_SUBST($1_FALSE)
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi])
# Like AC_CONFIG_HEADER, but automatically create stamp file.
AC_DEFUN(AM_CONFIG_HEADER,
[AC_PREREQ([2.12])
AC_CONFIG_HEADER([$1])
dnl When config.status generates a header, we must update the stamp-h file.
dnl This file resides in the same directory as the config header
dnl that is generated. We must strip everything past the first ":",
dnl and everything past the last "/".
AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
<<am_indx=1
for am_file in <<$1>>; do
case " <<$>>CONFIG_HEADERS " in
*" <<$>>am_file "*<<)>>
echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
;;
esac
am_indx=`expr "<<$>>am_indx" + 1`
done<<>>dnl>>)
changequote([,]))])

39
am2dsp.cfg Normal file
View File

@@ -0,0 +1,39 @@
type = StaticLibrary,Multithreaded,
exclude_dir = threads
include_path = .
include_path = ..
include_path = .\SimGear
include_path = .\SimGear\metakit-2.4.3\include
include_path = ..\SimGear\zlib-1.1.4
define = HAVE_CONFIG_H
add_project = .\SimGear\metakit-2.4.3\win\msvc60\mklib.dsp,mklib
add_project = .\SimGear\zlib.dsp,zlib
# Rule to create simgear_config.h
add_source_file = SOURCE=.\simgear\simgear_config.h.vc5\
\
!IF "$(CFG)" == "SimGear - Win32 Release"\
\
# Begin Custom Build - Creating config.h\
InputPath=.\simgear\simgear_config.h.vc5\
\
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h\
\
# End Custom Build\
\
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"\
\
# Begin Custom Build - Creating config.h\
InputPath=.\simgear\simgear_config.h.vc5\
\
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h\
\
# End Custom Build\
\
!ENDIF\

52
autogen.sh Executable file
View File

@@ -0,0 +1,52 @@
#!/bin/sh
OSTYPE=`uname -s`
MACHINE=`uname -m`
AUTO_MAKE_VERSION=`automake --version | head -1 | awk '{print $4}' | sed -e 's/\.\([0-9]*\).*/\1/'`
if test $AUTO_MAKE_VERSION -lt 15; then
echo ""
echo "You need to upgrade to automake version 1.5 or greater."
echo "Most distributions have packages available to install or you can"
echo "find the source for the most recent version at"
echo "ftp://ftp.gnu.org/gnu/automake"
exit 1
fi
echo "Host info: $OSTYPE $MACHINE"
echo -n " automake: `automake --version | head -1 | awk '{print $4}'`"
echo " ($AUTO_MAKE_VERSION)"
echo ""
echo "Running aclocal"
aclocal
echo "Running autoheader"
autoheader
if [ ! -e simgear/simgear_config.h.in ]; then
echo "ERROR: autoheader didn't create simgear/simgear_config.h.in!"
exit 1
fi
echo "Running automake --add-missing"
automake --add-missing
echo "Running autoconf"
autoconf
if [ ! -e configure ]; then
echo "ERROR: configure was not created!"
exit 1
fi
echo ""
echo "======================================"
if [ -f config.cache ]; then
echo "config.cache exists. Removing the config.cache file will force"
echo "the ./configure script to rerun all it's tests rather than using"
echo "the previously cached values."
echo ""
fi
echo "Now you are ready to run './configure'"
echo "======================================"

View File

@@ -3,10 +3,14 @@ dnl working configure script.
dnl
dnl $Id$
AC_INIT(simgear/bucket/newbucket.cxx)
AC_INIT
AC_CONFIG_SRCDIR([simgear/bucket/newbucket.cxx])
# Require at least automake 2.52
AC_PREREQ(2.52)
dnl Initialize the automake stuff
AM_INIT_AUTOMAKE(SimGear, 0.0.15)
AM_INIT_AUTOMAKE(SimGear, 0.2.0)
dnl Specify KAI C++ compiler and flags.
dnl Borrowed with slight modification from blitz distribution.
@@ -34,14 +38,20 @@ AC_PROG_RANLIB
AC_PROG_INSTALL
AC_PROG_LN_S
# Used on the Irix platform
AR="ar"
ARFLAGS="cru"
OS=`uname -s`
if test "$OS" = "IRIX" -o "$OS" = "IRIX64"; then
if test "$CXX" = "CC"; then
AR="CC -ar"
AC_SUBST(AR)
ARFLAGS="-o"
fi
fi
AC_SUBST(AR)
AC_SUBST(ARFLAGS)
if echo $includedir | egrep "simgear$" > /dev/null; then
echo "includedir is" $includedir "libdir is" $libdir
@@ -49,38 +59,67 @@ else
includedir="${includedir}/simgear"
echo "includedir changed to" $includedir "libdir is" $libdir
fi
# set logging default value
# with_logging=yes
AC_ARG_WITH(logging, [ --with-logging Include logging output (default)])
if test "x$with_logging" = "xno" ; then
AC_DEFINE(FG_NDEBUG)
AC_DEFINE([FG_NDEBUG], 1, [Define for no logging output])
fi
dnl specify if we are building with "checker"
AC_ARG_WITH(efence, [ --with-efence Specify if we are building with "electric-fence"])
if test "x$with_efence" = "xyes" ; then
echo "Building with efence"
LIBS="$LIBS -lefence"
# Specify if we want to build with Norman's jpeg image server support.
# This requires libjpeg to be installed and available.
# Default to with_jpeg_server=no
JPEGLIB=''
AC_ARG_WITH(jpeg_factory, [ --with-jpeg-factory Include Norman's jpeg image factory support code])
if test "x$with_jpeg_factory" = "xyes" ; then
echo "Building with Norman's jpeg image factory support"
AC_CHECK_LIB(jpeg, jpeg_start_compress)
if test "x$ac_cv_lib_jpeg_jpeg_start_compress" != "xyes" ; then
echo
echo "In order to build the jpeg factory code you need libjpeg installed."
echo "otherwise please configure with the --with-jpeg-sever=no option"
echo
echo "libjpeg is available at :"
echo " ftp://ftp.uu.net in the directory graphics/jpeg"
exit 1
fi
else
echo "Building without Norman's jpeg image server support"
fi
AM_CONDITIONAL(ENABLE_JPEG_SERVER, test "x$with_jpeg_factory" = "xyes")
dnl Check for MS Windows environment
AC_CHECK_HEADER(windows.h)
dnl extra library and include directories
EXTRA_DIRS="/usr/local /usr/local/plib /usr/X11R6"
AC_EGREP_CPP(yes,
[#ifdef __MINGW32__
yes
#endif
],is_mingw=yes, is_mingw=no)
if test -d /opt/X11R6 ; then
EXTRA_DIRS="$EXTRA_DIRS /opt/X11R6"
echo "IS_MINGW = $is_mingw"
AM_CONDITIONAL(IS_MINGW, test "x$is_mingw" = "xyes")
AC_EGREP_CPP(yes,
[#ifdef __CYGWIN__
yes
#endif
],is_cygwin=yes, is_cygwin=no)
echo "IS_CYGWIN = $is_cygwin"
AM_CONDITIONAL(IS_CYGWIN, test "x$is_cygwin" = "xyes")
if test "x$HOSTTYPE" != "xmacintosh" -a "x$is_mingw" != "xyes"; then
dnl extra library and include directories
EXTRA_DIRS="/usr/local /usr/X11R6"
if test -d /opt/X11R6 ; then
EXTRA_DIRS="$EXTRA_DIRS /opt/X11R6"
fi
fi
if test "x$ac_cv_header_windows_h" = "xyes" ; then
EXTRA_DIRS="${EXTRA_DIRS} `pwd`/Win32"
# elif test `uname -s` = "SunOS" ; then
# EXTRA_DIRS="${EXTRA_DIRS} `pwd`/SunOS"
fi
wi_EXTRA_DIRS(no, ${EXTRA_DIRS})
dnl Using AM_CONDITIONAL is a step out of the protected little
@@ -90,11 +129,11 @@ dnl enough. AM_CONDITIONALS are then referenced to conditionally
dnl build a Makefile.in from a Makefile.am which lets us define custom
dnl includes, compile alternative source files, etc.
dnl Enable serial support on Unix type systems
AM_CONDITIONAL(ENABLE_UNIX_SERIAL, true)
dnl Check for X11 (fancy)
AC_PATH_XTRA
dnl X11 might be installed on Mac OS X, don't want to use it if it is.
if test "x$HOSTTYPE" != "xmacintosh" ; then
dnl Check for X11 (fancy)
AC_PATH_XTRA
fi
dnl Checks for libraries.
@@ -114,18 +153,25 @@ fi
AM_CONDITIONAL(HAVE_THREADS, test "x$ac_cv_lib_pthread_pthread_exit" = "xyes" -a "x$ac_cv_header_pthread_h" = "xyes")
AC_CHECK_LIB(socket, socket)
AC_CHECK_LIB(X11, XCreateWindow)
AC_CHECK_LIB(Xext, XShmCreateImage)
AC_CHECK_LIB(Xi, XGetExtensionVersion)
AC_CHECK_LIB(ICE, IceOpenConnection)
AC_CHECK_LIB(SM, SmcOpenConnection)
AC_CHECK_LIB(Xt, XtMalloc)
AC_CHECK_LIB(Xmu, XmuLookupStandardColormap)
dnl X11 might be installed, but we don't want to use it for OSX -dw-
if test "x$HOSTTYPE" != "xmacintosh" ; then
AC_CHECK_LIB(X11, XCreateWindow)
AC_CHECK_LIB(Xext, XShmCreateImage)
AC_CHECK_LIB(Xi, XGetExtensionVersion)
AC_CHECK_LIB(ICE, IceOpenConnection)
AC_CHECK_LIB(SM, SmcOpenConnection)
AC_CHECK_LIB(Xt, XtMalloc)
AC_CHECK_LIB(Xmu, XmuLookupStandardColormap)
fi
dnl check for OpenGL related libraries
if test "x$ac_cv_header_windows_h" != "xyes" ; then
dnl Reasonable stuff for non-windoze variants ... :-)
if test "x$HOSTTYPE" = "xmacintosh" ; then
dnl Macintosh OSX
LIBS="$LIBS -framework OpenGL -framework GLUT"
elif test "x$ac_cv_header_windows_h" != "xyes" ; then
dnl Reasonable stuff for X-Windows based machines
AC_CHECK_LIB(GLcore, glNewList)
if test "x$ac_cv_lib_GLcore_glNewList" = "xno" ; then
@@ -142,10 +188,10 @@ if test "x$ac_cv_header_windows_h" != "xyes" ; then
dnl if using mesa, check for xmesa.h
if test "x$ac_cv_lib_MesaGL_glNewList" = "xyes" ; then
AC_CHECK_HEADER(GL/xmesa.h)
if test "x$ac_cv_header_GL_xmesa_h" = "xyes"; then
AC_DEFINE( XMESA )
AC_DEFINE( FX )
AC_CHECK_HEADER(GL/fxmesa.h)
if test "x$ac_cv_header_GL_fxmesa_h" = "xyes"; then
AC_DEFINE([XMESA], 1, [Define for fxmesa])
AC_DEFINE([FX], 1, [Define for fxmesa])
fi
fi
@@ -164,14 +210,10 @@ if test "x$ac_cv_header_windows_h" != "xyes" ; then
AC_CHECK_LIB(glut, glutGameModeString)
LIBS="$save_LIBS"
else
dnl Win32 is a little wierd because it has to try to handle the various
dnl winbloze-isms. We'll just do this manually for now.
dnl Win32 libs
echo Win32 specific hacks...
AC_DEFINE(WIN32)
dnl force a failed check since we will be building under windoze
AM_CONDITIONAL(ENABLE_XMESA_FX, test "no" = "yes")
AC_DEFINE([WIN32], 1, [Define for Win32 platforms])
dnl just define these to true and hope for the best
ac_cv_lib_glut_glutGetModifiers="yes"
@@ -191,6 +233,9 @@ else
LIBS="$LIBS -l${WIN32_GLUT} -l${WIN32_GLU} -l${WIN32_OPENGL}"
LIBS="$LIBS -luser32 -lgdi32"
if test "x$is_mingw" = "xyes" ; then
EXTRA_DIRS="${EXTRA_DIRS}"
fi
echo "Will link apps with $LIBS"
fi
@@ -204,7 +249,9 @@ fi
if test "x$ac_cv_lib_glut_glutGameModeString" = "xno"; then
echo
echo "Your version of glut doesn't support game mode."
echo "You need to fetch and install the latest version of glut from:"
echo "You need to install the latest version of glut. If your"
echo "distribution doesn't provide a newer version, you can get the source"
echo "code from:"
echo
echo " http://reality.sgi.com/opengl/glut3/glut3.html"
exit 1
@@ -218,12 +265,17 @@ AC_SUBST(opengl_LIBS)
AM_CONDITIONAL(HAVE_XWINDOWS, test "x$ac_cv_lib_X11_XCreateWindow" = "xyes" )
# The following are C++ items that need to be tested for with the c++
# compiler
AC_LANG_PUSH(C++)
dnl Check for "plib" without which we cannot go on
AC_CHECK_HEADER(plib/pu.h)
if test "x$ac_cv_header_plib_pu_h" != "xyes"; then
AC_CHECK_HEADER(plib/ul.h)
if test "x$ac_cv_header_plib_ul_h" != "xyes"; then
echo
echo "You *must* have the plib library installed on your system to build"
echo "the FGFS simulator!"
echo "SimGear!"
echo
echo "Please see README.plib for more details."
echo
@@ -231,35 +283,50 @@ if test "x$ac_cv_header_plib_pu_h" != "xyes"; then
exit
fi
# dnl Check for system installed gdbm
# AC_CHECK_HEADER(gdbm.h)
# if test "x$ac_cv_header_gdbm_h" = "xyes"; then
# AC_DEFINE( HAVE_GDBM )
# else
# echo "no gdbm found, configuring and building."
# fi
# AM_CONDITIONAL(HAVE_GDBM, test "x$ac_cv_header_gdbm_h" = "xyes" )
AC_MSG_CHECKING([for plib 1.6.0 or newer])
AC_TRY_RUN([
#include <plib/ul.h>
#define MIN_PLIB_VERSION 160
int main() {
int major, minor, micro;
if ( PLIB_VERSION < MIN_PLIB_VERSION ) {
return -1;
}
return 0;
}
],
AC_MSG_RESULT(yes),
[AC_MSG_RESULT(wrong version);
AC_MSG_ERROR([Install plib 1.6.0 or later first...])],
AC_MSG_RESULT(yes)
)
dnl Check for system installed metakit
AC_CHECK_HEADER(mk4.h)
if test "x$ac_cv_header_mk4_h" != "xyes"; then
echo "no metakit found, configuring and building."
# Run configure in the metakit subdir
AC_CONFIG_SUBDIRS( simgear/metakit/unix )
echo
echo "Metakit not found, you will need to install this first."
echo "Please read the README.metakit for more information."
exit
fi
AM_CONDITIONAL(HAVE_METAKIT, test "x$ac_cv_header_mk4_h" = "xyes" )
AC_LANG_POP
dnl Specify if we want logging (testing build) or not (release build)
dnl Check for system installed zlib
AC_CHECK_HEADER(zlib.h)
if test "x$ac_cv_header_zlib_h" = "xyes"; then
AC_DEFINE( HAVE_ZLIB )
else
echo "no zlib found, building."
if test "x$ac_cv_header_zlib_h" != "xyes"; then
echo
echo "zlib not found, you will need to install this first."
echo "Please read the README.zlib for more information."
exit
fi
AM_CONDITIONAL(HAVE_ZLIB, test "x$ac_cv_header_zlib_h" = "xyes" )
dnl Checks for header files.
AC_HEADER_STDC
@@ -268,7 +335,7 @@ AC_CHECK_HEADERS( \
sys/stat.h sys/time.h sys/timeb.h unistd.h windows.h winbase.h values.h )
if test "x$ac_cv_header_stdint_h" = "xyes"; then
AC_DEFINE( HAVE_STDINT_H )
AC_DEFINE([HAVE_STDINT_H], 1, [Define if stdint.h exists])
fi
dnl Checks for typedefs, structures, and compiler characteristics.
@@ -281,18 +348,20 @@ dnl Checks for library functions.
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS( ftime gettimeofday timegm memcpy bcopy mktime strstr rand \
random setitimer getitimer signal GetLocalTime rint getrusage )
random drand48 setitimer getitimer signal GetLocalTime rint getrusage )
AM_CONFIG_HEADER(simgear/simgear_config.h)
AC_OUTPUT( \
AC_CONFIG_FILES([ \
Makefile \
SimGear.spec \
src-libs/Makefile \
simgear/Makefile \
simgear/version.h \
simgear/bucket/Makefile \
simgear/debug/Makefile \
simgear/ephemeris/Makefile \
simgear/interpreter/Makefile \
simgear/io/Makefile \
simgear/magvar/Makefile \
simgear/math/Makefile \
@@ -306,14 +375,9 @@ AC_OUTPUT( \
simgear/timing/Makefile \
simgear/xgl/Makefile \
simgear/xml/Makefile \
simgear/zlib/Makefile \
)
AC_OUTPUT_COMMANDS([
# if test "x$ac_cv_header_windows_h" = "xyes" ; then
# cp simgear/gdbm/autoconf.h.cygwin32 simgear/gdbm/autoconf.h
# fi
])
AC_OUTPUT
echo ""
echo "Configure Summary"
@@ -327,22 +391,13 @@ else
echo "Debug messages: yes"
fi
if test "x$with_efence" != "x"; then
echo "Electric fence: $with_efence"
echo -n "Automake version: ($AUTO_MAKE_VERSION) "
automake --version | head -1
if test "x$with_jpeg_factory" = "xyes"; then
echo "With JPEG Factory support"
else
echo "Electric fence: no"
fi
# if test "x$ac_cv_header_gdbm_h" != "xyes"; then
# echo "Building gdbm"
# fi
if test "x$ac_cv_header_mk4_h" != "xyes"; then
echo "Building metakit"
fi
if test "x$ac_cv_header_zlib_h" != "xyes"; then
echo "Building zlib"
echo "Without JPEG Factory support"
fi
if test "x$ac_cv_lib_pthread_pthread_exit" = "xyes" -a "x$ac_cv_header_pthread_h" = "xyes"; then
@@ -350,9 +405,3 @@ if test "x$ac_cv_lib_pthread_pthread_exit" = "xyes" -a "x$ac_cv_header_pthread_h
else
echo "Threads: no threads (pthread lib not found.)"
fi
if test "$OS" = "IRIX" -o "$OS" = "IRIX64"; then
if test "$CXX" = "CC"; then
echo "\nRemember to run: sh ../FlightGear/irix-hack.sh!\07\n"
fi
fi

7
simgear/.cvsignore Normal file
View File

@@ -0,0 +1,7 @@
Makefile
Makefile.in
simgear_config.h
simgear_config.h.in
stamp-h
stamp-h.in
version.h

View File

@@ -1,21 +1,3 @@
if ENABLE_UNIX_SERIAL
SERIAL_DIRS = serial
else
SERIAL_DIRS =
endif
# if HAVE_GDBM
# GDBM_DIRS =
# else
# GDBM_DIRS = gdbm
# endif
if HAVE_ZLIB
ZLIB_DIRS =
else
ZLIB_DIRS = zlib
endif
if HAVE_THREADS
SGTHREAD_DIR = threads
else
@@ -25,13 +7,12 @@ endif
# METAR_DIRS =
METAR_DIRS = metar
EXTRA_DIST = version.h.in
EXTRA_DIST = simgear_config.h.vc5 version.h.in
include_HEADERS = \
compiler.h constants.h sg_inlines.h sg_traits.hxx sg_zlib.h version.h
SUBDIRS = \
$(ZLIB_DIRS) \
xml \
debug \
misc \
@@ -43,9 +24,10 @@ SUBDIRS = \
$(METAR_DIRS) \
route \
screen \
$(SERIAL_DIRS) \
serial \
sky \
$(SGTHREAD_DIR) \
timing \
xgl
DIST_SUBDIRS = $(SUBDIRS) interpreter

View File

@@ -0,0 +1,3 @@
.deps
Makefile
Makefile.in

View File

@@ -14,4 +14,4 @@ libsgbucket_a_SOURCES = newbucket.cxx
# $(top_builddir)/bucket/libsgbucket.a \
# $(top_builddir)/misc/libsgmisc.a
INCLUDES += -I$(top_srcdir)
INCLUDES = -I$(top_srcdir)

View File

@@ -71,6 +71,14 @@
#ifndef _SG_COMPILER_H
#define _SG_COMPILER_H
/*
* Helper macro SG_STRINGIZE:
* Converts the parameter X to a string after macro replacement
* on X has been performed.
*/
#define SG_STRINGIZE(X) SG_DO_STRINGIZE(X)
#define SG_DO_STRINGIZE(X) #X
#ifdef __GNUC__
# if __GNUC__ == 2
# if __GNUC_MINOR__ < 8
@@ -137,6 +145,15 @@
# else
# error Time to upgrade. GNU compilers < 2.7 not supported
# endif
# define SG_COMPILER_STR "GNU C++ version " SG_STRINGIZE(__GNUC__) "." SG_STRINGIZE(__GNUC_MINOR__)
#endif // __GNUC__
#if defined( __MINGW32__ )
# define bcopy(from, to, n) memcpy(to, from, n)
# define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
# define snprintf _snprintf
#endif
/* KAI C++ */
@@ -157,7 +174,10 @@
# define STL_STDEXCEPT <stdexcept>
# define STL_STRING <string>
# define STL_STRSTREAM <strstream>
#endif
# define SG_COMPILER_STR "Kai C++ version " SG_STRINGIZE(__KCC_VERSION)
#endif // __KCC
//
// Metrowerks
@@ -188,7 +208,10 @@
// -dw- currently used glut has no game mode stuff
# define GLUT_WRONG_VERSION
#endif
# define SG_COMPILER_STR "Metrowerks CodeWarrior C++ version " SG_STRINGIZE(__MWERKS__)
#endif // __MWERKS__
//
// Microsoft compilers.
@@ -213,13 +236,19 @@
# define STL_STRING <string>
# define STL_STRSTREAM <strstream>
# define snprintf _snprintf
# pragma warning(disable: 4786) // identifier was truncated to '255' characters
# pragma warning(disable: 4244) // conversion from double to float
# pragma warning(disable: 4305) //
# else
# error What version of MSVC++ is this?
# endif
#endif
# define SG_COMPILER_STR "Microsoft Visual C++ version " SG_STRINGIZE(_MSC_VER)
#endif // _MSC_VER
#ifdef __BORLANDC__
# if defined(HAVE_SGI_STL_PORT)
@@ -251,6 +280,8 @@
# define SG_NAMESPACES
// # define SG_HAVE_STD
# define SG_COMPILER_STR "Borland C++ version " SG_STRINGIZE(__BORLANDC__)
#endif // __BORLANDC__
//
@@ -278,6 +309,21 @@
# define STL_STRING <string>
# define STL_STRSTREAM <strstream.h>
// # define __STL_FUNCTION_TMPL_PARTIAL_ORDER
// typedef void PFNGLPOINTPARAMETERFEXTPROC
#define glPointParameterfEXT glPointParameterfSGIS
#define glPointParameterfvEXT glPointParameterfvSGIS
#pragma set woff 1001,1012,1014,1116,1155,1172,1174
#pragma set woff 1401,1460,1551,1552,1681
#ifdef __cplusplus
#pragma set woff 1682,3303
#endif
# define SG_COMPILER_STR "SGI Irix compiler version " SG_STRINGIZE(_COMPILER_VERSION)
#endif // Native SGI compilers
@@ -292,8 +338,35 @@
# else
extern void *memmove(void *, const void *, size_t);
# endif // __cplusplus
# define SG_COMPILER_STR "Sun compiler version " SG_STRINGIZE(__SUNPRO_CC)
#endif // sun
//
// Intel C++ Compiler
//
#if defined(__ICC) || defined (__ECC)
# define SG_NAMESPACES
# define SG_HAVE_STD
# define SG_HAVE_STREAMBUF
# define SG_HAVE_TRAITS
# define SG_HAVE_STD_INCLUDES
# define STL_ALGORITHM <algorithm>
# define STL_FUNCTIONAL <functional>
# define STL_IOMANIP <iomanip>
# define STL_IOSTREAM <iostream>
# define STL_ITERATOR <iterator>
# define STL_FSTREAM <fstream>
# define STL_STDEXCEPT <stdexcept>
# define STL_STRING <string>
# define STL_STRSTREAM <strstream>
# define SG_COMPILER_STR "Intel C++ version " SG_STRINGIZE(__ICC)
#endif // __ICC
//
// No user modifiable definitions beyond here.
//

View File

@@ -123,7 +123,7 @@
/** Highest binobj format version we know how to read/write. This starts at
* 0 and can go up to 65535 */
#define SG_BINOBJ_VERSION 5
#define SG_BINOBJ_VERSION 6
/** for backwards compatibility */
#define SG_SCENERY_FILE_FORMAT "0.4"

3
simgear/debug/.cvsignore Normal file
View File

@@ -0,0 +1,3 @@
.deps
Makefile
Makefile.in

View File

@@ -8,4 +8,4 @@ include_HEADERS = debug_types.h logstream.hxx
libsgdebug_a_SOURCES = logstream.cxx
INCLUDES += -I$(top_srcdir)
INCLUDES = -I$(top_srcdir)

View File

@@ -23,6 +23,8 @@
#include "logstream.hxx"
logstream *global_logstream = NULL;
bool logbuf::logging_enabled = true;
sgDebugClass logbuf::logClass = SG_NONE;
sgDebugPriority logbuf::logPriority = SG_INFO;
@@ -56,6 +58,30 @@ logbuf::set_log_level( sgDebugClass c, sgDebugPriority p )
logPriority = p;
}
void
logbuf::set_log_classes (sgDebugClass c)
{
logClass = c;
}
sgDebugClass
logbuf::get_log_classes ()
{
return logClass;
}
void
logbuf::set_log_priority (sgDebugPriority p)
{
logPriority = p;
}
sgDebugPriority
logbuf::get_log_priority ()
{
return logPriority;
}
void
logstream::setLogLevels( sgDebugClass c, sgDebugPriority p )
{

View File

@@ -105,6 +105,35 @@ public:
*/
static void set_log_level( sgDebugClass c, sgDebugPriority p );
/**
* Set the allowed logging classes.
* @param c All enabled logging classes anded together.
*/
static void set_log_classes (sgDebugClass c);
/**
* Get the logging classes currently enabled.
* @return All enabled debug logging anded together.
*/
static sgDebugClass get_log_classes ();
/**
* Set the logging priority.
* @param c The priority cutoff for logging messages.
*/
static void set_log_priority (sgDebugPriority p);
/**
* Get the current logging priority.
* @return The priority cutoff for logging messages.
*/
static sgDebugPriority get_log_priority ();
/**
* Set the stream buffer
* @param sb stream buffer
@@ -227,6 +256,7 @@ logstream::operator<< ( const loglevel& l )
return *this;
}
extern logstream *global_logstream;
/**
* \relates logstream
@@ -238,8 +268,22 @@ logstream::operator<< ( const loglevel& l )
inline logstream&
sglog()
{
static logstream logstrm( cerr );
return logstrm;
if (global_logstream == NULL) {
#ifdef __APPLE__
/**
* There appears to be a bug in the C++ runtime in Mac OS X that
* will crash if certain funtions are called (in this case
* cerr.rdbuf()) during static initialization of a class. This
* print statement is hack to kick the library in the pants so it
* won't crash when cerr.rdbuf() is first called -DW
**/
cout << "Using Mac OS X hack for initializing C++ stdio..." << endl;
#endif
global_logstream = new logstream (cerr);
}
return *global_logstream;
}

View File

@@ -1,16 +1,32 @@
#include <string>
#include "Debug/logstream.hxx"
class Test {
public:
Test() {
//cout << "Cout seems to work" << endl;
//cerr << "Cerr seems to work" << endl;
sglog().setLogLevels( SG_ALL, SG_INFO );
SG_LOG(SG_EVENT, SG_INFO, "Test::Test" << "foo");
}
};
Test test;
int
main( int argc, char* argv[] )
{
fglog().setLogLevels( SG_ALL, SG_INFO );
sglog().setLogLevels( SG_ALL, SG_INFO );
SG_LOG( FG_TERRAIN, FG_BULK, "terrain::bulk" ); // shouldnt appear
SG_LOG( FG_TERRAIN, SG_DEBUG, "terrain::debug" ); // shouldnt appear
SG_LOG( FG_TERRAIN, SG_INFO, "terrain::info" );
SG_LOG( FG_TERRAIN, FG_WARN, "terrain::warn" );
SG_LOG( FG_TERRAIN, SG_ALERT, "terrain::alert" );
//SG_LOG( FG_TERRAIN, FG_BULK, "terrain::bulk" ); // shouldnt appear
//SG_LOG( FG_TERRAIN, SG_DEBUG, "terrain::debug" ); // shouldnt appear
//SG_LOG( FG_TERRAIN, SG_INFO, "terrain::info" );
//SG_LOG( FG_TERRAIN, FG_WARN, "terrain::warn" );
//SG_LOG( FG_TERRAIN, SG_ALERT, "terrain::alert" );
int i = 12345;
long l = 54321L;

View File

@@ -0,0 +1,3 @@
.deps
Makefile
Makefile.in

View File

@@ -31,4 +31,4 @@ libsgephem_a_SOURCES = \
uranus.cxx \
venus.cxx
INCLUDES += -I$(top_srcdir)
INCLUDES = -I$(top_srcdir)

View File

@@ -158,22 +158,112 @@ double CelestialBody::sgCalcEccAnom(double M, double e)
return eccAnom;
}
/*****************************************************************************
* inline CelestialBody::CelestialBody
* public constructor for a generic celestialBody object.
* initializes the 6 primary orbital elements. The elements are:
* N: longitude of the ascending node
* i: inclination to the ecliptic
* w: argument of perihelion
* a: semi-major axis, or mean distance from the sun
* e: eccenticity
* M: mean anomaly
* Each orbital element consists of a constant part and a variable part that
* gradually changes over time.
*
* Argumetns:
* the 13 arguments to the constructor constitute the first, constant
* ([NiwaeM]f) and the second variable ([NiwaeM]s) part of the orbital
* elements. The 13th argument is the current time. Note that the inclination
* is written with a capital (If, Is), because 'if' is a reserved word in the
* C/C++ programming language.
***************************************************************************/
CelestialBody::CelestialBody(double Nf, double Ns,
double If, double Is,
double wf, double ws,
double af, double as,
double ef, double es,
double Mf, double Ms, double mjd)
{
NFirst = Nf; NSec = Ns;
iFirst = If; iSec = Is;
wFirst = wf; wSec = ws;
aFirst = af; aSec = as;
eFirst = ef; eSec = es;
MFirst = Mf; MSec = Ms;
updateOrbElements(mjd);
}
CelestialBody::CelestialBody(double Nf, double Ns,
double If, double Is,
double wf, double ws,
double af, double as,
double ef, double es,
double Mf, double Ms)
{
NFirst = Nf; NSec = Ns;
iFirst = If; iSec = Is;
wFirst = wf; wSec = ws;
aFirst = af; aSec = as;
eFirst = ef; eSec = es;
MFirst = Mf; MSec = Ms;
}
/****************************************************************************
* inline void CelestialBody::updateOrbElements(double mjd)
* given the current time, this private member calculates the actual
* orbital elements
*
* Arguments: double mjd: the current modified julian date:
*
* return value: none
***************************************************************************/
void CelestialBody::updateOrbElements(double mjd)
{
double actTime = sgCalcActTime(mjd);
M = SGD_DEGREES_TO_RADIANS * (MFirst + (MSec * actTime));
w = SGD_DEGREES_TO_RADIANS * (wFirst + (wSec * actTime));
N = SGD_DEGREES_TO_RADIANS * (NFirst + (NSec * actTime));
i = SGD_DEGREES_TO_RADIANS * (iFirst + (iSec * actTime));
e = eFirst + (eSec * actTime);
a = aFirst + (aSec * actTime);
}
/*****************************************************************************
* inline double CelestialBody::sgCalcActTime(double mjd)
* this private member function returns the offset in days from the epoch for
* wich the orbital elements are calculated (Jan, 1st, 2000).
*
* Argument: the current time
*
* return value: the (fractional) number of days until Jan 1, 2000.
****************************************************************************/
double CelestialBody::sgCalcActTime(double mjd)
{
return (mjd - 36523.5);
}
/*****************************************************************************
* inline void CelestialBody::getPos(double* ra, double* dec)
* gives public access to Right Ascension and declination
*
****************************************************************************/
void CelestialBody::getPos(double* ra, double* dec)
{
*ra = rightAscension;
*dec = declination;
}
/*****************************************************************************
* inline void CelestialBody::getPos(double* ra, double* dec, double* magnitude
* gives public acces to the current Right ascension, declination, and
* magnitude
****************************************************************************/
void CelestialBody::getPos(double* ra, double* dec, double* magn)
{
*ra = rightAscension;
*dec = declination;
*magn = magnitude;
}

View File

@@ -87,113 +87,6 @@ public:
void updatePosition(double mjd, Star *ourSun);
};
/*****************************************************************************
* inline CelestialBody::CelestialBody
* public constructor for a generic celestialBody object.
* initializes the 6 primary orbital elements. The elements are:
* N: longitude of the ascending node
* i: inclination to the ecliptic
* w: argument of perihelion
* a: semi-major axis, or mean distance from the sun
* e: eccenticity
* M: mean anomaly
* Each orbital element consists of a constant part and a variable part that
* gradually changes over time.
*
* Argumetns:
* the 13 arguments to the constructor constitute the first, constant
* ([NiwaeM]f) and the second variable ([NiwaeM]s) part of the orbital
* elements. The 13th argument is the current time. Note that the inclination
* is written with a capital (If, Is), because 'if' is a reserved word in the
* C/C++ programming language.
***************************************************************************/
inline CelestialBody::CelestialBody(double Nf, double Ns,
double If, double Is,
double wf, double ws,
double af, double as,
double ef, double es,
double Mf, double Ms, double mjd)
{
NFirst = Nf; NSec = Ns;
iFirst = If; iSec = Is;
wFirst = wf; wSec = ws;
aFirst = af; aSec = as;
eFirst = ef; eSec = es;
MFirst = Mf; MSec = Ms;
updateOrbElements(mjd);
}
inline CelestialBody::CelestialBody(double Nf, double Ns,
double If, double Is,
double wf, double ws,
double af, double as,
double ef, double es,
double Mf, double Ms)
{
NFirst = Nf; NSec = Ns;
iFirst = If; iSec = Is;
wFirst = wf; wSec = ws;
aFirst = af; aSec = as;
eFirst = ef; eSec = es;
MFirst = Mf; MSec = Ms;
}
/****************************************************************************
* inline void CelestialBody::updateOrbElements(double mjd)
* given the current time, this private member calculates the actual
* orbital elements
*
* Arguments: double mjd: the current modified julian date:
*
* return value: none
***************************************************************************/
inline void CelestialBody::updateOrbElements(double mjd)
{
double actTime = sgCalcActTime(mjd);
M = SGD_DEGREES_TO_RADIANS * (MFirst + (MSec * actTime));
w = SGD_DEGREES_TO_RADIANS * (wFirst + (wSec * actTime));
N = SGD_DEGREES_TO_RADIANS * (NFirst + (NSec * actTime));
i = SGD_DEGREES_TO_RADIANS * (iFirst + (iSec * actTime));
e = eFirst + (eSec * actTime);
a = aFirst + (aSec * actTime);
}
/*****************************************************************************
* inline double CelestialBody::sgCalcActTime(double mjd)
* this private member function returns the offset in days from the epoch for
* wich the orbital elements are calculated (Jan, 1st, 2000).
*
* Argument: the current time
*
* return value: the (fractional) number of days until Jan 1, 2000.
****************************************************************************/
inline double CelestialBody::sgCalcActTime(double mjd)
{
return (mjd - 36523.5);
}
/*****************************************************************************
* inline void CelestialBody::getPos(double* ra, double* dec)
* gives public access to Right Ascension and declination
*
****************************************************************************/
inline void CelestialBody::getPos(double* ra, double* dec)
{
*ra = rightAscension;
*dec = declination;
}
/*****************************************************************************
* inline void CelestialBody::getPos(double* ra, double* dec, double* magnitude
* gives public acces to the current Right ascension, declination, and
* magnitude
****************************************************************************/
inline void CelestialBody::getPos(double* ra, double* dec, double* magn)
{
*ra = rightAscension;
*dec = declination;
*magn = magnitude;
}
inline double CelestialBody::getRightAscension() { return rightAscension; }
inline double CelestialBody::getDeclination() { return declination; }
inline double CelestialBody::getMagnitude() { return magnitude; }
@@ -210,14 +103,3 @@ inline double CelestialBody::getLat()
#endif // _CELESTIALBODY_H_

View File

@@ -32,10 +32,14 @@
#endif
// Constructor
SGStarData::SGStarData() {
SGStarData::SGStarData() :
nstars(0)
{
}
SGStarData::SGStarData( SGPath path ) {
SGStarData::SGStarData( SGPath path ) :
nstars(0)
{
data_path = SGPath( path );
load();
}

View File

@@ -0,0 +1,3 @@
.deps
Makefile
Makefile.in

View File

@@ -0,0 +1,33 @@
includedir = @includedir@/js
lib_LIBRARIES = libsginterp.a
include_HEADERS = \
interpreter.hxx
libsginterp_a_SOURCES = \
interpreter.cxx interpreter.hxx \
ixlib_javascript.hh \
js_array.cc \
js_expression.cc \
js_interpreter.cc \
js_value.cc \
js_declaration.cc \
js_instruction.cc \
js_library.cc \
lex.javascript.cc ixlib_token_lex.hh ixlib_token_javascript.hh \
scanner.cc ixlib_scanner.hh ixlib_scanjs.hh \
exbase.cc \
numeric.cc ixlib_numeric.hh \
numconv.cc ixlib_numconv.hh \
re.cc ixlib_re.hh ixlib_re_impl.hh \
exgen.cc ixlib_exgen.hh \
string.cc ixlib_string.hh \
ixlib_base.hh \
ixlib_exbase.hh \
ixlib_garbage.hh \
ixlib_i18n.hh \
ixlib_js_internals.hh \
ixlib_random.hh
INCLUDES = -I$(top_srcdir)

View File

@@ -0,0 +1,77 @@
// ----------------------------------------------------------------------------
// Description : Exception handling
// ----------------------------------------------------------------------------
// (c) Copyright 1996 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <cstdio>
#include <cstring>
#include <ixlib_exbase.hh>
using namespace ixion;
// Description forms ----------------------------------------------------------
#define T_DESCRIPTION1 "[%s%04X] %s"
#define T_DESCRIPTION2 "[%s%04X] %s <%s>"
#define T_DESCRIPTION3 "[%s%04X] %s <%s,%d>"
#define T_DESCRIPTION1I "[%s%04X] %s (%s)"
#define T_DESCRIPTION2I "[%s%04X] %s (%s) <%s>"
#define T_DESCRIPTION3I "[%s%04X] %s (%s) <%s,%d>"
// base_exception -------------------------------------------------------------
char base_exception::RenderBuffer[EX_INFOMAX+1+100];
base_exception::base_exception(TErrorCode error,char const *info,char *module,
TIndex line,char *category)
: Error(error),Module(module),Line(line),Category(category) {
HasInfo = (info!=NULL);
if (info) {
if (strlen(info)>EX_INFOMAX) {
strncpy(Info,info,EX_INFOMAX);
Info[EX_INFOMAX] = '\0';
}
else strcpy(Info,info);
}
}
char const *base_exception::what() const throw () {
if (HasInfo) {
if (Module) {
if (Line)
sprintf(RenderBuffer,T_DESCRIPTION3I,Category,Error,getText(),Info,Module,Line);
else
sprintf(RenderBuffer,T_DESCRIPTION2I,Category,Error,getText(),Info,Module);
}
else
sprintf(RenderBuffer,T_DESCRIPTION1I,Category,Error,getText(),Info);
}
else {
if (Module) {
if (Line)
sprintf(RenderBuffer,T_DESCRIPTION3,Category,Error,getText(),Module,Line);
else
sprintf(RenderBuffer,T_DESCRIPTION2,Category,Error,getText(),Module);
}
else
sprintf(RenderBuffer,T_DESCRIPTION1,Category,Error,getText());
}
return RenderBuffer;
}

View File

@@ -0,0 +1,46 @@
// ----------------------------------------------------------------------------
// Description : Generic exceptions
// ----------------------------------------------------------------------------
// (c) Copyright 1996 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include "ixlib_i18n.hh"
#include <ixlib_exgen.hh>
#include <ixlib_numconv.hh>
using namespace ixion;
static char *(PlainText[]) = {
N_("Unable to evaluate expression"),
N_("Function not yet implemented"),
N_("General error"),
N_("NULL pointer encountered"),
N_("Invalid parameter"),
N_("Index out of range"),
N_("Buffer overrun"),
N_("Buffer underrun"),
N_("Item not found"),
N_("Invalid operation"),
N_("Dimension mismatch"),
N_("Operation cancelled"),
N_("Unable to operate on empty set"),
N_("Unable to remove GC entry"),
N_("Unable to protect non-freeable entry")
};
// generic_exception ----------------------------------------------------------
char const *generic_exception::getText() const {
return _(PlainText[Error]);
}

View File

@@ -0,0 +1,9 @@
#include "interpreter.hxx"
SGInterpreter::SGInterpreter ()
{
}
SGInterpreter::~SGInterpreter ()
{
}

View File

@@ -0,0 +1,13 @@
#ifndef __INTERPRETER_HXX
#define __INTERPRETER_HXX 1
class SGInterpreter
{
public:
SGInterpreter ();
virtual ~SGInterpreter ();
};
#endif

View File

@@ -0,0 +1,107 @@
/* ----------------------------------------------------------------------------
Description : iXiONmedia library base declarations
----------------------------------------------------------------------------
(c) Copyright 1996 by iXiONmedia, all rights reserved.
----------------------------------------------------------------------------
This header must be C-safe for autoconf purposes.
*/
#ifndef IXLIB_BASE
#define IXLIB_BASE
#undef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <ixlib_config.hh>
#undef PACKAGE
#undef VERSION
#endif
#ifdef __cplusplus
namespace ixion {
extern "C" {
#endif
/* Aliases --------------------------------------------------------------------
*/
const double Pi = 3.141592653589793285;
const double Euler = 2.718281828;
const double Gravity = 9.8065; // m/s^2
const double UniGravity = 6.673e-11; // m^3/kg s^2
const double Epsilon0 = 8.8542e-12; // F/m
const double Mu0 = 1.2566e-6; // H/m
const double LightSpeed = 2.9972e8; // m/s
const double Planck = 6.6261e-34; // Js
/* STL Helper macro -----------------------------------------------------------
*/
#define FOREACH(VAR,LIST,LISTTYPE) \
for (LISTTYPE::iterator VAR = (LIST).begin(),last = (LIST).end();VAR != last;VAR++)
#define FOREACH_CONST(VAR,LIST,LISTTYPE) \
for (LISTTYPE::const_iterator VAR = (LIST).begin(),last = (LIST).end();VAR != last;VAR++)
/* Nomenclature typedefs ------------------------------------------------------
*/
typedef unsigned char TUnsigned8;
typedef unsigned short TUnsigned16;
typedef unsigned long TUnsigned32;
typedef unsigned long long TUnsigned64;
typedef signed char TSigned8;
typedef signed short TSigned16;
typedef signed long TSigned32;
typedef signed long long TSigned64;
typedef TSigned8 TDelta8;
typedef TSigned16 TDelta16;
typedef TSigned32 TDelta32;
typedef TSigned64 TDelta64;
typedef signed TDelta;
typedef TUnsigned8 TSize8;
typedef TUnsigned16 TSize16;
typedef TUnsigned32 TSize32;
typedef TUnsigned64 TSize64;
typedef unsigned TSize;
typedef TUnsigned8 TIndex8;
typedef TUnsigned16 TIndex16;
typedef TUnsigned32 TIndex32;
typedef TUnsigned64 TIndex64;
typedef unsigned TIndex;
typedef TUnsigned8 TByte;
int ixlibGetMajorVersion();
int ixlibGetMinorVersion();
int ixlibGetMicroVersion();
void ixlibInitI18n();
#ifdef __cplusplus
}
}
#endif
#endif

View File

@@ -0,0 +1,72 @@
// ----------------------------------------------------------------------------
// Description : Exception handling
// ----------------------------------------------------------------------------
// (c) Copyright 1996 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_EXBASE
#define IXLIB_EXBASE
#include <stdexcept>
#include <ixlib_base.hh>
// constants ------------------------------------------------------------------
#define EX_INFOMAX 255
// throw macro ----------------------------------------------------------------
#define EX_THROW(TYPE,CODE)\
throw ::ixion::TYPE##_exception(CODE,NULL,__FILE__,__LINE__);
#define EX_THROWINFO(TYPE,CODE,INFO)\
throw ::ixion::TYPE##_exception(CODE,(char const *) INFO,__FILE__,__LINE__);
#define EX_CATCHCODE(TYPE,CODE,HANDLER)\
catch (TYPE##_exception &ex) { \
if (ex.Error != CODE) throw; \
HANDLER \
}
#define EX_CONVERT(TYPE,CODE,DESTTYPE,DESTCODE)\
catch (TYPE##_exception &ex) { \
if (ex.Error != CODE) throw; \
throw DESTTYPE##_exception(DESTCODE,ex.Info,__FILE__,__LINE__); \
}
// xBaseException -------------------------------------------------------------
namespace ixion {
typedef unsigned int TErrorCode;
struct base_exception : public std::exception {
TErrorCode Error;
char *Module;
TIndex Line;
char *Category;
bool HasInfo;
char Info[EX_INFOMAX+1];
static char RenderBuffer[EX_INFOMAX+1+100];
base_exception(TErrorCode error,char const *info = NULL,char *module = NULL,
TIndex line = 0,char *category = NULL);
char const *what() const throw ();
virtual const char *getText() const = 0;
};
}
#endif

View File

@@ -0,0 +1,67 @@
// ----------------------------------------------------------------------------
// Description : Generic exceptions
// ----------------------------------------------------------------------------
// (c) Copyright 1996 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_EXGEN
#define IXLIB_EXGEN
#include <ixlib_exbase.hh>
// Error codes ----------------------------------------------------------------
#define EC_CANNOTEVALUATE 0
#define EC_NOTYETIMPLEMENTED 1
#define EC_ERROR 2
#define EC_NULLPOINTER 3
#define EC_INVALIDPAR 4
#define EC_INDEX 5
#define EC_BUFFEROVERFLOW 6
#define EC_BUFFERUNDERFLOW 7
#define EC_ITEMNOTFOUND 8
#define EC_INVALIDOP 9
#define EC_DIMENSIONMISMATCH 10
#define EC_CANCELLED 11
#define EC_EMPTYSET 12
#define EC_CANNOTREMOVEFROMGC 13
#define EC_REMAININGREF 14
#define ECMEM_GENERAL 0
// Throw macro ----------------------------------------------------------------
#define EXGEN_THROW(CODE)\
EX_THROW(generic,CODE)
#define EXGEN_THROWINFO(CODE,INFO)\
EX_THROWINFO(generic,CODE,INFO)
#define EXGEN_NYI\
EXGEN_THROW(EC_NOTYETIMPLEMENTED)
namespace ixion {
// generic_exception ----------------------------------------------------------
struct generic_exception : public base_exception {
generic_exception(TErrorCode error,char const *info = NULL,char *module = NULL,
TIndex line = 0)
: base_exception(error,info,module,line,"GEN") {
}
virtual char const *getText() const;
};
}
#endif

View File

@@ -0,0 +1,491 @@
// ----------------------------------------------------------------------------
// Description : Garbage collection
// ----------------------------------------------------------------------------
// (c) Copyright 2000 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_GARBAGE
#define IXLIB_GARBAGE
#include <memory>
#include <ixlib_exgen.hh>
#include <ixlib_base.hh>
namespace ixion {
template<class T>
class delete_deallocator {
public:
void operator()(T const *instance) {
delete instance;
}
};
template<class T>
class delete_array_deallocator {
public:
void operator()(T const *instance) {
delete[] instance;
}
};
template<class T,class Deallocator = delete_deallocator<T> >
class reference_manager;
template<class T>
class ref_base {
protected:
T *Instance;
public:
ref_base(T *instance = NULL)
: Instance(instance) {
}
ref_base(ref_base const &src)
: Instance(src.Instance) {
}
// comparison
bool operator==(ref_base const &op2) const {
return Instance == op2.Instance;
}
// smart pointer nitty-gritty
T &operator*() const {
return *Instance;
}
T *operator->() const {
return Instance;
}
T *operator+(TIndex index) const {
return Instance + index;
}
T &operator[](TIndex index) const {
return Instance[index];
}
// methods
T *get() const {
return Instance;
}
};
template<class T,class T_Managed = T>
class ref;
template<class T,class T_Managed = T>
class no_free_ref;
template<class T_Managed>
class reference_manager_keeper {
public:
// *** FIXME should be private, but cannot be
// (partial specializations cannot be declared friends)
static reference_manager<T_Managed> Manager;
};
/**
An object that acts like a reference-counted pointer to an object.
The corresponding reference_manager is identified implicitly through
static references.
Example:
<code>
IXLIB_GARBAGE_DECLARE_MANAGER(int)
int main() {
ref<int> my_int = new int(5);
*my_int = 17;
ref<int> another_int = my_int;
*another_int = 12;
*my_int == 12; // true
}
</code>
*/
template<class T,class T_Managed>
class ref : public ref_base<T> {
public:
// we have to have an explicit copy constructor, otherwise the
// compiler generates one, which is *ahem* - fatal
ref(ref const &src)
: ref_base<T>(src) {
reference_manager_keeper<T_Managed>::Manager.addReference(Instance);
}
template<class T2>
ref(ref<T2,T_Managed> const &src)
: ref_base<T>(src.get()) {
reference_manager_keeper<T_Managed>::Manager.addReference(Instance);
}
template<class T2>
ref(no_free_ref<T2,T_Managed> const &src)
: ref_base<T>(src.get()) {
reference_manager_keeper<T_Managed>::Manager.addReference(Instance);
}
ref(T *instance = NULL)
: ref_base<T>(instance) {
reference_manager_keeper<T_Managed>::Manager.addReference(Instance);
}
~ref() {
reference_manager_keeper<T_Managed>::Manager.freeReference(Instance);
}
ref &operator=(ref const &src) {
set(src.get());
return *this;
}
ref &operator=(T *ptr) {
set(ptr);
return *this;
}
// methods
void release() {
reference_manager_keeper<T_Managed>::Manager.freeReference(Instance);
Instance = NULL;
}
void set(T *instance) {
if (instance == Instance) return;
reference_manager_keeper<T_Managed>::Manager.freeReference(Instance);
Instance = instance;
reference_manager_keeper<T_Managed>::Manager.addReference(Instance);
}
T *releaseFromGCArena() {
T *oldinst = Instance;
reference_manager_keeper<T_Managed>::Manager.forgetReference(Instance);
Instance = NULL;
return oldinst;
}
};
/**
An object that acts like a reference-counted pointer to an object.
However, the referenced object is not freed if the no_free_ref
is the last reference to the object to go out of scope.
This is useful to pass objects allocated e.g. on the stack along
inside ref's, while making sure they aren't freed.
(which would most probably lead to disaster)
no_free_ref's are mostly a hack, but there are situations where you cannot
avoid them. But even so, you should try not to use them where possible.
The corresponding reference_manager is identified implicitly through
static references.
*/
template<class T,class T_Managed>
class no_free_ref : public ref_base<T>{
public:
// we have to have an explicit copy constructor, otherwise the
// compiler generates one, which is *ahem* - fatal
no_free_ref(no_free_ref const &src)
: ref_base<T>(src) {
reference_manager_keeper<T_Managed>::Manager.addNoFreeReference(Instance);
}
template<class T2>
no_free_ref(ref<T2,T_Managed> const &src)
: ref_base<T>(src.get()) {
reference_manager_keeper<T_Managed>::Manager.addNoFreeReference(Instance);
}
template<class T2>
no_free_ref(no_free_ref<T2,T_Managed> const &src)
: ref_base<T>(src.get()) {
reference_manager_keeper<T_Managed>::Manager.addNoFreeReference(Instance);
}
no_free_ref(T *instance = NULL)
: ref_base<T>(instance) {
reference_manager_keeper<T_Managed>::Manager.addNoFreeReference(Instance);
}
~no_free_ref() {
reference_manager_keeper<T_Managed>::Manager.removeNoFreeReference(Instance);
}
// assignment
no_free_ref &operator=(no_free_ref const &src) {
set(src.get());
return *this;
}
no_free_ref &operator=(T *ptr) {
set(ptr);
return *this;
}
// methods
void release() {
reference_manager_keeper<T_Managed>::Manager.removeNoFreeReference(Instance);
Instance = NULL;
}
void set(T *instance) {
if (instance == Instance) return;
reference_manager_keeper<T_Managed>::Manager.removeNoFreeReference(Instance);
Instance = instance;
reference_manager_keeper<T_Managed>::Manager.addNoFreeReference(Instance);
}
T *releaseFromGCArena() {
T *oldinst = Instance;
reference_manager_keeper<T_Managed>::Manager.forgetReference(Instance);
Instance = NULL;
return oldinst;
}
};
/**
An object that acts like a reference-counted pointer to an object.
The corresponding reference_manager is identified explicitly.
*/
template<class T>
class dynamic_ref : public ref_base<T> {
protected:
reference_manager<T> &Manager;
public:
dynamic_ref(dynamic_ref const &src)
: ref_base<T>(src),Manager(src.Manager) {
Manager.addReference(Instance);
}
dynamic_ref(reference_manager<T> &mgr,T *instance = NULL)
: ref_base<T>(instance),Manager(mgr) {
Manager.addReference(Instance);
}
~dynamic_ref() {
Manager.freeReference(Instance);
}
// assignment
dynamic_ref &operator=(dynamic_ref const &src) {
set(src.get());
return *this;
}
dynamic_ref &operator=(T *ptr) {
set(ptr);
return *this;
}
// methods
void release() {
Manager.freeReference(Instance);
Instance = NULL;
}
void set(T *instance) {
if (instance == Instance) return;
Manager.freeReference(Instance);
Instance = instance;
Manager.addReference(Instance);
}
T *releaseFromGCArena() {
T *oldinst = Instance;
Manager.forgetReference(Instance);
Instance = NULL;
return oldinst;
}
};
/**
An object that acts like a reference-counted pointer to an object.
However, the referenced object is not freed if the no_free_ref
is the last reference to the object to go out of scope.
This is useful to pass objects allocated e.g. on the stack along
inside ref's, while making sure they aren't freed.
(which would most probably lead to disaster)
no_free_ref's are mostly a hack, but there are situations where you cannot
avoid them. But even so, you should try not to use them where possible.
The corresponding reference_manager is identified explicitly.
*/
template<class T>
class no_free_dynamic_ref : public ref_base<T> {
protected:
reference_manager<T> &Manager;
public:
no_free_dynamic_ref(no_free_dynamic_ref const &src)
: ref_base<T>(src),Manager(src.Manager) {
Manager.addNoFreeReference(Instance);
}
no_free_dynamic_ref(reference_manager<T> &mgr,T *instance = NULL)
: ref_base<T>(instance),Manager(mgr) {
Manager.addNoFreeReference(Instance);
}
~no_free_dynamic_ref() {
Manager.removeNoFreeReference(Instance);
}
// assignment
no_free_dynamic_ref &operator=(no_free_dynamic_ref const &src) {
set(src.get());
return *this;
}
no_free_dynamic_ref &operator=(T *ptr) {
set(ptr);
return *this;
}
// methods
void release() {
Manager.removeNoFreeReference(Instance);
Instance = NULL;
}
void set(T *instance) {
if (instance == Instance) return;
Manager.removeNoFreeReference(Instance);
Instance = instance;
Manager.addNoFreeReference(Instance);
}
T *releaseFromGCArena() {
T *oldinst = Instance;
Manager.forgetReference(Instance);
Instance = NULL;
return oldinst;
}
};
template<class T,class Deallocator>
class reference_manager {
protected:
struct instance_data {
T const *Instance;
TSize ReferenceCount,NoFreeReferenceCount;
instance_data *Next,*Previous;
};
class pointer_hash {
public:
};
typedef unsigned hash_value;
static hash_value const HASH_MAX = 0x3ff;
instance_data *Instances[HASH_MAX+1];
Deallocator Dealloc;
public:
reference_manager(Deallocator const &dealloc = Deallocator())
: Dealloc(dealloc) {
for (hash_value hv = 0;hv <= HASH_MAX;hv++)
Instances[hv] = NULL;
}
// *** FIXME should be
// protected:
// but cannot because partial specializations cannot be declared friends
void addReference(T const *instance) {
if (!instance) return;
instance_data *data = getHashEntry(instance);
data->ReferenceCount++;
}
void freeReference(T const *instance) {
if (!instance) return;
instance_data *data = getHashEntry(instance);
if (--data->ReferenceCount == 0 && data->NoFreeReferenceCount == 0) {
removeHashEntry(data);
Dealloc(instance);
}
}
void addNoFreeReference(T const *instance) {
if (!instance) return;
instance_data *data = getHashEntry(instance);
data->NoFreeReferenceCount++;
}
void removeNoFreeReference(T const *instance) {
if (!instance) return;
instance_data *data = getHashEntry(instance);
if (--data->NoFreeReferenceCount == 0) {
if (data->ReferenceCount != 0)
EXGEN_THROW(EC_REMAININGREF)
removeHashEntry(data);
}
}
void forgetReference(T const *instance) {
if (!instance) return;
instance_data *data = getHashEntry(instance);
if (data->ReferenceCount != 1)
EXGEN_THROW(EC_CANNOTREMOVEFROMGC)
removeHashEntry(data);
}
private:
hash_value hash(T const *ptr) const {
unsigned u = reinterpret_cast<unsigned>(ptr);
return (u ^ (u >> 8) ^ (u >> 16) ^ (u >> 24)) & HASH_MAX;
}
instance_data *getHashEntry(T const *instance) {
instance_data *data = Instances[hash(instance)];
while (data) {
if (data->Instance == instance) return data;
data = data->Next;
}
// not found, add new at front
instance_data *link = Instances[hash(instance)];
data = new instance_data;
data->Instance = instance;
data->ReferenceCount = 0;
data->NoFreeReferenceCount = 0;
data->Previous = NULL;
data->Next = link;
if (link) link->Previous = data;
Instances[hash(instance)] = data;
return data;
}
void removeHashEntry(instance_data *data) {
instance_data *prev = data->Previous;
if (prev) {
prev->Next = data->Next;
if (data->Next) data->Next->Previous = prev;
delete data;
}
else {
Instances[hash(data->Instance)] = data->Next;
if (data->Next) data->Next->Previous = NULL;
delete data;
}
}
};
#define IXLIB_GARBAGE_DECLARE_MANAGER(TYPE) \
ixion::reference_manager<TYPE> ixion::reference_manager_keeper<TYPE>::Manager;
}
#endif

View File

@@ -0,0 +1,23 @@
// ----------------------------------------------------------------------------
// Description : ixlib internationalization wrapper
// ----------------------------------------------------------------------------
// (c) Copyright 2001 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_I18N
#include <string>
#include <libintl.h>
#define _(String) gettext(String)
#define N_(String) (String)
#endif

View File

@@ -0,0 +1,380 @@
// ----------------------------------------------------------------------------
// Description : Javascript interpreter
// ----------------------------------------------------------------------------
// (c) Copyright 2000 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_JAVASCRIPT
#define IXLIB_JAVASCRIPT
#include <vector>
#if __GNUC__ < 3
#include <hash_map>
#else
#include <ext/hash_map>
#endif
#include <ixlib_string.hh>
#include <ixlib_exbase.hh>
#include <ixlib_garbage.hh>
#include <ixlib_scanner.hh>
// Error codes ----------------------------------------------------------------
#define ECJS_UNTERMINATED_COMMENT 0
#define ECJS_CANNOT_CONVERT 1
#define ECJS_INVALID_OPERATION 2
#define ECJS_UNEXPECTED 3
#define ECJS_UNEXPECTED_EOF 4
#define ECJS_CANNOT_MODIFY_RVALUE 5
#define ECJS_UNKNOWN_IDENTIFIER 6
#define ECJS_UNKNOWN_OPERATOR 7
#define ECJS_INVALID_NON_LOCAL_EXIT 8
#define ECJS_INVALID_NUMBER_OF_ARGUMENTS 9
#define ECJS_INVALID_TOKEN 10
#define ECJS_CANNOT_REDECLARE 11
#define ECJS_DOUBLE_CONSTRUCTION 12
#define ECJS_NO_SUPERCLASS 13
#define ECJS_DIVISION_BY_ZERO 14
// helpful macros -------------------------------------------------------------
#define IXLIB_JS_ASSERT_PARAMETERS(NAME,ARGMIN,ARGMAX) \
if (parameters.size() < ARGMIN || parameters.size() > ARGMAX) \
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,NAME)
#define IXLIB_JS_IF_METHOD(NAME,ARGMIN,ARGMAX) \
if (identifier == NAME) \
if (parameters.size() < ARGMIN || parameters.size() > ARGMAX) \
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,NAME) \
else
#define IXLIB_JS_DECLARE_FUNCTION(NAME) \
namespace { \
class NAME : public value { \
public: \
value_type getType() const { \
return VT_FUNCTION; \
} \
ixion::ref<ixion::javascript::value> call(parameter_list const &parameters); \
}; \
} \
ixion::ref<ixion::javascript::value> NAME::call(parameter_list const &parameters)
#define IXLIB_JS_CONVERT_PARAMETERS_0 \
// Exception throw macros -----------------------------------------------------
#define EXJS_THROW(CODE)\
EX_THROW(javascript,CODE)
#define EXJS_THROWINFO(CODE,INFO)\
EX_THROWINFO(javascript,CODE,INFO)
#define EXJS_THROW_NO_LOCATION(CODE)\
EX_THROW(no_location_javascript,CODE)
#define EXJS_THROWINFO_NO_LOCATION(CODE,INFO)\
EX_THROWINFO(no_location_javascript,CODE,INFO)
#define EXJS_THROWINFOLOCATION(CODE,INFO,LOCATION)\
throw ixion::javascript_exception(CODE,LOCATION,INFO,__FILE__,__LINE__);
#define EXJS_THROWINFOTOKEN(CODE,INFO,TOKEN)\
EXJS_THROWINFOLOCATION(CODE,INFO,code_location(TOKEN))
#define EXJS_THROWINFOEXPRESSION(CODE,INFO,EXPR)\
EXJS_THROWINFOLOCATION(CODE,INFO,(EXPR).getCodeLocation())
namespace ixion {
namespace javascript {
struct code_location;
}
// exceptions ---------------------------------------------------------------
struct no_location_javascript_exception : public base_exception {
no_location_javascript_exception(TErrorCode error,char const *info = NULL,char *module = NULL,
TIndex line = 0)
: base_exception(error,info,module,line,"JS") {
}
virtual char *getText() const;
};
struct javascript_exception : public base_exception {
javascript_exception(TErrorCode error,char const *info = NULL,char *module = NULL,
TIndex line = 0)
: base_exception(error,info,module,line,"JS") {
}
javascript_exception(TErrorCode error,javascript::code_location const &loc,char const *info = 0,char *module = NULL,
TIndex line = 0);
javascript_exception(no_location_javascript_exception const &half_ex,javascript::code_location const &loc);
virtual char *getText() const;
};
// javascript ---------------------------------------------------------------
/**
This code tries to be an implementation of ECMAScript 4, as available at
http://www.mozilla.org/js/language/
Note that ES4 is still in the process of standardization.
It is meant to behave like an ES4 interpreter in strict mode, none
of the backward-compatible braindead-isms like newline semicolon
insertion and other stuff will ever be implemented.
This is the list of its shortcomings:
<ul>
<li> exceptions
<li> namespaces,packages
<li> constness
<li> Number/String constructor and class methods
<li> real regexp's
<li> the methods listed in FIXME's (js_library.cc js_value.cc)
<li> cannot cross-assign predefined methods [won't be]
<li> Grammatical semicolon insertion [won't be]
<li> type declaration [won't be]
</ul>
Be advised that a javascript value that is passed to you through the
interpreter, e.g. as a call parameter, may not be of the type that
you expect. For example, in "var x = 4; f(x);", what comes in as
the parameter x into f is a wrapper value that adds assign()ability
to a value that is wrapped inside. The advised solution to get the
object that you expect is to call eliminateWrappers() on the potentially
wrapped value.
*/
namespace javascript {
class value;
class list_scope;
struct context {
ref<list_scope,value> DeclarationScope;
ref<value> LookupScope;
context(ref<list_scope,value> scope);
context(ref<value> scope);
context(ref<list_scope,value> decl_scope,ref<value> lookup_scope);
};
class expression;
class value {
public:
enum operator_id {
// unary, modifying
OP_PRE_INCREMENT,OP_POST_INCREMENT,
OP_PRE_DECREMENT,OP_POST_DECREMENT,
// unary, non-modifying
OP_UNARY_PLUS,OP_UNARY_MINUS,
OP_LOG_NOT,OP_BIN_NOT,
// binary, modifying
OP_PLUS_ASSIGN,OP_MINUS_ASSIGN,
OP_MUTLIPLY_ASSIGN,OP_DIVIDE_ASSIGN,OP_MODULO_ASSIGN,
OP_BIT_AND_ASSIGN,OP_BIT_OR_ASSIGN,OP_BIT_XOR_ASSIGN,
OP_LEFT_SHIFT_ASSIGN,OP_RIGHT_SHIFT_ASSIGN,
// binary, non-modifying
OP_PLUS,OP_MINUS,
OP_MULTIPLY,OP_DIVIDE,OP_MODULO,
OP_BIT_AND,OP_BIT_OR,OP_BIT_XOR,
OP_LEFT_SHIFT,OP_RIGHT_SHIFT,
OP_LOGICAL_OR,OP_LOGICAL_AND,
OP_EQUAL,OP_NOT_EQUAL,OP_IDENTICAL,OP_NOT_IDENTICAL,
OP_LESS_EQUAL,OP_GREATER_EQUAL,OP_LESS,OP_GREATER,
// special
OP_ASSIGN,
};
enum value_type {
VT_UNDEFINED,VT_NULL,
VT_INTEGER,VT_FLOATING_POINT,VT_STRING,
VT_FUNCTION,VT_OBJECT,VT_BUILTIN,VT_HOST,
VT_SCOPE,VT_BOUND_METHOD,VT_TYPE
};
typedef std::vector<ref<value> > parameter_list;
virtual ~value() {
}
virtual value_type getType() const = 0;
virtual std::string toString() const;
virtual int toInt() const;
virtual double toFloat() const;
virtual bool toBoolean() const;
// toString is meant as a type conversion, whereas stringify
// is for debuggers and the like
virtual std::string stringify() const;
virtual ref<value> eliminateWrappers();
virtual ref<value> duplicate();
virtual ref<value> lookup(std::string const &identifier);
virtual ref<value> subscript(value const &index);
virtual ref<value> call(parameter_list const &parameters);
virtual ref<value> callAsMethod(ref<value> instance,parameter_list const &parameters);
virtual ref<value> construct(parameter_list const &parameters);
virtual ref<value> assign(ref<value> op2);
virtual ref<value> operatorUnary(operator_id op) const;
virtual ref<value> operatorBinary(operator_id op,ref<value> op2) const;
virtual ref<value> operatorBinaryShortcut(operator_id op,expression const &op2,context const &ctx) const;
virtual ref<value> operatorUnaryModifying(operator_id op);
virtual ref<value> operatorBinaryModifying(operator_id op,ref<value> op2);
static operator_id token2operator(scanner::token const &token,bool unary = false,bool prefix = false);
static std::string operator2string(operator_id op);
static std::string valueType2string(value_type vt);
};
// obviously, any value can have methods, but with this neat little
// interface implementing methods has just become easier.
class value_with_methods : public value {
class bound_method : public value {
std::string Identifier;
ref<value_with_methods,value> Parent;
public:
bound_method(std::string const &identifier,ref<value_with_methods,value> parent);
value_type getType() const {
return VT_BOUND_METHOD;
}
ref<value> duplicate();
ref<value> call(parameter_list const &parameters);
};
public:
ref<value> lookup(std::string const &identifier);
virtual ref<value> callMethod(std::string const &identifier,parameter_list const &parameters) = 0;
};
// obviously, any value can already represent a scope ("lookup" member!).
// the list_scope class is an explicit scope that can "swallow"
// (=unite with) other scopes and keeps a list of registered members
class list_scope : public value {
protected:
typedef std::hash_map<std::string,ref<value>,string_hash> member_map;
typedef std::vector<ref<value> > swallowed_list;
member_map MemberMap;
swallowed_list SwallowedList;
public:
value_type getType() const {
return VT_SCOPE;
}
ref<value> lookup(std::string const &identifier);
void unite(ref<value> scope);
void separate(ref<value> scope);
void clearScopes();
bool hasMember(std::string const &name) const;
void addMember(std::string const &name,ref<value> member);
void removeMember(std::string const &name);
void clearMembers();
void clear();
};
class js_array : public value_with_methods {
private:
typedef value_with_methods super;
protected:
typedef std::vector<ref<value> > value_array;
value_array Array;
public:
js_array() {
}
js_array(TSize size);
js_array(value_array::const_iterator first,value_array::const_iterator last)
: Array(first,last) {
}
js_array(js_array const &src)
: Array(src.Array) {
}
value_type getType() const {
return VT_BUILTIN;
}
std::string stringify() const;
ref<value> duplicate();
ref<value> lookup(std::string const &identifier);
ref<value> subscript(value const &index);
ref<value> callMethod(std::string const &identifier,parameter_list const &parameters);
TSize size() const {
return Array.size();
}
void resize(TSize size);
ref<value> &operator[](TIndex idx);
void push_back(ref<value> val);
};
class expression;
ref<value> makeUndefined();
ref<value> makeNull();
ref<value> makeValue(signed long val);
ref<value> makeConstant(signed long val);
ref<value> makeValue(signed int val);
ref<value> makeConstant(signed int val);
ref<value> makeValue(unsigned long val);
ref<value> makeConstant(unsigned long val);
ref<value> makeValue(unsigned int val);
ref<value> makeConstant(unsigned int val);
ref<value> makeValue(double val);
ref<value> makeConstant(double val);
ref<value> makeValue(std::string const &val);
ref<value> makeConstant(std::string const &val);
ref<value> makeArray(TSize size = 0);
ref<value> makeLValue(ref<value> target);
ref<value> wrapConstant(ref<value> val);
class interpreter {
public:
ref<list_scope,value> RootScope;
public:
interpreter();
~interpreter();
ref<expression> parse(std::string const &str);
ref<expression> parse(std::istream &istr);
ref<value> execute(std::string const &str);
ref<value> execute(std::istream &istr);
ref<value> execute(ref<expression> expr);
private:
ref<value> evaluateCatchExits(ref<expression> expr);
};
void addGlobal(interpreter &ip);
void addMath(interpreter &ip);
void addStandardLibrary(interpreter &ip);
}
}
#endif

View File

@@ -0,0 +1,760 @@
// ----------------------------------------------------------------------------
// Description : Javascript interpreter
// ----------------------------------------------------------------------------
// (c) Copyright 2000 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_JS_INTERNALS
#define IXLIB_JS_INTERNALS
#include <ixlib_javascript.hh>
using namespace std;
namespace ixion {
namespace javascript {
struct code_location {
TIndex Line;
code_location(scanner::token &tok);
explicit code_location(TIndex line);
string stringify() const;
};
struct return_exception {
ref<value> ReturnValue;
code_location Location;
return_exception(ref<value> retval,code_location const &loc)
: ReturnValue(retval),Location(loc) {
}
};
struct break_exception {
bool HasLabel;
string Label;
code_location Location;
break_exception(bool has_label,string const &label,code_location const &loc)
: HasLabel(has_label),Label(label),Location(loc) {
}
};
struct continue_exception {
bool HasLabel;
string Label;
code_location Location;
continue_exception(bool has_label,string const &label,code_location const &loc)
: HasLabel(has_label),Label(label),Location(loc) {
}
};
// values -----------------------------------------------------------------
class null : public value {
private:
typedef value super;
public:
value_type getType() const;
bool toBoolean() const;
ref<value> duplicate();
};
class const_floating_point : public value_with_methods {
private:
typedef value_with_methods super;
protected:
double Value;
public:
const_floating_point(double value);
value_type getType() const;
int toInt() const;
double toFloat() const;
bool toBoolean() const;
string toString() const;
ref<value> duplicate();
ref<value> callMethod(string const &identifier,parameter_list const &parameters);
ref<value> operatorUnary(operator_id op) const;
ref<value> operatorBinary(operator_id op,ref<value> op2) const;
};
class floating_point : public const_floating_point {
private:
typedef const_floating_point super;
public:
floating_point(double value);
ref<value> operatorUnaryModifying(operator_id op);
ref<value> operatorBinaryModifying(operator_id op,ref<value> op2);
};
class const_integer : public value_with_methods {
private:
typedef value_with_methods super;
protected:
long Value;
public:
const_integer(long value);
value_type getType() const;
int toInt() const;
double toFloat() const;
bool toBoolean() const;
string toString() const;
ref<value> duplicate();
ref<value> callMethod(string const &identifier,parameter_list const &parameters);
ref<value> operatorUnary(operator_id op) const;
ref<value> operatorBinary(operator_id op,ref<value> op2) const;
};
class integer : public const_integer {
private:
typedef const_integer super;
public:
integer(long value);
ref<value> operatorUnaryModifying(operator_id op);
ref<value> operatorBinaryModifying(operator_id op,ref<value> op2);
};
class js_string : public value_with_methods {
private:
typedef value_with_methods super;
protected:
string Value;
public:
js_string(string const &value);
value_type getType() const;
string toString() const;
bool toBoolean() const;
string stringify() const;
ref<value> duplicate();
ref<value> lookup(string const &identifier);
ref<value> callMethod(string const &identifier,parameter_list const &parameters);
ref<value> operatorBinary(operator_id op,ref<value> op2) const;
ref<value> operatorBinaryModifying(operator_id op,ref<value> op2);
};
class lvalue : public value {
protected:
ref<value> Reference;
public:
lvalue(ref<value> ref);
value_type getType() const;
string toString() const;
int toInt() const;
double toFloat() const;
bool toBoolean() const;
string stringify() const;
ref<value> eliminateWrappers();
ref<value> duplicate();
ref<value> lookup(string const &identifier);
ref<value> subscript(value const &index);
ref<value> call(parameter_list const &parameters);
ref<value> callAsMethod(ref<value> instance,parameter_list const &parameters);
ref<value> construct(parameter_list const &parameters);
ref<value> assign(ref<value> op2);
ref<value> operatorUnary(operator_id op) const;
ref<value> operatorBinary(operator_id op,ref<value> op2) const;
ref<value> operatorBinaryShortcut(operator_id op,expression const &op2,context const &ctx) const;
ref<value> operatorUnaryModifying(operator_id op);
ref<value> operatorBinaryModifying(operator_id op,ref<value> op2);
};
class constant_wrapper : public value {
protected:
ref<value> Constant;
public:
constant_wrapper(ref<value> val);
value_type getType() const;
string toString() const;
int toInt() const;
double toFloat() const;
bool toBoolean() const;
string stringify() const;
ref<value> eliminateWrappers();
ref<value> duplicate();
ref<value> lookup(string const &identifier);
ref<value> subscript(value const &index);
ref<value> call(parameter_list const &parameters) const;
ref<value> callAsMethod(ref<value> instance,parameter_list const &parameters);
ref<value> construct(parameter_list const &parameters);
ref<value> assign(ref<value> value);
ref<value> operatorUnary(operator_id op) const;
ref<value> operatorBinary(operator_id op,ref<value> op2) const;
ref<value> operatorBinaryShortcut(operator_id op,expression const &op2,context const &ctx) const;
ref<value> operatorUnaryModifying(operator_id op);
ref<value> operatorBinaryModifying(operator_id op,ref<value> op2);
};
class callable_with_parameters : public value {
public:
typedef vector<string> parameter_name_list;
protected:
parameter_name_list ParameterNameList;
public:
callable_with_parameters(parameter_name_list const &pnames);
void addParametersTo(list_scope &scope,parameter_list const &parameters) const;
static ref<value> evaluateBody(expression &body,context const &ctx);
};
class function : public callable_with_parameters {
typedef callable_with_parameters super;
ref<expression> Body;
ref<value> LexicalScope;
public:
function(parameter_name_list const &pnames,ref<expression> body,ref<value> lex_scope);
value_type getType() const{
return VT_FUNCTION;
}
ref<value> duplicate();
ref<value> call(parameter_list const &parameters);
};
class method : public callable_with_parameters {
typedef callable_with_parameters super;
ref<expression> Body;
ref<value> LexicalScope;
public:
method(parameter_name_list const &pnames,ref<expression> body,ref<value> lex_scope);
value_type getType() const{
return VT_FUNCTION;
}
ref<value> duplicate();
ref<value> callAsMethod(ref<value> instance,parameter_list const &parameters);
};
class constructor : public callable_with_parameters {
typedef callable_with_parameters super;
ref<expression> Body;
ref<value> LexicalScope;
public:
constructor(parameter_name_list const &pnames,ref<expression> body,ref<value> lex_scope);
value_type getType() const{
return VT_FUNCTION;
}
ref<value> duplicate();
ref<value> callAsMethod(ref<value> instance,parameter_list const &parameters);
};
class js_class : public value {
class super_instance_during_construction : public value {
// this object constructs the superclass
// a) if it is called, by calling the super constructor
// with the aprropriate parameters
// b) implicitly with no super constructor arguments,
// if the super object is referenced explicitly
ref<value> SuperClass;
ref<value> SuperClassInstance;
public:
super_instance_during_construction(ref<value> super_class);
value_type getType() const {
return VT_OBJECT;
}
ref<value> call(parameter_list const &parameters);
ref<value> lookup(string const &identifier);
ref<value> getSuperClassInstance();
};
typedef vector<ref<expression> > declaration_list;
ref<value> LexicalScope;
ref<value> SuperClass;
ref<value> Constructor;
ref<value> StaticMethodScope;
ref<value> MethodScope;
ref<value> StaticVariableScope;
declaration_list VariableList;
public:
js_class(ref<value> lex_scope,ref<value> super_class,ref<value> constructor,
ref<value> static_method_scope,ref<value> method_scope,
ref<value> static_variable_scope,declaration_list const &variable_list);
value_type getType() const {
return VT_TYPE;
}
ref<value> duplicate();
ref<value> lookup(string const &identifier);
ref<value> lookupLocal(string const &identifier);
ref<value> construct(parameter_list const &parameters);
};
class js_class_instance : public value {
class bound_method : public value {
ref<value> Instance;
ref<value> Method;
public:
bound_method(ref<value> instance,ref<value> method);
value_type getType() const {
return VT_BOUND_METHOD;
}
ref<value> call(parameter_list const &parameters);
};
ref<value> SuperClassInstance;
ref<js_class,value> Class;
ref<value> MethodScope;
ref<value> VariableScope;
public:
js_class_instance(ref<js_class,value> cls,ref<value> method_scope,
ref<value> variable_scope);
void setSuperClassInstance(ref<value> super_class_instance);
value_type getType() const {
return VT_OBJECT;
}
ref<value> duplicate();
ref<value> lookup(string const &identifier);
};
class js_array_constructor : public value {
public:
value_type getType() const {
return VT_TYPE;
}
ref<value> duplicate();
ref<value> construct(parameter_list const &parameters);
};
// expressions ----------------------------------------------------------
class expression {
code_location Location;
public:
expression(code_location const &loc);
virtual ~expression();
virtual ref<value> evaluate(context const &ctx) const = 0;
code_location const &getCodeLocation() const {
return Location;
}
};
class constant : public expression {
ref<value> Value;
public:
constant(ref<value> val,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class unary_operator : public expression {
value::operator_id Operator;
ref<expression> Operand;
public:
unary_operator(value::operator_id opt,ref<expression> opn,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class modifying_unary_operator : public expression {
value::operator_id Operator;
ref<expression> Operand;
public:
modifying_unary_operator(value::operator_id opt,ref<expression> opn,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class binary_operator : public expression {
value::operator_id Operator;
ref<expression> Operand1;
ref<expression> Operand2;
public:
binary_operator(value::operator_id opt,ref<expression> opn1,ref<expression> opn2,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class binary_shortcut_operator : public expression {
value::operator_id Operator;
ref<expression> Operand1;
ref<expression> Operand2;
public:
binary_shortcut_operator(value::operator_id opt,ref<expression> opn1,ref<expression> opn2,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class modifying_binary_operator : public expression {
value::operator_id Operator;
ref<expression> Operand1;
ref<expression> Operand2;
public:
modifying_binary_operator(value::operator_id opt,ref<expression> opn1,ref<expression> opn2,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class ternary_operator : public expression {
ref<expression> Operand1;
ref<expression> Operand2;
ref<expression> Operand3;
public:
ternary_operator(ref<expression> opn1,ref<expression> opn2,ref<expression> opn3,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class subscript_operation : public expression {
ref<expression> Operand1;
ref<expression> Operand2;
public:
subscript_operation(ref<expression> opn1,ref<expression> opn2,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class lookup_operation : public expression {
ref<expression> Operand;
string Identifier;
public:
lookup_operation(string const &id,code_location const &loc);
lookup_operation(ref<expression> opn,string const &id,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class assignment : public expression {
ref<expression> Operand1;
ref<expression> Operand2;
public:
assignment(ref<expression> opn1,ref<expression> opn2,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class basic_call : public expression {
public:
typedef vector<ref<expression> > parameter_expression_list;
typedef vector<ref<value> > parameter_value_list;
private:
parameter_expression_list ParameterExpressionList;
public:
basic_call(parameter_expression_list const &pexps,code_location const &loc);
void makeParameterValueList(context const &ctx,parameter_value_list &pvalues) const;
};
class function_call : public basic_call {
typedef basic_call super;
ref<expression> Function;
public:
function_call(ref<expression> fun,parameter_expression_list const &pexps,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class construction : public basic_call {
typedef basic_call super;
ref<expression> Class;
public:
construction(ref<expression> cls,parameter_expression_list const &pexps,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
// declarations -----------------------------------------------------------
class variable_declaration : public expression {
protected:
string Identifier;
ref<expression> DefaultValue;
public:
variable_declaration(string const &id,ref<expression> def_value,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class constant_declaration : public expression {
protected:
string Identifier;
ref<expression> DefaultValue;
public:
constant_declaration(string const &id,ref<expression> def_value,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class function_declaration : public expression {
public:
typedef function::parameter_name_list parameter_name_list;
private:
string Identifier;
parameter_name_list ParameterNameList;
ref<expression> Body;
public:
function_declaration(string const &id,parameter_name_list const &pnames,
ref<expression> body,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class method_declaration : public expression {
public:
typedef method::parameter_name_list parameter_name_list;
private:
string Identifier;
parameter_name_list ParameterNameList;
ref<expression> Body;
public:
method_declaration(string const &id,parameter_name_list const &pnames,
ref<expression> body,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class constructor_declaration : public expression {
public:
typedef method::parameter_name_list parameter_name_list;
private:
parameter_name_list ParameterNameList;
ref<expression> Body;
public:
constructor_declaration(parameter_name_list const &pnames,
ref<expression> body,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class js_class_declaration : public expression {
typedef vector<ref<expression> > declaration_list;
string Identifier;
ref<expression> SuperClass;
ref<expression> ConstructorDeclaration;
declaration_list StaticMethodList;
declaration_list MethodList;
declaration_list StaticVariableList;
declaration_list VariableList;
public:
js_class_declaration(string const &id,ref<expression> superclass,
code_location const &loc);
ref<value> evaluate(context const &ctx) const;
void setConstructor(ref<expression> decl);
void addStaticMethod(ref<expression> decl);
void addMethod(ref<expression> decl);
void addStaticVariable(ref<expression> decl);
void addVariable(ref<expression> decl);
};
// instructions ---------------------------------------------------------
class instruction_list : public expression {
typedef vector<ref<expression> > expression_list;
expression_list ExpressionList;
public:
instruction_list(code_location const &loc)
: expression(loc) {
}
ref<value> evaluate(context const &ctx) const;
void add(ref<expression> expr);
};
class scoped_instruction_list : public instruction_list {
public:
scoped_instruction_list(code_location const &loc)
: instruction_list(loc) {
}
ref<value> evaluate(context const &ctx) const;
};
class js_if : public expression {
ref<expression> Conditional;
ref<expression> IfExpression;
ref<expression> IfNotExpression;
public:
js_if(ref<expression> cond,ref<expression> ifex,ref<expression> ifnotex,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class js_while : public expression {
ref<expression> Conditional;
ref<expression> LoopExpression;
bool HasLabel;
string Label;
public:
js_while(ref<expression> cond,ref<expression> loopex,code_location const &loc);
js_while(ref<expression> cond,ref<expression> loopex,string const &Label,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class js_do_while : public expression {
ref<expression> Conditional;
ref<expression> LoopExpression;
bool HasLabel;
string Label;
public:
js_do_while(ref<expression> cond,ref<expression> loopex,code_location const &loc);
js_do_while(ref<expression> cond,ref<expression> loopex,string const &Label,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class js_for : public expression {
ref<expression> Initialization;
ref<expression> Conditional;
ref<expression> Update;
ref<expression> LoopExpression;
bool HasLabel;
string Label;
public:
js_for(ref<expression> init,ref<expression> cond,ref<expression> update,ref<expression> loop,code_location const &loc);
js_for(ref<expression> init,ref<expression> cond,ref<expression> update,ref<expression> loop,string const &label,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class js_for_in : public expression {
ref<expression> Iterator;
ref<expression> Array;
ref<expression> LoopExpression;
bool HasLabel;
string Label;
public:
js_for_in(ref<expression> iter,ref<expression> array,ref<expression> loop,code_location const &loc);
js_for_in(ref<expression> iter,ref<expression> array,ref<expression> loop,string const &label,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class js_return : public expression {
ref<expression> ReturnValue;
public:
js_return(ref<expression> retval,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class js_break : public expression {
bool HasLabel;
string Label;
public:
js_break(code_location const &loc);
js_break(string const &label,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class js_continue : public expression {
bool HasLabel;
string Label;
public:
js_continue(code_location const &loc);
js_continue(string const &label,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class break_label : public expression {
string Label;
ref<expression> Expression;
public:
break_label(string const &label,ref<expression> expr,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
};
class js_switch : public expression {
bool HasLabel;
string Label;
ref<expression> Discriminant;
struct case_label {
ref<expression> DiscriminantValue;
ref<expression> Expression;
};
typedef vector<case_label> case_list;
case_list CaseList;
public:
js_switch(ref<expression> discriminant,code_location const &loc);
js_switch(ref<expression> discriminant,string const &label,code_location const &loc);
ref<value> evaluate(context const &ctx) const;
void addCase(ref<expression> dvalue,ref<expression> expr);
};
}
}
#endif

View File

@@ -0,0 +1,62 @@
// ----------------------------------------------------------------------------
// Description : Numeric conversions
// ----------------------------------------------------------------------------
// (c) Copyright 1999 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_NUMCONV
#define IXLIB_NUMCONV
#include <ixlib_base.hh>
#include <ixlib_string.hh>
// Macros ---------------------------------------------------------------------
#define IXLIB_NUMCHARS "0123456789ABCDEF"
// Functions ------------------------------------------------------------------
namespace ixion {
std::string float2dec(double value);
std::string float2dec(double value,unsigned int precision);
std::string unsigned2base(unsigned long value,char digits = 0,char radix = 10);
inline std::string unsigned2dec(unsigned long value,char digits = 0)
{ return unsigned2base(value,digits,10); }
inline std::string unsigned2hex(unsigned long value,char digits = 0)
{ return unsigned2base(value,digits,16); }
inline std::string unsigned2bin(unsigned long value,char digits = 0)
{ return unsigned2base(value,digits,2); }
inline std::string unsigned2oct(unsigned long value,char digits = 0)
{ return unsigned2base(value,digits,8); }
std::string signed2base(signed long value,char digits = 0,char radix = 10);
inline std::string signed2dec(signed long value,char digits = 0)
{ return signed2base(value,digits,10); }
inline std::string signed2hex(signed long value,char digits = 0)
{ return signed2base(value,digits,16); }
inline std::string signed2bin(signed long value,char digits = 0)
{ return signed2base(value,digits,2); }
inline std::string signed2oct(signed long value,char digits = 0)
{ return signed2base(value,digits,8); }
std::string bytes2dec(TSize bytes);
unsigned long evalNumeral(std::string const &numeral,unsigned radix = 10);
double evalFloat(std::string const &numeral);
unsigned long evalUnsigned(std::string const &numeral,unsigned default_base = 10);
signed long evalSigned(std::string const &numeral,unsigned default_base = 10);
}
#endif

View File

@@ -0,0 +1,127 @@
// ----------------------------------------------------------------------------
// Description : numeric / order processing
// ----------------------------------------------------------------------------
// (c) Copyright 1996 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_NUMERIC
#define IXLIB_NUMERIC
#include <cstring>
#include <ixlib_base.hh>
#include <ixlib_exgen.hh>
// Macros ---------------------------------------------------------------------
#ifdef _GNUC_
#define NUM_MIN(a,b) ( (a)<?(b) )
#define NUM_MAX(a,b) ( (a)>?(b) )
#define NUM_ABS(a) ( (a)<0 ? (-(a)) : (a) )
#else
#define NUM_MIN(a,b) ( (a)<(b) ? (a) : (b) )
#define NUM_MAX(a,b) ( (a)>(b) ? (a) : (b) )
#define NUM_ABS(a) ( (a)<0 ? (-(a)) : (a) )
#endif
#define NUM_LIMIT(lower,value,upper) \
( NUM_MAX(lower,NUM_MIN(upper,vallue)) )
#define NUM_INBOUND(lower,value,upper) \
(((lower) <= (value)) && ((value) <= (upper)))
#define NUM_OVERLAP(a1,a2,b1,b2) \
((((a1)<=(b1))&&((a2)>(b1)))||(((a1)<(b2))&&((a2)>(b2)))||(((a1)>=(b1))&&((a2)<=(b2))))
#define NUM_CIRCLEINC(index,size) \
( ((index)+1) >= (size) ? 0 : ((index)+1) )
#define NUM_CIRCLEDIST(head,tail,size) \
( (head)<(tail) ? ((head)+(size)-(tail)) : ((head)-(tail)) )
// Primitive inlines ---------------------------------------------------------
namespace ixion {
inline signed short sgn(signed long value);
inline bool getBit(unsigned long value,char bit);
inline TUnsigned8 hiByte(TUnsigned16 value);
inline TUnsigned16 hiWord(TUnsigned32 value);
inline TUnsigned8 loByte(TUnsigned16 value);
inline TUnsigned16 loWord(TUnsigned32 value);
inline TUnsigned16 makeWord(TUnsigned8 hi,TUnsigned8 lo);
inline TUnsigned32 makeDWord(TUnsigned16 hi,TUnsigned16 lo);
// BCD encoding ---------------------------------------------------------------
unsigned long unsigned2BCD(unsigned long value);
unsigned long BCD2unsigned(unsigned long value);
// Primitive inlines ---------------------------------------------------------
inline signed short ixion::sgn(signed long value) {
return (value<0) ? -1 : ( (value>0) ? 1 : 0);
}
inline bool ixion::getBit(unsigned long value,char bit) {
return (value >> bit) & 1;
}
inline TUnsigned8 ixion::hiByte(TUnsigned16 value) {
return value >> 8;
}
inline TUnsigned16 ixion::hiWord(TUnsigned32 value) {
return value >> 16;
}
inline TUnsigned8 ixion::loByte(TUnsigned16 value) {
return value & 0xff;
}
inline TUnsigned16 ixion::loWord(TUnsigned32 value) {
return value & 0xffff;
}
inline TUnsigned16 ixion::makeWord(TUnsigned8 hi,TUnsigned8 lo) {
return (TUnsigned16) hi << 8 | lo;
}
inline TUnsigned32 ixion::makeDWord(TUnsigned16 hi,TUnsigned16 lo) {
return (TUnsigned32) hi << 16 | lo;
}
}
#endif

View File

@@ -0,0 +1,82 @@
// ----------------------------------------------------------------------------
// Description : Random numbers
// ----------------------------------------------------------------------------
// (c) Copyright 1996 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_RANDOM
#define IXLIB_RANDOM
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <ixlib_base.hh>
#include <ixlib_numeric.hh>
namespace ixion {
class float_random {
double Seed;
public:
float_random()
: Seed(1)
{ }
void init() {
double current_time = time(NULL);
Seed = current_time*sin(current_time);
}
void init(double seed)
{ Seed = NUM_ABS(seed); }
/// Generate one random number in the interval [0,max).
double operator()(double max = 1) {
// normalize
while (Seed > 3) Seed = log(Seed);
Seed -= floor(Seed);
Seed = pow(Seed+Pi,8);
Seed -= floor(Seed);
return Seed*max;
}
};
class int_random {
float_random Generator;
public:
int_random()
{ }
void init()
{ Generator.init(); }
void init(unsigned seed)
{ Generator.init(seed); }
/// Generate one random number in the interval [0,max).
unsigned operator()(unsigned max = 32768) {
unsigned num = rng8() + (rng8() << 7) + (rng8() << 14) + (rng8() << 21) + (rng8() << 28);
return num % max;
}
private:
TUnsigned8 rng8() {
return (TUnsigned8) (Generator()*256);
}
};
}
#endif

View File

@@ -0,0 +1,493 @@
// ----------------------------------------------------------------------------
// Description : Regular expressions string object
// ----------------------------------------------------------------------------
// (c) Copyright 1998 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_RE
#define IXLIB_RE
#include <vector>
#include <memory>
#include <ixlib_exgen.hh>
#include <ixlib_string.hh>
// Regex exceptions -----------------------------------------------------------
#define ECRE_INVQUANTIFIER 0
#define ECRE_UNBALBACKREF 1
#define ECRE_INVESCAPE 2
#define ECRE_INVBACKREF 3
#define ECRE_UNTERMCLASS 4
#define ECRE_NOPATTERN 5
namespace ixion {
class regex_exception : public base_exception {
public:
regex_exception(TErrorCode error,char const *info = NULL,char *module = NULL,TIndex line = 0);
virtual char *getText() const;
};
}
// Regex token macros ---------------------------------------------------------
#define XSTRRE_LITERAL '\\'
#define XSTRRE_BACKREF '\\'
#define XSTRRE_ESCAPESEQ '\\'
#define XSTRRE_ANYCHAR '.'
#define XSTRRE_START '^'
#define XSTRRE_END '$'
#define XSTRRE_ALTERNATIVE '|'
#define XSTRRE_CLASSSTART '['
#define XSTRRE_CLASSNEG '^'
#define XSTRRE_CLASSRANGE '-'
#define XSTRRE_CLASSSTOP ']'
#define XSTRRE_BACKREFSTART '('
#define XSTRRE_BACKREFSTOP ')'
#define XSTRREQ_0PLUS '*'
#define XSTRREQ_1PLUS '+'
#define XSTRREQ_01 '?'
#define XSTRREQ_START '{'
#define XSTRREQ_RANGE ','
#define XSTRREQ_STOP '}'
#define XSTRREQ_NONGREEDY '?'
namespace ixion {
/**
A class implementing a generic regular expression matcher not only for strings.
If you are looking for a usual regular expresion parser, look at
ixion::regex_string.
If you query anything about the last match, and that last match did
never happen, behavior is undefined.
*/
template<class T>
class regex {
protected:
// various helper classes -----------------------------------------------
class backref_stack {
private:
struct backref_entry {
enum { OPEN,CLOSE } Type;
TIndex Index;
};
typedef std::vector<backref_entry> internal_stack;
internal_stack Stack;
public:
typedef TSize rewind_info;
void open(TIndex index);
void close(TIndex index);
rewind_info getRewindInfo() const;
void rewind(rewind_info ri);
void clear();
TSize size();
T get(TIndex number,T const &candidate) const;
};
// matchers -------------------------------------------------------------
class matcher {
protected:
matcher *Next;
bool OwnNext;
TSize MatchLength;
public:
matcher();
virtual ~matcher();
virtual matcher *duplicate() const = 0;
TSize getMatchLength() const {
return MatchLength;
}
TSize subsequentMatchLength() const;
virtual TSize minimumMatchLength() const = 0;
TSize minimumSubsequentMatchLength() const;
matcher *getNext() const {
return Next;
}
virtual void setNext(matcher *next,bool ownnext = true) {
Next = next;
OwnNext = ownnext;
}
// this routine must set the MatchLength member correctly.
virtual bool match(backref_stack &brstack,T const &candidate,TIndex at)
= 0;
protected:
bool matchNext(backref_stack &brstack,T const &candidate,TIndex at) const {
return Next ? Next->match(brstack,candidate,at) : true;
}
void copy(matcher const *src);
};
class quantifier : public matcher {
private:
typedef matcher super;
bool Greedy,MaxValid;
TSize MinCount,MaxCount;
matcher *Quantified;
struct backtrack_stack_entry {
TIndex Index;
backref_stack::rewind_info RewindInfo;
};
public:
quantifier()
: Quantified(NULL) {
}
quantifier(bool greedy,TSize mincount);
quantifier(bool greedy,TSize mincount,TSize maxcount);
~quantifier();
matcher *duplicate() const;
TSize minimumMatchLength() const;
void setQuantified(matcher *quantified) {
Quantified = quantified;
}
bool match(backref_stack &brstack,T const &candidate,TIndex at);
protected:
void copy(quantifier const *src);
};
class sequence_matcher : public matcher {
T MatchStr;
public:
sequence_matcher(T const &matchstr);
matcher *duplicate() const;
TSize minimumMatchLength() const {
return MatchStr.size();
}
bool match(backref_stack &brstack,T const &candidate,TIndex at);
};
class any_matcher : public matcher {
public:
any_matcher() {
MatchLength = 1;
}
matcher *duplicate() const;
TSize minimumMatchLength() const {
return 1;
}
bool match(backref_stack &brstack,T const &candidate,TIndex at) {
return at < candidate.size() && matchNext(brstack,candidate,at+1);
}
};
class start_matcher : public matcher {
public:
start_matcher() {
MatchLength = 0;
}
matcher *duplicate() const;
TSize minimumMatchLength() const {
return 0;
}
bool match(backref_stack &brstack,T const &candidate,TIndex at);
};
class end_matcher : public matcher {
public:
end_matcher() {
MatchLength = 0;
}
matcher *duplicate() const;
TSize minimumMatchLength() const {
return 0;
}
bool match(backref_stack &brstack,T const &candidate,TIndex at);
};
class backref_open_matcher : public matcher {
public:
backref_open_matcher() {
MatchLength = 0;
}
matcher *duplicate() const;
TSize minimumMatchLength() const {
return 0;
}
bool match(backref_stack &brstack,T const &candidate,TIndex at);
};
class backref_close_matcher : public matcher {
public:
backref_close_matcher() {
MatchLength = 0;
}
matcher *duplicate() const;
TSize minimumMatchLength() const {
return 0;
}
bool match(backref_stack &brstack,T const &candidate,TIndex at);
};
class alternative_matcher : public matcher {
// The connector serves two purposes:
// a) be a null-matcher that re-unites the different alternate token
// sequences
// b) make the end of each sequence identifiable to be able to compute
// the match length
class connector : public matcher {
public:
matcher *duplicate() const {
return NULL;
}
TSize minimumMatchLength() const {
return 0;
}
bool match(backref_stack &brstack,T const &candidate,TIndex at);
};
typedef matcher super;
typedef std::vector<matcher *> alt_list;
alt_list AltList;
connector Connector;
public:
~alternative_matcher();
matcher *duplicate() const;
TSize minimumMatchLength() const;
void setNext(matcher *next,bool ownnext = true);
void addAlternative(matcher *alternative);
bool match(backref_stack &brstack,T const &candidate,TIndex at);
protected:
void copy(alternative_matcher const *src);
};
class backref_matcher : public matcher {
TIndex Backref;
public:
backref_matcher(TIndex backref);
matcher *duplicate() const;
TSize minimumMatchLength() const {
return 0;
}
bool match(backref_stack &brstack,T const &candidate,TIndex at);
};
// instance data --------------------------------------------------------
std::auto_ptr<matcher> ParsedRegex;
backref_stack BackrefStack;
T LastCandidate;
TIndex MatchIndex;
TSize MatchLength;
public:
// interface ------------------------------------------------------------
regex();
regex(regex const &src);
regex &operator=(regex const &src);
bool match(T const &candidate,TIndex from = 0);
bool matchAt(T const &candidate,TIndex at = 0);
// Queries pertaining to the last match
TIndex getMatchIndex() {
return MatchIndex;
}
TSize getMatchLength() {
return MatchLength;
}
std::string getMatch() {
return T(LastCandidate.begin()+MatchIndex,
LastCandidate.begin()+MatchIndex+MatchLength);
}
TSize countBackrefs() {
return BackrefStack.size();
}
T getBackref(TIndex index) {
return BackrefStack.get(index,LastCandidate);
}
};
/**
A regular expression parser and matcher.
Backref numbering starts at \0.
ReplaceAll does not set the MatchIndex/MatchGlobal members.
What is there is compatible with perl5. (See man perlre or
http://www.cpan.org/doc/manual/html/pod/perlre.html)
However, not everything is there. Here's what's missing:
<ul>
<li> \Q-\E,\b,\B,\A,\Z,\z
<li> discerning between line and string
<li> (?#comments)
<li> (?:clustering)
<li> (?=positive lookahead assumptions)
<li> (?!negative lookahead assumptions
<li> (?<=positive lookbehind assumptions)
<li> (?<!negative lookbehind assumptions
<li> (?>independent substrings)
<li> modifiers such as "case independent"
</ul>
as well as all the stuff involving perl code, naturally.
None of these is actually hard to hack in. If you want them,
pester me or try for yourself (and submit patches!)
*/
class regex_string : public regex<std::string> {
private:
class class_matcher : public regex<std::string>::matcher {
private:
typedef regex<std::string>::matcher super;
static TSize const CharValues = 256;
bool Set[CharValues];
bool Negated;
public:
class_matcher();
class_matcher(std::string const &cls);
matcher *duplicate() const;
TSize minimumMatchLength() const {
return 1;
}
bool match(backref_stack &brstack,std::string const &candidate,TIndex at);
private:
void expandClass(std::string const &cls);
protected:
void copy(class_matcher const *src);
};
class special_class_matcher : public regex<std::string>::matcher {
public:
enum type { DIGIT,NONDIGIT,ALNUM,NONALNUM,SPACE,NONSPACE };
private:
type Type;
public:
special_class_matcher(type tp);
matcher *duplicate() const;
TSize minimumMatchLength() const {
return 1;
}
bool match(backref_stack &brstack,std::string const &candidate,TIndex at);
};
public:
regex_string() {
}
regex_string(std::string const &str) {
parse(str);
}
regex_string(char const *s) {
parse(s);
}
void parse(std::string const &expr);
std::string replaceAll(std::string const &candidate,std::string const &replacement,
TIndex from = 0);
private:
regex<std::string>::matcher *parseRegex(std::string const &expr);
quantifier *parseQuantifier(std::string const &expr,TIndex &at);
bool isGreedy(std::string const &expr,TIndex &at);
};
}
#endif

View File

@@ -0,0 +1,652 @@
// ----------------------------------------------------------------------------
// Description : Regular expressions string object.
// ----------------------------------------------------------------------------
// (c) Copyright 1998 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <stack>
#include <cctype>
#include "ixlib_i18n.hh"
#include <ixlib_exgen.hh>
#include <ixlib_numeric.hh>
#include <ixlib_numconv.hh>
#include <ixlib_re.hh>
// regex::backref_stack -------------------------------------------------------
template<class T>
void ixion::regex<T>::backref_stack::open(TIndex index) {
backref_entry entry = { backref_entry::OPEN,index };
Stack.push_back(entry);
}
template<class T>
void ixion::regex<T>::backref_stack::close(TIndex index) {
backref_entry entry = { backref_entry::CLOSE,index };
Stack.push_back(entry);
}
template<class T>
ixion::regex<T>::backref_stack::rewind_info
ixion::regex<T>::backref_stack::getRewindInfo() const {
return Stack.size();
}
template<class T>
void ixion::regex<T>::backref_stack::rewind(rewind_info ri) {
Stack.erase(Stack.begin()+ri,Stack.end());
}
template<class T>
void ixion::regex<T>::backref_stack::clear() {
Stack.clear();
}
template<class T>
ixion::TSize ixion::regex<T>::backref_stack::size() {
TSize result = 0;
FOREACH_CONST(first,Stack,internal_stack)
if (first->Type == backref_entry::OPEN) result++;
return result;
}
template<class T>
T ixion::regex<T>::backref_stack::get(TIndex number,T const &candidate) const {
TIndex level = 0,next_index = 0;
TIndex start;
TIndex startlevel;
internal_stack::const_iterator first = Stack.begin(),last = Stack.end();
while (first != last) {
if (first->Type == backref_entry::OPEN) {
if (number == next_index) {
start = first->Index;
startlevel = level;
level++;
break;
}
next_index++;
level++;
}
if (first->Type == backref_entry::CLOSE)
level--;
first++;
}
if (first == last)
EX_THROW(regex,ECRE_INVBACKREF)
first++;
while (first != last) {
if (first->Type == backref_entry::OPEN)
level++;
if (first->Type == backref_entry::CLOSE) {
level--;
if (startlevel == level)
return candidate.substr(start,first->Index - start);
}
first++;
}
EX_THROW(regex,ECRE_UNBALBACKREF)
}
// regex::matcher -------------------------------------------------------------
template<class T>
ixion::regex<T>::matcher::matcher()
: Next(NULL) {
}
template<class T>
ixion::regex<T>::matcher::~matcher() {
if (Next && OwnNext)
delete Next;
}
template<class T>
ixion::TSize ixion::regex<T>::matcher::subsequentMatchLength() const {
TSize totalml = 0;
matcher const *object = this;
while (object) {
totalml += object->MatchLength;
object = object->Next;
}
return totalml;
}
template<class T>
ixion::TSize ixion::regex<T>::matcher::minimumSubsequentMatchLength() const {
TSize totalml = 0;
matcher const *object = this;
while (object) {
totalml += object->minimumMatchLength();
object = object->Next;
}
return totalml;
}
template<class T>
void ixion::regex<T>::matcher::copy(matcher const *src) {
if (src->Next && src->OwnNext)
setNext(src->Next->duplicate(),src->OwnNext);
else
setNext(NULL);
}
// regex::quantifier ----------------------------------------------------------
template<class T>
ixion::regex<T>::quantifier::quantifier(bool greedy,TSize mincount)
: Greedy(greedy),MaxValid(false),MinCount(mincount) {
}
template<class T>
ixion::regex<T>::quantifier::quantifier(bool greedy,TSize mincount,TSize maxcount)
: Greedy(greedy),MaxValid(true),MinCount(mincount),MaxCount(maxcount) {
}
template<class T>
ixion::regex<T>::quantifier::~quantifier() {
if (Quantified)
delete Quantified;
}
template<class T>
ixion::regex<T>::matcher *ixion::regex<T>::quantifier::duplicate() const {
quantifier *dupe = new quantifier();
dupe->copy(this);
return dupe;
}
template<class T>
ixion::TSize ixion::regex<T>::quantifier::minimumMatchLength() const {
if (Quantified)
return MinCount * Quantified->minimumMatchLength();
else
return 0;
}
template<class T>
bool ixion::regex<T>::quantifier::match(backref_stack &brstack,T const &candidate,TIndex at) {
// this routine does speculative matching, so it must pay close attention
// to rewind the backref stack appropriately.
// NB: matchNext does the rewinding automatically, whereas speculative
// matches of the quantified portion must be rewound.
// There should be at least one character in each match, we'd
// run to Baghdad otherwise.
if (!Quantified)
return matchNext(brstack,candidate,at);
// calculate accurate maximum match count
TSize quant_min = Quantified->minimumSubsequentMatchLength();
if (quant_min == 0) quant_min = 1;
TSize max_count = candidate.size() - at;
if (Next) max_count -= Next->minimumSubsequentMatchLength();
max_count = max_count/quant_min + 1;
if (MaxValid) max_count = NUM_MIN(max_count,MaxCount);
// check that at least MinCount matches take place (non-speculative)
TIndex idx = at;
for (TSize c = 1;c <= MinCount;c++)
if (Quantified->match(brstack,candidate,idx))
idx += Quantified->subsequentMatchLength();
else
return false;
// determine number of remaining matches
TSize remcount = max_count-MinCount;
// test for the remaining matches in a way that depends on Greedy flag
if (Greedy) {
// try to gobble up as many matches of quantified part as possible
// (speculative)
std::stack<backtrack_stack_entry> successful_indices;
{ backtrack_stack_entry entry = { idx,brstack.getRewindInfo() };
successful_indices.push(entry);
}
while (Quantified->match(brstack,candidate,idx) && successful_indices.size()-1 < remcount) {
idx += Quantified->subsequentMatchLength();
backtrack_stack_entry entry = { idx,brstack.getRewindInfo() };
successful_indices.push(entry);
}
// backtrack until rest of sequence also matches
while (successful_indices.size() && !matchNext(brstack,candidate,successful_indices.top().Index)) {
brstack.rewind(successful_indices.top().RewindInfo);
successful_indices.pop();
}
if (successful_indices.size()) {
MatchLength = successful_indices.top().Index - at;
return true;
}
else return false;
}
else {
for (TSize c = 0;c <= remcount;c++) {
if (matchNext(brstack,candidate,idx)) {
MatchLength = idx-at;
return true;
}
// following part runs once too much, effectively:
// if c == remcount, idx may be increased, but the search fails anyway
// => no problem
if (Quantified->match(brstack,candidate,idx))
idx += Quantified->subsequentMatchLength();
else
return false;
}
return false;
}
}
template<class T>
void ixion::regex<T>::quantifier::copy(quantifier const *src) {
super::copy(src);
Greedy = src->Greedy;
MaxValid = src->MaxValid;
MinCount = src->MinCount;
MaxCount = src->MaxCount;
Quantified = src->Quantified->duplicate();
}
// regex::sequence_matcher ------------------------------------------------------
template<class T>
ixion::regex<T>::sequence_matcher::sequence_matcher(T const &matchstr)
: MatchStr(matchstr) {
MatchLength = MatchStr.size();
}
template<class T>
ixion::regex<T>::matcher *ixion::regex<T>::sequence_matcher::duplicate() const {
sequence_matcher *dupe = new sequence_matcher(MatchStr);
dupe->copy(this);
return dupe;
}
template<class T>
bool ixion::regex<T>::sequence_matcher::match(backref_stack &brstack,T const &candidate,TIndex at) {
if (at+MatchStr.size() > candidate.size()) return false;
return (T(candidate.begin()+at,candidate.begin()+at+MatchStr.size()) == MatchStr) &&
matchNext(brstack,candidate,at+MatchStr.size());
}
// regex::any_matcher ---------------------------------------------------------
template<class T>
ixion::regex<T>::matcher *ixion::regex<T>::any_matcher::duplicate() const {
any_matcher *dupe = new any_matcher();
dupe->copy(this);
return dupe;
}
// regex::start_matcher ---------------------------------------------------------
template<class T>
ixion::regex<T>::matcher *ixion::regex<T>::start_matcher::duplicate() const {
start_matcher *dupe = new start_matcher();
dupe->copy(this);
return dupe;
}
template<class T>
bool ixion::regex<T>::start_matcher::match(backref_stack &brstack,T const &candidate,TIndex at) {
return (at == 0) && matchNext(brstack,candidate,at);
}
// regex::end_matcher ---------------------------------------------------------
template<class T>
ixion::regex<T>::matcher *ixion::regex<T>::end_matcher::duplicate() const {
end_matcher *dupe = new end_matcher();
dupe->copy(this);
return dupe;
}
template<class T>
bool ixion::regex<T>::end_matcher::match(backref_stack &brstack,T const &candidate,TIndex at) {
return (at == candidate.size()) && matchNext(brstack,candidate,at);
}
// regex::backref_open_matcher ------------------------------------------------
template<class T>
ixion::regex<T>::matcher *ixion::regex<T>::backref_open_matcher::duplicate() const {
backref_open_matcher *dupe = new backref_open_matcher();
dupe->copy(this);
return dupe;
}
template<class T>
bool ixion::regex<T>::backref_open_matcher::match(backref_stack &brstack,T const &candidate,TIndex at) {
backref_stack::rewind_info ri = brstack.getRewindInfo();
brstack.open(at);
bool result = matchNext(brstack,candidate,at);
if (!result)
brstack.rewind(ri);
return result;
}
// regex::backref_close_matcher -----------------------------------------------
template<class T>
ixion::regex<T>::matcher *ixion::regex<T>::backref_close_matcher::duplicate() const {
backref_close_matcher *dupe = new backref_close_matcher();
dupe->copy(this);
return dupe;
}
template<class T>
bool ixion::regex<T>::backref_close_matcher::match(backref_stack &brstack,T const &candidate,TIndex at) {
backref_stack::rewind_info ri = brstack.getRewindInfo();
brstack.close(at);
bool result = matchNext(brstack,candidate,at);
if (!result)
brstack.rewind(ri);
return result;
}
// regex::alternative_matcher::connector --------------------------------------
template<class T>
bool ixion::regex<T>::alternative_matcher::connector::match(backref_stack &brstack,T const &candidate,TIndex at) {
return matchNext(brstack,candidate,at);
}
// regex::alternative_matcher -------------------------------------------------
template<class T>
ixion::regex<T>::alternative_matcher::~alternative_matcher() {
while (AltList.size()) {
delete AltList.back();
AltList.pop_back();
}
}
template<class T>
ixion::regex<T>::matcher *ixion::regex<T>::alternative_matcher::duplicate() const {
alternative_matcher *dupe = new alternative_matcher();
dupe->copy(this);
return dupe;
}
template<class T>
ixion::TSize ixion::regex<T>::alternative_matcher::minimumMatchLength() const {
TSize result = 0;
bool is_first = true;
FOREACH_CONST(first,AltList,alt_list)
if (is_first) {
result = (*first)->minimumMatchLength();
is_first = true;
}
else {
TSize current = (*first)->minimumMatchLength();
if (current < result) result = current;
}
return result;
}
template<class T>
void ixion::regex<T>::alternative_matcher::setNext(matcher *next,bool ownnext = true) {
matcher::setNext(next);
Connector.setNext(next,false);
}
template<class T>
void ixion::regex<T>::alternative_matcher::addAlternative(matcher *alternative) {
AltList.push_back(alternative);
matcher *searchlast = alternative,*last = NULL;
while (searchlast) {
last = searchlast;
searchlast = searchlast->getNext();
}
last->setNext(&Connector,false);
}
template<class T>
bool ixion::regex<T>::alternative_matcher::match(backref_stack &brstack,T const &candidate,TIndex at) {
std::vector<matcher *>::iterator first = AltList.begin(),last = AltList.end();
while (first != last) {
if ((*first)->match(brstack,candidate,at)) {
MatchLength = 0;
matcher const *object = *first;
while (object != &Connector) {
MatchLength += object->getMatchLength();
object = object->getNext();
}
return true;
}
first++;
}
return false;
}
template<class T>
void ixion::regex<T>::alternative_matcher::copy(alternative_matcher const *src) {
super::copy(src);
Connector.setNext(Next,false);
FOREACH_CONST(first,src->AltList,alt_list)
addAlternative((*first)->duplicate());
}
// regex::backref_matcher -----------------------------------------------------
template<class T>
ixion::regex<T>::backref_matcher::backref_matcher(TIndex backref)
: Backref(backref) {
}
template<class T>
ixion::regex<T>::matcher *ixion::regex<T>::backref_matcher::duplicate() const {
backref_matcher *dupe = new backref_matcher(Backref);
dupe->copy(this);
return dupe;
}
template<class T>
bool ixion::regex<T>::backref_matcher::match(backref_stack &brstack,T const &candidate,TIndex at) {
T matchstr = brstack.get(Backref,candidate);
MatchLength = matchstr.size();
if (at+matchstr.size() > candidate.size()) return false;
return (T(candidate.begin()+at,candidate.begin()+at+matchstr.size()) == matchstr) &&
matchNext(brstack,candidate,at+matchstr.size());
}
// regex ----------------------------------------------------------------------
template<class T>
ixion::regex<T>::regex()
: MatchIndex(0),MatchLength(0) {
}
template<class T>
ixion::regex<T>::regex(regex const &src)
: ParsedRegex(src.ParsedRegex->duplicate()),
MatchIndex(0),MatchLength(0) {
}
template<class T>
ixion::regex<T> &ixion::regex<T>::operator=(regex const &src) {
std::auto_ptr<matcher> regex_copy(src.ParsedRegex->duplicate());
ParsedRegex = regex_copy;
return *this;
}
template<class T>
bool ixion::regex<T>::match(T const &candidate,TIndex from) {
LastCandidate = candidate;
BackrefStack.clear();
if (ParsedRegex.get() == NULL)
EX_THROW(regex,ECRE_NOPATTERN)
for (TIndex index = from;index < candidate.size();index++)
if (ParsedRegex->match(BackrefStack,candidate,index)) {
MatchIndex = index;
MatchLength = ParsedRegex->subsequentMatchLength();
return true;
}
return false;
}
template<class T>
bool ixion::regex<T>::matchAt(T const &candidate,TIndex at) {
LastCandidate = candidate;
BackrefStack.clear();
if (ParsedRegex.get() == NULL)
EX_THROW(regex,ECRE_NOPATTERN)
if (ParsedRegex->match(BackrefStack,candidate,at)) {
MatchIndex = at;
MatchLength = ParsedRegex->subsequentMatchLength();
return true;
}
return false;
}

View File

@@ -0,0 +1,24 @@
// ----------------------------------------------------------------------------
// Description : Javascript scanner
// ----------------------------------------------------------------------------
// (c) Copyright 2000 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_SCANJS
#define IXLIB_SCANJS
#undef yyFlexLexer
#define yyFlexLexer jsFlexLexer
#include <FlexLexer.h>
#undef yyFlexLexer
#endif

View File

@@ -0,0 +1,75 @@
// ----------------------------------------------------------------------------
// Description : scanner wrapper for FlexLexer
// ----------------------------------------------------------------------------
// (c) Copyright 1999 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_SCANNER
#define IXLIB_SCANNER
#include <ixlib_base.hh>
#include <ixlib_exbase.hh>
#include <vector>
#include <ixlib_string.hh>
class FlexLexer;
// possible errors during execution -------------------------------------------
#define ECSCAN_UNKNOWN_TOKEN 0
#define ECSCAN_EOF 1
// scanner_exception ----------------------------------------------------------
namespace ixion {
struct scanner_exception : public base_exception {
scanner_exception(TErrorCode const error,TIndex const line,std::string const &info);
virtual char *getText() const;
};
// scanner --------------------------------------------------------------------
class scanner {
public:
typedef unsigned token_type;
struct token {
token_type Type;
TIndex Line;
std::string Text;
};
typedef std::vector<token> token_list;
typedef std::vector<token>::iterator token_iterator;
scanner(FlexLexer &lexer);
token_list scan();
protected:
FlexLexer &Lexer;
token CurrentToken;
token getNextToken();
bool reachedEOF() const;
};
}
#endif

View File

@@ -0,0 +1,64 @@
// ----------------------------------------------------------------------------
// Description : String crunching tools
// ----------------------------------------------------------------------------
// (c) Copyright 1999 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_STRING
#define IXLIB_STRING
#include <string>
#include <ixlib_base.hh>
#include <ixlib_exgen.hh>
namespace ixion {
template<class InputIterator>
inline std::string concat(InputIterator first,InputIterator last,std::string const &sep = " ") {
std::string str;
while (first != last) {
if (str.size()) str += sep;
str += *first++;
}
return str;
}
std::string findReplace(std::string const &target,std::string const &src,std::string const &dest);
std::string findReplace(std::string const &target,char* src,char *dest);
std::string findReplace(std::string const &target,char src,char dest);
std::string upper(std::string const &original);
std::string lower(std::string const &original);
std::string removeLeading(std::string const &original,char ch = ' ');
std::string removeTrailing(std::string const &original,char ch = ' ');
std::string removeLeadingTrailing(std::string const &original,char ch = ' ');
std::string parseCEscapes(std::string const &original);
TSize getMaxBase64DecodedSize(TSize encoded);
// data must provide enough space for the maximal size determined by the
// above function
TSize base64decode(TByte *data,std::string const &base64);
void base64encode(std::string &base64,TByte const *data,TSize size);
class string_hash {
public:
unsigned long operator()(std::string const &str) const;
};
}
#endif

View File

@@ -0,0 +1,85 @@
// ----------------------------------------------------------------------------
// Description : Token definitions for Javascript scanner
// ----------------------------------------------------------------------------
// (c) Copyright 2000 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_TOKEN_JAVASCRIPT
#define IXLIB_TOKEN_JAVASCRIPT
#include <ixlib_token_lex.hh>
// keywords
#define TT_JS_THIS (TT_USER + 0)
#define TT_JS_FUNCTION (TT_USER + 1)
#define TT_JS_VAR (TT_USER + 2)
#define TT_JS_NULL (TT_USER + 3)
#define TT_JS_IF (TT_USER + 4)
#define TT_JS_WHILE (TT_USER + 5)
#define TT_JS_DO (TT_USER + 6)
#define TT_JS_ELSE (TT_USER + 7)
#define TT_JS_FOR (TT_USER + 8)
#define TT_JS_RETURN (TT_USER + 9)
#define TT_JS_SWITCH (TT_USER + 10)
#define TT_JS_CASE (TT_USER + 11)
#define TT_JS_CONTINUE (TT_USER + 12)
#define TT_JS_BREAK (TT_USER + 13)
#define TT_JS_DEFAULT (TT_USER + 14)
#define TT_JS_IN (TT_USER + 15)
#define TT_JS_CONST (TT_USER + 16)
#define TT_JS_CLASS (TT_USER + 17)
#define TT_JS_EXTENDS (TT_USER + 18)
#define TT_JS_NAMESPACE (TT_USER + 19)
#define TT_JS_STATIC (TT_USER + 20)
#define TT_JS_CONSTRUCTOR (TT_USER + 21)
// operators
#define TT_JS_NEW (TT_USER + 1024)
#define TT_JS_PLUS_ASSIGN (TT_USER + 1025)
#define TT_JS_MINUS_ASSIGN (TT_USER + 1026)
#define TT_JS_MULTIPLY_ASSIGN (TT_USER + 1027)
#define TT_JS_DIVIDE_ASSIGN (TT_USER + 1028)
#define TT_JS_MODULO_ASSIGN (TT_USER + 1029)
#define TT_JS_BIT_XOR_ASSIGN (TT_USER + 1030)
#define TT_JS_BIT_AND_ASSIGN (TT_USER + 1031)
#define TT_JS_BIT_OR_ASSIGN (TT_USER + 1032)
#define TT_JS_LEFT_SHIFT (TT_USER + 1033)
#define TT_JS_RIGHT_SHIFT (TT_USER + 1034)
#define TT_JS_LEFT_SHIFT_ASSIGN (TT_USER + 1035)
#define TT_JS_RIGHT_SHIFT_ASSIGN (TT_USER + 1036)
#define TT_JS_EQUAL (TT_USER + 1037)
#define TT_JS_NOT_EQUAL (TT_USER + 1038)
#define TT_JS_LESS_EQUAL (TT_USER + 1039)
#define TT_JS_GREATER_EQUAL (TT_USER + 1040)
#define TT_JS_LOGICAL_AND (TT_USER + 1041)
#define TT_JS_LOGICAL_OR (TT_USER + 1042)
#define TT_JS_INCREMENT (TT_USER + 1043)
#define TT_JS_DECREMENT (TT_USER + 1044)
#define TT_JS_IDENTICAL (TT_USER + 1045)
#define TT_JS_NOT_IDENTICAL (TT_USER + 1046)
// literals
#define TT_JS_LIT_INT (TT_USER + 2048)
#define TT_JS_LIT_FLOAT (TT_USER + 2049)
#define TT_JS_LIT_STRING (TT_USER + 2050)
#define TT_JS_LIT_TRUE (TT_USER + 2051)
#define TT_JS_LIT_FALSE (TT_USER + 2052)
#define TT_JS_LIT_UNDEFINED (TT_USER + 2053)
// identifier
#define TT_JS_IDENTIFIER (TT_USER + 3072)
#endif

View File

@@ -0,0 +1,25 @@
// ----------------------------------------------------------------------------
// Description : Basic definitions
// ----------------------------------------------------------------------------
// (c) Copyright 2000 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#ifndef IXLIB_TOKENLEX
#define IXLIB_TOKENLEX
// Basic token types
#define TT_EOF 1024
#define TT_UNKNOWN 1025
#define TT_WHITESPACE 1026
#define TT_USER 2048
#endif

View File

@@ -0,0 +1,201 @@
// ----------------------------------------------------------------------------
// Description : Javascript interpreter
// ----------------------------------------------------------------------------
// (c) Copyright 2000 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <ixlib_js_internals.hh>
using namespace ixion;
using namespace javascript;
// js_array -------------------------------------------------------------------
js_array::
js_array(TSize size) {
Array.resize(size);
ref<value> null = javascript::makeNull();
for (TIndex i = 0;i < size;i++)
Array[i] = makeLValue(null);
}
string js_array::stringify() const {
value_array::const_iterator first = Array.begin(),last = Array.end();
string result = "{ ";
bool at_first = true;
while (first != last) {
if (!at_first) result += ',';
else at_first = false;
result += (*first)->stringify();
first++;
}
return result + " }";
}
ref<javascript::value>
js_array::
duplicate() {
ref<value> result = new js_array(*this);
return result;
}
ref<javascript::value>
js_array::
lookup(string const &identifier) {
if (identifier == "length") return javascript::makeConstant(Array.size());
return super::lookup(identifier);
}
ref<javascript::value>
js_array::
subscript(value const &index) {
TIndex idx = index.toInt();
return operator[](idx);
}
ref<javascript::value>
js_array::
callMethod(string const &id,parameter_list const &parameters) {
if (id == "pop" && parameters.size() == 0) {
if (Array.size() == 0) return javascript::makeNull();
else {
ref<value> back = Array.back();
Array.pop_back();
return back;
}
}
else if (id == "push") {
FOREACH_CONST(first,parameters,parameter_list) {
Array.push_back((*first)->duplicate());
}
return javascript::makeConstant(Array.size());
}
else if (id == "reverse" && parameters.size() == 0) {
reverse(Array.begin(),Array.end());
return this;
}
else if (id == "shift" && parameters.size() == 0) {
if (Array.size() == 0) return javascript::makeNull();
else {
ref<value> front = Array.front();
Array.erase(Array.begin());
return front;
}
}
else if (id == "slice" && parameters.size() == 2) {
value_array::const_iterator first = Array.begin() + parameters[0]->toInt();
value_array::const_iterator last = Array.begin() + parameters[1]->toInt();
auto_ptr<js_array> array(new js_array(first,last));
return array.release();
}
else if (id == "unshift") {
TIndex i = 0;
FOREACH_CONST(first,parameters,parameter_list) {
Array.insert(Array.begin() + i++,(*first)->duplicate());
}
return javascript::makeConstant(Array.size());
}
else if (id == "join" && parameters.size() == 1) {
string sep = parameters[0]->toString();
string result;
for( TIndex i = 0; i < Array.size(); ++i ) {
if (i != 0)
result += sep;
result += Array[i]->toString();
}
return javascript::makeValue(result);
}
// *** FIXME: implement splice and sort
EXJS_THROWINFO(ECJS_UNKNOWN_IDENTIFIER,("Array."+id).c_str())
}
void js_array::resize(TSize size) {
if (size >= Array.size()) {
TSize prevsize = Array.size();
Array.resize(size);
ref<value> null = javascript::makeNull();
for (TIndex i = prevsize;i < size;i++)
Array[i] = makeLValue(null);
}
}
ref<value> &js_array::operator[](TIndex idx) {
if (idx >= Array.size())
resize((Array.size()+1)*2);
return Array[idx];
}
void js_array::push_back(ref<value> val) {
Array.push_back(val);
}
// js_array_constructor -------------------------------------------------------
ref<javascript::value> js_array_constructor::duplicate() {
// array_constructor is not mutable
return this;
}
ref<javascript::value>
js_array_constructor::
construct(parameter_list const &parameters) {
if (parameters.size() == 0) return makeArray();
else if (parameters.size() == 1) return makeArray(parameters[0]->toInt());
else /* parameters.size() >= 2 */ {
auto_ptr<js_array> result(new js_array(parameters.size()));
TIndex i = 0;
FOREACH_CONST(first,parameters,parameter_list) {
(*result)[i++] = (*first)->duplicate();
}
return result.release();
}
}

View File

@@ -0,0 +1,216 @@
// ----------------------------------------------------------------------------
// Description : Javascript interpreter
// ----------------------------------------------------------------------------
// (c) Copyright 2000 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <ixlib_js_internals.hh>
#include <ixlib_token_javascript.hh>
#define EXJS_ADD_CODE_LOCATION \
catch (no_location_javascript_exception &half) { \
throw javascript_exception(half,getCodeLocation()); \
}
using namespace ixion;
using namespace javascript;
// variable_declaration -------------------------------------------------------
variable_declaration::variable_declaration(string const &id,ref<expression> def_value,code_location const &loc)
: expression(loc),Identifier(id),DefaultValue(def_value) {
}
ref<value> variable_declaration::evaluate(context const &ctx) const {
try {
ref<value> def;
if (DefaultValue.get() != NULL) def = DefaultValue->evaluate(ctx)->eliminateWrappers()->duplicate();
else def = makeNull();
ref<value> lv = makeLValue(def);
ctx.DeclarationScope->addMember(Identifier,lv);
return lv;
}
EXJS_ADD_CODE_LOCATION
}
// constant_declaration -------------------------------------------------------
constant_declaration::constant_declaration(string const &id,ref<expression> def_value,code_location const &loc)
: expression(loc),Identifier(id),DefaultValue(def_value) {
}
ref<value> constant_declaration::evaluate(context const &ctx) const {
try {
ref<value> def;
if (DefaultValue.get() != NULL) def = DefaultValue->evaluate(ctx)->eliminateWrappers()->duplicate();
else def = makeNull();
ref<value> cns = wrapConstant(def);
ctx.DeclarationScope->addMember(Identifier,cns);
return cns;
}
EXJS_ADD_CODE_LOCATION
}
// function_declaration -------------------------------------------------------
function_declaration::
function_declaration(string const &id,parameter_name_list const &pnames,
ref<expression> body,code_location const &loc)
: expression(loc),Identifier(id),ParameterNameList(pnames),Body(body) {
}
ref<value> function_declaration::evaluate(context const &ctx) const {
try {
ref<value> fun = new function(ParameterNameList,Body,ctx.LookupScope);
ctx.DeclarationScope->addMember(Identifier,fun);
return ref<value>(NULL);
}
EXJS_ADD_CODE_LOCATION
}
// method_declaration ---------------------------------------------------------
method_declaration::
method_declaration(string const &id,parameter_name_list const &pnames,
ref<expression> body,code_location const &loc)
: expression(loc),Identifier(id),ParameterNameList(pnames),Body(body) {
}
ref<value> method_declaration::evaluate(context const &ctx) const {
try {
ref<value> fun = new method(ParameterNameList,Body,ctx.LookupScope);
ctx.DeclarationScope->addMember(Identifier,fun);
return ref<value>(NULL);
}
EXJS_ADD_CODE_LOCATION
}
// constructor_declaration ---------------------------------------------------------
constructor_declaration::
constructor_declaration(parameter_name_list const &pnames,
ref<expression> body,code_location const &loc)
: expression(loc),ParameterNameList(pnames),Body(body) {
}
ref<value> constructor_declaration::evaluate(context const &ctx) const {
try {
ref<value> fun = new constructor(ParameterNameList,Body,ctx.LookupScope);
return fun;
}
EXJS_ADD_CODE_LOCATION
}
// js_class_declaration -------------------------------------------------------
js_class_declaration::js_class_declaration(string const &id,ref<expression> superclass,code_location const &loc)
: expression(loc),Identifier(id),SuperClass(superclass) {
}
ref<value> js_class_declaration::evaluate(context const &ctx) const {
try {
ref<list_scope,value> sml(new list_scope);
ref<list_scope,value> ml(new list_scope);
ref<list_scope,value> svl(new list_scope);
ref<value> sc;
if (SuperClass.get())
sc = SuperClass->evaluate(ctx);
ref<value> constructor;
if (ConstructorDeclaration.get())
constructor = ConstructorDeclaration->evaluate(ctx);
ref<value> cls(new js_class(ctx.LookupScope,sc,constructor,sml,ml,svl,VariableList));
ref<list_scope,value> static_scope(new list_scope);
static_scope->unite(ctx.LookupScope);
static_scope->unite(cls);
FOREACH_CONST(first,StaticMethodList,declaration_list)
(*first)->evaluate(context(sml,static_scope));
FOREACH_CONST(first,MethodList,declaration_list)
(*first)->evaluate(context(ml,ctx.LookupScope));
FOREACH_CONST(first,StaticVariableList,declaration_list)
(*first)->evaluate(context(svl,static_scope));
ctx.DeclarationScope->addMember(Identifier,cls);
return cls;
}
EXJS_ADD_CODE_LOCATION
}
void js_class_declaration::setConstructor(ref<expression> decl) {
ConstructorDeclaration = decl;
}
void js_class_declaration::addStaticMethod(ref<expression> decl) {
StaticMethodList.push_back(decl);
}
void js_class_declaration::addMethod(ref<expression> decl) {
MethodList.push_back(decl);
}
void js_class_declaration::addStaticVariable(ref<expression> decl) {
StaticVariableList.push_back(decl);
}
void js_class_declaration::addVariable(ref<expression> decl) {
VariableList.push_back(decl);
}

View File

@@ -0,0 +1,310 @@
// ----------------------------------------------------------------------------
// Description : Javascript interpreter
// ----------------------------------------------------------------------------
// (c) Copyright 2000 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <ixlib_js_internals.hh>
#include <ixlib_token_javascript.hh>
#define EXJS_ADD_CODE_LOCATION \
catch (no_location_javascript_exception &half) { \
throw javascript_exception(half,getCodeLocation()); \
}
using namespace ixion;
using namespace javascript;
// expression -----------------------------------------------------------------
expression::expression(code_location const &loc)
: Location(loc) {
}
expression::~expression() {
}
// constant -------------------------------------------------------------------
constant::constant(ref<value> val,code_location const &loc)
: expression(loc),Value(val) {
}
ref<value>
constant::
evaluate(context const &ctx) const {
return Value;
}
// unary_operator -------------------------------------------------
unary_operator::unary_operator(value::operator_id opt,ref<expression> opn,code_location const &loc)
: expression(loc),Operator(opt),Operand(opn) {
}
ref<value>
unary_operator::
evaluate(context const &ctx) const {
try {
return Operand->evaluate(ctx)->operatorUnary(Operator);
}
EXJS_ADD_CODE_LOCATION
}
// modifying_unary_operator ---------------------------------------------------
modifying_unary_operator::
modifying_unary_operator(value::operator_id opt,ref<expression> opn,code_location const &loc)
: expression(loc),Operator(opt),Operand(opn) {
}
ref<value>
modifying_unary_operator::
evaluate(context const &ctx) const {
try {
return Operand->evaluate(ctx)->operatorUnaryModifying(Operator);
}
EXJS_ADD_CODE_LOCATION
}
// binary_operator ------------------------------------------------------------
binary_operator::binary_operator(value::operator_id opt,ref<expression> opn1,ref<expression> opn2,code_location const &loc)
: expression(loc),Operator(opt),Operand1(opn1),Operand2(opn2) {
}
ref<value> binary_operator::evaluate(context const &ctx) const {
try {
return Operand1->evaluate(ctx)->operatorBinary(Operator,Operand2->evaluate(ctx));
}
EXJS_ADD_CODE_LOCATION
}
// binary_shortcut_operator ---------------------------------------------------
binary_shortcut_operator::binary_shortcut_operator(value::operator_id opt,ref<expression> opn1,ref<expression> opn2,code_location const &loc)
: expression(loc),Operator(opt),Operand1(opn1),Operand2(opn2) {
}
ref<value> binary_shortcut_operator::evaluate(context const &ctx) const {
try {
return Operand1->evaluate(ctx)->operatorBinaryShortcut(Operator,*Operand2,ctx);
}
EXJS_ADD_CODE_LOCATION
}
// modifying_binary_operator --------------------------------------
modifying_binary_operator::
modifying_binary_operator(value::operator_id opt,ref<expression> opn1,ref<expression> opn2,code_location const &loc)
: expression(loc),Operator(opt),Operand1(opn1),Operand2(opn2) {
}
ref<value>
modifying_binary_operator::
evaluate(context const &ctx) const {
try {
return Operand1->evaluate(ctx)->operatorBinaryModifying(Operator,Operand2->evaluate(ctx));
}
EXJS_ADD_CODE_LOCATION
}
// ternary_operator -----------------------------------------------------------
ternary_operator::
ternary_operator(ref<expression> opn1,ref<expression> opn2,ref<expression> opn3,code_location const &loc)
: expression(loc),Operand1(opn1),Operand2(opn2),Operand3(opn3) {
}
ref<value>
ternary_operator::
evaluate(context const &ctx) const {
try {
if (Operand1->evaluate(ctx)->toBoolean())
return Operand2->evaluate(ctx);
else
return Operand3->evaluate(ctx);
}
EXJS_ADD_CODE_LOCATION
}
// subscript_operation --------------------------------------------------------
subscript_operation::subscript_operation(ref<expression> opn1,ref<expression> opn2,code_location const &loc)
: expression(loc),Operand1(opn1),Operand2(opn2) {
}
ref<value> subscript_operation::evaluate(context const &ctx) const {
try {
ref<value> op2 = Operand2->evaluate(ctx);
return Operand1->evaluate(ctx)->subscript(*op2);
}
EXJS_ADD_CODE_LOCATION
}
// lookup_operation -----------------------------------------------------------
lookup_operation::lookup_operation(string const &id,code_location const &loc)
: expression(loc),Identifier(id) {
}
lookup_operation::lookup_operation(ref<expression> opn,string const &id,code_location const &loc)
: expression(loc),Operand(opn),Identifier(id) {
}
ref<value> lookup_operation::evaluate(context const &ctx) const {
try {
ref<value> scope(ctx.LookupScope);
if (Operand.get() != NULL)
scope = Operand->evaluate(ctx);
return scope->lookup(Identifier);
}
EXJS_ADD_CODE_LOCATION
}
// assignment -----------------------------------------------------------------
assignment::
assignment(ref<expression> opn1,ref<expression> opn2,code_location const &loc)
: expression(loc),Operand1(opn1),Operand2(opn2) {
}
ref<value>
assignment::evaluate(context const &ctx) const {
try {
return Operand1->evaluate(ctx)->assign(Operand2->evaluate(ctx)->eliminateWrappers()->duplicate());
}
EXJS_ADD_CODE_LOCATION
}
// basic_call -----------------------------------------------------------------
basic_call::basic_call(parameter_expression_list const &pexps,code_location const &loc)
: expression(loc),ParameterExpressionList(pexps) {
}
void basic_call::makeParameterValueList(context const &ctx,parameter_value_list &pvalues) const {
FOREACH_CONST(first,ParameterExpressionList,parameter_expression_list) {
pvalues.push_back((*first)->evaluate(ctx));
}
}
// function_call --------------------------------------------------------------
function_call::function_call(ref<expression> fun,parameter_expression_list const &pexps,code_location const &loc)
: super(pexps,loc),Function(fun) {
}
ref<value> function_call::evaluate(context const &ctx) const {
try {
ref<value> func_value = Function->evaluate(ctx);
value::parameter_list pvalues;
makeParameterValueList(ctx,pvalues);
ref<value> result = func_value->call(pvalues);
if (result.get() == NULL) return makeNull();
else return result;
}
EXJS_ADD_CODE_LOCATION
}
// construction ---------------------------------------------------------------
construction::construction(ref<expression> cls,parameter_expression_list const &pexps,code_location const &loc)
: super(pexps,loc),Class(cls) {
}
ref<value> construction::evaluate(context const &ctx) const {
try {
ref<value> class_value = Class->evaluate(ctx);
value::parameter_list pvalues;
makeParameterValueList(ctx,pvalues);
return class_value->construct(pvalues);
}
EXJS_ADD_CODE_LOCATION
}

View File

@@ -0,0 +1,413 @@
// ----------------------------------------------------------------------------
// Description : Javascript interpreter
// ----------------------------------------------------------------------------
// (c) Copyright 2000 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <ixlib_js_internals.hh>
#include <ixlib_token_javascript.hh>
using namespace ixion;
using namespace javascript;
// instruction_list -----------------------------------------------------------
ref<value>
instruction_list::evaluate(context const &ctx) const {
ref<value> result;
FOREACH_CONST(first,ExpressionList,expression_list)
result = (*first)->evaluate(ctx);
return result;
}
void instruction_list::add(ref<expression> expr) {
ExpressionList.push_back(expr);
}
// scoped_instruction_list ----------------------------------------
ref<value> scoped_instruction_list::evaluate(context const &ctx) const {
ref<list_scope,value> scope = new list_scope;
scope->unite(ctx.LookupScope);
ref<value> result = instruction_list::evaluate(context(scope));
if (result.get()) return result->duplicate();
return ref<value>(NULL);
// ATTENTION: this is a scope cancellation point.
}
// js_if ----------------------------------------------------------------------
js_if::js_if(ref<expression> cond,ref<expression> ifex,ref<expression> ifnotex,code_location const &loc)
: expression(loc),Conditional(cond),IfExpression(ifex),IfNotExpression(ifnotex) {
}
ref<value> js_if::evaluate(context const &ctx) const {
if (Conditional->evaluate(ctx)->toBoolean())
return IfExpression->evaluate(ctx);
else
if (IfNotExpression.get())
return IfNotExpression->evaluate(ctx);
else
return ref<value>(NULL);
}
// js_while -------------------------------------------------------------------
js_while::js_while(ref<expression> cond,ref<expression> loopex,code_location const &loc)
: expression(loc),Conditional(cond),LoopExpression(loopex),HasLabel(false) {
}
js_while::js_while(ref<expression> cond,ref<expression> loopex,string const &label,code_location const &loc)
: expression(loc),Conditional(cond),LoopExpression(loopex),HasLabel(true),Label(label) {
}
ref<value> js_while::evaluate(context const &ctx) const {
ref<value> result;
while (Conditional->evaluate(ctx)->toBoolean()) {
try {
result = LoopExpression->evaluate(ctx);
}
catch (break_exception &be) {
if (!be.HasLabel || (HasLabel && be.HasLabel && be.Label == Label))
break;
else throw;
}
catch (continue_exception &ce) {
if (!ce.HasLabel || (HasLabel && ce.HasLabel && ce.Label == Label))
continue;
else throw;
}
}
return result;
}
// js_do_while ----------------------------------------------------------------
js_do_while::js_do_while(ref<expression> cond,ref<expression> loopex,code_location const &loc)
: expression(loc),Conditional(cond),LoopExpression(loopex),HasLabel(false) {
}
js_do_while::js_do_while(ref<expression> cond,ref<expression> loopex,string const &label,code_location const &loc)
: expression(loc),Conditional(cond),LoopExpression(loopex),HasLabel(true),Label(label) {
}
ref<value> js_do_while::evaluate(context const &ctx) const {
ref<value> result;
do {
try {
result = LoopExpression->evaluate(ctx);
}
catch (break_exception &be) {
if (!be.HasLabel || (HasLabel && be.HasLabel && be.Label == Label))
break;
else throw;
}
catch (continue_exception &ce) {
if (!ce.HasLabel || (HasLabel && ce.HasLabel && ce.Label == Label))
continue;
else throw;
}
} while (Conditional->evaluate(ctx)->toBoolean());
return result;
}
// js_for ---------------------------------------------------------------------
js_for::js_for(ref<expression> init,ref<expression> cond,ref<expression> update,ref<expression> loop,code_location const &loc)
: expression(loc),Initialization(init),Conditional(cond),Update(update),
LoopExpression(loop),HasLabel(false) {
}
js_for::js_for(ref<expression> init,ref<expression> cond,ref<expression> update,ref<expression> loop,string const &label,code_location const &loc)
: expression(loc),Initialization(init),Conditional(cond),Update(update),LoopExpression(loop),
HasLabel(true),Label(label) {
}
ref<value> js_for::evaluate(context const &ctx) const {
ref<list_scope,value> scope = new list_scope;
scope->unite(ctx.LookupScope);
context inner_context(scope);
ref<value> result;
for (Initialization->evaluate(inner_context);Conditional->evaluate(inner_context)->toBoolean();
Update->evaluate(inner_context)) {
try {
result = LoopExpression->evaluate(inner_context);
}
catch (break_exception &be) {
if (!be.HasLabel || (HasLabel && be.HasLabel && be.Label == Label))
break;
else throw;
}
catch (continue_exception &ce) {
if (!ce.HasLabel || (HasLabel && ce.HasLabel && ce.Label == Label))
continue;
else throw;
}
}
return result;
}
// js_for_in ------------------------------------------------------------------
js_for_in::js_for_in(ref<expression> iter,ref<expression> array,ref<expression> loop,code_location const &loc)
: expression(loc),Iterator(iter),Array(array),LoopExpression(loop),HasLabel(false) {
}
js_for_in::js_for_in(ref<expression> iter,ref<expression> array,ref<expression> loop,string const &label,code_location const &loc)
: expression(loc),Iterator(iter),Array(array),LoopExpression(loop),
HasLabel(true),Label(label) {
}
ref<value> js_for_in::evaluate(context const &ctx) const {
ref<list_scope,value> scope = new list_scope;
scope->unite(ctx.LookupScope);
context inner_context(scope);
ref<value> result;
ref<value> iterator = Iterator->evaluate(inner_context);
ref<value> array = Array->evaluate(inner_context);
TSize size = array->lookup("length")->toInt();
for (TIndex i = 0;i < size;i++) {
try {
iterator->assign(array->subscript(*makeConstant(i)));
result = LoopExpression->evaluate(inner_context);
}
catch (break_exception &be) {
if (!be.HasLabel || (HasLabel && be.HasLabel && be.Label == Label))
break;
else throw;
}
catch (continue_exception &ce) {
if (!ce.HasLabel || (HasLabel && ce.HasLabel && ce.Label == Label))
continue;
else throw;
}
}
if (result.get()) return result->duplicate();
return ref<value>(NULL);
// ATTENTION: this is a scope cancellation point.
}
// js_return ------------------------------------------------------------------
js_return::js_return(ref<expression> retval,code_location const &loc)
: expression(loc),ReturnValue(retval) {
}
ref<value> js_return::evaluate(context const &ctx) const {
ref<value> retval;
if (ReturnValue.get())
retval = ReturnValue->evaluate(ctx);
throw return_exception(retval,getCodeLocation());
}
// js_break -------------------------------------------------------------------
js_break::js_break(code_location const &loc)
: expression(loc),HasLabel(false) {
}
js_break::js_break(string const &label,code_location const &loc)
: expression(loc),HasLabel(true),Label(label) {
}
ref<value> js_break::evaluate(context const &ctx) const {
throw break_exception(HasLabel,Label,getCodeLocation());
}
// js_continue ----------------------------------------------------------------
js_continue::js_continue(code_location const &loc)
: expression(loc),HasLabel(false) {
}
js_continue::js_continue(string const &label,code_location const &loc)
: expression(loc),HasLabel(true),Label(label) {
}
ref<value> js_continue::evaluate(context const &ctx) const {
throw continue_exception(HasLabel,Label,getCodeLocation());
}
// break_label ----------------------------------------------------------------
break_label::break_label(string const &label,ref<expression> expr,code_location const &loc)
: expression(loc),Label(label),Expression(expr) {
}
ref<value>
break_label::evaluate(context const &ctx) const {
try {
return Expression->evaluate(ctx);
}
catch (break_exception &be) {
if (be.HasLabel && be.Label == Label) return ref<value>(NULL);
else throw;
}
}
// js_switch -----------------------------------------------------------------
js_switch::js_switch(ref<expression> discriminant,code_location const &loc)
: expression(loc),HasLabel(false),Discriminant(discriminant) {
}
js_switch::js_switch(ref<expression> discriminant,string const &label,code_location const &loc)
: expression(loc),HasLabel(true),Label(label),Discriminant(discriminant) {
}
ref<value>
js_switch::
evaluate(context const &ctx) const {
ref<list_scope,value> scope = new list_scope;
scope->unite(ctx.LookupScope);
context inner_context(scope);
ref<value> discr = Discriminant->evaluate(inner_context);
case_list::const_iterator expr,def;
bool expr_found = false,def_found = false;
FOREACH_CONST(first,CaseList,case_list) {
if (first->DiscriminantValue.get()) {
if (first->DiscriminantValue->evaluate(inner_context)->
operatorBinary(value::OP_EQUAL,Discriminant->evaluate(inner_context))->toBoolean()) {
expr = first;
expr_found = true;
break;
}
}
else {
if (!def_found) {
def = first;
def_found = true;
}
}
}
try {
case_list::const_iterator exec,last = CaseList.end();
if (expr_found)
exec = expr;
else if (def_found)
exec = def;
else
return ref<value>(NULL);
ref<value> result;
while (exec != last) {
result = exec->Expression->evaluate(inner_context);
exec++;
}
if (result.get()) return result->duplicate();
return ref<value>(NULL);
}
catch (break_exception &be) {
if (!be.HasLabel || (HasLabel && be.HasLabel && be.Label == Label))
return ref<value>(NULL);
else
throw;
}
// ATTENTION: this is a scope cancellation point.
}
void js_switch::addCase(ref<expression> dvalue,ref<expression> expr) {
case_label cl;
cl.DiscriminantValue = dvalue;
cl.Expression = expr;
CaseList.push_back(cl);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,259 @@
// ----------------------------------------------------------------------------
// Description : Javascript interpreter library
// ----------------------------------------------------------------------------
// (c) Copyright 2000 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <ixlib_js_internals.hh>
#include <ixlib_numconv.hh>
#include <ixlib_random.hh>
using namespace ixion;
using namespace javascript;
namespace {
class eval : public value {
protected:
interpreter &Interpreter;
public:
value_type getType() const {
return VT_FUNCTION;
}
eval(interpreter &interpreter)
: Interpreter(interpreter) {
}
ref<value> call(parameter_list const &parameters);
};
class Math : public value_with_methods {
private:
typedef value_with_methods super;
protected:
float_random RNG;
public:
value_type getType() const {
return VT_BUILTIN;
}
ref<value> duplicate() const;
ref<value> lookup(string const &identifier);
ref<value> callMethod(string const &identifier,parameter_list const &parameters);
};
}
// eval -----------------------------------------------------------------------
ref<value>
eval::
call(parameter_list const &parameters) {
if (parameters.size() != 1) {
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,"eval")
}
if (parameters[0]->getType() != VT_STRING) return parameters[0];
return Interpreter.execute(parameters[0]->toString());
}
// parseInt -------------------------------------------------------------------
IXLIB_JS_DECLARE_FUNCTION(parseInt) {
if (parameters.size() != 1 && parameters.size() != 2) {
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,"parseInt")
}
unsigned radix = 10;
if (parameters.size() == 2)
radix = parameters[1]->toInt();
return makeConstant(evalSigned(parameters[0]->toString(),radix));
}
// parseFloat -----------------------------------------------------------------
IXLIB_JS_DECLARE_FUNCTION(parseFloat) {
if (parameters.size() != 1) {
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,"parseFloat")
}
return makeConstant(evalFloat(parameters[0]->toString()));
}
// isNaN ----------------------------------------------------------------------
#ifdef ADVANCED_MATH_AVAILABLE
IXLIB_JS_DECLARE_FUNCTION(isNaN) {
if (parameters.size() != 1) {
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,"isNaN")
}
int classification = fpclassify(parameters[0]->toFloat());
return makeConstant(classification == FP_NAN);
}
#endif
// isFinite -------------------------------------------------------------------
#ifdef ADVANCED_MATH_AVAILABLE
IXLIB_JS_DECLARE_FUNCTION(isFinite) {
if (parameters.size() != 1) {
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,"isFinite")
}
int classification = fpclassify(parameters[0]->toFloat());
return makeConstant(classification != FP_NAN && classification != FP_INFINITE);
}
#endif
// Math -----------------------------------------------------------------------
ref<value> Math::duplicate() const {
// Math is not mutable
return const_cast<Math *>(this);
}
ref<value> Math::lookup(string const &identifier) {
#define MATH_CONSTANT(NAME,VALUE) \
if (identifier == NAME) return makeConstant(VALUE);
MATH_CONSTANT("E",2.7182818284590452354)
MATH_CONSTANT("LN10",2.30258509299404568402)
MATH_CONSTANT("LN2",0.69314718055994530942)
MATH_CONSTANT("LOG2E",1.4426950408889634074)
MATH_CONSTANT("LOG10E,",0.43429448190325182765)
MATH_CONSTANT("PI",3.14159265358979323846)
MATH_CONSTANT("SQRT1_2",0.70710678118654752440)
MATH_CONSTANT("SQRT2",1.41421356237309504880)
return super::lookup(identifier);
}
ref<value> Math::callMethod(string const &identifier,parameter_list const &parameters) {
#define MATH_FUNCTION(NAME,C_NAME) \
if (identifier == NAME) { \
if (parameters.size() != 1) { \
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,"Math." NAME) \
} \
return makeConstant(C_NAME(parameters[0]->toFloat())); \
}
MATH_FUNCTION("abs",NUM_ABS)
MATH_FUNCTION("acos",acos)
MATH_FUNCTION("asin",asin)
MATH_FUNCTION("atan",atan)
MATH_FUNCTION("ceil",ceil)
MATH_FUNCTION("cos",cos)
MATH_FUNCTION("exp",exp)
MATH_FUNCTION("floor",floor)
MATH_FUNCTION("log",log)
#ifdef ADVANCED_MATH_AVAILABLE
MATH_FUNCTION("round",round)
#endif
MATH_FUNCTION("sin",sin)
MATH_FUNCTION("sqrt",sqrt)
MATH_FUNCTION("tan",tan)
if (identifier == "atan2") {
if (parameters.size() != 2) {
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,"Math.atan2")
}
return makeConstant(atan2(parameters[0]->toFloat(),parameters[1]->toFloat()));
}
if (identifier == "pow") {
if (parameters.size() != 2) {
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,"Math.pow")
}
return makeConstant(pow(parameters[0]->toFloat(),parameters[1]->toFloat()));
}
if (identifier == "random") {
if (parameters.size() != 0) {
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,"Math.random")
}
return makeConstant(RNG());
}
// *** FIXME this is non-compliant, but there is no equivalent standard function
if (identifier == "initRandom") {
if (parameters.size() >= 2) {
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS,"Math.initRandom")
}
if (parameters.size() == 0)
RNG.init();
else if (parameters.size() == 1)
RNG.init(parameters[0]->toFloat());
return makeNull();
}
// *** FIXME: implement max, min
EXJS_THROWINFO(ECJS_UNKNOWN_IDENTIFIER,("Math." + identifier).c_str())
}
// external interface functions -----------------------------------------------
#define ADD_GLOBAL_OBJECT(NAME,TYPE) \
{ ref<value> x = new TYPE(); \
ip.RootScope->addMember(NAME,x); \
}
void javascript::addGlobal(interpreter &ip) {
ref<value> ev = new eval(ip);
ip.RootScope->addMember("eval",ev);
ADD_GLOBAL_OBJECT("parseInt",parseInt)
ADD_GLOBAL_OBJECT("parseFloat",parseFloat)
#ifdef ADVANCED_MATH_AVAILABLE
ADD_GLOBAL_OBJECT("isNaN",isNaN)
ADD_GLOBAL_OBJECT("isFinite",isFinite)
#endif
// *** FIXME hope this is portable
float zero = 0;
ip.RootScope->addMember("NaN",makeConstant(0.0/zero));
ip.RootScope->addMember("Infinity",makeConstant(1.0/zero));
ip.RootScope->addMember("undefined",makeUndefined());
}
void javascript::addMath(interpreter &ip) {
ADD_GLOBAL_OBJECT("Math",Math)
}
void javascript::addStandardLibrary(interpreter &ip) {
addGlobal(ip);
addMath(ip);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
/* -------- definitions ------- */
%option c++ yylineno noyywrap prefix="js" outfile="lex.javascript.cc" batch
%{
#include <ixlib_js_internals.hh>
#include <ixlib_token_javascript.hh>
using namespace ixion;
using namespace javascript;
%}
WHITESPACE [ \t\n\r]
DIGIT [0-9]
DIGIT_NZ [1-9]
DIGIT_OCT [0-7]
DIGIT_HEX [0-9a-fA-F]
DIGIT_SEQ {DIGIT}+
NONDIGIT [_a-zA-Z]
ID_COMPONENT [_a-zA-Z0-9]
ESCAPE_SIMPLE \\['"?\\abfnrtv]
ESCAPE_OCTAL \\{DIGIT_OCT}{1,3}
ESCAPE_HEX \\x{DIGIT_HEX}{1,2}
ESCAPE {ESCAPE_SIMPLE}|{ESCAPE_OCTAL}|{ESCAPE_HEX}
S_CHAR [^"\\\n]|{ESCAPE}
SIGN \+|\-
SIGNopt {SIGN}?
/* higher-level entities ------------------------------------------------------
*/
IDENTIFIER {NONDIGIT}{ID_COMPONENT}*
/* literals -------------------------------------------------------------------
*/
LIT_DECIMAL {DIGIT_NZ}{DIGIT}*
LIT_OCTAL 0{DIGIT_OCT}*
LIT_HEX 0[xX]{DIGIT_HEX}+
LIT_INT ({LIT_DECIMAL}|{LIT_OCTAL}|{LIT_HEX})
LIT_STRING \"{S_CHAR}*\"|\'{S_CHAR}*\'
LIT_FRACTION {DIGIT_SEQ}?\.{DIGIT_SEQ}|{DIGIT_SEQ}\.
LIT_EXPONENT [eE]{SIGNopt}{DIGIT_SEQ}
LIT_FLOAT {LIT_FRACTION}{LIT_EXPONENT}?|{DIGIT_SEQ}{LIT_EXPONENT}
/* Contexts -------------------------------------------------------------------
*/
%x Comment
%x LineComment
/* Rules ----------------------------------------------------------------------
*/
%%
\/\* BEGIN(Comment);
<Comment>\*\/ BEGIN(INITIAL);
<Comment><<EOF>> EXJS_THROW(ECJS_UNTERMINATED_COMMENT)
<Comment>. /* nothing */
<Comment>\n /* nothing */
\/\/ BEGIN(LineComment);
<LineComment>[\n\r]+ BEGIN(INITIAL);
<LineComment>. /* nothing */
<<EOF>> return TT_EOF;
\{ return '{';
\} return '}';
\; return ';';
\[ return '[';
\] return ']';
\( return '(';
\) return ')';
\? return '?';
\: return ':';
\+ return '+';
\- return '-';
\* return '*';
\/ return '/';
\% return '%';
\^ return '^';
\& return '&';
\| return '|';
\~ return '~';
\! return '!';
\= return '=';
\< return '<';
\> return '>';
\, return ',';
\. return '.';
\+\= return TT_JS_PLUS_ASSIGN;
\-\= return TT_JS_MINUS_ASSIGN;
\*\= return TT_JS_MULTIPLY_ASSIGN;
\/\= return TT_JS_DIVIDE_ASSIGN;
\%\= return TT_JS_MODULO_ASSIGN;
\^\= return TT_JS_BIT_XOR_ASSIGN;
\&\= return TT_JS_BIT_AND_ASSIGN;
\|\= return TT_JS_BIT_OR_ASSIGN;
\<\< return TT_JS_LEFT_SHIFT;
\>\> return TT_JS_RIGHT_SHIFT;
\<\<\= return TT_JS_LEFT_SHIFT_ASSIGN;
\>\>\= return TT_JS_RIGHT_SHIFT_ASSIGN;
\=\=\= return TT_JS_IDENTICAL;
\!\=\= return TT_JS_NOT_IDENTICAL;
\=\= return TT_JS_EQUAL;
\!\= return TT_JS_NOT_EQUAL;
\<\= return TT_JS_LESS_EQUAL;
\>\= return TT_JS_GREATER_EQUAL;
\&\& return TT_JS_LOGICAL_AND;
\|\| return TT_JS_LOGICAL_OR;
\+\+ return TT_JS_INCREMENT;
\-\- return TT_JS_DECREMENT;
new return TT_JS_NEW;
this return TT_JS_THIS;
function return TT_JS_FUNCTION;
var return TT_JS_VAR;
null return TT_JS_NULL;
if return TT_JS_IF;
while return TT_JS_WHILE;
do return TT_JS_DO;
else return TT_JS_ELSE;
for return TT_JS_FOR;
return return TT_JS_RETURN;
switch return TT_JS_SWITCH;
case return TT_JS_CASE;
continue return TT_JS_CONTINUE;
break return TT_JS_BREAK;
default return TT_JS_DEFAULT;
true return TT_JS_LIT_TRUE;
false return TT_JS_LIT_FALSE;
undefined return TT_JS_LIT_UNDEFINED;
in return TT_JS_IN;
const return TT_JS_CONST;
class return TT_JS_CLASS;
extends return TT_JS_EXTENDS;
namespace return TT_JS_NAMESPACE;
static return TT_JS_STATIC;
constructor return TT_JS_CONSTRUCTOR;
{LIT_INT} return TT_JS_LIT_INT;
{LIT_FLOAT} return TT_JS_LIT_FLOAT;
{LIT_STRING} return TT_JS_LIT_STRING;
{IDENTIFIER} return TT_JS_IDENTIFIER;
{WHITESPACE}+ /* nothing */
. EXJS_THROWINFOLOCATION(ECJS_INVALID_TOKEN,YYText(),code_location(lineno()))

View File

@@ -0,0 +1,41 @@
#include <ixlib_js_internals.hh>
#include <ixlib_exbase.hh>
#include <ixlib_javascript.hh>
#include <fstream>
using namespace ixion;
using namespace ixion::javascript;
IXLIB_JS_DECLARE_FUNCTION(write)
{
if (parameters.size() != 1) {
EXJS_THROWINFO(ECJS_INVALID_NUMBER_OF_ARGUMENTS, "write");
}
std::cout << parameters[0]->toString();
return makeConstant(parameters[0]->toString());
}
int main (int ac, char ** av) {
interpreter *jsint = new interpreter();
addStandardLibrary(*jsint);
ref<value> x = new write();
jsint->RootScope->addMember("write", x);
if (ac == 1) {
std::cerr << "Usage: " << av[0] << "<file+>" << std::endl;
exit(1);
}
for (int i = 1; i < ac; i++) {
std::ifstream input(av[i]);
try {
ref<value> result = jsint->execute(input);
std::cout << av[i] << " returned " << result->stringify() << std::endl;
} catch (base_exception &ex) {
std::cerr << ex.getText() << ex.what() << std::endl;
}
input.close();
}
delete jsint;
}

View File

@@ -0,0 +1,144 @@
// ----------------------------------------------------------------------------
// Description : Numeric conversions
// ----------------------------------------------------------------------------
// (c) Copyright 1999 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <ixlib_exgen.hh>
#include <ixlib_numconv.hh>
#include <stdio.h>
using namespace std;
using namespace ixion;
// data objects --------------------------------------------------------------
static string numChars = IXLIB_NUMCHARS;
// exported subroutines -------------------------------------------------------
string ixion::float2dec(double value) {
char buf[255];
sprintf((char *)&buf,"%f",value);
return string(buf);
}
string ixion::float2dec(double value, unsigned int precision) {
char buf[255];
string cmd("%.");
cmd += unsigned2dec(precision) + "f";
sprintf((char *)&buf,cmd.c_str(),value);
return string(buf);
}
string ixion::unsigned2base(unsigned long value,char digits,char radix) {
string temp;
do {
temp = numChars[value % radix]+temp;
value /= radix;
if (digits) digits--;
} while (value || digits);
return temp;
}
string ixion::signed2base(signed long value,char digits,char radix) {
if (value < 0) return "-"+unsigned2base(-value,digits,radix);
else return unsigned2base(value,digits,radix);
}
string ixion::bytes2dec(TSize bytes) {
if (bytes>(TSize) 10*1024*1024)
return unsigned2dec(bytes / ((TSize) 1024*1024))+" MB";
if (bytes>(TSize) 10*1024)
return unsigned2dec(bytes / ((TSize) 1024))+" KB";
return unsigned2dec(bytes)+" Byte";
}
unsigned long ixion::evalNumeral(string const &numeral,unsigned radix) {
string numstr = upper(numeral);
if (numstr.size() == 0) return 0;
unsigned long value = 0, mulvalue = 1;
TIndex index = numstr.size()-1;
do {
string::size_type digvalue = numChars.find(numstr[index]);
if (digvalue == string::npos)
EXGEN_THROWINFO(EC_CANNOTEVALUATE,numstr.c_str())
value += mulvalue * digvalue;
mulvalue *= radix;
} while (index--);
return value;
}
double ixion::evalFloat(string const &numeral) {
double result;
int count = sscanf(numeral.c_str(), "%le", &result);
if (count == 0) EXGEN_THROWINFO(EC_CANNOTEVALUATE,numeral.c_str())
else return result;
}
unsigned long ixion::evalUnsigned(string const &numeral,unsigned default_base) {
if (numeral.size() == 0) return 0;
if (numeral.substr(0,2) == "0X" || numeral.substr(0,2) == "0x")
return evalNumeral(numeral.substr(2),0x10);
if (numeral.substr(0,1) == "$")
return evalNumeral(numeral.substr(1),0x10);
char lastchar = numeral[numeral.size()-1];
if (lastchar == 'H' || lastchar == 'h') return evalNumeral(numeral.substr(0,numeral.size()-1),0x10);
if (lastchar == 'B' || lastchar == 'b') return evalNumeral(numeral.substr(0,numeral.size()-1),2);
if (lastchar == 'D' || lastchar == 'd') return evalNumeral(numeral.substr(0,numeral.size()-1),10);
if (lastchar == 'O' || lastchar == 'o') return evalNumeral(numeral.substr(0,numeral.size()-1),8);
return evalNumeral(numeral,default_base);
}
signed long ixion::evalSigned(string const &numeral,unsigned default_base) {
if (numeral.size() == 0) return 0;
if (numeral[0] == '-')
return - (signed long) evalUnsigned(numeral.substr(1),default_base);
else {
if (numeral[0] == '+')
return evalUnsigned(numeral.substr(1),default_base);
else
return evalUnsigned(numeral,default_base);
}
}

View File

@@ -0,0 +1,38 @@
// ----------------------------------------------------------------------------
// Description : Numeric / order processing
// ----------------------------------------------------------------------------
// (c) Copyright 1998 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <ixlib_numeric.hh>
// BCD encoding ---------------------------------------------------------------
unsigned long ixion::unsigned2BCD(unsigned long value)
{
unsigned long bcdvalue = 0,bcdshift = 0;
while (value) {
bcdvalue += (value % 10) << bcdshift;
bcdshift += 4;
value /= 10;
}
return bcdvalue;
}
unsigned long ixion::BCD2unsigned(unsigned long value)
{
unsigned long decvalue = 0;
for (unsigned long i = 1;value;i *= 10) {
decvalue += (value & 0xf) * i;
value >>= 4;
}
return decvalue;
}

427
simgear/interpreter/re.cc Normal file
View File

@@ -0,0 +1,427 @@
// ----------------------------------------------------------------------------
// Description : Regular expressions string object.
// ----------------------------------------------------------------------------
// (c) Copyright 1998 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <stack>
#include <cctype>
#include "ixlib_i18n.hh"
#include <ixlib_exgen.hh>
#include <ixlib_numeric.hh>
#include <ixlib_numconv.hh>
#include <ixlib_re.hh>
#include <ixlib_re_impl.hh>
using namespace std;
using namespace ixion;
// Template instantiations ----------------------------------------------------
template regex<string>;
// Error texts ----------------------------------------------------------------
static char *RegexPlainText[] = {
N_("Invalid quantifier"),
N_("Unbalanced backreference"),
N_("Invalid escape sequence"),
N_("Invalid backreference"),
N_("Unterminated character class"),
N_("Unable to match without expression"),
};
// regex_exception ------------------------------------------------------------
regex_exception::regex_exception(TErrorCode error,
char const *info,char *module,TIndex line)
: base_exception(error,info,module,line,"RE") {
}
char *regex_exception::getText() const {
return _(RegexPlainText[Error]);
}
// regex_string::class_matcher ------------------------------------------------
regex_string::class_matcher::class_matcher()
: Negated(false) {
MatchLength = 1;
}
regex_string::class_matcher::class_matcher(string const &cls)
: Negated(false) {
MatchLength = 1;
if (cls.size() && cls[0] == XSTRRE_CLASSNEG) {
expandClass(cls.substr(1));
Negated = true;
}
else
expandClass(cls);
}
ixion::regex<string>::matcher *ixion::regex_string::class_matcher::duplicate() const {
class_matcher *dupe = new class_matcher();
dupe->copy(this);
return dupe;
}
bool regex_string::class_matcher::match(backref_stack &brstack,string const &candidate,TIndex at) {
if (at >= candidate.size()) return false;
bool result = Set[candidate[at]];
if (Negated) result = !result;
return result && matchNext(brstack,candidate,at+1);
}
void regex_string::class_matcher::expandClass(string const &cls) {
memset(&Set,0,sizeof(Set));
if (cls.size() == 0) return;
Set[cls[0]] = true;
char lastchar = cls[0];
for (TIndex index = 1;index < cls.size();index++) {
if ((cls[index] == XSTRRE_CLASSRANGE) && (index < cls.size()-1)) {
for (char ch = lastchar+1;ch < cls[index+1];ch++)
Set[ch] = true;
}
else Set[cls[index]] = true;
lastchar = cls[index];
}
}
void ixion::regex_string::class_matcher::copy(class_matcher const *src) {
super::copy(src);
for (TIndex i = 0;i < CharValues;i++)
Set[i] = src->Set[i];
Negated = src->Negated;
}
// regex_string::special_class_matcher ----------------------------------------
regex_string::special_class_matcher::special_class_matcher(type tp)
: Type(tp) {
MatchLength = 1;
}
ixion::regex<string>::matcher *ixion::regex_string::special_class_matcher::duplicate() const {
special_class_matcher *dupe = new special_class_matcher(Type);
dupe->copy(this);
return dupe;
}
bool regex_string::special_class_matcher::match(backref_stack &brstack,string const &candidate,TIndex at) {
if (at >= candidate.size()) return false;
enum type { DIGIT,NONDIGIT,ALNUM,NONALNUM,SPACE,NONSPACE };
bool result;
switch (Type) {
case DIGIT: result = isdigit(candidate[at]);
break;
case NONDIGIT: result = !isdigit(candidate[at]);
break;
case ALNUM: result = isalnum(candidate[at]);
break;
case NONALNUM: result = !isalnum(candidate[at]);
break;
case SPACE: result = isspace(candidate[at]);
break;
case NONSPACE: result = !isspace(candidate[at]);
break;
default:
EX_THROW(regex,ECRE_INVESCAPE)
}
return result && matchNext(brstack,candidate,at+1);
}
// regex_string ---------------------------------------------------------------
void regex_string::parse(string const &expr) {
auto_ptr<matcher> new_re(parseRegex(expr));
ParsedRegex = new_re;
}
string regex_string::replaceAll(string const &candidate,string const &replacement,TIndex from) {
string result;
string tempreplacement;
LastCandidate = candidate;
if (ParsedRegex.get() == NULL)
EX_THROW(regex,ECRE_NOPATTERN)
for (TIndex index = from;index < candidate.size();) {
BackrefStack.clear();
if (ParsedRegex->match(BackrefStack,candidate,index)) {
TIndex matchlength = ParsedRegex->subsequentMatchLength();
tempreplacement = replacement;
TSize backrefs = BackrefStack.size();
for (TIndex i = 0;i < backrefs;i++)
tempreplacement = findReplace(tempreplacement,XSTRRE_BACKREF+unsigned2dec(i),
BackrefStack.get(i,LastCandidate));
result += tempreplacement;
index += matchlength;
}
else result += candidate[index++];
}
return result;
}
regex_string::matcher *regex_string::parseRegex(string const &expr) {
if (!expr.size()) return NULL;
TIndex index = 0;
matcher *firstobject,*lastobject = NULL;
alternative_matcher *alternative = NULL;
while (index < expr.size()) {
matcher *object = NULL;
quantifier *quantifier = NULL;
bool quantified = true;
char ch;
// several objects may be inserted in one loop run
switch (expr[index++]) {
// case XSTRRE_BACKREF: (dupe)
// case XSTRRE_ESCAPESEQ: (dupe)
case XSTRRE_LITERAL: {
if (index >= expr.size()) EX_THROW(regex,ECRE_INVESCAPE)
ch = expr[index++];
if (isdigit(ch))
object = new backref_matcher(ch-'0');
else {
switch (ch) {
case 'd': object = new special_class_matcher(special_class_matcher::DIGIT);
break;
case 'D': object = new special_class_matcher(special_class_matcher::NONDIGIT);
break;
case 'w': object = new special_class_matcher(special_class_matcher::ALNUM);
break;
case 'W': object = new special_class_matcher(special_class_matcher::NONALNUM);
break;
case 's': object = new special_class_matcher(special_class_matcher::SPACE);
break;
case 'S': object = new special_class_matcher(special_class_matcher::NONSPACE);
break;
default: object = new sequence_matcher(string(1,ch));
}
}
break;
}
case XSTRRE_ANYCHAR:
object = new any_matcher;
break;
case XSTRRE_START:
quantified = false;
object = new start_matcher;
break;
case XSTRRE_END:
quantified = false;
object = new end_matcher;
break;
case XSTRRE_ALTERNATIVE: {
if (!alternative)
alternative = new alternative_matcher;
alternative->addAlternative(firstobject);
firstobject = NULL;
lastobject = NULL;
break;
}
case XSTRRE_CLASSSTART: {
TIndex classend = expr.find(XSTRRE_CLASSSTOP,index);
if (classend == string::npos)
EX_THROW(regex,ECRE_UNTERMCLASS)
object = new class_matcher(expr.substr(index,classend-index));
index = classend+1;
break;
}
case XSTRRE_BACKREFSTART: {
matcher *parsed;
TSize brlevel = 1;
for (TIndex searchstop = index;searchstop < expr.size();searchstop++) {
if ((expr[searchstop] == XSTRRE_BACKREFSTART) &&
(expr[searchstop-1] != XSTRRE_LITERAL))
brlevel++;
if ((expr[searchstop] == XSTRRE_BACKREFSTOP) &&
(expr[searchstop-1] != XSTRRE_LITERAL)) {
brlevel--;
if (brlevel == 0) {
parsed = parseRegex(expr.substr(index,searchstop-index));
if (!parsed) EX_THROW(regex,ECRE_INVBACKREF)
index = searchstop+1;
break;
}
}
}
if (!parsed) EX_THROW(regex,ECRE_UNBALBACKREF)
object = new backref_open_matcher;
object->setNext(parsed);
matcher *closer = new backref_close_matcher;
matcher *searchlast = parsed,*foundlast;
while (searchlast) {
foundlast = searchlast;
searchlast = searchlast->getNext();
}
foundlast->setNext(closer);
break;
}
case XSTRRE_BACKREFSTOP:
EX_THROW(regex,ECRE_UNBALBACKREF)
default:
object = new sequence_matcher(expr.substr(index-1,1));
break;
}
if (object) {
if (quantified) quantifier = parseQuantifier(expr,index);
if (quantifier) {
quantifier->setQuantified(object);
if (lastobject) lastobject->setNext(quantifier);
else firstobject = quantifier;
}
else {
if (lastobject) lastobject->setNext(object);
else firstobject = object;
}
}
// we need this for the alternative matcher, which also inserts
// its connector
matcher *searchlast = quantifier ? quantifier : object;
while (searchlast) {
lastobject = searchlast;
searchlast = searchlast->getNext();
}
}
if (alternative) {
alternative->addAlternative(firstobject);
return alternative;
}
else return firstobject;
}
regex_string::quantifier *regex_string::parseQuantifier(string const &expr,TIndex &at) {
quantifier *quant = NULL;
if (at == expr.size()) return NULL;
if (expr[at] == XSTRREQ_0PLUS) {
quant = new quantifier(isGreedy(expr,++at),0);
return quant;
}
if (expr[at] == XSTRREQ_1PLUS) {
quant = new quantifier(isGreedy(expr,++at),1);
return quant;
}
if (expr[at] == XSTRREQ_01) {
quant = new quantifier(isGreedy(expr,++at),0,1);
return quant;
}
if (expr[at] == XSTRREQ_START) {
TSize min,max;
at++;
TIndex endindex;
endindex = expr.find(XSTRREQ_STOP,at);
if (endindex == string::npos)
EXGEN_THROW(ECRE_INVQUANTIFIER)
string quantspec = expr.substr(at,endindex-at);
at = endindex+1;
try {
string::size_type rangeindex = quantspec.find(XSTRREQ_RANGE);
if (rangeindex == string::npos) {
min = evalUnsigned(quantspec);
quant = new quantifier(isGreedy(expr,at),min,min);
}
else if (rangeindex == quantspec.size()-1) {
min = evalUnsigned(quantspec.substr(0,rangeindex));
quant = new quantifier(isGreedy(expr,at),min);
}
else {
min = evalUnsigned(quantspec.substr(0,rangeindex));
max = evalUnsigned(quantspec.substr(rangeindex+1));
quant = new quantifier(isGreedy(expr,at),min,max);
}
return quant;
}
EX_CONVERT(generic,EC_CANNOTEVALUATE,regex,ECRE_INVQUANTIFIER)
}
return NULL;
}
bool regex_string::isGreedy(string const &expr,TIndex &at)
{
if (at == expr.size()) return true;
if (expr[at] == XSTRREQ_NONGREEDY) {
at++;
return false;
}
else return true;
}

View File

@@ -0,0 +1,108 @@
// ----------------------------------------------------------------------------
// Description : Scanner for xTextFile
// ----------------------------------------------------------------------------
// (c) Copyright 1999 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <FlexLexer.h>
#include "ixlib_i18n.hh"
#include <ixlib_numconv.hh>
#include <ixlib_token_lex.hh>
#include <ixlib_scanner.hh>
using namespace std;
using namespace ixion;
// Plain text rendering table -------------------------------------------------
static char *(PlainText[]) = {
N_("Unknown token"),
N_("End of input")
};
// scanner_exception ----------------------------------------------------------
scanner_exception::scanner_exception(TErrorCode error, TIndex line,
string const &info)
: base_exception(error, NULL, NULL, 0, "SCAN") {
HasInfo = true;
try {
string temp = "line ";
temp += unsigned2dec(line);
if (info != "") {
temp += " : ";
temp += info;
}
strcpy(Info, temp.c_str());
}
catch (...) { }
}
char *scanner_exception::getText() const {
return PlainText[Error];
}
// scanner --------------------------------------------------------------------
scanner::scanner(FlexLexer &lexer)
: Lexer(lexer) {
}
scanner::token_list scanner::scan() {
CurrentToken.Type = Lexer.yylex();
CurrentToken.Line = Lexer.lineno();
CurrentToken.Text = Lexer.YYText();
token_list tokenlist;
while (!reachedEOF()) {
tokenlist.push_back(getNextToken());
}
return tokenlist;
}
scanner::token scanner::getNextToken() {
if (!reachedEOF()) {
token lasttoken = CurrentToken;
CurrentToken.Type = Lexer.yylex();
CurrentToken.Line = Lexer.lineno();
CurrentToken.Text = Lexer.YYText();
if (CurrentToken.Type == TT_UNKNOWN)
throw scanner_exception(ECSCAN_UNKNOWN_TOKEN,CurrentToken.Line,CurrentToken.Text);
else return lasttoken;
}
throw scanner_exception(ECSCAN_UNKNOWN_TOKEN, CurrentToken.Line, "");
}
bool scanner::reachedEOF() const {
return (CurrentToken.Type == TT_EOF);
}

View File

@@ -0,0 +1,317 @@
// ----------------------------------------------------------------------------
// Description : String object
// ----------------------------------------------------------------------------
// (c) Copyright 1999 by iXiONmedia, all rights reserved.
// ----------------------------------------------------------------------------
#include <cstring>
#include <cctype>
#include <ixlib_numconv.hh>
#include <ixlib_string.hh>
using namespace std;
using namespace ixion;
// String utility functions ---------------------------------------------------
string ixion::findReplace(string const &target,string const &src,string const &dest) {
string result = target;
TIndex foundpos = string::npos;
TIndex n = src.size();
while ((foundpos = result.find(src)) != string::npos)
result.replace(foundpos,n,dest);
return result;
}
string ixion::findReplace(string const &target,char* src,char *dest) {
string result = target;
TSize foundpos = string::npos;
TSize n = strlen(src);
while ((foundpos = result.find(src)) != string::npos)
result.replace(foundpos,n,dest);
return result;
}
string ixion::findReplace(string const &target,char src,char dest) {
string result = target;
string::iterator first = result.begin(),last = result.end();
while (first != last) {
if (*first == src) *first = dest;
first++;
}
return result;
}
string ixion::upper(string const &original) {
string temp(original);
string::iterator first = temp.begin(),last = temp.end();
while (first != last) {
*first = toupper(*first);
first++;
}
return temp;
}
string ixion::lower(string const &original) {
string temp(original);
string::iterator first = temp.begin(),last = temp.end();
while (first != last) {
*first = tolower(*first);
first++;
}
return temp;
}
string ixion::removeLeading(string const &original,char ch) {
string copy(original);
string::iterator first = copy.begin(), last = copy.end();
while (first != last && *first == ch) first++;
if (first != copy.begin()) copy.erase(copy.begin(),first);
return copy;
}
string ixion::removeTrailing(string const &original,char ch) {
string copy(original);
string::iterator first = copy.begin(), last = copy.end();
if (first != last) {
last--;
while (first != last && *last == ch) last--;
if (*last != ch) last++;
}
if (last != copy.end()) copy.erase(last,copy.end());
return copy;
}
string ixion::removeLeadingTrailing(string const &original,char ch) {
string copy(original);
string::iterator first = copy.begin(), last = copy.end();
while (first != last && *first == ch) first++;
if (first != copy.begin()) copy.erase(copy.begin(),first);
first = copy.begin();
last = copy.end();
if (first != last) {
last--;
while (first != last && *last == ch) last--;
if (*last != ch) last++;
}
if (last != copy.end()) copy.erase(last,copy.end());
return copy;
}
string ixion::parseCEscapes(string const &original) {
string result = "";
string::const_iterator first = original.begin(),last = original.end();
while (first != last) {
if (*first == '\\') {
first++;
if (first == last) {
result += '\\';
break;
}
#define GET_TEMP_STRING(LENGTH) \
if (original.end()-first < LENGTH) \
EXGEN_THROWINFO(EC_INVALIDPAR,"invalid escape sequence") \
tempstring = string(first,first+LENGTH); \
first += LENGTH;
char value;
string tempstring;
switch (*first) {
case 'b': result += '\b'; first++; break;
case 'f': result += '\f'; first++; break;
case 'n': result += '\n'; first++; break;
case 't': result += '\t'; first++; break;
case 'v': result += '\v'; first++; break;
case 'X':
case 'x': first++;
GET_TEMP_STRING(2)
value = evalNumeral(tempstring,16);
result += value;
break;
case 'u': first++;
GET_TEMP_STRING(4)
value = evalNumeral(tempstring,16);
result += value;
break;
case '0':
GET_TEMP_STRING(3)
value = evalNumeral(tempstring,8);
result += value;
break;
default: result += *first++;
}
}
else result += *first++;
}
return result;
}
namespace {
TByte const B64_INVALID = 0xff;
TByte const B64_PAD = 0xfe;
char const B64_PAD_CHAR = '=';
char Base64EncodeTable[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
TByte Base64DecodeTable[] = { // based at 0
// see test/invertmap.js on how to generate this table
B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,
B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,
B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,
B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,
B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,
B64_INVALID,B64_INVALID,B64_INVALID,62,B64_INVALID,B64_INVALID,B64_INVALID,63,52,53,54,
55,56,57,58,59,60,61,B64_INVALID,B64_INVALID,B64_INVALID,B64_PAD,B64_INVALID,
B64_INVALID,B64_INVALID,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
19,20,21,22,23,24,25,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,
B64_INVALID,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,
44,45,46,47,48,49,50,51,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,B64_INVALID,
};
}
TSize ixion::getMaxBase64DecodedSize(TSize encoded) {
return ((encoded+3)/4)*3;
}
TSize ixion::base64decode(TByte *data,string const &base64) {
string::const_iterator first = base64.begin(),last = base64.end();
TByte *data_start = data;
TUnsigned32 block;
TByte a,b,c,d;
while (first != last) {
a = Base64DecodeTable[*(first++)];
b = Base64DecodeTable[*(first++)];
c = Base64DecodeTable[*(first++)];
d = Base64DecodeTable[*(first++)];
if (c == B64_PAD) {
block = a << 3*6 | b << 2*6;
*data++ = (block >> 16) & 0xff;
}
else if (d == B64_PAD) {
block = a << 3*6 | b << 2*6 | c << 1*6;
*data++ = (block >> 16) & 0xff;
*data++ = (block >> 8) & 0xff;
}
else {
block = a << 3*6 | b << 2*6 | c << 1*6 | d << 0*6;
*data++ = (block >> 16) & 0xff;
*data++ = (block >> 8) & 0xff;
*data++ = (block >> 0) & 0xff;
}
}
return data-data_start;
}
void ixion::base64encode(string &base64,TByte const *data,TSize size) {
base64.resize((size+2)/3*4);
TUnsigned32 block;
TByte a,b,c,d;
TByte const *end = data+size;
string::iterator first = base64.begin();
while (data < end)
if (data+1 == end) {
block = data[0] << 16;
a = (block >> 3*6) & 0x3f;
b = (block >> 2*6) & 0x3f;
*first++ = Base64EncodeTable[a];
*first++ = Base64EncodeTable[b];
*first++ = B64_PAD_CHAR;
*first++ = B64_PAD_CHAR;
data++;
}
else if (data+2 == end) {
block = data[0] << 16 | data[1] << 8;
a = (block >> 3*6) & 0x3f;
b = (block >> 2*6) & 0x3f;
c = (block >> 1*6) & 0x3f;
*first++ = Base64EncodeTable[a];
*first++ = Base64EncodeTable[b];
*first++ = Base64EncodeTable[c];
*first++ = B64_PAD_CHAR;
data += 2;
}
else {
block = data[0] << 16 | data[1] << 8 | data[2];
a = (block >> 3*6) & 0x3f;
b = (block >> 2*6) & 0x3f;
c = (block >> 1*6) & 0x3f;
d = (block >> 0*6) & 0x3f;
*first++ = Base64EncodeTable[a];
*first++ = Base64EncodeTable[b];
*first++ = Base64EncodeTable[c];
*first++ = Base64EncodeTable[d];
data += 3;
}
}
// string_hash ----------------------------------------------------------------
unsigned long ixion::string_hash::operator()(string const &str) const {
// the sgi stl uses the same hash algorithm
unsigned long h = 0;
FOREACH_CONST(first,str,string)
h = 5*h + *first;
return h;
}

8
simgear/io/.cvsignore Normal file
View File

@@ -0,0 +1,8 @@
.deps
Makefile
Makefile.in
decode_binobj
lowtest
socktest
tcp_client
tcp_server

View File

@@ -8,7 +8,8 @@ include_HEADERS = \
sg_binobj.hxx \
sg_file.hxx \
sg_serial.hxx \
sg_socket.hxx
sg_socket.hxx \
sg_socket_udp.hxx
libsgio_a_SOURCES = \
iochannel.cxx \
@@ -16,11 +17,38 @@ libsgio_a_SOURCES = \
sg_binobj.cxx \
sg_file.cxx \
sg_serial.cxx \
sg_socket.cxx
sg_socket.cxx \
sg_socket_udp.cxx
INCLUDES += -I$(top_srcdir)
INCLUDES = -I$(top_srcdir)
noinst_PROGRAMS = decode_binobj socktest lowtest
if IS_MINGW
NETWORK_LIB = -lwsock32
else
NETWORK_LIB =
endif
noinst_PROGRAMS = decode_binobj socktest lowtest tcp_server tcp_client
tcp_server_SOURCES = tcp_server.cxx
tcp_server_LDADD = \
$(top_builddir)/simgear/io/libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/xml/libsgxml.a \
-lplibnet -lplibul -lz $(NETWORK_LIB)
tcp_client_SOURCES = tcp_client.cxx
tcp_client_LDADD = \
$(top_builddir)/simgear/io/libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/xml/libsgxml.a \
-lplibnet -lplibul -lz $(NETWORK_LIB)
socktest_SOURCES = socktest.cxx
@@ -29,7 +57,8 @@ socktest_LDADD = \
$(top_builddir)/simgear/io/libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
-lz
$(top_builddir)/simgear/xml/libsgxml.a \
-lplibnet -lplibul -lz $(NETWORK_LIB)
lowtest_SOURCES = lowtest.cxx
@@ -43,4 +72,5 @@ decode_binobj_LDADD = \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
-lz
$(top_builddir)/simgear/xml/libsgxml.a \
-lz

View File

@@ -58,25 +58,49 @@ int main( int argc, char **argv ) {
}
cout << endl;
cout << "# triangle groups" << endl;
cout << "# geometry groups" << endl;
cout << endl;
string material;
int_list vertex_index;
int_list normal_index;
int_list tex_index;
// generate points
string_list pt_materials = obj.get_pt_materials();
group_list pts_v = obj.get_pts_v();
group_list pts_n = obj.get_pts_n();
for ( i = 0; i < (int)pts_v.size(); ++i ) {
material = pt_materials[i];
vertex_index = pts_v[i];
normal_index = pts_n[i];
cout << "# usemtl " << material << endl;
cout << "pt ";
for ( j = 0; j < (int)vertex_index.size(); ++j ) {
cout << vertex_index[j] << "/" << normal_index[j] << " ";
}
cout << endl;
}
// generate triangles
string_list tri_materials = obj.get_tri_materials();
group_list tris_v = obj.get_tris_v();
group_list tris_n = obj.get_tris_n();
group_list tris_tc = obj.get_tris_tc();
for ( i = 0; i < (int)tris_v.size(); ++i ) {
material = tri_materials[i];
vertex_index = tris_v[i];
normal_index = tris_n[i];
tex_index = tris_tc[i];
cout << "# usemtl " << material << endl;
cout << "f ";
for ( j = 0; j < (int)vertex_index.size(); ++j ) {
cout << vertex_index[j] << "/" << tex_index[j] << " ";
cout << vertex_index[j];
if ( normal_index.size() ) {
cout << "/" << normal_index[j];
}
cout << "/" << tex_index[j];
cout << " ";
}
cout << endl;
}
@@ -84,15 +108,21 @@ int main( int argc, char **argv ) {
// generate strips
string_list strip_materials = obj.get_strip_materials();
group_list strips_v = obj.get_strips_v();
group_list strips_n = obj.get_strips_n();
group_list strips_tc = obj.get_strips_tc();
for ( i = 0; i < (int)strips_v.size(); ++i ) {
material = strip_materials[i];
vertex_index = strips_v[i];
normal_index = strips_n[i];
tex_index = strips_tc[i];
cout << "# usemtl " << material << endl;
cout << "ts ";
for ( j = 0; j < (int)vertex_index.size(); ++j ) {
cout << vertex_index[j] << "/" << tex_index[j] << " ";
cout << vertex_index[j];
if ( normal_index.size() ) {
cout << "/" << normal_index[j];
}
cout << "/" << tex_index[j] << " ";
}
cout << endl;
}
@@ -100,15 +130,21 @@ int main( int argc, char **argv ) {
// generate fans
string_list fan_materials = obj.get_fan_materials();
group_list fans_v = obj.get_fans_v();
group_list fans_n = obj.get_fans_n();
group_list fans_tc = obj.get_fans_tc();
for ( i = 0; i < (int)fans_v.size(); ++i ) {
material = fan_materials[i];
vertex_index = fans_v[i];
normal_index = fans_n[i];
tex_index = fans_tc[i];
cout << "# usemtl " << material << endl;
cout << "tf ";
for ( j = 0; j < (int)vertex_index.size(); ++j ) {
cout << vertex_index[j] << "/" << tex_index[j] << " ";
cout << vertex_index[j];
if ( normal_index.size() ) {
cout << "/" << normal_index[j];
}
cout << "/" << tex_index[j] << " ";
}
cout << endl;
}

View File

@@ -22,8 +22,6 @@
#include "iochannel.hxx"
// #include "garmin.hxx"
// #include "nmea.hxx"
// constructor

View File

@@ -158,6 +158,7 @@ public:
inline void set_dir( const SGProtocolDir d ) { dir = d; }
inline SGProtocolDir get_dir() const { return dir; }
inline bool isvalid() const { return valid; }
inline void set_valid( const bool v ) { valid = v; }
};

View File

@@ -23,6 +23,8 @@
// $Id$
#include <string.h> // for memcpy()
#include "lowlevel.hxx"

View File

@@ -29,12 +29,7 @@
#include <stdio.h>
#ifdef HAVE_ZLIB
# include <zlib.h>
#else
# include <simgear/zlib/zlib.h>
#endif
#include <zlib.h>
#include <plib/sg.h>

View File

@@ -23,6 +23,8 @@ int main() {
}
cout << "endian" << endl;
cout << "sizeof(short) = " << sizeof(short) << endl;
short s = 1111;
cout << "short s = " << s << endl;
sgEndianSwap((unsigned short *)&s);

View File

@@ -49,17 +49,29 @@ enum {
SG_BOUNDING_SPHERE = 0,
SG_VERTEX_LIST = 1,
SG_COLOR_LIST = 4,
SG_NORMAL_LIST = 2,
SG_TEXCOORD_LIST = 3,
SG_POINTS = 9,
SG_TRIANGLE_FACES = 10,
SG_TRIANGLE_STRIPS = 11,
SG_TRIANGLE_FANS = 12
} tgObjectTypes;
} sgObjectTypes;
enum {
SG_MATERIAL = 0
} tgPropertyTypes;
SG_IDX_VERTICES = 0x01,
SG_IDX_NORMALS = 0x02,
SG_IDX_COLORS = 0x04,
SG_IDX_TEXCOORDS = 0x08
} sgIndexTypes;
enum {
SG_MATERIAL = 0,
SG_INDEX_TYPES = 1
} sgPropertyTypes;
class sgSimpleBuffer {
@@ -145,11 +157,131 @@ double sgCalcBoundingRadius( Point3D center, point_list& wgs84_nodes ) {
}
// read object properties
static void read_object( gzFile fp,
int obj_type,
int nproperties,
int nelements,
group_list *vertices,
group_list *normals,
group_list *colors,
group_list *texcoords,
string_list *materials )
{
unsigned int nbytes;
unsigned char idx_mask;
int idx_size;
bool do_vertices, do_normals, do_colors, do_texcoords;
int j, k, idx;
static sgSimpleBuffer buf( 32768 ); // 32 Kb
char material[256];
// default values
if ( obj_type == SG_POINTS ) {
idx_size = 1;
idx_mask = SG_IDX_VERTICES;
do_vertices = true;
do_normals = false;
do_colors = false;
do_texcoords = false;
} else {
idx_size = 2;
idx_mask = (char)(SG_IDX_VERTICES | SG_IDX_TEXCOORDS);
do_vertices = true;
do_normals = false;
do_colors = false;
do_texcoords = true;
}
for ( j = 0; j < nproperties; ++j ) {
char prop_type;
sgReadChar( fp, &prop_type );
sgReadUInt( fp, &nbytes );
// cout << "property size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
if ( prop_type == SG_MATERIAL ) {
strncpy( material, ptr, nbytes );
material[nbytes] = '\0';
// cout << "material type = " << material << endl;
} else if ( prop_type == SG_INDEX_TYPES ) {
idx_mask = ptr[0];
// cout << "idx_mask = " << (int)idx_mask << endl;
idx_size = 0;
do_vertices = false;
do_normals = false;
do_colors = false;
do_texcoords = false;
if ( idx_mask & SG_IDX_VERTICES ) {
do_vertices = true;
++idx_size;
}
if ( idx_mask & SG_IDX_NORMALS ) {
do_normals = true;
++idx_size;
}
if ( idx_mask & SG_IDX_COLORS ) {
do_colors = true;
++idx_size;
}
if ( idx_mask & SG_IDX_TEXCOORDS ) {
do_texcoords = true;
++idx_size;
}
}
}
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
// cout << "element size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (idx_size * sizeof(short));
short *sptr = (short *)ptr;
int_list vs; vs.clear();
int_list ns; ns.clear();
int_list cs; cs.clear();
int_list tcs; tcs.clear();
for ( k = 0; k < count; ++k ) {
if ( sgIsBigEndian() ) {
for ( idx = 0; idx < idx_size; ++idx ) {
sgEndianSwap( (unsigned short *)&(sptr[idx]) );
}
}
idx = 0;
if ( do_vertices ) {
vs.push_back( sptr[idx++] );
}
if ( do_normals ) {
ns.push_back( sptr[idx++] );
}
if ( do_colors ) {
cs.push_back( sptr[idx++] );
}
if ( do_texcoords ) {
tcs.push_back( sptr[idx++] );
}
// cout << sptr[0] << " ";
sptr += idx_size;
}
// cout << endl;
vertices->push_back( vs );
normals->push_back( ns );
colors->push_back( cs );
texcoords->push_back( tcs );
materials->push_back( material );
}
}
// read a binary file and populate the provided structures.
bool SGBinObject::read_bin( const string& file ) {
Point3D p;
int i, j, k;
char material[256];
unsigned int nbytes;
static sgSimpleBuffer buf( 32768 ); // 32 Kb
@@ -161,24 +293,36 @@ bool SGBinObject::read_bin( const string& file ) {
normals.clear();
texcoords.clear();
pts_v.clear();
pts_n.clear();
pts_c.clear();
pts_tc.clear();
pt_materials.clear();
tris_v.clear();
tris_n.clear();
tris_c.clear();
tris_tc.clear();
tri_materials.clear();
strips_v.clear();
strips_n.clear();
strips_c.clear();
strips_tc.clear();
strip_materials.clear();
fans_v.clear();
fans_n.clear();
fans_c.clear();
fans_tc.clear();
fan_materials.clear();
gzFile fp;
if ( (fp = gzopen( file.c_str(), "rb" )) == NULL ) {
string filegz = file + ".gz";
if ( (fp = gzopen( filegz.c_str(), "rb" )) == NULL ) {
// cout << "ERROR: opening " << file << " or " << filegz
// << "for reading!" << endl;
cout << "ERROR: opening " << file << " or " << filegz
<< "for reading!" << endl;
return false;
}
@@ -203,13 +347,21 @@ bool SGBinObject::read_bin( const string& file ) {
}
// read creation time
time_t calendar_time;
sgReadLong( fp, &calendar_time );
unsigned int foo_calendar_time;
sgReadUInt( fp, &foo_calendar_time );
#if 0
time_t calendar_time = foo_calendar_time;
// The following code has a global effect on the host application
// and can screws up the time elsewhere. It should be avoided
// unless you need this for debugging in which case you should
// disable it again once the debugging task is finished.
struct tm *local_tm;
local_tm = localtime( &calendar_time );
char time_str[256];
strftime( time_str, 256, "%a %b %d %H:%M:%S %Z %Y", local_tm);
// cout << "File created on " << time_str << endl;
cout << "File created on " << time_str << endl;
#endif
// read number of top level objects
short nobjects;
@@ -288,18 +440,51 @@ bool SGBinObject::read_bin( const string& file ) {
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(float) * 3);
float *fptr = (float *)ptr;
wgs84_nodes.reserve( count );
for ( k = 0; k < count; ++k ) {
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int *)&(fptr[0]) );
sgEndianSwap( (unsigned int *)&(fptr[1]) );
sgEndianSwap( (unsigned int *)&(fptr[2]) );
}
p = Point3D( fptr[0], fptr[1], fptr[2] );
// cout << "node = " << p << endl;
wgs84_nodes.push_back( p );
wgs84_nodes.push_back( Point3D(fptr[0], fptr[1], fptr[2]) );
fptr += 3;
}
}
} else if ( obj_type == SG_COLOR_LIST ) {
// read color list properties
for ( j = 0; j < nproperties; ++j ) {
char prop_type;
sgReadChar( fp, &prop_type );
sgReadUInt( fp, &nbytes );
// cout << "property size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
}
// read color list elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
// cout << "element size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(float) * 4);
float *fptr = (float *)ptr;
colors.reserve(count);
for ( k = 0; k < count; ++k ) {
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int *)&(fptr[0]) );
sgEndianSwap( (unsigned int *)&(fptr[1]) );
sgEndianSwap( (unsigned int *)&(fptr[2]) );
sgEndianSwap( (unsigned int *)&(fptr[3]) );
}
colors.push_back( Point3D( fptr[0], fptr[1], fptr[2] ) );
fptr += 4;
}
}
} else if ( obj_type == SG_NORMAL_LIST ) {
// read normal list properties
for ( j = 0; j < nproperties; ++j ) {
@@ -321,6 +506,7 @@ bool SGBinObject::read_bin( const string& file ) {
unsigned char *ptr = (unsigned char *)(buf.get_ptr());
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / 3;
normals.reserve( count );
for ( k = 0; k < count; ++k ) {
sgdVec3 normal;
sgdSetVec3( normal,
@@ -329,9 +515,7 @@ bool SGBinObject::read_bin( const string& file ) {
(ptr[2]) / 127.5 - 1.0 );
sgdNormalizeVec3( normal );
p = Point3D( normal[0], normal[1], normal[2] );
// cout << "normal = " << p << endl;
normals.push_back( p );
normals.push_back(Point3D(normal[0], normal[1], normal[2]));
ptr += 3;
}
}
@@ -357,149 +541,33 @@ bool SGBinObject::read_bin( const string& file ) {
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(float) * 2);
float *fptr = (float *)ptr;
texcoords.reserve(count);
for ( k = 0; k < count; ++k ) {
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int *)&(fptr[0]) );
sgEndianSwap( (unsigned int *)&(fptr[1]) );
}
p = Point3D( fptr[0], fptr[1], 0 );
// cout << "texcoord = " << p << endl;
texcoords.push_back( p );
texcoords.push_back( Point3D( fptr[0], fptr[1], 0 ) );
fptr += 2;
}
}
} else if ( obj_type == SG_POINTS ) {
// read point elements
read_object( fp, SG_POINTS, nproperties, nelements,
&pts_v, &pts_n, &pts_c, &pts_tc, &pt_materials );
} else if ( obj_type == SG_TRIANGLE_FACES ) {
// read triangle face properties
for ( j = 0; j < nproperties; ++j ) {
char prop_type;
sgReadChar( fp, &prop_type );
sgReadUInt( fp, &nbytes );
// cout << "property size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
if ( prop_type == SG_MATERIAL ) {
strncpy( material, ptr, nbytes );
material[nbytes] = '\0';
// cout << "material type = " << material << endl;
}
}
// read triangle face elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
// cout << "element size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(short) * 2);
short *sptr = (short *)ptr;
int_list vs, tcs;
vs.clear(); tcs.clear();
for ( k = 0; k < count; ++k ) {
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned short *)&(sptr[0]) );
sgEndianSwap( (unsigned short *)&(sptr[1]) );
}
vs.push_back( sptr[0] );
tcs.push_back( sptr[1] );
// cout << sptr[0] << "/" << sptr[1] << " ";
sptr += 2;
}
// cout << endl;
tris_v.push_back( vs );
tris_tc.push_back( tcs );
tri_materials.push_back( material );
}
read_object( fp, SG_TRIANGLE_FACES, nproperties, nelements,
&tris_v, &tris_n, &tris_c, &tris_tc, &tri_materials );
} else if ( obj_type == SG_TRIANGLE_STRIPS ) {
// read triangle strip properties
for ( j = 0; j < nproperties; ++j ) {
char prop_type;
sgReadChar( fp, &prop_type );
sgReadUInt( fp, &nbytes );
// cout << "property size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
if ( prop_type == SG_MATERIAL ) {
strncpy( material, ptr, nbytes );
material[nbytes] = '\0';
// cout << "material type = " << material << endl;
}
}
// read triangle strip elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
// cout << "element size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(short) * 2);
short *sptr = (short *)ptr;
int_list vs, tcs;
vs.clear(); tcs.clear();
for ( k = 0; k < count; ++k ) {
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned short *)&(sptr[0]) );
sgEndianSwap( (unsigned short *)&(sptr[1]) );
}
vs.push_back( sptr[0] );
tcs.push_back( sptr[1] );
// cout << sptr[0] << "/" << sptr[1] << " ";
sptr += 2;
}
// cout << endl;
strips_v.push_back( vs );
strips_tc.push_back( tcs );
strip_materials.push_back( material );
}
read_object( fp, SG_TRIANGLE_STRIPS, nproperties, nelements,
&strips_v, &strips_n, &strips_c, &strips_tc,
&strip_materials );
} else if ( obj_type == SG_TRIANGLE_FANS ) {
// read triangle fan properties
for ( j = 0; j < nproperties; ++j ) {
char prop_type;
sgReadChar( fp, &prop_type );
sgReadUInt( fp, &nbytes );
// cout << "property size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
if ( prop_type == SG_MATERIAL ) {
strncpy( material, ptr, nbytes );
material[nbytes] = '\0';
// cout << "material type = " << material << endl;
}
}
// read triangle fan elements
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
// cout << "element size = " << nbytes << endl;
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (sizeof(short) * 2);
short *sptr = (short *)ptr;
int_list vs, tcs;
vs.clear(); tcs.clear();
for ( k = 0; k < count; ++k ) {
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned short *)&(sptr[0]) );
sgEndianSwap( (unsigned short *)&(sptr[1]) );
}
vs.push_back( sptr[0] );
tcs.push_back( sptr[1] );
// cout << sptr[0] << "/" << sptr[1] << " ";
sptr += 2;
}
// cout << endl;
fans_v.push_back( vs );
fans_tc.push_back( tcs );
fan_materials.push_back( material );
}
read_object( fp, SG_TRIANGLE_FANS, nproperties, nelements,
&fans_v, &fans_n, &fans_c, &fans_tc, &fan_materials );
} else {
// unknown object type, just skip
@@ -547,11 +615,14 @@ bool SGBinObject::write_bin( const string& base, const string& name,
Point3D p;
sgVec2 t;
sgVec3 pt;
sgVec4 color;
int i, j;
unsigned char idx_mask;
int idx_size;
string dir = base + "/" + b.gen_base_path();
string command = "mkdir -p " + dir;
#ifdef _MSC_VER
#if defined(_MSC_VER) || defined(__MINGW32__)
system( (string("mkdir ") + dir).c_str() );
#else
system(command.c_str());
@@ -568,6 +639,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
sgClearWriteError();
cout << "points size = " << pts_v.size() << " pt_materials = "
<< pt_materials.size() << endl;
cout << "triangles size = " << tris_v.size() << " tri_materials = "
<< tri_materials.size() << endl;
cout << "strips size = " << strips_v.size() << " strip_materials = "
@@ -575,7 +648,9 @@ bool SGBinObject::write_bin( const string& base, const string& name,
cout << "fans size = " << fans_v.size() << " fan_materials = "
<< fan_materials.size() << endl;
cout << "points = " << wgs84_nodes.size() << endl;
cout << "nodes = " << wgs84_nodes.size() << endl;
cout << "colors = " << colors.size() << endl;
cout << "normals = " << normals.size() << endl;
cout << "tex coords = " << texcoords.size() << endl;
// write header magic
@@ -590,9 +665,24 @@ bool SGBinObject::write_bin( const string& base, const string& name,
short nobjects = 0;
nobjects++; // for gbs
nobjects++; // for vertices
nobjects++; // for colors
nobjects++; // for normals
nobjects++; // for texcoords
// points
short npts = 0;
start = 0; end = 1;
while ( start < (int)pt_materials.size() ) {
material = pt_materials[start];
while ( (end < (int)pt_materials.size()) &&
(material == pt_materials[end]) ) {
end++;
}
npts++;
start = end; end = start + 1;
}
nobjects += npts;
// tris
short ntris = 0;
start = 0; end = 1;
@@ -660,6 +750,20 @@ bool SGBinObject::write_bin( const string& base, const string& name,
sgWriteVec3( fp, pt );
}
// dump vertex color list
sgWriteChar( fp, (char)SG_COLOR_LIST ); // type
sgWriteShort( fp, 0 ); // nproperties
sgWriteShort( fp, 1 ); // nelements
sgWriteUInt( fp, colors.size() * sizeof(float) * 4 ); // nbytes
for ( i = 0; i < (int)colors.size(); ++i ) {
p = colors[i];
// Right now we have a place holder for color alpha but we
// need to update the interface so the calling program can
// provide the info.
sgSetVec4( color, p.x(), p.y(), p.z(), 1.0 );
sgWriteVec4( fp, color );
}
// dump vertex normal list
sgWriteChar( fp, (char)SG_NORMAL_LIST ); // type
sgWriteShort( fp, 0 ); // nproperties
@@ -685,6 +789,66 @@ bool SGBinObject::write_bin( const string& base, const string& name,
sgWriteVec2( fp, t );
}
// dump point groups if they exist
if ( pts_v.size() > 0 ) {
int start = 0;
int end = 1;
string material;
while ( start < (int)pt_materials.size() ) {
// find next group
material = pt_materials[start];
while ( (end < (int)pt_materials.size()) &&
(material == pt_materials[end]) )
{
// cout << "end = " << end << endl;
end++;
}
// cout << "group = " << start << " to " << end - 1 << endl;
// write group headers
sgWriteChar( fp, (char)SG_POINTS ); // type
sgWriteShort( fp, 2 ); // nproperties
sgWriteShort( fp, end - start ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes
sgWriteBytes( fp, material.length(), material.c_str() );
idx_mask = 0;
idx_size = 0;
if ( pts_v.size() ) { idx_mask |= SG_IDX_VERTICES; ++idx_size; }
if ( pts_n.size() ) { idx_mask |= SG_IDX_NORMALS; ++idx_size; }
if ( pts_c.size() ) { idx_mask |= SG_IDX_COLORS; ++idx_size; }
if ( pts_tc.size() ) { idx_mask |= SG_IDX_TEXCOORDS; ++idx_size; }
sgWriteChar( fp, (char)SG_INDEX_TYPES ); // property
sgWriteUInt( fp, 1 ); // nbytes
sgWriteChar( fp, idx_mask );
// write strips
for ( i = start; i < end; ++i ) {
// nbytes
sgWriteUInt( fp, pts_v[i].size() * idx_size * sizeof(short) );
for ( j = 0; j < (int)pts_v[i].size(); ++j ) {
if ( pts_v.size() ) {
sgWriteShort( fp, (short)pts_v[i][j] );
}
if ( pts_n.size() ) {
sgWriteShort( fp, (short)pts_n[i][j] );
}
if ( pts_c.size() ) {
sgWriteShort( fp, (short)pts_c[i][j] );
}
if ( pts_tc.size() ) {
sgWriteShort( fp, (short)pts_tc[i][j] );
}
}
}
start = end;
end = start + 1;
}
}
// dump individual triangles if they exist
if ( tris_v.size() > 0 ) {
int start = 0;
@@ -703,20 +867,41 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write group headers
sgWriteChar( fp, (char)SG_TRIANGLE_FACES ); // type
sgWriteShort( fp, 1 ); // nproperties
sgWriteShort( fp, 2 ); // nproperties
sgWriteShort( fp, 1 ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes
sgWriteBytes( fp, material.length(), material.c_str() );
sgWriteUInt( fp, (end - start) * 3 * 2 * sizeof(short) ); // nbytes
idx_mask = 0;
idx_size = 0;
if ( tris_v.size() ) { idx_mask |= SG_IDX_VERTICES; ++idx_size; }
if ( tris_n.size() ) { idx_mask |= SG_IDX_NORMALS; ++idx_size; }
if ( tris_c.size() ) { idx_mask |= SG_IDX_COLORS; ++idx_size; }
if ( tris_tc.size() ) { idx_mask |= SG_IDX_TEXCOORDS; ++idx_size; }
sgWriteChar( fp, (char)SG_INDEX_TYPES ); // property
sgWriteUInt( fp, 1 ); // nbytes
sgWriteChar( fp, idx_mask );
// nbytes
sgWriteUInt( fp, (end - start) * 3 * idx_size * sizeof(short) );
// write group
for ( i = start; i < end; ++i ) {
for ( j = 0; j < 3; ++j ) {
sgWriteShort( fp, (short)tris_v[i][j] );
sgWriteShort( fp, (short)tris_tc[i][j] );
if ( tris_v.size() ) {
sgWriteShort( fp, (short)tris_v[i][j] );
}
if ( tris_n.size() ) {
sgWriteShort( fp, (short)tris_n[i][j] );
}
if ( tris_c.size() ) {
sgWriteShort( fp, (short)tris_c[i][j] );
}
if ( tris_tc.size() ) {
sgWriteShort( fp, (short)tris_tc[i][j] );
}
}
}
@@ -743,20 +928,40 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write group headers
sgWriteChar( fp, (char)SG_TRIANGLE_STRIPS ); // type
sgWriteShort( fp, 1 ); // nproperties
sgWriteShort( fp, 2 ); // nproperties
sgWriteShort( fp, end - start ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes
sgWriteBytes( fp, material.length(), material.c_str() );
idx_mask = 0;
idx_size = 0;
if ( strips_v.size() ) { idx_mask |= SG_IDX_VERTICES; ++idx_size; }
if ( strips_n.size() ) { idx_mask |= SG_IDX_NORMALS; ++idx_size; }
if ( strips_c.size() ) { idx_mask |= SG_IDX_COLORS; ++idx_size; }
if ( strips_tc.size() ) { idx_mask |= SG_IDX_TEXCOORDS; ++idx_size;}
sgWriteChar( fp, (char)SG_INDEX_TYPES ); // property
sgWriteUInt( fp, 1 ); // nbytes
sgWriteChar( fp, idx_mask );
// write strips
for ( i = start; i < end; ++i ) {
// nbytes
sgWriteUInt( fp, strips_v[i].size() * 2 * sizeof(short) );
sgWriteUInt( fp, strips_v[i].size() * idx_size * sizeof(short));
for ( j = 0; j < (int)strips_v[i].size(); ++j ) {
sgWriteShort( fp, (short)strips_v[i][j] );
sgWriteShort( fp, (short)strips_tc[i][j] );
if ( strips_v.size() ) {
sgWriteShort( fp, (short)strips_v[i][j] );
}
if ( strips_n.size() ) {
sgWriteShort( fp, (short)strips_n[i][j] );
}
if ( strips_c.size() ) {
sgWriteShort( fp, (short)strips_c[i][j] );
}
if ( strips_tc.size() ) {
sgWriteShort( fp, (short)strips_tc[i][j] );
}
}
}
@@ -783,20 +988,40 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write group headers
sgWriteChar( fp, (char)SG_TRIANGLE_FANS ); // type
sgWriteShort( fp, 1 ); // nproperties
sgWriteShort( fp, 2 ); // nproperties
sgWriteShort( fp, end - start ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes
sgWriteBytes( fp, material.length(), material.c_str() );
idx_mask = 0;
idx_size = 0;
if ( fans_v.size() ) { idx_mask |= SG_IDX_VERTICES; ++idx_size; }
if ( fans_n.size() ) { idx_mask |= SG_IDX_NORMALS; ++idx_size; }
if ( fans_c.size() ) { idx_mask |= SG_IDX_COLORS; ++idx_size; }
if ( fans_tc.size() ) { idx_mask |= SG_IDX_TEXCOORDS; ++idx_size; }
sgWriteChar( fp, (char)SG_INDEX_TYPES ); // property
sgWriteUInt( fp, 1 ); // nbytes
sgWriteChar( fp, idx_mask );
// write fans
for ( i = start; i < end; ++i ) {
// nbytes
sgWriteUInt( fp, fans_v[i].size() * 2 * sizeof(short) );
sgWriteUInt( fp, fans_v[i].size() * idx_size * sizeof(short) );
for ( j = 0; j < (int)fans_v[i].size(); ++j ) {
sgWriteShort( fp, (short)fans_v[i][j] );
sgWriteShort( fp, (short)fans_tc[i][j] );
if ( fans_v.size() ) {
sgWriteShort( fp, (short)fans_v[i][j] );
}
if ( fans_n.size() ) {
sgWriteShort( fp, (short)fans_n[i][j] );
}
if ( fans_c.size() ) {
sgWriteShort( fp, (short)fans_c[i][j] );
}
if ( fans_tc.size() ) {
sgWriteShort( fp, (short)fans_tc[i][j] );
}
}
}
@@ -828,7 +1053,7 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
string dir = base + "/" + b.gen_base_path();
string command = "mkdir -p " + dir;
#ifdef _MSC_VER
#if defined(_MSC_VER) || defined(__MINGW32__)
system( (string("mkdir ") + dir).c_str() );
#else
system(command.c_str());

View File

@@ -70,7 +70,7 @@ typedef group_list::const_iterator const_group_list_iterator;
* - property: prop_typecode, nbytes, BYTE+
*
* - obj_typecode: bounding sphere | vertices | normals | texcoords |
* triangles | fans | strips
* points | triangles | fans | strips
*
* - prop_typecode: material_name | ???
*
@@ -91,58 +91,103 @@ class SGBinObject {
Point3D gbs_center;
float gbs_radius;
point_list wgs84_nodes;
point_list normals;
point_list texcoords;
group_list tris_v;
group_list tris_tc;
string_list tri_materials;
group_list strips_v;
group_list strips_tc;
string_list strip_materials;
group_list fans_v;
group_list fans_tc;
string_list fan_materials;
point_list wgs84_nodes; // vertex list
point_list colors; // color list
point_list normals; // normal list
point_list texcoords; // texture coordinate list
group_list pts_v; // points vertex index
group_list pts_n; // points normal index
group_list pts_c; // points color index
group_list pts_tc; // points texture coordinate index
string_list pt_materials; // points materials
group_list tris_v; // triangles vertex index
group_list tris_n; // triangles normal index
group_list tris_c; // triangles color index
group_list tris_tc; // triangles texture coordinate index
string_list tri_materials; // triangles materials
group_list strips_v; // tristrips vertex index
group_list strips_n; // tristrips normal index
group_list strips_c; // tristrips color index
group_list strips_tc; // tristrips texture coordinate index
string_list strip_materials;// tristrips materials
group_list fans_v; // fans vertex index
group_list fans_n; // fans normal index
group_list fans_c; // fans color index
group_list fans_tc; // fans texture coordinate index
string_list fan_materials; // fans materials
public:
inline unsigned short get_version() const { return version; }
inline Point3D get_gbs_center() const { return gbs_center; }
inline void set_gbs_center( Point3D p ) { gbs_center = p; }
inline const Point3D& get_gbs_center() const { return gbs_center; }
inline void set_gbs_center( const Point3D& p ) { gbs_center = p; }
inline float get_gbs_radius() const { return gbs_radius; }
inline void set_gbs_radius( float r ) { gbs_radius = r; }
inline point_list get_wgs84_nodes() const { return wgs84_nodes; }
inline void set_wgs84_nodes( point_list n ) { wgs84_nodes = n; }
inline const point_list& get_wgs84_nodes() const { return wgs84_nodes; }
inline void set_wgs84_nodes( const point_list& n ) { wgs84_nodes = n; }
inline point_list get_normals() const { return normals; }
inline void set_normals( point_list n ) { normals = n; }
inline const point_list& get_colors() const { return colors; }
inline void set_colors( const point_list& c ) { colors = c; }
inline point_list get_texcoords() const { return texcoords; }
inline void set_texcoords( point_list t ) { texcoords = t; }
inline const point_list& get_normals() const { return normals; }
inline void set_normals( const point_list& n ) { normals = n; }
inline group_list get_tris_v() const { return tris_v; }
inline void set_tris_v( group_list g ) { tris_v = g; }
inline group_list get_tris_tc() const { return tris_tc; }
inline void set_tris_tc( group_list g ) { tris_tc = g; }
inline string_list get_tri_materials() const { return tri_materials; }
inline void set_tri_materials( string_list s ) { tri_materials = s; }
inline const point_list& get_texcoords() const { return texcoords; }
inline void set_texcoords( const point_list& t ) { texcoords = t; }
inline const group_list& get_pts_v() const { return pts_v; }
inline void set_pts_v( const group_list& g ) { pts_v = g; }
inline const group_list& get_pts_n() const { return pts_n; }
inline void set_pts_n( const group_list& g ) { pts_n = g; }
inline const group_list& get_pts_c() const { return pts_c; }
inline void set_pts_c( const group_list& g ) { pts_c = g; }
inline const group_list& get_pts_tc() const { return pts_tc; }
inline void set_pts_tc( const group_list& g ) { pts_tc = g; }
inline const string_list& get_pt_materials() const { return pt_materials; }
inline void set_pt_materials( const string_list& s ) { pt_materials = s; }
inline const group_list& get_tris_v() const { return tris_v; }
inline void set_tris_v( const group_list& g ) { tris_v = g; }
inline const group_list& get_tris_n() const { return tris_n; }
inline void set_tris_n( const group_list& g ) { tris_n = g; }
inline const group_list& get_tris_c() const { return tris_c; }
inline void set_tris_c( const group_list& g ) { tris_c = g; }
inline const group_list& get_tris_tc() const { return tris_tc; }
inline void set_tris_tc( const group_list& g ) { tris_tc = g; }
inline const string_list& get_tri_materials() const { return tri_materials; }
inline void set_tri_materials( const string_list& s ) { tri_materials = s; }
inline group_list get_strips_v() const { return strips_v; }
inline void set_strips_v( group_list g ) { strips_v = g; }
inline group_list get_strips_tc() const { return strips_tc; }
inline void set_strips_tc( group_list g ) { strips_tc = g; }
inline string_list get_strip_materials() const { return strip_materials; }
inline void set_strip_materials( string_list s ) { strip_materials = s; }
inline const group_list& get_strips_v() const { return strips_v; }
inline void set_strips_v( const group_list& g ) { strips_v = g; }
inline const group_list& get_strips_n() const { return strips_n; }
inline void set_strips_n( const group_list& g ) { strips_n = g; }
inline const group_list& get_strips_c() const { return strips_c; }
inline void set_strips_c( const group_list& g ) { strips_c = g; }
inline const group_list& get_strips_tc() const { return strips_tc; }
inline void set_strips_tc( const group_list& g ) { strips_tc = g; }
inline const string_list& get_strip_materials() const { return strip_materials; }
inline void set_strip_materials( const string_list& s ) { strip_materials = s; }
inline group_list get_fans_v() const { return fans_v; }
inline void set_fans_v( group_list g ) { fans_v = g; }
inline group_list get_fans_tc() const { return fans_tc; }
inline void set_fans_tc( group_list g ) { fans_tc = g; }
inline string_list get_fan_materials() const { return fan_materials; }
inline void set_fan_materials( string_list s ) { fan_materials = s; }
inline const group_list& get_fans_v() const { return fans_v; }
inline void set_fans_v( const group_list& g ) { fans_v = g; }
inline const group_list& get_fans_n() const { return fans_n; }
inline void set_fans_n( const group_list& g ) { fans_n = g; }
inline const group_list& get_fans_c() const { return fans_c; }
inline void set_fans_c( const group_list& g ) { fans_c = g; }
inline const group_list& get_fans_tc() const { return fans_tc; }
inline void set_fans_tc( const group_list& g ) { fans_tc = g; }
inline const string_list& get_fan_materials() const { return fan_materials; }
inline void set_fan_materials( const string_list& s ) { fan_materials = s; }
/**
* Read a binary file object and populate the provided structures.

View File

@@ -25,7 +25,7 @@
#include STL_STRING
#ifdef _MSC_VER
#if defined(_MSC_VER) || defined(__MINGW32__)
# include <io.h>
#endif
@@ -51,7 +51,7 @@ bool SGFile::open( const SGProtocolDir d ) {
set_dir( d );
if ( get_dir() == SG_IO_OUT ) {
#ifdef _MSC_VER
#if defined(_MSC_VER) || defined(__MINGW32__)
int mode = 00666;
#else
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;

View File

@@ -1,6 +1,7 @@
// sg_socket.cxx -- Socket I/O routines
//
// Written by Curtis Olson, started November 1999.
// Modified by Bernie Bright <bbright@bigpond.net.au>, May 2002.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
//
@@ -23,16 +24,6 @@
#include <simgear/compiler.h>
#if !defined(_MSC_VER)
# include <sys/time.h> // select()
# include <sys/types.h> // socket(), bind(), select(), accept()
# include <sys/socket.h> // socket(), bind(), listen(), accept()
# include <netinet/in.h> // struct sockaddr_in
# include <netdb.h> // gethostbyname()
# include <unistd.h> // select(), fsync()/fdatasync(), fcntl()
# include <fcntl.h> // fcntl()
#endif
#if defined( sgi )
#include <strings.h>
#endif
@@ -41,25 +32,30 @@
#include "sg_socket.hxx"
bool SGSocket::init = false;
SGSocket::SGSocket( const string& host, const string& port,
SGSocket::SGSocket( const string& host, const string& port_,
const string& style ) :
hostname(host),
port_str(port),
save_len(0)
port_str(port_),
save_len(0),
client(0),
is_tcp(false),
is_server(false),
first_read(false)
{
#if defined(_MSC_VER)
if (!wsock_init && !wsastartup()) {
SG_LOG( SG_IO, SG_ALERT, "Winsock not available");
if (!init)
{
netInit(NULL, NULL); // plib-1.4.2 compatible
init = true;
}
#endif
if ( style == "udp" ) {
sock_style = SOCK_DGRAM;
} else if ( style == "tcp" ) {
sock_style = SOCK_STREAM;
} else {
sock_style = SOCK_DGRAM;
if ( style == "tcp" )
{
is_tcp = true;
}
else if ( style != (string)"udp" )
{
SG_LOG( SG_IO, SG_ALERT,
"Error: SGSocket() unknown style = " << style );
}
@@ -68,122 +64,65 @@ SGSocket::SGSocket( const string& host, const string& port,
}
SGSocket::~SGSocket() {
SGSocket::~SGSocket()
{
this->close();
}
SGSocket::SocketType SGSocket::make_server_socket () {
struct sockaddr_in name;
#if defined( __CYGWIN__ ) || defined( __CYGWIN32__ ) || defined( sgi ) || defined( _MSC_VER )
int length;
#else
socklen_t length;
#endif
// Create the socket.
sock = socket (PF_INET, sock_style, 0);
if (sock == INVALID_SOCKET) {
SG_LOG( SG_IO, SG_ALERT,
"Error: socket() failed in make_server_socket()" );
return INVALID_SOCKET;
}
// Give the socket a name.
name.sin_family = AF_INET;
name.sin_addr.s_addr = INADDR_ANY;
name.sin_port = htons(port); // set port to zero to let system pick
name.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) != 0) {
SG_LOG( SG_IO, SG_ALERT,
"Error: bind() failed in make_server_socket()" );
return INVALID_SOCKET;
}
// Find the assigned port number
length = sizeof(struct sockaddr_in);
if ( getsockname(sock, (struct sockaddr *) &name, &length) ) {
SG_LOG( SG_IO, SG_ALERT,
"Error: getsockname() failed in make_server_socket()" );
return INVALID_SOCKET;
}
port = ntohs(name.sin_port);
return sock;
}
SGSocket::SocketType SGSocket::make_client_socket () {
struct sockaddr_in name;
struct hostent *hp;
SG_LOG( SG_IO, SG_INFO, "Make client socket()" );
// Create the socket.
sock = socket (PF_INET, sock_style, 0);
if (sock == INVALID_SOCKET) {
SG_LOG( SG_IO, SG_ALERT,
"Error: socket() failed in make_server_socket()" );
return INVALID_SOCKET;
}
// specify address family
name.sin_family = AF_INET;
// get the hosts official name/info
hp = gethostbyname( hostname.c_str() );
// Connect this socket to the host and the port specified on the
// command line
#if defined( __CYGWIN__ ) || defined( __CYGWIN32__ )
bcopy(hp->h_addr, (char *)(&(name.sin_addr.s_addr)), hp->h_length);
#else
bcopy(hp->h_addr, &(name.sin_addr.s_addr), hp->h_length);
#endif
name.sin_port = htons(port);
if ( connect(sock, (struct sockaddr *) &name,
sizeof(struct sockaddr_in)) != 0 )
bool
SGSocket::make_server_socket()
{
if (!sock.open( is_tcp ))
{
SG_LOG( SG_IO, SG_ALERT,
"Error: socket() failed in make_server_socket()" );
return false;
}
if (sock.bind( "", port ) < 0)
{
SG_LOG( SG_IO, SG_ALERT,
"Error: bind() failed in make_server_socket()" );
sock.close();
return false;
}
return true;
}
bool
SGSocket::make_client_socket()
{
if (!sock.open( is_tcp ))
{
SG_LOG( SG_IO, SG_ALERT,
"Error: socket() failed in make_client_socket()" );
return false;
}
if (sock.connect( hostname.c_str(), port ) < 0)
{
closesocket(sock);
SG_LOG( SG_IO, SG_ALERT,
"Error: connect() failed in make_client_socket()" );
return INVALID_SOCKET;
sock.close();
return false;
}
return sock;
return true;
}
// Wrapper functions
size_t SGSocket::readsocket( int fd, void *buf, size_t count ) {
#if defined(_MSC_VER)
return ::recv( fd, (char *)buf, count, 0 );
#else
return ::read( fd, buf, count );
#endif
}
size_t SGSocket::writesocket( int fd, const void *buf, size_t count ) {
#if defined(_MSC_VER)
return ::send( fd, (const char*)buf, count, 0 );
#else
return ::write( fd, buf, count );
#endif
}
#if !defined(_MSC_VER)
int SGSocket::closesocket( int fd ) {
return ::close( fd );
}
#endif
// If specified as a server (in direction for now) open the master
// listening socket. If specified as a client (out direction), open a
// connection to a server.
bool SGSocket::open( const SGProtocolDir d ) {
set_dir( d );
bool
SGSocket::open( SGProtocolDir direction )
{
set_dir( direction );
is_server = is_tcp &&
(direction == SG_IO_IN || direction == SG_IO_BI);
if ( port_str == "" || port_str == "any" ) {
port = 0;
@@ -191,69 +130,71 @@ bool SGSocket::open( const SGProtocolDir d ) {
port = atoi( port_str.c_str() );
}
// client_connections.clear();
if ( get_dir() == SG_IO_IN ) {
if (direction == SG_IO_IN)
{
// this means server for now
// Setup socket to listen on. Set "port" before making this
// call. A port of "0" indicates that we want to let the os
// pick any available port.
sock = make_server_socket();
if ( sock == INVALID_SOCKET ) {
SG_LOG( SG_IO, SG_ALERT, "socket creation failed" );
if (!make_server_socket())
{
SG_LOG( SG_IO, SG_ALERT, "SG_IO_IN socket creation failed" );
return false;
}
SG_LOG( SG_IO, SG_INFO, "socket is connected to port = " << port );
if ( sock_style == SOCK_DGRAM ) {
if ( !is_tcp )
{
// Non-blocking UDP
nonblock();
} else {
}
else
{
// Blocking TCP
// Specify the maximum length of the connection queue
listen( sock, SG_MAX_SOCKET_QUEUE );
sock.listen( SG_MAX_SOCKET_QUEUE );
}
} else if ( get_dir() == SG_IO_OUT ) {
}
else if (direction == SG_IO_OUT)
{
// this means client for now
sock = make_client_socket();
// TODO: check for error.
if (!make_client_socket())
{
SG_LOG( SG_IO, SG_ALERT, "SG_IO_OUT socket creation failed" );
return false;
}
if ( sock_style == SOCK_DGRAM ) {
if ( !is_tcp )
{
// Non-blocking UDP
nonblock();
}
} else if ( get_dir() == SG_IO_BI && sock_style == SOCK_STREAM ) {
}
else if (direction == SG_IO_BI && is_tcp)
{
// this means server for TCP sockets
// Setup socket to listen on. Set "port" before making this
// call. A port of "0" indicates that we want to let the os
// pick any available port.
sock = make_server_socket();
// TODO: check for error.
SG_LOG( SG_IO, SG_INFO, "socket is connected to port = " << port );
if (!make_server_socket())
{
SG_LOG( SG_IO, SG_ALERT, "SG_IO_BI socket creation failed" );
return false;
}
// Blocking TCP
// Specify the maximum length of the connection queue
listen( sock, SG_MAX_SOCKET_QUEUE );
} else {
sock.listen( SG_MAX_SOCKET_QUEUE );
}
else
{
SG_LOG( SG_IO, SG_ALERT,
"Error: bidirection mode not available for UDP sockets." );
return false;
}
if ( sock < 0 ) {
SG_LOG( SG_IO, SG_ALERT, "Error opening socket: " << hostname
<< ":" << port );
return false;
}
// extra SOCK_STREAM stuff
msgsock = INVALID_SOCKET;
first_read = false;
return true;
@@ -262,40 +203,25 @@ bool SGSocket::open( const SGProtocolDir d ) {
// read data from socket (server)
// read a block of data of specified size
int SGSocket::read( char *buf, int length ) {
if ( sock == INVALID_SOCKET ) {
int
SGSocket::read( char *buf, int length )
{
if (sock.getHandle() == -1 &&
(client == 0 || client->getHandle() == -1))
{
return 0;
}
int result = 0;
// check for potential input
fd_set ready;
FD_ZERO(&ready);
FD_SET(sock, &ready);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
// test for any input available on sock (returning immediately, even if
// nothing)
select(32, &ready, 0, 0, &tv);
int result = poll();
if ( FD_ISSET(sock, &ready) ) {
// cout << "data ready" << endl;
if (result > 0)
{
result = sock.recv( buf, length );
if ( sock_style == SOCK_STREAM ) {
if ( msgsock == INVALID_SOCKET ) {
msgsock = accept(sock, 0, 0);
closesocket(sock);
sock = msgsock;
} else {
result = readsocket( sock, buf, length );
}
} else {
result = readsocket( sock, buf, length );
}
if ( result != length ) {
if ( result != length )
{
SG_LOG( SG_IO, SG_INFO,
"Warning: read() not enough bytes." );
}
@@ -306,94 +232,74 @@ int SGSocket::read( char *buf, int length ) {
// read a line of data, length is max size of input buffer
int SGSocket::readline( char *buf, int length ) {
if ( sock == INVALID_SOCKET ) {
int
SGSocket::readline( char *buf, int length )
{
if (sock.getHandle() == -1 &&
(client == 0 || client->getHandle() == -1))
{
return 0;
}
// cout << "sock = " << sock << endl;
// check for potential input
fd_set ready;
FD_ZERO(&ready);
FD_SET(sock, &ready);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
// test for any input read on sock (returning immediately, even if
// nothing)
int result = select(32, &ready, 0, 0, &tv);
// cout << "result = " << result << endl;
int result = this->poll();
if ( FD_ISSET(sock, &ready) ) {
// cout << "fd change state\n";
if (result > 0)
{
// read a chunk, keep in the save buffer until we have the
// requested amount read
if ( sock_style == SOCK_STREAM ) {
// cout << "sock_stream\n";
if ( msgsock == INVALID_SOCKET ) {
// cout << "msgsock == invalid\n";
msgsock = accept(sock, 0, 0);
closesocket(sock);
sock = msgsock;
} else {
// cout << "ready to read\n";
char *buf_ptr = save_buf + save_len;
result = readsocket( sock, buf_ptr, SG_IO_MAX_MSG_SIZE
- save_len );
// cout << "read result = " << result << endl;
if ( result > 0 ) {
first_read = true;
}
save_len += result;
// Try and detect that the remote end died. This
// could cause problems so if you see connections
// dropping for unexplained reasons, LOOK HERE!
if ( result == 0 && save_len == 0 && first_read == true ) {
SG_LOG( SG_IO, SG_ALERT,
"Connection closed by foreign host." );
closesocket(sock);
open( get_dir() );
}
}
} else {
if (is_tcp)
{
char *buf_ptr = save_buf + save_len;
result = readsocket( sock, buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
result = client->recv( buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
if ( result > 0 )
{
first_read = true;
}
save_len += result;
// Try and detect that the remote end died. This
// could cause problems so if you see connections
// dropping for unexplained reasons, LOOK HERE!
if (result == 0 && save_len == 0 && first_read == true)
{
SG_LOG( SG_IO, SG_ALERT,
"Connection closed by foreign host." );
delete client;
client = 0;
}
}
else
{
char *buf_ptr = save_buf + save_len;
result = sock.recv( buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
save_len += result;
}
// cout << "current read = " << buf_ptr << endl;
// cout << "current save_buf = " << save_buf << endl;
// cout << "save_len = " << save_len << endl;
} else {
// cout << "no data ready\n";
}
// look for the end of line in save_buf
int i;
for ( i = 0; i < save_len && save_buf[i] != '\n'; ++i );
for ( i = 0; i < save_len && save_buf[i] != '\n'; ++i )
;
if ( save_buf[i] == '\n' ) {
result = i + 1;
} else {
// no end of line yet
// cout << "no eol found" << endl;
return 0;
}
// cout << "line length = " << result << endl;
// we found an end of line
// copy to external buffer
strncpy( buf, save_buf, result );
buf[result] = '\0';
// cout << "sg_socket line = " << buf << endl;
// shift save buffer
//memmove( save_buf+, save_buf+, ? );
for ( i = result; i < save_len; ++i ) {
save_buf[ i - result ] = save_buf[i];
}
@@ -404,66 +310,23 @@ int SGSocket::readline( char *buf, int length ) {
// write data to socket (client)
int SGSocket::write( const char *buf, const int length ) {
if ( sock == INVALID_SOCKET ) {
int
SGSocket::write( const char *buf, const int length )
{
netSocket* s = client == 0 ? &sock : client;
if (s->getHandle() == -1)
{
return 0;
}
bool error_condition = false;
if ( writesocket(sock, buf, length) < 0 ) {
if ( s->send( buf, length ) < 0 )
{
SG_LOG( SG_IO, SG_ALERT, "Error writing to socket: " << port );
error_condition = true;
}
#if 0
// check for any new client connection requests
fd_set ready;
FD_ZERO(&ready);
FD_SET(sock, &ready);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
// test for any input on sock (returning immediately, even if
// nothing)
select(32, &ready, 0, 0, &tv);
// any new connections?
if ( FD_ISSET(sock, &ready) ) {
int msgsock = accept(sock, 0, 0);
if ( msgsock < 0 ) {
SG_LOG( SG_IO, SG_ALERT,
"Error: accept() failed in write()" );
return 0;
} else {
client_connections.push_back( msgsock );
}
}
SG_LOG( SG_IO, SG_INFO, "Client connections = " <<
client_connections.size() );
for ( int i = 0; i < (int)client_connections.size(); ++i ) {
int msgsock = client_connections[i];
// read and junk any possible incoming messages.
// char junk[ SG_IO_MAX_MSG_SIZE ];
// std::read( msgsock, junk, SG_IO_MAX_MSG_SIZE );
// write the interesting data to the socket
if ( writesocket(msgsock, buf, length) == SOCKET_ERROR ) {
SG_LOG( SG_IO, SG_ALERT, "Error writing to socket: " << port );
error_condition = true;
} else {
#ifdef _POSIX_SYNCHRONIZED_IO
// fdatasync(msgsock);
#else
// fsync(msgsock);
#endif
}
}
#endif
if ( error_condition ) {
return 0;
}
@@ -473,75 +336,62 @@ int SGSocket::write( const char *buf, const int length ) {
// write null terminated string to socket (server)
int SGSocket::writestring( const char *str ) {
if ( sock == INVALID_SOCKET ) {
return 0;
}
int
SGSocket::writestring( const char *str )
{
int length = strlen( str );
return write( str, length );
return this->write( str, length );
}
// close the port
bool SGSocket::close() {
if ( sock == INVALID_SOCKET ) {
return 0;
}
bool
SGSocket::close()
{
delete client;
client = 0;
closesocket( sock );
sock.close();
return true;
}
// configure the socket as non-blocking
bool SGSocket::nonblock() {
if ( sock == INVALID_SOCKET ) {
bool
SGSocket::nonblock()
{
if (sock.getHandle() == -1) {
return false;
}
sock.setBlocking( false );
return true;
}
int
SGSocket::poll()
{
netSocket* readers[2];
readers[0] = client != 0 ? client : &sock;
readers[1] = 0;
netSocket* writers[1];
writers[0] = 0;
int result = netSocket::select( readers, writers, 0 );
if (result > 0 && is_server && client == 0)
{
// Accept a new client connection
netAddress addr;
int new_fd = sock.accept( &addr );
SG_LOG( SG_IO, SG_INFO, "Accepted connection from "
<< addr.getHost() << ":" << addr.getPort() );
client = new netSocket();
client->setHandle( new_fd );
return 0;
}
#if defined(_MSC_VER)
u_long arg = 1;
if (ioctlsocket( sock, FIONBIO, &arg ) != 0) {
int error_code = WSAGetLastError();
SG_LOG( SG_IO, SG_ALERT,
"Error " << error_code << ": unable to set non-blocking mode"
);
return false;
}
#else
fcntl( sock, F_SETFL, O_NONBLOCK );
#endif
return true;
return result;
}
#if defined(_MSC_VER)
bool SGSocket::wsock_init = false;
bool
SGSocket::wsastartup() {
WORD wVersionRequested;
WSADATA wsaData;
//wVersionRequested = MAKEWORD( 2, 2 );
wVersionRequested = MAKEWORD( 1, 1 );
int err = WSAStartup( wVersionRequested, &wsaData );
if (err != 0)
{
SG_LOG( SG_IO, SG_ALERT, "Error: Couldn't load winsock" );
return false;
}
#if 0
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
SG_LOG( SG_IO, SG_ALERT, "Couldn't load a suitable winsock");
WSACleanup( );
return false;
}
#endif
wsock_init = true;
return true;
}
#endif

View File

@@ -39,11 +39,9 @@
#include <simgear/math/sg_types.hxx>
#include <simgear/io/iochannel.hxx>
SG_USING_STD(string);
#include <plib/netSocket.h>
#if defined(_MSC_VER)
# include <winsock.h>
#endif
SG_USING_STD(string);
#define SG_MAX_SOCKET_QUEUE 32
@@ -53,13 +51,6 @@ SG_USING_STD(string);
*/
class SGSocket : public SGIOChannel {
public:
#if defined(_MSC_VER)
typedef SOCKET SocketType;
#else
typedef int SocketType;
# define INVALID_SOCKET (-1)
#endif
private:
string hostname;
string port_str;
@@ -67,31 +58,23 @@ private:
char save_buf[ 2 * SG_IO_MAX_MSG_SIZE ];
int save_len;
SocketType sock;
SocketType msgsock;
short unsigned int port;
int sock_style; // SOCK_STREAM or SOCK_DGRAM
netSocket sock;
netSocket* client;
unsigned short port;
bool is_tcp;
bool is_server;
bool first_read;
static bool init;
// make a server (master listening) socket
SocketType make_server_socket();
bool make_server_socket();
// make a client socket
SocketType make_client_socket();
bool make_client_socket();
// wrapper functions
size_t readsocket( int fd, void *buf, size_t count );
size_t writesocket( int fd, const void *buf, size_t count );
#if !defined(_MSC_VER)
int closesocket(int fd);
#endif
#if defined(_MSC_VER)
// Ensure winsock has been initialised.
static bool wsock_init;
static bool wsastartup();
#endif
// Poll for new connections or data to read.
int poll();
public:

View File

@@ -0,0 +1,202 @@
// sg_socket.cxx -- Socket I/O routines
//
// Written by Curtis Olson, started November 1999.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
//
// 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 <simgear/compiler.h>
#if defined( sgi )
#include <strings.h>
#endif
#include <simgear/debug/logstream.hxx>
#include "sg_socket_udp.hxx"
SGSocketUDP::SGSocketUDP( const string& host, const string& port ) :
hostname(host),
port_str(port),
save_len(0)
{
set_valid( false );
}
SGSocketUDP::~SGSocketUDP() {
}
// If specified as a server (in direction for now) open the master
// listening socket. If specified as a client (out direction), open a
// connection to a server.
bool SGSocketUDP::open( const SGProtocolDir d ) {
set_dir( d );
if ( ! sock.open( false ) ) { // open a UDP socket
SG_LOG( SG_IO, SG_ALERT, "error opening socket" );
return false;
}
if ( port_str == "" || port_str == "any" ) {
port = 0;
} else {
port = atoi( port_str.c_str() );
}
// client_connections.clear();
if ( get_dir() == SG_IO_IN ) {
// this means server
// bind ...
if ( sock.bind( hostname.c_str(), port ) == -1 ) {
SG_LOG( SG_IO, SG_ALERT, "error binding to port" << port_str );
return false;
}
} else if ( get_dir() == SG_IO_OUT ) {
// this means client
// connect ...
if ( sock.connect( hostname.c_str(), port ) == -1 ) {
SG_LOG( SG_IO, SG_ALERT,
"error connecting to " << hostname << port_str );
return false;
}
} else {
SG_LOG( SG_IO, SG_ALERT,
"Error: bidirection mode not available for UDP sockets." );
return false;
}
set_valid( true );
return true;
}
// read data from socket (server)
// read a block of data of specified size
int SGSocketUDP::read( char *buf, int length ) {
if ( ! isvalid() ) {
return 0;
}
int result;
if ( (result = sock.recv(buf, SG_IO_MAX_MSG_SIZE, 0)) >= 0 ) {
buf[result] = '\0';
// printf("msg received = %s\n", buf);
}
return result;
}
// read a line of data, length is max size of input buffer
int SGSocketUDP::readline( char *buf, int length ) {
if ( ! isvalid() ) {
return 0;
}
// cout << "sock = " << sock << endl;
char *buf_ptr = save_buf + save_len;
int result = sock.recv(buf_ptr, SG_IO_MAX_MSG_SIZE, 0);
// printf("msg received = %s\n", buf);
save_len += result;
// look for the end of line in save_buf
int i;
for ( i = 0; i < save_len && save_buf[i] != '\n'; ++i );
if ( save_buf[i] == '\n' ) {
result = i + 1;
} else {
// no end of line yet
// cout << "no eol found" << endl;
return 0;
}
// cout << "line length = " << result << endl;
// we found an end of line
// copy to external buffer
strncpy( buf, save_buf, result );
buf[result] = '\0';
// cout << "sg_socket line = " << buf << endl;
// shift save buffer
for ( i = result; i < save_len; ++i ) {
save_buf[ i - result ] = save_buf[i];
}
save_len -= result;
return result;
}
// write data to socket (client)
int SGSocketUDP::write( const char *buf, const int length ) {
if ( ! isvalid() ) {
return 0;
}
bool error_condition = false;
if ( sock.send( buf, length, 0 ) < 0 ) {
SG_LOG( SG_IO, SG_ALERT, "Error writing to socket: " << port );
error_condition = true;
return 0;
}
return length;
}
// write null terminated string to socket (server)
int SGSocketUDP::writestring( const char *str ) {
if ( !isvalid() ) {
return 0;
}
int length = strlen( str );
return write( str, length );
}
// close the port
bool SGSocketUDP::close() {
if ( !isvalid() ) {
return 0;
}
sock.close();
return true;
}
// configure the socket as non-blocking
bool SGSocketUDP::setBlocking( bool value ) {
sock.setBlocking( value );
return true;
}

View File

@@ -0,0 +1,138 @@
/**
* \file sg_socket_udp.hxx
* UDP Socket I/O routines.
*/
// Written by Curtis Olson, started November 2001.
//
// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org
//
// 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 _SG_SOCKET_UDP_HXX
#define _SG_SOCKET_UDP_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <plib/netSocket.h>
#include <simgear/compiler.h>
#include STL_STRING
#include <simgear/math/sg_types.hxx>
#include <simgear/io/iochannel.hxx>
SG_USING_STD(string);
/**
* A UDP socket I/O class based on SGIOChannel and plib/net.
*/
class SGSocketUDP : public SGIOChannel {
private:
netSocket sock;
string hostname;
string port_str;
char save_buf[ 2 * SG_IO_MAX_MSG_SIZE ];
int save_len;
short unsigned int port;
public:
/**
* Create an instance of SGSocketUDP.
*
* When calling the constructor you need to provide a host name, and a
* port number. The convention used by the
* SGSocketUDP class is that the server side listens and the client
* side sends. For a server socket, the host name should be
* empty. For a server, the port number is optional, if you do not
* specify a port, the system will assign one. For a client
* socket, you need to specify both a destination host and
* destination port.
*
* UDP sockets are a lower level protocol than TCP sockets and are
* "connectionless" in the sense that either client or server can
* exist, or not exist, startup, quit, etc. in any order and
* whenever both ends are alive, the communication succeeds. With
* UDP sockets, the server end just sits and listens for incoming
* packets from anywhere. The client end sends it's message and
* forgets about it. It doesn't care if there isn't even a server
* out there listening and all the packets are getting
* lost. Although systems/networks usually do a pretty good job
* (statistically) of getting your UDP packets to their
* destination, there is no guarantee that any particular packet
* will make it. But, because of this low level implementation and
* lack of error checking, UDP packets are much faster and
* efficient. UDP packets are good for sending positional
* information to synchronize two applications. In this case, you
* want the information to arrive as quickly as possible, and if
* you lose a packet, you'd rather get new updated information
* rather than have the system waste time resending a packet that
* is becoming older and older with every retry.
* @param host name of host if direction is SG_IO_OUT or SG_IO_BI
* @param port port number if we care to choose one.
* @param style specify "udp" or "tcp" */
SGSocketUDP( const string& host, const string& port );
/** Destructor */
~SGSocketUDP();
// If specified as a server (in direction for now) open the master
// listening socket. If specified as a client (out direction),
// open a connection to a server.
bool open( const SGProtocolDir d );
// read data from socket
int read( char *buf, int length );
// read data from socket
int readline( char *buf, int length );
// write data to a socket
int write( const char *buf, const int length );
// write null terminated string to a socket
int writestring( const char *str );
// close file
bool close();
/**
* Set blocking true or false
* @return success/failure
*/
bool setBlocking( bool value );
/** @return the remote host name */
inline string get_hostname() const { return hostname; }
/** @return the port number (in string form) */
inline string get_port_str() const { return port_str; }
};
#endif // _SG_SOCKET_UDP_HXX

View File

@@ -41,6 +41,10 @@ int main() {
if ( s.readline( buf, 256 ) > 0 ) {
cout << "result = " << buf;
}
#ifdef __MINGW32__
Sleep(100);
#else
sleep(1);
#endif
}
}

89
simgear/io/tcp_client.cxx Normal file
View File

@@ -0,0 +1,89 @@
#include <simgear/compiler.h>
#include STL_IOSTREAM
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <simgear/debug/logstream.hxx>
#include "sg_socket.hxx"
#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
using std::cout;
#endif
class TcpClient
{
public:
TcpClient( const char* host, const char* port );
~TcpClient();
bool open();
bool process();
bool close();
private:
SGIOChannel* channel;
};
TcpClient::TcpClient( const char* host, const char* port )
{
channel = new SGSocket( host, port, "tcp" );
}
TcpClient::~TcpClient()
{
delete channel;
}
bool
TcpClient::open()
{
return channel->open( SG_IO_OUT );
}
bool
TcpClient::process()
{
char wbuf[1024];
sprintf( wbuf, "hello world\n" );
int length = channel->writestring( wbuf );
cout << "writestring returned " << length << "\n";
return true;
}
bool
TcpClient::close()
{
return channel->close();
}
int
main()
{
sglog().setLogLevels( SG_ALL, SG_INFO );
TcpClient client( "localhost", "5500" );
if (!client.open())
{
cout << "client open failed\n";
return 0;
}
for (int i = 0; i < 3; ++i)
{
client.process();
#ifdef _WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
//client.close();
return 0;
}

72
simgear/io/tcp_server.cxx Normal file
View File

@@ -0,0 +1,72 @@
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#include STL_STRING
#include STL_IOSTREAM
#include "sg_socket.hxx"
using std::string;
#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
using std::cout;
#endif
class TcpServer
{
public:
TcpServer();
bool open();
bool process();
bool close();
private:
SGIOChannel* channel;
};
TcpServer::TcpServer()
{
channel = new SGSocket( "", "5500", "tcp" );
}
bool
TcpServer::open()
{
channel->open( SG_IO_BI );
return true;
}
bool
TcpServer::process()
{
char buf[1024];
int len;
while ((len = channel->readline( buf, sizeof(buf) )) > 0)
{
cout << len << ": " << buf;
}
return true;
}
bool
TcpServer::close()
{
return channel->close();
}
int
main()
{
sglog().setLogLevels( SG_ALL, SG_INFO );
TcpServer server;
server.open();
SG_LOG( SG_IO, SG_INFO, "Created TCP server" );
while (1)
{
server.process();
}
server.close();
return 0;
}

View File

@@ -0,0 +1,4 @@
.deps
Makefile
Makefile.in
testmagvar

View File

@@ -14,4 +14,4 @@ testmagvar_SOURCES = testmagvar.cxx
testmagvar_LDADD = $(top_builddir)/simgear/magvar/libsgmagvar.a
INCLUDES += -I$(top_srcdir)
INCLUDES = -I$(top_srcdir)

View File

@@ -29,7 +29,10 @@
#include "magvar.hxx"
SGMagVar::SGMagVar() {
SGMagVar::SGMagVar()
: magvar(0.0),
magdip(0.0)
{
}
SGMagVar::~SGMagVar() {

View File

@@ -45,9 +45,9 @@ if (argc == 8){
var = calc_magvar( SGD_DEGREES_TO_RADIANS * lat_deg, SGD_DEGREES_TO_RADIANS * lon_deg, h,
yymmdd_to_julian_days(yy,mm,dd), field );
fprintf(stdout,"%6.0lf %6.0lf %6.0lf\n", field[0], field[1], field[2] );
fprintf(stdout,"%6.0lf %6.0lf %6.0lf\n", field[3], field[4], field[5] );
fprintf(stdout,"%6.0lf %6.0lf %6.0lf %4.2lf %4.2lf \n",
fprintf(stdout,"%6.0f %6.0f %6.0f\n", field[0], field[1], field[2] );
fprintf(stdout,"%6.0f %6.0f %6.0f\n", field[3], field[4], field[5] );
fprintf(stdout,"%6.0f %6.0f %6.0f %4.2f %4.2f \n",
field[3],field[4],field[5],
SGD_RADIANS_TO_DEGREES * (atan(field[5]/pow(field[3]*field[3]+field[4]*field[4],0.5))),
SGD_RADIANS_TO_DEGREES * var);

3
simgear/math/.cvsignore Normal file
View File

@@ -0,0 +1,3 @@
.deps
Makefile
Makefile.in

View File

@@ -1,11 +1,5 @@
includedir = @includedir@/math
if HAVE_ZLIB
ZLIB_INCL =
else
ZLIB_INCL = -I$(top_srcdir)/src/zlib
endif
lib_LIBRARIES = libsgmath.a
include_HEADERS = \
@@ -30,4 +24,4 @@ libsgmath_a_SOURCES = \
sg_random.c \
vector.cxx
INCLUDES += -I$(top_srcdir) $(ZLIB_INCL)
INCLUDES = -I$(top_srcdir)

View File

@@ -83,8 +83,9 @@ double SGInterpTable::interpolate(double x) const
int i;
double y;
if (size == 0.0)
if (size == 0.0) {
return 0.0;
}
i = 0;
@@ -96,14 +97,14 @@ double SGInterpTable::interpolate(double x) const
// printf ("i = %d ", i);
if ( (i == 0) && (x < table[0].ind) ) {
if ( i <= 0 ) {
SG_LOG( SG_MATH, SG_DEBUG,
"interpolate(): lookup error, x to small = " << x );
return table[0].dep;
}
// cout << " table[size-1].ind = " << table[size-1].ind << endl;
if ( x > table[size-1].ind ) {
if ( i >= size ) {
SG_LOG( SG_MATH, SG_DEBUG,
"interpolate(): lookup error, x to big = " << x );
return table[size-1].dep;

View File

@@ -22,6 +22,51 @@
// $Id$
/*
A C-program for MT19937, with initialization improved 2002/2/10.
Coded by Takuji Nishimura and Makoto Matsumoto.
This is a faster version by taking Shawn Cokus's optimization,
Matthe Bellew's simplification, Isaku Wada's real version.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Any feedback is very welcome.
http://www.math.keio.ac.jp/matumoto/emt.html
email: matumoto@math.keio.ac.jp
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
@@ -32,50 +77,87 @@
#include "sg_random.h"
#ifndef HAVE_RAND
# ifdef sgi
# undef RAND_MAX
# define RAND_MAX 2147483647
# endif
#endif
/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
#define UMASK 0x80000000UL /* most significant w-r bits */
#define LMASK 0x7fffffffUL /* least significant r bits */
#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
#ifdef __SUNPRO_CC
extern "C" {
long int random();
void srandom(unsigned int seed);
static unsigned long state[N]; /* the array for the state vector */
static int left = 1;
static int initf = 0;
static unsigned long *next;
/* initializes state[N] with a seed */
void init_genrand(unsigned long s)
{
int j;
state[0]= s & 0xffffffffUL;
for (j=1; j<N; j++) {
state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j);
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array state[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
state[j] &= 0xffffffffUL; /* for >32 bit machines */
}
#endif
left = 1; initf = 1;
}
static void next_state(void)
{
unsigned long *p=state;
int j;
/* if init_genrand() has not been called, */
/* a default initial seed is used */
if (initf==0) init_genrand(5489UL);
left = N;
next = state;
for (j=N-M+1; --j; p++)
*p = p[M] ^ TWIST(p[0], p[1]);
for (j=M; --j; p++)
*p = p[M-N] ^ TWIST(p[0], p[1]);
*p = p[M-N] ^ TWIST(p[0], state[0]);
}
// Seed the random number generater with time() so we don't see the
// same sequence every time
void sg_srandom_time() {
#ifdef HAVE_RAND
srand(time(NULL));
#else
srandom(time(NULL));
#endif
init_genrand(time(NULL));
}
// Seed the random number generater with your own seed so can set up
// repeatable randomization.
void sg_srandom( unsigned int seed ) {
#ifdef HAVE_RAND
srand( seed );
#else
srandom( seed );
#endif
init_genrand( seed );
}
// return a random number between [0.0, 1.0)
double sg_random() {
#ifdef HAVE_RAND
return(rand() / (double)RAND_MAX);
#else
return(random() / (double)RAND_MAX);
#endif
unsigned long y;
if (--left == 0)
next_state();
y = *next++;
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return (double)y * (1.0/4294967295.0);
/* divided by 2^32-1 */
}

3
simgear/metar/.cvsignore Normal file
View File

@@ -0,0 +1,3 @@
.deps
Makefile
Makefile.in

View File

@@ -1,13 +1,5 @@
#pragma comment(compiler)
#pragma comment(date)
#pragma comment(timestamp)
#include <stdlib.h>
#pragma title("antoi - char array to integer")
#pragma pagesize (80)
#pragma page(1)
/********************************************************************/
/* */
/* Title: antoi */
@@ -78,4 +70,3 @@ int antoi(char * string, int len)
} /* end antoi */
#pragma page(1)

Some files were not shown because too many files have changed in this diff Show More