Compare commits
209 Commits
RELEASE_0_
...
RELEASE_0_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1818102ffe | ||
|
|
406d6dd6fc | ||
|
|
c8ef854f01 | ||
|
|
87dcaf5a00 | ||
|
|
c3bdd0e537 | ||
|
|
c23fd6e66f | ||
|
|
e809eee896 | ||
|
|
c44ef2126c | ||
|
|
e2bfb5633b | ||
|
|
064ee8ba8f | ||
|
|
a5c130446e | ||
|
|
4162817c0b | ||
|
|
81cab6e089 | ||
|
|
d78204d147 | ||
|
|
d8b523d067 | ||
|
|
c4cfad6069 | ||
|
|
5bddb88ce2 | ||
|
|
8c4ee69aeb | ||
|
|
b3a533f8ce | ||
|
|
a885314a39 | ||
|
|
0567a76445 | ||
|
|
d6dc2d6eab | ||
|
|
b75a694682 | ||
|
|
2e7e9b73a0 | ||
|
|
7a11523692 | ||
|
|
f85a9866fe | ||
|
|
9b05c27938 | ||
|
|
fd96729362 | ||
|
|
c57cc096f8 | ||
|
|
c8efd0a465 | ||
|
|
db60139845 | ||
|
|
cadefd323a | ||
|
|
baab88f42a | ||
|
|
767b74dd35 | ||
|
|
90e8287f43 | ||
|
|
d8b7e5b8fd | ||
|
|
7769447283 | ||
|
|
d6a790cf13 | ||
|
|
033c66363d | ||
|
|
3ff1789963 | ||
|
|
9737c0c4dd | ||
|
|
b201383a80 | ||
|
|
2253b82304 | ||
|
|
2581446d85 | ||
|
|
a6291b286c | ||
|
|
96a396bfcb | ||
|
|
0833a11686 | ||
|
|
9c7f7f3d32 | ||
|
|
7847fe8074 | ||
|
|
c57d25ac51 | ||
|
|
1341b5b9f8 | ||
|
|
fb54e9e103 | ||
|
|
3a835dde7d | ||
|
|
128a4a36ca | ||
|
|
255bb6dd07 | ||
|
|
786b1e3a30 | ||
|
|
d5f38a558e | ||
|
|
ce5d4b7db8 | ||
|
|
8c0b36fe9e | ||
|
|
c7e6459c64 | ||
|
|
86e31e696d | ||
|
|
be0b1bb994 | ||
|
|
03e74bfeb4 | ||
|
|
972223cd50 | ||
|
|
761b7b9354 | ||
|
|
6a3d1895d9 | ||
|
|
d1178a26ce | ||
|
|
8ffdfa3cb1 | ||
|
|
384e56b9b4 | ||
|
|
d198e962b0 | ||
|
|
0136fdadbb | ||
|
|
c616568830 | ||
|
|
995d2c1ede | ||
|
|
051a5e9a38 | ||
|
|
60d89097de | ||
|
|
6c35255549 | ||
|
|
c985d8846d | ||
|
|
9a8ab26381 | ||
|
|
711622fd5b | ||
|
|
96474823b5 | ||
|
|
bbf4b54613 | ||
|
|
9795c5dd6b | ||
|
|
addcace80d | ||
|
|
77e43a5fa8 | ||
|
|
b751188e56 | ||
|
|
1ad9a15864 | ||
|
|
d0d7878e0a | ||
|
|
be5d365348 | ||
|
|
a8e0002a64 | ||
|
|
bf75cf7225 | ||
|
|
c024b680bc | ||
|
|
c896475765 | ||
|
|
101fdb3598 | ||
|
|
b13505afdf | ||
|
|
9d96b171a0 | ||
|
|
8b5a0cde69 | ||
|
|
bed7593cdd | ||
|
|
9fed946567 | ||
|
|
4d0bc0ae39 | ||
|
|
f9824aa7de | ||
|
|
4d2522964a | ||
|
|
dbe4a59b8e | ||
|
|
918f8a3ed4 | ||
|
|
f645596606 | ||
|
|
d778dd081d | ||
|
|
f6ed02c3fb | ||
|
|
7fa5dd7a35 | ||
|
|
a3186af099 | ||
|
|
a2d95ac742 | ||
|
|
10715bbea7 | ||
|
|
89fcb12556 | ||
|
|
cc3d7ddee5 | ||
|
|
cc01f99acb | ||
|
|
62b75190bb | ||
|
|
520124c1be | ||
|
|
e251bfcbaf | ||
|
|
aef809348f | ||
|
|
2d4a8774b8 | ||
|
|
b55c8fd828 | ||
|
|
dfff091b5f | ||
|
|
47eb7efafa | ||
|
|
b2a7fff26e | ||
|
|
5f70123723 | ||
|
|
dd629da8d3 | ||
|
|
74f7d52d95 | ||
|
|
7a65a990ba | ||
|
|
fe0076e291 | ||
|
|
1a8bc06cc6 | ||
|
|
8c41081a5c | ||
|
|
5b40eed554 | ||
|
|
b1c4d34eef | ||
|
|
0152b607f8 | ||
|
|
ab6e72047b | ||
|
|
15399bfe95 | ||
|
|
0ff748987b | ||
|
|
58e0e7736b | ||
|
|
2d1b2ca938 | ||
|
|
9a4152eb2d | ||
|
|
6ab443545f | ||
|
|
98a9b4a10c | ||
|
|
a6251606dd | ||
|
|
c3b21e143c | ||
|
|
b496593883 | ||
|
|
4ef4b019ca | ||
|
|
a8021531ab | ||
|
|
93fd948978 | ||
|
|
a1b3740dc6 | ||
|
|
40920457cb | ||
|
|
5039c84fd0 | ||
|
|
220a43bf46 | ||
|
|
45d3e19c38 | ||
|
|
5bab565cfe | ||
|
|
319a4282c8 | ||
|
|
c6aa8bc8e9 | ||
|
|
6f1bfa202e | ||
|
|
6fa9f86d1c | ||
|
|
019a9527d2 | ||
|
|
d100ca485f | ||
|
|
35ab6900ee | ||
|
|
c8570302f5 | ||
|
|
74f10486bc | ||
|
|
2b12425a62 | ||
|
|
c600aad7a7 | ||
|
|
67b2f0a977 | ||
|
|
70c6b48a07 | ||
|
|
76084f8538 | ||
|
|
64c408d2b7 | ||
|
|
73b050ae34 | ||
|
|
59991393ca | ||
|
|
69b2717b62 | ||
|
|
f2a323e048 | ||
|
|
7d07e6ea51 | ||
|
|
7c846972bf | ||
|
|
4f76c258af | ||
|
|
eca2afb982 | ||
|
|
9ff6934c83 | ||
|
|
e04839765d | ||
|
|
d0c655109f | ||
|
|
b28b55abb1 | ||
|
|
c3a0db1aba | ||
|
|
5e929d7d01 | ||
|
|
17f113f8cd | ||
|
|
445cd4ccda | ||
|
|
55845bbbb9 | ||
|
|
1976481ba2 | ||
|
|
5f17edbc72 | ||
|
|
6f7fe4b481 | ||
|
|
66ebe6e690 | ||
|
|
a9cd67e0ce | ||
|
|
994a470fbf | ||
|
|
0ce0684dae | ||
|
|
377eb4782a | ||
|
|
f1a79e6b9f | ||
|
|
007a1e4659 | ||
|
|
fcb873b6dd | ||
|
|
a66d1ad855 | ||
|
|
76a5950f19 | ||
|
|
b7a91bdb03 | ||
|
|
e4bbc5c50b | ||
|
|
b481ccd749 | ||
|
|
e7b9e55599 | ||
|
|
05eaa7135f | ||
|
|
d063b319e8 | ||
|
|
be4fd56660 | ||
|
|
a406a3c00b | ||
|
|
c7295da5eb | ||
|
|
505f561e1c | ||
|
|
7bd8477fa1 | ||
|
|
36ef15940e |
8
.cvsignore
Normal file
8
.cvsignore
Normal file
@@ -0,0 +1,8 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
SimGear.spec
|
||||
aclocal.m4
|
||||
config.cache
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
2
Doxyfile
2
Doxyfile
@@ -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.
|
||||
|
||||
108
Makefile.am
108
Makefile.am
@@ -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
122
NEWS
@@ -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
4
README
@@ -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
24
README.MSVC
Normal 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.
|
||||
@@ -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
16
README.plib
Normal 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
173
README.zlib
Normal 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.
|
||||
962
SimGear.dsp
962
SimGear.dsp
File diff suppressed because it is too large
Load Diff
24
SimGear.dsw
24
SimGear.dsw
@@ -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>
|
||||
|
||||
333
acconfig.h
333
acconfig.h
@@ -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). */
|
||||
|
||||
@@ -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
140
aclocal.m4
vendored
@@ -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
39
am2dsp.cfg
Normal 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
52
autogen.sh
Executable 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 "======================================"
|
||||
@@ -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
7
simgear/.cvsignore
Normal file
@@ -0,0 +1,7 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
simgear_config.h
|
||||
simgear_config.h.in
|
||||
stamp-h
|
||||
stamp-h.in
|
||||
version.h
|
||||
@@ -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
|
||||
|
||||
3
simgear/bucket/.cvsignore
Normal file
3
simgear/bucket/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
//
|
||||
|
||||
@@ -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
3
simgear/debug/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -8,4 +8,4 @@ include_HEADERS = debug_types.h logstream.hxx
|
||||
|
||||
libsgdebug_a_SOURCES = logstream.cxx
|
||||
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
3
simgear/ephemeris/.cvsignore
Normal file
3
simgear/ephemeris/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -31,4 +31,4 @@ libsgephem_a_SOURCES = \
|
||||
uranus.cxx \
|
||||
venus.cxx
|
||||
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
3
simgear/interpreter/.cvsignore
Normal file
3
simgear/interpreter/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
33
simgear/interpreter/Makefile.am
Normal file
33
simgear/interpreter/Makefile.am
Normal 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)
|
||||
77
simgear/interpreter/exbase.cc
Normal file
77
simgear/interpreter/exbase.cc
Normal 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;
|
||||
}
|
||||
46
simgear/interpreter/exgen.cc
Normal file
46
simgear/interpreter/exgen.cc
Normal 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]);
|
||||
}
|
||||
9
simgear/interpreter/interpreter.cxx
Normal file
9
simgear/interpreter/interpreter.cxx
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "interpreter.hxx"
|
||||
|
||||
SGInterpreter::SGInterpreter ()
|
||||
{
|
||||
}
|
||||
|
||||
SGInterpreter::~SGInterpreter ()
|
||||
{
|
||||
}
|
||||
13
simgear/interpreter/interpreter.hxx
Normal file
13
simgear/interpreter/interpreter.hxx
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __INTERPRETER_HXX
|
||||
#define __INTERPRETER_HXX 1
|
||||
|
||||
class SGInterpreter
|
||||
{
|
||||
public:
|
||||
|
||||
SGInterpreter ();
|
||||
virtual ~SGInterpreter ();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
107
simgear/interpreter/ixlib_base.hh
Normal file
107
simgear/interpreter/ixlib_base.hh
Normal 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
|
||||
72
simgear/interpreter/ixlib_exbase.hh
Normal file
72
simgear/interpreter/ixlib_exbase.hh
Normal 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
|
||||
67
simgear/interpreter/ixlib_exgen.hh
Normal file
67
simgear/interpreter/ixlib_exgen.hh
Normal 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
|
||||
491
simgear/interpreter/ixlib_garbage.hh
Normal file
491
simgear/interpreter/ixlib_garbage.hh
Normal 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
|
||||
23
simgear/interpreter/ixlib_i18n.hh
Normal file
23
simgear/interpreter/ixlib_i18n.hh
Normal 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
|
||||
380
simgear/interpreter/ixlib_javascript.hh
Normal file
380
simgear/interpreter/ixlib_javascript.hh
Normal 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 ¶meters); \
|
||||
}; \
|
||||
} \
|
||||
ixion::ref<ixion::javascript::value> NAME::call(parameter_list const ¶meters)
|
||||
|
||||
#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 ¶meters);
|
||||
virtual ref<value> callAsMethod(ref<value> instance,parameter_list const ¶meters);
|
||||
virtual ref<value> construct(parameter_list const ¶meters);
|
||||
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 ¶meters);
|
||||
};
|
||||
|
||||
public:
|
||||
ref<value> lookup(std::string const &identifier);
|
||||
virtual ref<value> callMethod(std::string const &identifier,parameter_list const ¶meters) = 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 ¶meters);
|
||||
|
||||
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
|
||||
760
simgear/interpreter/ixlib_js_internals.hh
Normal file
760
simgear/interpreter/ixlib_js_internals.hh
Normal 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 ¶meters);
|
||||
|
||||
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 ¶meters);
|
||||
|
||||
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 ¶meters);
|
||||
|
||||
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 ¶meters);
|
||||
ref<value> callAsMethod(ref<value> instance,parameter_list const ¶meters);
|
||||
ref<value> construct(parameter_list const ¶meters);
|
||||
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 ¶meters) const;
|
||||
ref<value> callAsMethod(ref<value> instance,parameter_list const ¶meters);
|
||||
ref<value> construct(parameter_list const ¶meters);
|
||||
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 ¶meters) 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 ¶meters);
|
||||
};
|
||||
|
||||
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 ¶meters);
|
||||
};
|
||||
|
||||
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 ¶meters);
|
||||
};
|
||||
|
||||
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 ¶meters);
|
||||
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 ¶meters);
|
||||
};
|
||||
|
||||
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 ¶meters);
|
||||
};
|
||||
|
||||
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 ¶meters);
|
||||
};
|
||||
|
||||
// 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
|
||||
62
simgear/interpreter/ixlib_numconv.hh
Normal file
62
simgear/interpreter/ixlib_numconv.hh
Normal 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
|
||||
127
simgear/interpreter/ixlib_numeric.hh
Normal file
127
simgear/interpreter/ixlib_numeric.hh
Normal 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
|
||||
82
simgear/interpreter/ixlib_random.hh
Normal file
82
simgear/interpreter/ixlib_random.hh
Normal 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
|
||||
493
simgear/interpreter/ixlib_re.hh
Normal file
493
simgear/interpreter/ixlib_re.hh
Normal 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
|
||||
652
simgear/interpreter/ixlib_re_impl.hh
Normal file
652
simgear/interpreter/ixlib_re_impl.hh
Normal 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;
|
||||
}
|
||||
24
simgear/interpreter/ixlib_scanjs.hh
Normal file
24
simgear/interpreter/ixlib_scanjs.hh
Normal 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
|
||||
75
simgear/interpreter/ixlib_scanner.hh
Normal file
75
simgear/interpreter/ixlib_scanner.hh
Normal 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
|
||||
64
simgear/interpreter/ixlib_string.hh
Normal file
64
simgear/interpreter/ixlib_string.hh
Normal 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
|
||||
85
simgear/interpreter/ixlib_token_javascript.hh
Normal file
85
simgear/interpreter/ixlib_token_javascript.hh
Normal 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
|
||||
25
simgear/interpreter/ixlib_token_lex.hh
Normal file
25
simgear/interpreter/ixlib_token_lex.hh
Normal 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
|
||||
201
simgear/interpreter/js_array.cc
Normal file
201
simgear/interpreter/js_array.cc
Normal 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 ¶meters) {
|
||||
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 ¶meters) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
216
simgear/interpreter/js_declaration.cc
Normal file
216
simgear/interpreter/js_declaration.cc
Normal 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);
|
||||
}
|
||||
310
simgear/interpreter/js_expression.cc
Normal file
310
simgear/interpreter/js_expression.cc
Normal 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
|
||||
}
|
||||
413
simgear/interpreter/js_instruction.cc
Normal file
413
simgear/interpreter/js_instruction.cc
Normal 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);
|
||||
}
|
||||
1133
simgear/interpreter/js_interpreter.cc
Normal file
1133
simgear/interpreter/js_interpreter.cc
Normal file
File diff suppressed because it is too large
Load Diff
259
simgear/interpreter/js_library.cc
Normal file
259
simgear/interpreter/js_library.cc
Normal 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 ¶meters);
|
||||
};
|
||||
|
||||
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 ¶meters);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// eval -----------------------------------------------------------------------
|
||||
ref<value>
|
||||
eval::
|
||||
call(parameter_list const ¶meters) {
|
||||
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 ¶meters) {
|
||||
#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);
|
||||
}
|
||||
1967
simgear/interpreter/js_value.cc
Normal file
1967
simgear/interpreter/js_value.cc
Normal file
File diff suppressed because it is too large
Load Diff
2031
simgear/interpreter/lex.javascript.cc
Normal file
2031
simgear/interpreter/lex.javascript.cc
Normal file
File diff suppressed because it is too large
Load Diff
168
simgear/interpreter/lex.javascript.yy
Normal file
168
simgear/interpreter/lex.javascript.yy
Normal 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()))
|
||||
41
simgear/interpreter/main.cc
Normal file
41
simgear/interpreter/main.cc
Normal 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;
|
||||
}
|
||||
|
||||
144
simgear/interpreter/numconv.cc
Normal file
144
simgear/interpreter/numconv.cc
Normal 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);
|
||||
}
|
||||
}
|
||||
38
simgear/interpreter/numeric.cc
Normal file
38
simgear/interpreter/numeric.cc
Normal 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
427
simgear/interpreter/re.cc
Normal 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;
|
||||
}
|
||||
108
simgear/interpreter/scanner.cc
Normal file
108
simgear/interpreter/scanner.cc
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
317
simgear/interpreter/string.cc
Normal file
317
simgear/interpreter/string.cc
Normal 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
8
simgear/io/.cvsignore
Normal file
@@ -0,0 +1,8 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
decode_binobj
|
||||
lowtest
|
||||
socktest
|
||||
tcp_client
|
||||
tcp_server
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
|
||||
#include "iochannel.hxx"
|
||||
// #include "garmin.hxx"
|
||||
// #include "nmea.hxx"
|
||||
|
||||
|
||||
// constructor
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
#include <string.h> // for memcpy()
|
||||
|
||||
#include "lowlevel.hxx"
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
202
simgear/io/sg_socket_udp.cxx
Normal file
202
simgear/io/sg_socket_udp.cxx
Normal 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;
|
||||
}
|
||||
138
simgear/io/sg_socket_udp.hxx
Normal file
138
simgear/io/sg_socket_udp.hxx
Normal 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
|
||||
@@ -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
89
simgear/io/tcp_client.cxx
Normal 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
72
simgear/io/tcp_server.cxx
Normal 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;
|
||||
}
|
||||
4
simgear/magvar/.cvsignore
Normal file
4
simgear/magvar/.cvsignore
Normal file
@@ -0,0 +1,4 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
testmagvar
|
||||
@@ -14,4 +14,4 @@ testmagvar_SOURCES = testmagvar.cxx
|
||||
|
||||
testmagvar_LDADD = $(top_builddir)/simgear/magvar/libsgmagvar.a
|
||||
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
@@ -29,7 +29,10 @@
|
||||
#include "magvar.hxx"
|
||||
|
||||
|
||||
SGMagVar::SGMagVar() {
|
||||
SGMagVar::SGMagVar()
|
||||
: magvar(0.0),
|
||||
magdip(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
SGMagVar::~SGMagVar() {
|
||||
|
||||
@@ -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
3
simgear/math/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
3
simgear/metar/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
Reference in New Issue
Block a user