Compare commits
217 Commits
a4fa5b9988
..
v0.3.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f8772f1bd | |||
| f09132f6b4 | |||
| bf57a67c43 | |||
| 091b3b3ee8 | |||
| 17033f1044 | |||
| 7c656fac71 | |||
| a6771b81c3 | |||
| eca184bac6 | |||
| 6ad2417804 | |||
| 21e87d8b6f | |||
| 52a5650a74 | |||
| 2158722ebc | |||
| bf11d66f60 | |||
| 371aa1e20c | |||
| 8348f61a94 | |||
| bf28918096 | |||
| 571aa6446d | |||
| 4290dd6e2f | |||
| de66664635 | |||
| 9e9c996813 | |||
| f67ea3803d | |||
| fa00e0dfd6 | |||
| ceaa76c497 | |||
| 9c9a5c2d8b | |||
| d611d83bb9 | |||
| 253b60217f | |||
| 39a536bb91 | |||
| 115a9d65f7 | |||
| 796920cb6b | |||
| c1c7d85195 | |||
| c5a6f76b1e | |||
| 5b198351be | |||
| 246d53201c | |||
| 999a239e67 | |||
| f091cb28ef | |||
| f415b0c94f | |||
| 0bf2afa5f8 | |||
| 706a9b1ebd | |||
| 4cec8b80a3 | |||
| 9e68b8c402 | |||
| 478ba82df7 | |||
| 7aef92dd68 | |||
| 01249bd115 | |||
| 9bee00c5dd | |||
| b9b274f2d6 | |||
| 4a17062487 | |||
| 1c73ce2c90 | |||
| 07a29c7f1d | |||
| f7a941406c | |||
| adecb88c29 | |||
| 857e19ed94 | |||
| f47224979e | |||
| c0833aa753 | |||
| 20d931a9ca | |||
| 1b2f8a1c6c | |||
| 95e75741ed | |||
| dc75c08081 | |||
| 8c204e317b | |||
| a672668c3a | |||
| 8638b53e45 | |||
| 394a6d045f | |||
| 29bbedcc8f | |||
| d66b4ffb37 | |||
| c0c4693782 | |||
| 9223d3da40 | |||
| 83e3f5ddbc | |||
| 0f4057aa97 | |||
| 591629e369 | |||
| 4a96ab3b13 | |||
| e955cff24f | |||
| fe405cfba8 | |||
| 92117aa791 | |||
| d4c2d9a871 | |||
| b2e2b91d31 | |||
| fa864c50cd | |||
| 1c6d1babe6 | |||
| ac27d1a9b6 | |||
| 28eb082655 | |||
| 9a945c156d | |||
| 83c742f7ec | |||
| 7a788c05c8 | |||
| 7b409a6ff4 | |||
| 87a631f5f0 | |||
| efd6b54ba7 | |||
| 553f2400e5 | |||
| 5c84e79e5b | |||
| 052b81ec8f | |||
| 7ecc550bc2 | |||
| b8267372e4 | |||
| 512dffabf4 | |||
| 50a3a56d2d | |||
| deb228948d | |||
| 58032b6ae4 | |||
| 7845736c05 | |||
| 77eb65d6b3 | |||
| 252c21b818 | |||
| 82c3b23e44 | |||
| 5764170975 | |||
| a2c85256e8 | |||
| 9419383ab0 | |||
| 4c63129876 | |||
| f2b876df49 | |||
| f229019ef5 | |||
| 3260bb7b89 | |||
| 2832572741 | |||
| 28df33b218 | |||
| 6ee0820659 | |||
| 2c73ccde9b | |||
| 90ce372081 | |||
| 15d75f7397 | |||
| f47c1a5024 | |||
| c74ed5135b | |||
| b08ecd21e6 | |||
| 1c98d47718 | |||
| 46e11f8d00 | |||
| 1e0a93e076 | |||
| f77f139abb | |||
| 2ae74d8cde | |||
| 369b5fd73a | |||
| 4de968d2f0 | |||
| 09b12701b5 | |||
| d00eee440c | |||
| c1df21f940 | |||
| 9117ad5381 | |||
| a96216e2f8 | |||
| 4140114d8d | |||
| bd34bf104f | |||
| 6a265efe48 | |||
| 983790a3ff | |||
| 43b65d5ca9 | |||
| 8bc61902ac | |||
| 4e0326ad6d | |||
| 808782b965 | |||
| 707f577f31 | |||
| 705244786e | |||
| 4e66e92671 | |||
| 283e7fae77 | |||
| 441936111a | |||
| f81a954d1d | |||
| 23c1730148 | |||
| 05257d287f | |||
| 64b5ebbdd2 | |||
| 91d6836fa5 | |||
| dd3613b214 | |||
| c96522c11b | |||
| 564b93f307 | |||
| 04eaf61c13 | |||
| b800dac9ce | |||
| 2cb78f5414 | |||
| 494459ee11 | |||
| 1cddbdf91e | |||
| 74ea603801 | |||
| 16854627d9 | |||
| 495c16892f | |||
| c596f23a05 | |||
| b69e042f21 | |||
| ec568966c8 | |||
| eb062fb0b8 | |||
| 9907a80136 | |||
| cd9079e7ff | |||
| 42a8338d1c | |||
| f44b1154b7 | |||
| 722f2f10ae | |||
| 2a7f38b187 | |||
| f9ab37530c | |||
| 442ff4b21d | |||
| ecacddb165 | |||
| 6aab2276ed | |||
| 5c9f9e8141 | |||
| 60563a7dc3 | |||
| 7255728049 | |||
| 50094fd8a9 | |||
| c45f4c137a | |||
| 16b46176a6 | |||
| 0df4bbcd29 | |||
| 3bbea95955 | |||
| fa0baad9a0 | |||
| 7b7493d560 | |||
| dc6de6d819 | |||
| b7a51a5764 | |||
| 145bc8d292 | |||
| f58ce3aec0 | |||
| 27b45a26d9 | |||
| 0653f81a0d | |||
| 1134cd5782 | |||
| aa1871dc66 | |||
| 56869d16a9 | |||
| ccf00dc460 | |||
| 57ad5fd0bc | |||
| 7d9553dd7c | |||
| cad3f43752 | |||
| 2605fb1a8f | |||
| 130b749dfe | |||
| 04bdf8574a | |||
| 0dfc805a49 | |||
| 022866b52b | |||
| 9ed0fe80d2 | |||
| 7837ff5d74 | |||
| bee42d1762 | |||
| 26c76662ac | |||
| e3a9762179 | |||
| d048f5a2ab | |||
| 0a95c79f3a | |||
| 762f0fb3e1 | |||
| 812b11a53d | |||
| c517b555d8 | |||
| f610e946fc | |||
| cb71c3dcf4 | |||
| 5c8ff568c3 | |||
| 87cdc7f7e7 | |||
| e694d862aa | |||
| 4df7aae11a | |||
| 55261b6149 | |||
| e3bea34342 | |||
| 79dd112598 | |||
| bc073fee9a | |||
| a32fe6a4dc |
@@ -1,2 +1,3 @@
|
||||
TAGS
|
||||
tags
|
||||
.svn
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
# To pass variables to cpack from cmake, they must be configured
|
||||
# in this file.
|
||||
|
||||
set (CPACK_SET_DESTDIR true)
|
||||
|
||||
set (CPACK_PACKAGE_VENDOR "@PROJECT_VENDOR@")
|
||||
set (CPACK_PACKAGE_CONTACT "@PROJECT_CONTACT@")
|
||||
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "@PROJECT_SUMMARY_DESCRIPTION@")
|
||||
set (CPACK_RESOURCE_FILE_LICENSE "@PROJECT_SOURCE_DIR@/COPYING")
|
||||
set (CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
|
||||
set (CPACK_PACKAGE_EXECUTABLES wsjtx "@PROJECT_NAME@")
|
||||
set (CPACK_CREATE_DESKTOP_LINKS wsjtx)
|
||||
set (CPACK_PACKAGE_EXECUTABLES ft8call "@PROJECT_NAME@")
|
||||
set (CPACK_CREATE_DESKTOP_LINKS ft8call)
|
||||
set (CPACK_STRIP_FILES TRUE)
|
||||
|
||||
#
|
||||
@@ -19,9 +21,10 @@ set (CPACK_STRIP_FILES TRUE)
|
||||
#set (CPACK_COMPONENT_RUNTIME_DESCRIPTION "@WSJTX_DESCRIPTION_SUMMARY@")
|
||||
|
||||
if (CPACK_GENERATOR MATCHES "NSIS")
|
||||
set (CPACK_SET_DESTDIR FALSE)
|
||||
set (CPACK_STRIP_FILES FALSE) # breaks Qt packaging on Windows
|
||||
|
||||
set (CPACK_NSIS_INSTALL_ROOT "C:\\WSJT")
|
||||
set (CPACK_NSIS_INSTALL_ROOT "C:\\FT8Call")
|
||||
|
||||
# set the install/unistall icon used for the installer itself
|
||||
# There is a bug in NSI that does not handle full unix paths properly.
|
||||
@@ -35,13 +38,13 @@ if (CPACK_GENERATOR MATCHES "NSIS")
|
||||
"@PROJECT_HOMEPAGE@" "@PROJECT_NAME@ Web Site"
|
||||
)
|
||||
# Use the icon from wsjtx for add-remove programs
|
||||
set (CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\wsjtx.exe")
|
||||
set (CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\ft8call.exe")
|
||||
|
||||
set (CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
|
||||
set (CPACK_NSIS_HELP_LINK "@PROJECT_MANUAL_DIRECTORY_URL@/@PROJECT_MANUAL@")
|
||||
set (CPACK_NSIS_URL_INFO_ABOUT "@PROJECT_HOMEPAGE@")
|
||||
set (CPACK_NSIS_CONTACT "${CPACK_PACKAGE_CONTACT}")
|
||||
set (CPACK_NSIS_MUI_FINISHPAGE_RUN "wsjtx.exe")
|
||||
set (CPACK_NSIS_MUI_FINISHPAGE_RUN "ft8call.exe")
|
||||
set (CPACK_NSIS_MODIFY_PATH ON)
|
||||
endif ()
|
||||
|
||||
@@ -65,9 +68,9 @@ if ("${CPACK_GENERATOR}" STREQUAL "WIX")
|
||||
# Reset CPACK_PACKAGE_VERSION to deal with WiX restriction.
|
||||
# But the file names still use the full CMake_VERSION value:
|
||||
set (CPACK_PACKAGE_FILE_NAME
|
||||
"${CPACK_PACKAGE_NAME}-@wsjtx_VERSION@-${CPACK_SYSTEM_NAME}")
|
||||
"${CPACK_PACKAGE_NAME}-@ft8call_VERSION@-${CPACK_SYSTEM_NAME}")
|
||||
set (CPACK_SOURCE_PACKAGE_FILE_NAME
|
||||
"${CPACK_PACKAGE_NAME}-@wsjtx_VERSION@-Source")
|
||||
"${CPACK_PACKAGE_NAME}-@ft8call_VERSION@-Source")
|
||||
|
||||
if (NOT CPACK_WIX_SIZEOF_VOID_P)
|
||||
set (CPACK_WIX_SIZEOF_VOID_P "@CMAKE_SIZEOF_VOID_P@")
|
||||
|
||||
@@ -22,7 +22,7 @@ Change this to the newest SDK available that you can install on your system (10.
|
||||
Do not override this if you intend to build an official deployable installer.")
|
||||
endif (APPLE)
|
||||
|
||||
project (wsjtx C CXX Fortran)
|
||||
project (ft8call C CXX Fortran)
|
||||
|
||||
#
|
||||
# CMake policies
|
||||
@@ -45,10 +45,10 @@ message (STATUS "Building ${CMAKE_PROJECT_NAME}-${wsjtx_VERSION}")
|
||||
#
|
||||
# project information
|
||||
#
|
||||
set (PROJECT_NAME "WSJT-X")
|
||||
set (PROJECT_VENDOR "Joe Taylor, K1JT")
|
||||
set (PROJECT_CONTACT "Joe Taylor <k1jt@arrl.net>")
|
||||
set (PROJECT_COPYRIGHT "Copyright (C) 2001-2017 by Joe Taylor, K1JT")
|
||||
set (PROJECT_NAME "FT8Call")
|
||||
set (PROJECT_VENDOR "Jordan Sherer, KN4CRD")
|
||||
set (PROJECT_CONTACT "Jordan Sherer <kn4crd@gmail.com>")
|
||||
set (PROJECT_COPYRIGHT "Copyright (C) 2001-2018 by Joe Taylor, K1JT, (C) 2018 by Jordan Sherer, KN4CRD")
|
||||
set (PROJECT_HOMEPAGE http://www.physics.princeton.edu/pulsar/K1JT/wsjtx.html)
|
||||
set (PROJECT_MANUAL wsjtx-main)
|
||||
set (PROJECT_MANUAL_DIRECTORY_URL http://www.physics.princeton.edu/pulsar/K1JT/wsjtx-doc/)
|
||||
@@ -303,6 +303,7 @@ set (wsjtx_CXXSRCS
|
||||
astro.cpp
|
||||
messageaveraging.cpp
|
||||
WsprTxScheduler.cpp
|
||||
varicode.cpp
|
||||
mainwindow.cpp
|
||||
Configuration.cpp
|
||||
main.cpp
|
||||
@@ -366,12 +367,12 @@ set (wsjt_FSRCS
|
||||
lib/averms.f90
|
||||
lib/azdist.f90
|
||||
lib/badmsg.f90
|
||||
lib/fsk4hf/baseline.f90
|
||||
lib/ft8/baseline.f90
|
||||
lib/bpdecode40.f90
|
||||
lib/bpdecode144.f90
|
||||
lib/fsk4hf/bpdecode120.f90
|
||||
lib/fsk4hf/bpdecode168.f90
|
||||
lib/fsk4hf/bpdecode174.f90
|
||||
lib/ft8/bpdecode174.f90
|
||||
lib/fsk4hf/bpdecode300.f90
|
||||
lib/baddata.f90
|
||||
lib/calibrate.f90
|
||||
@@ -379,11 +380,12 @@ set (wsjt_FSRCS
|
||||
lib/ccf65.f90
|
||||
lib/fsk4hf/chkcrc10.f90
|
||||
lib/fsk4hf/chkcrc12.f90
|
||||
lib/fsk4hf/chkcrc12a.f90
|
||||
lib/ft8/chkcrc12a.f90
|
||||
lib/chkcall.f90
|
||||
lib/chkhist.f90
|
||||
lib/chkmsg.f90
|
||||
lib/chkss2.f90
|
||||
lib/ft8/compress.f90
|
||||
lib/coord.f90
|
||||
lib/fsk4hf/cpolyfit.f90
|
||||
lib/fsk4hf/cpolyfitw.f90
|
||||
@@ -405,7 +407,7 @@ set (wsjt_FSRCS
|
||||
lib/encode_msk144.f90
|
||||
lib/fsk4hf/encode120.f90
|
||||
lib/fsk4hf/encode168.f90
|
||||
lib/fsk4hf/encode174.f90
|
||||
lib/ft8/encode174.f90
|
||||
lib/fsk4hf/encode300.f90
|
||||
lib/entail.f90
|
||||
lib/ephem.f90
|
||||
@@ -413,7 +415,7 @@ set (wsjt_FSRCS
|
||||
lib/extract4.f90
|
||||
lib/extractmessage144.f90
|
||||
lib/fsk4hf/extractmessage168.f90
|
||||
lib/fsk4hf/extractmessage174.f90
|
||||
lib/ft8/extractmessage174.f90
|
||||
lib/fano232.f90
|
||||
lib/fast9.f90
|
||||
lib/fast_decode.f90
|
||||
@@ -425,6 +427,7 @@ set (wsjt_FSRCS
|
||||
lib/fil4.f90
|
||||
lib/fil6521.f90
|
||||
lib/filbig.f90
|
||||
lib/ft8/filt8.f90
|
||||
lib/fitcal.f90
|
||||
lib/fix_contest_msg.f90
|
||||
lib/flat1.f90
|
||||
@@ -436,19 +439,23 @@ set (wsjt_FSRCS
|
||||
lib/fmtmsg.f90
|
||||
lib/foldspec9f.f90
|
||||
lib/four2a.f90
|
||||
lib/ft8/foxfilt.f90
|
||||
lib/ft8/foxgen.f90
|
||||
lib/ft8/foxgen_wrap.f90
|
||||
lib/fqso_first.f90
|
||||
lib/freqcal.f90
|
||||
lib/fsk4hf/fsk4hf.f90
|
||||
lib/fsk4hf/ft8apset.f90
|
||||
lib/fsk4hf/ft8b.f90
|
||||
lib/fsk4hf/ft8_downsample.f90
|
||||
lib/fsk4hf/ft8sim.f90
|
||||
lib/ft8/ft8apset.f90
|
||||
lib/ft8/ft8b.f90
|
||||
lib/ft8/ft8code.f90
|
||||
lib/ft8/ft8_downsample.f90
|
||||
lib/ft8/ft8sim.f90
|
||||
lib/gen4.f90
|
||||
lib/gen65.f90
|
||||
lib/gen9.f90
|
||||
lib/geniscat.f90
|
||||
lib/fsk4hf/genfsk4hf.f90
|
||||
lib/fsk4hf/genft8.f90
|
||||
lib/ft8/genft8.f90
|
||||
lib/genmsk144.f90
|
||||
lib/genmsk40.f90
|
||||
lib/fsk4hf/genmskhf.f90
|
||||
@@ -459,7 +466,7 @@ set (wsjt_FSRCS
|
||||
lib/fsk4hf/getfc1w.f90
|
||||
lib/fsk4hf/getfc2w.f90
|
||||
lib/genqra64.f90
|
||||
lib/fsk4hf/genft8refsig.f90
|
||||
lib/ft8/genft8refsig.f90
|
||||
lib/genwspr.f90
|
||||
lib/geodist.f90
|
||||
lib/getlags.f90
|
||||
@@ -468,6 +475,7 @@ set (wsjt_FSRCS
|
||||
lib/graycode65.f90
|
||||
lib/grayline.f90
|
||||
lib/grid2deg.f90
|
||||
lib/ft8/h1.f90
|
||||
lib/hash.f90
|
||||
lib/hint65.f90
|
||||
lib/hspec.f90
|
||||
@@ -484,7 +492,7 @@ set (wsjt_FSRCS
|
||||
lib/ldpcsim144.f90
|
||||
lib/fsk4hf/ldpcsim120.f90
|
||||
lib/fsk4hf/ldpcsim168.f90
|
||||
lib/fsk4hf/ldpcsim174.f90
|
||||
lib/ft8/ldpcsim174.f90
|
||||
lib/fsk4hf/ldpcsim300.f90
|
||||
lib/ldpcsim40.f90
|
||||
lib/libration.f90
|
||||
@@ -512,11 +520,12 @@ set (wsjt_FSRCS
|
||||
lib/mskrtd.f90
|
||||
lib/fsk4hf/msksoftsym.f90
|
||||
lib/fsk4hf/msksoftsymw.f90
|
||||
lib/fsk4hf/osd174.f90
|
||||
lib/ft8/osd174.f90
|
||||
lib/fsk4hf/osd300.f90
|
||||
lib/pctile.f90
|
||||
lib/peakdt9.f90
|
||||
lib/peakup.f90
|
||||
lib/plotsave.f90
|
||||
lib/polyfit.f90
|
||||
lib/fsk4hf/polyfit4.f90
|
||||
lib/prog_args.f90
|
||||
@@ -543,7 +552,7 @@ set (wsjt_FSRCS
|
||||
lib/spec9f.f90
|
||||
lib/stdmsg.f90
|
||||
lib/subtract65.f90
|
||||
lib/fsk4hf/subtractft8.f90
|
||||
lib/ft8/subtractft8.f90
|
||||
lib/sun.f90
|
||||
lib/symspec.f90
|
||||
lib/symspec2.f90
|
||||
@@ -551,8 +560,8 @@ set (wsjt_FSRCS
|
||||
lib/sync4.f90
|
||||
lib/sync64.f90
|
||||
lib/sync65.f90
|
||||
lib/fsk4hf/sync8.f90
|
||||
lib/fsk4hf/sync8d.f90
|
||||
lib/ft8/sync8.f90
|
||||
lib/ft8/sync8d.f90
|
||||
lib/sync9.f90
|
||||
lib/sync9f.f90
|
||||
lib/sync9w.f90
|
||||
@@ -561,12 +570,12 @@ set (wsjt_FSRCS
|
||||
lib/to_contest_msg.f90
|
||||
lib/tweak1.f90
|
||||
lib/twkfreq.f90
|
||||
lib/fsk4hf/twkfreq1.f90
|
||||
lib/ft8/twkfreq1.f90
|
||||
lib/twkfreq65.f90
|
||||
lib/unpackmsg144.f90
|
||||
lib/update_recent_calls.f90
|
||||
lib/update_hasharray.f90
|
||||
lib/fsk4hf/watterson.f90
|
||||
lib/ft8/watterson.f90
|
||||
lib/wav11.f90
|
||||
lib/wav12.f90
|
||||
lib/xcor.f90
|
||||
@@ -582,6 +591,9 @@ set (wsjt_FSRCS
|
||||
lib/zplot9.f90
|
||||
)
|
||||
|
||||
# temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit
|
||||
set_source_files_properties (lib/slasubs.f PROPERTIES COMPILE_FLAGS -O2)
|
||||
|
||||
set (ka9q_CSRCS
|
||||
lib/ftrsd/decode_rs.c
|
||||
lib/ftrsd/encode_rs.c
|
||||
@@ -602,7 +614,7 @@ set (qra_CSRCS
|
||||
|
||||
set (wsjt_CSRCS
|
||||
${ka9q_CSRCS}
|
||||
lib/ftrsd/ftrsd2.c
|
||||
lib/ftrsd/ftrsdap.c
|
||||
lib/sgran.c
|
||||
lib/golay24_table.c
|
||||
lib/gran.c
|
||||
@@ -675,6 +687,7 @@ set (message_aggregator_CXXSRCS
|
||||
UDPExamples/DecodesModel.cpp
|
||||
UDPExamples/BeaconsModel.cpp
|
||||
UDPExamples/ClientWidget.cpp
|
||||
MaidenheadLocatorValidator.cpp
|
||||
)
|
||||
|
||||
set (message_aggregator_STYLESHEETS
|
||||
@@ -943,7 +956,7 @@ if (Fortran_COMPILER_NAME MATCHES "gfortran.*")
|
||||
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -isysroot ${CMAKE_OSX_SYSROOT}")
|
||||
endif (CMAKE_OSX_SYSROOT)
|
||||
|
||||
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -funroll-all-loops -fno-f2c ${General_FFLAGS}")
|
||||
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -fbounds-check -funroll-all-loops -fno-f2c ${General_FFLAGS}")
|
||||
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fbounds-check -fno-f2c ${General_FFLAGS}")
|
||||
elseif (Fortran_COMPILER_NAME MATCHES "ifort.*")
|
||||
# ifort (untested)
|
||||
@@ -1202,8 +1215,8 @@ target_link_libraries (ldpcsim40 wsjt_fort wsjt_cxx)
|
||||
add_executable (ldpcsim120 lib/fsk4hf/ldpcsim120.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim120 wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ldpcsim300 lib/fsk4hf/ldpcsim300.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim300 wsjt_fort wsjt_cxx)
|
||||
add_executable (ldpcsim174 lib/ft8/ldpcsim174.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim174 wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ldpcsim144 lib/ldpcsim144.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim144 wsjt_fort wsjt_cxx)
|
||||
@@ -1214,7 +1227,10 @@ target_link_libraries (ldpcsim168 wsjt_fort wsjt_cxx)
|
||||
add_executable (fsk4hf lib/fsk4hf/fsk4hf.f90 wsjtx.rc)
|
||||
target_link_libraries (fsk4hf wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ft8sim lib/fsk4hf/ft8sim.f90 wsjtx.rc)
|
||||
add_executable (ft8code lib/ft8/ft8code.f90 wsjtx.rc)
|
||||
target_link_libraries (ft8code wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ft8sim lib/ft8/ft8sim.f90 wsjtx.rc)
|
||||
target_link_libraries (ft8sim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (wsprlfsim lib/fsk4hf/wsprlfsim.f90 wsjtx.rc)
|
||||
@@ -1283,7 +1299,7 @@ else (${OPENMP_FOUND} OR APPLE)
|
||||
endif (${OPENMP_FOUND} OR APPLE)
|
||||
|
||||
# build the main application
|
||||
add_executable (wsjtx MACOSX_BUNDLE
|
||||
add_executable (ft8call MACOSX_BUNDLE
|
||||
${wsjtx_CXXSRCS}
|
||||
${wsjtx_GENUISRCS}
|
||||
wsjtx.rc
|
||||
@@ -1292,10 +1308,10 @@ add_executable (wsjtx MACOSX_BUNDLE
|
||||
)
|
||||
|
||||
if (WSJT_CREATE_WINMAIN)
|
||||
set_target_properties (wsjtx PROPERTIES WIN32_EXECUTABLE ON)
|
||||
set_target_properties (ft8call PROPERTIES WIN32_EXECUTABLE ON)
|
||||
endif (WSJT_CREATE_WINMAIN)
|
||||
|
||||
set_target_properties (wsjtx PROPERTIES
|
||||
set_target_properties (ft8call PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_STRING "${WSJTX_DESCRIPTION_SUMMARY}"
|
||||
MACOSX_BUNDLE_ICON_FILE "${WSJTX_ICON_FILE}"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${wsjtx_VERSION}
|
||||
@@ -1306,27 +1322,27 @@ set_target_properties (wsjtx PROPERTIES
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "org.k1jt.wsjtx"
|
||||
)
|
||||
|
||||
target_include_directories (wsjtx PRIVATE ${FFTW3_INCLUDE_DIRS})
|
||||
target_include_directories (ft8call PRIVATE ${FFTW3_INCLUDE_DIRS})
|
||||
if (APPLE)
|
||||
target_link_libraries (wsjtx wsjt_fort wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
|
||||
target_link_libraries (ft8call wsjt_fort wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
|
||||
else ()
|
||||
target_link_libraries (wsjtx wsjt_fort_omp wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
|
||||
target_link_libraries (ft8call wsjt_fort_omp wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
|
||||
if (OpenMP_C_FLAGS)
|
||||
set_target_properties (wsjtx PROPERTIES
|
||||
set_target_properties (ft8call PROPERTIES
|
||||
COMPILE_FLAGS "${OpenMP_C_FLAGS}"
|
||||
LINK_FLAGS "${OpenMP_C_FLAGS}"
|
||||
)
|
||||
endif ()
|
||||
set_target_properties (wsjtx PROPERTIES
|
||||
set_target_properties (ft8call PROPERTIES
|
||||
Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
|
||||
)
|
||||
if (WIN32)
|
||||
set_target_properties (wsjtx PROPERTIES
|
||||
set_target_properties (ft8call PROPERTIES
|
||||
LINK_FLAGS -Wl,--stack,16777216
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
qt5_use_modules (wsjtx SerialPort) # not sure why the interface link library syntax above doesn't work
|
||||
qt5_use_modules (ft8call SerialPort) # not sure why the interface link library syntax above doesn't work
|
||||
|
||||
# make a library for WSJT-X UDP servers
|
||||
# add_library (wsjtx_udp SHARED ${UDP_library_CXXSRCS})
|
||||
@@ -1371,18 +1387,18 @@ endif (WSJT_CREATE_WINMAIN)
|
||||
if (UNIX)
|
||||
if (NOT WSJT_SKIP_MANPAGES)
|
||||
add_subdirectory (manpages)
|
||||
add_dependencies (wsjtx manpages)
|
||||
add_dependencies (ft8call manpages)
|
||||
endif (NOT WSJT_SKIP_MANPAGES)
|
||||
if (NOT APPLE)
|
||||
add_subdirectory (debian)
|
||||
add_dependencies (wsjtx debian)
|
||||
add_dependencies (ft8call debian)
|
||||
endif (NOT APPLE)
|
||||
endif (UNIX)
|
||||
|
||||
#
|
||||
# installation
|
||||
#
|
||||
install (TARGETS wsjtx
|
||||
install (TARGETS ft8call
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
BUNDLE DESTINATION . COMPONENT runtime
|
||||
)
|
||||
@@ -1409,7 +1425,7 @@ install (TARGETS udp_daemon message_aggregator
|
||||
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
)
|
||||
|
||||
install (TARGETS jt9 jt65code qra64code qra64sim jt9code jt4code
|
||||
install (TARGETS jt9 ft8code jt65code qra64code qra64sim jt9code jt4code
|
||||
msk144code wsprd wspr_fsk8d fmtave fcal fmeasure
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
@@ -1472,11 +1488,11 @@ add_custom_target (uninstall
|
||||
|
||||
|
||||
# creates svnversion.h using cmake script
|
||||
add_custom_target (revisiontag
|
||||
COMMAND ${CMAKE_COMMAND} -D SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -D OUTPUT_DIR=${PROJECT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/CMake/getsvn.cmake
|
||||
COMMENT "Generating Subversion revision information"
|
||||
VERBATIM
|
||||
)
|
||||
# add_custom_target (revisiontag
|
||||
# COMMAND ${CMAKE_COMMAND} -D SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -D OUTPUT_DIR=${PROJECT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/CMake/getsvn.cmake
|
||||
# COMMENT "Generating Subversion revision information"
|
||||
# VERBATIM
|
||||
# )
|
||||
# explicitly say that the wsjt_qt depends on custom target, this is
|
||||
# done indirectly so that the revisiontag target gets built exactly
|
||||
# once per build
|
||||
@@ -1496,7 +1512,7 @@ if (NOT WIN32 AND NOT APPLE)
|
||||
# install a desktop file so wsjtx appears in the application start
|
||||
# menu with an icon
|
||||
install (
|
||||
FILES wsjtx.desktop message_aggregator.desktop
|
||||
FILES ft8call.desktop message_aggregator.desktop
|
||||
DESTINATION share/applications
|
||||
#COMPONENT runtime
|
||||
)
|
||||
|
||||
@@ -10,6 +10,7 @@ auto CallsignValidator::validate (QString& input, int& pos) const -> State
|
||||
{
|
||||
auto match = re_.match (input, 0, QRegularExpression::PartialPreferCompleteMatch);
|
||||
input = input.toUpper ();
|
||||
if (input.count(QLatin1Char('/')) > 1) return Invalid;
|
||||
if (match.hasMatch ()) return Acceptable;
|
||||
if (!input.size () || match.hasPartialMatch ()) return Intermediate;
|
||||
pos = input.size ();
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
#include <QSettings>
|
||||
#include <QAudioDeviceInfo>
|
||||
#include <QAudioInput>
|
||||
#include <QDebug>
|
||||
#include <QDialog>
|
||||
#include <QAction>
|
||||
#include <QFileDialog>
|
||||
@@ -160,7 +161,6 @@
|
||||
#include <QColorDialog>
|
||||
#include <QSerialPortInfo>
|
||||
#include <QScopedPointer>
|
||||
#include <QDebug>
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
#include "qt_helpers.hpp"
|
||||
@@ -181,6 +181,8 @@
|
||||
#include "MaidenheadLocatorValidator.hpp"
|
||||
#include "CallsignValidator.hpp"
|
||||
|
||||
#include "varicode.h"
|
||||
|
||||
#include "ui_Configuration.h"
|
||||
#include "moc_Configuration.cpp"
|
||||
|
||||
@@ -430,6 +432,8 @@ private:
|
||||
Q_SLOT void on_add_macro_push_button_clicked (bool = false);
|
||||
Q_SLOT void on_delete_macro_push_button_clicked (bool = false);
|
||||
Q_SLOT void on_PTT_method_button_group_buttonClicked (int);
|
||||
Q_SLOT void on_station_message_line_edit_textChanged(QString const&);
|
||||
Q_SLOT void on_qth_message_line_edit_textChanged(QString const&);
|
||||
Q_SLOT void on_add_macro_line_edit_editingFinished ();
|
||||
Q_SLOT void delete_macro ();
|
||||
void delete_selected_macros (QModelIndexList);
|
||||
@@ -444,6 +448,10 @@ private:
|
||||
Q_SLOT void on_pbTxMsg_clicked();
|
||||
Q_SLOT void on_pbNewDXCC_clicked();
|
||||
Q_SLOT void on_pbNewCall_clicked();
|
||||
Q_SLOT void on_cbFox_clicked (bool);
|
||||
Q_SLOT void on_cbHound_clicked (bool);
|
||||
Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
|
||||
Q_SLOT void on_cbx4ToneSpacing_clicked(bool);
|
||||
|
||||
// typenames used as arguments must match registered type names :(
|
||||
Q_SIGNAL void start_transceiver (unsigned seqeunce_number) const;
|
||||
@@ -520,10 +528,16 @@ private:
|
||||
CalibrationParams calibration_;
|
||||
bool frequency_calibration_disabled_; // not persistent
|
||||
unsigned transceiver_command_number_;
|
||||
QString dynamic_grid_;
|
||||
|
||||
// configuration fields that we publish
|
||||
QString my_callsign_;
|
||||
QString my_grid_;
|
||||
QString my_station_;
|
||||
int my_dBm_;
|
||||
QString my_qth_;
|
||||
int callsign_aging_;
|
||||
int activity_aging_;
|
||||
QColor color_CQ_;
|
||||
QColor next_color_CQ_;
|
||||
QColor color_MyCall_;
|
||||
@@ -543,6 +557,7 @@ private:
|
||||
bool id_after_73_;
|
||||
bool tx_QSY_allowed_;
|
||||
bool spot_to_psk_reporter_;
|
||||
bool autoreply_off_at_startup_;
|
||||
bool monitor_off_at_startup_;
|
||||
bool monitor_last_used_;
|
||||
bool log_as_RTTY_;
|
||||
@@ -550,20 +565,33 @@ private:
|
||||
bool prompt_to_log_;
|
||||
bool insert_blank_;
|
||||
bool DXCC_;
|
||||
bool ppfx_;
|
||||
bool clear_DX_;
|
||||
bool miles_;
|
||||
bool quick_call_;
|
||||
bool disable_TX_on_73_;
|
||||
int beacon_;
|
||||
int watchdog_;
|
||||
bool TX_messages_;
|
||||
bool enable_VHF_features_;
|
||||
bool decode_at_52s_;
|
||||
bool single_decode_;
|
||||
bool twoPass_;
|
||||
bool bFox_;
|
||||
bool bHound_;
|
||||
bool x2ToneSpacing_;
|
||||
bool realTimeDecode_;
|
||||
bool x4ToneSpacing_;
|
||||
bool use_dynamic_grid_;
|
||||
QString opCall_;
|
||||
QString udp_server_name_;
|
||||
port_type udp_server_port_;
|
||||
// QString n1mm_server_name () const;
|
||||
QString n1mm_server_name_;
|
||||
port_type n1mm_server_port_;
|
||||
bool broadcast_to_n1mm_;
|
||||
// port_type n1mm_server_port () const;
|
||||
// bool valid_n1mm_info () const;
|
||||
// bool broadcast_to_n1mm() const;
|
||||
bool accept_udp_requests_;
|
||||
bool udpWindowToFront_;
|
||||
bool udpWindowRestore_;
|
||||
@@ -612,7 +640,6 @@ bool Configuration::restart_audio_input () const {return m_->restart_sound_input
|
||||
bool Configuration::restart_audio_output () const {return m_->restart_sound_output_device_;}
|
||||
auto Configuration::type_2_msg_gen () const -> Type2MsgGen {return m_->type_2_msg_gen_;}
|
||||
QString Configuration::my_callsign () const {return m_->my_callsign_;}
|
||||
QString Configuration::my_grid () const {return m_->my_grid_;}
|
||||
QColor Configuration::color_CQ () const {return m_->color_CQ_;}
|
||||
QColor Configuration::color_MyCall () const {return m_->color_MyCall_;}
|
||||
QColor Configuration::color_TxMsg () const {return m_->color_TxMsg_;}
|
||||
@@ -633,6 +660,15 @@ bool Configuration::spot_to_psk_reporter () const
|
||||
// rig must be open and working to spot externally
|
||||
return is_transceiver_online () && m_->spot_to_psk_reporter_;
|
||||
}
|
||||
void Configuration::set_spot_to_psk_reporter (bool spot)
|
||||
{
|
||||
if(m_->spot_to_psk_reporter_ != spot){
|
||||
m_->spot_to_psk_reporter_ = spot;
|
||||
m_->write_settings();
|
||||
}
|
||||
}
|
||||
|
||||
bool Configuration::autoreply_off_at_startup () const {return m_->autoreply_off_at_startup_;}
|
||||
bool Configuration::monitor_off_at_startup () const {return m_->monitor_off_at_startup_;}
|
||||
bool Configuration::monitor_last_used () const {return m_->rig_is_dummy_ || m_->monitor_last_used_;}
|
||||
bool Configuration::log_as_RTTY () const {return m_->log_as_RTTY_;}
|
||||
@@ -640,22 +676,30 @@ bool Configuration::report_in_comments () const {return m_->report_in_comments_;
|
||||
bool Configuration::prompt_to_log () const {return m_->prompt_to_log_;}
|
||||
bool Configuration::insert_blank () const {return m_->insert_blank_;}
|
||||
bool Configuration::DXCC () const {return m_->DXCC_;}
|
||||
bool Configuration::ppfx() const {return m_->ppfx_;}
|
||||
bool Configuration::clear_DX () const {return m_->clear_DX_;}
|
||||
bool Configuration::miles () const {return m_->miles_;}
|
||||
bool Configuration::quick_call () const {return m_->quick_call_;}
|
||||
bool Configuration::disable_TX_on_73 () const {return m_->disable_TX_on_73_;}
|
||||
int Configuration::beacon () const {return m_->beacon_;}
|
||||
int Configuration::watchdog () const {return m_->watchdog_;}
|
||||
bool Configuration::TX_messages () const {return m_->TX_messages_;}
|
||||
bool Configuration::enable_VHF_features () const {return m_->enable_VHF_features_;}
|
||||
bool Configuration::decode_at_52s () const {return m_->decode_at_52s_;}
|
||||
bool Configuration::single_decode () const {return m_->single_decode_;}
|
||||
bool Configuration::twoPass() const {return m_->twoPass_;}
|
||||
bool Configuration::bFox() const {return m_->bFox_;}
|
||||
bool Configuration::bHound() const {return m_->bHound_;}
|
||||
bool Configuration::x2ToneSpacing() const {return m_->x2ToneSpacing_;}
|
||||
bool Configuration::realTimeDecode() const {return m_->realTimeDecode_;}
|
||||
bool Configuration::x4ToneSpacing() const {return m_->x4ToneSpacing_;}
|
||||
bool Configuration::split_mode () const {return m_->split_mode ();}
|
||||
QString Configuration::opCall() const {return m_->opCall_;}
|
||||
QString Configuration::udp_server_name () const {return m_->udp_server_name_;}
|
||||
auto Configuration::udp_server_port () const -> port_type {return m_->udp_server_port_;}
|
||||
bool Configuration::accept_udp_requests () const {return m_->accept_udp_requests_;}
|
||||
QString Configuration::n1mm_server_name () const {return m_->n1mm_server_name_;}
|
||||
auto Configuration::n1mm_server_port () const -> port_type {return m_->n1mm_server_port_;}
|
||||
bool Configuration::broadcast_to_n1mm () const {return m_->broadcast_to_n1mm_;}
|
||||
bool Configuration::udpWindowToFront () const {return m_->udpWindowToFront_;}
|
||||
bool Configuration::udpWindowRestore () const {return m_->udpWindowRestore_;}
|
||||
Bands * Configuration::bands () {return &m_->bands_;}
|
||||
@@ -766,6 +810,55 @@ void Configuration::sync_transceiver (bool force_signal, bool enforce_mode_and_s
|
||||
}
|
||||
}
|
||||
|
||||
bool Configuration::valid_n1mm_info () const
|
||||
{
|
||||
// do very rudimentary checking on the n1mm server name and port number.
|
||||
//
|
||||
auto server_name = m_->n1mm_server_name_;
|
||||
auto port_number = m_->n1mm_server_port_;
|
||||
return(!(server_name.trimmed().isEmpty() || port_number == 0));
|
||||
}
|
||||
|
||||
QString Configuration::my_grid() const
|
||||
{
|
||||
auto the_grid = m_->my_grid_;
|
||||
if (m_->use_dynamic_grid_ && m_->dynamic_grid_.size () >= 4) {
|
||||
the_grid = m_->dynamic_grid_;
|
||||
}
|
||||
return the_grid;
|
||||
}
|
||||
|
||||
QString Configuration::my_station() const
|
||||
{
|
||||
return m_->my_station_;
|
||||
}
|
||||
|
||||
int Configuration::my_dBm() const {
|
||||
return m_->my_dBm_;
|
||||
}
|
||||
|
||||
QString Configuration::my_qth() const
|
||||
{
|
||||
return m_->my_qth_;
|
||||
}
|
||||
|
||||
int Configuration::callsign_aging() const
|
||||
{
|
||||
return m_->callsign_aging_;
|
||||
}
|
||||
|
||||
int Configuration::activity_aging() const
|
||||
{
|
||||
return m_->activity_aging_;
|
||||
}
|
||||
|
||||
void Configuration::set_location (QString const& grid_descriptor)
|
||||
{
|
||||
// change the dynamic grid
|
||||
qDebug () << "Configuration::set_location - location:" << grid_descriptor;
|
||||
m_->dynamic_grid_ = grid_descriptor.trimmed ();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
#if defined (Q_OS_MAC)
|
||||
@@ -897,10 +990,15 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
||||
ui_->callsign_line_edit->setValidator (new CallsignValidator {this});
|
||||
ui_->grid_line_edit->setValidator (new MaidenheadLocatorValidator {this});
|
||||
ui_->add_macro_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
|
||||
ui_->station_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
|
||||
ui_->qth_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
|
||||
|
||||
ui_->udp_server_port_spin_box->setMinimum (1);
|
||||
ui_->udp_server_port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
|
||||
|
||||
ui_->n1mm_server_port_spin_box->setMinimum (1);
|
||||
ui_->n1mm_server_port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
|
||||
|
||||
//
|
||||
// assign ids to radio buttons
|
||||
//
|
||||
@@ -1064,10 +1162,50 @@ void Configuration::impl::initialize_models ()
|
||||
{
|
||||
pal.setColor (QPalette::Base, Qt::white);
|
||||
}
|
||||
|
||||
QMap<int, int> dbm2mw = {
|
||||
{0 , 1},
|
||||
{3 , 2},
|
||||
{7 , 5},
|
||||
{10 , 10},
|
||||
{13 , 20},
|
||||
{17 , 50},
|
||||
{20 , 100},
|
||||
{23 , 200},
|
||||
{27 , 500},
|
||||
{30 , 1000}, // 1W
|
||||
{33 , 2000}, // 2W
|
||||
{37 , 5000}, // 5W
|
||||
{40 , 10000}, // 10W
|
||||
{43 , 20000}, // 20W
|
||||
{47 , 50000}, // 50W
|
||||
{50 , 100000}, // 100W
|
||||
{53 , 200000}, // 200W
|
||||
{57 , 500000}, // 500W
|
||||
{60 , 1000000}, // 1000W
|
||||
};
|
||||
|
||||
ui_->station_power_combo_box->clear();
|
||||
ui_->station_power_combo_box->addItem(QString(""), -1);
|
||||
|
||||
foreach(auto dbm, dbm2mw.keys()){
|
||||
ui_->station_power_combo_box->addItem(QString("%1 (%2 dBm)").arg(Varicode::formatPWR(dbm)).arg(dbm), dbm);
|
||||
|
||||
if(dbm == my_dBm_){
|
||||
ui_->station_power_combo_box->setCurrentIndex(ui_->station_power_combo_box->count()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ui_->callsign_line_edit->setPalette (pal);
|
||||
ui_->grid_line_edit->setPalette (pal);
|
||||
ui_->callsign_line_edit->setText (my_callsign_);
|
||||
ui_->grid_line_edit->setText (my_grid_);
|
||||
ui_->callsign_aging_spin_box->setValue(callsign_aging_);
|
||||
ui_->activity_aging_spin_box->setValue(activity_aging_);
|
||||
ui_->station_message_line_edit->setText (my_station_.toUpper());
|
||||
ui_->qth_message_line_edit->setText (my_qth_.toUpper());
|
||||
ui_->use_dynamic_grid->setChecked(use_dynamic_grid_);
|
||||
ui_->labCQ->setStyleSheet(QString("background: %1").arg(color_CQ_.name()));
|
||||
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(color_MyCall_.name()));
|
||||
ui_->labTx->setStyleSheet(QString("background: %1").arg(color_TxMsg_.name()));
|
||||
@@ -1085,6 +1223,7 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->CW_id_after_73_check_box->setChecked (id_after_73_);
|
||||
ui_->tx_QSY_check_box->setChecked (tx_QSY_allowed_);
|
||||
ui_->psk_reporter_check_box->setChecked (spot_to_psk_reporter_);
|
||||
ui_->autoreply_off_check_box->setChecked (autoreply_off_at_startup_);
|
||||
ui_->monitor_off_check_box->setChecked (monitor_off_at_startup_);
|
||||
ui_->monitor_last_used_check_box->setChecked (monitor_last_used_);
|
||||
ui_->log_as_RTTY_check_box->setChecked (log_as_RTTY_);
|
||||
@@ -1092,19 +1231,22 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->prompt_to_log_check_box->setChecked (prompt_to_log_);
|
||||
ui_->insert_blank_check_box->setChecked (insert_blank_);
|
||||
ui_->DXCC_check_box->setChecked (DXCC_);
|
||||
ui_->ppfx_check_box->setChecked (ppfx_);
|
||||
ui_->clear_DX_check_box->setChecked (clear_DX_);
|
||||
ui_->miles_check_box->setChecked (miles_);
|
||||
ui_->quick_call_check_box->setChecked (quick_call_);
|
||||
ui_->disable_TX_on_73_check_box->setChecked (disable_TX_on_73_);
|
||||
ui_->beacon_spin_box->setValue (beacon_);
|
||||
ui_->tx_watchdog_spin_box->setValue (watchdog_);
|
||||
ui_->TX_messages_check_box->setChecked (TX_messages_);
|
||||
ui_->enable_VHF_features_check_box->setChecked(enable_VHF_features_);
|
||||
ui_->decode_at_52s_check_box->setChecked(decode_at_52s_);
|
||||
ui_->single_decode_check_box->setChecked(single_decode_);
|
||||
ui_->cbTwoPass->setChecked(twoPass_);
|
||||
ui_->cbFox->setChecked(bFox_);
|
||||
ui_->cbHound->setChecked(bHound_);
|
||||
ui_->cbx2ToneSpacing->setChecked(x2ToneSpacing_);
|
||||
ui_->cbRealTime->setChecked(realTimeDecode_);
|
||||
ui_->cbRealTime->setVisible(false); //Tempoary -- probably will remove this control
|
||||
ui_->cbx4ToneSpacing->setChecked(x4ToneSpacing_);
|
||||
ui_->type_2_msg_gen_combo_box->setCurrentIndex (type_2_msg_gen_);
|
||||
ui_->rig_combo_box->setCurrentText (rig_params_.rig_name);
|
||||
ui_->TX_mode_button_group->button (data_mode_)->setChecked (true);
|
||||
@@ -1133,9 +1275,13 @@ void Configuration::impl::initialize_models ()
|
||||
}
|
||||
ui_->TX_audio_source_button_group->button (rig_params_.audio_source)->setChecked (true);
|
||||
ui_->CAT_poll_interval_spin_box->setValue (rig_params_.poll_interval);
|
||||
ui_->opCallEntry->setText (opCall_);
|
||||
ui_->udp_server_line_edit->setText (udp_server_name_);
|
||||
ui_->udp_server_port_spin_box->setValue (udp_server_port_);
|
||||
ui_->accept_udp_requests_check_box->setChecked (accept_udp_requests_);
|
||||
ui_->n1mm_server_name_line_edit->setText (n1mm_server_name_);
|
||||
ui_->n1mm_server_port_spin_box->setValue (n1mm_server_port_);
|
||||
ui_->enable_n1mm_broadcast_check_box->setChecked (broadcast_to_n1mm_);
|
||||
ui_->udpWindowToFront->setChecked(udpWindowToFront_);
|
||||
ui_->udpWindowRestore->setChecked(udpWindowRestore_);
|
||||
ui_->calibration_intercept_spin_box->setValue (calibration_.intercept);
|
||||
@@ -1178,6 +1324,11 @@ void Configuration::impl::read_settings ()
|
||||
|
||||
my_callsign_ = settings_->value ("MyCall", QString {}).toString ();
|
||||
my_grid_ = settings_->value ("MyGrid", QString {}).toString ();
|
||||
my_station_ = settings_->value("MyStation", QString {}).toString();
|
||||
my_dBm_ = settings_->value("MyPower", -1).toInt();
|
||||
callsign_aging_ = settings_->value ("CallsignAging", 0).toInt ();
|
||||
activity_aging_ = settings_->value ("ActivityAging", 2).toInt ();
|
||||
my_qth_ = settings_->value("MyQTH", QString {}).toString();
|
||||
next_color_CQ_ = color_CQ_ = settings_->value("colorCQ","#66ff66").toString();
|
||||
next_color_MyCall_ = color_MyCall_ = settings_->value("colorMyCall","#ff6666").toString();
|
||||
next_color_TxMsg_ = color_TxMsg_ = settings_->value("colorTxMsg","#ffff00").toString();
|
||||
@@ -1271,13 +1422,17 @@ void Configuration::impl::read_settings ()
|
||||
|
||||
type_2_msg_gen_ = settings_->value ("Type2MsgGen", QVariant::fromValue (Configuration::type_2_msg_3_full)).value<Configuration::Type2MsgGen> ();
|
||||
|
||||
autoreply_off_at_startup_ = settings_->value ("AutoreplyOFF", false).toBool ();
|
||||
monitor_off_at_startup_ = settings_->value ("MonitorOFF", false).toBool ();
|
||||
monitor_last_used_ = settings_->value ("MonitorLastUsed", false).toBool ();
|
||||
spot_to_psk_reporter_ = settings_->value ("PSKReporter", false).toBool ();
|
||||
id_after_73_ = settings_->value ("After73", false).toBool ();
|
||||
tx_QSY_allowed_ = settings_->value ("TxQSYAllowed", false).toBool ();
|
||||
use_dynamic_grid_ = settings_->value ("AutoGrid", false).toBool ();
|
||||
|
||||
macros_.setStringList (settings_->value ("Macros", QStringList {"TNX 73 GL"}).toStringList ());
|
||||
auto loadedMacros = settings_->value ("Macros", QStringList {"TNX 73 GL"}).toStringList();
|
||||
|
||||
macros_.setStringList (loadedMacros);
|
||||
|
||||
region_ = settings_->value ("Region", QVariant::fromValue (IARURegions::ALL)).value<IARURegions::Region> ();
|
||||
|
||||
@@ -1322,22 +1477,30 @@ void Configuration::impl::read_settings ()
|
||||
prompt_to_log_ = settings_->value ("PromptToLog", false).toBool ();
|
||||
insert_blank_ = settings_->value ("InsertBlank", false).toBool ();
|
||||
DXCC_ = settings_->value ("DXCCEntity", false).toBool ();
|
||||
ppfx_ = settings_->value ("PrincipalPrefix", false).toBool ();
|
||||
clear_DX_ = settings_->value ("ClearCallGrid", false).toBool ();
|
||||
miles_ = settings_->value ("Miles", false).toBool ();
|
||||
quick_call_ = settings_->value ("QuickCall", false).toBool ();
|
||||
disable_TX_on_73_ = settings_->value ("73TxDisable", false).toBool ();
|
||||
watchdog_ = settings_->value ("TxWatchdog", 6).toInt ();
|
||||
beacon_ = settings_->value ("TxBeacon", 15).toInt ();
|
||||
watchdog_ = settings_->value ("TxWatchdog", 0).toInt ();
|
||||
TX_messages_ = settings_->value ("Tx2QSO", true).toBool ();
|
||||
enable_VHF_features_ = settings_->value("VHFUHF",false).toBool ();
|
||||
decode_at_52s_ = settings_->value("Decode52",false).toBool ();
|
||||
single_decode_ = settings_->value("SingleDecode",false).toBool ();
|
||||
twoPass_ = settings_->value("TwoPass",true).toBool ();
|
||||
bFox_ = settings_->value("Fox",false).toBool ();
|
||||
bHound_ = settings_->value("Hound",false).toBool ();
|
||||
x2ToneSpacing_ = settings_->value("x2ToneSpacing",false).toBool ();
|
||||
realTimeDecode_ = settings_->value("RealTimeDecode",false).toBool ();
|
||||
x4ToneSpacing_ = settings_->value("x4ToneSpacing",false).toBool ();
|
||||
rig_params_.poll_interval = settings_->value ("Polling", 0).toInt ();
|
||||
rig_params_.split_mode = settings_->value ("SplitMode", QVariant::fromValue (TransceiverFactory::split_mode_none)).value<TransceiverFactory::SplitMode> ();
|
||||
opCall_ = settings_->value ("OpCall", "").toString ();
|
||||
udp_server_name_ = settings_->value ("UDPServer", "127.0.0.1").toString ();
|
||||
udp_server_port_ = settings_->value ("UDPServerPort", 2237).toUInt ();
|
||||
n1mm_server_name_ = settings_->value ("N1MMServer", "127.0.0.1").toString ();
|
||||
n1mm_server_port_ = settings_->value ("N1MMServerPort", 2333).toUInt ();
|
||||
broadcast_to_n1mm_ = settings_->value ("BroadcastToN1MM", false).toBool ();
|
||||
accept_udp_requests_ = settings_->value ("AcceptUDPRequests", false).toBool ();
|
||||
udpWindowToFront_ = settings_->value ("udpWindowToFront",false).toBool ();
|
||||
udpWindowRestore_ = settings_->value ("udpWindowRestore",false).toBool ();
|
||||
@@ -1353,6 +1516,11 @@ void Configuration::impl::write_settings ()
|
||||
|
||||
settings_->setValue ("MyCall", my_callsign_);
|
||||
settings_->setValue ("MyGrid", my_grid_);
|
||||
settings_->setValue ("MyStation", my_station_);
|
||||
settings_->setValue ("MyPower", my_dBm_);
|
||||
settings_->setValue ("MyQTH", my_qth_);
|
||||
settings_->setValue ("CallsignAging", callsign_aging_);
|
||||
settings_->setValue ("ActivityAging", activity_aging_);
|
||||
settings_->setValue("colorCQ",color_CQ_);
|
||||
settings_->setValue("colorMyCall",color_MyCall_);
|
||||
settings_->setValue("colorTxMsg",color_TxMsg_);
|
||||
@@ -1391,6 +1559,7 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("AudioInputChannel", AudioDevice::toString (audio_input_channel_));
|
||||
settings_->setValue ("AudioOutputChannel", AudioDevice::toString (audio_output_channel_));
|
||||
settings_->setValue ("Type2MsgGen", QVariant::fromValue (type_2_msg_gen_));
|
||||
settings_->setValue ("AutoreplyOFF", autoreply_off_at_startup_);
|
||||
settings_->setValue ("MonitorOFF", monitor_off_at_startup_);
|
||||
settings_->setValue ("MonitorLastUsed", monitor_last_used_);
|
||||
settings_->setValue ("PSKReporter", spot_to_psk_reporter_);
|
||||
@@ -1413,10 +1582,12 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("PromptToLog", prompt_to_log_);
|
||||
settings_->setValue ("InsertBlank", insert_blank_);
|
||||
settings_->setValue ("DXCCEntity", DXCC_);
|
||||
settings_->setValue ("PrincipalPrefix", ppfx_);
|
||||
settings_->setValue ("ClearCallGrid", clear_DX_);
|
||||
settings_->setValue ("Miles", miles_);
|
||||
settings_->setValue ("QuickCall", quick_call_);
|
||||
settings_->setValue ("73TxDisable", disable_TX_on_73_);
|
||||
settings_->setValue ("TxBeacon", beacon_);
|
||||
settings_->setValue ("TxWatchdog", watchdog_);
|
||||
settings_->setValue ("Tx2QSO", TX_messages_);
|
||||
settings_->setValue ("CATForceDTR", rig_params_.force_dtr);
|
||||
@@ -1430,10 +1601,16 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("Decode52", decode_at_52s_);
|
||||
settings_->setValue ("SingleDecode", single_decode_);
|
||||
settings_->setValue ("TwoPass", twoPass_);
|
||||
settings_->setValue ("Fox", bFox_);
|
||||
settings_->setValue ("Hound", bHound_);
|
||||
settings_->setValue ("x2ToneSpacing", x2ToneSpacing_);
|
||||
settings_->setValue ("RealTimeDecode", realTimeDecode_);
|
||||
settings_->setValue ("x4ToneSpacing", x4ToneSpacing_);
|
||||
settings_->setValue ("OpCall", opCall_);
|
||||
settings_->setValue ("UDPServer", udp_server_name_);
|
||||
settings_->setValue ("UDPServerPort", udp_server_port_);
|
||||
settings_->setValue ("N1MMServer", n1mm_server_name_);
|
||||
settings_->setValue ("N1MMServerPort", n1mm_server_port_);
|
||||
settings_->setValue ("BroadcastToN1MM", broadcast_to_n1mm_);
|
||||
settings_->setValue ("AcceptUDPRequests", accept_udp_requests_);
|
||||
settings_->setValue ("udpWindowToFront", udpWindowToFront_);
|
||||
settings_->setValue ("udpWindowRestore", udpWindowRestore_);
|
||||
@@ -1442,6 +1619,7 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("pwrBandTxMemory", pwrBandTxMemory_);
|
||||
settings_->setValue ("pwrBandTuneMemory", pwrBandTuneMemory_);
|
||||
settings_->setValue ("Region", QVariant::fromValue (region_));
|
||||
settings_->setValue ("AutoGrid", use_dynamic_grid_);
|
||||
}
|
||||
|
||||
void Configuration::impl::set_rig_invariants ()
|
||||
@@ -1795,6 +1973,11 @@ void Configuration::impl::accept ()
|
||||
|
||||
my_callsign_ = ui_->callsign_line_edit->text ();
|
||||
my_grid_ = ui_->grid_line_edit->text ();
|
||||
my_station_ = ui_->station_message_line_edit->text().toUpper();
|
||||
my_dBm_ = ui_->station_power_combo_box->currentData().toInt();
|
||||
my_qth_ = ui_->qth_message_line_edit->text().toUpper();
|
||||
callsign_aging_ = ui_->callsign_aging_spin_box->value();
|
||||
activity_aging_ = ui_->activity_aging_spin_box->value();
|
||||
spot_to_psk_reporter_ = ui_->psk_reporter_check_box->isChecked ();
|
||||
id_interval_ = ui_->CW_id_interval_spin_box->value ();
|
||||
ntrials_ = ui_->sbNtrials->value ();
|
||||
@@ -1804,6 +1987,7 @@ void Configuration::impl::accept ()
|
||||
RxBandwidth_ = ui_->sbBandwidth->value ();
|
||||
id_after_73_ = ui_->CW_id_after_73_check_box->isChecked ();
|
||||
tx_QSY_allowed_ = ui_->tx_QSY_check_box->isChecked ();
|
||||
autoreply_off_at_startup_ = ui_->autoreply_off_check_box->isChecked ();
|
||||
monitor_off_at_startup_ = ui_->monitor_off_check_box->isChecked ();
|
||||
monitor_last_used_ = ui_->monitor_last_used_check_box->isChecked ();
|
||||
type_2_msg_gen_ = static_cast<Type2MsgGen> (ui_->type_2_msg_gen_combo_box->currentIndex ());
|
||||
@@ -1812,10 +1996,12 @@ void Configuration::impl::accept ()
|
||||
prompt_to_log_ = ui_->prompt_to_log_check_box->isChecked ();
|
||||
insert_blank_ = ui_->insert_blank_check_box->isChecked ();
|
||||
DXCC_ = ui_->DXCC_check_box->isChecked ();
|
||||
ppfx_ = ui_->ppfx_check_box->isChecked ();
|
||||
clear_DX_ = ui_->clear_DX_check_box->isChecked ();
|
||||
miles_ = ui_->miles_check_box->isChecked ();
|
||||
quick_call_ = ui_->quick_call_check_box->isChecked ();
|
||||
disable_TX_on_73_ = ui_->disable_TX_on_73_check_box->isChecked ();
|
||||
beacon_ = ui_->beacon_spin_box->value ();
|
||||
watchdog_ = ui_->tx_watchdog_spin_box->value ();
|
||||
TX_messages_ = ui_->TX_messages_check_box->isChecked ();
|
||||
data_mode_ = static_cast<DataMode> (ui_->TX_mode_button_group->checkedId ());
|
||||
@@ -1825,12 +2011,15 @@ void Configuration::impl::accept ()
|
||||
decode_at_52s_ = ui_->decode_at_52s_check_box->isChecked ();
|
||||
single_decode_ = ui_->single_decode_check_box->isChecked ();
|
||||
twoPass_ = ui_->cbTwoPass->isChecked ();
|
||||
bFox_ = ui_->cbFox->isChecked ();
|
||||
bHound_ = ui_->cbHound->isChecked ();
|
||||
x2ToneSpacing_ = ui_->cbx2ToneSpacing->isChecked ();
|
||||
realTimeDecode_ = ui_->cbRealTime->isChecked ();
|
||||
x4ToneSpacing_ = ui_->cbx4ToneSpacing->isChecked ();
|
||||
calibration_.intercept = ui_->calibration_intercept_spin_box->value ();
|
||||
calibration_.slope_ppm = ui_->calibration_slope_ppm_spin_box->value ();
|
||||
pwrBandTxMemory_ = ui_->checkBoxPwrBandTxMemory->isChecked ();
|
||||
pwrBandTuneMemory_ = ui_->checkBoxPwrBandTuneMemory->isChecked ();
|
||||
opCall_=ui_->opCallEntry->text();
|
||||
auto new_server = ui_->udp_server_line_edit->text ();
|
||||
if (new_server != udp_server_name_)
|
||||
{
|
||||
@@ -1846,6 +2035,12 @@ void Configuration::impl::accept ()
|
||||
}
|
||||
|
||||
accept_udp_requests_ = ui_->accept_udp_requests_check_box->isChecked ();
|
||||
auto new_n1mm_server = ui_->n1mm_server_name_line_edit->text ();
|
||||
n1mm_server_name_ = new_n1mm_server;
|
||||
auto new_n1mm_port = ui_->n1mm_server_port_spin_box->value ();
|
||||
n1mm_server_port_ = new_n1mm_port;
|
||||
broadcast_to_n1mm_ = ui_->enable_n1mm_broadcast_check_box->isChecked ();
|
||||
|
||||
udpWindowToFront_ = ui_->udpWindowToFront->isChecked ();
|
||||
udpWindowRestore_ = ui_->udpWindowRestore->isChecked ();
|
||||
|
||||
@@ -1867,7 +2062,14 @@ void Configuration::impl::accept ()
|
||||
stations_.station_list(next_stations_.station_list ());
|
||||
stations_.sort (StationList::band_column);
|
||||
}
|
||||
|
||||
|
||||
if (ui_->use_dynamic_grid->isChecked() && !use_dynamic_grid_ )
|
||||
{
|
||||
// turning on so clear it so only the next location update gets used
|
||||
dynamic_grid_.clear ();
|
||||
}
|
||||
use_dynamic_grid_ = ui_->use_dynamic_grid->isChecked();
|
||||
|
||||
write_settings (); // make visible to all
|
||||
}
|
||||
|
||||
@@ -2060,6 +2262,22 @@ void Configuration::impl::on_sound_output_combo_box_currentTextChanged (QString
|
||||
default_audio_output_device_selected_ = QAudioDeviceInfo::defaultOutputDevice ().deviceName () == text;
|
||||
}
|
||||
|
||||
void Configuration::impl::on_station_message_line_edit_textChanged(QString const &text)
|
||||
{
|
||||
QString upper = text.toUpper();
|
||||
if(text != upper){
|
||||
ui_->station_message_line_edit->setText (upper);
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_qth_message_line_edit_textChanged(QString const &text)
|
||||
{
|
||||
QString upper = text.toUpper();
|
||||
if(text != upper){
|
||||
ui_->qth_message_line_edit->setText (upper);
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_add_macro_line_edit_editingFinished ()
|
||||
{
|
||||
ui_->add_macro_line_edit->setText (ui_->add_macro_line_edit->text ().toUpper ());
|
||||
@@ -2295,6 +2513,26 @@ void Configuration::impl::on_calibration_slope_ppm_spin_box_valueChanged (double
|
||||
rig_active_ = false; // force reset
|
||||
}
|
||||
|
||||
void Configuration::impl::on_cbFox_clicked (bool checked)
|
||||
{
|
||||
if (checked) ui_->cbHound->setChecked (false);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_cbHound_clicked (bool checked)
|
||||
{
|
||||
if (checked) ui_->cbFox->setChecked (false);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_cbx2ToneSpacing_clicked(bool b)
|
||||
{
|
||||
if(b) ui_->cbx4ToneSpacing->setChecked(false);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_cbx4ToneSpacing_clicked(bool b)
|
||||
{
|
||||
if(b) ui_->cbx2ToneSpacing->setChecked(false);
|
||||
}
|
||||
|
||||
bool Configuration::impl::have_rig ()
|
||||
{
|
||||
if (!open_rig ())
|
||||
|
||||
@@ -96,6 +96,11 @@ public:
|
||||
|
||||
QString my_callsign () const;
|
||||
QString my_grid () const;
|
||||
QString my_station () const;
|
||||
int my_dBm() const;
|
||||
int activity_aging() const;
|
||||
int callsign_aging() const;
|
||||
QString my_qth () const;
|
||||
QFont text_font () const;
|
||||
QFont decoded_text_font () const;
|
||||
qint32 id_interval () const;
|
||||
@@ -107,6 +112,8 @@ public:
|
||||
bool id_after_73 () const;
|
||||
bool tx_QSY_allowed () const;
|
||||
bool spot_to_psk_reporter () const;
|
||||
void set_spot_to_psk_reporter (bool);
|
||||
bool autoreply_off_at_startup () const;
|
||||
bool monitor_off_at_startup () const;
|
||||
bool monitor_last_used () const;
|
||||
bool log_as_RTTY () const;
|
||||
@@ -114,10 +121,12 @@ public:
|
||||
bool prompt_to_log () const;
|
||||
bool insert_blank () const;
|
||||
bool DXCC () const;
|
||||
bool ppfx() const;
|
||||
bool clear_DX () const;
|
||||
bool miles () const;
|
||||
bool quick_call () const;
|
||||
bool disable_TX_on_73 () const;
|
||||
int beacon () const;
|
||||
int watchdog () const;
|
||||
bool TX_messages () const;
|
||||
bool split_mode () const;
|
||||
@@ -125,17 +134,24 @@ public:
|
||||
bool decode_at_52s () const;
|
||||
bool single_decode () const;
|
||||
bool twoPass() const;
|
||||
bool bFox() const;
|
||||
bool bHound() const;
|
||||
bool x2ToneSpacing() const;
|
||||
bool x4ToneSpacing() const;
|
||||
bool contestMode() const;
|
||||
bool realTimeDecode() const;
|
||||
bool MyDx() const;
|
||||
bool CQMyN() const;
|
||||
bool NDxG() const;
|
||||
bool NN() const;
|
||||
bool EMEonly() const;
|
||||
bool post_decodes () const;
|
||||
QString opCall() const;
|
||||
QString udp_server_name () const;
|
||||
port_type udp_server_port () const;
|
||||
QString n1mm_server_name () const;
|
||||
port_type n1mm_server_port () const;
|
||||
bool valid_n1mm_info () const;
|
||||
bool broadcast_to_n1mm() const;
|
||||
bool accept_udp_requests () const;
|
||||
bool udpWindowToFront () const;
|
||||
bool udpWindowRestore () const;
|
||||
@@ -184,6 +200,9 @@ public:
|
||||
// Set the calibration parameters and enable calibration corrections.
|
||||
void set_calibration (CalibrationParams);
|
||||
|
||||
// Set the dynamic grid which is only used if configuration setting is enabled.
|
||||
void set_location (QString const&);
|
||||
|
||||
// This method queries if a CAT and PTT connection is operational.
|
||||
bool is_transceiver_online () const;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
//
|
||||
Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned downSampleFactor = 4u, QObject * parent = 0);
|
||||
|
||||
void setPeriod(unsigned p) {m_period=p;}
|
||||
void setTRPeriod(unsigned p) {m_period=p;}
|
||||
bool reset () override;
|
||||
|
||||
Q_SIGNAL void framesWritten (qint64) const;
|
||||
|
||||
@@ -666,14 +666,16 @@ void HRDTransceiver::do_tx_frequency (Frequency tx, MODE mode, bool /*no_ignore*
|
||||
set_data_mode (mode);
|
||||
set_dropdown (receiver_dropdown_, (reversed_ ? rx_B_selection_ : rx_A_selection_).front ());
|
||||
}
|
||||
else if (vfo_count_ > 1)
|
||||
else if (vfo_count_ > 1 && ((vfo_A_button_ >=0 && vfo_B_button_ >=0) || vfo_toggle_button_ >= 0))
|
||||
{
|
||||
set_button (vfo_A_button_ >= 0 ? (reversed_ ? vfo_A_button_ : vfo_B_button_) : vfo_toggle_button_);
|
||||
set_dropdown (mode_A_dropdown_, lookup_mode (mode, mode_A_map_));
|
||||
set_data_mode (mode);
|
||||
set_button (vfo_A_button_ >= 0 ? (reversed_ ? vfo_B_button_ : vfo_A_button_) : vfo_toggle_button_);
|
||||
}
|
||||
// else Tx VFO mode gets set with frequency below
|
||||
// else Tx VFO mode gets set with frequency below or we
|
||||
// don't have a way of setting it so we assume it is
|
||||
// always the same as the Rx VFO mode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -809,7 +811,7 @@ void HRDTransceiver::do_mode (MODE mode)
|
||||
set_dropdown (mode_A_dropdown_, lookup_mode (mode, mode_A_map_));
|
||||
set_dropdown (receiver_dropdown_, rx_B_selection_.front ());
|
||||
}
|
||||
else if (vfo_count_ > 1)
|
||||
else if (vfo_count_ > 1 && ((vfo_A_button_ >=0 && vfo_B_button_ >=0) || vfo_toggle_button_ >= 0))
|
||||
{
|
||||
set_button (vfo_A_button_ >= 0 ? vfo_A_button_ : vfo_toggle_button_);
|
||||
set_dropdown (mode_A_dropdown_, lookup_mode (mode, mode_A_map_));
|
||||
@@ -847,7 +849,7 @@ void HRDTransceiver::do_mode (MODE mode)
|
||||
set_dropdown (mode_A_dropdown_, lookup_mode (mode, mode_A_map_));
|
||||
set_dropdown (receiver_dropdown_, rx_A_selection_.front ());
|
||||
}
|
||||
else if (vfo_count_ > 1)
|
||||
else if (vfo_count_ > 1 && ((vfo_A_button_ >=0 && vfo_B_button_ >=0) || vfo_toggle_button_ >= 0))
|
||||
{
|
||||
set_button (vfo_B_button_ >= 0 ? vfo_B_button_ : vfo_toggle_button_);
|
||||
set_dropdown (mode_A_dropdown_, lookup_mode (mode, mode_A_map_));
|
||||
|
||||
@@ -804,9 +804,9 @@ void HamlibTransceiver::do_tx_frequency (Frequency tx, MODE mode, bool no_ignore
|
||||
if (UNK != mode)
|
||||
{
|
||||
auto new_mode = map_mode (mode);
|
||||
// TRACE_CAT ("HamlibTransceiver", "rig_set_split_freq_mode freq = " << tx
|
||||
// << " mode = " << rig_strrmode (new_mode));
|
||||
// error_check (rig_set_split_freq_mode (rig_.data (), RIG_VFO_CURR, tx, new_mode, RIG_PASSBAND_NOCHANGE), tr ("setting split TX frequency and mode"));
|
||||
TRACE_CAT ("HamlibTransceiver", "rig_set_split_freq_mode freq = " << tx
|
||||
<< " mode = " << rig_strrmode (new_mode));
|
||||
error_check (rig_set_split_freq_mode (rig_.data (), RIG_VFO_CURR, tx, new_mode, RIG_PASSBAND_NOCHANGE), tr ("setting split TX frequency and mode"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QPushButton>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "revision_utils.hpp"
|
||||
|
||||
@@ -13,7 +14,7 @@ MessageBox::MessageBox (QWidget * parent)
|
||||
|
||||
MessageBox::MessageBox (Icon icon, QString const& text, StandardButtons buttons
|
||||
, QWidget * parent, Qt::WindowFlags flags)
|
||||
: QMessageBox {icon, program_title (), text, buttons, parent, flags}
|
||||
: QMessageBox {icon, QCoreApplication::applicationName (), text, buttons, parent, flags}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "MessageClient.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <QUdpSocket>
|
||||
#include <QHostInfo>
|
||||
@@ -76,6 +78,7 @@ public:
|
||||
QHostAddress server_;
|
||||
quint32 schema_;
|
||||
QTimer * heartbeat_timer_;
|
||||
std::vector<QHostAddress> blocked_addresses_;
|
||||
|
||||
// hold messages sent before host lookup completes asynchronously
|
||||
QQueue<QByteArray> pending_messages_;
|
||||
@@ -93,15 +96,24 @@ void MessageClient::impl::host_info_results (QHostInfo host_info)
|
||||
}
|
||||
else if (host_info.addresses ().size ())
|
||||
{
|
||||
server_ = host_info.addresses ()[0];
|
||||
|
||||
// send initial heartbeat which allows schema negotiation
|
||||
heartbeat ();
|
||||
|
||||
// clear any backlog
|
||||
while (pending_messages_.size ())
|
||||
auto server = host_info.addresses ()[0];
|
||||
if (blocked_addresses_.end () == std::find (blocked_addresses_.begin (), blocked_addresses_.end (), server))
|
||||
{
|
||||
send_message (pending_messages_.dequeue ());
|
||||
server_ = server;
|
||||
|
||||
// send initial heartbeat which allows schema negotiation
|
||||
heartbeat ();
|
||||
|
||||
// clear any backlog
|
||||
while (pending_messages_.size ())
|
||||
{
|
||||
send_message (pending_messages_.dequeue ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_EMIT self_->error ("UDP server blocked, please try another");
|
||||
pending_messages_.clear (); // discard
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,6 +207,17 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkMessage::Location:
|
||||
{
|
||||
QByteArray location;
|
||||
in >> location;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->location (QString::fromUtf8 (location));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Ignore
|
||||
//
|
||||
@@ -349,6 +372,17 @@ void MessageClient::send_raw_datagram (QByteArray const& message, QHostAddress c
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::add_blocked_destination (QHostAddress const& a)
|
||||
{
|
||||
m_->blocked_addresses_.push_back (a);
|
||||
if (a == m_->server_)
|
||||
{
|
||||
m_->server_.clear ();
|
||||
Q_EMIT error ("UDP server blocked, please try another");
|
||||
m_->pending_messages_.clear (); // discard
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::status_update (Frequency f, QString const& mode, QString const& dx_call
|
||||
, QString const& report, QString const& tx_mode
|
||||
, bool tx_enabled, bool transmitting, bool decoding
|
||||
@@ -410,7 +444,9 @@ void MessageClient::clear_decodes ()
|
||||
void MessageClient::qso_logged (QDateTime time_off, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power
|
||||
, QString const& comments, QString const& name, QDateTime time_on)
|
||||
, QString const& comments, QString const& name, QDateTime time_on
|
||||
, QString const& operator_call, QString const& my_call
|
||||
, QString const& my_grid)
|
||||
{
|
||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||
{
|
||||
@@ -418,7 +454,19 @@ void MessageClient::qso_logged (QDateTime time_off, QString const& dx_call, QStr
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::QSOLogged, m_->id_, m_->schema_};
|
||||
out << time_off << dx_call.toUtf8 () << dx_grid.toUtf8 () << dial_frequency << mode.toUtf8 ()
|
||||
<< report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 ()
|
||||
<< name.toUtf8 () << time_on;
|
||||
<< name.toUtf8 () << time_on << operator_call.toUtf8 () << my_call.toUtf8 () << my_grid.toUtf8 ();
|
||||
m_->send_message (out, message);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::logged_ADIF (QByteArray const& ADIF_record)
|
||||
{
|
||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::LoggedADIF, m_->id_, m_->schema_};
|
||||
QByteArray ADIF {"\n<adif_ver:5>3.0.7\n<programid:6>WSJT-X\n<EOH>\n" + ADIF_record + " <EOR>"};
|
||||
out << ADIF;
|
||||
m_->send_message (out, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,13 +62,22 @@ public:
|
||||
Q_SLOT void qso_logged (QDateTime time_off, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime time_on);
|
||||
, QString const& name, QDateTime time_on, QString const& operator_call
|
||||
, QString const& my_call, QString const& my_grid);
|
||||
|
||||
// ADIF_record argument should be valid ADIF excluding any <EOR> end
|
||||
// of record marker
|
||||
Q_SLOT void logged_ADIF (QByteArray const& ADIF_record);
|
||||
|
||||
// this slot may be used to send arbitrary UDP datagrams to and
|
||||
// destination allowing the underlying socket to be used for general
|
||||
// UDP messaging if desired
|
||||
Q_SLOT void send_raw_datagram (QByteArray const&, QHostAddress const& dest_address, port_type dest_port);
|
||||
|
||||
// disallowed message destination (does not block datagrams sent
|
||||
// with send_raw_datagram() above)
|
||||
Q_SLOT void add_blocked_destination (QHostAddress const&);
|
||||
|
||||
// this signal is emitted if the server sends us a reply, the only
|
||||
// reply supported is reply to a prior CQ or QRZ message
|
||||
Q_SIGNAL void reply (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode
|
||||
@@ -90,6 +99,11 @@ public:
|
||||
// lookup fails
|
||||
Q_SIGNAL void error (QString const&) const;
|
||||
|
||||
// this signal is emitted if the message obtains a location from a
|
||||
// server. (It doesn't have to be new, could be a periodic location
|
||||
// update)
|
||||
Q_SIGNAL void location (QString const&);
|
||||
|
||||
private:
|
||||
class impl;
|
||||
pimpl<impl> m_;
|
||||
|
||||
@@ -291,14 +291,19 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
||||
QByteArray comments;
|
||||
QByteArray name;
|
||||
QDateTime time_on; // Note: LOTW uses TIME_ON for their +/- 30-minute time window
|
||||
QByteArray operator_call;
|
||||
QByteArray my_call;
|
||||
QByteArray my_grid;
|
||||
in >> time_off >> dx_call >> dx_grid >> dial_frequency >> mode >> report_sent >> report_received
|
||||
>> tx_power >> comments >> name >> time_on;
|
||||
>> tx_power >> comments >> name >> time_on >> operator_call >> my_call >> my_grid;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->qso_logged (id, time_off, QString::fromUtf8 (dx_call), QString::fromUtf8 (dx_grid)
|
||||
, dial_frequency, QString::fromUtf8 (mode), QString::fromUtf8 (report_sent)
|
||||
, QString::fromUtf8 (report_received), QString::fromUtf8 (tx_power)
|
||||
, QString::fromUtf8 (comments), QString::fromUtf8 (name), time_on);
|
||||
, QString::fromUtf8 (comments), QString::fromUtf8 (name), time_on
|
||||
, QString::fromUtf8 (operator_call), QString::fromUtf8 (my_call)
|
||||
, QString::fromUtf8 (my_grid));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -308,6 +313,17 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
||||
clients_.remove (id);
|
||||
break;
|
||||
|
||||
case NetworkMessage::LoggedADIF:
|
||||
{
|
||||
QByteArray ADIF;
|
||||
in >> ADIF;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->logged_ADIF (id, ADIF);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Ignore
|
||||
break;
|
||||
@@ -452,3 +468,15 @@ void MessageServer::free_text (QString const& id, QString const& text, bool send
|
||||
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageServer::location (QString const& id, QString const& loc)
|
||||
{
|
||||
auto iter = m_->clients_.find (id);
|
||||
if (iter != std::end (m_->clients_))
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::Location, id, (*iter).negotiated_schema_number_};
|
||||
out << loc.toUtf8 ();
|
||||
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,9 @@ public:
|
||||
// message and optionally send it ASAP
|
||||
Q_SLOT void free_text (QString const& id, QString const& text, bool send);
|
||||
|
||||
// ask the client with identification 'id' to set the location provided
|
||||
Q_SLOT void location (QString const& id, QString const& location);
|
||||
|
||||
// the following signals are emitted when a client broadcasts the
|
||||
// matching message
|
||||
Q_SIGNAL void client_opened (QString const& id, QString const& version, QString const& revision);
|
||||
@@ -77,8 +80,10 @@ public:
|
||||
Q_SIGNAL void qso_logged (QString const& id, QDateTime time_off, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime time_on);
|
||||
, QString const& name, QDateTime time_on, QString const& operator_call
|
||||
, QString const& my_call, QString const& my_grid);
|
||||
Q_SIGNAL void clear_decodes (QString const& id);
|
||||
Q_SIGNAL void logged_ADIF (QString const& id, QByteArray const& ADIF);
|
||||
|
||||
// this signal is emitted when a network error occurs
|
||||
Q_SIGNAL void error (QString const&) const;
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace
|
||||
"QRA64",
|
||||
"FreqCal",
|
||||
"FT8",
|
||||
"FT8Free"
|
||||
};
|
||||
std::size_t constexpr mode_names_size = sizeof (mode_names) / sizeof (mode_names[0]);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ public:
|
||||
QRA64,
|
||||
FreqCal,
|
||||
FT8,
|
||||
FT8Free,
|
||||
MODES_END_SENTINAL_AND_COUNT // this must be last
|
||||
};
|
||||
Q_ENUM (Mode)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <QDebug>
|
||||
#include "mainwindow.h"
|
||||
#include "soundout.h"
|
||||
#include "commons.h"
|
||||
|
||||
#include "moc_Modulator.cpp"
|
||||
|
||||
@@ -86,7 +87,8 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol,
|
||||
if(m_bFastMode) m_ic=0;
|
||||
|
||||
m_silentFrames = 0;
|
||||
// calculate number of silent frames to send
|
||||
// calculate number of silent frames to send, so that audio will start at
|
||||
// the nominal time "delay_ms" into the Tx sequence.
|
||||
if (synchronize && !m_tuning && !m_bFastMode) {
|
||||
m_silentFrames = m_ic + m_frameRate / (1000 / delay_ms) - (mstr * (m_frameRate / 1000));
|
||||
}
|
||||
@@ -168,6 +170,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
|
||||
case Active:
|
||||
{
|
||||
unsigned int isym=0;
|
||||
// qDebug() << "Mod A" << m_toneSpacing << m_ic;
|
||||
if(!m_tuning) isym=m_ic/(4.0*m_nsps); // Actual fsample=48000
|
||||
bool slowCwId=((isym >= m_symbolsLength) && (icw[0] > 0)) && (!m_bFastMode);
|
||||
if(m_TRperiod==3) slowCwId=false;
|
||||
@@ -248,7 +251,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
|
||||
i0=i1-816;
|
||||
}
|
||||
|
||||
|
||||
qint16 sample;
|
||||
for (unsigned i = 0; i < numFrames && m_ic <= i1; ++i) {
|
||||
isym=0;
|
||||
if(!m_tuning and m_TRperiod!=3) isym=m_ic / (4.0 * m_nsps); //Actual
|
||||
@@ -264,7 +267,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
|
||||
m_toneFrequency0=m_frequency + itone[isym]*m_toneSpacing;
|
||||
}
|
||||
}
|
||||
// qDebug() << "B" << m_bFastMode << m_ic << numFrames << isym << itone[isym]
|
||||
// qDebug() << "Mod B" << m_bFastMode << m_ic << numFrames << isym << itone[isym]
|
||||
// << m_toneFrequency0 << m_nsps;
|
||||
m_dphi = m_twoPi * m_toneFrequency0 / m_frameRate;
|
||||
m_isym0 = isym;
|
||||
@@ -285,7 +288,12 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
|
||||
if (m_ic > i0) m_amp = 0.98 * m_amp;
|
||||
if (m_ic > i1) m_amp = 0.0;
|
||||
|
||||
samples = load (postProcessSample (m_amp * qSin (m_phi)), samples);
|
||||
sample=qRound(m_amp*qSin(m_phi));
|
||||
if(m_toneSpacing < 0) sample=qRound(m_amp*foxcom_.wave[m_ic]);
|
||||
|
||||
// if(m_ic < 100) qDebug() << "Mod C" << m_ic << m_amp << foxcom_.wave[m_ic] << sample;
|
||||
|
||||
samples = load(postProcessSample(sample), samples);
|
||||
++framesGenerated;
|
||||
++m_ic;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
double frequency () const {return m_frequency;}
|
||||
bool isActive () const {return m_state != Idle;}
|
||||
void setSpread(double s) {m_fSpread=s;}
|
||||
void setPeriod(unsigned p) {m_period=p;}
|
||||
void setTRPeriod(unsigned p) {m_period=p;}
|
||||
void set_nsym(int n) {m_symbolsLength=n;}
|
||||
|
||||
Q_SLOT void start (unsigned symbolsLength, double framesPerSymbol, double frequency,
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
* Date & Time Off QDateTime
|
||||
* DX call utf8
|
||||
* DX grid utf8
|
||||
* Dial frequency (Hz) quint64
|
||||
* Tx frequency (Hz) quint64
|
||||
* Mode utf8
|
||||
* Report send utf8
|
||||
* Report received utf8
|
||||
@@ -237,6 +237,9 @@
|
||||
* Comments utf8
|
||||
* Name utf8
|
||||
* Date & Time On QDateTime
|
||||
* Operator call utf8
|
||||
* My call utf8
|
||||
* My grid utf8
|
||||
*
|
||||
* The QSO logged message is sent to the server(s) when the
|
||||
* WSJT-X user accepts the "Log QSO" dialog by clicking the "OK"
|
||||
@@ -304,6 +307,7 @@
|
||||
* command to determine the contents of the current free text
|
||||
* message.
|
||||
*
|
||||
*
|
||||
* WSPRDecode Out 10 quint32
|
||||
* Id (unique key) utf8
|
||||
* New bool
|
||||
@@ -327,6 +331,43 @@
|
||||
* from a played back recording.
|
||||
*
|
||||
*
|
||||
* Location In 11
|
||||
* Id (unique key) utf8
|
||||
* Location utf8
|
||||
*
|
||||
* This message allows the server to set the current current
|
||||
* geographical location of operation. The supplied location is
|
||||
* not persistent but is used as a session lifetime replacement
|
||||
* loction that overrides the Maidenhead grid locater set in the
|
||||
* application settings. The intent is to allow an external
|
||||
* application to update the operating location dynamically
|
||||
* during a mobile period of operation.
|
||||
*
|
||||
* Currently only Maidenhead grid squares or sub-squares are
|
||||
* accepted, i.e. 4- or 6-digit locators. Other formats may be
|
||||
* accepted in future.
|
||||
*
|
||||
*
|
||||
* Logged ADIF Out 12 quint32
|
||||
* Id (unique key) utf8
|
||||
* ADIF text ASCII (serialized like utf8)
|
||||
*
|
||||
* The logged ADIF message is sent to the server(s) when the
|
||||
* WSJT-X user accepts the "Log QSO" dialog by clicking the "OK"
|
||||
* button. The "ADIF text" field consists of a valid ADIF file
|
||||
* such that the WSJT-X UDP header information is encapsulated
|
||||
* into a valid ADIF header. E.g.:
|
||||
*
|
||||
* <magic-number><schema-number><type><id><32-bit-count> # binary encoded fields
|
||||
* # the remainder is the contents of the ADIF text field
|
||||
* <adif_ver:5>3.0.7
|
||||
* <programid:6>WSJT-X
|
||||
* <EOH>
|
||||
* ADIF log data fields ...<EOR>
|
||||
*
|
||||
* Note that receiving applications can treat the whole message
|
||||
* as a valid ADIF file with one record without special parsing.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QDataStream>
|
||||
@@ -353,6 +394,8 @@ namespace NetworkMessage
|
||||
HaltTx,
|
||||
FreeText,
|
||||
WSPRDecode,
|
||||
Location,
|
||||
LoggedADIF,
|
||||
maximum_message_type_ // ONLY add new message types
|
||||
// immediately before here
|
||||
};
|
||||
|
||||
@@ -1,9 +1,65 @@
|
||||
0; 0; 0
|
||||
0; 0; 87
|
||||
0; 79;114
|
||||
0;141; 61
|
||||
96;158; 0
|
||||
0; 0; 9
|
||||
0; 0; 21
|
||||
0; 0; 34
|
||||
0; 0; 45
|
||||
0; 0; 57
|
||||
0; 0; 67
|
||||
0; 0; 77
|
||||
0; 0; 86
|
||||
0; 0; 94
|
||||
0; 12;101
|
||||
0; 23;106
|
||||
0; 35;110
|
||||
0; 46;113
|
||||
0; 57;115
|
||||
0; 68;115
|
||||
0; 78;114
|
||||
0; 88;112
|
||||
0; 97;108
|
||||
0;106;103
|
||||
0;114; 97
|
||||
0;122; 90
|
||||
0;129; 81
|
||||
0;136; 72
|
||||
0;141; 62
|
||||
0;146; 51
|
||||
0;151; 39
|
||||
11;154; 27
|
||||
29;157; 15
|
||||
46;158; 2
|
||||
63;159; 0
|
||||
79;159; 0
|
||||
96;159; 0
|
||||
111;157; 0
|
||||
127;155; 0
|
||||
142;152; 0
|
||||
156;148; 0
|
||||
169;143; 0
|
||||
182;138; 0
|
||||
193;131; 0
|
||||
204;124; 0
|
||||
253; 50; 17
|
||||
214;117; 0
|
||||
223;109; 0
|
||||
231;100; 0
|
||||
238; 91; 0
|
||||
244; 81; 0
|
||||
248; 71; 0
|
||||
252; 60; 5
|
||||
254; 50; 19
|
||||
255; 38; 33
|
||||
255; 47; 47
|
||||
255; 61; 61
|
||||
255; 75; 75
|
||||
255; 90; 90
|
||||
255;105;105
|
||||
255;121;121
|
||||
255;138;138
|
||||
255;156;156
|
||||
255;175;175
|
||||
255;196;196
|
||||
255;218;218
|
||||
255;243;243
|
||||
255;255;255
|
||||
255;255;255
|
||||
255;255;255
|
||||
|
||||
@@ -0,0 +1,301 @@
|
||||
__ __ ______ _____ ________ __ __
|
||||
| \ _ | \ / \ | \| \ | \ | \
|
||||
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
|
||||
| $$/ $\| $$| $$___\$$ | $$ | $$ ______ \$$\/ $$
|
||||
| $$ $$$\ $$ \$$ \ __ | $$ | $$| \ >$$ $$
|
||||
| $$ $$\$$\$$ _\$$$$$$\| \ | $$ | $$ \$$$$$$/ $$$$\
|
||||
| $$$$ \$$$$| \__| $$| $$__| $$ | $$ | $$ \$$\
|
||||
| $$$ \$$$ \$$ $$ \$$ $$ | $$ | $$ | $$
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
|
||||
Copyright 2001 - 2018 by Joe Taylor, K1JT.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.9.0-rc2
|
||||
February 26, 2018
|
||||
---------------------------------
|
||||
|
||||
Changes from WSJT-X Version 1.8.0 include the following:
|
||||
|
||||
- New FT8 DXpedition Mode to facilitate high QSO rates in pileup
|
||||
situations
|
||||
|
||||
- Decoding improvements for JT65 mode, including a priori (AP)
|
||||
decoding when VHF/UHF/Microwave features are enabled
|
||||
|
||||
- Optional Auto-Sequencing in JT4, JT9, and JT65 when
|
||||
VHF/UHF/Microwave features are enabled
|
||||
|
||||
- Better suppression of low-confidence false decodes generated by AP
|
||||
decoding in FT8 mode
|
||||
|
||||
- Improved decoding performance for WSPR mode, especially effective at
|
||||
LF and MF
|
||||
|
||||
- Minor adjustments to auto-sequencing behavior
|
||||
|
||||
- More flexible Doppler control features for EME
|
||||
|
||||
- Improved waterfall sensitivity for very weak signals
|
||||
|
||||
- Automatic real-time forwarding of logged information to N1MM Logger+
|
||||
|
||||
- Expanded and improved UDP messages sent to companion programs
|
||||
|
||||
- Bug fixes and other minor tweaks to user interface
|
||||
|
||||
A primary purpose of this beta release is to allow field testing of
|
||||
FT8 DXpedition Mode. Instructions for this mode are posted here:
|
||||
|
||||
http://physics.princeton.edu/pulsar/k1jt/FT8_DXpedition_Mode.pdf
|
||||
|
||||
Contacts in FT8 DXpedition Mode must use WSJT-X v1.9.0 at both ends of
|
||||
the QSO. Please report any anomalous behavior to email list
|
||||
wsjt-devel@lists.sourceforge.net. You must be a subscriber in order
|
||||
to post there.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0
|
||||
October 27, 2017
|
||||
-----------------------------
|
||||
|
||||
This is the full General Availability release of WSJT-X Version 1.8.0.
|
||||
|
||||
Changes from WSJT-X Version 1.8.0-rc3 are very minor:
|
||||
|
||||
- Right-click on the Wide Graph now pops up a Context Menu. Select
|
||||
the item *Set Rx & Tx Offset* to complete a one-handed setting of
|
||||
both red and green frequency markers.
|
||||
|
||||
- Several clarifications and additions to Tool Tips and the User Guide.
|
||||
|
||||
|
||||
We recommend that all users should upgrade to WSJT-X Version 1.8.0.
|
||||
|
||||
If you upgrade from v1.8.0-rc1 it may be necessary to do a one-time
|
||||
reset of the default list of suggested operating frequencies. Go to
|
||||
*File->Settings->Frequencies*, right click on the table and select
|
||||
*Reset*.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0-rc3
|
||||
October 16, 2017
|
||||
---------------------------------
|
||||
|
||||
Most (but not all) changes since Version 1.8.0-rc2 involve user
|
||||
control of the increasingly popular FT8 mode. The "RC3" release also
|
||||
includes minor bug fixes and updates to the WSJT-X User Guide.
|
||||
|
||||
The following list includes all of the more important changes:
|
||||
|
||||
- New optimization of GUI for simplex and split behavior in FT8 mode.
|
||||
|
||||
1. Checkbox "Lock Tx Freq" on main window is relabeled "Hold Tx Freq".
|
||||
|
||||
2. Double-clicking on decoded messages that do not contain your own
|
||||
call moves both Rx and Tx frequencies. If the first callsign is
|
||||
your own call, only Rx freq moves.
|
||||
|
||||
3. Double-clicking on decoded messages moves the Rx frequency. If
|
||||
"Hold Tx Freq" is checked, Tx frequency is moved only if CTRL was
|
||||
held down.
|
||||
|
||||
4. Clicking on the waterfall moves Rx and Tx frequencies as
|
||||
before: Rx only on a simple click, Tx only on SHIFT-click, and
|
||||
both on CTRL-click. This happens even if "Hold Tx Freq" is
|
||||
checked.
|
||||
|
||||
- Add a semi-automated "FreqCal" procedure: see *Solve for calibration
|
||||
parameters* on the Tools menu.
|
||||
|
||||
- Improv auto-sequencing behavior: stop and on-frequency
|
||||
transmission if a called station comes back to someone else.
|
||||
|
||||
- Improve S/N estimation in some situations involving QRM.
|
||||
|
||||
- Fix an initialization issue with user-modified application fonts.
|
||||
|
||||
- Fix an issue with Tx5 message generation with Type 2 compound calls.
|
||||
|
||||
- Enhance and improve the ADIF parser of logbook records. Update
|
||||
the band limits as per ADIF 3.0.6 specification.
|
||||
|
||||
- Increase the FT8 DT range to +/- 2.5 s.
|
||||
|
||||
- Do not allow window manager events to close the astronomical data
|
||||
window.
|
||||
|
||||
- Add an "Erase" item to the context (right-click) menu for decoded
|
||||
text.
|
||||
|
||||
- Extend UDP messages with an "off air" boolean field indicating that
|
||||
the decode was derived from a .WAV file playback rather than an on air
|
||||
reception.
|
||||
|
||||
- Extend reference applications to use the new off air decode message
|
||||
field.
|
||||
|
||||
- Improve performance of FT8 decoder, especially for overlapping
|
||||
signals.
|
||||
|
||||
- Allow specialized use of "x2 Tone Spacing" in FT8 and slow JT9
|
||||
modes.
|
||||
|
||||
- Move "NA VHF Contest Mode" checkbox to main screen. Query the
|
||||
operator if d > 10000 km.
|
||||
|
||||
- Adjust UI to improve portability with font size changes and between
|
||||
platforms.
|
||||
|
||||
- Extend UDP Reply message to support keyboard modifiers. This allows
|
||||
UDP servers to emulate keyboard modified double-clicks on decoded
|
||||
messages, e.g. ALT+double-click for replying to a CQ or QRZ call
|
||||
without changing ones Tx frequency offset.
|
||||
|
||||
- Update the cty.dat file (21st Sept 2017).
|
||||
|
||||
- Ensure that Fast Graph is properly initialized.
|
||||
|
||||
- Better handling of worked before and country name display. Appended
|
||||
text is added at a fixed column unless the message overlaps in which
|
||||
case the appended information floats to the right.
|
||||
|
||||
- Restore printing of MSK144 decode quality information.
|
||||
|
||||
- Display Echo Graph automatically when Echo mode is started.
|
||||
|
||||
- Fix a bug that prevented double-click on a JT65 EME-style "OOO"
|
||||
message from populating the Tx message boxes.
|
||||
|
||||
- Fixed behavior with double-click on 'CQ <AA-ZZ> <call> <grid>.'
|
||||
|
||||
- Update the "blank line" divider with band ID at 4*TRperiod/5.
|
||||
|
||||
- Fix cty.dat lookups that were not honouring exact match flags
|
||||
|
||||
- Add some further Copyright protections.
|
||||
|
||||
- Fix a bug involving "firstcall contains mycall" but not equal to mycall.
|
||||
|
||||
- Fix an issue with editing IARU regions in the working frequencies table.
|
||||
|
||||
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0-rc2
|
||||
September 2, 2017
|
||||
---------------------------------
|
||||
|
||||
Implementation of FT8 and its auto-sequencing feature is now more
|
||||
capable and more polished. The decoder is faster and better: it now
|
||||
includes signal subtraction, multi-pass decoding, and the use of
|
||||
accumulated "a priori" information as a QSO progresses. Sensitivity
|
||||
extends downward as far as -24 dB in some circumstances. Overlapping
|
||||
signals 2 and 3 deep are frequently decoded at essentially the same
|
||||
frequency. On a crowded band we sometimes see more than 30 decodes in
|
||||
a single 15-second interval, over a 2 kHz window. The North American
|
||||
VHF Contesting Mode has been extended to include both FT8 and MSK144
|
||||
modes.
|
||||
|
||||
The "RC2" release also includes many minor bug fixes and an
|
||||
extensively updated WSJT-X User Guide.
|
||||
|
||||
Depending on what code revision you upgrade from, it may be necessary
|
||||
to do a one-time reset of the default list of suggested operating
|
||||
frequencies. Go to *File->Settings->Frequencies*, right click on
|
||||
the table and select *Reset*.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0
|
||||
-----------------------------
|
||||
|
||||
NEW FEATURES IN WSJT-X Version 1.8.0
|
||||
------------------------------------
|
||||
|
||||
1. New mode called FT8: sensitivity down to -20 dB on the AWGN
|
||||
channel; QSOs 4 times faster than JT65 or JT9; auto-sequencing
|
||||
includes an option to respond automatically to first decoded
|
||||
reply to your CQ.
|
||||
|
||||
2. New mode for accurate Frequency Calibration of your radio.
|
||||
|
||||
3. Improved performance of decoders for JT65, QRA64, and MSK144.
|
||||
MSK144 includes facilities for amplitide and phase equalization
|
||||
and an "SWL" mode for short-format messages.
|
||||
|
||||
4. Options to minimize screen space used by Main and Wide Graph
|
||||
windows.
|
||||
|
||||
5. Enhanced management scheme for table of operating frequencies, and
|
||||
a new set of default frequencies specific to the three IARU
|
||||
Regions.
|
||||
|
||||
6. Improved CAT control for many rigs, including those controlled
|
||||
through Commander or OmniRig.
|
||||
|
||||
7. New keyboard shortcuts to set "Tx even/1st" ON or OFF.
|
||||
|
||||
8. A number of (mostly minor) bug fixes and tweaks to the user
|
||||
interface. For example: new behavior for the audio level slider;
|
||||
correctly logged QSO start times in certain situations; correct
|
||||
control of FT-891/991 and some other radios via rigctld.
|
||||
|
||||
At the time of the v1.8.0-rc1 release the following tasks are yet to
|
||||
be completed:
|
||||
|
||||
1. Updates to WSJT-X User Guide.
|
||||
2. Sample files for FT8.
|
||||
3. Enhanced decoding using AP ("a priori") information.
|
||||
4. Signal subtraction and multi-pass decoding.
|
||||
5. Option to Auto-respond to the weakest responder to your CQ.
|
||||
|
||||
|
||||
Installation packages for Windows, Linux, OS X, and Raspbian can be
|
||||
downloaded from the WSJT web site:
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx.html
|
||||
|
||||
Please send bug reports to either wsjtgroup@yahoogroups.com or
|
||||
wsjt-devel@lists.sourceforge.net. Such reports should include a full
|
||||
prescription of steps to reproduce the undesired behavior. You must
|
||||
be a subscriber to post to either of these lists.
|
||||
|
||||
|
||||
Brief Description of the FT8 Protocol
|
||||
-------------------------------------
|
||||
|
||||
WSJT-X Version 1.8.0 includes a new mode called FT8, developed by K9AN
|
||||
and K1JT. The mode name "FT8" stands for "Franke and Taylor, 8-FSK
|
||||
modulation". FT8 uses 15-second T/R sequences and provides 50% or
|
||||
better decoding probability down to -20 dB on an AWGN channel. An
|
||||
auto-sequencing facility includes an option to respond automatically
|
||||
to the first decoded reply to your CQ. FT8 QSOs are 4 times faster
|
||||
than those made with JT65 or JT9. FT8 is an excellent mode for HF
|
||||
DXing and for situations like multi-hop E_s on 6 meters, where deep
|
||||
QSB may make fast and reliable completion of QSOs desirable.
|
||||
|
||||
Some important characteristics of FT8:
|
||||
|
||||
- T/R sequence length: 15 s
|
||||
- Message length: 75 bits + 12-bit CRC
|
||||
- FEC code: LDPC(174,87)
|
||||
- Modulation: 8-FSK, tone spacing 6.25 Hz
|
||||
- Constant-envelope waveform
|
||||
- Occupied bandwidth: 50 Hz
|
||||
- Synchronization: 7x7 Costas arrays at start, middle, and end
|
||||
- Transmission duration: 79*1920/12000 = 12.64 s
|
||||
- Decoding threshold: -20 dB; several dB lower with AP decoding
|
||||
- Multi-decoder finds and decodes all FT8 signals in passband
|
||||
- Optional auto-sequencing and auto-reply to a CQ response
|
||||
- Operational behavior similar to JT9, JT65
|
||||
|
||||
We plan to implement signal subtraction, two-pass decoding, and use of
|
||||
a priori (AP) information in the decoder. These features are not yet
|
||||
activated in v1.8.0.
|
||||
|
||||
We haven't yet finalized what the three extra bits in the message
|
||||
payload will be used for. Suggestions are welcome!
|
||||
|
||||
-- Joe, K1JT, for the WSJT Development Team
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <QRegExp>
|
||||
#include <QColor>
|
||||
|
||||
#include "MaidenheadLocatorValidator.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
//QRegExp message_alphabet {"[- A-Za-z0-9+./?]*"};
|
||||
@@ -120,9 +122,11 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
|
||||
, decodes_table_view_ {new QTableView}
|
||||
, beacons_table_view_ {new QTableView}
|
||||
, message_line_edit_ {new QLineEdit}
|
||||
, grid_line_edit_ {new QLineEdit}
|
||||
, decodes_stack_ {new QStackedLayout}
|
||||
, auto_off_button_ {new QPushButton {tr ("&Auto Off")}}
|
||||
, halt_tx_button_ {new QPushButton {tr ("&Halt Tx")}}
|
||||
, de_label_ {new QLabel}
|
||||
, mode_label_ {new QLabel}
|
||||
, fast_mode_ {false}
|
||||
, frequency_label_ {new QLabel}
|
||||
@@ -141,13 +145,18 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
|
||||
|
||||
auto form_layout = new QFormLayout;
|
||||
form_layout->addRow (tr ("Free text:"), message_line_edit_);
|
||||
form_layout->addRow (tr ("Temporary grid:"), grid_line_edit_);
|
||||
message_line_edit_->setValidator (new QRegExpValidator {message_alphabet, this});
|
||||
grid_line_edit_->setValidator (new MaidenheadLocatorValidator {this});
|
||||
connect (message_line_edit_, &QLineEdit::textEdited, [this] (QString const& text) {
|
||||
Q_EMIT do_free_text (id_, text, false);
|
||||
});
|
||||
connect (message_line_edit_, &QLineEdit::editingFinished, [this] () {
|
||||
Q_EMIT do_free_text (id_, message_line_edit_->text (), true);
|
||||
});
|
||||
connect (grid_line_edit_, &QLineEdit::editingFinished, [this] () {
|
||||
Q_EMIT location (id_, grid_line_edit_->text ());
|
||||
});
|
||||
|
||||
auto decodes_page = new QWidget;
|
||||
auto decodes_layout = new QVBoxLayout {decodes_page};
|
||||
@@ -189,6 +198,7 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
|
||||
|
||||
// set up status area
|
||||
auto status_bar = new QStatusBar;
|
||||
status_bar->addPermanentWidget (de_label_);
|
||||
status_bar->addPermanentWidget (mode_label_);
|
||||
status_bar->addPermanentWidget (frequency_label_);
|
||||
status_bar->addPermanentWidget (dx_label_);
|
||||
@@ -216,7 +226,7 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
|
||||
void ClientWidget::update_status (QString const& id, Frequency f, QString const& mode, QString const& dx_call
|
||||
, QString const& report, QString const& tx_mode, bool tx_enabled
|
||||
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
|
||||
, QString const& de_call, QString const& /*de_grid*/, QString const& dx_grid
|
||||
, QString const& de_call, QString const& de_grid, QString const& dx_grid
|
||||
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode)
|
||||
{
|
||||
if (id == id_)
|
||||
@@ -224,6 +234,8 @@ void ClientWidget::update_status (QString const& id, Frequency f, QString const&
|
||||
fast_mode_ = fast_mode;
|
||||
decodes_proxy_model_.de_call (de_call);
|
||||
decodes_proxy_model_.rx_df (rx_df);
|
||||
de_label_->setText (de_call.size () >= 0 ? QString {"DE: %1%2"}.arg (de_call)
|
||||
.arg (de_grid.size () ? '(' + de_grid + ')' : QString {}) : QString {});
|
||||
mode_label_->setText (QString {"Mode: %1%2%3%4"}
|
||||
.arg (mode)
|
||||
.arg (sub_mode)
|
||||
|
||||
@@ -43,6 +43,7 @@ public:
|
||||
Q_SIGNAL void do_reply (QModelIndex const&, quint8 modifier);
|
||||
Q_SIGNAL void do_halt_tx (QString const& id, bool auto_only);
|
||||
Q_SIGNAL void do_free_text (QString const& id, QString const& text, bool);
|
||||
Q_SIGNAL void location (QString const &id, QString const &text);
|
||||
|
||||
private:
|
||||
QString id_;
|
||||
@@ -69,9 +70,11 @@ private:
|
||||
QTableView * decodes_table_view_;
|
||||
QTableView * beacons_table_view_;
|
||||
QLineEdit * message_line_edit_;
|
||||
QLineEdit * grid_line_edit_;
|
||||
QStackedLayout * decodes_stack_;
|
||||
QAbstractButton * auto_off_button_;
|
||||
QAbstractButton * halt_tx_button_;
|
||||
QLabel * de_label_;
|
||||
QLabel * mode_label_;
|
||||
bool fast_mode_;
|
||||
QLabel * frequency_label_;
|
||||
|
||||
@@ -22,12 +22,15 @@ namespace
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Sent"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Rec'd"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Power"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Operator"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "My Call"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "My Grid"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Comments"),
|
||||
};
|
||||
}
|
||||
|
||||
MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
|
||||
: log_ {new QStandardItemModel {0, 11, this}}
|
||||
: log_ {new QStandardItemModel {0, 14, this}}
|
||||
, decodes_model_ {new DecodesModel {this}}
|
||||
, beacons_model_ {new BeaconsModel {this}}
|
||||
, server_ {new MessageServer {this}}
|
||||
@@ -111,10 +114,12 @@ MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
|
||||
show ();
|
||||
}
|
||||
|
||||
void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime time_off, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime time_on)
|
||||
void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime time_off, QString const& dx_call
|
||||
, QString const& dx_grid, Frequency dial_frequency, QString const& mode
|
||||
, QString const& report_sent, QString const& report_received
|
||||
, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime time_on, QString const& operator_call
|
||||
, QString const& my_call, QString const& my_grid)
|
||||
{
|
||||
QList<QStandardItem *> row;
|
||||
row << new QStandardItem {time_on.toString ("dd-MMM-yyyy hh:mm:ss")}
|
||||
@@ -127,6 +132,9 @@ void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime time
|
||||
<< new QStandardItem {report_sent}
|
||||
<< new QStandardItem {report_received}
|
||||
<< new QStandardItem {tx_power}
|
||||
<< new QStandardItem {operator_call}
|
||||
<< new QStandardItem {my_call}
|
||||
<< new QStandardItem {my_grid}
|
||||
<< new QStandardItem {comments};
|
||||
log_->appendRow (row);
|
||||
log_table_view_->resizeColumnsToContents ();
|
||||
@@ -149,6 +157,7 @@ void MessageAggregatorMainWindow::add_client (QString const& id, QString const&
|
||||
connect (dock, &ClientWidget::do_reply, decodes_model_, &DecodesModel::do_reply);
|
||||
connect (dock, &ClientWidget::do_halt_tx, server_, &MessageServer::halt_tx);
|
||||
connect (dock, &ClientWidget::do_free_text, server_, &MessageServer::free_text);
|
||||
connect (dock, &ClientWidget::location, server_, &MessageServer::location);
|
||||
connect (view_action, &QAction::toggled, dock, &ClientWidget::setVisible);
|
||||
dock_widgets_[id] = dock;
|
||||
server_->replay (id);
|
||||
|
||||
@@ -29,7 +29,8 @@ public:
|
||||
Q_SLOT void log_qso (QString const& /*id*/, QDateTime time_off, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime time_on);
|
||||
, QString const& name, QDateTime time_on, QString const& operator_call
|
||||
, QString const& my_call, QString const& my_grid);
|
||||
|
||||
private:
|
||||
void add_client (QString const& id, QString const& version, QString const& revision);
|
||||
|
||||
@@ -95,6 +95,38 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Q_SLOT void qso_logged (QString const&client_id, QDateTime time_off, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power
|
||||
, QString const& comments, QString const& name, QDateTime time_on
|
||||
, QString const& operator_call, QString const& my_call, QString const& my_grid)
|
||||
{
|
||||
if (client_id == id_)
|
||||
{
|
||||
qDebug () << "time_on:" << time_on << "time_off:" << time_off << "dx_call:" << dx_call << "grid:" << dx_grid
|
||||
<< "freq:" << dial_frequency << "mode:" << mode << "rpt_sent:" << report_sent
|
||||
<< "rpt_rcvd:" << report_received << "Tx_pwr:" << tx_power << "comments:" << comments
|
||||
<< "name:" << name << "operator_call:" << operator_call << "my_call:" << my_call
|
||||
<< "my_grid:" << my_grid;
|
||||
std::cout << QByteArray {80, '-'}.data () << '\n';
|
||||
std::cout << tr ("%1: Logged %2 grid: %3 power: %4 sent: %5 recd: %6 freq: %7 time_off: %8 op: %9 my_call: %10 my_grid: %11")
|
||||
.arg (id_).arg (dx_call).arg (dx_grid).arg (tx_power).arg (report_sent).arg (report_received)
|
||||
.arg (dial_frequency).arg (time_off.toString("yyyy-MM-dd hh:mm:ss.z")).arg (operator_call)
|
||||
.arg (my_call).arg (my_grid).toStdString ()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Q_SLOT void logged_ADIF (QString const&client_id, QByteArray const& ADIF)
|
||||
{
|
||||
if (client_id == id_)
|
||||
{
|
||||
qDebug () << "ADIF:" << ADIF;
|
||||
std::cout << QByteArray {80, '-'}.data () << '\n';
|
||||
std::cout << ADIF.data () << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QString id_;
|
||||
Frequency dial_frequency_;
|
||||
@@ -127,6 +159,8 @@ private:
|
||||
connect (server_, &MessageServer::status_update, client, &Client::update_status);
|
||||
connect (server_, &MessageServer::decode, client, &Client::decode_added);
|
||||
connect (server_, &MessageServer::WSPR_decode, client, &Client::beacon_spot_added);
|
||||
connect (server_, &MessageServer::qso_logged, client, &Client::qso_logged);
|
||||
connect (server_, &MessageServer::logged_ADIF, client, &Client::logged_ADIF);
|
||||
clients_[id] = client;
|
||||
server_->replay (id);
|
||||
std::cout << "Discovered WSJT-X instance: " << id.toStdString ();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Version number components
|
||||
set (WSJTX_VERSION_MAJOR 1)
|
||||
set (WSJTX_VERSION_MINOR 7)
|
||||
set (WSJTX_VERSION_PATCH 1)
|
||||
set (WSJTX_VERSION_MAJOR 0)
|
||||
set (WSJTX_VERSION_MINOR 3)
|
||||
set (WSJTX_VERSION_PATCH 2)
|
||||
set (WSJTX_RC 0) # release candidate number, comment out or zero for development versions
|
||||
set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build
|
||||
|
||||
@@ -18,7 +18,7 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
|
||||
+ " " + revision ()}.simplified () + "</h2><br />"
|
||||
"WSJT-X implements a number of digital modes designed for <br />"
|
||||
"weak-signal Amateur Radio communication. <br /><br />"
|
||||
"© 2001-2017 by Joe Taylor, K1JT, with grateful <br />"
|
||||
"© 2001-2018 by Joe Taylor, K1JT, with grateful <br />"
|
||||
"acknowledgment for contributions from AC6SL, AE4JY, <br />"
|
||||
"DJ0OT, G3WDG, G4KLA, G4WJS, IV3NWV, IW3RAB, K3WYC, K9AN, <br />"
|
||||
"KA6MAL, KA9Q, KB1ZMX, KD6EKQ, KI7MT, KK1D, ND0B, PY2SDR, <br />"
|
||||
|
||||
@@ -29,7 +29,7 @@ extern "C" {
|
||||
double* ramoon, double* decmoon, double* dgrd, double* poloffset,
|
||||
double* xnr, double* techo, double* width1, double* width2,
|
||||
bool* bTx, const char* AzElFileName, const char* jpleph,
|
||||
int len1, int len2, int len3, int len4);
|
||||
fortran_charlen_t, fortran_charlen_t, fortran_charlen_t, fortran_charlen_t);
|
||||
}
|
||||
|
||||
Astro::Astro(QSettings * settings, Configuration const * configuration, QWidget * parent)
|
||||
@@ -38,6 +38,9 @@ Astro::Astro(QSettings * settings, Configuration const * configuration, QWidget
|
||||
, configuration_ {configuration}
|
||||
, ui_ {new Ui::Astro}
|
||||
, m_DopplerMethod {0}
|
||||
, m_dop {0}
|
||||
, m_dop00 {0}
|
||||
, m_dx_two_way_dop {0}
|
||||
{
|
||||
ui_->setupUi (this);
|
||||
setWindowTitle (QApplication::applicationName () + " - " + tr ("Astronomical Data"));
|
||||
@@ -70,7 +73,9 @@ void Astro::read_settings ()
|
||||
case 0: ui_->rbNoDoppler->setChecked (true); break;
|
||||
case 1: ui_->rbFullTrack->setChecked (true); break;
|
||||
case 2: ui_->rbConstFreqOnMoon->setChecked (true); break;
|
||||
case 3: ui_->rbRxOnly->setChecked (true); break;
|
||||
case 3: ui_->rbOwnEcho->setChecked (true); break;
|
||||
case 4: ui_->rbOnDxEcho->setChecked (true); break;
|
||||
case 5: ui_->rbCallDx->setChecked (true); break;
|
||||
}
|
||||
move (settings_->value ("window/pos", pos ()).toPoint ());
|
||||
}
|
||||
@@ -104,14 +109,15 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
|
||||
double freq8 {static_cast<double> (freq_moon)};
|
||||
auto const& AzElFileName = QDir::toNativeSeparators (configuration_->azel_directory ().absoluteFilePath ("azel.dat"));
|
||||
auto const& jpleph = configuration_->data_dir ().absoluteFilePath ("JPLEPH");
|
||||
int ndop;
|
||||
int ndop00;
|
||||
|
||||
|
||||
|
||||
|
||||
QString mygrid_padded {(mygrid + " ").left (6)};
|
||||
QString hisgrid_padded {(hisgrid + " ").left (6)};
|
||||
astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid_padded.toLatin1().constData(),
|
||||
hisgrid_padded.toLatin1().constData(), &azsun, &elsun, &azmoon, &elmoon,
|
||||
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00, &ramoon, &decmoon,
|
||||
&azmoondx, &elmoondx, &ntsky, &m_dop, &m_dop00, &ramoon, &decmoon,
|
||||
&dgrd, &poloffset, &xnr, &techo, &width1, &width2, &bTx,
|
||||
AzElFileName.toLatin1().constData(), jpleph.toLatin1().constData(), 6, 6,
|
||||
AzElFileName.length(), jpleph.length());
|
||||
@@ -119,7 +125,7 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
|
||||
if(hisgrid_padded==" ") {
|
||||
azmoondx=0.0;
|
||||
elmoondx=0.0;
|
||||
ndop=0;
|
||||
m_dop=0;
|
||||
width2=0.0;
|
||||
}
|
||||
QString message;
|
||||
@@ -132,14 +138,14 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
|
||||
<< qSetRealNumberPrecision (1)
|
||||
<< "Az: " << azmoon << "\n"
|
||||
"El: " << elmoon << "\n"
|
||||
"SelfDop:" << ndop00 << "\n"
|
||||
"SelfDop:" << m_dop00 << "\n"
|
||||
"Width: " << int(width1) << "\n"
|
||||
<< qSetRealNumberPrecision (2)
|
||||
<< "Delay: " << techo << "\n"
|
||||
<< qSetRealNumberPrecision (1)
|
||||
<< "DxAz: " << azmoondx << "\n"
|
||||
"DxEl: " << elmoondx << "\n"
|
||||
"DxDop: " << ndop << "\n"
|
||||
"DxDop: " << m_dop << "\n"
|
||||
"DxWid: " << int(width2) << "\n"
|
||||
"Dec: " << decmoon << "\n"
|
||||
"SunAz: " << azsun << "\n"
|
||||
@@ -159,24 +165,48 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
|
||||
switch (m_DopplerMethod)
|
||||
{
|
||||
case 1: // All Doppler correction done here; DX station stays at nominal dial frequency.
|
||||
correction.rx = m_dop;
|
||||
break;
|
||||
case 4: // All Doppler correction done here; DX station stays at nominal dial frequency. (Trial for OnDxEcho)
|
||||
correction.rx = m_dop;
|
||||
break;
|
||||
//case 5: // All Doppler correction done here; DX station stays at nominal dial frequency.
|
||||
|
||||
case 3: // Both stations do full correction on Rx and none on Tx
|
||||
correction.rx = dx_is_self ? ndop00 : ndop;
|
||||
//correction.rx = dx_is_self ? m_dop00 : m_dop;
|
||||
correction.rx = m_dop00; // Now always sets RX to *own* echo freq
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 2:
|
||||
// Doppler correction to constant frequency on Moon
|
||||
correction.rx = ndop00 / 2;
|
||||
correction.rx = m_dop00 / 2;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (3 != m_DopplerMethod) correction.tx = -correction.rx;
|
||||
switch (m_DopplerMethod)
|
||||
{
|
||||
case 1: correction.tx = -correction.rx;
|
||||
break;
|
||||
case 2: correction.tx = -correction.rx;
|
||||
break;
|
||||
case 3: correction.tx = 0;
|
||||
break;
|
||||
case 4: // correction.tx = m_dop - m_dop00;
|
||||
|
||||
correction.tx = m_dx_two_way_dop - m_dop;
|
||||
qDebug () << "correction.tx:" << correction.tx;
|
||||
break;
|
||||
case 5: correction.tx = - m_dop00;
|
||||
break;
|
||||
}
|
||||
//if (3 != m_DopplerMethod || 4 != m_DopplerMethod) correction.tx = -correction.rx;
|
||||
|
||||
if(dx_is_self && m_DopplerMethod == 1) correction.rx = 0;
|
||||
|
||||
if (no_tx_QSY && 3 != m_DopplerMethod && 0 != m_DopplerMethod)
|
||||
{
|
||||
// calculate a single correction for transmit half way through
|
||||
// the period as a compromise for rigs that can't CAT QSY
|
||||
// while transmitting
|
||||
// calculate a single correction for transmit half way through
|
||||
// the period as a compromise for rigs that can't CAT QSY
|
||||
// while transmitting
|
||||
//
|
||||
// use a base time of (secs-since-epoch + 2) so as to be sure
|
||||
// we do the next period if we calculate just before it starts
|
||||
@@ -194,7 +224,7 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
|
||||
double uth {nhr + nmin/60.0 + sec/3600.0};
|
||||
astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid_padded.toLatin1().constData(),
|
||||
hisgrid_padded.toLatin1().constData(), &azsun, &elsun, &azmoon, &elmoon,
|
||||
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00, &ramoon, &decmoon,
|
||||
&azmoondx, &elmoondx, &ntsky, &m_dop, &m_dop00, &ramoon, &decmoon,
|
||||
&dgrd, &poloffset, &xnr, &techo, &width1, &width2, &bTx,
|
||||
"", jpleph.toLatin1().constData(), 6, 6,
|
||||
0, jpleph.length());
|
||||
@@ -203,15 +233,27 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
|
||||
{
|
||||
case 1:
|
||||
// All Doppler correction done here; DX station stays at nominal dial frequency.
|
||||
offset = dx_is_self ? ndop00 : ndop;
|
||||
offset = dx_is_self ? m_dop00 : m_dop;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Doppler correction to constant frequency on Moon
|
||||
offset = ndop00 / 2;
|
||||
offset = m_dop00 / 2;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// Doppler correction for OnDxEcho
|
||||
offset = m_dop - m_dx_two_way_dop;
|
||||
break;
|
||||
|
||||
//case 5: correction.tx = - m_dop00;
|
||||
case 5: offset = m_dop00;// version for _7
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
correction.tx = -offset;
|
||||
qDebug () << "correction.tx (no tx qsy):" << correction.tx;
|
||||
}
|
||||
}
|
||||
return correction;
|
||||
@@ -235,13 +277,31 @@ void Astro::on_rbFullTrack_clicked()
|
||||
Q_EMIT tracking_update ();
|
||||
}
|
||||
|
||||
void Astro::on_rbRxOnly_clicked()
|
||||
void Astro::on_rbOnDxEcho_clicked(bool checked)
|
||||
{
|
||||
m_DopplerMethod = 4;
|
||||
check_split ();
|
||||
if (checked) {
|
||||
m_dx_two_way_dop = 2 * (m_dop - (m_dop00/2));
|
||||
qDebug () << "Starting Doppler:" << m_dx_two_way_dop;
|
||||
}
|
||||
Q_EMIT tracking_update ();
|
||||
}
|
||||
|
||||
void Astro::on_rbOwnEcho_clicked()
|
||||
{
|
||||
m_DopplerMethod = 3;
|
||||
check_split ();
|
||||
Q_EMIT tracking_update ();
|
||||
}
|
||||
|
||||
void Astro::on_rbCallDx_clicked()
|
||||
{
|
||||
m_DopplerMethod = 5;
|
||||
check_split ();
|
||||
Q_EMIT tracking_update ();
|
||||
}
|
||||
|
||||
void Astro::on_rbConstFreqOnMoon_clicked()
|
||||
{
|
||||
m_DopplerMethod = 2;
|
||||
|
||||
@@ -57,8 +57,10 @@ protected:
|
||||
private slots:
|
||||
void on_rbConstFreqOnMoon_clicked();
|
||||
void on_rbFullTrack_clicked();
|
||||
void on_rbRxOnly_clicked();
|
||||
void on_rbOwnEcho_clicked();
|
||||
void on_rbNoDoppler_clicked();
|
||||
void on_rbOnDxEcho_clicked(bool);
|
||||
void on_rbCallDx_clicked();
|
||||
void on_cbDopplerTracking_toggled(bool);
|
||||
|
||||
private:
|
||||
@@ -71,6 +73,9 @@ private:
|
||||
QScopedPointer<Ui::Astro> ui_;
|
||||
|
||||
qint32 m_DopplerMethod;
|
||||
int m_dop;
|
||||
int m_dop00;
|
||||
int m_dx_two_way_dop;
|
||||
};
|
||||
|
||||
inline
|
||||
|
||||
@@ -48,12 +48,12 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbRxOnly">
|
||||
<widget class="QRadioButton" name="rbOwnEcho">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Both stations do full correction to their QSO partner's grid square during receive, no correction is applied on transmit.</p><p>This mode facilitates accurate Doppler shift correction when one or both stations have a rig that does not accept CAT QSY commands while transmitting.</p></body></html></string>
|
||||
<string><html><head/><body><p>Transmit takes place on sked frequency and receive frequency is corrected for own echoes. </p><p>This mode can be used for calling CQ, or when using Echo mode.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Receive only</string>
|
||||
<string>Own Echo</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -70,6 +70,32 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbOnDxEcho">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>DX station announces their TX Freq, which is entered as the Sked Freq. Correction applied to RX and TX so you appear on the DX's station's own echo Freq.</p><p>If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>On DX Echo</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbCallDx">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Tune radio manually and select this mode to put your echo on the same frequency.</p><p>If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Call DX</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbNoDoppler">
|
||||
<property name="toolTip">
|
||||
@@ -83,7 +109,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
See ./index.html for information about this release. The "Getting Started"
|
||||
section is a useful starting place.
|
||||
|
||||
---------------------------
|
||||
Copyright Beman Dawes, 2008
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
See ./LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt
|
||||
@@ -0,0 +1,312 @@
|
||||
# Copyright Vladimir Prus 2002-2006.
|
||||
# Copyright Dave Abrahams 2005-2006.
|
||||
# Copyright Rene Rivera 2005-2007.
|
||||
# Copyright Douglas Gregor 2005.
|
||||
#
|
||||
# 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)
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# b2 [options] [properties] [install|stage]
|
||||
#
|
||||
# Builds and installs Boost.
|
||||
#
|
||||
# Targets and Related Options:
|
||||
#
|
||||
# install Install headers and compiled library files to the
|
||||
# ======= configured locations (below).
|
||||
#
|
||||
# --prefix=<PREFIX> Install architecture independent files here.
|
||||
# Default; C:\Boost on Win32
|
||||
# Default; /usr/local on Unix. Linux, etc.
|
||||
#
|
||||
# --exec-prefix=<EPREFIX> Install architecture dependent files here.
|
||||
# Default; <PREFIX>
|
||||
#
|
||||
# --libdir=<DIR> Install library files here.
|
||||
# Default; <EPREFIX>/lib
|
||||
#
|
||||
# --includedir=<HDRDIR> Install header files here.
|
||||
# Default; <PREFIX>/include
|
||||
#
|
||||
# stage Build and install only compiled library files to the
|
||||
# ===== stage directory.
|
||||
#
|
||||
# --stagedir=<STAGEDIR> Install library files here
|
||||
# Default; ./stage
|
||||
#
|
||||
# Other Options:
|
||||
#
|
||||
# --build-type=<type> Build the specified pre-defined set of variations of
|
||||
# the libraries. Note, that which variants get built
|
||||
# depends on what each library supports.
|
||||
#
|
||||
# -- minimal -- (default) Builds a minimal set of
|
||||
# variants. On Windows, these are static
|
||||
# multithreaded libraries in debug and release
|
||||
# modes, using shared runtime. On Linux, these are
|
||||
# static and shared multithreaded libraries in
|
||||
# release mode.
|
||||
#
|
||||
# -- complete -- Build all possible variations.
|
||||
#
|
||||
# --build-dir=DIR Build in this location instead of building within
|
||||
# the distribution tree. Recommended!
|
||||
#
|
||||
# --show-libraries Display the list of Boost libraries that require
|
||||
# build and installation steps, and then exit.
|
||||
#
|
||||
# --layout=<layout> Determine whether to choose library names and header
|
||||
# locations such that multiple versions of Boost or
|
||||
# multiple compilers can be used on the same system.
|
||||
#
|
||||
# -- versioned -- Names of boost binaries include
|
||||
# the Boost version number, name and version of
|
||||
# the compiler and encoded build properties. Boost
|
||||
# headers are installed in a subdirectory of
|
||||
# <HDRDIR> whose name contains the Boost version
|
||||
# number.
|
||||
#
|
||||
# -- tagged -- Names of boost binaries include the
|
||||
# encoded build properties such as variant and
|
||||
# threading, but do not including compiler name
|
||||
# and version, or Boost version. This option is
|
||||
# useful if you build several variants of Boost,
|
||||
# using the same compiler.
|
||||
#
|
||||
# -- system -- Binaries names do not include the
|
||||
# Boost version number or the name and version
|
||||
# number of the compiler. Boost headers are
|
||||
# installed directly into <HDRDIR>. This option is
|
||||
# intended for system integrators building
|
||||
# distribution packages.
|
||||
#
|
||||
# The default value is 'versioned' on Windows, and
|
||||
# 'system' on Unix.
|
||||
#
|
||||
# --buildid=ID Add the specified ID to the name of built libraries.
|
||||
# The default is to not add anything.
|
||||
#
|
||||
# --python-buildid=ID Add the specified ID to the name of built libraries
|
||||
# that depend on Python. The default is to not add
|
||||
# anything. This ID is added in addition to --buildid.
|
||||
#
|
||||
# --help This message.
|
||||
#
|
||||
# --with-<library> Build and install the specified <library>. If this
|
||||
# option is used, only libraries specified using this
|
||||
# option will be built.
|
||||
#
|
||||
# --without-<library> Do not build, stage, or install the specified
|
||||
# <library>. By default, all libraries are built.
|
||||
#
|
||||
# Properties:
|
||||
#
|
||||
# toolset=toolset Indicate the toolset to build with.
|
||||
#
|
||||
# variant=debug|release Select the build variant
|
||||
#
|
||||
# link=static|shared Whether to build static or shared libraries
|
||||
#
|
||||
# threading=single|multi Whether to build single or multithreaded binaries
|
||||
#
|
||||
# runtime-link=static|shared
|
||||
# Whether to link to static or shared C and C++
|
||||
# runtime.
|
||||
#
|
||||
|
||||
# TODO:
|
||||
# - handle boost version
|
||||
# - handle python options such as pydebug
|
||||
|
||||
import boostcpp ;
|
||||
import package ;
|
||||
|
||||
import sequence ;
|
||||
import xsltproc ;
|
||||
import set ;
|
||||
import path ;
|
||||
import link ;
|
||||
|
||||
path-constant BOOST_ROOT : . ;
|
||||
constant BOOST_VERSION : 1.63.0 ;
|
||||
constant BOOST_JAMROOT_MODULE : $(__name__) ;
|
||||
|
||||
boostcpp.set-version $(BOOST_VERSION) ;
|
||||
|
||||
use-project /boost/architecture : libs/config/checks/architecture ;
|
||||
|
||||
local all-headers =
|
||||
[ MATCH .*libs/(.*)/include/boost : [ glob libs/*/include/boost libs/*/*/include/boost ] ] ;
|
||||
|
||||
for dir in $(all-headers)
|
||||
{
|
||||
link-directory $(dir)-headers : libs/$(dir)/include/boost : <location>. ;
|
||||
explicit $(dir)-headers ;
|
||||
}
|
||||
|
||||
if $(all-headers)
|
||||
{
|
||||
constant BOOST_MODULARLAYOUT : $(all-headers) ;
|
||||
}
|
||||
|
||||
project boost
|
||||
: requirements <include>.
|
||||
|
||||
[ boostcpp.architecture ]
|
||||
[ boostcpp.address-model ]
|
||||
|
||||
# Disable auto-linking for all targets here, primarily because it caused
|
||||
# troubles with V2.
|
||||
<define>BOOST_ALL_NO_LIB=1
|
||||
# Used to encode variant in target name. See the 'tag' rule below.
|
||||
<tag>@$(__name__).tag
|
||||
<conditional>@handle-static-runtime
|
||||
# Comeau does not support shared lib
|
||||
<toolset>como:<link>static
|
||||
<toolset>como-linux:<define>_GNU_SOURCE=1
|
||||
# When building docs within Boost, we want the standard Boost style
|
||||
<xsl:param>boost.defaults=Boost
|
||||
: usage-requirements <include>.
|
||||
: build-dir bin.v2
|
||||
;
|
||||
|
||||
# This rule is called by Boost.Build to determine the name of target. We use it
|
||||
# to encode the build variant, compiler name and boost version in the target
|
||||
# name.
|
||||
#
|
||||
rule tag ( name : type ? : property-set )
|
||||
{
|
||||
return [ boostcpp.tag $(name) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
|
||||
rule python-tag ( name : type ? : property-set )
|
||||
{
|
||||
return [ boostcpp.python-tag $(name) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
|
||||
rule handle-static-runtime ( properties * )
|
||||
{
|
||||
# Using static runtime with shared libraries is impossible on Linux, and
|
||||
# dangerous on Windows. Therefore, we disallow it. This might be drastic,
|
||||
# but it was disabled for a while without anybody complaining.
|
||||
|
||||
# For CW, static runtime is needed so that std::locale works.
|
||||
if <link>shared in $(properties) && <runtime-link>static in $(properties) &&
|
||||
! ( <toolset>cw in $(properties) )
|
||||
{
|
||||
ECHO "error: link=shared together with runtime-link=static is not allowed" ;
|
||||
ECHO "error: such property combination is either impossible " ;
|
||||
ECHO "error: or too dangerious to be of any use" ;
|
||||
EXIT ;
|
||||
}
|
||||
}
|
||||
|
||||
all-libraries = [ MATCH .*libs/(.*)/build/.* : [ glob libs/*/build/Jamfile.v2 ]
|
||||
[ glob libs/*/build/Jamfile ] ] ;
|
||||
|
||||
all-libraries = [ sequence.unique $(all-libraries) ] ;
|
||||
# The function_types library has a Jamfile, but it's used for maintenance
|
||||
# purposes, there's no library to build and install.
|
||||
all-libraries = [ set.difference $(all-libraries) : function_types ] ;
|
||||
|
||||
# Setup convenient aliases for all libraries.
|
||||
|
||||
local rule explicit-alias ( id : targets + )
|
||||
{
|
||||
alias $(id) : $(targets) ;
|
||||
explicit $(id) ;
|
||||
}
|
||||
|
||||
# First, the complicated libraries: where the target name in Jamfile is
|
||||
# different from its directory name.
|
||||
explicit-alias prg_exec_monitor : libs/test/build//boost_prg_exec_monitor ;
|
||||
explicit-alias test_exec_monitor : libs/test/build//boost_test_exec_monitor ;
|
||||
explicit-alias unit_test_framework : libs/test/build//boost_unit_test_framework ;
|
||||
explicit-alias bgl-vis : libs/graps/build//bgl-vis ;
|
||||
explicit-alias serialization : libs/serialization/build//boost_serialization ;
|
||||
explicit-alias wserialization : libs/serialization/build//boost_wserialization ;
|
||||
for local l in $(all-libraries)
|
||||
{
|
||||
if ! $(l) in test graph serialization
|
||||
{
|
||||
explicit-alias $(l) : libs/$(l)/build//boost_$(l) ;
|
||||
}
|
||||
}
|
||||
|
||||
# Log has an additional target
|
||||
explicit-alias log_setup : libs/log/build//boost_log_setup ;
|
||||
|
||||
alias headers : $(all-headers)-headers : : : <include>. ;
|
||||
explicit headers ;
|
||||
|
||||
# Make project ids of all libraries known.
|
||||
for local l in $(all-libraries)
|
||||
{
|
||||
use-project /boost/$(l) : libs/$(l)/build ;
|
||||
}
|
||||
|
||||
if [ path.exists $(BOOST_ROOT)/tools/inspect ]
|
||||
{
|
||||
use-project /boost/tools/inspect : tools/inspect/build ;
|
||||
}
|
||||
|
||||
if [ path.exists $(BOOST_ROOT)/libs/wave/tool ]
|
||||
{
|
||||
use-project /boost/libs/wave/tool : libs/wave/tool/build ;
|
||||
}
|
||||
|
||||
# This rule should be called from libraries' Jamfiles and will create two
|
||||
# targets, "install" and "stage", that will install or stage that library. The
|
||||
# --prefix option is respected, but --with and --without options, naturally, are
|
||||
# ignored.
|
||||
#
|
||||
# - libraries -- list of library targets to install.
|
||||
#
|
||||
rule boost-install ( libraries * )
|
||||
{
|
||||
package.install install
|
||||
: <dependency>/boost//install-proper-headers $(install-requirements)
|
||||
: # No binaries
|
||||
: $(libraries)
|
||||
: # No headers, it is handled by the dependency.
|
||||
;
|
||||
|
||||
install stage : $(libraries) : <location>$(BOOST_STAGE_LOCATE) ;
|
||||
|
||||
module [ CALLER_MODULE ]
|
||||
{
|
||||
explicit stage ;
|
||||
explicit install ;
|
||||
}
|
||||
}
|
||||
|
||||
# Creates a library target, adding autolink support and also creates
|
||||
# stage and install targets via boost-install, above.
|
||||
rule boost-lib ( name : sources * : requirements * : default-build * : usage-requirements * )
|
||||
{
|
||||
name = boost_$(name) ;
|
||||
autolink = <link>shared:<define>BOOST_$(name:U)_DYN_LINK=1 ;
|
||||
lib $(name)
|
||||
: $(sources)
|
||||
: $(requirements) $(autolink)
|
||||
: $(default-build)
|
||||
: $(usage-requirements) $(autolink)
|
||||
;
|
||||
boost-install $(name) ;
|
||||
}
|
||||
|
||||
|
||||
headers =
|
||||
# The .SUNWCCh files are present in tr1 include directory and have to be
|
||||
# installed (see http://lists.boost.org/Archives/boost/2007/05/121430.php).
|
||||
[ path.glob-tree $(BOOST_ROOT)/boost : *.hpp *.ipp *.h *.inc *.SUNWCCh : CVS .svn ]
|
||||
[ path.glob-tree $(BOOST_ROOT)/boost/compatibility/cpp_c_headers : c* : CVS .svn ]
|
||||
[ path.glob boost/tr1/tr1 : * : bcc32 sun CVS .svn ]
|
||||
;
|
||||
|
||||
# Declare special top-level targets that build and install the desired variants
|
||||
# of the libraries.
|
||||
boostcpp.declare-targets $(all-libraries) : $(headers) ;
|
||||
@@ -0,0 +1,23 @@
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,11 @@
|
||||
This boost tree is a cut down version of the 1.63.0 source tree built
|
||||
using the boost bcp utility, invoked thus:
|
||||
|
||||
cd <clean-boost-source-tree>
|
||||
<path-where-bcp-was-built>/bcp iterator range math numeric crc circular_buffer build bootstrap.bat bootstrap.sh boostcpp.jam boost-build.jam <this-directory>
|
||||
|
||||
Note that bcp is built from a separate boost source tree to avoid
|
||||
polluting the clean tree used to extract components from above.
|
||||
|
||||
Add other boost libraries as necessary. See the Subversion book for
|
||||
details on how to maintain 3rd-party vendor content used in a project.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2002-2003 David Abrahams.
|
||||
# Copyright (C) 2002-2003 Vladimir Prus.
|
||||
# Copyright (C) 2003,2007 Rene Rivera.
|
||||
# Use, modification and distribution are subject to 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)
|
||||
|
||||
# This is the initial file loaded by Boost Jam when run from any Boost library
|
||||
# folder. It allows us to choose which Boost Build installation to use for
|
||||
# building Boost libraries. Unless explicitly selected using a command-line
|
||||
# option, the version included with the Boost library distribution is used (as
|
||||
# opposed to any other Boost Build version installed on the user's sytem).
|
||||
|
||||
BOOST_ROOT = $(.boost-build-file:D) ;
|
||||
BOOST_BUILD = [ MATCH --boost-build=(.*) : $(ARGV) ] ;
|
||||
BOOST_BUILD ?= tools/build/src ;
|
||||
boost-build $(BOOST_BUILD) ;
|
||||
@@ -0,0 +1,66 @@
|
||||
/*=============================================================================
|
||||
Copyright 2002 William E. Kempf
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompany-
|
||||
ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
|
||||
H1
|
||||
{
|
||||
FONT-SIZE: 200%;
|
||||
COLOR: #00008B;
|
||||
}
|
||||
H2
|
||||
{
|
||||
FONT-SIZE: 150%;
|
||||
}
|
||||
H3
|
||||
{
|
||||
FONT-SIZE: 125%;
|
||||
}
|
||||
H4
|
||||
{
|
||||
FONT-SIZE: 108%;
|
||||
}
|
||||
BODY
|
||||
{
|
||||
FONT-SIZE: 100%;
|
||||
BACKGROUND-COLOR: #ffffff;
|
||||
COLOR: #000000;
|
||||
}
|
||||
PRE
|
||||
{
|
||||
MARGIN-LEFT: 2em;
|
||||
FONT-FAMILY: Courier,
|
||||
monospace;
|
||||
}
|
||||
CODE
|
||||
{
|
||||
FONT-FAMILY: Courier,
|
||||
monospace;
|
||||
}
|
||||
CODE.as_pre
|
||||
{
|
||||
white-space: pre;
|
||||
}
|
||||
.index
|
||||
{
|
||||
TEXT-ALIGN: left;
|
||||
}
|
||||
.page-index
|
||||
{
|
||||
TEXT-ALIGN: left;
|
||||
}
|
||||
.definition
|
||||
{
|
||||
TEXT-ALIGN: left;
|
||||
}
|
||||
.footnote
|
||||
{
|
||||
FONT-SIZE: 66%;
|
||||
VERTICAL-ALIGN: super;
|
||||
TEXT-DECORATION: none;
|
||||
}
|
||||
.function-semantics
|
||||
{
|
||||
CLEAR: left;
|
||||
}
|
||||
|
After Width: | Height: | Size: 6.2 KiB |
@@ -0,0 +1,62 @@
|
||||
// Circular buffer library header file.
|
||||
|
||||
// Copyright (c) 2003-2008 Jan Gaspar
|
||||
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
// See www.boost.org/libs/circular_buffer for documentation.
|
||||
|
||||
#if !defined(BOOST_CIRCULAR_BUFFER_HPP)
|
||||
#define BOOST_CIRCULAR_BUFFER_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/circular_buffer_fwd.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
// BOOST_CB_ENABLE_DEBUG: Debug support control.
|
||||
#if !defined(BOOST_CB_ENABLE_DEBUG)
|
||||
#define BOOST_CB_ENABLE_DEBUG 0
|
||||
#endif
|
||||
|
||||
// BOOST_CB_ASSERT: Runtime assertion.
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
#include <boost/assert.hpp>
|
||||
#define BOOST_CB_ASSERT(Expr) BOOST_ASSERT(Expr)
|
||||
#else
|
||||
#define BOOST_CB_ASSERT(Expr) ((void)0)
|
||||
#endif
|
||||
|
||||
// BOOST_CB_IS_CONVERTIBLE: Check if Iterator::value_type is convertible to Type.
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0550) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
#define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) ((void)0)
|
||||
#else
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) \
|
||||
BOOST_STATIC_ASSERT((is_convertible<typename detail::iterator_traits<Iterator>::value_type, Type>::value))
|
||||
#endif
|
||||
|
||||
// BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS:
|
||||
// Check if the STL provides templated iterator constructors for its containers.
|
||||
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
|
||||
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS BOOST_STATIC_ASSERT(false);
|
||||
#else
|
||||
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS ((void)0);
|
||||
#endif
|
||||
|
||||
#include <boost/circular_buffer/debug.hpp>
|
||||
#include <boost/circular_buffer/details.hpp>
|
||||
#include <boost/circular_buffer/base.hpp>
|
||||
#include <boost/circular_buffer/space_optimized.hpp>
|
||||
|
||||
#undef BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS
|
||||
#undef BOOST_CB_IS_CONVERTIBLE
|
||||
#undef BOOST_CB_ASSERT
|
||||
|
||||
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_HPP)
|
||||
@@ -0,0 +1,248 @@
|
||||
// Debug support for the circular buffer library.
|
||||
|
||||
// Copyright (c) 2003-2008 Jan Gaspar
|
||||
|
||||
// Use, modification, and distribution is subject to 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 !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP)
|
||||
#define BOOST_CIRCULAR_BUFFER_DEBUG_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
#include <cstring>
|
||||
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std {
|
||||
using ::memset;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BOOST_CB_ENABLE_DEBUG
|
||||
namespace boost {
|
||||
|
||||
namespace cb_details {
|
||||
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
|
||||
// The value the uninitialized memory is filled with.
|
||||
const int UNINITIALIZED = 0xcc;
|
||||
|
||||
template <class T>
|
||||
inline void do_fill_uninitialized_memory(T* data, std::size_t size_in_bytes) BOOST_NOEXCEPT {
|
||||
std::memset(static_cast<void*>(data), UNINITIALIZED, size_in_bytes);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void do_fill_uninitialized_memory(T& /*data*/, std::size_t /*size_in_bytes*/) BOOST_NOEXCEPT {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
class debug_iterator_registry;
|
||||
|
||||
/*!
|
||||
\class debug_iterator_base
|
||||
\brief Registers/unregisters iterators into the registry of valid iterators.
|
||||
|
||||
This class is intended to be a base class of an iterator.
|
||||
*/
|
||||
class debug_iterator_base {
|
||||
|
||||
private:
|
||||
// Members
|
||||
|
||||
//! Iterator registry.
|
||||
mutable const debug_iterator_registry* m_registry;
|
||||
|
||||
//! Next iterator in the iterator chain.
|
||||
mutable const debug_iterator_base* m_next;
|
||||
|
||||
public:
|
||||
// Construction/destruction
|
||||
|
||||
//! Default constructor.
|
||||
debug_iterator_base();
|
||||
|
||||
//! Constructor taking the iterator registry as a parameter.
|
||||
debug_iterator_base(const debug_iterator_registry* registry);
|
||||
|
||||
//! Copy constructor.
|
||||
debug_iterator_base(const debug_iterator_base& rhs);
|
||||
|
||||
//! Destructor.
|
||||
~debug_iterator_base();
|
||||
|
||||
// Methods
|
||||
|
||||
//! Assign operator.
|
||||
debug_iterator_base& operator = (const debug_iterator_base& rhs);
|
||||
|
||||
//! Is the iterator valid?
|
||||
bool is_valid(const debug_iterator_registry* registry) const;
|
||||
|
||||
//! Invalidate the iterator.
|
||||
/*!
|
||||
\note The method is const in order to invalidate const iterators, too.
|
||||
*/
|
||||
void invalidate() const;
|
||||
|
||||
//! Return the next iterator in the iterator chain.
|
||||
const debug_iterator_base* next() const;
|
||||
|
||||
//! Set the next iterator in the iterator chain.
|
||||
/*!
|
||||
\note The method is const in order to set a next iterator to a const iterator, too.
|
||||
*/
|
||||
void set_next(const debug_iterator_base* it) const;
|
||||
|
||||
private:
|
||||
// Helpers
|
||||
|
||||
//! Register self as a valid iterator.
|
||||
void register_self();
|
||||
|
||||
//! Unregister self from valid iterators.
|
||||
void unregister_self();
|
||||
};
|
||||
|
||||
/*!
|
||||
\class debug_iterator_registry
|
||||
\brief Registry of valid iterators.
|
||||
|
||||
This class is intended to be a base class of a container.
|
||||
*/
|
||||
class debug_iterator_registry {
|
||||
|
||||
//! Pointer to the chain of valid iterators.
|
||||
mutable const debug_iterator_base* m_iterators;
|
||||
|
||||
public:
|
||||
// Methods
|
||||
|
||||
//! Default constructor.
|
||||
debug_iterator_registry() : m_iterators(0) {}
|
||||
|
||||
//! Register an iterator into the list of valid iterators.
|
||||
/*!
|
||||
\note The method is const in order to register iterators into const containers, too.
|
||||
*/
|
||||
void register_iterator(const debug_iterator_base* it) const {
|
||||
it->set_next(m_iterators);
|
||||
m_iterators = it;
|
||||
}
|
||||
|
||||
//! Unregister an iterator from the list of valid iterators.
|
||||
/*!
|
||||
\note The method is const in order to unregister iterators from const containers, too.
|
||||
*/
|
||||
void unregister_iterator(const debug_iterator_base* it) const {
|
||||
const debug_iterator_base* previous = 0;
|
||||
for (const debug_iterator_base* p = m_iterators; p != it; previous = p, p = p->next()) {}
|
||||
remove(it, previous);
|
||||
}
|
||||
|
||||
//! Invalidate every iterator pointing to the same element as the iterator passed as a parameter.
|
||||
template <class Iterator>
|
||||
void invalidate_iterators(const Iterator& it) {
|
||||
const debug_iterator_base* previous = 0;
|
||||
for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) {
|
||||
if (((Iterator*)p)->m_it == it.m_it) {
|
||||
p->invalidate();
|
||||
remove(p, previous);
|
||||
continue;
|
||||
}
|
||||
previous = p;
|
||||
}
|
||||
}
|
||||
|
||||
//! Invalidate all iterators except an iterator poining to the same element as the iterator passed as a parameter.
|
||||
template <class Iterator>
|
||||
void invalidate_iterators_except(const Iterator& it) {
|
||||
const debug_iterator_base* previous = 0;
|
||||
for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) {
|
||||
if (((Iterator*)p)->m_it != it.m_it) {
|
||||
p->invalidate();
|
||||
remove(p, previous);
|
||||
continue;
|
||||
}
|
||||
previous = p;
|
||||
}
|
||||
}
|
||||
|
||||
//! Invalidate all iterators.
|
||||
void invalidate_all_iterators() {
|
||||
for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next())
|
||||
p->invalidate();
|
||||
m_iterators = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
// Helpers
|
||||
|
||||
//! Remove the current iterator from the iterator chain.
|
||||
void remove(const debug_iterator_base* current,
|
||||
const debug_iterator_base* previous) const {
|
||||
if (previous == 0)
|
||||
m_iterators = m_iterators->next();
|
||||
else
|
||||
previous->set_next(current->next());
|
||||
}
|
||||
};
|
||||
|
||||
// Implementation of the debug_iterator_base methods.
|
||||
|
||||
inline debug_iterator_base::debug_iterator_base() : m_registry(0), m_next(0) {}
|
||||
|
||||
inline debug_iterator_base::debug_iterator_base(const debug_iterator_registry* registry)
|
||||
: m_registry(registry), m_next(0) {
|
||||
register_self();
|
||||
}
|
||||
|
||||
inline debug_iterator_base::debug_iterator_base(const debug_iterator_base& rhs)
|
||||
: m_registry(rhs.m_registry), m_next(0) {
|
||||
register_self();
|
||||
}
|
||||
|
||||
inline debug_iterator_base::~debug_iterator_base() { unregister_self(); }
|
||||
|
||||
inline debug_iterator_base& debug_iterator_base::operator = (const debug_iterator_base& rhs) {
|
||||
if (m_registry == rhs.m_registry)
|
||||
return *this;
|
||||
unregister_self();
|
||||
m_registry = rhs.m_registry;
|
||||
register_self();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool debug_iterator_base::is_valid(const debug_iterator_registry* registry) const {
|
||||
return m_registry == registry;
|
||||
}
|
||||
|
||||
inline void debug_iterator_base::invalidate() const { m_registry = 0; }
|
||||
|
||||
inline const debug_iterator_base* debug_iterator_base::next() const { return m_next; }
|
||||
|
||||
inline void debug_iterator_base::set_next(const debug_iterator_base* it) const { m_next = it; }
|
||||
|
||||
inline void debug_iterator_base::register_self() {
|
||||
if (m_registry != 0)
|
||||
m_registry->register_iterator(this);
|
||||
}
|
||||
|
||||
inline void debug_iterator_base::unregister_self() {
|
||||
if (m_registry != 0)
|
||||
m_registry->unregister_iterator(this);
|
||||
}
|
||||
|
||||
#endif // #if BOOST_CB_ENABLE_DEBUG
|
||||
|
||||
} // namespace cb_details
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP)
|
||||
@@ -0,0 +1,498 @@
|
||||
// Helper classes and functions for the circular buffer.
|
||||
|
||||
// Copyright (c) 2003-2008 Jan Gaspar
|
||||
// Copyright (c) 2014 Glen Fernandes // C++11 allocator model support.
|
||||
|
||||
// Use, modification, and distribution is subject to 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 !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)
|
||||
#define BOOST_CIRCULAR_BUFFER_DETAILS_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <iterator>
|
||||
|
||||
// Silence MS /W4 warnings like C4913:
|
||||
// "user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used"
|
||||
// This might happen when previously including some boost headers that overload the coma operator.
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4913)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace cb_details {
|
||||
|
||||
template <class Traits> struct nonconst_traits;
|
||||
|
||||
template<class ForwardIterator, class Diff, class T, class Alloc>
|
||||
void uninitialized_fill_n_with_alloc(
|
||||
ForwardIterator first, Diff n, const T& item, Alloc& alloc);
|
||||
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
|
||||
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
|
||||
|
||||
/*!
|
||||
\struct const_traits
|
||||
\brief Defines the data types for a const iterator.
|
||||
*/
|
||||
template <class Traits>
|
||||
struct const_traits {
|
||||
// Basic types
|
||||
typedef typename Traits::value_type value_type;
|
||||
typedef typename Traits::const_pointer pointer;
|
||||
typedef typename Traits::const_reference reference;
|
||||
typedef typename Traits::size_type size_type;
|
||||
typedef typename Traits::difference_type difference_type;
|
||||
|
||||
// Non-const traits
|
||||
typedef nonconst_traits<Traits> nonconst_self;
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct nonconst_traits
|
||||
\brief Defines the data types for a non-const iterator.
|
||||
*/
|
||||
template <class Traits>
|
||||
struct nonconst_traits {
|
||||
// Basic types
|
||||
typedef typename Traits::value_type value_type;
|
||||
typedef typename Traits::pointer pointer;
|
||||
typedef typename Traits::reference reference;
|
||||
typedef typename Traits::size_type size_type;
|
||||
typedef typename Traits::difference_type difference_type;
|
||||
|
||||
// Non-const traits
|
||||
typedef nonconst_traits<Traits> nonconst_self;
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct iterator_wrapper
|
||||
\brief Helper iterator dereference wrapper.
|
||||
*/
|
||||
template <class Iterator>
|
||||
struct iterator_wrapper {
|
||||
mutable Iterator m_it;
|
||||
explicit iterator_wrapper(Iterator it) : m_it(it) {}
|
||||
Iterator operator () () const { return m_it++; }
|
||||
private:
|
||||
iterator_wrapper<Iterator>& operator = (const iterator_wrapper<Iterator>&); // do not generate
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct item_wrapper
|
||||
\brief Helper item dereference wrapper.
|
||||
*/
|
||||
template <class Pointer, class Value>
|
||||
struct item_wrapper {
|
||||
Value m_item;
|
||||
explicit item_wrapper(Value item) : m_item(item) {}
|
||||
Pointer operator () () const { return &m_item; }
|
||||
private:
|
||||
item_wrapper<Pointer, Value>& operator = (const item_wrapper<Pointer, Value>&); // do not generate
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct assign_n
|
||||
\brief Helper functor for assigning n items.
|
||||
*/
|
||||
template <class Value, class Alloc>
|
||||
struct assign_n {
|
||||
typedef typename boost::container::allocator_traits<Alloc>::size_type size_type;
|
||||
size_type m_n;
|
||||
Value m_item;
|
||||
Alloc& m_alloc;
|
||||
assign_n(size_type n, Value item, Alloc& alloc) : m_n(n), m_item(item), m_alloc(alloc) {}
|
||||
template <class Pointer>
|
||||
void operator () (Pointer p) const {
|
||||
uninitialized_fill_n_with_alloc(p, m_n, m_item, m_alloc);
|
||||
}
|
||||
private:
|
||||
assign_n<Value, Alloc>& operator = (const assign_n<Value, Alloc>&); // do not generate
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct assign_range
|
||||
\brief Helper functor for assigning range of items.
|
||||
*/
|
||||
template <class Iterator, class Alloc>
|
||||
struct assign_range {
|
||||
Iterator m_first;
|
||||
Iterator m_last;
|
||||
Alloc& m_alloc;
|
||||
|
||||
assign_range(const Iterator& first, const Iterator& last, Alloc& alloc)
|
||||
: m_first(first), m_last(last), m_alloc(alloc) {}
|
||||
|
||||
template <class Pointer>
|
||||
void operator () (Pointer p) const {
|
||||
boost::cb_details::uninitialized_copy(m_first, m_last, p, m_alloc);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Iterator, class Alloc>
|
||||
inline assign_range<Iterator, Alloc> make_assign_range(const Iterator& first, const Iterator& last, Alloc& a) {
|
||||
return assign_range<Iterator, Alloc>(first, last, a);
|
||||
}
|
||||
|
||||
/*!
|
||||
\class capacity_control
|
||||
\brief Capacity controller of the space optimized circular buffer.
|
||||
*/
|
||||
template <class Size>
|
||||
class capacity_control {
|
||||
|
||||
//! The capacity of the space-optimized circular buffer.
|
||||
Size m_capacity;
|
||||
|
||||
//! The lowest guaranteed or minimum capacity of the adapted space-optimized circular buffer.
|
||||
Size m_min_capacity;
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor.
|
||||
capacity_control(Size buffer_capacity, Size min_buffer_capacity = 0)
|
||||
: m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity)
|
||||
{ // Check for capacity lower than min_capacity.
|
||||
BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity);
|
||||
}
|
||||
|
||||
// Default copy constructor.
|
||||
|
||||
// Default assign operator.
|
||||
|
||||
//! Get the capacity of the space optimized circular buffer.
|
||||
Size capacity() const { return m_capacity; }
|
||||
|
||||
//! Get the minimal capacity of the space optimized circular buffer.
|
||||
Size min_capacity() const { return m_min_capacity; }
|
||||
|
||||
//! Size operator - returns the capacity of the space optimized circular buffer.
|
||||
operator Size() const { return m_capacity; }
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct iterator
|
||||
\brief Random access iterator for the circular buffer.
|
||||
\param Buff The type of the underlying circular buffer.
|
||||
\param Traits Basic iterator types.
|
||||
\note This iterator is not circular. It was designed
|
||||
for iterating from begin() to end() of the circular buffer.
|
||||
*/
|
||||
template <class Buff, class Traits>
|
||||
struct iterator :
|
||||
public std::iterator<
|
||||
std::random_access_iterator_tag,
|
||||
typename Traits::value_type,
|
||||
typename Traits::difference_type,
|
||||
typename Traits::pointer,
|
||||
typename Traits::reference>
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
, public debug_iterator_base
|
||||
#endif // #if BOOST_CB_ENABLE_DEBUG
|
||||
{
|
||||
// Helper types
|
||||
|
||||
//! Base iterator.
|
||||
typedef std::iterator<
|
||||
std::random_access_iterator_tag,
|
||||
typename Traits::value_type,
|
||||
typename Traits::difference_type,
|
||||
typename Traits::pointer,
|
||||
typename Traits::reference> base_iterator;
|
||||
|
||||
//! Non-const iterator.
|
||||
typedef iterator<Buff, typename Traits::nonconst_self> nonconst_self;
|
||||
|
||||
// Basic types
|
||||
|
||||
//! The type of the elements stored in the circular buffer.
|
||||
typedef typename base_iterator::value_type value_type;
|
||||
|
||||
//! Pointer to the element.
|
||||
typedef typename base_iterator::pointer pointer;
|
||||
|
||||
//! Reference to the element.
|
||||
typedef typename base_iterator::reference reference;
|
||||
|
||||
//! Size type.
|
||||
typedef typename Traits::size_type size_type;
|
||||
|
||||
//! Difference type.
|
||||
typedef typename base_iterator::difference_type difference_type;
|
||||
|
||||
// Member variables
|
||||
|
||||
//! The circular buffer where the iterator points to.
|
||||
const Buff* m_buff;
|
||||
|
||||
//! An internal iterator.
|
||||
pointer m_it;
|
||||
|
||||
// Construction & assignment
|
||||
|
||||
// Default copy constructor.
|
||||
|
||||
//! Default constructor.
|
||||
iterator() : m_buff(0), m_it(0) {}
|
||||
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
|
||||
//! Copy constructor (used for converting from a non-const to a const iterator).
|
||||
iterator(const nonconst_self& it) : debug_iterator_base(it), m_buff(it.m_buff), m_it(it.m_it) {}
|
||||
|
||||
//! Internal constructor.
|
||||
/*!
|
||||
\note This constructor is not intended to be used directly by the user.
|
||||
*/
|
||||
iterator(const Buff* cb, const pointer p) : debug_iterator_base(cb), m_buff(cb), m_it(p) {}
|
||||
|
||||
#else
|
||||
|
||||
iterator(const nonconst_self& it) : m_buff(it.m_buff), m_it(it.m_it) {}
|
||||
|
||||
iterator(const Buff* cb, const pointer p) : m_buff(cb), m_it(p) {}
|
||||
|
||||
#endif // #if BOOST_CB_ENABLE_DEBUG
|
||||
|
||||
//! Assign operator.
|
||||
iterator& operator = (const iterator& it) {
|
||||
if (this == &it)
|
||||
return *this;
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
debug_iterator_base::operator =(it);
|
||||
#endif // #if BOOST_CB_ENABLE_DEBUG
|
||||
m_buff = it.m_buff;
|
||||
m_it = it.m_it;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Random access iterator methods
|
||||
|
||||
//! Dereferencing operator.
|
||||
reference operator * () const {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end()
|
||||
return *m_it;
|
||||
}
|
||||
|
||||
//! Dereferencing operator.
|
||||
pointer operator -> () const { return &(operator*()); }
|
||||
|
||||
//! Difference operator.
|
||||
template <class Traits0>
|
||||
difference_type operator - (const iterator<Buff, Traits0>& it) const {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
return linearize_pointer(*this) - linearize_pointer(it);
|
||||
}
|
||||
|
||||
//! Increment operator (prefix).
|
||||
iterator& operator ++ () {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end()
|
||||
m_buff->increment(m_it);
|
||||
if (m_it == m_buff->m_last)
|
||||
m_it = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Increment operator (postfix).
|
||||
iterator operator ++ (int) {
|
||||
iterator<Buff, Traits> tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//! Decrement operator (prefix).
|
||||
iterator& operator -- () {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(m_it != m_buff->m_first); // check for iterator pointing to begin()
|
||||
if (m_it == 0)
|
||||
m_it = m_buff->m_last;
|
||||
m_buff->decrement(m_it);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Decrement operator (postfix).
|
||||
iterator operator -- (int) {
|
||||
iterator<Buff, Traits> tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//! Iterator addition.
|
||||
iterator& operator += (difference_type n) {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
if (n > 0) {
|
||||
BOOST_CB_ASSERT(m_buff->end() - *this >= n); // check for too large n
|
||||
m_it = m_buff->add(m_it, n);
|
||||
if (m_it == m_buff->m_last)
|
||||
m_it = 0;
|
||||
} else if (n < 0) {
|
||||
*this -= -n;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Iterator addition.
|
||||
iterator operator + (difference_type n) const { return iterator<Buff, Traits>(*this) += n; }
|
||||
|
||||
//! Iterator subtraction.
|
||||
iterator& operator -= (difference_type n) {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
if (n > 0) {
|
||||
BOOST_CB_ASSERT(*this - m_buff->begin() >= n); // check for too large n
|
||||
m_it = m_buff->sub(m_it == 0 ? m_buff->m_last : m_it, n);
|
||||
} else if (n < 0) {
|
||||
*this += -n;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Iterator subtraction.
|
||||
iterator operator - (difference_type n) const { return iterator<Buff, Traits>(*this) -= n; }
|
||||
|
||||
//! Element access operator.
|
||||
reference operator [] (difference_type n) const { return *(*this + n); }
|
||||
|
||||
// Equality & comparison
|
||||
|
||||
//! Equality.
|
||||
template <class Traits0>
|
||||
bool operator == (const iterator<Buff, Traits0>& it) const {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
return m_it == it.m_it;
|
||||
}
|
||||
|
||||
//! Inequality.
|
||||
template <class Traits0>
|
||||
bool operator != (const iterator<Buff, Traits0>& it) const {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
return m_it != it.m_it;
|
||||
}
|
||||
|
||||
//! Less.
|
||||
template <class Traits0>
|
||||
bool operator < (const iterator<Buff, Traits0>& it) const {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
return linearize_pointer(*this) < linearize_pointer(it);
|
||||
}
|
||||
|
||||
//! Greater.
|
||||
template <class Traits0>
|
||||
bool operator > (const iterator<Buff, Traits0>& it) const { return it < *this; }
|
||||
|
||||
//! Less or equal.
|
||||
template <class Traits0>
|
||||
bool operator <= (const iterator<Buff, Traits0>& it) const { return !(it < *this); }
|
||||
|
||||
//! Greater or equal.
|
||||
template <class Traits0>
|
||||
bool operator >= (const iterator<Buff, Traits0>& it) const { return !(*this < it); }
|
||||
|
||||
// Helpers
|
||||
|
||||
//! Get a pointer which would point to the same element as the iterator in case the circular buffer is linearized.
|
||||
template <class Traits0>
|
||||
typename Traits0::pointer linearize_pointer(const iterator<Buff, Traits0>& it) const {
|
||||
return it.m_it == 0 ? m_buff->m_buff + m_buff->size() :
|
||||
(it.m_it < m_buff->m_first ? it.m_it + (m_buff->m_end - m_buff->m_first)
|
||||
: m_buff->m_buff + (it.m_it - m_buff->m_first));
|
||||
}
|
||||
};
|
||||
|
||||
//! Iterator addition.
|
||||
template <class Buff, class Traits>
|
||||
inline iterator<Buff, Traits>
|
||||
operator + (typename Traits::difference_type n, const iterator<Buff, Traits>& it) {
|
||||
return it + n;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest)
|
||||
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type.
|
||||
*/
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) {
|
||||
ForwardIterator next = dest;
|
||||
BOOST_TRY {
|
||||
for (; first != last; ++first, ++dest)
|
||||
boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), *first);
|
||||
} BOOST_CATCH(...) {
|
||||
for (; next != dest; ++next)
|
||||
boost::container::allocator_traits<Alloc>::destroy(a, boost::addressof(*next));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return dest;
|
||||
}
|
||||
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
|
||||
true_type) {
|
||||
for (; first != last; ++first, ++dest)
|
||||
boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), boost::move(*first));
|
||||
return dest;
|
||||
}
|
||||
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
|
||||
false_type) {
|
||||
return uninitialized_copy(first, last, dest, a);
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest)
|
||||
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type and moves elements if they have noexcept move constructors.
|
||||
*/
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) {
|
||||
typedef typename boost::is_nothrow_move_constructible<typename boost::container::allocator_traits<Alloc>::value_type>::type tag_t;
|
||||
return uninitialized_move_if_noexcept_impl(first, last, dest, a, tag_t());
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc)
|
||||
\brief Equivalent of <code>std::uninitialized_fill_n</code> with allocator.
|
||||
*/
|
||||
template<class ForwardIterator, class Diff, class T, class Alloc>
|
||||
inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc) {
|
||||
ForwardIterator next = first;
|
||||
BOOST_TRY {
|
||||
for (; n > 0; ++first, --n)
|
||||
boost::container::allocator_traits<Alloc>::construct(alloc, boost::addressof(*first), item);
|
||||
} BOOST_CATCH(...) {
|
||||
for (; next != first; ++next)
|
||||
boost::container::allocator_traits<Alloc>::destroy(alloc, boost::addressof(*next));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
} // namespace cb_details
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)
|
||||
@@ -0,0 +1,43 @@
|
||||
// Forward declaration of the circular buffer and its adaptor.
|
||||
|
||||
// Copyright (c) 2003-2008 Jan Gaspar
|
||||
|
||||
// Use, modification, and distribution is subject to 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)
|
||||
|
||||
// See www.boost.org/libs/circular_buffer for documentation.
|
||||
|
||||
#if !defined(BOOST_CIRCULAR_BUFFER_FWD_HPP)
|
||||
#define BOOST_CIRCULAR_BUFFER_FWD_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if !defined(BOOST_NO_STD_ALLOCATOR)
|
||||
#include <memory>
|
||||
#else
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
#if !defined(BOOST_NO_STD_ALLOCATOR)
|
||||
#define BOOST_CB_DEFAULT_ALLOCATOR(T) std::allocator<T>
|
||||
#else
|
||||
#define BOOST_CB_DEFAULT_ALLOCATOR(T) BOOST_DEDUCED_TYPENAME std::vector<T>::allocator_type
|
||||
#endif
|
||||
|
||||
template <class T, class Alloc = BOOST_CB_DEFAULT_ALLOCATOR(T)>
|
||||
class circular_buffer;
|
||||
|
||||
template <class T, class Alloc = BOOST_CB_DEFAULT_ALLOCATOR(T)>
|
||||
class circular_buffer_space_optimized;
|
||||
|
||||
#undef BOOST_CB_DEFAULT_ALLOCATOR
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_FWD_HPP)
|
||||
@@ -0,0 +1,36 @@
|
||||
// boost/detail/lightweight_main.hpp -------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2010
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// //
|
||||
// exception reporting main() that calls cpp_main() //
|
||||
// //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
int cpp_main(int argc, char* argv[]);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
return cpp_main(argc, argv);
|
||||
}
|
||||
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
std::cout
|
||||
<< "\nERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR\n"
|
||||
<< "\n****************************** std::exception *****************************\n"
|
||||
<< ex.what()
|
||||
<< "\n***************************************************************************\n"
|
||||
<< std::endl;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
// boost progress.hpp header file ------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 1994-99. 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)
|
||||
|
||||
// See http://www.boost.org/libs/timer for documentation.
|
||||
|
||||
// Revision History
|
||||
// 1 Dec 01 Add leading progress display strings (suggested by Toon Knapen)
|
||||
// 20 May 01 Introduce several static_casts<> to eliminate warning messages
|
||||
// (Fixed by Beman, reported by Herve Bronnimann)
|
||||
// 12 Jan 01 Change to inline implementation to allow use without library
|
||||
// builds. See docs for more rationale. (Beman Dawes)
|
||||
// 22 Jul 99 Name changed to .hpp
|
||||
// 16 Jul 99 Second beta
|
||||
// 6 Jul 99 Initial boost version
|
||||
|
||||
#ifndef BOOST_PROGRESS_HPP
|
||||
#define BOOST_PROGRESS_HPP
|
||||
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/cstdint.hpp> // for uintmax_t
|
||||
#include <iostream> // for ostream, cout, etc
|
||||
#include <string> // for string
|
||||
|
||||
namespace boost {
|
||||
|
||||
// progress_timer ----------------------------------------------------------//
|
||||
|
||||
// A progress_timer behaves like a timer except that the destructor displays
|
||||
// an elapsed time message at an appropriate place in an appropriate form.
|
||||
|
||||
class progress_timer : public timer, private noncopyable
|
||||
{
|
||||
|
||||
public:
|
||||
explicit progress_timer( std::ostream & os = std::cout )
|
||||
// os is hint; implementation may ignore, particularly in embedded systems
|
||||
: timer(), noncopyable(), m_os(os) {}
|
||||
~progress_timer()
|
||||
{
|
||||
// A) Throwing an exception from a destructor is a Bad Thing.
|
||||
// B) The progress_timer destructor does output which may throw.
|
||||
// C) A progress_timer is usually not critical to the application.
|
||||
// Therefore, wrap the I/O in a try block, catch and ignore all exceptions.
|
||||
try
|
||||
{
|
||||
// use istream instead of ios_base to workaround GNU problem (Greg Chicares)
|
||||
std::istream::fmtflags old_flags = m_os.setf( std::istream::fixed,
|
||||
std::istream::floatfield );
|
||||
std::streamsize old_prec = m_os.precision( 2 );
|
||||
m_os << elapsed() << " s\n" // "s" is System International d'Unites std
|
||||
<< std::endl;
|
||||
m_os.flags( old_flags );
|
||||
m_os.precision( old_prec );
|
||||
}
|
||||
|
||||
catch (...) {} // eat any exceptions
|
||||
} // ~progress_timer
|
||||
|
||||
private:
|
||||
std::ostream & m_os;
|
||||
};
|
||||
|
||||
|
||||
// progress_display --------------------------------------------------------//
|
||||
|
||||
// progress_display displays an appropriate indication of
|
||||
// progress at an appropriate place in an appropriate form.
|
||||
|
||||
// NOTE: (Jan 12, 2001) Tried to change unsigned long to boost::uintmax_t, but
|
||||
// found some compilers couldn't handle the required conversion to double.
|
||||
// Reverted to unsigned long until the compilers catch up.
|
||||
|
||||
class progress_display : private noncopyable
|
||||
{
|
||||
public:
|
||||
explicit progress_display( unsigned long expected_count_,
|
||||
std::ostream & os = std::cout,
|
||||
const std::string & s1 = "\n", //leading strings
|
||||
const std::string & s2 = "",
|
||||
const std::string & s3 = "" )
|
||||
// os is hint; implementation may ignore, particularly in embedded systems
|
||||
: noncopyable(), m_os(os), m_s1(s1), m_s2(s2), m_s3(s3) { restart(expected_count_); }
|
||||
|
||||
void restart( unsigned long expected_count_ )
|
||||
// Effects: display appropriate scale
|
||||
// Postconditions: count()==0, expected_count()==expected_count_
|
||||
{
|
||||
_count = _next_tic_count = _tic = 0;
|
||||
_expected_count = expected_count_;
|
||||
|
||||
m_os << m_s1 << "0% 10 20 30 40 50 60 70 80 90 100%\n"
|
||||
<< m_s2 << "|----|----|----|----|----|----|----|----|----|----|"
|
||||
<< std::endl // endl implies flush, which ensures display
|
||||
<< m_s3;
|
||||
if ( !_expected_count ) _expected_count = 1; // prevent divide by zero
|
||||
} // restart
|
||||
|
||||
unsigned long operator+=( unsigned long increment )
|
||||
// Effects: Display appropriate progress tic if needed.
|
||||
// Postconditions: count()== original count() + increment
|
||||
// Returns: count().
|
||||
{
|
||||
if ( (_count += increment) >= _next_tic_count ) { display_tic(); }
|
||||
return _count;
|
||||
}
|
||||
|
||||
unsigned long operator++() { return operator+=( 1 ); }
|
||||
unsigned long count() const { return _count; }
|
||||
unsigned long expected_count() const { return _expected_count; }
|
||||
|
||||
private:
|
||||
std::ostream & m_os; // may not be present in all imps
|
||||
const std::string m_s1; // string is more general, safer than
|
||||
const std::string m_s2; // const char *, and efficiency or size are
|
||||
const std::string m_s3; // not issues
|
||||
|
||||
unsigned long _count, _expected_count, _next_tic_count;
|
||||
unsigned int _tic;
|
||||
void display_tic()
|
||||
{
|
||||
// use of floating point ensures that both large and small counts
|
||||
// work correctly. static_cast<>() is also used several places
|
||||
// to suppress spurious compiler warnings.
|
||||
unsigned int tics_needed = static_cast<unsigned int>((static_cast<double>(_count)
|
||||
/ static_cast<double>(_expected_count)) * 50.0);
|
||||
do { m_os << '*' << std::flush; } while ( ++_tic < tics_needed );
|
||||
_next_tic_count =
|
||||
static_cast<unsigned long>((_tic/50.0) * static_cast<double>(_expected_count));
|
||||
if ( _count == _expected_count ) {
|
||||
if ( _tic < 51 ) m_os << '*';
|
||||
m_os << std::endl;
|
||||
}
|
||||
} // display_tic
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_PROGRESS_HPP
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef BOOST_THREAD_CONDITION_HPP
|
||||
#define BOOST_THREAD_CONDITION_HPP
|
||||
// (C) Copyright 2007 Anthony Williams
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_CONDITION
|
||||
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
typedef condition_variable_any condition;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,155 @@
|
||||
#ifndef BOOST_THREAD_DETAIL_THREAD_GROUP_HPP
|
||||
#define BOOST_THREAD_DETAIL_THREAD_GROUP_HPP
|
||||
// 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)
|
||||
// (C) Copyright 2007-9 Anthony Williams
|
||||
|
||||
#include <list>
|
||||
#include <boost/thread/csbl/memory/unique_ptr.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/lock_guard.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4251)
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class thread_group
|
||||
{
|
||||
private:
|
||||
thread_group(thread_group const&);
|
||||
thread_group& operator=(thread_group const&);
|
||||
public:
|
||||
thread_group() {}
|
||||
~thread_group()
|
||||
{
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_this_thread_in()
|
||||
{
|
||||
thread::id id = this_thread::get_id();
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
if ((*it)->get_id() == id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_thread_in(thread* thrd)
|
||||
{
|
||||
if(thrd)
|
||||
{
|
||||
thread::id id = thrd->get_id();
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
if ((*it)->get_id() == id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
thread* create_thread(F threadfunc)
|
||||
{
|
||||
boost::lock_guard<shared_mutex> guard(m);
|
||||
boost::csbl::unique_ptr<thread> new_thread(new thread(threadfunc));
|
||||
threads.push_back(new_thread.get());
|
||||
return new_thread.release();
|
||||
}
|
||||
|
||||
void add_thread(thread* thrd)
|
||||
{
|
||||
if(thrd)
|
||||
{
|
||||
BOOST_THREAD_ASSERT_PRECONDITION( ! is_thread_in(thrd) ,
|
||||
thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost::thread_group: trying to add a duplicated thread")
|
||||
);
|
||||
|
||||
boost::lock_guard<shared_mutex> guard(m);
|
||||
threads.push_back(thrd);
|
||||
}
|
||||
}
|
||||
|
||||
void remove_thread(thread* thrd)
|
||||
{
|
||||
boost::lock_guard<shared_mutex> guard(m);
|
||||
std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd);
|
||||
if(it!=threads.end())
|
||||
{
|
||||
threads.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void join_all()
|
||||
{
|
||||
BOOST_THREAD_ASSERT_PRECONDITION( ! is_this_thread_in() ,
|
||||
thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost::thread_group: trying joining itself")
|
||||
);
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
if ((*it)->joinable())
|
||||
(*it)->join();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
void interrupt_all()
|
||||
{
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
(*it)->interrupt();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
return threads.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<thread*> threads;
|
||||
mutable shared_mutex m;
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,716 @@
|
||||
#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
|
||||
#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
|
||||
|
||||
// (C) Copyright 2006-8 Anthony Williams
|
||||
// (C) Copyright 2012 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
#include <boost/thread/detail/thread_interruption.hpp>
|
||||
#endif
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#include <boost/chrono/ceil.hpp>
|
||||
#endif
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class shared_mutex
|
||||
{
|
||||
private:
|
||||
class state_data
|
||||
{
|
||||
public:
|
||||
state_data () :
|
||||
shared_count(0),
|
||||
exclusive(false),
|
||||
upgrade(false),
|
||||
exclusive_waiting_blocked(false)
|
||||
{}
|
||||
|
||||
void assert_free() const
|
||||
{
|
||||
BOOST_ASSERT( ! exclusive );
|
||||
BOOST_ASSERT( ! upgrade );
|
||||
BOOST_ASSERT( shared_count==0 );
|
||||
}
|
||||
|
||||
void assert_locked() const
|
||||
{
|
||||
BOOST_ASSERT( exclusive );
|
||||
BOOST_ASSERT( shared_count==0 );
|
||||
BOOST_ASSERT( ! upgrade );
|
||||
}
|
||||
|
||||
void assert_lock_shared () const
|
||||
{
|
||||
BOOST_ASSERT( ! exclusive );
|
||||
BOOST_ASSERT( shared_count>0 );
|
||||
//BOOST_ASSERT( (! upgrade) || (shared_count>1));
|
||||
// if upgraded there are at least 2 threads sharing the mutex,
|
||||
// except when unlock_upgrade_and_lock has decreased the number of readers but has not taken yet exclusive ownership.
|
||||
}
|
||||
|
||||
void assert_lock_upgraded () const
|
||||
{
|
||||
BOOST_ASSERT( ! exclusive );
|
||||
BOOST_ASSERT( upgrade );
|
||||
BOOST_ASSERT( shared_count>0 );
|
||||
}
|
||||
|
||||
void assert_lock_not_upgraded () const
|
||||
{
|
||||
BOOST_ASSERT( ! upgrade );
|
||||
}
|
||||
|
||||
bool can_lock () const
|
||||
{
|
||||
return ! (shared_count || exclusive);
|
||||
}
|
||||
|
||||
void exclusive_blocked (bool blocked)
|
||||
{
|
||||
exclusive_waiting_blocked = blocked;
|
||||
}
|
||||
|
||||
void lock ()
|
||||
{
|
||||
exclusive = true;
|
||||
}
|
||||
|
||||
void unlock ()
|
||||
{
|
||||
exclusive = false;
|
||||
exclusive_waiting_blocked = false;
|
||||
}
|
||||
|
||||
bool can_lock_shared () const
|
||||
{
|
||||
return ! (exclusive || exclusive_waiting_blocked);
|
||||
}
|
||||
|
||||
bool more_shared () const
|
||||
{
|
||||
return shared_count > 0 ;
|
||||
}
|
||||
unsigned get_shared_count () const
|
||||
{
|
||||
return shared_count ;
|
||||
}
|
||||
unsigned lock_shared ()
|
||||
{
|
||||
return ++shared_count;
|
||||
}
|
||||
|
||||
|
||||
void unlock_shared ()
|
||||
{
|
||||
--shared_count;
|
||||
}
|
||||
|
||||
bool unlock_shared_downgrades()
|
||||
{
|
||||
if (upgrade) {
|
||||
upgrade=false;
|
||||
exclusive=true;
|
||||
return true;
|
||||
} else {
|
||||
exclusive_waiting_blocked=false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void lock_upgrade ()
|
||||
{
|
||||
++shared_count;
|
||||
upgrade=true;
|
||||
}
|
||||
bool can_lock_upgrade () const
|
||||
{
|
||||
return ! (exclusive || exclusive_waiting_blocked || upgrade);
|
||||
}
|
||||
|
||||
void unlock_upgrade ()
|
||||
{
|
||||
upgrade=false;
|
||||
--shared_count;
|
||||
}
|
||||
|
||||
//private:
|
||||
unsigned shared_count;
|
||||
bool exclusive;
|
||||
bool upgrade;
|
||||
bool exclusive_waiting_blocked;
|
||||
};
|
||||
|
||||
|
||||
|
||||
state_data state;
|
||||
boost::mutex state_change;
|
||||
boost::condition_variable shared_cond;
|
||||
boost::condition_variable exclusive_cond;
|
||||
boost::condition_variable upgrade_cond;
|
||||
|
||||
void release_waiters()
|
||||
{
|
||||
exclusive_cond.notify_one();
|
||||
shared_cond.notify_all();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
BOOST_THREAD_NO_COPYABLE(shared_mutex)
|
||||
|
||||
shared_mutex()
|
||||
{
|
||||
}
|
||||
|
||||
~shared_mutex()
|
||||
{
|
||||
}
|
||||
|
||||
void lock_shared()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
while(!state.can_lock_shared())
|
||||
{
|
||||
shared_cond.wait(lk);
|
||||
}
|
||||
state.lock_shared();
|
||||
}
|
||||
|
||||
bool try_lock_shared()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
if(!state.can_lock_shared())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
state.lock_shared();
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
bool timed_lock_shared(system_time const& timeout)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
while(!state.can_lock_shared())
|
||||
{
|
||||
if(!shared_cond.timed_wait(lk,timeout))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
state.lock_shared();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock_shared(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock_shared(get_system_time()+relative_time);
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
while(!state.can_lock_shared())
|
||||
//while(state.exclusive || state.exclusive_waiting_blocked)
|
||||
{
|
||||
if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
state.lock_shared();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
void unlock_shared()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_shared();
|
||||
state.unlock_shared();
|
||||
if (! state.more_shared())
|
||||
{
|
||||
if (state.upgrade)
|
||||
{
|
||||
// As there is a thread doing a unlock_upgrade_and_lock that is waiting for ! state.more_shared()
|
||||
// avoid other threads to lock, lock_upgrade or lock_shared, so only this thread is notified.
|
||||
state.upgrade=false;
|
||||
state.exclusive=true;
|
||||
//lk.unlock();
|
||||
upgrade_cond.notify_one();
|
||||
}
|
||||
else
|
||||
{
|
||||
state.exclusive_waiting_blocked=false;
|
||||
//lk.unlock();
|
||||
}
|
||||
release_waiters();
|
||||
}
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
while (state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=true;
|
||||
exclusive_cond.wait(lk);
|
||||
}
|
||||
state.exclusive=true;
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
bool timed_lock(system_time const& timeout)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
while(state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=true;
|
||||
if(!exclusive_cond.timed_wait(lk,timeout))
|
||||
{
|
||||
if(state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
state.exclusive=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock(get_system_time()+relative_time);
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
while(state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=true;
|
||||
if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
|
||||
{
|
||||
if(state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
state.exclusive=true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
if(state.shared_count || state.exclusive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.exclusive=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_locked();
|
||||
state.exclusive=false;
|
||||
state.exclusive_waiting_blocked=false;
|
||||
state.assert_free();
|
||||
release_waiters();
|
||||
}
|
||||
|
||||
void lock_upgrade()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
shared_cond.wait(lk);
|
||||
}
|
||||
state.lock_shared();
|
||||
state.upgrade=true;
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
bool timed_lock_upgrade(system_time const& timeout)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
if(!shared_cond.timed_wait(lk,timeout))
|
||||
{
|
||||
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
state.lock_shared();
|
||||
state.upgrade=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock_upgrade(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock_upgrade(get_system_time()+relative_time);
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
|
||||
{
|
||||
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
state.lock_shared();
|
||||
state.upgrade=true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
bool try_lock_upgrade()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.lock_shared();
|
||||
state.upgrade=true;
|
||||
state.assert_lock_upgraded();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void unlock_upgrade()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
//state.upgrade=false;
|
||||
state.unlock_upgrade();
|
||||
if(! state.more_shared() )
|
||||
{
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
} else {
|
||||
shared_cond.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
// Upgrade <-> Exclusive
|
||||
void unlock_upgrade_and_lock()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_upgraded();
|
||||
state.unlock_shared();
|
||||
while (state.more_shared())
|
||||
{
|
||||
upgrade_cond.wait(lk);
|
||||
}
|
||||
state.upgrade=false;
|
||||
state.exclusive=true;
|
||||
state.assert_locked();
|
||||
}
|
||||
|
||||
void unlock_and_lock_upgrade()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_locked();
|
||||
state.exclusive=false;
|
||||
state.upgrade=true;
|
||||
state.lock_shared();
|
||||
state.exclusive_waiting_blocked=false;
|
||||
state.assert_lock_upgraded();
|
||||
release_waiters();
|
||||
}
|
||||
|
||||
bool try_unlock_upgrade_and_lock()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_upgraded();
|
||||
if( !state.exclusive
|
||||
&& !state.exclusive_waiting_blocked
|
||||
&& state.upgrade
|
||||
&& state.shared_count==1)
|
||||
{
|
||||
state.shared_count=0;
|
||||
state.exclusive=true;
|
||||
state.upgrade=false;
|
||||
state.assert_locked();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_unlock_upgrade_and_lock_for(
|
||||
const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_unlock_upgrade_and_lock_until(
|
||||
chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_unlock_upgrade_and_lock_until(
|
||||
const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_upgraded();
|
||||
if (state.shared_count != 1)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
cv_status status = shared_cond.wait_until(lk,abs_time);
|
||||
if (state.shared_count == 1)
|
||||
break;
|
||||
if(status == cv_status::timeout)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
state.upgrade=false;
|
||||
state.exclusive=true;
|
||||
state.exclusive_waiting_blocked=false;
|
||||
state.shared_count=0;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Shared <-> Exclusive
|
||||
void unlock_and_lock_shared()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_locked();
|
||||
state.exclusive=false;
|
||||
state.lock_shared();
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
bool try_unlock_shared_and_lock()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_shared();
|
||||
if( !state.exclusive
|
||||
&& !state.exclusive_waiting_blocked
|
||||
&& !state.upgrade
|
||||
&& state.shared_count==1)
|
||||
{
|
||||
state.shared_count=0;
|
||||
state.exclusive=true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_unlock_shared_and_lock_for(
|
||||
const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_unlock_shared_and_lock_until(
|
||||
chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_unlock_shared_and_lock_until(
|
||||
const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_shared();
|
||||
if (state.shared_count != 1)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
cv_status status = shared_cond.wait_until(lk,abs_time);
|
||||
if (state.shared_count == 1)
|
||||
break;
|
||||
if(status == cv_status::timeout)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
state.upgrade=false;
|
||||
state.exclusive=true;
|
||||
state.exclusive_waiting_blocked=false;
|
||||
state.shared_count=0;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Shared <-> Upgrade
|
||||
void unlock_upgrade_and_lock_shared()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_upgraded();
|
||||
state.upgrade=false;
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
bool try_unlock_shared_and_lock_upgrade()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_shared();
|
||||
if( !state.exclusive
|
||||
&& !state.exclusive_waiting_blocked
|
||||
&& !state.upgrade
|
||||
)
|
||||
{
|
||||
state.upgrade=true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_unlock_shared_and_lock_upgrade_for(
|
||||
const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_unlock_shared_and_lock_upgrade_until(
|
||||
chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_unlock_shared_and_lock_upgrade_until(
|
||||
const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_shared();
|
||||
if( state.exclusive
|
||||
|| state.exclusive_waiting_blocked
|
||||
|| state.upgrade
|
||||
)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
cv_status status = exclusive_cond.wait_until(lk,abs_time);
|
||||
if( ! state.exclusive
|
||||
&& ! state.exclusive_waiting_blocked
|
||||
&& ! state.upgrade
|
||||
)
|
||||
break;
|
||||
if(status == cv_status::timeout)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
state.upgrade=true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef shared_mutex upgrade_mutex;
|
||||
}
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef BOOST_THREAD_SHARED_MUTEX_HPP
|
||||
#define BOOST_THREAD_SHARED_MUTEX_HPP
|
||||
|
||||
// shared_mutex.hpp
|
||||
//
|
||||
// (C) Copyright 2007 Anthony Williams
|
||||
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#if defined(BOOST_THREAD_PLATFORM_WIN32)
|
||||
#if defined(BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN)
|
||||
#include <boost/thread/pthread/shared_mutex.hpp>
|
||||
#else
|
||||
#include <boost/thread/win32/shared_mutex.hpp>
|
||||
#endif
|
||||
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
|
||||
//#include <boost/thread/v2/shared_mutex.hpp>
|
||||
#include <boost/thread/pthread/shared_mutex.hpp>
|
||||
#else
|
||||
#error "Boost threads unavailable on this platform"
|
||||
#endif
|
||||
|
||||
#include <boost/thread/lockable_traits.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
typedef shared_mutex shared_timed_mutex;
|
||||
namespace sync
|
||||
{
|
||||
#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
|
||||
template<>
|
||||
struct is_basic_lockable<shared_mutex>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
template<>
|
||||
struct is_lockable<shared_mutex>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef BOOST_THREAD_THREAD_HPP
|
||||
#define BOOST_THREAD_THREAD_HPP
|
||||
|
||||
// thread.hpp
|
||||
//
|
||||
// (C) Copyright 2007-8 Anthony Williams
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/thread/detail/thread_group.hpp>
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,903 @@
|
||||
#ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
|
||||
#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
|
||||
|
||||
// (C) Copyright 2006-8 Anthony Williams
|
||||
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
#include <boost/thread/win32/thread_primitives.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <limits.h>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#include <boost/chrono/ceil.hpp>
|
||||
#endif
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class shared_mutex
|
||||
{
|
||||
private:
|
||||
struct state_data
|
||||
{
|
||||
unsigned shared_count:11,
|
||||
shared_waiting:11,
|
||||
exclusive:1,
|
||||
upgrade:1,
|
||||
exclusive_waiting:7,
|
||||
exclusive_waiting_blocked:1;
|
||||
|
||||
friend bool operator==(state_data const& lhs,state_data const& rhs)
|
||||
{
|
||||
return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
T interlocked_compare_exchange(T* target,T new_value,T comparand)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long));
|
||||
long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target),
|
||||
*reinterpret_cast<long*>(&new_value),
|
||||
*reinterpret_cast<long*>(&comparand));
|
||||
return *reinterpret_cast<T const*>(&res);
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
unlock_sem = 0,
|
||||
exclusive_sem = 1
|
||||
};
|
||||
|
||||
state_data state;
|
||||
detail::win32::handle semaphores[2];
|
||||
detail::win32::handle upgrade_sem;
|
||||
|
||||
void release_waiters(state_data old_state)
|
||||
{
|
||||
if(old_state.exclusive_waiting)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
|
||||
}
|
||||
|
||||
if(old_state.shared_waiting || old_state.exclusive_waiting)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
|
||||
}
|
||||
}
|
||||
void release_shared_waiters(state_data old_state)
|
||||
{
|
||||
if(old_state.shared_waiting || old_state.exclusive_waiting)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
BOOST_THREAD_NO_COPYABLE(shared_mutex)
|
||||
shared_mutex()
|
||||
{
|
||||
semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
|
||||
semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX);
|
||||
if (!semaphores[exclusive_sem])
|
||||
{
|
||||
detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX);
|
||||
boost::throw_exception(thread_resource_error());
|
||||
}
|
||||
upgrade_sem=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX);
|
||||
if (!upgrade_sem)
|
||||
{
|
||||
detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX);
|
||||
detail::win32::release_semaphore(semaphores[exclusive_sem],LONG_MAX);
|
||||
boost::throw_exception(thread_resource_error());
|
||||
}
|
||||
state_data state_={0,0,0,0,0,0};
|
||||
state=state_;
|
||||
}
|
||||
|
||||
~shared_mutex()
|
||||
{
|
||||
detail::win32::CloseHandle(upgrade_sem);
|
||||
detail::win32::CloseHandle(semaphores[unlock_sem]);
|
||||
detail::win32::CloseHandle(semaphores[exclusive_sem]);
|
||||
}
|
||||
|
||||
bool try_lock_shared()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
return !(old_state.exclusive| old_state.exclusive_waiting_blocked);
|
||||
}
|
||||
|
||||
void lock_shared()
|
||||
{
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
|
||||
#else
|
||||
BOOST_VERIFY(try_lock_shared_until(chrono::steady_clock::now()));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock_shared(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock_shared(get_system_time()+relative_time);
|
||||
}
|
||||
bool timed_lock_shared(boost::system_time const& wait_until)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
|
||||
{
|
||||
++new_state.shared_waiting;
|
||||
if(!new_state.shared_waiting)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long const res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until), 0);
|
||||
if(res==detail::win32::timeout)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
|
||||
{
|
||||
if(new_state.shared_waiting)
|
||||
{
|
||||
--new_state.shared_waiting;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(res==0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& t)
|
||||
{
|
||||
using namespace chrono;
|
||||
system_clock::time_point s_now = system_clock::now();
|
||||
typename Clock::time_point c_now = Clock::now();
|
||||
return try_lock_shared_until(s_now + ceil<system_clock::duration>(t - c_now));
|
||||
}
|
||||
template <class Duration>
|
||||
bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, Duration>& t)
|
||||
{
|
||||
using namespace chrono;
|
||||
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
|
||||
return try_lock_shared_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
|
||||
}
|
||||
bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
|
||||
{
|
||||
++new_state.shared_waiting;
|
||||
if(!new_state.shared_waiting)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
chrono::system_clock::time_point n = chrono::system_clock::now();
|
||||
unsigned long res;
|
||||
if (tp>n) {
|
||||
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n);
|
||||
res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],
|
||||
static_cast<unsigned long>(rel_time.count()), 0);
|
||||
} else {
|
||||
res=detail::win32::timeout;
|
||||
}
|
||||
if(res==detail::win32::timeout)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
|
||||
{
|
||||
if(new_state.shared_waiting)
|
||||
{
|
||||
--new_state.shared_waiting;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(res==0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void unlock_shared()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
bool const last_reader=!--new_state.shared_count;
|
||||
|
||||
if(last_reader)
|
||||
{
|
||||
if(new_state.upgrade)
|
||||
{
|
||||
new_state.upgrade=false;
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
new_state.shared_waiting=0;
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
if(last_reader)
|
||||
{
|
||||
if(old_state.upgrade)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0);
|
||||
}
|
||||
else
|
||||
{
|
||||
release_waiters(old_state);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
|
||||
#else
|
||||
BOOST_VERIFY(try_lock_until(chrono::steady_clock::now()));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock(get_system_time()+relative_time);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.shared_count || new_state.exclusive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
bool timed_lock(boost::system_time const& wait_until)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data old_state=state;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.shared_count || new_state.exclusive)
|
||||
{
|
||||
++new_state.exclusive_waiting;
|
||||
if(!new_state.exclusive_waiting)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
|
||||
new_state.exclusive_waiting_blocked=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!old_state.shared_count && !old_state.exclusive)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#ifndef UNDER_CE
|
||||
const bool wait_all = true;
|
||||
#else
|
||||
const bool wait_all = false;
|
||||
#endif
|
||||
unsigned long const wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until), 0);
|
||||
if(wait_res==detail::win32::timeout)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
bool must_notify = false;
|
||||
state_data new_state=old_state;
|
||||
if(new_state.shared_count || new_state.exclusive)
|
||||
{
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
if(!--new_state.exclusive_waiting)
|
||||
{
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
must_notify = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if (must_notify)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
|
||||
}
|
||||
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
if(!old_state.shared_count && !old_state.exclusive)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
BOOST_ASSERT(wait_res<2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
|
||||
{
|
||||
using namespace chrono;
|
||||
system_clock::time_point s_now = system_clock::now();
|
||||
typename Clock::time_point c_now = Clock::now();
|
||||
return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now));
|
||||
}
|
||||
template <class Duration>
|
||||
bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
|
||||
{
|
||||
using namespace chrono;
|
||||
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
|
||||
return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
|
||||
}
|
||||
bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data old_state=state;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.shared_count || new_state.exclusive)
|
||||
{
|
||||
++new_state.exclusive_waiting;
|
||||
if(!new_state.exclusive_waiting)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
|
||||
new_state.exclusive_waiting_blocked=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!old_state.shared_count && !old_state.exclusive)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#ifndef UNDER_CE
|
||||
const bool wait_all = true;
|
||||
#else
|
||||
const bool wait_all = false;
|
||||
#endif
|
||||
|
||||
chrono::system_clock::time_point n = chrono::system_clock::now();
|
||||
unsigned long wait_res;
|
||||
if (tp>n) {
|
||||
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
|
||||
wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,
|
||||
static_cast<unsigned long>(rel_time.count()), 0);
|
||||
} else {
|
||||
wait_res=detail::win32::timeout;
|
||||
}
|
||||
if(wait_res==detail::win32::timeout)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
bool must_notify = false;
|
||||
state_data new_state=old_state;
|
||||
if(new_state.shared_count || new_state.exclusive)
|
||||
{
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
if(!--new_state.exclusive_waiting)
|
||||
{
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
must_notify = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if (must_notify)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
|
||||
}
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
if(!old_state.shared_count && !old_state.exclusive)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
BOOST_ASSERT(wait_res<2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void unlock()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
new_state.exclusive=false;
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
new_state.shared_waiting=0;
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
release_waiters(old_state);
|
||||
}
|
||||
|
||||
void lock_upgrade()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
|
||||
{
|
||||
++new_state.shared_waiting;
|
||||
if(!new_state.shared_waiting)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
new_state.upgrade=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],detail::win32::infinite, 0));
|
||||
}
|
||||
}
|
||||
|
||||
bool try_lock_upgrade()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
new_state.upgrade=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void unlock_upgrade()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
new_state.upgrade=false;
|
||||
bool const last_reader=!--new_state.shared_count;
|
||||
|
||||
new_state.shared_waiting=0;
|
||||
if(last_reader)
|
||||
{
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
if(last_reader)
|
||||
{
|
||||
release_waiters(old_state);
|
||||
}
|
||||
else {
|
||||
release_shared_waiters(old_state);
|
||||
}
|
||||
// #7720
|
||||
//else {
|
||||
// release_waiters(old_state);
|
||||
//}
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
}
|
||||
|
||||
void unlock_upgrade_and_lock()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
bool const last_reader=!--new_state.shared_count;
|
||||
|
||||
if(last_reader)
|
||||
{
|
||||
new_state.upgrade=false;
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
if(!last_reader)
|
||||
{
|
||||
BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(upgrade_sem,detail::win32::infinite, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
}
|
||||
|
||||
void unlock_and_lock_upgrade()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
new_state.exclusive=false;
|
||||
new_state.upgrade=true;
|
||||
++new_state.shared_count;
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
new_state.shared_waiting=0;
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
release_waiters(old_state);
|
||||
}
|
||||
// bool try_unlock_upgrade_and_lock()
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//#ifdef BOOST_THREAD_USES_CHRONO
|
||||
// template <class Rep, class Period>
|
||||
// bool
|
||||
// try_unlock_upgrade_and_lock_for(
|
||||
// const chrono::duration<Rep, Period>& rel_time)
|
||||
// {
|
||||
// return try_unlock_upgrade_and_lock_until(
|
||||
// chrono::steady_clock::now() + rel_time);
|
||||
// }
|
||||
// template <class Clock, class Duration>
|
||||
// bool
|
||||
// try_unlock_upgrade_and_lock_until(
|
||||
// const chrono::time_point<Clock, Duration>& abs_time)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//#endif
|
||||
|
||||
void unlock_and_lock_shared()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
new_state.exclusive=false;
|
||||
++new_state.shared_count;
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
new_state.shared_waiting=0;
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
release_waiters(old_state);
|
||||
}
|
||||
void unlock_upgrade_and_lock_shared()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
new_state.upgrade=false;
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
new_state.shared_waiting=0;
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
release_waiters(old_state);
|
||||
}
|
||||
|
||||
};
|
||||
typedef shared_mutex upgrade_mutex;
|
||||
|
||||
}
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,173 @@
|
||||
// (C) Copyright John Maddock 2005-7.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
|
||||
# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#if (defined(__GNUC__) && !(defined(linux) || defined(__linux) || defined(__linux__))) \
|
||||
|| (!defined(__FreeBSD__) && defined(__GNUC__)) \
|
||||
|| (!defined(_AIX) && defined(__IBMCPP__) && (__IBMCPP__ >= 800))
|
||||
// Disable use of #include_next on Linux as typically we are installed in a
|
||||
// directory that is searched *after* the std lib include path.
|
||||
#if !defined(BOOST_HAS_INCLUDE_NEXT)
|
||||
# define BOOST_HAS_INCLUDE_NEXT
|
||||
#endif
|
||||
// Need to find out if we're using GLIBC:
|
||||
#ifdef BOOST_TR1_UTILITY_INCLUDED
|
||||
// Oops we're in a recursive include path!!
|
||||
// Need to include utility, or some std lib header,
|
||||
// but *not* via <utility> or <boost/config/no_tr1/utility.hpp>
|
||||
# ifndef BOOST_TR1_NO_RECURSION
|
||||
# define BOOST_TR1_NO_RECURSION
|
||||
# define BOOST_TR1_NO_CONFIG_RECURSION
|
||||
# endif
|
||||
# if defined(BOOST_HAS_INCLUDE_NEXT) && !defined(BOOST_TR1_DISABLE_INCLUDE_NEXT)
|
||||
# include_next <utility>
|
||||
# else
|
||||
# include BOOST_TR1_STD_HEADER(utility)
|
||||
# endif
|
||||
# ifdef BOOST_TR1_NO_CONFIG_RECURSION
|
||||
# undef BOOST_TR1_NO_CONFIG_RECURSION
|
||||
# undef BOOST_TR1_NO_RECURSION
|
||||
# endif
|
||||
#else
|
||||
#include <boost/config/no_tr1/utility.hpp>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__GLIBCXX__) && !defined(BOOST_TR1_PATH)
|
||||
# define BOOST_TR1_PATH(name) tr1/name
|
||||
#endif
|
||||
#if !defined(BOOST_TR1_PATH)
|
||||
# define BOOST_TR1_PATH(name) name
|
||||
#endif
|
||||
|
||||
#define BOOST_TR1_HEADER(name) <BOOST_TR1_PATH(name)>
|
||||
|
||||
// Can't use BOOST_WORKAROUND here, it leads to recursive includes:
|
||||
#if (defined(__BORLANDC__) && (__BORLANDC__ <= 0x600))
|
||||
# define BOOST_TR1_USE_OLD_TUPLE
|
||||
#endif
|
||||
|
||||
#ifdef __IBMCPP_TR1__
|
||||
// turn on support for everything:
|
||||
# define BOOST_HAS_TR1
|
||||
#endif
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
|
||||
# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_TR1
|
||||
// turn on support for everything:
|
||||
# define BOOST_HAS_TR1_ARRAY
|
||||
# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
|
||||
# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG
|
||||
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
|
||||
# define BOOST_HAS_TR1_RESULT_OF
|
||||
# define BOOST_HAS_TR1_MEM_FN
|
||||
# define BOOST_HAS_TR1_BIND
|
||||
# define BOOST_HAS_TR1_FUNCTION
|
||||
# define BOOST_HAS_TR1_HASH
|
||||
# define BOOST_HAS_TR1_SHARED_PTR
|
||||
# define BOOST_HAS_TR1_RANDOM
|
||||
# define BOOST_HAS_TR1_REGEX
|
||||
# define BOOST_HAS_TR1_TUPLE
|
||||
# define BOOST_HAS_TR1_TYPE_TRAITS
|
||||
# define BOOST_HAS_TR1_UTILITY
|
||||
# define BOOST_HAS_TR1_UNORDERED_MAP
|
||||
# define BOOST_HAS_TR1_UNORDERED_SET
|
||||
# define BOOST_HAS_TR1_CMATH
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__MWERKS__) && (__MWERKS__ >= 0x3205)
|
||||
//
|
||||
// Very preliminary MWCW support, may not be right:
|
||||
//
|
||||
# define BOOST_HAS_TR1_SHARED_PTR
|
||||
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
|
||||
# define BOOST_HAS_TR1_FUNCTION
|
||||
# define BOOST_HAS_TR1_TUPLE
|
||||
# define BOOST_HAS_TR1_RESULT_OF
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_GCC_TR1
|
||||
// turn on support for everything in gcc 4.0.x:
|
||||
# define BOOST_HAS_TR1_ARRAY
|
||||
#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
|
||||
//# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
|
||||
# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG
|
||||
#endif
|
||||
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
|
||||
# define BOOST_HAS_TR1_RESULT_OF
|
||||
# define BOOST_HAS_TR1_MEM_FN
|
||||
# define BOOST_HAS_TR1_BIND
|
||||
# define BOOST_HAS_TR1_FUNCTION
|
||||
# define BOOST_HAS_TR1_HASH
|
||||
# define BOOST_HAS_TR1_SHARED_PTR
|
||||
#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
|
||||
# define BOOST_HAS_TR1_RANDOM
|
||||
//# define BOOST_HAS_TR1_REGEX
|
||||
#ifdef _GLIBCXX_USE_C99_MATH_TR1
|
||||
# define BOOST_HAS_TR1_CMATH
|
||||
#endif
|
||||
#endif
|
||||
# define BOOST_HAS_TR1_TUPLE
|
||||
# define BOOST_HAS_TR1_TYPE_TRAITS
|
||||
# define BOOST_HAS_TR1_UTILITY
|
||||
# define BOOST_HAS_TR1_UNORDERED_MAP
|
||||
# define BOOST_HAS_TR1_UNORDERED_SET
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1500) \
|
||||
&& defined(_MSC_FULL_VER) && \
|
||||
!defined(__SGI_STL_PORT) && \
|
||||
!defined(_STLPORT_VERSION) && \
|
||||
!defined(_RWSTD_VER_STR) && \
|
||||
!defined(_RWSTD_VER)
|
||||
//
|
||||
// MSVC-9.0 defines a not-quite TR1 conforming hash
|
||||
// function object in <functional>, so we must define
|
||||
// this here, in addition the feature pack for VC9
|
||||
// provides a more or less full TR1 implementation:
|
||||
//
|
||||
# if (defined(_HAS_TR1) && (_HAS_TR1 + 0)) || (_CPPLIB_VER >= 540)
|
||||
# define BOOST_HAS_TR1_ARRAY
|
||||
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
|
||||
# define BOOST_HAS_TR1_RESULT_OF
|
||||
# define BOOST_HAS_TR1_MEM_FN
|
||||
# define BOOST_HAS_TR1_BIND
|
||||
# define BOOST_HAS_TR1_FUNCTION
|
||||
# define BOOST_HAS_TR1_HASH
|
||||
# define BOOST_HAS_TR1_SHARED_PTR
|
||||
# define BOOST_HAS_TR1_RANDOM
|
||||
# define BOOST_HAS_TR1_REGEX
|
||||
# define BOOST_HAS_TR1_TUPLE
|
||||
# define BOOST_HAS_TR1_TYPE_TRAITS
|
||||
# define BOOST_HAS_TR1_UTILITY
|
||||
# define BOOST_HAS_TR1_UNORDERED_MAP
|
||||
# define BOOST_HAS_TR1_UNORDERED_SET
|
||||
# else
|
||||
# define BOOST_HAS_TR1_HASH
|
||||
# endif
|
||||
# if _MSC_VER >= 1600
|
||||
# define BOOST_HAS_CPP_0X
|
||||
# endif
|
||||
# if _MSC_VER >= 1700
|
||||
# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,705 @@
|
||||
# Boost.Build support specific for the Boost C++ Libraries.
|
||||
# Copyright Vladimir Prus 2002-2010.
|
||||
# Copyright Dave Abrahams 2005-2006.
|
||||
# Copyright Rene Rivera 2005-2007.
|
||||
# Copyright Douglas Gregor 2005.
|
||||
#
|
||||
# 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)
|
||||
|
||||
import "class" : new ;
|
||||
import common ;
|
||||
import configure ;
|
||||
import build-system ;
|
||||
import generate ;
|
||||
import modules ;
|
||||
import option ;
|
||||
import os ;
|
||||
import package ;
|
||||
import path ;
|
||||
import project ;
|
||||
import regex ;
|
||||
import set ;
|
||||
import targets ;
|
||||
import feature ;
|
||||
import property ;
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# 0. General setup. Parse options, check them.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
BOOST_ROOT = [ modules.binding $(__name__) ] ;
|
||||
BOOST_ROOT = $(BOOST_ROOT:D) ;
|
||||
|
||||
rule set-version ( version )
|
||||
{
|
||||
BOOST_VERSION = $(version) ;
|
||||
|
||||
local version-tag = [ MATCH ^([^.]+)[.]([^.]+)[.]([^.]+) : $(BOOST_VERSION)
|
||||
] ;
|
||||
if $(version-tag[3]) = 0
|
||||
{
|
||||
version-tag = $(version-tag[1-2]) ;
|
||||
}
|
||||
BOOST_VERSION_TAG = $(version-tag:J=_) ;
|
||||
}
|
||||
|
||||
# Option to choose how many variants to build. The default is "minimal".
|
||||
build-type = [ option.get build-type ] ;
|
||||
build-type ?= minimal ;
|
||||
if ! ( $(build-type) in complete minimal )
|
||||
{
|
||||
EXIT The value of the --build-type option should be either 'complete' or
|
||||
'minimal' ;
|
||||
}
|
||||
|
||||
# What kind of layout are we doing?
|
||||
layout = [ option.get layout : "" ] ;
|
||||
# On Windows, we used versioned layout by default in order to be compatible with
|
||||
# autolink. On other systems, we use system layout which is what every other
|
||||
# program uses. Note that the Windows check is static, and will not be affected
|
||||
# by specific build properties used.
|
||||
if ! $(layout)
|
||||
{
|
||||
if [ os.name ] = NT
|
||||
{
|
||||
layout = versioned ;
|
||||
}
|
||||
else
|
||||
{
|
||||
layout = system ;
|
||||
}
|
||||
}
|
||||
layout-$(layout) = true ;
|
||||
|
||||
if $(layout) = system && $(build-type) = complete
|
||||
{
|
||||
ECHO error: Cannot use --layout=system with --build-type complete. ;
|
||||
ECHO error: Please use either --layout=versioned or --layout=tagged ;
|
||||
ECHO error: if you wish to build multiple variants. ;
|
||||
if [ os.name ] != NT
|
||||
{
|
||||
ECHO error: Note that --layout=system is used by default on Unix
|
||||
starting with Boost 1.40. ;
|
||||
}
|
||||
EXIT ;
|
||||
}
|
||||
|
||||
# Possible stage only location.
|
||||
stage-locate = [ option.get stagedir ] ;
|
||||
stage-locate ?= stage ;
|
||||
BOOST_STAGE_LOCATE = $(stage-locate) ;
|
||||
|
||||
# Custom build ID.
|
||||
build-id = [ option.get buildid ] ;
|
||||
if $(build-id)
|
||||
{
|
||||
BUILD_ID = [ regex.replace $(build-id) "[*\\/:.\"\' ]" _ ] ;
|
||||
}
|
||||
|
||||
# Python build id (for Python libraries only).
|
||||
python-id = [ option.get "python-buildid" ] ;
|
||||
if $(python-id)
|
||||
{
|
||||
PYTHON_ID = [ regex.replace $(python-id) [*\\/:.\"\'] _ ] ;
|
||||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# 1. 'tag' function adding decorations suitable to the properties if versioned
|
||||
# or tagged layout is requested. Called from Jamroot.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
rule tag ( name : type ? : property-set )
|
||||
{
|
||||
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
|
||||
{
|
||||
local result ;
|
||||
if $(layout) = versioned
|
||||
{
|
||||
result = [ common.format-name
|
||||
<base> <toolset> <threading> <runtime> -$(BOOST_VERSION_TAG)
|
||||
-$(BUILD_ID)
|
||||
: $(name) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
else if $(layout) = tagged
|
||||
{
|
||||
result = [ common.format-name
|
||||
<base> <threading> <runtime>
|
||||
-$(BUILD_ID)
|
||||
: $(name) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
else if $(layout) = system
|
||||
{
|
||||
result = [ common.format-name
|
||||
<base>
|
||||
-$(BUILD_ID)
|
||||
: $(name) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
EXIT error: invalid layout '$(layout:E=)' ;
|
||||
}
|
||||
|
||||
# Optionally add version suffix. On NT, library with version suffix will
|
||||
# not be recognized by linkers. On CYGWIN, we get strage duplicate
|
||||
# symbol errors when library is generated with version suffix. On OSX,
|
||||
# version suffix is not needed -- the linker expects the
|
||||
# libFoo.1.2.3.dylib format. AIX linkers do not accept version suffixes
|
||||
# either. Pgi compilers can not accept a library with version suffix.
|
||||
if $(type) = SHARED_LIB &&
|
||||
! [ $(property-set).get <target-os> ] in windows cygwin darwin aix &&
|
||||
! [ $(property-set).get <toolset> ] in pgi
|
||||
{
|
||||
result = $(result).$(BOOST_VERSION) ;
|
||||
}
|
||||
|
||||
return $(result) ;
|
||||
}
|
||||
}
|
||||
|
||||
# Specialized tag function to use for libraries linking to Python.
|
||||
# Appends value of --python-buildid if provided.
|
||||
rule python-tag ( name : type ? : property-set )
|
||||
{
|
||||
local result = $(name) ;
|
||||
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB && $(PYTHON_ID)
|
||||
{
|
||||
result = $(result)-$(PYTHON_ID) ;
|
||||
}
|
||||
|
||||
# forward to the boost tagging rule
|
||||
return [ tag $(result) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# 2. Declare targets that build and install all libraries. Specifically:
|
||||
#
|
||||
# - 'stage-proper' that puts all libraries in stage/lib
|
||||
# - 'install-proper' that install libraries and headers to system location
|
||||
# - 'stage-unversioned' that creates links to libraries without boost version
|
||||
# in name
|
||||
# - 'install-unversioned' which creates unversioned linked to installed
|
||||
# libraries.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
# Worker function suitable to the 'generate' metatarget. Creates a link to
|
||||
# 'source', striping any version number information from the name.
|
||||
rule make-unversioned-links ( project name ? : property-set : sources * )
|
||||
{
|
||||
local filter ;
|
||||
if [ modules.peek : NT ]
|
||||
{
|
||||
filter = (.*[.]lib) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
filter =
|
||||
(.*[.]so)[.0-9]*
|
||||
(.*[.]dylib)
|
||||
(.*[.]a) ;
|
||||
}
|
||||
|
||||
local result ;
|
||||
for local s in $(sources)
|
||||
{
|
||||
local m = [ MATCH ^(.*)-[0-9_]+$(filter)$ : [ $(s).name ] ] ;
|
||||
if $(m)
|
||||
{
|
||||
local ea = [ $(s).action ] ;
|
||||
local ep = [ $(ea).properties ] ;
|
||||
local a = [ new non-scanning-action $(s) : symlink.ln : $(ep) ] ;
|
||||
result += [ new file-target $(m:J=) exact : [ $(s).type ] :
|
||||
$(project) : $(a) ] ;
|
||||
}
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
rule filtered-target ( name : message + : sources + : requirements * )
|
||||
{
|
||||
message $(name)-message : warning: $(message) ;
|
||||
alias $(name) : $(sources) : $(requirements) ;
|
||||
alias $(name) : $(name)-message ;
|
||||
|
||||
local p = [ project.current ] ;
|
||||
$(p).mark-target-as-explicit $(name) ;
|
||||
$(p).mark-target-as-explicit $(name)-message ;
|
||||
}
|
||||
|
||||
rule declare_install_and_stage_proper_targets ( libraries * : headers * )
|
||||
{
|
||||
local p = [ project.current ] ;
|
||||
for local l in $(libraries)
|
||||
{
|
||||
if $(l) = locale
|
||||
{
|
||||
filtered-target $(l)-for-install :
|
||||
Skipping Boost.Locale library with threading=single. :
|
||||
libs/$(l)/build : <threading>multi ;
|
||||
}
|
||||
else if $(l) = wave
|
||||
{
|
||||
filtered-target $(l)-for-install :
|
||||
Skipping Boost.Wave library with threading=single. :
|
||||
libs/$(l)/build : <threading>multi ;
|
||||
}
|
||||
else if $(l) = thread
|
||||
{
|
||||
filtered-target $(l)-for-install :
|
||||
Skipping Boost.Thread library with threading=single. :
|
||||
libs/$(l)/build : <threading>multi ;
|
||||
}
|
||||
else
|
||||
{
|
||||
alias $(l)-for-install : libs/$(l)/build ;
|
||||
$(p).mark-target-as-explicit $(l)-for-install ;
|
||||
}
|
||||
}
|
||||
local library-targets = $(libraries)-for-install ;
|
||||
|
||||
install-requirements = <install-source-root>$(BOOST_ROOT)/boost ;
|
||||
|
||||
if $(layout-versioned)
|
||||
{
|
||||
install-requirements +=
|
||||
<install-header-subdir>boost-$(BOOST_VERSION_TAG)/boost ;
|
||||
}
|
||||
else
|
||||
{
|
||||
install-requirements += <install-header-subdir>boost ;
|
||||
}
|
||||
|
||||
if [ os.name ] = NT
|
||||
{
|
||||
install-requirements += <install-default-prefix>C:/Boost ;
|
||||
}
|
||||
else
|
||||
{
|
||||
install-requirements += <install-default-prefix>/usr/local ;
|
||||
}
|
||||
|
||||
p = [ project.current ] ;
|
||||
|
||||
# Complete install.
|
||||
package.install install-proper
|
||||
: $(install-requirements) <install-no-version-symlinks>on
|
||||
:
|
||||
: $(libraries)-for-install
|
||||
: $(headers)
|
||||
;
|
||||
$(p).mark-target-as-explicit install-proper ;
|
||||
|
||||
# Install just library.
|
||||
install stage-proper
|
||||
: $(libraries)-for-install
|
||||
: <location>$(stage-locate)/lib
|
||||
<install-dependencies>on <install-type>LIB
|
||||
<install-no-version-symlinks>on
|
||||
;
|
||||
$(p).mark-target-as-explicit stage-proper ;
|
||||
|
||||
# Commented out as it does not seem to work. Whoever wrote this originally,
|
||||
# left some typos in the code, but when that got corrected and the code got
|
||||
# enabled - it started reporting ambiguous/duplicate target Boost Build
|
||||
# errors. Anyone requiring unversioned staged libraries needs to correct
|
||||
# those errors before reenabling this code. For more detailed information
|
||||
# see the related Boost library development mailing list thread at
|
||||
# 'http://lists.boost.org/Archives/boost/2012/06/194312.php'.
|
||||
# (06.07.2012.) (Jurko)
|
||||
#~ if $(layout-versioned) && ( [ modules.peek : NT ] || [ modules.peek : UNIX ] )
|
||||
#~ {
|
||||
#~ generate stage-unversioned : stage-proper :
|
||||
#~ <generating-rule>@boostcpp.make-unversioned-links ;
|
||||
#~ $(p).mark-target-as-explicit stage-unversioned ;
|
||||
#~
|
||||
#~ generate install-unversioned : install-proper :
|
||||
#~ <generating-rule>@boostcpp.make-unversioned-links ;
|
||||
#~ $(p).mark-target-as-explicit install-unversioned ;
|
||||
#~ }
|
||||
#~ else
|
||||
{
|
||||
# Create do-nothing aliases.
|
||||
alias stage-unversioned ;
|
||||
$(p).mark-target-as-explicit stage-unversioned ;
|
||||
alias install-unversioned ;
|
||||
$(p).mark-target-as-explicit install-unversioned ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# 3. Declare top-level targets 'stage' and 'install'. These examine the
|
||||
# --build-type option and, in case it is 'complete', build the 'install-proper'
|
||||
# and 'stage-proper' targets with a number of property sets.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
class top-level-target : alias-target-class
|
||||
{
|
||||
import modules ;
|
||||
|
||||
rule __init__ ( name : project : sources * : requirements *
|
||||
: default-build * : usage-requirements * )
|
||||
{
|
||||
alias-target-class.__init__ $(name) : $(project) : $(sources) :
|
||||
$(requirements) : $(default-build) : $(usage-requirements) ;
|
||||
|
||||
self.build-type = [ modules.peek boostcpp : build-type ] ;
|
||||
# On Linux, we build the release variant by default, since few users
|
||||
# will ever want to debug C++ Boost libraries, and there is no ABI
|
||||
# incompatibility between debug and release variants. We build shared
|
||||
# and static libraries since that is what most packages seem to provide
|
||||
# (.so in libfoo and .a in libfoo-dev).
|
||||
self.minimal-properties = [ property-set.create <variant>release
|
||||
<threading>multi <link>shared <link>static <runtime-link>shared ] ;
|
||||
# On Windows, new IDE projects use:
|
||||
#
|
||||
# runtime-link=dynamic, threading=multi, variant=(debug|release)
|
||||
#
|
||||
# and in addition, C++ Boost's autolink defaults to static linking.
|
||||
self.minimal-properties-win = [ property-set.create <variant>debug
|
||||
<variant>release <threading>multi <link>static <runtime-link>shared
|
||||
] ;
|
||||
|
||||
self.complete-properties = [ property-set.create
|
||||
<variant>debug <variant>release
|
||||
<threading>single <threading>multi
|
||||
<link>shared <link>static
|
||||
<runtime-link>shared <runtime-link>static ] ;
|
||||
}
|
||||
|
||||
rule generate ( property-set )
|
||||
{
|
||||
modules.poke : top-level-targets : [ modules.peek : top-level-targets ]
|
||||
$(self.name) ;
|
||||
if $(self.build-type) = minimal
|
||||
{
|
||||
local expanded ;
|
||||
|
||||
local os = [ $(property-set).get <target-os> ] ;
|
||||
# Because we completely override the parent's 'generate' we need to
|
||||
# check for default feature values ourselves.
|
||||
if ! $(os)
|
||||
{
|
||||
os = [ feature.defaults <target-os> ] ;
|
||||
os = $(os:G=) ;
|
||||
}
|
||||
|
||||
if $(os) = windows
|
||||
{
|
||||
expanded = [ targets.apply-default-build $(property-set)
|
||||
: $(self.minimal-properties-win) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
expanded = [ targets.apply-default-build $(property-set)
|
||||
: $(self.minimal-properties) ] ;
|
||||
}
|
||||
return [ build-multiple $(expanded) ] ;
|
||||
}
|
||||
else if $(self.build-type) = complete
|
||||
{
|
||||
local expanded = [ targets.apply-default-build $(property-set)
|
||||
: $(self.complete-properties) ] ;
|
||||
|
||||
# Filter inappopriate combinations.
|
||||
local filtered ;
|
||||
for local p in $(expanded)
|
||||
{
|
||||
# See comment in handle-static-runtime regarding this logic.
|
||||
if [ $(p).get <link> ] = shared
|
||||
&& [ $(p).get <runtime-link> ] = static
|
||||
&& [ $(p).get <toolset> ] != cw
|
||||
{
|
||||
# Skip this.
|
||||
}
|
||||
else
|
||||
{
|
||||
filtered += $(p) ;
|
||||
}
|
||||
}
|
||||
return [ build-multiple $(filtered) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
import errors ;
|
||||
errors.error "Unknown build type" ;
|
||||
}
|
||||
}
|
||||
|
||||
rule build-multiple ( property-sets * )
|
||||
{
|
||||
local usage-requirements = [ property-set.empty ] ;
|
||||
local result ;
|
||||
for local p in $(property-sets)
|
||||
{
|
||||
local r = [ alias-target-class.generate $(p) ] ;
|
||||
if $(r)
|
||||
{
|
||||
usage-requirements = [ $(usage-requirements).add $(r[1]) ] ;
|
||||
result += $(r[2-]) ;
|
||||
}
|
||||
}
|
||||
return $(usage-requirements) [ sequence.unique $(result) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
rule declare_top_level_targets ( libraries * : headers * )
|
||||
{
|
||||
declare_install_and_stage_proper_targets $(libraries) : $(headers) ;
|
||||
|
||||
targets.create-metatarget top-level-target : [ project.current ]
|
||||
: install
|
||||
: install-proper install-unversioned
|
||||
;
|
||||
targets.create-metatarget top-level-target : [ project.current ]
|
||||
: stage
|
||||
: stage-proper stage-unversioned
|
||||
;
|
||||
|
||||
p = [ project.current ] ;
|
||||
$(p).mark-target-as-explicit install stage ;
|
||||
|
||||
# This target is built by default, and will forward to 'stage' after
|
||||
# producing some explanations.
|
||||
targets.create-metatarget top-level-target : [ project.current ]
|
||||
: forward
|
||||
: explain stage
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
stage-abs = [ path.native [ path.root $(stage-locate)/lib [ path.pwd ] ] ] ;
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# 4. Add hook to report configuration before the build, and confirmation with
|
||||
# setup instructions after the build.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
message explain : "\nBuilding the Boost C++ Libraries.\n\n" ;
|
||||
local p = [ project.current ] ;
|
||||
$(p).mark-target-as-explicit explain ;
|
||||
|
||||
rule pre-build ( )
|
||||
{
|
||||
local tl = [ modules.peek : top-level-targets ] ;
|
||||
if stage in $(tl) || install in $(tl)
|
||||
{
|
||||
# FIXME: Remove 'if' when Boost regression tests start using trunk bjam.
|
||||
if PAD in [ RULENAMES ]
|
||||
{
|
||||
configure.print-component-configuration ;
|
||||
}
|
||||
}
|
||||
}
|
||||
IMPORT $(__name__) : pre-build : : $(__name__).pre-build ;
|
||||
build-system.set-pre-build-hook $(__name__).pre-build ;
|
||||
|
||||
# FIXME: Revise stage_abs.
|
||||
rule post-build ( ok ? )
|
||||
{
|
||||
if forward in [ modules.peek : top-level-targets ]
|
||||
{
|
||||
if $(ok)
|
||||
{
|
||||
local include-path = [ path.native $(BOOST_ROOT) ] ;
|
||||
ECHO "
|
||||
|
||||
The Boost C++ Libraries were successfully built!
|
||||
|
||||
The following directory should be added to compiler include paths:
|
||||
|
||||
$(include-path)
|
||||
|
||||
The following directory should be added to linker library paths:
|
||||
|
||||
$(stage-abs)
|
||||
" ;
|
||||
}
|
||||
}
|
||||
}
|
||||
IMPORT $(__name__) : post-build : : $(__name__).post-build ;
|
||||
build-system.set-post-build-hook $(__name__).post-build ;
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# 5. Top-level setup.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
# Decides which libraries are to be installed by looking at --with-<library>
|
||||
# --without-<library> arguments. Returns the list of directories under "libs"
|
||||
# which must be built and installed.
|
||||
#
|
||||
rule libraries-to-install ( existing-libs * )
|
||||
{
|
||||
local argv = [ modules.peek : ARGV ] ;
|
||||
local with-parameter = [ MATCH ^--with-(.*) : $(argv) ] ;
|
||||
local without-parameter = [ MATCH ^--without-(.*) : $(argv) ] ;
|
||||
|
||||
if ! $(with-parameter) && ! $(without-parameter)
|
||||
{
|
||||
# Nothing is specified on command line. See if maybe project-config.jam
|
||||
# has some choices.
|
||||
local libs = [ modules.peek project-config : libraries ] ;
|
||||
with-parameter = [ MATCH ^--with-(.*) : $(libs) ] ;
|
||||
without-parameter = [ MATCH ^--without-(.*) : $(libs) ] ;
|
||||
}
|
||||
|
||||
# Do some checks.
|
||||
if $(with-parameter) && $(without-parameter)
|
||||
{
|
||||
EXIT error: both --with-<library> and --without-<library> specified ;
|
||||
}
|
||||
|
||||
local wrong = [ set.difference $(with-parameter) : $(existing-libs) ] ;
|
||||
if $(wrong)
|
||||
{
|
||||
EXIT error: wrong library name '$(wrong[1])' in the --with-<library>
|
||||
option. ;
|
||||
}
|
||||
local wrong = [ set.difference $(without-parameter) : $(existing-libs) ] ;
|
||||
if $(wrong)
|
||||
{
|
||||
EXIT error: wrong library name '$(wrong[1])' in the --without-<library>
|
||||
option. ;
|
||||
}
|
||||
|
||||
if $(with-parameter)
|
||||
{
|
||||
return [ set.intersection $(existing-libs) : $(with-parameter) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return [ set.difference $(existing-libs) : $(without-parameter) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
rule declare-targets ( all-libraries * : headers * )
|
||||
{
|
||||
configure.register-components $(all-libraries) ;
|
||||
|
||||
# Select the libraries to install.
|
||||
libraries = [ libraries-to-install $(all-libraries) ] ;
|
||||
configure.components-building $(libraries) ;
|
||||
|
||||
if [ option.get "show-libraries" : : true ]
|
||||
{
|
||||
ECHO The following libraries require building: ;
|
||||
for local l in $(libraries)
|
||||
{
|
||||
ECHO " - $(l)" ;
|
||||
}
|
||||
EXIT ;
|
||||
}
|
||||
|
||||
declare_top_level_targets $(libraries) : $(headers) ;
|
||||
}
|
||||
|
||||
# Returns the properties identifying the toolset. We'll use them
|
||||
# below to configure checks. These are essentially same as in
|
||||
# configure.builds, except we don't use address-model and
|
||||
# architecture - as we're trying to detect them here.
|
||||
#
|
||||
rule toolset-properties ( properties * )
|
||||
{
|
||||
local toolset = [ property.select <toolset> : $(properties) ] ;
|
||||
local toolset-version-property = "<toolset-$(toolset:G=):version>" ;
|
||||
return [ property.select <target-os> <toolset> $(toolset-version-property) : $(properties) ] ;
|
||||
}
|
||||
|
||||
feature.feature deduced-address-model : 32 64 : propagated optional composite hidden ;
|
||||
feature.compose <deduced-address-model>32 : <address-model>32 ;
|
||||
feature.compose <deduced-address-model>64 : <address-model>64 ;
|
||||
|
||||
rule deduce-address-model ( properties * )
|
||||
{
|
||||
local result ;
|
||||
local filtered = [ toolset-properties $(properties) ] ;
|
||||
|
||||
if [ configure.builds /boost/architecture//32 : $(filtered) : 32-bit ]
|
||||
{
|
||||
result = 32 ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//64 : $(filtered) : 64-bit ]
|
||||
{
|
||||
result = 64 ;
|
||||
}
|
||||
|
||||
if $(result)
|
||||
{
|
||||
# Normally, returning composite feature here is equivalent to forcing
|
||||
# consituent properties as well. But we only want to indicate toolset
|
||||
# deduced default, so also pick whatever address-model is explicitly
|
||||
# specified, if any.
|
||||
result = <deduced-address-model>$(result) [ property.select <address-model> : $(properties) ] ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
rule address-model ( )
|
||||
{
|
||||
return <conditional>@boostcpp.deduce-address-model ;
|
||||
}
|
||||
|
||||
local deducable-architectures = arm mips1 power sparc x86 combined ;
|
||||
feature.feature deduced-architecture : $(deducable-architectures) : propagated optional composite hidden ;
|
||||
for a in $(deducable-architectures)
|
||||
{
|
||||
feature.compose <deduced-architecture>$(a) : <architecture>$(a) ;
|
||||
}
|
||||
|
||||
rule deduce-architecture ( properties * )
|
||||
{
|
||||
local result ;
|
||||
local filtered = [ toolset-properties $(properties) ] ;
|
||||
if [ configure.builds /boost/architecture//arm : $(filtered) : arm ]
|
||||
{
|
||||
result = arm ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//mips1 : $(filtered) : mips1 ]
|
||||
{
|
||||
result = mips1 ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//power : $(filtered) : power ]
|
||||
{
|
||||
result = power ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//sparc : $(filtered) : sparc ]
|
||||
{
|
||||
result = sparc ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//x86 : $(filtered) : x86 ]
|
||||
{
|
||||
result = x86 ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//combined : $(filtered) : combined ]
|
||||
{
|
||||
result = combined ;
|
||||
}
|
||||
|
||||
if $(result)
|
||||
{
|
||||
# See comment in deduce-address-model.
|
||||
result = <deduced-architecture>$(result) [ property.select <architecture> : $(properties) ] ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
rule architecture ( )
|
||||
{
|
||||
return <conditional>@boostcpp.deduce-architecture ;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Copyright (C) 2009 Vladimir Prus
|
||||
REM
|
||||
REM Distributed under the Boost Software License, Version 1.0.
|
||||
REM (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
ECHO Building Boost.Build engine
|
||||
if exist ".\tools\build\src\engine\bin.ntx86\b2.exe" del tools\build\src\engine\bin.ntx86\b2.exe
|
||||
if exist ".\tools\build\src\engine\bin.ntx86\bjam.exe" del tools\build\src\engine\bin.ntx86\bjam.exe
|
||||
if exist ".\tools\build\src\engine\bin.ntx86_64\b2.exe" del tools\build\src\engine\bin.ntx86_64\b2.exe
|
||||
if exist ".\tools\build\src\engine\bin.ntx86_64\bjam.exe" del tools\build\src\engine\bin.ntx86_64\bjam.exe
|
||||
pushd tools\build\src\engine
|
||||
|
||||
call .\build.bat %* > ..\..\..\..\bootstrap.log
|
||||
@ECHO OFF
|
||||
|
||||
popd
|
||||
|
||||
if exist ".\tools\build\src\engine\bin.ntx86\bjam.exe" (
|
||||
copy .\tools\build\src\engine\bin.ntx86\b2.exe . > nul
|
||||
copy .\tools\build\src\engine\bin.ntx86\bjam.exe . > nul
|
||||
goto :bjam_built)
|
||||
|
||||
if exist ".\tools\build\src\engine\bin.ntx86_64\bjam.exe" (
|
||||
copy .\tools\build\src\engine\bin.ntx86_64\b2.exe . > nul
|
||||
copy .\tools\build\src\engine\bin.ntx86_64\bjam.exe . > nul
|
||||
goto :bjam_built)
|
||||
|
||||
goto :bjam_failure
|
||||
|
||||
:bjam_built
|
||||
|
||||
REM Ideally, we should obtain the toolset that build.bat has
|
||||
REM guessed. However, it uses setlocal at the start and does not
|
||||
REM export BOOST_JAM_TOOLSET, and I don't know how to do that
|
||||
REM properly. Default to msvc for now.
|
||||
set toolset=msvc
|
||||
|
||||
ECHO import option ; > project-config.jam
|
||||
ECHO. >> project-config.jam
|
||||
ECHO using %toolset% ; >> project-config.jam
|
||||
ECHO. >> project-config.jam
|
||||
ECHO option.set keep-going : false ; >> project-config.jam
|
||||
ECHO. >> project-config.jam
|
||||
|
||||
ECHO.
|
||||
ECHO Bootstrapping is done. To build, run:
|
||||
ECHO.
|
||||
ECHO .\b2
|
||||
ECHO.
|
||||
ECHO To adjust configuration, edit 'project-config.jam'.
|
||||
ECHO Further information:
|
||||
ECHO.
|
||||
ECHO - Command line help:
|
||||
ECHO .\b2 --help
|
||||
ECHO.
|
||||
ECHO - Getting started guide:
|
||||
ECHO http://boost.org/more/getting_started/windows.html
|
||||
ECHO.
|
||||
ECHO - Boost.Build documentation:
|
||||
ECHO http://www.boost.org/build/doc/html/index.html
|
||||
|
||||
goto :end
|
||||
|
||||
:bjam_failure
|
||||
|
||||
ECHO.
|
||||
ECHO Failed to build Boost.Build engine.
|
||||
ECHO Please consult bootstrap.log for further diagnostics.
|
||||
ECHO.
|
||||
ECHO You can try to obtain a prebuilt binary from
|
||||
ECHO.
|
||||
ECHO http://sf.net/project/showfiles.php?group_id=7586^&package_id=72941
|
||||
ECHO.
|
||||
ECHO Also, you can file an issue at http://svn.boost.org
|
||||
ECHO Please attach bootstrap.log in that case.
|
||||
|
||||
goto :end
|
||||
|
||||
:end
|
||||
@@ -0,0 +1,409 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2005, 2006 Douglas Gregor.
|
||||
# Copyright (C) 2006 The Trustees of Indiana University
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# boostinspect:notab - Tabs are required for the Makefile.
|
||||
|
||||
BJAM=""
|
||||
TOOLSET=""
|
||||
BJAM_CONFIG=""
|
||||
BUILD=""
|
||||
PREFIX=/usr/local
|
||||
EPREFIX=
|
||||
LIBDIR=
|
||||
INCLUDEDIR=
|
||||
LIBS=""
|
||||
PYTHON=python
|
||||
PYTHON_VERSION=
|
||||
PYTHON_ROOT=
|
||||
ICU_ROOT=
|
||||
|
||||
# Handle case where builtin shell version of echo command doesn't
|
||||
# support -n. Use the installed echo executable if there is one
|
||||
# rather than builtin version to ensure -n is supported.
|
||||
ECHO=`which echo`
|
||||
if test "x$ECHO" = x; then
|
||||
ECHO=echo
|
||||
fi
|
||||
|
||||
# Internal flags
|
||||
flag_no_python=
|
||||
flag_icu=
|
||||
flag_show_libraries=
|
||||
|
||||
for option
|
||||
do
|
||||
case $option in
|
||||
|
||||
-help | --help | -h)
|
||||
want_help=yes ;;
|
||||
|
||||
-prefix=* | --prefix=*)
|
||||
PREFIX=`expr "x$option" : "x-*prefix=\(.*\)"`
|
||||
;;
|
||||
|
||||
-exec-prefix=* | --exec-prefix=*)
|
||||
EPREFIX=`expr "x$option" : "x-*exec-prefix=\(.*\)"`
|
||||
;;
|
||||
|
||||
-libdir=* | --libdir=*)
|
||||
LIBDIR=`expr "x$option" : "x-*libdir=\(.*\)"`
|
||||
;;
|
||||
|
||||
-includedir=* | --includedir=*)
|
||||
INCLUDEDIR=`expr "x$option" : "x-*includedir=\(.*\)"`
|
||||
;;
|
||||
|
||||
-show-libraries | --show-libraries )
|
||||
flag_show_libraries=yes
|
||||
;;
|
||||
|
||||
-with-bjam=* | --with-bjam=* )
|
||||
BJAM=`expr "x$option" : "x-*with-bjam=\(.*\)"`
|
||||
;;
|
||||
|
||||
-with-icu | --with-icu )
|
||||
flag_icu=yes
|
||||
;;
|
||||
|
||||
-with-icu=* | --with-icu=* )
|
||||
flag_icu=yes
|
||||
ICU_ROOT=`expr "x$option" : "x-*with-icu=\(.*\)"`
|
||||
;;
|
||||
|
||||
-without-icu | --without-icu )
|
||||
flag_icu=no
|
||||
;;
|
||||
|
||||
-with-libraries=* | --with-libraries=* )
|
||||
library_list=`expr "x$option" : "x-*with-libraries=\(.*\)"`
|
||||
if test "$library_list" != "all"; then
|
||||
old_IFS=$IFS
|
||||
IFS=,
|
||||
for library in $library_list
|
||||
do
|
||||
LIBS="$LIBS --with-$library"
|
||||
|
||||
if test $library = python; then
|
||||
requested_python=yes
|
||||
fi
|
||||
done
|
||||
IFS=$old_IFS
|
||||
|
||||
if test "x$requested_python" != xyes; then
|
||||
flag_no_python=yes
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
-without-libraries=* | --without-libraries=* )
|
||||
library_list=`expr "x$option" : "x-*without-libraries=\(.*\)"`
|
||||
old_IFS=$IFS
|
||||
IFS=,
|
||||
for library in $library_list
|
||||
do
|
||||
LIBS="$LIBS --without-$library"
|
||||
|
||||
if test $library = python; then
|
||||
flag_no_python=yes
|
||||
fi
|
||||
done
|
||||
IFS=$old_IFS
|
||||
;;
|
||||
|
||||
-with-python=* | --with-python=* )
|
||||
PYTHON=`expr "x$option" : "x-*with-python=\(.*\)"`
|
||||
;;
|
||||
|
||||
-with-python-root=* | --with-python-root=* )
|
||||
PYTHON_ROOT=`expr "x$option" : "x-*with-python-root=\(.*\)"`
|
||||
;;
|
||||
|
||||
-with-python-version=* | --with-python-version=* )
|
||||
PYTHON_VERSION=`expr "x$option" : "x-*with-python-version=\(.*\)"`
|
||||
;;
|
||||
|
||||
-with-toolset=* | --with-toolset=* )
|
||||
TOOLSET=`expr "x$option" : "x-*with-toolset=\(.*\)"`
|
||||
;;
|
||||
|
||||
-*)
|
||||
{ echo "error: unrecognized option: $option
|
||||
Try \`$0 --help' for more information." >&2
|
||||
{ (exit 1); exit 1; }; }
|
||||
;;
|
||||
|
||||
esac
|
||||
done
|
||||
|
||||
if test "x$want_help" = xyes; then
|
||||
cat <<EOF
|
||||
\`./bootstrap.sh' prepares Boost for building on a few kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]...
|
||||
|
||||
Defaults for the options are specified in brackets.
|
||||
|
||||
Configuration:
|
||||
-h, --help display this help and exit
|
||||
--with-bjam=BJAM use existing Boost.Jam executable (bjam)
|
||||
[automatically built]
|
||||
--with-toolset=TOOLSET use specific Boost.Build toolset
|
||||
[automatically detected]
|
||||
--show-libraries show the set of libraries that require build
|
||||
and installation steps (i.e., those libraries
|
||||
that can be used with --with-libraries or
|
||||
--without-libraries), then exit
|
||||
--with-libraries=list build only a particular set of libraries,
|
||||
describing using either a comma-separated list of
|
||||
library names or "all"
|
||||
[all]
|
||||
--without-libraries=list build all libraries except the ones listed []
|
||||
--with-icu enable Unicode/ICU support in Regex
|
||||
[automatically detected]
|
||||
--without-icu disable Unicode/ICU support in Regex
|
||||
--with-icu=DIR specify the root of the ICU library installation
|
||||
and enable Unicode/ICU support in Regex
|
||||
[automatically detected]
|
||||
--with-python=PYTHON specify the Python executable [python]
|
||||
--with-python-root=DIR specify the root of the Python installation
|
||||
[automatically detected]
|
||||
--with-python-version=X.Y specify the Python version as X.Y
|
||||
[automatically detected]
|
||||
|
||||
Installation directories:
|
||||
--prefix=PREFIX install Boost into the given PREFIX
|
||||
[/usr/local]
|
||||
--exec-prefix=EPREFIX install Boost binaries into the given EPREFIX
|
||||
[PREFIX]
|
||||
|
||||
More precise control over installation directories:
|
||||
--libdir=DIR install libraries here [EPREFIX/lib]
|
||||
--includedir=DIR install headers here [PREFIX/include]
|
||||
|
||||
EOF
|
||||
fi
|
||||
test -n "$want_help" && exit 0
|
||||
|
||||
# TBD: Determine where the script is located
|
||||
my_dir="."
|
||||
|
||||
# Determine the toolset, if not already decided
|
||||
if test "x$TOOLSET" = x; then
|
||||
guessed_toolset=`$my_dir/tools/build/src/engine/build.sh --guess-toolset`
|
||||
case $guessed_toolset in
|
||||
acc | darwin | gcc | como | mipspro | pathscale | pgi | qcc | vacpp )
|
||||
TOOLSET=$guessed_toolset
|
||||
;;
|
||||
|
||||
intel-* )
|
||||
TOOLSET=intel
|
||||
;;
|
||||
|
||||
mingw )
|
||||
TOOLSET=gcc
|
||||
;;
|
||||
|
||||
sun* )
|
||||
TOOLSET=sun
|
||||
;;
|
||||
|
||||
* )
|
||||
# Not supported by Boost.Build
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
rm -f config.log
|
||||
|
||||
# Build bjam
|
||||
if test "x$BJAM" = x; then
|
||||
$ECHO -n "Building Boost.Build engine with toolset $TOOLSET... "
|
||||
pwd=`pwd`
|
||||
(cd "$my_dir/tools/build/src/engine" && ./build.sh "$TOOLSET") > bootstrap.log 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo
|
||||
echo "Failed to build Boost.Build build engine"
|
||||
echo "Consult 'bootstrap.log' for more details"
|
||||
exit 1
|
||||
fi
|
||||
cd "$pwd"
|
||||
arch=`cd $my_dir/tools/build/src/engine && ./bootstrap/jam0 -d0 -f build.jam --toolset=$TOOLSET --toolset-root= --show-locate-target && cd ..`
|
||||
BJAM="$my_dir/tools/build/src/engine/$arch/b2"
|
||||
echo "tools/build/src/engine/$arch/b2"
|
||||
cp "$BJAM" .
|
||||
cp "$my_dir/tools/build/src/engine/$arch/bjam" .
|
||||
|
||||
fi
|
||||
|
||||
# TBD: Turn BJAM into an absolute path
|
||||
|
||||
# If there is a list of libraries
|
||||
if test "x$flag_show_libraries" = xyes; then
|
||||
cat <<EOF
|
||||
|
||||
The following Boost libraries have portions that require a separate build
|
||||
and installation step. Any library not listed here can be used by including
|
||||
the headers only.
|
||||
|
||||
The Boost libraries requiring separate building and installation are:
|
||||
EOF
|
||||
$BJAM -d0 --show-libraries | grep '^[[:space:]]*-'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Setup paths
|
||||
if test "x$EPREFIX" = x; then
|
||||
EPREFIX="$PREFIX"
|
||||
fi
|
||||
|
||||
if test "x$LIBDIR" = x; then
|
||||
LIBDIR="$EPREFIX/lib"
|
||||
fi
|
||||
|
||||
if test "x$INCLUDEDIR" = x; then
|
||||
INCLUDEDIR="$PREFIX/include"
|
||||
fi
|
||||
|
||||
# Find Python
|
||||
if test "x$flag_no_python" = x; then
|
||||
result=`$PYTHON -c "exit" > /dev/null 2>&1`
|
||||
if [ "$?" -ne "0" ]; then
|
||||
flag_no_python=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$flag_no_python" = x; then
|
||||
if test "x$PYTHON_VERSION" = x; then
|
||||
$ECHO -n "Detecting Python version... "
|
||||
PYTHON_VERSION=`$PYTHON -c "import sys; print (\"%d.%d\" % (sys.version_info[0], sys.version_info[1]))"`
|
||||
echo $PYTHON_VERSION
|
||||
fi
|
||||
|
||||
if test "x$PYTHON_ROOT" = x; then
|
||||
$ECHO -n "Detecting Python root... "
|
||||
PYTHON_ROOT=`$PYTHON -c "import sys; print(sys.prefix)"`
|
||||
echo $PYTHON_ROOT
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configure ICU
|
||||
$ECHO -n "Unicode/ICU support for Boost.Regex?... "
|
||||
if test "x$flag_icu" != xno; then
|
||||
if test "x$ICU_ROOT" = x; then
|
||||
COMMON_ICU_PATHS="/usr /usr/local /sw"
|
||||
for p in $COMMON_ICU_PATHS; do
|
||||
if test -r $p/include/unicode/utypes.h; then
|
||||
ICU_ROOT=$p
|
||||
fi
|
||||
done
|
||||
|
||||
if test "x$ICU_ROOT" = x; then
|
||||
echo "not found."
|
||||
else
|
||||
BJAM_CONFIG="$BJAM_CONFIG -sICU_PATH=$ICU_ROOT"
|
||||
echo "$ICU_ROOT"
|
||||
fi
|
||||
else
|
||||
BJAM_CONFIG="$BJAM_CONFIG -sICU_PATH=$ICU_ROOT"
|
||||
echo "$ICU_ROOT"
|
||||
fi
|
||||
else
|
||||
echo "disabled."
|
||||
fi
|
||||
|
||||
# Backup the user's existing project-config.jam
|
||||
JAM_CONFIG_OUT="project-config.jam"
|
||||
if test -r "project-config.jam"; then
|
||||
counter=1
|
||||
|
||||
while test -r "project-config.jam.$counter"; do
|
||||
counter=`expr $counter + 1`
|
||||
done
|
||||
|
||||
echo "Backing up existing Boost.Build configuration in project-config.jam.$counter"
|
||||
mv "project-config.jam" "project-config.jam.$counter"
|
||||
fi
|
||||
|
||||
# Generate user-config.jam
|
||||
echo "Generating Boost.Build configuration in project-config.jam..."
|
||||
cat > project-config.jam <<EOF
|
||||
# Boost.Build Configuration
|
||||
# Automatically generated by bootstrap.sh
|
||||
|
||||
import option ;
|
||||
import feature ;
|
||||
|
||||
# Compiler configuration. This definition will be used unless
|
||||
# you already have defined some toolsets in your user-config.jam
|
||||
# file.
|
||||
if ! $TOOLSET in [ feature.values <toolset> ]
|
||||
{
|
||||
using $TOOLSET ;
|
||||
}
|
||||
|
||||
project : default-build <toolset>$TOOLSET ;
|
||||
EOF
|
||||
|
||||
# - Python configuration
|
||||
if test "x$flag_no_python" = x; then
|
||||
cat >> project-config.jam <<EOF
|
||||
|
||||
# Python configuration
|
||||
import python ;
|
||||
if ! [ python.configured ]
|
||||
{
|
||||
using python : $PYTHON_VERSION : $PYTHON_ROOT ;
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test "x$ICU_ROOT" != x; then
|
||||
cat >> project-config.jam << EOF
|
||||
|
||||
path-constant ICU_PATH : $ICU_ROOT ;
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >> project-config.jam << EOF
|
||||
|
||||
# List of --with-<library> and --without-<library>
|
||||
# options. If left empty, all libraries will be built.
|
||||
# Options specified on the command line completely
|
||||
# override this variable.
|
||||
libraries = $LIBS ;
|
||||
|
||||
# These settings are equivivalent to corresponding command-line
|
||||
# options.
|
||||
option.set prefix : $PREFIX ;
|
||||
option.set exec-prefix : $EPREFIX ;
|
||||
option.set libdir : $LIBDIR ;
|
||||
option.set includedir : $INCLUDEDIR ;
|
||||
|
||||
# Stop on first error
|
||||
option.set keep-going : false ;
|
||||
EOF
|
||||
|
||||
cat << EOF
|
||||
|
||||
Bootstrapping is done. To build, run:
|
||||
|
||||
./b2
|
||||
|
||||
To adjust configuration, edit 'project-config.jam'.
|
||||
Further information:
|
||||
|
||||
- Command line help:
|
||||
./b2 --help
|
||||
|
||||
- Getting started guide:
|
||||
http://www.boost.org/more/getting_started/unix-variants.html
|
||||
|
||||
- Boost.Build documentation:
|
||||
http://www.boost.org/build/doc/html/index.html
|
||||
|
||||
EOF
|
||||
@@ -0,0 +1,149 @@
|
||||
@import url("doc/src/boostbook.css");
|
||||
@import url("doc/src/docutils.css");
|
||||
/* Copyright David Abrahams 2006. 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)
|
||||
*/
|
||||
|
||||
dl.docutils dt {
|
||||
font-weight: bold }
|
||||
|
||||
img.boost-logo {
|
||||
border: none;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
pre.literal-block span.concept {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: inline;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.prevpage {
|
||||
padding-top: -5px;
|
||||
text-align: left;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.nextpage {
|
||||
padding-top: -20px;
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
div.small {
|
||||
font-size: smaller }
|
||||
|
||||
h2 a {
|
||||
font-size: 90%;
|
||||
}
|
||||
h3 a {
|
||||
font-size: 80%;
|
||||
}
|
||||
h4 a {
|
||||
font-size: 70%;
|
||||
}
|
||||
h5 a {
|
||||
font-size: 60%;
|
||||
}
|
||||
|
||||
dl,table
|
||||
{
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
|
||||
/*=============================================================================
|
||||
Tables
|
||||
=============================================================================*/
|
||||
|
||||
/* The only clue docutils gives us that tables are logically tables,
|
||||
and not, e.g., footnotes, is that they have border="1". Therefore
|
||||
we're keying off of that. We used to manually patch docutils to
|
||||
add a "table" class to all logical tables, but that proved much too
|
||||
fragile.
|
||||
*/
|
||||
|
||||
table[border="1"]
|
||||
{
|
||||
width: 92%;
|
||||
margin-left: 4%;
|
||||
margin-right: 4%;
|
||||
}
|
||||
|
||||
table[border="1"]
|
||||
{
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/* Table Cells */
|
||||
table[border="1"] tr td
|
||||
{
|
||||
padding: 0.5em;
|
||||
text-align: left;
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
table[border="1"] tr th
|
||||
{
|
||||
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||
border: 1pt solid white;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
@media screen
|
||||
{
|
||||
|
||||
/* Tables */
|
||||
table[border="1"] tr td
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
table[border="1"] tr th
|
||||
{
|
||||
background-color: #F0F0F0;
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
pre,
|
||||
.screen
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
td pre
|
||||
td .screen
|
||||
{
|
||||
border: 0px
|
||||
}
|
||||
|
||||
.sidebar pre
|
||||
{
|
||||
border: 0px
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pre,
|
||||
.screen
|
||||
{
|
||||
font-size: 9pt;
|
||||
display: block;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
/* Program listings in tables don't get borders */
|
||||
td pre,
|
||||
td .screen
|
||||
{
|
||||
margin: 0pc 0pc 0pc 0pc;
|
||||
padding: 0pc 0pc 0pc 0pc;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,9 @@ extern struct dec_data {
|
||||
int nsubmode;
|
||||
bool nagain;
|
||||
int ndepth;
|
||||
bool lapon;
|
||||
bool lft8apon;
|
||||
bool lapcqonly;
|
||||
bool ljt65apon;
|
||||
int napwid;
|
||||
int ntxmode;
|
||||
int nmode;
|
||||
@@ -78,6 +80,15 @@ extern struct {
|
||||
float red[4096];
|
||||
} echocom_;
|
||||
|
||||
extern struct {
|
||||
float wave[606720];
|
||||
int nslots;
|
||||
int nfreq;
|
||||
int i3bit[5];
|
||||
char cmsg[5][40];
|
||||
char mycall[12];
|
||||
} foxcom_;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
#include <QRegularExpression>
|
||||
#include <QDebug>
|
||||
|
||||
#include <varicode.h>
|
||||
|
||||
extern "C" {
|
||||
bool stdmsg_(char const * msg, bool contest_mode, char const * mygrid, int len_msg, int len_grid);
|
||||
bool stdmsg_(char const * msg, bool contest_mode, char const * mygrid, fortran_charlen_t, fortran_charlen_t);
|
||||
}
|
||||
|
||||
namespace
|
||||
@@ -50,8 +52,109 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
|
||||
, contest_mode_
|
||||
, grid_c_string.constData ()
|
||||
, 22, 6);
|
||||
|
||||
// We're only going to unpack standard messages for CQs && beacons...
|
||||
// TODO: jsherer - this is a hack for now...
|
||||
if(is_standard_){
|
||||
is_standard_ = QRegularExpression("^(CQ|DE|QRZ)\\s").match(message_).hasMatch();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
tryUnpack();
|
||||
}
|
||||
|
||||
DecodedText::DecodedText (QString const& ft8callmessage){
|
||||
message_ = ft8callmessage;
|
||||
is_standard_ = false;
|
||||
tryUnpack();
|
||||
}
|
||||
|
||||
bool DecodedText::tryUnpack(){
|
||||
if(is_standard_){
|
||||
return false;
|
||||
}
|
||||
|
||||
bool unpacked = false;
|
||||
if(!unpacked){
|
||||
unpacked = tryUnpackCompound();
|
||||
}
|
||||
|
||||
if(!unpacked){
|
||||
unpacked = tryUnpackDirected();
|
||||
}
|
||||
|
||||
if(!unpacked){
|
||||
unpacked = tryUnpackData();
|
||||
}
|
||||
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
bool DecodedText::tryUnpackCompound(){
|
||||
QString m = message().trimmed();
|
||||
|
||||
// directed calls will always be 12+ chars and contain no spaces.
|
||||
if(m.length() < 12 || m.contains(' ')){
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList parts = Varicode::unpackCompoundMessage(m, nullptr);
|
||||
|
||||
if(parts.isEmpty() || parts.length() < 2){
|
||||
return false;
|
||||
}
|
||||
|
||||
compound_ = QString("%1/%2").arg(parts.at(0), parts.at(1));
|
||||
message_ = QString("%1: ").arg(compound_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodedText::tryUnpackDirected(){
|
||||
QString m = message().trimmed();
|
||||
|
||||
// directed calls will always be 12+ chars and contain no spaces.
|
||||
if(m.length() < 12 || m.contains(' ')){
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList parts = Varicode::unpackDirectedMessage(m);
|
||||
|
||||
if(parts.isEmpty()){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(parts.length() == 3){
|
||||
// replace it with the correct unpacked (directed)
|
||||
message_ = QString("%1: %2%3 ").arg(parts.at(0), parts.at(1), parts.at(2));
|
||||
} else if(parts.length() == 4){
|
||||
// replace it with the correct unpacked (directed numeric)
|
||||
message_ = QString("%1: %2%3 %4 ").arg(parts.at(0), parts.at(1), parts.at(2), parts.at(3));
|
||||
} else {
|
||||
// replace it with the correct unpacked (freetext)
|
||||
message_ = QString(parts.join(""));
|
||||
}
|
||||
|
||||
directed_ = parts;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodedText::tryUnpackData(){
|
||||
QString m = message().trimmed();
|
||||
|
||||
// data frames calls will always be 12+ chars and contain no spaces.
|
||||
if(m.length() < 12 || m.contains(' ')){
|
||||
return false;
|
||||
}
|
||||
|
||||
QString data = Varicode::unpackDataMessage(m);
|
||||
|
||||
if(data.isEmpty()){
|
||||
return false;
|
||||
}
|
||||
|
||||
message_ = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList DecodedText::messageWords () const
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#define DECODEDTEXT_H
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
|
||||
|
||||
@@ -30,15 +31,28 @@ class DecodedText
|
||||
{
|
||||
public:
|
||||
explicit DecodedText (QString const& message, bool, QString const& my_grid);
|
||||
explicit DecodedText (QString const& ft8callmessage);
|
||||
|
||||
QString string() const { return string_; };
|
||||
bool tryUnpack();
|
||||
bool tryUnpackCompound();
|
||||
bool tryUnpackDirected();
|
||||
bool tryUnpackData();
|
||||
|
||||
QString compoundCall() const { return compound_; }
|
||||
bool isCompoundMessage() const { return !compound_.isEmpty(); }
|
||||
|
||||
QStringList directedMessage() const { return directed_; }
|
||||
bool isDirectedMessage() const { return !directed_.isEmpty() && directed_.length() > 2; }
|
||||
|
||||
QString string() const { return string_; }
|
||||
QString message() const { return message_; }
|
||||
QStringList messageWords () const;
|
||||
int indexOf(QString s) const { return string_.indexOf(s); };
|
||||
int indexOf(QString s, int i) const { return string_.indexOf(s,i); };
|
||||
QString mid(int f, int t) const { return string_.mid(f,t); };
|
||||
QString left(int i) const { return string_.left(i); };
|
||||
int indexOf(QString s) const { return string_.indexOf(s); }
|
||||
int indexOf(QString s, int i) const { return string_.indexOf(s,i); }
|
||||
QString mid(int f, int t) const { return string_.mid(f,t); }
|
||||
QString left(int i) const { return string_.left(i); }
|
||||
|
||||
void clear() { string_.clear(); };
|
||||
void clear() { string_.clear(); }
|
||||
|
||||
QString CQersCall() const;
|
||||
|
||||
@@ -49,6 +63,8 @@ public:
|
||||
bool isLowConfidence () const;
|
||||
int frequencyOffset() const; // hertz offset from the tuned dial or rx frequency, aka audio frequency
|
||||
int snr() const;
|
||||
bool hasBits() const { return !string_.right(5).trimmed().isEmpty(); }
|
||||
int bits() const { return string_.right(5).trimmed().toShort(); }
|
||||
float dt() const;
|
||||
|
||||
// find and extract any report. Returns true if this is a standard message
|
||||
@@ -75,6 +91,8 @@ private:
|
||||
column_mode = 19,
|
||||
column_qsoText = 22 };
|
||||
|
||||
QString compound_;
|
||||
QStringList directed_;
|
||||
QString string_;
|
||||
int padding_;
|
||||
bool contest_mode_;
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
Here are the "displayWidgets()" strings for WSJT-X modes
|
||||
|
||||
1 2 3
|
||||
012345678901234567890123456789012
|
||||
----------------------------------------------
|
||||
JT4 111010000000111000110000000000000
|
||||
JT4/VHF 111110010010111110111100000000000
|
||||
JT9 111010000000111000010000000000001
|
||||
JT9/VHF 111110101000111110010000000000000
|
||||
JT9+JT65 111010000001111000010000000000001
|
||||
JT65 111010000000111000010000000000001
|
||||
JT65/VHF 111110010000111110101100010000000
|
||||
QRA64 111110010110111110000000001000000
|
||||
ISCAT 100111000000000110000000000000000
|
||||
MSK144 101111110100000000010001000010000
|
||||
WSPR 000000000000000001010000000000000
|
||||
Echo 000000000000000000000010000000000
|
||||
FCal 001101000000000000000000000001000
|
||||
FT8 111010000100111000010000100100001
|
||||
FT8/VHF 111010000100111000010000100110001
|
||||
FT8/Fox 111010000100111000010000000000100
|
||||
FT8/Hound 111010000100111000010000000000110
|
||||
----------------------------------------------
|
||||
1 2 3
|
||||
012345678901234567890123456789012
|
||||
|
||||
----------------------------------------------
|
||||
Mapping of column numbers to widgets
|
||||
----------------------------------------------
|
||||
0. txFirstCheckbox
|
||||
1. TxFreqSpinBox
|
||||
2. RxFreqSpinBox
|
||||
3. sbFtol
|
||||
4. rptSpinBox
|
||||
5. sbTR
|
||||
6. sbCQTxFreq, cbCQTx
|
||||
7. cbShMsgs
|
||||
8. cbFast9
|
||||
9. cbAutoSeq
|
||||
10. cbTx6
|
||||
11. pbTxMode
|
||||
12. pbR2T
|
||||
13. pbT2R
|
||||
14. cbHoldTxFreq
|
||||
15. sbSubmode
|
||||
16. syncSpinBox
|
||||
17. WSPR_Controls_Widget
|
||||
18. ClrAvgButton
|
||||
19. Fast/Normal/Deep
|
||||
20. Include Avg
|
||||
21. Include Deep Search
|
||||
22. Echo Graph
|
||||
23. cbSWL
|
||||
24. AP FT8
|
||||
25. AP JT65
|
||||
26. AP DX Call
|
||||
27. cbFirst
|
||||
28. cbVHFcontest
|
||||
29. measure_check_box
|
||||
30. labDXped
|
||||
31. cbRxAll
|
||||
32. cbCQonly
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "displaytext.h"
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include <QMouseEvent>
|
||||
#include <QDateTime>
|
||||
#include <QTextCharFormat>
|
||||
@@ -121,7 +121,6 @@ QString DisplayText::appendDXCCWorkedB4(QString message, QString const& callsign
|
||||
if(!call.contains(QRegExp("[0-9]|[A-Z]"))) return message;
|
||||
|
||||
logBook.match(/*in*/call,/*out*/countryName,callWorkedBefore,countryWorkedBefore);
|
||||
|
||||
message = message.trimmed ();
|
||||
QString appendage;
|
||||
if (!countryWorkedBefore) // therefore not worked call either
|
||||
@@ -143,25 +142,32 @@ QString DisplayText::appendDXCCWorkedB4(QString message, QString const& callsign
|
||||
}
|
||||
}
|
||||
|
||||
int i1=countryName.indexOf(";");
|
||||
if(m_bPrincipalPrefix) {
|
||||
int i2=countryName.lastIndexOf(";");
|
||||
if(i1>0) countryName=countryName.mid(i1+2,i2-i1-2);
|
||||
} else {
|
||||
if(i1>0) countryName=countryName.mid(0,i1);
|
||||
// do some obvious abbreviations
|
||||
countryName.replace ("Islands", "Is.");
|
||||
countryName.replace ("Island", "Is.");
|
||||
countryName.replace ("North ", "N. ");
|
||||
countryName.replace ("Northern ", "N. ");
|
||||
countryName.replace ("South ", "S. ");
|
||||
countryName.replace ("East ", "E. ");
|
||||
countryName.replace ("Eastern ", "E. ");
|
||||
countryName.replace ("West ", "W. ");
|
||||
countryName.replace ("Western ", "W. ");
|
||||
countryName.replace ("Central ", "C. ");
|
||||
countryName.replace (" and ", " & ");
|
||||
countryName.replace ("Republic", "Rep.");
|
||||
countryName.replace ("United States", "U.S.A.");
|
||||
countryName.replace ("Fed. Rep. of ", "");
|
||||
countryName.replace ("French ", "Fr.");
|
||||
countryName.replace ("Asiatic", "AS");
|
||||
countryName.replace ("European", "EU");
|
||||
countryName.replace ("African", "AF");
|
||||
countryName.replace ("Islands", "Is.");
|
||||
countryName.replace ("Island", "Is.");
|
||||
countryName.replace ("North ", "N. ");
|
||||
countryName.replace ("Northern ", "N. ");
|
||||
countryName.replace ("South ", "S. ");
|
||||
countryName.replace ("East ", "E. ");
|
||||
countryName.replace ("Eastern ", "E. ");
|
||||
countryName.replace ("West ", "W. ");
|
||||
countryName.replace ("Western ", "W. ");
|
||||
countryName.replace ("Central ", "C. ");
|
||||
countryName.replace (" and ", " & ");
|
||||
countryName.replace ("Republic", "Rep.");
|
||||
countryName.replace ("United States", "U.S.A.");
|
||||
countryName.replace ("Fed. Rep. of ", "");
|
||||
countryName.replace ("French ", "Fr.");
|
||||
countryName.replace ("Asiatic", "AS");
|
||||
countryName.replace ("European", "EU");
|
||||
countryName.replace ("African", "AF");
|
||||
}
|
||||
|
||||
appendage += countryName;
|
||||
|
||||
@@ -181,9 +187,11 @@ QString DisplayText::appendDXCCWorkedB4(QString message, QString const& callsign
|
||||
void DisplayText::displayDecodedText(DecodedText const& decodedText, QString const& myCall,
|
||||
bool displayDXCCEntity, LogBook const& logBook,
|
||||
QColor color_CQ, QColor color_MyCall,
|
||||
QColor color_DXCC, QColor color_NewCall)
|
||||
QColor color_DXCC, QColor color_NewCall, bool ppfx,
|
||||
bool bCQonly)
|
||||
{
|
||||
QColor bg {Qt::white};
|
||||
m_bPrincipalPrefix=ppfx;
|
||||
QColor bg {Qt::transparent};
|
||||
bool CQcall = false;
|
||||
if (decodedText.string ().contains (" CQ ")
|
||||
|| decodedText.string ().contains (" CQDX ")
|
||||
@@ -192,6 +200,7 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con
|
||||
CQcall = true;
|
||||
bg = color_CQ;
|
||||
}
|
||||
if(bCQonly and !CQcall) return;
|
||||
if (myCall != "" and (
|
||||
decodedText.indexOf (" " + myCall + " ") >= 0
|
||||
or decodedText.indexOf (" " + myCall + "/") >= 0
|
||||
@@ -225,6 +234,9 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx
|
||||
if(bFastMode or modeTx=="FT8") {
|
||||
t = QDateTime::currentDateTimeUtc().toString("hhmmss") + \
|
||||
" Tx " + t2 + t1 + text;
|
||||
} else if(modeTx.mid(0,6)=="FT8fox") {
|
||||
t = QDateTime::currentDateTimeUtc().toString("hhmmss") + \
|
||||
" Tx" + modeTx.mid(7) + " " + text;
|
||||
} else {
|
||||
t = QDateTime::currentDateTimeUtc().toString("hhmm") + \
|
||||
" Tx " + t2 + t1 + text;
|
||||
@@ -237,3 +249,8 @@ void DisplayText::displayQSY(QString text)
|
||||
QString t = QDateTime::currentDateTimeUtc().toString("hhmmss") + " " + text;
|
||||
appendText (t, "hotpink");
|
||||
}
|
||||
|
||||
void DisplayText::displayFoxToBeCalled(QString t, QColor bg)
|
||||
{
|
||||
appendText(t,bg);
|
||||
}
|
||||
|
||||
@@ -20,11 +20,12 @@ public:
|
||||
void setContentFont (QFont const&);
|
||||
void insertLineSpacer(QString const&);
|
||||
void displayDecodedText(DecodedText const& decodedText, QString const& myCall, bool displayDXCCEntity,
|
||||
LogBook const& logBook, QColor color_CQ, QColor color_MyCall,
|
||||
QColor color_DXCC, QColor color_NewCall);
|
||||
LogBook const& logBook, QColor color_CQ, QColor color_MyCall,
|
||||
QColor color_DXCC, QColor color_NewCall, bool ppfx, bool bCQonly=false);
|
||||
void displayTransmittedText(QString text, QString modeTx, qint32 txFreq,
|
||||
QColor color_TxMsg, bool bFastMode);
|
||||
void displayQSY(QString text);
|
||||
void displayFoxToBeCalled(QString t, QColor bg);
|
||||
|
||||
Q_SIGNAL void selectCallsign (Qt::KeyboardModifiers);
|
||||
Q_SIGNAL void erased ();
|
||||
@@ -36,6 +37,7 @@ protected:
|
||||
void mouseDoubleClickEvent(QMouseEvent *e);
|
||||
|
||||
private:
|
||||
bool m_bPrincipalPrefix;
|
||||
QString appendDXCCWorkedB4(QString message, QString const& callsign, QColor * bg, LogBook const& logBook,
|
||||
QColor color_CQ, QColor color_DXCC, QColor color_NewCall);
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ set (UG_IMGS
|
||||
images/decode-menu.png
|
||||
images/decodes.png
|
||||
images/download_samples.png
|
||||
images/echo_144.png
|
||||
images/file-menu.png
|
||||
images/FreqCal.png
|
||||
images/FreqCal_Graph.png
|
||||
|
||||
@@ -23,7 +23,7 @@ the following copyright notice prominently:
|
||||
*The algorithms, source code, look-and-feel of _{prog}_ and related
|
||||
programs, and protocol specifications for the modes FSK441, FT8, JT4,
|
||||
JT6M, JT9, JT65, JTMS, QRA64, ISCAT, and MSK144 are Copyright (C)
|
||||
2001-2017 by one or more of the following authors: Joseph Taylor,
|
||||
2001-2018 by one or more of the following authors: Joseph Taylor,
|
||||
K1JT; Bill Somerville, G4WJS; Steven Franke, K9AN; Nico Palermo,
|
||||
IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR;
|
||||
Philip Karn, KA9Q; and other members of the WSJT Development Group.*
|
||||
|
||||
@@ -68,6 +68,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
||||
:fmt_k5cm: http://www.k5cm.com/[FMT Event Info]
|
||||
:fmt_wspr: http://www.physics.princeton.edu/pulsar/K1JT/FMT_User.pdf[Accurate Frequency Measurements with your WSPR Setup]
|
||||
:ft8_tips: http://www.physics.princeton.edu/pulsar/K1JT/FT8_Operating_Tips.pdf[here]
|
||||
:ft8_DXped: http://physics.princeton.edu/pulsar/k1jt/FT8_DXpedition_Mode.pdf[FT8 DXpedition Mode]
|
||||
:gnu_gpl: http://www.gnu.org/licenses/gpl-3.0.txt[GNU General Public License]
|
||||
:homepage: http://physics.princeton.edu/pulsar/K1JT/[WSJT Home Page]
|
||||
:hrd: http://www.hrdsoftwarellc.com/[Ham Radio Deluxe]
|
||||
@@ -104,7 +105,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
||||
:jtsdk_qt: http://physics.princeton.edu/pulsar/K1JT/JTSDK-QT.exe[Download]
|
||||
:jtsdk_vcredist: http://sourceforge.net/projects/jtsdk/files/win32/2.0.0/base/contrib/vcredist_x86.exe/download[Download]
|
||||
:nh6z: http://www.nh6z.net/Amatuer_Radio_Station_NH6Z/Other_Peoples_Software.html[here]
|
||||
:omnirig: http://www.dxatlas.com/OmniRig/Files/OmniRig.zip[Download]
|
||||
:omnirig: http://www.dxatlas.com/OmniRig/Files/OmniRig.zip[Omni-Rig]
|
||||
:osx: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-Darwin.dmg[wsjtx-{VERSION}-Darwin.dmg]
|
||||
:QRA64_EME: http://physics.princeton.edu/pulsar/K1JT/QRA64_EME.pdf[QRA64 for microwave EME]
|
||||
:svn: http://subversion.apache.org/packages.html#windows[Subversion]
|
||||
|
||||
@@ -56,7 +56,8 @@ and reception in ISCAT, MSK144, and the fast JT9 modes.
|
||||
MSK144 and the fast JT9 submodes you can activate the spinner control
|
||||
*Tx CQ nnn* by checking the box to its right. The program will then
|
||||
generate something like `CQ nnn K1ABC FN42` for your CQ message, where
|
||||
`nnn` is the kHz portion of your current operating frequency. Your CQ
|
||||
`nnn` is the kHz portion of your current operating frequency,
|
||||
in the range 010 to 999. Your CQ
|
||||
message *Tx6* will then be transmitted at the calling frequency
|
||||
selected in the *Tx CQ nnn* spinner control. All other messages will
|
||||
be transmitted at your current operating frequency. On reception,
|
||||
@@ -67,7 +68,7 @@ specified response frequency.
|
||||
* Checkboxes at bottom center of the main window control special
|
||||
features for particular operating modes:
|
||||
|
||||
** *Sh* enables shorthand messages in JT4, JT65, and MSK144 modes
|
||||
** *Sh* enables shorthand messages in JT4, JT65, QRA64 and MSK144 modes
|
||||
|
||||
** *Fast* enables fast JT9 submodes
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
// Status=review
|
||||
The following buttons appear just under the decoded text windows on
|
||||
The following controls appear just under the decoded text windows on
|
||||
the main screen:
|
||||
|
||||
//.Main UI
|
||||
image::main-ui-controls.png[align="left",width=650,alt="Main UI Controls"]
|
||||
image::main-ui-controls.png[align="center",width=650,alt="Main UI Controls"]
|
||||
|
||||
* When *CQ only* is checked, only messages from stations calling CQ will
|
||||
be displayed in the left text panel.
|
||||
|
||||
* *Log QSO* raises a dialog window pre-filled with known information
|
||||
about a QSO you have nearly completed. You can edit or add to this
|
||||
@@ -62,3 +65,5 @@ Toggle the button a second time or click *Halt Tx* to terminate the
|
||||
*Tune* process. Note that activating *Tune* interrupts a receive
|
||||
sequence and will prevent decoding during that sequence.
|
||||
|
||||
* Uncheck the box *Menus* to make the top-of-window menus disappear,
|
||||
leaving more vertical space for decoded messages.
|
||||
@@ -1,9 +1,10 @@
|
||||
=== AP Decoding
|
||||
|
||||
The _WSJT-X_ decoders for QRA64 and FT8 include optional procedures
|
||||
that use naturally accumulating information during a minimal QSO.
|
||||
This _a priori_ (AP) information increases sensitivity of the decoder
|
||||
by up to 4 dB, at the cost of a slightly higher rate of false decodes.
|
||||
The _WSJT-X_ decoders for JT65, QRA64, and FT8 include optional
|
||||
procedures that use naturally accumulating information during a
|
||||
minimal QSO. This _a priori_ (AP) information increases sensitivity
|
||||
of the decoder by up to 4 dB, at the cost of a slightly higher rate of
|
||||
false decodes.
|
||||
|
||||
For example: when you decide to answer a CQ, you already know your own
|
||||
callsign and that of your potential QSO partner. The software
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
////
|
||||
Questions:
|
||||
Should be short one liners ending with ?::
|
||||
Should be short one liners (in the .adoc file) ending with ?::
|
||||
If your question is too long for one line, consider multiple questions or rephrase
|
||||
|
||||
Answers:
|
||||
@@ -47,11 +47,11 @@ location for each instance of _WSJT-X_.
|
||||
wsjtx --rig-name=TS2000
|
||||
wsjtx --rig-name=FT847
|
||||
|
||||
When setting up rig control through _OmniRig_, something goes wrong when I click *Test CAT*. What can I do about it?::
|
||||
Rig control through _OmniRig_ seems to fail when I click *Test CAT*. What can I do about it?::
|
||||
|
||||
_OmniRig_ apparently has a bug that appears when you click *Test CAT*.
|
||||
Forget using *Test CAT* and just click *OK*. _OmniRig_ then behaves
|
||||
normally.
|
||||
_Omni-Rig_ apparently has a bug that appears when you click *Test
|
||||
CAT*. Forget using *Test CAT* and just click *OK*. _Omni-Rig_ then
|
||||
behaves normally.
|
||||
|
||||
I am using _WSJT-X_ with _Ham Radio Deluxe_. All seems well until I start HRD Logbook or DM780 running in parallel; then CAT control becomes unreliable.::
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
@@ -1,4 +1,4 @@
|
||||
// These instructions are up-to-date for WSJT-X v1.8
|
||||
// These instructions are up-to-date for WSJT-X v1.9
|
||||
|
||||
*OS X 10.9* and later: Download the file {osx} to your desktop,
|
||||
double-click on it and consult its `ReadMe` file for important
|
||||
@@ -6,13 +6,18 @@ installation notes.
|
||||
|
||||
If you have already installed a previous version, you can retain it by
|
||||
changing its name in the *Applications* folder (say, from _WSJT-X_ to
|
||||
_WSJT-X_1.7_). You can then proceed to the installation phase.
|
||||
_WSJT-X_1.8_). You can then proceed to the installation phase.
|
||||
|
||||
Take note also of the following:
|
||||
|
||||
* Use the Mac's *Audio MIDI Setup* utility to configure your sound
|
||||
card for 48000 Hz, two-channel, 16-bit format.
|
||||
|
||||
NOTE: If you are using macOS with an external audio device and find
|
||||
that Tx audio spontaneously switches to the motherboard sound device
|
||||
after a few transmissions, try setting the sample rate to 44100 Hz
|
||||
rather than the otherwise recommended 48000 Hz.
|
||||
|
||||
* Use *System Preferences* to select an external time source to keep
|
||||
your system clock synchronized to UTC.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ K1**JT**,`" while the suffix "`-X`" indicates that _WSJT-X_ started as
|
||||
an extended and experimental branch of the program
|
||||
_WSJT_.
|
||||
|
||||
_WSJT-X_ Version 1.8 offers nine different protocols or modes: *FT8*,
|
||||
_WSJT-X_ Version 1.9 offers nine different protocols or modes: *FT8*,
|
||||
*JT4*, *JT9*, *JT65*, *QRA64*, *ISCAT*, *MSK144*, *WSPR*, and *Echo*.
|
||||
The first five are designed for making reliable QSOs under extreme
|
||||
weak-signal conditions. They use nearly identical message structure
|
||||
@@ -62,3 +62,13 @@ tracking for EME QSOs and Echo testing. The program runs equally well
|
||||
on Windows, Macintosh, and Linux systems, and installation packages
|
||||
are available for all three platforms.
|
||||
|
||||
*Version Numbers:* _WSJT-X_ release numbers have major, minor, and
|
||||
patch numbers separated by periods: for example, _WSJT-X_ Version
|
||||
1.9.0. Temporary "`beta`" release candidates are sometimes made in
|
||||
advance of a new general-availability release, in order to obtain user
|
||||
feedback. For example, version 1.9.0-rc1, 1.9.0-rc2, etc., would
|
||||
be beta releases leading up to the final release of v1.9.0.
|
||||
Release candidates should be used _only_ during a short testing
|
||||
period. They carry an implied obligation to provide feedback to the
|
||||
program development group. Candidate releases should not be used on
|
||||
the air after a full release with the same number has been made.
|
||||
|
||||
@@ -41,7 +41,7 @@ are desirable. Double-click the *Tx1* control under _Now_ or _Next_
|
||||
to toggle use of the Tx2 message rather than Tx1 to start a QSO.
|
||||
Similarly, double-click the *Tx4* control to toggle between sending
|
||||
`RRR` and `RR73` in that message. The `RR73` message should be used
|
||||
only if you are reasonably confident that no repititions will be
|
||||
only if you are reasonably confident that no repetitions will be
|
||||
required.
|
||||
|
||||
=== Free-Text Messages
|
||||
@@ -57,12 +57,14 @@ or rag-chewing.
|
||||
|
||||
=== Auto-Sequencing
|
||||
|
||||
The slow modes JT4, JT9, JT65, and QRA64 allow nearly 10 seconds at
|
||||
the end of each one-minute receiving sequence -- enough time for you
|
||||
to inspect decoded messages and decide how to reply. The 15-second
|
||||
T/R cycles of FT8 allow only about two seconds for this task, which is
|
||||
often not enough. For this reason a basic auto-sequencing feature is
|
||||
offered. Check *Auto Seq* on the main window to enable this feature:
|
||||
The 15-second T/R cycles of FT8 allow only about two seconds to inspect
|
||||
decoded messages and decide how to reply, which is often not enough.
|
||||
The slow modes JT4, JT9, JT65, and QRA64 allow nearly 10 seconds
|
||||
for this task, but operators may find that this is still insufficient
|
||||
when workload is high, especially on EME. For these reasons a basic
|
||||
auto-sequencing feature is offered.
|
||||
|
||||
Check *Auto Seq* on the main window to enable this feature:
|
||||
|
||||
image::auto-seq.png[align="center",alt="AutoSeq"]
|
||||
|
||||
|
||||
@@ -1,31 +1,32 @@
|
||||
=== New in Version 1.8
|
||||
=== New in Version 1.9
|
||||
|
||||
For quick reference, here's a short list of features and capabilities
|
||||
added to _WSJT-X_ since Version 1.7.0:
|
||||
added to _WSJT-X_ since Version 1.8.0:
|
||||
|
||||
- New mode *FT8* designed for fast QSOs
|
||||
- New *FT8 DXpedition Mode* to facilitate high QSO rates in pileup
|
||||
situations
|
||||
|
||||
- New tool *FreqCal* for accurate frequency calibration of your radio
|
||||
- Decoding improvements for JT65 mode, including _a priori_ (AP)
|
||||
decoding when VHF/UHF/Microwave features are enabled
|
||||
|
||||
- Improved decoding performance for JT65, QRA64, and MSK144
|
||||
- Optional Auto-Sequencing in JT4, JT9, and JT65 when VHF/UHF/Microwave features are enabled
|
||||
|
||||
- *SWL* option for third-party decoding short-format MSK144 messages
|
||||
- Better suppression of low-confidence false decodes generated by AP
|
||||
decoding in FT8 mode
|
||||
|
||||
- Experimental phase equalization for MSK144
|
||||
|
||||
- Options to minimize screen space used by *Main* and *Wide Graph*
|
||||
windows
|
||||
|
||||
- New set of suggested default frequencies specific to the three IARU
|
||||
regions
|
||||
- Improved decoding performance for WSPR mode, especially effective at LF and MF
|
||||
|
||||
- Enhanced scheme for managing table of suggested default operating
|
||||
frequencies
|
||||
- Minor adjustments to auto-sequencing behavior
|
||||
|
||||
- Improved CAT control for many radios, including those controlled
|
||||
through Commander or OmniRig
|
||||
- More flexible Doppler control features for EME
|
||||
|
||||
- Bug fixes and minor tweaks to user interface
|
||||
- Improved waterfall sensitivity for very weak signals
|
||||
|
||||
- Automatic real-time forwarding of logged information to _N1MM Logger+_
|
||||
|
||||
- Expanded and improved UDP messages sent to companion programs
|
||||
|
||||
- Bug fixes and other minor tweaks to user interface
|
||||
|
||||
=== Documentation Conventions
|
||||
|
||||
|
||||
@@ -9,9 +9,11 @@ additional bit flags a message containing arbitrary alphanumeric text,
|
||||
up to 13 characters. Special cases allow other information such as
|
||||
add-on callsign prefixes (e.g., ZA/K1ABC) or suffixes (e.g., K1ABC/P)
|
||||
to be encoded. The basic aim is to compress the most common messages
|
||||
used for minimally valid QSOs into a fixed 72-bit length. Information
|
||||
payloads in FT8 include 3 additional bits (75 bits total), with
|
||||
definitions yet to be defined.
|
||||
used for minimally valid QSOs into a fixed 72-bit length. The
|
||||
information payload in FT8 includes 3 additional bits (75 bits total).
|
||||
One of the added bits is used to flag special messages used by the
|
||||
DXpedition station in FT8 DXpedition Mode. Uses for the remaining two
|
||||
bits are yet to be defined.
|
||||
|
||||
A standard amateur callsign consists of a one- or two-character
|
||||
prefix, at least one of which must be a letter, followed by a digit
|
||||
@@ -166,6 +168,51 @@ QRA64 presently offers no message averaging capability, though that
|
||||
feature may be added. In early tests, many EME QSOs were made using
|
||||
submodes QRA64A-E on bands from 144 MHz to 24 GHz.
|
||||
|
||||
[[WSPR_PROTOCOL]]
|
||||
==== WSPR
|
||||
|
||||
WSPR is designed for probing potential radio propagation paths using
|
||||
low power beacon-like transmissions. WSPR signals convey a callsign,
|
||||
Maidenhead grid locator, and power level using a compressed data
|
||||
format with strong forward error correction and narrow-band 4-FSK
|
||||
modulation. The protocol is effective at signal-to-noise ratios as low
|
||||
as –31 dB in a 2500 Hz bandwidth.
|
||||
|
||||
WSPR messages can have one of three possible formats illustrated by
|
||||
the following examples:
|
||||
|
||||
- Type 1: K1ABC FN42 37
|
||||
- Type 2: PJ4/K1ABC 37
|
||||
- Type 3: <PJ4/K1ABC> FK52UD 37
|
||||
|
||||
Type 1 messages contain a standard callsign, a 4-character Maidenhead
|
||||
grid locator, and power level in dBm. Type 2 messages omit the grid
|
||||
locator but include a compound callsign, while type 3 messages replace
|
||||
the callsign with a 15-bit hash code and include a 6-character locator
|
||||
as well as the power level. Lossless compression techniques squeeze
|
||||
all three message types into exactly 50 bits of user
|
||||
information. Standard callsigns require 28 bits and 4-character grid
|
||||
locators 15 bits. In Type 1 messages, the remaining 7 bits convey the
|
||||
power level. In message types 2 and 3 these 7 bits convey power level
|
||||
along with an extension or re-definition of fields normally used for
|
||||
callsign and locator. Together, these compression techniques amount to
|
||||
“source encoding” the user message into the smallest possible number
|
||||
of bits.
|
||||
|
||||
WSPR uses a convolutional code with constraint length K=32 and rate
|
||||
r=1/2. Convolution extends the 50 user bits into a total of (50 + K –
|
||||
1) × 2 = 162 one-bit symbols. Interleaving is applied to scramble the
|
||||
order of these symbols, thereby minimizing the effect of short bursts
|
||||
of errors in reception that might be caused by fading or interference.
|
||||
The data symbols are combined with an equal number of synchronizing
|
||||
symbols, a pseudo-random pattern of 0’s and 1’s. The 2-bit
|
||||
combination for each symbol is the quantity that determines which of
|
||||
four possible tones to transmit in any particular symbol
|
||||
interval. Data information is taken as the most significant bit, sync
|
||||
information the least significant. Thus, on a 0 – 3 scale, the tone
|
||||
for a given symbol is twice the value (0 or 1) of the data bit, plus
|
||||
the sync bit.
|
||||
|
||||
[[SLOW_SUMMARY]]
|
||||
==== Summary
|
||||
|
||||
|
||||
@@ -31,12 +31,14 @@ IMPORTANT: For the health of your T/R relays and external
|
||||
preamplifier, we strongly recommend using a hardware sequencer and
|
||||
testing to make sure that sequencing is correct.
|
||||
|
||||
- Check *FT8 and MSK144: NA VHF Contest Mode* to enable generation and
|
||||
auto-sequencing of messages using four-character grid locators in
|
||||
place of signal reports, as required for most North American VHF
|
||||
contests.
|
||||
- Check *x 2 Tone spacing* or *x 4 Tone spacing* to generate Tx audio
|
||||
with twice or four times the normal tone spacing. This feature is
|
||||
intended for use with specialized LF/MF transmitters that divide
|
||||
generated frequencies by 2 or 4 as part of the transmission process.
|
||||
|
||||
_FT8 DXpedition Mode_
|
||||
|
||||
- Check *Fox* if you are a DXpedition station operating in FT8
|
||||
DXpedition Mode. Check *Hound* if you wish to make QSOs with such a
|
||||
Fox. Be sure to read the operating instructions for {ft8_DXped}.
|
||||
|
||||
- Check *x 2 Tone spacing* to generate Tx audio with twice the normal
|
||||
tone spacing. This feature is intended for use with specialized LF/MF
|
||||
transmitters that divide the audio waveform by 2 before further
|
||||
processing.
|
||||
|
||||
@@ -11,7 +11,7 @@ your radio, select the *Radio* tab.
|
||||
|
||||
- Alternatively, if you have configured your station for control by
|
||||
*DX Lab Suite Commander*, *Ham Radio Deluxe*, *Hamlib NET rigctl*, or
|
||||
*OmniRig*, you may select one of those program names from the *Rig*
|
||||
*Omni-Rig*, you may select one of those program names from the *Rig*
|
||||
list. In these cases the entry field immediately under _CAT Control_
|
||||
will be relabeled as *Network Server*. Leave this field blank to
|
||||
access the default instance of your control program, running on the
|
||||
@@ -19,9 +19,9 @@ same computer. If the control program runs on a different computer
|
||||
and/or port, specify it here. Hover the mouse pointer over the entry
|
||||
field to see the required formatting details.
|
||||
|
||||
- Select *OmniRig Rig 1* or *OmniRig Rig 2* to connect to an _OmniRig_
|
||||
server running on the same computer. Note that _OmniRig_ is available
|
||||
only under Windows.
|
||||
- Select *Omni-Rig Rig 1* or *Omni-Rig Rig 2* to connect to an
|
||||
_Omni-Rig_ server running on the same computer. Note that _Omni-Rig_
|
||||
is available only under Windows.
|
||||
|
||||
- Set *Poll Interval* to the desired interval for _WSJT-X_ to query
|
||||
your radio. For most radios a small number (say, 1 – 3 s) is
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
[[FIG_CONFIG_RPT]]
|
||||
image::reporting.png[align="center",alt="Reporting Screen"]
|
||||
|
||||
- _Logging_: Choose any desired options from this group.
|
||||
- _Logging_: Choose any desired options from this group. Operators in
|
||||
a multi-operator station may wish to enter their home callsign as *Op
|
||||
Call*.
|
||||
|
||||
- _Network Services_: Check *Enable PSK Reporter Spotting* to send
|
||||
reception reports to the {pskreporter} mapping facility.
|
||||
@@ -13,3 +15,7 @@ updates from _WSJT-X_. Cooperating applications like _JTAlert_ use
|
||||
this feature to obtain information about a running _WSJT-X_ instance.
|
||||
If you are using _JTAlert_, be sure to check the three boxes at lower
|
||||
right.
|
||||
|
||||
- _N1MM Logger+ Broadcasts_: To send information on logged QSOs
|
||||
directly to _N1MM Logger+_, check the box and enter the IP address and
|
||||
port number for _N1MM_.
|
||||
@@ -40,8 +40,8 @@ try clicking with the mouse on the decoded text lines and on the
|
||||
waterfall spectral display. You should be able to confirm the
|
||||
following behavior:
|
||||
|
||||
- Double-click on either of the decoded lines highlighted in
|
||||
green. This action produces the following results:
|
||||
- Click or double-click on either of the decoded lines highlighted in
|
||||
green. These actions produce the following results:
|
||||
|
||||
** Callsign and locator of a station calling CQ are copied to the *DX
|
||||
Call* and *DX Grid* entry fields.
|
||||
@@ -57,14 +57,16 @@ station.
|
||||
** The *Gen Msg* ("`generated message`") radio button at bottom right
|
||||
of the main window is selected.
|
||||
|
||||
** If you had checked *Double-click on call sets Tx Enable* on the
|
||||
*Setup* menu, *Enable Tx* would be activated and a transmission would
|
||||
start automatically at the proper time.
|
||||
** *Double-click* does all of the above and also activates *Enable Tx*
|
||||
so that a transmission will start automatically at the proper time.
|
||||
|
||||
** You can modify the double-click behavior by holding down the
|
||||
*Shift* key to move only the Tx frequency or the *Ctrl* key to move
|
||||
both Rx and Tx frequencies.
|
||||
|
||||
NOTE: You can prevent your Tx frequency from being changed by checking the
|
||||
box *Hold Tx Freq*.
|
||||
|
||||
- Double-click on the decoded message `K1JT N5KDV EM41`, highlighted
|
||||
in red. Results will be similar to those in the previous step. The Tx
|
||||
frequency (red marker) is not moved unless *Shift* or *Ctrl* is held
|
||||
@@ -72,13 +74,6 @@ down. Messages highlighted in red are usually in response to your own
|
||||
CQ or from a tail-ender, and you probably want your Tx frequency to
|
||||
stay where it was.
|
||||
|
||||
NOTE: Double-clicking on decoded messages can be defaulted to simplex
|
||||
operation by checking *Double click on call sets Tx and Rx freqs* on
|
||||
the *Settings -> General* tab.
|
||||
|
||||
NOTE: You can prevent your Tx frequency from being changed by checking the
|
||||
box *Lock Tx Freq*.
|
||||
|
||||
- Click somewhere on the waterfall to set Rx frequency (green marker
|
||||
on waterfall scale).
|
||||
|
||||
|
||||
@@ -45,16 +45,28 @@ when double-clicking.
|
||||
|
||||
NOTE: To avoid QRM from competing callers, it is frequently desirable
|
||||
to answer a CQ on a different frequency from that of the CQing
|
||||
station. Choose a Tx frequency that appears to be not in use. The
|
||||
same is true when you tail-end another QSO.
|
||||
station. The same is true when you tail-end another QSO. Choose a Tx
|
||||
frequency that appears to be not in use.
|
||||
|
||||
NOTE: The FT8 decoder can often copy several overlapping signals at
|
||||
nearly the same frequency. Keyboard shortcuts *Shift+F11* and
|
||||
*Shift+F12* provide an easy way to move your Tx frequency down or up
|
||||
in 60 Hz steps.
|
||||
NOTE: Keyboard shortcuts *Shift+F11* and *Shift+F12* provide an easy
|
||||
way to move your Tx frequency down or up in 60 Hz steps.
|
||||
|
||||
NOTE: Further helpful tips on FT8 operating procedures are available
|
||||
{ft8_tips}. Thanks to ZL2IFB!
|
||||
|
||||
.FT8 DXpedition Mode:
|
||||
|
||||
- This special operating mode enables DXpeditions to make FT8 QSOs at
|
||||
very high rates. Both stations must use _WSJT-X_ Version 1.9 or
|
||||
later. Detailed operating instructions for {ft8_DXped} are available
|
||||
online. Do not try to use DXpedition mode without reading these
|
||||
instructions carefully!
|
||||
|
||||
IMPORTANT: FT8 DXpedition mode is suitable for use only by legitimate
|
||||
DXpeditions and those attempting to work them. Do not try to use
|
||||
DXpedition mode for normal FT8 operation. Do not use it in the
|
||||
conventional FT8 subbands. And especially, do not use the
|
||||
multi-signal capability unless you are a DXpedition.
|
||||
|
||||
IMPORTANT: When finished with this Tutorial, don't forget to re-enter
|
||||
your own callsign as *My Call* on the *Settings | General* tab.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
_WSJT-X_ v1.8 suppports a number of features designed for use
|
||||
_WSJT-X_ v1.9 suppports a number of features designed for use
|
||||
on the VHF and higher bands. These features include:
|
||||
|
||||
- *FT8*, a mode designed for making fast QSOs with weak, fading
|
||||
@@ -8,6 +8,8 @@ signals
|
||||
|
||||
- *JT9* fast modes, useful for scatter propagation on VHF bands
|
||||
|
||||
- *JT65*, widely used for EME on VHF and higher bands
|
||||
|
||||
- *QRA64*, a mode for EME using a "`Q-ary Repeat Accumulate`" code,
|
||||
a low-density parity-check (LDPC) code using a 64-character symbol
|
||||
alphabet
|
||||
@@ -24,6 +26,8 @@ propagation
|
||||
- *Doppler tracking*, which becomes increasingly important for EME
|
||||
on bands above 1.2 GHz.
|
||||
|
||||
- Optional *Auto-Sequencing* in JT4, JT9, and JT65 as well as FT8 and QRA64.
|
||||
|
||||
[[VHF_SETUP]]
|
||||
=== VHF Setup
|
||||
|
||||
@@ -32,8 +36,8 @@ To activate the VHF-and-up features:
|
||||
- On the *Settings | General* tab check *Enable VHF/UHF/Microwave
|
||||
features* and *Single decode*.
|
||||
|
||||
- For EME, check *Decode at t = 52 s* to allow for extra path delay on
|
||||
received signals.
|
||||
- For EME, check *Decode after EME delay* to allow for extra path
|
||||
delay on received signals.
|
||||
|
||||
- If you will use automatic Doppler tracking and your radio accepts
|
||||
frequency-setting commands while transmitting, check *Allow Tx
|
||||
@@ -77,13 +81,16 @@ becomes visible when you check *Doppler tracking*.
|
||||
|
||||
image::Astronomical_data.png[align="center",alt="Astronomical data"]
|
||||
|
||||
Three different types of Doppler tracking are provided:
|
||||
Five different types of Doppler tracking are provided:
|
||||
|
||||
- Select *Full Doppler to DX Grid* if you know your QSO partner's locator
|
||||
and he/she will not be using any Doppler control.
|
||||
|
||||
- Select *Receive only* to enable EME Doppler tracking of your receive
|
||||
frequency to a specific locator. Your Tx frequency will remain fixed.
|
||||
- Select *Own Echo* to enable EME Doppler tracking of your receive
|
||||
frequency to your own echo frequency. Your Tx frequency will remain fixed
|
||||
and is set to the Sked frequency. This mode can be used when announcing
|
||||
your CQ call on a specific frequency and listening on your own echo
|
||||
frequency. It can also be used for echo testing with Echo mode.
|
||||
|
||||
- Select *Constant frequency on Moon* to correct for your own one-way
|
||||
Doppler shift to or from the Moon. If your QSO partner does the same
|
||||
@@ -91,6 +98,25 @@ thing, both stations will have the required Doppler compensation.
|
||||
Moreover, anyone else using this option will hear both of you
|
||||
without the need for manual frequency changes.
|
||||
|
||||
- Select *On Dx Echo* when your QSO partner is not using automated
|
||||
Doppler tracking, and announces his/her transmit frequency and listening
|
||||
on their own echo frequency. When clicked, this Doppler method will
|
||||
set your rig frequency on receive to correct for the mutual Doppler
|
||||
shift. On transmit, your rig frequency will be set so that your
|
||||
QSO partner will receive you on the same frequency as their own echo
|
||||
at the start of the QSO. As the QSO proceeds, your QSO partner will
|
||||
receive you on this starting frequency so that they do not have to
|
||||
retune their receiver as the Doppler changes. Sked frequency in this
|
||||
case is set to that announced by your QSO partner.
|
||||
|
||||
- Select *Call DX* after tuning the radio manually to find a station,
|
||||
with the Doppler mode initally set to *None*. You may be tuning the band
|
||||
looking for random stations, or to a frequency where a station has been
|
||||
seen on an SDR display. It is usually necessary to hold down the Ctrl key
|
||||
while tuning the radio. From the moment *Call DX* is pressed, your
|
||||
transmit frequency is set so that your echo will fall on the same
|
||||
frequency you (and the DX station) are listening.
|
||||
|
||||
- See <<ASTRODATA,Astronomical Data>> for details on the quantities
|
||||
displayed in this window.
|
||||
|
||||
@@ -142,8 +168,9 @@ shorthand messages for RO, RRR, and 73. These messages are always
|
||||
enabled for reception; they will be automatically generated for
|
||||
transmission if you check the shorthand message box *Sh*.
|
||||
|
||||
Be sure to check *Deep* on the *Decode* menu; you may optionally
|
||||
include *Enable averaging* and *Deep search*.
|
||||
*Deep* on the *Decode* menu will be automatically selected. You may
|
||||
optionally include *Enable averaging*, *Enable Deep search*, and
|
||||
*Enable AP*.
|
||||
|
||||
The following screen shot shows three transmissions from a 144 MHz EME
|
||||
QSO using submode JT65B and shorthand messages. Take note of the
|
||||
|
||||
@@ -29,7 +29,6 @@ private slots:
|
||||
void on_gainSlider_valueChanged(int value);
|
||||
void on_zeroSlider_valueChanged(int value);
|
||||
void on_binsPerPixelSpinBox_valueChanged(int n);
|
||||
|
||||
void on_pbColors_clicked();
|
||||
|
||||
private:
|
||||
|
||||
@@ -85,7 +85,7 @@ void FastGraph::on_greenZeroSlider_valueChanged(int value)
|
||||
ui->fastPlot->draw();
|
||||
}
|
||||
|
||||
void FastGraph::setTRperiod(int n)
|
||||
void FastGraph::setTRPeriod(int n)
|
||||
{
|
||||
m_TRperiod=n;
|
||||
ui->fastPlot->setTRperiod(m_TRperiod);
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
|
||||
void plotSpec(bool diskData, int UTCdisk);
|
||||
void saveSettings();
|
||||
void setTRperiod(int n);
|
||||
void setTRPeriod(int n);
|
||||
void setMode(QString mode);
|
||||
|
||||
signals:
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=ft8call
|
||||
Comment=Amateur Radio Weak Signal Operating
|
||||
Exec=ft8call
|
||||
Icon=wsjtx_icon
|
||||
Terminal=false
|
||||
X-MultipleArgs=false
|
||||
Type=Application
|
||||
Categories=AudioVideo;Audio;HamRadio;
|
||||
StartupNotify=true
|
||||
@@ -38,15 +38,15 @@ his locator AJ10:
|
||||
2. KH1DX K1ABC FN42, KH1DX W9XYZ EN37, ...
|
||||
3. K1ABC KH1DX -13
|
||||
4. KH1DX K1ABC R-11
|
||||
5. K1ABC R 73; W9XYZ <KH1DX> -17
|
||||
5. K1ABC RR73; W9XYZ <KH1DX> -17
|
||||
6. ... no copy from W9XYZ ...
|
||||
7. W9XYZ KH1DX -17
|
||||
8. ... no copy from W9XYZ ...
|
||||
9. G4AAA KH1DX -11
|
||||
10. KH1DX G4AAA R-03
|
||||
11. G4AAA R 73; DL3BBB <KH1DX> -12
|
||||
11. G4AAA RR73; DL3BBB <KH1DX> -12
|
||||
12. KH1DX DL3BBB R-09
|
||||
13. DL3BBB R 73; DE <KH1DX>
|
||||
13. DL3BBB RR73; DE <KH1DX>
|
||||
14. ...
|
||||
------------------------------------------------------------------------
|
||||
|
||||
@@ -144,7 +144,7 @@ hoping to find a clear slot, by using Shift+F11 and Shift+F12.
|
||||
sent automatically.
|
||||
|
||||
- After you send the "R+rpt" message, AutoSeq will watch for a
|
||||
message that starts with "MyCall R 73; ...". When that is
|
||||
message that starts with "MyCall RR73; ...". When that is
|
||||
received, you're in his log, and you'll be prompted to log the QSO.
|
||||
|
||||
Random thoughts
|
||||
|
||||
@@ -12,10 +12,10 @@ subroutine azdist(grid1,grid2,utch,nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter)
|
||||
data mygrid0/" "/,hisgrid0/" "/,utch0/-999.d0/
|
||||
save
|
||||
|
||||
MyGrid=grid1
|
||||
HisGrid=grid2
|
||||
if(ichar(grid1(5:5)).eq.0) MyGrid(5:6)=' '
|
||||
if(ichar(grid2(5:5)).eq.0) HisGrid(5:6)=' '
|
||||
MyGrid=grid1//' '
|
||||
HisGrid=grid2//' '
|
||||
if(ichar(MyGrid(5:5)).eq.0) MyGrid(5:6)=' '
|
||||
if(ichar(HisGrid(5:5)).eq.0) HisGrid(5:6)=' '
|
||||
|
||||
if(MyGrid.eq.HisGrid) then
|
||||
naz=0
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
subroutine ccf2(ss,nz,nflip,ccfbest,xlagpk)
|
||||
|
||||
parameter (LAGMIN=-86,LAGMAX=258)
|
||||
! parameter (LAGMIN=-86,LAGMAX=258)
|
||||
parameter (LAGMIN=-112,LAGMAX=258) ! Look for DT from -3.6s to +5.0s
|
||||
real ss(nz)
|
||||
real ccf(-LAGMAX:LAGMAX)
|
||||
integer npr(126)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
subroutine decode65a(dd,npts,newdat,nqd,f0,nflip,mode65,ntrials, &
|
||||
naggressive,ndepth,ntol,mycall,hiscall,hisgrid,nexp_decode, &
|
||||
naggressive,ndepth,ntol,mycall,hiscall,hisgrid,nQSOProgress, &
|
||||
ljt65apon, nexp_decode, &
|
||||
bVHF,sync2,a,dt,nft,nspecial,qual,nhist,nsmo,decoded)
|
||||
|
||||
! Apply AFC corrections to a candidate JT65 signal, then decode it.
|
||||
@@ -15,7 +16,7 @@ subroutine decode65a(dd,npts,newdat,nqd,f0,nflip,mode65,ntrials, &
|
||||
complex c5a(512)
|
||||
real s2(66,126)
|
||||
real a(5)
|
||||
logical bVHF,first
|
||||
logical bVHF,first,ljt65apon
|
||||
character decoded*22,decoded_best*22
|
||||
character mycall*12,hiscall*12,hisgrid*6
|
||||
character*27 cr
|
||||
@@ -122,10 +123,11 @@ subroutine decode65a(dd,npts,newdat,nqd,f0,nflip,mode65,ntrials, &
|
||||
endif
|
||||
s2(i,1:126)=s1(jj,1:126)
|
||||
enddo
|
||||
|
||||
nadd=ismo !### ??? ###
|
||||
call decode65b(s2,nflip,nadd,mode65,ntrials,naggressive,ndepth, &
|
||||
mycall,hiscall,hisgrid,nexp_decode,nqd,nft,qual,nhist,decoded)
|
||||
mycall,hiscall,hisgrid,nQSOProgress,ljt65apon,nexp_decode, &
|
||||
nqd,nft,qual, &
|
||||
nhist,decoded)
|
||||
|
||||
if(nft.eq.1) then
|
||||
nsmo=ismo
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
subroutine decode65b(s2,nflip,nadd,mode65,ntrials,naggressive,ndepth, &
|
||||
mycall,hiscall,hisgrid,nexp_decode,nqd,nft,qual,nhist,decoded)
|
||||
mycall,hiscall,hisgrid,nQSOProgress,ljt65apon,nexp_decode,nqd, &
|
||||
nft,qual, &
|
||||
nhist,decoded)
|
||||
|
||||
use jt65_mod
|
||||
real s2(66,126)
|
||||
real s3(64,63)
|
||||
logical ltext
|
||||
logical ltext,ljt65apon
|
||||
character decoded*22
|
||||
character mycall*12,hiscall*12,hisgrid*6
|
||||
save
|
||||
@@ -19,7 +21,8 @@ subroutine decode65b(s2,nflip,nadd,mode65,ntrials,naggressive,ndepth, &
|
||||
enddo
|
||||
|
||||
call extract(s3,nadd,mode65,ntrials,naggressive,ndepth,nflip,mycall, &
|
||||
hiscall,hisgrid,nexp_decode,ncount,nhist,decoded,ltext,nft,qual)
|
||||
hiscall,hisgrid,nQSOProgress,ljt65apon,nexp_decode,ncount, &
|
||||
nhist,decoded,ltext,nft,qual)
|
||||
|
||||
! Suppress "birdie messages" and other garbage decodes:
|
||||
if(decoded(1:7).eq.'000AAA ') ncount=-1
|
||||
|
||||
@@ -54,10 +54,13 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
10 if (params%nagain) then
|
||||
open(13,file=trim(temp_dir)//'/decoded.txt',status='unknown', &
|
||||
position='append',iostat=ios)
|
||||
if(params%nmode.eq.8) open(19,file=trim(temp_dir)//'/houndcallers.txt', &
|
||||
status='unknown',position='append',iostat=ios)
|
||||
else
|
||||
open(13,file=trim(temp_dir)//'/decoded.txt',status='unknown', &
|
||||
iostat=ios)
|
||||
end if
|
||||
open(13,file=trim(temp_dir)//'/decoded.txt',status='unknown',iostat=ios)
|
||||
if(params%nmode.eq.8) open(19,file=trim(temp_dir)//'/houndcallers.txt', &
|
||||
status='unknown',iostat=ios)
|
||||
endif
|
||||
if(ios.ne.0) then
|
||||
nfail=nfail+1
|
||||
if(nfail.le.3) then
|
||||
@@ -73,9 +76,38 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
call my_ft8%decode(ft8_decoded,id2,params%nQSOProgress,params%nfqso, &
|
||||
params%nftx,newdat,params%nutc,params%nfa,params%nfb, &
|
||||
params%nexp_decode,params%ndepth,logical(params%nagain), &
|
||||
logical(params%lapon),params%napwid,params%mycall, &
|
||||
params%mygrid,params%hiscall,params%hisgrid)
|
||||
logical(params%lft8apon),logical(params%lapcqonly),params%napwid, &
|
||||
params%mycall,params%mygrid,params%hiscall,params%hisgrid)
|
||||
call timer('decft8 ',1)
|
||||
if(nfox.gt.0) then
|
||||
n30min=minval(n30fox(1:nfox))
|
||||
n30max=maxval(n30fox(1:nfox))
|
||||
endif
|
||||
j=0
|
||||
rewind 19
|
||||
if(nfox.eq.0) then
|
||||
endfile 19
|
||||
rewind 19
|
||||
else
|
||||
do i=1,nfox
|
||||
n=n30fox(i)
|
||||
if(n30max-n30fox(i).le.4) then
|
||||
j=j+1
|
||||
c2fox(j)=c2fox(i)
|
||||
g2fox(j)=g2fox(i)
|
||||
nsnrfox(j)=nsnrfox(i)
|
||||
nfreqfox(j)=nfreqfox(i)
|
||||
n30fox(j)=n
|
||||
m=n30max-n
|
||||
call azdist(params%mygrid,g2fox(j),0.d0,nAz,nEl,nDmiles,nDkm, &
|
||||
nHotAz,nHotABetter)
|
||||
write(19,1004) c2fox(j),g2fox(j),nsnrfox(j),nfreqfox(j),nDkm,m
|
||||
1004 format(a12,1x,a4,i5,i6,i7,i3)
|
||||
endif
|
||||
enddo
|
||||
nfox=j
|
||||
flush(19)
|
||||
endif
|
||||
go to 800
|
||||
endif
|
||||
|
||||
@@ -153,7 +185,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
logical(params%nagain),params%n2pass,logical(params%nrobust), &
|
||||
ntrials,params%naggressive,params%ndepth,params%emedelay, &
|
||||
logical(params%nclearave),params%mycall,params%hiscall, &
|
||||
params%hisgrid,params%nexp_decode)
|
||||
params%hisgrid,params%nexp_decode,params%nQSOProgress, &
|
||||
logical(params%ljt65apon))
|
||||
call timer('jt65a ',1)
|
||||
|
||||
else if(params%nmode.eq.9 .or. (params%nmode.eq.(65+9) .and. params%ntxmode.eq.9)) then
|
||||
@@ -178,7 +211,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
logical(params%nagain),params%n2pass,logical(params%nrobust), &
|
||||
ntrials,params%naggressive,params%ndepth,params%emedelay, &
|
||||
logical(params%nclearave),params%mycall,params%hiscall, &
|
||||
params%hisgrid,params%nexp_decode)
|
||||
params%hisgrid,params%nexp_decode,params%nQSOProgress, &
|
||||
logical(params%ljt65apon))
|
||||
call timer('jt65a ',1)
|
||||
else
|
||||
call timer('decjt9 ',0)
|
||||
@@ -197,7 +231,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
write(*,1010) nsynced,ndecoded
|
||||
1010 format('<DecodeFinished>',2i4)
|
||||
call flush(6)
|
||||
close(13)
|
||||
close(13)
|
||||
close(19)
|
||||
if(params%nmode.eq.4 .or. params%nmode.eq.65) close(14)
|
||||
|
||||
return
|
||||
@@ -290,7 +325,7 @@ contains
|
||||
integer, intent(in) :: nsum
|
||||
integer, intent(in) :: minsync
|
||||
|
||||
integer i,nft
|
||||
integer i,nap,nft
|
||||
logical is_deep,is_average
|
||||
character decoded*22,csync*2,cflags*3
|
||||
|
||||
@@ -332,6 +367,10 @@ contains
|
||||
write(cflags(2:2),'(i1)') min(nsum,9)
|
||||
if(nsum.ge.10) cflags(2:2)='*'
|
||||
endif
|
||||
nap=ishft(ft,-2)
|
||||
if(nap.ne.0) then
|
||||
write(cflags(1:3),'(a1,i1)') 'a',nap
|
||||
endif
|
||||
endif
|
||||
csync='# '
|
||||
i=0
|
||||
@@ -399,22 +438,80 @@ contains
|
||||
integer, intent(in) :: snr
|
||||
real, intent(in) :: dt
|
||||
real, intent(in) :: freq
|
||||
character(len=22), intent(in) :: decoded
|
||||
character(len=37), intent(in) :: decoded
|
||||
character c1*12,c2*6,g2*4,w*4
|
||||
integer i0,i1,i2,i3,i4,i5,n30,nwrap
|
||||
integer, intent(in) :: nap
|
||||
real, intent(in) :: qual
|
||||
character*2 annot
|
||||
character*22 decoded0
|
||||
|
||||
decoded0=decoded
|
||||
character*37 decoded0
|
||||
logical isgrid4,first,b0,b1,b2
|
||||
data first/.true./
|
||||
save
|
||||
|
||||
isgrid4(w)=(len_trim(w).eq.4 .and. &
|
||||
ichar(w(1:1)).ge.ichar('A') .and. ichar(w(1:1)).le.ichar('R') .and. &
|
||||
ichar(w(2:2)).ge.ichar('A') .and. ichar(w(2:2)).le.ichar('R') .and. &
|
||||
ichar(w(3:3)).ge.ichar('0') .and. ichar(w(3:3)).le.ichar('9') .and. &
|
||||
ichar(w(4:4)).ge.ichar('0') .and. ichar(w(4:4)).le.ichar('9'))
|
||||
|
||||
if(first) then
|
||||
c2fox=' '
|
||||
g2fox=' '
|
||||
nsnrfox=-99
|
||||
nfreqfox=-99
|
||||
n30z=0
|
||||
nwrap=0
|
||||
nfox=0
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
decoded0=decoded
|
||||
|
||||
annot=' '
|
||||
if(nap.ne.0) then
|
||||
write(annot,'(a1,i1)') 'a',nap
|
||||
if(qual.lt.0.17) decoded0(22:22)='?'
|
||||
write(annot,'(a1,i1)') 'a',nap
|
||||
if(qual.lt.0.17) decoded0(22:22)='?'
|
||||
endif
|
||||
write(*,1000) params%nutc,snr,dt,nint(freq),decoded0,annot
|
||||
|
||||
i0=index(decoded0,';')
|
||||
if(i0.le.0) write(*,1000) params%nutc,snr,dt,nint(freq),decoded0(1:22),annot
|
||||
1000 format(i6.6,i4,f5.1,i5,' ~ ',1x,a22,1x,a2)
|
||||
if(i0.gt.0) write(*,1001) params%nutc,snr,dt,nint(freq),decoded0
|
||||
1001 format(i6.6,i4,f5.1,i5,' ~ ',1x,a37)
|
||||
write(13,1002) params%nutc,nint(sync),snr,dt,freq,0,decoded0
|
||||
1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a22,' FT8')
|
||||
1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FT8')
|
||||
|
||||
i1=index(decoded0,' ')
|
||||
i2=i1 + index(decoded0(i1+1:),' ')
|
||||
i3=i2 + index(decoded0(i2+1:),' ')
|
||||
if(i1.ge.3 .and. i2.ge.7 .and. i3.ge.10) then
|
||||
c1=decoded0(1:i1-1)//' '
|
||||
c2=decoded0(i1+1:i2-1)
|
||||
g2=decoded0(i2+1:i3-1)
|
||||
b0=c1.eq.params%mycall
|
||||
if(len(trim(c1)).ne.len(trim(params%mycall))) then
|
||||
i4=index(trim(c1),trim(params%mycall))
|
||||
i5=index(trim(params%mycall),trim(c1))
|
||||
if(i4.ge.1 .or. i5.ge.1) b0=.true.
|
||||
endif
|
||||
b1=i3-i2.eq.5 .and. isgrid4(g2)
|
||||
b2=i3-i2.eq.1
|
||||
if(b0 .and. (b1.or.b2) .and. nint(freq).ge.1000) then
|
||||
n=params%nutc
|
||||
n30=(3600*(n/10000) + 60*mod((n/100),100) + mod(n,100))/30
|
||||
if(n30.lt.n30z) nwrap=nwrap+5760 !New UTC day, handle the wrap
|
||||
n30z=n30
|
||||
n30=n30+nwrap
|
||||
nfox=nfox+1
|
||||
c2fox(nfox)=c2
|
||||
g2fox(nfox)=g2
|
||||
nsnrfox(nfox)=snr
|
||||
nfreqfox(nfox)=nint(freq)
|
||||
n30fox(nfox)=n30
|
||||
endif
|
||||
endif
|
||||
|
||||
call flush(6)
|
||||
call flush(13)
|
||||
|
||||
|
||||