Compare commits

...

706 Commits

Author SHA1 Message Date
James Turner
1b3c048363 New version : 2018.3.4 2019-08-07 09:58:45 +01:00
Dan Wickstrom
01f689a0e4 Aircraft model reinit deletes sound effect samples, but leaves them defined in the sample group, so a reload doesn't re-add them. 2019-07-30 16:36:49 +01:00
Scott Giese
b155f2e40f [soundmgr_openal] Pause/Resume Sound.
The following changes fixes a case for me where I hear the sound change levels up and down for each pause un-pause cycle.
Patch provided by daniel.c.wickstrom@gmail.com.
2019-07-30 16:36:49 +01:00
Tim Moore
10ab8b830a nasal/lib.c: Make copy of va_list for each traversal
It's not portable to traverse a va_list more than once.
2019-07-30 16:36:49 +01:00
James Turner
8a4871db83 Improve HTTP redirect handling, and add test.
Ensure we get the final status code for the request after redirecting.
2019-07-30 16:36:49 +01:00
Torsten Dreyer
9a8c10cb0b New version: 2018.3.3 2019-07-28 22:43:16 +02:00
Erik Hofman
fd32023437 Do not attempt to deregister the same emitter more than once 2019-01-26 10:17:11 +01:00
Erik Hofman
c1ee4a9172 Use AAX_PROCESSED since AAX_STOPPED is only a request to stop but the library decides when it is actually stopped. And AeonWave has become more picky about destroying emitters which aren't completely processed yet since MIDI support was added. 2019-01-26 10:16:38 +01:00
Richard Harrison
a5b32f8eb2 Fix for deleting referenced object from model registry
This should have been in the previous commit - However I managed to mess up the merging of this module due to other changes related to the DDS texture cache.
2019-01-25 21:39:03 +00:00
Richard Harrison
4a86368c8f Fix null ref during load.
This happened a few times
2019-01-25 21:39:03 +00:00
Richard Harrison
3730cc48a5 Fix particles active even when disabled during load.
Possibly this could be fixed better by using the plugin string data - but there is nothing that currently set this; and it seems easier to use the particle callback enabled flag.
2019-01-25 21:39:03 +00:00
Richard Harrison
8a55c2f44f Fix for deleting still referenced object
ref https://sourceforge.net/p/flightgear/codetickets/2105/

Use the thread safe versions (getRef) of the objectcache methods
2019-01-25 21:39:03 +00:00
Erik Hofman
ef1cbae22b Split up SIMD support in ENABLE_SIMD which enables sse2 support for the compiler and ENABLE_SIMD_CODE which enables the hand crafted SIMD math functions which defaults to OFF now since compilers have catched up on generating optimized vectorized SIMD code. 2019-01-15 11:01:24 +01:00
James Turner
61f322f201 Bump patch version to 2018.3.2 2019-01-06 16:14:10 +00:00
Stuart Buchanan
becbef96f5 Fix effects for MP models - ticket 2076
https://sourceforge.net/p/flightgear/codetickets/2076/

Effects were being instantiated by the loader for
all models, rather than just simple .ac/.obj models.
2018-11-06 17:44:06 +00:00
James Turner
89b3fadf0f Fix for assert with empty systems
Empty subsystem groups didn’t set their init state correctly, leading
to an assert on post-init. Fix this and add a test for it.

https://sourceforge.net/p/flightgear/codetickets/2043/
2018-10-23 15:30:32 +01:00
James Turner
4a1a9ea9c1 Catalogs: allow migration to alternate IDs 2018-10-17 16:24:26 +01:00
James Turner
efc609577f Packages: check for existing update when scheduling
This is fixing an issue identified in the launcher in a secondary way,
to ensure if another user of the API tries to schedule an already
scheduled package, we ignore the second request.
2018-10-17 16:24:20 +01:00
James Turner
6ffc501566 Mac: Set CMake OS-X deployment target correctly
Also raises the OS-X min version to 10.9 for libc++ compat
2018-10-17 16:24:15 +01:00
James Turner
9785cadbd0 Fix a debug message left in the terrasync code 2018-10-05 10:41:39 +01:00
Torsten Dreyer
0494af48a3 new version: 2018.3.1 2018-09-21 17:18:46 +02:00
James Turner
f4cad42958 Lat-lon parsing: catch exceptions from std::stod
The standard library throws exceptions in some cases, catch those
and return false. Extend the test coverage for some of the problematic
cases.
2018-09-13 23:47:24 +02:00
James Turner
32189b7239 Event-manager: add dump() method for debugging 2018-09-01 18:08:32 +01:00
James Turner
c192071f03 TerraSync: improve copy-installed-files logic 2018-08-31 16:05:48 +01:00
James Turner
8c9fda9137 Fix Utf-8 literal on MSVC 2018-08-31 16:05:48 +01:00
James Turner
8dd0833993 Fix setting OPENAL_DIR on Windows
We need to set this in all cases, since AeonWave is requested by
default, but may not be available.
2018-08-23 19:11:50 +01:00
James Turner
306eaeaba9 Fix subsystem-remove bug 2018-08-19 12:32:30 +01:00
James Turner
7853a5329d Extend propsfwd.hxx so it can be used in more places 2018-08-11 18:41:29 +02:00
James Turner
1fa77078fc Subsystems: bind/init/unbind on add/remove
When adding/remove subsystems to a group which is already bound or
inited, transition the subsystem automatically. This removes the
need to manually transition the subsystem in various places in
Flightgear.
2018-08-11 18:41:04 +02:00
James Turner
8e8ce04e18 Subsystems: default name to group name when adding 2018-08-11 18:16:33 +02:00
James Turner
264779e1d3 Packages: fix download progress
(Broke it when improving zip/tar support)
2018-08-08 11:12:53 +02:00
James Turner
6f505f3a76 formatGeodAsString: add ICAO route format 2018-07-30 10:08:34 +02:00
Edward d'Auvergne
3817bdd602 NotifyLogger: Shifted the class from flightgear to simgear.
This is to allow the code to be reused in the flightgear test suite.
2018-07-26 20:48:12 +02:00
Edward d'Auvergne
2c9420d9bc Logstream: Added a logging class for outputting messages in headless mode. 2018-07-26 20:48:12 +02:00
James Turner
2e3cace7f9 Canvas::path: early return for descendant changes
The ‘rect’ attributes of Path were before the early-return when the
change is for a descendant node.
2018-07-24 13:13:08 +01:00
James Turner
9553a604ac Cache parsed lat/lon values in Canvas::Map
This avoids re-parsing each lat/lon in the map from a string, each
time the project changes
2018-07-24 13:13:08 +01:00
James Turner
f1e1bf11b6 Cache x/y nodes in Canvas::Map::GeoPair
This removes a bad CPU hit when Canvas map is used continuously,
since this is two named property lookups per map coord per frame
2018-07-24 13:13:08 +01:00
James Turner
f77724a646 Fix terrasync hash persistence 2018-07-19 07:40:23 +01:00
James Turner
a0c4913f84 Fix .dirindex preservation on Windows
Ensure we don't treat the special files as regular children
when updating.
2018-07-18 16:30:44 +01:00
James Turner
3dfce43de2 Fixes to HTTP repo tests on Windows.
Large alloca fails, and SGFIle dtor doesn't close the handle,
which breaks _wunlink on Windows :(
2018-07-18 07:20:18 +01:00
Erik Hofman
0e9e5f77cc It turns out the 16-bit version was not introduced until gcc-4.8 2018-07-05 10:29:03 +02:00
James Turner
f2f465960b Tar code: handle symlink and PAX extensions
This now accepts the GitLab .tgz archives without problems, eg
the Tu-144.
2018-07-04 23:47:14 +01:00
James Turner
05d8ab3000 Fix Windows build
Clean out legacy crap from stdint.h while we're here
2018-07-04 14:08:57 +01:00
James Turner
126f69434b Refactor untar/unzip code
This is to enable reuse in more places, especially scenery extraction and TerraSync
2018-07-04 10:32:09 +01:00
Erik Hofman
3e081ae869 Use CPU optimized versions of endian swap functions when available 2018-07-04 09:35:45 +02:00
Erik Hofman
4e8df9dcc8 Remove a bunch og gcc-8 warnings 2018-07-04 09:33:32 +02:00
James Turner
d7a413d5e7 Lat-lon parsing: allow lon,lat order, and detect order
Flightplan/route-manager defaults to lon,lat order. Allow the parser
to detect the correct order when NSEW suffixes are provided and 
consistent.
2018-06-29 13:28:02 +01:00
James Turner
609ac93c10 Lat-lon parsing: accept lower case NSEW, fix precision
Thanks to Wkitty for catching both problems.
2018-06-28 22:43:30 +01:00
James Turner
b1d6a41c65 Fix a bug in lat-lon parsing - accept ‘*’
Previously, trailing * symbols confused the parser.
2018-06-27 14:29:45 +01:00
James Turner
a4e2fdfad2 Merge /u/scttgs0/simgear/ branch to-be-merged into next
https://sourceforge.net/p/flightgear/simgear/merge-requests/46/
2018-06-24 20:07:40 +00:00
James Turner
22c2971c3c Lat-lon formatting: support nice degree symbols
Allow Latin-1 (for PUI fnt) and UTF-8 (for Qt, osgText and everybody
else) degree symbols as well as the use of *
2018-06-24 10:30:50 +01:00
Scott Giese
123c597e01 msvc has no support plans beyond OpenMP 2.0
We must use a signed integral data type
2018-06-23 14:44:48 -05:00
Scott Giese
05e3c29ee4 Support Visual Studio 2017 2018-06-22 22:19:49 -05:00
James Turner
9b1444deb5 Strutils to format and parse SGGeod/lat/lon
Format portion is taken from code in fg_props, parsing code is my
own horrible concoction.
2018-06-20 22:00:58 +01:00
James Turner
99d30d5bb7 CMake tweak: include headers in targets
This improves navigation in XCode (any maybe some other tools)
2018-06-20 22:00:03 +01:00
James Turner
100bb3a571 Fix flags passed to SHGetKnownFolderPath
Custom folder locations were not being picked up.
Fixes: https://sourceforge.net/p/flightgear/codetickets/2019/
2018-06-15 11:08:53 +01:00
Stuart Buchanan
7fb89e4d45 Multiple LoD levels of MP Aircraft
Support loading multiple models into PagedLOD.
2018-06-05 21:56:36 +01:00
Stuart Buchanan
1d7c3984ca Fix minor warning for no return value. 2018-06-05 21:55:23 +01:00
Erik Hofman
03156a6d94 Better AeoNWave detection 2018-06-05 09:39:51 +02:00
Erik Hofman
08258ee4b3 Detect AeonWave and if it is installed use it, otherwise fall back to OpenAL. Also let get_available_devices() use C++ strings instead of const char* 2018-06-02 14:06:15 +02:00
Erik Hofman
3dceaf7a0b Update to the latest version 2018-06-02 10:53:03 +02:00
Erik Hofman
856473ca43 Add missing headers 2018-05-29 09:44:37 +02:00
James Turner
7dfe705717 Resource manager clean-up code 2018-05-28 21:57:31 +02:00
ThomasS
dc2f142480 Feature for requesting canvas images per HTTP as described in http://wiki.flightgear.org/Read_canvas_image_by_HTTP 2018-05-28 14:23:12 +01:00
Torsten Dreyer
94a1156a6b new version: 2018.3.0 2018-05-19 21:02:35 +02:00
Torsten Dreyer
5ed4fbd4a3 new version: 2018.2.1 2018-05-19 21:02:35 +02:00
xDraconian
d92a289c25 Bug fix: svg dirty flag 2018-05-17 09:11:07 +01:00
Edward d'Auvergne
2ba5676eb0 SGTime: Stripped trailing '\n' from some debugging messages. 2018-05-14 21:36:54 +02:00
Edward d'Auvergne
66cfa800be SGEventMgr: Reset the shutdown flag on init as a reset does not call the ctor.
This fixes the reset process that was broken by
dfed2184f1.
2018-05-14 14:05:04 +02:00
James Turner
9755110ec7 Packages: Remove deprecation warnings for now
Probably a bit over-zealous for these.
2018-05-09 10:15:07 +01:00
James Turner
f5ff969cd4 Warning improvements when requesting bad URLs
Found while debugging some issues with add-default-catalog flow in
the launcher.
2018-05-08 06:50:15 +01:00
Edward d'Auvergne
a232565b3e SGSubsystemMgr: Bug fix for the global_registrations vector.
The vector is now a static function variable that is returned by reference by
the new getGlobalRegistrations() function, which remains in the anonymous
namespace.

This solves the issue of the global_registrations vector being populated during
static init, but then been subsequently allocated and hence reset at the end of
static init.
2018-05-04 09:09:15 +02:00
Edward d'Auvergne
fd4ca1c811 Revert "Speculative fix for global symbol issues for Edward"
This reverts commit b6f5b40557.

The changes did not solve the static init vector allocation issue.
2018-05-04 09:02:08 +02:00
James Turner
b6f5b40557 Speculative fix for global symbol issues for Edward
Let’s see if an explicit static at file scope is better or different
to an anonymous namespace scope
2018-05-03 14:29:07 +01:00
James Turner
5710d33dbf Subsystem commands in the manager
Migrate and update these commands from FlightGear’s subsystem factory.
Currently disabled until subsystem-factory is removed, to avoid
duplicate registration.
2018-05-02 23:27:34 +01:00
James Turner
831369f653 Packages: add archive-path XML support
Allow the in-archive file path to differ from the after-install path.
Requested to allow easier operation with GitHub/Labs zip generation.
2018-04-27 15:25:13 +01:00
James Turner
6db59c64aa Subsystems: change naming scheme, add accessors
Add some hopefully clearer accessors for the subsystem naming, and some
comments documenting what is stored where.
2018-04-27 13:59:11 +01:00
James Turner
888d7fb262 Packages: archive-type support in catalogs
Allow URLs which don’t encode the file extension to work
2018-04-27 12:07:10 +01:00
James Turner
8b4ace6fb8 Subsystems: stub code for smart add+remove
Groups track their state, which will enable them to correctly transition
added and removed children in the future. Only stubbed for now, to avoid
breakage on the FG side.
2018-04-25 22:20:12 +01:00
James Turner
368120c479 Track a root property on subsystem-manager 2018-04-25 21:34:17 +01:00
James Turner
48b228f68f Packages: additional test for updating invalid
This is part of trying to trace a crash reported on the devel list,
unfortunately the test passes but it’s sill good to have it
2018-04-25 17:04:07 +01:00
James Turner
bf21c0e099 MSVC build fixes, ooops 2018-04-25 11:41:40 +01:00
James Turner
d85d85e7dc Subsystem improvements for testing
- track more meta-data and a factory function for each subsystem, 
registered either explicitly or via a helper static class.
- add a delegate to receive notifications of subsystem changes
- make sub-grouped subsystems work more naturally, especially for
child lookups
- add some test coverage for all of this
2018-04-25 08:58:58 +01:00
Florent Rougon
99c1dd8124 Add compiler options for GCC and Clang when CMAKE_BUILD_TYPE is Debug
When CMAKE_BUILD_TYPE is Debug and we are compiling with GCC, add the
following options to CMAKE_C_FLAGS and CMAKE_CXX_FLAGS:

  -O0 -fno-omit-frame-pointer -fno-inline

Ditto for Clang, except that -fno-inline-functions is used instead of
-fno-inline.

cf. thread starting at
https://sourceforge.net/p/flightgear/mailman/message/36295412/
2018-04-18 08:25:10 +02:00
James Turner
2797970837 Catalogs: better invalid data handling 2018-04-08 23:57:24 +01:00
James Turner
cf03307b70 More verbose error logging from Repository code 2018-03-30 17:24:58 +01:00
Edward d'Auvergne
dfed2184f1 SGEventMgr: Protection from timer insertion after shutdown.
This actually happens, Nasal timers are added after the event manager shutdown()
subsystem API call.
2018-03-25 22:45:04 +02:00
Edward d'Auvergne
340a469153 LogStream: Added a testing mode to the simgear logstreams.
The new function logstream::setTestingMode() has been created to allow for a
testing mode to be set.  This stores a boolean in the private logstream thread
which modifies the behaviour of the would_log() function, allowing for
everything to be logged.  The removeCallbacks() function has also been added,
allowing for the default fgfs output to STDOUT and STDERR to be silenced when
calling setTestingMode().
2018-03-22 14:45:32 +00:00
Thomas Geymayer
62ae6ca35e Mostly canvas doxygen improvements and C++11 refactoring. 2018-03-02 09:07:01 +01:00
Thomas Geymayer
711a4fe0c8 canvas::Map: Preserve default values without new values
Ensure default values are used (instead of 0) if no values are
specified.
2018-03-01 09:10:24 +01:00
James Turner
cba07157d5 Packages: better version handling & migration
Add test coverage for disabling a catalog due to version, and also
for auto-migrating to a new version. Expose disabled catalogs on the
Root, so they can be checked for.
2018-02-28 17:26:15 +00:00
Thomas Geymayer
a653d67aae canvas: Event improvements and new events (dragstart, dragend) 2018-02-25 14:50:49 +01:00
Erik Hofman
6a142bc264 Merge branch 'release/2018.1' into next 2018-02-20 10:11:38 +01:00
Erik Hofman
8bcdd89796 Properly initialize _bad_doppler 2018-02-20 10:11:04 +01:00
Torsten Dreyer
489573329e new version: 2018.2.0 2018-02-18 21:22:54 +01:00
Torsten Dreyer
843df4b334 new version: 2018.1.1 2018-02-18 21:22:54 +01:00
Erik Hofman
ef1821c025 Switch to C++11 2018-02-16 16:09:26 +01:00
James Turner
ed5372f439 Add new PROTECTED property attribute 2018-02-04 17:10:41 +00:00
James Turner
bc63381fb0 Packages: tweaks to thumbnail cache
Don’t discard the existing data when expiring from the cache, in case
the refresh request fails.
2018-01-31 15:00:58 +00:00
James Turner
c59f2a0749 Fix Windows _wutime compilation 2018-01-31 13:10:34 +00:00
James Turner
5c30ca5dc6 Add SGPath::touch() helper 2018-01-31 11:04:10 +00:00
Thomas Geymayer
37bc43c7aa canvas::Path: support for stroke-opacity and fill-opacity 2018-01-29 09:07:04 +01:00
Thomas Geymayer
4edd3f45b7 canvas: Refactor and protect against expired pointers 2018-01-28 15:57:14 +01:00
Thomas Geymayer
087ea4c5f3 canvas: Refactor with C++11 2018-01-28 00:49:05 +01:00
Florent Rougon
40534d6316 Remove overzealous, invasive behavior from SGBinding's destructor
Since the dawn of times (FG commit
1bcaf4bfdd38f18ac7c375dd9319935ff3df56ac, where SGBinding was called
FGBinding), SGBinding's destructor has had a strange behavior:

SGBinding::~SGBinding()
{
  if(_arg && _arg->getParent())
    _arg->getParent()->removeChild(_arg->getName(), _arg->getIndex());
}

In other words, it used to remove the passed-in <binding> node from its
parent node (if any) once the SGBinding instance got destroyed. This
behavior is very unintuitive to several people and has resulted in a few
workarounds in the FG code base just to cope with this strangeness.

This commit gives SGBinding the implictly-generated destructor,
therefore SGBinding::~SGBinding() does not attempt to remove the
property node anymore.

See disussion at:

  https://sourceforge.net/p/flightgear/mailman/flightgear-devel/thread/87d12b1h0h.fsf%40frougon.crabdance.com/#msg36190666
2018-01-27 11:03:06 +01:00
James Turner
8621925e75 Floating-point comparison helpers for SGMath<T>
Implemented using numeric_limits::epsilon and std::abs, fingers
crossed this is sufficiently portable!
2018-01-26 11:29:18 +00:00
Thomas Geymayer
5cb2360985 cppbind: Use separet Context::to_nasal_vec instead of overload 2018-01-23 16:15:56 +01:00
Thomas Geymayer
b831d2b64a cppbind: Fix for old g++ 2018-01-23 14:02:18 +01:00
Thomas Geymayer
e81597a176 cppbind: Opimize convert fixed size arrays and more type_traits 2018-01-23 09:30:00 +01:00
James Turner
7df4f32de6 Merge /u/janodesbois/simgear-jano/ branch mp-merge into next
https://sourceforge.net/p/flightgear/simgear/merge-requests/42/
2018-01-22 09:48:01 +00:00
Thomas Geymayer
db3725880e cppbind: simplify with 'auto' 2018-01-21 14:39:24 +01:00
Thomas Geymayer
af5833cbc5 cppbind: Refactor to use C++11+ type_traits 2018-01-21 13:21:55 +01:00
James Turner
9078a085c3 Kill exception if removeDelegate fails
This simplifies logic when changing the package::Root
2018-01-20 16:19:13 +00:00
jean pellotier
396a7d7f09 a system clock from simgear, using std::chrono libs
this is to use some kind of utc time for timestamps in mp protocol,
to improve the lag correction system for mp planes, using a
"real time" mode when possible.
2018-01-20 09:15:56 +01:00
Thomas Geymayer
8a128a57cd cppbind: forward declarations 2018-01-19 10:34:37 +01:00
Thomas Geymayer
3dca9b8a68 cppbind: Make Mac and Windows happy and add forward declaration 2018-01-19 10:24:33 +01:00
Thomas Geymayer
5f8f5a1c33 cppbind: More refactoring and finally getting rid of boost.preprocessor 2018-01-19 09:12:11 +01:00
Thomas Geymayer
5a72a7d9f4 canvas: Refactor Path::addSegment with std::initializer_list 2018-01-16 09:01:55 +01:00
James Turner
51a91bfa8a Ignore CmakeList.txt.user files 2018-01-12 22:19:54 +00:00
Thomas Geymayer
4cedd0a346 cppbind: refactor Ghost::method to use variadic templates 2018-01-12 08:32:57 +01:00
Thomas Geymayer
b989f4085d Various doxygen improvements/fixes. 2018-01-12 08:32:04 +01:00
Thomas Geymayer
19cc797c41 cppbind: fix exporting integer_sequence and small codingstyle fixes 2018-01-12 07:57:17 +01:00
Thomas Geymayer
99ee3d9dec cppbind: nasal::Context refactoring and doxygen improvements. 2018-01-09 22:50:29 +01:00
Florent Rougon
455753c774 Simplify code in NetChannelPoller::removeChannel()
Remove an apparently bogus portability workaround (which was presumably
targetting one of the bugs fixed in the previous commit [1]) and further
simplify the code using std::find().

[1] da099d4312/
2018-01-08 10:26:18 +01:00
James Turner
da099d4312 Correct use of remove_if in the test-server
Should fix erratic crashes of some tests.
2018-01-07 16:10:50 +00:00
xDraconian
a88b9181b6 Enable the test 'test_precipitation' 2018-01-04 08:18:43 +01:00
xDraconian
7f7c632914 Simgear::test_precipitation test coverage
Lines:     0.0% >> 92.3%
Functions: 0.0% >> 97.1%

Memory leaks resolved - reclaiming 169kb in 126 blocks
No memory leaks remain
2018-01-03 12:40:49 +00:00
Alessandro Menti
e7356223bb CMakeLists.txt: explicitly enable the CMP0067 (C/C++ standard flags) policy
Explicitly enable the CMP0067 policy to have try_compile use the correct
C/C++ standard flags; otherwise, CMake will default to not honoring those,
causing the C/C++ checks to be compiled with no standard flags and SimGear
to be compiled with them. This causes errors if we try to detect a new
prototype which is only present in C++14 and above).
2018-01-03 11:54:04 +01:00
Florent Rougon
7547ad0391 Improve formatting of the HAVE_WORKING_STD_REGEX test
Indent the test code in a nicer way and shorten it, taking advantage of
this guarantee from the C++ standard:

  If control reaches the end of main without encountering a return
  statement, the effect is that of executing return 0.

-> no need for "#include <cstdlib>" nor for "return EXIT_SUCCESS".
2018-01-03 00:34:52 +01:00
Thomas Geymayer
ca30d6bb3d Add missing simgear_config.h include
Required for HAVE_STD_INDEX_SEQUENCE to be properly set.
2018-01-02 11:37:46 +01:00
Thomas Geymayer
ebd2cdb7a7 SGPickAnimation: fix member initialization order 2018-01-02 09:13:14 +01:00
Thomas Geymayer
52b8f60953 Add std::index_sequence for C++11
Will be required for nasal::Ghost
2018-01-02 08:00:49 +01:00
Florent Rougon
ab1e2d49ab Add a CMake check for a working <regex> implementation
Define HAVE_WORKING_STD_REGEX if, and only if <regex> is usable.

Normally, <regex> should be available and working in any compliant C++11
implementation, however at least g++ 4.8[1] lies about its C++11
compliance: its <regex> is utterly unusable, see [2] and [3] for
details.

[1] Which appears to be (precisely 4.8.5) the version shipped in
    CentOS 7, and used on FlightGear's current Jenkins installation.

[2] https://stackoverflow.com/a/12665408/4756009

[3] https://sourceforge.net/p/flightgear/mailman/message/36170781/
2017-12-29 13:46:42 +01:00
xDraconian
401bd1c643 Simgear::test_bucket code coverage
Lines:     82.1% >>  98.7%
Functions: 83.0% >> 100.0%

No memory leaks
2017-12-23 08:52:23 +00:00
xDraconian
53e6bec425 Tests: resolve several memory leaks 2017-12-17 10:06:20 +01:00
James Turner
f6ded69fa3 Untar failure path fixes
By xDraconian, ensure we call inflateEnd in failure cases, otherwise
the inflate context is leaked.
2017-12-11 18:14:40 +00:00
Thomas Geymayer
68053d64b5 function_list<>: Simplify with C++11 2017-12-04 08:47:51 +01:00
Richard Harrison
1f12966628 Add condition to knob animation.
This will prevent both input from being received and the position being updated by property change.
2017-12-04 07:53:39 +01:00
Richard Harrison
8d3723c91f Prevent nullptr exception in treenodes.
Happened to me once or twice mainly during reposition probably as scenery changed whilst still loading.
2017-12-04 07:33:45 +01:00
Richard Harrison
7dcc359110 add condition to pick animations 2017-12-04 07:31:59 +01:00
Richard Harrison
854881bba2 Prevent nullptr exception. Had this happen once. 2017-12-04 07:30:48 +01:00
Alessandro Menti
ddb7958f40 Remove old .spec files
Remove old SuSE/Red Hat packaging files (in line with what was done
in commit ef66ba in FlightGear).
2017-12-02 17:47:05 +01:00
Alessandro Menti
fe0d3fd448 Remove the dependency on the UTF-8 external library
Remove the dependency on the UTF-8 external library by writing the
UTF-8/code point conversion routines in KeyboardEvent.cxx.
2017-12-02 16:32:27 +01:00
Thomas Geymayer
15d5c878f3 canvas::NasalWidget: don't call unsafe method in destructor
Calling a virtual method in a destructor has undefined behaviour.
Furthermore passing 'this' to nasal from within the destructor
is not safe. 'onRemove' is called for widgets within layouts
on destruction anyhow, so no need to call it here again. If widgets
are arranged manually without any layout 'onRemoved' should be
called upon removing them from a dialog.
2017-12-01 08:14:44 +01:00
Thomas Geymayer
4f63c3f8a8 nasal::Object: Simplify with C++11
C++11 variadic templates finally allow us to get rid of the
ugly boost preprocessor workaround.
2017-12-01 07:32:49 +01:00
James Turner
b766ce76ff Package thumbnail caching tweaks
Resolves some issue with expired thumbnails not being reloaded
correctly.
2017-11-27 23:37:56 +00:00
ThorstenB
0b4b09958f Merge /u/thbr/simgear/ branch next into next
https://sourceforge.net/p/flightgear/simgear/merge-requests/41/
2017-11-24 21:58:52 +00:00
Florent Rougon
e12fc5a89d Use common definition of simgear::enumValue() from <simgear/sg_inlines.h>
This avoids code duplication.
2017-11-19 08:15:44 +01:00
Florent Rougon
bd3c351f1f Add function template simgear::enumValue() to simgear/sg_inlines.h
This function template is useful to get the value of a member of a
scoped enumeration, without having to hardcode its type while casting
it.
2017-11-19 00:45:47 +01:00
Florent Rougon
6064be33e5 SGPath: add comparison operators (<, >, <=, >=) and an std::hash specialization
This allows one to use SGPath in containers such as std::map,
std::unordered_map and std::unordered_set.

Like the existing == and !=, all these operators rely solely on the
UTF-8 internal representation of the path.
2017-11-19 00:45:47 +01:00
Florent Rougon
1540d6f472 SGPath: mark the str() and utf8Str() methods as 'noexcept'
We'll use this to cleanly declare std::hash<SGPath> as 'noexcept' in the
next commit, which appears to be desirable for std::hash template
specializations, according to:

  http://en.cppreference.com/w/cpp/utility/hash
2017-11-18 16:04:32 +01:00
Florent Rougon
1310092c0c SGPath: enable move operations
This is done by simply not user-defining the copy constructor,
copy-assignment operator and destructor. See [1] for more info.

[1] http://accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf

For the benchmark below (compiled with the next commit to allow sorting
SGPath instances), on Linux amd64 with g++ 6.3.0, I observe that
enabling SGPath move operations with this commit increases the
performance by 31% or 28% respectively, depending on whether I use this:

  // Typical code that creates a data structure in several steps and
  // benefits from move operations (the std::move() does nothing when
  // running the test with move operations disabled: a copy is made).
  auto p = SGPath::fromUtf8(randomString(0, 30));
  v.emplace_back(std::move(p));

or that:

  v.emplace_back(randomString(0, 30))

for the initialization code. Now the benchmark code:

using std::string;

static std::default_random_engine randomNumbersGenerator;

// Utility function: generate a random string whose length is in the
// [minLen, maxLen] range.
string randomString(string::size_type minLen, string::size_type maxLen)
{
  std::uniform_int_distribution<string::size_type> sLenDist(minLen, maxLen);
  std::uniform_int_distribution<int> byteDist(0, 255);
  auto randomByte = std::bind(byteDist, randomNumbersGenerator);

  string::size_type len = sLenDist(randomNumbersGenerator);
  string str;

  while (str.size() < len) {
    str += std::char_traits<char>::to_char_type(randomByte());
  }

  return str;
}

// The test function, run with nbIterations = 500000, minSize = 0 and
// maxSize = 200 to obtain the figures given above.
void SGPath_perfTest(std::size_t nbIterations,
                     std::size_t minSize, std::size_t maxSize)
{
  std::uniform_int_distribution<std::size_t> sizeDist(minSize, maxSize);
  auto randomSize = std::bind(sizeDist, randomNumbersGenerator);

  std::chrono::time_point<std::chrono::system_clock> start, end;
  start = std::chrono::system_clock::now();

  vector<SGPath> v;

  for (std::size_t i=0; i < nbIterations; i++) {
    v = vector<SGPath>{};          // start anew

    for (std::size_t j=0; j < randomSize(); j++) {
      v.emplace_back(randomString(0, 30));
    }

    std::shuffle(v.begin(), v.end(), randomNumbersGenerator);
    std::sort(v.begin(), v.end());
  }

  end = std::chrono::system_clock::now();
  std::chrono::duration<double> elapsedSecs = end - start;
  std::cout << elapsedSecs.count() << "\n"; // duration in seconds
}
2017-11-18 14:54:33 +01:00
ThorstenB
e485fac8ed Provide polar earth radius as a simgear constant. 2017-11-16 21:38:50 +01:00
Florent Rougon
55d75f18de Add missing include <algorithm> for std::max() and std::min()
This include was missing in several files from the simgear/hla
directory.
2017-11-16 16:00:14 +01:00
Florent Rougon
e8648a3f71 Add missing include <algorithm> for std::max() 2017-11-16 00:42:22 +01:00
Florent Rougon
0c7cabe46f SGSharedPtr: optimized version of the free function swap()
With this simple change, the speedup as compared to commit 18f048424 is
now 37 % for the benchmark given in the previous commit. This is because
optimized swap() only needs to swap the raw pointers, which is certainly
less work than the three move assignments on SGSharedPtr (not raw
pointers) done by std::swap().

To benefit from this, write code like:

  using std::swap;  // now useless for SGSharedPtr, but idiomatic
  swap(ptr1, ptr2); // *not* std::swap()!
2017-11-14 01:31:03 +01:00
Florent Rougon
a9ec3be2fd SGSharedPtr: the move constructor and move assignment operator are now 'noexcept'
This automatically makes SGSharedPtr more efficient when used in
standard containers (among others). See below for the benchmark details.

Mark as 'noexcept' (after checking it's legitimate!) the SGSharedPtr and
SGReferenced methods required for SGSharedPtr's move constructor and
move assignment operator to be guaranteed 'noexcept'.

Benchmark
---------

I measured a 25 % speedup with g++ 6.3.0 on Linux amd64, CFLAGS=-Wall -O2
as compared to commit 18f0484249 (which is
just before my changes to SGSharedPtr.hxx) on the following test code,
called with:

  nbIterations = 3000000
  minSize      =       0
  maxSize      =     200

------------------------------------------------------------------------
static std::default_random_engine randomNumbersGenerator;

class SGReferencedTestClass : public SGReferenced
{ int i; };

void SGSharedPtr_perfTest(std::size_t nbIterations,
                          std::size_t minSize, std::size_t maxSize)
{
  using Ref = SGSharedPtr<SGReferencedTestClass>;

  std::uniform_int_distribution<std::size_t> sizeDist(minSize, maxSize);
  auto randomSize = std::bind(sizeDist, randomNumbersGenerator);

  std::chrono::time_point<std::chrono::system_clock> start, end;
  start = std::chrono::system_clock::now();

  std::vector<Ref> v;

  for (std::size_t i=0; i < nbIterations; i++) {
    v = std::vector<Ref>{};          // start anew

    for (std::size_t j=0; j < randomSize(); j++) {
      auto p = Ref(new SGReferencedTestClass());
      v.emplace_back(std::move(p));
    }

    std::shuffle(v.begin(), v.end(), randomNumbersGenerator);
    std::sort(v.begin(), v.end());
  }

  end = std::chrono::system_clock::now();
  std::chrono::duration<double> elapsedSecs = end - start;
  std::cout << elapsedSecs.count() << "\n"; // duration in seconds
}
------------------------------------------------------------------------

Basically, these gains can be explained by the fact that copying an
SGSharedPtr requires to test SGReferenced::ref, increase the refcount,
and then when the object is destroyed, test again SGReferenced::ref,
decrease the refcount and test it in order to maybe delete. With the
move constructor and move assignment operator, copying the argument is
never necessary: its raw pointer can be swapped with the one contained
in *this, which is very fast. For the move constructor, this is all that
is needed; move assignment just needs one reset() call after that in
order to release the resource from the moved-from shared pointer.
2017-11-13 23:43:43 +01:00
Florent Rougon
abaaee1af2 Add simgear::noexceptSwap() to simgear/sg_inlines.h
This is a function template that is guaranteed to be 'noexcept' as long
as compilation succeeds. Idea and implementation from
<https://akrzemi1.wordpress.com/2011/06/10/using-noexcept/>.
2017-11-13 11:59:11 +01:00
Florent Rougon
6283a515b9 Fix missing headers in simgear/io/DNSClient.cxx and simgear/props/props_test.cxx
<algorithm> is needed for std::sort() and std::find().
2017-11-13 10:04:34 +01:00
Thomas Geymayer
ce7d463710 Fix wrong argument
One more catch by Florent Rougon.
2017-11-13 08:22:14 +01:00
Florent Rougon
bc3404fcbe SGSharedPtr: more efficient copy and move assignment operators
The copy-and-swap idiom is certainly very cute, but often causes
unnecessary copies. My commit fedafb9352
did exactly that, unfortunately.

Restore the exact same code for the copy-assignment operator as before
commit fedafb935, and add a more efficient implementation for the
move-assignment operator.

As explained by Howard Hinnant in [1] and [2], if some particular piece
of code really needs a strong exception safety guarantee, one can easily
add a specific method for that; this is not a valid reason to make the
code slower for all other places that have no use for such a guarantee!

[1] http://www.slideshare.net/ripplelabs/howard-hinnant-accu2014
[2] https://stackoverflow.com/a/9322542/4756009
2017-11-13 07:34:48 +01:00
Thomas Geymayer
bd87d3963a Fix leak in NasalObjectHolder
Thanks to Florent Rougon for spotting it.
2017-11-12 22:41:14 +01:00
Richard Harrison
fed449a801 Fix error message in axis object animation 2017-11-12 17:07:29 +01:00
Florent Rougon
19dd92d3e0 Remove or replace obsolete uses of throw()
In C++11, destructors are 'noexcept' by default -> remove useless
throw() specifiers. There was one case that wasn't about a destructor: I
replaced the 'throw()' with 'noexcept' because this use of 'throw()' is
deprecated and 'noexcept' offers the intended meaning as far as I can
guess (in C++17, 'throw()' will be equivalent to 'noexcept' anyway). For
more info, see:

  http://en.cppreference.com/w/cpp/language/noexcept_spec
  https://akrzemi1.wordpress.com/2013/08/20/noexcept-destructors/
2017-11-12 09:56:26 +01:00
Florent Rougon
f22b9ba9f1 SGSharedPtr: add unit tests
Add unit tests for move ctor and move assignment operator, as well for a
few other SGSharedPtr methods.
2017-11-11 17:55:54 +01:00
Florent Rougon
fedafb9352 SGSharedPtr: add move constructor and move assignment operator 2017-11-11 16:18:36 +01:00
Florent Rougon
18f0484249 Convert structure/shared_ptr_test.cpp to use the SG test macros (no more boost) 2017-11-11 01:29:49 +01:00
James Turner
10956056b3 Own code for UTF-32 <-> UTF-8 conversion
Avoids codecvt dependency on Unix where it might not be present, eg
with GCC 4.8; on Windows we use <codecvt> since it’s present in VS2015
to avoid writing a seperate UTF-16 <-> UTF-8 conversion.
2017-11-01 17:04:56 +00:00
Erik Hofman
e482f04123 int16_t needs cstdint 2017-10-31 11:22:39 +01:00
Erik Hofman
db89f0d4d1 Oops, use the proper project name 2017-10-31 10:49:04 +01:00
Erik Hofman
2ac97a9f1f std::wstring_convert requires locale 2017-10-31 10:47:12 +01:00
Erik Hofman
c03359a189 Update to the (now GPL) AeonWave version 3.0+ 2017-10-31 10:42:44 +01:00
Erik Hofman
84b636debc Add a frequency filter and a bitcrusher filetr 2017-10-31 10:42:16 +01:00
James Turner
2642299d77 We require C++11 now, simplify this code.
This ensures wstring to std::string conversion is always available,
needed for some HID work I’m doing on a branch,.
2017-10-29 13:20:39 +00:00
Richard Harrison
2a60e5e338 Added touch animation.
Designed for 2d objects, such as a canvas placements, this permits the receipt of touch (mouse click) events to enable the simulation of avionics with a touchscreen.

The coordinates are passed in as arguments to the action; these can be accessed with Nasal via the cmdarg() method.

example:

    <animation>
         <type>touch</type>
         <visible>true</visible>
         <object-name>VSDImage</object-name>
         <action>
             <touch>0</touch>
             <repeatable>false</repeatable>
             <binding>
                 <command>nasal</command>
                 <script>print("touch input
(",cmdarg().getNode("x").getValue(),",",cmdarg().getNode("y").getValue())</script>
             </binding>
         </action>
     </animation>
2017-10-29 01:04:36 +02:00
Florent Rougon
880c063d04 Remove useless readdir() calls in Dir::isEmpty()
simgear::Dir::isEmpty() used to make up to 5 calls to readdir(), while 3
are enough to say whether the directory has entries other than '.' and
'..'.

Also add an automated test for this method.
2017-10-27 20:49:17 +02:00
Florent Rougon
7a374c43dc Fix CMake test for std::isnan()
It used the wrong header; std::isnan() is defined in <cmath>.
2017-10-23 19:29:07 +02:00
Richard Harrison
7be1fcc32e Add method to copy entire properry subtree 2017-10-15 16:54:36 +02:00
Stuart Buchanan
b57dca66be Handle case where no tranform matrix exists. 2017-10-13 17:35:21 +01:00
Florent Rougon
d455f5f445 props_io.cxx: use SG_ORIGIN when throwing exceptions
This will provide more accurate info than the fixed string "SimGear
Property Reader".
2017-10-10 20:15:54 +02:00
Florent Rougon
2200fad30e Rename the ResourceProxy class to EmbeddedResourceProxy
This is done so as to avoid confusion with the unrelated classes
ResourceProvider and ResourceManager already present in SimGear.

Despite this new name, EmbeddedResourceProxy is a proxy not only for
embedded resources, but also for real files (hence the initial name
choice): its purpose is precisely to allow zero-work switching from one
data source to the other.
2017-10-07 16:36:49 +02:00
Florent Rougon
e5e112c3c2 Add a ResourceProxy class
The ResourceProxy class allows one to access real files or embedded
resources in a unified way. When using it, one can switch from one data
source to the other with minimal code changes, possibly even at runtime
(in which case there is obviously no code change at all).

Sample usage (from FlightGear for the globals->get_fg_root() bit):

  simgear::ResourceProxy proxy(globals->get_fg_root(), "/FGData");
  std::string s = proxy.getString("/some/path");
  std::unique_ptr<std::istream> streamp = proxy.getIStream("/some/path");

The methods ResourceProxy::getString(const std::string& path) and
ResourceProxy::getIStream(const std::string& path) decide whether to use
embedded resources or real files depending on the boolean value passed
to ResourceProxy::setUseEmbeddedResources() (also available as an
optional parameter to the ResourceProxy constructor, defaulting to
true). It is often most convenient to set this boolean once and don't
worry about it anymore---it's stored inside the ResourceProxy object.
Otherwise, if you want to fetch resources some times from real files,
other times from embedded resources, you may use the following methods:

  // Retrieve contents using embedded resources
  std:string s = proxy.getString("/some/path", true);
  std:string s = proxy.getStringDecideOnPrefix(":/some/path");

  // Retrieve contents using real files
  std:string s = proxy.getString("/some/path", false);
  std:string s = proxy.getStringDecideOnPrefix("/some/path");

(alternatively, you could use several ResourceProxy objects with
different values for the constructor's third parameter)
2017-10-01 07:54:17 +02:00
James Turner
dd3cdf63e6 Terrasync: Fix exception deleting orphaned directories. 2017-09-29 12:47:42 +01:00
Stuart Buchanan
a800189c25 Add support for Slippy Map Canvas layers.
- Add so-called Web Mercator projection and ability to choose
  projection for a Canvas Map.
- Add supporting functions for Slippy Maps (i.e. OSM)
2017-09-28 15:36:48 +01:00
James Turner
b342245619 Fix lib64 mode on Ubuntu 17.04 / CMake 3.7 2017-09-28 15:11:09 +01:00
James Turner
6cd5ac2d0d Move readTime (parse_time) from options.cxx 2017-09-27 15:06:37 +01:00
James Turner
872a48dacb Extend the state-machine parsing test slightly 2017-09-27 14:33:57 +01:00
James Turner
721aa544c9 Use C++11 in the state-machine code 2017-09-26 16:39:04 +02:00
Richard Harrison
7bfbda7188 Fix for AMD / Radeon rendering of lights as point sprites.
Tested against R9-290 and GTX 550 Ti (thanks Nikolai V. Chr.)
2017-09-24 22:10:44 +02:00
James Turner
602244979b Tar extractor can filter file paths. 2017-09-21 17:47:28 +01:00
Torsten Dreyer
8e29cae309 new version: 2017.4.0 2017-09-17 12:14:00 +02:00
Torsten Dreyer
2a73e6c0d5 new version: 2017.3.1 2017-09-17 12:14:00 +02:00
Richard Harrison
16b5dd5e78 Remove message "Could not find at least one of the following objects for axis animation" when not relevant.
By default you can either do

1. axis -> object-name ...
2. axis -> x-m ...
3. omit axis. This will now try to find an 'object-name' with -axis appended. If this can't be found then no message will be output; and the default behaviour of just using (0,0,0) will appyl.
2017-08-31 00:30:18 +02:00
James Turner
1aba20d642 Merge /u/gallaert/simgear/ branch next into next
https://sourceforge.net/p/flightgear/simgear/merge-requests/38/
2017-08-18 22:25:48 +00:00
Florent Rougon
27786d709d EmbeddedResourceManager: better API with respect to rehashing
Add a rehash() method to EmbeddedResourceManager::Impl to update
'poolSearchList'. Introduce a 'dirty' flag so that
EmbeddedResourceManager::Impl::rehash() is automatically called whenever
needed. It is not necessary anymore to call
EmbeddedResourceManager::selectLocale() after adding resources: changing
the EmbeddedResourceManager's locale or adding resources are both
operations that set the dirty flag. Whenever someone tries to fetch a
resource for the selected locale and the dirty flag is set, a rehash is
triggered before the actual fetching so as to ensure it is correct.
2017-08-16 23:49:19 +02:00
gallaert
e0e6a29150 CMake fails to detect OpenRTI include files. 2017-08-16 21:15:20 +01:00
Torsten Dreyer
dfd6076e19 Fix a warning 2017-08-12 22:34:52 +02:00
Alessandro Menti
e589ef8627 Remove the .spec file
Remove the .spec file as it is unused and we leave the packaging to
upstream (as it has been done with FlightGear).
2017-08-06 15:08:11 +02:00
Stuart Buchanan
e8c1baa396 Clear Uniform cache on reset. 2017-08-01 21:23:35 +01:00
James Turner
69ba2617d2 Fix thumbnail loading on Windows 2017-07-28 12:05:35 +01:00
James Turner
34c215ad83 Persistent thumbnail cache for aircraft packages
This should reduce the load on Ibiblio when browsing aircraft, the
package system caches thumbnails for seven days. Also we detect for
certain failure conditions and retry, to deal with Ibiblio’s rate-
limiting mechanism.
2017-07-28 11:38:59 +01:00
James Turner
2a3bb62001 Add efficient hasTag check to Package.
Avoids copying the tags set each time to check for presence / absence
of a particular tag.
2017-07-27 23:26:06 +01:00
James Turner
fe46ae09ef Fix MSVC build.
MSVC really needs these methods to be out of line, to avoid generating code for the shared pointers
in each translation unit which includes the header.
2017-07-19 13:00:33 +01:00
Ganael Laplanche
46f67fce7a Remove dependency to TR1.
TR1 will be deprecated in Boost 1.65, see:
https://github.com/boostorg/admin/issues/123
2017-07-17 14:49:51 +02:00
Torsten Dreyer
629e68428f Fix SimGear test target for change in commandmgr api 2017-07-07 08:56:13 +02:00
Richard Harrison
100439aadd Model relative property tree root binding.
This fixes the animation bindings to use the defined property tree root - to support multiplayer (or other) model that can bind to the correct part of the property tree.

Requires a corresponding fix in fg to allow the command methods to take an optional root parameter.

What this means is that when inside someone else's multiplayer model (e.g. backseat, or co-pilot), the multipalyer (AI) model will correctly modify properties inside the correct part of the property tree inside (/ai), rather than modifying the properties inside the same part of the tree as the non-ai model.

This means that a properly setup model will operate within it's own space in the property tree; and permit more generic multiplayer code to be written.

This is probably responsible for some of the pollution of the /sim property tree with MP aircraft properties.
2017-07-05 12:05:01 +02:00
Stuart Buchanan
f6a348ba94 Enable display lists for random trees. 2017-07-04 21:45:56 +01:00
James Turner
a54b3ffcee Extend Package delegate callbacks.
This makes it easier to report the status in the launcher, at least.
2017-06-28 22:27:40 +01:00
James Turner
47842c9ea7 Work-around older Curl on macOS 10.8n and earlier 2017-06-28 10:18:35 +01:00
Richard Harrison
834e25521b Axis based animation use ObjectName-axis as default if nothing specified. 2017-06-25 09:25:06 +02:00
James Turner
f78597f010 Merge /u/reavertm/simgear/ branch next into next
https://sourceforge.net/p/flightgear/simgear/merge-requests/35/
2017-06-21 10:52:24 +00:00
James Turner
c06e433e74 Templated lookup of subsystem-group members. 2017-06-15 18:30:27 +01:00
Maciej Mrozowski
9971d517fd Link shared SimGearScene with libgdal when enabled 2017-06-15 04:58:03 +02:00
Florent Rougon
f8548029a2 EmbeddedResourceManager.hxx: refine the previous MSVC workaround
The previous fix was successful, but a priori doesn't need to be applied
to *all* compilers that define _WIN32. Apply it only when _MSC_VER is
defined, and only to the template instantiations that MSVC doesn't
recognize (i.e., those that use a parameter from the variadic template).
2017-06-11 17:30:58 +02:00
Florent Rougon
3e337e3e97 Fix build errors related to template instantiations on Windows
The MS compiler doesn't seem to recognize our templates here:

g:\jenkins\workspace\simgear-win\source\simgear\embedded_resources\EmbeddedResourceManager.hxx(169): error C3190: 'std::shared_ptr<const simgear::AbstractEmbeddedResource> simgear::EmbeddedResourceManager::getResource(const std::string &,const std::string &) const' with the provided template arguments is not the explicit instantiation of any member function of 'simgear::EmbeddedResourceManager' (compiling source file G:\Jenkins\workspace\SimGear-Win\source\simgear\embedded_resources\EmbeddedResourceManager.cxx) [G:\Jenkins\workspace\SimGear-Win\build32\simgear\SimGearCore.vcxproj]
g:\jenkins\workspace\simgear-win\source\simgear\embedded_resources\EmbeddedResourceManager.hxx(169): error C2945: explicit instantiation does not refer to a template-class specialization (compiling source file G:\Jenkins\workspace\SimGear-Win\source\simgear\embedded_resources\EmbeddedResourceManager.cxx) [G:\Jenkins\workspace\SimGear-Win\build32\simgear\SimGearCore.vcxproj]

-> try without the explicit instantiations on Windows.
2017-06-11 10:29:43 +02:00
Florent Rougon
e59f8eda74 Embedded resources system: SimGear part
Add the EmbeddedResourceManager class as well as
AbstractEmbeddedResource and two derived concrete classes:
RawEmbeddedResource and ZlibEmbeddedResource.

The purpose of this is to provide a way for FlightGear to use data from
files without relying on FG_ROOT to be set. The whole system (SimGear
and FlightGear parts) was described in detail at [1]. I'll probably
include a copy in $FG_ROOT/Docs too for fear of the link becoming dead
one day.

Basically, classes derived from AbstractEmbeddedResource provide access
to some data---the source of which is a priori of static storage
class---and handle the conversion from whatever format it is stored in
to allow convenient use of said data. At the very least, they allow
obtaining ready-to-use data as an std::string, as well as reading it
incrementally via an std::streambuf or an std::istream interface.
ZlibEmbeddedResource instances also provide access to the compressed
size of the data (i.e., as stored in static memory) as well as its
uncompressed size, without requiring any prior decompression.

EmbeddedResourceManager is a class which FlightGear will normally
instantiate exactly once---it has createInstance() and instance() static
methods for this. It maintains a map between resource paths and
instances of concrete classes derived from AbstractEmbeddedResource. It
also provides convenience methods allowing to access a resource data in
one step (not requiring to manually fetch the
AbstractEmbeddedResource-derived object corresponding to the given
resource path before calling the appropriate method of this object).

From the EmbeddedResourceManager's point of view, resource paths (keys
of the map) are just plain std::string instances in the current
implementation. However, unless there is a good reason not to, I think
it's a good idea to only use values obtained with SGPath::utf8Str()[2].
This is precisely what fgrcc, the resource compiler in the FlightGear
repository, does; so, unless you register resources manually, your
resource paths will automatically comply with this suggestion.

[1] https://sourceforge.net/p/flightgear/mailman/message/35870025/
[2] This allows later addition of methods listing all resources under a
    given virtual path, as well as optimized resource lookup using a
    tree-like data structure instead of an std::unordered_map (not
    justified now IMO).
2017-06-10 23:38:59 +02:00
Florent Rougon
31e70b205c CharArrayStream_test: fix failing test (logic error in the test code) 2017-06-10 20:59:15 +02:00
Florent Rougon
5d02f1db5f CharArrayStream_test.cxx: attempt to fix build errors on Windows 2017-06-10 16:58:16 +02:00
Florent Rougon
b01bd93a20 Add CharArrayStreambuf and related IOStreams classes for working with char arrays
Add the following classes in the 'simgear' namespace:
  - CharArrayStreambuf    subclass of std::streambuf      stream buffer
  - ROCharArrayStreambuf  subclass of CharArrayStreambuf  stream buffer
  - CharArrayIStream      subclass of std::istream        input stream
  - CharArrayOStream      subclass of std::ostream        output stream
  - CharArrayIOStream     subclass of std::iostream       input/output stream

CharArrayStreambuf is a stream buffer class allowing to read from, and
write to char arrays (std::strstream has been deprecated since C++98).
Contrary to std::strstream, this class does no dynamic allocation: it is
very simple, strictly staying for both reads and writes within the
limits of the buffer specified in the constructor. Contrary to
std::stringstream, CharArrayStreambuf allows one to work on an array of
char (that could be static data or on the stack) without having to make
a whole copy of it.

CharArrayStreambuf supports reading and writing (including efficient
implementations of xsgetn() and xsputn()), seeking (with independent
read and write stream pointers, as for std::stringstream) and putting
back chars up to the beginning of the char array. The internal buffer
for both reads and writes is defined to be the whole buffer specified in
the constructor call. As a consequence, flushing the stream buffer with
pubsync() is useless: data is always written directly to the buffer
passed to the constructor, never to an intermediate buffer.

Of course, this buffer must remain available as long as the stream
buffer object is used.

ROCharArrayStreambuf is a read-only subclass of CharArrayStreambuf.
CharArrayIStream, CharArrayOStream and CharArrayIOStream are very simple
convenience stream classes using either CharArrayStreambuf or
ROCharArrayStreambuf as their stream buffer class.
2017-06-10 09:45:15 +02:00
Alessandro Menti
05bbba5074 Remove the last traces of enhanced lighting support
Remove some traces of the enhanced lighting support which were left
there from a refactoring several years ago.

See discussion at <https://sourceforge.net/p/flightgear/mailman/message/35875305/>
2017-06-04 16:51:27 +02:00
Automatic Release Builder
679d4e1dcd new version: 2017.3.0 2017-05-18 15:15:48 +02:00
Automatic Release Builder
aaa6231f89 new version: 2017.2.1 2017-05-18 15:15:48 +02:00
Erik Hofman
446c8cd70c Fix a bug when using properties instead of a fixed position 2017-05-17 08:28:01 +02:00
Richard Harrison
11ff1d256c Fix mesh visibility on pick animations.
(caused by incorrectly overloaded methods)
2017-05-11 19:17:24 +02:00
Richard Harrison
4acd047982 Fix animation axis text for new calling conventions.
NOTE: the transient model data as initialized contains nullptrs for mostly everything - except the required data for this test.
2017-05-11 13:02:40 +02:00
Erik Hofman
ee4b6621e7 Fit the property definied positions to the axis definition by negating them 2017-05-11 10:29:08 +02:00
Richard Harrison
77517b15fd Allow animations to take an object as the centre and axis.
Applicable to / works with rotate, translate and knob. Once the axis object-name has been used it will be hidden, however it still can be used for object-name animations. The hiding of the axis object is a useful guide as to what is left to be wired up to animations.

This allows the follow to work (on a combined ASI / Mach instrument).

 <animation>
    <type>rotate</type>
    <object-name>asi-needle</object-name>
...
    <axis>
      <object-name>airspeed-asi-axis</object-name>
    </axis>
  </animation>
  <animation>
    <type>rotate</type>
    <object-name>asi-mach-scale</object-name>
...
    <axis>
      <object-name>airspeed-asi-axis</object-name>
    </axis>
  </animation>
2017-05-11 06:32:27 +02:00
Florent Rougon
19a86a6f0d Change license from GPL2+ to LGPL2.0+ for the SimGear files I wrote
Change as per the FlightGear Policy Document:

  http://www.flightgear.org/flightgear-policy-document/
2017-05-10 17:03:50 +02:00
Stuart Buchanan
a7dee1164d materials.xml support for osm2city Buildings etc. 2017-05-09 14:30:57 +01:00
Erik Hofman
7512bc0fb2 Make position properties work for relative positions too 2017-05-09 10:57:31 +02:00
Florent Rougon
d6b57d0937 Fix MSVC warning: redefinition of default template parameter
The default values for template parameters don't have to be repeated in
the .cxx file, apparently.
2017-05-03 19:11:30 +02:00
Florent Rougon
1e99c4b2ec Add function template simgear::strutils::readNonNegativeInt()
This function is similar to simgear::strutils::to_int(), except it is:

  - generic: the return type, selected with the first template
    parameter, can be an arbitrary integral type. This type also defines
    the set of accepted input strings ("values").

  - stricter regarding the input: it must be non-empty and contain only
    valid digits for the specified base (second template parameter). If
    the input doesn't conform to these constraints or is too large to
    fit into the specified type, an exception with a suitable error
    message is raised.

  - faster (12 to 17 times as fast as simgear::strutils::to_int() on my
    system, depending on compilation flags): this is probably a
    consequence of not using std::stringstream to do the conversion.

The function template is only instantiated for <int, 10> and
<unsigned int, 10> in order to be sure not to waste memory (see comments
in strutils.cxx). If you need it for other combinations of type and
base, just enable them by adjusting the corresponding '#if 0 / #endif'
pairs in strutils.cxx and strutils_test.cxx.
2017-05-03 16:33:53 +02:00
Torsten Dreyer
04ca3ad8f4 Fix bug "dns timeout, no terrasync servers found"
The existance of a dns entry with a protocol defined caused the
naptr callback being terminated early and the request never completed.
This patch also adds a unit test for this particular case.
test_dns now also accepts up to two command line parameters:
first: dns DN to query for NAPTR records (default: terrasync.flightgear.org)
second: service to query (default: empty)
2017-05-03 10:41:11 +02:00
Florent Rougon
2b8915e35f zlibstream.cxx: explicitly mark as virtual the inherited virtual methods
Since the virtuality of a method is inherited by derived classes, this
makes the virtual status of such methods clearly visible in the
declarations of derived classes.
2017-04-30 16:19:50 +02:00
Florent Rougon
2a0801da6b zlibstream*: use C++11 scoped enumerations instead of C-style enums
These enumerations are those declared with 'enum class' instead of just
'enum' (cf. §7.2 of the C++11 standard).

+ add missing include (<zlib.h>)
2017-04-30 15:45:52 +02:00
Florent Rougon
2935d78490 Fix build failure in strutils_test.cxx
The Windows and Mac builders on jenkins complain that '\U12345678' is
an invalid universal character; let's try with '\U000000E9' instead,
which should be LATIN SMALL LETTER E WITH ACUTE.

Also replace '\uab42' with '\u00e0' to remove a warning on the Windows
builder, due to the fact that '\uab42' cannot be represented in the
current code page (1252). This doesn't mean '\uab42' was incorrect,
though; I'm only changing this to make the warning disappear.
2017-04-28 23:16:15 +02:00
Florent Rougon
2404924bcb Add function strutils::escape()
This function complements the existing strutils::unescape(). It
backslash-escapes a string for C/C++ string literal syntax.

For every std::string s, the following holds:

  unescape(escape(s)) == s

(not the other way around, because there are many ways to escape a given
character in a string literal)
2017-04-28 22:24:21 +02:00
Florent Rougon
e4c4db5cf9 strutils::unescape(): minor change
Use static_cast<char> for clarity when adding an int to an std::string
with std::string::operator+=().
2017-04-28 22:14:52 +02:00
Florent Rougon
e1c655c570 strutils::unescape(): fix handling of hexadecimal escape sequences
Hexadecimal escape sequences have no length limit and terminate at the
first character that is not a valid hexadecimal digit.
2017-04-28 22:14:52 +02:00
Florent Rougon
2788da9c51 strutils::unescape(): fix off-by-one error
An octal escape sequence in a string literal can't have more than 3
octal digits after the backslash. The previous code was using up to 4
digits per octal escape sequence.
2017-04-28 22:14:35 +02:00
Erik Hofman
4860a70443 Fix (hopefully) sim4_t class initialization problems 2017-04-27 14:54:21 +02:00
Florent Rougon
22d1433ab0 argparse.cxx: allow arguments consisting of a single '-'
Such an argument is /a priori/ perfectly valid, and not an option.
Typical use in a command line:

  -o -

equivalent to:

  -o-

The former way wasn't accepted before this commit; now it is (also
'--output -', equivalent to '--output=-').

If the last option is followed by an argument consisting of a single
'-', this argument marks the end of options and is the first non-option
argument (contrary to '--' which, given its special status, would mark
the end of options but would *not* count as a non-option argument).

This commit also adds an std::string length check in
ArgumentParser::parseArgs() that was missing before using operator[]()
(important difference between operator[]() for std::string and std::map
or std::unordered_map!).
2017-04-21 22:30:45 +02:00
Florent Rougon
ef9eedf35a Fix misleading indentation in sg_path.cxx (g++ warning) 2017-04-15 09:33:27 +02:00
Florent Rougon
a962c90b30 Change SGPath::pathListSep into a const char array of size 2
Previously, SGPath::pathListSep was a char in static memory, that could
be followed by anything (often '\0', as it seems... but not always).
This is (was) dangerous, because it is then tempting to take its address
and pass it to functions expecting a char * corresponding to a
null-terminated string (C-style).

SGPath::pathListSep is now a static array of two const chars: the path
list separator followed by a '\0'. This implies that
&SGPath::pathListSep can now be reliably interpreted as a C-style string
of length 1 (not counting the null terminator), containing only the path
list separator.
2017-04-15 09:29:59 +02:00
Florent Rougon
36275f5cce Add classes to ease writing command line parsers with GNU-style options handling
See simgear/misc/argparse.hxx for API and documentation
(simgear/misc/argparse_test.cxx also has examples, although argparse.hxx
features a very simple one at the top).

These classes were also presented in
<https://sourceforge.net/p/flightgear/mailman/message/35785019/>.
2017-04-13 11:04:01 +02:00
James Turner
60d1c87cef New string helper function: property path matching
Match property path strings against template strings containing wild
card characters.
2017-04-13 07:29:05 +01:00
Stuart Buchanan
9223f30f08 Improve warning of object in wrong bucket.
Reduce level to DEV_WARN from DEV_ALERT as it's
largely benign.
2017-04-07 21:20:42 +01:00
James Turner
fe87e7f60d Define SG_DEPRECATED, remove unused DEPRECATED.
Use this to mark two Package APIs as deprecated.
2017-04-05 22:09:52 +09:00
James Turner
f3e83cf020 Package APIs to support multiple primary aircraft.
This (with some catalog and front-end changes) will allow packages to
supply multiple primary aircraft.
2017-04-04 07:04:43 +02:00
Richard Harrison
9eee41d74a Add logging support for hexdumps 2017-04-02 17:56:31 +02:00
Florent Rougon
991d76b69e Fix build failure due to missing <osg/Version> include
Failure observed on Debian jessie with openscenegraph 3.2.1-6.
2017-04-01 15:58:07 +02:00
Richard Harrison
6f0c7da6ad OSG 3.5.x support 2017-03-30 03:58:27 +02:00
James Turner
c170f576b6 Ensure <simgear_config.h> is always included.
This is going to become important soon - prep for enabling SIMGEAR_SHARED on Windows.
2017-03-28 09:36:53 +01:00
Erik Hofman
1446f559cc Add -fPIC to make FlightGear's shared library linking for fgtestlib happy 2017-03-26 10:17:10 +02:00
James Turner
4467e68db1 Make test macros public. 2017-03-24 16:52:02 +00:00
James Turner
cc1118b330 And make Windows happier again. 2017-03-19 12:16:10 +00:00
James Turner
a1126bd42c Make the LogStreamPrivate a d-ptr. 2017-03-19 10:28:57 +00:00
James Turner
370523d5bf Remove sgGMTime, no longer used.
(And the implementation was wrong on Windows)
2017-03-17 23:25:25 +00:00
James Turner
96b4d2c03d Make debugClassToString a public static.
This helps with implementing log-callbacks in other places, which
the unit-testing framework does.
2017-03-17 23:22:59 +00:00
James Turner
c4898502bf Use std::unique_ptr to avoid leaking logging
This makes calling shutdownLogging unnecessary on exit.
2017-03-17 23:22:59 +00:00
Florent Rougon
f7a511d1b3 Fix includes in zlibstream.hxx
Forward declarations of std::streambuf and std::istream are not enough,
since this file declares classes derived from them.
2017-03-14 20:24:32 +01:00
Florent Rougon
b66c51a6f8 Fix handling of SG_LOG()'s second argument
The popup/no popup logic in SG_LOG() could be wrong before this commit,
because of missing parentheses around uses of the second macro argument.
For instance, this:

  SG_LOG(SG_NAVCACHE, t == 0 ? SG_WARN : SG_ALERT, "Message");

could cause a popup window to be displayed even though neither SG_WARN
nor SG_ALERT should do that in the current state of the logging system.

Thanks to Szymon Acedański for finding this.
2017-03-09 10:25:40 +01:00
Torsten Dreyer
a4cf38925b move TS dns lookup into the worker thread 2017-03-07 11:32:39 +01:00
Torsten Dreyer
41059a24a7 Fix indention, no functional change 2017-03-07 09:22:05 +01:00
Erik Hofman
ee4f5a5190 Disable SIMD for now as a test. 2017-02-28 12:42:48 +01:00
James Turner
141e98564c Generic string -> bool parser. 2017-02-27 23:11:05 +00:00
James Turner
72341a6de4 Adjust some messages to be developer-mode.
Still deciding how far to go with this, comments welcome.
2017-02-27 00:13:39 +00:00
Bertrand Coconnier
55ee59ac99 Flags ENABLE_GDAL and ENABLE_OPENMP are now carried over to FlightGear. 2017-02-26 16:39:48 +01:00
Peter Sadrozinski
61525c555e Disable GDAL, and compiling new terrain engine by default 2017-02-26 09:46:29 -05:00
Peter Sadrozinski
dad30b0cc2 alternative terrain engine - SGMesh utilizing pagedLOD 2017-02-25 19:17:55 -05:00
James Turner
9c9e4e86e7 Packages allows thumbnails per variant.
Change API for thumbnail access, so each variant can have a unique thumbnail alongside other data. Map existing catalog XML format to
this system.
2017-02-25 20:52:35 +00:00
James Turner
b88aa46e1c Merge /u/accek/simgear/ branch prop-strings into next
https://sourceforge.net/p/flightgear/simgear/merge-requests/32/
2017-02-25 16:36:49 +00:00
Bertrand Coconnier
10fa8a471a SGPath::set is called by SGPath::operator=(const char*p) so it needs to be unconditionnally compiled. 2017-02-25 16:02:36 +01:00
Szymon Acedański
4e875be0dd Added SGStringValueMethods property implementation
This is to be used in places where SGRawValueMethods returning .c_str()
from local strings were used, causing use-after-free later.
2017-02-25 15:02:37 +01:00
Bertrand Coconnier
23cc940743 gcc fails to catch std::ios_base::failure due to an inconsistent C++11 ABI between headers and libraries. See bug#66145 for more details (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145). 2017-02-25 14:38:38 +01:00
Florent Rougon
4b010cc416 Minor change to simgear/io/iostreams/zlibstream_test.cxx 2017-02-25 11:30:16 +01:00
Florent Rougon
46f39d5fbd zlibstream classes: add constructors with sink semantic based on std::unique_ptr
Add an alternate constructor to each of the following classes:
ZlibAbstractIStreambuf, ZlibCompressorIStreambuf,
ZlibDecompressorIStreambuf, ZlibCompressorIStream and
ZlibDecompressorIStream. These new constructors are passed the source
std::istream wrapped inside an std::unique_ptr instead of by reference,
and store the unique_ptr object as an instance member. This ensures that
the source std::istream object is available as long as the
ZlibDecompressorIStreambuf, etc. instance is alive (which is necessary
for its getInputData() method) without any additional work for callers,
and that it is automatically destroyed afterwards.

This is particularly useful when writing functions that create and
return an object 'zobj' whose type is a subclass of
ZlibAbstractIStreambuf, when the source std::istream is only of interest
for its role of feeding data to 'zobj'. For instance:

std::unique_ptr<simgear::ZlibCompressorIStream>
myZlibCompressorIStreamProducer(std::string str)
{
  std::unique_ptr<std::istringstream> iss(new std::istringstream(str));

  return std::unique_ptr<simgear::ZlibCompressorIStream>(
    new simgear::ZlibCompressorIStream(std::move(iss))); // new ctor here
}

Callers of such a function get access to a new ZlibCompressorIStream
instance fed by an std::istringstream object ('iss'), but they don't
even have to know this detail, nor to take any measure to ensure that
'iss' lives at least as long as the ZlibCompressorIStream object. The
std::unique_ptr<std::istream> pointing to 'iss' and stored as a member
of the ZlibCompressorIStream object by its constructor automatically
takes care of this lifetime problem.
2017-02-24 22:51:21 +01:00
Florent Rougon
03515151f0 Add new test trying to read max amount with ZlibDecompressorIStreambuf::xsgetn()
New automated test for ZlibDecompressorIStreambuf::xsgetn(). xsgetn() is
called by sgetn() from the base class std::streambuf. In our case,
xsgetn() is actually defined in the base class ZlibAbstractIStreambuf
(subclass of std::streambuf), therefore this new test also applies to
ZlibCompressorIStreambuf and the two other related classes,
ZlibCompressorIStream and ZlibDecompressorIStream.

This test asks [x]sgetn() the largest possible amount of chars every
time it is called, i.e., the largest value that can be represented by
std::streamsize. This exercises the code in interesting ways due to the
various types involved (zlib's uInt, std::size_t and std::streamsize,
which have various sizes depending on the platform).
2017-02-24 22:51:21 +01:00
Florent Rougon
8cd723d91b Fix build errors in zlibstream*.cxx, re-enable their compilation
Compilation of these files was disabled in commit
e21ad4b5c1.

Fix build errors and warnings:

  - Ambiguous template parameters for std::min();

  - No appropriate default constructor available for
    std::basic_istream<char,std::char_traits<char>> (the std::istream
    subclasses didn't explicitly call the std::istream constructor,
    which requires an argument). This is presumably exactly the reason
    why sg_gzifstream is declared like this:

      class sg_gzifstream : private gzifstream_base, public std::istream

    where gzifstream_base is an empty shell for a stream buffer object:

      struct gzifstream_base
      {
          gzifstream_base() {}

          gzfilebuf gzbuf;
      };

    This ensures that the stream buffer object (gzbuf) is initialized
    before std::istream's constructor is called. I solved this problem
    in a different way, hopefully easier to understand, and requiring
    neither an additional class nor multiple inheritance: first, we
    initialize the std::istream base with a nullptr as the
    std::streambuf * argument (this is valid C++11), then in the
    constructor bodies for ZlibCompressorIStream and
    ZlibDecompressorIStream, we call std::istream::rdbuf() to attach the
    std::istream instance to the now-initialized stream buffer object.

  - Possible truncation of constant value on 32 bits systems (this was
    in zlibMaxChunkSize() which is now removed, see below).

Type-related improvements:

  - Remove zlibMaxChunkSize() and zlibMaxChunk: in C++, one can simply
    use std::numeric_limits<uInt>::max()---most of the code in
    zlibMaxChunkSize() was there only to find this value via a zlib
    function call.

  - Add helper function templates zlibChunk() and clipCast().

  - Split preparation of the putback area out of
    ZlibAbstractIStreambuf::xsgetn() to a new utility method:
    xsgetn_preparePutbackArea().

  - More rigorous type handling in zlibstream_test.cxx.

    Some precautions are necessary because the IOStreams API uses
    std::streamsize in many places (e.g., the return value of
    std::istream::gcount()), but functions such as the following
    std::string constructor:

      std::string(const char* s, std::size_t n);

    work with std::size_t instead. Since these types are different and
    opaque, this requires some care!
2017-02-24 22:51:21 +01:00
Torsten Dreyer
6f2943ed9a disable service test for now 2017-02-23 18:34:48 +01:00
Torsten Dreyer
e509fc3f5d Prepare for terrasync/https 2017-02-23 16:35:29 +01:00
James Turner
707d9e12cf Fix issues with package upgrades on Windows. 2017-02-23 13:26:02 +00:00
Automatic Release Builder
9840302931 new version: 2017.2.0 2017-02-20 18:52:12 +01:00
Automatic Release Builder
983047982f new version: 2017.1.1 2017-02-20 18:52:12 +01:00
James Turner
f977be5fe4 Concept for developer log messages. 2017-02-14 18:27:40 -08:00
Florent Rougon
e21ad4b5c1 Disable building of zlibstream.cxx for now
It is unclear to me how to correctly fix some of the remaining build
errors obtained on jenkins, therefore I am disabling it from the build
for now.
2017-02-12 23:55:03 +01:00
Florent Rougon
619055f544 Attempt at fixing build errors for simgear/io/iostreams/zlibstream.cxx
Apparently (on Jenkins), std::unordered_map doesn't like enums as keys.
Too bad, this made the code more compact...
2017-02-12 22:22:08 +01:00
Florent Rougon
c9611fc45b Add stream buffers and std::istream subclasses to deal with zlib compression
Add:
 - two stream buffer classes (ZlibCompressorIStreambuf and
   ZlibDecompressorIStreambuf), both based on the same abstract class:
   ZlibAbstractIStreambuf;
 - two std::istream subclasses (ZlibCompressorIStream and
   ZlibDecompressorIStream), each creating and using the corresponding
   stream buffer class from the previous item.

All these allow one to work with RFC 1950 and RFC 1952 compression
formats, respectively known as the zlib and gzip formats.

These classes are *input* streaming classes, which means they can
efficiently handle arbitrary amounts of data without using any disk
space nor increasing amounts of memory, and allow "client code" to pull
exactly as much data as it wants at any given time, resuming later when
it is ready to handle the next chunk.

See comments in simgear/io/iostreams/zlibstream.hxx for more details.
2017-02-12 21:18:52 +01:00
Florent Rougon
79f869a7f3 Move IOStreams-related files to simgear/io/iostreams; rename zfstream.[ch]xx to gzfstream.[ch]xx
- Rename zfstream.cxx (resp. zfstream.hxx) to gzfstream.cxx (resp.
  gzfstream.hxx)

  This is because these files only deal with the gzip format (RFC 1952),
  while zlib can actually read and write two slightly different formats:
  this one and the "ZLIB Compressed Data Format" (RFC 1950). Since I am
  going to add std::streambuf and std::istream subclasses able to deal
  with both formats (and supporting data sources that are general
  std::istream instances, not just files), this renaming will make
  things a bit clearer, I hope.

- Add new folder simgear/io/iostreams and move the following files to
  this folder:

    simgear/misc/gzcontainerfile.cxx
    simgear/misc/gzcontainerfile.hxx
    simgear/misc/gzfstream.cxx
    simgear/misc/gzfstream.hxx
    simgear/misc/sgstream.cxx
    simgear/misc/sgstream.hxx
    simgear/misc/sgstream_test.cxx

- Adapt other files accordingly (mainly #includes and CMakeLists.txt
  files).
2017-02-12 21:18:52 +01:00
Torsten Dreyer
1b8dfb2bef Accept time token for .dirindex files
print the timestamp on log-level "info"
2017-02-12 17:39:12 +01:00
Richard Harrison
143a47482b Change the log level of the "failed to load sound buffer" as it shouldn't be a popup because within my interpreation it is not within the definition of what POPUP should be used for. 2017-02-11 13:34:01 +01:00
James Turner
a28cf0f860 Additional SGPath test for remove + rename.
Trying to track down failure to update aircraft on Windows.
2017-02-09 18:48:05 +00:00
James Turner
d9f4d7373f SGFile uses wide-string APIs on Windows. 2017-02-07 16:15:14 +00:00
James Turner
c3f48c7261 Use sg_ofstream in one more place. 2017-02-07 16:05:06 +00:00
James Turner
48b7b70e23 BinObj code uses wide-strings on Windows. 2017-02-07 16:05:06 +00:00
James Turner
b93b362e2f Fix wide-string support for wav-file reader. 2017-02-07 16:05:06 +00:00
Bertrand Coconnier
2082b18e2e Export the symbol ENABLE_SIMD for FG to build with the same setting. 2017-02-07 00:02:39 +01:00
Erik Hofman
7f65e7f905 We need to copy the matrix before altering it's contents: Fix a SGMathTest failure 2017-02-03 15:07:35 +01:00
Erik Hofman
3417ca7e49 Add a linear-interpolation function 2017-02-02 11:35:11 +01:00
Richard Senior
6334c30eb6 Allow empty reason string in validation of HTTP response.
HTTP/1.0 and HTTP/1.1 allow the reason string to be empty.
Some servers produce empty reason strings on success,
e.g. "HTTP/1.1 200 ", which throws a "bad HTTP response"
exception.

From the specification:
    "Reason-Phrase  = *<TEXT, excluding CR, LF>"

From notational conventions:
    "*(element) allows any number, including zero"

References:
www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2
www.w3.org/Protocols/HTTP/1.0/spec.html
www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
2017-02-01 10:23:10 +00:00
Erik Hofman
c87dff7e8f More code cleanups ans fix a Clang problem. And disable AVX for good, I don't have time for this crap anymore: it looks like a hardware or compielr bug 2017-01-31 00:04:01 +01:00
Erik Hofman
332f76f34d Last code cleanups and more explicit constructors 2017-01-30 18:25:42 +01:00
Erik Hofman
3387f3d084 Switch to c++11 alignas instead of our own hacks 2017-01-30 16:00:29 +01:00
Erik Hofman
bd421c381c Also make AVX available for simd4x4 2017-01-30 12:53:52 +01:00
Erik Hofman
0cce949837 Fix the last bug that prevented AVX from working properly. Hopefully this fixes all other SIMD related problems too 2017-01-30 12:25:51 +01:00
James Turner
ed3ba67925 Logging system buffers startup messages.
This allows adding log callbacks easier during startup, without 
missing the initial messages, which might be very important.
2017-01-30 07:43:35 +01:00
Erik Hofman
866f85064a Fix a mistake 2017-01-30 00:18:36 +01:00
Erik Hofman
9215c530b3 Explicit declaration of more constructors to make sure the laste lane of simd4_t<T,3> and the last two lanes of simd4_t<T,2> remain zero 2017-01-29 15:26:34 +01:00
James Turner
a6437f4e96 More SGPropertyNode::getPositions tests. 2017-01-28 15:37:41 +00:00
James Turner
5bd7be6ed1 Check for file permissions via SGPath. 2017-01-28 15:37:41 +00:00
Florent Rougon
d9cc3738b9 Improve sgstream_test.cxx
- Create "testfile" in a temporary directory (and make sure the temp dir
  and the file it contains are both removed when the test program exits).

- Use test macros such as SG_CHECK_EQUAL() instead of by-hand checks and
  "return EXIT_FAILURE" statements.

- Use sg_ofstream instead of plain std::ostream. This simplifies things
  a tiny bit, because one SGPath instance is enough to create both the
  sg_ofstream instance and the sg_gzifstream instance used afterwards to
  reread the created file.

- Don't call (sg_)ofstream::close() at the end of the block the instance
  is declared in: this is entirely unnecessary, since sg_ofstream
  derives from std::ofstream, which is automatically close()d when
  destroyed (RAII behavior).
2017-01-26 16:58:20 +01:00
Erik Hofman
edec5bbc01 There is still a segmenttion fault issue with the AVX code, disable it until this is sorted out 2017-01-26 14:46:36 +01:00
Florent Rougon
6a2d86c526 Small improvements for simgear::Dir
- Add method simgear::Dir::isNull(), analogous to SGPath::isNull().

- Make sure that simgear::Dir::tempDir() returns a null simgear::Dir
  instance when creation of the directory failed (so far, this was only
  the case on systems where HAVE_MKDTEMP is defined).

- Use simgear::strutils::error_string() instead of strerror() (the
  latter is not guaranteed to be thread-safe).

- Make sure <cerrno> is #included, regardless of the platform.

- Add automated tests for isNull(), setRemoveOnDestroy() and tempDir().
2017-01-26 12:41:59 +01:00
Stuart Buchanan
6c64e9b36c Add scenery-path-suffix support to terrasync
Remove /sim/rendering/building-mesh as it is
redundant.

Add check that objects are in the correct bounding
box of the containing STG file.
2017-01-21 22:19:38 +00:00
Erik Hofman
bcecee0f76 Small optimization to my own cross product implementation 2017-01-21 10:28:24 +01:00
Richard Harrison
c5cdfa1a1d Prevent null pointer deference when load has failed.
This was triggered by the TU154B; probably related to the console error

* "Image loading failed:Warning: reading "fgdata\AI\Aircraft\tu154b\Model" not supported.
2017-01-21 00:54:30 +01:00
Erik Hofman
f9f2b4cbdb Bring the ARM NEON code in line with the SSE code 2017-01-20 15:32:28 +01:00
Erik Hofman
33feb9a416 Move SIMD flags to CMAKE_CXX_FLAGS_RELEASE and fix a typo in the process 2017-01-20 14:56:15 +01:00
Erik Hofman
9e1aaa8b56 Make a distinction between a null-pointer and the value of 0 2017-01-19 23:14:39 +01:00
Erik Hofman
ef2eb635af Fix a header path 2017-01-19 16:41:01 +01:00
Erik Hofman
2db412a923 Specialize class constructors in the hope to ged rid of wrong compiler assignment of an unaligned float array to an SSE register 2017-01-19 16:39:30 +01:00
Erik Hofman
061fea48c8 Add an ARM NEON readu simd4x4_neon.hxx and small fixes for simd_neon.hxx 2017-01-19 13:20:52 +01:00
Erik Hofman
c4ea62a899 Add a version of simd.hxx for ARM NEON 2017-01-18 15:41:12 +01:00
Erik Hofman
789c09a402 I forgot the linux variant of ALIGN 2017-01-12 14:19:09 +01:00
Erik Hofman
de9b329115 reorganize the code a bit 2017-01-12 11:43:46 +01:00
Erik Hofman
1b793a127c Be more explicit about alignment 2017-01-12 10:18:39 +01:00
James Turner
3cb3084725 Rename ‘new’ thumbnails to ‘previews’
This avoids an XML naming clash, and allows both systems to exist in
parallel peacefully. Update the tests to check both the thumbnails
and preview system in parallel with each other.
2017-01-10 18:05:40 +00:00
Erik Hofman
637f67888a Reinstate AVX support again 2017-01-07 13:55:09 +01:00
Erik Hofman
fbc0986fd8 Do not rely on SSE3, this is just a slight drawback 2017-01-06 15:10:52 +01:00
Erik Hofman
14ebe0b618 Disable AVX support until someone figures out why it is not working properly 2017-01-06 00:11:05 +01:00
James Turner
fd34cc30b8 compare_versions: limit how many parts are checked.
This can be used to only check the first one or two parts of a version,
to ensure only the major, or major+minor parts match.
2017-01-05 10:55:14 +00:00
Erik Hofman
7b0faed03a Fix an AVX error 2017-01-04 16:30:19 +01:00
Erik Hofman
8d1dc30b07 Try to fix a possible AVX core dump 2017-01-04 12:55:28 +01:00
Erik Hofman
03cff6abca Fix Never use <avxintrin.h> directly; include <immintrin.h> instead. 2017-01-01 13:26:36 +01:00
Erik Hofman
d7821324b8 Fix a wrong enclosing bracket 2017-01-01 11:40:59 +01:00
Ron Haertel
f3e066cce0 Bug fix for bug 1920
In pt_lights.cxx in SGLightFactory::getOdal, at segment "centerline lights",
the decrement loop index i is initialized with lights.getNumLights(), then is used at lights.getLight. (ERROR)
The function getNumLights is set to the size of the vector which is one more than the max index refernce.

This restores the behavior that was in place before commit 8ddb99f62f
2016-12-30 18:49:19 -05:00
James Turner
45ac758cc9 Expose position on SGPropertyNode. 2016-12-27 11:09:07 +00:00
Erik Hofman
f0e6402fff One more, and hopefully the last, MSVC fix 2016-12-23 15:31:40 +01:00
Erik Hofman
41bf142e31 Try to fix an MSVC compile error 2016-12-23 14:50:14 +01:00
Erik Hofman
2e9efa98d7 Add accelearated cross product 2016-12-22 13:43:04 +01:00
Erik Hofman
2c2a57f368 Addd support for AVX, 4 double precision operations in one go 2016-12-21 09:04:46 +01:00
Erik Hofman
4ea1326126 A better MSVC fix and code speedups 2016-12-20 09:54:19 +01:00
Erik Hofman
09b44ac68a MSVC compiler fix (hopefully) 2016-12-19 18:37:52 +01:00
Erik Hofman
a48ab434ab Convert more code to SIMD 2016-12-19 15:58:57 +01:00
Florent Rougon
d39a56d4fb Add missing include: <cctype> for unary std::islower()
Thanks to Ron H. for the report.
2016-12-18 11:02:01 +01:00
Erik Hofman
892579456d add SSE support for the C compiler (gcc and clang) 2016-12-18 09:40:38 +01:00
Erik Hofman
4dde1d365c MSVC 2013+ for 64-bit automatically sets /arch:SSE2 and doesn't recognise te option 2016-12-17 10:50:19 +01:00
James Turner
2f21b582cd Canvas image fill and source rect setters.
C++ code can set the fill and source rect directly.
2016-12-16 19:14:44 +00:00
James Turner
b29536f8b7 Set Canvas element transforms from C++
Also allow transforms to be disabled.
2016-12-16 19:14:44 +00:00
James Turner
039f9920db Direct rect support. 2016-12-16 19:14:44 +00:00
James Turner
7c254e9c04 Native SVG path-data parsing in the Canvas.
This substantially cuts down the amount of properties needed when
importing SVG elements into Canvas paths.
2016-12-16 19:14:44 +00:00
Erik Hofman
35a115bfd4 Fix a stupid mistake and move hsum_ps_sse to shVector.c 2016-12-16 16:01:59 +01:00
Erik Hofman
70dd9d35b1 Also accelerate SHVector3 using SIMD 2016-12-16 15:12:53 +01:00
Erik Hofman
31e3cf06fb Accelerate SHVector4 and SHMatrix3x3 operations using SIMD 2016-12-16 14:54:24 +01:00
Erik Hofman
175eddd1fa Add the proper SSE options to Clang too 2016-12-16 11:05:03 +01:00
Erik Hofman
fe73247b82 Really use _mm_setzero_ps9) instead 2016-12-16 11:04:49 +01:00
Erik Hofman
203db3d095 Enable SSE and SSE2 by default 2016-12-16 10:49:44 +01:00
James Turner
8c4695b991 Fix duplicate variants in packages. 2016-12-15 17:37:32 +00:00
James Turner
a2b111bb09 Bugfix: reject dubious paths in HTTP repos.
This avoids a malicious repository writing to files outside the local
storage root.
2016-12-15 17:37:28 +00:00
James Turner
2a1542d544 Helper for parsing CSS/SVG strings. 2016-12-15 17:37:25 +00:00
Erik Hofman
e5b51677c5 MacOS fix 2016-12-15 13:11:31 +01:00
Erik Hofman
f9450d136d Minor speedups in small tweaks 2016-12-15 09:57:10 +01:00
Erik Hofman
0586cb62c3 Fix the pink-sky bug, don't initilize the vector with (z,y,z,w) but use the proper (x,y,z,w) instead 2016-12-15 09:56:52 +01:00
Erik Hofman
8fee04b32b Generalize the code to be able to test integers too 2016-12-14 11:05:56 +01:00
Erik Hofman
04e16c95e2 Consolidate some code, exlicitly use intrinsics (instead of the usual math operators): this fixes a compiler bug for integers and add some SSE4.1 accelerations for integers 2016-12-14 11:05:31 +01:00
Erik Hofman
e257dbe6ed accelerate float rotation_matrix and fix a bug for double rotation_matrix 2016-12-14 11:03:32 +01:00
Erik Hofman
abf78f8e31 Make absolutely sure the unions are 16-bytes aligned, move more setters and min() and max() to the simd implementation and add horizontal SIMD add functions for magnitude2 and dot 2016-12-12 20:27:07 +01:00
Stuart Buchanan
da13bd9f04 Fix minor compiler warnings 2016-12-10 16:00:28 +00:00
Alessandro Menti
86fb1ed00f BoostTestTargets.cmake: fix a wrong include test
BoostTestTargets.cmake requires the CMake-configurable form of the Boost
test framework to be used (i.e. "#include <BoostTestTargetConfig.h>"), and
checks each test source code file for this, outputting a warning in case
this requirement is not met.

Unfortunately, a conditional in the check is badly specified (the CMake
variable syntax is not followed), so the warning is emitted even when it
should not be.

This patch fixes this bug and restores the correct behavior.

Submitted upstream at https://github.com/rpavlik/cmake-modules/pull/44
2016-12-08 11:47:18 +01:00
Erik Hofman
56fb81dc03 Hopefuly the last MSVC fix 2016-12-08 09:39:45 +01:00
Erik Hofman
343ce57468 Tupe conversion is evil, don't allow it 2016-12-08 01:02:44 +01:00
Erik Hofman
3e52e37181 remove explicit, it looks like SMVC chokes on it 2016-12-07 13:22:17 +01:00
Erik Hofman
e768553a4a Replace auto_ptr with unique_ptr 2016-12-07 11:03:49 +01:00
Erik Hofman
b74d1a8351 Add some more accelerated functions (dot, magnitude, matrix transpose), allow simd_t4 with non mathcing elements to be assigned and a bunch of fixes. Make sure the code compiles when SSE is not available. 2016-12-07 10:00:02 +01:00
James Turner
801d8c4af5 Revert recursive listeners for the moment.
Want to verify this is the cause of crashes inside the property code,
since if it's not we have a much bigger problem.

This means all listeners are recursive, with a parent-chain walk on each
setValue call, as has been the case since 'forever'.
2016-12-05 12:57:29 +00:00
Florent Rougon
3a4693803b strutils: new functions stripTrailingNewlines() and stripTrailingNewlines_inplace() 2016-12-04 22:41:12 +01:00
Florent Rougon
79f0d3356e Convert strutils_test.cxx to use the SG test macros instead of BOOST 2016-12-04 22:41:12 +01:00
Florent Rougon
6a1bf02ddb Use appropriate test macros in parse_color_test.cxx and state_machine_test.cxx
- osg::Vec4 objects can't be output to a stream -> use the _NOSTREAM
  variant of the test macro.

- ditto for the NULL... thing -> use SG_CHECK_IS_NULL().
2016-12-04 22:41:12 +01:00
Florent Rougon
6662800deb Expand the test macros framework
- Add an _NOSTREAM variant for each macro (except for SG_TEST_FAIL, that
  doesn't take any argument, and for SG_VERIFY, which doesn't attempt to
  print its argument to a stream---doesn't sound very useful). So, if a
  and b can be output to a stream (without any undesirable side effect,
  of course), use for instance SG_CHECK_EQUAL(a, b); otherwise, use
  SG_CHECK_EQUAL_NOSTREAM(a, b).

- Add test macros SG_CHECK_IS_NULL, SG_CHECK_IS_NULL_NOSTREAM,
  SG_CHECK_IS_NOT_NULL and SG_CHECK_IS_NOT_NULL_NOSTREAM.

- Add a few comments.
2016-12-04 22:41:04 +01:00
Florent Rougon
c9bb6102c0 Test macros: add parentheses around arguments 2016-12-04 21:22:43 +01:00
Florent Rougon
90479419cc Add test macros: SG_CHECK_NE, SG_CHECK_LT, SG_CHECK_LE, SG_CHECK_GT, SG_CHECK_GE 2016-12-04 21:09:39 +01:00
Florent Rougon
b4178ae888 Test macros: be more rigorous and consistent
- Because of possible operator overloading, make SG_CHECK_EQUAL(a, b)
  fail if, and only if (a) == (b) is false (testing if (a) != (b) for
  this macro is not correct in general).

- For clarity and consistency, change the messages printed when some
  tests fail: SG_VERIFY(some_test) prints 'failed: some_test' (okay),
  but SG_CHECK_EQUAL(a, b) used to print 'failed: a != b', which is
  inconsistent. Instead, print: 'failed: a == b' because this is what we
  know that failed (again, because of possible operator overloading,
  pretending we know the the logical value of (a != b) after testing
  (a == b) is not correct in general.

  Similarly, the "approximate equality tests" SG_CHECK_EQUAL_EP() and
  SG_CHECK_EQUAL_EP2() now print something like 'failed: a ~= b' when
  they fail, instead of 'failed with epsilon: a != b'.
2016-12-04 21:09:39 +01:00
Florent Rougon
ab4814c916 simgear/misc/test_macros.hxx: add missing <iostream> header + minor changes
- The header is needed for std::cerr.
- Also improve the messages when tests fail (spacing, and in some cases
  an argument was missing).
- Reorder the macros a tiny bit.
2016-12-04 21:09:39 +01:00
Florent Rougon
6b16f96c8a Test macros: use defensive parentheses and std::fabs() for SG_CHECK_EQUAL_EP*
Some of the modules where I previously removed duplicate private
definitions of these macros had these features, and since they seem wise
to me, I'm applying them to the canonical SG_CHECK_EQUAL_EP() and
SG_CHECK_EQUAL_EP2() macros defined in simgear/misc/test_macros.hxx.
2016-12-04 21:09:39 +01:00
Florent Rougon
e655d41817 Rename the COMPARE, COMPARE_EP, COMPARE_EP2 and VERIFY test macros
COMPARE     -> SG_CHECK_EQUAL
COMPARE_EP  -> SG_CHECK_EQUAL_EP
COMPARE_EP2 -> SG_CHECK_EQUAL_EP2
VERIFY      -> SG_VERIFY

Also remove duplicate private definitions of these macros in test
modules, using instead those defined in simgear/misc/test_macros.hxx.
2016-12-04 21:04:40 +01:00
James Turner
b5c1902a2d Tweaks to recursive listener behaviour 2016-12-03 14:09:56 +00:00
James Turner
d088259739 Add aliased listener test, disabled for now. 2016-12-02 17:15:11 +00:00
James Turner
d8acf44a3a Revert unintended change in listener refactoring. 2016-12-02 17:14:27 +00:00
Torsten Dreyer
4664af12fa Fix lockup on Windows when polling DNS, add test 2016-12-02 14:44:38 +01:00
James Turner
7a909d0c0b Improved Package search function.
Handle or/and groups, and search variant descriptions and names.
2016-11-30 21:32:31 +00:00
James Turner
919c25769c Quiet a canvas message. 2016-11-30 12:18:44 +00:00
James Turner
5a0908d5bb Package::indexOfvariant works on fully-qualified IDs.
Should fix issues restoring variants in the launcher.
2016-11-29 15:36:00 +00:00
Erik Hofman
1c39daec07 Fix an error 2016-11-27 10:19:17 +01:00
James Turner
835ae941ce Unit-tests for localised-variant strings. 2016-11-26 14:28:22 +00:00
James Turner
63edff078f Fix warnings in sgvec4 test.
Use C++ type-overloaded fabs call.
2016-11-26 14:20:17 +00:00
Erik Hofman
0ea9786601 Add SIMD matrix operations 2016-11-26 11:40:01 +01:00
Florent Rougon
9e0bb33d58 Fix missing include in simgear/props/props_test.cxx 2016-11-26 01:12:34 +01:00
James Turner
64531c85e3 Generalise per-variant localised string lookup.
Will be used for per-variant long-descriptions.
2016-11-25 22:44:24 +00:00
James Turner
14cdae5102 Unit-test for copy-installed children. 2016-11-25 22:19:55 +00:00
James Turner
2aaad212e8 Revert partial-update mode for TerraSync repos.
Going to implement this a different, simpler way now,
2016-11-25 22:19:51 +00:00
James Turner
bd88bf1126 Explicit handling of recursive listeners.
Use a different strategy for recursive listeners, and make them opt-in.
2016-11-25 16:07:18 +00:00
James Turner
ea9da65b7c Expanded property unit-tests. 2016-11-25 16:07:18 +00:00
Erik Hofman
e7f80cf5f3 Finish SIMD Vector code, do not change matrix operations yet since it seems to have a problem 2016-11-25 13:31:54 +01:00
Erik Hofman
16d62f93c8 Fix a clang reported error 2016-11-22 15:18:16 +01:00
Erik Hofman
e96834fcc6 Fix an error 2016-11-22 14:36:28 +01:00
Erik Hofman
22a74c63b4 First changes for SIMD matrix operations 2016-11-22 14:27:42 +01:00
James Turner
5681fcbdc5 Unit-tests for property listener. 2016-11-22 00:19:18 +00:00
James Turner
7755f8e094 Override changes for atomic listener. 2016-11-22 00:15:14 +00:00
James Turner
e266e44f63 Extended scenery/STG suffix handling 2016-11-22 00:09:51 +00:00
Erik Hofman
4dc66a385e Include SGMathFwd.hxx to add unknown math types 2016-11-21 09:22:09 +01:00
Erik Hofman
aec29a3a37 Fix clang errors 2016-11-20 23:54:15 +01:00
Erik Hofman
0d213a1990 Fix a typo 2016-11-20 16:16:28 +01:00
Erik Hofman
8162a49f6c Give vector math a (potential) boost. Next stoP; matrices 2016-11-20 16:15:40 +01:00
Torsten Dreyer
d2e2603400 initialize udns_library on first use 2016-11-20 16:12:01 +01:00
Erik Hofman
43a8277bdb Merge branch 'next' of ssh://git.code.sf.net/p/flightgear/simgear into next 2016-11-20 15:01:10 +01:00
Erik Hofman
61a8bd5cd3 _m128d ony holds two doubles instead of 4 (obviously). 2016-11-20 15:00:24 +01:00
Erik Hofman
ad6f3d2db2 Small updates 2016-11-20 14:59:43 +01:00
Torsten Dreyer
9088f41352 Use private udns context for each DNSClient 2016-11-20 12:35:43 +01:00
Erik Hofman
73f57bbbd8 Add a test utility 2016-11-19 15:57:05 +01:00
Erik Hofman
a8673356a2 Be more specific about the exact type 2016-11-19 15:56:06 +01:00
James Turner
5ecc1ab6f2 Simplify timing code.
Assumes we have timegm on Unix, and use _mkgmtime on Windows.
This means we never need to use ftime() / timeb.h
2016-11-17 21:23:56 +01:00
Automatic Release Builder
0702f85540 new version: 2017.1.0 2016-11-17 13:43:29 +01:00
Automatic Release Builder
277dab0d55 new version: 2016.4.1 2016-11-17 13:43:29 +01:00
Erik Hofman
321a3fdaba Fix a typo 2016-11-17 13:05:08 +01:00
Erik Hofman
2eb17d0083 Revetr previous paatch for SGVec4 so close to the release 2016-11-17 11:50:15 +01:00
Erik Hofman
ff7e4597e7 Maximize simd optimization 2016-11-17 11:48:16 +01:00
Erik Hofman
4a4baf1b42 Merge branch 'next' of ssh://git.code.sf.net/p/flightgear/simgear into next 2016-11-17 09:15:02 +01:00
Erik Hofman
2672d5cd11 include simd.hxx 2016-11-17 09:14:51 +01:00
Erik Hofman
1bf3d7c9b1 Add a copyright header 2016-11-16 15:34:25 +01:00
Erik Hofman
f7c0a7f933 Add a simd_t<int> class and more inlining 2016-11-16 14:00:25 +01:00
Erik Hofman
6bf864babb Add class assingment functions 2016-11-16 13:33:51 +01:00
Erik Hofman
43bd1b15ee Add a SIMD accelerator class for float[4] and double[4] types 2016-11-16 12:45:14 +01:00
Rebecca N. Palmer
14c79d9ffb Nasal: disable NASAL_NAN64 on non-x86
Not every architecture has <=48-bit virtual address spaces:
http://meetings-archive.debian.net/pub/debian-meetings/2016/miniconf_cambridge16/Thanks_for_the_Memory.webm
2016-11-15 22:50:41 +00:00
James Turner
3009aadaa6 Simplify Boost auto-detection on MSVC. 2016-11-14 23:05:10 +01:00
James Turner
fca64343ae Attempting to fix Windows include issues.
Only handle PackageRef by reference in the header file, so we don’t
create calls to the copy constructor and/or destructor. If this doesn’t
work will need to create a stub implementation file.
2016-11-14 07:52:15 +01:00
James Turner
042a2659f6 Disable Codecvt for now, libstdc++ is problematic.
Need to research which libstdc++ versions implement codecvt.
2016-11-14 07:45:23 +01:00
James Turner
fe54af405c Zlib is a public, not private include in Simgear.
Should fix Windows compilation as reported by Alan Teeder on the list.
2016-11-14 07:31:54 +01:00
James Turner
ab70090a0a Finally fix bogus terrasync download numbers.
(Staying a hotel with sufficiently slow wi-fi to debug this!)
2016-11-13 22:18:32 +01:00
James Turner
ee02750e95 Enforce VS2013/2015 requirement on Windows. 2016-11-13 14:57:39 +00:00
James Turner
f55007394e Make more includes target-specific. 2016-11-13 14:57:21 +00:00
James Turner
60a9e8fb7e Implement UTF-8 conversion using codecvt 2016-11-13 14:56:52 +00:00
James Turner
7f8455f731 Multi-thumbnail support in packages.
Allow multiple thumbnails per variant / package, including
tagging with types so we can require certain thumbnails in the future.
2016-11-13 14:56:31 +00:00
James Turner
6ae86fc4ca Fix a warning. 2016-11-13 12:02:12 +00:00
Torsten Dreyer
e1fb13bed8 Allow passing of service and protocol for DNS SRV requests 2016-11-09 13:30:58 +01:00
Torsten Dreyer
27fff3b72a Sort DNS TXT entries and provide an attribute map 2016-11-09 12:03:37 +01:00
Torsten Dreyer
6a9235223e Set correct class for DNS TXT queries 2016-11-09 09:44:10 +01:00
Stuart Buchanan
c1e50e9a9c Correct mesh size correction for building LOD ranges 2016-11-08 20:06:34 +00:00
Stuart Buchanan
dcbf5b7c11 Fix for OBJECT_BUILDING_MESH_DETAILED 2016-11-08 19:56:08 +00:00
Torsten Dreyer
4b571f2a24 Implement SRV and TXT DNS records 2016-11-08 17:09:37 +01:00
Erik Hofman
679b7b845c Always define the class destructor 2016-11-08 13:17:15 +01:00
Edward d'Auvergne
50d7127c51 Calculation of the illuminance factor for the moon.
This is a number ranging between 0 and 1 based on the log of the illuminance of
the moon outside the atmosphere.  It is calculated as

    factor = (log(I) - max_loglux) / (max_loglux - min_loglux) + 1.0,

where I is the illuminance of the moon outside the atmosphere and min_loglux and
max_loglux are hardcoded to -0.504030345621 and -4.39964634562 respectively.
Although the value should never be outside of [0, 1], for safety it is clipped
to be between these values.  For more background, see
http://forum.flightgear.org/viewtopic.php?f=47&t=28201&start=60#p270516 .
2016-11-08 09:49:57 +01:00
Edward d'Auvergne
0e09ee4bce Calculation of the log of the illuminance of the moon outside the atmosphere.
This is the base 10 log of equation 20, converted from foot-candles to lux,
from:

   Krisciunas K. and Schaefer B.E. (1991). A model of the brightness of
moonlight, Publ. Astron.  Soc. Pacif. 103(667), 1033-1039 (DOI:
http://dx.doi.org/10.1086/132921).
2016-11-08 09:49:57 +01:00
Edward d'Auvergne
76ebd569d5 Calculation and exposure of the moon's age and phase.
To obtain the sun's true longitude, the Star::getlonEcl() function has been
created.  The moon's age is then calculated as the difference between the moon's
and sun's true longitudes.  The phase is then simply half of one minus the
cosine of the age.  Hence these calculations are very cheap compared to the rest
of the moon position calculations.  The algorithm is from:

    Duffett-Smith, Peter. Practical Astronomy With Your Calculator. 3rd ed.
Cambridge: Cambridge University Press, 1981. ISBN 0-521-28411-2.

The code can replicate the example in the book of Feb 26, 1979 at 16h UT, with
an age of -0.4767 degrees a phase of 0.0:

$ fgfs --aircraft=UFO --start-date-gmt=1979:02:26:16:00:00 --airport=EGLL \
--altitude=50000 --enable-hud

The calculated phase is 1.459e-5 and the age is -6.2908 (which is -0.43628
degrees).  For a recent full moon:

$ fgfs --aircraft=UFO --start-date-gmt=2015:11:25:22:44:00 --airport=EGLL \
--altitude=50000 --enable-hud

The calculated age is -3.1413 and the phase is 0.9999999778.
2016-11-08 09:49:57 +01:00
Edward d'Auvergne
edcd42bc2d Optimisation of the celestialBody ephemeris code.
By storing repetitive intermediate calculations, the number of mathematical
operations for a single call to CelestialBody::updatePosition() has decreased by
12.  This matches the changes to MoonPos::updatePosition().
2016-11-08 09:49:57 +01:00
Edward d'Auvergne
f04e501472 Exposure of the moon position.
The following functions have been added:  MoonPos::getM(), MoonPos::getw(),
MoonPos::getxg(), MoonPos::getyg(), MoonPos::getye(), MoonPos::getze(),
MoonPos::getDistance().  These are copied from and match the Star class
functions (but with xs and ys replaced by xg and yg).
2016-11-08 09:49:57 +01:00
Edward d'Auvergne
32d152ba38 A few spelling fixes for the moon position ephemeris code. 2016-11-08 09:49:57 +01:00
Edward d'Auvergne
94c4c44d92 Optimisation of the moon position ephemeris code.
By storing repetitive intermediate calculations, the number of mathematical
operations for a single call to MoonPos::updatePosition() has decreased by 32.
2016-11-08 09:49:57 +01:00
James Turner
ab1d4e651e Bugfix: avoid bogus download size on start
Missed a default init of the HTTP repo download content size, so until
the request response header was received, this could report a very
large value.
2016-11-07 15:49:07 +01:00
James Turner
5cd250e452 Packages: notify delegate of uninstalls. 2016-11-06 21:58:01 +01:00
James Turner
2dcff4bb8e Ensure build include location is used first.
Otherwise PREFIX_PATH headers might be found first, but these could be
from an older SimGear version.
2016-11-06 21:57:30 +01:00
James Turner
604a9ff614 Hopefully fix Win32 linkage. 2016-11-02 22:57:39 +00:00
James Turner
a09630bcca Cmake export fixes.
Should hopefully fix importing in FlightGear
2016-11-02 13:59:43 +00:00
James Turner
b44c70b3f4 Simplify isnan detection with C++11 library. 2016-10-30 22:49:38 +00:00
James Turner
e4cddb100e Drastically simplify compiler.h 2016-10-30 22:49:11 +00:00
Erik Hofman
e3a4144e6c Switch to SGMisc::isNaN 2016-10-28 11:18:40 +02:00
James Turner
51e7d95bf2 Require CMake 3.0, enable C++11
Let’s see what this breaks.
2016-10-24 22:52:51 +02:00
James Turner
202571386b Exported package fix.
https://sourceforge.net/p/flightgear/codetickets/1892/
2016-10-20 20:26:51 +01:00
Florent Rougon
7837bd0e11 Add parameter 'use_exact_name' to sg_gzifstream's constructor and open() method
This allows one to be sure about which file is opened.
2016-10-20 14:07:08 +02:00
Florent Rougon
11c6e5bf04 Require zlib 1.2.4 or compatible
Commit 8277857827 relies on zlib's
gzoffset() function (not just offset(): that was a typo in the commit
message, sorry). This function appeared in zlib 1.2.4 (which dates from
2010). Enforce this requirement with CMake.
2016-10-19 21:17:54 +02:00
Florent Rougon
8277857827 Add gzfilebuf::approxOffset() and sg_gzifstream::approxOffset()
gzfilebuf::approxOffset() is a wrapper for zlib's offset() function.
It can be useful to implement progress indicators and such.
2016-10-19 00:30:55 +02:00
Florent Rougon
412111ba5a Change sgSearchPathSep into a public static member: SGPath::pathListSep
This way, one can easily use the OS-dependent separarator for path lists in
other places to build and split path lists in an optimal way (e.g., not
sacrificing ';' on Unix, since the path list separator is ':' on this
platform).
2016-10-12 09:05:21 +02:00
James Turner
dd52b6af50 Remove some archaic code. 2016-10-09 11:08:17 +02:00
Erik Hofman
a97c145f56 Always return a value 2016-10-04 09:08:43 +02:00
Erik Hofman
b9deebb59d It's perfectly valid to call is_sample_stopped() even if the sample was already stopped. So remove the assert and replace it with an if-test 2016-10-03 09:55:31 +02:00
Richard Harrison
906813c90b Console handling: VS2015 seems to only work with redirection when both stdout and stderr are redirected; so show a message box error when redirecting only one stream. 2016-10-02 02:29:22 +02:00
Florent Rougon
1711592e64 A few more tests for simgear::strutils::split() 2016-10-01 10:44:33 +02:00
James Turner
7b2507cb19 Config changes to warn on older tools.
Warn on to-be-deprecated versions of Cmake, Visual Studio and GCC
2016-09-28 17:20:51 -05:00
James Turner
2e19aaaff9 Remove multi-arch workaround in CMake
Since we now require 2.8.11, we can rely on this bug being fixed.
2016-09-27 20:43:03 -05:00
James Turner
6854598b79 Initial pieces for full OBJ support.
Needs testing by aircraft developers, this is just the first piece.
2016-09-27 20:41:31 -05:00
Stuart Buchanan
809ddb21c9 Add STG verbs for building mesh integration.
Add OBJECT_BUILDING_MESH_ROUGH and OBJECT_BUILDING_MESH_DETAILED

Intended for use by OSM buildings.
2016-09-22 20:38:58 +01:00
Richard Harrison
38bab59c1a Revised Windows console handling
- When started from the console use the console (when no --console)

- When started from the GUI (with --console) open a new console window

- When started from the GUI (without --console) don't open a new console window; stdout/stderr will not appear (except in logfiles as they do now). This opens stderr/stdout on the NUL device to alleviate any potential issues

- When started from the Console (with --console) open a new console window

- Ensure that IO redirection still works when started from the console. When redirecting stdout stderr will also be redirected (providing it wasn't already via 2>&1) - otherwise output from stderr will be lost.

- When using redirection from the command prompt --console will produce an error message box.

Notes:
- fgfs needs to be a linked as Win32 GUI subsystem app - which it already is
- What can't be done is to make the cmd prompt run fgfs synchronously; this is only something that can be done via "start /wait fgfs"

Basically the way that Win32 works is quite sensible, but slightly at odds with the unix nature of the C-RTL; so the standard streams sort of get lost for GUI apps. AttachConsole and AllocConsole are provided to address this - but they do slightly different things. AttachConsole will attach to the cmd.exe (or any console related to the parent process), whereas AllocConsole will open a new one. Depending on where the application was launched from it makes sense to use AttachConsole for a cmd.exe launch and do nothing (unless --console is given) for a GUI launch.

Redirection is not available from the GUI (unless set in the Process Create block) - so really only available when launched from the command line. If any stream is redirected then all must be otherwise it appears that AttachConsole will undo the redirection by changing the standard handles.
2016-09-21 00:50:13 +02:00
James Turner
87590cafb2 Fix terrasync behaviour when net is down. 2016-09-07 22:49:03 +01:00
Automatic Release Builder
6e5cbd7fc5 new version: 2016.4.0 2016-09-06 12:50:55 +02:00
Automatic Release Builder
4200572cad new version: 2016.3.1 2016-09-06 12:50:55 +02:00
James Turner
9b997ea1f7 Only reopen the streams if AllocConsole succeeds.
Avoid a crash with FGRun when OSG tries to use the console.
2016-09-02 00:05:13 +01:00
Torsten Dreyer
c1ba974538 Make requested tsync scenery-version settable from prop
set /sim/terrasync/scenery-version=ws30 to filter the DNS NAPTR
records for service=ws30
current default (and only available) scenery version is ws20

This enables usage of multiple scenery repositories
2016-08-29 21:00:03 +02:00
James Turner
d7d59b08a2 Copy-from-install support in TerraSync
Allows repositories to be initialised based on data in the install.
This avoids duplicate downloading of the Model and Airport data,
and the starting scenery.

Requires a corresponding FlightGear change to be functional.
2016-08-18 16:21:31 +01:00
James Turner
6b82b78c7c Warn when OSG is not in UTF-8 mode.
This will become an error in the near future.
2016-08-15 22:38:00 +01:00
James Turner
8201301064 Improve Windows linkage.
When using a patched OSG, avoid /FORCE:MULTIPLE work-around.
2016-08-15 22:38:00 +01:00
James Turner
899778b354 Fix inverted logic in any-bindings test. 2016-08-08 16:59:06 +01:00
James Turner
a31d1342d5 Simplify Aeonwave/OpenAL logic in Cmake slightly 2016-08-06 14:40:14 +01:00
Erik Hofman
8d266491c5 Fix the header location 2016-08-06 11:26:47 +02:00
Erik Hofman
0acbe1f087 Clean up the code a bit and combine soundmgr_openal.hxx and soundmgr_aeonwave.hxx into a single file 2016-08-06 11:25:27 +02:00
Erik Hofman
f8d5e58ccc Clean up the code a bit and combine soundmgr_openal.hxx and soundmgr_aeonwave.hxx into a single file 2016-08-06 11:24:58 +02:00
Erik Hofman
fcd0f15ff2 Remove an unused variable 2016-08-05 11:20:33 +02:00
Erik Hofman
f092f000fa AeonWave is off by default 2016-08-05 10:57:20 +02:00
Alessandro Menti
69b127e2e6 Have the SimGear HTTP client follow redirects 2016-08-04 20:36:38 +02:00
Erik Hofman
65a3d9ed6c Search for the right header file 2016-08-04 18:40:12 +02:00
Erik Hofman
85c4e03823 Merge branch 'next' of ssh://git.code.sf.net/p/flightgear/simgear into next 2016-08-04 18:39:54 +02:00
Erik Hofman
7754f88be7 Finish AeonWave integration 2016-08-04 18:38:38 +02:00
Erik Hofman
1e24245d6c Reflect the latest header changes 2016-08-03 10:52:40 +02:00
James Turner
5ea01039f9 Improve pick-callback enabled testing. 2016-07-31 22:21:03 +01:00
James Turner
8b8dbeb00d Quiet a log message 2016-07-31 22:21:03 +01:00
Erik Hofman
52ec6cee85 Add the compile time option to test the return values 2016-07-29 12:36:13 +02:00
Erik Hofman
eb53d4ca78 Add get_no_tracks() 2016-07-29 12:35:43 +02:00
Erik Hofman
f3c3b7ec1b Split include dirs 2016-07-29 12:35:20 +02:00
Erik Hofman
f6e92ac9e5 Update to the latestaienwave.hpp header file 2016-07-26 15:22:09 +02:00
Erik Hofman
48c5e5e43b Update to the latestaienwave.hpp header file 2016-07-26 15:21:26 +02:00
Erik Hofman
7cc9a1753c updates for the aeonwave.hpp header changes 2016-07-25 11:40:40 +02:00
Erik Hofman
068745617c Add support for stereo 2016-07-21 13:05:40 +02:00
Erik Hofman
935c3f901d Add some tests for AeonWave 2016-07-21 13:05:40 +02:00
Erik Hofman
0b60669075 Add some tests for AeonWave 2016-07-21 13:05:40 +02:00
Erik Hofman
488039d1de Either install soundmgr_openal.hxx or soundmgr_aeonwave.hxx as soundmgr.hxx 2016-07-21 13:05:40 +02:00
Erik Hofman
efe9648afa Activate AeonWave by setting USE_AEONWAVE to ON 2016-07-21 13:05:40 +02:00
Erik Hofman
d12cd4945e Get soundmgr_aeonwave in a compilig state 2016-07-21 13:05:40 +02:00
Erik Hofman
968e0b4cd2 Make stereo files a SG_POPUP message 2016-07-21 09:54:11 +02:00
Erik Hofman
d902fffa46 Make a failed wav file a SG_POPUP message 2016-07-20 15:02:24 +02:00
Erik Hofman
3092274cac Add support for SG_POPUP messages which show a dialog at startup 2016-07-20 15:01:30 +02:00
Erik Hofman
5f54388ed9 Be more specific about what audio type is detected and for which file if it is not supported. 2016-07-20 08:37:07 +02:00
Erik Hofman
9b4f1b0ff8 Reluctantly add support for stereo files again: there are external hangars which did not update to the mono-files only principle 2016-07-19 10:44:46 +02:00
Erik Hofman
c48a28beb9 Remove some unusal ocde..??? 2016-07-18 13:49:40 +02:00
Erik Hofman
96986c9377 Try to prevent a crash in unusual situations 2016-07-18 11:59:47 +02:00
Maciej Mrozowski
33bd02f926 FindUdns.cmake: fix check for cached paths 2016-07-17 03:48:32 +02:00
James Turner
93226fc500 Change location used for path tests
Jenkins seems to dislike non-Latin-1 characters inside the build
tree on Linux, so use a location inside /tmp instead.
2016-07-15 17:57:32 +01:00
James Turner
31ba9dfa70 Further SGPath API usage cleanups. 2016-07-15 16:33:52 +01:00
James Turner
19df18fefb Use wide-string APIs on Windows.
SGPath and simgear::Dir use ‘w’ versions of POSIX APIs on Windows,
and convert UTF-8 SGPath to wide-strings as part of this.

Includes improved unit-tests for this code, with some very basic
tests of creating and iterating files with Unicode characters in
their names.

No user-visible changes should result from this, on any platform; in
particular wide-string support is still incomplete so FlightGear will
not yet work with arbitrary Unicode paths on Windows.
2016-07-15 09:50:44 +01:00
James Turner
a5a4bf6d41 Another HLA/SGPath fix 2016-07-04 09:31:34 +01:00
James Turner
9812315d96 realpath returns a path, not a string. 2016-07-04 09:04:46 +01:00
James Turner
c40044feeb Fix HLAFederate for readXML API change 2016-07-04 07:20:23 +01:00
James Turner
a636da6959 SGPath in easyXML API 2016-07-03 23:41:07 +01:00
James Turner
ca84d2046a Fix sg_gzofstream path type (now SGPath) 2016-07-03 23:05:42 +01:00
James Turner
c037a0e461 Windows string conversion for SGPath 2016-07-03 22:56:04 +01:00
Bertrand Coconnier
5ab595b401 The Shlwapi library is now needed for the Windows build (required in simgear/misc/sg_dir.cxx which calls to PathIsDirectoryEmpty) 2016-07-03 14:36:22 +02:00
Bertrand Coconnier
7e06e5382a One (last?) fix for compilation errors with MSVC++ 2016-07-03 12:38:56 +02:00
Bertrand Coconnier
d3c5c45262 Fixed compilation errors with MSVC++ 2016-07-03 11:53:23 +02:00
Erik Hofman
efa1292b2d Fix a compiler wrning 2016-07-03 09:44:04 +02:00
Erik Hofman
98de216878 No need to count all 150 or so entries, 3 is enough 2016-07-03 09:39:52 +02:00
Erik Hofman
82a9491de4 Much shorter version of Dir::isEmpty() 2016-07-03 09:35:03 +02:00
Erik Hofman
b23e9a3424 Detect the actual number of wchars required for the buffer and allocate it properly 2016-07-03 09:34:19 +02:00
Erik Hofman
0e62c11fd0 AeonWave based sound manager 2016-07-03 09:03:37 +02:00
Erik Hofman
5b54481555 Merge branch 'next' of ssh://git.code.sf.net/p/flightgear/simgear into next 2016-07-02 11:07:11 +02:00
Erik Hofman
f4344c5c6a Fix directory creation: 'ds' remains the same while 'dir' gets updated so use 'dir' instead 2016-07-02 11:06:36 +02:00
Erik Hofman
372dead21a Convert _filename to an SGPath 2016-07-02 11:03:32 +02:00
James Turner
cf18d4eaaf SGPath can convert to std::wstring 2016-07-02 09:34:27 +01:00
James Turner
32735428bb More SGPath APIs 2016-07-01 17:14:34 +01:00
James Turner
b862cf7e54 Fix repository test. 2016-07-01 09:02:52 +01:00
James Turner
f21eac8473 Building with clean SGPath API 2016-06-30 16:17:52 +01:00
James Turner
38c8931950 Fix debug runtime assert 2016-06-29 16:26:42 +01:00
James Turner
cfe1c0933f Further SG stream APIs 2016-06-27 12:29:23 -05:00
Erik Hofman
a8d8158fac Properly et frequency, format and buffer size 2016-06-27 13:19:37 +02:00
Erik Hofman
2321d9783d Move the isNaN function to soundmgr_openal_private.hxx to make it avaiable for the soundmanager too 2016-06-27 12:35:58 +02:00
James Turner
a3b3280123 iostream overloads taking an SGPath 2016-06-25 16:30:24 +01:00
James Turner
8cfe5a2e08 Native SGPath API on SGInterpTable
- string-based version will be removed in the future.
2016-06-23 15:21:26 +01:00
James Turner
bd896096cc Changing SGPath APIs, using SGPath in more places.
Change most places we control (i.e not helper libs) to use SGPath
to represent a path, instead of using std::string. Extend SGPath
API to explicitly expose the path in either UTF-8 or the
system 8-bit encoding.
2016-06-22 17:15:32 +01:00
James Turner
855ff5a8b0 Fix Linux compilation of untar.hxx 2016-06-16 04:46:37 -05:00
James Turner
e695505e62 Tests for un-tar code. 2016-06-15 22:27:01 +01:00
James Turner
f824cf85a4 Fix Untar namespacing. 2016-06-14 15:13:58 +01:00
James Turner
fb8b60b6fe Export untar header
Needed for scenery installation helper.
2016-06-14 15:12:20 +01:00
James Turner
516d76d41b VS215 tweaks, warning fixes 2016-06-09 20:38:01 +01:00
Jasin Colegrove
d0e31c5cf5 Use STD_ERROR_HANDLE since SG_LOG uses stderr stream
Fixed spacing, cleaned up uneccessary #ifdef's
2016-06-09 14:27:56 -04:00
James Turner
daa10503e6 Fixes to Windows console interaction.
Thanks To Jasin Colegrove for helping me understand the issues here!
2016-06-09 15:11:44 +01:00
Thomas Geymayer
1c25d343a0 Fix missing throw. 2016-06-09 13:03:40 +02:00
James Turner
c762dbe864 Fix dependency on ‘version’ file. 2016-06-09 11:03:35 +01:00
James Turner
37c551bae7 Fix for HTTP/curl waiting on update
This improves responsiveness of TerraSync with small files and general
throughout dramatically.
2016-06-08 15:43:59 +01:00
James Turner
0ccf3e1629 Threadsafe terrasync state updates/reading. 2016-06-08 15:27:47 +01:00
Erik Hofman
da1aeece14 Merge branch 'next' of ssh://git.code.sf.net/p/flightgear/simgear into next 2016-06-07 21:51:21 +02:00
Erik Hofman
c722f90848 Only throw an expection if buf == NULL.. 2016-06-07 12:59:16 +02:00
James Turner
5ba9004853 More repository test tweaks for Jenkins. 2016-06-07 11:24:01 +01:00
Erik Hofman
dc1696dfd5 Throw an exception when the current working directory can not be retrieved 2016-06-07 11:51:28 +02:00
James Turner
cb80af0ebe Improving channel lifetime in HTTP-based tests.
Previously, closed channels were not cleaned up, which looks to be
the caused of the test failures on Jenkins.
2016-06-06 17:26:50 +01:00
James Turner
1492de4391 Fix a leak / potential crash 2016-06-06 11:36:47 +01:00
James Turner
fad905e7e0 Increase test timeout value.
- investigating failing tests on Jenkins
2016-06-03 15:26:48 +01:00
James Turner
fb1b1b9c5e Fix uninitialized var 2016-06-03 08:44:25 -05:00
James Turner
b7b304ecfb Fix a warning with GCC 2016-06-03 08:40:55 -05:00
James Turner
8690e4617f CMake tweaks for MSVC detection 2016-06-03 12:19:21 +01:00
James Turner
a6bed69d19 Fix user-after-free in HTTP repo code 2016-06-02 23:53:15 +01:00
James Turner
100e327684 More permissive catalog version checks
- support wildcard prefixes on FlightGear versions
- drop catalog version equality check
2016-06-01 22:46:17 +01:00
James Turner
729c9e3faa More VS2015 fixes 2016-06-01 22:36:36 +01:00
Erik Hofman
add3a934af XMerge branch 'next' of ssh://git.code.sf.net/p/flightgear/simgear into next 2016-06-01 23:13:59 +02:00
Erik Hofman
e82e4f8c93 Merge branch 'aeonwave' into next 2016-06-01 23:13:09 +02:00
Erik Hofman
6582d041e6 Make sure block align is in samples when calling alBufferi with AL_UNPACK_BLOCK_ALIGNMENT_SOFT 2016-06-01 23:12:55 +02:00
Jasin Colegrove
92878f37f9 MSVC 12 still requires snprintf to be defined 2016-06-01 10:24:30 -04:00
Erik Hofman
4224d2b86b block_alignment for AL_SOFT_block_alignment is in samples, not in bytes 2016-06-01 14:16:49 +02:00
Erik Hofman
c3db9b9d86 Fix a comment 2016-06-01 10:10:34 +02:00
Erik Hofman
3223f16fe6 Merge branch 'next' of ssh://git.code.sf.net/p/flightgear/simgear into next 2016-06-01 09:52:00 +02:00
Erik Hofman
03f7f82856 Revert to the previous way of handling OpenAL. The reason was to find alext.h but that reason has gone by copying a small number of defines 2016-06-01 09:51:41 +02:00
James Turner
be4ebddb60 Fix for VS2015 compilation 2016-05-31 13:41:28 +01:00
James Turner
34e804b784 Fix VS2015 compilation 2016-05-31 13:40:32 +01:00
James Turner
75b2ef9372 Fix VS2015 compilation 2016-05-31 13:40:00 +01:00
Erik Hofman
f71e2e0e9f Merge branch 'next' into aeonwave 2016-05-31 13:40:50 +02:00
Erik Hofman
ce0cdcdcb0 Add the option to define volume and pitch using an expression 2016-05-31 13:40:46 +02:00
Erik Hofman
426912173a Merge branch 'next' of ssh://git.code.sf.net/p/flightgear/simgear into next 2016-05-30 18:36:20 +02:00
Erik Hofman
976c85ff57 Add IMA4 support 2016-05-30 14:17:16 +02:00
James Turner
1ae9e74539 More libCurl version guards. 2016-05-30 13:02:25 +01:00
James Turner
980ae3115c Whitespace fixes. 2016-05-30 13:02:24 +01:00
James Turner
5ca9a06273 FreeBSD fixes from Ganael LAPLANCHE 2016-05-30 13:02:24 +01:00
Erik Hofman
469097ed5b Add test files for mulaw en IMA4 ADPCM 2016-05-30 11:50:11 +02:00
Erik Hofman
ae375f44f2 Add support for native mulaw encoded samples if the OpenAL implementation supports it 2016-05-30 11:46:41 +02:00
Erik Hofman
d1a808c630 Find OpenAL the proper way 2016-05-30 10:50:22 +02:00
Erik Hofman
733c283b1a Do not forget to alter the function declaration as well 2016-05-27 22:43:52 +02:00
Erik Hofman
f65a970d2e Fix two OpenAL related compiler errors 2016-05-27 19:08:20 +02:00
Erik Hofman
ef5b9ee66b Move all OpenAL function calls from SampleMgr to soundMgr 2016-05-27 14:40:49 +02:00
Erik Hofman
c5a94e8899 Switch to out own audio format defines 2016-05-27 11:58:01 +02:00
Erik Hofman
b05488649a Remove unused sample queue code 2016-05-27 11:37:47 +02:00
Erik Hofman
c654c82a3f Remove support for stereo sounds 2016-05-27 10:52:04 +02:00
Erik Hofman
4b7d577883 Merge branch 'next' into aeonwave 2016-05-27 10:03:56 +02:00
James Turner
1b0289b11f HTTP: Always use absolute paths for hashes
Ensure we only compute / retrieve hashes for absolute paths. Fixes
duplicate paths in repository hash cache.
2016-05-26 23:36:03 +01:00
James Turner
00f4248137 Partial update support for HTTP repos.
Not used yet, we set full-update mode on repositories for the
moment. Pending Terrasync change will enable partial mode.
2016-05-26 23:35:11 +01:00
James Turner
8211f1c482 Allow updating a Catalog URL explicitly.
Needed for fallback Catalog URL support.
2016-05-26 17:38:02 +01:00
James Turner
43ebde9914 Expose pending count from terrasync
Total and expose HTTP pending download value as a new
property under terrasync-root.
2016-05-26 17:38:02 +01:00
James Turner
7d59dd977f AbstractRepository interface removed. 2016-05-26 17:38:02 +01:00
James Turner
3e2f37418a Remove SVN sync code. 2016-05-26 17:38:02 +01:00
James Turner
9d2df12ab8 Remove old terraysnc backend methods.
Only in-process HTTP access is supported now, SVN and rsync
and removed. This is to allow changes for better use of the
HTTP API.
2016-05-26 17:38:02 +01:00
Maciej Mrozowski
2b15b6b8ad Add SYSTEM_UDNS CMake option. Remove spurious EXPAT_LIBRARIES linking when using bundled expat. 2016-05-26 02:33:24 +02:00
James Turner
49bd96c55d Guard usage of CURLMOPT_MAX_TOTAL_CONNECTIONS
Check the Curl patch version to avoid breaking on older
sustems.
2016-05-25 20:08:40 +01:00
Erik Hofman
b3d95c0754 Probably a better fix 2016-05-25 14:30:06 +02:00
Erik Hofman
87c2427cfe MSVC 2013 and later define std::isnan 2016-05-25 09:08:52 +02:00
Erik Hofman
857f7c9e61 Revert to c++98 2016-05-24 21:37:12 +02:00
Erik Hofman
91f184caff Do not expose both std::isnan() and isnan() 2016-05-24 17:32:22 +02:00
Erik Hofman
7cab98cf29 First layer of separation between SimGear an OpenAL 2016-05-24 15:47:20 +02:00
Erik Hofman
e9ea5e9036 Revert the check fro std::isnan() and isnan() 2016-05-24 14:51:17 +02:00
Erik Hofman
03a8a2a3fb Switch to c++11 2016-05-24 10:42:01 +02:00
Erik Hofman
f1bffc7397 Add more missing header files 2016-05-24 10:12:39 +02:00
James Turner
5fdc756a64 Fix missing <cstdint> on non-Mac 2016-05-24 08:16:40 +01:00
James Turner
5b71d84a3a Merge /u/elgaton/simgear/ branch specify-standards-fixes into next
https://sourceforge.net/p/flightgear/simgear/merge-requests/15/
2016-05-24 07:02:08 +00:00
Alessandro Menti
b1270376c9 Indentation fixes (and signed/unsigned comparison fix) to silence GCC 6 warnings 2016-05-24 00:11:22 +02:00
James Turner
871b418242 Initial Tar package support.
Needs proper testing, but basic unit-test passes.
2016-05-23 22:23:16 +01:00
Alessandro Menti
fd124e91de CMakeLists.txt: explicitly set the standard to C++98
Set the C++ standard to C++98 to avoid GCC 6 compilation failures.
2016-05-23 23:16:35 +02:00
Florent Rougon
5b71ede2ea Fix missing includes
When SimGear header files are included in a particular order, these
missing includes can cause the compilation to fail.
2016-05-23 12:24:37 +02:00
James Turner
6285a409ed Fix a crash with mismatch package versions. 2016-05-18 19:02:41 +01:00
James Turner
9818a123ca Fix removal of directories. 2016-05-18 10:50:57 +01:00
Automatic Release Builder
09ab029e2f new version: 2016.3.0 2016-05-17 10:03:44 +02:00
Automatic Release Builder
da2f365cd2 new version: 2016.2.1 2016-05-17 10:03:43 +02:00
Florent Rougon
496d458d22 Use _WIN32 instead of SG_WINDOWS for tests in simgear::strutils::error_string()
Since Cygwin has SG_WINDOWS defined but is likely to expose a POSIX or
GNU-like interface, using _WIN32 to decide whether Windows-specific
functions are available seems more appropriate than SG_WINDOWS to me.
2016-05-13 12:04:02 +02:00
James Turner
9dda5a4e31 Fix platform check for strerror_r on Mac 2016-05-10 20:47:25 +02:00
Florent Rougon
289daf0fbc Fix missing include in simgear/misc/strutils_test.cxx
strutils_test.cxx uses std::string but doesn't include <string>
directly. This doesn't cause any error because it includes this header
indirectly via "strutils.hxx". However, I believe relying on this is bad
practice, hence the tiny fix.
2016-05-09 16:37:09 +02:00
Florent Rougon
61e2d2dd3b Fix missing include in simgear/misc/strutils.cxx
Thanks to Alan Teeder for the report.
2016-05-09 16:03:37 +02:00
Torsten Dreyer
2523236cec Merge /u/frougon/flightgear-simgear/ branch thread-safe-alternative-to-strerror into next
https://sourceforge.net/p/flightgear/simgear/merge-requests/9/
2016-05-09 10:51:13 +00:00
Torsten Dreyer
1c182ff69d Merge /u/psadro/simgear/ branch terragear-changes into next
https://sourceforge.net/p/flightgear/simgear/merge-requests/8/
2016-05-09 10:47:04 +00:00
Florent Rougon
757970fe41 Thread-safe alternative to strerror()
Uses:
  - strerror_s() on Windows;
  - the GNU strerror_r() on non-Windows systems where _GNU_SOURCE is
    defined (which is currently the case when the GNU libstdc++ is used,
    even if one doesn't explicitely define _GNU_SOURCE, cf.
    <https://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.predefined>);
  - the XSI-compliant strerror_r() on other systems, as long as
    _POSIX_C_SOURCE >= 200112L (otherwise, the compilation will abort
    due to a #error preprocessor instruction).
2016-05-08 23:28:01 +02:00
Peter Sadrozinski
6e904ba1aa add siblings function to bucket.
At some latitudes, buckets can have multiple siblings.
2016-05-07 07:43:22 -04:00
James Turner
616826ab69 Remove non-CURL HTTP option. 2016-05-07 10:11:40 +01:00
James Turner
6e4da15a58 Use SGBinaryFile in a couple more places.
Most importantly, when computing a hash from the on-disk
state.
2016-05-07 10:03:48 +01:00
Torsten Dreyer
561e451192 Introduce SGBinaryFile
For Windows, default file mode is TEXT.
If binary files should be created _O_BINARY shall be or'ed to the open
flags. This is not necessary on *nixes.

Introduce a SGBinaryFile as extension to SGFile which adds the flag
upon construction on Windows.

This should keep existing behaviour for all other usages of SGFile.
2016-05-06 22:01:42 +02:00
Torsten Dreyer
74b4df9452 Don't use object returned from vector::end()
Replace all use of c->name by it->file() in
updateChildrenBasedOnHash()'s fsChildren loop
to avoid confusion.

Thanks to Geoff for spotting this!
2016-05-06 16:21:43 +02:00
Torsten Dreyer
862980a67a Remove unneeded local scope
(no functional change intended)
2016-05-06 16:20:09 +02:00
Torsten Dreyer
5fb8891e86 Fix one more crash on Windows in HTTPRepository
inner scope it seems to overwrite out scope it on Win :-/

Anyway, the erase-remove-idiom is a better solution for that task
https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

Also remove some useless debug messages
2016-05-06 10:48:16 +02:00
Torsten Dreyer
f3d68a170e Don't continue parsing after processing version line 2016-05-05 21:59:35 +02:00
James Turner
1fe8931129 Packages: fix extract dir cleanup on success.
Don’t leave extract_xxxxxxx dirs in the Aircraft tree after successfully
extract the contents to the final location.
2016-05-04 22:22:34 +01:00
James Turner
d39b055ed1 Avoid unlink of an open file.
Works on Unix, not so great on Windows it turns out. Thanks to Jasin
and Geoff for figuring this out in the end.
2016-05-04 22:13:15 +01:00
Torsten Dreyer
639e16b722 use safer stl functions instead of pointer operations 2016-05-04 21:10:12 +02:00
Torsten Dreyer
9456ff838c Add a bunch of debug messages to help fixing the Windows crash
This patch should be reverted once the bug is fixed
2016-05-04 15:44:55 +02:00
Torsten Dreyer
eac3402176 Enable DNS resolver code by default 2016-05-03 14:58:38 +02:00
Torsten Dreyer
9a29f54f8a Terrasync: implement HTTP service lookup via DNS
Let terrasync use the http repository if
  /sim/terrasync/http-server == "automatic"
  resolve DNS NAPTR RR for terrasync.flightgear.org with service "ws20"
  and flags "U". Pick one of the returned entries with lowest order
  and preference. If more than one entry  with the same order and
  preference is returned, pick a random entry of those returned.

or if
  /sim/terrasync/http-server != "automatic"
  explicitly use the value of that property as the http server

if
  /sim/terrasync/http-server is empty, fall back to the legacy
  SVN repository
2016-05-03 12:11:38 +02:00
Torsten Dreyer
5e7b5cbf68 udns: fix self baked inet_pton 2016-05-03 09:43:56 +02:00
Torsten Dreyer
bba11c18d1 Fix Nasal math.clamp()
Thanks to "Red Leader" from the forum for spotting
2016-05-02 21:57:35 +02:00
Torsten Dreyer
379a171d24 Use simgear sleep instead of usleep 2016-05-02 21:25:19 +02:00
Torsten Dreyer
87eaec3ce7 Fix some warnings reported from msvc 2016-05-02 20:54:28 +02:00
Torsten Dreyer
b5dace5f08 Fix Windows build (hopefully) 2016-05-02 20:46:42 +02:00
Torsten Dreyer
5ecf07e92d udns: add missing config.h 2016-05-02 20:27:04 +02:00
Torsten Dreyer
53d8dcfc77 Try fix windows compile for udns 2016-05-02 17:42:01 +02:00
Torsten Dreyer
6b31646d61 Hardening the DNSClient code
- add a timeout to avoid deadlock without a dns server
- test against existing terrasync.flightgear.org RR's
2016-05-02 16:21:42 +02:00
Stuart Buchanan
06f888d38c Display random objects independently of buildings
Fix bug reported by Thorsten RENK on the mailing list
that random objects were only being displayed if random
objects were also present for the tile.  Also fix crash
if none of the random object models were found.
2016-05-01 22:35:21 +01:00
Torsten Dreyer
51ad61061f Fix broken build/install with DNS enabled 2016-04-28 10:50:15 +02:00
Torsten Dreyer
ff5b09c97b Initial commit for a DNS service resolver
- import udns library
  (http://www.corpit.ru/mjt/udns.html)
- initial draft for a DNSClient (derived from HTTPClient)

Enable compile and test by adding -D ENABLE_DNS=Yes to cmake flags
2016-04-28 09:37:08 +02:00
James Turner
46ed4b2f79 Catalog refresh / package updating test. 2016-04-20 11:58:35 +02:00
James Turner
8582676100 Catalog removal test
- verifies installed packages are removed also.
2016-04-19 13:56:07 +02:00
James Turner
32181a3956 Expand package-system unit-tests.
More to come, but this covers the absolute basics now.
2016-04-19 13:50:37 +02:00
James Turner
c17324b5ea Fixes for HTTP cancellation.
(Forgot to stage these from previous commit)
2016-04-14 09:42:04 +01:00
James Turner
a3f1bb546f HTTP request cancellation
- replaces abort() with something more structured.
2016-04-14 09:16:36 +01:00
Stuart Buchanan
493aab8bab Make LOD for buildings/trees/STG configurable.
Now based on /sim/rendering/static-lod/rough.
2016-04-08 22:36:06 +01:00
Richard Senior
92a51059b4 Fix problems parsing METAR strings that denote temporary sensor failures
1. Weather (normally blank, RA, SN, etc.) can be "//"
2. Cloud can be suffixed by "///", e.g. FEW045///

Also updated unit test.
2016-04-05 12:12:04 +01:00
James Turner
177c5ec709 Guard against disabling a not-yet-active catalog. 2016-03-30 17:09:51 +01:00
Erik Hofman
63b2b04977 Code cleanups and fix codecPCM16 for big-endian systems (they seem rare these days) 2016-03-28 15:08:28 +02:00
James Turner
2e1f01a86a Use ref-ptr in canvas adapter getImage
Adjusted while investigating missing tooltip texture with recent
OSG versions.
2016-03-26 19:55:37 +00:00
James Turner
27baafab0d Packages: handle catalog versions better
When a catalog version is stale, disable it but don’t remove it,
and still try to refresh it. This should give much better behaviour
when the FG version changes, should behave as users expect.
2016-03-25 23:04:45 +00:00
James Turner
8ddcef9142 Fix HTTP unit-test 2016-03-25 13:28:24 +00:00
James Turner
aa679ffb86 HTTP terra sync: fix hash cache handling
Avoids very long pauses blocking the terrasync thread, while existing
file trees are verified.

Also split the request queue so we don’t submit vary large numbers of
requests from a single repository, and hence block other repositories
from getting traffic.
2016-03-24 19:15:20 +00:00
James Turner
4fdcfb8623 HTTP/curl - pick up sleep value 2016-03-24 18:41:30 +00:00
James Turner
c199c95218 Expose total bytes to download / remaining
For HTTP repositories, support some additional metrics about ongoing
transfers. Not currently exposed via properties / TerraSync API, but
will be shortly.
2016-03-22 21:14:17 +00:00
James Turner
3f9b6d632e HTTP/curl - transfer byte metric work
Should fix the missing download rate feedback on the splash screen
and terra sync dialog.
2016-03-22 21:13:22 +00:00
James Turner
714a6ac47d Disable HTTP pipelining if the connection closes.
Don’t keep attempting to pipeline if the next server sets Close on
its response, since this just generates needless overhead.
2016-03-22 20:06:22 +00:00
James Turner
2438dd8a08 Disable persistent TerraSync cache for HTTP
- since the root-level request for an HTTP repo is small, and static,
  it doesn’t make sense to use the same persistent cache, especially
  for initial testing.
2016-03-05 09:53:37 +00:00
James Turner
49146f41e3 Expose more pipelining controls on HTTP code
- used for both implementations, restrict default pipeline depth to
  5 instead of 32 which was perhaps a little ambitious for some
  servers.
2016-03-01 12:44:22 +00:00
James Turner
8009a33b26 Fix attempt to remove missing files. 2016-03-01 12:35:08 +00:00
James Turner
b8d07cc460 Fixes for error handling in NetChannel
- return the correct errno value instead of using -1
2016-03-01 12:34:56 +00:00
James Turner
43dacf5951 HTTP repository testing tool. 2016-02-27 06:35:41 +02:00
James Turner
8adbefb2b7 Fix Windows compile of HTTP repo tests. 2016-02-26 21:21:00 +02:00
James Turner
4eb272f4f0 Lots of work on HTTP repository failure handling. 2016-02-26 21:18:26 +02:00
James Turner
f84dac822a Fix a nasty bug in non-libCurl HTTP pipelining.
- when requests were closely overlapped, but not submitted at the
  same time, connection state could get corrupted.
2016-02-26 00:10:34 +02:00
James Turner
0b4f416ddc More error reporting from TerraSync/HTTP
- raise more errors when requests fail, and report/catch these.
2016-02-25 21:20:33 +02:00
James Turner
6cef1f9091 Fix compilation with older versions of libCurl. 2016-02-25 21:19:44 +02:00
James Turner
5c9f5361bd Fix for libCurl pipelining and connection count. 2016-02-24 23:36:25 +02:00
Torsten Dreyer
ce245059b8 Merge /u/edauvergne/simgear/ branch particles into next
http://sourceforge.net/p/flightgear/simgear/merge-requests/4/
2016-02-23 21:55:18 +00:00
James Turner
4fb205b317 Work around lack of endian.h on Windows 2016-02-22 23:53:27 +02:00
James Turner
624dae5958 Fix a typo breaking HTTP unit-test. 2016-02-22 23:41:13 +02:00
James Turner
d4384422f4 HTTP repository: replace an assert.
- Torsten is seeing this on his setup.
2016-02-22 21:27:03 +02:00
James Turner
935d649096 More HTTP repository compile tweaks. 2016-02-22 21:07:16 +02:00
James Turner
2b147f7429 Use SGFile to avoid Windows breakage. 2016-02-22 20:59:03 +02:00
Torsten Dreyer
da6b395008 Fix SimGear compile on Linux 2016-02-22 19:49:20 +01:00
James Turner
dda922a651 Hopefully fix Linux compilation. 2016-02-22 18:05:02 +02:00
James Turner
d179fccfcb Optionally use HTTP repository.
- disabled by default since needs much testing.
2016-02-21 21:49:20 +02:00
James Turner
ae4d96872d HTTP repository implementation
A plain-HTTP terrasync repository implementation, using the
SimGear HTTP abstraction. File validity is based on SHA hashes,
and existing files are not re-downloaded if their hash matches,
so soft upgrade from an SVN checkout is possible.
2016-02-21 21:49:20 +02:00
James Turner
7075a8707b Create TerraSync repo API
- create an abstract API for a remote repository, based on the current
  SVN repository API, and update the code accordingly.
2016-02-21 15:49:12 +01:00
Edward d'Auvergne
4b7f7861cd Debugging message improvements for the particle system. 2016-02-19 14:33:30 +01:00
Automatic Release Builder
e7598df4d3 new version: 2016.2.0 2016-02-17 21:16:33 +01:00
495 changed files with 48811 additions and 13838 deletions

1
.gitignore vendored
View File

@@ -14,3 +14,4 @@ CTestTestfile.cmake
install_manifest.txt
build*
Build
CMakeLists.txt.user

View File

@@ -2,4 +2,6 @@ if (NOT SYSTEM_EXPAT)
add_subdirectory(expat)
endif()
add_subdirectory(utf8)
if (ENABLE_DNS AND NOT SYSTEM_UDNS)
add_subdirectory(udns)
endif()

41
3rdparty/udns/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,41 @@
include (SimGearComponent)
INCLUDE (CheckFunctionExists)
INCLUDE (CheckSymbolExists)
include (CheckIncludeFile)
CHECK_FUNCTION_EXISTS(poll HAVE_POLL)
CHECK_FUNCTION_EXISTS(getopt HAVE_GETOPT)
CHECK_FUNCTION_EXISTS(inet_ntop HAVE_INET_PTON_NTOP)
CHECK_SYMBOL_EXISTS(AF_INET6 "netinet/in.h" HAVE_IPv6)
# WINDOWS should be defined by msvc, should it?
# somehow it is not, if somebody know a better way to define WINDOWS, please fix
check_include_file(windows.h WINDOWS)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_BINARY_DIR}/config.h)
include_directories(${CMAKE_BINARY_DIR})
set(HEADERS
)
set(SOURCES
udns_resolver.c
udns_dn.c
udns_dntosp.c
udns_parse.c
udns_resolver.c
udns_init.c
udns_misc.c
udns_rr_a.c
udns_rr_ptr.c
udns_rr_mx.c
udns_rr_txt.c
udns_bl.c
udns_rr_srv.c
udns_rr_naptr.c
udns_codes.c
udns_jran.c
udns_XtoX.c
)
simgear_component(udns 3rdparty/udns "${SOURCES}" "${HEADERS}")

502
3rdparty/udns/COPYING.LGPL vendored Normal file
View File

@@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

197
3rdparty/udns/Makefile.in vendored Normal file
View File

@@ -0,0 +1,197 @@
#! /usr/bin/make -rf
# Makefile.in
# libudns Makefile
#
# Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
# This file is part of UDNS library, an async DNS stub resolver.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library, in file named COPYING.LGPL; if not,
# write to the Free Software Foundation, Inc., 59 Temple Place,
# Suite 330, Boston, MA 02111-1307 USA
NAME = udns
VERS = 0.4
SOVER = 0
SRCS = udns_dn.c udns_dntosp.c udns_parse.c udns_resolver.c udns_init.c \
udns_misc.c udns_XtoX.c \
udns_rr_a.c udns_rr_ptr.c udns_rr_mx.c udns_rr_txt.c udns_bl.c \
udns_rr_srv.c udns_rr_naptr.c udns_codes.c udns_jran.c
USRCS = dnsget.c rblcheck.c ex-rdns.c
DIST = COPYING.LGPL udns.h udns.3 dnsget.1 rblcheck.1 $(SRCS) $(USRCS) \
NEWS TODO NOTES Makefile.in configure configure.lib \
inet_XtoX.c getopt.c
OBJS = $(SRCS:.c=.o) $(GEN:.c=.o)
LIB = lib$(NAME).a
LIBFL = -L. -l$(NAME)
SOBJS = $(OBJS:.o=.lo)
SOLIB = lib$(NAME)_s.so
SOLIBV = lib$(NAME).so.$(SOVER)
SOLIBFL= -L. -l$(NAME)_s
UTILS = $(USRCS:.c=)
UOBJS = $(USRCS:.c=.o)
SOUTILS = $(USRCS:.c=_s)
NAMEPFX = $(NAME)-$(VERS)
CC = @CC@
CFLAGS = @CFLAGS@
CDEFS = @CDEFS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
LDSHARED = $(LD) -shared
PICFLAGS = -fPIC
AWK = awk
TAR = tar
all: static
.SUFFIXES: .c .o .lo
static: $(LIB) $(UTILS)
staticlib: $(LIB)
$(LIB): $(OBJS)
-rm -f $@
$(AR) rv $@ $(OBJS)
.c.o:
$(CC) $(CFLAGS) $(CDEFS) -c $<
shared: $(SOLIBV) $(SOUTILS)
sharedlib: $(SOLIBV)
$(SOLIBV): $(SOBJS)
$(LDSHARED) -Wl,--soname,$(SOLIBV) -o $@ $(SOBJS) $(LDFLAGS) $(LIBS)
$(SOLIB): $(SOLIBV)
rm -f $@
ln -s $(SOLIBV) $@
.c.lo:
$(CC) $(CFLAGS) $(PICFLAGS) $(CDEFS) -o $@ -c $<
# udns_codes.c is generated from udns.h
udns_codes.c: udns.h
@echo Generating $@
@set -e; exec >$@.tmp; \
set T type C class R rcode; \
echo "/* Automatically generated. */"; \
echo "#include \"udns.h\""; \
while [ "$$1" ]; do \
echo; \
echo "const struct dns_nameval dns_$${2}tab[] = {"; \
$(AWK) "/^ DNS_$${1}_[A-Z0-9_]+[ ]*=/ \
{ printf \" {%s,\\\"%s\\\"},\\n\", \$$1, substr(\$$1,7) }" \
udns.h ; \
echo " {0,0}};"; \
echo "const char *dns_$${2}name(enum dns_$${2} code) {"; \
echo " static char nm[20];"; \
echo " switch(code) {"; \
$(AWK) "BEGIN{i=0} \
/^ DNS_$${1}_[A-Z0-9_]+[ ]*=/ \
{printf \" case %s: return dns_$${2}tab[%d].name;\\n\",\$$1,i++}\
" udns.h ; \
echo " }"; \
echo " return _dns_format_code(nm,\"$$2\",code);"; \
echo "}"; \
shift 2; \
done
@mv $@.tmp $@
udns.3.html: udns.3
groff -man -Thtml udns.3 > $@.tmp
mv $@.tmp $@
dist: $(NAMEPFX).tar.gz
$(NAMEPFX).tar.gz: $(DIST)
$(TAR) -cv -f $@ -z --transform 's|^|$(NAMEPFX)/|' $(DIST)
subdist:
cp -p $(DIST) $(TARGET)/
clean:
rm -f $(OBJS)
rm -f $(SOBJS)
rm -f $(UOBJS)
rm -f config.log
distclean: clean
rm -f $(LIB) $(SOLIB) $(SOLIBV) udns.3.html
rm -f $(UTILS) $(SOUTILS)
rm -f config.status config.h Makefile
Makefile: configure configure.lib Makefile.in
./configure
@echo
@echo Please rerun make >&2
@exit 1
.PHONY: all static staticlib shared sharedlib dist clean distclean subdist \
depend dep deps
depend dep deps: $(SRCS) $(USRC)
@echo Generating deps for:
@echo \ $(SRCS)
@echo \ $(USRCS)
@sed '/^# depend/q' Makefile.in > Makefile.tmp
@set -e; \
for f in $(SRCS) $(USRCS); do \
echo $${f%.c}.o $${f%.c}.lo: $$f \
`sed -n 's/^#[ ]*include[ ]*"\(.*\)".*/\1/p' $$f`; \
done >> Makefile.tmp; \
for f in $(USRCS:.c=.o); do \
echo "$${f%.?}: $$f \$$(LIB)"; \
echo " \$$(LD) \$$(LDLAGS) -o \$$@ $$f \$$(LIBFL) \$$(LIBS)"; \
echo "$${f%.?}_s: $$f \$$(SOLIB)"; \
echo " \$$(LD) \$$(LDFLAGS) -o \$$@ $$f \$$(SOLIBFL)"; \
done >> Makefile.tmp ; \
if cmp Makefile.tmp Makefile.in >/dev/null 2>&1 ; then \
echo Makefile.in unchanged; rm -f Makefile.tmp; \
else \
echo Updating Makfile.in; mv -f Makefile.tmp Makefile.in ; \
fi
# depend
udns_dn.o udns_dn.lo: udns_dn.c udns.h
udns_dntosp.o udns_dntosp.lo: udns_dntosp.c udns.h
udns_parse.o udns_parse.lo: udns_parse.c udns.h
udns_resolver.o udns_resolver.lo: udns_resolver.c config.h udns.h
udns_init.o udns_init.lo: udns_init.c config.h udns.h
udns_misc.o udns_misc.lo: udns_misc.c udns.h
udns_XtoX.o udns_XtoX.lo: udns_XtoX.c config.h udns.h inet_XtoX.c
udns_rr_a.o udns_rr_a.lo: udns_rr_a.c udns.h
udns_rr_ptr.o udns_rr_ptr.lo: udns_rr_ptr.c udns.h
udns_rr_mx.o udns_rr_mx.lo: udns_rr_mx.c udns.h
udns_rr_txt.o udns_rr_txt.lo: udns_rr_txt.c udns.h
udns_bl.o udns_bl.lo: udns_bl.c udns.h
udns_rr_srv.o udns_rr_srv.lo: udns_rr_srv.c udns.h
udns_rr_naptr.o udns_rr_naptr.lo: udns_rr_naptr.c udns.h
udns_codes.o udns_codes.lo: udns_codes.c udns.h
udns_jran.o udns_jran.lo: udns_jran.c udns.h
dnsget.o dnsget.lo: dnsget.c config.h udns.h getopt.c
rblcheck.o rblcheck.lo: rblcheck.c config.h udns.h getopt.c
ex-rdns.o ex-rdns.lo: ex-rdns.c udns.h
dnsget: dnsget.o $(LIB)
$(LD) $(LDLAGS) -o $@ dnsget.o $(LIBFL) $(LIBS)
dnsget_s: dnsget.o $(SOLIB)
$(LD) $(LDFLAGS) -o $@ dnsget.o $(SOLIBFL)
rblcheck: rblcheck.o $(LIB)
$(LD) $(LDLAGS) -o $@ rblcheck.o $(LIBFL) $(LIBS)
rblcheck_s: rblcheck.o $(SOLIB)
$(LD) $(LDFLAGS) -o $@ rblcheck.o $(SOLIBFL)
ex-rdns: ex-rdns.o $(LIB)
$(LD) $(LDLAGS) -o $@ ex-rdns.o $(LIBFL) $(LIBS)
ex-rdns_s: ex-rdns.o $(SOLIB)
$(LD) $(LDFLAGS) -o $@ ex-rdns.o $(SOLIBFL)

136
3rdparty/udns/NEWS vendored Normal file
View File

@@ -0,0 +1,136 @@
NEWS
User-visible changes in udns library. Recent changes on top.
0.4 (Jan 2014)
- bugfix: fix a bug in new list code introduced in 0.3
- portability: use $(LD)/$(LDFLAGS)/$(LIBS)
0.3 (Jan 2014)
- bugfix: refactor double-linked list implementation in udns_resolver.c
(internal to the library) to be more strict-aliasing-friendly, because
old code were miscompiled by gcc.
- bugfix: forgotten strdup() in rblcheck
0.2 (Dec 2011)
- bugfix: SRV RR handling: fix domain name parsing and crash in case
if no port is specified on input for SRV record query
- (trivial api) dns_set_opts() now returns number of unrecognized
options instead of always returning 0
- dnsget: combine -f and -o options in dnsget (and stop documenting -f),
and report unknown/invalid -o options (and error out)
- dnsget: pretty-print SSHFP RRs
0.1 (Dec 2010)
- bugfix: udns_new(old) - when actually cloning another context -
makes the new context referencing memory from old, which leads
to crashes when old is modified later
- use random queue IDs (the 16bit qID) in queries instead of sequentional
ones, based on simple pseudo-random RNG by Bob Jenkins (udns_jran.[ch]).
Some people believe that this improves security (CVE-2008-1447). I'm
still not convinced (see comments in udns_resolver.c), but it isn't
difficult to add after all.
- deprecate dns_random16() function which was declared in udns.h
(not anymore) but never documented. In order to keep ABI compatible
it is still exported.
- library has a way now to set query flags (DNS_SET_DO; DNS_SET_CD).
- dnsget now prints non-printable chars in all strings in DNS RRs using
decimal escape sequences (\%03u) instead of hexadecimal (\%02x) when
before - other DNS software does it like this.
- recognize a few more record types in dnsget, notable some DNSSEC RRs;
add -f option for dnsget to set query flags.
- udns is not a Debian native package anymore (was a wrong idea)
0.0.9 (16 Jan 2007)
- incompat: minor API changes in dns_init() &friends. dns_init()
now requires extra `struct dns_ctx *' argument. Not bumped
soversion yet - I only expect one "release" with this change.
- many small bugfixes, here and there
- more robust FORMERR replies handling - not only such replies are now
recognized, but udns retries queries without EDNS0 extensions if tried
with, but server reported FORMERR
- portability changes, udns now includes getopt() implementation fo
the systems lacking it (mostly windows), and dns_ntop()&dns_pton(),
which are either just wrappers for system functions or reimplementations.
- build is now based on autoconf-like configuration
- NAPTR (RFC3403) RR decoding support
- new file NOTES which complements TODO somewhat, and includes some
important shortcomings
- many internal cleanups, including some preparations for better error
recovery, security and robustness (and thus API changes)
- removed some #defines which are now unused (like DNS_MAXSRCH)
- changed WIN32 to WINDOWS everywhere in preprocessor tests,
to be able to build it on win64 as well
0.0.8 (12 Sep 2005)
- added SRV records (rfc2782) parsing,
thanks to Thadeu Lima de Souza Cascardo for implementation.
- bugfixes:
o use uninitialized value when no reply, library died with assertion:
assert((status < 0 && result == 0) || (status >= 0 && result != 0)).
o on some OSes, struct sockaddr_in has additional fields, so
memcmp'ing two sockaddresses does not work.
- rblcheck(.1)
0.0.7 (20 Apr 2005)
- dnsget.1 manpage and several enhancements to dnsget.
- allow nameserver names for -n option of dnsget.
- API change: all dns_submit*() routines now does not expect
last `now' argument, since requests aren't sent immediately
anymore.
- API change: different application timer callback mechanism.
Udns now uses single per-context timer instead of per-query.
- don't assume DNS replies only contain backward DN pointers,
allow forward pointers too. Change parsing API.
- debianize
0.0.6 (08 Apr 2005)
- use double sorted list for requests (sorted by deadline).
This should significantly speed up timeout processing for
large number of requests.
- changed debugging interface, so it is finally useable
(still not documented).
- dnsget routine is now Officially Useable, and sometimes
even more useable than `host' from BIND distribution
(and sometimes not - dnsget does not have -C option
and TCP mode)
- Debian packaging in debian/ -- udns is now maintained as a
native Debian package.
- alot (and I really mean alot) of code cleanups all over.

226
3rdparty/udns/NOTES vendored Normal file
View File

@@ -0,0 +1,226 @@
Assorted notes about udns (library).
UDP-only mode
~~~~~~~~~~~~~
First of all, since udns is (currently) UDP-only, there are some
shortcomings.
It assumes that a reply will fit into a UDP buffer. With adoption of EDNS0,
and general robustness of IP stacks, in most cases it's not an issue. But
in some cases there may be problems:
- if an RRset is "very large" so it does not fit even in buffer of size
requested by the library (current default is 4096; some servers limits
it further), we will not see the reply, or will only see "damaged"
reply (depending on the server).
- many DNS servers ignores EDNS0 option requests. In this case, no matter
which buffer size udns library will request, such servers reply is limited
to 512 bytes (standard pre-EDNS0 DNS packet size). (Udns falls back to
non-EDNO0 query if EDNS0-enabled one received FORMERR or NOTIMPL error).
The problem is that with this, udns currently will not consider replies with
TC (truncation) bit set, and will treat such replies the same way as it
treats SERVFAIL replies, thus trying next server, or temp-failing the query
if no more servers to try. In other words, if the reply is really large, or
if the servers you're using don't support EDNS0, your application will be
unable to resolve a given name.
Yet it's not common situation - in practice, it's very rare.
Implementing TCP mode isn't difficult, but it complicates API significantly.
Currently udns uses only single UDP socket (or - maybe in the future - two,
see below), but in case of TCP, it will need to open and close sockets for
TCP connections left and right, and that have to be integrated into an
application's event loop in an easy and efficient way. Plus all the
timeouts - different for connect(), write, and several stages of read.
IPv6 vs IPv4 usage
~~~~~~~~~~~~~~~~~~
This is only relevant for nameservers reachable over IPv6, NOT for IPv6
queries. I.e., if you've IPv6 addresses in 'nameservers' line in your
/etc/resolv.conf file. Even more: if you have BOTH IPv6 AND IPv4 addresses
there. Or pass them to udns initialization routines.
Since udns uses a single UDP socket to communicate with all nameservers,
it should support both v4 and v6 communications. Most current platforms
supports this mode - using PF_INET6 socket and V4MAPPED addresses, i.e,
"tunnelling" IPv4 inside IPv6. But not all systems supports this. And
more, it has been said that such mode is deprecated.
So, list only IPv4 or only IPv6 addresses, but don't mix them, in your
/etc/resolv.conf.
An alternative is to use two sockets instead of 1 - one for IPv6 and one
for IPv4. For now I'm not sure if it's worth the complexity - again, of
the API, not the library itself (but this will not simplify library either).
Single socket for all queries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using single UDP socket for sending queries to all nameservers has obvious
advantages. First it's, again, trivial, simple to use API. And simple
library too. Also, after sending queries to all nameservers (in case first
didn't reply in time), we will be able to receive late reply from first
nameserver and accept it.
But this mode has disadvantages too. Most important is that it's much easier
to send fake reply to us, as the UDP port where we expects the reply to come
to is constant during the whole lifetime of an application. More secure
implementations uses random port for every single query. While port number
(16 bits integer) can not hold much randomness, it's still of some help.
Ok, udns is a stub resolver, so it expects sorta friendly environment, but
on LAN it's usually much easier to fire an attack, due to the speed of local
network, where a bad guy can generate alot of packets in a short time.
Spoofing of replies (Kaminsky attack, CVE-2008-1447)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
While udns uses random numbers for query IDs, it uses single UDP port for
all queries (see previous item). And even if it used random UDP port for
each query, the attack described in CVE-2008-1447 is still quite trivial.
This is not specific to udns library unfortunately - it is inherent property
of the protocol. Udns is designed to work in a LAN, it needs full recursive
resolver nearby, and modern LAN usually uses high-bandwidth equipment which
makes the Kaminsky attack trivial. The problem is that even with qID (16
bits) and random UDP port (about 20 bits available to a regular process)
combined still can not hold enough randomness, so on a fast network it is
still easy to flood the target with fake replies and hit the "right" reply
before real reply comes. So random qIDs don't add much protection anyway,
even if this feature is implemented in udns, and using all available
techniques wont solve it either.
See also long comment in udns_resolver.c, udns_newid().
Assumptions about RRs returned
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Currently udns processes records in the reply it received sequentially.
This means that order of the records is significant. For example, if
we asked for foo.bar A, but the server returned that foo.bar is a CNAME
(alias) for bar.baz, and bar.baz, in turn, has address 1.2.3.4, when
the CNAME should come first in reply, followed by A. While DNS specs
does not say anything about order of records - it's an rrSET - unordered, -
I think an implementation which returns the records in "wrong" order is
somewhat insane...
CNAME recursion
~~~~~~~~~~~~~~~
Another interesting point is the handling of CNAMEs returned as replies
to non-CNAME queries. If we asked for foo.bar A, but it's a CNAME, udns
expects BOTH the CNAME itself and the target DN to be present in the reply.
In other words, udns DOES NOT RECURSE CNAMES. If we asked for foo.bar A,
but only record in reply was that foo.bar is a CNAME for bar.baz, udns will
return no records to an application (NXDOMAIN). Strictly speaking, udns
should repeat the query asking for bar.baz A, and recurse. But since it's
stub resolver, recursive resolver should recurse for us instead.
It's not very difficult to implement, however. Probably with some (global?)
flag to en/dis-able the feature. Provided there's some demand for it.
To clarify: udns handles CNAME recursion in a single reply packet just fine.
Note also that standard gethostbyname() routine does not recurse in this
situation, too.
Error reporting
~~~~~~~~~~~~~~~
Too many places in the code (various failure paths) sets generic "TEMPFAIL"
error condition. For example, if no nameserver replied to our query, an
application will get generic TEMPFAIL, instead of something like TIMEDOUT.
This probably should be fixed, but most applications don't care about the
exact reasons of failure - 4 common cases are already too much:
- query returned some valid data
- NXDOMAIN
- valid domain but no data of requested type - =NXDOMAIN in most cases
- temporary error - this one sometimes (incorrectly!) treated as NXDOMAIN
by (naive) applications.
DNS isn't yes/no, it's at least 3 variants, temp err being the 3rd important
case! And adding more variations for the temp error case is complicating things
even more - again, from an application writer standpoint. For diagnostics,
such more specific error cases are of good help.
Planned API changes
~~~~~~~~~~~~~~~~~~~
At least one thing I want to change for some future version is a way how
queries are submitted and how replies are handled.
I want to made dns_query object to be owned by an application. So that instead
of udns library allocating it for the lifetime of query, it will be pre-
allocated by an application. This simplifies and enhances query submitting
interface, and complicates it a bit too, in simplest cases.
Currently, we have:
dns_submit_dn(dn, cls, typ, flags, parse, cbck, data)
dns_submit_p(name, cls, typ, flags, parse, cbck, data)
dns_submit_a4(ctx, name, flags, cbck, data)
and so on -- with many parameters missed for type-specific cases, but generic
cases being too complex for most common usage.
Instead, with dns_query being owned by an app, we will be able to separately
set up various parts of the query - domain name (various forms), type&class,
parser, flags, callback... and even change them at runtime. And we will also
be able to reuse query structures, instead of allocating/freeing them every
time. So the whole thing will look something like:
q = dns_alloc_query();
dns_submit(dns_q_flags(dns_q_a4(q, name, cbck), DNS_F_NOSRCH), data);
The idea is to have a set of functions accepting struct dns_query* and
returning it (so the calls can be "nested" like the above), to set up
relevant parts of the query - specific type of callback, conversion from
(type-specific) query parameters into a domain name (this is for type-
specific query initializers), and setting various flags and options and
type&class things.
One example where this is almost essential - if we want to support
per-query set of nameservers (which isn't at all useless: imagine a
high-volume mail server, were we want to direct DNSBL queries to a separate
set of nameservers, and rDNS queries to their own set and so on). Adding
another argument (set of nameservers to use) to EVERY query submitting
routine is.. insane. Especially since in 99% cases it will be set to
default NULL. But with such "nesting" of query initializers, it becomes
trivial.
This change (the way how queries gets submitted) will NOT break API/ABI
compatibility with old versions, since the new submitting API works in
parallel with current (and current will use the new one as building
blocks, instead of doing all work at once).
Another way to do the same is to manipulate query object right after a
query has been submitted, but before any events processing (during this
time, query object is allocated and initialized, but no actual network
packets were sent - it will happen on the next event processing). But
this way it become impossible to perform syncronous resolver calls, since
those calls hide query objects they use internally.
Speaking of replies handling - the planned change is to stop using dynamic
memory (malloc) inside the library. That is, instead of allocating a buffer
for a reply dynamically in a parsing routine (or memdup'ing the raw reply
packet if no parsing routine is specified), I want udns to return the packet
buffer it uses internally, and change parsing routines to expect a buffer
for result. When parsing, a routine will return true amount of memory it
will need to place the result, regardless of whenever it has enough room
or not, so that an application can (re)allocate properly sized buffer and
call a parsing routine again.
This, in theory, also can be done without breaking current API/ABI, but in
that case we'll again need a parallel set of routines (parsing included),
which makes the library more complicated with too many ways of doing the
same thing. Still, code reuse is at good level.
Another modification I plan to include is to have an ability to work in
terms of domain names (DNs) as used with on-wire DNS packets, not only
with asciiz representations of them. For this to work, the above two
changes (query submission and result passing) have to be completed first
(esp. the query submission part), so that it will be possible to specify
some additional query flags (for example) to request domain names instead
of the text strings, and to allow easy query submissions with either DNs
or text strings.

59
3rdparty/udns/TODO vendored Normal file
View File

@@ -0,0 +1,59 @@
TODO
The following is mostly an internal, not user-visible stuff.
* rearrange an API to make dns_query object owned by application,
so that it'll look like this:
struct dns_query *q;
q = dns_query_alloc(ctx);
dns_query_set(q, options, domain_name, flags, ...);
dns_query_submit(ctx, q);
For more information see NOTES file, section "Planned API changes".
* allow NULL callbacks? Or provide separate resolver
context list of queries which are done but wich did not
have callback, and dns_pick() routine to retrieve results
from this query, i.e. allow non-callback usage? The
non-callback usage may be handy sometimes (any *good*
example?), but it will be difficult to provide type-safe
non-callback interface due to various RR-specific types
in use.
* DNS_OPT_FLAGS should be DNS_OPT_ADDFLAGS and DNS_OPT_SETFLAGS.
Currently one can't add a single flag bit but preserve
existing bits... at least not without retrieving all current
flags before, which isn't that bad anyway.
* dns_set_opts() may process flags too (such as aaonly etc)
* a way to disable $NSCACHEIP et al processing?
(with now separate dns_init() and dns_reset(), it has finer
control, but still no way to init from system files but ignore
environment variables and the like)
* initialize/open the context automatically, and be more
liberal about initialization in general?
* dns_init(ctx, do_open) - make the parameter opposite, aka
dns_init(ctx, skip_open) ?
* allow TCP queue?
* more accurate error reporting. Currently, udns always returns TEMPFAIL,
but don't specify why it happened (ENOMEM, timeout, etc).
* check the error value returned by recvfrom() and
sendto() and determine which errors to ignore.
* maybe merge dns_timeouts() and dns_ioevent(), to have
only one entry point for everything? For traditional
select-loop-based eventloop it may be easier, but for
callback-driven event loops the two should be separate.
Provide an option, or a single dns_events() entry point
for select-loop approach, or just call dns_ioevent()
from within dns_timeouts() (probably after renaming
it to be dns_events()) ?
* implement /etc/hosts lookup too, ala [c-]ares??
* sortlist support?

5
3rdparty/udns/config.h.in vendored Normal file
View File

@@ -0,0 +1,5 @@
#cmakedefine HAVE_POLL
#cmakedefine HAVE_GETOPT
#cmakedefine HAVE_INET_PTON_NTOP
#cmakedefine HAVE_IPv6
#cmakedefine WINDOWS

165
3rdparty/udns/configure vendored Executable file
View File

@@ -0,0 +1,165 @@
#! /bin/sh
# autoconf-style configuration script
#
set -e
name=udns
if [ -f udns.h -a -f udns_resolver.c ] ; then :
else
echo "configure: error: sources not found at `pwd`" >&2
exit 1
fi
options="ipv6"
for opt in $options; do
eval enable_$opt=
done
if [ -f config.status ]; then
. ./config.status
fi
enable() {
opt=`echo "$1" | sed 's/^--[^-]*-//'`
case "$opt" in
ipv6) ;;
*) echo "configure: unrecognized option \`$1'" >&2; exit 1;;
esac
eval enable_$opt=$2
}
while [ $# -gt 0 ]; do
case "$1" in
--disable-*|--without-*|--no-*) enable "$1" n;;
--enable-*|--with-*) enable "$1" y;;
--help | --hel | --he | --h | -help | -hel | -he | -h )
cat <<EOF
configure: configure $name package.
Usage: ./configure [options]
where options are:
--enable-option, --with-option --
enable the named option/feature
--disable-option, --without-option, --no-option --
disable the named option/feature
--help - print this help and exit
Optional features (all enabled by default if system supports a feature):
ipv6 - enable/disable IP version 6 (IPv6) support
EOF
exit 0
;;
*) echo "configure: unknown option \`$1'" >&2; exit 1 ;;
esac
shift
done
. ./configure.lib
ac_msg "configure"
ac_result "$name package"
ac_prog_c_compiler_v
ac_prog_ranlib_v
ac_ign ac_yesno "for getopt()" ac_have GETOPT ac_link <<EOF
#include <stdio.h>
extern int optind;
extern char *optarg;
extern int getopt(int, char **, char *);
int main(int argc, char **argv) {
getopt(argc, argv, "abc");
return optarg ? optind : 0;
}
EOF
if ac_library_find_v 'socket and connect' "" "-lsocket -lnsl" <<EOF
int main() { socket(); connect(); return 0; }
EOF
then :
else
ac_fatal "cannot find libraries needed for sockets"
fi
ac_ign \
ac_yesno "for inet_pton() && inet_ntop()" \
ac_have INET_PTON_NTOP \
ac_link <<EOF
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main() {
char buf[64];
long x = 0;
inet_pton(AF_INET, &x, buf);
return inet_ntop(AF_INET, &x, buf, sizeof(buf));
}
EOF
if ac_yesno "for socklen_t" ac_compile <<EOF
#include <sys/types.h>
#include <sys/socket.h>
int foo() { socklen_t len; len = 0; return len; }
EOF
then :
else
ac_define socklen_t int
fi
if [ n != "$enable_ipv6" ]; then
if ac_yesno "for IPv6" ac_have IPv6 ac_compile <<EOF
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
struct sockaddr_in6 sa;
sa.sin6_family = AF_INET6;
return 0;
}
EOF
then :
elif [ "$enable_ipv6" ]; then
ac_fatal "IPv6 is requested but not available"
fi
fi # !disable_ipv6?
if ac_yesno "for poll()" ac_have POLL ac_link <<EOF
#include <sys/types.h>
#include <sys/poll.h>
int main() {
struct pollfd pfd[2];
return poll(pfd, 2, 10);
}
EOF
then :
else
ac_ign ac_yesno "for sys/select.h" ac_have SYS_SELECT_H ac_cpp <<EOF
#include <sys/types.h>
#include <sys/select.h>
EOF
fi
ac_config_h
ac_output Makefile
ac_msg "creating config.status"
rm -f config.status
{
echo "# automatically generated by configure to hold command-line options"
echo
found=
for opt in $options; do
eval val=\$enable_$opt
if [ -n "$val" ]; then
echo enable_$opt=$val
found=y
fi
done
if [ ! "$found" ]; then
echo "# (no options encountered)"
fi
} > config.status
ac_result ok
ac_result "all done."
exit 0

268
3rdparty/udns/configure.lib vendored Normal file
View File

@@ -0,0 +1,268 @@
# configure.lib
# a library of shell routines for simple autoconf system
#
set -e
ac_substitutes=
rm -f conftest* config.log
exec 5>config.log
cat <<EOF >&5
This file contains any messages produced by compilers etc while
running configure, to aid debugging if configure script makes a mistake.
EOF
case `echo "a\c"` in
*c*) ac_en=-n ac_ec= ;;
*) ac_en= ac_ec='\c' ;;
esac
##### Messages
ac_msg() {
echo $ac_en "$*... $ac_ec"
echo ">>> $*" >&5
}
ac_checking() {
echo $ac_en "checking $*... $ac_ec"
echo ">>> checking $*" >&5
}
ac_result() {
echo "$1"
echo "=== $1" >&5
}
ac_fatal() {
echo "configure: fatal: $*" >&2
echo "=== FATAL: $*" >&5
exit 1
}
ac_warning() {
echo "configure: warning: $*" >&2
echo "=== WARNING: $*" >&5
}
ac_ign() {
"$@" || :
}
# ac_run command...
# captures output in conftest.out
ac_run() {
# apparently UnixWare (for one) /bin/sh optimizes the following "if"
# "away", by checking if there's such a command BEFORE redirecting
# output. So error message (like "gcc: command not found") goes
# to stderr instead of to conftest.out, and `cat conftest.out' below
# fails.
if "$@" >conftest.out 2>&1; then
return 0
else
echo "==== Command invocation failed. Command line was:" >&5
echo "$*" >&5
echo "==== compiler input was:" >&5
cat conftest.c >&5
echo "==== output was:" >&5
cat conftest.out >&5
echo "====" >&5
return 1
fi
}
# common case for ac_verbose: yes/no result
ac_yesno() {
ac_checking "$1"
shift
if "$@"; then
ac_result yes
return 0
else
ac_result no
return 1
fi
}
ac_subst() {
ac_substitutes="$ac_substitutes $*"
}
ac_define() {
CDEFS="$CDEFS -D$1=${2:-1}"
}
ac_have() {
ac_what=$1; shift
if "$@"; then
ac_define HAVE_$ac_what
eval ac_have_$ac_what=yes
return 0
else
eval ac_have_$ac_what=no
return 1
fi
}
##### Compiling, linking
# run a compiler
ac_run_compiler() {
rm -f conftest*; cat >conftest.c
ac_run $CC $CFLAGS $CDEFS "$@" conftest.c
}
ac_compile() {
ac_run_compiler -c
}
ac_link() {
ac_run_compiler -o conftest $LIBS "$@"
}
ac_cpp() {
ac_run_compiler -E "$@"
}
### check for C compiler. Set $CC, $CFLAGS etc
ac_prog_c_compiler_v() {
ac_checking "for C compiler"
rm -f conftest*
echo 'int main(int argc, char **argv) { return 0; }' >conftest.c
if [ -n "$CC" ]; then
if ac_run $CC -o conftest conftest.c && ac_run ./conftest; then
ac_result "\$CC ($CC)"
else
ac_result no
ac_fatal "\$CC ($CC) is not a working compiler"
fi
else
for cc in gcc cc ; do
if ac_run $cc -o conftest conftest.c && ac_run ./conftest; then
ac_result "$cc"
CC=$cc
break
fi
done
if [ -z "$CC" ]; then
ac_result no
ac_fatal "no working C compiler found in \$PATH. please set \$CC variable"
fi
fi
if [ -z "$CFLAGS" ]; then
if ac_yesno "whenever C compiler ($CC) is GNU CC" \
ac_grep_cpp yEs_mAsTeR <<EOF
#ifdef __GNUC__
yEs_mAsTeR;
#endif
EOF
then
CFLAGS="-Wall -W -O2 -pipe"
else
CFLAGS=-O
fi
fi
cc="$CC $CFLAGS"
ccld="$cc"
if [ -n "$LDFLAGS" ]; then ccld="$ccld $LDFLAGS"; fi
if [ -n "$LIBS" ]; then ccld="$ccld $LIBS"; fi
if ac_yesno "whenever the C compiler ($ccld)
can produce executables" \
ac_compile_run <<EOF
int main() { return 0; }
EOF
then :
else
ac_fatal "no working C compiler found"
fi
LD='$(CC)'
[ -n "$AR" ] || AR=ar
[ -n "$ARFLAGS" ] || ARFLAGS=rv
[ -n "$AWK" ] || AWK=awk
ac_substitutes="$ac_substitutes CC CFLAGS CDEFS LD LDFLAGS LIBS AR ARFLAGS AWK"
}
ac_prog_ranlib_v() {
ac_checking "for ranlib"
if [ -n "$RANLIB" ]; then
ac_result "\$RANLIB ($RANLIB)"
else
ifs="$IFS"
IFS=:
for dir in $PATH; do
[ -n "$dir" ] || dir=.
if [ -f $dir/ranlib ]; then
RANLIB=ranlib
break
fi
done
IFS="$ifs"
if [ -z "$RANLIB" ]; then ac_result no; RANLIB=:
else ac_result "$RANLIB"
fi
fi
ac_substitutes="$ac_substitutes RANLIB"
}
ac_library_find_v() {
ac_checking "for libraries needed for $1"
shift
fond=
rm -f conftest*; cat >conftest.c
for lib in "$@"; do
if ac_run $CC $CFLAGS $LDFLAGS conftest.c -o conftest $LIBS $lib; then
found=y
break
fi
done
if [ ! "$found" ]; then
ac_result "not found"
return 1
fi
if [ -z "$lib" ]; then
ac_result "ok (none needed)"
else
ac_result "ok ($lib)"
LIBS="$LIBS $lib"
fi
}
ac_compile_run() {
ac_link "$@" && ac_run ./conftest
}
ac_grep_cpp() {
pattern="$1"; shift
ac_cpp "$@" && grep "$pattern" conftest.out >/dev/null
}
ac_output() {
for var in $ac_substitutes; do
eval echo "\"s|@$var@|\$$var|\""
done >conftest.sed
for file in "$@"; do
ac_msg "creating $file"
if [ -f $file.in ]; then
sed -f conftest.sed $file.in > $file.tmp
mv -f $file.tmp $file
ac_result ok
else
ac_result failed
ac_fatal "$file.in not found"
fi
done
rm -f conftest*
}
ac_config_h() {
h=${1:-config.h}
ac_msg "creating $h"
rm -f $1.tmp
echo "/* automatically generated by configure. */" > $h.tmp
echo "$CDEFS" | tr ' ' '
' | sed -e 's/^-D/#define /' -e 's/=/ /' >> $h.tmp
if [ -f $h ] && cmp -s $h.tmp $h ; then
rm -f $h.tmp
ac_result unchanged
else
mv -f $h.tmp $h
ac_result ok
fi
CDEFS=-DHAVE_CONFIG_H
}

195
3rdparty/udns/dnsget.1 vendored Normal file
View File

@@ -0,0 +1,195 @@
.\" dnsget.1: dnsget manpage
.\"
.\" Copyright (C) 2005-2014 Michael Tokarev <mjt+udns@tls.msk.ru>
.\" This file is part of UDNS library, an async DNS stub resolver.
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library, in file named COPYING.LGPL; if not,
.\" write to the Free Software Foundation, Inc., 59 Temple Place,
.\" Suite 330, Boston, MA 02111-1307 USA
.TH dnsget 1 "Jan 2014" "User Utilities"
.SH NAME
dnsget \- DNS lookup utility
.SH SYNOPSYS
.B dnsget
.RB [\| \-v \||\| \-q \|]
.RB [\| \-c
.IR class \|]
.RB [\| \-t
.IR type \|]
.RB [\| \-o
.IR opt , opt ,...]
.IR name \|.\|.\|.
.SH DESCRIPTION
.B dnsget
is a simple command-line to perform DNS lookups, similar to
.BR host (1)
and
.BR dig (1).
It is useable for both interactive/debugging scenarious and
in scripts.
The program is implemented using
.BR udns (3)
library.
.PP
By default,
.B dnsget
produces a human-readable output, similar to
.RS
.nf
alias.example.com. CNAME www.example.com.
www.example.com. A 192.168.1.1
www.example.com. MX 10 mx.example.com.
.fi
.RE
which is just sufficient to see how a given name resolves.
Output format is controllable with
.B \-v
and
.B \-q
options -- the former increases verbosity level up to printing
the whole DNS contents of all packets sent and received, which
is suitable for debugging DNS problems, while the latter reduces
the level, making output more quiet, up to bare result with no
error messages, which is good for scripts.
.SH OPTIONS
The following options are recognized by
.BR dnsget :
.TP
.B \-v
produce more detailed output. More
.BR \-v 's
means more details will be produced. With single
.BR \-v , dnsget
will print contents of all received DNS packets (in a readable format),
while with
.BR \-vv ,
it will output all outgoing DNS packets too.
.TP
.B \-q
the opposite for \fB\-v\fR -- produce less detailed output.
With single
.BR \-q , dnsget
will only show (decoded) data from final DNS resource records (RR),
while
.B \-qq
also suppresses error messages.
.TP
\fB\-t \fItype\fR
request record(s) of the given type \fItype\fR. By default,
.B dnsget
will ask for IPv4 address (A) record, or for PTR record if the
argument in question is an IPv4 or IPv6 address. Recognized
types include A, AAAA, MX, TXT, CNAME, PTR, NS, SOA, ANY and
others.
.TP
\fB\-c \fIclass\fR
request DNS record(s) of the given class \fIclass\fR. By
default
.B dnsget
uses IN class. Valid classes include IN, CH, HS, ANY.
.TP
.B \-a
(compatibility option). Equivalent to setting query type to
.B ANY
and increasing verbosity level
.RB ( \-v ).
.TP
.B \-C
(planned)
.TP
.B \-x
(planned)
.TP
\fB\-o \fIopt\fR,\fIopt\fR,...
(may be specified several times).
Set resolver options (in a form \fIoption\fR:\fIvalue\fR) as if they
were set in
.RB $ RES_OPTIONS
environment variable, or set query flags:
.RS
.TP
\fBtimeout\fR:\fIsec\fR
Set initial query timeout to \fIsec\fR.
.TP
\fBattempts\fR:\fInum\fR
(re)try every query \fInum\fR times before failing.
.TP
\fBudpbuf\fR:\fIbytes\fR
set DNS UDP buffer size to \fIbytes\fR bytes. Valid values
are from 512 to 65535. If \fIbytes\fR is greather than 512,
EDNS0 (RFC 2671) extensions will be used.
.TP
\fBport\fR:\fInum\fR
Use given UDP port number \fInum\fR instead of the default port 53 (domain).
.TP
\fBaa\fR
set AA (auth only) query bit.
.TP
\fBnord\fR
do not set RD (recursion desired) query bit (set by default).
.TP
\fBdnssec\fR or \fBdo\fR
set DNSSEC OK (DO) query flag (\fBdnsget\fR does not verify DNSSEC signatures,
only displays them; this is set in EDNS RR).
.TP
\fBcd\fR
set CD (checking disabled) query bit.
.RE
.TP
\fB\-n \fInameserver\fR
Use the given nameserver(s) (may be specified more than once)
instead of the default. Using this option has the same same effect as
.RB $ NSCACHEIP
or
.RB $ NAMESERVERS
environment variables, with the only difference that only IPv4 addresses
are recognized for now, and it is possible to specify names (which will
be resolved using default settings) instead of IP addresses.
.TP
.B \-h
print short help and exit.
.SH "RETURN VALUE"
When all names where resovled successefully,
.B dnsget
exits with zero exit status. If at least one name was not found,
.B dnsget
will exit with return code 100. If some other error occured during
name resolution, it will exit with code 99. In case of usage or
initialization error,
.B dnsget
will return 1.
.SH "SEE ALSO"
.BR host (1)
.BR dig (1)
.BR resolv.conf (5)
.BR udns (3).

759
3rdparty/udns/dnsget.c vendored Normal file
View File

@@ -0,0 +1,759 @@
/* dnsget.c
simple host/dig-like application using UDNS library
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef WINDOWS
#include <windows.h>
#include <winsock2.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <unistd.h>
#endif
#include <time.h>
#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "udns.h"
#ifndef HAVE_GETOPT
# include "getopt.c"
#endif
#ifndef AF_INET6
# define AF_INET6 10
#endif
static char *progname;
static int verbose = 1;
static int errors;
static int notfound;
/* verbosity level:
* <0 - bare result
* 0 - bare result and error messages
* 1 - readable result
* 2 - received packet contents and `trying ...' stuff
* 3 - sent and received packet contents
*/
static void die(int errnum, const char *fmt, ...) {
va_list ap;
fprintf(stderr, "%s: ", progname);
va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap);
if (errnum) fprintf(stderr, ": %s\n", strerror(errnum));
else putc('\n', stderr);
fflush(stderr);
exit(1);
}
static const char *dns_xntop(int af, const void *src) {
static char buf[6*5+4*4];
return dns_ntop(af, src, buf, sizeof(buf));
}
struct query {
const char *name; /* original query string */
unsigned char *dn; /* the DN being looked up */
enum dns_type qtyp; /* type of the query */
};
static void query_free(struct query *q) {
free(q->dn);
free(q);
}
static struct query *
query_new(const char *name, const unsigned char *dn, enum dns_type qtyp) {
struct query *q = malloc(sizeof(*q));
unsigned l = dns_dnlen(dn);
unsigned char *cdn = malloc(l);
if (!q || !cdn) die(0, "out of memory");
memcpy(cdn, dn, l);
q->name = name;
q->dn = cdn;
q->qtyp = qtyp;
return q;
}
static enum dns_class qcls = DNS_C_IN;
static void
dnserror(struct query *q, int errnum) {
if (verbose >= 0)
fprintf(stderr, "%s: unable to lookup %s record for %s: %s\n", progname,
dns_typename(q->qtyp), dns_dntosp(q->dn), dns_strerror(errnum));
if (errnum == DNS_E_NXDOMAIN || errnum == DNS_E_NODATA)
++notfound;
else
++errors;
query_free(q);
}
static const unsigned char *
printtxt(const unsigned char *c) {
unsigned n = *c++;
const unsigned char *e = c + n;
if (verbose > 0) while(c < e) {
if (*c < ' ' || *c >= 127) printf("\\%03u", *c);
else if (*c == '\\' || *c == '"') printf("\\%c", *c);
else putchar(*c);
++c;
}
else
fwrite(c, n, 1, stdout);
return e;
}
static void
printhex(const unsigned char *c, const unsigned char *e) {
while(c < e)
printf("%02x", *c++);
}
static unsigned char to_b64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void
printb64(const unsigned char *c, const unsigned char *e) {
while(c < e) {
putchar(to_b64[c[0] >> 2]);
if (c+1 < e) {
putchar(to_b64[(c[0] & 0x3) << 4 | c[1] >> 4]);
if (c+2 < e) {
putchar(to_b64[(c[1] & 0xf) << 2 | c[2] >> 6]);
putchar(to_b64[c[2] & 0x3f]);
}
else {
putchar(to_b64[(c[1] & 0xf) << 2]);
putchar('=');
break;
}
}
else {
putchar(to_b64[(c[0] & 0x3) << 4]);
putchar('=');
putchar('=');
break;
}
c += 3;
}
}
static void
printdate(time_t time) {
struct tm *tm = gmtime(&time);
printf("%04d%02d%02d%02d%02d%02d",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
static void
printrr(const struct dns_parse *p, struct dns_rr *rr) {
const unsigned char *pkt = p->dnsp_pkt;
const unsigned char *end = p->dnsp_end;
const unsigned char *dptr = rr->dnsrr_dptr;
const unsigned char *dend = rr->dnsrr_dend;
unsigned char *dn = rr->dnsrr_dn;
const unsigned char *c;
unsigned n;
if (verbose > 0) {
if (verbose > 1) {
if (!p->dnsp_rrl && !rr->dnsrr_dn[0] && rr->dnsrr_typ == DNS_T_OPT) {
printf(";EDNS%d OPT record (UDPsize: %d, ERcode: %d, Flags: 0x%02x): %d bytes\n",
(rr->dnsrr_ttl>>16) & 0xff, /* version */
rr->dnsrr_cls, /* udp size */
(rr->dnsrr_ttl>>24) & 0xff, /* extended rcode */
rr->dnsrr_ttl & 0xffff, /* flags */
rr->dnsrr_dsz);
return;
}
n = printf("%s.", dns_dntosp(rr->dnsrr_dn));
printf("%s%u\t%s\t%s\t",
n > 15 ? "\t" : n > 7 ? "\t\t" : "\t\t\t",
rr->dnsrr_ttl,
dns_classname(rr->dnsrr_cls),
dns_typename(rr->dnsrr_typ));
}
else
printf("%s. %s ", dns_dntosp(rr->dnsrr_dn), dns_typename(rr->dnsrr_typ));
}
switch(rr->dnsrr_typ) {
case DNS_T_CNAME:
case DNS_T_PTR:
case DNS_T_NS:
case DNS_T_MB:
case DNS_T_MD:
case DNS_T_MF:
case DNS_T_MG:
case DNS_T_MR:
if (dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN) <= 0) goto xperr;
printf("%s.", dns_dntosp(dn));
break;
case DNS_T_A:
if (rr->dnsrr_dsz != 4) goto xperr;
printf("%d.%d.%d.%d", dptr[0], dptr[1], dptr[2], dptr[3]);
break;
case DNS_T_AAAA:
if (rr->dnsrr_dsz != 16) goto xperr;
printf("%s", dns_xntop(AF_INET6, dptr));
break;
case DNS_T_MX:
c = dptr + 2;
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || c != dend) goto xperr;
printf("%d %s.", dns_get16(dptr), dns_dntosp(dn));
break;
case DNS_T_TXT:
/* first verify it */
for(c = dptr; c < dend; c += n) {
n = *c++;
if (c + n > dend) goto xperr;
}
c = dptr; n = 0;
while (c < dend) {
if (verbose > 0) printf(n++ ? "\" \"":"\"");
c = printtxt(c);
}
if (verbose > 0) putchar('"');
break;
case DNS_T_HINFO: /* CPU, OS */
c = dptr;
n = *c++; if ((c += n) >= dend) goto xperr;
n = *c++; if ((c += n) != dend) goto xperr;
c = dptr;
if (verbose > 0) putchar('"');
c = printtxt(c);
if (verbose > 0) printf("\" \""); else putchar(' ');
printtxt(c);
if (verbose > 0) putchar('"');
break;
case DNS_T_WKS:
c = dptr;
if (dptr + 4 + 2 >= end) goto xperr;
printf("%s %d", dns_xntop(AF_INET, dptr), dptr[4]);
c = dptr + 5;
for (n = 0; c < dend; ++c, n += 8) {
if (*c) {
unsigned b;
for (b = 0; b < 8; ++b)
if (*c & (1 << (7-b))) printf(" %d", n + b);
}
}
break;
case DNS_T_SRV: /* prio weight port targetDN */
c = dptr;
c += 2 + 2 + 2;
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || c != dend) goto xperr;
c = dptr;
printf("%d %d %d %s.",
dns_get16(c+0), dns_get16(c+2), dns_get16(c+4),
dns_dntosp(dn));
break;
case DNS_T_NAPTR: /* order pref flags serv regexp repl */
c = dptr;
c += 4; /* order, pref */
for (n = 0; n < 3; ++n)
if (c >= dend) goto xperr;
else c += *c + 1;
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || c != dend) goto xperr;
c = dptr;
printf("%u %u", dns_get16(c+0), dns_get16(c+2));
c += 4;
for(n = 0; n < 3; ++n) {
putchar(' ');
if (verbose > 0) putchar('"');
c = printtxt(c);
if (verbose > 0) putchar('"');
}
printf(" %s.", dns_dntosp(dn));
break;
case DNS_T_KEY:
case DNS_T_DNSKEY:
/* flags(2) proto(1) algo(1) pubkey */
case DNS_T_DS:
case DNS_T_DLV:
/* ktag(2) proto(1) algo(1) pubkey */
c = dptr;
if (c + 2 + 1 + 1 > dend) goto xperr;
printf("%d %d %d", dns_get16(c), c[2], c[3]);
c += 2 + 1 + 1;
if (c < dend) {
putchar(' ');
printb64(c, dend);
}
break;
case DNS_T_SIG:
case DNS_T_RRSIG:
/* type(2) algo(1) labels(1) ottl(4) sexp(4) sinc(4) tag(2) sdn sig */
c = dptr;
c += 2 + 1 + 1 + 4 + 4 + 4 + 2;
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0) goto xperr;
printf("%s %u %u %u ",
dns_typename(dns_get16(dptr)), dptr[2], dptr[3], dns_get32(dptr+4));
printdate(dns_get32(dptr+8));
putchar(' ');
printdate(dns_get32(dptr+12));
printf(" %d %s. ", dns_get16(dptr+10), dns_dntosp(dn));
printb64(c, dend);
break;
case DNS_T_SSHFP: /* algo(1), fp type(1), fp... */
if (dend < dptr + 3) goto xperr;
printf("%u %u ", dptr[0], dptr[1]); /* algo, fp type */
printhex(dptr + 2, dend);
break;
#if 0 /* unused RR types? */
case DNS_T_NSEC: /* nextDN bitmaps */
c = dptr;
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0) goto xperr;
printf("%s.", dns_dntosp(dn));
unfinished.
break;
#endif
case DNS_T_SOA:
c = dptr;
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 ||
dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 ||
c + 4*5 != dend)
goto xperr;
dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN);
printf("%s. ", dns_dntosp(dn));
dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN);
printf("%s. ", dns_dntosp(dn));
printf("%u %u %u %u %u",
dns_get32(dptr), dns_get32(dptr+4), dns_get32(dptr+8),
dns_get32(dptr+12), dns_get32(dptr+16));
break;
case DNS_T_MINFO:
c = dptr;
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 ||
dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 ||
c != dend)
goto xperr;
dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN);
printf("%s. ", dns_dntosp(dn));
dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN);
printf("%s.", dns_dntosp(dn));
break;
case DNS_T_NULL:
default:
printhex(dptr, dend);
break;
}
putchar('\n');
return;
xperr:
printf("<parse error>\n");
++errors;
}
static int
printsection(struct dns_parse *p, int nrr, const char *sname) {
struct dns_rr rr;
int r;
if (!nrr) return 0;
if (verbose > 1) printf("\n;; %s section (%d):\n", sname, nrr);
p->dnsp_rrl = nrr;
while((r = dns_nextrr(p, &rr)) > 0)
printrr(p, &rr);
if (r < 0) printf("<<ERROR>>\n");
return r;
}
/* dbgcb will only be called if verbose > 1 */
static void
dbgcb(int code, const struct sockaddr *sa, unsigned slen,
const unsigned char *pkt, int r,
const struct dns_query *unused_q, void *unused_data) {
struct dns_parse p;
const unsigned char *cur, *end;
int numqd;
if (code > 0) {
printf(";; trying %s.\n", dns_dntosp(dns_payload(pkt)));
printf(";; sending %d bytes query to ", r);
}
else
printf(";; received %d bytes response from ", r);
if (sa->sa_family == AF_INET && slen >= sizeof(struct sockaddr_in))
printf("%s port %d\n",
dns_xntop(AF_INET, &((struct sockaddr_in*)sa)->sin_addr),
htons(((struct sockaddr_in*)sa)->sin_port));
#ifdef HAVE_IPv6
else if (sa->sa_family == AF_INET6 && slen >= sizeof(struct sockaddr_in6))
printf("%s port %d\n",
dns_xntop(AF_INET6, &((struct sockaddr_in6*)sa)->sin6_addr),
htons(((struct sockaddr_in6*)sa)->sin6_port));
#endif
else
printf("<<unknown socket type %d>>\n", sa->sa_family);
if (code > 0 && verbose < 3) {
putchar('\n');
return;
}
if (code == -2) printf(";; reply from unexpected source\n");
if (code == -5) printf(";; reply to a query we didn't sent (or old)\n");
if (r < DNS_HSIZE) {
printf(";; short packet (%d bytes)\n", r);
return;
}
if (dns_opcode(pkt) != 0)
printf(";; unexpected opcode %d\n", dns_opcode(pkt));
if (dns_tc(pkt) != 0)
printf(";; warning: TC bit set, probably incomplete reply\n");
printf(";; ->>HEADER<<- opcode: ");
switch(dns_opcode(pkt)) {
case 0: printf("QUERY"); break;
case 1: printf("IQUERY"); break;
case 2: printf("STATUS"); break;
default: printf("UNKNOWN(%u)", dns_opcode(pkt)); break;
}
printf(", status: %s, id: %d, size: %d\n;; flags:",
dns_rcodename(dns_rcode(pkt)), dns_qid(pkt), r);
if (dns_qr(pkt)) printf(" qr");
if (dns_aa(pkt)) printf(" aa");
if (dns_tc(pkt)) printf(" tc");
if (dns_rd(pkt)) printf(" rd");
if (dns_ra(pkt)) printf(" ra");
/* if (dns_z(pkt)) printf(" z"); only one reserved bit left */
if (dns_ad(pkt)) printf(" ad");
if (dns_cd(pkt)) printf(" cd");
numqd = dns_numqd(pkt);
printf("; QUERY: %d, ANSWER: %d, AUTHORITY: %d, ADDITIONAL: %d\n",
numqd, dns_numan(pkt), dns_numns(pkt), dns_numar(pkt));
if (numqd != 1)
printf(";; unexpected number of entries in QUERY section: %d\n",
numqd);
printf("\n;; QUERY SECTION (%d):\n", numqd);
cur = dns_payload(pkt);
end = pkt + r;
while(numqd--) {
if (dns_getdn(pkt, &cur, end, p.dnsp_dnbuf, DNS_MAXDN) <= 0 ||
cur + 4 > end) {
printf("; invalid query section\n");
return;
}
r = printf(";%s.", dns_dntosp(p.dnsp_dnbuf));
printf("%s%s\t%s\n",
r > 23 ? "\t" : r > 15 ? "\t\t" : r > 7 ? "\t\t\t" : "\t\t\t\t",
dns_classname(dns_get16(cur+2)), dns_typename(dns_get16(cur)));
cur += 4;
}
p.dnsp_pkt = pkt;
p.dnsp_cur = p.dnsp_ans = cur;
p.dnsp_end = end;
p.dnsp_qdn = NULL;
p.dnsp_qcls = p.dnsp_qtyp = 0;
p.dnsp_ttl = 0xffffffffu;
p.dnsp_nrr = 0;
r = printsection(&p, dns_numan(pkt), "ANSWER");
if (r == 0)
r = printsection(&p, dns_numns(pkt), "AUTHORITY");
if (r == 0)
r = printsection(&p, dns_numar(pkt), "ADDITIONAL");
putchar('\n');
}
static void dnscb(struct dns_ctx *ctx, void *result, void *data) {
int r = dns_status(ctx);
struct query *q = data;
struct dns_parse p;
struct dns_rr rr;
unsigned nrr;
unsigned char dn[DNS_MAXDN];
const unsigned char *pkt, *cur, *end;
if (!result) {
dnserror(q, r);
return;
}
pkt = result; end = pkt + r; cur = dns_payload(pkt);
dns_getdn(pkt, &cur, end, dn, sizeof(dn));
dns_initparse(&p, NULL, pkt, cur, end);
p.dnsp_qcls = p.dnsp_qtyp = 0;
nrr = 0;
while((r = dns_nextrr(&p, &rr)) > 0) {
if (!dns_dnequal(dn, rr.dnsrr_dn)) continue;
if ((qcls == DNS_C_ANY || qcls == rr.dnsrr_cls) &&
(q->qtyp == DNS_T_ANY || q->qtyp == rr.dnsrr_typ))
++nrr;
else if (rr.dnsrr_typ == DNS_T_CNAME && !nrr) {
if (dns_getdn(pkt, &rr.dnsrr_dptr, end,
p.dnsp_dnbuf, sizeof(p.dnsp_dnbuf)) <= 0 ||
rr.dnsrr_dptr != rr.dnsrr_dend) {
r = DNS_E_PROTOCOL;
break;
}
else {
if (verbose == 1) {
printf("%s.", dns_dntosp(dn));
printf(" CNAME %s.\n", dns_dntosp(p.dnsp_dnbuf));
}
dns_dntodn(p.dnsp_dnbuf, dn, sizeof(dn));
}
}
}
if (!r && !nrr)
r = DNS_E_NODATA;
if (r < 0) {
dnserror(q, r);
free(result);
return;
}
if (verbose < 2) { /* else it is already printed by dbgfn */
dns_rewind(&p, NULL);
p.dnsp_qtyp = q->qtyp == DNS_T_ANY ? 0 : q->qtyp;
p.dnsp_qcls = qcls == DNS_C_ANY ? 0 : qcls;
while(dns_nextrr(&p, &rr))
printrr(&p, &rr);
}
free(result);
query_free(q);
}
int main(int argc, char **argv) {
int i;
int fd;
fd_set fds;
struct timeval tv;
time_t now;
char *ns[DNS_MAXSERV];
int nns = 0;
struct query *q;
enum dns_type qtyp = 0;
struct dns_ctx *nctx = NULL;
int flags = 0;
if (!(progname = strrchr(argv[0], '/'))) progname = argv[0];
else argv[0] = ++progname;
if (argc <= 1)
die(0, "try `%s -h' for help", progname);
if (dns_init(NULL, 0) < 0 || !(nctx = dns_new(NULL)))
die(errno, "unable to initialize dns library");
/* we keep two dns contexts: one may be needed to resolve
* nameservers if given as names, using default options.
*/
while((i = getopt(argc, argv, "vqt:c:an:o:f:h")) != EOF) switch(i) {
case 'v': ++verbose; break;
case 'q': --verbose; break;
case 't':
if (optarg[0] == '*' && !optarg[1])
i = DNS_T_ANY;
else if ((i = dns_findtypename(optarg)) <= 0)
die(0, "unrecognized query type `%s'", optarg);
qtyp = i;
break;
case 'c':
if (optarg[0] == '*' && !optarg[1])
i = DNS_C_ANY;
else if ((i = dns_findclassname(optarg)) < 0)
die(0, "unrecognized query class `%s'", optarg);
qcls = i;
break;
case 'a':
qtyp = DNS_T_ANY;
++verbose;
break;
case 'n':
if (nns >= DNS_MAXSERV)
die(0, "too many nameservers, %d max", DNS_MAXSERV);
ns[nns++] = optarg;
break;
case 'o':
case 'f': {
char *opt;
const char *const delim = " \t,;";
for(opt = strtok(optarg, delim); opt != NULL; opt = strtok(NULL, delim)) {
if (dns_set_opts(NULL, optarg) == 0)
;
else if (strcmp(opt, "aa") == 0) flags |= DNS_AAONLY;
else if (strcmp(optarg, "nord") == 0) flags |= DNS_NORD;
else if (strcmp(optarg, "dnssec") == 0) flags |= DNS_SET_DO;
else if (strcmp(optarg, "do") == 0) flags |= DNS_SET_DO;
else if (strcmp(optarg, "cd") == 0) flags |= DNS_SET_CD;
else
die(0, "invalid option: `%s'", opt);
}
break;
}
case 'h':
printf(
"%s: simple DNS query tool (using udns version %s)\n"
"Usage: %s [options] domain-name...\n"
"where options are:\n"
" -h - print this help and exit\n"
" -v - be more verbose\n"
" -q - be less verbose\n"
" -t type - set query type (A, AAA, PTR etc)\n"
" -c class - set query class (IN (default), CH, HS, *)\n"
" -a - equivalent to -t ANY -v\n"
" -n ns - use given nameserver(s) instead of default\n"
" (may be specified multiple times)\n"
" -o opt,opt,... (comma- or space-separated list,\n"
" may be specified more than once):\n"
" set resovler options (the same as setting $RES_OPTIONS):\n"
" timeout:sec - initial query timeout\n"
" attempts:num - number of attempt to resovle a query\n"
" ndots:num - if name has more than num dots, lookup it before search\n"
" port:num - port number for queries instead of default 53\n"
" udpbuf:num - size of UDP buffer (use EDNS0 if >512)\n"
" or query flags:\n"
" aa,nord,dnssec,do,cd - set query flag (auth-only, no recursion,\n"
" enable DNSSEC (DNSSEC Ok), check disabled)\n"
, progname, dns_version(), progname);
return 0;
default:
die(0, "try `%s -h' for help", progname);
}
argc -= optind; argv += optind;
if (!argc)
die(0, "no name(s) to query specified");
if (nns) {
/* if nameservers given as names, resolve them.
* We only allow IPv4 nameservers as names for now.
* Ok, it is easy enouth to try both AAAA and A,
* but the question is what to do by default.
*/
struct sockaddr_in sin;
int j, r = 0, opened = 0;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(dns_set_opt(NULL, DNS_OPT_PORT, -1));
dns_add_serv(NULL, NULL);
for(i = 0; i < nns; ++i) {
if (dns_pton(AF_INET, ns[i], &sin.sin_addr) <= 0) {
struct dns_rr_a4 *rr;
if (!opened) {
if (dns_open(nctx) < 0)
die(errno, "unable to initialize dns context");
opened = 1;
}
rr = dns_resolve_a4(nctx, ns[i], 0);
if (!rr)
die(0, "unable to resolve nameserver %s: %s",
ns[i], dns_strerror(dns_status(nctx)));
for(j = 0; j < rr->dnsa4_nrr; ++j) {
sin.sin_addr = rr->dnsa4_addr[j];
if ((r = dns_add_serv_s(NULL, (struct sockaddr *)&sin)) < 0)
break;
}
free(rr);
}
else
r = dns_add_serv_s(NULL, (struct sockaddr *)&sin);
if (r < 0)
die(errno, "unable to add nameserver %s",
dns_xntop(AF_INET, &sin.sin_addr));
}
}
dns_free(nctx);
fd = dns_open(NULL);
if (fd < 0)
die(errno, "unable to initialize dns context");
if (verbose > 1)
dns_set_dbgfn(NULL, dbgcb);
if (flags)
dns_set_opt(NULL, DNS_OPT_FLAGS, flags);
for (i = 0; i < argc; ++i) {
char *name = argv[i];
union {
struct in_addr addr;
struct in6_addr addr6;
} a;
unsigned char dn[DNS_MAXDN];
enum dns_type l_qtyp = 0;
int abs;
if (dns_pton(AF_INET, name, &a.addr) > 0) {
dns_a4todn(&a.addr, 0, dn, sizeof(dn));
l_qtyp = DNS_T_PTR;
abs = 1;
}
#ifdef HAVE_IPv6
else if (dns_pton(AF_INET6, name, &a.addr6) > 0) {
dns_a6todn(&a.addr6, 0, dn, sizeof(dn));
l_qtyp = DNS_T_PTR;
abs = 1;
}
#endif
else if (!dns_ptodn(name, strlen(name), dn, sizeof(dn), &abs))
die(0, "invalid name `%s'\n", name);
else
l_qtyp = DNS_T_A;
if (qtyp) l_qtyp = qtyp;
q = query_new(name, dn, l_qtyp);
if (abs) abs = DNS_NOSRCH;
if (!dns_submit_dn(NULL, dn, qcls, l_qtyp, abs, 0, dnscb, q))
dnserror(q, dns_status(NULL));
}
FD_ZERO(&fds);
now = 0;
while((i = dns_timeouts(NULL, -1, now)) > 0) {
FD_SET(fd, &fds);
tv.tv_sec = i;
tv.tv_usec = 0;
i = select(fd+1, &fds, 0, 0, &tv);
now = time(NULL);
if (i > 0) dns_ioevent(NULL, now);
}
return errors ? 1 : notfound ? 100 : 0;
}

114
3rdparty/udns/ex-rdns.c vendored Normal file
View File

@@ -0,0 +1,114 @@
/* ex-rdns.c
parallel rDNS resolver example - read IP addresses from stdin,
write domain names to stdout
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/poll.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "udns.h"
static int curq;
static const char *n2ip(const unsigned char *c) {
static char b[sizeof("255.255.255.255")];
sprintf(b, "%u.%u.%u.%u", c[0], c[1], c[2], c[3]);
return b;
}
static void dnscb(struct dns_ctx *ctx, struct dns_rr_ptr *rr, void *data) {
const char *ip = n2ip((unsigned char *)&data);
int i;
--curq;
if (rr) {
printf("%s", ip);
for(i = 0; i < rr->dnsptr_nrr; ++i)
printf(" %s", rr->dnsptr_ptr[i]);
putchar('\n');
free(rr);
}
else
fprintf(stderr, "%s: %s\n", ip, dns_strerror(dns_status(ctx)));
}
int main(int argc, char **argv) {
int c;
time_t now;
int maxq = 10;
struct pollfd pfd;
char linebuf[1024];
char *eol;
int eof;
if (dns_init(NULL, 1) < 0) {
fprintf(stderr, "unable to initialize dns library\n");
return 1;
}
while((c = getopt(argc, argv, "m:r")) != EOF) switch(c) {
case 'm': maxq = atoi(optarg); break;
case 'r':
dns_set_opt(0, DNS_OPT_FLAGS,
dns_set_opt(0, DNS_OPT_FLAGS, -1) | DNS_NORD);
break;
default: return 1;
}
if (argc != optind) return 1;
pfd.fd = dns_sock(0);
pfd.events = POLLIN;
now = time(NULL);
c = optind;
eof = 0;
while(curq || !eof) {
if (!eof && curq < maxq) {
union { struct in_addr a; void *p; } pa;
if (!fgets(linebuf, sizeof(linebuf), stdin)) {
eof = 1;
continue;
}
eol = strchr(linebuf, '\n');
if (eol) *eol = '\0';
if (!linebuf[0]) continue;
if (dns_pton(AF_INET, linebuf, &pa.a) <= 0)
fprintf(stderr, "%s: invalid address\n", linebuf);
else if (dns_submit_a4ptr(0, &pa.a, dnscb, pa.p) == 0)
fprintf(stderr, "%s: unable to submit query: %s\n",
linebuf, dns_strerror(dns_status(0)));
else
++curq;
continue;
}
if (curq) {
c = dns_timeouts(0, -1, now);
c = poll(&pfd, 1, c < 0 ? -1 : c * 1000);
now = time(NULL);
if (c)
dns_ioevent(0, now);
}
}
return 0;
}

165
3rdparty/udns/getopt.c vendored Normal file
View File

@@ -0,0 +1,165 @@
/* getopt.c
* Simple getopt() implementation.
*
* Standard interface:
* extern int getopt(int argc, char *const *argv, const char *opts);
* extern int optind; current index in argv[]
* extern char *optarg; argument for the current option
* extern int optopt; the current option
* extern int opterr; to control error printing
*
* Some minor extensions:
* ignores leading `+' sign in opts[] (unemplemented GNU extension)
* handles optional arguments, in form "x::" in opts[]
* if opts[] starts with `:', will return `:' in case of missing required
* argument, instead of '?'.
*
* Compile with -DGETOPT_NO_OPTERR to never print errors internally.
* Compile with -DGETOPT_NO_STDIO to use write() calls instead of fprintf() for
* error reporting (ignored with -DGETOPT_NO_OPTERR).
* Compile with -DGETOPT_CLASS=static to get static linkage.
* Compile with -DGETOPT_MY to redefine all visible symbols to be prefixed
* with "my_", like my_getopt instead of getopt.
* Compile with -DTEST to get a test executable.
*
* Written by Michael Tokarev. Public domain.
*/
#include <string.h>
#ifndef GETOPT_CLASS
# define GETOPT_CLASS
#endif
#ifdef GETOPT_MY
# define optarg my_optarg
# define optind my_optind
# define opterr my_opterr
# define optopt my_optopt
# define getopt my_getopt
#endif
GETOPT_CLASS char *optarg /* = NULL */;
GETOPT_CLASS int optind = 1;
GETOPT_CLASS int opterr = 1;
GETOPT_CLASS int optopt;
static char *nextc /* = NULL */;
#if defined(GETOPT_NO_OPTERR)
#define printerr(argv, msg)
#elif defined(GETOPT_NO_STDIO)
extern int write(int, void *, int);
static void printerr(char *const *argv, const char *msg) {
if (opterr) {
char buf[64];
unsigned pl = strlen(argv[0]);
unsigned ml = strlen(msg);
char *p;
if (pl + /*": "*/2 + ml + /*" -- c\n"*/6 > sizeof(buf)) {
write(2, argv[0], pl);
p = buf;
}
else {
memcpy(buf, argv[0], ml);
p = buf + pl;
}
*p++ = ':'; *p++ = ' ';
memcpy(p, msg, ml); p += ml;
*p++ = ' '; *p++ = '-'; *p++ = '-'; *p++ = ' ';
*p++ = optopt;
*p++ = '\n';
write(2, buf, p - buf);
}
}
#else
#include <stdio.h>
static void printerr(char *const *argv, const char *msg) {
if (opterr)
fprintf(stderr, "%s: %s -- %c\n", argv[0], msg, optopt);
}
#endif
GETOPT_CLASS int getopt(int argc, char *const *argv, const char *opts) {
char *p;
optarg = 0;
if (*opts == '+') /* GNU extension (permutation) - isn't supported */
++opts;
if (!optind) { /* a way to reset things */
nextc = 0;
optind = 1;
}
if (!nextc || !*nextc) { /* advance to the next argv element */
/* done scanning? */
if (optind >= argc)
return -1;
/* not an optional argument */
if (argv[optind][0] != '-')
return -1;
/* bare `-' */
if (argv[optind][1] == '\0')
return -1;
/* special case `--' argument */
if (argv[optind][1] == '-' && argv[optind][2] == '\0') {
++optind;
return -1;
}
nextc = argv[optind] + 1;
}
optopt = *nextc++;
if (!*nextc)
++optind;
p = strchr(opts, optopt);
if (!p || optopt == ':') {
printerr(argv, "illegal option");
return '?';
}
if (p[1] == ':') {
if (*nextc) {
optarg = nextc;
nextc = NULL;
++optind;
}
else if (p[2] != ':') { /* required argument */
if (optind >= argc) {
printerr(argv, "option requires an argument");
return *opts == ':' ? ':' : '?';
}
else
optarg = argv[optind++];
}
}
return optopt;
}
#ifdef TEST
#include <stdio.h>
int main(int argc, char **argv) {
int c;
while((c = getopt(argc, argv, "ab:c::")) != -1) switch(c) {
case 'a':
case 'b':
case 'c':
printf("option %c %s\n", c, optarg ? optarg : "(none)");
break;
default:
return -1;
}
for(c = optind; c < argc; ++c)
printf("non-opt: %s\n", argv[c]);
return 0;
}
#endif

327
3rdparty/udns/inet_XtoX.c vendored Normal file
View File

@@ -0,0 +1,327 @@
/* inet_XtoX.c
* Simple implementation of the following functions:
* inet_ntop(), inet_ntoa(), inet_pton(), inet_aton().
*
* Differences from traditional implementaitons:
* o modifies destination buffers even on error return.
* o no fancy (hex, or 1.2) input support in inet_aton()
* o inet_aton() does not accept junk after an IP address.
* o inet_ntop(AF_INET) requires at least 16 bytes in dest,
* and inet_ntop(AF_INET6) at least 40 bytes
* (traditional inet_ntop() will try to fit anyway)
*
* Compile with -Dinet_XtoX_prefix=pfx_ to have pfx_*() instead of inet_*()
* Compile with -Dinet_XtoX_no_ntop or -Dinet_XtoX_no_pton
* to disable net2str or str2net conversions.
*
* #define inet_XtoX_prototypes and #include "this_file.c"
* to get function prototypes only (but not for inet_ntoa()).
* #define inet_XtoX_decl to be `static' for static visibility,
* or use __declspec(dllexport) or somesuch...
*
* Compile with -DTEST to test against stock implementation.
*
* Written by Michael Tokarev. Public domain.
*/
#ifdef inet_XtoX_prototypes
struct in_addr;
#else
#include <errno.h>
#ifdef TEST
# include <netinet/in.h>
# include <sys/socket.h>
# include <arpa/inet.h>
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
# undef inet_XtoX_prefix
# define inet_XtoX_prefix mjt_inet_
# undef inet_XtoX_no_ntop
# undef inet_XtoX_no_pton
#else /* !TEST */
struct in_addr { /* declare it here to avoid messing with headers */
unsigned char x[4];
};
#endif /* TEST */
#endif /* inet_XtoX_prototypes */
#ifndef inet_XtoX_prefix
# define inet_XtoX_prefix inet_
#endif
#ifndef inet_XtoX_decl
# define inet_XtoX_decl /*empty*/
#endif
#define cc2_(x,y) cc2__(x,y)
#define cc2__(x,y) x##y
#define fn(x) cc2_(inet_XtoX_prefix,x)
#ifndef inet_XtoX_no_ntop
inet_XtoX_decl const char *
fn(ntop)(int af, const void *src, char *dst, unsigned size);
#ifndef inet_XtoX_prototypes
static int mjt_ntop4(const void *_src, char *dst, int size) {
unsigned i, x, r;
char *p;
const unsigned char *s = _src;
if (size < 4*4) /* for simplicity, disallow non-max-size buffer */
return 0;
for (i = 0, p = dst; i < 4; ++i) {
if (i) *p++ = '.';
x = r = s[i];
if (x > 99) { *p++ = (char)(r / 100 + '0'); r %= 100; }
if (x > 9) { *p++ = (char)(r / 10 + '0'); r %= 10; }
*p++ = (char)(r + '0');
}
*p = '\0';
return 1;
}
static char *hexc(char *p, unsigned x) {
static char hex[16] = "0123456789abcdef";
if (x > 0x0fff) *p++ = hex[(x >>12) & 15];
if (x > 0x00ff) *p++ = hex[(x >> 8) & 15];
if (x > 0x000f) *p++ = hex[(x >> 4) & 15];
*p++ = hex[x & 15];
return p;
}
static int mjt_ntop6(const void *_src, char *dst, int size) {
unsigned i;
unsigned short w[8];
unsigned bs = 0, cs = 0;
unsigned bl = 0, cl = 0;
char *p;
const unsigned char *s = _src;
if (size < 40) /* for simplicity, disallow non-max-size buffer */
return 0;
for(i = 0; i < 8; ++i, s += 2) {
w[i] = (((unsigned short)(s[0])) << 8) | s[1];
if (!w[i]) {
if (!cl++) cs = i;
}
else {
if (cl > bl) bl = cl, bs = cs;
}
}
if (cl > bl) bl = cl, bs = cs;
p = dst;
if (bl == 1)
bl = 0;
if (bl) {
for(i = 0; i < bs; ++i) {
if (i) *p++ = ':';
p = hexc(p, w[i]);
}
*p++ = ':';
i += bl;
if (i == 8)
*p++ = ':';
}
else
i = 0;
for(; i < 8; ++i) {
if (i) *p++ = ':';
if (i == 6 && !bs && (bl == 6 || (bl == 5 && w[5] == 0xffff)))
return mjt_ntop4(s - 4, p, size - (p - dst));
p = hexc(p, w[i]);
}
*p = '\0';
return 1;
}
inet_XtoX_decl const char *
fn(ntop)(int af, const void *src, char *dst, unsigned size) {
switch(af) {
/* don't use AF_*: don't mess with headers */
case 2: /* AF_INET */ if (mjt_ntop4(src, dst, size)) return dst; break;
case 10: /* AF_INET6 */ if (mjt_ntop6(src, dst, size)) return dst; break;
default: errno = EAFNOSUPPORT; return (char*)0;
}
errno = ENOSPC;
return (char*)0;
}
inet_XtoX_decl const char *
fn(ntoa)(struct in_addr addr) {
static char buf[4*4];
mjt_ntop4(&addr, buf, sizeof(buf));
return buf;
}
#endif /* inet_XtoX_prototypes */
#endif /* inet_XtoX_no_ntop */
#ifndef inet_XtoX_no_pton
inet_XtoX_decl int fn(pton)(int af, const char *src, void *dst);
inet_XtoX_decl int fn(aton)(const char *src, struct in_addr *addr);
#ifndef inet_XtoX_prototypes
static int mjt_pton4(const char *c, void *dst) {
unsigned char *a = dst;
unsigned n, o;
for (n = 0; n < 4; ++n) {
if (*c < '0' || *c > '9')
return 0;
o = *c++ - '0';
while(*c >= '0' && *c <= '9')
if ((o = o * 10 + (*c++ - '0')) > 255)
return 0;
if (*c++ != (n == 3 ? '\0' : '.'))
return 0;
*a++ = (unsigned char)o;
}
return 1;
}
static int mjt_pton6(const char *c, void *dst) {
unsigned short w[8], *a = w, *z, *i;
unsigned v, o;
const char *sc;
unsigned char *d = dst;
if (*c != ':') z = (unsigned short*)0;
else if (*++c != ':') return 0;
else ++c, z = a;
i = 0;
for(;;) {
v = 0;
sc = c;
for(;;) {
if (*c >= '0' && *c <= '9') o = *c - '0';
else if (*c >= 'a' && *c <= 'f') o = *c - 'a' + 10;
else if (*c >= 'A' && *c <= 'F') o = *c - 'A' + 10;
else break;
v = (v << 4) | o;
if (v > 0xffff) return 0;
++c;
}
if (sc == c) {
if (z == a && !*c)
break;
else
return 0;
}
if (*c == ':') {
if (a >= w + 8)
return 0;
*a++ = v;
if (*++c == ':') {
if (z)
return 0;
z = a;
if (!*++c)
break;
}
}
else if (!*c) {
if (a >= w + 8)
return 0;
*a++ = v;
break;
}
else if (*c == '.') {
if (a > w + 6)
return 0;
if (!mjt_pton4(sc, d))
return 0;
*a++ = ((unsigned)(d[0]) << 8) | d[1];
*a++ = ((unsigned)(d[2]) << 8) | d[3];
break;
}
else
return 0;
}
v = w + 8 - a;
if ((v && !z) || (!v && z))
return 0;
for(i = w; ; ++i) {
if (i == z)
while(v--) { *d++ = '\0'; *d++ = '\0'; }
if (i >= a)
break;
*d++ = (unsigned char)((*i >> 8) & 255);
*d++ = (unsigned char)(*i & 255);
}
return 1;
}
inet_XtoX_decl int fn(pton)(int af, const char *src, void *dst) {
switch(af) {
/* don't use AF_*: don't mess with headers */
case 2 /* AF_INET */: return mjt_pton4(src, dst);
case 10 /* AF_INET6 */: return mjt_pton6(src, dst);
default: errno = EAFNOSUPPORT; return -1;
}
}
inet_XtoX_decl int fn(aton)(const char *src, struct in_addr *addr) {
return mjt_pton4(src, addr);
}
#endif /* inet_XtoX_prototypes */
#endif /* inet_XtoX_no_pton */
#ifdef TEST
int main(int argc, char **argv) {
int i;
char n0[16], n1[16];
char p0[64], p1[64];
int af = AF_INET;
int pl = sizeof(p0);
int r0, r1;
const char *s0, *s1;
while((i = getopt(argc, argv, "46a:p:")) != EOF) switch(i) {
case '4': af = AF_INET; break;
case '6': af = AF_INET6; break;
case 'a': case 'p': pl = atoi(optarg); break;
default: return 1;
}
for(i = optind; i < argc; ++i) {
char *a = argv[i];
printf("%s:\n", a);
r0 = inet_pton(af, a, n0);
printf(" p2n stock: %s\n",
(r0 < 0 ? "(notsupp)" : !r0 ? "(inval)" : fn(ntop)(af,n0,p0,sizeof(p0))));
r1 = fn(pton)(af, a, n1);
printf(" p2n this : %s\n",
(r1 < 0 ? "(notsupp)" : !r1 ? "(inval)" : fn(ntop)(af,n1,p1,sizeof(p1))));
if ((r0 > 0) != (r1 > 0) ||
(r0 > 0 && r1 > 0 && memcmp(n0, n1, af == AF_INET ? 4 : 16) != 0))
printf(" DIFFER!\n");
s0 = inet_ntop(af, n1, p0, pl);
printf(" n2p stock: %s\n", s0 ? s0 : "(inval)");
s1 = fn(ntop)(af, n1, p1, pl);
printf(" n2p this : %s\n", s1 ? s1 : "(inval)");
if ((s0 != 0) != (s1 != 0) ||
(s0 && s1 && strcmp(s0, s1) != 0))
printf(" DIFFER!\n");
}
return 0;
}
#endif /* TEST */

151
3rdparty/udns/rblcheck.1 vendored Normal file
View File

@@ -0,0 +1,151 @@
.\" rblcheck.1
.\" rblckeck manpage
.\"
.\" Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
.\" This file is part of UDNS library, an async DNS stub resolver.
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library, in file named COPYING.LGPL; if not,
.\" write to the Free Software Foundation, Inc., 59 Temple Place,
.\" Suite 330, Boston, MA 02111-1307 USA
.TH rblckeck 1 "Apr 2005" "User Utilities"
.SH NAME
rblckeck \- DNSBL lookup utility
.SH SYNOPSYS
.B rblcheck
.RB [\| \-s
.IR zone \|]
.RB [\| \-S
.IR zone\-file \|]
.RB [\| \-c \|]
.RB [\| \-tmvq \|]
.RB [\| \-n
.IR nsaddr \|]
.IR address \|.\|.\|.
.SH DESCRIPTION
.B rblcheck
is a simple command-line to perform DNSBL (DNS-based blocklists) lookups.
For every IP address (or a name, in which case it will be resolved to an
address first), the utility verifies whenever it is listed in a (list of)
DNS blocklists specified with
.B \-s
or
.B \-S
options, optionally obtains text assotiated with the listing (usually it
is either some description about the reason of the listing or an URL
referring to such a description), and displays results on standard output.
.PP
The program is implemented on top of
.BR udns (3)
library.
.SH OPTIONS
The following options are recognized by
.BR rblcheck :
.TP
.B \-s \fIzone\fR
add the given \fIzone\fR DNSBL name to the list of active zones.
.TP
.B \-S \fIzone-file\fR
add list of zones from the named \fIzone-file\fR to the list of
active zones (the file specifies one zone as the first word on a
line, empty lines and lines starting with `#' character are ignored).
.TP
.B \-c
reset active zone list.
.TP
.B \-v
be more verbose, produce more detailed output.
.TP
.B \-q
the opposite for \fB\-v\fR -- produce less detailed output.
.TP
.B \-t
obtain text for listed addresses.
.TP
.B \-n \fInsaddr\fR
Use the given nameserver (given as IPv4 or IPv6 address) instead of the
default. The same effect may be achieved by setting $NSCACHEIP environment
variable.
.TP
.B \-m
stop after first hit, ie after the first address which is found to be
listed.
.TP
.B \-h
print short help and exit.
.PP
If no
.BR \-s ,
.BR \-S
and
.B \-c
options are given,
.B rblcheck
will try to obtain list of zones using $RBLCHECK_ZONES environment variable,
or ~/.rblcheckrc, or /etc/rblckechrc files, in that order. If no zones are
found, it will exit unsuccessefully.
.SH "RETURN VALUE"
When no addresses given are listed and no errors occured,
.B rblcheck
exits with code 0. If at least one address is listed,
.B rblcheck
returns 100. In case of DNS errors,
.B rblcheck
returns 2.
.SH ENVIRONMENT
.TP
.B $RBLCHECK_ZONES
if no
.BR \-s ,
.B \-S
or
.B \-c
option is given,
.B rblcheck
tries this variable to obtain list of DNSBL zones to check against.
.SH FILES
.TP
$HOME/.rblcheckrc and /etc/rblcheckrc
if no
.BR \-s ,
.B \-S
or
.B \-c
option is given, and no $RBLCHECK_ZONES environment variable is set,
.B rblcheck
will try the two files (the first one that exists) to obtain list of
DNSBL zones to check against.
Each line specifies one zone (only first word in each line is used).
Empty lines and lines starting with `#' character are ignored.
.SH "SEE ALSO"
.BR dnsget (1)
.BR resolv.conf (5)
.BR udns (3).
.SH AUTHOR
This program and manual pages are written by Michael Tokarev.

378
3rdparty/udns/rblcheck.c vendored Normal file
View File

@@ -0,0 +1,378 @@
/* rblcheck.c
dnsbl (rbl) checker application
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WINDOWS
# include <winsock2.h>
#else
# include <unistd.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
#endif
#include <time.h>
#include <errno.h>
#include <stdarg.h>
#include "udns.h"
#ifndef HAVE_GETOPT
# include "getopt.c"
#endif
static const char *version = "udns-rblcheck 0.4";
static char *progname;
static void error(int die, const char *fmt, ...) {
va_list ap;
fprintf(stderr, "%s: ", progname);
va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap);
putc('\n', stderr);
fflush(stderr);
if (die)
exit(1);
}
struct rblookup {
struct ipcheck *parent;
struct in_addr key;
const char *zone;
struct dns_rr_a4 *addr;
struct dns_rr_txt *txt;
};
struct ipcheck {
const char *name;
int naddr;
int listed;
struct rblookup *lookup;
};
#define notlisted ((void*)1)
static int nzones, nzalloc;
static const char **zones;
static int do_txt;
static int stopfirst;
static int verbose = 1;
/* verbosity level:
* <0 - only bare As/TXTs
* 0 - what RBL result
* 1(default) - what is listed by RBL: result
* 2 - what is[not ]listed by RBL: result, name lookups
*/
static int listed;
static int failures;
static void *ecalloc(int size, int cnt) {
void *t = calloc(size, cnt);
if (!t)
error(1, "out of memory");
return t;
}
static void addzone(const char *zone) {
if (nzones >= nzalloc) {
const char **zs = (const char**)ecalloc(sizeof(char*), (nzalloc += 16));
if (zones) {
memcpy(zs, zones, nzones * sizeof(char*));
free(zones);
}
zones = zs;
}
zones[nzones++] = zone;
}
static int addzonefile(const char *fname) {
FILE *f = fopen(fname, "r");
char linebuf[2048];
if (!f)
return 0;
while(fgets(linebuf, sizeof(linebuf), f)) {
char *p = linebuf, *e;
while(*p == ' ' || *p == '\t') ++p;
if (*p == '#' || *p == '\n') continue;
e = p;
while(*e && *e != ' ' && *e != '\t' && *e != '\n')
++e;
*e++ = '\0';
p = memcpy(ecalloc(e - p, 1), p, e - p); // strdup
addzone(p);
}
fclose(f);
return 1;
}
static void dnserror(struct rblookup *ipl, const char *what) {
char buf[4*4];
error(0, "unable to %s for %s (%s): %s",
what, dns_ntop(AF_INET, &ipl->key, buf, sizeof(buf)),
ipl->zone, dns_strerror(dns_status(0)));
++failures;
}
static void display_result(struct ipcheck *ipc) {
int j;
struct rblookup *l, *le;
char buf[4*4];
if (!ipc->naddr) return;
for (l = ipc->lookup, le = l + nzones * ipc->naddr; l < le; ++l) {
if (!l->addr) continue;
if (verbose < 2 && l->addr == notlisted) continue;
if (verbose >= 0) {
dns_ntop(AF_INET, &l->key, buf, sizeof(buf));
if (ipc->name) printf("%s[%s]", ipc->name, buf);
else printf("%s", buf);
}
if (l->addr == notlisted) {
printf(" is NOT listed by %s\n", l->zone);
continue;
}
else if (verbose >= 1)
printf(" is listed by %s: ", l->zone);
else if (verbose >= 0)
printf(" %s ", l->zone);
if (verbose >= 1 || !do_txt)
for (j = 0; j < l->addr->dnsa4_nrr; ++j)
printf("%s%s", j ? " " : "",
dns_ntop(AF_INET, &l->addr->dnsa4_addr[j], buf, sizeof(buf)));
if (!do_txt) ;
else if (l->txt) {
for(j = 0; j < l->txt->dnstxt_nrr; ++j) {
unsigned char *t = l->txt->dnstxt_txt[j].txt;
unsigned char *e = t + l->txt->dnstxt_txt[j].len;
printf("%s\"", verbose > 0 ? "\n\t" : j ? " " : "");
while(t < e) {
if (*t < ' ' || *t >= 127) printf("\\x%02x", *t);
else if (*t == '\\' || *t == '"') printf("\\%c", *t);
else putchar(*t);
++t;
}
putchar('"');
}
free(l->txt);
}
else
printf("%s<no text available>", verbose > 0 ? "\n\t" : "");
free(l->addr);
putchar('\n');
}
free(ipc->lookup);
}
static void txtcb(struct dns_ctx *ctx, struct dns_rr_txt *r, void *data) {
struct rblookup *ipl = data;
if (r) {
ipl->txt = r;
++ipl->parent->listed;
}
else if (dns_status(ctx) != DNS_E_NXDOMAIN)
dnserror(ipl, "lookup DNSBL TXT record");
}
static void a4cb(struct dns_ctx *ctx, struct dns_rr_a4 *r, void *data) {
struct rblookup *ipl = data;
if (r) {
ipl->addr = r;
++listed;
if (do_txt) {
if (dns_submit_a4dnsbl_txt(0, &ipl->key, ipl->zone, txtcb, ipl))
return;
dnserror(ipl, "submit DNSBL TXT record");
}
++ipl->parent->listed;
}
else if (dns_status(ctx) != DNS_E_NXDOMAIN)
dnserror(ipl, "lookup DNSBL A record");
else
ipl->addr = notlisted;
}
static int
submit_a_queries(struct ipcheck *ipc,
int naddr, const struct in_addr *addr) {
int z, a;
struct rblookup *rl = ecalloc(sizeof(*rl), nzones * naddr);
ipc->lookup = rl;
ipc->naddr = naddr;
for(a = 0; a < naddr; ++a) {
for(z = 0; z < nzones; ++z) {
rl->key = addr[a];
rl->zone = zones[z];
rl->parent = ipc;
if (!dns_submit_a4dnsbl(0, &rl->key, rl->zone, a4cb, rl))
dnserror(rl, "submit DNSBL A query");
++rl;
}
}
return 0;
}
static void namecb(struct dns_ctx *ctx, struct dns_rr_a4 *rr, void *data) {
struct ipcheck *ipc = data;
if (rr) {
submit_a_queries(ipc, rr->dnsa4_nrr, rr->dnsa4_addr);
free(rr);
}
else {
error(0, "unable to lookup `%s': %s",
ipc->name, dns_strerror(dns_status(ctx)));
++failures;
}
}
static int submit(struct ipcheck *ipc) {
struct in_addr addr;
if (dns_pton(AF_INET, ipc->name, &addr) > 0) {
submit_a_queries(ipc, 1, &addr);
ipc->name = NULL;
}
else if (!dns_submit_a4(0, ipc->name, 0, namecb, ipc)) {
error(0, "unable to submit name query for %s: %s\n",
ipc->name, dns_strerror(dns_status(0)));
++failures;
}
return 0;
}
static void waitdns(struct ipcheck *ipc) {
struct timeval tv;
fd_set fds;
int c;
int fd = dns_sock(NULL);
time_t now = 0;
FD_ZERO(&fds);
while((c = dns_timeouts(NULL, -1, now)) > 0) {
FD_SET(fd, &fds);
tv.tv_sec = c;
tv.tv_usec = 0;
c = select(fd+1, &fds, NULL, NULL, &tv);
now = time(NULL);
if (c > 0)
dns_ioevent(NULL, now);
if (stopfirst && ipc->listed)
break;
}
}
int main(int argc, char **argv) {
int c;
struct ipcheck ipc;
char *nameserver = NULL;
int zgiven = 0;
if (!(progname = strrchr(argv[0], '/'))) progname = argv[0];
else argv[0] = ++progname;
while((c = getopt(argc, argv, "hqtvms:S:cn:")) != EOF) switch(c) {
case 's': ++zgiven; addzone(optarg); break;
case 'S':
++zgiven;
if (addzonefile(optarg)) break;
error(1, "unable to read zonefile `%s'", optarg);
case 'c': ++zgiven; nzones = 0; break;
case 'q': --verbose; break;
case 'v': ++verbose; break;
case 't': do_txt = 1; break;
case 'n': nameserver = optarg; break;
case 'm': ++stopfirst; break;
case 'h':
printf("%s: %s (udns library version %s).\n",
progname, version, dns_version());
printf("Usage is: %s [options] address..\n", progname);
printf(
"Where options are:\n"
" -h - print this help and exit\n"
" -s service - add the service (DNSBL zone) to the serice list\n"
" -S service-file - add the DNSBL zone(s) read from the given file\n"
" -c - clear service list\n"
" -v - increase verbosity level (more -vs => more verbose)\n"
" -q - decrease verbosity level (opposite of -v)\n"
" -t - obtain and print TXT records if any\n"
" -m - stop checking after first address match in any list\n"
" -n ipaddr - use the given nameserver instead of the default\n"
"(if no -s or -S option is given, use $RBLCHECK_ZONES, ~/.rblcheckrc\n"
"or /etc/rblcheckrc in that order)\n"
);
return 0;
default:
error(1, "use `%s -h' for help", progname);
}
if (!zgiven) {
char *s = getenv("RBLCHECK_ZONES");
if (s) {
char *k;
s = strdup(s);
for(k = strtok(s, " \t"); k; k = strtok(NULL, " \t"))
addzone(k);
free(s);
}
else { /* probably worthless on windows? */
char *path;
char *home = getenv("HOME");
if (!home) home = ".";
path = malloc(strlen(home) + 1 + sizeof(".rblcheckrc"));
sprintf(path, "%s/.rblcheckrc", home);
if (!addzonefile(path))
addzonefile("/etc/rblcheckrc");
free(path);
}
}
if (!nzones)
error(1, "no service (zone) list specified (-s or -S option)");
argv += optind;
argc -= optind;
if (!argc)
return 0;
if (dns_init(NULL, 0) < 0)
error(1, "unable to initialize DNS library: %s", strerror(errno));
if (nameserver) {
dns_add_serv(NULL, NULL);
if (dns_add_serv(NULL, nameserver) < 0)
error(1, "wrong IP address for a nameserver: `%s'", nameserver);
}
if (dns_open(NULL) < 0)
error(1, "unable to initialize DNS library: %s", strerror(errno));
for (c = 0; c < argc; ++c) {
if (c && (verbose > 1 || (verbose == 1 && do_txt))) putchar('\n');
memset(&ipc, 0, sizeof(ipc));
ipc.name = argv[c];
submit(&ipc);
waitdns(&ipc);
display_result(&ipc);
if (stopfirst > 1 && listed) break;
}
return listed ? 100 : failures ? 2 : 0;
}

1352
3rdparty/udns/udns.3 vendored Normal file

File diff suppressed because it is too large Load Diff

779
3rdparty/udns/udns.h vendored Normal file
View File

@@ -0,0 +1,779 @@
/* udns.h
header file for the UDNS library.
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef UDNS_VERSION /* include guard */
#define UDNS_VERSION "0.4"
#ifdef WINDOWS
# ifdef UDNS_DYNAMIC_LIBRARY
# ifdef DNS_LIBRARY_BUILD
# define UDNS_API __declspec(dllexport)
# define UDNS_DATA_API __declspec(dllexport)
# else
# define UDNS_API __declspec(dllimport)
# define UDNS_DATA_API __declspec(dllimport)
# endif
# endif
#endif
#ifndef UDNS_API
# define UDNS_API
#endif
#ifndef UDNS_DATA_API
# define UDNS_DATA_API
#endif
#include <sys/types.h> /* for time_t */
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
/* forward declarations if sockets stuff isn't #include'd */
struct in_addr;
struct in6_addr;
struct sockaddr;
/**************************************************************************/
/**************** Common definitions **************************************/
UDNS_API const char *
dns_version(void);
struct dns_ctx;
struct dns_query;
/* shorthand for [const] unsigned char */
typedef unsigned char dnsc_t;
typedef const unsigned char dnscc_t;
#define DNS_MAXDN 255 /* max DN length */
#define DNS_DNPAD 1 /* padding for DN buffers */
#define DNS_MAXLABEL 63 /* max DN label length */
#define DNS_MAXNAME 1024 /* max asciiz domain name length */
#define DNS_HSIZE 12 /* DNS packet header size */
#define DNS_PORT 53 /* default domain port */
#define DNS_MAXSERV 6 /* max servers to consult */
#define DNS_MAXPACKET 512 /* max traditional-DNS UDP packet size */
#define DNS_EDNS0PACKET 4096 /* EDNS0 packet size to use */
enum dns_class { /* DNS RR Classes */
DNS_C_INVALID = 0, /* invalid class */
DNS_C_IN = 1, /* Internet */
DNS_C_CH = 3, /* CHAOS */
DNS_C_HS = 4, /* HESIOD */
DNS_C_ANY = 255 /* wildcard */
};
enum dns_type { /* DNS RR Types */
DNS_T_INVALID = 0, /* Cookie. */
DNS_T_A = 1, /* Host address. */
DNS_T_NS = 2, /* Authoritative server. */
DNS_T_MD = 3, /* Mail destination. */
DNS_T_MF = 4, /* Mail forwarder. */
DNS_T_CNAME = 5, /* Canonical name. */
DNS_T_SOA = 6, /* Start of authority zone. */
DNS_T_MB = 7, /* Mailbox domain name. */
DNS_T_MG = 8, /* Mail group member. */
DNS_T_MR = 9, /* Mail rename name. */
DNS_T_NULL = 10, /* Null resource record. */
DNS_T_WKS = 11, /* Well known service. */
DNS_T_PTR = 12, /* Domain name pointer. */
DNS_T_HINFO = 13, /* Host information. */
DNS_T_MINFO = 14, /* Mailbox information. */
DNS_T_MX = 15, /* Mail routing information. */
DNS_T_TXT = 16, /* Text strings. */
DNS_T_RP = 17, /* Responsible person. */
DNS_T_AFSDB = 18, /* AFS cell database. */
DNS_T_X25 = 19, /* X_25 calling address. */
DNS_T_ISDN = 20, /* ISDN calling address. */
DNS_T_RT = 21, /* Router. */
DNS_T_NSAP = 22, /* NSAP address. */
DNS_T_NSAP_PTR = 23, /* Reverse NSAP lookup (deprecated). */
DNS_T_SIG = 24, /* Security signature. */
DNS_T_KEY = 25, /* Security key. */
DNS_T_PX = 26, /* X.400 mail mapping. */
DNS_T_GPOS = 27, /* Geographical position (withdrawn). */
DNS_T_AAAA = 28, /* Ip6 Address. */
DNS_T_LOC = 29, /* Location Information. */
DNS_T_NXT = 30, /* Next domain (security). */
DNS_T_EID = 31, /* Endpoint identifier. */
DNS_T_NIMLOC = 32, /* Nimrod Locator. */
DNS_T_SRV = 33, /* Server Selection. */
DNS_T_ATMA = 34, /* ATM Address */
DNS_T_NAPTR = 35, /* Naming Authority PoinTeR */
DNS_T_KX = 36, /* Key Exchange */
DNS_T_CERT = 37, /* Certification record */
DNS_T_A6 = 38, /* IPv6 address (deprecates AAAA) */
DNS_T_DNAME = 39, /* Non-terminal DNAME (for IPv6) */
DNS_T_SINK = 40, /* Kitchen sink (experimentatl) */
DNS_T_OPT = 41, /* EDNS0 option (meta-RR) */
DNS_T_DS = 43, /* DNSSEC */
DNS_T_SSHFP = 44,
DNS_T_IPSECKEY = 45,
DNS_T_RRSIG = 46, /* DNSSEC */
DNS_T_NSEC = 47, /* DNSSEC */
DNS_T_DNSKEY = 48,
DNS_T_DHCID = 49,
DNS_T_NSEC3 = 50,
DNS_T_NSEC3PARAMS = 51,
DNS_T_TALINK = 58, /* draft-ietf-dnsop-trust-history */
DNS_T_SPF = 99,
DNS_T_UINFO = 100,
DNS_T_UID = 101,
DNS_T_GID = 102,
DNS_T_UNSPEC = 103,
DNS_T_TSIG = 250, /* Transaction signature. */
DNS_T_IXFR = 251, /* Incremental zone transfer. */
DNS_T_AXFR = 252, /* Transfer zone of authority. */
DNS_T_MAILB = 253, /* Transfer mailbox records. */
DNS_T_MAILA = 254, /* Transfer mail agent records. */
DNS_T_ANY = 255, /* Wildcard match. */
DNS_T_ZXFR = 256, /* BIND-specific, nonstandard. */
DNS_T_DLV = 32769, /* RFC 4431, 5074, DNSSEC Lookaside Validation */
DNS_T_MAX = 65536
};
/**************************************************************************/
/**************** Domain Names (DNs) **************************************/
/* return length of the DN */
UDNS_API unsigned
dns_dnlen(dnscc_t *dn);
/* return #of labels in a DN */
UDNS_API unsigned
dns_dnlabels(dnscc_t *dn);
/* lower- and uppercase single DN char */
#define DNS_DNLC(c) ((c) >= 'A' && (c) <= 'Z' ? (c) - 'A' + 'a' : (c))
#define DNS_DNUC(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c))
/* compare the DNs, return dnlen of equal or 0 if not */
UDNS_API unsigned
dns_dnequal(dnscc_t *dn1, dnscc_t *dn2);
/* copy one DN to another, size checking */
UDNS_API unsigned
dns_dntodn(dnscc_t *sdn, dnsc_t *ddn, unsigned ddnsiz);
/* convert asciiz string of length namelen (0 to use strlen) to DN */
UDNS_API int
dns_ptodn(const char *name, unsigned namelen,
dnsc_t *dn, unsigned dnsiz, int *isabs);
/* simpler form of dns_ptodn() */
#define dns_sptodn(name,dn,dnsiz) dns_ptodn((name),0,(dn),(dnsiz),0)
UDNS_DATA_API extern dnscc_t dns_inaddr_arpa_dn[14];
#define DNS_A4RSIZE 30
UDNS_API int
dns_a4todn(const struct in_addr *addr, dnscc_t *tdn,
dnsc_t *dn, unsigned dnsiz);
UDNS_API int
dns_a4ptodn(const struct in_addr *addr, const char *tname,
dnsc_t *dn, unsigned dnsiz);
UDNS_API dnsc_t *
dns_a4todn_(const struct in_addr *addr, dnsc_t *dn, dnsc_t *dne);
UDNS_DATA_API extern dnscc_t dns_ip6_arpa_dn[10];
#define DNS_A6RSIZE 74
UDNS_API int
dns_a6todn(const struct in6_addr *addr, dnscc_t *tdn,
dnsc_t *dn, unsigned dnsiz);
UDNS_API int
dns_a6ptodn(const struct in6_addr *addr, const char *tname,
dnsc_t *dn, unsigned dnsiz);
UDNS_API dnsc_t *
dns_a6todn_(const struct in6_addr *addr, dnsc_t *dn, dnsc_t *dne);
/* convert DN into asciiz string */
UDNS_API int
dns_dntop(dnscc_t *dn, char *name, unsigned namesiz);
/* convert DN into asciiz string, using static buffer (NOT thread-safe!) */
UDNS_API const char *
dns_dntosp(dnscc_t *dn);
/* return buffer size (incl. null byte) required for asciiz form of a DN */
UDNS_API unsigned
dns_dntop_size(dnscc_t *dn);
/* either wrappers or reimplementations for inet_ntop() and inet_pton() */
UDNS_API const char *dns_ntop(int af, const void *src, char *dst, int size);
UDNS_API int dns_pton(int af, const char *src, void *dst);
/**************************************************************************/
/**************** DNS raw packet layout ***********************************/
enum dns_rcode { /* reply codes */
DNS_R_NOERROR = 0, /* ok, no error */
DNS_R_FORMERR = 1, /* format error */
DNS_R_SERVFAIL = 2, /* server failed */
DNS_R_NXDOMAIN = 3, /* domain does not exists */
DNS_R_NOTIMPL = 4, /* not implemented */
DNS_R_REFUSED = 5, /* query refused */
/* these are for BIND_UPDATE */
DNS_R_YXDOMAIN = 6, /* Name exists */
DNS_R_YXRRSET = 7, /* RRset exists */
DNS_R_NXRRSET = 8, /* RRset does not exist */
DNS_R_NOTAUTH = 9, /* Not authoritative for zone */
DNS_R_NOTZONE = 10, /* Zone of record different from zone section */
/*ns_r_max = 11,*/
/* The following are TSIG extended errors */
DNS_R_BADSIG = 16,
DNS_R_BADKEY = 17,
DNS_R_BADTIME = 18
};
static __inline unsigned dns_get16(dnscc_t *s) {
return ((unsigned)s[0]<<8) | s[1];
}
static __inline unsigned dns_get32(dnscc_t *s) {
return ((unsigned)s[0]<<24) | ((unsigned)s[1]<<16)
| ((unsigned)s[2]<<8) | s[3];
}
static __inline dnsc_t *dns_put16(dnsc_t *d, unsigned n) {
*d++ = (dnsc_t)((n >> 8) & 255); *d++ = (dnsc_t)(n & 255); return d;
}
static __inline dnsc_t *dns_put32(dnsc_t *d, unsigned n) {
*d++ = (dnsc_t)((n >> 24) & 255); *d++ = (dnsc_t)((n >> 16) & 255);
*d++ = (dnsc_t)((n >> 8) & 255); *d++ = (dnsc_t)(n & 255);
return d;
}
/* DNS Header layout */
enum {
/* bytes 0:1 - query ID */
DNS_H_QID1 = 0,
DNS_H_QID2 = 1,
DNS_H_QID = DNS_H_QID1,
#define dns_qid(pkt) dns_get16((pkt)+DNS_H_QID)
/* byte 2: flags1 */
DNS_H_F1 = 2,
DNS_HF1_QR = 0x80, /* query response flag */
#define dns_qr(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_QR)
DNS_HF1_OPCODE = 0x78, /* opcode, 0 = query */
#define dns_opcode(pkt) (((pkt)[DNS_H_F1]&DNS_HF1_OPCODE)>>3)
DNS_HF1_AA = 0x04, /* auth answer */
#define dns_aa(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_AA)
DNS_HF1_TC = 0x02, /* truncation flag */
#define dns_tc(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_TC)
DNS_HF1_RD = 0x01, /* recursion desired (may be set in query) */
#define dns_rd(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_RD)
/* byte 3: flags2 */
DNS_H_F2 = 3,
DNS_HF2_RA = 0x80, /* recursion available */
#define dns_ra(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_RA)
DNS_HF2_Z = 0x40, /* reserved */
DNS_HF2_AD = 0x20, /* DNSSEC: authentic data */
#define dns_ad(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_AD)
DNS_HF2_CD = 0x10, /* DNSSEC: checking disabled */
#define dns_cd(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_CD)
DNS_HF2_RCODE = 0x0f, /* response code, DNS_R_XXX above */
#define dns_rcode(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_RCODE)
/* bytes 4:5: qdcount, numqueries */
DNS_H_QDCNT1 = 4,
DNS_H_QDCNT2 = 5,
DNS_H_QDCNT = DNS_H_QDCNT1,
#define dns_numqd(pkt) dns_get16((pkt)+4)
/* bytes 6:7: ancount, numanswers */
DNS_H_ANCNT1 = 6,
DNS_H_ANCNT2 = 7,
DNS_H_ANCNT = DNS_H_ANCNT1,
#define dns_numan(pkt) dns_get16((pkt)+6)
/* bytes 8:9: nscount, numauthority */
DNS_H_NSCNT1 = 8,
DNS_H_NSCNT2 = 9,
DNS_H_NSCNT = DNS_H_NSCNT1,
#define dns_numns(pkt) dns_get16((pkt)+8)
/* bytes 10:11: arcount, numadditional */
DNS_H_ARCNT1 = 10,
DNS_H_ARCNT2 = 11,
DNS_H_ARCNT = DNS_H_ARCNT1,
#define dns_numar(pkt) dns_get16((pkt)+10)
#define dns_payload(pkt) ((pkt)+DNS_HSIZE)
/* EDNS0 (OPT RR) flags (Ext. Flags) */
DNS_EF1_DO = 0x80, /* DNSSEC OK */
};
/* packet buffer: start at pkt, end before pkte, current pos *curp.
* extract a DN and set *curp to the next byte after DN in packet.
* return -1 on error, 0 if dnsiz is too small, or dnlen on ok.
*/
UDNS_API int
dns_getdn(dnscc_t *pkt, dnscc_t **curp, dnscc_t *end,
dnsc_t *dn, unsigned dnsiz);
/* skip the DN at position cur in packet ending before pkte,
* return pointer to the next byte after the DN or NULL on error */
UDNS_API dnscc_t *
dns_skipdn(dnscc_t *end, dnscc_t *cur);
struct dns_rr { /* DNS Resource Record */
dnsc_t dnsrr_dn[DNS_MAXDN]; /* the DN of the RR */
enum dns_class dnsrr_cls; /* Class */
enum dns_type dnsrr_typ; /* Type */
unsigned dnsrr_ttl; /* Time-To-Live (TTL) */
unsigned dnsrr_dsz; /* data size */
dnscc_t *dnsrr_dptr; /* pointer to start of data */
dnscc_t *dnsrr_dend; /* past end of data */
};
struct dns_parse { /* RR/packet parsing state */
dnscc_t *dnsp_pkt; /* start of the packet */
dnscc_t *dnsp_end; /* end of the packet */
dnscc_t *dnsp_cur; /* current packet position */
dnscc_t *dnsp_ans; /* start of answer section */
int dnsp_rrl; /* number of RRs left to go */
int dnsp_nrr; /* RR count so far */
unsigned dnsp_ttl; /* TTL value so far */
dnscc_t *dnsp_qdn; /* the RR DN we're looking for */
enum dns_class dnsp_qcls; /* RR class we're looking for or 0 */
enum dns_type dnsp_qtyp; /* RR type we're looking for or 0 */
dnsc_t dnsp_dnbuf[DNS_MAXDN]; /* domain buffer */
};
/* initialize the parse structure */
UDNS_API void
dns_initparse(struct dns_parse *p, dnscc_t *qdn,
dnscc_t *pkt, dnscc_t *cur, dnscc_t *end);
/* search next RR, <0=error, 0=no more RRs, >0 = found. */
UDNS_API int
dns_nextrr(struct dns_parse *p, struct dns_rr *rr);
UDNS_API void
dns_rewind(struct dns_parse *p, dnscc_t *qdn);
/**************************************************************************/
/**************** Resolver Context ****************************************/
/* default resolver context */
UDNS_DATA_API extern struct dns_ctx dns_defctx;
/* reset resolver context to default state, close it if open, drop queries */
UDNS_API void
dns_reset(struct dns_ctx *ctx);
/* reset resolver context and read in system configuration */
UDNS_API int
dns_init(struct dns_ctx *ctx, int do_open);
/* return new resolver context with the same settings as copy */
UDNS_API struct dns_ctx *
dns_new(const struct dns_ctx *copy);
/* free resolver context returned by dns_new(); all queries are dropped */
UDNS_API void
dns_free(struct dns_ctx *ctx);
/* add nameserver for a resolver context (or reset nslist if serv==NULL) */
UDNS_API int
dns_add_serv(struct dns_ctx *ctx, const char *serv);
/* add nameserver using struct sockaddr structure (with ports) */
UDNS_API int
dns_add_serv_s(struct dns_ctx *ctx, const struct sockaddr *sa);
/* add search list element for a resolver context (or reset it if srch==NULL) */
UDNS_API int
dns_add_srch(struct dns_ctx *ctx, const char *srch);
/* set options for a resolver context */
UDNS_API int
dns_set_opts(struct dns_ctx *ctx, const char *opts);
enum dns_opt { /* options */
DNS_OPT_FLAGS, /* flags, DNS_F_XXX */
DNS_OPT_TIMEOUT, /* timeout in secounds */
DNS_OPT_NTRIES, /* number of retries */
DNS_OPT_NDOTS, /* ndots */
DNS_OPT_UDPSIZE, /* EDNS0 UDP size */
DNS_OPT_PORT, /* port to use */
};
/* set or get (if val<0) an option */
UDNS_API int
dns_set_opt(struct dns_ctx *ctx, enum dns_opt opt, int val);
enum dns_flags {
DNS_NOSRCH = 0x00010000, /* do not perform search */
DNS_NORD = 0x00020000, /* request no recursion */
DNS_AAONLY = 0x00040000, /* set AA flag in queries */
DNS_SET_DO = 0x00080000, /* set EDNS0 "DO" bit (DNSSEC OK) */
DNS_SET_CD = 0x00100000, /* set CD bit (DNSSEC: checking disabled) */
};
/* set the debug function pointer */
typedef void
(dns_dbgfn)(int code, const struct sockaddr *sa, unsigned salen,
dnscc_t *pkt, int plen,
const struct dns_query *q, void *data);
UDNS_API void
dns_set_dbgfn(struct dns_ctx *ctx, dns_dbgfn *dbgfn);
/* open and return UDP socket */
UDNS_API int
dns_open(struct dns_ctx *ctx);
/* return UDP socket or -1 if not open */
UDNS_API int
dns_sock(const struct dns_ctx *ctx);
/* close the UDP socket */
UDNS_API void
dns_close(struct dns_ctx *ctx);
/* return number of requests queued */
UDNS_API int
dns_active(const struct dns_ctx *ctx);
/* return status of the last operation */
UDNS_API int
dns_status(const struct dns_ctx *ctx);
UDNS_API void
dns_setstatus(struct dns_ctx *ctx, int status);
/* handle I/O event on UDP socket */
UDNS_API void
dns_ioevent(struct dns_ctx *ctx, time_t now);
/* process any timeouts, return time in secounds to the
* next timeout (or -1 if none) but not greather than maxwait */
UDNS_API int
dns_timeouts(struct dns_ctx *ctx, int maxwait, time_t now);
/* define timer requesting routine to use */
typedef void dns_utm_fn(struct dns_ctx *ctx, int timeout, void *data);
UDNS_API void
dns_set_tmcbck(struct dns_ctx *ctx, dns_utm_fn *fn, void *data);
/**************************************************************************/
/**************** Making Queries ******************************************/
/* query callback routine */
typedef void dns_query_fn(struct dns_ctx *ctx, void *result, void *data);
/* query parse routine: raw DNS => application structure */
typedef int
dns_parse_fn(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
void **res);
enum dns_status {
DNS_E_NOERROR = 0, /* ok, not an error */
DNS_E_TEMPFAIL = -1, /* timeout, SERVFAIL or similar */
DNS_E_PROTOCOL = -2, /* got garbled reply */
DNS_E_NXDOMAIN = -3, /* domain does not exists */
DNS_E_NODATA = -4, /* domain exists but no data of reqd type */
DNS_E_NOMEM = -5, /* out of memory while processing */
DNS_E_BADQUERY = -6 /* the query is malformed */
};
/* submit generic DN query */
UDNS_API struct dns_query *
dns_submit_dn(struct dns_ctx *ctx,
dnscc_t *dn, int qcls, int qtyp, int flags,
dns_parse_fn *parse, dns_query_fn *cbck, void *data);
/* submit generic name query */
UDNS_API struct dns_query *
dns_submit_p(struct dns_ctx *ctx,
const char *name, int qcls, int qtyp, int flags,
dns_parse_fn *parse, dns_query_fn *cbck, void *data);
/* cancel the given async query in progress */
UDNS_API int
dns_cancel(struct dns_ctx *ctx, struct dns_query *q);
/* resolve a generic query, return the answer */
UDNS_API void *
dns_resolve_dn(struct dns_ctx *ctx,
dnscc_t *qdn, int qcls, int qtyp, int flags,
dns_parse_fn *parse);
UDNS_API void *
dns_resolve_p(struct dns_ctx *ctx,
const char *qname, int qcls, int qtyp, int flags,
dns_parse_fn *parse);
UDNS_API void *
dns_resolve(struct dns_ctx *ctx, struct dns_query *q);
/* Specific RR handlers */
#define dns_rr_common(prefix) \
char *prefix##_cname; /* canonical name */ \
char *prefix##_qname; /* original query name */ \
unsigned prefix##_ttl; /* TTL value */ \
int prefix##_nrr /* number of records */
struct dns_rr_null { /* NULL RRset, aka RRset template */
dns_rr_common(dnsn);
};
UDNS_API int
dns_stdrr_size(const struct dns_parse *p);
UDNS_API void *
dns_stdrr_finish(struct dns_rr_null *ret, char *cp, const struct dns_parse *p);
struct dns_rr_a4 { /* the A RRset */
dns_rr_common(dnsa4);
struct in_addr *dnsa4_addr; /* array of addresses, naddr elements */
};
UDNS_API dns_parse_fn dns_parse_a4; /* A RR parsing routine */
typedef void /* A query callback routine */
dns_query_a4_fn(struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data);
/* submit A IN query */
UDNS_API struct dns_query *
dns_submit_a4(struct dns_ctx *ctx, const char *name, int flags,
dns_query_a4_fn *cbck, void *data);
/* resolve A IN query */
UDNS_API struct dns_rr_a4 *
dns_resolve_a4(struct dns_ctx *ctx, const char *name, int flags);
struct dns_rr_a6 { /* the AAAA RRset */
dns_rr_common(dnsa6);
struct in6_addr *dnsa6_addr; /* array of addresses, naddr elements */
};
UDNS_API dns_parse_fn dns_parse_a6; /* A RR parsing routine */
typedef void /* A query callback routine */
dns_query_a6_fn(struct dns_ctx *ctx, struct dns_rr_a6 *result, void *data);
/* submit AAAA IN query */
UDNS_API struct dns_query *
dns_submit_a6(struct dns_ctx *ctx, const char *name, int flags,
dns_query_a6_fn *cbck, void *data);
/* resolve AAAA IN query */
UDNS_API struct dns_rr_a6 *
dns_resolve_a6(struct dns_ctx *ctx, const char *name, int flags);
struct dns_rr_ptr { /* the PTR RRset */
dns_rr_common(dnsptr);
char **dnsptr_ptr; /* array of PTRs */
};
UDNS_API dns_parse_fn dns_parse_ptr; /* PTR RR parsing routine */
typedef void /* PTR query callback */
dns_query_ptr_fn(struct dns_ctx *ctx, struct dns_rr_ptr *result, void *data);
/* submit PTR IN in-addr.arpa query */
UDNS_API struct dns_query *
dns_submit_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr,
dns_query_ptr_fn *cbck, void *data);
/* resolve PTR IN in-addr.arpa query */
UDNS_API struct dns_rr_ptr *
dns_resolve_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr);
/* the same as above, but for ip6.arpa */
UDNS_API struct dns_query *
dns_submit_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr,
dns_query_ptr_fn *cbck, void *data);
UDNS_API struct dns_rr_ptr *
dns_resolve_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr);
struct dns_mx { /* single MX RR */
int priority; /* MX priority */
char *name; /* MX name */
};
struct dns_rr_mx { /* the MX RRset */
dns_rr_common(dnsmx);
struct dns_mx *dnsmx_mx; /* array of MXes */
};
UDNS_API dns_parse_fn dns_parse_mx; /* MX RR parsing routine */
typedef void /* MX RR callback */
dns_query_mx_fn(struct dns_ctx *ctx, struct dns_rr_mx *result, void *data);
/* submit MX IN query */
UDNS_API struct dns_query *
dns_submit_mx(struct dns_ctx *ctx, const char *name, int flags,
dns_query_mx_fn *cbck, void *data);
/* resolve MX IN query */
UDNS_API struct dns_rr_mx *
dns_resolve_mx(struct dns_ctx *ctx, const char *name, int flags);
struct dns_txt { /* single TXT record */
int len; /* length of the text */
dnsc_t *txt; /* pointer to text buffer. May contain nulls. */
};
struct dns_rr_txt { /* the TXT RRset */
dns_rr_common(dnstxt);
struct dns_txt *dnstxt_txt; /* array of TXT records */
};
UDNS_API dns_parse_fn dns_parse_txt; /* TXT RR parsing routine */
typedef void /* TXT RR callback */
dns_query_txt_fn(struct dns_ctx *ctx, struct dns_rr_txt *result, void *data);
/* submit TXT query */
UDNS_API struct dns_query *
dns_submit_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags,
dns_query_txt_fn *cbck, void *data);
/* resolve TXT query */
UDNS_API struct dns_rr_txt *
dns_resolve_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags);
struct dns_srv { /* single SRV RR */
int priority; /* SRV priority */
int weight; /* SRV weight */
int port; /* SRV port */
char *name; /* SRV name */
};
struct dns_rr_srv { /* the SRV RRset */
dns_rr_common(dnssrv);
struct dns_srv *dnssrv_srv; /* array of SRVes */
};
UDNS_API dns_parse_fn dns_parse_srv; /* SRV RR parsing routine */
typedef void /* SRV RR callback */
dns_query_srv_fn(struct dns_ctx *ctx, struct dns_rr_srv *result, void *data);
/* submit SRV IN query */
UDNS_API struct dns_query *
dns_submit_srv(struct dns_ctx *ctx,
const char *name, const char *srv, const char *proto,
int flags, dns_query_srv_fn *cbck, void *data);
/* resolve SRV IN query */
UDNS_API struct dns_rr_srv *
dns_resolve_srv(struct dns_ctx *ctx,
const char *name, const char *srv, const char *proto,
int flags);
/* NAPTR (RFC3403) RR type */
struct dns_naptr { /* single NAPTR RR */
int order; /* NAPTR order */
int preference; /* NAPTR preference */
char *flags; /* NAPTR flags */
char *service; /* NAPTR service */
char *regexp; /* NAPTR regexp */
char *replacement; /* NAPTR replacement */
};
struct dns_rr_naptr { /* the NAPTR RRset */
dns_rr_common(dnsnaptr);
struct dns_naptr *dnsnaptr_naptr; /* array of NAPTRes */
};
UDNS_API dns_parse_fn dns_parse_naptr; /* NAPTR RR parsing routine */
typedef void /* NAPTR RR callback */
dns_query_naptr_fn(struct dns_ctx *ctx,
struct dns_rr_naptr *result, void *data);
/* submit NAPTR IN query */
UDNS_API struct dns_query *
dns_submit_naptr(struct dns_ctx *ctx, const char *name, int flags,
dns_query_naptr_fn *cbck, void *data);
/* resolve NAPTR IN query */
UDNS_API struct dns_rr_naptr *
dns_resolve_naptr(struct dns_ctx *ctx, const char *name, int flags);
UDNS_API struct dns_query *
dns_submit_a4dnsbl(struct dns_ctx *ctx,
const struct in_addr *addr, const char *dnsbl,
dns_query_a4_fn *cbck, void *data);
UDNS_API struct dns_query *
dns_submit_a4dnsbl_txt(struct dns_ctx *ctx,
const struct in_addr *addr, const char *dnsbl,
dns_query_txt_fn *cbck, void *data);
UDNS_API struct dns_rr_a4 *
dns_resolve_a4dnsbl(struct dns_ctx *ctx,
const struct in_addr *addr, const char *dnsbl);
UDNS_API struct dns_rr_txt *
dns_resolve_a4dnsbl_txt(struct dns_ctx *ctx,
const struct in_addr *addr, const char *dnsbl);
UDNS_API struct dns_query *
dns_submit_a6dnsbl(struct dns_ctx *ctx,
const struct in6_addr *addr, const char *dnsbl,
dns_query_a4_fn *cbck, void *data);
UDNS_API struct dns_query *
dns_submit_a6dnsbl_txt(struct dns_ctx *ctx,
const struct in6_addr *addr, const char *dnsbl,
dns_query_txt_fn *cbck, void *data);
UDNS_API struct dns_rr_a4 *
dns_resolve_a6dnsbl(struct dns_ctx *ctx,
const struct in6_addr *addr, const char *dnsbl);
UDNS_API struct dns_rr_txt *
dns_resolve_a6dnsbl_txt(struct dns_ctx *ctx,
const struct in6_addr *addr, const char *dnsbl);
UDNS_API struct dns_query *
dns_submit_rhsbl(struct dns_ctx *ctx,
const char *name, const char *rhsbl,
dns_query_a4_fn *cbck, void *data);
UDNS_API struct dns_query *
dns_submit_rhsbl_txt(struct dns_ctx *ctx,
const char *name, const char *rhsbl,
dns_query_txt_fn *cbck, void *data);
UDNS_API struct dns_rr_a4 *
dns_resolve_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl);
UDNS_API struct dns_rr_txt *
dns_resolve_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl);
/**************************************************************************/
/**************** Names, Names ********************************************/
struct dns_nameval {
int val;
const char *name;
};
UDNS_DATA_API extern const struct dns_nameval dns_classtab[];
UDNS_DATA_API extern const struct dns_nameval dns_typetab[];
UDNS_DATA_API extern const struct dns_nameval dns_rcodetab[];
UDNS_API int
dns_findname(const struct dns_nameval *nv, const char *name);
#define dns_findclassname(cls) dns_findname(dns_classtab, (cls))
#define dns_findtypename(type) dns_findname(dns_typetab, (type))
#define dns_findrcodename(rcode) dns_findname(dns_rcodetab, (rcode))
UDNS_API const char *dns_classname(enum dns_class cls);
UDNS_API const char *dns_typename(enum dns_type type);
UDNS_API const char *dns_rcodename(enum dns_rcode rcode);
const char *_dns_format_code(char *buf, const char *prefix, int code);
UDNS_API const char *dns_strerror(int errnum);
/* simple pseudo-random number generator, code by Bob Jenkins */
struct udns_jranctx { /* the context */
unsigned a, b, c, d;
};
/* initialize the RNG with a given seed */
UDNS_API void
udns_jraninit(struct udns_jranctx *x, unsigned seed);
/* return next random number. 32bits on most platforms so far. */
UDNS_API unsigned
udns_jranval(struct udns_jranctx *x);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* include guard */

50
3rdparty/udns/udns_XtoX.c vendored Normal file
View File

@@ -0,0 +1,50 @@
/* udns_XtoX.c
udns_ntop() and udns_pton() routines, which are either
- wrappers for inet_ntop() and inet_pton() or
- reimplementations of those routines.
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "udns.h"
#ifdef HAVE_INET_PTON_NTOP
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
const char *dns_ntop(int af, const void *src, char *dst, int size) {
return inet_ntop(af, src, dst, size);
}
int dns_pton(int af, const char *src, void *dst) {
return inet_pton(af, src, dst);
}
#else
#define inet_XtoX_no_ntop
#define inet_XtoX_prefix dns_
#include "inet_XtoX.c"
#endif

160
3rdparty/udns/udns_bl.c vendored Normal file
View File

@@ -0,0 +1,160 @@
/* udns_bl.c
DNSBL stuff
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#include "udns.h"
#ifndef NULL
# define NULL 0
#endif
struct dns_query *
dns_submit_a4dnsbl(struct dns_ctx *ctx,
const struct in_addr *addr, const char *dnsbl,
dns_query_a4_fn *cbck, void *data) {
dnsc_t dn[DNS_MAXDN];
if (dns_a4ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) {
dns_setstatus(ctx, DNS_E_BADQUERY);
return NULL;
}
return
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_A, DNS_NOSRCH,
dns_parse_a4, (dns_query_fn*)cbck, data);
}
struct dns_query *
dns_submit_a4dnsbl_txt(struct dns_ctx *ctx,
const struct in_addr *addr, const char *dnsbl,
dns_query_txt_fn *cbck, void *data) {
dnsc_t dn[DNS_MAXDN];
if (dns_a4ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) {
dns_setstatus(ctx, DNS_E_BADQUERY);
return NULL;
}
return
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_TXT, DNS_NOSRCH,
dns_parse_txt, (dns_query_fn*)cbck, data);
}
struct dns_rr_a4 *
dns_resolve_a4dnsbl(struct dns_ctx *ctx,
const struct in_addr *addr, const char *dnsbl) {
return (struct dns_rr_a4 *)
dns_resolve(ctx, dns_submit_a4dnsbl(ctx, addr, dnsbl, 0, 0));
}
struct dns_rr_txt *
dns_resolve_a4dnsbl_txt(struct dns_ctx *ctx,
const struct in_addr *addr, const char *dnsbl) {
return (struct dns_rr_txt *)
dns_resolve(ctx, dns_submit_a4dnsbl_txt(ctx, addr, dnsbl, 0, 0));
}
struct dns_query *
dns_submit_a6dnsbl(struct dns_ctx *ctx,
const struct in6_addr *addr, const char *dnsbl,
dns_query_a4_fn *cbck, void *data) {
dnsc_t dn[DNS_MAXDN];
if (dns_a6ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) {
dns_setstatus(ctx, DNS_E_BADQUERY);
return NULL;
}
return
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_A, DNS_NOSRCH,
dns_parse_a4, (dns_query_fn*)cbck, data);
}
struct dns_query *
dns_submit_a6dnsbl_txt(struct dns_ctx *ctx,
const struct in6_addr *addr, const char *dnsbl,
dns_query_txt_fn *cbck, void *data) {
dnsc_t dn[DNS_MAXDN];
if (dns_a6ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) {
dns_setstatus(ctx, DNS_E_BADQUERY);
return NULL;
}
return
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_TXT, DNS_NOSRCH,
dns_parse_txt, (dns_query_fn*)cbck, data);
}
struct dns_rr_a4 *
dns_resolve_a6dnsbl(struct dns_ctx *ctx,
const struct in6_addr *addr, const char *dnsbl) {
return (struct dns_rr_a4 *)
dns_resolve(ctx, dns_submit_a6dnsbl(ctx, addr, dnsbl, 0, 0));
}
struct dns_rr_txt *
dns_resolve_a6dnsbl_txt(struct dns_ctx *ctx,
const struct in6_addr *addr, const char *dnsbl) {
return (struct dns_rr_txt *)
dns_resolve(ctx, dns_submit_a6dnsbl_txt(ctx, addr, dnsbl, 0, 0));
}
static int
dns_rhsbltodn(const char *name, const char *rhsbl, dnsc_t dn[DNS_MAXDN])
{
int l = dns_sptodn(name, dn, DNS_MAXDN);
if (l <= 0) return 0;
l = dns_sptodn(rhsbl, dn+l-1, DNS_MAXDN-l+1);
if (l <= 0) return 0;
return 1;
}
struct dns_query *
dns_submit_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl,
dns_query_a4_fn *cbck, void *data) {
dnsc_t dn[DNS_MAXDN];
if (!dns_rhsbltodn(name, rhsbl, dn)) {
dns_setstatus(ctx, DNS_E_BADQUERY);
return NULL;
}
return
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_A, DNS_NOSRCH,
dns_parse_a4, (dns_query_fn*)cbck, data);
}
struct dns_query *
dns_submit_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl,
dns_query_txt_fn *cbck, void *data) {
dnsc_t dn[DNS_MAXDN];
if (!dns_rhsbltodn(name, rhsbl, dn)) {
dns_setstatus(ctx, DNS_E_BADQUERY);
return NULL;
}
return
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_TXT, DNS_NOSRCH,
dns_parse_txt, (dns_query_fn*)cbck, data);
}
struct dns_rr_a4 *
dns_resolve_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl) {
return (struct dns_rr_a4*)
dns_resolve(ctx, dns_submit_rhsbl(ctx, name, rhsbl, 0, 0));
}
struct dns_rr_txt *
dns_resolve_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl)
{
return (struct dns_rr_txt*)
dns_resolve(ctx, dns_submit_rhsbl_txt(ctx, name, rhsbl, 0, 0));
}

199
3rdparty/udns/udns_codes.c vendored Normal file
View File

@@ -0,0 +1,199 @@
/* Automatically generated. */
#include "udns.h"
const struct dns_nameval dns_typetab[] = {
{DNS_T_INVALID,"INVALID"},
{DNS_T_A,"A"},
{DNS_T_NS,"NS"},
{DNS_T_MD,"MD"},
{DNS_T_MF,"MF"},
{DNS_T_CNAME,"CNAME"},
{DNS_T_SOA,"SOA"},
{DNS_T_MB,"MB"},
{DNS_T_MG,"MG"},
{DNS_T_MR,"MR"},
{DNS_T_NULL,"NULL"},
{DNS_T_WKS,"WKS"},
{DNS_T_PTR,"PTR"},
{DNS_T_HINFO,"HINFO"},
{DNS_T_MINFO,"MINFO"},
{DNS_T_MX,"MX"},
{DNS_T_TXT,"TXT"},
{DNS_T_RP,"RP"},
{DNS_T_AFSDB,"AFSDB"},
{DNS_T_X25,"X25"},
{DNS_T_ISDN,"ISDN"},
{DNS_T_RT,"RT"},
{DNS_T_NSAP,"NSAP"},
{DNS_T_NSAP_PTR,"NSAP_PTR"},
{DNS_T_SIG,"SIG"},
{DNS_T_KEY,"KEY"},
{DNS_T_PX,"PX"},
{DNS_T_GPOS,"GPOS"},
{DNS_T_AAAA,"AAAA"},
{DNS_T_LOC,"LOC"},
{DNS_T_NXT,"NXT"},
{DNS_T_EID,"EID"},
{DNS_T_NIMLOC,"NIMLOC"},
{DNS_T_SRV,"SRV"},
{DNS_T_ATMA,"ATMA"},
{DNS_T_NAPTR,"NAPTR"},
{DNS_T_KX,"KX"},
{DNS_T_CERT,"CERT"},
{DNS_T_A6,"A6"},
{DNS_T_DNAME,"DNAME"},
{DNS_T_SINK,"SINK"},
{DNS_T_OPT,"OPT"},
{DNS_T_DS,"DS"},
{DNS_T_SSHFP,"SSHFP"},
{DNS_T_IPSECKEY,"IPSECKEY"},
{DNS_T_RRSIG,"RRSIG"},
{DNS_T_NSEC,"NSEC"},
{DNS_T_DNSKEY,"DNSKEY"},
{DNS_T_DHCID,"DHCID"},
{DNS_T_NSEC3,"NSEC3"},
{DNS_T_NSEC3PARAMS,"NSEC3PARAMS"},
{DNS_T_TALINK,"TALINK"},
{DNS_T_SPF,"SPF"},
{DNS_T_UINFO,"UINFO"},
{DNS_T_UID,"UID"},
{DNS_T_GID,"GID"},
{DNS_T_UNSPEC,"UNSPEC"},
{DNS_T_TSIG,"TSIG"},
{DNS_T_IXFR,"IXFR"},
{DNS_T_AXFR,"AXFR"},
{DNS_T_MAILB,"MAILB"},
{DNS_T_MAILA,"MAILA"},
{DNS_T_ANY,"ANY"},
{DNS_T_ZXFR,"ZXFR"},
{DNS_T_DLV,"DLV"},
{DNS_T_MAX,"MAX"},
{0,0}};
const char *dns_typename(enum dns_type code) {
static char nm[20];
switch(code) {
case DNS_T_INVALID: return dns_typetab[0].name;
case DNS_T_A: return dns_typetab[1].name;
case DNS_T_NS: return dns_typetab[2].name;
case DNS_T_MD: return dns_typetab[3].name;
case DNS_T_MF: return dns_typetab[4].name;
case DNS_T_CNAME: return dns_typetab[5].name;
case DNS_T_SOA: return dns_typetab[6].name;
case DNS_T_MB: return dns_typetab[7].name;
case DNS_T_MG: return dns_typetab[8].name;
case DNS_T_MR: return dns_typetab[9].name;
case DNS_T_NULL: return dns_typetab[10].name;
case DNS_T_WKS: return dns_typetab[11].name;
case DNS_T_PTR: return dns_typetab[12].name;
case DNS_T_HINFO: return dns_typetab[13].name;
case DNS_T_MINFO: return dns_typetab[14].name;
case DNS_T_MX: return dns_typetab[15].name;
case DNS_T_TXT: return dns_typetab[16].name;
case DNS_T_RP: return dns_typetab[17].name;
case DNS_T_AFSDB: return dns_typetab[18].name;
case DNS_T_X25: return dns_typetab[19].name;
case DNS_T_ISDN: return dns_typetab[20].name;
case DNS_T_RT: return dns_typetab[21].name;
case DNS_T_NSAP: return dns_typetab[22].name;
case DNS_T_NSAP_PTR: return dns_typetab[23].name;
case DNS_T_SIG: return dns_typetab[24].name;
case DNS_T_KEY: return dns_typetab[25].name;
case DNS_T_PX: return dns_typetab[26].name;
case DNS_T_GPOS: return dns_typetab[27].name;
case DNS_T_AAAA: return dns_typetab[28].name;
case DNS_T_LOC: return dns_typetab[29].name;
case DNS_T_NXT: return dns_typetab[30].name;
case DNS_T_EID: return dns_typetab[31].name;
case DNS_T_NIMLOC: return dns_typetab[32].name;
case DNS_T_SRV: return dns_typetab[33].name;
case DNS_T_ATMA: return dns_typetab[34].name;
case DNS_T_NAPTR: return dns_typetab[35].name;
case DNS_T_KX: return dns_typetab[36].name;
case DNS_T_CERT: return dns_typetab[37].name;
case DNS_T_A6: return dns_typetab[38].name;
case DNS_T_DNAME: return dns_typetab[39].name;
case DNS_T_SINK: return dns_typetab[40].name;
case DNS_T_OPT: return dns_typetab[41].name;
case DNS_T_DS: return dns_typetab[42].name;
case DNS_T_SSHFP: return dns_typetab[43].name;
case DNS_T_IPSECKEY: return dns_typetab[44].name;
case DNS_T_RRSIG: return dns_typetab[45].name;
case DNS_T_NSEC: return dns_typetab[46].name;
case DNS_T_DNSKEY: return dns_typetab[47].name;
case DNS_T_DHCID: return dns_typetab[48].name;
case DNS_T_NSEC3: return dns_typetab[49].name;
case DNS_T_NSEC3PARAMS: return dns_typetab[50].name;
case DNS_T_TALINK: return dns_typetab[51].name;
case DNS_T_SPF: return dns_typetab[52].name;
case DNS_T_UINFO: return dns_typetab[53].name;
case DNS_T_UID: return dns_typetab[54].name;
case DNS_T_GID: return dns_typetab[55].name;
case DNS_T_UNSPEC: return dns_typetab[56].name;
case DNS_T_TSIG: return dns_typetab[57].name;
case DNS_T_IXFR: return dns_typetab[58].name;
case DNS_T_AXFR: return dns_typetab[59].name;
case DNS_T_MAILB: return dns_typetab[60].name;
case DNS_T_MAILA: return dns_typetab[61].name;
case DNS_T_ANY: return dns_typetab[62].name;
case DNS_T_ZXFR: return dns_typetab[63].name;
case DNS_T_DLV: return dns_typetab[64].name;
case DNS_T_MAX: return dns_typetab[65].name;
}
return _dns_format_code(nm,"type",code);
}
const struct dns_nameval dns_classtab[] = {
{DNS_C_INVALID,"INVALID"},
{DNS_C_IN,"IN"},
{DNS_C_CH,"CH"},
{DNS_C_HS,"HS"},
{DNS_C_ANY,"ANY"},
{0,0}};
const char *dns_classname(enum dns_class code) {
static char nm[20];
switch(code) {
case DNS_C_INVALID: return dns_classtab[0].name;
case DNS_C_IN: return dns_classtab[1].name;
case DNS_C_CH: return dns_classtab[2].name;
case DNS_C_HS: return dns_classtab[3].name;
case DNS_C_ANY: return dns_classtab[4].name;
}
return _dns_format_code(nm,"class",code);
}
const struct dns_nameval dns_rcodetab[] = {
{DNS_R_NOERROR,"NOERROR"},
{DNS_R_FORMERR,"FORMERR"},
{DNS_R_SERVFAIL,"SERVFAIL"},
{DNS_R_NXDOMAIN,"NXDOMAIN"},
{DNS_R_NOTIMPL,"NOTIMPL"},
{DNS_R_REFUSED,"REFUSED"},
{DNS_R_YXDOMAIN,"YXDOMAIN"},
{DNS_R_YXRRSET,"YXRRSET"},
{DNS_R_NXRRSET,"NXRRSET"},
{DNS_R_NOTAUTH,"NOTAUTH"},
{DNS_R_NOTZONE,"NOTZONE"},
{DNS_R_BADSIG,"BADSIG"},
{DNS_R_BADKEY,"BADKEY"},
{DNS_R_BADTIME,"BADTIME"},
{0,0}};
const char *dns_rcodename(enum dns_rcode code) {
static char nm[20];
switch(code) {
case DNS_R_NOERROR: return dns_rcodetab[0].name;
case DNS_R_FORMERR: return dns_rcodetab[1].name;
case DNS_R_SERVFAIL: return dns_rcodetab[2].name;
case DNS_R_NXDOMAIN: return dns_rcodetab[3].name;
case DNS_R_NOTIMPL: return dns_rcodetab[4].name;
case DNS_R_REFUSED: return dns_rcodetab[5].name;
case DNS_R_YXDOMAIN: return dns_rcodetab[6].name;
case DNS_R_YXRRSET: return dns_rcodetab[7].name;
case DNS_R_NXRRSET: return dns_rcodetab[8].name;
case DNS_R_NOTAUTH: return dns_rcodetab[9].name;
case DNS_R_NOTZONE: return dns_rcodetab[10].name;
case DNS_R_BADSIG: return dns_rcodetab[11].name;
case DNS_R_BADKEY: return dns_rcodetab[12].name;
case DNS_R_BADTIME: return dns_rcodetab[13].name;
}
return _dns_format_code(nm,"rcode",code);
}

379
3rdparty/udns/udns_dn.c vendored Normal file
View File

@@ -0,0 +1,379 @@
/* udns_dn.c
domain names manipulation routines
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include "udns.h"
unsigned dns_dnlen(dnscc_t *dn) {
register dnscc_t *d = dn;
while(*d)
d += 1 + *d;
return (unsigned)(d - dn) + 1;
}
unsigned dns_dnlabels(register dnscc_t *dn) {
register unsigned l = 0;
while(*dn)
++l, dn += 1 + *dn;
return l;
}
unsigned dns_dnequal(register dnscc_t *dn1, register dnscc_t *dn2) {
register unsigned c;
dnscc_t *dn = dn1;
for(;;) {
if ((c = *dn1++) != *dn2++)
return 0;
if (!c)
return (unsigned)(dn1 - dn);
while(c--) {
if (DNS_DNLC(*dn1) != DNS_DNLC(*dn2))
return 0;
++dn1; ++dn2;
}
}
}
unsigned
dns_dntodn(dnscc_t *sdn, dnsc_t *ddn, unsigned ddnsiz) {
unsigned sdnlen = dns_dnlen(sdn);
if (ddnsiz < sdnlen)
return 0;
memcpy(ddn, sdn, sdnlen);
return sdnlen;
}
int
dns_ptodn(const char *name, unsigned namelen,
dnsc_t *dn, unsigned dnsiz, int *isabs)
{
dnsc_t *dp; /* current position in dn (len byte first) */
dnsc_t *const de /* end of dn: last byte that can be filled up */
= dn + (dnsiz >= DNS_MAXDN ? DNS_MAXDN : dnsiz) - 1;
dnscc_t *np = (dnscc_t *)name;
dnscc_t *ne = np + (namelen ? namelen : strlen((char*)np));
dnsc_t *llab; /* start of last label (llab[-1] will be length) */
unsigned c; /* next input character, or length of last label */
if (!dnsiz)
return 0;
dp = llab = dn + 1;
while(np < ne) {
if (*np == '.') { /* label delimiter */
c = dp - llab; /* length of the label */
if (!c) { /* empty label */
if (np == (dnscc_t *)name && np + 1 == ne) {
/* special case for root dn, aka `.' */
++np;
break;
}
return -1; /* zero label */
}
if (c > DNS_MAXLABEL)
return -1; /* label too long */
llab[-1] = (dnsc_t)c; /* update len of last label */
llab = ++dp; /* start new label, llab[-1] will be len of it */
++np;
continue;
}
/* check whenever we may put out one more byte */
if (dp >= de) /* too long? */
return dnsiz >= DNS_MAXDN ? -1 : 0;
if (*np != '\\') { /* non-escape, simple case */
*dp++ = *np++;
continue;
}
/* handle \-style escape */
/* note that traditionally, domain names (gethostbyname etc)
* used decimal \dd notation, not octal \ooo (RFC1035), so
* we're following this tradition here.
*/
if (++np == ne)
return -1; /* bad escape */
else if (*np >= '0' && *np <= '9') { /* decimal number */
/* we allow not only exactly 3 digits as per RFC1035,
* but also 2 or 1, for better usability. */
c = *np++ - '0';
if (np < ne && *np >= '0' && *np <= '9') { /* 2digits */
c = c * 10 + *np++ - '0';
if (np < ne && *np >= '0' && *np <= '9') {
c = c * 10 + *np++ - '0';
if (c > 255)
return -1; /* bad escape */
}
}
}
else
c = *np++;
*dp++ = (dnsc_t)c; /* place next out byte */
}
if ((c = dp - llab) > DNS_MAXLABEL)
return -1; /* label too long */
if ((llab[-1] = (dnsc_t)c) != 0) {
*dp++ = 0;
if (isabs)
*isabs = 0;
}
else if (isabs)
*isabs = 1;
return dp - dn;
}
dnscc_t dns_inaddr_arpa_dn[14] = "\07in-addr\04arpa";
dnsc_t *
dns_a4todn_(const struct in_addr *addr, dnsc_t *dn, dnsc_t *dne) {
const unsigned char *s = ((const unsigned char *)addr) + 4;
while(s > (const unsigned char *)addr) {
unsigned n = *--s;
dnsc_t *p = dn + 1;
if (n > 99) {
if (p + 2 > dne) return 0;
*p++ = n / 100 + '0';
*p++ = (n % 100 / 10) + '0';
*p = n % 10 + '0';
}
else if (n > 9) {
if (p + 1 > dne) return 0;
*p++ = n / 10 + '0';
*p = n % 10 + '0';
}
else {
if (p > dne) return 0;
*p = n + '0';
}
*dn = p - dn;
dn = p + 1;
}
return dn;
}
int dns_a4todn(const struct in_addr *addr, dnscc_t *tdn,
dnsc_t *dn, unsigned dnsiz) {
dnsc_t *dne = dn + (dnsiz > DNS_MAXDN ? DNS_MAXDN : dnsiz);
dnsc_t *p;
unsigned l;
p = dns_a4todn_(addr, dn, dne);
if (!p) return 0;
if (!tdn)
tdn = dns_inaddr_arpa_dn;
l = dns_dnlen(tdn);
if (p + l > dne) return dnsiz >= DNS_MAXDN ? -1 : 0;
memcpy(p, tdn, l);
return (p + l) - dn;
}
int dns_a4ptodn(const struct in_addr *addr, const char *tname,
dnsc_t *dn, unsigned dnsiz) {
dnsc_t *p;
int r;
if (!tname)
return dns_a4todn(addr, NULL, dn, dnsiz);
p = dns_a4todn_(addr, dn, dn + dnsiz);
if (!p) return 0;
r = dns_sptodn(tname, p, dnsiz - (p - dn));
return r != 0 ? r : dnsiz >= DNS_MAXDN ? -1 : 0;
}
dnscc_t dns_ip6_arpa_dn[10] = "\03ip6\04arpa";
dnsc_t *
dns_a6todn_(const struct in6_addr *addr, dnsc_t *dn, dnsc_t *dne) {
const unsigned char *s = ((const unsigned char *)addr) + 16;
if (dn + 64 > dne) return 0;
while(s > (const unsigned char *)addr) {
unsigned n = *--s & 0x0f;
*dn++ = 1;
*dn++ = n > 9 ? n + 'a' - 10 : n + '0';
*dn++ = 1;
n = *s >> 4;
*dn++ = n > 9 ? n + 'a' - 10 : n + '0';
}
return dn;
}
int dns_a6todn(const struct in6_addr *addr, dnscc_t *tdn,
dnsc_t *dn, unsigned dnsiz) {
dnsc_t *dne = dn + (dnsiz > DNS_MAXDN ? DNS_MAXDN : dnsiz);
dnsc_t *p;
unsigned l;
p = dns_a6todn_(addr, dn, dne);
if (!p) return 0;
if (!tdn)
tdn = dns_ip6_arpa_dn;
l = dns_dnlen(tdn);
if (p + l > dne) return dnsiz >= DNS_MAXDN ? -1 : 0;
memcpy(p, tdn, l);
return (p + l) - dn;
}
int dns_a6ptodn(const struct in6_addr *addr, const char *tname,
dnsc_t *dn, unsigned dnsiz) {
dnsc_t *p;
int r;
if (!tname)
return dns_a6todn(addr, NULL, dn, dnsiz);
p = dns_a6todn_(addr, dn, dn + dnsiz);
if (!p) return 0;
r = dns_sptodn(tname, p, dnsiz - (p - dn));
return r != 0 ? r : dnsiz >= DNS_MAXDN ? -1 : 0;
}
/* return size of buffer required to convert the dn into asciiz string.
* Keep in sync with dns_dntop() below.
*/
unsigned dns_dntop_size(dnscc_t *dn) {
unsigned size = 0; /* the size reqd */
dnscc_t *le; /* label end */
while(*dn) {
/* *dn is the length of the next label, non-zero */
if (size)
++size; /* for the dot */
le = dn + *dn + 1;
++dn;
do {
switch(*dn) {
case '.':
case '\\':
/* Special modifiers in zone files. */
case '"':
case ';':
case '@':
case '$':
size += 2;
break;
default:
if (*dn <= 0x20 || *dn >= 0x7f)
/* \ddd decimal notation */
size += 4;
else
size += 1;
}
} while(++dn < le);
}
size += 1; /* zero byte at the end - string terminator */
return size > DNS_MAXNAME ? 0 : size;
}
/* Convert the dn into asciiz string.
* Keep in sync with dns_dntop_size() above.
*/
int dns_dntop(dnscc_t *dn, char *name, unsigned namesiz) {
char *np = name; /* current name ptr */
char *const ne = name + namesiz; /* end of name */
dnscc_t *le; /* label end */
while(*dn) {
/* *dn is the length of the next label, non-zero */
if (np != name) {
if (np >= ne) goto toolong;
*np++ = '.';
}
le = dn + *dn + 1;
++dn;
do {
switch(*dn) {
case '.':
case '\\':
/* Special modifiers in zone files. */
case '"':
case ';':
case '@':
case '$':
if (np + 2 > ne) goto toolong;
*np++ = '\\';
*np++ = *dn;
break;
default:
if (*dn <= 0x20 || *dn >= 0x7f) {
/* \ddd decimal notation */
if (np + 4 >= ne) goto toolong;
*np++ = '\\';
*np++ = '0' + (*dn / 100);
*np++ = '0' + ((*dn % 100) / 10);
*np++ = '0' + (*dn % 10);
}
else {
if (np >= ne) goto toolong;
*np++ = *dn;
}
}
} while(++dn < le);
}
if (np >= ne) goto toolong;
*np++ = '\0';
return np - name;
toolong:
return namesiz >= DNS_MAXNAME ? -1 : 0;
}
#ifdef TEST
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int i;
int sz;
dnsc_t dn[DNS_MAXDN+10];
dnsc_t *dl, *dp;
int isabs;
sz = (argc > 1) ? atoi(argv[1]) : 0;
for(i = 2; i < argc; ++i) {
int r = dns_ptodn(argv[i], 0, dn, sz, &isabs);
printf("%s: ", argv[i]);
if (r < 0) printf("error\n");
else if (!r) printf("buffer too small\n");
else {
printf("len=%d dnlen=%d size=%d name:",
r, dns_dnlen(dn), dns_dntop_size(dn));
dl = dn;
while(*dl) {
printf(" %d=", *dl);
dp = dl + 1;
dl = dp + *dl;
while(dp < dl) {
if (*dp <= ' ' || *dp >= 0x7f)
printf("\\%03d", *dp);
else if (*dp == '.' || *dp == '\\')
printf("\\%c", *dp);
else
putchar(*dp);
++dp;
}
}
if (isabs) putchar('.');
putchar('\n');
}
}
return 0;
}
#endif /* TEST */

30
3rdparty/udns/udns_dntosp.c vendored Normal file
View File

@@ -0,0 +1,30 @@
/* udns_dntosp.c
dns_dntosp() = convert DN to asciiz string using static buffer
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#include "udns.h"
static char name[DNS_MAXNAME];
const char *dns_dntosp(dnscc_t *dn) {
return dns_dntop(dn, name, sizeof(name)) > 0 ? name : 0;
}

231
3rdparty/udns/udns_init.c vendored Normal file
View File

@@ -0,0 +1,231 @@
/* udns_init.c
resolver initialisation stuff
Copyright (C) 2006 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef WINDOWS
# include <winsock2.h> /* includes <windows.h> */
# include <iphlpapi.h> /* for dns server addresses etc */
#else
# include <sys/types.h>
# include <unistd.h>
# include <fcntl.h>
#endif /* !WINDOWS */
#include <stdlib.h>
#include <string.h>
#include "udns.h"
#define ISSPACE(x) (x == ' ' || x == '\t' || x == '\r' || x == '\n')
static const char space[] = " \t\r\n";
static void dns_set_serv_internal(struct dns_ctx *ctx, char *serv) {
dns_add_serv(ctx, NULL);
for(serv = strtok(serv, space); serv; serv = strtok(NULL, space))
dns_add_serv(ctx, serv);
}
static void dns_set_srch_internal(struct dns_ctx *ctx, char *srch) {
dns_add_srch(ctx, NULL);
for(srch = strtok(srch, space); srch; srch = strtok(NULL, space))
dns_add_srch(ctx, srch);
}
#ifdef WINDOWS
#ifndef NO_IPHLPAPI
/* Apparently, some systems does not have proper headers for IPHLPAIP to work.
* The best is to upgrade headers, but here's another, ugly workaround for
* this: compile with -DNO_IPHLPAPI.
*/
typedef DWORD (WINAPI *GetAdaptersAddressesFunc)(
ULONG Family, DWORD Flags, PVOID Reserved,
PIP_ADAPTER_ADDRESSES pAdapterAddresses,
PULONG pOutBufLen);
static int dns_initns_iphlpapi(struct dns_ctx *ctx) {
HANDLE h_iphlpapi;
GetAdaptersAddressesFunc pfnGetAdAddrs;
PIP_ADAPTER_ADDRESSES pAddr, pAddrBuf;
PIP_ADAPTER_DNS_SERVER_ADDRESS pDnsAddr;
ULONG ulOutBufLen;
DWORD dwRetVal;
int ret = -1;
h_iphlpapi = LoadLibrary("iphlpapi.dll");
if (!h_iphlpapi)
return -1;
pfnGetAdAddrs = (GetAdaptersAddressesFunc)
GetProcAddress(h_iphlpapi, "GetAdaptersAddresses");
if (!pfnGetAdAddrs) goto freelib;
ulOutBufLen = 0;
dwRetVal = pfnGetAdAddrs(AF_UNSPEC, 0, NULL, NULL, &ulOutBufLen);
if (dwRetVal != ERROR_BUFFER_OVERFLOW) goto freelib;
pAddrBuf = malloc(ulOutBufLen);
if (!pAddrBuf) goto freelib;
dwRetVal = pfnGetAdAddrs(AF_UNSPEC, 0, NULL, pAddrBuf, &ulOutBufLen);
if (dwRetVal != ERROR_SUCCESS) goto freemem;
for (pAddr = pAddrBuf; pAddr; pAddr = pAddr->Next)
for (pDnsAddr = pAddr->FirstDnsServerAddress;
pDnsAddr;
pDnsAddr = pDnsAddr->Next)
dns_add_serv_s(ctx, pDnsAddr->Address.lpSockaddr);
ret = 0;
freemem:
free(pAddrBuf);
freelib:
FreeLibrary(h_iphlpapi);
return ret;
}
#else /* NO_IPHLPAPI */
#define dns_initns_iphlpapi(ctx) (-1)
#endif /* NO_IPHLPAPI */
static int dns_initns_registry(struct dns_ctx *ctx) {
LONG res;
HKEY hk;
DWORD type = REG_EXPAND_SZ | REG_SZ;
DWORD len;
char valBuf[1024];
#define REGKEY_WINNT "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
#define REGKEY_WIN9x "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP"
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WINNT, 0, KEY_QUERY_VALUE, &hk);
if (res != ERROR_SUCCESS)
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WIN9x,
0, KEY_QUERY_VALUE, &hk);
if (res != ERROR_SUCCESS)
return -1;
len = sizeof(valBuf) - 1;
res = RegQueryValueEx(hk, "NameServer", NULL, &type, (BYTE*)valBuf, &len);
if (res != ERROR_SUCCESS || !len || !valBuf[0]) {
len = sizeof(valBuf) - 1;
res = RegQueryValueEx(hk, "DhcpNameServer", NULL, &type,
(BYTE*)valBuf, &len);
}
RegCloseKey(hk);
if (res != ERROR_SUCCESS || !len || !valBuf[0])
return -1;
valBuf[len] = '\0';
/* nameservers are stored as a whitespace-seperate list:
* "192.168.1.1 123.21.32.12" */
dns_set_serv_internal(ctx, valBuf);
return 0;
}
#else /* !WINDOWS */
static int dns_init_resolvconf(struct dns_ctx *ctx) {
char *v;
char buf[2049]; /* this buffer is used to hold /etc/resolv.conf */
int has_srch = 0;
/* read resolv.conf... */
{ int fd = open("/etc/resolv.conf", O_RDONLY);
if (fd >= 0) {
int l = read(fd, buf, sizeof(buf) - 1);
close(fd);
buf[l < 0 ? 0 : l] = '\0';
}
else
buf[0] = '\0';
}
if (buf[0]) { /* ...and parse it */
char *line, *nextline;
line = buf;
do {
nextline = strchr(line, '\n');
if (nextline) *nextline++ = '\0';
v = line;
while(*v && !ISSPACE(*v)) ++v;
if (!*v) continue;
*v++ = '\0';
while(ISSPACE(*v)) ++v;
if (!*v) continue;
if (strcmp(line, "domain") == 0) {
dns_set_srch_internal(ctx, strtok(v, space));
has_srch = 1;
}
else if (strcmp(line, "search") == 0) {
dns_set_srch_internal(ctx, v);
has_srch = 1;
}
else if (strcmp(line, "nameserver") == 0)
dns_add_serv(ctx, strtok(v, space));
else if (strcmp(line, "options") == 0)
dns_set_opts(ctx, v);
} while((line = nextline) != NULL);
}
buf[sizeof(buf)-1] = '\0';
/* get list of nameservers from env. vars. */
if ((v = getenv("NSCACHEIP")) != NULL ||
(v = getenv("NAMESERVERS")) != NULL) {
strncpy(buf, v, sizeof(buf) - 1);
dns_set_serv_internal(ctx, buf);
}
/* if $LOCALDOMAIN is set, use it for search list */
if ((v = getenv("LOCALDOMAIN")) != NULL) {
strncpy(buf, v, sizeof(buf) - 1);
dns_set_srch_internal(ctx, buf);
has_srch = 1;
}
if ((v = getenv("RES_OPTIONS")) != NULL)
dns_set_opts(ctx, v);
/* if still no search list, use local domain name */
if (has_srch &&
gethostname(buf, sizeof(buf) - 1) == 0 &&
(v = strchr(buf, '.')) != NULL &&
*++v != '\0')
dns_add_srch(ctx, v);
return 0;
}
#endif /* !WINDOWS */
int dns_init(struct dns_ctx *ctx, int do_open) {
if (!ctx)
ctx = &dns_defctx;
dns_reset(ctx);
#ifdef WINDOWS
if (dns_initns_iphlpapi(ctx) != 0)
dns_initns_registry(ctx);
/*XXX WINDOWS: probably good to get default domain and search list too...
* And options. Something is in registry. */
/*XXX WINDOWS: maybe environment variables are also useful? */
#else
dns_init_resolvconf(ctx);
#endif
return do_open ? dns_open(ctx) : 0;
}

52
3rdparty/udns/udns_jran.c vendored Normal file
View File

@@ -0,0 +1,52 @@
/* udns_jran.c: small non-cryptographic random number generator
* taken from http://burtleburtle.net/bob/rand/smallprng.html
* by Bob Jenkins, Public domain.
*/
#include "udns.h"
#define rot32(x,k) (((x) << (k)) | ((x) >> (32-(k))))
#define rot64(x,k) (((x) << (k)) | ((x) >> (64-(k))))
#define tr32(x) ((x)&0xffffffffu)
unsigned udns_jranval(struct udns_jranctx *x) {
/* This routine can be made to work with either 32 or 64bit words -
* if JRAN_32_64 is defined when compiling the file.
* We use if() instead of #if since there's no good
* portable way to check sizeof() in preprocessor without
* introducing some ugly configure-time checks.
* Most compilers will optimize the wrong branches away anyway.
* By default it assumes 32bit integers
*/
#ifdef JRAN_32_64
if (sizeof(unsigned) == 4) {
#endif
unsigned e = tr32(x->a - rot32(x->b, 27));
x->a = tr32(x->b ^ rot32(x->c, 17));
x->b = tr32(x->c + x->d);
x->c = tr32(x->d + e);
x->d = tr32(e + x->a);
#ifdef JRAN_32_64
}
else if (sizeof(unsigned) == 8) { /* assuming it's 64bits */
unsigned e = x->a - rot64(x->b, 7);
x->a = x->b ^ rot64(x->c, 13);
x->b = x->c + rot64(x->d, 37);
x->c = x->d + e;
x->d = e + x->a;
}
else {
unsigned e = 0;
x->d = 1/e; /* bail */
}
#endif
return x->d;
}
void udns_jraninit(struct udns_jranctx *x, unsigned seed) {
unsigned i;
x->a = 0xf1ea5eed;
x->b = x->c = x->d = seed;
for (i = 0; i < 20; ++i)
(void)udns_jranval(x);
}

67
3rdparty/udns/udns_misc.c vendored Normal file
View File

@@ -0,0 +1,67 @@
/* udns_misc.c
miscellaneous routines
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#include "udns.h"
int dns_findname(const struct dns_nameval *nv, const char *name) {
register const char *a, *b;
for(; nv->name; ++nv)
for(a = name, b = nv->name; ; ++a, ++b)
if (DNS_DNUC(*a) != *b) break;
else if (!*a) return nv->val;
return -1;
}
const char *_dns_format_code(char *buf, const char *prefix, int code) {
char *bp = buf;
unsigned c, n;
do *bp++ = DNS_DNUC(*prefix);
while(*++prefix);
*bp++ = '#';
if (code < 0) code = -code, *bp++ = '-';
n = 0; c = code;
do ++n;
while((c /= 10));
c = code;
bp[n--] = '\0';
do bp[n--] = c % 10 + '0';
while((c /= 10));
return buf;
}
const char *dns_strerror(int err) {
if (err >= 0) return "successeful completion";
switch(err) {
case DNS_E_TEMPFAIL: return "temporary failure in name resolution";
case DNS_E_PROTOCOL: return "protocol error";
case DNS_E_NXDOMAIN: return "domain name does not exist";
case DNS_E_NODATA: return "valid domain but no data of requested type";
case DNS_E_NOMEM: return "out of memory";
case DNS_E_BADQUERY: return "malformed query";
default: return "unknown error";
}
}
const char *dns_version(void) {
return UDNS_VERSION;
}

169
3rdparty/udns/udns_parse.c vendored Normal file
View File

@@ -0,0 +1,169 @@
/* udns_parse.c
raw DNS packet parsing routines
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include <assert.h>
#include "udns.h"
dnscc_t *dns_skipdn(dnscc_t *cur, dnscc_t *end) {
unsigned c;
for(;;) {
if (cur >= end)
return NULL;
c = *cur++;
if (!c)
return cur;
if (c & 192) /* jump */
return cur + 1 >= end ? NULL : cur + 1;
cur += c;
}
}
int
dns_getdn(dnscc_t *pkt, dnscc_t **cur, dnscc_t *end,
register dnsc_t *dn, unsigned dnsiz) {
unsigned c;
dnscc_t *pp = *cur; /* current packet pointer */
dnsc_t *dp = dn; /* current dn pointer */
dnsc_t *const de /* end of the DN dest */
= dn + (dnsiz < DNS_MAXDN ? dnsiz : DNS_MAXDN);
dnscc_t *jump = NULL; /* ptr after first jump if any */
unsigned loop = 100; /* jump loop counter */
for(;;) { /* loop by labels */
if (pp >= end) /* reached end of packet? */
return -1;
c = *pp++; /* length of the label */
if (!c) { /* empty label: terminate */
if (dn >= de) /* can't fit terminator */
goto noroom;
*dp++ = 0;
/* return next pos: either after the first jump or current */
*cur = jump ? jump : pp;
return dp - dn;
}
if (c & 192) { /* jump */
if (pp >= end) /* eop instead of jump pos */
return -1;
if (!jump) jump = pp + 1; /* remember first jump */
else if (!--loop) return -1; /* too many jumps */
c = ((c & ~192) << 8) | *pp; /* new pos */
if (c < DNS_HSIZE) /* don't allow jump into the header */
return -1;
pp = pkt + c;
continue;
}
if (c > DNS_MAXLABEL) /* too long label? */
return -1;
if (pp + c > end) /* label does not fit in packet? */
return -1;
if (dp + c + 1 > de) /* if enouth room for the label */
goto noroom;
*dp++ = c; /* label length */
memcpy(dp, pp, c); /* and the label itself */
dp += c;
pp += c; /* advance to the next label */
}
noroom:
return dnsiz < DNS_MAXDN ? 0 : -1;
}
void dns_rewind(struct dns_parse *p, dnscc_t *qdn) {
p->dnsp_qdn = qdn;
p->dnsp_cur = p->dnsp_ans;
p->dnsp_rrl = dns_numan(p->dnsp_pkt);
p->dnsp_ttl = 0xffffffffu;
p->dnsp_nrr = 0;
}
void
dns_initparse(struct dns_parse *p, dnscc_t *qdn,
dnscc_t *pkt, dnscc_t *cur, dnscc_t *end) {
p->dnsp_pkt = pkt;
p->dnsp_end = end;
p->dnsp_rrl = dns_numan(pkt);
p->dnsp_qdn = qdn;
assert(cur + 4 <= end);
if ((p->dnsp_qtyp = dns_get16(cur+0)) == DNS_T_ANY) p->dnsp_qtyp = 0;
if ((p->dnsp_qcls = dns_get16(cur+2)) == DNS_C_ANY) p->dnsp_qcls = 0;
p->dnsp_cur = p->dnsp_ans = cur + 4;
p->dnsp_ttl = 0xffffffffu;
p->dnsp_nrr = 0;
}
int dns_nextrr(struct dns_parse *p, struct dns_rr *rr) {
dnscc_t *cur = p->dnsp_cur;
while(p->dnsp_rrl > 0) {
--p->dnsp_rrl;
if (dns_getdn(p->dnsp_pkt, &cur, p->dnsp_end,
rr->dnsrr_dn, sizeof(rr->dnsrr_dn)) <= 0)
return -1;
if (cur + 10 > p->dnsp_end)
return -1;
rr->dnsrr_typ = dns_get16(cur);
rr->dnsrr_cls = dns_get16(cur+2);
rr->dnsrr_ttl = dns_get32(cur+4);
rr->dnsrr_dsz = dns_get16(cur+8);
rr->dnsrr_dptr = cur = cur + 10;
rr->dnsrr_dend = cur = cur + rr->dnsrr_dsz;
if (cur > p->dnsp_end)
return -1;
if (p->dnsp_qdn && !dns_dnequal(p->dnsp_qdn, rr->dnsrr_dn))
continue;
if ((!p->dnsp_qcls || p->dnsp_qcls == rr->dnsrr_cls) &&
(!p->dnsp_qtyp || p->dnsp_qtyp == rr->dnsrr_typ)) {
p->dnsp_cur = cur;
++p->dnsp_nrr;
if (p->dnsp_ttl > rr->dnsrr_ttl) p->dnsp_ttl = rr->dnsrr_ttl;
return 1;
}
if (p->dnsp_qdn && rr->dnsrr_typ == DNS_T_CNAME && !p->dnsp_nrr) {
if (dns_getdn(p->dnsp_pkt, &rr->dnsrr_dptr, p->dnsp_end,
p->dnsp_dnbuf, sizeof(p->dnsp_dnbuf)) <= 0 ||
rr->dnsrr_dptr != rr->dnsrr_dend)
return -1;
p->dnsp_qdn = p->dnsp_dnbuf;
if (p->dnsp_ttl > rr->dnsrr_ttl) p->dnsp_ttl = rr->dnsrr_ttl;
}
}
p->dnsp_cur = cur;
return 0;
}
int dns_stdrr_size(const struct dns_parse *p) {
return
dns_dntop_size(p->dnsp_qdn) +
(p->dnsp_qdn == dns_payload(p->dnsp_pkt) ? 0 :
dns_dntop_size(dns_payload(p->dnsp_pkt)));
}
void *dns_stdrr_finish(struct dns_rr_null *ret, char *cp,
const struct dns_parse *p) {
cp += dns_dntop(p->dnsp_qdn, (ret->dnsn_cname = cp), DNS_MAXNAME);
if (p->dnsp_qdn == dns_payload(p->dnsp_pkt))
ret->dnsn_qname = ret->dnsn_cname;
else
dns_dntop(dns_payload(p->dnsp_pkt), (ret->dnsn_qname = cp), DNS_MAXNAME);
ret->dnsn_ttl = p->dnsp_ttl;
return ret;
}

1323
3rdparty/udns/udns_resolver.c vendored Normal file

File diff suppressed because it is too large Load Diff

126
3rdparty/udns/udns_rr_a.c vendored Normal file
View File

@@ -0,0 +1,126 @@
/* udns_rr_a.c
parse/query A/AAAA IN records
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#ifndef WINDOWS
# include <sys/types.h>
# include <netinet/in.h>
#endif
#include "udns.h"
/* here, we use common routine to parse both IPv4 and IPv6 addresses.
*/
/* this structure should match dns_rr_a[46] */
struct dns_rr_a {
dns_rr_common(dnsa);
unsigned char *dnsa_addr;
};
static int
dns_parse_a(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
void **result, unsigned dsize) {
struct dns_rr_a *ret;
struct dns_parse p;
struct dns_rr rr;
int r;
/* first, validate and count number of addresses */
dns_initparse(&p, qdn, pkt, cur, end);
while((r = dns_nextrr(&p, &rr)) > 0)
if (rr.dnsrr_dsz != dsize)
return DNS_E_PROTOCOL;
if (r < 0)
return DNS_E_PROTOCOL;
else if (!p.dnsp_nrr)
return DNS_E_NODATA;
ret = malloc(sizeof(*ret) + dsize * p.dnsp_nrr + dns_stdrr_size(&p));
if (!ret)
return DNS_E_NOMEM;
ret->dnsa_nrr = p.dnsp_nrr;
ret->dnsa_addr = (unsigned char*)(ret+1);
/* copy the RRs */
for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r)
memcpy(ret->dnsa_addr + dsize * r, rr.dnsrr_dptr, dsize);
dns_stdrr_finish((struct dns_rr_null *)ret,
(char *)(ret->dnsa_addr + dsize * p.dnsp_nrr), &p);
*result = ret;
return 0;
}
int
dns_parse_a4(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
void **result) {
#ifdef AF_INET
assert(sizeof(struct in_addr) == 4);
#endif
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_A);
return dns_parse_a(qdn, pkt, cur, end, result, 4);
}
struct dns_query *
dns_submit_a4(struct dns_ctx *ctx, const char *name, int flags,
dns_query_a4_fn *cbck, void *data) {
return
dns_submit_p(ctx, name, DNS_C_IN, DNS_T_A, flags,
dns_parse_a4, (dns_query_fn*)cbck, data);
}
struct dns_rr_a4 *
dns_resolve_a4(struct dns_ctx *ctx, const char *name, int flags) {
return (struct dns_rr_a4 *)
dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_A, flags, dns_parse_a4);
}
int
dns_parse_a6(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
void **result) {
#ifdef AF_INET6
assert(sizeof(struct in6_addr) == 16);
#endif
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_AAAA);
return dns_parse_a(qdn, pkt, cur, end, result, 16);
}
struct dns_query *
dns_submit_a6(struct dns_ctx *ctx, const char *name, int flags,
dns_query_a6_fn *cbck, void *data) {
return
dns_submit_p(ctx, name, DNS_C_IN, DNS_T_AAAA, flags,
dns_parse_a6, (dns_query_fn*)cbck, data);
}
struct dns_rr_a6 *
dns_resolve_a6(struct dns_ctx *ctx, const char *name, int flags) {
return (struct dns_rr_a6 *)
dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_AAAA, flags, dns_parse_a6);
}

91
3rdparty/udns/udns_rr_mx.c vendored Normal file
View File

@@ -0,0 +1,91 @@
/* udns_rr_mx.c
parse/query MX IN records
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "udns.h"
int
dns_parse_mx(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
void **result) {
struct dns_rr_mx *ret;
struct dns_parse p;
struct dns_rr rr;
int r, l;
char *sp;
dnsc_t mx[DNS_MAXDN];
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_MX);
/* first, validate the answer and count size of the result */
l = 0;
dns_initparse(&p, qdn, pkt, cur, end);
while((r = dns_nextrr(&p, &rr)) > 0) {
cur = rr.dnsrr_dptr + 2;
r = dns_getdn(pkt, &cur, end, mx, sizeof(mx));
if (r <= 0 || cur != rr.dnsrr_dend)
return DNS_E_PROTOCOL;
l += dns_dntop_size(mx);
}
if (r < 0)
return DNS_E_PROTOCOL;
if (!p.dnsp_nrr)
return DNS_E_NODATA;
/* next, allocate and set up result */
l += dns_stdrr_size(&p);
ret = malloc(sizeof(*ret) + sizeof(struct dns_mx) * p.dnsp_nrr + l);
if (!ret)
return DNS_E_NOMEM;
ret->dnsmx_nrr = p.dnsp_nrr;
ret->dnsmx_mx = (struct dns_mx *)(ret+1);
/* and 3rd, fill in result, finally */
sp = (char*)(ret->dnsmx_mx + p.dnsp_nrr);
for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r) {
ret->dnsmx_mx[r].name = sp;
cur = rr.dnsrr_dptr;
ret->dnsmx_mx[r].priority = dns_get16(cur);
cur += 2;
dns_getdn(pkt, &cur, end, mx, sizeof(mx));
sp += dns_dntop(mx, sp, DNS_MAXNAME);
}
dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p);
*result = ret;
return 0;
}
struct dns_query *
dns_submit_mx(struct dns_ctx *ctx, const char *name, int flags,
dns_query_mx_fn *cbck, void *data) {
return
dns_submit_p(ctx, name, DNS_C_IN, DNS_T_MX, flags,
dns_parse_mx, (dns_query_fn *)cbck, data);
}
struct dns_rr_mx *
dns_resolve_mx(struct dns_ctx *ctx, const char *name, int flags) {
return (struct dns_rr_mx *)
dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_MX, flags, dns_parse_mx);
}

128
3rdparty/udns/udns_rr_naptr.c vendored Normal file
View File

@@ -0,0 +1,128 @@
/* udns_rr_naptr.c
parse/query NAPTR IN records
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
Copyright (C) 2006 Mikael Magnusson <mikma@users.sourceforge.net>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "udns.h"
/* Get a single string for NAPTR record, pretty much like a DN label.
* String length is in first byte in *cur, so it can't be >255.
*/
static int dns_getstr(dnscc_t **cur, dnscc_t *ep, char *buf)
{
unsigned l;
dnscc_t *cp = *cur;
l = *cp++;
if (cp + l > ep)
return DNS_E_PROTOCOL;
if (buf) {
memcpy(buf, cp, l);
buf[l] = '\0';
}
cp += l;
*cur = cp;
return l + 1;
}
int
dns_parse_naptr(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
void **result) {
struct dns_rr_naptr *ret;
struct dns_parse p;
struct dns_rr rr;
int r, l;
char *sp;
dnsc_t dn[DNS_MAXDN];
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_NAPTR);
/* first, validate the answer and count size of the result */
l = 0;
dns_initparse(&p, qdn, pkt, cur, end);
while((r = dns_nextrr(&p, &rr)) > 0) {
int i;
dnscc_t *ep = rr.dnsrr_dend;
/* first 4 bytes: order & preference */
cur = rr.dnsrr_dptr + 4;
/* flags, services and regexp */
for (i = 0; i < 3; i++) {
r = dns_getstr(&cur, ep, NULL);
if (r < 0)
return r;
l += r;
}
/* replacement */
r = dns_getdn(pkt, &cur, end, dn, sizeof(dn));
if (r <= 0 || cur != rr.dnsrr_dend)
return DNS_E_PROTOCOL;
l += dns_dntop_size(dn);
}
if (r < 0)
return DNS_E_PROTOCOL;
if (!p.dnsp_nrr)
return DNS_E_NODATA;
/* next, allocate and set up result */
l += dns_stdrr_size(&p);
ret = malloc(sizeof(*ret) + sizeof(struct dns_naptr) * p.dnsp_nrr + l);
if (!ret)
return DNS_E_NOMEM;
ret->dnsnaptr_nrr = p.dnsp_nrr;
ret->dnsnaptr_naptr = (struct dns_naptr *)(ret+1);
/* and 3rd, fill in result, finally */
sp = (char*)(&ret->dnsnaptr_naptr[p.dnsp_nrr]);
for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r) {
cur = rr.dnsrr_dptr;
ret->dnsnaptr_naptr[r].order = dns_get16(cur); cur += 2;
ret->dnsnaptr_naptr[r].preference = dns_get16(cur); cur += 2;
sp += dns_getstr(&cur, end, (ret->dnsnaptr_naptr[r].flags = sp));
sp += dns_getstr(&cur, end, (ret->dnsnaptr_naptr[r].service = sp));
sp += dns_getstr(&cur, end, (ret->dnsnaptr_naptr[r].regexp = sp));
dns_getdn(pkt, &cur, end, dn, sizeof(dn));
sp += dns_dntop(dn, (ret->dnsnaptr_naptr[r].replacement = sp), DNS_MAXNAME);
}
dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p);
*result = ret;
return 0;
}
struct dns_query *
dns_submit_naptr(struct dns_ctx *ctx, const char *name, int flags,
dns_query_naptr_fn *cbck, void *data) {
return
dns_submit_p(ctx, name, DNS_C_IN, DNS_T_NAPTR, flags,
dns_parse_naptr, (dns_query_fn *)cbck, data);
}
struct dns_rr_naptr *
dns_resolve_naptr(struct dns_ctx *ctx, const char *name, int flags) {
return (struct dns_rr_naptr *)
dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_NAPTR, flags, dns_parse_naptr);
}

109
3rdparty/udns/udns_rr_ptr.c vendored Normal file
View File

@@ -0,0 +1,109 @@
/* udns_rr_ptr.c
parse/query PTR records
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include <assert.h>
#include "udns.h"
int
dns_parse_ptr(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
void **result) {
struct dns_rr_ptr *ret;
struct dns_parse p;
struct dns_rr rr;
int r, l, c;
char *sp;
dnsc_t ptr[DNS_MAXDN];
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_PTR);
/* first, validate the answer and count size of the result */
l = c = 0;
dns_initparse(&p, qdn, pkt, cur, end);
while((r = dns_nextrr(&p, &rr)) > 0) {
cur = rr.dnsrr_dptr;
r = dns_getdn(pkt, &cur, end, ptr, sizeof(ptr));
if (r <= 0 || cur != rr.dnsrr_dend)
return DNS_E_PROTOCOL;
l += dns_dntop_size(ptr);
++c;
}
if (r < 0)
return DNS_E_PROTOCOL;
if (!c)
return DNS_E_NODATA;
/* next, allocate and set up result */
ret = malloc(sizeof(*ret) + sizeof(char **) * c + l + dns_stdrr_size(&p));
if (!ret)
return DNS_E_NOMEM;
ret->dnsptr_nrr = c;
ret->dnsptr_ptr = (char **)(ret+1);
/* and 3rd, fill in result, finally */
sp = (char*)(ret->dnsptr_ptr + c);
c = 0;
dns_rewind(&p, qdn);
while((r = dns_nextrr(&p, &rr)) > 0) {
ret->dnsptr_ptr[c] = sp;
cur = rr.dnsrr_dptr;
dns_getdn(pkt, &cur, end, ptr, sizeof(ptr));
sp += dns_dntop(ptr, sp, DNS_MAXNAME);
++c;
}
dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p);
*result = ret;
return 0;
}
struct dns_query *
dns_submit_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr,
dns_query_ptr_fn *cbck, void *data) {
dnsc_t dn[DNS_A4RSIZE];
dns_a4todn(addr, 0, dn, sizeof(dn));
return
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_PTR, DNS_NOSRCH,
dns_parse_ptr, (dns_query_fn *)cbck, data);
}
struct dns_rr_ptr *
dns_resolve_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr) {
return (struct dns_rr_ptr *)
dns_resolve(ctx, dns_submit_a4ptr(ctx, addr, NULL, NULL));
}
struct dns_query *
dns_submit_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr,
dns_query_ptr_fn *cbck, void *data) {
dnsc_t dn[DNS_A6RSIZE];
dns_a6todn(addr, 0, dn, sizeof(dn));
return
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_PTR, DNS_NOSRCH,
dns_parse_ptr, (dns_query_fn *)cbck, data);
}
struct dns_rr_ptr *
dns_resolve_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr) {
return (struct dns_rr_ptr *)
dns_resolve(ctx, dns_submit_a6ptr(ctx, addr, NULL, NULL));
}

155
3rdparty/udns/udns_rr_srv.c vendored Normal file
View File

@@ -0,0 +1,155 @@
/* udns_rr_srv.c
parse/query SRV IN (rfc2782) records
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
Copyright 2005 Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
2005-09-11:
Changed MX parser file into a SRV parser file
*/
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "udns.h"
int
dns_parse_srv(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
void **result) {
struct dns_rr_srv *ret;
struct dns_parse p;
struct dns_rr rr;
int r, l;
char *sp;
dnsc_t srv[DNS_MAXDN];
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_SRV);
/* first, validate the answer and count size of the result */
l = 0;
dns_initparse(&p, qdn, pkt, cur, end);
while((r = dns_nextrr(&p, &rr)) > 0) {
cur = rr.dnsrr_dptr + 6;
r = dns_getdn(pkt, &cur, end, srv, sizeof(srv));
if (r <= 0 || cur != rr.dnsrr_dend)
return DNS_E_PROTOCOL;
l += dns_dntop_size(srv);
}
if (r < 0)
return DNS_E_PROTOCOL;
if (!p.dnsp_nrr)
return DNS_E_NODATA;
/* next, allocate and set up result */
l += dns_stdrr_size(&p);
ret = malloc(sizeof(*ret) + sizeof(struct dns_srv) * p.dnsp_nrr + l);
if (!ret)
return DNS_E_NOMEM;
ret->dnssrv_nrr = p.dnsp_nrr;
ret->dnssrv_srv = (struct dns_srv *)(ret+1);
/* and 3rd, fill in result, finally */
sp = (char*)(ret->dnssrv_srv + p.dnsp_nrr);
for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r) {
ret->dnssrv_srv[r].name = sp;
cur = rr.dnsrr_dptr;
ret->dnssrv_srv[r].priority = dns_get16(cur);
ret->dnssrv_srv[r].weight = dns_get16(cur+2);
ret->dnssrv_srv[r].port = dns_get16(cur+4);
cur += 6;
dns_getdn(pkt, &cur, end, srv, sizeof(srv));
sp += dns_dntop(srv, sp, DNS_MAXNAME);
}
dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p);
*result = ret;
return 0;
}
/* Add a single service or proto name prepending an undescore (_),
* according to rfc2782 rules.
* Return 0 or the label length.
* Routing assumes dn holds enouth space for a single DN label. */
static int add_sname(dnsc_t *dn, const char *sn) {
int l = dns_ptodn(sn, 0, dn + 1, DNS_MAXLABEL-1, NULL);
if (l <= 1 || l - 2 != dn[1])
/* Should we really check if sn is exactly one label? Do we care? */
return 0;
dn[0] = l - 1;
dn[1] = '_';
return l;
}
/* Construct a domain name for SRV query from the given name, service and proto.
* The code allows any combinations of srv and proto (both are non-NULL,
* both NULL, or either one is non-NULL). Whenever it makes any sense or not
* is left as an exercise to programmer.
* Return negative value on error (malformed query) or addition query flag(s).
*/
static int
build_srv_dn(dnsc_t *dn, const char *name, const char *srv, const char *proto)
{
int p = 0, l, isabs;
if (srv) {
l = add_sname(dn + p, srv);
if (!l)
return -1;
p += l;
}
if (proto) {
l = add_sname(dn + p, proto);
if (!l)
return -1;
p += l;
}
l = dns_ptodn(name, 0, dn + p, DNS_MAXDN - p, &isabs);
if (l < 0)
return -1;
return isabs ? DNS_NOSRCH : 0;
}
struct dns_query *
dns_submit_srv(struct dns_ctx *ctx,
const char *name, const char *srv, const char *proto,
int flags, dns_query_srv_fn *cbck, void *data) {
dnsc_t dn[DNS_MAXDN];
int r = build_srv_dn(dn, name, srv, proto);
if (r < 0) {
dns_setstatus (ctx, DNS_E_BADQUERY);
return NULL;
}
return
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_SRV, flags | r,
dns_parse_srv, (dns_query_fn *)cbck, data);
}
struct dns_rr_srv *
dns_resolve_srv(struct dns_ctx *ctx,
const char *name, const char *srv, const char *proto, int flags)
{
dnsc_t dn[DNS_MAXDN];
int r = build_srv_dn(dn, name, srv, proto);
if (r < 0) {
dns_setstatus(ctx, DNS_E_BADQUERY);
return NULL;
}
return (struct dns_rr_srv *)
dns_resolve_dn(ctx, dn, DNS_C_IN, DNS_T_SRV, flags | r, dns_parse_srv);
}

98
3rdparty/udns/udns_rr_txt.c vendored Normal file
View File

@@ -0,0 +1,98 @@
/* udns_rr_txt.c
parse/query TXT records
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
This file is part of UDNS library, an async DNS stub resolver.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library, in file named COPYING.LGPL; if not,
write to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "udns.h"
int
dns_parse_txt(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
void **result) {
struct dns_rr_txt *ret;
struct dns_parse p;
struct dns_rr rr;
int r, l;
dnsc_t *sp;
dnscc_t *cp, *ep;
assert(dns_get16(cur+0) == DNS_T_TXT);
/* first, validate the answer and count size of the result */
l = 0;
dns_initparse(&p, qdn, pkt, cur, end);
while((r = dns_nextrr(&p, &rr)) > 0) {
cp = rr.dnsrr_dptr; ep = rr.dnsrr_dend;
while(cp < ep) {
r = *cp++;
if (cp + r > ep)
return DNS_E_PROTOCOL;
l += r;
cp += r;
}
}
if (r < 0)
return DNS_E_PROTOCOL;
if (!p.dnsp_nrr)
return DNS_E_NODATA;
/* next, allocate and set up result */
l += (sizeof(struct dns_txt) + 1) * p.dnsp_nrr + dns_stdrr_size(&p);
ret = malloc(sizeof(*ret) + l);
if (!ret)
return DNS_E_NOMEM;
ret->dnstxt_nrr = p.dnsp_nrr;
ret->dnstxt_txt = (struct dns_txt *)(ret+1);
/* and 3rd, fill in result, finally */
sp = (dnsc_t*)(ret->dnstxt_txt + p.dnsp_nrr);
for(dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr) > 0; ++r) {
ret->dnstxt_txt[r].txt = sp;
cp = rr.dnsrr_dptr; ep = rr.dnsrr_dend;
while(cp < ep) {
l = *cp++;
memcpy(sp, cp, l);
sp += l;
cp += l;
}
ret->dnstxt_txt[r].len = sp - ret->dnstxt_txt[r].txt;
*sp++ = '\0';
}
dns_stdrr_finish((struct dns_rr_null *)ret, (char*)sp, &p);
*result = ret;
return 0;
}
struct dns_query *
dns_submit_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags,
dns_query_txt_fn *cbck, void *data) {
return
dns_submit_p(ctx, name, qcls, DNS_T_TXT, flags,
dns_parse_txt, (dns_query_fn *)cbck, data);
}
struct dns_rr_txt *
dns_resolve_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags) {
return (struct dns_rr_txt *)
dns_resolve_p(ctx, name, qcls, DNS_T_TXT, flags, dns_parse_txt);
}

View File

@@ -1,17 +0,0 @@
include (SimGearComponent)
set(HEADERS
source/utf8.h
)
set(HEADERS_utf8
source/utf8/checked.h
source/utf8/core.h
source/utf8/unchecked.h
)
set(SOURCES
)
simgear_component(utf8 3rdparty/utf8 "${SOURCES}" "${HEADERS}")
simgear_component(utf8-internal 3rdparty/utf8/utf8 "" "${HEADERS_utf8}")

View File

@@ -1,12 +0,0 @@
utf8 cpp library
Release 2.3.4
A minor bug fix release. Thanks to all who reported bugs.
Note: Version 2.3.3 contained a regression, and therefore was removed.
Changes from version 2.3.2
- Bug fix [39]: checked.h Line 273 and unchecked.h Line 182 have an extra ';'
- Bug fix [36]: replace_invalid() only works with back_inserter
Files included in the release: utf8.h, core.h, checked.h, unchecked.h, utf8cpp.html, ReleaseNotes

File diff suppressed because it is too large Load Diff

View File

@@ -1,34 +0,0 @@
// Copyright 2006 Nemanja Trifunovic
/*
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
#include "utf8/checked.h"
#include "utf8/unchecked.h"
#endif // header guard

View File

@@ -1,327 +0,0 @@
// Copyright 2006 Nemanja Trifunovic
/*
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#include "core.h"
#include <stdexcept>
namespace utf8
{
// Base for the exceptions that may be thrown from the library
class exception : public ::std::exception {
};
// Exceptions that may be thrown from the library functions.
class invalid_code_point : public exception {
uint32_t cp;
public:
invalid_code_point(uint32_t cp) : cp(cp) {}
virtual const char* what() const throw() { return "Invalid code point"; }
uint32_t code_point() const {return cp;}
};
class invalid_utf8 : public exception {
uint8_t u8;
public:
invalid_utf8 (uint8_t u) : u8(u) {}
virtual const char* what() const throw() { return "Invalid UTF-8"; }
uint8_t utf8_octet() const {return u8;}
};
class invalid_utf16 : public exception {
uint16_t u16;
public:
invalid_utf16 (uint16_t u) : u16(u) {}
virtual const char* what() const throw() { return "Invalid UTF-16"; }
uint16_t utf16_word() const {return u16;}
};
class not_enough_room : public exception {
public:
virtual const char* what() const throw() { return "Not enough space"; }
};
/// The library API - functions intended to be called by the users
template <typename octet_iterator>
octet_iterator append(uint32_t cp, octet_iterator result)
{
if (!utf8::internal::is_code_point_valid(cp))
throw invalid_code_point(cp);
if (cp < 0x80) // one octet
*(result++) = static_cast<uint8_t>(cp);
else if (cp < 0x800) { // two octets
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
else if (cp < 0x10000) { // three octets
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
else { // four octets
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
return result;
}
template <typename octet_iterator, typename output_iterator>
output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
{
while (start != end) {
octet_iterator sequence_start = start;
internal::utf_error err_code = utf8::internal::validate_next(start, end);
switch (err_code) {
case internal::UTF8_OK :
for (octet_iterator it = sequence_start; it != start; ++it)
*out++ = *it;
break;
case internal::NOT_ENOUGH_ROOM:
throw not_enough_room();
case internal::INVALID_LEAD:
out = utf8::append (replacement, out);
++start;
break;
case internal::INCOMPLETE_SEQUENCE:
case internal::OVERLONG_SEQUENCE:
case internal::INVALID_CODE_POINT:
out = utf8::append (replacement, out);
++start;
// just one replacement mark for the sequence
while (start != end && utf8::internal::is_trail(*start))
++start;
break;
}
}
return out;
}
template <typename octet_iterator, typename output_iterator>
inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
{
static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
return utf8::replace_invalid(start, end, out, replacement_marker);
}
template <typename octet_iterator>
uint32_t next(octet_iterator& it, octet_iterator end)
{
uint32_t cp = 0;
internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
switch (err_code) {
case internal::UTF8_OK :
break;
case internal::NOT_ENOUGH_ROOM :
throw not_enough_room();
case internal::INVALID_LEAD :
case internal::INCOMPLETE_SEQUENCE :
case internal::OVERLONG_SEQUENCE :
throw invalid_utf8(*it);
case internal::INVALID_CODE_POINT :
throw invalid_code_point(cp);
}
return cp;
}
template <typename octet_iterator>
uint32_t peek_next(octet_iterator it, octet_iterator end)
{
return utf8::next(it, end);
}
template <typename octet_iterator>
uint32_t prior(octet_iterator& it, octet_iterator start)
{
// can't do much if it == start
if (it == start)
throw not_enough_room();
octet_iterator end = it;
// Go back until we hit either a lead octet or start
while (utf8::internal::is_trail(*(--it)))
if (it == start)
throw invalid_utf8(*it); // error - no lead byte in the sequence
return utf8::peek_next(it, end);
}
/// Deprecated in versions that include "prior"
template <typename octet_iterator>
uint32_t previous(octet_iterator& it, octet_iterator pass_start)
{
octet_iterator end = it;
while (utf8::internal::is_trail(*(--it)))
if (it == pass_start)
throw invalid_utf8(*it); // error - no lead byte in the sequence
octet_iterator temp = it;
return utf8::next(temp, end);
}
template <typename octet_iterator, typename distance_type>
void advance (octet_iterator& it, distance_type n, octet_iterator end)
{
for (distance_type i = 0; i < n; ++i)
utf8::next(it, end);
}
template <typename octet_iterator>
typename std::iterator_traits<octet_iterator>::difference_type
distance (octet_iterator first, octet_iterator last)
{
typename std::iterator_traits<octet_iterator>::difference_type dist;
for (dist = 0; first < last; ++dist)
utf8::next(first, last);
return dist;
}
template <typename u16bit_iterator, typename octet_iterator>
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
{
while (start != end) {
uint32_t cp = utf8::internal::mask16(*start++);
// Take care of surrogate pairs first
if (utf8::internal::is_lead_surrogate(cp)) {
if (start != end) {
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
if (utf8::internal::is_trail_surrogate(trail_surrogate))
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
else
throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
}
else
throw invalid_utf16(static_cast<uint16_t>(cp));
}
// Lone trail surrogate
else if (utf8::internal::is_trail_surrogate(cp))
throw invalid_utf16(static_cast<uint16_t>(cp));
result = utf8::append(cp, result);
}
return result;
}
template <typename u16bit_iterator, typename octet_iterator>
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
{
while (start != end) {
uint32_t cp = utf8::next(start, end);
if (cp > 0xffff) { //make a surrogate pair
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
}
else
*result++ = static_cast<uint16_t>(cp);
}
return result;
}
template <typename octet_iterator, typename u32bit_iterator>
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
{
while (start != end)
result = utf8::append(*(start++), result);
return result;
}
template <typename octet_iterator, typename u32bit_iterator>
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
{
while (start != end)
(*result++) = utf8::next(start, end);
return result;
}
// The iterator class
template <typename octet_iterator>
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
octet_iterator it;
octet_iterator range_start;
octet_iterator range_end;
public:
iterator () {}
explicit iterator (const octet_iterator& octet_it,
const octet_iterator& range_start,
const octet_iterator& range_end) :
it(octet_it), range_start(range_start), range_end(range_end)
{
if (it < range_start || it > range_end)
throw std::out_of_range("Invalid utf-8 iterator position");
}
// the default "big three" are OK
octet_iterator base () const { return it; }
uint32_t operator * () const
{
octet_iterator temp = it;
return utf8::next(temp, range_end);
}
bool operator == (const iterator& rhs) const
{
if (range_start != rhs.range_start || range_end != rhs.range_end)
throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
return (it == rhs.it);
}
bool operator != (const iterator& rhs) const
{
return !(operator == (rhs));
}
iterator& operator ++ ()
{
utf8::next(it, range_end);
return *this;
}
iterator operator ++ (int)
{
iterator temp = *this;
utf8::next(it, range_end);
return temp;
}
iterator& operator -- ()
{
utf8::prior(it, range_start);
return *this;
}
iterator operator -- (int)
{
iterator temp = *this;
utf8::prior(it, range_start);
return temp;
}
}; // class iterator
} // namespace utf8
#endif //header guard

View File

@@ -1,329 +0,0 @@
// Copyright 2006 Nemanja Trifunovic
/*
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#include <iterator>
namespace utf8
{
// The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
// You may need to change them to match your system.
// These typedefs have the same names as ones from cstdint, or boost/cstdint
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
// Helper code - not intended to be directly called by the library users. May be changed at any time
namespace internal
{
// Unicode constants
// Leading (high) surrogates: 0xd800 - 0xdbff
// Trailing (low) surrogates: 0xdc00 - 0xdfff
const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10);
const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;
// Maximum valid value for a Unicode code point
const uint32_t CODE_POINT_MAX = 0x0010ffffu;
template<typename octet_type>
inline uint8_t mask8(octet_type oc)
{
return static_cast<uint8_t>(0xff & oc);
}
template<typename u16_type>
inline uint16_t mask16(u16_type oc)
{
return static_cast<uint16_t>(0xffff & oc);
}
template<typename octet_type>
inline bool is_trail(octet_type oc)
{
return ((utf8::internal::mask8(oc) >> 6) == 0x2);
}
template <typename u16>
inline bool is_lead_surrogate(u16 cp)
{
return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
}
template <typename u16>
inline bool is_trail_surrogate(u16 cp)
{
return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
}
template <typename u16>
inline bool is_surrogate(u16 cp)
{
return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
}
template <typename u32>
inline bool is_code_point_valid(u32 cp)
{
return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
}
template <typename octet_iterator>
inline typename std::iterator_traits<octet_iterator>::difference_type
sequence_length(octet_iterator lead_it)
{
uint8_t lead = utf8::internal::mask8(*lead_it);
if (lead < 0x80)
return 1;
else if ((lead >> 5) == 0x6)
return 2;
else if ((lead >> 4) == 0xe)
return 3;
else if ((lead >> 3) == 0x1e)
return 4;
else
return 0;
}
template <typename octet_difference_type>
inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
{
if (cp < 0x80) {
if (length != 1)
return true;
}
else if (cp < 0x800) {
if (length != 2)
return true;
}
else if (cp < 0x10000) {
if (length != 3)
return true;
}
return false;
}
enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
/// Helper for get_sequence_x
template <typename octet_iterator>
utf_error increase_safely(octet_iterator& it, octet_iterator end)
{
if (++it == end)
return NOT_ENOUGH_ROOM;
if (!utf8::internal::is_trail(*it))
return INCOMPLETE_SEQUENCE;
return UTF8_OK;
}
#define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
/// get_sequence_x functions decode utf-8 sequences of the length x
template <typename octet_iterator>
utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
{
if (it == end)
return NOT_ENOUGH_ROOM;
code_point = utf8::internal::mask8(*it);
return UTF8_OK;
}
template <typename octet_iterator>
utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
{
if (it == end)
return NOT_ENOUGH_ROOM;
code_point = utf8::internal::mask8(*it);
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
return UTF8_OK;
}
template <typename octet_iterator>
utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
{
if (it == end)
return NOT_ENOUGH_ROOM;
code_point = utf8::internal::mask8(*it);
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point += (*it) & 0x3f;
return UTF8_OK;
}
template <typename octet_iterator>
utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
{
if (it == end)
return NOT_ENOUGH_ROOM;
code_point = utf8::internal::mask8(*it);
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point += (*it) & 0x3f;
return UTF8_OK;
}
#undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
template <typename octet_iterator>
utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
{
// Save the original value of it so we can go back in case of failure
// Of course, it does not make much sense with i.e. stream iterators
octet_iterator original_it = it;
uint32_t cp = 0;
// Determine the sequence length based on the lead octet
typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
const octet_difference_type length = utf8::internal::sequence_length(it);
// Get trail octets and calculate the code point
utf_error err = UTF8_OK;
switch (length) {
case 0:
return INVALID_LEAD;
case 1:
err = utf8::internal::get_sequence_1(it, end, cp);
break;
case 2:
err = utf8::internal::get_sequence_2(it, end, cp);
break;
case 3:
err = utf8::internal::get_sequence_3(it, end, cp);
break;
case 4:
err = utf8::internal::get_sequence_4(it, end, cp);
break;
}
if (err == UTF8_OK) {
// Decoding succeeded. Now, security checks...
if (utf8::internal::is_code_point_valid(cp)) {
if (!utf8::internal::is_overlong_sequence(cp, length)){
// Passed! Return here.
code_point = cp;
++it;
return UTF8_OK;
}
else
err = OVERLONG_SEQUENCE;
}
else
err = INVALID_CODE_POINT;
}
// Failure branch - restore the original value of the iterator
it = original_it;
return err;
}
template <typename octet_iterator>
inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
uint32_t ignored;
return utf8::internal::validate_next(it, end, ignored);
}
} // namespace internal
/// The library API - functions intended to be called by the users
// Byte order mark
const uint8_t bom[] = {0xef, 0xbb, 0xbf};
template <typename octet_iterator>
octet_iterator find_invalid(octet_iterator start, octet_iterator end)
{
octet_iterator result = start;
while (result != end) {
utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
if (err_code != internal::UTF8_OK)
return result;
}
return result;
}
template <typename octet_iterator>
inline bool is_valid(octet_iterator start, octet_iterator end)
{
return (utf8::find_invalid(start, end) == end);
}
template <typename octet_iterator>
inline bool starts_with_bom (octet_iterator it, octet_iterator end)
{
return (
((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
((it != end) && (utf8::internal::mask8(*it)) == bom[2])
);
}
//Deprecated in release 2.3
template <typename octet_iterator>
inline bool is_bom (octet_iterator it)
{
return (
(utf8::internal::mask8(*it++)) == bom[0] &&
(utf8::internal::mask8(*it++)) == bom[1] &&
(utf8::internal::mask8(*it)) == bom[2]
);
}
} // namespace utf8
#endif // header guard

View File

@@ -1,228 +0,0 @@
// Copyright 2006 Nemanja Trifunovic
/*
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#include "core.h"
namespace utf8
{
namespace unchecked
{
template <typename octet_iterator>
octet_iterator append(uint32_t cp, octet_iterator result)
{
if (cp < 0x80) // one octet
*(result++) = static_cast<uint8_t>(cp);
else if (cp < 0x800) { // two octets
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
else if (cp < 0x10000) { // three octets
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
else { // four octets
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
return result;
}
template <typename octet_iterator>
uint32_t next(octet_iterator& it)
{
uint32_t cp = utf8::internal::mask8(*it);
typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
switch (length) {
case 1:
break;
case 2:
it++;
cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
break;
case 3:
++it;
cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
++it;
cp += (*it) & 0x3f;
break;
case 4:
++it;
cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
++it;
cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
++it;
cp += (*it) & 0x3f;
break;
}
++it;
return cp;
}
template <typename octet_iterator>
uint32_t peek_next(octet_iterator it)
{
return utf8::unchecked::next(it);
}
template <typename octet_iterator>
uint32_t prior(octet_iterator& it)
{
while (utf8::internal::is_trail(*(--it))) ;
octet_iterator temp = it;
return utf8::unchecked::next(temp);
}
// Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
template <typename octet_iterator>
inline uint32_t previous(octet_iterator& it)
{
return utf8::unchecked::prior(it);
}
template <typename octet_iterator, typename distance_type>
void advance (octet_iterator& it, distance_type n)
{
for (distance_type i = 0; i < n; ++i)
utf8::unchecked::next(it);
}
template <typename octet_iterator>
typename std::iterator_traits<octet_iterator>::difference_type
distance (octet_iterator first, octet_iterator last)
{
typename std::iterator_traits<octet_iterator>::difference_type dist;
for (dist = 0; first < last; ++dist)
utf8::unchecked::next(first);
return dist;
}
template <typename u16bit_iterator, typename octet_iterator>
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
{
while (start != end) {
uint32_t cp = utf8::internal::mask16(*start++);
// Take care of surrogate pairs first
if (utf8::internal::is_lead_surrogate(cp)) {
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
}
result = utf8::unchecked::append(cp, result);
}
return result;
}
template <typename u16bit_iterator, typename octet_iterator>
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
{
while (start < end) {
uint32_t cp = utf8::unchecked::next(start);
if (cp > 0xffff) { //make a surrogate pair
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
}
else
*result++ = static_cast<uint16_t>(cp);
}
return result;
}
template <typename octet_iterator, typename u32bit_iterator>
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
{
while (start != end)
result = utf8::unchecked::append(*(start++), result);
return result;
}
template <typename octet_iterator, typename u32bit_iterator>
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
{
while (start < end)
(*result++) = utf8::unchecked::next(start);
return result;
}
// The iterator class
template <typename octet_iterator>
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
octet_iterator it;
public:
iterator () {}
explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
// the default "big three" are OK
octet_iterator base () const { return it; }
uint32_t operator * () const
{
octet_iterator temp = it;
return utf8::unchecked::next(temp);
}
bool operator == (const iterator& rhs) const
{
return (it == rhs.it);
}
bool operator != (const iterator& rhs) const
{
return !(operator == (rhs));
}
iterator& operator ++ ()
{
::std::advance(it, utf8::internal::sequence_length(it));
return *this;
}
iterator operator ++ (int)
{
iterator temp = *this;
::std::advance(it, utf8::internal::sequence_length(it));
return temp;
}
iterator& operator -- ()
{
utf8::unchecked::prior(it);
return *this;
}
iterator operator -- (int)
{
iterator temp = *this;
utf8::unchecked::prior(it);
return temp;
}
}; // class iterator
} // namespace utf8::unchecked
} // namespace utf8
#endif // header guard

View File

@@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 2.8.11)
cmake_minimum_required (VERSION 3.0)
if(COMMAND cmake_policy)
if(POLICY CMP0054)
@@ -7,6 +7,20 @@ if(COMMAND cmake_policy)
if(POLICY CMP0042)
cmake_policy(SET CMP0042 NEW)
endif()
if(POLICY CMP0067)
cmake_policy(SET CMP0067 NEW)
endif()
endif()
message(STATUS "CMAKE Build type: ${CMAKE_BUILD_TYPE}")
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Debug' as none was specified.")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
include (CheckFunctionExists)
@@ -16,19 +30,25 @@ include (CheckCXXSourceCompiles)
include (CheckCXXCompilerFlag)
include (GenerateExportHeader)
# using 10.7 because boost requires libc++ and 10.6 doesn't include it
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7)
# only relevant for building shared libs but let's set it regardless
set(CMAKE_OSX_RPATH 1)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
project(SimGear)
# let's use & require C++11 - note these are only functional with CMake 3.1
# we do manual fallbacks for CMake 3.0 in the compilers section
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
# read 'version' file into a variable (stripping any newlines or spaces)
file(READ version versionFile)
string(STRIP ${versionFile} SIMGEAR_VERSION)
set(FIND_LIBRARY_USE_LIB64_PATHS ON)
project(SimGear VERSION ${SIMGEAR_VERSION} LANGUAGES C CXX)
# add a dependency on the version file
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS version)
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)
# use simgear version also as the SO version (if building SOs)
SET(SIMGEAR_SOVERSION ${SIMGEAR_VERSION})
@@ -63,8 +83,6 @@ set(CPACK_SOURCE_PACKAGE_FILE_NAME "simgear-${SIMGEAR_VERSION}" CACHE INTERNAL "
set(CPACK_SOURCE_IGNORE_FILES
"^${PROJECT_SOURCE_DIR}/.git;\\\\.gitignore;Makefile.am;~$;${CPACK_SOURCE_IGNORE_FILES}")
message(STATUS "ignoring: ${CPACK_SOURCE_IGNORE_FILES}")
include (CPack)
# We have some custom .cmake scripts not in the official distribution.
@@ -87,37 +105,49 @@ message(STATUS "Library installation directory: ${CMAKE_INSTALL_LIBDIR}")
# Configure library search paths
#####################################################################################
if(NOT "${CMAKE_LIBRARY_ARCHITECTURE}" STREQUAL "")
# Workaround for Ubuntu/Debian which introduced the "multiarch" library
# directory structure, which is unsupported by CMake < 2.8.10, so we need to
# add paths manually
# see http://www.cmake.org/Bug/view.php?id=12049 and
# http://www.cmake.org/Bug/view.php?id=12037
list(APPEND ADDITIONAL_LIBRARY_PATHS
/usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE}
/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
/lib/${CMAKE_LIBRARY_ARCHITECTURE})
message(STATUS "additional library directories: ${ADDITIONAL_LIBRARY_PATHS}")
endif()
#####################################################################################
if (NOT MSVC)
option(SIMGEAR_SHARED "Set to ON to build SimGear as a shared library/framework" OFF)
option(SYSTEM_EXPAT "Set to ON to build SimGear using the system libExpat" OFF)
option(SYSTEM_EXPAT "Set to ON to build SimGear using the system expat library" OFF)
option(SYSTEM_UDNS "Set to ON to build SimGear using the system udns library" OFF)
else()
# Building SimGear DLLs is currently not supported for MSVC.
set(SIMGEAR_SHARED OFF)
# Using a system expat is currently not supported for MSVC - it would require shared simgear (DLL).
# Using external 3rd party libraries is currently not supported for MSVC - it would require shared simgear (DLL).
set(SYSTEM_EXPAT OFF)
set(SYSTEM_UDNS OFF)
endif()
option(SIMGEAR_HEADLESS "Set to ON to build SimGear without GUI/graphics support" OFF)
option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
option(ENABLE_GDAL "Set to ON to build SimGear with GDAL support" OFF)
option(ENABLE_TESTS "Set to OFF to disable building SimGear's test applications" ON)
option(ENABLE_SOUND "Set to OFF to disable building SimGear's sound support" ON)
option(USE_AEONWAVE "Set to ON to use AeonWave instead of OpenAL" ON)
option(ENABLE_PKGUTIL "Set to ON to build the sg_pkgutil application (default)" ON)
option(ENABLE_CURL "Set to ON to use libCurl as the HTTP client backend" OFF)
option(ENABLE_DNS "Set to ON to use udns library and DNS service resolver" ON)
option(ENABLE_SIMD "Enable SSE/SSE2 support for compilers" ON)
option(ENABLE_SIMD_CODE "Enable SSE/SSE2 support code for compilers" OFF)
option(ENABLE_OPENMP "Enable OpenMP compiler support" OFF)
if (NOT ENABLE_SIMD AND ENABLE_SIMD_CODE)
set(ENABLE_SIMD_CODE OFF)
endif()
include (DetectArch)
# until the fstream fix is applied and generally available in OSG,
# keep the compatability link option as the default
option(OSG_FSTREAM_EXPORT_FIXED "Set to ON if the osgDB fstream export patch is applied" OFF)
if (CMAKE_COMPILER_IS_GNUCXX OR CLANG)
if (CMAKE_VERSION VERSION_LESS 3.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++${CMAKE_CXX_STANDARD}")
elseif (CMAKE_VERSION VERSION_LESS 3.8)
# policy CMP0067 (try_compile does not honor CMAKE_CXX_STANDARD)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++${CMAKE_CXX_STANDARD}")
endif()
endif()
if (MSVC)
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_BINARY_DIR} PATH)
@@ -137,14 +167,23 @@ endif (MSVC)
if (MSVC AND MSVC_3RDPARTY_ROOT)
message(STATUS "3rdparty files located in ${MSVC_3RDPARTY_ROOT}")
string(SUBSTRING ${MSVC_VERSION} 0 2 MSVC_VERSION_MAJOR)
string(SUBSTRING ${MSVC_VERSION} 2 2 MSVC_VERSION_MINOR)
set( OSG_MSVC "msvc" )
if (${MSVC_VERSION} EQUAL 1700)
set( OSG_MSVC ${OSG_MSVC}110 )
elseif (${MSVC_VERSION} EQUAL 1600)
set( OSG_MSVC ${OSG_MSVC}100 )
else (${MSVC_VERSION} EQUAL 1700)
set( OSG_MSVC ${OSG_MSVC}90 )
endif (${MSVC_VERSION} EQUAL 1700)
if (${MSVC_VERSION_MAJOR} EQUAL "19")
if (${MSVC_VERSION_MINOR} EQUAL "00")
set( OSG_MSVC ${OSG_MSVC}140 )
else ()
set( OSG_MSVC ${OSG_MSVC}141 )
endif ()
elseif (${MSVC_VERSION_MAJOR} EQUAL "18")
set( OSG_MSVC ${OSG_MSVC}120 )
else ()
message(FATAL_ERROR "Visual Studio 2013/15/17 is required")
endif ()
if (CMAKE_CL_64)
set( OSG_MSVC ${OSG_MSVC}-64 )
set( MSVC_3RDPARTY_DIR 3rdParty.x64 )
@@ -154,44 +193,31 @@ if (MSVC AND MSVC_3RDPARTY_ROOT)
set (CMAKE_LIBRARY_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenRTI/lib )
set (CMAKE_INCLUDE_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenRTI/include)
find_path(BOOST_ROOT boost/version.hpp
${MSVC_3RDPARTY_ROOT}/boost
${MSVC_3RDPARTY_ROOT}/boost_1_52_0
${MSVC_3RDPARTY_ROOT}/boost_1_51_0
${MSVC_3RDPARTY_ROOT}/boost_1_50_0
${MSVC_3RDPARTY_ROOT}/boost_1_49_0
${MSVC_3RDPARTY_ROOT}/boost_1_48_0
${MSVC_3RDPARTY_ROOT}/boost_1_47_0
${MSVC_3RDPARTY_ROOT}/boost_1_46_1
${MSVC_3RDPARTY_ROOT}/boost_1_46_0
${MSVC_3RDPARTY_ROOT}/boost_1_45_0
${MSVC_3RDPARTY_ROOT}/boost_1_44_0
)
# set (BOOST_ROOT ${MSVC_3RDPARTY_ROOT}/boost_1_44_0)
message(STATUS "BOOST_ROOT is ${BOOST_ROOT}")
if(NOT BOOST_INCLUDEDIR)
# if this variable was not set by the user, set it to 3rdparty root's
# parent dir, which is the normal location for people using our
# windows-3rd-party repo
GET_FILENAME_COMPONENT(MSVC_ROOT_PARENT_DIR ${MSVC_3RDPARTY_ROOT} PATH)
set(BOOST_INCLUDEDIR ${MSVC_ROOT_PARENT_DIR})
message(STATUS "BOOST_INCLUDEDIR is ${BOOST_INCLUDEDIR}")
endif()
set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib)
endif (MSVC AND MSVC_3RDPARTY_ROOT)
if(APPLE)
find_library(COCOA_LIBRARY Cocoa)
# this should be handled by setting CMAKE_OSX_DEPLOYMENT_TARGET
# but it's not working reliably, so forcing it for now
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.7")
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR
${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
find_package(Threads REQUIRED)
endif()
# Somehow this only works if included before searching for Boost...
include(BoostTestTargets)
find_package(Boost REQUIRED)
set (BOOST_CXX_FLAGS "-DBOOST_BIMAP_DISABLE_SERIALIZATION")
include(BoostTestTargets)
if(SIMGEAR_HEADLESS)
message(STATUS "SimGear mode: HEADLESS")
@@ -201,19 +227,42 @@ else()
find_package(OpenGL REQUIRED)
if (ENABLE_SOUND)
find_package(OpenAL REQUIRED)
message(STATUS "Sound support: ENABLED")
if (USE_AEONWAVE)
find_package(AAX)
endif()
if(NOT AAX_FOUND)
set(USE_AEONWAVE FALSE)
find_package(OpenAL REQUIRED)
endif()
if(AAX_FOUND)
message(STATUS "Sound support: AeonWave")
else()
message(STATUS "Sound support: OpenAL")
endif()
endif(ENABLE_SOUND)
find_package(OpenSceneGraph 3.2.0 REQUIRED osgText osgSim osgDB osgParticle osgGA osgViewer osgUtil)
if (MSVC)
set(CMAKE_REQUIRED_INCLUDES ${OPENSCENEGRAPH_INCLUDE_DIRS})
# ensure OSG was compiled with OSG_USE_UTF8_FILENAME set
check_cxx_source_compiles(
"#include <osg/Config>
#if !defined(OSG_USE_UTF8_FILENAME)
#error OSG UTF8 support not enabled
#endif
int main() { return 0; }"
SIMGEAR_OSG_USE_UTF8_FILENAME)
if (NOT SIMGEAR_OSG_USE_UTF8_FILENAME)
message(FATAL_ERROR "Please rebuild OSG with OSG_USE_UTF8_FILENAME set to ON")
endif()
endif()
endif(SIMGEAR_HEADLESS)
find_package(ZLIB REQUIRED)
if (ENABLE_CURL)
find_package(CURL REQUIRED)
message(STATUS "Curl HTTP client: ENABLED")
endif()
find_package(ZLIB 1.2.4 REQUIRED)
find_package(CURL REQUIRED)
if (SYSTEM_EXPAT)
message(STATUS "Requested to use system Expat library, forcing SIMGEAR_SHARED to true")
@@ -226,15 +275,12 @@ else()
# declaring symbols as declspec(import)
add_definitions(-DHAVE_EXPAT_CONFIG_H -DXML_STATIC)
set(EXPAT_INCLUDE_DIRS
${PROJECT_SOURCE_DIR}/3rdparty/expat
${PROJECT_BINARY_DIR}/3rdparty/expat)
${PROJECT_SOURCE_DIR}/3rdparty/expat
${PROJECT_BINARY_DIR}/3rdparty/expat)
endif(SYSTEM_EXPAT)
include_directories(${EXPAT_INCLUDE_DIRS})
check_include_file(inttypes.h HAVE_INTTYPES_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(sys/timeb.h HAVE_SYS_TIMEB_H)
check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(windows.h HAVE_WINDOWS_H)
@@ -244,21 +290,41 @@ if(HAVE_INTTYPES_H)
endif()
if(ENABLE_RTI)
# See if we have any rti library variant installed
message(STATUS "RTI: ENABLED")
find_package(RTI)
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
SET(ENV{PKG_CONFIG_PATH} "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}")
pkg_check_modules(RTI hla-rti13)
endif(PKG_CONFIG_FOUND)
if(RTI_FOUND)
SET(RTI_INCLUDE_DIR "${RTI_INCLUDE_DIRS}")
message(STATUS "RTI: ENABLED")
else()
message(STATUS "RTI: DISABLED")
endif(RTI_FOUND)
else()
message(STATUS "RTI: DISABLED")
endif(ENABLE_RTI)
if(ENABLE_GDAL)
find_package(GDAL 2.0.0 REQUIRED)
if (GDAL_FOUND)
include_directories(${GDAL_INCLUDE_DIR})
endif(GDAL_FOUND)
endif(ENABLE_GDAL)
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
check_function_exists(ftime HAVE_FTIME)
check_function_exists(timegm HAVE_TIMEGM)
check_function_exists(rint HAVE_RINT)
check_function_exists(mkdtemp HAVE_MKDTEMP)
check_function_exists(bcopy HAVE_BCOPY)
check_function_exists(mmap HAVE_MMAP)
if (NOT MSVC)
check_function_exists(timegm HAVE_TIMEGM)
if (NOT HAVE_TIMEGM)
message(FATAL_ERROR "Non-Windows platforms must support timegm()")
endif()
endif()
if(HAVE_UNISTD_H)
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
check_cxx_source_compiles(
@@ -302,19 +368,59 @@ SET(CMAKE_RELWITHDEBINFO_POSTFIX "" CACHE STRING "add a postfix, usually empty o
SET(CMAKE_MINSIZEREL_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
# isnan might not be real symbol, so can't check using function_exists
check_cxx_source_compiles(
"#include <cmath>
int main() { return isnan(0.0);} "
HAVE_ISNAN)
check_cxx_source_compiles(
"#include <cmath>
int main() { return std::isnan(0.0);} "
HAVE_STD_ISNAN)
if (NOT ${HAVE_STD_ISNAN})
message(FATAL_ERROR "Your compiler lacks C++11 std::isnan, please update it")
endif()
# Check if the <regex> implementation in the C++ standard library is usable.
# This is necessary because g++ 4.8 lies about its C++11 compliance: its
# <regex> is utterly unusable, cf. [1].
# The big preprocessor test essentially comes from [2], and gcc upstream devs
# appear to back it (see comments following [2], as well as [3]).
#
# [1] https://stackoverflow.com/a/12665408/4756009
# [2] https://stackoverflow.com/a/41186162/4756009
# [3] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78905
check_cxx_source_compiles(
"#include <regex>
int main() {
#if __cplusplus >= 201103L && \
(!defined(__GLIBCXX__) || \
(__cplusplus >= 201402L) || \
defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
defined(_GLIBCXX_REGEX_STATE_LIMIT) || \
(defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE > 4))
#else
nullptr = void; // intentionally trigger a compilation error
#endif
}"
HAVE_WORKING_STD_REGEX)
if(CMAKE_COMPILER_IS_GNUCXX)
set(WARNING_FLAGS_CXX "-Wall")
set(WARNING_FLAGS_C "-Wall")
set(WARNING_FLAGS_CXX "-Wall -fPIC")
set(WARNING_FLAGS_C "-Wall -fPIC")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
message(WARNING "GCC 4.4 will be required soon, please upgrade")
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} -O0 -fno-omit-frame-pointer -fno-inline")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -O0 -fno-omit-frame-pointer -fno-inline")
elseif (ENABLE_SIMD)
if (X86 OR X86_64)
set(CMAKE_C_FLAGS_RELEASE "-O3 -msse2 -mfpmath=sse -ftree-vectorize -ftree-slp-vectorize")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -msse2 -mfpmath=sse -ftree-vectorize -ftree-slp-vectorize")
endif()
endif()
# certain GCC versions don't provide the atomic builds, and hence
# require is to provide them in SGAtomic.cxx
@@ -324,13 +430,38 @@ if(CMAKE_COMPILER_IS_GNUCXX)
GCC_ATOMIC_BUILTINS_FOUND)
endif(CMAKE_COMPILER_IS_GNUCXX)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if (CLANG)
# Boost redeclares class members
set(WARNING_FLAGS_CXX "-Wall -Wno-overloaded-virtual -Wno-redeclared-class-member")
set(WARNING_FLAGS_C "-Wall")
set(WARNING_FLAGS_CXX "-Wall -fPIC -Wno-overloaded-virtual -Wno-redeclared-class-member")
set(WARNING_FLAGS_C "-Wall -fPIC")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
# fix Boost compilation :(
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} -O0 -fno-omit-frame-pointer -fno-inline-functions")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -O0 -fno-omit-frame-pointer -fno-inline-functions")
elseif (ENABLE_SIMD)
if (X86 OR X86_64)
set(CMAKE_C_FLAGS_RELEASE "-O3 -msse2 -mfpmath=sse -ftree-vectorize -ftree-slp-vectorize")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -msse2 -mfpmath=sse -ftree-vectorize -ftree-slp-vectorize")
endif()
endif()
endif()
if (ENABLE_OPENMP)
find_package(OpenMP)
if(OPENMP_FOUND)
message(STATUS "OpenMP: ENABLED")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
else()
message(STATUS "OpenMP: NOT FOUND")
endif()
else()
message(STATUS "OpenMP: DISABLED")
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
@@ -348,21 +479,35 @@ if(WIN32)
endif()
if(MSVC)
# turn off various warnings
# foreach(warning 4244 4251 4267 4275 4290 4786 4305 4996)
# SET(WARNING_FLAGS "${WARNING_FLAGS} /wd${warning}")
# endforeach(warning)
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS /MP")
if(ENABLE_SIMD)
if (X86)
SET(CMAKE_C_FLAGS_RELEASE "/O2 /arch:SSE /arch:SSE2")
SET(CMAKE_CXX_FLAGS_RELEASE "/O2 /arch:SSE /arch:SSE2")
else()
SET(CMAKE_C_FLAGS_RELEASE "/O2")
SET(CMAKE_CXX_FLAGS_RELEASE "/O2")
endif()
endif()
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS /wd4996 /wd4250 -Dstrdup=_strdup")
if (${MSVC_VERSION} GREATER 1599)
if (NOT OSG_FSTREAM_EXPORT_FIXED)
message(STATUS "For better linking performance, use OSG with patched fstream header")
# needed to avoid link errors on multiply-defined standard C++
# symbols. Suspect this may be an OSG-DB export bug
set( MSVC_LD_FLAGS "/FORCE:MULTIPLE" )
endif (${MSVC_VERSION} GREATER 1599)
endif ()
if (${MSVC_VERSION} GREATER 1899)
# needed for debug builds with VS2015
set( MSVC_FLAGS "${MSVC_FLAGS} /bigobj" )
endif()
endif(MSVC)
# assumed on Windows
set(HAVE_GETLOCALTIME 1)
set( WINSOCK_LIBRARY "ws2_32.lib" )
set( SHLWAPI_LIBRARY "Shlwapi.lib" )
set( RT_LIBRARY "winmm" )
endif(WIN32)
@@ -370,19 +515,12 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS_C} ${MSVC_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_CXX} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
include(CheckCXXFeatures)
# use BEFORE to ensure local directories are used first,
# ahead of system-installed libs
include_directories(BEFORE ${PROJECT_SOURCE_DIR})
include_directories(BEFORE ${PROJECT_SOURCE_DIR}/simgear/canvas/ShivaVG/include)
include_directories(BEFORE ${PROJECT_BINARY_DIR}/simgear)
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIR}
${OPENAL_INCLUDE_DIR}
${CURL_INCLUDE_DIRS}
)
add_definitions(-DHAVE_CONFIG_H)
# configure a header file to pass some of the CMake settings
@@ -407,10 +545,12 @@ set(TEST_LIBS_INTERNAL_CORE
${CMAKE_THREAD_LIBS_INIT}
${ZLIB_LIBRARY}
${WINSOCK_LIBRARY}
${SHLWAPI_LIBRARY}
${RT_LIBRARY}
${DL_LIBRARY}
${COCOA_LIBRARY}
${CURL_LIBRARIES})
${CURL_LIBRARIES}
${GDAL_LIBRARY})
set(TEST_LIBS SimGearCore ${TEST_LIBS_INTERNAL_CORE})
if(NOT SIMGEAR_HEADLESS)
@@ -419,7 +559,19 @@ endif()
install (FILES ${PROJECT_BINARY_DIR}/simgear/simgear_config.h DESTINATION include/simgear/)
include_directories(3rdparty/utf8/source)
if(ENABLE_DNS)
if(SYSTEM_UDNS)
message(STATUS "Requested to use system udns library, forcing SIMGEAR_SHARED to true")
set(SIMGEAR_SHARED ON)
find_package(Udns REQUIRED)
else()
message(STATUS "DNS resolver: ENABLED")
include_directories(3rdparty/udns)
endif()
else()
message(STATUS "DNS resolver: DISABLED")
endif()
add_subdirectory(3rdparty)
add_subdirectory(simgear)
@@ -446,7 +598,7 @@ configure_file(SimGearConfig.cmake.in
@ONLY
)
set(ConfigPackageLocation lib/cmake/SimGear)
set(ConfigPackageLocation ${CMAKE_INSTALL_LIBDIR}/cmake/SimGear)
install(EXPORT SimGearTargets
DESTINATION ${ConfigPackageLocation}
)

View File

@@ -157,7 +157,7 @@ function(add_boost_test _name)
endforeach()
if(NOT _boostTestTargetsNagged${_name} STREQUAL "${includeType}")
if("includeType" STREQUAL "CONFIGURED")
if("${includeType}" STREQUAL "CONFIGURED")
message(STATUS
"Test '${_name}' uses the CMake-configurable form of the boost test framework - congrats! (Including File: ${includeFileLoc})")
elseif("${includeType}" STREQUAL "INCLUDED")

View File

@@ -0,0 +1,30 @@
check_cxx_source_compiles("
#include <utility>
#include <type_traits>
std::make_index_sequence<0> t;
int main() {}" HAVE_STD_INDEX_SEQUENCE
)
check_cxx_source_compiles("
#include <type_traits>
std::remove_cv_t<const int> t;
int main() {}" HAVE_STD_REMOVE_CV_T
)
check_cxx_source_compiles("
#include <type_traits>
std::remove_cvref_t<const int&> t;
int main() {}" HAVE_STD_REMOVE_CVREF_T
)
check_cxx_source_compiles("
#include <type_traits>
std::enable_if_t<true, int> t;
int main() {}" HAVE_STD_ENABLE_IF_T
)
check_cxx_source_compiles("
#include <type_traits>
std::bool_constant<true> t;
int main() {}" HAVE_STD_BOOL_CONSTANT
)

View File

@@ -0,0 +1,37 @@
IF(CMAKE_SYSTEM_PROCESSOR MATCHES amd64.*|x86_64.* OR CMAKE_GENERATOR MATCHES "Visual Studio.*Win64")
IF(CMAKE_C_FLAGS MATCHES -m32 OR CMAKE_CXX_FLAGS MATCHES -m32)
SET(X86 1)
ELSE(CMAKE_C_FLAGS MATCHES -m32 OR CMAKE_CXX_FLAGS MATCHES -m32)
SET(X86_64 1)
ENDIF(CMAKE_C_FLAGS MATCHES -m32 OR CMAKE_CXX_FLAGS MATCHES -m32)
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES i686.*|i386.*|x86.* OR WIN32)
IF(CMAKE_C_FLAGS MATCHES -m64 OR CMAKE_CXX_FLAGS MATCHES -m64)
SET(X86_64 1)
ELSE(CMAKE_C_FLAGS MATCHES -m64 OR CMAKE_CXX_FLAGS MATCHES -m64)
SET(X86 1)
ENDIF(CMAKE_C_FLAGS MATCHES -m64 OR CMAKE_CXX_FLAGS MATCHES -m64)
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES arm.* AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
SET(ARM 1)
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES mips)
SET(MIPS 1)
ENDIF()
IF ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
# using Clang
SET(CLANG 1)
ELSEIF ("${CMAKE_C_COMPILER_ID}" STREQUAL "TinyCC")
# using TinyCC
SET(TINYCC 1)
ELSEIF ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
# using GCC
SET(GCC 1)
ELSEIF ("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel")
# using Intel C++
SET(INTELCC 1)
ELSEIF ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
# using Visual Studio C++
SET(MSVC 1)
ELSEIF ("${CMAKE_C_COMPILER_ID}" STREQUAL "MIPSpro")
# using SGI MIPSpro
SET(MIPSPRO 1)
ENDIF()

View File

@@ -0,0 +1,74 @@
# Try to find AAX (AeonWave)
# This module defines
#
# AAX_FOUND - if false, do not try to link to AAX
# AAX_INCLUDE_DIR - where to find the headers
# AAX_LIBRARIES - Link these to use AAX
#
# Copyright (C) 2016-2018 by Erik Hofman.
# Copyright (C) 2016-2018 by Adalin B.V.
#
# $AAXDIR is an environment variable that would
# correspond to the ./configure --prefix=$AAXDIR
# used in building AAX.
#
# This file is Public Domain (www.unlicense.org)
# This is free and unencumbered software released into the public domain.
if (AAX_LIBRARY AND AAX_INCLUDE_DIR)
# in cache already
set(AAX_FOUND TRUE)
else()
find_path(AAX_INCLUDE_DIR aax/aax.h
HINTS
$ENV{AAXDIR}
$ENV{ProgramFiles}/aax
$ENV{ProgramFiles}/AeonWave
$ENV{ProgramFiles}/Adalin/AeonWave
${CMAKE_SOURCE_DIR}/aax
PATH_SUFFIXES include
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
find_library(AAX_LIBRARY
NAMES AAX aax libAAX
HINTS
$ENV{AAXDIR}
$ENV{ProgramFiles}/AAX
$ENV{ProgramFiles}/AeonWave
$ENV{ProgramFiles}/Adalin/AeonWave
${CMAKE_BUILD_DIR}/aax
PATH_SUFFIXES lib64 lib lib/${CMAKE_LIBRARY_ARCHITECTURE} libs64 libs libs/Win32 libs/Win64 bin
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
set(AAX_DEFINITIONS "")
if (AAX_LIBRARY AND AAX_INCLUDE_DIR)
set(AAX_FOUND TRUE)
endif()
if (AAX_FOUND)
if (NOT Udns_FIND_QUIETLY)
message(STATUS "Found AeonWave: ${AAX_LIBRARIES}")
endif ()
else ()
if (Udns_FIND_REQUIRED)
message(FATAL_ERROR "Could not find AeonWave")
endif ()
endif ()
# show the AAX_INCLUDE_DIRS and AAX_LIBRARIES variables only in the advanced view
mark_as_advanced(AAX_INCLUDE_DIRS AAX_LIBRARIES)
endif()

View File

@@ -0,0 +1,42 @@
# - Try to find UDNS library
# Once done this will define
#
# UDNS_FOUND - system has UDNS
# UDNS_INCLUDE_DIRS - the UDNS include directory
# UDNS_LIBRARIES - Link these to use UDNS
# UDNS_DEFINITIONS - Compiler switches required for using UDNS
#
# Copyright (c) 2016 Maciej Mrozowski <reavertm@gmail.com>
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if (UDNS_LIBRARIES AND UDNS_INCLUDE_DIRS)
# in cache already
set(UDNS_FOUND TRUE)
else ()
set(UDNS_DEFINITIONS "")
find_path(UDNS_INCLUDE_DIRS NAMES udns.h)
find_library(UDNS_LIBRARIES NAMES udns)
if (UDNS_INCLUDE_DIRS AND UDNS_LIBRARIES)
set(UDNS_FOUND TRUE)
endif ()
if (UDNS_FOUND)
if (NOT Udns_FIND_QUIETLY)
message(STATUS "Found UDNS: ${UDNS_LIBRARIES}")
endif ()
else ()
if (Udns_FIND_REQUIRED)
message(FATAL_ERROR "Could not find UDNS")
endif ()
endif ()
# show the UDNS_INCLUDE_DIRS and UDNS_LIBRARIES variables only in the advanced view
mark_as_advanced(UDNS_INCLUDE_DIRS UDNS_LIBRARIES)
endif ()

View File

@@ -12,6 +12,11 @@ macro(simgear_component_common name includePath sourcesList sources headers)
set_property(GLOBAL
APPEND PROPERTY PUBLIC_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${h}")
set(fh${sourcesList} "${fh${sourcesList}}#${CMAKE_CURRENT_SOURCE_DIR}/${h}")
# also append headers to the sources list, so that IDEs find the files
# correctly (otherwise they are not in the project)
set_property(GLOBAL
APPEND PROPERTY ${sourcesList} "${CMAKE_CURRENT_SOURCE_DIR}/${h}")
endforeach()
set_property(GLOBAL APPEND PROPERTY FG_GROUPS_${sourcesList}_C "${fc${sourcesList}}@")

View File

@@ -2,6 +2,10 @@
documentation. It has a .cxx extension so that emacs will happily
autoindent correctly. */
/**
* \namespace simgear
* \brief \ref index "SimGear" main namespace.
*/
/** \mainpage SimGear
* Simulation, Visualization, and Game development libraries.

View File

@@ -1,20 +0,0 @@
[This file is mirrored in both the FlightGear and SimGear packages.]
You *must* have the development components of OpenAL installed on your system
to build FlightGear!" You can get a copy here:
http://connect.creativelabs.com/openal/default.aspx
Build notes:
You can download a versioned release of the openal library from
http://www.openal.org/downloads.html. Download the openal source,
release 0.0.8 (dated February 11, 2006) and run:
tar xjvf openal-soft-1.5.304.tar.bz2
cd openal-soft-1.5.304/
ccmake .
[ While running ccmake: press 'c' to configure, press 'c' once more, and
then press 'g' to generate and exit ]

39
README.sound Normal file
View File

@@ -0,0 +1,39 @@
[This file is mirrored in both the FlightGear and SimGear packages.]
For Sound support FlightGear requires one of the two following packages:
- OpenAL
- AeonWave
== OpenAL ===
You *must* have the development components of OpenAL installed on your system
to build FlightGear!" You can get a copy here:
http://connect.creativelabs.com/openal/default.aspx
Build notes:
You can download a versioned release of the openal library from
http://www.openal.org/downloads.html. Download the openal source,
release 0.0.8 (dated February 11, 2006) and run:
tar xjvf openal-soft-1.5.304.tar.bz2
cd openal-soft-1.5.304/
ccmake .
[ While running ccmake: press 'c' to configure, press 'c' once more, and
then press 'g' to generate and exit ]
== AeonWave ===
For FlightGear AeonWave has a number of advantages over OpenAL:
* Correct Doppler effect behavior
* Default distance attenuation frequency filtering
* Native support for 29 types of audio formats.
* Native support for wav, mp3, vorbis and raw file formats.
The source code of AeonWave can be found on GitHub:
https://github.com/adalinbv
Optimized binary packages are available at:
http://www.adalin.com/

View File

@@ -1,76 +0,0 @@
%define ver @VERSION@
%define rel 1
%define prefix /usr
Summary: Simulator Construction Gear.
Name: @PACKAGE@
Version: %ver
Release: %rel
Copyright: LGPL
Group: Libraries/Graphics
Source: %{name}-%{version}.tar.gz
#URL:
BuildRoot: /tmp/%{name}-%{version}-%{rel}-root
Packager: Fill In As You Wish
Docdir: %{prefix}/doc
%description
This package contains a tools and libraries useful for constructing
simulation and visualization applications such as FlightGear or TerraGear.
Authors:
N/A
%prep
%setup -n %{name}-%{version}
%build
# Needed for snapshot releases.
if [ ! -f configure ]; then
CFLAGS="$RPM_OPT_FLAGS" ./autogen.sh --prefix=%prefix
else
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix
fi
if [ "$SMP" != "" ]; then
JSMP = '"MAKE=make -k -j $SMP"'
fi
make ${JSMP};
%install
[ -d ${RPM_BUILD_ROOT} ] && rm -rf ${RPM_BUILD_ROOT}
make prefix=${RPM_BUILD_ROOT}%{prefix} install
#
# Generating file lists and store them in file-lists
# Starting with the directory listings
#
find ${RPM_BUILD_ROOT}%{prefix}/{bin,include,lib} -type d | sed "s#^${RPM_BUILD_ROOT}#\%attr (-\,root\,root) \%dir #" > file-lists
%{?ETCDR:find ${RPM_BUILD_ROOT}%{!?SYSCF:%{prefix}}/etc -type d | sed "s#^${RPM_BUILD_ROOT}#\%attr (-\,root\,root) \%dir #" >> file-lists}
#
# Then, the file listings
#
echo "%defattr (-, root, root)" >> file-lists
%{?ETCDR:find ${RPM_BUILD_ROOT}%{!?SYSCF:%{prefix}}/etc/%{name}.conf -type f | sed -e "s#^${RPM_BUILD_ROOT}#%config #g" >> file-lists}
find ${RPM_BUILD_ROOT}%{prefix} -type f | sed -e "s#^${RPM_BUILD_ROOT}##g" >> file-lists
%clean
(cd ..; rm -rf %{name}-%{version} ${RPM_BUILD_ROOT})
%files -f file-lists
%defattr (-, root, root)
%doc AUTHORS
%doc COPYING
%doc ChangeLog
%doc INSTALL
%doc NEWS
%doc README
%doc %{name}.spec.in

View File

@@ -7,10 +7,20 @@ find_dependency(Threads)
set(SIMGEAR_HEADLESS @SIMGEAR_HEADLESS@)
set(SIMGEAR_SOUND @ENABLE_SOUND@)
set(USE_AEONWAVE @USE_AEONWAVE@)
# OpenAL isn't a public dependency, so maybe not needed
#if (SIMGEAR_SOUND)
# find_dependency(OpenAL)
#endif()
# SSE/SSE2 support
set(ENABLE_SIMD @ENABLE_SIMD@)
# Alternative terrain engine based on pagedLOD
set(ENABLE_GDAL @ENABLE_GDAL@)
set(ENABLE_OPENMP @ENABLE_OPENMP@)
include("${CMAKE_CURRENT_LIST_DIR}/SimGearTargets.cmake")

View File

@@ -1,13 +0,0 @@
Building a SimGear RPM package for Red Hat
Please see the "package/openSUSE" directory for an
example how to build a SimGear RPM package with
shared SimGear libraries.
You may need to adapt the names (exact spelling) of some
of the package dependencies in the openSUSE RPM spec,
since these may slightly differ for Red Hat.
(If you have a working and tested Red Hat RPM spec,
you're welcome to contribute it to this project.)

View File

@@ -1,23 +0,0 @@
Building a SimGear RPM package for openSUSE
(Last tested with openSUSE 11.4+12.1)
This directory contains the files which, along with
the source code tar files, can be used to build
an RPM package targeted at an openSUSE Linux system.
To build SimGear from source do the following:
1. obtain simgear-2.8.0.tar.bz2 (adapt version if
necessary) and copy it into ~/rpmbuild/SOURCES
2. look in the BuildRequires section of SimGear.spec
and check that all the packages referred to are
installed (note, some of these packages may be part
of openSUSE's "games" repository).
3. run 'rpmbuild -ba simgear.spec' and find the RPM
build result in ~/rpmbuild/RPMS
That's all!

View File

@@ -1,63 +0,0 @@
Summary: Simulator Construction Gear
Name: SimGear
Version: 2.8.0
Release: 1
License: LGPL
URL: http://www.flightgear.org
Group: Amusements/Games/3D/Simulation
Source: http://mirrors.ibiblio.org/pub/mirrors/flightgear/ftp/Source/simgear-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: gcc, gcc-c++, cmake
BuildRequires: libopenal1-soft, openal-soft
BuildRequires: libOpenSceneGraph-devel >= 3.0
BuildRequires: zlib, zlib-devel
BuildRequires: libjpeg62, libjpeg62-devel
BuildRequires: boost-devel >= 1.37
BuildRequires: subversion-devel, libapr1-devel
Requires: OpenSceneGraph-plugins >= 3.0
%description
This package contains a tools and libraries useful for constructing
simulation and visualization applications such as FlightGear or TerraGear.
%package devel
Group: Development/Libraries/Other
Summary: Development header files for SimGear
Requires: SimGear = %{version}
%description devel
Development headers and libraries for building applications against SimGear.
%prep
%setup -T -q -n simgear-%{version} -b 0
%build
export CFLAGS="$RPM_OPT_FLAGS"
export CXXFLAGS="$RPM_OPT_FLAGS"
# build SHARED simgear libraries
cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -DSIMGEAR_SHARED:BOOL=ON -DENABLE_TESTS:BOOL=OFF -DJPEG_FACTORY:BOOL=ON
make %{?_smp_mflags}
%install
make DESTDIR=%{buildroot} install
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr (-, root, root, -)
%doc AUTHORS COPYING ChangeLog NEWS README
%{_libdir}/libSimGear*.so.*
%files devel
%defattr(-,root,root,-)
%dir %{_includedir}/simgear
%{_includedir}/simgear/*
%{_libdir}/libSimGear*.so
%changelog
* Mon Jul 02 2012 thorstenb@flightgear.org
- Initial version

View File

@@ -5,6 +5,7 @@ foreach( mylibfolder
bucket
bvh
debug
embedded_resources
ephemeris
io
magvar
@@ -14,6 +15,7 @@ foreach( mylibfolder
nasal/cppbind
props
serial
std
structure
threads
timing
@@ -54,24 +56,14 @@ if(SIMGEAR_SHARED)
set_property(TARGET SimGearCore PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET SimGearCore PROPERTY VERSION ${SIMGEAR_VERSION})
set_property(TARGET SimGearCore PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
install(TARGETS SimGearCore
EXPORT SimGearTargets
LIBRARY DESTINATION
${CMAKE_INSTALL_LIBDIR})
if(NOT SIMGEAR_HEADLESS)
add_library(SimGearScene SHARED ${sceneSources})
set_property(TARGET SimGearScene PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET SimGearScene PROPERTY VERSION ${SIMGEAR_VERSION})
set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
# EXPORT SimGearSceneConfig
install(TARGETS SimGearScene
EXPORT SimGearTargets
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR} )
endif()
else()
message(STATUS "Library building mode: STATIC LIBRARIES")
@@ -94,9 +86,6 @@ else()
endforeach()
add_library(SimGearCore STATIC ${coreSources} ${localExpatSources})
install(TARGETS SimGearCore
EXPORT SimGearTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(NOT SIMGEAR_HEADLESS)
get_property(FG_GROUPS_SCENE_SOURCES_C GLOBAL PROPERTY FG_GROUPS_SCENE_SOURCES_C)
@@ -118,22 +107,65 @@ else()
endforeach()
add_library(SimGearScene STATIC ${sceneSources})
install(TARGETS SimGearScene
EXPORT SimGearTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(NOT SIMGEAR_HEADLESS)
endif(SIMGEAR_SHARED)
target_include_directories(SimGearCore BEFORE PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
target_include_directories(SimGearCore PUBLIC
${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR})
target_include_directories(SimGearCore PRIVATE
${EXPAT_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS})
install(TARGETS SimGearCore
EXPORT SimGearTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if (NOT SIMGEAR_HEADLESS)
install(TARGETS SimGearScene
EXPORT SimGearTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
target_include_directories(SimGearScene BEFORE PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
target_include_directories(SimGearScene PUBLIC ${OPENSCENEGRAPH_INCLUDE_DIRS})
if (USE_AEONWAVE)
target_include_directories(SimGearScene PRIVATE ${AAX_INCLUDE_DIR} )
else()
target_include_directories(SimGearScene PRIVATE ${OPENAL_INCLUDE_DIR} )
endif()
endif()
target_link_libraries(SimGearCore
${ZLIB_LIBRARY}
${RT_LIBRARY}
${DL_LIBRARY}
${EXPAT_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${COCOA_LIBRARY}
${CURL_LIBRARIES})
${CURL_LIBRARIES}
${WINSOCK_LIBRARY})
if(SYSTEM_EXPAT)
target_link_libraries(SimGearCore
${EXPAT_LIBRARIES})
endif()
if(ENABLE_DNS AND SYSTEM_UDNS)
target_link_libraries(SimGearCore
${UDNS_LIBRARIES})
endif()
if(NOT SIMGEAR_HEADLESS)
target_include_directories(SimGearScene PRIVATE ${PROJECT_SOURCE_DIR}/simgear/canvas/ShivaVG/include)
target_link_libraries(SimGearScene
SimGearCore
${ZLIB_LIBRARY}
@@ -141,6 +173,14 @@ if(NOT SIMGEAR_HEADLESS)
${OPENAL_LIBRARY}
${OPENGL_LIBRARY}
${JPEG_LIBRARY})
if(ENABLE_GDAL)
target_link_libraries(SimGearScene
${GDAL_LIBRARIES})
endif()
# only actually needed by canvas/KeyboardEvent.cxx
target_include_directories(SimGearScene PRIVATE ${PROJECT_SOURCE_DIR}/3rdparty/utf8/source)
endif()
if(ENABLE_RTI)

View File

@@ -227,9 +227,7 @@ std::string SGBucket::gen_base_path() const {
hem, top_lon, pole, top_lat,
hem, main_lon, pole, main_lat);
SGPath path( raw_path );
return path.str();
return raw_path;
}
@@ -286,6 +284,54 @@ double SGBucket::get_height_m() const {
return SG_BUCKET_SPAN * degree_height;
}
unsigned int SGBucket::siblings( int dx, int dy, std::vector<SGBucket>& buckets ) const
{
if (!isValid()) {
SG_LOG(SG_TERRAIN, SG_WARN, "SGBucket::sibling: requesting sibling of invalid bucket");
return 0;
}
double src_span = sg_bucket_span( get_center_lat() );
double clat = get_center_lat() + dy * SG_BUCKET_SPAN;
// return invalid here instead of clipping, so callers can discard
// invalid buckets without having to check if it's an existing one
if ((clat < -90.0) || (clat > 90.0)) {
return 0;
}
// find the lon span for the new latitude
double trg_span = sg_bucket_span( clat );
// if target span < src_span, return multiple buckets...
if ( trg_span < src_span ) {
// calc center longitude of westernmost sibling
double start_lon = get_center_lat() - src_span/2 + trg_span/2;
unsigned int num_buckets = src_span/trg_span;
for ( unsigned int x = 0; x < num_buckets; x++ ) {
double tmp = start_lon + x * trg_span;
tmp = SGMiscd::normalizePeriodic(-180.0, 180.0, tmp);
SGBucket b;
b.innerSet(tmp, clat);
buckets.push_back( b );
}
} else {
// just return the single sibling
double tmp = get_center_lon() + dx * trg_span;
tmp = SGMiscd::normalizePeriodic(-180.0, 180.0, tmp);
SGBucket b;
b.innerSet(tmp, clat);
buckets.push_back( b );
}
return buckets.size();
}
SGBucket SGBucket::sibling(int dx, int dy) const
{
if (!isValid()) {

View File

@@ -288,6 +288,11 @@ public:
*/
SGBucket sibling(int dx, int dy) const;
/**
* @return multiple buckets offset from this by dx,dy
*/
unsigned int siblings(int dz, int dy, std::vector<SGBucket>& buckets) const;
// friends
friend std::ostream& operator<< ( std::ostream&, const SGBucket& );

View File

@@ -35,124 +35,152 @@ using std::endl;
void testBucketSpans()
{
COMPARE(sg_bucket_span(0.0), 0.125);
COMPARE(sg_bucket_span(-20), 0.125);
COMPARE(sg_bucket_span(-40), 0.25);
COMPARE(sg_bucket_span(89.9), 12.0);
COMPARE(sg_bucket_span(88.1), 4.0);
COMPARE(sg_bucket_span(-89.9), 12.0);
SG_CHECK_EQUAL(sg_bucket_span(0.0), 0.125);
SG_CHECK_EQUAL(sg_bucket_span(-20), 0.125);
SG_CHECK_EQUAL(sg_bucket_span(-40), 0.25);
SG_CHECK_EQUAL(sg_bucket_span(89.9), 12.0);
SG_CHECK_EQUAL(sg_bucket_span(88.1), 4.0);
SG_CHECK_EQUAL(sg_bucket_span(-89.9), 12.0);
}
void testBasic()
{
SGBucket b1(5.1, 55.05);
COMPARE(b1.get_chunk_lon(), 5);
COMPARE(b1.get_chunk_lat(), 55);
COMPARE(b1.get_x(), 0);
COMPARE(b1.get_y(), 0);
COMPARE(b1.gen_index(), 3040320);
COMPARE(b1.gen_base_path(), "e000n50/e005n55");
VERIFY(b1.isValid());
SG_CHECK_EQUAL(b1.get_chunk_lon(), 5);
SG_CHECK_EQUAL(b1.get_chunk_lat(), 55);
SG_CHECK_EQUAL(b1.get_x(), 0);
SG_CHECK_EQUAL(b1.get_y(), 0);
SG_CHECK_EQUAL(b1.gen_index(), 3040320);
SG_CHECK_EQUAL(b1.gen_base_path(), "e000n50/e005n55");
SG_VERIFY(b1.isValid());
SGBucket b2(-10.1, -43.8);
COMPARE(b2.get_chunk_lon(), -11);
COMPARE(b2.get_chunk_lat(), -44);
COMPARE(b2.get_x(), 3);
COMPARE(b2.get_y(), 1); // latitude chunks numbered bottom to top, it seems
COMPARE(b2.gen_base_path(), "w020s50/w011s44");
VERIFY(b2.isValid());
SG_CHECK_EQUAL(b2.get_chunk_lon(), -11);
SG_CHECK_EQUAL(b2.get_chunk_lat(), -44);
SG_CHECK_EQUAL(b2.get_x(), 3);
// Latitude chunks numbered bottom to top, it seems
SG_CHECK_EQUAL(b2.get_y(), 1);
SG_CHECK_EQUAL(b2.gen_base_path(), "w020s50/w011s44");
SG_VERIFY(b2.isValid());
SGBucket b3(123.48, 9.01);
COMPARE(b3.get_chunk_lon(), 123);
COMPARE(b3.get_chunk_lat(), 9);
COMPARE(b3.get_x(), 3);
COMPARE(b3.get_y(), 0);
COMPARE(b3.gen_base_path(), "e120n00/e123n09");
VERIFY(b3.isValid());
SG_CHECK_EQUAL(b3.get_chunk_lon(), 123);
SG_CHECK_EQUAL(b3.get_chunk_lat(), 9);
SG_CHECK_EQUAL(b3.get_x(), 3);
SG_CHECK_EQUAL(b3.get_y(), 0);
SG_CHECK_EQUAL(b3.gen_base_path(), "e120n00/e123n09");
SG_VERIFY(b3.isValid());
SGBucket defBuck;
VERIFY(!defBuck.isValid());
SG_VERIFY(!defBuck.isValid());
b3.make_bad();
VERIFY(!b3.isValid());
SG_VERIFY(!b3.isValid());
SGBucket atAntiMeridian(180.0, 12.3);
VERIFY(atAntiMeridian.isValid());
COMPARE(atAntiMeridian.get_chunk_lon(), -180);
COMPARE(atAntiMeridian.get_x(), 0);
SG_VERIFY(atAntiMeridian.isValid());
SG_CHECK_EQUAL(atAntiMeridian.get_chunk_lon(), -180);
SG_CHECK_EQUAL(atAntiMeridian.get_x(), 0);
SGBucket atAntiMeridian2(-180.0, -78.1);
VERIFY(atAntiMeridian2.isValid());
COMPARE(atAntiMeridian2.get_chunk_lon(), -180);
COMPARE(atAntiMeridian2.get_x(), 0);
// check comparisom operator overload
SG_VERIFY(atAntiMeridian2.isValid());
SG_CHECK_EQUAL(atAntiMeridian2.get_chunk_lon(), -180);
SG_CHECK_EQUAL(atAntiMeridian2.get_x(), 0);
// check comparison operator overload
SGBucket b4(5.11, 55.1);
VERIFY(b1 == b4); // should be equal
VERIFY(b1 == b1);
VERIFY(b1 != defBuck);
VERIFY(b1 != b2);
// check wrapping/clipping of inputs
SG_VERIFY(b1 == b4); // should be equal
SG_VERIFY(b1 == b1);
SG_VERIFY(b1 != defBuck);
SG_VERIFY(b1 != b2);
// check wrapping/clipping of inputs
SGBucket wrapMeridian(-200.0, 45.0);
COMPARE(wrapMeridian.get_chunk_lon(), 160);
SG_CHECK_EQUAL(wrapMeridian.get_chunk_lon(), 160);
SGBucket clipPole(48.9, 91);
COMPARE(clipPole.get_chunk_lat(), 89);
SG_CHECK_EQUAL(clipPole.get_chunk_lat(), 89);
// test override of a bucket's geod
auto geod = SGGeod::fromDegFt(-86.678, 36.1248, 599.0);
#ifndef NO_DEPRECATED_API
SGBucket bna_airport;
bna_airport.set_bucket(geod);
#else
SGBucket bna_airport(geod);
#endif
SG_VERIFY(bna_airport.isValid());
SG_CHECK_EQUAL(bna_airport.get_chunk_lon(), -87); // left origin of the 1-degree chunk
SG_CHECK_EQUAL(bna_airport.get_chunk_lat(), 36); // bottom origin of the 1-degree chunk
SG_CHECK_EQUAL(bna_airport.get_x(), 1); // buckets are 0.25 deg wide at the W87 parallel
// we're 0.322 deg from the origin (second bucket)
SG_CHECK_EQUAL(bna_airport.get_y(), 0); // buckets are always 0.125 deg tall
// we're 0.1248 deg from the origin (first bucket)
SG_CHECK_EQUAL(bna_airport.gen_base_path(), "w090n30/w087n36");
SG_CHECK_EQUAL_EP2(bna_airport.get_width_m(), 22479.1, 0.1);
SG_CHECK_EQUAL_EP2(bna_airport.get_height_m(), 13914.9, 0.1);
SG_CHECK_EQUAL(bna_airport.gen_index_str(), "1531777"); // 0x175F81 = b01011101|01111110|000|001
// = 93-180 | 126-90 | 0 | 1
// = -87 | 36 | 0 | 1
// test stream output
cout << "[TEST] BNA Airport: " << bna_airport << endl;
auto center = bna_airport.get_center();
cout << "[TEST] BNA lon: " << center.getLongitudeDeg() << endl;
cout << "[TEST] BNA lat: " << center.getLatitudeDeg() << endl;
}
void testPolar()
{
SGBucket b1(0.0, 89.92);
SGBucket b2(10.0, 89.96);
COMPARE(b1.get_chunk_lat(), 89);
COMPARE(b1.get_chunk_lon(), 0);
COMPARE(b1.get_x(), 0);
COMPARE(b1.get_y(), 7);
COMPARE_EP(b1.get_highest_lat(), 90.0);
COMPARE_EP(b1.get_width_m(), 10.0);
COMPARE(b2.get_chunk_lat(), 89);
COMPARE(b2.get_chunk_lon(), 0);
COMPARE(b2.get_x(), 0);
COMPARE(b2.get_y(), 7);
COMPARE(b1.gen_index(), b2.gen_index());
SG_CHECK_EQUAL(b1.get_chunk_lat(), 89);
SG_CHECK_EQUAL(b1.get_chunk_lon(), 0);
SG_CHECK_EQUAL(b1.get_x(), 0);
SG_CHECK_EQUAL(b1.get_y(), 7);
SG_CHECK_EQUAL_EP(b1.get_highest_lat(), 90.0);
SG_CHECK_EQUAL_EP(b1.get_width_m(), 10.0);
SG_CHECK_EQUAL(b2.get_chunk_lat(), 89);
SG_CHECK_EQUAL(b2.get_chunk_lon(), 0);
SG_CHECK_EQUAL(b2.get_x(), 0);
SG_CHECK_EQUAL(b2.get_y(), 7);
SG_CHECK_EQUAL(b1.gen_index(), b2.gen_index());
SGGeod actualNorthPole1 = b1.get_corner(2);
SGGeod actualNorthPole2 = b1.get_corner(3);
COMPARE_EP(actualNorthPole1.getLatitudeDeg(), 90.0);
COMPARE_EP(actualNorthPole1.getLongitudeDeg(), 12.0);
COMPARE_EP(actualNorthPole2.getLatitudeDeg(), 90.0);
COMPARE_EP(actualNorthPole2.getLongitudeDeg(), 0.0);
SG_CHECK_EQUAL_EP(actualNorthPole1.getLatitudeDeg(), 90.0);
SG_CHECK_EQUAL_EP(actualNorthPole1.getLongitudeDeg(), 12.0);
SG_CHECK_EQUAL_EP(actualNorthPole2.getLatitudeDeg(), 90.0);
SG_CHECK_EQUAL_EP(actualNorthPole2.getLongitudeDeg(), 0.0);
SGBucket b3(-2, 89.88);
SGBucket b4(-7, 89.88);
COMPARE(b3.gen_index(), b4.gen_index());
SG_CHECK_EQUAL(b3.gen_index(), b4.gen_index());
// south pole
SGBucket b5(-170, -89.88);
SGBucket b6(-179, -89.88);
COMPARE(b5.get_chunk_lat(), -90);
COMPARE(b5.get_chunk_lon(), -180);
COMPARE(b5.get_x(), 0);
COMPARE(b5.get_y(), 0);
COMPARE(b5.gen_index(), b6.gen_index());
COMPARE_EP(b5.get_highest_lat(), -90.0);
COMPARE_EP(b5.get_width_m(), 10.0);
SG_CHECK_EQUAL(b5.get_chunk_lat(), -90);
SG_CHECK_EQUAL(b5.get_chunk_lon(), -180);
SG_CHECK_EQUAL(b5.get_x(), 0);
SG_CHECK_EQUAL(b5.get_y(), 0);
SG_CHECK_EQUAL(b5.gen_index(), b6.gen_index());
SG_CHECK_EQUAL_EP(b5.get_highest_lat(), -90.0);
SG_CHECK_EQUAL_EP(b5.get_width_m(), 10.0);
SGGeod actualSouthPole1 = b5.get_corner(0);
SGGeod actualSouthPole2 = b5.get_corner(1);
COMPARE_EP(actualSouthPole1.getLatitudeDeg(), -90.0);
COMPARE_EP(actualSouthPole1.getLongitudeDeg(), -180);
COMPARE_EP(actualSouthPole2.getLatitudeDeg(), -90.0);
COMPARE_EP(actualSouthPole2.getLongitudeDeg(), -168);
SGBucket b7(200, 89.88);
COMPARE(b7.get_chunk_lon(), -168);
SG_CHECK_EQUAL_EP(actualSouthPole1.getLatitudeDeg(), -90.0);
SG_CHECK_EQUAL_EP(actualSouthPole1.getLongitudeDeg(), -180);
SG_CHECK_EQUAL_EP(actualSouthPole2.getLatitudeDeg(), -90.0);
SG_CHECK_EQUAL_EP(actualSouthPole2.getLongitudeDeg(), -168);
SGBucket b7(200, 89.88);
SG_CHECK_EQUAL(b7.get_chunk_lon(), -168);
}
// test the tiles just below the pole (between 86 & 89 degrees N/S)
@@ -160,15 +188,15 @@ void testNearPolar()
{
SGBucket b1(1, 88.5);
SGBucket b2(-1, 88.8);
COMPARE(b1.get_chunk_lon(), 0);
COMPARE(b1.get_chunk_lat(), 88);
VERIFY(b1.gen_index() != b2.gen_index());
SG_CHECK_EQUAL(b1.get_chunk_lon(), 0);
SG_CHECK_EQUAL(b1.get_chunk_lat(), 88);
SG_VERIFY(b1.gen_index() != b2.gen_index());
SGBucket b3(176.1, 88.5);
COMPARE(b3.get_chunk_lon(), 176);
SG_CHECK_EQUAL(b3.get_chunk_lon(), 176);
SGBucket b4(-178, 88.5);
COMPARE(b4.get_chunk_lon(), -180);
SG_CHECK_EQUAL(b4.get_chunk_lon(), -180);
}
void testOffset()
@@ -176,74 +204,74 @@ void testOffset()
// bucket just below the 22 degree cutoff, so the next tile north
// is twice the width
SGBucket b1(-59.8, 21.9);
COMPARE(b1.get_chunk_lat(), 21);
COMPARE(b1.get_chunk_lon(), -60);
COMPARE(b1.get_x(), 1);
COMPARE(b1.get_y(), 7);
SG_CHECK_EQUAL(b1.get_chunk_lat(), 21);
SG_CHECK_EQUAL(b1.get_chunk_lon(), -60);
SG_CHECK_EQUAL(b1.get_x(), 1);
SG_CHECK_EQUAL(b1.get_y(), 7);
// offset vertically
SGBucket b2(b1.sibling(0, 1));
COMPARE(b2.get_chunk_lat(), 22);
COMPARE(b2.get_chunk_lon(), -60);
COMPARE(b2.get_x(), 0);
COMPARE(b2.get_y(), 0);
SG_CHECK_EQUAL(b2.get_chunk_lat(), 22);
SG_CHECK_EQUAL(b2.get_chunk_lon(), -60);
SG_CHECK_EQUAL(b2.get_x(), 0);
SG_CHECK_EQUAL(b2.get_y(), 0);
SG_CHECK_EQUAL(b2.gen_index(), sgBucketOffset(-59.8, 21.9, 0, 1));
COMPARE(b2.gen_index(), sgBucketOffset(-59.8, 21.9, 0, 1));
// offset vertically and horizontally. We compute horizontal (x)
// movement at the target latitude, so this should move 0.25 * -3 degrees,
// NOT 0.125 * -3 degrees.
SGBucket b3(b1.sibling(-3, 1));
COMPARE(b3.get_chunk_lat(), 22);
COMPARE(b3.get_chunk_lon(), -61);
COMPARE(b3.get_x(), 1);
COMPARE(b3.get_y(), 0);
COMPARE(b3.gen_index(), sgBucketOffset(-59.8, 21.9, -3, 1));
SG_CHECK_EQUAL(b3.get_chunk_lat(), 22);
SG_CHECK_EQUAL(b3.get_chunk_lon(), -61);
SG_CHECK_EQUAL(b3.get_x(), 1);
SG_CHECK_EQUAL(b3.get_y(), 0);
SG_CHECK_EQUAL(b3.gen_index(), sgBucketOffset(-59.8, 21.9, -3, 1));
}
void testPolarOffset()
{
SGBucket b1(-11.7, -89.6);
COMPARE(b1.get_chunk_lat(), -90);
COMPARE(b1.get_chunk_lon(), -12);
COMPARE(b1.get_x(), 0);
COMPARE(b1.get_y(), 3);
SG_CHECK_EQUAL(b1.get_chunk_lat(), -90);
SG_CHECK_EQUAL(b1.get_chunk_lon(), -12);
SG_CHECK_EQUAL(b1.get_x(), 0);
SG_CHECK_EQUAL(b1.get_y(), 3);
// offset horizontally
SGBucket b2(b1.sibling(-2, 0));
COMPARE(b2.get_chunk_lat(), -90);
COMPARE(b2.get_chunk_lon(), -36);
COMPARE(b2.get_x(), 0);
COMPARE(b2.get_y(), 3);
COMPARE(b2.gen_index(), sgBucketOffset(-11.7, -89.6, -2, 0));
// offset and wrap
SG_CHECK_EQUAL(b2.get_chunk_lat(), -90);
SG_CHECK_EQUAL(b2.get_chunk_lon(), -36);
SG_CHECK_EQUAL(b2.get_x(), 0);
SG_CHECK_EQUAL(b2.get_y(), 3);
SG_CHECK_EQUAL(b2.gen_index(), sgBucketOffset(-11.7, -89.6, -2, 0));
// offset and wrap
SGBucket b3(-170, 89.1);
SGBucket b4(b3.sibling(-1, 0));
COMPARE(b4.get_chunk_lat(), 89);
COMPARE(b4.get_chunk_lon(), 168);
COMPARE(b4.get_x(), 0);
COMPARE(b4.get_y(), 0);
COMPARE(b4.gen_index(), sgBucketOffset(-170, 89.1, -1, 0));
SG_CHECK_EQUAL(b4.get_chunk_lat(), 89);
SG_CHECK_EQUAL(b4.get_chunk_lon(), 168);
SG_CHECK_EQUAL(b4.get_x(), 0);
SG_CHECK_EQUAL(b4.get_y(), 0);
SG_CHECK_EQUAL(b4.gen_index(), sgBucketOffset(-170, 89.1, -1, 0));
SGBucket b5(177, 87.3);
SGBucket b6(b5.sibling(1, 1));
COMPARE(b6.get_chunk_lat(), 87);
COMPARE(b6.get_chunk_lon(), -180);
COMPARE(b6.get_x(), 0);
COMPARE(b6.get_y(), 3);
COMPARE(b6.gen_index(), sgBucketOffset(177, 87.3, 1, 1));
SG_CHECK_EQUAL(b6.get_chunk_lat(), 87);
SG_CHECK_EQUAL(b6.get_chunk_lon(), -180);
SG_CHECK_EQUAL(b6.get_x(), 0);
SG_CHECK_EQUAL(b6.get_y(), 3);
SG_CHECK_EQUAL(b6.gen_index(), sgBucketOffset(177, 87.3, 1, 1));
// offset vertically towards the pole
SGBucket b7(b1.sibling(0, -5));
VERIFY(!b7.isValid());
VERIFY(!SGBucket(0, 90).sibling(0, 1).isValid());
SG_VERIFY(!b7.isValid());
SG_VERIFY(!SGBucket(0, 90).sibling(0, 1).isValid());
}
// test behaviour of bucket-offset near the anti-meridian (180-meridian)
@@ -251,33 +279,84 @@ void testOffsetWrap()
{
// near the equator
SGBucket b1(-179.8, 16.8);
COMPARE(b1.get_chunk_lat(), 16);
COMPARE(b1.get_chunk_lon(), -180);
COMPARE(b1.get_x(), 1);
COMPARE(b1.get_y(), 6);
SG_CHECK_EQUAL(b1.get_chunk_lat(), 16);
SG_CHECK_EQUAL(b1.get_chunk_lon(), -180);
SG_CHECK_EQUAL(b1.get_x(), 1);
SG_CHECK_EQUAL(b1.get_y(), 6);
SGBucket b2(b1.sibling(-2, 0));
COMPARE(b2.get_chunk_lat(), 16);
COMPARE(b2.get_chunk_lon(), 179);
COMPARE(b2.get_x(), 7);
COMPARE(b2.get_y(), 6);
COMPARE(b2.gen_index(), sgBucketOffset(-179.8, 16.8, -2, 0));
SG_CHECK_EQUAL(b2.get_chunk_lat(), 16);
SG_CHECK_EQUAL(b2.get_chunk_lon(), 179);
SG_CHECK_EQUAL(b2.get_x(), 7);
SG_CHECK_EQUAL(b2.get_y(), 6);
SG_CHECK_EQUAL(b2.gen_index(), sgBucketOffset(-179.8, 16.8, -2, 0));
}
void testSiblings()
{
SGBucket bna_airport(-86.678, 36.1248);
SG_VERIFY(bna_airport.isValid());
// retrieve the sibling two positions north-east of my position
auto sib1 = bna_airport.sibling(2, 2);
SG_CHECK_EQUAL(sib1.get_chunk_lon(), bna_airport.get_chunk_lon());
SG_CHECK_EQUAL(sib1.get_chunk_lat(), bna_airport.get_chunk_lat());
SG_CHECK_EQUAL(sib1.get_x(), 3); // my x-pos (1) + 2 = 3
SG_CHECK_EQUAL(sib1.get_y(), 2); // my y-pos (0) + 2 = 2
SG_CHECK_EQUAL(sib1.gen_base_path(), bna_airport.gen_base_path());
// retrieve the one sibling two positions to the north-east
std::vector<SGBucket> siblings;
bna_airport.siblings(2, 2, siblings);
SG_CHECK_EQUAL(siblings.size(), static_cast<std::vector<SGBucket>::size_type>(1));
siblings.clear();
// retrieve the one sibling at the chunk origin of sib1
sib1.siblings(-2, -2, siblings);
SG_CHECK_EQUAL(siblings.size(), static_cast<std::vector<SGBucket>::size_type>(1));
siblings.clear();
// calculate delta between two buckets
int dx = 0;
int dy = 0;
sgBucketDiff(bna_airport, sib1, &dx, &dy);
SG_CHECK_EQUAL(dx, 2);
SG_CHECK_EQUAL(dy, 2);
// retrieve all siblings between two geodetic locations
auto geod_bna = SGGeod::fromDegFt(-86.678, 36.1248, 599.0);
auto geod_m54 = SGGeod::fromDegFt(-86.317, 36.1908, 122.0);
sgGetBuckets(geod_bna, geod_m54, siblings);
SG_CHECK_EQUAL(siblings.size(), static_cast<std::vector<SGBucket>::size_type>(4));
siblings.clear();
// edge cases
// ensure you cannot retrieve the sibling of an invalid bucket
SGBucket bad;
auto bad_sib = bad.sibling(1, 1);
SG_CHECK_EQUAL(bad_sib.get_chunk_lon(), -1000);
SG_CHECK_EQUAL(bad.siblings(2, 2, siblings), 0);
// if we drop below the 22nd parallel, the bucket widths are half the size
// expect this to retrieve two buckets
bna_airport.siblings(0, -160, siblings);
SG_CHECK_EQUAL(siblings.size(), static_cast<std::vector<SGBucket>::size_type>(2));
siblings.clear();
}
int main(int argc, char* argv[])
{
testBucketSpans();
testBasic();
testPolar();
testNearPolar();
testOffset();
testOffsetWrap();
testPolarOffset();
testSiblings();
cout << "all tests passed OK" << endl;
return 0; // passed
}

View File

@@ -15,6 +15,8 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include <simgear_config.h>
#include "BVHMaterial.hxx"
namespace simgear {

View File

@@ -15,6 +15,8 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include <simgear_config.h>
#include "BVHPageNode.hxx"
#include "BVHPager.hxx"

View File

@@ -15,6 +15,8 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include <simgear_config.h>
#include "BVHPageRequest.hxx"
namespace simgear {

View File

@@ -15,6 +15,8 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include <simgear_config.h>
#include "BVHPager.hxx"
#include <list>

View File

@@ -15,6 +15,8 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include <simgear_config.h>
#include "BVHStaticNode.hxx"
namespace simgear {

View File

@@ -15,6 +15,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include <simgear_config.h>
#include <iostream>
#include <simgear/structure/SGSharedPtr.hxx>

View File

@@ -1,4 +1,5 @@
// The canvas for rendering with the 2d API
///@file
/// The canvas for rendering with the 2d API
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -16,12 +17,16 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "Canvas.hxx"
#include "CanvasEventManager.hxx"
#include "CanvasEventVisitor.hxx"
#include "CanvasPlacement.hxx"
#include <simgear/canvas/events/KeyboardEvent.hxx>
#include <simgear/canvas/events/MouseEvent.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/scene/util/parse_color.hxx>
#include <simgear/scene/util/RenderConstants.hxx>
@@ -30,13 +35,79 @@
#include <osgText/Text>
#include <osgViewer/Viewer>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/foreach.hpp>
namespace simgear
{
namespace canvas
{
static int globalinstanceid = 1;
/**
* Camera Callback for moving completed canvas images to subscribed listener.
*/
class CanvasImageCallback : public osg::Camera::DrawCallback {
public:
osg::Image *_rawImage;
CanvasImageCallback(osg::Image *rawImage)
: _min_delta_tick(1.0 / 8.0) {
_previousFrameTick = osg::Timer::instance()->tick();
_rawImage = rawImage;
SG_LOG(SG_GENERAL,SG_INFO,"CanvasImageCallback created. instance is " << instanceid);
}
virtual void operator()(osg::RenderInfo& renderInfo) const {
osg::Timer_t n = osg::Timer::instance()->tick();
double dt = osg::Timer::instance()->delta_s(_previousFrameTick, n);
if (dt < _min_delta_tick)
return;
_previousFrameTick = n;
SG_LOG(SG_GENERAL,SG_DEBUG,"CanvasImageCallback " << instanceid << ": image available for " << _subscribers.size() << " subscribers. camera is " << renderInfo.getCurrentCamera());
bool hasSubscribers = false;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lock);
hasSubscribers = !_subscribers.empty();
}
if (hasSubscribers) {
//Make sure image can be overwritten by next frame while it is still returned to the client
osg::Image* image = new osg::Image(*_rawImage, osg::CopyOp::DEEP_COPY_ALL);
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lock);
while (!_subscribers.empty()) {
try {
CanvasImageReadyListener *subs = _subscribers.back();
if (subs){
subs->imageReady(image);
}else{
SG_LOG(SG_GENERAL,SG_WARN,"CanvasImageCallback subscriber null");
}
} catch (...) { }
_subscribers.pop_back();
}
}
}
}
void subscribe(CanvasImageReadyListener * subscriber) {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lock);
_subscribers.push_back(subscriber);
}
void unsubscribe(CanvasImageReadyListener * subscriber) {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lock);
_subscribers.remove(subscriber);
}
int getSubscriberCount() {
return _subscribers.size();
}
private:
mutable list<CanvasImageReadyListener*> _subscribers;
mutable OpenThreads::Mutex _lock;
mutable double _previousFrameTick;
double _min_delta_tick;
int instanceid = globalinstanceid++;
};
//----------------------------------------------------------------------------
Canvas::CullCallback::CullCallback(const CanvasWeakPtr& canvas):
@@ -62,18 +133,9 @@ namespace canvas
//----------------------------------------------------------------------------
Canvas::Canvas(SGPropertyNode* node):
PropertyBasedElement(node),
_canvas_mgr(0),
_event_manager(new EventManager),
_size_x(-1),
_size_y(-1),
_view_width(-1),
_view_height(-1),
_status(node, "status"),
_status_msg(node, "status-msg"),
_sampling_dirty(false),
_render_dirty(true),
_visible(true),
_render_always(false)
_status_msg(node, "status-msg")
{
_status = 0;
setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y);
@@ -234,6 +296,10 @@ namespace canvas
if( _status & STATUS_DIRTY )
{
// Retrieve reference here, to ensure the scene group is not deleted while
// creating the new texture and camera
osg::ref_ptr<osg::Group> root_scene_group = _root_group->getSceneGroup();
_texture.setSize(_size_x, _size_y);
if( !_texture.serviceable() )
@@ -251,6 +317,21 @@ namespace canvas
osg::Camera* camera = _texture.getCamera();
string canvasname = _node->getStringValue("name");
int renderToImage = _node->getBoolValue("render-to-image");
if (renderToImage){
CanvasImageCallback *_screenshotCallback = dynamic_cast<CanvasImageCallback*> (camera->getFinalDrawCallback());
if (!_screenshotCallback) {
// no draw callback yet
osg::Image* shot = new osg::Image();
shot->allocateImage(getSizeX(), getSizeY(), 24, GL_RGB, GL_UNSIGNED_BYTE);
camera->attach(osg::Camera::COLOR_BUFFER, shot);
camera->setFinalDrawCallback(new CanvasImageCallback(shot));
SG_LOG(SG_GENERAL,SG_INFO,"CanvasImage: attached image and draw callback to camera " << camera << " for canvas " << canvasname << ". Ready for subscriber now.");
}
}
// TODO Allow custom render order? For now just keep in order with
// property tree.
camera->setRenderOrder(osg::Camera::PRE_RENDER, _node->getIndex());
@@ -259,7 +340,7 @@ namespace canvas
parseColor(_node->getStringValue("background"), clear_color);
camera->setClearColor(clear_color);
camera->addChild(_root_group->getMatrixTransform());
camera->addChild(root_scene_group);
if( _texture.serviceable() )
{
@@ -279,7 +360,7 @@ namespace canvas
if( _visible || _render_always )
{
BOOST_FOREACH(CanvasWeakPtr canvas_weak, _child_canvases)
for(auto& canvas_weak: _child_canvases)
{
// TODO should we check if the image the child canvas is displayed
// within is really visible?
@@ -291,7 +372,7 @@ namespace canvas
if( _render_dirty )
{
// Also mark all canvases this canvas is displayed within as dirty
BOOST_FOREACH(CanvasWeakPtr canvas_weak, _parent_canvases)
for(auto& canvas_weak: _parent_canvases)
{
CanvasPtr canvas = canvas_weak.lock();
if( canvas )
@@ -350,6 +431,41 @@ namespace canvas
}
}
int Canvas::subscribe(CanvasImageReadyListener * subscriber) {
osg::Camera* camera = _texture.getCamera();
const string canvasname = _node->getStringValue("name");
SG_LOG(SG_GENERAL,SG_DEBUG,"CanvasImage: subscribe to canvas " << canvasname.c_str() << ", camera ="<< camera);
if (!_node->getBoolValue("render-to-image")) {
SG_LOG(SG_GENERAL,SG_INFO,"CanvasImage: Setting render-to-image");
_node->addChild("render-to-image", 0)->setBoolValue(1);
setStatusFlags(STATUS_DIRTY, true);
}
CanvasImageCallback *_screenshotCallback = dynamic_cast<CanvasImageCallback*> (camera->getFinalDrawCallback());
if (_screenshotCallback) {
// Camera ready for subscriber. Otherwise, draw callback is created by canvas thread later.
SG_LOG(SG_GENERAL,SG_DEBUG,"CanvasImage: adding subscriber to camera draw callback");
_screenshotCallback->subscribe(subscriber);
// TODO: check: Is this the correct way to ensure the canvas will be available?
enableRendering(true);
return 1;
}
return 0;
}
int Canvas::unsubscribe(CanvasImageReadyListener * subscriber) {
osg::Camera* camera = _texture.getCamera();
SG_LOG(SG_GENERAL,SG_DEBUG,"CanvasImage: unsubscribe");
CanvasImageCallback *cb = dynamic_cast<CanvasImageCallback*> (camera->getFinalDrawCallback());
if (cb) {
SG_LOG(SG_GENERAL,SG_DEBUG,"CanvasImage: unsubscribe from camera " << camera);
cb->unsubscribe(subscriber);
}
return 0;
}
//----------------------------------------------------------------------------
bool Canvas::addEventListener( const std::string& type,
const EventListener& cb )
@@ -520,8 +636,8 @@ namespace canvas
{
const std::string& name = node->getNameString();
if( boost::starts_with(name, "status")
|| boost::starts_with(name, "data-") )
if( strutils::starts_with(name, "status")
|| strutils::starts_with(name, "data-") )
return;
_render_dirty = true;
@@ -536,7 +652,7 @@ namespace canvas
if( !placements.empty() )
{
bool placement_dirty = false;
BOOST_FOREACH(PlacementPtr& placement, placements)
for(auto& placement: placements)
{
// check if change can be directly handled by placement
if( placement->getProps() == node->getParent()

View File

@@ -33,7 +33,7 @@
#include <osg/NodeCallback>
#include <osg/observer_ptr>
#include <boost/scoped_ptr.hpp>
#include <memory>
#include <string>
namespace simgear
@@ -44,6 +44,17 @@ namespace canvas
class CanvasMgr;
class MouseEvent;
/**
* A listener interested in completed canvas drawing.
*/
class CanvasImageReadyListener {
public:
virtual void imageReady(osg::ref_ptr<osg::Image>) = 0;
virtual ~CanvasImageReadyListener()
{
}
};
/**
* Canvas to draw onto (to an off-screen render target).
*/
@@ -71,18 +82,18 @@ namespace canvas
public osg::NodeCallback
{
public:
CullCallback(const CanvasWeakPtr& canvas);
explicit CullCallback(const CanvasWeakPtr& canvas);
private:
CanvasWeakPtr _canvas;
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
void operator()(osg::Node* node, osg::NodeVisitor* nv) override;
};
typedef osg::ref_ptr<CullCallback> CullCallbackPtr;
Canvas(SGPropertyNode* node);
explicit Canvas(SGPropertyNode* node);
virtual ~Canvas();
virtual void onDestroy();
void onDestroy() override;
void setCanvasMgr(CanvasMgr* canvas_mgr);
CanvasMgr* getCanvasMgr() const;
@@ -160,7 +171,12 @@ namespace canvas
*/
void enableRendering(bool force = false);
void update(double delta_time_sec);
void update(double delta_time_sec) override;
osg::Camera* getCamera();
int subscribe(CanvasImageReadyListener * subscriber);
int unsubscribe(CanvasImageReadyListener * subscriber);
int getSubscriberCount();
bool addEventListener(const std::string& type, const EventListener& cb);
bool dispatchEvent(const EventPtr& event);
@@ -184,11 +200,9 @@ namespace canvas
bool propagateEvent( EventPtr const& event,
EventPropagationPath const& path );
virtual void childAdded( SGPropertyNode * parent,
SGPropertyNode * child );
virtual void childRemoved( SGPropertyNode * parent,
SGPropertyNode * child );
virtual void valueChanged (SGPropertyNode * node);
void childAdded(SGPropertyNode* parent, SGPropertyNode* child) override;
void childRemoved(SGPropertyNode* parent, SGPropertyNode* child) override;
void valueChanged(SGPropertyNode * node) override;
osg::Texture2D* getTexture() const;
@@ -211,21 +225,21 @@ namespace canvas
protected:
CanvasMgr *_canvas_mgr;
CanvasMgr *_canvas_mgr {nullptr};
boost::scoped_ptr<EventManager> _event_manager;
std::unique_ptr<EventManager> _event_manager;
int _size_x,
_size_y,
_view_width,
_view_height;
int _size_x {-1},
_size_y {-1},
_view_width {-1},
_view_height {-1};
PropertyObject<int> _status;
PropertyObject<std::string> _status_msg;
bool _sampling_dirty,
_render_dirty,
_visible;
bool _sampling_dirty {false},
_render_dirty {true},
_visible {true};
ODGauge _texture;
@@ -235,7 +249,9 @@ namespace canvas
ElementWeakPtr _focus_element;
CullCallbackPtr _cull_callback;
bool _render_always; //!< Used to disable automatic lazy rendering (culling)
/** Used to disable automatic lazy rendering (culling) */
bool _render_always {false};
std::vector<SGPropertyNode*> _dirty_placements;
std::vector<Placements> _placements;
@@ -252,8 +268,8 @@ namespace canvas
static SystemAdapterPtr _system_adapter;
Canvas(const Canvas&); // = delete;
Canvas& operator=(const Canvas&); // = delete;
Canvas(const Canvas&) = delete;
Canvas& operator=(const Canvas&) = delete;
};
} // namespace canvas

View File

@@ -1,4 +1,5 @@
// Canvas Event for event model similar to DOM Level 3 Event Model
///@file
/// Canvas Event for event model similar to DOM Level 3 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -16,6 +17,8 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasEvent.hxx"
namespace simgear
@@ -123,10 +126,10 @@ namespace canvas
//----------------------------------------------------------------------------
std::string Event::typeToStr(int type)
{
TypeMap const& type_map = getTypeMap();
auto const& map_by_id = getTypeMap().by<id>();
TypeMap::map_by<id>::const_iterator it = type_map.by<id>().find(type);
if( it == type_map.by<id>().end() )
auto it = map_by_id.find(type);
if( it == map_by_id.end() )
return "unknown";
return it->second;
}

View File

@@ -65,6 +65,11 @@ namespace canvas
// of the actual event instances.
virtual ~Event();
/**
* Clone event and set to the given type (Same type if not specified)
*/
virtual Event* clone(int type = 0) const = 0;
/**
* Get whether this events support bubbling
*/
@@ -110,7 +115,14 @@ namespace canvas
*/
bool defaultPrevented() const;
/**
* Register a new type string or get the id of an existing type string
*
* @param type Type string
* @return Id of the given @a type
*/
static int getOrRegisterType(const std::string& type);
static int strToType(const std::string& type);
static std::string typeToStr(int type);

View File

@@ -1,4 +1,5 @@
// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
///@file
/// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -16,9 +17,12 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasEventManager.hxx"
#include <simgear/canvas/events/MouseEvent.hxx>
#include <simgear/canvas/elements/CanvasElement.hxx>
#include "elements/CanvasElement.hxx"
#include "events/MouseEvent.hxx"
#include <cmath>
namespace simgear
@@ -113,6 +117,8 @@ namespace canvas
return handled;
}
case Event::DRAG:
case Event::DRAG_START:
case Event::DRAG_END:
if( !_last_mouse_down.valid() )
return false;
else

View File

@@ -1,4 +1,5 @@
// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
///@file
/// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//

View File

@@ -1,4 +1,5 @@
// Mapping between canvas gui Event types and their names
///@file
/// Mapping between canvas gui Event types and their names
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -25,6 +26,8 @@ ENUM_MAPPING(MOUSE_UP, "mouseup", MouseEvent)
ENUM_MAPPING(CLICK, "click", MouseEvent)
ENUM_MAPPING(DBL_CLICK, "dblclick", MouseEvent)
ENUM_MAPPING(DRAG, "drag", MouseEvent)
ENUM_MAPPING(DRAG_START, "dragstart", MouseEvent)
ENUM_MAPPING(DRAG_END, "dragend", MouseEvent)
ENUM_MAPPING(WHEEL, "wheel", MouseEvent)
ENUM_MAPPING(MOUSE_MOVE, "mousemove", MouseEvent)
ENUM_MAPPING(MOUSE_OVER, "mouseover", MouseEvent)

View File

@@ -1,5 +1,6 @@
// Visitor for traversing a canvas element hierarchy similar to the traversal
// of the DOM Level 3 Event Model
///@file
/// Visitor for traversing a canvas element hierarchy similar to the traversal
/// of the DOM Level 3 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -17,9 +18,11 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasEvent.hxx"
#include "CanvasEventVisitor.hxx"
#include <simgear/canvas/elements/CanvasElement.hxx>
#include "elements/CanvasElement.hxx"
namespace simgear
{

View File

@@ -1,5 +1,6 @@
// Visitor for traversing a canvas element hierarchy similar to the traversal
// of the DOM Level 3 Event Model
///@file
/// Visitor for traversing a canvas element hierarchy similar to the traversal
/// of the DOM Level 3 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//

View File

@@ -1,4 +1,5 @@
// Canvas with 2D rendering API
///@file
/// Canvas with 2D rendering API
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -16,12 +17,12 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasMgr.hxx"
#include "Canvas.hxx"
#include "CanvasEventManager.hxx"
#include <boost/bind.hpp>
namespace simgear
{
namespace canvas

View File

@@ -1,4 +1,5 @@
// Canvas with 2D rendering API
///@file
/// Canvas with 2D rendering API
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -61,7 +62,7 @@ namespace canvas
protected:
virtual void elementCreated(PropertyBasedElementPtr element);
void elementCreated(PropertyBasedElementPtr element) override;
};
} // namespace canvas

View File

@@ -1,4 +1,5 @@
// Canvas placement for placing a canvas texture onto osg objects.
///@file
/// Canvas placement for placing a canvas texture onto osg objects
//
// It also provides a SGPickCallback for passing mouse events to the canvas and
// manages emissive lighting of the placed canvas.
@@ -19,6 +20,8 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "Canvas.hxx"
#include "CanvasObjectPlacement.hxx"
#include <simgear/canvas/events/MouseEvent.hxx>

View File

@@ -1,5 +1,5 @@
///@file
/// Placement for putting a canvas texture onto OpenSceneGraph objects.
/// Placement for putting a canvas texture onto OpenSceneGraph objects
///
/// It also provides a SGPickCallback for passing mouse events to the canvas and
/// manages emissive lighting of the placed canvas.
@@ -60,7 +60,7 @@ namespace canvas
*/
void setCaptureEvents(bool enable);
virtual bool childChanged(SGPropertyNode* child);
bool childChanged(SGPropertyNode* child) override;
protected:
typedef SGSharedPtr<SGPickCallback> PickCallbackPtr;

View File

@@ -1,4 +1,5 @@
// Base class for canvas placements
///@file
/// Base class for canvas placements
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -16,6 +17,7 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasPlacement.hxx"
#include <simgear/props/props.hxx>

View File

@@ -1,4 +1,5 @@
// Base class for canvas placements
///@file
/// Base class for canvas placements
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -40,9 +41,8 @@ namespace canvas
protected:
SGPropertyNode_ptr _node;
private:
Placement(const Placement&) /* = delete */;
Placement& operator=(const Placement&) /* = delete */;
Placement(const Placement&) = delete;
Placement& operator=(const Placement&) = delete;
};
} // namespace canvas

View File

@@ -1,4 +1,5 @@
// Adapter for using the canvas with different applications
///@file
/// Adapter for using the canvas with different applications
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -29,6 +30,10 @@ namespace HTTP { class Client; }
namespace canvas
{
/**
* Provides access to different required systems of the application to the
* Canvas
*/
class SystemAdapter
{
public:
@@ -37,7 +42,7 @@ namespace canvas
virtual FontPtr getFont(const std::string& name) const = 0;
virtual void addCamera(osg::Camera* camera) const = 0;
virtual void removeCamera(osg::Camera* camera) const = 0;
virtual osg::Image* getImage(const std::string& path) const = 0;
virtual osg::ref_ptr<osg::Image> getImage(const std::string& path) const = 0;
virtual SGSubsystem* getSubsystem(const std::string& name) const = 0;
virtual HTTP::Client* getHTTPClient() const = 0;
};

View File

@@ -1,4 +1,5 @@
// Window for placing a Canvas onto it (for dialogs, menus, etc.)
///@file
/// Window for placing a Canvas onto it (for dialogs, menus, etc.)
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -16,18 +17,17 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasMgr.hxx"
#include "CanvasSystemAdapter.hxx"
#include "CanvasWindow.hxx"
#include <simgear/canvas/Canvas.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/scene/util/OsgMath.hxx>
#include <osgGA/GUIEventHandler>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/foreach.hpp>
namespace simgear
{
namespace canvas
@@ -42,9 +42,6 @@ namespace canvas
const Style& parent_style,
Element* parent ):
Image(canvas, node, parent_style, parent),
_attributes_dirty(0),
_resizable(false),
_capture_events(true),
_resize_top(node, "resize-top"),
_resize_right(node, "resize-right"),
_resize_bottom(node, "resize-bottom"),
@@ -91,7 +88,7 @@ namespace canvas
_capture_events = node->getBoolValue();
else if( name == "decoration-border" )
parseDecorationBorder(node->getStringValue());
else if( boost::starts_with(name, "shadow-")
else if( strutils::starts_with(name, "shadow-")
|| name == "content-size" )
_attributes_dirty |= DECORATION;
else
@@ -102,16 +99,10 @@ namespace canvas
Image::valueChanged(node);
}
//----------------------------------------------------------------------------
osg::Group* Window::getGroup()
{
return getMatrixTransform();
}
//----------------------------------------------------------------------------
const SGVec2<float> Window::getPosition() const
{
const osg::Matrix& m = getMatrixTransform()->getMatrix();
auto const& m = getMatrix();
return SGVec2<float>( m(3, 0), m(3, 1) );
}
@@ -222,6 +213,19 @@ namespace canvas
_resize_left = getRegion().l() + offset.x();
}
//----------------------------------------------------------------------------
bool Window::handleEvent(const EventPtr& event)
{
if( auto mouse_event = dynamic_cast<MouseEvent*>(event.get()) )
{
mouse_event->local_pos =
mouse_event->client_pos =
mouse_event->screen_pos - toOsg(getPosition());
}
return Image::handleEvent(event);
}
//----------------------------------------------------------------------------
void Window::parseDecorationBorder(const std::string& str)
{

View File

@@ -1,4 +1,5 @@
// Window for placing a Canvas onto it (for dialogs, menus, etc.)
///@file
/// Window for placing a Canvas onto it (for dialogs, menus, etc.)
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -70,7 +71,6 @@ namespace canvas
virtual void update(double delta_time_sec);
virtual void valueChanged(SGPropertyNode* node);
osg::Group* getGroup();
const SGVec2<float> getPosition() const;
const SGRect<float> getScreenRegion() const;
@@ -97,6 +97,8 @@ namespace canvas
void handleResize( uint8_t mode,
const osg::Vec2f& offset = osg::Vec2f() );
bool handleEvent(const EventPtr& event) override;
protected:
enum Attributes
@@ -104,7 +106,7 @@ namespace canvas
DECORATION = 1
};
uint32_t _attributes_dirty;
uint32_t _attributes_dirty {0};
CanvasPtr _canvas_decoration;
CanvasWeakPtr _canvas_content;
@@ -113,8 +115,8 @@ namespace canvas
ImagePtr _image_content,
_image_shadow;
bool _resizable,
_capture_events;
bool _resizable {false},
_capture_events {true};
PropertyObject<int> _resize_top,
_resize_right,

View File

@@ -1,4 +1,5 @@
// Owner Drawn Gauge helper class
///@file
/// Owner Drawn Gauge helper class
//
// Written by Harald JOHNSEN, started May 2005.
//
@@ -6,9 +7,9 @@
//
// Ported to OSG by Tim Moore - Jun 2007
//
// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April 2012
// Supports now multisampling/mipmapping, usage of the stencil buffer and placing
// the texture in the scene by certain filter criteria
// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April
// 2012 Supports now multisampling/mipmapping, usage of the stencil buffer and
// placing the texture in the scene by certain filter criteria.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public

View File

@@ -1,4 +1,5 @@
// Owner Drawn Gauge helper class
///@file
/// Owner Drawn Gauge helper class
//
// Written by Harald JOHNSEN, started May 2005.
//
@@ -6,9 +7,9 @@
//
// Ported to OSG by Tim Moore - Jun 2007
//
// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April 2012
// Supports now multisampling/mipmapping, usage of the stencil buffer and placing
// the texture in the scene by certain filter criteria
// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April
// 2012 Supports now multisampling/mipmapping, usage of the stencil buffer and
// placing the texture in the scene by certain filter criteria.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public

View File

@@ -44,6 +44,11 @@
#if defined(_MSC_VER)
# pragma warning(disable:4311)
# pragma warning(disable:4312)
# define ALIGN16 __declspec(align(16))
# define ALIGN16C
#elif defined(__GNUC__)
# define ALIGN16
# define ALIGN16C __attribute__((aligned(16)))
#endif
/* Type definitions */

View File

@@ -80,8 +80,12 @@ void updateBlendingStateGL(VGContext *c, int alphaIsOne)
case VG_BLEND_SRC_OVER: default:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (alphaIsOne) glDisable(GL_BLEND);
else glEnable(GL_BLEND); break;
if (alphaIsOne) {
glDisable(GL_BLEND);
} else {
glEnable(GL_BLEND);
}
break;
};
}

View File

@@ -35,21 +35,33 @@ void SHVector2_dtor(SHVector2 *v) {
}
void SHVector3_ctor(SHVector3 *v) {
#ifdef SHIVA_USE_SIMD
v->vec = _mm_setzero_ps();
#else
v->x=0.0f; v->y=0.0f; v->z=0.0f;
#endif
}
void SHVector3_dtor(SHVector3 *v) {
}
void SHVector4_ctor(SHVector4 *v) {
#ifdef SHIVA_USE_SIMD
v->vec = _mm_setzero_ps();
#else
v->x=0.0f; v->y=0.0f; v->z=0.0f; v->w=0.0f;
#endif
}
void SHVector4_dtor(SHVector4 *v) {
}
void SHRectangle_ctor(SHRectangle *r) {
#ifdef SHIVA_USE_SIMD
r->vec = _mm_setzero_ps();
#else
r->x=0.0f; r->y=0.0f; r->w=0.0f; r->h=0.0f;
#endif
}
void SHRectangle_dtor(SHRectangle *r) {
@@ -135,3 +147,24 @@ int shLineLineXsection(SHVector2 *o1, SHVector2 *v1,
xsection->y = o1->y + t1*v1->y;
return 1;
}
#ifdef SHIVA_USE_SIMD
# ifdef __SSE3__
# include <pmmintrin.h>
inline float hsum_ps_sse(__m128 v) {
__m128 shuf = _mm_movehdup_ps(v);
__m128 sums = _mm_add_ps(v, shuf);
shuf = _mm_movehl_ps(shuf, sums);
sums = _mm_add_ss(sums, shuf);
return _mm_cvtss_f32(sums);
}
# else
inline float hsum_ps_sse(__m128 v) {
__m128 shuf = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 3, 0, 1));
__m128 sums = _mm_add_ps(v, shuf);
shuf = _mm_movehl_ps(shuf, sums);
sums = _mm_add_ss(sums, shuf);
return _mm_cvtss_f32(sums);
}
# endif
#endif

View File

@@ -21,6 +21,21 @@
#ifndef __SHVECTORS_H
#define __SHVECTORS_H
#ifdef HAVE_CONFIG_H
# include <simgear/simgear_config.h>
#endif
#ifdef ENABLE_SIMD
# ifdef __SSE__
// # define SHIVA_USE_SIMD
# endif
# endif
#ifdef SHIVA_USE_SIMD
# include <xmmintrin.h>
float hsum_ps_sse(__m128 v);
#endif
#include "shDefs.h"
/* Vector structures
@@ -33,9 +48,17 @@ typedef struct
void SHVector2_ctor(SHVector2 *v);
void SHVector2_dtor(SHVector2 *v);
typedef struct
{
#ifdef SHIVA_USE_SIMD
union ALIGN16 {
__m128 vec;
struct { SHfloat x,y,z,w; };
} ALIGN16C;
#else
SHfloat x,y,z;
#endif
} SHVector3;
void SHVector3_ctor(SHVector3 *v);
@@ -43,7 +66,14 @@ void SHVector3_dtor(SHVector3 *v);
typedef struct
{
#ifdef SHIVA_USE_SIMD
union ALIGN16 {
__m128 vec;
struct { SHfloat x,y,z,w; };
} ALIGN16C;
#else
SHfloat x,y,z,w;
#endif
} SHVector4;
void SHVector4_ctor(SHVector4 *v);
@@ -51,7 +81,14 @@ void SHVector4_dtor(SHVector4 *v);
typedef struct
{
#ifdef SHIVA_USE_SIMD
union ALIGN16 {
__m128 vec;
struct { SHfloat x,y,w,h; };
} ALIGN16C;
#else
SHfloat x,y,w,h;
#endif
} SHRectangle;
void SHRectangle_ctor(SHRectangle *r);
@@ -61,7 +98,14 @@ void shRectangleSet(SHRectangle *r, SHfloat x,
typedef struct
{
#ifdef SHIVA_USE_SIMD
union ALIGN16 {
__m128 mtx[4];
SHfloat m[4][4];
} ALIGN16C;
#else
SHfloat m[3][3];
#endif
} SHMatrix3x3;
void SHMatrix3x3_ctor(SHMatrix3x3 *m);
@@ -83,12 +127,22 @@ void SHMatrix3x3_dtor(SHMatrix3x3 *m);
*--------------------------------------------------------- */
#define SET2(v,xs,ys) { v.x=xs; v.y=ys; }
#define SET3(v,xs,ys,zs) { v.x=xs; v.y=ys; v.z=zs; }
#define SET4(v,xs,ys,zs,ws) { v.x=xs; v.y=ys; v.z=zs; v.w=ws; }
#ifdef SHIVA_USE_SIMD
# define SET3(v,xs,ys,zs,ws) { v.vec=_mm_set_ps(0,zs,ys,xs); }
# define SET4(v,xs,ys,zs,ws) { v.vec=_mm_set_ps(ws,zs,ys,xs); }
#else
# define SET3(v,xs,ys,zs) { v.x=xs; v.y=ys; v.z=zs; }
# define SET4(v,xs,ys,zs,ws) { v.x=xs; v.y=ys; v.z=zs; v.w=ws; }
#endif
#define SET2V(v1,v2) { v1.x=v2.x; v1.y=v2.y; }
#define SET3V(v1,v2) { v1.x=v2.x; v1.y=v2.y; v1.z=v2.z; }
#define SET4V(v1,v2) { v1.x=v2.x; v1.y=v2.y; v1.z=v2.z; v1.w=v2.w; }
#ifdef SHIVA_USE_SIMD
# define SET3V(v1,v2) { v1.vec=v2.vec; }
# define SET4V(v1,v2) { v1.vec=v2.vec; }
#else
# define SET3V(v1,v2) { v1.x=v2.x; v1.y=v2.y; v1.z=v2.z; }
# define SET4V(v1,v2) { v1.x=v2.x; v1.y=v2.y; v1.z=v2.z; v1.w=v2.w; }
#endif
#define EQ2(v,xx,yy) ( v.x==xx && v.y==yy )
#define EQ3(v,xx,yy,zz) ( v.x==xx && v.y==yy && v.z==zz )
@@ -103,48 +157,89 @@ void SHMatrix3x3_dtor(SHMatrix3x3 *m);
#define EQ4V(v1,v2) ( v1.x==v2.x && v1.y==v2.y && v1.z==v2.z && v1.w==v2.w )
#define ADD2(v,xx,yy) { v.x+=xx; v.y+=yy; }
#define ADD3(v,xx,yy,zz) { v.x+=xx; v.y+=yy; v.z+=zz; }
#define ADD4(v,xx,yy,zz,ww) { v.x+=xx; v.y+=yy; v.z+=zz; v.w+=ww; }
#ifdef SHIVA_USE_SIMD
# define ADD3(v,xx,yy,zz,ww) { v.vec=_mm_add_ps(v.vec,_mm_set_ps(0,zz,yy,xx)); }
# define ADD4(v,xx,yy,zz,ww) { v.vec=_mm_add_ps(v.vec,_mm_set_ps(ww,zz,yy,xx)); }
#else
# define ADD3(v,xx,yy,zz) { v.x+=xx; v.y+=yy; v.z+=zz; }
# define ADD4(v,xx,yy,zz,ww) { v.x+=xx; v.y+=yy; v.z+=zz; v.w+=ww; }
#endif
#define ADD2V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; }
#define ADD3V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; }
#define ADD4V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; v1.w+=v2.w; }
#ifdef SHIVA_USE_SIMD
# define ADD3V(v1,v2) { v1.vec=_mm_add_ps(v1.vec,v2.vec); }
# define ADD4V(v1,v2) { v1.vec=_mm_add_ps(v1.vec,v2.vec); }
#else
# define ADD3V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; }
# define ADD4V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; v1.w+=v2.w; }
#endif
#define SUB2(v,xx,yy) { v.x-=xx; v.y-=yy; }
#define SUB3(v,xx,yy,zz) { v.x-=xx; v.y-=yy; v.z-=zz; }
#define SUB4(v,xx,yy,zz,ww) { v.x-=xx; v.y-=yy; v.z-=zz; v.w-=v2.w; }
#ifdef SHIVA_USE_SIMD
# define SUB3(v,xx,yy,zz,ww) { v.vec=_mm_sub_ps(v.vec,_mm_set_ps(0,zz,yy,xx)); }
# define SUB4(v,xx,yy,zz,ww) { v.vec=_mm_sub_ps(v.vec,_mm_set_ps(ww,zz,yy,xx)); }
#else
# define SUB3(v,xx,yy,zz) { v.x-=xx; v.y-=yy; v.z-=zz; }
# define SUB4(v,xx,yy,zz,ww) { v.x-=xx; v.y-=yy; v.z-=zz; v.w-=v2.w; }
#endif
#define SUB2V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; }
#define SUB3V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; }
#define SUB4V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; v1.w-=v2.w; }
#ifdef SHIVA_USE_SIMD
# define SUB3V(v1,v2) { v1.vec=_mm_sub_ps(v1.vec,v2.vec); }
# define SUB4V(v1,v2) { v1.vec=_mm_sub_ps(v1.vec,v2.vec); }
#else
# define SUB3V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; }
# define SUB4V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; v1.w-=v2.w; }
#endif
#define MUL2(v,f) { v.x*=f; v.y*=f; }
#define MUL3(v,f) { v.x*=f; v.y*=f; v.z*=z; }
#define MUL4(v,f) { v.x*=f; v.y*=f; v.z*=z; v.w*=w; }
#ifdef SHIVA_USE_SIMD
# define MUL3(v,f) { v.vec=_mm_mul_ps(v.vec,_mm_set1_ps(f)); }
# define MUL4(v,f) { v.vec=_mm_mul_ps(v.vec,_mm_set1_ps(f)); }
#else
# define MUL3(v,f) { v.x*=f; v.y*=f; v.z*=z; }
# define MUL4(v,f) { v.x*=f; v.y*=f; v.z*=z; v.w*=w; }
#endif
#define DIV2(v,f) { v.x/=f; v.y/=f; }
#define DIV3(v,f) { v.x/=f; v.y/=f; v.z/=z; }
#define DIV4(v,f) { v.x/=f; v.y/=f; v.z/=z; v.w/=w; }
#ifdef SHIVA_USE_SIMD
# define DIV3(v,f) { v.vec=_mm_div_ps(v.vec,_mm_set1_ps(f)); }
# define DIV4(v,f) { v.vec=_mm_div_ps(v.vec,_mm_set1_ps(f)); }
#else
# define DIV3(v,f) { v.x/=f; v.y/=f; v.z/=z; }
# define DIV4(v,f) { v.x/=f; v.y/=f; v.z/=z; v.w/=w; }
#endif
#define ABS2(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); }
#define ABS3(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); v.z=SH_ABS(v.z); }
#define ABS4(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); v.z=SH_ABS(v.z); v.w=SH_ABS(v.w); }
#ifdef SHIVA_USE_SIMD
# define ABS_MASK _mm_set1_ps(-0.f)
# define ABS3(v) { v.vec=_mm_andnot_ps(ABS_MASK, v.vec); }
# define ABS4(v) { v.vec=_mm_andnot_ps(ABS_MASK, v.vec); }
#else
# define ABS3(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); v.z=SH_ABS(v.z); }
# define ABS4(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); v.z=SH_ABS(v.z); v.w=SH_ABS(v.w); }
#endif
#define NORMSQ2(v) (v.x*v.x + v.y*v.y)
#define NORMSQ3(v) (v.x*v.x + v.y*v.y + v.z*v.z)
#define NORMSQ4(v) (v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w)
#define NORMSQ2(v) DOT2(v,v)
#define NORMSQ3(v) DOT3(v,v)
#define NORMSQ4(v) DOT4(v,v)
#define NORM2(v) SH_SQRT(NORMSQ2(v))
#define NORM3(v) SH_SQRT(NORMSQ3(v))
#define NORM4(v) SH_SQRT(NORMSQ4(v))
#define NORMALIZE2(v) { SHfloat n=NORM2(v); v.x/=n; v.y/=n; }
#define NORMALIZE3(v) { SHfloat n=NORM3(v); v.x/=n; v.y/=n; v.z/=n; }
#define NORMALIZE4(v) { SHfloat n=NORM4(v); v.x/=n; v.y/=n; v.z/=n; v.w/=w; }
#define NORMALIZE2(v) { SHfloat n=NORM2(v); DIV2(v,n); }
#define NORMALIZE3(v) { SHfloat n=NORM3(v); DIV3(v,n); }
#define NORMALIZE4(v) { SHfloat n=NORM4(v); DIV4(v,n); }
#define DOT2(v1,v2) (v1.x*v2.x + v1.y*v2.y)
#define DOT3(v1,v2) (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z)
#define DOT4(v1,v2) (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w)
#ifdef SHIVA_USE_SIMD
# define DOT4(v1,v2) hsum_ps_sse(_mm_mul_ps(v1.vec,v2.vec))
# define DOT4(v1,v2) hsum_ps_sse(_mm_mul_ps(v1.vec,v2.vec))
#else
# define DOT3(v1,v2) (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z)
# define DOT4(v1,v2) (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w)
#endif
#define CROSS2(v1,v2) (v1.x*v2.y - v2.x*v1.y)
@@ -152,37 +247,84 @@ void SHMatrix3x3_dtor(SHMatrix3x3 *m);
#define ANGLE2N(v1,v2) (SH_ACOS( DOT2(v1,v2) ))
#define OFFSET2V(v, o, s) { v.x += o.x*s; v.y += o.y*s; }
#define OFFSET3V(v, o, s) { v.x += o.x*s; v.y += o.y*s; v.z += o.z*s; }
#define OFFSET4V(v, o, s) { v.x += o.x*s; v.y += o.y*s; v.z += o.z*s; v.w += o.w*s; }
#ifdef SHIVA_USE_SIMD
# define OFFSET4V(v, o, s) { v.vec=_mm_add_ps(v.vec,_mm_mul_ps(o.vec,_mm_set1_ps(s))); }
# define OFFSET4V(v, o, s) { v.vec=_mm_add_ps(v.vec,_mm_mul_ps(o.vec,_mm_set1_ps(s))); }
#else
# define OFFSET3V(v, o, s) { v.x += o.x*s; v.y += o.y*s; v.z += o.z*s; }
# define OFFSET4V(v, o, s) { v.x += o.x*s; v.y += o.y*s; v.z += o.z*s; v.w += o.w*s; }
#endif
/*-----------------------------------------------------
* Macros for matrix operations
*-----------------------------------------------------*/
#define SETMAT(mat, m00, m01, m02, m10, m11, m12, m20, m21, m22) { \
mat.m[0][0] = m00; mat.m[0][1] = m01; mat.m[0][2] = m02; \
#ifdef SHIVA_USE_SIMD
# define SETMAT(mat, m00, m01, m02, m10, m11, m12, m20, m21, m22) { \
mat.mtx[0] = _mm_set_ps(0,m02,m01,m00); \
mat.mtx[1] = _mm_set_ps(0,m12,m11,m10); \
mat.mtx[2] = _mm_set_ps(0,m22,m21,m20); \
mat.mtx[3] = _mm_setzero_ps(); }
#else
# define SETMAT(mat, m00, m01, m02, m10, m11, m12, m20, m21, m22) { \
mat.m[0][0] = m00; mat.m[0][1] = m01; mat.m[0][2] = m02; \
mat.m[1][0] = m10; mat.m[1][1] = m11; mat.m[1][2] = m12; \
mat.m[2][0] = m20; mat.m[2][1] = m21; mat.m[2][2] = m22; }
#endif
#define SETMATMAT(m1, m2) { \
#ifdef SHIVA_USE_SIMD
# define SETMATMAT(m1, m2) { \
m1.mtx[0] = m2.mtx[0]; \
m1.mtx[1] = m2.mtx[1]; \
m1.mtx[2] = m2.mtx[2]; }
#else
# define SETMATMAT(m1, m2) { \
int i,j; \
for(i=0;i<3;i++) \
for(j=0;j<3;j++) \
m1.m[i][j] = m2.m[i][j]; }
#endif
#define MULMATS(mat, s) { \
#ifdef SHIVA_USE_SIMD
# define MULMATS(mat, s) { \
mat.mtx[0] = _mm_mul_ps(mat.mtx[0],_mm_set1_ps(s)); \
mat.mtx[1] = _mm_mul_ps(mat.mtx[1],_mm_set1_ps(s)); \
mat.mtx[2] = _mm_mul_ps(mat.mtx[2],_mm_set1_ps(s)); }
#else
# define MULMATS(mat, s) { \
int i,j; \
for(i=0;i<3;i++) \
for(j=0;j<3;j++) \
mat.m[i][j] *= s; }
#endif
#define DIVMATS(mat, s) { \
#ifdef SHIVA_USE_SIMD
# define DIVMATS(mat, s) { \
mat.mtx[0] = _mm_mul_ps(mat.mtx[0],_mm_set1_ps(1/s)); \
mat.mtx[1] = _mm_mul_ps(mat.mtx[1],_mm_set1_ps(1/s)); \
mat.mtx[2] = _mm_mul_ps(mat.mtx[2],_mm_set1_ps(1/s)); }
#else
# define DIVMATS(mat, s) { \
int i,j; \
for(i=0;i<3;i++) \
for(j=0;j<3;j++) \
mat.m[i][j] /= s; }
#endif
#define MULMATMAT(m1, m2, mout) { \
#ifdef SHIVA_USE_SIMD
# define MULMATMAT(m2, m1, mout) { \
int i,j; \
for (i=0;i<4;i++) { \
__m128 a = m1.mtx[0]; \
__m128 b = _mm_set1_ps(m2.m[i][0]); \
mout.mtx[i] = a*b; \
for (j=1;j<4;j++) { \
a = m1.mtx[j]; \
b = _mm_set1_ps(m2.m[i][j]); \
mout.mtx[i] += a*b; } } }
#else
# define MULMATMAT(m1, m2, mout) { \
int i,j; \
for(i=0;i<3;i++) \
for(j=0;j<3;j++) \
@@ -190,6 +332,7 @@ int i,j; \
m1.m[i][0] * m2.m[0][j] + \
m1.m[i][1] * m2.m[1][j] + \
m1.m[i][2] * m2.m[2][j]; }
#endif
#define IDMAT(mat) SETMAT(mat, 1,0,0, 0,1,0, 0,0,1)

View File

@@ -1,4 +1,5 @@
// osg::Operation to initialize the OpenVG context used for path rendering
///@file
/// osg::Operation to initialize the OpenVG context used for path rendering
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//

View File

@@ -1,4 +1,5 @@
// osg::Operation to initialize the OpenVG context used for path rendering
///@file
/// osg::Operation to initialize the OpenVG context used for path rendering
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//

View File

@@ -1,4 +1,5 @@
// Canvas forward declarations
///@file
/// Canvas forward declarations
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//

View File

@@ -9,10 +9,6 @@ set(HEADERS
CanvasText.hxx
)
set(DETAIL_HEADERS
detail/add_segment_variadic.hxx
)
set(SOURCES
CanvasElement.cxx
CanvasGroup.cxx
@@ -23,7 +19,6 @@ set(SOURCES
)
simgear_scene_component(canvas-elements canvas/elements "${SOURCES}" "${HEADERS}")
simgear_component(canvas-elements/detail canvas/elements/detail "" "${DETAIL_HEADERS}")
add_boost_test(canvas_element
SOURCES canvas_element_test.cpp

View File

@@ -1,4 +1,5 @@
// Interface for 2D Canvas element
///@file
/// Interface for 2D Canvas element
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -16,6 +17,8 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasElement.hxx"
#include <simgear/canvas/Canvas.hxx>
#include <simgear/canvas/CanvasEventVisitor.hxx>
@@ -29,10 +32,6 @@
#include <osg/StateAttribute>
#include <osg/Version>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
#include <cassert>
#include <cmath>
#include <cstring>
@@ -212,22 +211,22 @@ namespace canvas
//----------------------------------------------------------------------------
void Element::onDestroy()
{
if( !_transform.valid() )
if( !_scene_group.valid() )
return;
// The transform node keeps a reference on this element, so ensure it is
// deleted.
BOOST_FOREACH(osg::Group* parent, _transform->getParents())
for(osg::Group* parent: _scene_group->getParents())
{
parent->removeChild(_transform.get());
parent->removeChild(_scene_group.get());
}
// Hide in case someone still holds a reference
setVisible(false);
removeListener();
_parent = 0;
_transform = 0;
_parent = nullptr;
_scene_group = nullptr;
}
//----------------------------------------------------------------------------
@@ -245,29 +244,8 @@ namespace canvas
//----------------------------------------------------------------------------
void Element::update(double dt)
{
if( !isVisible() )
return;
// Trigger matrix update
getMatrix();
// Update bounding box on manual update (manual updates pass zero dt)
if( dt == 0 && _drawable )
_drawable->getBound();
if( (_attributes_dirty & BLEND_FUNC) && _transform.valid() )
{
parseBlendFunc(
_transform->getOrCreateStateSet(),
_node->getChild("blend-source"),
_node->getChild("blend-destination"),
_node->getChild("blend-source-rgb"),
_node->getChild("blend-destination-rgb"),
_node->getChild("blend-source-alpha"),
_node->getChild("blend-destination-alpha")
);
_attributes_dirty &= ~BLEND_FUNC;
}
if( isVisible() )
updateImpl(dt);
}
//----------------------------------------------------------------------------
@@ -294,8 +272,7 @@ namespace canvas
//----------------------------------------------------------------------------
void Element::setFocus()
{
CanvasPtr canvas = _canvas.lock();
if( canvas )
if( auto canvas = _canvas.lock() )
canvas->setFocusElement(this);
}
@@ -339,7 +316,8 @@ namespace canvas
if( listeners == _listener.end() )
return false;
BOOST_FOREACH(EventListener const& listener, listeners->second)
for(auto const& listener: listeners->second)
{
try
{
listener(event);
@@ -352,6 +330,7 @@ namespace canvas
"canvas::Element: event handler error: '" << ex.what() << "'"
);
}
}
return true;
}
@@ -393,9 +372,9 @@ namespace canvas
getBoundingBox()
#endif
.contains(osg::Vec3f(local_pos, 0));
else if( _transform.valid() )
else if( _scene_group.valid() )
// ... for other elements, i.e. groups only a bounding sphere is available
return _transform->getBound().contains(osg::Vec3f(parent_pos, 0));
return _scene_group->getBound().contains(osg::Vec3f(parent_pos, 0));
else
return false;
}
@@ -404,34 +383,32 @@ namespace canvas
//----------------------------------------------------------------------------
void Element::setVisible(bool visible)
{
if( _transform.valid() )
if( _scene_group.valid() )
// TODO check if we need another nodemask
_transform->setNodeMask(visible ? 0xffffffff : 0);
_scene_group->setNodeMask(visible ? 0xffffffff : 0);
}
//----------------------------------------------------------------------------
bool Element::isVisible() const
{
return _transform.valid() && _transform->getNodeMask() != 0;
return _scene_group.valid() && _scene_group->getNodeMask() != 0;
}
//----------------------------------------------------------------------------
osg::MatrixTransform* Element::getMatrixTransform()
osg::MatrixTransform* Element::getSceneGroup() const
{
return _transform.get();
}
//----------------------------------------------------------------------------
osg::MatrixTransform const* Element::getMatrixTransform() const
{
return _transform.get();
return _scene_group.get();
}
//----------------------------------------------------------------------------
osg::Vec2f Element::posToLocal(const osg::Vec2f& pos) const
{
getMatrix();
const osg::Matrix& m = _transform->getInverseMatrix();
if( !_scene_group )
// TODO log warning?
return pos;
updateMatrix();
const osg::Matrix& m = _scene_group->getInverseMatrix();
return osg::Vec2f
(
m(0, 0) * pos[0] + m(1, 0) * pos[1] + m(3, 0),
@@ -484,9 +461,6 @@ namespace canvas
{
if( child->getNameString() == NAME_TRANSFORM )
{
if( !_transform.valid() )
return;
if( child->getIndex() >= static_cast<int>(_transform_types.size()) )
{
SG_LOG
@@ -523,7 +497,7 @@ namespace canvas
if( parent == _node )
{
const std::string& name = child->getNameString();
if( boost::starts_with(name, "data-") )
if( strutils::starts_with(name, "data-") )
return;
else if( StyleInfo const* style_info = getStyleInfo(name) )
{
@@ -538,7 +512,7 @@ namespace canvas
}
else if( name == "update" )
return update(0);
else if( boost::starts_with(name, "blend-") )
else if( strutils::starts_with(name, "blend-") )
return (void)(_attributes_dirty |= BLEND_FUNC);
}
else if( parent
@@ -562,6 +536,10 @@ namespace canvas
//----------------------------------------------------------------------------
void Element::setClip(const std::string& clip)
{
if( !_scene_group )
// TODO warn?
return;
osg::StateSet* ss = getOrCreateStateSet();
if( !ss )
return;
@@ -575,8 +553,8 @@ namespace canvas
// TODO generalize CSS property parsing
const std::string RECT("rect(");
if( !boost::ends_with(clip, ")")
|| !boost::starts_with(clip, RECT) )
if( !strutils::ends_with(clip, ")")
|| !strutils::starts_with(clip, RECT) )
{
SG_LOG(SG_GENERAL, SG_WARN, "Canvas: invalid clip: " << clip);
return;
@@ -616,7 +594,7 @@ namespace canvas
}
if( !_scissor )
_scissor = new RelativeScissor(_transform.get());
_scissor = new RelativeScissor(_scene_group.get());
// <top>, <right>, <bottom>, <left>
_scissor->x() = values[3];
@@ -640,6 +618,27 @@ namespace canvas
_scissor->_coord_reference = rf;
}
//----------------------------------------------------------------------------
void Element::setRotation(unsigned int index, double r)
{
_node->getChild(NAME_TRANSFORM, index, true)->setDoubleValue("rot", r);
}
//----------------------------------------------------------------------------
void Element::setTranslation(unsigned int index, double x, double y)
{
SGPropertyNode* tf = _node->getChild(NAME_TRANSFORM, index, true);
tf->getChild("t", 0, true)->setDoubleValue(x);
tf->getChild("t", 1, true)->setDoubleValue(y);
}
//----------------------------------------------------------------------------
void Element::setTransformEnabled(unsigned int index, bool enabled)
{
SGPropertyNode* tf = _node->getChild(NAME_TRANSFORM, index, true);
tf->setBoolValue("enabled", enabled);
}
//----------------------------------------------------------------------------
osg::BoundingBox Element::getBoundingBox() const
{
@@ -652,8 +651,8 @@ namespace canvas
osg::BoundingBox bb;
if( _transform.valid() )
bb.expandBy(_transform->getBound());
if( _scene_group.valid() )
bb.expandBy( _scene_group->getBound() );
return bb;
}
@@ -687,70 +686,11 @@ namespace canvas
//----------------------------------------------------------------------------
osg::Matrix Element::getMatrix() const
{
if( !_transform )
if( !_scene_group )
return osg::Matrix::identity();
if( !(_attributes_dirty & TRANSFORM) )
return _transform->getMatrix();
osg::Matrix m;
for( size_t i = 0; i < _transform_types.size(); ++i )
{
// Skip unused indizes...
if( _transform_types[i] == TT_NONE )
continue;
SGPropertyNode* tf_node = _node->getChild("tf", i, true);
// Build up the matrix representation of the current transform node
osg::Matrix tf;
switch( _transform_types[i] )
{
case TT_MATRIX:
tf = osg::Matrix( tf_node->getDoubleValue("m[0]", 1),
tf_node->getDoubleValue("m[1]", 0),
0,
tf_node->getDoubleValue("m[6]", 0),
tf_node->getDoubleValue("m[2]", 0),
tf_node->getDoubleValue("m[3]", 1),
0,
tf_node->getDoubleValue("m[7]", 0),
0,
0,
1,
0,
tf_node->getDoubleValue("m[4]", 0),
tf_node->getDoubleValue("m[5]", 0),
0,
tf_node->getDoubleValue("m[8]", 1) );
break;
case TT_TRANSLATE:
tf.makeTranslate( osg::Vec3f( tf_node->getDoubleValue("t[0]", 0),
tf_node->getDoubleValue("t[1]", 0),
0 ) );
break;
case TT_ROTATE:
tf.makeRotate( tf_node->getDoubleValue("rot", 0), 0, 0, 1 );
break;
case TT_SCALE:
{
float sx = tf_node->getDoubleValue("s[0]", 1);
// sy defaults to sx...
tf.makeScale( sx, tf_node->getDoubleValue("s[1]", sx), 1 );
break;
}
default:
break;
}
m.postMult( tf );
}
_transform->setMatrix(m);
_attributes_dirty &= ~TRANSFORM;
return m;
updateMatrix();
return _scene_group->getMatrix();
}
//----------------------------------------------------------------------------
@@ -764,11 +704,8 @@ namespace canvas
PropertyBasedElement(node),
_canvas( canvas ),
_parent( parent ),
_attributes_dirty( 0 ),
_transform( new osg::MatrixTransform ),
_style( parent_style ),
_scissor( 0 ),
_drawable( 0 )
_scene_group( new osg::MatrixTransform ),
_style( parent_style )
{
staticInit();
@@ -780,15 +717,15 @@ namespace canvas
);
// Ensure elements are drawn in order they appear in the element tree
_transform->getOrCreateStateSet()
->setRenderBinDetails
(
0,
"PreOrderBin",
osg::StateSet::OVERRIDE_RENDERBIN_DETAILS
);
_scene_group
->getOrCreateStateSet()
->setRenderBinDetails(
0,
"PreOrderBin",
osg::StateSet::OVERRIDE_RENDERBIN_DETAILS
);
_transform->setUserData( new OSGUserData(this) );
_scene_group->setUserData( new OSGUserData(this) );
}
//----------------------------------------------------------------------------
@@ -876,11 +813,21 @@ namespace canvas
void Element::setDrawable( osg::Drawable* drawable )
{
_drawable = drawable;
assert( _drawable );
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
if( !_drawable )
{
SG_LOG(SG_GL, SG_WARN, "canvas::Element::setDrawable: NULL drawable");
return;
}
if( !_scene_group )
{
SG_LOG(SG_GL, SG_WARN, "canvas::Element::setDrawable: NULL scenegroup");
return;
}
auto geode = new osg::Geode;
geode->addDrawable(_drawable);
_transform->addChild(geode);
_scene_group->addChild(geode);
}
//----------------------------------------------------------------------------
@@ -888,18 +835,109 @@ namespace canvas
{
if( _drawable.valid() )
return _drawable->getOrCreateStateSet();
if( _transform.valid() )
return _transform->getOrCreateStateSet();
return 0;
else if( _scene_group.valid() )
return _scene_group->getOrCreateStateSet();
else
return nullptr;
}
//----------------------------------------------------------------------------
void Element::setupStyle()
{
BOOST_FOREACH( Style::value_type style, _style )
for(auto const& style: _style)
setStyle(style.second);
}
//----------------------------------------------------------------------------
void Element::updateMatrix() const
{
if( !(_attributes_dirty & TRANSFORM) || !_scene_group )
return;
osg::Matrix m;
for( size_t i = 0; i < _transform_types.size(); ++i )
{
// Skip unused indizes...
if( _transform_types[i] == TT_NONE )
continue;
SGPropertyNode* tf_node = _node->getChild("tf", i, true);
if (!tf_node->getBoolValue("enabled", true)) {
continue; // skip disabled transforms
}
// Build up the matrix representation of the current transform node
osg::Matrix tf;
switch( _transform_types[i] )
{
case TT_MATRIX:
tf = osg::Matrix( tf_node->getDoubleValue("m[0]", 1),
tf_node->getDoubleValue("m[1]", 0),
0,
tf_node->getDoubleValue("m[6]", 0),
tf_node->getDoubleValue("m[2]", 0),
tf_node->getDoubleValue("m[3]", 1),
0,
tf_node->getDoubleValue("m[7]", 0),
0,
0,
1,
0,
tf_node->getDoubleValue("m[4]", 0),
tf_node->getDoubleValue("m[5]", 0),
0,
tf_node->getDoubleValue("m[8]", 1) );
break;
case TT_TRANSLATE:
tf.makeTranslate( osg::Vec3f( tf_node->getDoubleValue("t[0]", 0),
tf_node->getDoubleValue("t[1]", 0),
0 ) );
break;
case TT_ROTATE:
tf.makeRotate( tf_node->getDoubleValue("rot", 0), 0, 0, 1 );
break;
case TT_SCALE:
{
float sx = tf_node->getDoubleValue("s[0]", 1);
// sy defaults to sx...
tf.makeScale( sx, tf_node->getDoubleValue("s[1]", sx), 1 );
break;
}
default:
break;
}
m.postMult( tf );
}
_scene_group->setMatrix(m);
_attributes_dirty &= ~TRANSFORM;
}
//----------------------------------------------------------------------------
void Element::updateImpl(double dt)
{
updateMatrix();
// Update bounding box on manual update (manual updates pass zero dt)
if( dt == 0 && _drawable )
_drawable->getBound();
if( (_attributes_dirty & BLEND_FUNC) )
{
parseBlendFunc(
_scene_group->getOrCreateStateSet(),
_node->getChild("blend-source"),
_node->getChild("blend-destination"),
_node->getChild("blend-source-rgb"),
_node->getChild("blend-destination-rgb"),
_node->getChild("blend-source-alpha"),
_node->getChild("blend-destination-alpha")
);
_attributes_dirty &= ~BLEND_FUNC;
}
}
} // namespace canvas
} // namespace simgear

View File

@@ -24,13 +24,13 @@
#include <simgear/canvas/CanvasEvent.hxx>
#include <simgear/props/PropertyBasedElement.hxx>
#include <simgear/misc/stdint.hxx> // for uint32_t
#include <simgear/std/type_traits.hxx>
#include <osg/BoundingBox>
#include <osg/MatrixTransform>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/type_traits/is_base_of.hpp>
namespace osg
{
@@ -49,6 +49,7 @@ namespace canvas
public PropertyBasedElement
{
public:
using SceneGroupWeakPtr = osg::observer_ptr<osg::MatrixTransform>;
/**
* Store pointer to window as user data
@@ -94,7 +95,7 @@ namespace canvas
*
*/
virtual ~Element() = 0;
virtual void onDestroy();
void onDestroy() override;
ElementPtr getParent() const;
CanvasWeakPtr getCanvas() const;
@@ -104,7 +105,7 @@ namespace canvas
*
* @param dt Frame time in seconds
*/
virtual void update(double dt);
void update(double dt) override;
bool addEventListener(const std::string& type, const EventListener& cb);
virtual void clearEventListener();
@@ -142,19 +143,20 @@ namespace canvas
*/
virtual bool isVisible() const;
osg::MatrixTransform* getMatrixTransform();
osg::MatrixTransform const* getMatrixTransform() const;
/**
* Get the according group in the OSG scene graph
*/
// TODO ref_ptr
osg::MatrixTransform* getSceneGroup() const;
/**
* Transform position to local coordinages.
*/
osg::Vec2f posToLocal(const osg::Vec2f& pos) const;
virtual void childAdded( SGPropertyNode * parent,
SGPropertyNode * child );
virtual void childRemoved( SGPropertyNode * parent,
SGPropertyNode * child );
virtual void valueChanged(SGPropertyNode * child);
void childAdded(SGPropertyNode* parent, SGPropertyNode* child) override;
void childRemoved(SGPropertyNode* parent, SGPropertyNode* child) override;
void valueChanged(SGPropertyNode* child) override;
virtual bool setStyle( const SGPropertyNode* child,
const StyleInfo* style_info = 0 );
@@ -172,6 +174,22 @@ namespace canvas
*/
void setClipFrame(ReferenceFrame rf);
/**
*
*/
void setRotation(unsigned int index, double r);
/**
*
*/
void setTranslation(unsigned int index, double x, double y);
/**
*
*
*/
void setTransformEnabled(unsigned int index, bool enabled);
/**
* Get bounding box (may not be as tight as bounding box returned by
* #getTightBoundingBox)
@@ -201,13 +219,14 @@ namespace canvas
*/
template<typename Derived>
static
typename boost::enable_if<
boost::is_base_of<Element, Derived>,
std::enable_if_t<
std::is_base_of<Element, Derived>::value,
ElementPtr
>::type create( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& style = Style(),
Element* parent = NULL )
>
create( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& style = Style(),
Element* parent = NULL )
{
return ElementPtr( new Derived(canvas, node, style, parent) );
}
@@ -235,13 +254,13 @@ namespace canvas
CanvasWeakPtr _canvas;
ElementWeakPtr _parent;
mutable uint32_t _attributes_dirty;
mutable uint32_t _attributes_dirty = 0;
osg::observer_ptr<osg::MatrixTransform> _transform;
std::vector<TransformType> _transform_types;
SceneGroupWeakPtr _scene_group;
std::vector<TransformType> _transform_types;
Style _style;
RelativeScissor *_scissor;
RelativeScissor *_scissor = nullptr;
typedef std::vector<EventListener> Listener;
typedef std::map<int, Listener> ListenerMap;
@@ -568,11 +587,15 @@ namespace canvas
void setupStyle();
void updateMatrix() const;
virtual void updateImpl(double dt);
private:
osg::ref_ptr<osg::Drawable> _drawable;
Element(const Element&);// = delete
Element(const Element&) = delete;
template<class Derived>
static Derived& derived_cast(Element& el)

View File

@@ -1,4 +1,5 @@
// A group of 2D Canvas elements
///@file
/// A group of 2D Canvas elements
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -16,18 +17,17 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasGroup.hxx"
#include "CanvasImage.hxx"
#include "CanvasMap.hxx"
#include "CanvasPath.hxx"
#include "CanvasText.hxx"
#include <simgear/canvas/CanvasEventVisitor.hxx>
#include <simgear/canvas/events/MouseEvent.hxx>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/lambda/core.hpp>
namespace simgear
{
namespace canvas
@@ -46,7 +46,7 @@ namespace canvas
ElementFactories Group::_child_factories;
const std::string Group::TYPE_NAME = "group";
void warnTransformExpired(const char* member_name)
void warnSceneGroupExpired(const char* member_name)
{
SG_LOG( SG_GENERAL,
SG_WARN,
@@ -133,63 +133,58 @@ namespace canvas
//----------------------------------------------------------------------------
ElementPtr Group::getElementById(const std::string& id)
{
if( !_transform.valid() )
if( !_scene_group.valid() )
{
warnTransformExpired("getElementById");
return ElementPtr();
warnSceneGroupExpired("getElementById");
return {};
}
std::vector<GroupPtr> groups;
for(size_t i = 0; i < _transform->getNumChildren(); ++i)
// TODO check search algorithm. Not completely breadth-first and might be
// possible with using less dynamic memory
std::vector<GroupPtr> child_groups;
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i)
{
const ElementPtr& el = getChildByIndex(i);
if( el->get<std::string>("id") == id )
return el;
Group* group = dynamic_cast<Group*>(el.get());
if( group )
groups.push_back(group);
if( Group* child_group = dynamic_cast<Group*>(el.get()) )
child_groups.push_back(child_group);
}
BOOST_FOREACH( GroupPtr group, groups )
for(auto group: child_groups)
{
ElementPtr el = group->getElementById(id);
if( el )
if( ElementPtr el = group->getElementById(id) )
return el;
}
return ElementPtr();
return {};
}
//----------------------------------------------------------------------------
void Group::clearEventListener()
{
if( !_transform.valid() )
return warnTransformExpired("clearEventListener");
for(size_t i = 0; i < _transform->getNumChildren(); ++i)
getChildByIndex(i)->clearEventListener();
Element::clearEventListener();
}
//----------------------------------------------------------------------------
void Group::update(double dt)
{
for(size_t i = 0; i < _transform->getNumChildren(); ++i)
getChildByIndex(i)->update(dt);
if( !_scene_group.valid() )
return warnSceneGroupExpired("clearEventListener");
Element::update(dt);
// TODO should this be recursive?
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i)
getChildByIndex(i)->clearEventListener();
}
//----------------------------------------------------------------------------
bool Group::traverse(EventVisitor& visitor)
{
// Iterate in reverse order as last child is displayed on top
for(size_t i = _transform->getNumChildren(); i --> 0;)
if( _scene_group.valid() )
{
if( getChildByIndex(i)->accept(visitor) )
return true;
// Iterate in reverse order as last child is displayed on top
for(size_t i = _scene_group->getNumChildren(); i --> 0;)
{
if( getChildByIndex(i)->accept(visitor) )
return true;
}
}
return false;
}
@@ -204,13 +199,13 @@ namespace canvas
bool handled = setStyleImpl(style, style_info);
if( style_info->inheritable )
{
if( !_transform.valid() )
if( !_scene_group.valid() )
{
warnTransformExpired("setStyle");
warnSceneGroupExpired("setStyle");
return false;
}
for(size_t i = 0; i < _transform->getNumChildren(); ++i)
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i)
handled |= getChildByIndex(i)->setStyle(style, style_info);
}
@@ -220,26 +215,20 @@ namespace canvas
//----------------------------------------------------------------------------
osg::BoundingBox Group::getTransformedBounds(const osg::Matrix& m) const
{
osg::BoundingBox bb;
if( !_transform.valid() )
if( !_scene_group.valid() )
{
warnTransformExpired("getTransformedBounds");
return bb;
warnSceneGroupExpired("getTransformedBounds");
return {};
}
for(size_t i = 0; i < _transform->getNumChildren(); ++i)
osg::BoundingBox bb;
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i)
{
const ElementPtr& child = getChildByIndex(i);
if( !child->getMatrixTransform()->getNodeMask() )
auto child = getChildByIndex(i);
if( !child || !child->isVisible() )
continue;
bb.expandBy
(
child->getTransformedBounds
(
child->getMatrixTransform()->getMatrix() * m
)
);
bb.expandBy( child->getTransformedBounds(child->getMatrix() * m) );
}
return bb;
@@ -255,6 +244,15 @@ namespace canvas
return ElementFactory();
}
//----------------------------------------------------------------------------
void Group::updateImpl(double dt)
{
Element::updateImpl(dt);
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i)
getChildByIndex(i)->update(dt);
}
//----------------------------------------------------------------------------
void Group::childAdded(SGPropertyNode* child)
{
@@ -264,13 +262,13 @@ namespace canvas
ElementFactory child_factory = getChildFactory( child->getNameString() );
if( child_factory )
{
if( !_transform.valid() )
return warnTransformExpired("childAdded");
if( !_scene_group.valid() )
return warnSceneGroupExpired("childAdded");
ElementPtr element = child_factory(_canvas, child, _style, this);
// Add to osg scene graph...
_transform->addChild( element->getMatrixTransform() );
_scene_group->addChild(element->getSceneGroup());
// ...and ensure correct ordering
handleZIndexChanged(element);
@@ -291,7 +289,7 @@ namespace canvas
if( getChildFactory(node->getNameString()) )
{
if( !_transform.valid() )
if( !_scene_group.valid() )
// If transform is destroyed also all children are destroyed, so we can
// not do anything here.
return;
@@ -321,7 +319,7 @@ namespace canvas
void Group::childChanged(SGPropertyNode* node)
{
SGPropertyNode* parent = node->getParent();
SGPropertyNode* grand_parent = parent ? parent->getParent() : NULL;
SGPropertyNode* grand_parent = parent ? parent->getParent() : nullptr;
if( grand_parent == _node
&& node->getNameString() == "z-index" )
@@ -331,16 +329,18 @@ namespace canvas
//----------------------------------------------------------------------------
void Group::handleZIndexChanged(ElementPtr child, int z_index)
{
if( !child || !_transform.valid() )
if( !child || !_scene_group.valid() )
return;
osg::ref_ptr<osg::MatrixTransform> tf = child->getMatrixTransform();
size_t index = _transform->getChildIndex(tf),
// Keep reference to prevent deleting while removing and re-inserting later
osg::ref_ptr<osg::MatrixTransform> tf = child->getSceneGroup();
size_t index = _scene_group->getChildIndex(tf),
index_new = index;
for(;; ++index_new)
{
if( index_new + 1 == _transform->getNumChildren() )
if( index_new + 1 == _scene_group->getNumChildren() )
break;
// Move to end of block with same index (= move upwards until the next
@@ -367,13 +367,13 @@ namespace canvas
return;
}
_transform->removeChild(index);
_transform->insertChild(index_new, tf);
_scene_group->removeChild(index);
_scene_group->insertChild(index_new, tf);
SG_LOG
(
SG_GENERAL,
SG_INFO,
SG_DEBUG,
"canvas::Group: Moved element " << index << " to position " << index_new
);
}
@@ -381,24 +381,27 @@ namespace canvas
//----------------------------------------------------------------------------
ElementPtr Group::getChildByIndex(size_t index) const
{
assert(_transform.valid());
OSGUserData* ud =
static_cast<OSGUserData*>(_transform->getChild(index)->getUserData());
assert(ud);
return ud->element;
assert( _scene_group.valid() );
auto child = _scene_group->getChild(index);
if( !child )
return {};
auto ud = static_cast<OSGUserData*>(child->getUserData());
return ud ? ud->element : ElementPtr();
}
//----------------------------------------------------------------------------
ElementPtr Group::findChild( const SGPropertyNode* node,
const std::string& id ) const
{
if( !_transform.valid() )
if( !_scene_group.valid() )
{
warnTransformExpired("findChild");
return ElementPtr();
warnSceneGroupExpired("findChild");
return {};
}
for(size_t i = 0; i < _transform->getNumChildren(); ++i)
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i)
{
ElementPtr el = getChildByIndex(i);
@@ -414,7 +417,7 @@ namespace canvas
}
}
return ElementPtr();
return {};
}
} // namespace canvas

View File

@@ -1,4 +1,5 @@
// A group of 2D Canvas elements
///@file
/// A group of 2D Canvas elements
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
@@ -86,16 +87,15 @@ namespace canvas
*/
ElementPtr getElementById(const std::string& id);
virtual void clearEventListener();
void clearEventListener() override;
virtual void update(double dt);
bool traverse(EventVisitor& visitor) override;
virtual bool traverse(EventVisitor& visitor);
bool setStyle( const SGPropertyNode* child,
const StyleInfo* style_info = 0 ) override;
virtual bool setStyle( const SGPropertyNode* child,
const StyleInfo* style_info = 0 );
virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const;
osg::BoundingBox
getTransformedBounds(const osg::Matrix& m) const override;
protected:
@@ -107,9 +107,11 @@ namespace canvas
*/
virtual ElementFactory getChildFactory(const std::string& type) const;
virtual void childAdded(SGPropertyNode * child);
virtual void childRemoved(SGPropertyNode * child);
virtual void childChanged(SGPropertyNode * child);
void updateImpl(double dt) override;
void childAdded(SGPropertyNode * child) override;
void childRemoved(SGPropertyNode * child) override;
void childChanged(SGPropertyNode * child) override;
void handleZIndexChanged(ElementPtr child, int z_index = 0);

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